Workflow Metadata
Use Flow for automation and state machines for strict lifecycle transitions.
Workflow Metadata
ObjectStack no longer has a standalone Salesforce-style Workflow Rule authoring type. Use:
- Flow for event-triggered or scheduled automation.
- State machine metadata for strict lifecycle transitions.
- Approval nodes inside Flow for human approval pauses.
This page keeps the historical route but documents the current split.
Flow for automation
Use Flow when something should happen after a record event, schedule, button, or subflow call:
import type { Flow } from '@objectstack/spec/automation';
export const dealClosedWon: Flow = {
name: 'deal_closed_won',
label: 'Deal Closed Won',
type: 'record_change',
status: 'active',
nodes: [
{
id: 'start',
type: 'start',
label: 'Start',
config: {
triggerType: 'record-after-update',
objectName: 'opportunity',
condition: "record.stage == 'closed_won' && previous.stage != 'closed_won'",
},
},
{ id: 'set_closed_date', type: 'update_record', label: 'Set Closed Date' },
{ id: 'notify_sales', type: 'notify', label: 'Notify Sales' },
{ id: 'end', type: 'end', label: 'End' },
],
edges: [
{ id: 'e1', source: 'start', target: 'set_closed_date' },
{ id: 'e2', source: 'set_closed_date', target: 'notify_sales' },
{ id: 'e3', source: 'notify_sales', target: 'end' },
],
};Flow node types are open-ended: the schema accepts built-in node ids and plugin-registered node ids. The live automation engine validates executors at registration/runtime.
State machines for lifecycle constraints
Use StateMachineSchema when the core requirement is "this object can only move
through these states by these events."
import type { StateMachineConfig } from '@objectstack/spec/automation';
export const caseLifecycle: StateMachineConfig = {
id: 'case_lifecycle',
initial: 'new',
states: {
new: {
on: {
ASSIGN: { target: 'assigned' },
},
},
assigned: {
on: {
RESOLVE: { target: 'resolved', cond: 'has_resolution' },
ESCALATE: { target: 'escalated' },
},
},
escalated: {
on: {
RESOLVE: { target: 'resolved', cond: 'has_resolution' },
},
},
resolved: {
type: 'final',
},
},
};State machines describe valid transitions and guards. Use Flow nodes for side effects around those transitions when you need notifications, record updates, or external calls.
Approvals
Approvals are Flow nodes:
{
id: 'manager_approval',
type: 'approval',
label: 'Manager Approval',
config: {
approvers: [{ type: 'field', value: 'owner_manager_id' }],
behavior: 'unanimous',
approvalStatusField: 'approval_status',
lockRecord: true,
},
}The approvals plugin persists sys_approval_request and
sys_approval_action, enforces record locks, mirrors the optional status field,
and resumes the paused Flow after approve/reject.
Migration
| Old concept | Current equivalent |
|---|---|
| Workflow Rule | Flow |
| Time trigger | Scheduled Flow |
| Field update action | update_record node |
| Email alert | notify node |
| HTTP call | http node |
| Approval Process | Flow with one or more approval nodes |
If the old rule was "when X happens, do Y", model it as a small Flow. If the old rule was "this record must move through controlled states", model the lifecycle as a state machine and use Flow for side effects.