MEGAINFRA-WEBAPP/src/components
DEls 1899ed8e2c fix(dn): unstick long OCR runs, preserve OCR data through manual saves
Tick path
- Bump STALE_CLAIM_MS from 10 to 30 minutes. A 29-source OCR batch
  hit ~29 min and was being reclaimed mid-run by the 10-minute cap,
  leaving the batch in inbox with last_error='reclaimed after a
  stalled run' even though nothing was stalled. MAX_ATTEMPTS still
  bounds a truly stuck batch.
- After each dn_batch_pages create, the staged runner bumps
  dn_batches.page_count in the same lease-fenced batch. Final
  assembly write at run-staged.ts:223 still sets the authoritative
  value, so any drift from a reclaim-then-restart cycle is corrected.
  Inbox tiles now show live progress instead of 0 pages for the
  entire reading window.

PocketBase batch transport
- sendRecordBatch chunks across pb.createBatch() calls at the
  server 50-request cap. A 71-candidate assembly sent as one
  request was returning Invalid batch request data. and 500ing —
  the assembly route caught it and surfaced as the generic Grouping
  could not be saved. 73 mutations now split into 50 + 23 and land.

Assembly save UX
- The dismiss dialog now renders directly under the open-pages alert
  instead of at the bottom of the section (which was hidden behind 71
  document tiles on big batches). Clicking Dismiss page opens the
  reason input where the user is looking.
- saveGrouping surfaces the server-side error code
  (stale_revision / posted_candidate / dismissed_candidate /
  assembly_in_progress / invalid_page_coverage) instead of a generic
  Try again. On success, the page now redirects to /inbox so the
  documents land in their columns.
- The Technical details disclosure is gone from the grouping screen.
  Open pages already surface their reason in the alert above; the
  duplicate disclosure just competed with the decision UI.

Assembly route correctness
- After a successful manual save the route now writes
  stage=complete, status=needs_attention, notes_detected,
  processing_completed_at and clears claimed_at/last_error. The
  runner advances stage on its own runs but a manual save was
  never followed by a runner pass — without this the batch stayed
  in Check page grouping forever even though assembly was done.
- For existing candidates the route only updates grouping metadata
  (pages, page_from, page_to, assembly_revision, status, stage,
  checks). OCR-derived fields (doc_number, supplier_name_raw,
  items, raw_text) are preserved on the row — the runner only
  re-fills those for batches in status=inbox, and post-save the
  batch moves to needs_attention and never reaches the runner
  again. New candidates still get a createdCandidateFields row
  with the OCR fields blank, ready for the runner or operator
  entry.
- A Re-run batch button was added to the document detail header
  so the operator can refill the wiped OCR data (or re-resolve
  checks after a manual override) without first navigating to the
  batch detail page.

Customer identity check
- A Skip this check toggle on the document detail page records
  manual_overrides.skip_customer_identity. run-staged reads the
  override and turns the customer_identity check into passed=null
  (skip) instead of passed=false (fail), so OCR false-positives
  on the customer VAT no longer block posting while still
  requiring an explicit operator decision.
- The PATCH route accepts skip_customer_identity as an editable
  field so the toggle saves through the standard note route.

Tests
- 180 files / 1767 tests pass; typecheck clean.
2026-09-27 13:40:27 +02:00
..
layout fix(dn): unstick long OCR runs, preserve OCR data through manual saves 2026-09-27 13:40:27 +02:00
ui fix(mobile): audit and fix layout overflow across dashboard pages at 375/768px 2026-09-27 09:44:19 +02:00
add-plant-button.tsx refactor(schema): resolve project_code through site, not a stored copy 2026-09-11 16:01:14 +02:00
auth-gate.tsx fix(auth): return to the originating page after PIN unlock 2026-09-12 00:14:55 +02:00
edit-mode-bar.tsx feat(fuel-view): enhance inline editing and UI components 2026-08-26 08:54:57 +02:00
fixed-cost-dialog.tsx refactor(fixed-cost-dialog): drop defaultType prop, use field-message lookup, local-date default 2026-08-28 13:22:07 +02:00
import-fuel-logs-button.tsx fix: overview counts, wrong-unit fuel limits, meter guard, en-ZA numbers, vehicle merge, docs 2026-09-25 22:04:08 +02:00
import-plant-hours-button.tsx fix: overview counts, wrong-unit fuel limits, meter guard, en-ZA numbers, vehicle merge, docs 2026-09-25 22:04:08 +02:00
import-timesheets-button.tsx fix: overview counts, wrong-unit fuel limits, meter guard, en-ZA numbers, vehicle merge, docs 2026-09-25 22:04:08 +02:00
install-prompt.tsx feat(clock): in-app PWA install prompt with Chrome + iOS branches 2026-09-14 11:17:54 +02:00
limit-mismatch-badge.tsx fix: overview counts, wrong-unit fuel limits, meter guard, en-ZA numbers, vehicle merge, docs 2026-09-25 22:04:08 +02:00
logo.tsx
merge-vehicle-button.tsx fix: overview counts, wrong-unit fuel limits, meter guard, en-ZA numbers, vehicle merge, docs 2026-09-25 22:04:08 +02:00
needs-review-dns.tsx feat(delivery-notes): let an operator pick the purchase order themselves 2026-09-18 08:48:38 +02:00
po-picker.tsx feat(delivery-notes): let an operator pick the purchase order themselves 2026-09-18 08:48:38 +02:00
project-period-badge.tsx feat(project-calendar): add shared Month/Week badge component 2026-09-11 22:24:45 +02:00
pwa-register.tsx
rain-outlook-card.tsx fix: overview counts, wrong-unit fuel limits, meter guard, en-ZA numbers, vehicle merge, docs 2026-09-25 22:04:08 +02:00
site-form-dialog.tsx feat(sites): add work-month-start-day field to the site form 2026-09-11 22:25:32 +02:00
slip-preview.tsx fix(purchasing): proxy PB files so PDFs render in the slip iframe 2026-09-07 14:53:22 +02:00
supplier-form-dialog.tsx feat(suppliers): add create/edit dialog 2026-09-11 18:16:40 +02:00
theme-toggle.tsx
upload-delivery-note-button.tsx feat(dn): store bulk uploads as one batch 2026-09-18 19:19:05 +02:00
upload-purchase-order-button.tsx fix: overview counts, wrong-unit fuel limits, meter guard, en-ZA numbers, vehicle merge, docs 2026-09-25 22:04:08 +02:00
upload-status-ui.tsx feat(financial): wire up per-collection upload status pages 2026-09-11 21:44:12 +02:00
vehicle-unit-type-cell.tsx fix(components): keep UnitTypePill text on a single line 2026-08-31 14:18:19 +02:00
worker-qr-batch-dialog.tsx feat(worker-qr): real PDF + CSV batch export 2026-09-20 20:43:10 +02:00
worker-qr-card.tsx feat(workforce): workers roster slim + QR badge card + batch export 2026-09-11 20:57:52 +02:00