diff --git a/src/__tests__/baselines/source-function-lines.json b/src/__tests__/baselines/source-function-lines.json
index a9e9c0346..a23121b84 100644
--- a/src/__tests__/baselines/source-function-lines.json
+++ b/src/__tests__/baselines/source-function-lines.json
@@ -1,7 +1,7 @@
{
"$comment": "Production functions over 200 lines, keyed \"file :: name\", and their length. Maintained by src/__tests__/source-size-ratchet.test.ts.",
"count": 345,
- "total": 111929,
+ "total": 111930,
"entries": {
"app/achievements/page.tsx :: AchievementsPage": 206,
"app/api/admin/backups/upload/route.ts :: apiHandler(arg)": 275,
@@ -93,7 +93,7 @@
"components/documents/document-card.tsx :: DocumentCard": 354,
"components/documents/document-detail-sheet.tsx :: DocumentDetailSheet": 325,
"components/documents/document-facts-review.tsx :: DocumentFactsSection": 242,
- "components/documents/document-facts-review.tsx :: FactRow": 262,
+ "components/documents/document-facts-review.tsx :: FactRow": 263,
"components/documents/document-filter-bar.tsx :: DocumentFilterBar": 348,
"components/documents/document-record-links.tsx :: DocumentRecordLinks": 202,
"components/documents/document-timeline.tsx :: DocumentTimeline": 314,
diff --git a/src/components/documents/__tests__/document-facts-review.test.tsx b/src/components/documents/__tests__/document-facts-review.test.tsx
index fbb28cccb..23cc24dd8 100644
--- a/src/components/documents/__tests__/document-facts-review.test.tsx
+++ b/src/components/documents/__tests__/document-facts-review.test.tsx
@@ -8,7 +8,7 @@ import type {
InboundDocumentDetailDto,
} from "@/lib/validations/inbound-documents";
-import { DocumentFactsSection } from "../document-facts-review";
+import { DocumentFactsSection, FactRow } from "../document-facts-review";
/**
* The staged-facts block's honest states, pinned by static render:
@@ -173,3 +173,56 @@ describe("", () => {
expect(html).toBe("");
});
});
+
+describe("", () => {
+ // A confident lab value the last save refused (here a ratio printed without
+ // a unit) gets the same edit control as a low-confidence one: it is the only
+ // way to add the unit and finish the review.
+ const unitless = fact({
+ data: {
+ label: "Ratio",
+ code: null,
+ codeSystem: null,
+ value: 4.2,
+ valueText: null,
+ unit: null,
+ referenceLow: null,
+ referenceHigh: 5,
+ referenceText: "<5.0",
+ effectiveDate: "2026-08-01",
+ },
+ provenance: {
+ sourceText: "Ratio 4.2 <5.0",
+ anchored: true,
+ sourceOffset: 10,
+ page: 0,
+ confidence: 0.95,
+ },
+ });
+
+ const rowProps = {
+ documentId: "doc-1",
+ checked: true,
+ onCheckedChange: () => {},
+ chosenBiomarkerId: null,
+ onChooseBiomarker: () => {},
+ markerName: () => null,
+ };
+
+ it("offers the edit control on a confident row whose save was refused", () => {
+ const html = render(
+ ,
+ );
+ expect(html).toContain('data-slot="document-fact-verify-open"');
+ expect(html).toContain("A numeric value needs a unit");
+ });
+
+ it("leaves a confident row without a refusal free of the edit control", () => {
+ const html = render();
+ expect(html).not.toContain('data-slot="document-fact-verify-open"');
+ });
+});
diff --git a/src/components/documents/document-facts-review.tsx b/src/components/documents/document-facts-review.tsx
index ded9d2d6a..c2b0f39d9 100644
--- a/src/components/documents/document-facts-review.tsx
+++ b/src/components/documents/document-facts-review.tsx
@@ -204,8 +204,8 @@ function draftFor(fact: ExtractedFactDto): VerifyDraft {
};
}
-/** One pending fact: include-toggle, stated values, verify-first when low-confidence. */
-function FactRow({
+/** One pending fact: include-toggle, stated values, and the edit control when it is low-confidence or its last save was refused. */
+export function FactRow({
documentId,
fact,
checked,
@@ -319,9 +319,10 @@ function FactRow({
) : null}
- {fact.needsReview && !verifying ? (
+ {(fact.needsReview || failure !== null) && !verifying ? (