Fresh duplicate check before posting, dismiss route sets stage, free accessory lines no longer crash promotion, readiness treats only posted notes as terminal, document-reference/usable-PO helpers, PO delivery reconciliation API + docs and audit register. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
13 KiB
Delivery-note inbox: agent handoff
Checkpoint: 27 September 2026, 22:43 Africa/Johannesburg. The user's request is to process the delivery-note inbox PO by PO, book each genuine delivery once at the PO's unit and rate, preserve supporting scans, and make future matching/reconciliation easier. The user expressly confirmed that the Vula 2.5 m pipe lines are ordered and booked in metres. Work has begun on genuine Vula PO MEGCPO9109 (0oxer2vuae370m4).
Read this file and the two linked audits before modifying data. The working tree contains extensive uncommitted edits by both Codex and a previous MiniMax agent. Preserve them; do not reset or blindly commit .env.local, .claude/worktrees, .codex, chat export.md, or temporary scripts. Follow root AGENTS.md: this is a changed Next.js version, so read the relevant node_modules/next/dist/docs/ guide before editing Next code.
Live checkpoint: do not post these again
The Vula PO now has seven posted delivery receipts, verified by the read-only reconciliation endpoint:
| Supplier invoice | delivery_notes.id |
PO quantities booked |
|---|---|---|
| VCINV073787 | urvc9qjgg9p14pl |
450 mm: 137.5 m |
| VCINV074058 | 21gz03njx23wh4w |
1050 mm: 27.5 m |
| VCINV074078 | fo06jfxxi81qp4c |
1050 mm: 27.5 m; zero-booked free rings |
| VCINV074143 | r1mj5nt4yo4y9fx |
1050 mm: 32.5 m; zero-booked free rings |
| VCINV074056 | zcrehww97ulrpt6 |
1050 mm: 27.5 m; zero-booked free rings |
| VCINV073935 | 3tdjr8cw3wv4jqb |
750 mm: 27.5 m; 900 mm: 27.5 m |
| VCINV073801 | b4jtyc0wj3l9hd0 |
450 mm: 85 m; 600 mm: 32.5 m |
The last two were posted in this session from source pages 36 and 28 respectively, after visual review. They returned HTTP 200 and were read back from the ledger. VCINV073801's other scans on pages 33, 39, and 59 were marked dismissed with manual_overrides.duplicate_of = wiw9a6r4hywr8vg and dn_review_events audit entries. Its retained page 28 candidate is now posted. VCINV073935 had no same-reference scan in the batch. No other unposted Vula invoice has been promoted during this session.
The live PO balance after those postings is:
| PO line | Line ID | Ordered m | Posted m | Open m | Posted value ex VAT |
|---|---|---|---|---|---|
| 450 mm | p6wa4072t7pvztl |
222.5 | 222.5 | 0 | R75,574.35 |
| 600 mm | s4dss10wzjrkfoj |
237.5 | 32.5 | 205 | R16,714.75 |
| 675 mm | ydiqzdj7krnm34w |
150 | 0 | 150 | R0.00 |
| 750 mm | 9bmxea7bhsyt80z |
27.5 | 27.5 | 0 | R21,678.25 |
| 900 mm | 1qxm32y8bml4k1x |
78 | 27.5 | 50.5 | R28,320.33 |
| 1050 mm | qgqpfpv460bceej |
252.5 | 115 | 137.5 | R182,162.30 |
Ordered total is R811,626.64 ex VAT; posted total is R324,449.98 ex VAT. The 900 mm line has a half-cent rounding boundary: 27.5 m × R1,029.83/m is R28,320.33, matching the printed invoice amount. currencyLineValue now uses integer cents and quantity ten-thousandths to avoid the earlier R28,320.32 preview. Full test suite: 185 files / 1,844 tests passed, npm run typecheck passed, git diff --check passed after the change.
Remaining Vula delivery decisions
There are ten distinct unposted Vula invoices on this PO. The table gives one proposed source page to retain, but compare its image and current ledger again before any posting. Pages are in batch 3ce6tdvkinny9is. Dismiss extra scans only with an explicit audit link to the retained candidate; original page files remain in PocketBase. The signed delivery notes on pages 55 and 72 are separate supporting documents, not extra deliveries.
| Invoice / delivery ref | Candidate to retain (page) | Other pages | Proposed new PO quantity and ex-VAT value | Particular check |
|---|---|---|---|---|
| VCINV073799 / VDN074329 | z0rriva39pj041f (18) |
31, 70 | 600 mm: 85 m / R43,715.50 | Page 70 is stamped “Tax Invoice copy” and prints a different item code while description, qty, ref and total agree. Inspect before dismissing it. |
| VCINV073800 / VDN074334 | r65odltqtd5xjmi (32) |
29, 38, 58 | 600 mm: 35 m / R18,000.50; 675 mm: 50 m / R37,312.00 | Page 29's OCR said VCINV073900; its scan clearly prints VCINV073800. Audited override already saved. |
| VCINV073802 / VDN074348 | lyw6s31sr7getrf (34) |
30, 37, 57 | 675 mm: 75 m / R55,968.00 | Page 30 OCR read item code P67S-100; image prints P675-100. |
| VCINV073832 / VDN074366 | 8rjtu7f9m5guwvz (26) |
35, 41, 61 | 600 mm: 85 m / R43,715.50 | Verify the same 34 pipes across scans. |
| VCINV074055 / VDN074559 | le894m86keazh3h (48) |
22, 66 | 1050 mm: 27.5 m / R43,560.55; 11 free rings | Page 22 OCR misread VDN074555; audited override corrects it to VDN074559. If choosing page 48, check runner's terminal-candidate pending-identity behavior noted below. |
| VCINV074057 / VDN074588 | yex1b01hzfaeq1b (20) |
50, 53, 68 | 1050 mm: 27.5 m / R43,560.55 | Same invoice in four scans. |
| VCINV074077 / VDN074606 | tn9ho8j9l2ron2r (65) |
46 | 1050 mm: 27.5 m / R43,560.55; 11 free rings | Page 46 OCR said VCINV0746T7; source prints VCINV074077. Audited override saved. |
| VCINV074079 / VDN074616 | 2x71gsd21gobas8 (23) |
45, 64, 71 | 1050 mm: 27.5 m / R43,560.55; 36 free rings | Rings are explicit R0 extras, not pipe metres. |
| VCINV074063 / VDN074597 | 5xa0gs5dinunxff (47) |
supporting signed DN 55 | 1050 mm: 27.5 m / R43,560.55; 11 free rings | Compare signed DN 55 and invoice 47; count once. DN has no price and must not be posted as another receipt. |
| VCINV074156 / VDN074699 | i69vrng0sn0dj98 (43) |
supporting signed DN 72 | 675 mm: 15 m / R11,193.60 | Compare signed DN 72 and invoice 43; count once. |
If all ten prove genuine and are booked once, 600 mm and 1050 mm reach their PO quantities exactly. The 675 mm line should still have 10 m (four 2.5 m pipes) outstanding; 900 mm should still have 50.5 m outstanding. Do not invent documents to close those balances. The invoice and delivery-note references must both be checked for duplicates before posting.
Already posted Vula invoices still have active scan copies in the inbox: VCINV073787 (pages 27, 40, 60), VCINV074056 (21, 49, 67), VCINV074058 (51, 54, 69), VCINV074078 (44, 63), and VCINV074143 (42, 62). Their posted receipts are listed above. The signed DN on page 56 (VDN074673) supports posted VCINV074143 and must not add 13 pipes again. Compare each to the posted receipt/slip, then stand down the duplicate scan with an audit event.
Other POs and the current inbox
After the two new postings and three verified-copy dismissals, the numbered inbox had 57 Needs matching and zero Ready to post. Some 14 blank split-review placeholders in other batches are excluded from that numbered count. Outside the Vula PO, eleven numbered scans remain:
| Document | Candidate ID | Current PO ID | Main task |
|---|---|---|---|
| IN018888 | hmwsh8kymxu2vel |
zr44xtb5u567npw |
Avidan pipe lengths/rolls; resolve PO line units and product mapping. |
| IO019079 | cgcpg2nu2uhn3dz |
zr44xtb5u567npw |
Avidan related delivery; compare kit/component lines. |
| INA00005204 | n9g3t22xcvr2iwu |
ctcz8y9kej4n51r |
Signs R Us; returned line and several unlinked components. |
| INV70963 | ie00wpe98qtnzks |
none | Ikhasi; OCR has MEGCPO9199 in alternate refs but PO field blank. Verify printed label and actual order before linking. |
| INV71060 | xyfjrk4yx9ox7d9 |
none | Ikhasi; OCR has MEGCP09255 in alternate refs but PO field blank. Verify. |
| 090005815 | br2uwjqtjlbyt4v |
none | Raumix; printed #MEGCPO9185, genuine matching PO not found. Do not substitute a nearby order. |
| IRN010002024 | ktrfy7v4h6alpyz |
y35epf1bpx9vai8 |
Raumix; distinct invoice despite shared supplier order BORN010000034; inspect ticket AS0002066. |
| 22433700 | 7bhke1nqi5qjjfh |
jsx87ptwjvj1iwk |
Builders collection note already has posted counterpart; compare and stand down if same. |
| DEL53312 | zxjwfcera04us6a |
m67a4jwi9ges4ma |
Product decision. |
| LI513543 | nm0mbh6chvhj2vy |
s24atzm69empbwv |
Supplier relation missing despite checks; verify supplier identity before linking. |
| T0255611 | qu12z7bt0r2lbbf |
pslduk2tyr4ool0 |
No line items extracted; read source before any booking. |
Historical per-scan detail is in 2026-09-27-delivery-note-matching-review.md and the more recent 2026-09-27-delivery-note-remediation.md. Their old counts and row statuses are snapshots; use the live API/database for current state.
Safe continuation procedure
- Read state first.
GET /api/purchase-orders/0oxer2vuae370m4/delivery-reconciliationwith the existingx-ingest-secret: $N8N_INGEST_SECRETgives posted lines, pending groups, page paths and PO balances. Do not print the secret. A development server is currently athttp://localhost:6004; it may need restarting. The endpoint is read-only, not a scheduler. - Open the cached source page for each proposed invoice and compare printed invoice number, VDN number, date, PO, line code, count, rate and amount.
dn_batch_pages.extractionholds the first OCR; the original PNG is available through/api/dn-batches/{batchId}/pages/{n}or PocketBasedn_batch_pages.image. Do not equate a signed DN with an invoice scan. - For verified repeated scans, retain one candidate. Stand the other candidates down with an explicit
duplicate_ofrelation inmanual_overridesand adn_review_eventsrow. The current/dismissroute does not write an audit event and only setsstatus, so either improve it first or use an atomic PocketBase batch as this session did. Do not dismiss the posted receipt itself. - Re-run
runStagedBatch(pb, "3ce6tdvkinny9is")against cached pages after decisions. It reads 73 cached pages, takes roughly 1–2 minutes, and does not post. Check the retained candidate becomesstage=ready_to_post; if not, inspect itschecks. Only then call the normalPOST /api/dn-batches/{batchId}/notes/{noteId}/postroute. Read the receipt and PO line quantities back immediately. Post one invoice at a time and recompute remaining balances. - Known runner edge case to fix/test:
run-staged.tsexcludes terminal candidates frombatchPrimaryClaims/batchReferenceClaims, but still registers them inpendingDocumentIdentitieslater in the loop. A dismissed earlier page can therefore block a retained later page (for example page 22 dismissed, page 48 retained). Add a focused failing test, then skip terminal candidates when registering pending identities. Avoid manualready_to_postflags as a workaround. - Known API preview gap: the PO reconciliation API's
bookingPreview.lines[].alreadyReceivedandoutstandingAfterPostingare currentlynullbecause it passes PO lines without receipt totals intobuildDeliveryNoteBookingPreview. The top-levellines[]balances are correct. Fill preview balances from posted totals and test it; do not interpret null as zero. - After Vula, repeat the same read/compare/resolve/book cycle for the other PO groups. Never auto-post all
Needs matchingitems. The separate n8n/agent endpoint and usage notes are in delivery-reconciliation-api.md; no daily schedule or n8n workflow has been created.
Code and data changes already made
- The invoice accidentally imported as PO
#MEGCP09109(tkw4p3qq14vg3of) was quarantined asdocument_kind=tax_invoice; the true order isMEGCPO9109(0oxer2vuae370m4). Four pre-existing 1050 mm receipts were moved to the genuine order in an audited transaction. Five blank Vula pipe units on the genuine PO were corrected tomafter user confirmation. - PO matching now strips surrounding hashes and normalises the known
MEGCP0/MEGCPOOCR form only when it identifies a unique exact order. New PO imports reject invoices. The export registration21615145is excluded from Vula document identity. - Duplicate checks distinguish posted receipts from other pending scans and hold both sides of a repeated primary/alternate reference. Explicit numeric R0 accessory lines can remain unlinked without being priced or booked as pipe quantity. Failed ledger reads and severe quantity plausibility failures block readiness.
- The inbox groups scans and displays page references; document detail shows PO-based value and unit conversion. New
GET /api/purchase-orders/[id]/delivery-reconciliationis read-only and reports ordered, posted and open quantities/values, grouped pending scans and warnings. The 900 mm half-cent valuation was corrected insrc/lib/metrics/delivery-note-value.tsandsrc/lib/po-delivery-reconciliation.ts. - Three verified OCR reference corrections are recorded in
manual_overridesanddn_review_events: page 29VCINV073900 → VCINV073800, page 46VCINV0746T7 → VCINV074077, page 22VDN074555 → VDN074559. The source page extraction remains as originally read; overrides survive reruns.
Verification at handoff: npm run test:run passed 1,844 tests across 185 files; npm run typecheck and git diff --check passed. Re-run after further changes. The current work is uncommitted and there is no PR. Preserve the existing worktree and review the diff before packaging it.