Process Execution Commands Reference
Overview
This document provides comprehensive reference for all Process Execution Commands in the BankLingo BPM Engine. These commands handle the lifecycle management of process instances, from creation to completion, including error handling, supervision, and state management.
Table of Contents
- StartProcessInstanceCommand - Create and start a new process instance
- GetProcessInstanceListQuery - Retrieve paginated list of process instances
- GetProcessInstanceStateCommand - Get detailed state of a single process instance
- SignalProcessInstanceCommand - Send signal to waiting process instance
- CancelProcessInstanceCommand - Cancel a running process instance
- SkipFailedTaskCommand - Skip a failed task and continue process
- StepForwardCommand - Move process forward by one step
- StepBackwardCommand - Move process backward by one step
- ResumeProcessInstanceCommand - Resume a paused process instance
StartProcessInstanceCommand
Creates and starts a new process instance from a process definition.
Request
{
"processDefinitionId": 123,
"executionMode": "Supervised", // "Supervised" or "Unsupervised"
"businessKey": "ORDER-2024-001",
"variables": {
"customerId": "CUST123",
"orderAmount": 5000.00,
"approverEmail": "manager@bank.com"
}
}
Request Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
processDefinitionId | long | Yes | - | ID of the process definition to instantiate |
executionMode | string | No | "Unsupervised" | Execution mode: "Supervised" (manual step control) or "Unsupervised" (automatic execution) |
businessKey | string | No | null | Business-level identifier for the process instance |
variables | object | No | Initial variables for the process instance |
Response
{
"isSuccessful": true,
"message": "Process instance started successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"processDefinitionId": 123,
"businessKey": "ORDER-2024-001",
"status": "RUNNING",
"executionMode": "Supervised",
"isSupervised": true,
"currentActivityId": "Task_ApproveOrder",
"currentTaskName": "Approve Order"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
processInstanceId | string (guid) | Unique identifier for the created process instance |
processDefinitionId | long | ID of the process definition |
businessKey | string | Business identifier |
status | string | Current process status (RUNNING, WAITING, COMPLETED, etc.) |
executionMode | string | Execution mode used |
isSupervised | boolean | Whether instance is running in supervised mode |
currentActivityId | string | BPMN ID of current activity |
currentTaskName | string | Human-readable name of current task |
Process Instance Tracking Fields
When a process instance is created, the following fields are automatically tracked:
| Field | Type | Description |
|---|---|---|
InstanceGuid | Guid | Unique identifier for the process instance |
ProcessDefinitionId | long | Foreign key to ProcessDefinition |
ProcessDefinitionXml | string | Snapshot of BPMN XML at start time |
BusinessKey | string | Optional business identifier |
ProcessRunStatus | enum | Current status (RUNNING, WAITING, ERROR, COMPLETED, etc.) |
StateJson | string (JSON) | Complete engine state (variables, tokens, call stack) |
CurrentActivityId | string | BPMN ID of current activity |
CurrentActivityType | string | Type of current activity (userTask, serviceTask, gateway, etc.) |
CurrentTaskName | string | Human-readable name of current task |
LastError | string (JSON) | Details of last error encountered |
ErrorCount | int | Total number of errors encountered |
RetryCount | int | Number of retry attempts for failed tasks |
IsSupervised | boolean | Whether instance is running in supervised mode |
Execution Modes
Unsupervised Mode (Default)
- Process executes automatically without manual intervention
- Service tasks, gateways, and events execute immediately
- Process continues until it reaches a user task or completes
- Suitable for automated workflows (e.g., scheduled jobs, system integrations)
Supervised Mode
- Process execution is controlled manually via step commands
- Each activity requires explicit StepForward command to proceed
- Allows inspection of process state between steps
- Suitable for debugging, testing, or workflows requiring manual oversight
Example Usage
// Start unsupervised process (automatic execution)
const unsupervisedInstance = await startProcess({
processDefinitionId: 123,
executionMode: "Unsupervised",
businessKey: "AUTO-LOAN-001",
variables: {
loanAmount: 50000,
creditScore: 750
}
});
// Start supervised process (manual step control)
const supervisedInstance = await startProcess({
processDefinitionId: 123,
executionMode: "Supervised",
businessKey: "MANUAL-APPROVAL-001",
variables: {
amount: 100000,
requiresReview: true
}
});
GetProcessInstanceListQuery
Retrieves a paginated list of process instances with filtering, sorting, and action availability flags.
Request
{
"pageNumber": 1,
"pageSize": 20,
"filters": {
"processDefinitionId": 123,
"status": "WAITING",
"businessKey": "ORDER-2024",
"isSupervised": true,
"dateFrom": "2024-01-01",
"dateTo": "2024-12-31"
},
"sortBy": "createdAt",
"sortDirection": "desc"
}
Response
{
"isSuccessful": true,
"message": "Process instances retrieved successfully",
"data": {
"items": [
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"processDefinitionId": 123,
"processDefinitionName": "Loan Approval Process",
"businessKey": "LOAN-2024-001",
"processRunStatus": "WAITING",
"processRunStatusDesc": "Waiting for User Input",
"currentActivityId": "Task_ManagerApproval",
"currentActivityType": "userTask",
"currentTaskName": "Manager Approval",
"errorCount": 0,
"retryCount": 0,
"isSupervised": false,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T11:45:00Z",
// Action Availability Flags
"canView": true,
"canOpen": true,
"canRetry": false,
"canCancel": true
}
],
"totalCount": 150,
"pageNumber": 1,
"pageSize": 20,
"totalPages": 8
}
}
Action Availability Flags
The response includes action flags that frontend applications can use to enable/disable UI buttons:
| Flag | Type | Logic | Description |
|---|---|---|---|
canView | boolean | true (always) | Process instance details can be viewed |
canOpen | boolean | currentActivityType == "userTask" && status == WAITING | Process can be opened for user interaction |
canRetry | boolean | status == ERROR | Process can be retried after error |
canCancel | boolean | status NOT IN (COMPLETED, CANCELLED, EXPIRED) | Process can be cancelled |
Example Frontend Usage
interface ProcessInstance {
processInstanceId: string;
processDefinitionName: string;
businessKey: string;
processRunStatus: string;
currentTaskName: string;
isSupervised: boolean;
// Action flags
canView: boolean;
canOpen: boolean;
canRetry: boolean;
canCancel: boolean;
}
// React component example
function ProcessInstanceRow({ instance }: { instance: ProcessInstance }) {
return (
<tr>
<td>{instance.businessKey}</td>
<td>{instance.currentTaskName}</td>
<td>
<Badge variant={instance.isSupervised ? "warning" : "info"}>
{instance.isSupervised ? "Supervised" : "Automatic"}
</Badge>
</td>
<td>
{instance.canView && (
<Button onClick={() => viewInstance(instance.processInstanceId)}>
View
</Button>
)}
{instance.canOpen && (
<Button onClick={() => openTask(instance.processInstanceId)}>
Open Task
</Button>
)}
{instance.canRetry && (
<Button variant="warning" onClick={() => retryInstance(instance.processInstanceId)}>
Retry
</Button>
)}
{instance.canCancel && (
<Button variant="danger" onClick={() => cancelInstance(instance.processInstanceId)}>
Cancel
</Button>
)}
</td>
</tr>
);
}
GetProcessInstanceStateCommand
Retrieves detailed state information for a single process instance, including BPMN engine state, variables, and action availability.
Request
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Response
{
"isSuccessful": true,
"message": "Process instance state retrieved successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"processDefinitionId": 123,
"processDefinitionName": "Loan Approval Process",
"processDefinitionXml": "<bpmn:definitions>...</bpmn:definitions>",
"status": "WAITING",
"processRunStatus": "WAITING",
"processRunStatusDesc": "Waiting for User Input",
"currentActivityId": "Task_ManagerApproval",
"currentTaskName": "Manager Approval",
"currentStep": "Manager Approval",
// Action Availability Flags
"canView": true,
"canOpen": true,
"canRetry": false,
"canCancel": true,
// Execution Mode
"isSupervised": false,
// BPMN Engine State
"state": {
"status": "WAITING",
"variables": {
"customerId": "CUST123",
"loanAmount": 50000,
"creditScore": 750,
"approverEmail": "manager@bank.com"
},
"tokens": [
{
"elementId": "Task_ManagerApproval",
"elementType": "userTask"
}
],
"callStack": []
},
// Waiting Activities
"waiting": [
{
"elementId": "Task_ManagerApproval",
"elementType": "userTask",
"elementName": "Manager Approval"
}
],
// Next Available Actions
"nextActions": [
{
"action": "complete",
"elementId": "Task_ManagerApproval",
"label": "Complete Manager Approval"
},
{
"action": "cancel",
"elementId": "Task_ManagerApproval",
"label": "Cancel Process"
}
]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
processInstanceId | string (guid) | Unique identifier |
processDefinitionId | long | Process definition ID |
processDefinitionName | string | Process definition name |
processDefinitionXml | string | BPMN XML snapshot |
status | string | Engine status |
processRunStatus | string | Process run status enum |
processRunStatusDesc | string | Human-readable status description |
currentActivityId | string | Current BPMN activity ID |
currentTaskName | string | Human-readable task name |
currentStep | string | Current step display name |
canView | boolean | Whether instance can be viewed |
canOpen | boolean | Whether instance can be opened for interaction |
canRetry | boolean | Whether instance can be retried |
canCancel | boolean | Whether instance can be cancelled |
isSupervised | boolean | Whether instance is supervised |
state | object | Complete BPMN engine state |
waiting | array | Activities waiting for signal/input |
nextActions | array | Available actions for the instance |
Use Cases
1. Process Monitoring Dashboard
Display detailed process state with real-time visualization of current activity.
2. Debug Process Issues
Inspect variables, tokens, and call stack to diagnose process execution problems.
3. User Task Forms
Retrieve process variables to pre-populate task forms with context.
4. Action Button Visibility
Use action flags to show/hide appropriate action buttons.
Example Frontend Usage
async function loadProcessDetails(instanceId: string) {
const response = await getProcessInstanceState(instanceId);
const data = response.data;
// Display process information
console.log(`Process: ${data.processDefinitionName}`);
console.log(`Current Step: ${data.currentStep}`);
console.log(`Status: ${data.processRunStatusDesc}`);
console.log(`Mode: ${data.isSupervised ? 'Supervised' : 'Automatic'}`);
// Show available actions
const actions = [];
if (data.canOpen) actions.push('Open Task');
if (data.canRetry) actions.push('Retry');
if (data.canCancel) actions.push('Cancel');
console.log(`Available Actions: ${actions.join(', ')}`);
// Access process variables
const variables = data.state.variables;
console.log('Variables:', variables);
// Render BPMN diagram with current activity highlighted
renderBpmnDiagram(data.processDefinitionXml, data.currentActivityId);
}
SignalProcessInstanceCommand
Sends a signal to a waiting process instance to resume execution.
Request
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"elementId": "Task_ManagerApproval",
"variables": {
"approved": true,
"comments": "Loan approved with conditions",
"approvedBy": "john.manager@bank.com"
}
}
Response
{
"isSuccessful": true,
"message": "Signal sent successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "RUNNING",
"currentActivityId": "Task_NotifyCustomer",
"currentTaskName": "Notify Customer",
"errorCount": 0
}
}
Behavior
- Success Path: Process continues execution from the signaled element
- Error Path: If signal causes error,
LastErrorfield is updated with error details,ErrorCountincremented, and status set to ERROR - Variables: Variables provided in signal request are merged with existing process variables
- Current Task Tracking:
CurrentActivityId,CurrentActivityType, andCurrentTaskNameare automatically updated as process advances
Error Persistence
When a signaled task fails:
{
"isSuccessful": false,
"message": "Task execution failed",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "ERROR",
"errorCount": 1,
"lastError": {
"timestamp": "2024-01-15T12:30:00Z",
"elementId": "Task_ProcessPayment",
"errorMessage": "Payment gateway timeout",
"stackTrace": "...",
"variables": {
"amount": 50000,
"accountNumber": "123456789"
}
}
}
}
CancelProcessInstanceCommand
Cancels a running or waiting process instance.
Request
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"reason": "Customer requested cancellation"
}
Response
{
"isSuccessful": true,
"message": "Process instance cancelled successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "CANCELLED",
"cancelledAt": "2024-01-15T14:00:00Z"
}
}
Behavior
- Status Update:
ProcessRunStatusset to CANCELLED - Current Task Clearing:
CurrentActivityId,CurrentActivityType, andCurrentTaskNamecleared (set to null/"") - State Preservation: Final state preserved in
StateJsonfor audit purposes - Validation: Cannot cancel already COMPLETED, CANCELLED, or EXPIRED instances
Validation Rules
- ✅ Can cancel: RUNNING, WAITING, ERROR, PAUSED
- ❌ Cannot cancel: COMPLETED, CANCELLED, EXPIRED
SkipFailedTaskCommand
Skips a failed task and continues process execution.
Request
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"elementId": "Task_SendEmail"
}
Response
{
"isSuccessful": true,
"message": "Task skipped successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "RUNNING",
"skippedTask": "Task_SendEmail",
"currentActivityId": "Task_NextStep",
"currentTaskName": "Next Step"
}
}
Behavior
- Error Clearing:
LastErrorfield cleared,ErrorCountreset to 0 - Status Update:
ProcessRunStatuschanged from ERROR to RUNNING - Current Task Tracking: As process moves forward,
CurrentActivityId,CurrentActivityType, andCurrentTaskNameupdated to reflect new position - Token Advancement: Token moved past failed task to next activity
Use Cases
- Non-Critical Failures: Skip optional notifications or logging tasks
- Workaround Applied: Manual intervention completed, skip automated step
- Time-Sensitive Workflows: Continue process despite non-blocking errors
StepForwardCommand
Moves a supervised process forward by one step.
Request
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Response
{
"isSuccessful": true,
"message": "Process stepped forward successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "RUNNING",
"previousActivityId": "Task_ValidateData",
"currentActivityId": "Task_ProcessPayment",
"currentTaskName": "Process Payment",
"currentActivityType": "serviceTask"
}
}
Behavior
- Supervised Mode Only: Only works for instances with
IsSupervised = true - Single Step Execution: Executes exactly one activity and pauses
- Current Task Tracking:
CurrentActivityId,CurrentActivityType, andCurrentTaskNameupdated after each step - State Update:
StateJsonupdated with new engine state after step
Use Cases
- Debugging: Step through process execution to identify issues
- Training: Demonstrate process flow step-by-step
- Validation: Verify process logic before unsupervised execution
StepBackwardCommand
Moves a supervised process backward by one step (undo last action).
Request
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Response
{
"isSuccessful": true,
"message": "Process stepped backward successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "RUNNING",
"currentActivityId": "Task_ValidateData",
"currentTaskName": "Validate Data",
"restoredToStep": "Task_ValidateData"
}
}
Behavior
- Supervised Mode Only: Only works for instances with
IsSupervised = true - State Rollback: Engine state rolled back to previous activity
- Current Task Tracking:
CurrentActivityId,CurrentActivityType, andCurrentTaskNamereverted to previous step - Variable Preservation: Variables typically preserved unless explicitly modified
Limitations
- May not be possible for all process types (e.g., after irreversible operations)
- Some gateways and events may not support backward movement
ResumeProcessInstanceCommand
Resumes a paused or waiting process instance.
Request
{
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Response
{
"isSuccessful": true,
"message": "Process instance resumed successfully",
"data": {
"processInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "RUNNING",
"currentActivityId": "Task_ContinueProcess",
"currentTaskName": "Continue Process"
}
}
Behavior
- Status Update:
ProcessRunStatuschanged to RUNNING - Execution Continuation: Process continues from current position
- Current Task Tracking:
CurrentActivityId,CurrentActivityType, andCurrentTaskNameupdated as process advances
Process Run Status Enum
The ProcessRunStatus field uses the following enum values:
| Value | Description | Can Signal | Can Cancel | Can Retry |
|---|---|---|---|---|
RUNNING | Process is actively executing | No | Yes | No |
WAITING | Process waiting for external input | Yes | Yes | No |
ERROR | Process encountered an error | Yes | Yes | Yes |
COMPLETED | Process finished successfully | No | No | No |
CANCELLED | Process was cancelled | No | No | No |
EXPIRED | Process expired due to timeout | No | No | No |
PAUSED | Process manually paused | Yes | Yes | No |
Common Integration Patterns
1. Process List with Actions
async function displayProcessList() {
const response = await getProcessInstanceList({
pageNumber: 1,
pageSize: 20,
filters: { status: 'WAITING' }
});
response.data.items.forEach(instance => {
console.log(`${instance.businessKey} - ${instance.currentTaskName}`);
if (instance.canOpen) {
console.log(' [Open] button enabled');
}
if (instance.canRetry) {
console.log(' [Retry] button enabled');
}
if (instance.canCancel) {
console.log(' [Cancel] button enabled');
}
});
}
2. Process Detail Page with State Visualization
async function showProcessDetail(instanceId: string) {
const stateResponse = await getProcessInstanceState(instanceId);
const state = stateResponse.data;
// Display process info
displayProcessInfo({
name: state.processDefinitionName,
businessKey: state.businessKey,
status: state.processRunStatusDesc,
currentStep: state.currentStep,
isSupervised: state.isSupervised
});
// Display BPMN diagram with highlighted current activity
renderBpmnDiagram(state.processDefinitionXml, state.currentActivityId);
// Display process variables
displayVariables(state.state.variables);
// Show action buttons based on flags
if (state.canOpen) {
showButton('Open Task', () => openTask(instanceId));
}
if (state.canRetry) {
showButton('Retry', () => retryProcess(instanceId));
}
if (state.canCancel) {
showButton('Cancel', () => cancelProcess(instanceId));
}
}
3. Supervised Process Debugger
async function debugProcess(instanceId: string) {
let state = await getProcessInstanceState(instanceId);
if (!state.data.isSupervised) {
console.log('Process must be supervised for debugging');
return;
}
while (state.data.status !== 'COMPLETED') {
console.log(`Current: ${state.data.currentStep}`);
console.log('Variables:', state.data.state.variables);
const action = await promptUser('Action: [F]orward, [B]ackward, [Q]uit');
if (action === 'F') {
await stepForward(instanceId);
} else if (action === 'B') {
await stepBackward(instanceId);
} else if (action === 'Q') {
break;
}
state = await getProcessInstanceState(instanceId);
}
}
4. Error Recovery Workflow
async function handleProcessError(instanceId: string) {
const state = await getProcessInstanceState(instanceId);
if (state.data.processRunStatus !== 'ERROR') {
console.log('Process is not in error state');
return;
}
const lastError = state.data.state.lastError;
console.log('Error:', lastError.errorMessage);
console.log('Failed Task:', lastError.elementId);
const action = await promptUser('Action: [R]etry, [S]kip, [C]ancel');
if (action === 'R') {
// Retry with same parameters
await signalProcess(instanceId, lastError.elementId, lastError.variables);
} else if (action === 'S') {
// Skip failed task
await skipFailedTask(instanceId, lastError.elementId);
} else if (action === 'C') {
// Cancel process
await cancelProcess(instanceId, 'User cancelled after error');
}
}
Summary of Recent Enhancements
1. IsSupervised Field Addition
- What Changed: Added
IsSupervisedboolean field toProcessInstanceentity - Why: Previously tracked supervision at definition level, but needed to track at instance level since same definition can be started in different modes
- Impact:
- Each process instance now tracks its own execution mode
StartProcessInstanceCommandcaptures execution mode at start timeGetProcessInstanceListQueryandGetProcessInstanceStateCommandreturn actual instance execution mode
2. Action Availability Flags
- What Changed: Added
CanView,CanOpen,CanRetry,CanCancelflags to list and state commands - Why: Frontend needs to know which actions are available for each instance based on current state
- Impact:
- No need for frontend to duplicate business logic for button visibility
- Consistent action availability across all UI components
- Easier to maintain - logic centralized in backend
3. Enhanced Error Tracking
- What Changed: Added
LastError,ErrorCount,RetryCountfields - Why: Better error diagnostics and retry management
- Impact:
- Detailed error information preserved for troubleshooting
- Retry attempts tracked
- Error history available for audit
4. Current Task Tracking
- What Changed: Added
CurrentActivityId,CurrentActivityType,CurrentTaskNamefields - Why: Quick access to current position without parsing state JSON
- Impact:
- Faster queries for current task information
- Better support for process monitoring dashboards
- Easier filtering and sorting by current task
Database Migration Required
To implement the IsSupervised field, execute the following SQL migration:
-- Add IsSupervised field to ProcessInstance table
ALTER TABLE BPM.ProcessInstance
ADD IsSupervised BIT NOT NULL DEFAULT 0;
-- Update existing records based on ProcessDefinition type
-- Assumes ProcessType = 1 (MANUAL) indicates supervised processes
UPDATE pi
SET pi.IsSupervised = CASE
WHEN pd.ProcessType = 1 THEN 1 -- MANUAL = Supervised
ELSE 0
END
FROM BPM.ProcessInstance pi
INNER JOIN BPM.ProcessDefinitiion pd ON pi.ProcessDefinitionId = pd.Id;
-- Create index for performance (optional but recommended)
CREATE NONCLUSTERED INDEX IX_ProcessInstance_IsSupervised
ON BPM.ProcessInstance(IsSupervised)
INCLUDE (ProcessRunStatus, CurrentActivityType);
Rollback Script:
-- Remove IsSupervised field
ALTER TABLE BPM.ProcessInstance
DROP COLUMN IsSupervised;
-- Drop index if created
DROP INDEX IX_ProcessInstance_IsSupervised ON BPM.ProcessInstance;
API Testing Checklist
StartProcessInstanceCommand
- Start process in Unsupervised mode (default)
- Start process in Supervised mode (explicit)
- Verify
IsSupervisedfield in database matches execution mode - Verify process executes automatically in Unsupervised mode
- Verify process pauses in Supervised mode
GetProcessInstanceListQuery
- Verify
IsSupervisedfield matches instance execution mode - Verify
CanViewis always true - Verify
CanOpenis true only for userTask + WAITING - Verify
CanRetryis true only for ERROR status - Verify
CanCancelexcludes COMPLETED, CANCELLED, EXPIRED - Test filtering by
IsSupervisedfield
GetProcessInstanceStateCommand
- Verify all action flags present in response
- Verify action flags match instance state
- Verify
IsSupervisedfield included - Verify
CurrentStepfield populated - Verify
ProcessRunStatusDescprovides human-readable status
SignalProcessInstanceCommand
- Signal successful task completion
- Signal with variables
- Signal failing task (verify
LastErrorupdated) - Signal failing task (verify
ErrorCountincremented) - Verify
CurrentActivityIdupdated after signal
CancelProcessInstanceCommand
- Cancel RUNNING instance
- Cancel WAITING instance
- Cancel ERROR instance
- Attempt to cancel COMPLETED instance (should fail)
- Verify
CurrentActivityIdcleared after cancellation
SkipFailedTaskCommand
- Skip failed task in ERROR status
- Verify
LastErrorcleared - Verify
ErrorCountreset - Verify status changed to RUNNING
- Verify
CurrentActivityIdupdated
StepForwardCommand
- Step forward in supervised process
- Attempt step forward in unsupervised process (should fail)
- Verify
CurrentActivityIdupdated after step - Verify
CurrentTaskNameupdated after step
StepBackwardCommand
- Step backward in supervised process
- Attempt step backward in unsupervised process (should fail)
- Verify
CurrentActivityIdreverted after step - Verify
CurrentTaskNamereverted after step
ResumeProcessInstanceCommand
- Resume PAUSED instance
- Resume WAITING instance
- Verify status changed to RUNNING
- Verify
CurrentActivityIdupdated as process advances
Frontend Integration Examples
Angular Example
// process-instance.service.ts
export interface ProcessInstance {
processInstanceId: string;
processDefinitionName: string;
businessKey: string;
processRunStatus: string;
processRunStatusDesc: string;
currentTaskName: string;
isSupervised: boolean;
canView: boolean;
canOpen: boolean;
canRetry: boolean;
canCancel: boolean;
}
@Injectable({ providedIn: 'root' })
export class ProcessInstanceService {
constructor(private http: HttpClient) {}
getProcessInstanceList(params: any): Observable<ProcessInstance[]> {
return this.http.post<any>('/api/process/list', params)
.pipe(map(response => response.data.items));
}
getProcessInstanceState(instanceId: string): Observable<any> {
return this.http.post<any>('/api/process/state', { processInstanceId: instanceId })
.pipe(map(response => response.data));
}
}
// process-list.component.ts
@Component({
selector: 'app-process-list',
template: `
<table>
<thead>
<tr>
<th>Business Key</th>
<th>Current Task</th>
<th>Status</th>
<th>Mode</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let instance of instances">
<td>{{ instance.businessKey }}</td>
<td>{{ instance.currentTaskName }}</td>
<td>{{ instance.processRunStatusDesc }}</td>
<td>
<span class="badge" [class.badge-warning]="instance.isSupervised">
{{ instance.isSupervised ? 'Supervised' : 'Automatic' }}
</span>
</td>
<td>
<button *ngIf="instance.canView" (click)="viewInstance(instance)">View</button>
<button *ngIf="instance.canOpen" (click)="openTask(instance)">Open</button>
<button *ngIf="instance.canRetry" (click)="retryInstance(instance)">Retry</button>
<button *ngIf="instance.canCancel" (click)="cancelInstance(instance)">Cancel</button>
</td>
</tr>
</tbody>
</table>
`
})
export class ProcessListComponent implements OnInit {
instances: ProcessInstance[] = [];
constructor(private processService: ProcessInstanceService) {}
ngOnInit() {
this.loadInstances();
}
loadInstances() {
this.processService.getProcessInstanceList({ pageNumber: 1, pageSize: 20 })
.subscribe(instances => {
this.instances = instances;
});
}
viewInstance(instance: ProcessInstance) {
this.router.navigate(['/process', instance.processInstanceId]);
}
openTask(instance: ProcessInstance) {
this.router.navigate(['/task', instance.processInstanceId]);
}
retryInstance(instance: ProcessInstance) {
// Retry logic
}
cancelInstance(instance: ProcessInstance) {
// Cancel logic
}
}
React Example
// useProcessInstance.ts
import { useState, useEffect } from 'react';
interface ProcessInstance {
processInstanceId: string;
processDefinitionName: string;
businessKey: string;
processRunStatus: string;
processRunStatusDesc: string;
currentTaskName: string;
isSupervised: boolean;
canView: boolean;
canOpen: boolean;
canRetry: boolean;
canCancel: boolean;
}
export function useProcessInstances() {
const [instances, setInstances] = useState<ProcessInstance[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchInstances();
}, []);
async function fetchInstances() {
const response = await fetch('/api/process/list', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ pageNumber: 1, pageSize: 20 })
});
const data = await response.json();
setInstances(data.data.items);
setLoading(false);
}
return { instances, loading, refetch: fetchInstances };
}
// ProcessListTable.tsx
export function ProcessListTable() {
const { instances, loading } = useProcessInstances();
if (loading) return <div>Loading...</div>;
return (
<table className="process-table">
<thead>
<tr>
<th>Business Key</th>
<th>Current Task</th>
<th>Status</th>
<th>Mode</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{instances.map(instance => (
<tr key={instance.processInstanceId}>
<td>{instance.businessKey}</td>
<td>{instance.currentTaskName}</td>
<td>{instance.processRunStatusDesc}</td>
<td>
<span className={`badge ${instance.isSupervised ? 'badge-warning' : 'badge-info'}`}>
{instance.isSupervised ? 'Supervised' : 'Automatic'}
</span>
</td>
<td>
{instance.canView && (
<button onClick={() => viewInstance(instance.processInstanceId)}>
View
</button>
)}
{instance.canOpen && (
<button onClick={() => openTask(instance.processInstanceId)}>
Open
</button>
)}
{instance.canRetry && (
<button onClick={() => retryInstance(instance.processInstanceId)}>
Retry
</button>
)}
{instance.canCancel && (
<button onClick={() => cancelInstance(instance.processInstanceId)}>
Cancel
</button>
)}
</td>
</tr>
))}
</tbody>
</table>
);
}
function viewInstance(instanceId: string) {
window.location.href = `/process/${instanceId}`;
}
function openTask(instanceId: string) {
window.location.href = `/task/${instanceId}`;
}
async function retryInstance(instanceId: string) {
await fetch('/api/process/signal', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ processInstanceId: instanceId })
});
// Refresh list
window.location.reload();
}
async function cancelInstance(instanceId: string) {
if (confirm('Are you sure you want to cancel this process?')) {
await fetch('/api/process/cancel', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ processInstanceId: instanceId })
});
// Refresh list
window.location.reload();
}
}
Conclusion
This comprehensive reference covers all Process Execution Commands with their request/response formats, behavior, and integration patterns. The recent enhancements provide:
- Better Execution Mode Tracking -
IsSupervisedfield tracks instance-level execution mode - Simplified Frontend Logic - Action availability flags (
CanView,CanOpen,CanRetry,CanCancel) eliminate frontend business logic duplication - Enhanced Error Handling - Detailed error tracking with
LastError,ErrorCount, andRetryCount - Improved Monitoring - Current task tracking fields enable better process monitoring dashboards
These enhancements make the BPM engine more robust, easier to integrate, and provide better visibility into process execution.