A human-in-the-loop expense approval workflow built with AWS Lambda Durable Execution — no Step Functions, no DynamoDB, no SQS. Just TypeScript.
Companion code for the Medium article "Is Step Functions Still Necessary? The Case for Lambda Durable Functions in 2026"
POST /expenses→ Orchestrator starts a Durable Worker, which pauses atwaitForCallbackand sends an approval emailPOST /approve?callbackId=xxx→ Orchestrator callsSendDurableExecutionCallbackSuccess→ Worker resumes and finalizes
├── lib/
│ └── durable-approval-stack.ts # CDK stack
├── lambda/
│ ├── worker.ts # Durable workflow (pauses, resumes)
│ └── orchestrator.ts # API router
└── cdk.json
Prerequisites: Node.js 20+, AWS CDK v2, AWS CLI configured
npm install
cdk bootstrap # first time only
cdk deployThen submit an expense:
curl -X POST https://<api-url>/expenses \
-H "Content-Type: application/json" \
-d '{ "expenseId": "exp-001", "amount": 450, "submittedBy": "alice@example.com" }'And approve it:
curl -X POST "https://<api-url>/approve?callbackId=<id>"MIT