6.5 Workflow Approval Nodes
An approval node creates a durable WorkflowApproval, marks its execution log waiting, and pauses the WorkflowInstance. DefaultWorkflowApprovalManager validates responders, records immutable WorkflowApprovalResponse rows, updates the gate, and resumes the engine when the configured outcome is reached.
Approver types
approverType |
Main approverConfig |
Meaning |
|---|---|---|
permission |
permission |
Members with an active role granting the named permission |
role |
role |
Members with the named active role |
member |
member_id |
One configured/resolved member |
dynamic |
registered service plus resolver-specific fields |
Server-side resolver returns eligible member IDs |
policy |
policyClass, policyAction, entityTable, entityIdKey |
Eligibility evaluated against a policy/resource context |
Use WorkflowApproverResolverRegistry for dynamic resolvers so the designer sees safe metadata while the server retains class/method details. Direct class-name configuration exists for compatibility; new plugin integrations should register a stable resolver key.
Common node configuration
requiredCount: integer or supported application-setting reference.allowParallel/parallel: whether eligible decisions may be collected in parallel.serialPickNext: each responder selects the next eligible approver.initialApproverId: optional context expression for the first assignee.allowCommentsandcommentWarning: response UI contract.deadline: optional gate deadline used by workflow behavior.approverConfig: explicit configuration;$.values are resolved from the instance context.
Use the designer/definition validator rather than relying on undocumented fields. The JSON definition and provider schema must agree.
Status and decisions
Approval statuses are pending, approved, rejected, expired, and cancelled. Response decisions are approve, reject, abstain, and request_changes. Use entity constants.
Eligibility is checked again when recording a response. Client-side eligible-approver lists and hidden controls are not security boundaries. Dynamic resolvers receive the persisted approval and must return tenant-local member IDs; a pinned current_approver_id further restricts who may respond.
Approval versus other waiting work
- Use an approval node for a decision that gates workflow progression.
- Use a
humanTasknode for workflow-owned manual task completion. - Use core ActionItems for durable domain follow-up work that may outlive one workflow node and needs assignee/form integration.
Do not create plugin-specific approval tables. Use approval context renderers to add safe domain context to the unified /approvals UI.
Multi-tenant and lifecycle rules
The definition/version, instance, approval, responses, members, and domain entity all belong to one tenant database. Workers must bind that tenant before deadlines, reassignment, or resumption. Cancellation/restart flows should preserve historical responses but ensure they never count toward a replacement gate.
Verification
Cover every approver type, active-window eligibility, required counts, parallel and serial-pick-next behavior, reassignment, duplicate/concurrent responses, reject/abstain/request-changes outcomes, cancellation/expiry, resolver failure, policy resource loading, context-expression validation, restart history, and tenant isolation.