Skip to content
bitzorcas
中EN

Concept

Workflow developer manual

Source-verified navigation from the visual designer and JSON DSL through deployment, runtime, tasks, notifications, history, migration, embedding, and operations.

Last updated

This manual explains what the current code does, how consumers integrate it, and what facts remain after failure. Workflow fits human approval, countersignature, conditional routing, escalation, and business-state coordination. It is not a general distributed transaction orchestrator and does not replace a Saga or Outbox.

1. Product fit

RequirementGuidance
Approval, rejection, transfer, multi-signature, and trailUse Workflow
Tenant or office-specific approval versionsUse deployment bindings
A simple single-aggregate state machinePrefer the domain aggregate
Cross-service compensation and exactly-once messagingDesign Saga/Outbox first
Full BPMN 2.0 XML interoperabilityNot supported by this engine

2. Reading map

Architecture and boundaries

JSON definition DSL

Visual design, drafts, validation

Deployment and rollback

Runtime instances

Tasks and candidates

Notifications / history / analytics

Migration / standalone embedding

API, tests, operations, GA

GoalChapter
Understand Framework, Platform, Host, and adaptersArchitecture
Author executable nodes, edges, and assigneesDefining workflows
Use server schema, AOT metadata, revisioned drafts, and path simulationVisual designer
Publish and understand real grayscale semanticsDeployment
Start, approve, reject, withdraw, and controlRunning instances
Todo, done, candidates, read markers, and cacheTask management
Trail, archive, reports, and precision limitsHistory and analytics
Reconstruct legacy in-flight workMigration and import
Recipients, templates, preferences, and failureNotification pipeline
Routes and errorsAPI reference
Embed in another productStandalone embedding

3. Instance lifecycle

Start / StartAtNode / ImportSuspend (sub-state)ResumeComplete / Reject /Transfer / Delegatereaches EndEventCancel and WithdrawResubmitTerminateArchiveArchiveArchive

Running

Suspended

Completed

Cancelled

Terminated

Archived

States come from the engine enum ProcessInstanceStatus: Running / Completed / Cancelled / Terminated / Suspended — there are no business-facing enum values like Withdrawn or Approved. The engine keeps a two-field model: Status carries the machine state above; a withdrawal maps to Cancelled while the string BusinessStatus records Draft / InProcess / Active, etc.; FlowState encodes the trail as node prefix plus tail letter (ABW = node B pending). Business code should test BusinessStatus == "Active" for “approved”, never an enum value.

Start snapshots DefinitionId, DefinitionVersion, TenantId, OfficeId, StarterId, and BusinessKey. TokenExecutor runs node behavior. UserTask creates work and suspends an Execution. Completion resumes the Execution, selects edges, updates FlowState/BusinessStatus, and appends an activity record.

4. Minimal business integration

Submit a matter for approval
public async Task<Result<string>> SubmitAsync(
MatterIntake matter,
string trustedUserId,
string trustedTenantId,
CancellationToken cancellationToken)
{
// Pre-submit rules stay owned by the MatterIntake aggregate:
// parties complete, initial conflict check passed.
if (!matter.CanSubmitForApproval())
return Result.Failure<string>("Matter.IntakeInvalid");
var started = await transitions.StartAsync(
"matter-intake-approval",
matter.MatterNo,
"MatterIntake",
trustedUserId,
trustedTenantId,
matter.OfficeId,
new Dictionary<string, object?>
{
["disputeAmount"] = matter.DisputeAmount,
["crossBorder"] = matter.IsCrossBorder
},
cancellationToken);
// No client idempotency key exists; reconcile by business key after timeout.
return started.IsSuccess
? Result.Success(started.Value.Id)
: Result.Failure<string>(started.Error.Code);
}

5. Three distinct authorization layers

Layer one is HTTP authentication, rate limiting, and timeout. Layer two is IAuthorizedRequest module/resource/action authorization. Layer three is engine View/Operate/Manage data permission. Candidate membership assigns responsibility; it does not grant unrestricted access to the business object.

WorkflowPermissions strings are governance catalog facts (actual authorization comes from ResourceDescriptor and AuthorizationAction). The workflow.runtime feature is enforced: WorkflowRuntimeLicenseGuard evaluates it via ILicenseGate before every workflow write and every background job, fail-closed.

6. Meaning of success

  • Transactional instance, execution, task, and trail writes completed.
  • Notification persistence rides the same fact chain: the INotificationChannel implementation writes per-recipient inbox entries plus a CAP Outbox row and throws when any recipient fails; the dispatcher logs and rethrows. A committed command therefore proves notifications were persisted — external delivery stays asynchronous in the Notifications module.
  • Listener exceptions are no longer silently isolated: EventDispatcher logs and rethrows, failing the whole write. Custom listeners must be designed to transactional semantics.
  • Timer processed count means iterated records, not successful actions.
  • BatchComplete marks tasks completed without advancing the process.

7. Pre-production evidence

Exercise both ORMs, duplicate completion, parallel gateways, candidate refresh, cross-tenant denial, publish races, timer crash windows, notification and callback failure, interrupted import, archive orphans, large reports, and cache invalidation. Every drill needs a reproducible command, expected database state, alert, and recovery step.

8. Current implementation boundaries

workflow.runtime is now enforced before runtime writes and background jobs; it is no longer a catalog-only gap. The visual designer also has an end-to-end server schema, AOT business metadata, optimistic draft revisions, validation, simulation, and publication flow.

Boundaries that still need explicit acceptance include the legacy direct deployment endpoint not running the designer’s full validation, simulation previewing only one reachable path, browser crash snapshots being keyed by tenant plus definition key rather than user, and external delivery confirmation depending on the Notifications module’s Outbox consumer (standalone hosts rolling their own channel get whatever durability they build). Validate timer, import, archive, and concurrency SLOs against their current chapters and release-candidate tests rather than carrying forward an old blocker list.

9. Learning path

First use the visual designer to build a three-node approval and run save, validate, simulate, publish, start, and complete. Add an exclusive gateway, then parallel signatures, transfer, and timeout. Finally drill notification failure, concurrent completion, and interrupted import while inspecting Instance, Execution, Task, ActivityRecord, and TimerJob.

10. Source entry points

Terminal window
rg --files src/Framework/BitzOrcas.Workflow src/Platform/Workflow src/Hosts/BitzOrcas.Api/Endpoints/Workflow
rg --files tests | rg 'Workflow|workflow'

Back to Workflow module


Chapter Navigation

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%