Workflow Patterns
This guide covers common workflow patterns and how to implement them in RocketWave Pulse.
Pattern 1: Linear Pipeline
The simplest pattern - events flow through nodes in sequence.
Event → Prompt → Action
Use Cases:
- Chatbots
- Simple content generation
- Data transformation and posting
workflowData Structure:
{
"nodes": {
"n1": { "entityType": "event", "name": "Entry Point", ... },
"n2": { "entityType": "prompt", "name": "Process", ... },
"n3": { "entityType": "action", "name": "Execute", ... }
},
"connectors": {
"c1": { "source": "n1", "target": "n2", "sourcePort": "out", "targetPort": "in" },
"c2": { "source": "n2", "target": "n3", "sourcePort": "out", "targetPort": "in" }
},
"workflow": {
"ref": "n1",
"children": [
{ "ref": "n2", "children": [
{ "ref": "n3", "children": [] }
]}
]
}
}
Pattern 2: True/False Branching
Route messages based on a condition evaluating to true or false.
┌─ [true] → Prompt → Action
Event ──┤
└─ [false] → (ignored or different processing)
Use Cases:
- Filter valid/invalid messages
- Premium vs free user handling
- Feature flag routing
Event Configuration:
- Set
tfConditionto"True/False" - The condition evaluation determines which branch executes
workflowData Structure:
{
"nodes": {
"n1": {
"entityId": "uuid",
"name": "Check Premium User",
"entityType": "event",
"tfCondition": "True/False",
"presentation": { "type": "circle", "position": { "x": 100, "y": 200 } }
},
"n2": {
"name": "true",
"entityType": "logic-branch",
"branchValue": "true",
"presentation": { "type": "logic-branch", "position": { "x": 300, "y": 100 } }
},
"n3": {
"name": "false",
"entityType": "logic-branch",
"branchValue": "false",
"presentation": { "type": "logic-branch", "position": { "x": 300, "y": 300 } }
},
"n4": {
"entityId": "uuid",
"name": "Premium Processing",
"entityType": "prompt",
"presentation": { "type": "brain", "position": { "x": 500, "y": 100 } }
}
},
"connectors": {
"c1": { "source": "n1", "target": "n2", "sourcePort": "out", "targetPort": "in" },
"c2": { "source": "n1", "target": "n3", "sourcePort": "out", "targetPort": "in" },
"c3": { "source": "n2", "target": "n4", "sourcePort": "out", "targetPort": "in" }
},
"workflow": {
"ref": "n1",
"children": [
{ "ref": "n2", "value": "true", "children": [
{ "ref": "n4", "children": [...] }
]},
{ "ref": "n3", "value": "false", "children": [] }
]
}
}
Key Points:
- Logic branch nodes have
entityType: "logic-branch"and abranchValue - The
workflowref tree must includevalueproperties on branch children - Both branches can connect to subsequent nodes or be left empty
Pattern 3: Multi-Value Routing
Route based on a specific field value (like a switch statement).
┌─ [admin] → Admin Handler
│
Event ────────┼─ [user] → User Handler
│
└─ [guest] → Guest Handler
Use Cases:
- Role-based processing
- Event type routing
- Category-specific handling
Event Configuration:
- Set
tfConditionto"Multi" - Set
logicFieldto the field to switch on (e.g.,"userRole")
workflowData Structure:
{
"nodes": {
"n1": {
"entityId": "uuid",
"name": "Route by Role",
"entityType": "event",
"tfCondition": "Multi",
"logicField": "userRole",
"presentation": { "type": "circle", "position": { "x": 100, "y": 250 } }
},
"n2": {
"name": "admin",
"entityType": "logic-branch",
"branchValue": "admin",
"presentation": { "type": "logic-branch", "position": { "x": 300, "y": 100 } }
},
"n3": {
"name": "user",
"entityType": "logic-branch",
"branchValue": "user",
"presentation": { "type": "logic-branch", "position": { "x": 300, "y": 250 } }
},
"n4": {
"name": "guest",
"entityType": "logic-branch",
"branchValue": "guest",
"presentation": { "type": "logic-branch", "position": { "x": 300, "y": 400 } }
}
},
"workflow": {
"ref": "n1",
"children": [
{ "ref": "n2", "value": "admin", "children": [...] },
{ "ref": "n3", "value": "user", "children": [...] },
{ "ref": "n4", "value": "guest", "children": [...] }
]
}
}
Pattern 3.5: Iterable Processing (Loop Pattern)
Process each item in an array field separately, repeating the workflow for each element.
┌─ iteration 1 → Prompt → Action
│
Event ──[array]─────┼─ iteration 2 → Prompt → Action
(Iterable) │
└─ iteration N → Prompt → Action
Use Cases:
- Batch notifications (send to multiple recipients)
- Processing list items (multiple products in an order)
- Multi-target publishing (post to multiple social accounts)
- Parallel-like execution over array data
Event Configuration:
- Set
tfConditionto"Iterable" - Set
logicFieldto the array field path (e.g.,"message.recipients")
workflowData Structure:
{
"nodes": {
"n1": {
"entityId": "uuid",
"name": "Process Each Order Item",
"entityType": "event",
"tfCondition": "Iterable",
"logicField": "message.items",
"presentation": { "type": "circle", "position": { "x": 100, "y": 200 } }
},
"n2": {
"entityId": "uuid",
"name": "Generate Item Description",
"entityType": "prompt",
"presentation": { "type": "brain", "position": { "x": 350, "y": 200 } }
},
"n3": {
"entityId": "uuid",
"name": "Store Item Result",
"entityType": "action",
"presentation": { "type": "star", "position": { "x": 600, "y": 200 } }
}
},
"connectors": {
"c1": { "source": "n1", "target": "n2", "sourcePort": "out", "targetPort": "in" },
"c2": { "source": "n2", "target": "n3", "sourcePort": "out", "targetPort": "in" }
},
"workflow": {
"ref": "n1",
"children": [
{ "ref": "n2", "children": [
{ "ref": "n3", "children": [] }
]}
]
}
}
Accessing Iterable Items:
In downstream scripts (Prompts, Actions), access the current item:
// Current iteration item
const currentItem = ___iterableItem___;
// Example: if iterating over message.recipients
const recipientEmail = currentItem.email;
const recipientName = currentItem.name;
print('Processing recipient:', recipientName);
Real-World Example: Multi-Recipient Notification
{
"name": "Send Team Notifications",
"tfCondition": "Iterable",
"logicField": "message.team.members",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{ "type": "rule", "field": "message.type", "comparison": "equals", "value": "announcement" }
]
}
}
Given this input message:
{
"type": "announcement",
"content": "Team meeting at 3pm",
"team": {
"members": [
{ "name": "Alice", "email": "alice@example.com" },
{ "name": "Bob", "email": "bob@example.com" },
{ "name": "Charlie", "email": "charlie@example.com" }
]
}
}
The workflow executes 3 times, once for each team member.
Pattern 4: Sequential Processing
Chain multiple AI calls or actions in sequence.
Event → Prompt (Summarize) → Prompt (Translate) → Action (Store)
Use Cases:
- Multi-step AI processing
- Data enrichment pipelines
- Content moderation + generation
Accessing Previous Responses:
// In Action script after multiple prompts
const firstResponse = await getPromptResponse(1); // First prompt result
const secondResponse = await getPromptResponse(2); // Second prompt result
const latestResponse = await latestPromptResponse(); // Same as getPromptResponse(2)
print('Summary:', firstResponse);
print('Translation:', secondResponse);
Pattern 5: Fan-Out / Parallel (via Multiple Connectors)
Process the same event through multiple branches simultaneously.
┌─ Action (Post to Twitter)
Event ──┼─ Action (Post to Mastodon)
└─ Action (Store in S3)
Note: In the current architecture, this is achieved by having multiple children in the workflow tree. The consumer processes them in sequence but each branch is independent.
Pattern 6: Conditional Error Handling
Use branching to handle success and error cases differently.
┌─ [true] → Action (Post)
Event → Prompt ─────┤
└─ [false] → Action (Log Error)
Implementation:
- After the Prompt, add an Event that checks if the response is valid
- Branch based on validation result
- Use try/catch in scripts for graceful error handling
Building Workflows via API
When creating workflows programmatically, you need:
1. Create the Entities First
// Create Event entity
const event = await fetch('/api/workflow-entities', {
method: 'POST',
body: JSON.stringify({
organizationId: 'org-uuid',
environmentId: 'env-uuid',
name: 'My Event',
workflowEntityTypeId: 'event-type-uuid',
condition: { type: 'group', operator: 'AND', conditions: [...] }
})
});
2. Create the Workflow with workflowData
const workflow = await fetch('/api/workflows', {
method: 'POST',
body: JSON.stringify({
organizationId: 'org-uuid',
environmentId: 'env-uuid',
name: 'My Workflow',
description: 'Workflow description',
isActive: true,
workflowData: {
nodes: {
n1: { entityId: event.id, name: 'My Event', entityType: 'event', ... }
},
connectors: { ... },
workflow: { ref: 'n1', children: [...] }
}
})
});
Node Types and Shapes
| Entity Type | Presentation Type | Visual |
|---|---|---|
| event | circle | ⭕ |
| prompt | brain | 🧠 |
| action | star | ⭐ |
| logic-branch | logic-branch | ◇ |
Workflow Outcomes
Workflow outcomes are determined automatically based on execution:
| Outcome | When it occurs |
|---|---|
| Success | All entities execute without errors |
| Error | A script throws an error or times out |
| Ignore | Event condition doesn't match |
Best Practices
- Start Simple - Begin with a linear pipeline, add branching as needed
- Name Descriptively - Use clear names like "Check Premium Status" not "Event 1"
- One Responsibility - Each node should do one thing well
- Handle Both Branches - True/False events should have handlers for both cases
- Use Error Handling - Wrap risky operations in try/catch blocks
- Test Incrementally - Verify each node works before adding the next
Related Topics
- Workflow Data Schema - Complete JSON structure
- Workflow Examples - Full working examples
- Building Your First Workflow - Step-by-step tutorial