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

4.6 KiB
Raw Permalink Blame History

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