Commit graph

673 commits

Author SHA1 Message Date
DEls
6e5aa8cf10 feat(mcp): set delivery documents aside and restore them
Co-Authored-By: MiniMax Code <noreply@minimax.io>
2026-10-09 02:28:05 +02:00
DEls
e3b285cd17 feat(mcp): post a whole delivery slip in one call
Agents plan slip lines (not shifting indexes), may group lines into one
kit allocation, and NIL lines close automatically. Commits line by line
under the inbox's PO and batch leases; journaled and resumable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:25:06 +02:00
DEls
86abe6b1db docs(dn): stage 2 implementation plan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:21:41 +02:00
DEls
62bd5af576 docs(dn): stage 1 implementation plan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:01:47 +02:00
DEls
6c6f767cfb fix(dn): stop blocking second deliveries that share a supplier order number
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:01:36 +02:00
DEls
8e01f0172c feat(dn): decide receipt identity by primary document numbers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 01:59:52 +02:00
DEls
db75a8fe0b fix(mcp): return and journal the real purchasing error with a hint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 01:59:21 +02:00
DEls
ab61182ced docs(dn): Avidan matching study and agent tools design
Study of 18 Avidan delivery documents matched by hand against their POs,
with root causes for why nearly every slip is flagged. Design for giving
agents full delivery-note tooling (everything except delete), staged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 01:55:21 +02:00
DEls
cb463c0faa feat(workforce): add timesheet exports and duplicate protection
Add per-site CSV and PDF matrix reports, editable sick-note date ranges, and weekend calendar styling. Preserve verified duplicate uploads for audit while excluding their entries from hours and costs, and prevent repeat files and overlapping daily imports.
2026-10-07 23:53:47 +02:00
DEls
a21c728d61 feat(workforce): add calendar and sick notes 2026-10-07 14:27:44 +02:00
DEls
f72397259c feat(auth): add Office access and restrict Clock users 2026-10-07 14:22:57 +02:00
DEls
8d53e3688c feat(workforce): add active and inactive workers 2026-10-07 13:41:05 +02:00
DEls
0df711875c feat(workforce): add rate history and missing-rate editor 2026-10-07 13:19:50 +02:00
DEls
5b141db5dd Merge remote purchasing MCP into main
# Conflicts:
#	docs/setup/api-and-mcp-connections.md
#	docs/setup/env-and-mcp.md
#	scripts/check-connections.mjs
2026-10-05 07:13:36 +02:00
DEls
29e20f3caf docs: record API and MCP connection audit 2026-10-05 07:13:23 +02:00
DEls
4922d649ae feat: add remote purchasing MCP to existing app 2026-10-05 02:46:36 +02:00
DEls
9f0698f1d1 feat: run durable MCP processing jobs in the existing app 2026-10-05 02:04:15 +02:00
DEls
4be0b2fa4e feat: expose matching and fenced receipt posting through MCP 2026-10-05 02:00:37 +02:00
DEls
f9a5ca80a7 feat: add immutable purchasing uploads and candidate edits 2026-10-05 01:55:31 +02:00
DEls
68e1c223a3 feat: share validated purchasing writes with MCP 2026-10-05 01:48:49 +02:00
DEls
cc8e2c8f01 feat: expose purchasing details and protected source documents 2026-10-05 01:42:27 +02:00
DEls
08becc6270 feat: journal MCP operations and fence purchasing writes 2026-10-05 01:38:15 +02:00
DEls
f9d3427767 feat: enforce MCP capabilities and no-delete policy 2026-10-05 01:33:37 +02:00
DEls
96da8ac4e8 feat: add authenticated same-app MCP transport 2026-10-05 01:31:17 +02:00
DEls
9c9a9d1866 docs: plan same-app remote purchasing MCP implementation 2026-10-05 01:22:08 +02:00
DEls
7ffe4eb94d docs: use existing app URL for remote MCP design 2026-10-05 01:16:34 +02:00
DEls
4970e61e70 docs: specify remote purchasing MCP service 2026-10-05 00:51:44 +02:00
DEls
6824d2c62e Add Workforce attention alerts and 24-hour correction times 2026-10-04 23:38:43 +02:00
DEls
ed69b517e8 Integrate agent work and add dashboard attention indicators
Remove repeated Plant, Financial and Workforce shortcut cards. Add site-scoped Plant and Financial sidebar attention status with automatic refresh.

Include accumulated delivery processing, purchase order recovery, supplier reconciliation, plant data and user management changes and audit records.
2026-10-04 21:53:32 +02:00
DEls
bcbd3167e4 feat(clock): unify scanners and document capture 2026-09-30 06:44:36 +02:00
DEls
758999ce3b fix(clock): keep fleet dialogs above phone keyboard 2026-09-30 01:07:11 +02:00
DEls
b92449d337 fix(clock): pause QR decoding and fit search above keyboard 2026-09-30 01:03:23 +02:00
DEls
8f0407c49c Improve user settings layout and forms on mobile 2026-09-30 01:00:42 +02:00
DEls
32d4a82cdf feat: add employee search and save pending fleet updates 2026-09-30 00:42:38 +02:00
DEls
4ad262b508 Let site managers create clock users for assigned sites 2026-09-30 00:11:24 +02:00
DEls
71499f5222 Allow assigned-site users to perform operational actions 2026-09-29 23:58:40 +02:00
DEls
7f8561ff6b Use file token when posting protected delivery note page 2026-09-29 14:45:35 +02:00
DEls
11a227bb4e Allow clock users to upload purchase orders for assigned sites 2026-09-29 13:33:46 +02:00
DEls
223da69884 Fix document upload permissions and clock correction origin 2026-09-29 13:26:47 +02:00
DEls
b700252932 fix(auth): verify PocketBase backup key before migration 2026-09-29 07:01:15 +02:00
DEls
f5259d852f feat(auth): add PocketBase logins and site access controls 2026-09-28 23:51:47 +02:00
DEls
3ba004ffd3 fix(dn): harden delivery-note matching, posting and PO reconciliation
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>
2026-09-28 21:16:24 +02:00
DEls
da9dca7c6e feat(plant): add "Add vehicle" button to the Fleet & Fuel page
Generalizes the Plant page's add-dialog into a shared AddVehicleButton
component parameterized by unit_type, and wires it into the vehicles
page against the existing POST /api/vehicles endpoint.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 08:33:53 +02:00
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
DEls
39d85fa8a9 fix(ask): supplier balances, payable per supplier per period, PDF fallback
- Ask's supplier loader didn't pass date_received, so supplier_balances
  and the supplier_balance dataset crashed
- supplier_balances takes a period (thisMonth, thisWeek, month1-3) and
  returns what was received from each supplier in it (payable)
- PocketBase's space-separated dates dropped deliveries on the 1st from
  period filters, including the Suppliers page's Payable KPI
- The PDF route falls back to the answer text when a saved report has
  no sections (older format), instead of a 500

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:56:40 +02:00
DEls
0f022d5ffa fix(ask): keep the Asking-as bar pinned under the navbar
The Ask page sized itself as 100svh-4rem, but the Topbar is 89px on
desktop and 167px on phones, so the page overflowed and the bar scrolled
under the header. The Topbar now publishes its live height as
--topbar-h and the Ask page fills exactly the space below it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:56:40 +02:00
DEls
1d8307453f fix(ask): key tool-provenance pills by index and name
A turn can call the same tool more than once (e.g. two query_records),
which gave duplicate React keys and a console warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:51:39 +02:00
DEls
956ba4e116 Merge branch 'feat/mobile-friendly'
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:45:35 +02:00
DEls
3feddebcaa fix(mobile): audit and fix layout overflow across dashboard pages at 375/768px
Audited /dashboard, /dashboard/sites (+ detail), /dashboard/workforce/workers,
/dashboard/workforce/on-site, /dashboard/plant/vehicles (+ detail),
/dashboard/plant/equipment (+ detail), /dashboard/plant/fuel-logs,
/dashboard/financial/purchase-orders (+ detail),
/dashboard/financial/delivery-notes/inbox, /dashboard/financial/suppliers,
and /dashboard/chat at 375x812 and 768x1024 using a scroll-right test to
catch real horizontal page overflow (as opposed to a table's own,
intentional internal scroll).

Two repeating bug patterns accounted for every overflow found:

1. A page-specific `right={<div className="flex items-center gap-2">...}`
   passed to Topbar can carry two or three labelled buttons (edit/import/
   merge/back etc.). Without `flex-wrap` they don't fit a 375px screen in
   one row and push the whole page sideways. Fixed on the vehicles,
   equipment, and site detail pages, plus their list-page counterparts
   (vehicles fuel-view, equipment plant-view) — all five instances of
   this exact pattern. Same fix applied to a delivery-note card's button
   cluster on the PO detail page, and to Topbar's own right-side
   container as a general backstop.

2. `Intl.NumberFormat("en-ZA", ...)` joins currency/number groups with
   non-breaking spaces, so a wide value like "R 24 988 663" can't wrap.
   In a 3-up grid (site cards' Contract/Spent/Remaining) that overflowed
   the column; fixed by stacking those to 1-up below `sm`. In a 2-up grid
   (PO detail KPI tiles) added `min-w-0` so the tile clips instead of
   growing the grid track past the viewport.

Also: the shared Dialog now caps at `max-h-[90dvh]` with internal
scroll (a dialog taller than the phone viewport had no way to reach
its close button or footer before), and the sidebar hamburger button
was overlapping the Topbar's title on every page below `lg` — reserved
space for it instead.

Tables already scroll horizontally inside their own card via the
shared `<Table>` component or an `overflow-auto` wrapper, and KPI
grids already collapse responsively — both were fine everywhere checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:44:19 +02:00
DEls
64d8fe1be2 fix(reports): externalize pdfmake's font stack, thin dense chart labels
Found live: rendering a report PDF 500'd with "ENOENT ... data.trie".
pdfmake's server PdfPrinter pulls in pdfkit -> @foliojs-fork/fontkit,
which loads font-shaping tables from a path relative to its own
installed location at runtime; webpack-bundled into the route's chunk,
that lookup can't find them. serverExternalPackages leaves the whole
chain on native Node `require`, where the real node_modules layout
resolves them — the same reason Next already ships `sharp` and
`@react-pdf/renderer` externalized by default.

Also found live: a bar chart with ~30 categories (fuel by vehicle)
printed completely overlapping x-axis labels. categoryLabelStride
thins them the way recharts' minTickGap does, keeping only as many
labels as the plot width can fit without collision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:33:14 +02:00