Skip to content

Workflow Engine

SCOPE_ITEM: Configurable workflow system that models business processes as explicit state machines with approval chains, escalation rules, SLA tracking, and notification triggers.

Architecture Overview

┌─────────────────────────────────────────────┐
│  Workflow Definition (admin-configured)      │
│  ┌─────────┐  ┌──────────┐  ┌───────────┐  │
│  │ States  │  │Transitions│  │ Guards    │  │
│  └─────────┘  └──────────┘  └───────────┘  │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│  Workflow Instance (per request/ticket)      │
│  ┌─────────┐  ┌──────────┐  ┌───────────┐  │
│  │ Current │  │ History  │  │ SLA Clock │  │
│  │  State  │  │          │  │           │  │
│  └─────────┘  └──────────┘  └───────────┘  │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│  Side Effects                                │
│  ┌─────────┐  ┌──────────┐  ┌───────────┐  │
│  │ Notify  │  │ Assign   │  │ Webhook   │  │
│  └─────────┘  └──────────┘  └───────────┘  │
└─────────────────────────────────────────────┘

State Machine Definitions

SCOPE_ITEM: Define states and transitions for each workflow type.

State Configuration

INCLUDES: - Named states with display label and colour code. - State categories: initial, in_progress, pending_approval, approved, rejected, completed, cancelled. - Required fields per state (e.g., "reason" required on rejection). - Entry actions (triggered when entering a state). - Exit actions (triggered when leaving a state).

OPTIONAL: - Visual state machine editor (drag-and-drop). - State machine diagram auto-generation (Mermaid). - State machine versioning (new requests use latest version, existing requests continue on their original version).

Transition Rules

INCLUDES: - Allowed transitions per state (whitelist model). - Transition guard conditions (field value checks, role checks). - Transition side effects (notifications, assignments, webhooks). - Transition reason field (optional or required per transition).

OPTIONAL: - Conditional transitions based on form field values. - Automatic transitions on external event (e.g., payment received). - Transition confirmation dialog with custom message.

CHECK: Every workflow must have at least one terminal state. CHECK: Unreachable states must be flagged in validation. CHECK: Circular transitions allowed but infinite loops prevented by maximum transition count per instance (default: 100).

Data Model

-- Workflow type definition
CREATE TABLE workflow_definitions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL,
  version INTEGER NOT NULL DEFAULT 1,
  states JSONB NOT NULL,       -- [{name, label, color, category, required_fields, entry_actions}]
  transitions JSONB NOT NULL,  -- [{from, to, guards, side_effects, requires_reason}]
  is_active BOOLEAN DEFAULT true,
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);

-- Workflow instance
CREATE TABLE workflow_instances (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  definition_id UUID REFERENCES workflow_definitions(id),
  definition_version INTEGER NOT NULL,
  current_state TEXT NOT NULL,
  data JSONB NOT NULL DEFAULT '{}',
  created_by UUID REFERENCES users(id),
  assigned_to UUID REFERENCES users(id),
  sla_deadline TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now()
);

-- Transition history (immutable audit log)
CREATE TABLE workflow_transitions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  instance_id UUID REFERENCES workflow_instances(id),
  from_state TEXT NOT NULL,
  to_state TEXT NOT NULL,
  actor_id UUID REFERENCES users(id),
  reason TEXT,
  metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ DEFAULT now()
);

Approval Chains

SCOPE_ITEM: Multi-level approval routing with configurable approvers.

Sequential Approval

INCLUDES: - Ordered list of approval steps. - Each step has an approver assignment rule: - Named individual — specific user ID. - Role-based — any user with a given role. - Manager hierarchy — reporting line from requester. - Department head — head of requester's department. - Approve or reject action per step. - Rejection at any step returns to requester (configurable).

Parallel Approval

OPTIONAL: - All-must-approve: every approver must approve before proceeding. - Quorum (n-of-m): configurable threshold (e.g., 2 of 3 must approve). - First-response: first approval or rejection is final. - Mixed chains: some steps sequential, some parallel.

Conditional Routing

OPTIONAL: - Route to different approval chains based on field values. IF: amount > 10000. THEN: Add CFO approval step. IF: department = "Engineering". THEN: Route to CTO. IF: risk_level = "high". THEN: Add compliance review step. - Conditions evaluated at runtime, not definition time.

Delegation

OPTIONAL: - Out-of-office delegation (user A delegates to user B for date range). - Permanent delegation (admin delegates on behalf of inactive user). - Delegation chain limit (max 1 hop to prevent responsibility diffusion).

Data Model

CREATE TABLE approval_steps (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  instance_id UUID REFERENCES workflow_instances(id),
  step_order INTEGER NOT NULL,
  approver_rule JSONB NOT NULL,  -- {type: "role"|"manager"|"named", value: "..."}
  assigned_to UUID REFERENCES users(id),
  status TEXT DEFAULT 'pending', -- pending, approved, rejected, skipped
  decided_at TIMESTAMPTZ,
  reason TEXT,
  created_at TIMESTAMPTZ DEFAULT now()
);

Escalation Rules

SCOPE_ITEM: Automatic escalation when approvals or tasks stall.

Time-Based Escalation

INCLUDES: - Escalation timer per approval step (e.g., 24h, 48h, 72h). - Escalation action: notify next-level approver. - Escalation action: notify requester of delay. - Escalation action: notify administrator. - Maximum escalation levels (default: 3).

OPTIONAL: - Auto-approve on timeout (for low-risk items). - Skip-level escalation (jump to department head). - Escalation to distribution group (multiple people notified). - Business hours calendar (escalation timers pause outside hours).

Escalation Implementation

SCOPE_ITEM: Background job checks for overdue steps.

BullMQ scheduled job (runs every 5 minutes)
  └── Query: approval_steps WHERE status = 'pending'
        AND created_at < (now() - escalation_threshold)
        AND escalation_count < max_escalations
  └── For each overdue step:
        1. Increment escalation_count
        2. Resolve next escalation target
        3. Send notification
        4. Log escalation event in workflow_transitions

CHECK: Escalation job must be idempotent (same step not escalated twice). CHECK: Business hours calendar must account for public holidays. CHECK: Escalation notifications must clearly state what is overdue and include a direct link to the approval action.


SLA Tracking

SCOPE_ITEM: Define and monitor service level agreements per workflow.

SLA Definition

INCLUDES: - SLA target per workflow type (e.g., "resolve within 48 business hours"). - SLA clock starts on instance creation (configurable per state). - SLA clock pauses on specific states (e.g., "waiting for requester"). - SLA clock resumes on state exit. - SLA breach threshold (warning at 80%, breach at 100%).

SLA Dashboard

INCLUDES: - Current SLA status per open workflow instance (on-track, at-risk, breached). - SLA compliance rate (percentage met over time period). - Average resolution time by workflow type. - Breach count by team / approver / category.

OPTIONAL: - SLA trend charts (improving or degrading). - Drill-down from dashboard to individual breached items. - SLA reporting export (CSV, PDF).

SLA Data Model

ALTER TABLE workflow_instances ADD COLUMN
  sla_config JSONB DEFAULT '{}';
  -- {target_hours: 48, clock_paused_states: ["waiting_requester"], warning_pct: 80}

CREATE TABLE sla_events (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  instance_id UUID REFERENCES workflow_instances(id),
  event_type TEXT NOT NULL,  -- clock_start, clock_pause, clock_resume, warning, breach
  elapsed_hours NUMERIC,
  created_at TIMESTAMPTZ DEFAULT now()
);

Notification Triggers

SCOPE_ITEM: Automated notifications on workflow events.

Event-Based Notifications

INCLUDES: - Notification on state change (configurable per transition). - Notification recipients: requester, assignee, approver, watchers. - Notification channels: in-app, email. - Notification templates with variable substitution: {{requester_name}}, {{workflow_title}}, {{current_state}}, {{action_url}}, {{due_date}}.

OPTIONAL: - Slack / Microsoft Teams channel notifications. - Webhook notifications to external systems. - Digest notifications (batch multiple events into one email). - Quiet hours (delay non-urgent notifications).

Notification Template Structure

Subject: [{{workflow_type}}] {{title}} — Action Required
Body:
  {{requester_name}} submitted a {{workflow_type}} that requires your approval.
  Title: {{title}}
  Current status: {{current_state}}
  Due by: {{sla_deadline}}

  [View and Approve →]({{action_url}})

CHECK: All notification emails must have unsubscribe/preference link. CHECK: Action URLs must include authentication context (magic link or redirect to SSO).


Custom Forms per Workflow Step

OPTIONAL: SCOPE_ITEM: Different form fields visible/required at different states.

INCLUDES: - Field visibility rules per state (show/hide/readonly). - Required fields per transition (e.g., "rejection reason" required on reject transition). - Dynamic field sets based on workflow type.

IF: Client needs complex conditional forms. THEN: Include form builder module (see feature-tree.md section 3).


Common Workflow Examples

Purchase Order Approval

Draft → Submitted → Manager Review → Finance Review → Approved → Ordered → Received
                  ↘ Rejected (→ back to Draft)
                                    ↘ Rejected (→ back to Draft)

IF: amount < 1000. THEN: Skip Finance Review. IF: amount > 10000. THEN: Add Director approval after Finance.

Leave Request

Draft → Submitted → Manager Approval → HR Notification → Approved
                  ↘ Rejected

Change Request (IT)

Draft → Submitted → Technical Review → CAB Review → Scheduled → Implemented → Verified → Closed
                  ↘ Rejected          ↘ Deferred

Incident Management

New → Triaged → In Progress → Resolved → Closed
             ↘ Escalated → In Progress
                         ↘ Resolved → Verified → Closed

Performance Considerations

CHECK: Index workflow_instances.current_state for dashboard queries. CHECK: Index workflow_instances.assigned_to for "my tasks" queries. CHECK: Index approval_steps(instance_id, status) for pending approvals. CHECK: Transition history table is append-only — partition by month if >1M transitions/month. CHECK: SLA check job should query only open instances with active SLA.


Scoping Questions

CHECK: How many distinct workflow types does the client need? CHECK: What is the maximum number of approval levels? CHECK: Does the client need parallel approval (multiple approvers)? CHECK: Are SLA targets required? What are the business hours? CHECK: Does the client need conditional routing based on field values? CHECK: Should rejected items return to requester or to a specific state? CHECK: Are delegation / out-of-office rules needed? CHECK: What notification channels are required (email, Slack, Teams)? CHECK: How many concurrent open workflow instances are expected?