Personnel
Staff, timesheets and shifts. Part of the business vertical. Legend: β done Β· π‘ in progress Β· β¬ pending.
Checklist
β Timesheets
Staff, timesheets and shifts.
β Staff records
Roster CRUD plus an append-only effective-dated pay history over /v1/staff/:id/compensation β a raise is a new row.
β Shifts
Shift-type vocabulary and staff-on-date assignments; the joined roster read renders a week grid from one call, and double-booking is a DB refusal (409).
β Time tracking
Kiosk punch clock over /v1/time-tracking β clock-in guarded against a double punch (409), a break toggle that accumulates closed breaks, approval stamps and ranged reads.
β Leave
Leave balance is always SUM(delta_days) over a signed ledger; approval writes the negative row in the request-flip transaction, and day counts exclude weekends and public holidays.
β Overtime
Computed from approved time entries against the day's shift window (worked β scheduled β grace) with upsert on recompute; manual entries and approve/reject.
β Payroll
Runs over /v1/payroll calculate deterministically from compensation + approved time/overtime/paid leave; posting writes a balanced Salary Expense / Wages Payable journal entry in the status-flip transaction, mark-paid moves Wages Payable to Cash.
Evidence
Personnel is real: staff_members + staff_compensation (V08_03) behind /v1/staff and shift_types + shift_assignments (V08_04) behind /v1/shifts, company-scoped. Live-proven on the dev catalog β two staff created (one salaried, one hourly with a raise as a new effective-dated row, never a mutation), Morning and Evening shift types, six assignments across three days read back as a joined roster, completed/absent transitions applied, and a duplicate assignment refused by the DB unique as 409; a foreign company sees nothing. Rows verified in Postgres. The full-HR wave is live too: time_entries (V08_05) behind /v1/time-tracking β kiosk clock-in/out with a double clock-in refused as 409 and a break toggle β leave_types + leave_requests + leave_ledger + public_holidays (V08_06) behind /v1/leave and /v1/holidays, and overtime_entries (V08_07) behind /v1/overtime. Proven end to end: a 9h entry against a Morning assignment computed 55 overtime minutes (8h shift, 5min grace) and recomputes upsert; a Vacation allowance of 15 allocated, a Thu-to-Tue request counted 3 days because the weekend and a created Friday holiday are excluded, and approval wrote the -3 ledger row in the same transaction, leaving balance 12 as SUM(delta_days). And the epic closes with Payroll: payroll_runs + payroll_run_lines (V08_08) behind /v1/payroll, runs that calculate deterministically from compensation plus approved time, overtime and paid leave, and post REAL balanced journal entries to the finance ledger. Proven live: the 2026-08 run paid the salaried monthly rate plus a 3-day vacation at monthly/21.67 and the hourly 9h plus 55 overtime minutes at 1.5x, a 10.67% CCSS rule withheld per line, and posting wrote journal entry Salary Expense 288,760,060 = Wages Payable 257,949,362 + Tax Payable 30,810,698 β debits equal credits in journal_entry_lines, a re-post was refused with exactly one entry under the idempotency key, and mark-paid posted the second balanced entry moving Wages Payable to Cash. Timesheets stays on the hospitality time-clock registration; staff, shifts, time-tracking, leave, overtime and payroll are commerce registrations.