Workflow
Verified against source (12)
decision/Decision.csdecision/Decision.Fields.csdecision/DecisionStep.csdecision/DecisionStep.Fields.csdecision/DecisionStepTemplate.Fields.csdecision/DecisionTemplate.csdecision/DecisionDelay.csConfig/Decision.configConfig/DecisionStep.configProperties/Settings.settingsTables/DecisionStep.sqlTables/DecisionDelay.sql
Workflows are Decision records; steps are DecisionStep records. Operations follow the standard route pattern:
/api/{module}/{operation}runs synchronously on the web server, for example/api/decision/process./api/{module}/queue/{operation}queues the operation for an app server, for example/api/decision/queue/process.
Classes
Section titled “Classes”| Type | Purpose |
|---|---|
DecisionTemplateObject |
Implements ITemplate. Repeatable (One, OneActive, Many), AppliesTo (maps to Object), EnforceStartDates, EnforceDelay. ExtranetEnabled is always Self. |
DecisionObject |
A workflow on Object / ObjectID. Dates: EstimatedStart/Completion (from templates), ProjectedStart/Completion (user estimates), ActualStart/Completion, CanceledDate. Hold fields: Delayed, DelayCount, DelayDuration. Child links: ParentDecisionStepID. |
DecisionStepTemplateObject |
A step definition: Object + ObjectID (template to instantiate) or Object + Operation + Parameters (operation to call), Method (data source or loop query), StepXml/StepXslt (if/then and polling), DurationScale + EstimatedDuration, ReferenceDate, Repeatability, Queue, Async, QueueParameters, ObjectMatrixID, MonitorScheduleID, CreateOnCompletion, OnStart*/OnComplete* status fields. |
DecisionStepObject |
A step instance. Object / ObjectID point to what the step created; IsTrue holds an if/then result; ErrorDate / ErrorGUID record failures. |
DecisionDependencyObject |
DecisionStepTemplateID depends on DependencyStepTemplateID, optionally when IsTrue matches, combined by GroupNumber. |
DecisionDelayTemplateObject / DecisionDelayObject |
Hold definitions and holds on a DecisionID. |
DurationScale: 0 days, 1 hours, 2 minutes, 3 seconds, 4 months, 5 years, 6 business days. Step Repeatability: 1 one, 2 multiple, 0 ad-hoc.
Processing model
Section titled “Processing model”Process is the engine. Each pass:
- Inserts every step whose template isn’t yet on the workflow, isn’t ad-hoc, and whose dependencies are satisfied. A step is ready when each
GroupNumbergroup has at least one completed dependency whoseIsTruematches the dependency’sIsTrue(polling steps match regardless). Estimated dates come from the latest completed dependency plus the step’s duration. - Starts each new step:
Asyncsteps are queued (DecisionStep/Starton the step’sQueue, with optionalQueueParametersrouting and{…}substitution in the queue name); others start inline. - Repeats while steps keep completing inline. When no step was inserted and none is pending, the workflow is completed (
ActualCompletion), its parent step (if it’s a child workflow) is completed, and any callbacks waiting on it are released.
Completed and canceled workflows are ignored. A new workflow processes on insert (setting DecisionProcessOnInsert, default true); if its ActualStart is in the future, processing is queued for that date.
How a step runs
Section titled “How a step runs”| Step shape | Behavior |
|---|---|
StepXml set, type Polling |
Evaluates StepXslt against the Method output (or the parent’s summary). 1 completes the step with IsTrue = true; otherwise status Pending and a re-check is queued per MonitorScheduleID. |
StepXml set, other type |
If/then: evaluates StepXslt, sets IsTrue (1 is true), completes. |
Template object, no Operation |
Calls ITemplate.CreateInstance with Object, ObjectID, TemplateID, DecisionStepID, ParentDecisionID, the step’s dates, and substituted Parameters. With ObjectMatrixID, the matrix’s TemplateName output picks the template, and outputs prefixed {Instance}_ are passed through. If the instance type has an ActualCompletion field (such as tasks and child workflows) the step waits for it; otherwise it completes immediately. |
Operation, no Method |
Invokes {Object}/{Operation} with substituted Parameters. Async operations leave the step Pending and call back DecisionStep/Complete when done. |
Operation with Method |
Loops: runs Method and invokes the operation once per row (parallel, throttled by BatchStepTheadCount). With BatchLog, the step stays Pending until the batch finishes. If Method returns XML or JSON, its output is used for parameter substitution instead. |
CreateOnCompletion completes a step as soon as it starts (fire and forget). Step statuses you’ll see: Started, Queued, Pending, Complete, Error, Canceled, Reprocessing.
A failed step is saved with Status = Error, ErrorDate, and an ErrorGUID that matches the error log entry. By default (DecisionProcessErrorThrow) the exception is also re-thrown to the caller.
Start a workflow
Section titled “Start a workflow”POST /api/decision/save?Template=Application Review&Object=Contact&ObjectID=42&Output=XmlThe template’s Repeatable rule applies: with One or OneActive, saving against a parent that already has a matching workflow selects it instead of inserting. Workflows also start from a process template or a “Launch a Workflow” step.
Drive a workflow
Section titled “Drive a workflow”POST /api/decision/process?ID=310POST /api/decisionstep/complete?ID=8812POST /api/decisionstep/complete?ID=8813&IsTrue=0POST /api/decisionstep/start?ID=8814GET /api/decision/project?DecisionID=310processruns a processing pass. Use it after changing data a polling or if/then step depends on, or after editing a template.completemarks steps complete (optionally setting the if/then result withIsTrue=1or0), appliesOnComplete*statuses, and processes the workflow. This is the callback target for asynchronous work.startruns (or re-runs) a step now, clearing anErrorstatus.projectreturns the steps that exist and those projected to come, with estimated dates, for timelines.
POST /api/decisiondelay/save?DecisionID=310&DecisionDelay=Awaiting Third Party&ReasonDetail=Waiting on inspection reportPOST /api/decisiondelay/save?ID=55&ActualCompletion=2026-10-05A hold template is resolved by name within the workflow’s Object (or pass DecisionDelayTemplateID). If the template has a task, its form is created with the hold, and other parameters are passed to it. OnStartParentStatus updates the parent’s status. A database trigger maintains Delayed, DelayCount, and DelayDuration on the workflow and its in-progress steps. While Delayed is set, a check constraint prevents completing those steps unless the template’s EnforceDelay is false.
Restart, skip forward, cancel
Section titled “Restart, skip forward, cancel”POST /api/decision/restart?ID=310&DecisionStepID=8790&ActualStart=2026-10-05&BodyText=Documents resubmittedPOST /api/decision/skipforward?ID=310&DecisionStepID=4411&BodyText=Completed offlinePOST /api/decision/cancel?ID=310POST /api/decision/reactivate?ID=310| Operation | Behavior |
|---|---|
restart |
Requires ID, DecisionStepID (a completed step instance), and BodyText; ActualStart defaults to now. Fails if a hold is open. Cancels the workflow with status Restart, creates a new one with the same parent and template, copies every step except those downstream of DecisionStepID (the step itself is kept), logs a message, and queues process on the new workflow (optional QueueName). Returns the new workflow. |
skipforward |
Requires ID and BodyText. DecisionStepID here is a step template ID. Creates and completes that step and all its upstream steps, completes in-progress steps, logs a message, and queues process. |
cancel |
Sets CanceledDate and status (Canceled, or Status if passed) on the workflow and its unfinished steps, and cancels their open tasks and worklist items. KeepImportForm=1 detaches tasks instead. |
reactivate |
Clears CanceledDate and ActualCompletion and sets status Reactivated. Call process afterward. |
Recovery
Section titled “Recovery”| Operation | Use |
|---|---|
/api/decision/reprocess |
For the selected workflows (ID), resets steps of DecisionStepTemplateID and queues them. ProcessTime=ProcessFuture with QueueUnit and QueueScale delays the run. Re-activates completed workflows. |
/api/decisionstep/errorrequeue |
Re-queues incomplete steps of DecisionStepTemplateID created between StartDate and EndDate, skipping workflows that are complete, canceled, or on hold. |
/api/decisionstep/stalledstepsrequeue |
Re-queues steps with no status or stuck in Queued for more than AgeMinutes (default 10) that have no live queue message. |
/api/decision/backfill |
Starts eligible steps, completes those that have a ProjectedCompletion as of that date, then queues process. Useful when loading work that is already in flight. |
Templates as code
Section titled “Templates as code”GET /api/decisiontemplate/flowchart?ID=12Returns a Mermaid flowchart of the template’s steps and dependencies. Templates can be copied (copy) and exported, and bulk-loaded through imports using SubscriberID values so re-imports update rather than duplicate.