Building an Entity-Trigger Workflow
In this lesson you will scaffold a real workflow that validates an Order before it is saved, add a configuration variable, a validation step, a logging activity, and a failure handler. You will then deploy it, trigger it, and read the logs.
By the end you will have a working Before-trigger workflow that blocks invalid Order saves and logs every execution.
Step 1: Scaffold the Workflow
Use the entity-trigger template. Place it in a feature folder for the orders domain:
bash1npx cxtms create workflow order-status-validator \2 --template entity-trigger \3 --feature orders
The CLI creates:
features/orders/workflows/order-status-validator.yaml
Open the generated file and read through it before making any changes. Notice:
workflowIdis already set to a UUID — do not change this.filePathmatches the file location — do not change this either.- There is a placeholder entity trigger, a sample activity, and event handlers.
executionModeisSync— correct for a Before trigger.
Step 2: Configure the Workflow Metadata
Update the workflow section with a meaningful name, description, and log level:
yaml1workflow:2 workflowId: "<uuid from scaffold>" # Keep as generated3 name: "Order Status Validator"4 description: "Validates that an Order status transition is allowed before saving"5 version: "1.0"6 executionMode: Sync7 logLevel: Information8 isActive: true9 enableAudit: true10 filePath: "features/orders/workflows/order-status-validator.yaml"11 tags: ["orders", "validation"]
Step 3: Configure the Before Trigger
Replace the scaffold's placeholder trigger with a concrete Before-Modified trigger on the Order entity. Add a condition so the workflow only fires when the status field is part of the change:
yaml1triggers:2 - type: Entity3 entityName: "Order"4 eventType: Modified5 position: Before6 name: OrderStatusChanged7 conditions:8 - expression: "[changes.status?] != null"
This condition prevents the workflow from running on saves that only change unrelated fields like notes or estimated delivery.
Step 4: Add a Configuration Variable
Your workflow needs to know which statuses are considered valid transition targets. Store this in app configuration so it can be changed without redeploying the workflow:
yaml1variables:2 - name: allowedStatuses3 fromConfig: "apps.orderValidation.allowedStatuses"
In a real project, the configuration entry would be a JSON array: ["Pending", "Processing", "Dispatched", "Delivered", "Cancelled"]. The variable is loaded once at workflow startup.
Step 5: Build the Validation Activity
Replace the scaffold's placeholder activity. Name it Validate and add a Validation/Validate@1 step that checks the new status value:
yaml1activities:2 - name: Validate3 steps:4 - task: "Validation/Validate@1"5 name: CheckStatusTransition6 inputs:7 rules:8 - field: "status"9 condition: "isNullOrEmpty([entity.status?]) = false"10 message: "Status cannot be empty"11 - field: "status"12 condition: "[entity.status?] != 'Unknown'"13 message: "Status 'Unknown' is not a valid transition target"
The Validation/Validate@1 task evaluates each rule and, if any rule fails, throws a validation error that stops the save. The error message is returned to the UI so the user sees a meaningful explanation.
Access the entity being saved via entity.fieldName — for Before triggers, entity reflects the proposed new values (after the user's edits, before the database write).
Step 6: Add a Logging Activity
Add a second activity to log a confirmation message after validation passes:
yaml1 - name: Log2 steps:3 - task: "Utilities/Log@1"4 name: LogValidationPassed5 inputs:6 message: "Order {{ entity.orderNumber }} status transition to '{{ entity.status }}' validated successfully"7 level: Information
Because activities are sequential, Log only runs if Validate completes without error. If validation fails, the workflow stops at the Validate activity and the Log activity is never reached.
Step 7: Add an onWorkflowFailed Handler
Add a workflow-level failure handler so errors are recorded with context:
yaml1events:2 onWorkflowFailed:3 - task: "Utilities/Log@1"4 name: LogFailure5 inputs:6 message: "Order status validation failed for Order {{ entity.orderNumber }}: {{ exception.message }}"7 level: Error
This handler fires whenever the workflow stops due to an unhandled error — including validation failures thrown by Validation/Validate@1. The exception.message variable contains the error detail.
Step 8: The Complete Workflow
Your finished YAML should look like this (with the actual UUID from the scaffold):
yaml1workflow:2 workflowId: "<uuid from scaffold>"3 name: "Order Status Validator"4 description: "Validates that an Order status transition is allowed before saving"5 version: "1.0"6 executionMode: Sync7 logLevel: Information8 isActive: true9 enableAudit: true10 filePath: "features/orders/workflows/order-status-validator.yaml"11 tags: ["orders", "validation"]1213variables:14 - name: allowedStatuses15 fromConfig: "apps.orderValidation.allowedStatuses"1617triggers:18 - type: Entity19 entityName: "Order"20 eventType: Modified21 position: Before22 name: OrderStatusChanged23 conditions:24 - expression: "[changes.status?] != null"2526activities:27 - name: Validate28 steps:29 - task: "Validation/Validate@1"30 name: CheckStatusTransition31 inputs:32 rules:33 - field: "status"34 condition: "isNullOrEmpty([entity.status?]) = false"35 message: "Status cannot be empty"36 - field: "status"37 condition: "[entity.status?] != 'Unknown'"38 message: "Status 'Unknown' is not a valid transition target"3940 - name: Log41 steps:42 - task: "Utilities/Log@1"43 name: LogValidationPassed44 inputs:45 message: "Order {{ entity.orderNumber }} status transition to '{{ entity.status }}' validated successfully"46 level: Information4748events:49 onWorkflowFailed:50 - task: "Utilities/Log@1"51 name: LogFailure52 inputs:53 message: "Order status validation failed for Order {{ entity.orderNumber }}: {{ exception.message }}"54 level: Error
Step 9: Validate the YAML
Always validate before deploying:
bash1npx cxtms features/orders/workflows/order-status-validator.yaml
The validator checks against the JSON schema — it will flag missing required fields, incorrect task names, and type mismatches. Fix any reported errors before proceeding.
Step 10: Deploy to the Server
bash1npx cxtms workflow deploy features/orders/workflows/order-status-validator.yaml --org 42
The CLI creates or updates the workflow on the CX server using the workflowId to identify it. The output confirms the deployment status.
Step 11: Test the Trigger
Open the CXTMS UI, find any Order, and try to save it with status set to Unknown. The save should be blocked with the validation message.
Then save with a valid status — the save should succeed and the Log step should record a confirmation message.
For a manual test without the UI, use the CLI with explicit inputs. Note that entity trigger workflows cannot be executed manually via the CLI in Before mode (there is no entity to provide) — use a Manual trigger workflow for CLI testing during development.
Step 12: Check the Logs
List recent executions:
bash1npx cxtms workflow logs features/orders/workflows/order-status-validator.yaml --org 42
Download and view a specific execution log:
bash1npx cxtms workflow log <executionId> --org 42 --console
The log shows each activity and step with timestamps, inputs, outputs, and any errors. The --json flag provides structured data including exact input and output values per step:
bash1npx cxtms workflow log <executionId> --org 42 --json --console
Summary
In this lesson you:
- Scaffolded a workflow with
npx cxtms create workflow --template entity-trigger - Configured a
Beforetrigger onOrder Modifiedwith achanges.statuscondition - Added a
fromConfigvariable for app-managed configuration - Built a
Validation/Validate@1step to block invalid status transitions - Added a
Logactivity that runs only when validation passes - Added an
onWorkflowFailedhandler to capture error context - Validated the YAML with
npx cxtms <file.yaml> - Deployed with
npx cxtms workflow deploy - Verified execution through the UI and inspected logs with
npx cxtms workflow logsandnpx cxtms workflow log