Regularization
When an employee forgets to punch or a punch is wrong, they file a regularization.
Request
POST /api/v1/regularizations
{
"for_date": "2026-04-22",
"requested_in": "2026-04-22T09:00:00Z",
"requested_out": "2026-04-22T17:30:00Z",
"reason": "Phone battery died after lunch"
}
Approval Chain
Same chain as leave (ShiftManager → HR → SuperAdmin override). Decision endpoint:
POST /api/v1/regularizations/{id}/decide
{ "action": "approve", "comment": "Manager verified on CCTV" }
Recalculation
On hr_approved:
AttendanceRecalculatoris invoked for(employee, for_date).- Virtual punches are seeded from
requested_in/requested_out(channel =regularization). - The attendance row is recomputed; flags are re-evaluated.
- An audit row captures the before / after.
Edge Cases
- Multiple open regularizations for the same date — only one may be open at a time; a new request supersedes the old.
- Regularization across a locked month — rejected unless SuperAdmin overrides, which triggers an unlock + edit + re-lock cycle.
- Regularization against an overnight shift —
for_datemust match the shift's start date.