105 lines
5.1 KiB
Markdown
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).
|