Skip to content

Commit

Permalink
Merge pull request #741 from FluxNotes/external_fhir_mapping
Browse files Browse the repository at this point in the history
External fhir mapping
  • Loading branch information
dehall authored Aug 26, 2019
2 parents ec9a1d3 + bf3203f commit 5671536
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 30 deletions.
10 changes: 10 additions & 0 deletions config-overrides.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
const CopyWebpackPlugin = require('copy-webpack-plugin');
const {
override,
useEslintRc,
addWebpackExternals,
addWebpackPlugin
} = require("customize-cra");


module.exports = override(
useEslintRc(),
addWebpackExternals({
'fhir-mapper': "Mapper",
'babel-polyfill': "_babelPolyfill"
}),
addWebpackPlugin(new CopyWebpackPlugin([
{ context:'node_modules/fhir-mapper/dist/', from: 'app.bundle.js*', to: 'static/js/fhir-mapper' }
]))
);
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"downshift": "^1.31.16",
"elasticlunr": "https://github.com/mgramigna/elasticlunr.js",
"es6-shim": "0.35.3",
"fhir-mapper": "^1.0.6",
"fhir-mapper": "^2.0.1",
"fhirclient": "^0.1.12",
"flat": "^4.1.0",
"flux_notes_treatment_options_rest_client": "^1.1.2",
Expand Down Expand Up @@ -95,7 +95,8 @@
"react-scripts": "2.1.8",
"react-test-renderer": "15.6.2",
"redux-mock-store": "1.5.3",
"testcafe": "0.17.1"
"testcafe": "0.17.1",
"copy-webpack-plugin" : "5.0.4"
},
"resolutions": {
"moment": "2.22.0",
Expand Down
13 changes: 7 additions & 6 deletions public/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ CONFIG = {
isExact: true,
launchContext: {
client: {
client_id: '6c12dff4-24e7-4475-a742-b08972c4ea27',
scope: 'patient/*.read user/*.* openid profile',
client_id: '5a14eeb1-973b-4362-9289-59ff27fcc29a',
scope: 'patient/AllergyIntolerance.read patient/Appointment.read patient/Binary.read patient/CarePlan.read patient/Condition.read patient/Contract.read patient/Device.read patient/DiagnosticReport.read patient/DocumentReference.read patient/Encounter.read patient/Goal.read patient/Immunization.read patient/MedicationAdministration.read patient/MedicationOrder.read patient/MedicationStatement.read patient/Observation.read patient/Patient.read patient/Person.read patient/Procedure.read patient/ProcedureRequest.read patient/RelatedPerson.read patient/Schedule.read patient/Slot.read user/AllergyIntolerance.read user/Appointment.read user/Binary.read user/CarePlan.read user/Condition.read user/Contract.read user/Device.read user/DiagnosticReport.read user/DocumentReference.read user/Encounter.read user/Goal.read user/Immunization.read user/MedicationAdministration.read user/MedicationOrder.read user/MedicationStatement.read user/Observation.read user/Patient.read user/Person.read user/Practitioner.read user/Procedure.read user/ProcedureRequest.read user/RelatedPerson.read user/Schedule.read user/Slot.read openid profile',
// note: the redirect_uri below may need to change in different environments.
// a relative URL (ex. /smart or ../smart) won't work in IE
redirect_uri: 'http://localhost:3000/smartcompass'
Expand All @@ -30,9 +30,10 @@ CONFIG = {
display: 'Compass™',
app: "SmartCompassApp",
isExact: true,
dataSource: 'McodeV05SmartOnFhirDataSource',
dataSource: 'GenericSmartOnFhirDstu2DataSource',
dataSourceProps: {
resourceTypes: ['Patient', 'Condition', 'Encounter', 'MedicationOrder', 'Observation', 'Organization', 'Practitioner', 'Procedure']
mapper: 'cernerSandbox',
resourceTypes: ['Patient', 'Condition', 'Encounter', 'MedicationOrder', 'Observation', 'Procedure']
},
logoObject: {
path: './compass-logo.png',
Expand Down Expand Up @@ -60,7 +61,7 @@ CONFIG = {
// (aka, the server listed here can be used as a 'shim')
// server: "http://localhost:3001/1_0_2"
}
},
},
{
path: '/smart',
display: 'Flux Notes™',
Expand Down Expand Up @@ -96,7 +97,7 @@ CONFIG = {
dataSource: 'GenericSmartOnFhirDstu2DataSource',
shortcuts: [],
dataSourceProps: {
mapper: 'syntheaToV05'
mapper: 'cernerSandbox'
}
},
{
Expand Down
2 changes: 2 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
return window.fluxnotes_app.receive_command(name,data);
}
</script>
<script src="static/js/fhir-mapper/app.bundle.js" language="javascript"></script>
<script src="config.js" language="javascript"></script>
<script src="mapper.js" language="javascript"></script>
</head>
<body>
<div id="root"></div>
Expand Down
Empty file added public/mapper.js
Empty file.
8 changes: 6 additions & 2 deletions src/dataaccess/GenericSmartOnFhirDstu2DataSource.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import McodeV05SmartOnFhirDataSource from "./McodeV05SmartOnFhirDataSource";
import processFHIRResources from './utils/fhir-entry-processor';
import mappers from 'fhir-mapper';
import mappers from './mappers';

class GenericSmartOnFhirDstu2DataSource extends McodeV05SmartOnFhirDataSource {
constructor(props) {
super(props);
this.mapper = props && props.mapper ? mappers[props.mapper] : null;
if (props && typeof props.mapper === 'string') {
this.mapper = mappers[props.mapper];
} else {
this.mapper = props && props.mapper ? props.mapper: null;
}
}

getPatient(id, callback) {
Expand Down
2 changes: 1 addition & 1 deletion src/dataaccess/McodeV05SmartOnFhirDataSource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class McodeV05SmartOnFhirDataSource extends IDataSource {
}

_handleResponseBundle(newBundle, prevBundle=null) {
if (prevBundle) {
if (prevBundle && newBundle && newBundle.entry) {
// merge the entries from the previous bundle into the new one
newBundle.entry.unshift(...prevBundle.entry);
newBundle.total = newBundle.entry.length;
Expand Down
76 changes: 76 additions & 0 deletions src/dataaccess/mappers/CernerSandboxMapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {
buildMappers,
mappers,
utils
} from 'fhir-mapper';

const primaryCancerConditionCodes = [
'254837009', // Malignant neoplasm of breast (disorder) (B)
'93761005', // Primary malignant neoplasm of colon (C)
'109838007', // Overlapping malignant neoplasm of colon (C)
'363406005', // Malignant tumor of colon (C)
'94260004', // Secondary malignant neoplasm of colon (C) -- note this is a "secondary" code but is intended to be a primary cancer
'254637007', // Non-small cell lung cancer (disorder) (L)
'254632001', // Small cell carcinoma of lung (disorder) (L)
'424132000', // Non-small cell carcinoma of lung, TNM stage 1 (disorder) (L)
'425048006', // Non-small cell carcinoma of lung, TNM stage 2 (disorder) (L)
'422968005', // Non-small cell carcinoma of lung, TNM stage 3 (disorder) (L)
'423121009', // Non-small cell carcinoma of lung, TNM stage 4 (disorder) (L)
'67811000119102', // Primary small cell malignant neoplasm of lung, TNM stage 1 (disorder) (L)
'67821000119109', // Primary small cell malignant neoplasm of lung, TNM stage 2 (disorder) (L)
'67831000119107', // Primary small cell malignant neoplasm of lung, TNM stage 3 (disorder) (L)
'67841000119103', // Primary small cell malignant neoplasm of lung, TNM stage 4 (disorder) (L)
// note that none of the 3 prostate cancer codes are in the recommended VS
'126906006', // Neoplasm of prostate (P)
'92691004', // Carcinoma in situ of prostate (disorder) (P)
'314994000', // Metastasis from malignant tumor of prostate (disorder) (P) -- also a "secondary" code but intended to be a primary cancer
];



let mapper = {
filter: () => true,
default: (resource, context) => mappers['syntheaToV05'].execute(resource, context),
mappers: [
{
filter: "Condition.code.coding.where($this.code in %primaryCancerConditionCodes.first())",
exec: (resource, context) =>
utils.applyProfile(resource, 'http://hl7.org/fhir/us/fhirURL/StructureDefinition/oncocore-CancerDisorderPresent')
},
{filter: "Observation.code.text = 'AJCCV7 Breast Distant Metastasis (M) Pat'",
exec: (resource, context) => {
resource.code = {coding: [{code: '21901-4' , system: 'http://loinc.org'}]};
resource.valueCodeableConcept.coding = [{code: resource.valueCodeableConcept.text }];

// utils.applyProfile(resource, 'http://hl7.org/fhir/us/fhirURL/StructureDefinition/');
return resource;
}
},
{filter: "Observation.code.text = 'AJCCV7 Breast Distant Metastasis (M) Cli'",
exec: (resource, context) => {
resource.code = {coding: [{code: '21907-1' , system: 'http://loinc.org'}]};
resource.valueCodeableConcept.coding = [{code: resource.valueCodeableConcept.text }];
utils.applyProfile(resource, 'http://hl7.org/fhir/us/fhirURL/StructureDefinition/oncocore-TNMClinicalDistantMetastasesClassification');
return resource;
}
},
{filter: "Observation.code.text = 'AJCCV7 Breast Regional Lymph Nodes (N) P'",
exec: (resource, context) => {
resource.code = {coding: [{code: '21900-6' , system: 'http://loinc.org'}]};
resource.valueCodeableConcept.coding = [{code: resource.valueCodeableConcept.text }];
//utils.applyProfile(resource, 'http://hl7.org/fhir/us/fhirURL/StructureDefinition/');
return resource;
}
},
{filter: "Observation.code.text = 'AJCCV7 Breast Regional Lymph Nodes (N) C'",
exec: (resource, context) => {
resource.code = {coding: [{code: '21906-3' , system: 'http://loinc.org'}]};
resource.valueCodeableConcept.coding = [{code: resource.valueCodeableConcept.text }];
utils.applyProfile(resource, 'http://hl7.org/fhir/us/fhirURL/StructureDefinition/oncocore-TNMClinicalRegionalNodesClassification');
return resource;
}
}],
};
export default buildMappers(mapper, {
primaryCancerConditionCodes
});
3 changes: 3 additions & 0 deletions src/dataaccess/mappers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import {mappers} from 'fhir-mapper';
import cernerSandbox from './CernerSandboxMapper';
export default {...mappers, cernerSandbox};
19 changes: 13 additions & 6 deletions src/model/base/FluxConditionPresentAssertion.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ class FluxConditionPresentAssertion extends FluxEntry {
}

get code() {
if (!this._condition.findingTopicCode || !this._condition.findingTopicCode.value) return null;
return this._condition.findingTopicCode.value.coding[0].code.value;
if (!this._getTopicCodeCoding()){ return null;}
return this._getTopicCodeCoding().code.value;
}

get codeSystem() {
if (!this._condition.findingTopicCode || !this._condition.findingTopicCode.value) return null;
return this._condition.findingTopicCode.value.coding[0].codeSystem.value;
if (!this._getTopicCodeCoding()) return null;
return this._getTopicCodeCoding().codeSystem.value;
}

get codeURL() {
return this.codeSystem + "/" + this.code;
}

get type() {
if (!this._condition.findingTopicCode || !this._condition.findingTopicCode.value) return null;
return this._displayTextOrCode(this._condition.findingTopicCode.value.coding[0]);
if (!this._getTopicCodeCoding()) return null;
return this._displayTextOrCode(this._getTopicCodeCoding());
}

get observation() {
Expand Down Expand Up @@ -599,6 +599,13 @@ class FluxConditionPresentAssertion extends FluxEntry {
return 0;
}

_getTopicCodeCoding(){
if (this._condition.findingTopicCode &&
this._condition.findingTopicCode.value &&
this._condition.findingTopicCode.value.coding &&
this._condition.findingTopicCode.value.coding.length > 0 ) return this._condition.findingTopicCode.value.coding[0];
return null;
}
/**
* Extract a human-readable string from a code.
*
Expand Down
Loading

0 comments on commit 5671536

Please sign in to comment.