Awarded (not started) and non-calculated projects now appear on the
Retention table, labelled, blank until values are entered. Entered values
count towards totals and the company balance, and the retention save
endpoint accepts any project in the plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add planned vs actual turnover dashboards, monthly actual costs, editable retention forecasts and actuals, starting retention, payouts and running balances. Preserve manual values across workbook imports and include retention backfill tooling.
Add Cedar Gate model extraction and reports, measured service routes and ground surfaces, plus site-map section totals and quantity refinements.
Move the Management planning snapshots into PocketBase collections
(plans, projects, per-year project plans, retention, edit log), loaded
with a bundled-JSON fallback. Admins can double-click an income cell to
enter forecast and actual, edit awarded jobs' planned amounts, change
status and costs, and add jobs, with revision checks and an audit trail.
Income chart now shows forecast and invoiced bars with not-yet-started
money stacked in red; Income is in the sidebar. Adds schema and import
scripts, and jsdom/Testing Library dev dependencies for UI tests.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The employer and broker API routes were never named in the path
classifier, so they fell through to its admin-only default and the
proxy rejected a site manager with a bare {"error":"Not allowed"}
before the route handler ran. The handler's own site scoping was
always correct — it just never got the chance to apply.
- classify /api/employers as dashboard and map it to the workforce
module, mirroring /api/employees
- let the site dropdown be chosen when adding an employer; only a
rename freezes the site, which preserves assignment history
- cover the rename path, which had no route test, and the proxy
gate for the site-manager role
- Tick runs new scans before batches requeued for PO rechecks; old
uploaded_at dates kept rechecks ahead of today's scans for hours.
- Supplier records with the same normalised name and no conflicting
registration/VAT count as one company, so PO9480 (held by the second
Drift Laezonia record) no longer fails as a supplier conflict.
- Inbox shows a queued scan as waiting rather than being read.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Improve workforce scanning, site transfers and timesheet exports.
Audit plant imports, duplicate identities, rates and dashboard totals.
Repair delivery PO selection, periodic rechecks and receiving guards.
Align financial ledgers, supplier periods and mobile layouts.
Add the site map preview, shared theme controls and audit evidence.
Verify 3,455 application tests, six fuel export tests, TypeScript and
an optimized production build. Clean up a leaked test timer and keep
local worktrees and generated reports out of ESLint traversal.
Changed-file lint passes; repository-wide lint retains 33 existing
errors in unchanged files.
- write PocketBase batches in chunks of at most 50 (production limit)
- survey import: refuse files with no rows, write peg events before the import record
- read en-ZA Excel CSVs (decimal comma), quoted fields, CR line endings; no crash without pegs
- save queue: reset on model reload, drop 400-refused items instead of blocking,
keep queued values on screen when a server state arrives, flush on leaving the page
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Text PDFs already get it from pdftotext; photos and scans have no text,
so 4 of 5 undated POs were photos that do print a PO Creation Date.
- n8n PO reader (stored patch): asked for order_date = 'PO Creation
Date' (day/month/year), never Required By or Printed; the callback
passes it on.
- process-batch accepts extracted.order_date (YYYY-MM-DD); the PDF text
wins when both exist.
- create_purchase_order / update_purchase_order / move_to_purchase_orders
take order_date, so agents record it too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reader always read the slip date (and receiver, site name, customer
VAT, supplier registration), but dn_batch_notes never had those fields,
so they were dropped on save and every receipt was dated the moment it
was posted. The Financial dashboard dated orders by upload date, so 24
of 41 POs (R7.08M) sat in no month and deliveries piled up in the month
they were booked: 'R1.1M ordered, R2.4M delivered'.
- scripts/pb-add-dn-dates.py: adds the five header fields,
delivery_notes.posted_at and purchase_orders.order_date (applied).
- scripts/dn-backfill-dates.py: filled 270 documents from the stored
readings, moved 192 receipts to their slip date (booking time kept in
posted_at) and read 36 PO order dates from the PDFs (applied; replaced
values in docs/audits/2026-10-11-dates-backfill-backup.json).
- Posting refuses a slip without a delivery date instead of using today;
receipts record posted_at. The review page shows the date and locks
Post with a plain message when it is missing.
- PO intake reads 'PO Creation Date' from the PDF text (pdftotext).
- Dashboard tile and monthly chart date orders by order_date only; an
order without one is undated, never put on its upload month.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Set-aside delivery documents were kept but shown nowhere, so they looked
lost (e.g. The Waste Group slip T025511, set aside 'Waiting for
invoice'). The inbox now has a Set aside button: every set-aside
document with why (in plain words) and when, a link to its page, and a
Restore button that puts it back in the inbox through the same restore
the agents use, recorded with who and why.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A scan in up to 07:10 pays from 07:00; a scan out between 16:20 and
16:40 pays to 16:30; a session over five hours loses a 30-minute lunch.
A normal day is therefore exactly 9 hours (green on the calendar and
matrix); late arrivals, early exits and overtime use the real times.
Applied on clock-out, in missed-scan corrections and their preview.
The calendar keeps the raw scan times and labels hours "Paid hours".
Includes a dry-run-first script to recalculate existing QR entries; it
only rewrites rows still equal to their raw scan total.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agents can now save a whole receiving plan (lines by number, kits, NIL
auto-close) and leave the slip in Ready to post; the site manager checks
the totals and presses Confirm delivery, which posts exactly what was
saved. Quantities over the PO need acceptExcess (site-approved) and a
slip with an open site question is refused.
Confirm delivery on the web now refreshes a slip whose match went stale
because another slip on the same PO was booked, re-applying the saved
decisions instead of sending the user back to an AI re-match.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When nobody scanned a worker in, the evening scan was stored as the IN
and the correction dialog only allowed a leaving time after it. The
dialog now shows an editable arrival and leaving time, with a one-click
"this scan was actually the clock-out" swap. Late scans (16:00+) get a
hint on the card. A corrected arrival is stored as the optional
actual_in_at on the correction row (migration script included, not
applied); the original QR scan is untouched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both are page reads; two in one tick can pass the 300s ceiling and get a
batch reclaimed and read twice. The job waits for the next tick instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add turnover, project, retention, and year comparison pages from the supplied workbook, protected by named admin access. Include the local chart gallery, grouped monthly hover, smooth comparison toggle, and monthly income minus cost series.
Require named PocketBase sign-in in every environment and remove the shared PIN bypass. Update access documentation and business-route test fixtures.
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.
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.
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>