Approval Workflow Example
Multi-level approval chain demonstrating conditional branching and memory-informed thresholds.
Overview
This example shows:
- Multi-step approval chain (initial → manager → director)
- Conditional branching based on decisions
- Memory-informed approval thresholds
- Workflow state management
Code
import { Workflow } from "@mdwr/sdk";
const approvalWorkflow = Workflow.create("approval_v1")
.step("initial_review", async (ctx) => {
const { documentType, amount, urgency } = ctx.input;
// Query memory for similar approval decisions
const insights = await ctx.memory.similar({
situation: "approval_decision",
context: { documentType, amount, urgency }
});
let decision = "approve";
let reason = "Passed initial review";
let confidence = 0.7;
// Use historical insights
if (insights.length > 0) {
const best = insights[0];
if (best.outcome?.success) {
decision = best.decision.decision;
reason = `Based on similar case: ${best.decision.reason}`;
confidence = Math.min(0.95, (best.decision.confidence || 0.7) + 0.1);
}
}
// Business rules
if (amount > 10000) {
decision = "requires_manager";
reason = "Amount exceeds automatic approval limit";
confidence = 0.9;
}
if (urgency === "high" && amount < 5000) {
decision = "approve";
reason = "High urgency, low amount - fast track";
confidence = 0.85;
}
return { decision, reason, confidence };
}, true)
.step("manager_review", async (ctx) => {
// Only runs if manager review required
if (ctx.state.initial_review?.decision !== "requires_manager") {
return { decision: "skip", reason: "Manager review not required", confidence: 1.0 };
}
const { managerId, amount } = ctx.input;
// Query memory for manager decisions
const insights = await ctx.memory.similar({
situation: "manager_approval",
context: { managerId, amount }
});
let decision = "approve";
let reason = "Manager approved";
let confidence = 0.8;
if (insights.length > 0) {
const best = insights[0];
decision = best.decision.decision;
reason = `Manager decision based on history: ${best.decision.reason}`;
confidence = best.decision.confidence || 0.8;
}
// Manager-specific rules
if (amount > 50000) {
decision = "requires_director";
reason = "Amount exceeds manager approval limit";
confidence = 0.9;
}
return { decision, reason, confidence };
}, true)
.step("director_review", async (ctx) => {
// Only runs if director review required
if (ctx.state.manager_review?.decision !== "requires_director") {
return { decision: "skip", reason: "Director review not required", confidence: 1.0 };
}
const { directorId, amount } = ctx.input;
// Query memory for director decisions
const insights = await ctx.memory.similar({
situation: "director_approval",
context: { directorId, amount }
});
let decision = "approve";
let reason = "Director approved";
let confidence = 0.85;
if (insights.length > 0) {
const best = insights[0];
decision = best.decision.decision;
reason = `Director decision: ${best.decision.reason}`;
confidence = best.decision.confidence || 0.85;
}
return { decision, reason, confidence };
}, true)
.step("finalize_approval", async (ctx) => {
// Determine final status based on all reviews
const initialDecision = ctx.state.initial_review?.decision;
const managerDecision = ctx.state.manager_review?.decision;
const directorDecision = ctx.state.director_review?.decision;
let finalStatus = "pending";
let reason = "Approval pending";
if (initialDecision === "approve") {
finalStatus = "approved";
reason = "Approved in initial review";
} else if (managerDecision === "approve") {
finalStatus = "approved";
reason = "Approved by manager";
} else if (directorDecision === "approve") {
finalStatus = "approved";
reason = "Approved by director";
} else if (directorDecision === "reject" || managerDecision === "reject" || initialDecision === "reject") {
finalStatus = "rejected";
reason = "Rejected in review process";
}
return {
decision: finalStatus === "approved" ? "success" : "failed",
reason,
confidence: 1.0,
metadata: {
finalStatus,
approvalChain: {
initial: initialDecision,
manager: managerDecision,
director: directorDecision
}
}
};
}, true);
export default approvalWorkflow;
Running the Example
# Deploy the workflow
npx ts-node scripts/deploy.ts
# Execute with sample input
npx ts-node scripts/execute.ts approval_v1
Input Example
{
"documentType": "expense",
"amount": 5000,
"urgency": "normal",
"managerId": "mgr123",
"directorId": "dir456"
}
Key Features
Multi-Level Approval Chain
initial_review → manager_review → director_review → finalize_approval
Conditional Branching
// Manager review only if required
if (ctx.state.initial_review?.decision !== "requires_manager") {
return { decision: "skip", reason: "...", confidence: 1.0 };
}
Memory-Informed Thresholds
const insights = await ctx.memory.similar({
situation: "approval_decision",
context: { documentType, amount, urgency }
});
Use Cases
- Document approval workflows
- Expense approval systems
- Content review processes
- Purchase order approvals
Next Steps
- Order Processing - E-commerce workflow
- Creating Workflows - Learn more patterns
- Examples Index - View all examples