diff --git a/src/lib/documents/__tests__/extract-reads.test.ts b/src/lib/documents/__tests__/extract-reads.test.ts index 37792100e..57fa54549 100644 --- a/src/lib/documents/__tests__/extract-reads.test.ts +++ b/src/lib/documents/__tests__/extract-reads.test.ts @@ -103,6 +103,24 @@ describe("runInboundExtraction over several reads", () => { expect(result.incomplete).toBe(false); }); + it("keeps a value two reads list for different report dates, and merges it on the same date", async () => { + const page = (reportDate: string | null) => ({ + content: JSON.stringify({ reportDate, facts: [observation("Hb", 14)] }), + }); + // Two reports of different days, one value each with no date of its own. + const twoDays = await run( + scripted([page("2026-09-01"), page("2026-09-30")]), + reads(2), + ); + expect(twoDays.facts).toHaveLength(2); + // A page without a date reads under the report's, as the lab scan does. + const sameDay = await run( + scripted([page("2026-09-01"), page(null)]), + reads(2), + ); + expect(sameDay.facts).toHaveLength(1); + }); + it("keeps the lab scan's row cap, and says when a report holds more", async () => { expect(INBOUND_MAX_FACTS).toBe(OCR_MAX_ROWS); const reply = (r: number) => ({ diff --git a/src/lib/documents/extract.ts b/src/lib/documents/extract.ts index cd821fd76..d48803484 100644 --- a/src/lib/documents/extract.ts +++ b/src/lib/documents/extract.ts @@ -293,8 +293,13 @@ function factPage(raw: ExtractedFactRaw, chunk: OcrChunk): number | null { : null; } -/** The identity of a fact for the merge: the same fact in two reads is one. */ -function factKey(raw: ExtractedFactRaw): string { +/** + * The identity of a fact for the merge: the same fact in two reads is one. + * A fact without a date of its own is keyed on the date of the report its + * read belongs to, as the lab scan keys a row, so the same value on two + * reports of different days stays two facts. + */ +function factKey(raw: ExtractedFactRaw, readDate: string | null): string { return [ raw.type, raw.label.trim().toLowerCase(), @@ -303,7 +308,7 @@ function factKey(raw: ExtractedFactRaw): string { (raw.unit ?? "").trim().toLowerCase(), (raw.referenceText ?? "").trim().toLowerCase(), (raw.dose ?? "").trim().toLowerCase(), - normaliseDate(raw.effectiveDate) ?? "", + normaliseDate(raw.effectiveDate) ?? readDate ?? "", ].join("|"); } @@ -345,9 +350,12 @@ export async function runInboundExtraction( let droppedFacts = 0; for (const { envelope, chunk } of reads.reads) { droppedFacts += envelope.droppedFacts; + // A read that prints its own date keeps it; the others read under the + // report's. + const readDate = normaliseDate(envelope.reportDate) ?? reportDate; const readKeys: string[] = []; for (const raw of envelope.facts) { - const key = factKey(raw); + const key = factKey(raw, readDate); if (seen.has(key)) { mergedDuplicates += 1; continue;