/** * The whole path a printed reference range travels, against a real Postgres. * * The failure this pins is a two-ended one: until now the document reading * pulled the value off a lab report and dropped the range printed beside it, * and every end of that pipe looked healthy on its own. So the assertions here * follow ONE range through the real assembly rather than checking each end in * isolation: * * extract → the staged fact carries the printed string * commit → the written row carries the derived bounds AND the string * read → the API DTO serves both windows and says which is in force * verdict → the reading is judged against the REPORT's window, not the * catalog band — the case where the two disagree is the point * report → the doctor-report payload and the FHIR bundle agree with it * * The catalog band is deliberately set so that the same number reads * "in-range" against the report and "above" against the catalog. A test whose * two windows agree cannot tell whether the precedence rule is wired at all. */ import { NextRequest } from "next/server"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { cookieJar } from "./mock-next-headers"; import { getPrismaClient, truncateAllTables } from "./setup"; const USER_ID = "user-lab-source-range"; vi.mock("next/headers", async () => { const { cookieJar, headerJar } = await import("./mock-next-headers"); return { headers: vi.fn(async () => ({ get: (name: string) => headerJar.get(name.toLowerCase()) ?? null, })), cookies: vi.fn(async () => ({ get: (name: string) => { const value = cookieJar.get(name); return value ? { name, value } : undefined; }, set: (name: string, value: string) => { cookieJar.set(name, value); }, delete: (name: string) => { cookieJar.delete(name); }, })), }; }); vi.mock("@/lib/db-compat", () => ({ ensureDbCompatibility: vi.fn().mockResolvedValue(undefined), })); beforeEach(async () => { await truncateAllTables(getPrismaClient()); cookieJar.clear(); const prisma = getPrismaClient(); await prisma.user.create({ data: { id: USER_ID, username: "lab-source-range", email: "lab-source-range@example.test", }, }); const session = await prisma.session.create({ data: { userId: USER_ID, expiresAt: new Date(Date.now() + 3_600_000) }, }); cookieJar.set("healthlog_session", session.id); }); /** The catalog band the marker carries. 5.2 sits ABOVE this window. */ const CATALOG = { lowerBound: 3.5, upperBound: 5.0 }; /** The window the report printed. 5.2 sits INSIDE this one. */ const PRINTED = "3,9 - 5,4"; const VALUE = 5.2; async function seedMarker() { return getPrismaClient().biomarker.create({ data: { userId: USER_ID, name: "Kalium", unit: "mmol/L", ...CATALOG }, }); } function postReq(body: unknown): NextRequest { return new NextRequest("http://localhost/api/labs", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body), }); } async function readDto(analyte = "Kalium") { const { GET } = await import("@/app/api/labs/route"); const res = await GET( new NextRequest(`http://localhost/api/labs?analyte=${analyte}`), ); expect(res.status).toBe(200); const body = await res.json(); return body.data.results[0]; } describe("a printed reference range, end to end", () => { it("survives the document path onto the row and governs its verdict", async () => { const prisma = getPrismaClient(); const marker = await seedMarker(); // The document path, through the REAL commit helper the confirm route // calls. The fact carries what a report prints: a value, a unit, and a // window stated in German notation beside it. const { commitApprovedFact } = await import("@/lib/documents/commit"); const { encryptFactData, encryptFactProvenance } = await import("@/lib/documents/store"); const doc = await prisma.inboundDocument.create({ data: { userId: USER_ID, filename: "befund.pdf", mimeType: "application/pdf", byteSize: 1024, contentEncrypted: Buffer.from("stand-in for the stored bytes"), status: "EXTRACTED", }, }); const fact = await prisma.extractedFact.create({ data: { documentId: doc.id, userId: USER_ID, factType: "OBSERVATION", status: "APPROVED", confidence: 0.9, needsReview: false, dataEncrypted: encryptFactData({ label: "Kalium", code: null, codeSystem: null, value: VALUE, valueText: null, unit: "mmol/L", referenceLow: null, referenceHigh: null, referenceText: PRINTED, effectiveDate: "2026-07-01", }), provenanceEncrypted: encryptFactProvenance({ sourceText: "Kalium 5,2 mmol/l 3,9 - 5,4", anchored: true, sourceOffset: 0, page: 0, confidence: 0.9, }), }, }); const ref = await commitApprovedFact(USER_ID, fact); expect(ref.recordType).toBe("labResult"); // The row carries BOTH readings of the printed window: the bounds derived // from it and the string itself. const row = await prisma.labResult.findUniqueOrThrow({ where: { id: ref.recordId }, }); expect(row.sourceReferenceLow).toBe(3.9); expect(row.sourceReferenceHigh).toBe(5.4); expect(row.sourceReferenceText).toBe(PRINTED); // The catalog stamp is untouched — the marker already existed, so the // document's window did not rewrite the user's own band. expect(row.referenceLow).toBe(CATALOG.lowerBound); expect(row.referenceHigh).toBe(CATALOG.upperBound); const markerAfter = await prisma.biomarker.findUniqueOrThrow({ where: { id: marker.id }, }); expect(markerAfter.lowerBound).toBe(CATALOG.lowerBound); expect(markerAfter.upperBound).toBe(CATALOG.upperBound); // The read side serves both windows, names the winner, and flags that the // two disagree. const dto = await readDto(); expect(dto).toMatchObject({ value: VALUE, referenceLow: 3.9, referenceHigh: 5.4, catalogReferenceLow: CATALOG.lowerBound, catalogReferenceHigh: CATALOG.upperBound, sourceReferenceLow: 3.9, sourceReferenceHigh: 5.4, sourceReferenceText: PRINTED, referenceOrigin: "source", referenceDivergesFromCatalog: true, }); // The verdict is the point. Against the catalog band 5.2 is above range; // against the window the lab printed it is inside it, and the lab's window // is the one the physician read the value against. expect(dto.rangeStatus).toBe("in-range"); // The doctor report reads the same window, and prints the report's own // string rather than a reformatted version of it. const { loadLabResults } = await import("@/lib/doctor-report/clinical-records"); const labs = await loadLabResults( USER_ID, new Date("2026-01-01T00:00:00.000Z"), new Date("2026-12-31T23:59:59.000Z"), ); expect(labs?.[0]).toMatchObject({ referenceLow: 3.9, referenceHigh: 5.4, catalogReferenceLow: CATALOG.lowerBound, catalogReferenceHigh: CATALOG.upperBound, sourceReferenceText: PRINTED, referenceOrigin: "source", referenceDivergesFromCatalog: true, }); // FHIR exports the same window — a receiver that trusts referenceRange // must not be handed the catalog band while the app shows another. const { labObservations } = await import("@/lib/fhir/resources/labs"); let seq = 0; const observations = labObservations( { labResults: labs } as Parameters[0], () => `obs-${++seq}`, ); expect(observations[0].referenceRange?.[0]).toMatchObject({ low: { value: 3.9 }, high: { value: 5.4 }, text: PRINTED, }); }); it("keeps a window it cannot read as text and leaves the catalog in force", async () => { const prisma = getPrismaClient(); await seedMarker(); const { POST } = await import("@/app/api/labs/route"); const marker = await prisma.biomarker.findFirstOrThrow({ where: { userId: USER_ID }, }); const res = await POST( postReq({ biomarkerId: marker.id, value: VALUE, sourceReferenceText: "siehe Befund", takenAt: "2026-07-02T08:00:00.000Z", }), ); expect(res.status).toBe(201); const row = await prisma.labResult.findFirstOrThrow({ where: { userId: USER_ID }, }); // The string is on the record — absence would be the old failure, and a // fabricated bound would be worse than either. expect(row.sourceReferenceText).toBe("siehe Befund"); expect(row.sourceReferenceLow).toBeNull(); expect(row.sourceReferenceHigh).toBeNull(); const dto = await readDto(); expect(dto).toMatchObject({ sourceReferenceText: "siehe Befund", referenceOrigin: "catalog", referenceDivergesFromCatalog: false, referenceLow: CATALOG.lowerBound, referenceHigh: CATALOG.upperBound, }); // No derivable window means the catalog stays the net, so the catalog's // verdict stands. expect(dto.rangeStatus).toBe("above"); }); it("carries the window through a backup round trip", async () => { const prisma = getPrismaClient(); const marker = await seedMarker(); await prisma.labResult.create({ data: { userId: USER_ID, biomarkerId: marker.id, analyte: "Kalium", unit: "mmol/L", value: VALUE, referenceLow: CATALOG.lowerBound, referenceHigh: CATALOG.upperBound, sourceReferenceLow: 3.9, sourceReferenceHigh: 5.4, sourceReferenceText: PRINTED, takenAt: new Date("2026-07-01T08:00:00.000Z"), }, }); const { buildRecordsBackupSection } = await import("@/lib/export/records-backup"); const backup = await buildRecordsBackupSection(prisma, USER_ID, { purpose: "disaster-recovery", }); expect(backup.labResults[0]).toMatchObject({ sourceReferenceLow: 3.9, sourceReferenceHigh: 5.4, sourceReferenceText: PRINTED, }); }); });