diff --git a/docs/CSV_Templates.xlsx b/docs/CSV_Templates.xlsx index 512870c7..1d187b35 100755 Binary files a/docs/CSV_Templates.xlsx and b/docs/CSV_Templates.xlsx differ diff --git a/docs/ctc-adverse-event.csv b/docs/ctc-adverse-event.csv index c062b8b9..09bc9d44 100644 --- a/docs/ctc-adverse-event.csv +++ b/docs/ctc-adverse-event.csv @@ -1,4 +1,4 @@ -mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade -mrn-full-example,example-id-1,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code,code-system,category-dislpay,id,1994-12-09,1994-12-09,1, -mrn-two-category-example,example-id-2,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code|category-code,code-system|code-system,category-display|category-display,id,1994-12-09,1994-12-09,3 -mrn-minimal-example,,code-from-default-system,,,,,,,,,,,,,,1994-12-09,,1 +mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade,expectation,resolvedDate,seriousnessOutcome +mrn-full-example,example-id-1,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code,code-system,category-dislpay,id,1994-12-09,1994-12-09,1,expectation-code,YYYY-MM-DD,seriousness-outcome-code +mrn-two-category-example,example-id-2,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code,code-system,category-dislpay,id,1994-12-09,1994-12-09,1,expectation-code,YYYY-MM-DD,seriousness-outcome-code +mrn-minimal-example,,code-from-default-system,,,,,,,,,,,,,1994-12-09,,1,,,,, diff --git a/src/extractors/CSVCTCAdverseEventExtractor.js b/src/extractors/CSVCTCAdverseEventExtractor.js index 5b1177af..6657a709 100644 --- a/src/extractors/CSVCTCAdverseEventExtractor.js +++ b/src/extractors/CSVCTCAdverseEventExtractor.js @@ -1,8 +1,10 @@ +const path = require('path'); const { BaseCSVExtractor } = require('./BaseCSVExtractor'); const { generateMcodeResources } = require('../templates'); const { getEmptyBundle } = require('../helpers/fhirUtils'); const { getPatientFromContext } = require('../helpers/contextUtils'); const { formatDateTime } = require('../helpers/dateUtils'); +const { getDisplayFromConcept } = require('../helpers/valueSetUtils'); const { ctcAEGradeCodeToTextLookup } = require('../helpers/lookups/ctcAdverseEventLookup'); const logger = require('../helpers/logger'); @@ -29,6 +31,9 @@ function formatData(adverseEventData, patientId) { effectivedate: effectiveDate, recordeddate: recordedDate, grade, + expectation, + resolveddate: resolvedDate, + seriousnessoutcome: seriousnessOutcome, } = data; if (!(adverseEventCode && effectiveDate && grade)) { @@ -43,7 +48,6 @@ function formatData(adverseEventData, patientId) { throw new Error('A category attribute on the adverse event is missing a corresponding categoryCodeSystem or categoryDisplayText value.'); } - return { ...(adverseEventId && { id: adverseEventId }), subjectId: patientId, @@ -67,6 +71,25 @@ function formatData(adverseEventData, patientId) { effectiveDateTime: formatDateTime(effectiveDate), recordedDateTime: !recordedDate ? null : formatDateTime(recordedDate), grade: { code: grade, display: ctcAEGradeCodeToTextLookup[grade] }, + resolvedDate: !resolvedDate ? null : formatDateTime(resolvedDate), + expectation: !expectation ? null : { + code: expectation, + system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + display: getDisplayFromConcept( + path.resolve(__dirname, '..', 'helpers', 'valueSets', 'adverse-event-expectation-value-set.json'), + expectation, + 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + ), + }, + seriousnessOutcome: !seriousnessOutcome ? null : { + code: seriousnessOutcome, + system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + display: getDisplayFromConcept( + path.resolve(__dirname, '..', 'helpers', 'valueSets', 'adverse-event-seriousness-outcome-value-set.json'), + seriousnessOutcome, + 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + ), + }, }; }); } diff --git a/src/helpers/valueSetUtils.js b/src/helpers/valueSetUtils.js index e3396cfd..abca3eaf 100644 --- a/src/helpers/valueSetUtils.js +++ b/src/helpers/valueSetUtils.js @@ -35,6 +35,37 @@ function loadVs(absoluteFilepath, typeOfVS) { } } +function getConceptFromVSExpansion(valueSet, code, codeSystem) { + if (!code || !codeSystem || !valueSet) return undefined; + return valueSet.expansion.contains.find((containsItem) => containsItem + && containsItem.system + && code === containsItem.code + && codeSystem === containsItem.system); +} + +function getConceptFromVSCompose(valueSet, code, codeSystem) { + if (!code || !codeSystem || !valueSet) return undefined; + const includeItem = valueSet.compose.include.find((item) => item + && item.system + && item.system === codeSystem + && item.concept); + if (!includeItem) return undefined; + return includeItem.concept.find((concept) => concept.code === code); +} + +function getDisplayFromConcept(pathToValueSet, code, codeSystem) { + if (!code || !codeSystem || !pathToValueSet) return undefined; + const valueSet = loadVs(pathToValueSet, vsTypes.json); + let concept; + if (valueSet.expansion) { + // If valueSet has expansion, we only need to check these codes + concept = getConceptFromVSExpansion(valueSet, code, codeSystem); + return (concept && concept.display) ? concept.display : undefined; + } + concept = getConceptFromVSCompose(valueSet, code, codeSystem); + return (concept && concept.display) ? concept.display : undefined; +} + /** * Check if code is in value set * @param {string} code value to look for in a valueset @@ -43,22 +74,21 @@ function loadVs(absoluteFilepath, typeOfVS) { * @param {string} typeOfVS the file type of the value set to be searched * @return {boolean} true if condition is in valueSet's compose block or expansion block */ -const checkCodeInVs = (code, codeSystem, valueSetFilePath, typeOfVS = vsTypes.json) => { +const checkCodeInVs = ( + code, + codeSystem, + valueSetFilePath, + typeOfVS = vsTypes.json, +) => { const valueSet = loadVs(valueSetFilePath, typeOfVS); let inVSExpansion = false; let inVSCompose = false; if (valueSet.expansion) { // If valueSet has expansion, we only need to check these codes - inVSExpansion = valueSet.expansion.contains.some((containsItem) => { - if (!code || !codeSystem || !containsItem || !containsItem.system) return false; - return code === containsItem.code && codeSystem === containsItem.system; - }); + inVSExpansion = (getConceptFromVSExpansion(valueSet, code, codeSystem) !== undefined); } else { // Checks if code is in any of the valueSet.compose.include arrays - inVSCompose = valueSet.compose.include.some((includeItem) => { - if (!code || !codeSystem || !includeItem || !includeItem.system || !includeItem.concept) return false; - return includeItem.system === codeSystem && includeItem.concept.map((concept) => concept.code).includes(code); - }); + inVSCompose = (getConceptFromVSCompose(valueSet, code, codeSystem) !== undefined); } return inVSCompose || inVSExpansion; }; @@ -68,4 +98,7 @@ module.exports = { loadJsonVs, loadVs, checkCodeInVs, + getDisplayFromConcept, + getConceptFromVSCompose, + getConceptFromVSExpansion, }; diff --git a/src/helpers/valueSets/adverse-event-expectation-value-set.json b/src/helpers/valueSets/adverse-event-expectation-value-set.json new file mode 100644 index 00000000..95934dd5 --- /dev/null +++ b/src/helpers/valueSets/adverse-event-expectation-value-set.json @@ -0,0 +1,55 @@ +{ + "resourceType": "ValueSet", + "id": "adverse-event-expectation-value-set", + "text": { + "status": "generated", + "div": "
" + }, + "url": "http://hl7.org/fhir/us/ctcae/ValueSet/adverse-event-expectation-value-set", + "version": "0.0.1", + "name": "AdverseEventExpectationVS", + "title": "Adverse Event Expectation Value Set", + "status": "active", + "date": "2021-12-03T16:46:43+00:00", + "publisher": "HL7 International Clinical Interoperability Council", + "contact": [ + { + "name": "HL7 International Clinical Interoperability Council", + "telecom": [ + { + "system": "url", + "value": "http://www.mcodeinitiative.org" + } + ] + } + ], + "description": "An expected adverse event is one whose nature and severity have been previously observed, identified in nature, severity, or frequency, and documented in the investigator brochure, investigational plan, protocol, current consent form, scientific publication, or in other relevant and reliable document. An unexpected adverse event is one that has not been previously observed, whether or not the event was anticipated because of the pharmacologic properties of the study agent or the nature of the medical procedure. This includes events that are more serious than expected or occur more frequently than expected, particularly, any adverse experience, the nature, severity or frequency of which is not consistent with the product label, or with the current investigator brochure for investigational agent; or with the risk information described in the investigational plan or protocol or consent form (NCI Thesaurus).", + "jurisdiction": [ + { + "coding": [ + { + "system": "urn:iso:std:iso:3166", + "code": "US", + "display": "United States of America" + } + ] + } + ], + "compose": { + "include": [ + { + "system": "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl", + "concept": [ + { + "code": "C41333", + "display": "Expected Adverse Event" + }, + { + "code": "C41334", + "display": "Unexpected Adverse Event" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/helpers/valueSets/adverse-event-seriousness-outcome-value-set.json b/src/helpers/valueSets/adverse-event-seriousness-outcome-value-set.json new file mode 100644 index 00000000..50b7968d --- /dev/null +++ b/src/helpers/valueSets/adverse-event-seriousness-outcome-value-set.json @@ -0,0 +1,70 @@ +{ + "resourceType": "ValueSet", + "id": "adverse-event-seriousness-outcome-value-set", + "text": { + "status": "generated", + "div": "
" + }, + "url": "http://hl7.org/fhir/us/ctcae/ValueSet/adverse-event-seriousness-outcome-value-set", + "version": "0.0.1", + "name": "AdverseEventSeriousnessOutcomeVS", + "title": "Adverse Event Seriousness Outcome Value Set", + "status": "active", + "date": "2021-12-03T16:46:43+00:00", + "publisher": "HL7 International Clinical Interoperability Council", + "contact": [ + { + "name": "HL7 International Clinical Interoperability Council", + "telecom": [ + { + "system": "url", + "value": "http://www.mcodeinitiative.org" + } + ] + } + ], + "description": "The outcome of a serious adverse event", + "jurisdiction": [ + { + "coding": [ + { + "system": "urn:iso:std:iso:3166", + "code": "US", + "display": "United States of America" + } + ] + } + ], + "compose": { + "include": [ + { + "system": "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl", + "concept": [ + { + "code": "C84266", + "display": "Life Threatening Adverse Event" + }, + { + "code": "C48275", + "display": "Death Related to Adverse Event" + }, + { + "code": "C113380", + "display": "Disabling Adverse Event" + }, + { + "code": "C83052", + "display": "Adverse Event associated with Hospitalization" + }, + { + "code": "C2849", + "display": "Congenital Abnormality" + }, + { + "code": "C52668", + "display": "Intervention Required" + } + ] + } + ] + }} \ No newline at end of file diff --git a/src/templates/CTCAdverseEventTemplate.js b/src/templates/CTCAdverseEventTemplate.js index a00f661f..fb0fd1ea 100644 --- a/src/templates/CTCAdverseEventTemplate.js +++ b/src/templates/CTCAdverseEventTemplate.js @@ -1,4 +1,4 @@ -const { coding, reference, extensionArr } = require('./snippets'); +const { coding, reference, extensionArr, valueX } = require('./snippets'); const { ifAllArgsObj, ifSomeArgsObj, ifAllArgs, ifSomeArgs, ifSomeArgsArr, } = require('../helpers/templateUtils'); @@ -73,9 +73,39 @@ function gradeTemplate(grade) { }; } +function resolvedDateTemplate(resolvedDate) { + return { + url: 'http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-resolved-date', + ...valueX(resolvedDate, 'valueDateTime'), + }; +} + +function expectationTemplate(expectation) { + return { + url: 'http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-expectation', + valueCodeableConcept: { + coding: [ + coding(expectation), + ], + }, + }; +} + +function seriousnessOutcomeTemplate(seriousnessOutcome) { + return { + url: 'http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-seriousness-outcome', + valueCodeableConcept: { + coding: [ + coding(seriousnessOutcome), + ], + }, + }; +} + + function CTCAdverseEventTemplate({ id, subjectId, code, system, version, display, text, suspectedCauseId, suspectedCauseType, seriousnessCode, seriousnessCodeSystem, seriousnessDisplayText, category, - studyId, effectiveDateTime, recordedDateTime, grade, + studyId, effectiveDateTime, recordedDateTime, grade, resolvedDate, expectation, seriousnessOutcome, }) { if (!(subjectId && code && system && effectiveDateTime && grade)) { throw Error('Trying to render an AdverseEventTemplate, but a required argument is messing; ensure that subjectId, code, system, grade, and effectiveDateTime are all present'); @@ -84,7 +114,12 @@ function CTCAdverseEventTemplate({ return { resourceType: 'AdverseEvent', id, - ...extensionArr(gradeTemplate(grade)), + ...extensionArr( + gradeTemplate(grade), + resolvedDate ? resolvedDateTemplate(resolvedDate) : null, + expectation ? expectationTemplate(expectation) : null, + seriousnessOutcome ? seriousnessOutcomeTemplate(seriousnessOutcome) : null, + ), subject: reference({ id: subjectId, resourceType: 'Patient' }), ...ifSomeArgs(eventTemplate)({ code, system, version, display }, text), ...ifAllArgsObj(suspectedCauseTemplate)({ suspectedCauseId, suspectedCauseType }), diff --git a/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json b/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json index b6bf0be1..339a2c81 100644 --- a/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json +++ b/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json @@ -19,6 +19,34 @@ } ] } + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-resolved-date", + "valueDateTime": "2021-12-01" + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-expectation", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl", + "code": "C41333", + "display": "Expected Adverse Event" + } + ] + } + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-seriousness-outcome", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl", + "code": "C113380", + "display": "Disabling Adverse Event" + } + ] + } } ], "subject": { diff --git a/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json b/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json index 732d7c1d..0d3bfa6f 100644 --- a/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json +++ b/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json @@ -18,6 +18,9 @@ "studyid": "researchId-1", "effectivedate": "12-09-1994", "recordeddate": "12-09-1994", - "grade": "1" + "grade": "1", + "resolveddate": "2021-12-01", + "seriousnessoutcome": "C113380", + "expectation": "C41333" } ] \ No newline at end of file diff --git a/test/helpers/valueSetUtils.test.js b/test/helpers/valueSetUtils.test.js index 2a1af824..61541ff9 100644 --- a/test/helpers/valueSetUtils.test.js +++ b/test/helpers/valueSetUtils.test.js @@ -1,5 +1,7 @@ const path = require('path'); -const { checkCodeInVs, vsTypes, loadJsonVs, loadVs } = require('../../src/helpers/valueSetUtils.js'); +const { + checkCodeInVs, vsTypes, loadJsonVs, loadVs, getDisplayFromConcept, getConceptFromVSCompose, getConceptFromVSExpansion, +} = require('../../src/helpers/valueSetUtils.js'); const exampleValueSet = require('./fixtures/valueset-without-expansion.json'); describe('valueSetUtils', () => { @@ -99,4 +101,65 @@ describe('valueSetUtils', () => { expect(checkCodeInVs(missingCode, icd10System, vsPath)).toBeFalsy(); }); }); + + describe('getConceptFromVSExpansion', () => { + const vsWithExpansionPath = path.resolve(__dirname, 'fixtures', 'valueset-with-expansion.json'); + const vs = loadVs(vsWithExpansionPath, vsTypes.json); + test('Should retrieve a concept from a ValueSet when the code and system are found in the expansion array', () => { + const concept = getConceptFromVSExpansion(vs, 'C00.2', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(concept).toStrictEqual({ code: 'C00.2', system: 'http://hl7.org/fhir/sid/icd-10-cm', display: 'Malignant neoplasm of external lower lip' }); + }); + test('Should not retrieve a concept from a ValueSet when the code or system are not found in the expansion array', () => { + const undefinedConcept1 = getConceptFromVSExpansion(vs, 'C00.2', 'invalid-system'); + const undefinedConcept2 = getConceptFromVSExpansion(vs, 'incalid-code', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(undefinedConcept1).toBeUndefined(); + expect(undefinedConcept2).toBeUndefined(); + }); + test('Should not retrieve concepts without systems from the expansion array of a ValueSet', () => { + const undefinedConcept = getConceptFromVSExpansion(vs, 'C00.0', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(undefinedConcept).toBeUndefined(); + }); + }); + + describe('getConceptFromVSCompose', () => { + const vsWithoutExpansionPath = path.resolve(__dirname, 'fixtures', 'valueset-without-expansion.json'); + const vs = loadVs(vsWithoutExpansionPath, vsTypes.json); + + test('Should retrieve a concept from a ValueSet when the code and system are found in the compose array', () => { + const concept = getConceptFromVSCompose(vs, 'C00.0', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(concept).toStrictEqual({ code: 'C00.0', display: 'Malignant neoplasm of external upper lip' }); + }); + test('Should not retrieve a concept from a ValueSet when the code or system are not found in the compose array', () => { + const undefinedConcept1 = getConceptFromVSCompose(vs, 'C00.0', 'invalid-system'); + const undefinedConcept2 = getConceptFromVSCompose(vs, 'incalid-code', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(undefinedConcept1).toBeUndefined(); + expect(undefinedConcept2).toBeUndefined(); + }); + test('Should not retrieve concepts without systems from the compose array of a ValueSet', () => { + const undefinedConcept = getConceptFromVSCompose(vs, 'C00.1', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(undefinedConcept).toBeUndefined(); + }); + }); + + describe('getDisplayFromConcept', () => { + const vsWithExpansionPath = path.resolve(__dirname, 'fixtures', 'valueset-with-expansion.json'); + const vsWithoutExpansionPath = path.resolve(__dirname, 'fixtures', 'valueset-without-expansion.json'); + + test('Should retrieve a display for a concept found in the expansion array of a ValueSet', () => { + const display = getDisplayFromConcept(vsWithExpansionPath, 'C00.2', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(display).toEqual('Malignant neoplasm of external lower lip'); + }); + test('Should retrieve a display for a concept found in the compose array of a ValueSet', () => { + const display = getDisplayFromConcept(vsWithoutExpansionPath, 'C00.0', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(display).toEqual('Malignant neoplasm of external upper lip'); + }); + test('Should not retrieve a display for a concept with a code system that does not match', () => { + const undefinedDisplay = getDisplayFromConcept(vsWithoutExpansionPath, 'C00.0', 'wrong-system'); + expect(undefinedDisplay).toBeUndefined(); + }); + test('Should not retrieve a display for a concept that does not exist within a ValueSet', () => { + const undefinedDisplay = getDisplayFromConcept(vsWithoutExpansionPath, 'C00.4', 'http://hl7.org/fhir/sid/icd-10-cm'); + expect(undefinedDisplay).toBeUndefined(); + }); + }); }); diff --git a/test/sample-client-data/ctc-adverse-event-information.csv b/test/sample-client-data/ctc-adverse-event-information.csv index 0b10ab05..794c1ee9 100644 --- a/test/sample-client-data/ctc-adverse-event-information.csv +++ b/test/sample-client-data/ctc-adverse-event-information.csv @@ -1,4 +1,4 @@ -mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade -123,adverseEventId-1,10012174,http://terminology.hl7.org/CodeSystem/MDRAE,20.0,Dehydration,DHN IV given,procedure-id,Procedure,serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Serious,product-use-error|product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|http://snomed.info/sct|http://terminology.hl7.org/CodeSystem/adverse-event-category,Product Use Error|Product Quality|Wrong Rate,researchId-1,12-09-1994,12-09-1994,1 -456,adverseEventId-2,C143283,http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl,20.0,Anemia,AIHA NGTD,medicationId-1,Medication,non-serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Non-serious,product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|,Product Quality|,researchId-2,12-10-1995,12-10-1995,2 -789,adverseEventId-3,150003,,,,,,,,,,product-use-error,,,,12-09-1994,,3 \ No newline at end of file +mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade,expectation,resolvedDate,seriousnessOutcome +123,adverseEventId-1,10012174,http://terminology.hl7.org/CodeSystem/MDRAE,20.0,Dehydration,DHN IV given,procedure-id,Procedure,serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Serious,product-use-error|product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|http://snomed.info/sct|http://terminology.hl7.org/CodeSystem/adverse-event-category,Product Use Error|Product Quality|Wrong Rate,researchId-1,12-09-1994,12-09-1994,1,C41333,2021-12-01,C113380 +456,adverseEventId-2,C143283,http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl,20.0,Anemia,AIHA NGTD,medicationId-1,Medication,non-serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Non-serious,product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|,Product Quality|,researchId-2,12-10-1995,12-10-1995,2,C41333,2020-10-02,C113380 +789,adverseEventId-3,150003,,,,,,,,,,product-use-error,,,,12-09-1994,,3,,, \ No newline at end of file diff --git a/test/templates/ctcAdverseEvent.test.js b/test/templates/ctcAdverseEvent.test.js index 2e2d0e1f..625cadd1 100644 --- a/test/templates/ctcAdverseEvent.test.js +++ b/test/templates/ctcAdverseEvent.test.js @@ -22,6 +22,17 @@ const VALID_DATA = { effectiveDateTime: '1994-12-09', recordedDateTime: '1994-12-09', grade: { code: '2', display: 'Moderate Adverse Event' }, + resolvedDate: '2021-12-09', + seriousnessOutcome: { + code: 'C113380', + system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + display: 'Disabling Adverse Event', + }, + expectation: { + code: 'C41333', + system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + display: 'Expected Adverse Event', + }, }; const MINIMAL_DATA = { @@ -43,6 +54,9 @@ const MINIMAL_DATA = { category: [null], studyId: null, recordedDateTime: null, + resolvedDate: null, + seriousnessOutcome: null, + expectation: null, }; @@ -65,6 +79,17 @@ const INVALID_DATA = { category: [{ code: 'product-use-error', system: 'http://terminology.hl7.org/CodeSystem/adverse-event-category' }], studyId: 'researchId-1', recordedDateTime: '1994-12-09', + resolvedDate: '2021-12-09', + seriousnessOutcome: { + code: 'C113380', + system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + display: 'Disabling Adverse Event', + }, + expectation: { + code: 'C41333', + system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', + display: 'Expected Adverse Event', + }, }; describe('test Adverse Event template', () => { diff --git a/test/templates/fixtures/maximal-ctc-adverse-event-resource.json b/test/templates/fixtures/maximal-ctc-adverse-event-resource.json index 9e076f09..21e40a8a 100644 --- a/test/templates/fixtures/maximal-ctc-adverse-event-resource.json +++ b/test/templates/fixtures/maximal-ctc-adverse-event-resource.json @@ -17,6 +17,34 @@ } ] } + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-resolved-date", + "valueDateTime": "2021-12-09" + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-expectation", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl", + "code": "C41333", + "display": "Expected Adverse Event" + } + ] + } + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-seriousness-outcome", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl", + "code": "C113380", + "display": "Disabling Adverse Event" + } + ] + } } ], "event": {