Skip to content
sarmakska edited this page Jun 1, 2026 · 1 revision

Leave

The leave module covers leave applications, multi-step approval, per-balance carry-forward caps, and PDF certificates on approval. Balances are tracked per user and per leave type.

Applying for leave

A user opens the Leave page, picks a leave type, the start date, and the end date, and chooses up to three approvers in priority order. The request is written to leave_requests with the chosen approvers stored in approvers JSONB, the current step in current_approver_index, and per-approver outcomes in approver_status JSONB. The balance is provisionally decremented so the user cannot over-apply.

Multi-step approval

When the request is created an email goes to approver one with an approve and decline link. If approver one approves the request is accepted, the balance is consumed, and a PDF certificate is emailed back to the user. If approver one declines, or does not act within LEAVE_APPROVAL_TIMEOUT_HOURS (default 48), the request advances to approver two, then approver three. If everyone declines or the chain runs out, the request is marked declined and the provisional balance is refunded.

Withdrawal

A user can withdraw an unapproved or future-dated approved request. Withdrawals refund the balance and write an audit-log entry.

Balances and carry-forward

Each user has one leave_balances row per leave type with entitlement, used, carry_forward, and max_carry_forward. The accounts team sets max_carry_forward per user from the admin area. On 1 January the year-end-rollover cron runs at 00:05 UTC, capping unused days to max_carry_forward and writing the new year's opening balance. The job is idempotent: a second run on the same day is a no-op.

Accruals

Balances with accrual_rate > 0 accrue monthly via the leave-accrual cron. See Leave-Accruals.

PDF certificate

On approval a PDF is generated with pdfkit and emailed to the worker via Resend. The template carries the company name, the employee name, the leave type, the dates, the approver name, and a signature line. The same PDF is available on demand from /api/leave-pdf/[id].

Data shape

leave_requests(id, user_id, leave_type, start_date, end_date, days, status, approvers JSONB, current_approver_index, approver_status JSONB, created_at). leave_balances(user_id, leave_type, year, entitlement, used, carry_forward, max_carry_forward, accrual_rate, accrued_to_date, last_accrued_on).

Clone this wiki locally