No description
Find a file
Dave 3a8dc15438 feat(expenses): build the cards from the sheet, and make the total real
The Expenses Overview had three cards pointing at routes that were never created
("Plant Overheads", "Insurance", "Tracking" were GL-account labels living inside
"Vehicle Costs" and "Bastion Finance", not section names). Each showed R 0 and
404'd, while three real sections had no card at all, and the headline read
R 437 159,01 against a stored R 680 485,37 - the R 243 326,36 the 2026-11-04
audit flagged as omitted (EX-01, EX-02).

The card list is now built FROM the overhead rows (lib/expenses-sections.ts), not
from a hand-written array of section names. A hard-coded list is what caused the
bug: the next section added to the sheet would be dropped the same way. A
section with no catalogue entry still gets a card, flagged, and still counts
toward the total - so a category can never vanish again. lib/expenses-sections.test.ts
reads data/source/overheads.json directly rather than a hand-typed fixture, so
it cannot drift by a cent, and asserts the total equals the sum of every row.

The cards are in TWO groups, because the money is not the same money:

  Running cost - tied to a vehicle      R 143 326,36
    Vehicle Costs, Bastion Finance
  Overheads - not tied to a vehicle      R 537 159,01
    Personnel, Maintenance, Rent & Utilities, Cash Floats, Subscriptions

  Total monthly overhead                R 680 485,37

The vehicle sections are the SAME money the per-vehicle registers on /running
already show - TLB06 R 29 036,08 is the Bastion finance row, DT01 R 1 033,29 and
WB02 R 3 318,14 are the Vehicle Costs rows - so those two cards carry an "Also
shown on Running Costs - do not add the two" note, and the split is printed
under the headline. The grand total is the sum of every overhead row, so /expenses
and /overheads now agree to the rand.

Also:

- /expenses/maintenance is new (the R 100 000 section had no page anywhere),
  built on the same ExpenseSectionPage as its siblings.
- Purchase orders sit OUTSIDE the overhead total on purpose: a PO becomes
  running cost when it lands on a machine. The strip reads the same loader as
  the Suppliers page (lib/supplier-spend-data.ts) over the same default view,
  so the two screens quote identical rands.
- /expenses/petty-cash now shows the R 10 000 monthly float allocation, so the
  hub card and the page cannot disagree.
- The /overheads reconciliation note is generated from OVERHEAD_RECONCILIATION
  instead of being typed. It quoted R 689 640,49, which reconciles with neither
  the workbook nor the app. The real arithmetic is R 1 110 486,87 - R 415 523,94
  (plant instalments, they live on each asset) - R 19 800,00 (the workbook's own
  Personnel total is too high) + R 5 322,44 (Santam: the app keeps it, the
  workbook subtotal skips it) = R 680 485,37.
- Maintenance is in the sidebar - every other expense section page is.

Vehicle Costs and Bastion Finance stay OUT of the sidebar: Running Costs
already covers them. The hub cards still link to their pages.

The Subscriptions VAT rows are still broken and npm run seed still exits
non-zero on them. Flagged, not quietly fixed.

Verified: typecheck clean, 162 tests (156 pass, 0 fail, 6 skipped), production
build clean, mobile checklist at 375x812 and 768x1024 on /expenses,
/expenses/maintenance, /expenses/petty-cash, /expenses/suppliers-2 and
/overheads - no horizontal scroll, no text under 12px, no tap target under
44x44.
2026-11-05 07:26:58 +02:00
.mavis/canvas-assets Mega Plant dashboard — fix & harden (Parts 0-5) 2026-09-12 09:35:48 +02:00
app feat(expenses): build the cards from the sheet, and make the total real 2026-11-05 07:26:58 +02:00
components feat(running): the year to date AND the live month on the running-cost pages 2026-11-05 01:42:23 +02:00
data/source feat(plant): vehicle site history from Fuel Logs 2026-11-05 00:18:24 +02:00
docs feat(income): posted income per site, and the LIVE month on the overview 2026-11-05 00:19:06 +02:00
lib feat(expenses): build the cards from the sheet, and make the total real 2026-11-05 07:26:58 +02:00
outputs chore(audit): keep the 2026-11-04 audit evidence and workbooks 2026-11-05 02:02:27 +02:00
public Add Workforce pages, Plant Clock tab bar and oil & diesel book-out 2026-10-22 11:39:18 +02:00
scripts feat(plant): vehicle site history from Fuel Logs 2026-11-05 00:18:24 +02:00
worker feat: add user access and improve plant dashboard 2026-10-06 04:02:08 +02:00
.dockerignore Round 4: regressions fixed + mobile standard 2026-09-12 12:05:43 +02:00
.env.example Mega Plant dashboard — fix & harden (Parts 0-5) 2026-09-12 09:35:48 +02:00
.gitignore chore(audit): keep the 2026-11-04 audit evidence and workbooks 2026-11-05 02:02:27 +02:00
AGENTS.md feat(expenses): build the cards from the sheet, and make the total real 2026-11-05 07:26:58 +02:00
COOLIFY.md Round 4: regressions fixed + mobile standard 2026-09-12 12:05:43 +02:00
Dockerfile feat: show the build commit as a faint corner mark 2026-10-30 01:27:22 +02:00
HANDOFF-PROMPT-2.md Round 2 (Parts B-D): asset register restructure, type field, sequential codes, flat sortable table, cost_lines, removed synthetic code, fail loudly 2026-09-12 10:24:26 +02:00
HANDOFF-PROMPT-3.md Round 3 (Parts A-B): charts fixes + expenses/overheads cleanup 2026-09-12 11:24:18 +02:00
HANDOFF-PROMPT-4.md Round 4: regressions fixed + mobile standard 2026-09-12 12:05:43 +02:00
HANDOFF-PROMPT.md Auto-create synthetic assets for unmatched machines in seed; update open-questions report 2026-09-12 09:40:18 +02:00
next.config.ts feat: add user access and improve plant dashboard 2026-10-06 04:02:08 +02:00
package-lock.json feat(clock): add standalone employee clock PWA 2026-10-21 06:39:15 +02:00
package.json feat(clock): add standalone employee clock PWA 2026-10-21 06:39:15 +02:00
postcss.config.mjs Mega Plant dashboard — fix & harden (Parts 0-5) 2026-09-12 09:35:48 +02:00
proxy.ts Cash float card, Office role + Slips tab, job card PDF, manual close/delete 2026-10-22 15:09:57 +02:00
tsconfig.json Mega Plant dashboard — fix & harden (Parts 0-5) 2026-09-12 09:35:48 +02:00