Implement Conditional Logic
Guides: Implement Conditional Logic (inclusionCondition)
Real-world business processes often have branches – steps or documents that are only included if certain conditions are met. SignStack handles this using the inclusionCondition property, a powerful feature that makes your Blueprints dynamic and adaptive.
This guide explains how to use inclusionCondition with JSONata expressions to control your workflow's path based on your Entities data.
The inclusionCondition Property
The inclusionCondition is an optional property you can add to:
-
BlueprintDocument: To conditionally include a document in the workflow. -
BlueprintStep: To conditionally include a step (and all its children) in the workflow.
How it Works:
-
JSONata Expression: You provide a JSONata expression string as the value for
inclusionCondition. -
Context: This expression is evaluated against the current
EntityContextat the moment the workflow engine is deciding whether to include the document or start the step. -
Boolean Result: The expression must evaluate to a boolean (
trueorfalse).-
If
true, the document or step is included/executed. -
If
false, the document or step is skipped entirely.
-
Example 1: Conditionally Including a Document
Let's modify our "SaaS Subscription Agreement" Blueprint. We only want to include the SLAAddendum document if the customer is on the "Enterprise" plan.
Blueprint (documents array):
"documents": [
{
"key": "mainAgreement",
"displayName": "SaaS Subscription Agreement",
"docTemplateKey": "saasAgreementTplV1",
// ... roleMapping, entityMapping ...
},
{
"key": "slaAddendum",
"displayName": "Service Level Agreement Addendum",
"docTemplateKey": "slaAddendumTplV1",
// ... roleMapping, entityMapping ...
"inclusionCondition": "entities.subscriptionPlan.planName = 'Enterprise'" // <-- THE CONDITION
}
],
-
Logic: When a
Workflowis created from thisBlueprint, the engine evaluates theinclusionCondition. If theplanNameproperty within thesubscriptionPlanentity (provided in theentityData) is exactly "Enterprise", theslaAddendumdocument will be included. Otherwise, it will be omitted.
Example 2: Conditionally Including an Approval Step (Using Multiple Entities)
Let's enhance a sales contract workflow. An extra "VP Approval" step is only required if the deal value is high and the client has a high internal risk score. This demonstrates combining data from multiple entities.
Blueprint (steps array - simplified sequential):
"steps": [
{
"key": "root",
"stepType": "CONTAINER",
"executionMode": "SEQUENTIAL",
"children": ["salesRepStep", "managerApprovalStep", "vpApprovalStep", "finalStep"]
},
{
"key": "salesRepStep",
// ... config ...
},
{
"key": "managerApprovalStep",
// ... config ...
// Assume this step might update clientInfo.riskScore
},
{
"key": "vpApprovalStep",
"stepType": "PARTICIPANT_TASK",
"name": "VP Final Approval",
"roleKey": "vpRole",
// This condition uses data from TWO entities: dealInfo and clientInfo
"inclusionCondition": "entities.dealInfo.value > 100000 and entities.clientInfo.riskScore = 'HIGH'", // <-- THE CONDITION
"links": [ /* Links for VP signature */ ]
},
{
"key": "finalStep",
// ... config ...
}
]
-
Logic: After the
managerApprovalStepcompletes, the engine evaluates theinclusionConditionforvpApprovalStep. It checks both thevaluein thedealInfoentity and theriskScorein theclientInfoentity. Only if the deal is over $100,000 AND the client's risk score is marked as 'HIGH' will thevpApprovalSteprun. Otherwise, it will be skipped, and the workflow will proceed directly tofinalStep.
Best Practices
-
Keep it Simple: While JSONata is powerful, aim for clear and focused conditions.
-
Encapsulate Complexity with Functions: If your condition involves complex logic or needs to be reused across multiple steps or
Blueprints, consider encapsulating that logic within a Custom Function. This keeps yourinclusionConditionclean and readable (e.g.,$should_vp_approve(entities.dealInfo, entities.clientInfo)). -
Ensure Data Exists: Verify the entity data needed for your condition is available in the
EntityContextbefore the condition is evaluated. UserootEntitySlotKeysor ensure preceding steps gather the required data viaonCompleteMappers. -
Test Thoroughly: Use
Scenarioswith different data sets to confirm your conditional logic behaves correctly in all branches.
The inclusionCondition is fundamental for creating dynamic, intelligent Blueprints that adapt to the specific data of each transaction.
➡️ Next: Guides: Map Data with onCompleteMappers