Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/v 4 lib upgrade #140

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c2f119a
update CQL to using FHIR401, update node JS version, package.json upd…
Jan 10, 2022
151e414
version changes, bug fix
Jan 20, 2022
369df95
CQL changes, fix broken tests
Jan 27, 2022
6864588
update comments, remove un-intended changes
Jan 27, 2022
0006a6a
move back old changes
Jan 28, 2022
c58cd38
add missing rxnorm
Jan 28, 2022
4256207
refactor functions
Jan 28, 2022
be48138
put dstu2 changes back
Jan 28, 2022
e5bc0c2
add back old changes
Jan 28, 2022
32c74ab
add comments, remove old valueset update file
Jan 28, 2022
93af0d7
add comments
Jan 28, 2022
bbd14eb
check for existence of environment var
Jan 31, 2022
234fdb1
update comments
Jan 31, 2022
7dc6637
break function into smaller ones
Jan 31, 2022
9d3c867
syntax refactor
Jan 31, 2022
2f4f40e
remove debug statements
Jan 31, 2022
e125ffe
accessibility fixes
Jan 31, 2022
3893cb4
minor styling fix
Feb 1, 2022
5dd8dd6
fix total to check for null
Feb 1, 2022
659595d
fix comment
Feb 2, 2022
2308f5b
Merge branch 'develop' of https://github.com/uwcirg/AHRQ-CDS-Connect-…
Feb 9, 2022
ce5e5ee
Merge branch 'develop' of https://github.com/uwcirg/AHRQ-CDS-Connect-…
Feb 18, 2022
c69b1ed
update comments, fix graph position
Feb 22, 2022
01f48f1
graph fix
Feb 22, 2022
be0ad18
Merge branch 'develop' of https://github.com/uwcirg/AHRQ-CDS-Connect-…
Feb 22, 2022
330f02d
fix comment, check for null
Feb 25, 2022
962f07e
update libs
Mar 1, 2022
776f196
remove unintended changes
Mar 3, 2022
3226a98
fix README based on feedback
Mar 9, 2022
6d55971
new provider resources section with additional links
Apr 5, 2022
9529b57
minor styling fix
Apr 7, 2022
e8dce1a
minor side nav styling fix
Apr 7, 2022
41aac55
fix nav styling
Apr 7, 2022
856d565
fix broken links
Apr 7, 2022
37fae58
fix broken link
Apr 7, 2022
554bff1
Merge branch 'feature/provider-resources-section' of https://github.c…
Apr 7, 2022
f2a9131
Merge branch 'feature/provider-resources-section' of https://github.c…
Apr 7, 2022
27f3c24
Merge branch 'develop' of https://github.com/uwcirg/AHRQ-CDS-Connect-…
Apr 7, 2022
fc62ae3
Merge branch 'develop' of https://github.com/uwcirg/AHRQ-CDS-Connect-…
Apr 7, 2022
933abb7
Merge branch 'develop' of https://github.com/uwcirg/AHRQ-CDS-Connect-…
Apr 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.11.3
12.20.0
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12.*
2 changes: 1 addition & 1 deletion .rescriptsrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ module.exports = [
addHtmlWebpackPluginForLaunch,
stubUnneededFiles
// ,logConfig
];
];
38 changes: 30 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The Pain Management Summary SMART on FHIR application was developed to support t

The Pain Management Summary SMART on FHIR application was piloted during Summer 2018. Local modifications and development were needed to fully support this application in the pilot environment. For example, custom development was needed to expose pain assessments via the FHIR API. See the pilot reports for more information.

This application was originally piloted with support for FHIR DSTU2. The app has been updated since the pilot to also support FHIR R4, although pilot R4 support has not been piloted in a clinical setting.
This application was originally piloted with support for FHIR DSTU2. The app has been updated since the pilot to also support FHIR R4. In addition, value sets and standardized codes have been updated since the pilot. See the comments in the bundled CQL for details.

This prototype application is part of the [CDS Connect](https://cds.ahrq.gov/cdsconnect) project, sponsored by the [Agency for Healthcare Research and Quality](https://www.ahrq.gov/) (AHRQ), and developed under contract with AHRQ by [MITRE's CAMH](https://www.mitre.org/centers/cms-alliances-to-modernize-healthcare/who-we-are) FFRDC.

Expand All @@ -30,11 +30,6 @@ This CDS logic queries for several concepts that do not yet have standardized co

| Code | System | Display |
| --- | --- | --- |
| PEGASSESSMENT | http://cds.ahrq.gov/cdsconnect/pms | Pain Enjoyment General Activity (PEG) Assessment |
| PEGPAIN | http://cds.ahrq.gov/cdsconnect/pms | Pain |
| PEGENJOYMENT | http://cds.ahrq.gov/cdsconnect/pms | Enjoyment of life |
| PEGGENERALACTIVITY | http://cds.ahrq.gov/cdsconnect/pms | General activity |
| STARTBACK | http://cds.ahrq.gov/cdsconnect/pms | STarT Back Screening Tool |
| SQETOHUSE | http://cds.ahrq.gov/cdsconnect/pms | Single question r/t ETOH use |
| SQDRUGUSE | http://cds.ahrq.gov/cdsconnect/pms | Single question r/t drug use |
| MME | http://cds.ahrq.gov/cdsconnect/pms | Morphine Milligram Equivalent (MME) |
Expand All @@ -43,7 +38,7 @@ Systems integrating the Pain Management Summary will need to expose the correspo

### To build and run in development:

1. Install [Node.js](https://nodejs.org/en/download/) (LTS edition, currently 8.x)
1. Install [Node.js](https://nodejs.org/en/download/) (LTS edition, currently 12.x)
2. Install [Yarn](https://yarnpkg.com/en/docs/install) (1.3.x or above)
3. Install dependencies by executing `yarn` from the project's root directory
4. If you have a SMART-on-FHIR client ID, edit `public/launch-context.json` to specify it
Expand All @@ -55,7 +50,7 @@ Systems integrating the Pain Management Summary will need to expose the correspo

The Pain Management Summary can be deployed as static web resources on any HTTP server. There are several customizations, however, that need to be made based on the site where it is deployed.

1. Install [Node.js](https://nodejs.org/en/download/) (LTS edition, currently 8.x)
1. Install [Node.js](https://nodejs.org/en/download/) (LTS edition, currently 12.x)
2. Install [Yarn](https://yarnpkg.com/en/docs/install) (1.3.x or above)
3. Install dependencies by executing `yarn` from the project's root directory
4. Modify the `homepage` value in `package.json` to reflect the path (after the hostname) at which it will be deployed
Expand All @@ -71,12 +66,39 @@ The Pain Management Summary can be deployed as static web resources on any HTTP

Optionally to step 9, you can run the static build contents in a simple Node http-server via the command: `yarn start-static`.

### To update the valueset-db.json file

The value set content used by the CQL is cached in a file named `valueset-db.json`. If the CQL has been modified to add or remove value sets, or if the value sets themselves have been updated, you may wish to update the valueset-db.json with the latest codes. To do this, you will need a [UMLS Terminology Services account](https://uts.nlm.nih.gov//license.html).

To update the `valueset-db.json` file:

1. Run `node src/utils/updateValueSetDB.js UMLS_API_KEY` _(replacing UMLS\_API\_KEY with your actual UMLS API key)_

To get you UMLS API Key:

1. Sign into your UMLS account at [https://uts.nlm.nih.gov/uts.html](https://uts.nlm.nih.gov/uts.html)
2. Click 'My Profile' in the orange banner at the top of the screen
3. Your API key should be listed below your username in the table
4. If no API key is listed:
1. Click ‘Edit Profile’
2. Select the ‘Generate new API Key’ checkbox
3. Click ‘Save Profile’
4. Your new API key should now be listed.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice addition, thanks.

### To run the unit tests

To execute the unit tests:

1. Run `yarn test`

### To update the test patients' date-based fields

Testing this SMART App is more meaningful when we can supply test patients that exercise various aspects of the application. Test patients are represented as FHIR bundles at `src/utils/dstu2_test_patients` and `r4_test_patients`. Since the CDS uses lookbacks (for example, only show MME in the last 6 months), the patient data occasionally needs to be updated to fit within the lookback windows. To automatically update the data to fit within the lookback windows as of today's date:

1. Run `yarn update-test-patients`

This will update all of the entries in the patient bundles to be appropriate relative to today's date. In addition, it sets each bundle's `meta.lastUpdated` to the current date. This is essential for ensuring that future updates work correctly since it uses the `meta.lastUpdated` date to determine how far back each other date should be relative to today.

## To test the app using the public SMART sandbox

Run the app via one of the options above, then:
Expand Down
22 changes: 13 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pain-management-factors",
"version": "0.3.0",
"version": "0.4.0",
"description": "Pain Management Factors SMART-on-FHIR App",
"license": "Apache-2.0",
"dependencies": {
Expand All @@ -10,9 +10,9 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"core-js": "^3.6.5",
"cql-exec-fhir": "^1.3.1",
"cql-execution": "^1.3.7",
"core-js": "^3.12.1",
"cql-exec-fhir": "^2.0.0",
"cql-execution": "^2.3.1",
"d3": "^5.16.0",
"d3-array": "^2.4.0",
"d3-axis": "^1.0.12",
Expand All @@ -37,20 +37,24 @@
"tocbot": "^4.10.0"
},
"devDependencies": {
"@rescripts/cli": "^0.0.13",
"@rescripts/utilities": "^0.0.6",
"@rescripts/cli": "^0.0.16",
"@rescripts/utilities": "^0.0.8",
"cors": "^2.8.5",
"cql-exec-vsac": "^1.2.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"express": "^4.17.1",
"gh-pages": "^2.2.0",
"gh-pages": "^3.2.3",
"jest-enzyme": "^7.1.2",
"mock-local-storage": "^1.1.11",
"react-router-test-context": "^0.1.0",
"temp": "^0.9.1",
"typescript": "^3.7.5"
},
"resolutions": {
"ucum": "cmoesel/ucum.js#es5-friendly"
"immer": "^9.0.2",
"ssri": "^8.0.1",
"ansi-regex": "^5.0.1"
},
"eslintConfig": {
"extends": "react-app"
Expand Down Expand Up @@ -79,7 +83,7 @@
"eject": "rescripts eject",
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
"fix-vs-db": "node ./src/utils/fixVsDb",
"update-test-patients": "node ./src/utils/updateTestPatients",
"upload-test-patients": "node ./src/utils/uploadTestPatients",
"lint": "eslint ."
}
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/helpers/flagit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ it.skip('flags "Most Recent MME" entries correctly', () => {
"Result": "50 {MME}/d",
"Date": "2018-04-30T00:00:00.000+00:00"
};
const mockFlag = "Most recent MED assessment is 50+ MED/day.";
const mockFlag = {"class": "", "date": "Date", "text": "Most recent MED assessment is 50+ MED/day."};
expect(flagit(mockEntryB, subSection, mockSummaryA)).toEqual(mockFlag);
expect(flagit(mockEntryA, subSection, mockSummaryA)).toEqual(false);
expect(flagit(null, subSection, mockSummaryA)).toEqual(false);
Expand Down Expand Up @@ -184,7 +184,7 @@ it('flags "Benzodiazepine Medications" entries correctly', () => {
"End": null
};
const mockFlagA = {"class": "", "date": "", "text": "Possible co-prescribing of sedatives with opioids."};
const mockFlagB = "Caution for opioid prescribing, patient has been prescribed barbiturates.";
const mockFlagB = "Caution for opioid prescribing, patient has been prescribed sedatives.";
// one or more benzo (true) AND one or more opioids (true) => mockFlagA
expect(flagit(mockEntry, subSection, mockSummaryA)).toEqual(mockFlagA);
// no benzo (false) AND one or more opioids (true) => false
Expand Down
54 changes: 21 additions & 33 deletions src/cql/dstu2/CDS_Connect_Commons_for_FHIRv102.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"library" : {
"annotation" : [ {
"translatorOptions" : "",
"type" : "CqlToElmInfo"
} ],
"identifier" : {
"id" : "CDS_Connect_Commons_for_FHIRv102",
"version" : "1.3.1"
Expand Down Expand Up @@ -34,16 +38,12 @@
"expression" : {
"type" : "If",
"condition" : {
"asType" : "{urn:hl7-org:elm-types:r1}Boolean",
"type" : "As",
"type" : "Not",
"operand" : {
"type" : "Not",
"type" : "IsNull",
"operand" : {
"type" : "IsNull",
"operand" : {
"name" : "Cpt",
"type" : "OperandRef"
}
"name" : "Cpt",
"type" : "OperandRef"
}
}
},
Expand Down Expand Up @@ -79,16 +79,12 @@
"expression" : {
"type" : "If",
"condition" : {
"asType" : "{urn:hl7-org:elm-types:r1}Boolean",
"type" : "As",
"type" : "Not",
"operand" : {
"type" : "Not",
"type" : "IsNull",
"operand" : {
"type" : "IsNull",
"operand" : {
"name" : "Pd",
"type" : "OperandRef"
}
"name" : "Pd",
"type" : "OperandRef"
}
}
},
Expand Down Expand Up @@ -144,22 +140,18 @@
} ]
}, {
"name" : "NullSafeToQuantity",
"context" : "Patient",
"context" : "Unfiltered",
"accessLevel" : "Public",
"type" : "FunctionDef",
"expression" : {
"type" : "If",
"condition" : {
"asType" : "{urn:hl7-org:elm-types:r1}Boolean",
"type" : "As",
"type" : "Not",
"operand" : {
"type" : "Not",
"type" : "IsNull",
"operand" : {
"type" : "IsNull",
"operand" : {
"name" : "Qty",
"type" : "OperandRef"
}
"name" : "Qty",
"type" : "OperandRef"
}
}
},
Expand Down Expand Up @@ -233,16 +225,12 @@
"expression" : {
"type" : "If",
"condition" : {
"asType" : "{urn:hl7-org:elm-types:r1}Boolean",
"type" : "As",
"type" : "Not",
"operand" : {
"type" : "Not",
"type" : "IsNull",
"operand" : {
"type" : "IsNull",
"operand" : {
"name" : "Rg",
"type" : "OperandRef"
}
"name" : "Rg",
"type" : "OperandRef"
}
}
},
Expand Down
73 changes: 70 additions & 3 deletions src/cql/dstu2/FHIRHelpers.cql
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,80 @@ define function ToInterval(period FHIR.Period):
if period is null then
null
else
Interval[period."start".value, period."end".value]
if period."start" is null then
Interval(period."start".value, period."end".value]
else
Interval[period."start".value, period."end".value]

define function ToCalendarUnit(unit System.String):
case unit
when 'ms' then 'millisecond'
when 's' then 'second'
when 'min' then 'minute'
when 'h' then 'hour'
when 'd' then 'day'
when 'wk' then 'week'
when 'mo' then 'month'
when 'a' then 'year'
else unit
end

define function ToQuantity(quantity FHIR.Quantity):
if quantity is null then
case
when quantity is null then null
when quantity.value is null then null
when quantity.comparator is not null then
Message(null, true, 'FHIRHelpers.ToQuantity.ComparatorQuantityNotSupported', 'Error', 'FHIR Quantity value has a comparator and cannot be converted to a System.Quantity value.')
when quantity.system is null or quantity.system.value = 'http://unitsofmeasure.org'
or quantity.system.value = 'http://hl7.org/fhirpath/CodeSystem/calendar-units' then
System.Quantity { value: quantity.value.value, unit: ToCalendarUnit(Coalesce(quantity.code.value, quantity.unit.value, '1')) }
else
Message(null, true, 'FHIRHelpers.ToQuantity.InvalidFHIRQuantity', 'Error', 'Invalid FHIR Quantity code: ' & quantity.unit.value & ' (' & quantity.system.value & '|' & quantity.code.value & ')')
end

define function ToQuantityIgnoringComparator(quantity FHIR.Quantity):
case
when quantity is null then null
when quantity.value is null then null
when quantity.system is null or quantity.system.value = 'http://unitsofmeasure.org'
or quantity.system.value = 'http://hl7.org/fhirpath/CodeSystem/calendar-units' then
System.Quantity { value: quantity.value.value, unit: ToCalendarUnit(Coalesce(quantity.code.value, quantity.unit.value, '1')) }
else
Message(null, true, 'FHIRHelpers.ToQuantity.InvalidFHIRQuantity', 'Error', 'Invalid FHIR Quantity code: ' & quantity.unit.value & ' (' & quantity.system.value & '|' & quantity.code.value & ')')
end

define function ToInterval(quantity FHIR.Quantity):
if quantity is null then null else
case quantity.comparator.value
when '<' then
Interval[
null,
ToQuantityIgnoringComparator(quantity)
)
when '<=' then
Interval[
null,
ToQuantityIgnoringComparator(quantity)
]
when '>=' then
Interval[
ToQuantityIgnoringComparator(quantity),
null
]
when '>' then
Interval(
ToQuantityIgnoringComparator(quantity),
null
]
else
Interval[ToQuantity(quantity), ToQuantity(quantity)]
end

define function ToRatio(ratio FHIR.Ratio):
if ratio is null then
null
else
System.Quantity { value: quantity.value.value, unit: quantity.unit.value }
System.Ratio { numerator: ToQuantity(ratio.numerator), denominator: ToQuantity(ratio.denominator) }

define function ToInterval(range FHIR.Range):
if range is null then
Expand Down
Loading