Creating WorkflowsPreview

Workflows are defined using Terraform or CUE. This approach provides version control, reproducibility, and integration with other platform services.

Directory Structure

terraform/
├── workflow.tf          # Workflow definitions
├── scripts/
│   └── workflow/
│       ├── validate_order.js
│       ├── check_inventory.js
│       └── process_payment.js
└── variables.tf
services/workflow/
├── workflow.cue         # Workflow definitions
├── job_functions/
│   ├── order/
│   │   ├── validate.cue
│   │   └── check_inventory.cue
│   └── payment/
│       └── process.cue
└── script/
    └── workflow/
        ├── order/
        │   ├── validate.js
        │   └── check_inventory.js
        └── payment/
            └── process.js

Defining Job Functions

Each job function is defined as a separate resource:

<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_workflow_job_function&quot; &quot;validate_order&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_workspace.main.id</span></span>
<span><span style="color: var(--shiki-color-text)">  name         </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;validate-order&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  script       </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">file(</span><span style="color: var(--shiki-token-string-expression)">&quot;</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-string-expression)">path</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-string-expression)">module</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/scripts/workflow/validate_order.js&quot;</span><span style="color: var(--shiki-token-function)">)</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_workflow_job_function&quot; &quot;check_inventory&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_workspace.main.id</span></span>
<span><span style="color: var(--shiki-color-text)">  name         </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;check-inventory&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  script       </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">file(</span><span style="color: var(--shiki-token-string-expression)">&quot;</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-string-expression)">path</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-string-expression)">module</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/scripts/workflow/check_inventory.js&quot;</span><span style="color: var(--shiki-token-function)">)</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_workflow_job_function&quot; &quot;process_payment&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_workspace.main.id</span></span>
<span><span style="color: var(--shiki-color-text)">  name         </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;process-payment&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  script       </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">file(</span><span style="color: var(--shiki-token-string-expression)">&quot;</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-string-expression)">path</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-string-expression)">module</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">/scripts/workflow/process_payment.js&quot;</span><span style="color: var(--shiki-token-function)">)</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Properties:

  • workspace_id (String, Required) - Workspace ID
  • name (String, Required) - Job function name (unique within workspace)
  • script (String, Required) - JavaScript code
  • version (Number, Computed) - Version number (auto-incremented by server)
<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> order</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">ValidateOrder: {</span></span>
<span><span style="color: var(--shiki-color-text)">  Name:       </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">validate-order</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  ScriptPath: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">./script/workflow/order/validate.js</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

job_functions/order/check_inventory.cue:

<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> order</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">CheckInventory: {</span></span>
<span><span style="color: var(--shiki-color-text)">  Name:       </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">check-inventory</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  ScriptPath: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">./script/workflow/order/check_inventory.js</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Defining Workflows

Create a workflow that references the job functions:

<span><span style="color: var(--shiki-color-text)">resource </span><span style="color: var(--shiki-token-string-expression)">&quot;tailor_workflow&quot;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;order_processing&quot;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id           </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">tailor_workspace</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">main</span><span style="color: var(--shiki-color-text)">.id</span></span>
<span><span style="color: var(--shiki-color-text)">  name                   </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;order-processing&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  main_job_function_name </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;validate-order&quot;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  job_functions </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;validate-order&quot;</span><span style="color: var(--shiki-color-text)">  = tailor_workflow_job_function.validate_order.version</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;check-inventory&quot;</span><span style="color: var(--shiki-color-text)"> = tailor_workflow_job_function.check_inventory.version</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;process-payment&quot;</span><span style="color: var(--shiki-color-text)"> = tailor_workflow_job_function.process_payment.version</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Properties:

  • workspace_id (String, Required) - Workspace ID
  • name (String, Required) - Workflow name (unique within workspace)
  • main_job_function_name (String, Required) - Entry point job function name
  • job_functions (Map of Number, Required) - Map of job function names to version numbers

workflow.cue:

<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> workflow</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">github.com/tailor-platform/tailorctl/schema/v2/workflow</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/myapp/services/workflow/job_functions/order</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/myapp/services/workflow/job_functions/payment</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">)</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">workflow.#Spec </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  JobFunctions: [</span></span>
<span><span style="color: var(--shiki-color-text)">    order.ValidateOrder</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    order.CheckInventory</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    payment.ProcessPayment</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  Workflows: [</span></span>
<span><span style="color: var(--shiki-color-text)">    {</span></span>
<span><span style="color: var(--shiki-color-text)">      Name:                </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">order-processing</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">      MainJobFunctionName: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">validate-order</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">      JobFunctions: [</span></span>
<span><span style="color: var(--shiki-color-text)">        {name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">validate-order</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">        {name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">check-inventory</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">        {name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">process-payment</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      ]</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Schema:

  • JobFunctions - Array of job function definitions
    • Name (String, Required) - Job function name
    • Script (String, Optional) - Inline JavaScript code
    • ScriptPath (String, Optional) - Path to JavaScript file
  • Workflows - Array of workflow definitions
    • Name (String, Required) - Workflow name
    • MainJobFunctionName (String, Required) - Entry point function name
    • JobFunctions - Array of job function references
      • name (String, Required) - Job function name
      • version (Number, Optional) - Specific version (defaults to latest)

Versioning

Job functions are automatically versioned:

  • When a job function's script changes, a new version is created
  • Unchanged scripts reuse the existing version
  • Workflows can reference specific versions or always use the latest

Managing Workflows

List workflows:

<span><span style="color: var(--shiki-token-function)">tailorctl</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workspace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workflow</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">list</span></span>
<span></span>

Get workflow details:

<span><span style="color: var(--shiki-token-function)">tailorctl</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workspace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workflow</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">get</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">--workflow-name</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">my-workflow</span></span>
<span></span>

Delete a workflow:

<span><span style="color: var(--shiki-token-function)">tailorctl</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workspace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workflow</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">delete</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">--workflow-name</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">my-workflow</span></span>
<span></span>

Export to Terraform:

<span><span style="color: var(--shiki-token-function)">tailorctl</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">workspace</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">-o</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">terraform</span></span>
<span></span>

Writing Job Functions

Job functions are JavaScript functions that form the building blocks of your workflow. Each job function is written using the ES6 export syntax:

<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">main</span><span style="color: var(--shiki-color-text)">(args) {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Your code here</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> { result</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;success&quot;</span><span style="color: var(--shiki-color-text)"> };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Function signature:

  • Input: args object (already JSON parsed)
  • Output: JSON-serializable object

Calling other job functions

Use tailor.workflow.triggerJobFunction() to call other job functions within your workflow:

<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">main</span><span style="color: var(--shiki-color-text)">(args) {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Call another job function</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">result</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">tailor</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">workflow</span><span style="color: var(--shiki-token-function)">.triggerJobFunction</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;otherFunction&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    param1</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;value1&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    param2</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.inputData</span></span>
<span><span style="color: var(--shiki-color-text)">  });</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    processed</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> result</span></span>
<span><span style="color: var(--shiki-color-text)">  };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Parameters:

  • First argument: Name of the job function to call
  • Second argument: Input arguments (object)

Return value:

  • The result returned by the called function

Example: Multi-step workflow

Here's a complete example showing how to compose multiple job functions:

<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">main</span><span style="color: var(--shiki-color-text)">(args) {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">console</span><span style="color: var(--shiki-token-function)">.log</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Starting workflow with orderId:&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.orderId);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Step 1: Fetch order data</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">order</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">tailor</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">workflow</span><span style="color: var(--shiki-token-function)">.triggerJobFunction</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;fetchOrder&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    orderId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.orderId</span></span>
<span><span style="color: var(--shiki-color-text)">  });</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Step 2: Validate order</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">validated</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">tailor</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">workflow</span><span style="color: var(--shiki-token-function)">.triggerJobFunction</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;validateOrder&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> order);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Step 3: Process payment</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">payment</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">tailor</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">workflow</span><span style="color: var(--shiki-token-function)">.triggerJobFunction</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;processPayment&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    orderId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">validated</span><span style="color: var(--shiki-color-text)">.id</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    amount</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">validated</span><span style="color: var(--shiki-color-text)">.total</span></span>
<span><span style="color: var(--shiki-color-text)">  });</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Step 4: Send confirmation</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">tailor</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">workflow</span><span style="color: var(--shiki-token-function)">.triggerJobFunction</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;sendConfirmation&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    orderId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">validated</span><span style="color: var(--shiki-color-text)">.id</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    email</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">validated</span><span style="color: var(--shiki-color-text)">.customerEmail</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    paymentId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">payment</span><span style="color: var(--shiki-color-text)">.id</span></span>
<span><span style="color: var(--shiki-color-text)">  });</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    success</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    orderId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">validated</span><span style="color: var(--shiki-color-text)">.id</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    paymentId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">payment</span><span style="color: var(--shiki-color-text)">.id</span></span>
<span><span style="color: var(--shiki-color-text)">  };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">main</span><span style="color: var(--shiki-color-text)">(args) {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">console</span><span style="color: var(--shiki-token-function)">.log</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Fetching order:&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.orderId);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Simulate fetching from API</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    id</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.orderId</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    customerEmail</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;customer@example.com&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    items</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> [{ name</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Product A&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> price</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">100</span><span style="color: var(--shiki-color-text)"> }]</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    total</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">100</span></span>
<span><span style="color: var(--shiki-color-text)">  };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">main</span><span style="color: var(--shiki-color-text)">(args) {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">console</span><span style="color: var(--shiki-token-function)">.log</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Validating order:&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.id);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.items </span><span style="color: var(--shiki-token-keyword)">||</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">items</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">length</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">===</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Order has no items&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.customerEmail) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Customer email is required&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> args; </span><span style="color: var(--shiki-token-comment)">// Return validated order</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Error Handling

Throw errors to mark a job function as failed:

<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">main</span><span style="color: var(--shiki-color-text)">(args) {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-token-constant)">args</span><span style="color: var(--shiki-color-text)">.requiredField) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;requiredField is missing&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">try</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// Risky operation</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">result</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">performOperation</span><span style="color: var(--shiki-color-text)">();</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> { success</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> result };</span></span>
<span><span style="color: var(--shiki-color-text)">  } </span><span style="color: var(--shiki-token-keyword)">catch</span><span style="color: var(--shiki-color-text)"> (error) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">`Operation failed: </span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-constant)">error</span><span style="color: var(--shiki-color-text)">.message</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

When an error occurs:

  • The workflow execution is marked as failed
  • The error message and stack trace are saved
  • The workflow can be resumed using the resume command

Logging

Use console.log() for logging:

<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">main</span><span style="color: var(--shiki-color-text)">(args) {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">console</span><span style="color: var(--shiki-token-function)">.log</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Processing started&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">console</span><span style="color: var(--shiki-token-function)">.log</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Input:&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">JSON</span><span style="color: var(--shiki-token-function)">.stringify</span><span style="color: var(--shiki-color-text)">(args));</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Your code</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">console</span><span style="color: var(--shiki-token-function)">.log</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Processing completed&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> { status</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;done&quot;</span><span style="color: var(--shiki-color-text)"> };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>