4.7 KiB
Final cross-feature fix wave report
Base: 9ace0fb
Code commit: 9ae498a
Addressed blockers
- Staged assembly now aggregates every ordered page read, uses first-nonempty header evidence, preserves every extracted line, persists line links and the complete canonical check list, and marks a candidate ready only when PO/site/supplier/item/check gates are satisfied.
- Added a two-page continuation regression proving that distinct lines on both pages survive aggregation.
- Manual assembly split/join now clears derived document identity, supplier/PO relations, items, checks, match evidence, candidate identity, and posting relation for every affected nonterminal candidate. New candidates start
needs_review; posted/dismissed candidates remain protected. - Added optional
global_pageto canonical pages, assigned during staged normalisation, with a batch-wide unique index. Posting and page proxy lookup use it. Legacy rows are remapped only when source ordinal/page identities are contiguous and unique; mixed or gapped rows fail closed. - Added a missing-middle-page posting regression: persisted global pages 1 and 3 with candidate
[3]selects page 3.
Verification evidence
Commands run from the worktree:
npx vitest run src/lib/dn-pipeline/run-staged.test.ts src/lib/dn-pipeline/page-store.test.ts src/lib/dn-pipeline/normalise-source.test.ts src/lib/dn-pipeline/promote.test.ts src/lib/dn-pipeline/readiness.test.ts src/lib/dn-pipeline/assemble.test.ts "src/app/api/dn-batches/[id]/assembly/route.test.ts" "src/app/api/dn-batches/[id]/notes/[noteId]/post/route.test.ts"
8 files passed, 89 tests passed
npm run typecheck
passed
python3 scripts/pb-add-dn-staged-ingestion.py --self-test
self-test: index replacement and idempotence passed
python3 scripts/pb-add-dn-staged-ingestion.py --dry-run
offline preview completed; no schema changes written
git diff --check
passed
Residual risk
The migration remains unapplied and DN_STAGED_INGESTION_ENABLED remains unchanged. Existing rows without global_page and with a source-page gap require manual repair/re-extraction; the posting path intentionally refuses to infer their identity.
Follow-up P1 fixes
- Exported
evaluateRequiredChecks; the staged runner and posting readiness gate now share the exact required/optional policy. A nullproduct_matched,units_convertible, orqty_plausibleresult cannot produceready_to_post. - Staged checks now load cumulative
delivery_note_items.qty_receivedtotals once per run and pass them toqty_plausible. Missing schema, failed reads, or invalid quantities persist a faileddelivered_totals_availablegate and fail closed. A sequential over-delivery regression proves the current candidate remains review-only.
Follow-up code commit: 199dfba
Follow-up focused verification: 4 files, 92 tests passed; npm run typecheck; git diff --check.
Follow-up 2
delivery_note_items totals are now queried with an escaped OR filter built from the batch's site-scoped purchase-order item IDs. Rows outside that set are ignored before validation. Relevant malformed quantities, including negatives, add a failed persisted gate; zero remains valid. Added regressions for unrelated malformed rows, relevant malformed/negative rows, and cumulative over-delivery.
Follow-up 2 code commit: bb70f33
Follow-up 2 focused verification: 4 files, 95 tests passed; npm run typecheck; git diff --check.
Migration idempotency follow-up
merge_indexes now compares semantic-normalized CREATE INDEX definitions: index names, keywords, quoted identifiers, whitespace, and punctuation are normalized for comparison, while uniqueness, column order/content, and WHERE predicates remain meaningful. Self-tests cover the exact PocketBase uppercased/multiline variants and near-miss definitions that must replace.
Migration code commit: bee2b3d
Verification: migration self-test passed; authenticated live --dry-run against the configured PocketBase reported every collection/index already present and ended with DRY RUN. No schema changes written.; git diff --check passed. No live writes were made.
Migration normalizer follow-up
The comparison now treats backtick-quoted, double-quoted, and safely unquoted SQLite identifiers as equivalent. It tokenizes around double/backtick identifiers and preserves single-quoted literals exactly, so a literal near-miss remains a real replacement. Self-tests cover all identifier styles and a changed single-quoted predicate literal.
Normalizer code commit: 1a97d7d
Verification: migration self-test passed; authenticated live --dry-run reported all indexes already present and no changes; git diff --check passed. No schema apply was performed.