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

Add Date of Death, Extended Race, Extended Ethnicity #2697

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
efebc76
Add Date of Death
lina-roth Oct 8, 2024
cbb5be7
Add extended race and ethnicity
lina-roth Oct 8, 2024
79b61d0
Fix issue with fhir converter integration tests
lina-roth Oct 8, 2024
92e0c71
remove uneeded console.log
lina-roth Oct 8, 2024
6506841
Merge branch 'main' into lr/death-date
lina-roth Oct 8, 2024
797d883
fix tests
lina-roth Oct 8, 2024
38a95fd
Merge branch 'lr/death-date' of github.com:CDCgov/phdi into lr/death-…
lina-roth Oct 8, 2024
9677291
Fix fhir converter integration test
lina-roth Oct 8, 2024
ecc1290
Fix tests, add JSDoc
lina-roth Oct 9, 2024
3348e13
Merge branch 'main' into lr/death-date
lina-roth Oct 10, 2024
48d7395
Add Date of Death
lina-roth Oct 8, 2024
283eb7a
Add extended race and ethnicity
lina-roth Oct 8, 2024
6aa0b3f
Fix issue with fhir converter integration tests
lina-roth Oct 8, 2024
bc89611
fix tests
lina-roth Oct 8, 2024
de0e3bd
Fix fhir converter integration test
lina-roth Oct 8, 2024
bcffb8f
Fix tests, add JSDoc
lina-roth Oct 9, 2024
36ed1a8
Merge branch 'lr/death-date' of github.com:CDCgov/phdi into lr/death-…
lina-roth Oct 15, 2024
4c16020
Fix fhir converter
lina-roth Oct 17, 2024
154a0ce
Uppdate snap and fhirDataService check
lina-roth Oct 17, 2024
c9f563c
Fix issue with fhir converter integration tests
lina-roth Oct 8, 2024
57bd288
fix tests
lina-roth Oct 8, 2024
1550eb2
Fix fhir converter
lina-roth Oct 17, 2024
3d0cdc0
Uppdate snap and fhirDataService check
lina-roth Oct 17, 2024
2bbbc2a
Merge branch 'lr/death-date' of github.com:CDCgov/phdi into lr/death-…
lina-roth Oct 17, 2024
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

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions containers/ecr-viewer/src/app/api/fhirPath.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ patientCounty: "Bundle.entry.resource.where(resourceType = 'Patient').address.fi
patientIds: "Bundle.entry.resource.where(resourceType = 'Patient').identifier"
patientDOB: "Bundle.entry.resource.where(resourceType = 'Patient').birthDate"
patientVitalStatus: "Bundle.entry.resource.where(resourceType = 'Patient').deceasedBoolean"
patientDOD: "Bundle.entry.resource.where(resourceType = 'Patient').deceasedDate"
patientGender: "Bundle.entry.resource.where(resourceType = 'Patient').gender"
patientRace: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race').extension.where(url = 'ombCategory').valueCoding.display"
patinetRaceExtension: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race').extension.where(url = 'detailed').valueCoding.display"
patientEthnicity: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity').extension.first().valueCoding.display"
patientRaceDetailed: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race').extension.where(url = 'detailed').valueCoding.display"
patientEthnicity: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity').extension.where(url = 'ombCategory').valueCoding.display"
patientEthnicityDetailed: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity').extension.where(url = 'detailed').valueCoding.display"
patientLanguage: "Bundle.entry.resource.where(resourceType = 'Patient').communication.first().language.coding.first().display"
patientTribalAffiliation: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url='http: //hl7.org/fhir/us/ecr/StructureDefinition/us-ph-tribal-affiliation-extension').extension.where(url='TribeName').value.display"
patientEmergencyContact: "Bundle.entry.resource.where(resourceType = 'Patient').contact.first()"
Expand Down
83 changes: 70 additions & 13 deletions containers/ecr-viewer/src/app/services/evaluateFhirDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,37 @@ export const evaluatePatientRace = (
mappings: PathMappings,
) => {
const raceCat = evaluate(fhirBundle, mappings.patientRace)[0];
const raceDetailedExt =
evaluate(fhirBundle, mappings.patinetRaceExtension)[0] ?? "";
const raceDetailed =
evaluate(fhirBundle, mappings.patientRaceDetailed)[0] ?? "";

if (raceDetailedExt) {
return `${raceCat}, ${raceDetailedExt}`;
if (raceDetailed) {
return raceCat + "\n" + raceDetailed;
} else {
return raceCat;
}
};

/**
* Evaluates the patients ethnicity from the FHIR bundle and formats for display.
* @param fhirBundle - The FHIR bundle containing patient contact info.
* @param mappings - The object containing the fhir paths.
* @returns - The patient's ethnicity information, including additional ethnicity extension (if available).
*/
export const evaluatePatientEthnicity = (
fhirBundle: Bundle,
mappings: PathMappings,
) => {
const ethnicity = evaluate(fhirBundle, mappings.patientEthnicity)[0] ?? "";
const ethnicityDetailed =
evaluate(fhirBundle, mappings.patientEthnicityDetailed)[0] ?? "";

if (ethnicityDetailed) {
return ethnicity + "\n" + ethnicityDetailed;
} else {
return ethnicity;
}
};

/**
* Evaluates patient address from the FHIR bundle and formats it into structured data for display.
* @param fhirBundle - The FHIR bundle containing patient contact info.
Expand Down Expand Up @@ -157,22 +178,49 @@ const evaluateTravelHistory = (
};

/**
* Calculates the age of a patient to a given date or today.
* Calculates the age of a patient to a given date or today, unless DOD exists.
* @param fhirBundle - The FHIR bundle containing patient information.
* @param fhirPathMappings - The mappings for retrieving patient date of birth.
* @param [givenDate] - Optional. The target date to calculate the age. Defaults to the current date if not provided.
* @returns - The age of the patient in years, or undefined if date of birth is not available.
* @returns - The age of the patient in years, or undefined if date of birth is not available or if date of death exists.
*/
export const calculatePatientAge = (
fhirBundle: Bundle,
fhirPathMappings: PathMappings,
givenDate?: string,
) => {
const patientDOBString = evaluate(fhirBundle, fhirPathMappings.patientDOB)[0];
if (patientDOBString) {
const patientDODString = evaluate(fhirBundle, fhirPathMappings.patientDOD)[0];
if (patientDOBString && !patientDODString && !givenDate) {
const patientDOB = new Date(patientDOBString);
const targetDate = givenDate ? new Date(givenDate) : new Date();
return dateFns.differenceInYears(targetDate, patientDOB);
return dateFns.differenceInYears(new Date(), patientDOB);
} else if (patientDOBString && givenDate) {
const patientDOB = new Date(patientDOBString);
return dateFns.differenceInYears(new Date(givenDate), patientDOB);
} else {
return undefined;
}
};

/**
* Calculates Patient Age at Death if DOB and DOD exist, otherwise returns undefined
* @param fhirBundle - The FHIR bundle containing patient information.
* @param fhirPathMappings - The mappings for retrieving patient date of birth and date of death.
* @returns - The age of the patient at death in years, or undefined if date of birth or date of death is not available.
*/
export const calculatePatientAgeAtDeath = (
fhirBundle: Bundle,
fhirPathMappings: PathMappings,
) => {
const patientDOBString = evaluate(fhirBundle, fhirPathMappings.patientDOB)[0];
const patientDODString = evaluate(fhirBundle, fhirPathMappings.patientDOD)[0];

if (patientDOBString && patientDODString) {
const patientDOB = new Date(patientDOBString);
const patientDOD = new Date(patientDODString);
return dateFns.differenceInYears(patientDOD, patientDOB);
} else {
return undefined;
}
};

Expand Down Expand Up @@ -247,11 +295,20 @@ export const evaluateDemographicsData = (
title: "Current Age",
value: calculatePatientAge(fhirBundle, mappings)?.toString(),
},
{
title: "Age at Death",
value: calculatePatientAgeAtDeath(fhirBundle, mappings),
},
{
title: "Vital Status",
value: evaluate(fhirBundle, mappings.patientVitalStatus)[0]
? "Deceased"
: "Alive",
value:
evaluate(fhirBundle, mappings.patientVitalStatus)[0] === false
? "Alive"
: "Deceased",
},
{
title: "Date of Death",
value: evaluate(fhirBundle, mappings.patientDOD)[0],
},
{ title: "Sex", value: evaluate(fhirBundle, mappings.patientGender)[0] },
{
Expand All @@ -260,7 +317,7 @@ export const evaluateDemographicsData = (
},
{
title: "Ethnicity",
value: evaluate(fhirBundle, mappings.patientEthnicity)[0],
value: evaluatePatientEthnicity(fhirBundle, mappings),
},
{
title: "Tribal Affiliation",
Expand Down
7 changes: 7 additions & 0 deletions containers/ecr-viewer/src/app/tests/assets/BundlePatient.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@
"display": "Hispanic or Latino"
}
},
{
"url": "detailed",
"valueCoding": {
"code": "2106-3",
"display": "White"
}
},
{
"url": "text",
"valueString": "Hispanic or Latino"
Expand Down
143 changes: 143 additions & 0 deletions containers/ecr-viewer/src/app/tests/assets/BundlePatientDeceased.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
{
"resourceType": "Bundle",
"type": "batch",
"entry": [
{
"fullUrl": "urn:uuid:6b6b3c4c-4884-4a96-b6ab-c46406839cea",
"resource": {
"resourceType": "Patient",
"id": "6b6b3c4c-4884-4a96-b6ab-c46406839cea",
"meta": {
"profile": [
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
],
"source": [
"ecr"
]
},
"identifier": [
{
"system": "urn:oid:2.16.840.1.113883.3.3316.100",
"value": "10308625"
}
],
"name": [
{
"family": "CASTILLO",
"given": [
"ABEL"
]
}
],
"birthDate": "2015-04-15",
"deceasedBoolean": true,
"deceasedDate": "2020-02-27",
"gender": "male",
"extension": [
{
"url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race",
"extension": [
{
"url": "ombCategory",
"valueCoding": {
"code": "2054-5",
"display": "Black or African American"
}
},
{
"url": "detailed",
"valueCoding": {
"code": "2076-8",
"display": "African"
}
},
{
"url": "text",
"valueString": "Black or African American"
}
]
},
{
"url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity",
"extension": [
{
"url": "ombCategory",
"valueCoding": {
"code": "2135-2",
"display": "Hispanic or Latino"
}
},
{
"url": "detailed",
"valueCoding": {
"code": "2106-3",
"display": "White"
}
},
{
"url": "text",
"valueString": "Hispanic or Latino"
}
]
},
{
"url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex",
"extension": [
{
"url": "value",
"valueCodeableConcept": {
"coding": [
{
"code": "M",
"display": "Male",
"system": "urn:oid:2.16.840.1.113883.5.1"
}
]
}
}
]
}
],
"address": [
{
"line": [
"1050 CARPENTER ST"
],
"city": "EDWARDS",
"state": "CA",
"country": "US",
"postalCode": "93523-2800"
}
],
"telecom": [
{
"system": "phone",
"value": "+18184195968",
"use": "home"
},
{
"system": "email",
"value": "[email protected]"
}
],
"communication": [
{
"language": {
"coding": [
{
"system": "urn:ietf:bcp:47",
"code": "en",
"display": "English"
}
]
}
}
]
},
"request": {
"method": "PUT",
"url": "Patient/6b6b3c4c-4884-4a96-b6ab-c46406839cea"
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ exports[`Snapshot test for Accordion Content Given no data, info message for emp
<div
class="grid-col maxw7 text-pre-line"
>
Alive
Deceased
</div>
</div>
<div
Expand Down Expand Up @@ -284,6 +284,44 @@ exports[`Snapshot test for Accordion Content Given no data, info message for emp
class="section__line_gray"
/>
</div>
<div>
<div
class="grid-row"
>
<div
class="data-title padding-right-1"
>
Age at Death
</div>
<div
class="grid-col maxw7 text-pre-line text-italic text-base"
>
No data
</div>
</div>
<div
class="section__line_gray"
/>
</div>
<div>
<div
class="grid-row"
>
<div
class="data-title padding-right-1"
>
Date of Death
</div>
<div
class="grid-col maxw7 text-pre-line text-italic text-base"
>
No data
</div>
</div>
<div
class="section__line_gray"
/>
</div>
<div>
<div
class="grid-row"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
evaluateEncounterId,
evaluateFacilityId,
evaluateIdentifiers,
evaluatePatientEthnicity,
evaluatePatientRace,
evaluatePractitionerRoleReference,
evaluateReference,
Expand Down Expand Up @@ -107,7 +108,17 @@ describe("Evaluate Patient Race", () => {
BundleWithPatient as unknown as Bundle,
mappings,
);
expect(actual).toEqual("Black or African American, African");
expect(actual).toEqual("Black or African American\nAfrican");
});
});

describe("Evaluate Patient Ethnicity", () => {
it("should return ethnicity category and extension if available", () => {
const actual = evaluatePatientEthnicity(
BundleWithPatient as unknown as Bundle,
mappings,
);
expect(actual).toEqual("Hispanic or Latino\nWhite");
});
});

Expand Down
Loading
Loading