orchestrator
npx skills add https://github.com/a1exra/orchestrator-skill --skill orchestrator
Agent 安装分布
Skill 文档
Orchestrator Flow Builder Expert v2.0.0
You are an expert in Papaya Global Payments orchestrator flow development. When invoked, help users build, validate, debug, and understand orchestrator flows using comprehensive knowledge of the codebase.
Table of Contents
- Quick Reference
- Core Concepts
- Task Types Reference
- Expression Operators
- Advanced Features
- Component Library Reference
- Common Patterns
- Troubleshooting Guide
- Validation Rules
- Best Practices
- Search Strategies
Quick Reference
Task Types Summary
| Task Type | Purpose | Blocking | Common Use |
|---|---|---|---|
| SEQUENCE | Sequential execution | ALL/FIRST/NONE | Multi-step workflows |
| COMPONENT | External service call | – | API integrations |
| SUB_FLOW | Nested flow call | – | Reusable logic |
| TRANSFORM | Data manipulation | – | JSON transforms |
| MAP | Batch processing | – | Array iteration |
| SWITCH | Conditional branching | – | Status routing |
| FORK | Parallel execution | – | Independent operations |
| TRY_CATCH | Error handling | – | Failure recovery |
| EVALUATE | Dynamic expressions | – | Runtime evaluation |
| AWAIT | Async operations | – | Wait for events |
| TAGS | Metadata attachment | – | Observability |
| STATUS | Progress reporting | – | Long operations |
| TERMINATE | Flow termination | – | Early exit |
| SLEEP | Delayed execution | – | Rate limiting |
Operators Cheat Sheet
Conditional & Control: $$first, $$if, $$switch, $$and, $$or, $$not, $$coalesce
Array: $$map, $$filter, $$reduce, $$partition, $$group, $$flat, $$sort, $$at, $$slice, $$concat, $$distinct, $$reverse, $$lookup, $$entries, $$flatten
Object: $$object, $$entries, $$keys, $$values, $$merge, $$get, $$wrap, $$normalize, $$flatten, $$unflatten
String: $$join, $$split, $$replace, $$substring, $$upper, $$lower, $$trim, $$template, $$test, $$match, $$digest
Math: $$math, $$numberparse, $$abs, $$ceil, $$floor, $$round, $$min, $$max
Date/Time: $$date (FORMAT, ADD, SUB, DIFF, EPOCH)
Type & Validation: $$is, $$isnull, $$boolean, $$length, $$jsonpath, $$jsonvalidate
Advanced: $$eval, $$transform, $$uuid, $$base64, $$hash
Special Variables Reference
| Variable | Scope | Purpose | Example |
|---|---|---|---|
#now |
Global | Current timestamp | $$date(ADD,DAYS,30):#now |
#current |
Local | Current input context | #current.field |
##current |
Iterator | Current iteration item | $$map $.array (x) => ##current.id |
##outer |
Nested | Parent iteration context | Used in nested $$map |
##target |
Lookup | Joined item from $$lookup |
##target.field |
#env.* |
Global | Environment variables | #env.rnd_contact_service_alerts |
#caller_id |
Global | Flow execution ID | Tracking/logging |
#uuid |
Global | Generate UUID | Unique identifiers |
#null |
Global | Explicit null value | Default handling |
#exception |
Catch | Error object in TRY_CATCH | #exception.error_info |
$._init |
Global | Flow input | $._init.user_id |
$._call |
Global | Call metadata | $._call.id |
Core Concepts
Context Variables: ##current vs #now vs #env.*
#current – References the current task’s input/scope:
{
"type": "TRANSFORM",
"input": {
"user_name": "#current.user.first_name" // Access input field
}
}
##current – References the current iteration item in operators:
{
"items": "$$map $.users (user) => { \"id\": ##current.id }"
// ##current refers to each user in the iteration
}
#now – Current timestamp (ISO 8601):
{
"due_date": "$$date(ADD,DAYS,30):#now"
}
#env.* – Environment-specific configuration:
{
"alert_email": "#env.rnd_contact_service_alerts",
"environment": "#env.full_environment_name"
}
Spread Operator (*)
The * operator spreads object properties or array elements:
// Merge objects
{
"output": {
"*": "#current.base_object",
"new_field": "value"
}
}
// Flatten arrays
{
"all_items": {
"*": [
"$.list1",
"$.list2"
]
}
}
Example from flows/fileupload/validate/items/1.0.3.json:69:
{
"to": {
"index": "##current.index",
"*": "##current.payment" // Spread all payment fields
}
}
Escape Sequences
Use \\$ to output literal $ characters in strings:
{
"message": "Cost is \\$100" // Outputs: "Cost is $100"
}
Without escaping, $ would be interpreted as JSONPath.
JSONPath Filtering Syntax
Filter arrays using [?(@.condition)]:
// Get items where payment exists
"payments": "$._init.items[?(@.payment != null)]"
// Get active users
"active": "$.users[?(@.status == 'active')]"
// Complex conditions
"valid": "$.items[?(@.amount > 100 && @.approved == true)]"
Example from flows/fileupload/validate/items/1.0.3.json:35:
"input": "$$first:$._init.items[?(@.payment != null)]"
Comparison Operators in $$is
The $$is operator supports multiple comparison modes:
| Operator | Syntax | Example |
|---|---|---|
| Equal | eq or = |
$$is(=,value):$.field |
| Not equal | ne or != |
$$is(!=,null):$.field |
| Greater than | gt or > |
$$is(>,100):$.amount |
| Greater/equal | gte or >= |
$$is(>=,0):$.count |
| Less than | lt or < |
$$is(<,50):$.score |
| Less/equal | lte or <= |
$$is(<=,1000):$.limit |
| In list | in |
$$is(in,['A','B']):$.type |
| Not in list | nin |
$$is(nin,['X','Y']):$.status |
Example from flows/fileupload/validate/items/1.0.3.json:339:
"by": "$$is(>,1):##current[1].length()"
Task Types Reference
SEQUENCE
Sequential task execution with blocking modes.
{
"type": "SEQUENCE",
"description": "Execute tasks in order",
"block": "ALL", // ALL|FIRST|NONE
"result": "results", // Expose results to scope
"tasks": [...]
}
Blocking Modes:
ALL: Wait for all tasks to complete (default)FIRST: Stop after first successful taskNONE: Fire-and-forget, don’t wait
Use Cases: Multi-step workflows, ordered operations
Search: grep -r '"type": "SEQUENCE"' flows/
COMPONENT
Call external services via components.
{
"type": "COMPONENT",
"description": "Call external service",
"component_id": "standalone.service.operation",
"component_version": "1.0.0",
"input": {...},
"retries": 2,
"backoff": 100,
"multiplier": 3,
"result": "service_response"
}
Retry Configuration:
retries: Number of retry attempts (default: 2)backoff: Initial delay in ms (default: 100)multiplier: Backoff multiplier (default: 3)
Use Cases: API calls, service integration
Search Components: glob 'components/**/*.json'
SUB_FLOW
Call nested flows with version constraints.
{
"type": "SUB_FLOW",
"description": "Call nested flow",
"flow_id": "admin.security.permissions.check",
"flow_version": ">=1.0.0 <2.0.0",
"input": {...},
"fail_retry_filter": ["ERROR_CODE_1"],
"result": "sub_flow_result"
}
Version Constraints:
^1.0.0: Compatible with 1.x.x>=1.0.0 <2.0.0: Range constraint1.0.0: Exact version
Fire-and-Forget Pattern (flows/payments/screening/screen/2.0.2.json):
{
"type": "SEQUENCE",
"block": "NONE", // Don't wait for completion
"tasks": [
{
"type": "SUB_FLOW",
"flow_id": "background.process",
"input": {...}
}
]
}
Use Cases: Reusable logic, permission checks, complex workflows
Search: grep -r '"type": "SUB_FLOW"' flows/
TRANSFORM
Data manipulation with expression operators.
{
"type": "TRANSFORM",
"description": "Transform data",
"result": "transformed",
"map": {
"output_field": "$$first $.input_field1 $.input_field2",
"items": "$$map $.array_field (item) => { \"id\": $.item.id }",
"filtered": "$$filter $.items (x) => $$is $.x.active true"
}
}
Inline Syntax:
{
"type": "TRANSFORM",
"input": "$$map $.items (x) => ##current.id"
}
Object Syntax:
{
"type": "TRANSFORM",
"input": {
"$$map": "$.items",
"to": {
"id": "##current.id",
"name": "##current.name"
}
}
}
Important: Use $$first at root level only, not nested inside other operators.
Use Cases: Data transformation, field mapping, validation
MAP
Batch processing with parallel execution.
{
"type": "MAP",
"description": "Process items in batch",
"input": "$.items",
"task": {
"type": "COMPONENT",
"component_id": "process.item",
"input": {
"item_id": "#current.id"
}
},
"result": "processed_items"
}
Key Features:
- Processes array elements in parallel
- Each iteration has access to
#current(current item) - Returns array of results
- Failures in one item don’t stop others
Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:28:
{
"type": "MAP",
"id": "loop",
"input": "$._init.items",
"task": {
"type": "SEQUENCE",
"tasks": [
{
"type": "TRANSFORM",
"input": "$$at(-1):$$split(::):#current.payee.id"
}
]
}
}
Use Cases: Bulk operations, parallel processing, batch imports
Search: grep -r '"type": "MAP"' flows/
SWITCH
Conditional branching with cases.
{
"type": "SWITCH",
"description": "Branch on condition",
"result": "branch_result", // IMPORTANT: Expose result for scope
"cases": [
{
"condition": "$$is $.status \"approved\"",
"task": {...}
}
],
"default": {...}
}
Evaluation:
- Cases evaluated in order
- First matching case executes
defaultexecutes if no case matches- Missing
resultfield causes scope errors in subsequent tasks
Use Cases: Conditional logic, status-based routing
Common Issue: Missing result field causes scope errors
FORK
Parallel execution with result aggregation.
{
"type": "FORK",
"description": "Execute in parallel",
"result": "parallel_results",
"tasks": [...]
}
Key Differences from MAP:
FORK: Fixed number of parallel tasks (defined in JSON)MAP: Dynamic parallel processing based on input array
Use Cases: Independent operations, parallel API calls
Search: grep -r '"type": "FORK"' flows/
TRY_CATCH
Error handling with typed catches.
{
"type": "TRY_CATCH",
"description": "Handle errors",
"try": {...},
"catches": [
{
"codes": ["VALIDATION_ERROR"],
"task": {...}
}
],
"default": {...}
}
Error Object (#exception):
{
"code": "ERROR_CODE",
"message": "Error description",
"error_info": {
"errors": [
{
"properties": ["field.path"],
"description": "Error detail"
}
]
}
}
Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:263:
{
"default": {
"type": "TRANSFORM",
"input": {
"$$transform": {
"$$if": "$$not:$$isnull:#exception.error_info.errors[0].properties",
"then": {
"message": {
"$$join": [
"$$at(-1):$$split(\\.):#exception.error_info.errors[0].properties[0]",
" ",
"#exception.error_info.errors[0].description"
]
}
},
"else": "#exception"
}
}
}
}
Use Cases: Error recovery, validation handling, external service failures Best Practice: Always wrap risky operations (COMPONENT, SUB_FLOW)
EVALUATE
Dynamic expression evaluation at runtime.
{
"type": "EVALUATE",
"description": "Evaluate dynamic expression",
"expression": "$.dynamic_expression_string",
"result": "evaluated_result"
}
Key Features:
- Evaluates expressions stored as strings
- Useful for user-defined rules
- Can reference scope variables
- Runtime validation
Use Cases: Dynamic rules, user-defined logic, conditional expressions
Search: grep -r '"type": "EVALUATE"' flows/
AWAIT
Wait for async operations or external events.
{
"type": "AWAIT",
"description": "Wait for async operation",
"event": "payment.completed",
"timeout": 300000, // 5 minutes in ms
"result": "event_data"
}
Timeout Configuration:
timeout: Maximum wait time in milliseconds- If timeout expires, flow terminates with error
- Use TRY_CATCH to handle timeout gracefully
Use Cases: Webhook callbacks, async processing, event-driven flows
Search: grep -r '"type": "AWAIT"' flows/
TAGS
Attach metadata for tracking.
{
"type": "TAGS",
"description": "Tag for observability",
"tags": {
"entity_id": "$.entity.id",
"operation": "payment_send"
}
}
Use Cases: Logging, tracking, debugging Best Practice: Tag at flow start for context
STATUS
Report status to orchestrator.
{
"type": "STATUS",
"description": "Report processing status",
"status": "PROCESSING",
"message": "Payment validation in progress"
}
Use Cases: Long-running flows, progress tracking
TERMINATE
Stop flow execution.
{
"type": "TERMINATE",
"description": "Stop execution",
"fail": false, // true for failure, false for success
"code": "EARLY_EXIT",
"message": "Condition not met"
}
Use Cases: Early exit, validation failures
SLEEP
Delayed execution.
{
"type": "SLEEP",
"description": "Wait before retry",
"duration": 5000 // milliseconds
}
Use Cases: Rate limiting, scheduled operations, retry delays
Expression Operators
Conditional & Control Flow (7 operators)
$$first – Fallback Values
Returns first non-null value. MUST be at root level, not nested.
Syntax:
"field": "$$first $.optional_field $.default_value"
Object Form:
{
"field": {
"$$first": [
"$.optional_field1",
"$.optional_field2",
"default_value"
]
}
}
Example from flows/fileupload/validate/items/1.0.3.json:192:
{
"target_currency": {
"$$first": [
"##target.bank_details.currency",
"##target.target.currency"
]
}
}
Use Case: Provide fallback values for optional fields
Search: grep '$$first' flows/
$$if – Conditional Expression
Ternary conditional operator.
Syntax:
"field": "$$if ($$is $.status \"approved\") $.approved_value $.rejected_value"
Object Form:
{
"field": {
"$$if": "##current.condition",
"then": "value_if_true",
"else": "value_if_false"
}
}
Example from flows/fileupload/validate/items/1.0.3.json:206:
{
"missing": {
"$$if": "##target.id",
"then": false,
"else": true
}
}
Use Case: Conditional value assignment
Search: grep '$$if' flows/
$$switch – Switch Statement
Multi-case conditional branching.
Syntax:
{
"field": {
"$$switch": "$.status",
"cases": {
"approved": "Approved value",
"pending": "Pending value",
"default": "Default value"
}
}
}
Nested Example from flows/fileupload/validate/items/1.0.3.json:239:
{
"enforce_whole_number": {
"default": false,
"$$switch": "whole_amount",
"cases": {
"default": {
"whole_amount": false
},
"$$switch": "##current.currency",
"cases": "$.payment_validation_config"
}
}
}
Use Case: Multi-branch conditional logic
Search: grep '$$switch' flows/
$$and – Logical AND
Returns true if all conditions are true.
Syntax:
"valid": "$$and [$$is $.amount > 0, $$is $.status \"active\"]"
Example from flows/fileupload/validate/items/1.0.3.json:283:
{
"by": {
"$$and": [
"$$is(>,##current.amount):##current.min_amount",
"$$is(=,##current.target_currency):##current.currency"
]
}
}
Use Case: Combine multiple conditions
Search: grep '$$and' flows/
$$or – Logical OR
Returns true if any condition is true.
Syntax:
"valid": "$$or [$$is $.type \"A\", $$is $.type \"B\"]"
Example from flows/fileupload/validate/items/1.0.3.json:181:
{
"on": {
"$$or": [
"$$is(=,##target.source.id):##current.payment.target.id",
"$$is(=,##target.payee.id):##current.payment.target.id"
]
}
}
Use Case: Alternative conditions
Search: grep '$$or' flows/
$$not – Logical NOT
Negates boolean value.
Syntax:
"inactive": "$$not:$.active"
Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:263:
{
"$$if": "$$not:$$isnull:#exception.error_info.errors[0].properties"
}
Use Case: Boolean negation
Search: grep '$$not' flows/
$$coalesce – First Non-Null
Similar to $$first but with different syntax.
Syntax:
"value": "$$coalesce [$.field1, $.field2, \"default\"]"
Use Case: Fallback chain for null values
Search: grep '$$coalesce' flows/
Array Operations (15 operators)
$$map – Array Transformation
Transform each array element.
Syntax:
"items": "$$map $.array (item) => { \"id\": ##current.id }"
Object Form:
{
"items": {
"$$map": "$.array",
"to": {
"id": "##current.id",
"name": "##current.name"
}
}
}
Context Variables:
{
"$$map": "$.items",
"context": {
"##outer": "##current"
},
"to": {
"item_id": "##current.id",
"parent_ref": "##outer.parent_id"
}
}
Example from flows/fileupload/validate/items/1.0.3.json:67:
{
"$$map": "$._init.items[?(@.payment != null)]",
"to": {
"index": "##current.index",
"*": "##current.payment"
}
}
Use Case: Transform arrays
Search: grep '$$map' flows/
$$filter – Array Filtering
Filter array elements by condition.
Syntax:
"active": "$$filter $.items (x) => $$is $.x.active true"
Object Form:
{
"active": {
"$$filter": "$.items",
"by": "##current.active"
}
}
Example from flows/fileupload/validate/items/1.0.3.json:266:
{
"$$filter": "$.get_config_for_targets",
"by": "##current.missing"
}
Use Case: Filter arrays by conditions
Search: grep '$$filter' flows/
$$reduce – Array Reduction
Reduce array to single value.
Syntax:
{
"total": {
"$$reduce": "$.amounts",
"init": 0,
"by": "$$math(ADD) [##accumulator, ##current]"
}
}
Variables:
##accumulator: Current accumulated value##current: Current array item
Use Case: Sum, concatenate, aggregate arrays
Search: grep '$$reduce' flows/
$$partition – Split Array
Split array into chunks.
Syntax:
{
"batches": {
"$$partition": "$.items",
"size": 100
}
}
Returns: Array of arrays, each with max size elements
Use Case: Batch processing, pagination
Search: grep '$$partition' flows/
$$group – Group By Key
Group array elements by key.
Syntax:
{
"grouped": {
"$$group": "$.items",
"by": "##current.category"
}
}
Returns: Object with keys as group values, values as arrays
Example from flows/fileupload/validate/items/1.0.3.json:329:
{
"$$group": {
"$$map": "$._init.items[?(@.payment.id != null)]",
"to": {
"id": "##current.payment.id",
"index": "##current.index"
}
},
"by": "##current.id"
}
Use Case: Group items by field
Search: grep '$$group' flows/
$$flat – Flatten Array
Flatten nested arrays one level.
Syntax:
"flattened": "$$flat [$.array1, $.array2]"
Object Form:
{
"flattened": {
"$$flat": [
"$.array1",
"$.array2"
]
}
}
Example from flows/fileupload/validate/items/1.0.3.json:173:
{
"with": {
"$$flat": [
"$.find_targets.items[*]",
"$._init.items[*].beneficiary"
]
}
}
Use Case: Merge multiple arrays
Search: grep '$$flat' flows/
$$sort – Sort Array
Sort array by field or comparator.
Syntax:
{
"sorted": {
"$$sort": "$.items",
"by": "##current.date",
"order": "asc" // or "desc"
}
}
Use Case: Sort arrays
Search: grep '$$sort' flows/
$$at – Array Element Access
Access array elements by index, including negative indices for reverse access.
Syntax:
"first": "$$at(0):$.array" // First element
"last": "$$at(-1):$.array" // Last element (reverse)
"second_last": "$$at(-2):$.array" // Second from end
Object Form:
{
"external_id": {
"$$at": -1,
"from": "$$split(::,2):##current.payee.source.id"
}
}
Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:45:
{
"type": "TRANSFORM",
"id": "external_id",
"input": "$$at(-1):$$split(::):#current.payee.id"
}
Use Case: Reverse List Access
When you need the last element but don’t want to use $$first (which requires non-null check):
{
"external_id": {
"$$at": -1,
"from": "$$split(::,2):##current.payee.source.id"
}
}
This splits “prefix::id::suffix” by “::” and takes the last element.
Key Differences from $$first:
$$at(-1)– Always returns last element (or null if empty)$$first– Returns first non-null value from list of fallbacks- Use
$$atfor positional access,$$firstfor fallback chains
Negative Indices:
-1= last element-2= second to last-n= nth from end
Edge Cases:
- Empty array: Returns null
- Index out of bounds: Returns null
- Non-array input: Returns null
Search: grep '$$at' flows/
$$slice – Array Slice
Extract array subrange.
Syntax:
{
"subset": {
"$$slice": "$.items",
"start": 0,
"end": 10
}
}
Use Case: Pagination, truncation
Search: grep '$$slice' flows/
$$concat – Concatenate Arrays
Combine multiple arrays.
Syntax:
"combined": "$$concat [$.array1, $.array2, $.array3]"
Use Case: Merge arrays
Search: grep '$$concat' flows/
$$distinct – Unique Elements
Remove duplicates from array.
Syntax:
"unique": "$$distinct:$.items"
Example from flows/fileupload/validate/items/1.0.3.json:130:
{
"source": "$$distinct:$._init.items[*].payment.target"
}
Use Case: Deduplicate arrays
Search: grep '$$distinct' flows/
$$reverse – Reverse Array
Reverse array order.
Syntax:
"reversed": "$$reverse:$.items"
Use Case: Reverse order
Search: grep '$$reverse' flows/
$$lookup – Array Join
Join arrays like SQL JOIN.
Syntax:
{
"joined": {
"$$lookup": "$.left_array",
"using": [
{
"with": "$.right_array",
"as": "match",
"on": "$$is(=,##current.id):##match.id"
}
],
"to": {
"*": "##current",
"matched_field": "##match.field"
}
}
}
Example from flows/fileupload/validate/items/1.0.3.json:728:
{
"items": {
"$$lookup": "$._init.items",
"using": [
{
"with": "$.check_for_payments.targets",
"as": "target",
"on": "$$is(=,##current.payment.target):##target.source"
}
],
"to": {
"*": "##current",
"payment": {
"$$if": "##current.payment",
"then": {
"*": "##current.payment",
"target": {
"*": "##current.payment.target",
"_currency": "##target.target.currency"
}
}
}
}
}
}
Use Case: Join related data
Search: grep '$$lookup' flows/
$$entries – Object to Array
Convert object to array of [key, value] pairs.
Syntax:
"pairs": "$$entries:$.object"
Returns: [["key1", "value1"], ["key2", "value2"]]
Example from flows/fileupload/validate/items/1.0.3.json:328:
{
"$$entries": {
"$$group": {
"$$map": "$._init.items",
"to": {
"id": "##current.payment.id"
}
},
"by": "##current.id"
}
}
Use Case: Iterate over object keys
Search: grep '$$entries' flows/
$$flatten – Deep Flatten
Flatten nested arrays recursively.
Syntax:
"flat": "$$flatten:$.nested_arrays"
Difference from $$flat:
$$flat: One level only$$flatten: Recursive (all levels)
Use Case: Deep nested array flattening
Search: grep '$$flatten' flows/
Object Operations (12 operators)
$$object – Create Object
Create object from key-value pairs.
Syntax:
{
"obj": {
"$$object": [
["key1", "value1"],
["key2", "value2"]
]
}
}
Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:51:
{
"$$object": {
"$$map": {
"$$filter": "$$entries:#current.tags",
"by": "$$test(^#):##current[0]"
},
"to": [
"$$substring(1):##current[0]",
"##current[1]"
]
}
}
Use Case: Dynamic object creation
Search: grep '$$object' flows/
$$entries – Object to Array
See Array Operations section.
$$keys – Object Keys
Extract object keys as array.
Syntax:
"keys": "$$keys:$.object"
Use Case: Get object keys
Search: grep '$$keys' flows/
$$values – Object Values
Extract object values as array.
Syntax:
"values": "$$values:$.object"
Use Case: Get object values
Search: grep '$$values' flows/
$$merge – Merge Objects
Merge multiple objects.
Syntax:
{
"merged": {
"$$merge": [
"$.object1",
"$.object2"
]
}
}
Use Case: Combine objects
Search: grep '$$merge' flows/
$$get – Safe Object Access
Safely access nested object properties.
Syntax:
"value": "$$get $.object \"nested.path\" \"default\""
Object Form:
{
"value": {
"$$get": "$.object",
"path": "nested.path",
"default": "fallback_value"
}
}
Use Case: Safe property access
Search: grep '$$get' flows/
$$wrap – Wrap in Object
Wrap value in object with key.
Syntax:
"wrapped": "$$wrap(key):$.value"
Returns: {"key": value}
Example from flows/fileupload/validate/items/1.0.3.json:100:
{
"$$wrap(.):$$substring(17):##current.message"
}
Chained Example:
{
"$$wrap(payment.):$$substring(1):$$replace(/,.):##current"
}
Use Case: Dynamic key creation
Search: grep '$$wrap' flows/
$$normalize – Normalize Object
Normalize object structure.
Syntax:
{
"normalized": {
"$$normalize": "$.object",
"schema": "$.schema_definition"
}
}
Use Case: Schema normalization
Search: grep '$$normalize' flows/
$$flatten – Flatten Nested Object
Flatten nested object to dot notation.
Syntax:
"flattened": "$$flatten:$.nested_object"
Example:
- Input:
{"a": {"b": {"c": 1}}} - Output:
{"a.b.c": 1}
Use Case: Flatten object hierarchy
Search: grep '$$flatten' flows/
$$unflatten – Unflatten Object
Convert dot notation to nested object.
Syntax:
"nested": "$$unflatten:$.flat_object"
Example:
- Input:
{"a.b.c": 1} - Output:
{"a": {"b": {"c": 1}}}
Use Case: Restore nested structure
Search: grep '$$unflatten' flows/
String Operations (18 operators)
$$join – String Concatenation
Join array elements or strings.
Syntax:
"full_name": "$$join [$.first_name, \" \", $.last_name]"
With Separator:
"csv": "$$join(,):$.array"
Example from flows/fileupload/validate/items/1.0.3.json:292:
{
"message": {
"$$join": [
"Minimun amount for ",
"##current.target_currency",
" is ",
"##current.min_amount"
]
}
}
Use Case: Concatenate strings
Search: grep '$$join' flows/
$$split – String Split
Split string into array.
Syntax:
"parts": "$$split(,):$.csv_string"
With Limit:
"parts": "$$split(::,2):$.id"
Example from flows/fileupload/validate/items/1.0.3.json:211:
{
"target": {
"$$transform": "$$split(::,2):##current.payment.target.id",
"to": "##current[1]"
}
}
Use Case: Parse delimited strings
Search: grep '$$split' flows/
$$replace – String Replacement
Replace substring or regex pattern.
Syntax:
"cleaned": "$$replace $.text \"old\" \"new\""
Regex Mode:
"cleaned": "$$replace(/pattern/,replacement):$.text"
Example from flows/fileupload/validate/items/1.0.3.json:105:
{
"$$wrap(payment.):$$substring(1):$$replace(/,.):##current"
}
Use Case: String substitution
Search: grep '$$replace' flows/
$$substring – Substring Extraction
Extract substring.
Syntax:
"sub": "$$substring(0,10):$.text" // First 10 chars
"from": "$$substring(5):$.text" // From index 5
Example from flows/fileupload/validate/items/1.0.3.json:94:
{
"$$is": "$$substring(0,16):##current.message",
"eq": "Missing property"
}
Use Case: Extract substrings
Search: grep '$$substring' flows/
$$upper – Uppercase
Convert to uppercase.
Syntax:
"upper": "$$upper:$.text"
Use Case: Case normalization
Search: grep '$$upper' flows/
$$lower – Lowercase
Convert to lowercase.
Syntax:
"lower": "$$lower:$.text"
Use Case: Case normalization
Search: grep '$$lower' flows/
$$trim – Trim Whitespace
Remove leading/trailing whitespace.
Syntax:
"trimmed": "$$trim:$.text"
Use Case: Clean input
Search: grep '$$trim' flows/
$$template – Text Templates
Advanced string templating with variables.
Syntax:
{
"message": {
"$$template": "Hello {{name}}, your balance is {{balance}}",
"vars": {
"name": "$.user.name",
"balance": "$.account.balance"
}
}
}
Use Case: Dynamic message generation
Search: grep '$$template' flows/
$$test – Regex Test
Test if string matches regex.
Syntax:
"is_email": "$$test $.input \"^[\\w.-]+@[\\w.-]+\\.\\w+$\""
Returns: Boolean
Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:54:
{
"by": "$$test(^#):##current[0]"
}
Use Case: Pattern validation
Search: grep '$$test' flows/
$$match – Regex Match
Extract regex matches.
Syntax:
{
"matches": {
"$$match": "$.text",
"pattern": "(\\d+)"
}
}
Returns: Array of matches
Use Case: Pattern extraction
Search: grep '$$match' flows/
$$digest – Hash String
Generate hash digest.
Syntax:
{
"hash": {
"$$digest": "$.data",
"algorithm": "SHA256"
}
}
Use Case: Generate hashes
Search: grep '$$digest' flows/
Mathematical Operations (10 operators)
$$math – Mathematical Operations
Perform math operations.
Syntax:
"rounded": "$$math(ROUND,2) $.amount"
"total": "$$math(ADD) [$.subtotal, $.tax]"
Operations:
ADD: Sum valuesSUB: SubtractMUL: MultiplyDIV: DivideMOD: ModuloROUND: Round to decimalsABS: Absolute valueCEIL: Round upFLOOR: Round down
Example from flows/fileupload/validate/items/1.0.3.json:249:
{
"rounded_amount": {
"$$math": [
"ROUND",
"##current.amount"
]
}
}
Use Case: Calculations
Search: grep '$$math' flows/
$$numberparse – Parse Number
Parse string to number.
Syntax:
"num": "$$numberparse:$.string_number"
Example from flows/fileupload/validate/items/1.0.3.json:219:
{
"min_amount": {
"$$numberparse": {
"$$first": [
{"$$jsonpath": "$.payment_validation_config", "path": "..."},
0
]
}
}
}
Use Case: Convert strings to numbers
Search: grep '$$numberparse' flows/
$$abs – Absolute Value
Get absolute value.
Syntax:
"absolute": "$$abs:$.number"
Use Case: Remove sign
Search: grep '$$abs' flows/
$$ceil – Round Up
Round up to integer.
Syntax:
"ceiled": "$$ceil:$.number"
Use Case: Round up
Search: grep '$$ceil' flows/
$$floor – Round Down
Round down to integer.
Syntax:
"floored": "$$floor:$.number"
Use Case: Round down
Search: grep '$$floor' flows/
$$round – Round Number
Round to nearest integer or decimals.
Syntax:
"rounded": "$$round(2):$.number" // 2 decimals
Use Case: Rounding
Search: grep '$$round' flows/
$$min – Minimum Value
Get minimum value from array.
Syntax:
"minimum": "$$min:$.numbers"
Use Case: Find minimum
Search: grep '$$min' flows/
$$max – Maximum Value
Get maximum value from array.
Syntax:
"maximum": "$$max:$.numbers"
Example from flows/fileupload/validate/items/1.0.3.json:688:
{
"existing_beneficiaries": {
"$$max": [
"$.existing_beneficiaries_check.exists.length()",
"$.existing_beneficiaries_use_lookup_search.items.length()"
]
}
}
Use Case: Find maximum
Search: grep '$$max' flows/
Date/Time Operations (8 operators)
$$date – Date Operations
Manipulate and format dates.
Operations:
FORMAT – Format date:
"formatted": "$$date(FORMAT,\"yyyy-MM-dd\") $.timestamp"
ADD – Add duration:
"due_date": "$$date(ADD,DAYS,30) #now"
SUB – Subtract duration:
"past": "$$date(SUB,HOURS,3) #now"
DIFF – Date difference:
"days_diff": "$$date(DIFF,DAYS) [$.start_date, $.end_date]"
EPOCH – Unix timestamp:
"timestamp": "$$date(EPOCH) #now"
Example from flows/fileupload/validate/items/1.0.3.json:372:
{
"$$is": "$$date(FORMAT,yyyy-MM-dd):##current.date",
"lt": "$$date(FORMAT,yyyy-MM-dd):$$date(SUB,HOURS,3):#now"
}
Units: YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS
Use Case: Date manipulation
Search: grep '$$date' flows/
Type & Validation (12 operators)
$$is – Comparison
Compare values with operators.
Syntax:
"valid": "$$is $.amount > 100"
"equal": "$$is(=,value):$.field"
Operators: =, !=, >, >=, <, <=, in, nin, eq, ne, gt, gte, lt, lte
Use Case: Comparisons
Search: grep '$$is' flows/
$$isnull – Null Check
Check if value is null.
Syntax:
"is_null": "$$isnull:$.field"
Returns: Boolean
Example from flows/fileupload/validate/items/1.0.3.json:675:
{
"by": "$$isnull:##current.beneficiary.entity_type"
}
Use Case: Null validation
Search: grep '$$isnull' flows/
$$boolean – Convert to Boolean
Convert value to boolean.
Syntax:
"bool": "$$boolean:$.value"
Use Case: Type conversion
Search: grep '$$boolean' flows/
$$length – Get Length
Get length of string or array.
Syntax:
"count": "$.items.length()"
Use Case: Count items
Search: grep 'length()' flows/
$$jsonpath – JSONPath Query
Execute JSONPath query.
Syntax:
{
"result": {
"$$jsonpath": "$.object",
"path": "$.nested.path"
}
}
Example from flows/fileupload/validate/items/1.0.3.json:222:
{
"$$jsonpath": "$.payment_validation_config",
"path": "$$wrap(##current.currency,##current.country):.min."
}
Use Case: Complex queries
Search: grep '$$jsonpath' flows/
$$jsonvalidate – JSON Schema Validation
Validate JSON against schema.
Syntax:
{
"validation": {
"$$jsonvalidate": "$.data",
"schema": "$.schema_definition"
}
}
Returns:
{
"count": 2,
"errors": [
{
"field": "field.path",
"message": "Error message",
"uri": "#/path/to/field"
}
],
"item": {original_data}
}
Example from flows/fileupload/validate/items/1.0.3.json:66:
{
"$$jsonvalidate": {
"$$map": "$._init.items[?(@.payment != null)]",
"to": {
"index": "##current.index",
"*": "##current.payment"
}
},
"schema": "$.fetch_schema"
}
Use Case: Schema validation
Search: grep '$$jsonvalidate' flows/
Advanced & Meta (11 operators)
$$eval – Evaluate Expression
Evaluate dynamic expression.
Syntax:
{
"result": {
"$$eval": "$.dynamic_expression"
}
}
Example from flows/fileupload/validate/items/1.0.3.json:110:
{
"$$eval": "$$wrap(,.$ui.errorMessage):$$replace((\\.(\\d+)),[$2],REGEX):$$replace(/,.):$$wrap(\\$.fetch_schema):$$substring(1):##current.path"
}
Use Case: Dynamic expressions
Search: grep '$$eval' flows/
$$transform – Nested Transform
Nest transformation logic.
Syntax:
{
"result": {
"$$transform": "$.data",
"to": {
"field": "##current.value"
}
}
}
Example from flows/fileupload/validate/items/1.0.3.json:211:
{
"target": {
"$$transform": "$$split(::,2):##current.payment.target.id",
"to": "##current[1]"
}
}
Use Case: Complex transformations
Search: grep '$$transform' flows/
$$uuid – Generate UUID
Generate UUID v4.
Syntax:
"id": "#uuid"
Use Case: Unique identifiers
Search: grep '#uuid' flows/
$$base64 – Base64 Encoding
Encode/decode base64.
Encode:
"encoded": "$$base64(encode):$.data"
Decode:
"decoded": "$$base64(decode):$.encoded_data"
Use Case: Encoding
Search: grep '$$base64' flows/
$$hash – Generate Hash
Generate hash of value.
Syntax:
{
"hash": {
"$$hash": "$.data",
"algorithm": "SHA256"
}
}
Use Case: Hashing
Search: grep '$$hash' flows/
Advanced Features
Text Templates with $$template
Advanced string templating with variable interpolation:
{
"email_body": {
"$$template": "Dear {{user.name}},\n\nYour payment of {{payment.amount}} {{payment.currency}} was {{status}}.\n\nReference: {{payment.id}}",
"vars": {
"user": "$.user",
"payment": "$.payment",
"status": "$$lower:$.status"
}
}
}
Use Cases:
- Email/notification templates
- Dynamic message generation
- Report formatting
Chained Transformations
Chain multiple operators using : separator:
"result": "$$wrap(payment.):$$substring(1):$$replace(/,.):##current"
Execution Order: Right to left (like function composition)
Example from flows/fileupload/validate/items/1.0.3.json:105:
{
"type": {
"$$transform": {
"$$if": {
"$$is": "$$substring(0,16):##current.message",
"eq": "Missing property"
},
"then": {
"$$join": [
"##current.field",
"$$wrap(.):$$substring(17):##current.message"
]
},
"else": "$$substring(1):##current.uri"
},
"to": "$$wrap(payment.):$$substring(1):$$replace(/,.):##current"
}
}
Context Variable Scoping in Nested Operations
When nesting operators, use context to preserve outer scope:
{
"$$map": "$.outer_array",
"to": {
"$$map": "##current.inner_array",
"context": {
"##outer": "##current" // Preserve outer item
},
"to": {
"outer_id": "##outer.id",
"inner_id": "##current.id"
}
}
}
Example from flows/fileupload/validate/items/1.0.3.json:87:
{
"$$map": "##current.errors",
"context": {
"##outer": "##current"
},
"to": {
"type": {...},
"index": "##outer.item.index"
}
}
$$eval for Dynamic Expressions
Use $$eval to evaluate expressions stored as strings:
{
"type": "TRANSFORM",
"input": {
"result": {
"$$eval": "$.user_defined_rule"
}
}
}
Use Cases:
- User-defined validation rules
- Dynamic field mapping
- Conditional logic from configuration
Comparison Logic with $$is
Advanced comparison patterns:
Range Checks:
{
"valid": {
"$$and": [
"$$is(>=,0):$.value",
"$$is(<=,100):$.value"
]
}
}
List Membership:
{
"is_valid_status": {
"$$is": "$.status",
"in": ["APPROVED", "PENDING", "PROCESSING"]
}
}
Exclusion:
{
"not_failed": {
"$$is": "$.status",
"nin": ["FAILED", "REJECTED", "CANCELLED"]
}
}
Component Library Reference
Toolbox Components
Excel Operations (toolbox.parse.xlsx):
- Parse Excel files
- Extract sheets, cells, rows, columns
- Cell manipulation: setValue, getValue, getFormula
- Row/column operations: insert, delete, copy
- Data transforms: filtering, mapping, aggregation
CSV Operations (toolbox.parse.csv):
- Parse CSV files
- Handle delimiters, encoding
- Data extraction
S3 Operations (toolbox.s3.*):
- Upload, download files
- List, delete objects
- Bucket operations
ISO 20022 Parsing (toolbox.parse.iso20022):
- Parse ISO 20022 XML messages
- Payment instructions
- Financial messaging
Email (toolbox.aws.ses.send):
- Send emails via AWS SES
- HTML/text support
- Attachments
Integration Components (84 components)
HRIS & Payroll:
- Employee data sync
- Payroll processing
- Time & attendance
Data Sync:
- System integrations
- Data pipeline components
NetSuite:
- Financial data sync
- Journal entries
- Vendor management
Journal Entries:
- Accounting integrations
- Financial posting
Rain Components (13)
Payment Cards:
- Card issuance
- Card management
- Transaction processing
Crypto Wallets:
- Wallet creation
- Balance management
- Transaction operations
Crossmint Components (6)
Blockchain Wallets:
- Multi-chain wallet support
- Wallet creation and management
Crypto Transfers:
- Cross-chain transfers
- Transaction tracking
Sumsub Components (7)
KYC/AML Verification:
- Identity verification
- Document verification
- Screening and monitoring
Authorization Components (6)
Auth & User Management:
- Authentication
- Authorization
- User operations
Payments Components (2)
Crypto Operations:
- Payment processing
- Transaction validation
AI Validation:
- Intelligent validation
- Fraud detection
Apps & Payroll (2)
Events:
- Event handling
- Webhooks
KYC:
- Know Your Customer
- Compliance checks
Finding Components
Search Strategies:
# All components
glob 'components/**/*.json'
# By service
glob 'components/standalone/**/*.json'
glob 'components/toolbox/**/*.json'
# By name
grep '"component_id": "screening"' components/
# By capability
grep 'payment' components/
Common Patterns
Permission Check Pattern
{
"type": "SEQUENCE",
"block": "ALL",
"tasks": [
{
"type": "SUB_FLOW",
"description": "Check permissions",
"flow_id": "admin.security.permissions.check",
"flow_version": ">=1.0.0",
"input": {
"user_id": "$.user.id",
"resource": "payment.send"
},
"result": "permission_check"
},
{
"type": "SWITCH",
"result": "switch_result",
"cases": [
{
"condition": "$$is $.permission_check.allowed false",
"task": {
"type": "TERMINATE",
"fail": true,
"code": "PERMISSION_DENIED"
}
}
],
"default": {
"type": "COMPONENT",
"description": "Execute protected operation",
"component_id": "payment.send",
"input": {...}
}
}
]
}
Error Handling Pattern
{
"type": "TRY_CATCH",
"try": {
"type": "COMPONENT",
"component_id": "external.service.call",
"retries": 2,
"backoff": 100,
"multiplier": 3,
"result": "service_result"
},
"catches": [
{
"codes": ["VALIDATION_ERROR"],
"task": {
"type": "TERMINATE",
"fail": true,
"code": "VALIDATION_FAILED",
"message": "Input validation failed"
}
}
],
"default": {
"type": "TERMINATE",
"fail": true,
"code": "UNKNOWN_ERROR",
"message": "Unexpected error occurred"
}
}
Parallel Processing Pattern
{
"type": "FORK",
"description": "Execute checks in parallel",
"result": "checks",
"tasks": [
{
"type": "COMPONENT",
"component_id": "screening.check",
"input": {"entity_id": "$.entity.id"},
"result": "screening"
},
{
"type": "COMPONENT",
"component_id": "compliance.check",
"input": {"entity_id": "$.entity.id"},
"result": "compliance"
}
]
}
Retry with Filter Pattern
{
"type": "SUB_FLOW",
"flow_id": "payment.process",
"flow_version": ">=2.0.0",
"input": {...},
"fail_retry_filter": ["TEMPORARY_ERROR", "RATE_LIMIT"],
"result": "process_result"
}
Batch Processing with MAP and $$partition
Pattern: Process large arrays in batches
{
"type": "SEQUENCE",
"tasks": [
{
"type": "TRANSFORM",
"id": "create_batches",
"input": {
"batches": {
"$$partition": "$.items",
"size": 100
}
}
},
{
"type": "MAP",
"id": "process_batches",
"input": "$.create_batches.batches",
"task": {
"type": "COMPONENT",
"component_id": "process.batch",
"input": {
"items": "#current"
}
}
}
]
}
Example: flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json
Nested Transformations ($$group â $$entries â $$filter â $$map)
Pattern: Complex data aggregation and transformation
{
"duplicate_check": {
"$$flat": {
"$$map": {
"$$filter": {
"$$entries": {
"$$group": {
"$$map": "$.items",
"to": {
"id": "##current.id",
"index": "##current.index"
}
},
"by": "##current.id"
}
},
"by": "$$is(>,1):##current[1].length()"
},
"to": {
"$$map": "##current[1]",
"to": {
"type": "duplicate",
"index": "##current.index"
}
}
}
}
}
Explanation:
$$group: Group items by ID$$entries: Convert to [key, value] pairs$$filter: Keep only duplicates (length > 1)$$map: Transform to error objects$$flat: Flatten result
Example: flows/fileupload/validate/items/1.0.3.json:326
Fire-and-Forget SUB_FLOW
Pattern: Background processing without waiting
{
"type": "SEQUENCE",
"block": "NONE", // Don't wait for completion
"tasks": [
{
"type": "SUB_FLOW",
"flow_id": "notifications.send.async",
"input": {
"user_id": "$.user.id",
"message": "$.message"
}
}
]
}
Use Cases:
- Notifications
- Logging
- Analytics tracking
- Audit trails
Example: flows/payments/screening/screen/2.0.2.json
Context Variables in Nested $$map
Pattern: Access outer scope in nested iterations
{
"result": {
"$$map": "$.outer_array",
"to": {
"outer_id": "##current.id",
"items": {
"$$map": "##current.inner_array",
"context": {
"##outer": "##current"
},
"to": {
"outer_id": "##outer.id",
"inner_id": "##current.id"
}
}
}
}
}
Example: flows/fileupload/validate/items/1.0.3.json:343
Pure Memory Flows
Pattern: In-memory processing without persistence
{
"schema_version": "2",
"properties": {
"pure_memory": true
},
"task": {
"type": "TRANSFORM",
"input": {
"processed": "$$map $.items (x) => ##current.id"
}
}
}
Use Cases:
- Validation flows
- Preprocessing
- Temporary calculations
Example: flows/fileupload/validate/items/1.0.3.json:19
$$lookup for Data Enrichment
Pattern: Join arrays to enrich data
{
"enriched_items": {
"$$lookup": "$.items",
"using": [
{
"with": "$.reference_data",
"as": "ref",
"on": "$$is(=,##current.id):##ref.id"
}
],
"to": {
"*": "##current",
"additional_field": "##ref.field"
}
}
}
Example: flows/fileupload/validate/items/1.0.3.json:728
SEQUENCE Blocking Strategies
ALL – Wait for all tasks:
{
"type": "SEQUENCE",
"block": "ALL",
"tasks": [...]
}
FIRST – Stop after first success:
{
"type": "SEQUENCE",
"block": "FIRST",
"tasks": [
{"type": "COMPONENT", "component_id": "primary.service"},
{"type": "COMPONENT", "component_id": "fallback.service"}
]
}
NONE – Fire-and-forget:
{
"type": "SEQUENCE",
"block": "NONE",
"tasks": [
{"type": "SUB_FLOW", "flow_id": "async.operation"}
]
}
Troubleshooting Guide
Scope Resolution Errors
Error: “Field not in scope”
Causes:
- Missing
resultfield in SWITCH/SEQUENCE/FORK - Referencing field from wrong scope
- Typo in field name
Fix:
// Before (broken)
{
"type": "SWITCH",
"cases": [...]
}
// Later: $.branch_result.field // ERROR: Not in scope
// After (fixed)
{
"type": "SWITCH",
"result": "branch_result", // Add this
"cases": [...]
}
Operator Syntax Errors
Error: “Invalid operator syntax”
Common Mistakes:
- $$first nested in other operators:
// Wrong
"items": "$$map $.array (x) => $$first ##current.field1 ##current.field2"
// Right
"items": "$$map $.array (x) => { \"value\": { \"$$first\": [\"##current.field1\", \"##current.field2\"] } }"
- Missing escape sequences:
// Wrong
"message": "Cost is $100" // $ interpreted as JSONPath
// Right
"message": "Cost is \\$100"
- Incorrect ##current usage:
// Wrong (outside iterator)
"field": "##current.value"
// Right (inside $$map)
"items": "$$map $.array (x) => ##current.value"
JSONPath Issues
Error: “JSONPath evaluation failed”
Common Issues:
- Invalid filter syntax:
// Wrong
"items": "$.array[?(@.status = 'active')]" // Use == not =
// Right
"items": "$.array[?(@.status == 'active')]"
- Missing brackets:
// Wrong
"items": "$.array[*]field"
// Right
"items": "$.array[*].field"
Context Variable Problems
Error: “##current shadowing”
Problem: Nested $$map with same variable name
Fix: Use context to preserve outer scope:
{
"$$map": "$.outer",
"to": {
"$$map": "##current.inner",
"context": {
"##outer": "##current" // Preserve outer
},
"to": {
"outer_id": "##outer.id",
"inner_id": "##current.id"
}
}
}
Performance Issues
Problem: Slow flow execution
Causes:
- Large array operations without batching
- Sequential operations that could be parallel
- Unnecessary transformations
Solutions:
- Use $$partition for large arrays:
{
"batches": {
"$$partition": "$.large_array",
"size": 100
}
}
- Use FORK for parallel operations:
{
"type": "FORK",
"tasks": [
{"type": "COMPONENT", "component_id": "service1"},
{"type": "COMPONENT", "component_id": "service2"}
]
}
- Avoid deep nesting:
// Instead of deeply nested $$map
// Break into multiple TRANSFORM tasks
Common Anti-Patterns
1. Overusing $$first:
// Anti-pattern
"field": "$$first $.a $.b $.c $.d $.e"
// Better
"field": {
"$$first": [
"$.primary_source",
"$.fallback_source",
"default_value"
]
}
2. Missing error handling:
// Anti-pattern
{
"type": "COMPONENT",
"component_id": "external.service"
}
// Better
{
"type": "TRY_CATCH",
"try": {
"type": "COMPONENT",
"component_id": "external.service"
},
"default": {
"type": "TERMINATE",
"fail": true,
"code": "SERVICE_ERROR"
}
}
3. Not using result field:
// Anti-pattern
{
"type": "SWITCH",
"cases": [...]
}
// Later: $.branch_result // ERROR
// Better
{
"type": "SWITCH",
"result": "branch_result",
"cases": [...]
}
Validation Rules
Deployment Readiness Checklist
- Flow ID matches directory structure (entity.domain.action)
- Version is semantic (1.0.0, 1.2.3, etc.)
- Meta labels include “deployable” and “ci/cd”
- Schema version is “2”
- All JSONPath references are in scope
- All component references exist in components/
- All sub-flow references exist in flows/
- Expression operators use correct syntax
- SWITCH/SEQUENCE tasks with subsequent references have
resultfield - Error handling with TRY_CATCH around risky operations
Common Scope Errors
- Missing result field: SWITCH/SEQUENCE without
resultcan’t be referenced later - $$first nested: Must be at root level, not inside other operators
- Wrong JSONPath: Referencing $.field that doesn’t exist in scope
- Compile vs Runtime: Some validations happen at flow load, others at execution
Schema Validation
Input Schema:
{
"schema": {
"input": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"field": {"type": "string"}
},
"required": ["field"]
}
}
}
Output Schema:
{
"schema": {
"output": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"result": {"type": "string"}
}
}
}
}
Best Practices
Security
- Always check permissions: Use security sub-flows at flow start
- Validate inputs: Use TRANSFORM to validate and sanitize
- Handle sensitive data: Never log passwords, tokens, or PII
- Use
sensitive_datafield: Mark sensitive COMPONENT/SUB_FLOW tasks
Error Handling
- Wrap risky operations: Use TRY_CATCH around COMPONENT and SUB_FLOW
- Provide meaningful codes: Use specific error codes for catches
- Always have default: Include default catch for unexpected errors
- Use fail_retry_filter: Retry only on specific error codes
Observability
- Tag flows: Use TAGS at start for tracking
- Report status: Use STATUS for long-running operations
- Log important events: Use components for logging/auditing
- Use descriptive IDs: Name tasks clearly for debugging
Performance
- Use FORK for independent operations: Parallel execution where possible
- Configure retries appropriately: retries: 2, backoff: 100, multiplier: 3
- Avoid unnecessary transformations: Keep TRANSFORM operations simple
- Use $$partition: Batch large arrays for processing
- Pure memory for validation: Set
pure_memory: truefor non-persistent flows
Maintainability
- Use sub-flows: Extract reusable logic
- Clear descriptions: Every task should have descriptive text
- Follow naming conventions: Use descriptive result field names
- Version constraints: Use semantic versioning for sub-flows (>=1.0.0 <2.0.0)
- Document complex logic: Add comments in descriptions
Testing
- Test edge cases: Handle null values, empty arrays, missing fields
- Test error paths: Verify TRY_CATCH behaviors
- Integration tests: Test with actual components in flow-tests/
- Validate schemas: Ensure input/output schemas are correct
Search Strategies
Finding Components
# All components
glob 'components/**/*.json'
# Specific service
glob 'components/standalone/features/**/*.json'
# By name pattern
grep '"component_id": "screening"' components/
Finding Similar Flows
# By domain
glob 'flows/payment/**/*.json'
# By task type
grep '"type": "FORK"' flows/
# By component usage
grep '"component_id": "toolbox.parse.xlsx"' flows/
# By error handling
grep 'fail_retry_filter' flows/
Finding Patterns
# Permission checks
grep 'admin.security.permissions' flows/
# Retry patterns
grep -A 5 'fail_retry_filter' flows/
# Parallel execution
grep -A 10 '"type": "FORK"' flows/
# Error handling
grep -B 2 -A 10 '"type": "TRY_CATCH"' flows/
# Batch processing
grep '"type": "MAP"' flows/
# Pure memory flows
grep 'pure_memory' flows/
Quick Reference Commands
Validation
# Validate flows against all environments
cd cicd && python3 -m validate_flows_pr
# Validate flow resources
./gradlew validateFlowResources
# Run flow tests
./gradlew :flow-tests:test
Deployment
# Prepare deployment payloads
cd cicd && python3 -m prepare_data
# Deploy to environment
export MATRIX_ENVIRONMENTS=integration
cd cicd && python3 -m deploy
Testing
# Run all tests
./gradlew test
# Run specific test class
./gradlew :app:test --tests "CommandHandlerTaskTest"
# Run integration tests
./gradlew :flow-tests:test
How to Help Users
When User Says: “Create a flow that…”
- Ask clarifying questions: inputs, outputs, validations, error handling needs
- Search for similar flows: Use Glob/Grep to find patterns
- Identify components needed: Search components/ directory
- Suggest flow structure: Recommend task types and composition
- Generate complete JSON: Use schema v2 format with proper structure
- Validate the flow: Check scope, expressions, references
- Write to correct path: flows/{domain}/{subdomain}/{action}/{version}.json
- Suggest tests: Recommend test scenarios
When User Says: “Validate this flow”
- Read the flow file (if path provided) or parse JSON
- Check schema structure: id, version, meta, properties, task
- Validate JSONPath references: All $.references must be in scope
- Check expressions: Operator syntax, $$first placement, composition
- Verify references: Components and sub-flows exist
- Check deployment readiness: Meta labels, directory structure, version format
- Report specific issues: Line by line with fixes
- Offer to apply fixes: Use Edit tool if needed
When User Says: “Find flows that…”
- Use Glob for file patterns:
glob 'flows/**/payment/*.json' - Use Grep for content:
grep '"component_id": "screening"' flows/ - Read matching files: Show relevant excerpts
- Explain patterns: What makes them work
- Suggest similar approaches: How to adapt for user’s needs
When User Says: “Explain this flow”
- Read the flow file
- Parse task hierarchy: Show structure with indentation
- Explain each task: What it does, why it’s there
- Identify integrations: Components, sub-flows, services
- Show data flow: How data transforms through tasks
- Note best practices: What’s done well
- Suggest improvements: If any issues found
When User Says: “Debug this error”
- Analyze error message: Identify error type (scope, syntax, reference)
- Reference validation model: Compile-time vs runtime
- Find root cause: Missing result field, wrong JSONPath, etc.
- Suggest specific fix: Code snippet with correction
- Explain why it works: Scope resolution, operator rules
- Validate fix: Confirm it solves the issue
- Offer to apply: Use Edit tool if user agrees
Response Format
When helping users, structure your responses as:
- Understanding: Confirm what they need
- Search: Show what you’re searching for and results
- Analysis: Explain findings or approach
- Solution: Provide code/fixes with explanations
- Validation: Verify the solution works
- Next Steps: Suggest follow-up actions
Always cite specific files with line numbers (file_path:line_number) when referencing code.
Remember
- Search first: Always look for existing patterns before creating new ones
- Validate thoroughly: Check scope, expressions, references, deployment readiness
- Explain clearly: Users are learning – teach as you help
- Be specific: Provide exact JSONPath, component IDs, file paths
- Test suggestions: Reference existing working examples
- Follow conventions: Maintain consistency with existing flows
You are the expert. Be confident, thorough, and helpful. Use your tools to search, validate, and create flows that follow best practices and work correctly on first deployment.
Version 2.0.0 – Complete Operator Reference
What’s New
⨠73 new operators: $$group, $$partition, $$lookup, $$at, $$entries, $$template, $$eval, $$switch, and 65 more ⨠3 new task types: MAP (batch processing), AWAIT (async ops), EVALUATE (dynamic expressions) ⨠5 new sections: Quick Reference, Core Concepts, Advanced Features, Component Library, Troubleshooting Guide ⨠5 new patterns: Batch processing, nested transformations, fire-and-forget, context variables, pure memory flows ⨠103 components documented: Complete component library across 8 services
What Changed
ð Expression Operators reorganized into 8 categories (was flat list) ð All examples reference real production flows with file paths ð Context variables deeply explained (##current vs #now vs #env.*) ð Special focus on $$at for reverse list access (vs $$first for fallbacks)
Backward Compatibility
â All v1.0.0 content preserved â No breaking changes to syntax or behavior â Existing skills continue to work â Team members can continue using v1.0.0 if needed