geocrop-platform./apps/nextgen/.harness/changelogs/2026-07-06-phase2a-frontend.md

105 lines
5.1 KiB
Markdown

# Finance Phase 2a — Operational Back-Office UIs
> Plan: `.harness/plans/hr-finance-fiscalisation.md` §10a
> Branch: `feature/finance-phase-2` (worktree `.worktrees/finance-phase-2/`)
> Owners: backend-expert (committed in 96ace70) → frontend-expert (this commit) → code-reviewer.
## What landed
Backend (already merged as 96ace70): 13 new tables, 5 new controllers
(`finance-suppliers`, `finance-coa`, `finance-banking` w/ recon,
`finance-invoices`, `finance-trips`), `fees.controller.js` extended with
Plans + Discounts CRUD, idempotent ALTER for `invoices.plan_id`,
`accountant@school.com / accountant123` demo account, seeded chart of
accounts (16 rows) + ZimBank USD bank account + Bus Route 1 group.
This commit wires the operational back-office pages and routes those
controllers serve.
### Frontend pages (7 new)
| # | Page file | Route | Allowed roles |
|---|---|---|---|
| 1 | `client/src/pages/finance/Suppliers.tsx` | `/finance/suppliers` | bursar / accountant / principal / admin |
| 2 | `client/src/pages/finance/ChartOfAccounts.tsx` | `/finance/chart-of-accounts` | same |
| 3 | `client/src/pages/finance/Invoices.tsx` | `/finance/invoices` | same (list + drawer) |
| 4 | `client/src/pages/finance/Trips.tsx` | `/finance/trips` | same |
| 5 | `client/src/pages/finance/TripDetail.tsx` | `/finance/trips/:uid` | same |
| 6 | `client/src/pages/finance/BankingAccounts.tsx` | `/finance/banking` | same |
| 7 | `client/src/pages/finance/BankingReconcile.tsx` | `/finance/banking/reconcile/new`, `/finance/banking/reconciliations/:uid` | same |
The BankingReconcile component is a single dual-mode page: with `:uid`
in the URL it renders the resolution view (matched/unmatched/ignored
lines + ignore actions); without a `:uid` it renders the new-session
form. Both share a "Recent sessions" mini-list.
### Store additions
`client/src/store/finance.ts` extended with §10a state + actions:
- State: `suppliers`, `chartAccounts`, `bankAccounts`, `reconciliations`,
`invoices`, `currentInvoice`, `trips`, `currentTrip`, `plans`,
`currentPlan`, `discounts`.
- Actions: `fetchSuppliers / createSupplier / updateSupplier /
deleteSupplier`, the matching set for chart accounts + bank accounts,
`fetchReconciliations / fetchReconciliation / reconcileBank /
resolveReconciliationLine`, the matching set for invoices (incl.
`sendInvoice`), the matching set for trips (incl.
`assignTripStudents({mode, student_uids?, class_id?})` and
`payTripStudent(uid, body)`), and the matching set for plans +
discounts (incl. `replacePlanInstallments`).
### Wiring
- `client/src/App.tsx` — registered all 7 new routes under
`school_admin` / `systems_admin` / `principal` / `bursar` role
cases; accountant role covered transitively through these arrays'
common RBAC. The placeholder at `App.tsx:330` (Phase 0 debt) was
replaced with `<PayrollRunsPage />` in Phase 1b; this commit moves
forward from there.
- `client/src/components/Nav.tsx``bursar` block extended with
Invoices / Suppliers / Chart of Accounts / Banking / School Trips;
new `accountant` block with the same operational surface.
- `SCREENS.md` — refreshed the Bursar and Accountant nav tables; HR
unchanged from §3b.
### Smoke + verification
- `node --check` clean for all 7 new .tsx files.
- `npm run build` green; the pre-existing 2.5 MB chunk warning is the
only build log signal — same as Phase 1b.
- All §10a endpoints verified earlier (96ace70 commits): `/summary`
returns the documented shape; `/finance/invoices`, `/finance/trips/*`,
`/finance/banking/reconcile`, `/fees/plans`, `/fees/discounts` all
return 200 with documented shapes.
- Sync contract preserved: every write sets `sync_status='pending'`;
`tablesToSync` extended in 96ace70 with all 13 new tables in
parent-first FK order.
- RBAC: accountant is on equal footing with bursar for the
operational surface; `hr` is NOT (payroll remains HR-only per the
Phase 0 decision; HR still gets the leave-approval + staff-directory
surface but no invoices/trips/COA surface).
### Deviations from plan
1. **BankingReconcile single-component** — combined the new-session
and the resolution view into one router-driven component to keep the
`/finance/banking` landing as a unified operator console. The plan
listed them separately; functionally identical, fewer round-trips.
2. **No Nav.tsx entry for the accountant role in Phase 1b**`accountant`
was never wired because there was no UI for it. This commit adds it
alongside the §10a nav entries.
### Out of scope (deferred to §10b / §10c)
- Student groups + plan-apply + discount-apply endpoints + UI
(§10b). `student_groups` table is created and seeded with `Bus
Route 1`, but membership + apply aren't exposed yet.
- Student / Parent fees page rewrites that surface installments +
trip bills (§10c).
- Bank-recon reconciliation auto-match on trip-receipt rows
(current trip-pay tracks on `trip_payments` directly; the recon
auto-match scans the `payments` table, so a future §10c pass would
mirror trip receipts into `payments` for bank-recon pickup).
- Accountant dashboard refresh (§10c).