Approval Workflows
Human-in-the-loop approval workflows using signals. A workflow pauses at an approval step and resumes when a human sends an approve or reject signal.
Prerequisites: Workflows, Durable Execution. What you'll learn: How to build workflows that wait for human decisions.
The Pattern
- A workflow reaches an approval node
- The node signals and waits for a response
- A human reviews and sends an approve or reject signal
- The workflow resumes and branches based on the decision
Example: Expense Approval
workflow approve_expense v1 {
node validate = validate_expense v1
node notify = notify_approver v1
node wait = wait_for_approval v1
node approved = process_approved v1
node rejected = process_rejected v1
edge validate -> notify
edge notify -> wait
edge wait -> approved
edge wait -> rejected
}
activity wait_for_approval v1 {
data decision {
signal approval_decision {
timeout: 7d
}
}
apply(input: ApprovalInput) -> ApprovalDecision {
return {
approved: decision.approved,
reason: decision.reason
}
}
}
Sending the Signal
External systems (UI, API, email handler) send the signal to resume the workflow:
# Approve
curl -X POST 'http://localhost:3000/api/signal/approval_decision' \
-H 'content-type: application/json' \
-d '{"workflow_id": "exp-123", "approved": true, "reason": "Within budget"}'
# Reject
curl -X POST 'http://localhost:3000/api/signal/approval_decision' \
-H 'content-type: application/json' \
-d '{"workflow_id": "exp-123", "approved": false, "reason": "Over budget limit"}'
Timeout Handling
If no signal arrives within the timeout period, the activity fails. Use compensation or a default branch to handle timeouts:
activity wait_for_approval v1 {
data decision {
signal approval_decision {
timeout: 7d
}
}
apply(input: ApprovalInput) -> ApprovalDecision {
return {
approved: decision.approved ?? false,
reason: decision.reason ?? "Timed out - auto-rejected"
}
}
retry_policy {
max_attempts: 1
}
}
See Also
- Durable Execution -- Signals and sleep
- Compensation & Sagas -- Handling failures
- Scheduled Data Sync -- Another workflow pattern