The person scanner now reads the phone location when it opens and when the app
returns to the front, and selects the nearest site unless one was picked by hand.
The Fix missing clock time button stays available, accepts 5:00 style times and
leaves out-of-range times for the server to explain.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Clock slip form: no cost code (a slip is booked to its site). Each photo
is previewed, with "Add another page" for the invoice behind a bank slip,
up to 5 pages in order; extra pages can be removed.
- Slip API takes 1-5 photos; the photo route serves ?page=N and is now
holder-or-admin only (the shared-login rule was left over).
- Movements sheet shows every page; CSV drops the cost code column.
- Cash Floats table: a card under its limit gets a red row, and the card
number opens its movements.
- Sidebar: the low-card mark shows on Cash Floats only, not on Management.
- Migration: slip_photo holds up to 5 files (applied to production
2026-10-28).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Retention is about a tenth of the certified invoice, so on one shared
scale its bars were barely visible and paired bars sat off their month
labels. Each figure now gets its own chart and scale.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inflows (claims) now shows only Certified invoice (VAT incl) and Retention
(ex VAT), fed by an Import certificate dialog that reads the PDF (INVOICE
TOTAL, this month's Less RETENTION, valuation number, date) for review
before saving. Adds a monthly + cumulative chart and a certificates table
linking each stored PDF.
- income_claims gains retention_amount and certificate (migration applied)
- pdftotext with an unpdf fallback for machines without poppler
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds a /dashboard/plant/fuel-prices page to view, add, edit and delete
dated diesel prices, plus a monthly check that prices each fuel log at
the rate in force on its own date.
- admin-only POST/PATCH/DELETE /api/fuel-prices with zod validation
- monthly cost helper flags months that fall back to the default rate
- plant landing and fuel logs pages link to the new screen and show the
current rate per litre
- /api/fuel-prices added to the plant module path access list
Stack the slip line over its PO line picker in one column and show
value with left-on-PO beneath it, so every column fits beside a 300px
documents column without horizontal scroll.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clock scanner: double-tap the previous reading to remove the latest
scanner-entered reading. Fuel Logs and vehicle pages: double-click a
meter-only row to delete it. Reason, actor and values are logged.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Rate / hr column put every worker's wage on a wide table that is
glanceable, projected and exported. The rate already lives on the worker
detail page, where it is a deliberate lookup.
Drop the column from the roster and the rate from its CSV export — the
export is the wider accidental leak, since that file gets emailed and
opened on shared machines. Site managers can still see a worker's rate by
opening the worker, which stays deliberate access.
Surveying → Maps is open to every dashboard user, scoped to their sites.
Sites (contracts and profitability) shows for admins, and for site managers
only when "Can see Sites" is ticked on their account. Old map links redirect.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each cash float card lives on its holder's user record (card number, last
4-6 digits of the physical card, low limit, assigned date). Every movement
goes in one cash_float_log collection: opening, top-up, slip, handover and
correction rows with signed amounts. Balances are always summed from the log.
- Management -> Cash Floats: cards table (lowest balance first), add, edit,
top up, hand over, correct balance, retire, movements sheet with slip
photos and CSV export. Admin-only.
- Settings -> Users: card section in the edit form and the balance per holder.
- Clock app: Slips tab, shown only to a user who holds a card. Photo, site,
supplier and amount; the slip comes off that user's own card.
- Sidebar needs-attention mark when a card is under its limit.
- Slips count as site spend ("Cash float slips" on the site page).
- Migration scripts/migrations/2026-10-24-cash-floats.py (already applied to
production on 2026-10-24).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds an all-sites payroll (Excel/PDF/CSV, one row per worker, per-site split and
site wage cost), a period-selectable labour cost by site table on the Workforce
dashboard, and each worker's all-sites total plus site wage cost in the
timesheet matrix and its exports.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A destination scan now ends the worker's previous site session at that moment
(transfer OUT, hours booked at the origin) and opens the new one, so nothing is
left for the office to review. Vehicle scans take a scanning site, move the unit
there and log the reading against it. Adds a script to close already-flagged moves.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
New /dashboard/sites/[id]/map3: a 3D map forked from Map 2 (Map 1 and 2 untouched) with ground heat map, contours, cut & fill from the Chris survey, a longitudinal profile, yellow/green progress glow, a Services tab for stormwater/sewer/water routes, and status popups on earthworks strips and routes. Pure logic and tests in src/lib/site-map-v3.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Remove the planned-cost line from the actual vs forecast income chart and colour the Turnover Overview cumulative result purple (planned) or green (actual).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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>
- Sites → Maps in the sidebar replaces the per-site Site map / Map 2 links.
The Maps page shows each site's model as a plan preview (built sections
solid) with % of road layerworks built and links to Site map and Map 2.
- Double-clicking a road section opens its progress tick-boxes over the map
(Site map saves to the server; Map 2 stays a local scenario).
- Cedar Gate: 40 drawn cross-sections extracted from C3277-912-001 Rev A
(extract_cedar_gate_xs.py), cut/fill limited to Cedar Gate Road, a Cut &
fill workspace in Map 2 with a chainage chart, and pavement layers shown
in their material colours.
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.
Show invoiced, forecast and awarded split in the turnover KPI; pin the
cash result column and add per-month invoiced/forecast lines; stack the
side panels in a column with a year comparison chart so both columns end
level; reword the income-less-cost chart labels. KPI band follows the
app greys in dark mode and a light grey in light mode, with all figures
neutral except the accent-coloured turnover.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Income tab shows Actual, Forecast, Planned and a combined total with
colour stripes matching the chart; month columns right-align with their
headers; the forecast line under an actual uses the forecast purple;
the red stack falls back to the forecast bar when a month has no
invoiced figure yet.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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 delivery notes page showed the "Possible duplicate receipts need office
review" notice before the KPI strip, so the numbers the office acts on sat
below the thing it needs to act on. The notice now sits directly under the
KPIs and directly above the search and table.
The KPI strip moves out of the client-side table view into its own server
component, so the page owns the order of the three blocks. That also removes
a double padding bug: the page and the view each applied p-4 sm:p-6, which
indented the KPI and table column 32px while the notice sat at 16px.
The figures are unchanged - they always described the full site-scoped set
of delivery notes, not the filtered rows.
A page test locks the new order (KPI < notice < search < table) and fails
if the blocks are rearranged.
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>