From c8b32ccaea9501abaeda9f9c368ac9c782e4a60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Wed, 11 Nov 2026 00:42:05 +0100 Subject: [PATCH] fix(documents): judge the review flag on the unit as stored A "1 (calc)" unit is stored as "1", the explicit no-unit value, but the dimensionless check ran on the raw string and missed it, so the read went straight through instead of to review. --- src/lib/documents/__tests__/extract.test.ts | 21 +++++++++++++++++++++ src/lib/documents/extract.ts | 9 +++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/lib/documents/__tests__/extract.test.ts b/src/lib/documents/__tests__/extract.test.ts index e18ee8f8c..eab86d047 100644 --- a/src/lib/documents/__tests__/extract.test.ts +++ b/src/lib/documents/__tests__/extract.test.ts @@ -226,6 +226,27 @@ describe("runInboundExtraction — stated-status-only mapping", () => { expect(result.facts.map((f) => f.needsReview)).toEqual([false, true]); }); + it('sends a "1 (calc)" unit to review like a plain "1"', async () => { + const provider = fakeProvider( + JSON.stringify({ + facts: [ + { + type: "OBSERVATION", + label: "CHOL/HDLC RATIO", + value: 4, + unit: "1 (calc)", + confidence: 0.95, + sourceText: "CHOL/HDLC RATIO 4.0 (calc)", + }, + ], + }), + ); + + const result = await runInboundExtraction(oneRead(provider)); + expect((result.facts[0].data as ObservationFactData).unit).toBe("1"); + expect(result.facts[0].needsReview).toBe(true); + }); + it("stores the document's real span, not the model's echo of it", async () => { // The OCR text says "Hämoglobin 14.2 g/dL"; the model echoes a tidied // rendering of it. The stored provenance must be the document's characters. diff --git a/src/lib/documents/extract.ts b/src/lib/documents/extract.ts index 54000da5f..734d2ccd0 100644 --- a/src/lib/documents/extract.ts +++ b/src/lib/documents/extract.ts @@ -393,6 +393,9 @@ export async function runInboundExtraction( // every fact from it is unanchored by construction. const anchor = anchorSourceText(raw.sourceText, args.ocrText); if (!anchor.anchored) unanchored += 1; + // The unit as it will be stored, with any "(calc)" note gone, so a + // "1 (calc)" is judged as the "1" it becomes. + const unit = observationUnit(raw.unit); facts.push({ factType: raw.type, confidence, @@ -404,10 +407,8 @@ export async function runInboundExtraction( needsReview: confidence < INBOUND_CONFIDENCE_FLOOR || (raw.type === "OBSERVATION" && - (isDimensionlessUnit(raw.unit) || - (raw.unit !== null && - raw.unit.trim() !== "" && - observationUnit(raw.unit) === null))), + (isDimensionlessUnit(unit) || + (raw.unit !== null && raw.unit.trim() !== "" && unit === null))), data, provenance: { sourceText: anchor.sourceText,