K.33 — Step-2 resume, preview flake (twice-broken worker), Daftar Setoran page-jump
Deployed: ahu-ai-ocr:6e331863 @ x056.ahu-demo.ocr.val.id · 2026-07-20
Suites: backend 2718 · frontend 1019 (0 fail)
Live proof submission: 0f94caef-307a-4174-aed0-951f2774ef10 (fresh re-run of your 5d2bdead files)
1. "I was on Ekstraksi, reopening sent me to Step 3" — fixed
The dashboard routed every READY submission to the review (a deliberate 2026-07-10 ruling — but it assumed you had CLICKED "Lanjut ke Tinjauan"). When the pipeline reaches READY while you're still reading the Ekstraksi page, nothing recorded that you never confirmed — so the next visit teleported you.
Now there's a server-side stamp:
(READY, reading)"] -- "Lanjut ke Tinjauan click
→ POST /extraction-ack" --> R["Step 3 Tinjauan
(also stamps on mount)"] D["Dashboard"] -- "READY + stamped → Review" --> R D -- "READY + NO stamp →
Lanjut Ekstraksi" --> E
Submission.extractionAckAt+ idempotentPOST /:id/extraction-ack; both the button and the review page itself stamp it (deep links can't loop).- Migration backfills rows already past review; READY rows deliberately stay unstamped — so your
4bfe3ffbnow correctly shows "Lanjut Ekstraksi" and re-enters at step 2. Verified live on the notaris dashboard. - Scoped to Pendirian PT (the reported flow); other flows keep the 2026-07-10 behavior.
2. "Failed to load the page." then it works — the worker was broken twice
- Why intermittent: the pdf.js worker loaded from unpkg.com — an external CDN, on a system that's on-prem by contract. First preview of a session raced that fetch; once the browser cached it, everything "worked". Fixed: the worker is Vite-bundled and served by our own origin (verified: zero unpkg references in the shipped bundle, worker asset 200 from
/assets/). - The trap under the fix: that import resolved the top-level
pdfjs-dist@5.5.207while react-pdf pins its own5.4.296— API/worker version mismatch, which kills EVERY load, deterministically. The top-level package is now pinned to react-pdf's exact version. - Viewer hardening while there: switching documents resets page state (a 6-page rekening koran used to display "1 / 21" after the 21-page akta), a failed load now shows "Pratinjau PDF gagal dimuat" with a working Coba lagi retry, and the real error reason is logged instead of swallowed.
3. Daftar Setoran rows now jump to the right page
The old verdict ("bbox impossible — word boxes discarded") was true of the stored data, but not of extraction time — the OCR words with page indexes were in hand and thrown away. Now:
- The setoran pass anchors each fact by matching its distinctive values against the per-page OCR words — transaction id → jumlah digits → rekening → tanggal, ≥5-char needles, and only single-page hits count (an amount printed on three pages proves nothing).
- Anchors persist as real
setoran_row_<i>BoundingBox rows, so the click rides the exact same viewer path as every other field: document switch → page jump → word-tight highlight on the credit line. Also fixedpageCount, which this path never recorded (rows sat at 0). - One viewer-race fix made it stick: the jump now re-fires when the target document's boxes finish loading (clicking a row for doc B while viewing doc A used to race the box fetch and stay on page 1).
Verified live on 0f94caef: clicking the "Rp 12.420.000" row switches to Rekening Koran, jumps to page 3/6, and highlights the exact "124.200,00" credit entry.
Note: existing submissions (your 5d2bdead) were extracted before anchoring existed — their rows still open the document without a jump. Re-uploading the files gets full anchoring (that's precisely what 0f94caef is).
4. Bonus find — why the rekening koran's rows kept disappearing
Reproduced on staging: the 3B extraction call had no max_tokens, so the server's default cap truncated a 15-row guided-JSON array mid-object — and JSON.parse threw the WHOLE document's rows away. That nondeterminism is why the same koran sometimes showed rows and sometimes nothing. Fixed with an explicit 4096 budget sized to the schema ceiling plus a salvage parser that trims a truncated payload to its last complete row (grounding already rejects half-rows).
Result on the same file: 0 → 31 facts, all 31 page-anchored.
Commits
ac959447 |
resume stamp + bundled worker + page anchoring + processor split |
01530ac7 |
max_tokens + truncation salvage (0 → 31 rows) |
0abb9ab8 |
worker version-matched to react-pdf + doc-switch reset + retry UI |
6e331863 |
page-jump re-fires when the target doc's boxes arrive |