fix(documents): keep an incomplete extraction on the document

A long document read in parts can end with a part cut at the provider's
output limit, a part never read, or more facts than one review takes.
That was told once, as a notice when the run finished; a review opened
later looked complete.

InboundDocument.extractionIncomplete (migration 0483) is written with
the facts by both stagings, the extract route or run and lab
auto-staging. The document detail publishes it and the review shows the
same note whenever it is opened. The disaster-recovery backup carries
it; an older file restores it as false.

Refs #1257
This commit is contained in:
Marc-André Bombeck committed 2026-10-25 01:01:13 +02:00
1 parent 5cfaf4869d
commit 958d230b9f
15 files changed
+233 -44

No files matched your search

@@ -59,6 +59,7 @@ export const documentBackupSchema = z
.nullable()
.optional(),
aiReadDeferred: z.boolean().optional(),
extractionIncomplete: z.boolean().optional(),
summary: z.string().nullable().optional(),
createdAt: isoDateTime.optional(),
updatedAt: isoDateTime.optional(),
+7
View File
@@ -61,6 +61,8 @@ export interface DocumentBackupEntry {
sourceInstance?: string | null;
/** Canonical DR only: the import's hold on automatic AI reading. */
aiReadDeferred?: boolean;
/** Canonical DR only: the staged facts may leave part of it out. */
extractionIncomplete?: boolean;
}
/** The document columns both purposes carry. */
@@ -96,6 +98,7 @@ const DOCUMENT_DR_METADATA_SELECT = {
lastIndexAttemptAt: true,
lastIndexOutcome: true,
aiReadDeferred: true,
extractionIncomplete: true,
updatedAt: true,
} as const satisfies Prisma.InboundDocumentSelect;
@@ -166,6 +169,7 @@ function serialiseDocument(
lastIndexAttemptAt: dr.lastIndexAttemptAt?.toISOString() ?? null,
lastIndexOutcome: dr.lastIndexOutcome,
aiReadDeferred: dr.aiReadDeferred,
extractionIncomplete: dr.extractionIncomplete,
};
}
@@ -404,6 +408,9 @@ export async function restoreDocuments(ctx: RestoreContext): Promise<void> {
// An older file has no marker: those documents predate the hold and
// restore as ordinary ones.
aiReadDeferred: document.aiReadDeferred ?? false,
// An older file has no marker: its staged facts read as complete,
// as they were shown when it was written.
extractionIncomplete: document.extractionIncomplete ?? false,
sourceSystem: document.sourceSystem ?? null,
sourceId: document.sourceSystem ? (document.sourceId ?? null) : null,
// A file written before v1.39.3 has no instance: the key then