PAYCRAFT

PAYCRAFT

A manpower services company was running payroll for twenty-plus client organisations in spreadsheets. Each organisation had its own salary structure, statutory mix, and pay cycle, so every month was a manual rebuild with no audit trail and no lock against sending the same bank file twice. Mistakes showed up after money moved. Adding organisations meant adding sheets — the process could not scale with headcount. This is a confidential client project; there is no public demo.

PAYCRAFT still 2

The hard part was encoding Indian payroll law and tenant isolation in the same system. PF, ESIC, Professional Tax, MLWF, bonus, and gratuity had to be calculated in the engine, not checked off in a document. Twenty-plus tenants share one database, so a missed filter is a data leak. Salary components vary by system default, client, designation, and employee, and a back-dated revision has to produce arrears without rewriting a closed month.

PAYCRAFT still 3

The UI is React: React Query for server state, Zustand for client state, React Hook Form and Zod on payroll forms, Recharts for company-wise metrics and employee drill-down, Tailwind for layout. SuperAdmin, Admin, Employee, and Auditor each get a different tree — the dashboard, attendance lock, and payslip viewer are not one screen with hidden buttons. The API is Node and Express with role-based access. A payroll run is a five-state machine (Draft → Submitted → Approved → Bank File Generated → Disbursed) so approval and disbursement cannot be skipped. Components resolve System → Client → Designation → Employee. Statutory rules live in the calculator. NEFT export stamps unique transaction references so a retry cannot double-pay. Payslips freeze as PDFs on approval, then go out on WhatsApp with email as fallback. Sensitive writes append to an audit log.

PAYCRAFT still 4

Multi-tenancy is a query contract, not a folder of databases — isolation either holds on every read or it does not exist. Statutory rules belong in the calculator; a settings screen that does not match the act is a payroll bug waiting for month-end. Client work means the closed month is the test: a duplicate bank file or a leaked tenant row is a payment, not a ticket. Immutability and the lifecycle exist because payroll has to stay correct after approval, not only while the form is open.