mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
feat(doctor-report): add a surgical history section
New structured leaf SURGICAL_HISTORY in the history group and in the standard template: every procedure that took place, oldest first, with its date, what was done (the visit's reason), the body site with its side and the outcome. Lifetime reference data like the immunization record, so it ignores the report window. The PDF prints it as a table and the clinician share page renders it; saved selections do not widen. The FHIR bundle carries no Procedure resource, on the same terms as visits: no REST route or capability entry exists for it. Refs #1025
This commit is contained in:
1 parent
ad0d50fa28
commit
0b28498d83
16 files changed
+428
-16
No files matched your search
@@ -46,6 +46,7 @@ import { EmergencySection, PatientIdentitySection } from "./identity-sections";
|
||||
import {
|
||||
IllnessSection,
|
||||
ImmunizationsSection,
|
||||
SurgicalHistorySection,
|
||||
LabResultsSection,
|
||||
VisitsSection,
|
||||
} from "./history-sections";
|
||||
@@ -256,6 +257,12 @@ export function ClinicianView({
|
||||
scope={scope}
|
||||
fmtDate={fmtDate}
|
||||
/>
|
||||
<SurgicalHistorySection
|
||||
t={t}
|
||||
report={report}
|
||||
scope={scope}
|
||||
fmtDate={fmtDate}
|
||||
/>
|
||||
<ImmunizationsSection
|
||||
t={t}
|
||||
report={report}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* The `labs` and `history` groups on the clinician view: lab results, illness
|
||||
* episodes, visits and the immunization record.
|
||||
* episodes, visits, the surgical history and the immunization record.
|
||||
*
|
||||
* All four were selectable on a share link and none of them reached the page,
|
||||
* while the PDF download from the same link printed every one. What each
|
||||
@@ -12,8 +12,11 @@
|
||||
* A pure server component: no client hooks, no session, no markdown — every
|
||||
* value renders as escaped React text.
|
||||
*/
|
||||
import type { EncounterKind } from "@/generated/prisma/client";
|
||||
import { encounterKindLabelKey } from "@/lib/encounters/kind-label";
|
||||
import type { EncounterKind, Laterality } from "@/generated/prisma/client";
|
||||
import {
|
||||
encounterKindLabelKey,
|
||||
lateralityLabelKey,
|
||||
} from "@/lib/encounters/kind-label";
|
||||
import { formatReferenceRange } from "@/lib/labs/reference-range";
|
||||
import type { DoctorReportData } from "@/lib/doctor-report-data";
|
||||
import {
|
||||
@@ -221,6 +224,53 @@ export function VisitsSection({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The surgical history. Reference data, not window-bounded, like the
|
||||
* immunization record below: every procedure that happened, oldest first. What
|
||||
* was done is the row's label; the date, the site with its side and the
|
||||
* outcome compose onto the value side, the shape the immunization rows use.
|
||||
*/
|
||||
export function SurgicalHistorySection({
|
||||
t,
|
||||
report,
|
||||
scope,
|
||||
fmtDate,
|
||||
}: {
|
||||
t: Translate;
|
||||
report: DoctorReportData;
|
||||
scope: LeafScope;
|
||||
fmtDate: (iso: string) => string;
|
||||
}) {
|
||||
const procedures = report.surgicalHistory ?? [];
|
||||
|
||||
const site = (row: (typeof procedures)[number]) => {
|
||||
if (!row.bodySite) return null;
|
||||
if (!row.laterality) return row.bodySite;
|
||||
return t("encounters.bodySiteWithSide", {
|
||||
site: row.bodySite,
|
||||
side: t(lateralityLabelKey(row.laterality as Laterality)),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<LeafSection
|
||||
t={t}
|
||||
scope={scope}
|
||||
leaves={["SURGICAL_HISTORY"]}
|
||||
title={t("doctorReport.surgicalHistoryTitle")}
|
||||
empty={procedures.length === 0}
|
||||
>
|
||||
{procedures.map((row, index) => (
|
||||
<StatRow
|
||||
key={`${row.occurredAt}-${index}`}
|
||||
label={row.procedure ?? "—"}
|
||||
value={compose([fmtDate(row.occurredAt), site(row), row.outcome])}
|
||||
/>
|
||||
))}
|
||||
</LeafSection>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The immunization record. Reference data, not window-bounded: an Impfpass is
|
||||
* a lifetime document and the whole of it rides when the leaf and the module
|
||||
|
||||
@@ -192,8 +192,8 @@ describe("<HealthRecordExportPanel> — the first run", () => {
|
||||
expect(groupChip(html, "body")).toBe("0/12");
|
||||
expect(groupChip(html, "labs")).toBe("0/1");
|
||||
expect(groupChip(html, "medications")).toBe("0/4");
|
||||
// ALLERGIES, ILLNESS_EPISODES and now VISITS.
|
||||
expect(groupChip(html, "history")).toBe("0/4");
|
||||
// ALLERGIES, ILLNESS_EPISODES, VISITS, SURGICAL_HISTORY, IMMUNIZATIONS.
|
||||
expect(groupChip(html, "history")).toBe("0/5");
|
||||
expect(groupChip(html, "cardio")).toBe("0/14");
|
||||
expect(groupChip(html, "activity")).toBe("0/8");
|
||||
expect(groupChip(html, "sleepRecovery")).toBe("0/16");
|
||||
|
||||
Reference in new issue
Block a user