Files
HealthLog/src/lib/documents/__tests__/commit.test.ts
T
Marc-André Bombeck 2321ce29db fix(insights): route alert-card compliance through the cadence-aware engine + deep data cleanups
The insights alert cards computed medication compliance with the naive
`schedules.length × days` denominator, so a fully-adherent weekly
injectable read ~14% and fired a false low-compliance alert (and a paused
medication mis-fired the same way). Route the alert path through the
canonical `calculateCompliance` engine like every other compliance
surface — pause eras, schedule revisions and dose windows honoured.

Document confirm: committing a numeric observation against an existing
biomarker silently replaced the stated unit with the catalog's, with no
conversion — a stated "6.1 mmol/L" against a mg/dL marker committed
"6.1 mg/dL". Reject on a unit mismatch (fail closed) so the user
reconciles on the review screen, the same posture as the unit-required
guard.

Wire grip strength, waist (with waist-to-height) and pain into the
briefing feature set and the grounding allow-set so the clinical-depth
signals reach the daily narrative; the mental-health screeners stay
excluded by construction.

Biomarker detail: fall back to a generic description for catalog-less
markers, and keep the heading + description with a retry on the error
state. Collapse the medication External-API and Lifecycle groups by
default. Re-enable the insights scroll-to-top regression and assert the
shipped main-content reset.

Align the EN haemoglobin/haematocrit display names to British spelling.

Drop the redundant `(userId, deletedAt)` index on inbound documents — a
strict prefix of the new three-column index. Trim the dead
MedicalDisclaimer variants to the one live `dataPosture`. Move the
crisis-resources card off the retired amber tint to a calm
destructive-subtle border. Add a registry invariant asserting every
biomarker signal key resolves to a real catalog slug.
2026-06-29 00:37:39 +02:00

99 lines
3.0 KiB
TypeScript

/**
* v1.25.1 — commit-path unit-integrity tests.
*
* Committing a numeric observation against an EXISTING biomarker must not
* silently rewrite the document's stated unit with the catalog's. When the
* units disagree the fact is rejected (fail closed) so the user reconciles on
* the review screen, exactly like the `unitRequired` guard — never a corrupt
* "6.1 mmol/L written as 6.1 mg/dL" reading.
*/
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@/lib/db", () => ({
prisma: {
labResult: { create: vi.fn() },
},
}));
vi.mock("@/lib/labs/biomarker-store", () => ({
resolveOrMintBiomarker: vi.fn(),
}));
vi.mock("@/lib/documents/store", () => ({
decryptFactData: vi.fn(),
}));
import { commitApprovedFact, FactCommitError } from "@/lib/documents/commit";
import { prisma } from "@/lib/db";
import { resolveOrMintBiomarker } from "@/lib/labs/biomarker-store";
import { decryptFactData } from "@/lib/documents/store";
import type { ExtractedFact } from "@/generated/prisma/client";
function observationFact(): ExtractedFact {
return {
id: "fact-1",
factType: "OBSERVATION",
dataEncrypted: new Uint8Array(),
} as unknown as ExtractedFact;
}
beforeEach(() => {
vi.resetAllMocks();
});
describe("commitApprovedFact — OBSERVATION unit integrity", () => {
it("rejects a numeric observation whose stated unit differs from an existing marker's unit", async () => {
vi.mocked(decryptFactData).mockReturnValue({
label: "Glucose",
value: 6.1,
unit: "mmol/L",
referenceLow: null,
referenceHigh: null,
effectiveDate: "2025-01-01",
} as never);
// Existing marker stored in mg/dL — the resolver returns it as-is.
vi.mocked(resolveOrMintBiomarker).mockResolvedValue({
id: "bm-1",
name: "Glucose",
unit: "mg/dL",
lowerBound: 70,
upperBound: 100,
panel: null,
});
await expect(
commitApprovedFact("user-1", observationFact()),
).rejects.toMatchObject({ code: "observation.unitMismatch" });
await expect(
commitApprovedFact("user-1", observationFact()),
).rejects.toBeInstanceOf(FactCommitError);
expect(prisma.labResult.create).not.toHaveBeenCalled();
});
it("commits when the stated unit matches the marker's unit (case/space-insensitive)", async () => {
vi.mocked(decryptFactData).mockReturnValue({
label: "Glucose",
value: 95,
unit: " mg/DL ",
referenceLow: null,
referenceHigh: null,
effectiveDate: "2025-01-01",
} as never);
vi.mocked(resolveOrMintBiomarker).mockResolvedValue({
id: "bm-1",
name: "Glucose",
unit: "mg/dL",
lowerBound: 70,
upperBound: 100,
panel: null,
});
vi.mocked(prisma.labResult.create).mockResolvedValue({
id: "lr-1",
} as never);
const ref = await commitApprovedFact("user-1", observationFact());
expect(ref).toEqual({ recordType: "labResult", recordId: "lr-1" });
expect(prisma.labResult.create).toHaveBeenCalledOnce();
});
});