# 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 `` 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).