Skip to content

Workflow

Verified against source (12)

  • decision/Decision.cs
  • decision/Decision.Fields.cs
  • decision/DecisionStep.cs
  • decision/DecisionStep.Fields.cs
  • decision/DecisionStepTemplate.Fields.cs
  • decision/DecisionTemplate.cs
  • decision/DecisionDelay.cs
  • Config/Decision.config
  • Config/DecisionStep.config
  • Properties/Settings.settings
  • Tables/DecisionStep.sql
  • Tables/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.
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.

Process is the engine. Each pass:

  1. 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 GroupNumber group has at least one completed dependency whose IsTrue matches the dependency’s IsTrue (polling steps match regardless). Estimated dates come from the latest completed dependency plus the step’s duration.
  2. Starts each new step: Async steps are queued (DecisionStep/Start on the step’s Queue, with optional QueueParameters routing and {…} substitution in the queue name); others start inline.
  3. 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.

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.

POST /api/decision/save?Template=Application Review&Object=Contact&ObjectID=42&Output=Xml

The 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.

POST /api/decision/process?ID=310
POST /api/decisionstep/complete?ID=8812
POST /api/decisionstep/complete?ID=8813&IsTrue=0
POST /api/decisionstep/start?ID=8814
GET /api/decision/project?DecisionID=310
  • process runs a processing pass. Use it after changing data a polling or if/then step depends on, or after editing a template.
  • complete marks steps complete (optionally setting the if/then result with IsTrue=1 or 0), applies OnComplete* statuses, and processes the workflow. This is the callback target for asynchronous work.
  • start runs (or re-runs) a step now, clearing an Error status.
  • project returns 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 report
POST /api/decisiondelay/save?ID=55&ActualCompletion=2026-10-05

A 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.

POST /api/decision/restart?ID=310&DecisionStepID=8790&ActualStart=2026-10-05&BodyText=Documents resubmitted
POST /api/decision/skipforward?ID=310&DecisionStepID=4411&BodyText=Completed offline
POST /api/decision/cancel?ID=310
POST /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.
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.
GET /api/decisiontemplate/flowchart?ID=12

Returns 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.