mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(fhir): code the body-site side with active SNOMED CT qualifiers
The HL7 validator reports 419161000 and 419465000, the left and right concepts of the R4 bodysite-laterality value set, as inactive. Use the active qualifier values 7771000 Left and 24028007 Right, with 51440002 Right and left. The side word in bodySite.text stays English, the language of every other generated text in the Bundle; the builder takes no locale.
This commit is contained in:
1 parent
8934a2900e
commit
87526e3df6
3 files changed
+32
-13
No files matched your search
@@ -51,9 +51,9 @@ describe("conditionsFromReportData — bodySite", () => {
|
||||
});
|
||||
|
||||
it.each([
|
||||
["LEFT", "419161000", "Unilateral left", "left"],
|
||||
["RIGHT", "419465000", "Unilateral right", "right"],
|
||||
["BOTH", "51440002", "Bilateral", "both sides"],
|
||||
["LEFT", "7771000", "Left", "left"],
|
||||
["RIGHT", "24028007", "Right", "right"],
|
||||
["BOTH", "51440002", "Right and left", "both sides"],
|
||||
])(
|
||||
"carries %s as SNOMED %s on a contained BodyStructure",
|
||||
(laterality, code, display, sideText) => {
|
||||
@@ -91,6 +91,14 @@ describe("conditionsFromReportData — bodySite", () => {
|
||||
expect(c.bodySite?.[0]?.coding).toBeUndefined();
|
||||
});
|
||||
|
||||
it("writes the side in the Bundle's language and the site in the user's words", () => {
|
||||
const c = conditionFor({ bodySite: "Knie", laterality: "LEFT" });
|
||||
expect(c.bodySite?.[0]?.text).toBe("Knie (left)");
|
||||
// The same language as the rest of the generated Condition text.
|
||||
expect(c.note?.[0]?.text).toMatch(/^Self-recorded /);
|
||||
expect(c.contained?.[0]?.location?.text).toBe("Knie");
|
||||
});
|
||||
|
||||
it("falls back to the site alone for an unknown side value", () => {
|
||||
const c = conditionFor({ bodySite: "Knee", laterality: "SIDEWAYS" });
|
||||
expect(c.bodySite).toEqual([{ text: "Knee" }]);
|
||||
|
||||
@@ -194,9 +194,9 @@ describe("Condition.bodySite", () => {
|
||||
const structure = condition.contained?.find((c) => `#${c.id}` === target);
|
||||
expect(structure?.resourceType).toBe("BodyStructure");
|
||||
expect(structure?.patient.reference).toBe(patientUrl);
|
||||
// A code from the R4 core bodysite-laterality value set.
|
||||
// An active SNOMED CT laterality qualifier value.
|
||||
expect(
|
||||
["419161000", "419465000", "51440002"].includes(
|
||||
["7771000", "24028007", "51440002"].includes(
|
||||
structure?.locationQualifier?.[0]?.coding?.[0]?.code ?? "",
|
||||
),
|
||||
).toBe(true);
|
||||
|
||||
@@ -21,19 +21,23 @@ import { SNOMED_SYSTEM, patientRef } from "@/lib/fhir/resources/common";
|
||||
const DISEASE_SNOMED = { code: "64572001", display: "Disease" } as const;
|
||||
|
||||
/**
|
||||
* The side of a body site, as SNOMED CT laterality qualifiers from the R4 core
|
||||
* value set `http://hl7.org/fhir/ValueSet/bodysite-laterality`
|
||||
* (https://hl7.org/fhir/R4/valueset-bodysite-laterality.html); the same three
|
||||
* concepts sit in `bodystructure-relative-location`, the value set R4 binds to
|
||||
* `BodyStructure.locationQualifier`. Keyed on the `Laterality` enum.
|
||||
* The side of a body site, as active SNOMED CT laterality qualifier values:
|
||||
* 7771000 Left, 24028007 Right, 51440002 Right and left. These are the codes
|
||||
* of the HL7 mCODE Laterality Qualifier value set
|
||||
* (https://build.fhir.org/ig/HL7/fhir-mCODE-ig/ValueSet-mcode-laterality-qualifier-vs.html).
|
||||
* The R4 core `bodysite-laterality` value set lists 419161000 / 419465000 for
|
||||
* left / right, but the HL7 validator reports both as inactive in current
|
||||
* SNOMED CT, so they are not used. R4 binds `BodyStructure.locationQualifier`
|
||||
* with example strength, so any SNOMED CT qualifier is conformant there.
|
||||
* Keyed on the `Laterality` enum.
|
||||
*/
|
||||
const LATERALITY_SNOMED: Record<
|
||||
string,
|
||||
{ code: string; display: string; text: string }
|
||||
> = {
|
||||
LEFT: { code: "419161000", display: "Unilateral left", text: "left" },
|
||||
RIGHT: { code: "419465000", display: "Unilateral right", text: "right" },
|
||||
BOTH: { code: "51440002", display: "Bilateral", text: "both sides" },
|
||||
LEFT: { code: "7771000", display: "Left", text: "left" },
|
||||
RIGHT: { code: "24028007", display: "Right", text: "right" },
|
||||
BOTH: { code: "51440002", display: "Right and left", text: "both sides" },
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -58,6 +62,13 @@ const BODY_STRUCTURE_ID = "bodysite-1";
|
||||
* `locationQualifier` holds the SNOMED CT side. The side is also written into
|
||||
* `bodySite.text`, because a receiver that ignores extensions must still read
|
||||
* "Knee (left)" rather than a bare "Knee".
|
||||
*
|
||||
* The side word is English on purpose. The builder takes no locale
|
||||
* (`FhirBuildOptions` carries none, unlike the PDF path), and every other
|
||||
* generated text in the Bundle is English: section titles, the Condition note,
|
||||
* the narratives. The site stays in the words the user wrote, so a German
|
||||
* record reads "Knie (left)", the same mix as a German label beside the
|
||||
* English "Self-recorded … condition journal entry" note.
|
||||
*/
|
||||
function bodySiteOf(
|
||||
bodySite: string | null | undefined,
|
||||
|
||||
Reference in new issue
Block a user