Workflow Automation Services
Build multi-step workflow automation services with conditional logic, parallel execution, error handling, and orchestration
Build sophisticated multi-step workflow automation services that orchestrate complex business processes with conditional branching, parallel execution, error handling, and state management.
Overview
Workflow automation services coordinate multiple steps into cohesive processes that run automatically. They're ideal for:
- Order Fulfillment: Process orders from validation to shipping
- Customer Onboarding: Guide new users through setup steps
- Approval Workflows: Route requests through approval chains
- Document Processing: Extract, validate, and route documents
- Employee Onboarding: Automate HR processes
- Issue Resolution: Automated troubleshooting and remediation
Core Concepts
Workflow Components
import $, { db, on, send } from 'sdk.do'
// Define workflow structure
const orderFulfillmentWorkflow = await $.Service.create({
name: 'Order Fulfillment Automation',
type: $.ServiceType.Automation,
subtype: 'workflow',
// Define workflow steps
steps: [
{
id: 'validate',
name: 'Validate Order',
type: 'function',
required: true,
timeout: 5000,
retryPolicy: { maxAttempts: 3, backoff: 'exponential' },
},
{
id: 'payment',
name: 'Process Payment',
type: 'function',
required: true,
timeout: 30000,
dependsOn: ['validate'],
},
{
id: 'inventory',
name: 'Reserve Inventory',
type: 'parallel',
required: true,
dependsOn: ['payment'],
steps: [
{ id: 'check-stock', name: 'Check Stock' },
{ id: 'reserve', name: 'Reserve Items' },
],
},
{
id: 'shipping',
name: 'Schedule Shipping',
type: 'function',
required: true,
dependsOn: ['inventory'],
},
{
id: 'notification',
name: 'Send Confirmation',
type: 'function',
required: false,
dependsOn: ['shipping'],
},
],
// Pricing model
pricing: {
model: 'per-execution',
baseRate: 0.5,
stepRates: {
payment: 0.2,
shipping: 0.15,
notification: 0.05,
},
},
})Building a Complete Workflow Service
Basic Workflow Execution
// Execute workflow with sequential steps
on.ServiceRequest.created(async (request) => {
if (request.serviceId !== orderFulfillmentWorkflow.id) return
const workflowState = {
requestId: request.id,
currentStep: null,
completedSteps: [],
results: {},
context: request.inputs,
}
try {
for (const step of orderFulfillmentWorkflow.steps) {
// Check dependencies
if (step.dependsOn) {
const dependenciesMet = step.dependsOn.every((dep) => workflowState.completedSteps.includes(dep))
if (!dependenciesMet) {
throw new Error(`Dependencies not met for step: ${step.id}`)
}
}
// Update current step
workflowState.currentStep = step.id
await send.WorkflowProgress.updated({
requestId: request.id,
currentStep: step.id,
completedSteps: workflowState.completedSteps,
})
// Execute step
const result = await executeStep(step, workflowState)
// Store result
workflowState.results[step.id] = result
workflowState.completedSteps.push(step.id)
// Pass results to context for next steps
workflowState.context = {
...workflowState.context,
...result,
}
}
// Workflow complete
await send.ServiceResult.deliver({
requestId: request.id,
outputs: {
success: true,
results: workflowState.results,
completedSteps: workflowState.completedSteps,
},
})
// Calculate and charge
const cost = calculateWorkflowCost(orderFulfillmentWorkflow, workflowState.completedSteps)
await send.Payment.charge({
customerId: request.customerId,
amount: cost,
description: 'Order Fulfillment Workflow',
})
} catch (error) {
await send.ServiceRequest.fail({
requestId: request.id,
error: error.message,
failedStep: workflowState.currentStep,
completedSteps: workflowState.completedSteps,
partialResults: workflowState.results,
})
}
})
// Execute individual step
async function executeStep(step: any, state: any) {
switch (step.type) {
case 'function':
return await executeFunction(step, state)
case 'parallel':
return await executeParallel(step, state)
case 'condition':
return await executeCondition(step, state)
default:
throw new Error(`Unknown step type: ${step.type}`)
}
}Conditional Branching Workflows
// Customer onboarding with conditional paths
const onboardingWorkflow = await $.Service.create({
name: 'Customer Onboarding',
type: $.ServiceType.Automation,
subtype: 'workflow',
steps: [
{
id: 'profile',
name: 'Create Profile',
type: 'function',
required: true,
},
{
id: 'verify-identity',
name: 'Identity Verification',
type: 'condition',
required: true,
dependsOn: ['profile'],
condition: 'inputs.accountType === "business"',
then: {
id: 'business-verification',
name: 'Business Verification',
type: 'function',
},
else: {
id: 'personal-verification',
name: 'Personal Verification',
type: 'function',
},
},
{
id: 'setup-features',
name: 'Setup Features',
type: 'condition',
dependsOn: ['verify-identity'],
condition: 'results["verify-identity"].verified === true',
then: {
id: 'enable-all-features',
type: 'parallel',
steps: [
{ id: 'api-access', name: 'Enable API Access' },
{ id: 'integrations', name: 'Setup Integrations' },
{ id: 'team-invite', name: 'Invite Team Members' },
],
},
else: {
id: 'limited-access',
name: 'Enable Basic Features',
type: 'function',
},
},
{
id: 'send-welcome',
name: 'Send Welcome Email',
type: 'function',
required: false,
dependsOn: ['setup-features'],
},
],
pricing: {
model: 'per-execution',
rate: 1.0,
},
})
// Execute conditional workflow
on.ServiceRequest.created(async (request) => {
if (request.serviceId !== onboardingWorkflow.id) return
const state = {
requestId: request.id,
inputs: request.inputs,
results: {},
completedSteps: [],
}
try {
for (const step of onboardingWorkflow.steps) {
const shouldExecute = await evaluateStepCondition(step, state)
if (!shouldExecute && step.required) {
throw new Error(`Required step skipped: ${step.id}`)
}
if (shouldExecute) {
if (step.type === 'condition') {
// Evaluate condition
const conditionMet = await evaluateCondition(step.condition, state)
// Execute appropriate branch
const branch = conditionMet ? step.then : step.else
if (branch) {
const result = await executeStep(branch, state)
state.results[step.id] = { branch: conditionMet ? 'then' : 'else', result }
}
} else {
const result = await executeStep(step, state)
state.results[step.id] = result
}
state.completedSteps.push(step.id)
}
}
await send.ServiceResult.deliver({
requestId: request.id,
outputs: {
success: true,
results: state.results,
path: determinePath(state.results),
},
})
} catch (error) {
await handleWorkflowError(error, state)
}
})
// Evaluate condition dynamically
async function evaluateCondition(condition: string, state: any): Promise<boolean> {
try {
// Create safe evaluation context
const context = {
inputs: state.inputs,
results: state.results,
completedSteps: state.completedSteps,
}
// Safe evaluation (in production, use a proper expression evaluator)
const func = new Function('ctx', `with(ctx) { return ${condition} }`)
return func(context)
} catch {
return false
}
}Parallel Execution Workflows
// Content production with parallel tasks
const contentProductionWorkflow = await $.Service.create({
name: 'Content Production Pipeline',
type: $.ServiceType.Automation,
subtype: 'workflow',
steps: [
{
id: 'research',
name: 'Topic Research',
type: 'function',
required: true,
timeout: 120000, // 2 minutes
},
{
id: 'create-assets',
name: 'Create Content Assets',
type: 'parallel',
required: true,
dependsOn: ['research'],
strategy: 'all', // wait for all, or 'any', 'first'
steps: [
{
id: 'write-article',
name: 'Write Article',
type: 'function',
timeout: 300000, // 5 minutes
},
{
id: 'generate-images',
name: 'Generate Images',
type: 'function',
timeout: 180000, // 3 minutes
},
{
id: 'create-social',
name: 'Create Social Posts',
type: 'function',
timeout: 120000, // 2 minutes
},
{
id: 'record-video',
name: 'Generate Video Script',
type: 'function',
timeout: 240000, // 4 minutes
},
],
},
{
id: 'quality-check',
name: 'Quality Assurance',
type: 'parallel',
required: true,
dependsOn: ['create-assets'],
steps: [
{
id: 'grammar-check',
name: 'Grammar Check',
type: 'function',
},
{
id: 'seo-check',
name: 'SEO Analysis',
type: 'function',
},
{
id: 'plagiarism-check',
name: 'Plagiarism Check',
type: 'function',
},
],
},
{
id: 'publish',
name: 'Publish Content',
type: 'function',
required: true,
dependsOn: ['quality-check'],
},
],
pricing: {
model: 'per-execution',
baseRate: 50.0,
parallelDiscount: 0.1, // 10% discount for parallel execution efficiency
},
})
// Execute parallel workflows
async function executeParallel(step: any, state: any) {
const promises = step.steps.map(async (substep: any) => {
try {
const result = await executeStep(substep, state)
return {
id: substep.id,
success: true,
result,
}
} catch (error) {
return {
id: substep.id,
success: false,
error: error.message,
}
}
})
// Execute based on strategy
switch (step.strategy) {
case 'all':
// Wait for all steps to complete
const results = await Promise.all(promises)
// Check if any failed
const failures = results.filter((r) => !r.success)
if (failures.length > 0 && step.required) {
throw new Error(`Parallel steps failed: ${failures.map((f) => f.id).join(', ')}`)
}
return {
strategy: 'all',
results,
successes: results.filter((r) => r.success).length,
failures: failures.length,
}
case 'any':
// Wait for at least one to succeed
const anyResult = await Promise.race(promises)
return {
strategy: 'any',
result: anyResult,
}
case 'first':
// Return first completed (success or failure)
const firstResult = await Promise.race(promises)
return {
strategy: 'first',
result: firstResult,
}
default:
return await Promise.all(promises)
}
}Advanced Error Handling
// Invoice processing with retry and compensation
const invoiceWorkflow = await $.Service.create({
name: 'Invoice Processing',
type: $.ServiceType.Automation,
subtype: 'workflow',
steps: [
{
id: 'extract',
name: 'Extract Invoice Data',
type: 'function',
required: true,
timeout: 30000,
retryPolicy: {
maxAttempts: 3,
backoff: 'exponential',
baseDelay: 1000,
maxDelay: 30000,
},
onError: 'retry',
},
{
id: 'validate',
name: 'Validate Invoice',
type: 'function',
required: true,
timeout: 10000,
retryPolicy: {
maxAttempts: 2,
backoff: 'linear',
baseDelay: 2000,
},
onError: 'human-review', // Escalate to human
},
{
id: 'approve',
name: 'Get Approval',
type: 'function',
required: true,
timeout: 300000, // 5 minutes for approval
onError: 'notify-manager',
},
{
id: 'process-payment',
name: 'Process Payment',
type: 'function',
required: true,
dependsOn: ['approve'],
timeout: 60000,
retryPolicy: {
maxAttempts: 3,
backoff: 'exponential',
baseDelay: 5000,
},
onError: 'rollback',
compensation: {
// If payment fails, reverse approval
steps: [
{ action: 'reverse-approval', stepId: 'approve' },
{ action: 'notify-failure', params: { reason: 'payment-failed' } },
],
},
},
{
id: 'update-accounting',
name: 'Update Accounting System',
type: 'function',
required: true,
dependsOn: ['process-payment'],
timeout: 30000,
onError: 'log-and-continue', // Non-critical, can be retried later
},
{
id: 'notify-completion',
name: 'Send Completion Notice',
type: 'function',
required: false,
dependsOn: ['update-accounting'],
},
],
// Global error handling
errorHandling: {
defaultRetryPolicy: {
maxAttempts: 2,
backoff: 'exponential',
baseDelay: 1000,
},
compensationStrategy: 'reverse-order', // Undo in reverse
notifyOnFailure: true,
},
pricing: {
model: 'per-execution',
rate: 2.0,
failureRefund: 1.0, // Partial refund on failure
},
})
// Execute with advanced error handling
on.ServiceRequest.created(async (request) => {
if (request.serviceId !== invoiceWorkflow.id) return
const state = {
requestId: request.id,
inputs: request.inputs,
results: {},
completedSteps: [],
failedSteps: [],
compensations: [],
}
try {
for (const step of invoiceWorkflow.steps) {
let result
let attempts = 0
const maxAttempts = step.retryPolicy?.maxAttempts || 1
while (attempts < maxAttempts) {
try {
result = await executeStepWithTimeout(step, state)
break // Success
} catch (error) {
attempts++
if (attempts >= maxAttempts) {
// Max attempts reached
await handleStepFailure(step, error, state)
if (step.required) {
throw error // Fail workflow
}
break // Continue to next step
}
// Wait before retry
const delay = calculateRetryDelay(
attempts,
step.retryPolicy?.backoff || 'exponential',
step.retryPolicy?.baseDelay || 1000,
step.retryPolicy?.maxDelay || 30000
)
await new Promise((resolve) => setTimeout(resolve, delay))
}
}
if (result) {
state.results[step.id] = result
state.completedSteps.push(step.id)
} else {
state.failedSteps.push(step.id)
}
}
// Workflow completed (successfully or partially)
await send.ServiceResult.deliver({
requestId: request.id,
outputs: {
success: state.failedSteps.length === 0,
results: state.results,
completedSteps: state.completedSteps,
failedSteps: state.failedSteps,
},
})
// Charge based on completion
const cost = state.failedSteps.length > 0 ? invoiceWorkflow.pricing.failureRefund : invoiceWorkflow.pricing.rate
await send.Payment.charge({
customerId: request.customerId,
amount: cost,
description: `Invoice Processing - ${state.completedSteps.length} steps completed`,
})
} catch (error) {
// Critical failure - execute compensations
await executeCompensations(state)
await send.ServiceRequest.fail({
requestId: request.id,
error: error.message,
failedStep: state.failedSteps[state.failedSteps.length - 1],
compensations: state.compensations,
})
}
})
// Execute compensation actions
async function executeCompensations(state: any) {
// Get steps that need compensation (in reverse order)
const stepsToCompensate = [...state.completedSteps].reverse()
for (const stepId of stepsToCompensate) {
const step = invoiceWorkflow.steps.find((s) => s.id === stepId)
if (step?.compensation) {
try {
for (const compensationAction of step.compensation.steps) {
await executeCompensationAction(compensationAction, state)
state.compensations.push({
step: stepId,
action: compensationAction.action,
success: true,
})
}
} catch (error) {
state.compensations.push({
step: stepId,
action: 'compensation',
success: false,
error: error.message,
})
}
}
}
}
// Calculate retry delay with backoff
function calculateRetryDelay(attempt: number, backoff: string, baseDelay: number, maxDelay: number): number {
let delay: number
switch (backoff) {
case 'exponential':
delay = baseDelay * Math.pow(2, attempt - 1)
break
case 'linear':
delay = baseDelay * attempt
break
case 'constant':
delay = baseDelay
break
default:
delay = baseDelay
}
return Math.min(delay, maxDelay)
}Human-in-the-Loop Workflows
// Expense approval workflow with human review
const expenseApprovalWorkflow = await $.Service.create({
name: 'Expense Approval Workflow',
type: $.ServiceType.Automation,
subtype: 'workflow',
steps: [
{
id: 'extract',
name: 'Extract Expense Data',
type: 'function',
required: true,
},
{
id: 'policy-check',
name: 'Check Against Policy',
type: 'function',
required: true,
dependsOn: ['extract'],
},
{
id: 'approval-routing',
name: 'Route for Approval',
type: 'condition',
required: true,
dependsOn: ['policy-check'],
condition: 'results["policy-check"].autoApprove === true',
then: {
id: 'auto-approve',
name: 'Auto Approve',
type: 'function',
},
else: {
id: 'human-approval',
name: 'Human Approval Required',
type: 'human-task',
timeout: 86400000, // 24 hours
assignTo: 'results["policy-check"].approver',
escalationPolicy: {
timeout: 43200000, // 12 hours
escalateTo: 'manager',
},
},
},
{
id: 'process',
name: 'Process Expense',
type: 'function',
required: true,
dependsOn: ['approval-routing'],
},
],
pricing: {
model: 'per-execution',
rates: {
automated: 0.25,
humanReview: 1.0,
},
},
})
// Handle human tasks
on.HumanTask.created(async (task) => {
// Notify assigned user
await send.Notification.send({
userId: task.assignedTo,
type: 'approval-required',
data: {
taskId: task.id,
workflowId: task.workflowId,
requestId: task.requestId,
details: task.details,
dueDate: new Date(Date.now() + task.timeout),
},
})
// Set up escalation timer
if (task.escalationPolicy) {
setTimeout(async () => {
const currentTask = await db.HumanTask.get({ id: task.id })
if (currentTask.status === 'pending') {
await send.HumanTask.escalate({
taskId: task.id,
escalateTo: task.escalationPolicy.escalateTo,
reason: 'timeout',
})
}
}, task.escalationPolicy.timeout)
}
})
// Resume workflow after human task completion
on.HumanTask.completed(async (task) => {
// Update workflow state
const workflowState = await db.WorkflowState.get({
requestId: task.requestId,
})
// Store human task result
workflowState.results[task.stepId] = {
approved: task.decision === 'approved',
decision: task.decision,
comments: task.comments,
reviewedBy: task.completedBy,
reviewedAt: task.completedAt,
}
// Mark step as completed
workflowState.completedSteps.push(task.stepId)
await db.update(workflowState, workflowState)
// Resume workflow execution
await send.Workflow.resume({
requestId: task.requestId,
stepId: task.stepId,
result: workflowState.results[task.stepId],
})
})Workflow Orchestration Patterns
State Machine Workflows
// Order state machine
const orderStateMachine = await $.Service.create({
name: 'Order State Machine',
type: $.ServiceType.Automation,
subtype: 'state-machine',
states: {
pending: {
on: {
VALIDATE: 'validating',
CANCEL: 'cancelled',
},
},
validating: {
on: {
VALIDATION_SUCCESS: 'validated',
VALIDATION_FAILED: 'validation-failed',
},
timeout: 30000,
timeoutTransition: 'validation-failed',
},
validated: {
on: {
PROCESS_PAYMENT: 'processing-payment',
},
},
'processing-payment': {
on: {
PAYMENT_SUCCESS: 'paid',
PAYMENT_FAILED: 'payment-failed',
},
retry: {
maxAttempts: 3,
on: 'PAYMENT_FAILED',
},
},
paid: {
on: {
FULFILL: 'fulfilling',
},
},
fulfilling: {
on: {
SHIPPED: 'shipped',
FULFILLMENT_FAILED: 'fulfillment-failed',
},
},
shipped: {
on: {
DELIVERED: 'delivered',
RETURN_REQUESTED: 'returning',
},
},
delivered: {
terminal: true,
},
cancelled: {
terminal: true,
},
'validation-failed': {
terminal: true,
},
'payment-failed': {
terminal: true,
},
'fulfillment-failed': {
on: {
RETRY: 'fulfilling',
},
},
},
initialState: 'pending',
})
// State machine execution
class StateMachineExecutor {
async execute(machine: any, initialContext: any) {
let currentState = machine.initialState
const context = { ...initialContext }
const history = []
while (true) {
const state = machine.states[currentState]
// Check if terminal state
if (state.terminal) {
break
}
// Execute state entry actions
if (state.onEntry) {
await this.executeActions(state.onEntry, context)
}
// Wait for event or timeout
const event = await this.waitForEvent(state, context)
// Record transition
history.push({
from: currentState,
event: event.type,
at: new Date(),
})
// Transition to next state
const nextState = state.on[event.type]
if (!nextState) {
throw new Error(`No transition for event ${event.type} in state ${currentState}`)
}
// Execute state exit actions
if (state.onExit) {
await this.executeActions(state.onExit, context)
}
currentState = nextState
// Update context with event data
Object.assign(context, event.data)
}
return {
finalState: currentState,
history,
context,
}
}
async waitForEvent(state: any, context: any) {
// Implement event waiting logic
// Could use event emitters, message queues, etc.
return new Promise((resolve) => {
// Wait for next event or timeout
})
}
async executeActions(actions: any[], context: any) {
for (const action of actions) {
await this.executeAction(action, context)
}
}
async executeAction(action: any, context: any) {
// Execute action based on type
switch (action.type) {
case 'function':
return await action.handler(context)
case 'emit':
return await send(action.event, context)
default:
throw new Error(`Unknown action type: ${action.type}`)
}
}
}Pricing Models for Workflows
Per-Execution Pricing
const workflow = await $.Service.create({
name: 'Document Processing',
pricing: {
model: 'per-execution',
baseRate: 0.5, // Base cost per execution
stepRates: {
ocr: 0.25,
classify: 0.1,
extract: 0.15,
validate: 0.05,
},
discounts: {
volume: [
{ min: 100, max: 1000, discount: 0.1 },
{ min: 1001, max: 10000, discount: 0.2 },
{ min: 10001, max: Infinity, discount: 0.3 },
],
},
},
})
// Calculate execution cost
function calculateExecutionCost(workflow: any, completedSteps: string[], volume: number) {
let cost = workflow.pricing.baseRate
// Add step costs
for (const stepId of completedSteps) {
const stepCost = workflow.pricing.stepRates[stepId] || 0
cost += stepCost
}
// Apply volume discount
const discount = workflow.pricing.discounts.volume.find((tier) => volume >= tier.min && volume <= tier.max)
if (discount) {
cost *= 1 - discount.discount
}
return cost
}Time-Based Pricing
const workflow = await $.Service.create({
name: 'Video Processing Pipeline',
pricing: {
model: 'time-based',
rate: 0.1, // Per second
minimum: 1.0,
maximum: 100.0,
stepMultipliers: {
transcode: 1.5,
analyze: 1.2,
'generate-thumbnails': 0.8,
},
},
})
// Calculate time-based cost
function calculateTimeCost(workflow: any, execution: any) {
const durationSeconds = (execution.endTime - execution.startTime) / 1000
let cost = durationSeconds * workflow.pricing.rate
// Apply step multipliers
for (const [stepId, duration] of Object.entries(execution.stepDurations)) {
const multiplier = workflow.pricing.stepMultipliers[stepId] || 1.0
cost += ((duration as number) / 1000) * workflow.pricing.rate * (multiplier - 1.0)
}
// Apply bounds
cost = Math.max(cost, workflow.pricing.minimum)
cost = Math.min(cost, workflow.pricing.maximum)
return cost
}Best Practices
1. Idempotency
Ensure workflows can be safely retried:
on.ServiceRequest.created(async (request) => {
// Check for existing execution
const existing = await db.WorkflowExecution.get({
requestId: request.id,
})
if (existing) {
if (existing.status === 'completed') {
// Return cached result
return await send.ServiceResult.deliver({
requestId: request.id,
outputs: existing.result,
cached: true,
})
} else if (existing.status === 'running') {
// Return execution status
return await send.ServiceProgress.status({
requestId: request.id,
status: 'running',
currentStep: existing.currentStep,
})
}
}
// Start new execution
const execution = await db.create($.WorkflowExecution, {
requestId: request.id,
status: 'running',
startedAt: new Date(),
})
// Execute workflow...
})2. Progress Tracking
Keep users informed of workflow progress:
// Real-time progress updates
async function updateWorkflowProgress(requestId: string, step: any, state: any) {
const totalSteps = state.workflow.steps.length
const completedSteps = state.completedSteps.length
const progress = completedSteps / totalSteps
await send.WorkflowProgress.updated({
requestId,
currentStep: step.id,
currentStepName: step.name,
completedSteps: state.completedSteps,
totalSteps,
progress,
estimatedTimeRemaining: estimateTimeRemaining(state),
})
}3. Error Recovery
Implement robust error handling:
// Checkpoint workflow state
async function checkpointWorkflowState(state: any) {
await db.upsert($.WorkflowCheckpoint, {
where: { requestId: state.requestId },
data: {
requestId: state.requestId,
currentStep: state.currentStep,
completedSteps: state.completedSteps,
results: state.results,
context: state.context,
checkpointedAt: new Date(),
},
})
}
// Resume from checkpoint
async function resumeFromCheckpoint(requestId: string) {
const checkpoint = await db.WorkflowCheckpoint.get({
requestId,
})
if (!checkpoint) {
throw new Error('No checkpoint found')
}
return {
requestId: checkpoint.requestId,
currentStep: checkpoint.currentStep,
completedSteps: checkpoint.completedSteps,
results: checkpoint.results,
context: checkpoint.context,
}
}Real-World Examples
Customer Support Ticket Workflow
const supportTicketWorkflow = await $.Service.create({
name: 'Support Ticket Routing',
steps: [
{ id: 'classify', name: 'Classify Ticket' },
{ id: 'priority', name: 'Assign Priority' },
{ id: 'route', name: 'Route to Team', type: 'condition' },
{ id: 'auto-respond', name: 'Auto Respond' },
{ id: 'monitor', name: 'Monitor Resolution' },
],
pricing: { model: 'per-execution', rate: 0.15 },
})E-commerce Order Fulfillment
const ecommerceWorkflow = await $.Service.create({
name: 'E-commerce Fulfillment',
steps: [
{ id: 'validate-order', name: 'Validate Order' },
{ id: 'check-inventory', name: 'Check Inventory' },
{ id: 'process-payment', name: 'Process Payment' },
{ id: 'pick-pack', name: 'Pick and Pack', type: 'parallel' },
{ id: 'ship', name: 'Ship Order' },
{ id: 'track', name: 'Track Shipment' },
{ id: 'confirm', name: 'Confirm Delivery' },
],
pricing: { model: 'per-execution', rate: 1.5 },
})Next Steps
- Data Pipeline Services → - ETL and data processing
- Business Process Automation → - Complete business processes
- Integration Services → - System orchestration
- Service Composition → - Combine services
- Monetization → - Pricing strategies
Integration Automation Services
Build services that orchestrate multi-system workflows, API choreography, event routing, service coordination, and cross-platform automation
Data Transformation Services
Build powerful data transformation services that convert, normalize, and cleanse data across formats and schemas