develop full initial module

This commit is contained in:
Dhananjaya99
2026-07-23 19:54:56 +05:30
parent eacc21afad
commit 755df494fe
188 changed files with 13894 additions and 49 deletions
+28
View File
@@ -87,6 +87,34 @@ Convention: `docs/01-DOC-GUIDE.md §6`. Update this file in the **same commit**
- [~] Loading / empty / error states on every list — done for the GRN list/create/detail screens; other screens still unbuilt
- [x] Transactional actions show server-returned side effects as confirmation — GRN confirm renders `createdLayers`/`ledgerRefs`/`poStatus` from the response
---
# HRM (Phase 2)
Spec: `docs/21-FRONTEND-HRM.md` (flows + rules) · `docs/13-BACKEND-HRM-API.md` (API contract).
## 8. Screens (per `21-FRONTEND-HRM.md §1`)
> **Code complete (2026-07-23).** All screens below built against the live HRM API (`lib/api/{employees,hrm-masters,hrm-master-factory,attendance,leave,payroll,hr-reports}.ts`, `types/hrm.ts`). `tsc --noEmit` clean for every new/changed file (the only remaining project-wide tsc errors are pre-existing, unrelated syntax errors in `app/dashboard/receiving/grn/new/page.tsx` — not touched this pass, not introduced by it). `eslint` clean on all new/changed files. Runtime browser verification not yet done — see the note at the end of this section.
- [x] Employees (`app/dashboard/hrm/employees/{page,[id]/page}.tsx`) — list + create dialog (department/designation/employment-type/work-shift selects) + detail page with an Overview/Bank Details/Documents/Salary & Loans tab switcher (plain button-based tabs — no `Tabs` primitive exists in `components/ui/` yet). Email-lookup cross-link suggestion chip on the create dialog's email field (`onBlur``employeesApi.emailLookup`), never auto-linking — the human must have already seen the match before `linkUserId` is set on submit.
- [x] **Salary & Loans tab** (added same session, follow-up to the initial pass) — Salary Structure section shows effective-dated history (`employeesApi.salaryStructureHistory`) + a "New Structure" dialog (effective date, basic salary, dynamic allowance/deduction lines picked from `salaryComponentsApi`, `employeesApi.createSalaryStructure`); Loans & Advances section shows the loan list (`employeesApi.listLoans`) + a "New Loan" dialog (Loan/Advance, principal, installment amount, count, start year/month, `employeesApi.createLoan`).
- [x] Users screen (`app/dashboard/settings/users/page.tsx`) extended with the same cross-link suggestion chip in reverse (`employeeCrossLinkApi.findStaffByEmail` on email blur), setting `linkEmployeeId` on submit. `ManagedUser`/`CreateUserRequest` types extended with `email`/`linkEmployeeId` to match the backend DTO changes.
- [x] Attendance (`app/dashboard/hrm/attendance/{page,[id]/page}.tsx`) — batch list + upload dialog (period start/end + file picker, `.xlsx`/`.csv`) + template download link (`attendanceTemplateUrl()`) + detail page rendering the Working Hours/Late/OT preview table with per-row validation-status badges, Validate/Confirm/Unlock actions gated on batch status, and Keep/Discard duplicate-resolution buttons (Draft only).
- [x] Leave (`app/dashboard/hrm/leave/page.tsx`) — single-page request list + create dialog (employee/leave-type selects, immediately submits after create) + inline Approve/Reject actions on Submitted rows (reject via a `window.prompt` for the reason — the simplest correct UX given the time budget; a proper dialog is a nicer follow-up, not a correctness gap).
- [x] Payroll (`app/dashboard/hrm/payroll/{page,[id]/page,[id]/lines/[lineId]/page}.tsx`) — run list + Generate dialog (year/month), detail page rendering the exact Basic/OT/Allowances/Deductions/Net preview table plus Approve/Lock/Unlock(with mandatory reason)/Generate Payslips actions gated on `status`, and a line-breakdown page matching the user's exact Earnings/Deductions/Employer-Contributions layout (EPF-employer/ETF explicitly labeled "informational — not deducted"). **Backend gap found and fixed during this pass**: there was no endpoint to list all `PayrollLine`s for a run (only single-line lookup existed) — added `GET /payroll-runs/{id}/lines` (`IPayrollRunService.ListLinesAsync`, `PayrollRunsController.ListLines`) since the Payroll Preview table genuinely needs it; documented in `docs/13-BACKEND-HRM-API.md §6`.
- [x] Reports (`app/dashboard/hrm/reports/page.tsx`) — single page, a report-type select switches which filter fields + table are shown (Attendance Summary / Overtime / Late Arrivals / Payroll Register / Salary History / Leave Balances / Document Expiry), each calling its own `hrReportsApi` method on demand.
- [x] Settings screens (`app/dashboard/hrm/settings/{page,branches,departments,designations,employment-types,work-shifts,document-types,leave-types,salary-components,statutory}/page.tsx`) — a hub page linking to 9 sub-screens. `components/hrm/CodeNameMasterPage.tsx` is a shared generic component for the three byte-identical "code + name" masters (Branch, Designation, EmploymentType) — the other masters (Department's parent/branch selects, WorkShift's many fields + working-days bitmask, HrDocumentType's category enum, LeaveType's paid/no-pay/carry-forward flags, SalaryComponent's type enum) each have their own page since their forms genuinely differ, matching this codebase's own existing convention of one file per master rather than a forced one-size-fits-all abstraction. Statutory settings page covers both `PayrollStatutorySetting` and `TaxSlab` (list + create, no edit — both are effective-dated/append-only by design).
- [x] Sidebar (`components/Layouts/AppSidebar.tsx`) — new "HRM" section with 6 children (Employees/Attendance/Leave/Payroll/Reports/Settings). **Deviation, matching existing precedent**: no backend `NavItem`/`SubNavItem` seed exists for `hrm`/`hrm.*` codes yet, so — exactly like the pre-existing `procurement` bypass — `hrm` is added to the same frontend-only `bypassCodes` set that skips the `navCodes` visibility check. This is also the AR-09 sidebar-visibility stopgap called out in `02-SECURITY.md §C.8`: it hides HRM from the UI for now but enforces nothing server-side. Remove the bypass once a real nav/permission seed exists.
- [x] `lib/api-client.ts` extended to support `FormData` request bodies (attendance file upload, staff document upload) — previously every request body was unconditionally `JSON.stringify`'d; now a `FormData` body skips both that and the `Content-Type` header (the browser sets its own multipart boundary).
## 9. Validation posture (HRM specifics, per `21-FRONTEND-HRM.md §3`)
- [x] Client format/required checks on the Employee create dialog (code/name/hire-date/department/designation/employment-type/work-shift) and Attendance upload (period dates, file presence) — UX only, per `20-FRONTEND.md §3`
- [x] Server-authoritative, never assumed client-side: employee-code uniqueness, email-lookup match existence, one-User-per-Employee, attendance duplicate detection (within-batch/cross-batch), attendance batch lock state, payroll generation's attendance-confirmed precondition, payroll run lock state, and every calculated amount (Gross/Net/Tax/EPF/ETF/OT/Late/No-Pay) — the client never computes or previews these independently of what the server returns; all payroll tables render server-supplied numbers verbatim.
**Not yet done, flagged rather than silently skipped:**
- **Runtime/browser verification.** Every screen above type-checks and lints clean, and was built directly against the live API contract confirmed by the backend smoke test (71+ registered routes, correct 401 gating), but no screen has been driven in an actual browser this pass — that needs a running AuthHex session (see `Backend/PROGRESS.md`'s sub-phase 2.1 note on why deep functional testing was deferred) to get past the login wall.
- **Leave reject uses a native `window.prompt`** instead of a dialog — functionally correct, but a lower-fidelity UX than the rest of the app's dialog-based patterns.
- **A pre-existing, unrelated syntax error in `app/dashboard/receiving/grn/new/page.tsx`** (unclosed JSX, last touched 2026-07-23 before this HRM pass started) blocks a clean whole-project `tsc --noEmit` run. Not introduced by this work and not fixed by it — confirmed via `git status`/`git log` that this file was untouched this session; scoped `eslint`/`tsc` checks against every HRM file individually (and the fact this is the *only* file `tsc` reports) confirm the HRM additions themselves are clean.
## Done
<!-- move [x] items here with date + note if the active list grows long -->