geocrop-platform./apps/nextgen/.harness/changelogs/2026-07-04-phase1-frontend.md

92 lines
4.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog — 2026-07-04 (Phase 1 frontend)
## feat(frontend): HR & Finance Phase 1 surfaces — frontend
Branch: `feature/hr-finance-phase-1-frontend` (off `dev`).
Depends on: `feature/hr-finance-phase-1` backend endpoints (B1B8).
### What ships
Six user-facing pages consuming the Phase 1 backend, plus merged stores
preserving Phase 0 state shape so HRManagement.tsx and FinanceManagement
consumers keep working.
| Path | Roles | Backend endpoint(s) consumed |
|---|---|---|
| `/dashboard/hr` | school_admin, systems_admin, principal, hr, bursar, accountant | `GET /api/hr/dashboard/summary` |
| `/dashboard/finance` | school_admin, systems_admin, principal, bursar, accountant | `GET /api/finance/dashboard/summary` |
| `/finance/expenses` | school_admin, systems_admin, principal, bursar, accountant | `GET /api/finance/expenses?status=&category=&date_from=&date_to=` |
| `/finance/expenses/new` | as above | `POST /api/finance/expenses` |
| `/finance/expenses/:id/edit` | as above | `PATCH /api/finance/expenses/:id` (see deviation #1) |
| `/hr/payslips/:id` | school_admin, systems_admin, principal, hr, bursar, accountant | `GET /api/hr/payslips/:id` |
### Stores
- `client/src/store/hr.ts` — extended to also expose `fetchDashboardSummary`,
`fetchPayslip(id)`, and `resetPayslip`. New `currentPayslip` and
`dashboardSummary` state slots. Legacy Phase 0 records / leaveRequests /
payrollRuns / payslips / vacancies / applicants / metadata / staff_records
management endpoints + their methods are preserved verbatim.
- `client/src/store/finance.ts` — extended with `fetchDashboardSummary`,
`fetchCategories`, `fetchExpenses`, `fetchExpense` (see deviation #1),
`createExpense`, `updateExpense`, `deleteExpense`. Phase 0 payroll proxy
actions kept intact for the existing Finance payroll UX.
### Routing / Nav
- New routes wired into App.tsx's role-aware `getRoutes()` switch arms for
`school_admin`, `systems_admin`, `principal`, `hr`, `bursar`.
- Nav.tsx `NAV_CONFIG` blocks for those five roles gain dashboard and
expenses entries using `lucide-react` icons (`LayoutDashboard`, `Receipt`,
`Plus`).
- Role gating is in App.tsx via `<ProtectedRoute>` — no in-component
role checks.
### Deviations from the dispatch
1. **`PATCH` instead of `PUT` for expense updates.** The Phase 1 backend
exposes `PATCH /api/finance/expenses/:id`, not `PUT`. Store and form both
use `api.patch(...)`.
2. **`GET /api/finance/expenses/:id` does not exist on the backend.**
The edit page prefills by fetching the list endpoint with `limit=500`
and matching by id. Caches the row for subsequent visits.
See `client/src/store/finance.ts` `fetchExpense` for the rationale.
3. **`FinanceDashboard` uses `/api/finance/dashboard/summary` directly.**
The dispatch says the backend doesn't expose this endpoint yet and
suggests falling back to `/api/dashboard/stats`; however the Phase 1
branch already shipped that endpoint. We consume it directly. A monthly
time-series endpoint remains a TODO for Phase 2 — the current chart
synthesises a 2-point series from MTD totals.
4. **`PayslipDetail` uses `/api/hr/payslips/:id` directly.** Same as above;
the Phase 1 branch already exposed it.
### Files added (8)
- `client/src/store/hr.ts` (modified, +139 lines)
- `client/src/store/finance.ts` (modified, +282 lines)
- `client/src/App.tsx` (modified, +42 lines)
- `client/src/components/Nav.tsx` (modified, +13 lines)
- `client/src/pages/dashboard/HRDashboard.tsx` (new)
- `client/src/pages/dashboard/FinanceDashboard.tsx` (new)
- `client/src/pages/finance/Expenses.tsx` (new)
- `client/src/pages/finance/ExpenseNew.tsx` (new)
- `client/src/pages/finance/ExpenseEdit.tsx` (new)
- `client/src/pages/hr/PayslipView.tsx` (new)
### Acceptance check
-`npm run build` succeeds — `✓ built in 13.48s`, no TS errors.
- ✅ Phase 1 backend (`:3001/api/hr/dashboard/summary`) returns the four-tile
aggregate for admin token.
-`/api/finance/dashboard/summary` returns collected_mtd / outstanding_fees /
payroll_last_run / expenses_mtd / pending_expenses.
-`/api/finance/expenses` GET returns `{ expenses, pagination }`.
- ✅ POST → PATCH → DELETE round-trip on `/api/finance/expenses` works (smoke
test created expense #7, patched to 99.99, deleted).
- ✅ RBAC denial — student@school.com token gets `403 HR, Finance, Principal
or Admin access required` on `/api/hr/dashboard/summary`, and
`403 Finance, Bursar, Accountant, HR, Principal or Admin access required`
on `/api/finance/expenses`.
- ✅ Print stylesheet wired into `PayslipView.tsx` (`@media print` block
scopes the visible content to `#payslip` only).