Approval workflows
Configure multi-step approval chains for any request type — leave, expense, loan, travel, custom forms.
Concepts
- Policy — one chain per request type. Multiple policies allowed; criteria (amount, department) decide which fires.
- Step — ordered approver. Picks who: Reporting manager / Department head / HR Admin (any) / Payroll Admin (any) / Specific user. Optional SLA in hours.
- Request — created when an employee submits. Lives at
currentStepOrder; advances on each approve until final. - Action — every approve/reject/comment with actor + timestamp, never edited.
Typical chains
- Leave: Reporting manager → HR Admin
- Reimbursement < ₹5k: HR Admin only (single step)
- Reimbursement ≥ ₹5k: Reporting manager → Department head → Payroll Admin
- Loan / advance: Reporting manager → HR Admin → Specific user (CFO)
- Travel approval: Department head → HR Admin
How approvers act
- Approver opens /admin/approvals → My queue.
- For each row, click Approve (advances to next step) or Reject with optional reason (ends the request).
- Requester is notified on final approve / any reject.
- Comments don't advance the chain — useful for back-and-forth without final decision.
API integration (for module authors)
// When the employee submits, ask the engine to start a chain:
await approvals.createRequest({
companyId, objectType: "REIMBURSEMENT", objectId: claim.id,
requestedById: user.sub,
summary: { amount, currency, category }, // shown in queue
amount, departmentId, // used for policy match
});
// Before letting the requester edit/cancel, check current status:
const r = await approvals.getStatusByObject(companyId, "REIMBURSEMENT", id);
if (r?.status === "APPROVED") block();