Maker submit → threshold check → PENDING_APPROVAL → checker → অনুমোদন/প্রত্যাখ্যান। থ্রেশহোল্ড (BDT): বুকিং 200K, রিফান্ড 100K, ক্রেডিট লিমিট 500K, JE 50K, পেআউট 1M, সরবরাহকারী ব্যাঙ্ক পরিবর্তন (সর্বদা)।
Chapter 13.5 — Approval Workflows
Context
Many operations require a second pair of eyes beyond the initiating user — the maker-checker pattern. This chapter visualises the approval workflow as it applies across the platform: bookings over threshold, refunds over threshold, credit-limit changes, supplier bank-detail changes, journal entries above threshold, payouts, period close, and write-offs.
Text definitions of specific thresholds live in the respective module chapters; this chapter shows the common workflow shape.
Roles
| Role | Involvement |
|---|---|
| Initiator (Maker) | Creates the request |
| Approver (Checker) | Reviews and decides |
| Notifier | System — surfaces request to approver |
| Auditor | Reviews after-the-fact via audit log |
Core invariants
- Maker ≠ Checker. The same user cannot both create and approve.
- Reason required. Both maker and approver capture free-text reasons.
- Threshold-driven entry. Below threshold → auto-approved (no human approver); at or above → workflow.
- Time-bound. Requests expire after a configurable TTL.
- Audit trail mandatory. Every state change goes to the audit log.
Generic state machine
Generic sequence
Threshold examples
The platform's partner_approval_thresholds table defines per-partner thresholds. Examples (BDT):
| Operation | Default threshold | Approver role |
|---|---|---|
| Single booking | 200,000 | Mid-Office Supervisor |
| Single refund | 100,000 | Mid-Office Supervisor |
| Customer credit-limit increase | 500,000 | Controller |
| Supplier bank-detail change | (any) | Controller |
| Manual journal entry | 50,000 | Accountant Supervisor |
| Payout | 1,000,000 | Treasurer |
| Period close | (any) | Controller |
| Write-off | 25,000 | Controller |
Thresholds can be tiered: - 200K–500K → Supervisor. - 500K–2M → Controller. - > 2M → Controller + Director.
Multi-step approval supported.
Specific approval flows
Booking over threshold
Refund approval
Identical shape; approver_role often differs (refund-specific approver).
Customer credit-limit change
Supplier bank-detail change
Special case: always requires approval regardless of amount, due to vendor-fraud risk (Chapter 3.2). Additional control: 30-minute payout hold post-approval.
Journal entry over threshold
Payout
Cash leaves the platform; always approver-gated above small thresholds.
Period close
The close operation itself requires maker-checker (Chapter 5.10).
Approver eligibility
The system computes eligible approvers from: - Role membership matching the required approver role. - Active (not on leave). - Not the maker. - Has access to the resource (branch / partner scope).
If no eligible approver exists, the request raises a configuration alert (often during onboarding, before any approver is assigned).
Delegation & escalation
- Delegation: an approver can delegate to a named alternative for a time window.
- Escalation: if no decision in (configurable) hours, escalate to a higher tier.
- Pull-back: approvers can re-assign requests within the eligible pool.
SLA
- Default response SLA: 4 business hours during partner business hours.
- Configurable per request type.
- SLA breach triggers escalation + dashboard flag.
Approval bypass / emergency
For genuine emergencies (e.g., need to issue a critical ticket immediately):
- An emergency override path exists for partner_admin role.
- Override creates a partner_emergency_override record with extended audit (witness user, justification, post-hoc review).
- All overrides reviewed weekly by controller.
- Excessive overrides trigger policy review.
Database tables touched
| Table | Role |
|---|---|
approval_requests |
Header per request |
approval_decisions |
Per-decision audit |
partner_approval_thresholds |
Configuration |
audit_logs |
Every transition |
notifications |
Approver alerts |
Common pitfalls
- ⚠️ Same user as maker and checker via role-juggling. Engine enforces by user-id identity.
- ⚠️ Approver auto-approving without reading payload. UX shows full diff; reason field forces engagement.
- ⚠️ Stale thresholds. Review annually; inflation drifts thresholds.
- ⚠️ No eligible approver configured. Catch at onboarding.
- 🔒 Approval-flow bypass attempts are themselves audited; suspicious patterns trigger security review.