Re-verified every file:line against the current tree. Three were wrong:
the Overview ranges in task 6 (and it listed two sites.items uses where
there are four), the hamburger line in task 5, and a claim that
plant/page.tsx still had perPage: 5000 caps — it does not.
Also records that tasks 1-5 have landed, so the next worker starts at 6,
and keeps the scope-aware Sites sub-label that was implemented in place
of the deletion this plan originally specified.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The migration's docstring pointed at a spec file that was never
written for this feature (the design was worked out via conversation,
not a separate spec doc) — points at the plan instead.
A concurrent project Month/Week feature is landing in the same view
files and has already shifted purchasing-view.tsx by ~10 lines, adding
a periodFilter beside projectFilter. The removal steps now match on
identifiers and snippets, and the plan header says to treat every
file:line as a hint.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
16 TDD tasks: pure scope helpers, the getSiteScope seam, the topbar
switcher, then per-module server-side filtering. Task 15 records why
the chat agent's default-site change is deferred out of this plan.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replaces the four independent per-table project-code dropdowns with a
single global scope carried in the URL as ?site=, resolved server-side,
and applied as a PocketBase site= filter. Defines the getSiteScope()
seam so the separate PocketBase users work plugs in without touching
the 23 Topbar call sites.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds the "Upload status" buttons on Purchase Orders and Delivery Notes,
the shared badge/KPI/filter UI they use, and removes the now-dead
Uploads sidebar entry and Financial landing card.
Purchase Orders and Delivery Notes each get their own unlinked
"upload status" page reached via a button next to the upload action,
mirroring the Timesheets pattern. Removes the combined
/dashboard/financial/uploads page and its sidebar entry, since its two
halves (PO status, DN status) are now scoped to the page they belong to.
Timesheets now shows only entries + filters; an "Upload status" button
next to Import Timesheets opens the sheet-by-sheet processing view on
its own route, not listed in the sidebar.
Workers becomes a lean roster (name, employee number, position, type,
site, rate) with filters unchanged. Everything currently cluttering the
list row -- total hours, cost, the 8-week sparkline, per-employee entry
history -- moves to a new worker detail page that doesn't exist yet
(today's "detail" is a dialog). Same pattern already used for Suppliers
and Vehicles/Equipment this session: lean list, detail page carries
depth.
Timesheets keeps its flat entries table but gains a genuinely separate
upload-status section -- the timesheets document collection already has
this data, it's just currently squeezed into a per-row badge instead of
being its own thing. The duplicated Import-timesheets button (currently
on both pages) moves here only.
QR badges: encodes employee_no directly, no new PocketBase field --
every worker already has a valid code the moment they exist, with no
generation step. Explicitly a deliberate tradeoff (guessable numbers,
no revocation) the user chose for now, pending seeing how the separate
timekeeping PWA wants identity handled -- moving to a stored opaque
token later is additive, not a rework. Card layout confirmed via the
visual companion (centered, QR-forward). Both single-worker and
batch-sheet print confirmed in scope. Rendering via the qrcode npm
package + the browser's own print dialog (@media print), not a PDF
library -- CSS handles real-world card dimensions more reliably than
fighting a PDF engine's coordinate system.
The timekeeping PWA itself is explicitly out of scope -- a separate
project this spec only needs to stay compatible with.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Card is rounded-xl with no overflow-hidden. TableHeader is sticky with
its own opaque background (bg-card/95) that sits flush against the
card's edge -- with nothing clipping it, the header's square background
corners poke past the card's rounded ones. Visible on every page built
with the shared <Card><CardContent className="p-0"><Table> pattern:
Suppliers, Supplier Detail, Uploads, Delivery Notes, Fuel Logs,
Timesheets. Purchase Orders is unaffected -- it uses a card-per-row
layout, not an HTML table.
Added overflow-hidden to each affected Card. Standard, deterministic
Tailwind behavior -- reliably clips child content to the parent's
border-radius, no visual regression risk.
Also added click-to-sort on the Suppliers list (Supplier/POs/Ordered/
Delivered/Outstanding, toggling asc/desc) -- the page previously only
supported a fixed server-side default (outstanding descending) with no
way to change it. No existing sort-header convention exists elsewhere
in the app, so this is self-contained rather than a premature shared
abstraction for what is still a single use site.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
13 tasks across 6 phases: additive schema, pure matching/ledger
functions (TDD, tested in isolation), the one irreversible migration
(guarded, dry-run default), OCR wiring, API routes, and UI.
Grounded in the actual codebase rather than the spec's prose: the
existing "unknown supplier" inline-editor on the PO detail page
(SupplierEditor + POST /api/purchase-orders/[id]/supplier) is upgraded
in place rather than duplicated, following the same principle applied
to the sidebar restructure's delivery-note review queue. Every code
sample is written against files actually read during planning, not
guessed -- site-form-dialog.tsx, the /api/sites routes, matchSite,
po-fulfilment.ts, and the live purchase_orders.supplier data.
Self-review caught a real gap before committing: pb-bootstrap-schema.py
and pb-types.ts were named in the file-structure table but no task
actually touched them -- exactly the foot-gun docs/data-model.md
section 7 warns about. Added as Task 1 steps 5-8.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>