Step Backward
Overview
The StepBackwardCommand moves back to the previous task in a process running in Supervised Mode. This allows reviewing previous task results and revisiting earlier steps during debugging or inspection.
Supervised Mode Only
This command only works for processes started with executionMode: "Supervised". Unsupervised processes execute automatically and cannot step backward.
API Endpoint
POST /api/core/cmd
Headers
Content-Type: application/json
Authorization: Bearer {access_token}
X-Tenant-ID: {tenant_id}
Request Structure
{
"cmd": "StepBackwardCommand",
"data": {
"instanceGuid": "abc-123-def-456"
}
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
instanceGuid | string | Yes | The unique identifier of the supervised process instance |
When to Use
- Review Previous Task: Inspect what the previous task did
- Verify Logic: Check task outputs before proceeding
- Debug Issues: Go back to see where an error occurred
- Training: Demonstrate workflow navigation
Sample Requests
1. Step Back to Previous Task
{
"cmd": "StepBackwardCommand",
"data": {
"instanceGuid": "loan-approval-supervised-001"
}
}
2. Review Earlier Task Results
{
"cmd": "StepBackwardCommand",
"data": {
"instanceGuid": "test-workflow-debug-789"
}
}
Response Structure
Stepped Back Successfully
{
"isSuccessful": true,
"message": "Stepped back to previous task successfully",
"statusCode": "00",
"data": {
"instanceGuid": "loan-approval-supervised-001",
"status": "waiting",
"currentActivityId": "Task_ValidateCustomer",
"executionMode": "Supervised",
"movedFrom": {
"taskId": "Task_CreditCheck",
"taskName": "Perform Credit Check"
},
"currentTask": {
"taskId": "Task_ValidateCustomer",
"taskName": "Validate Customer Information",
"taskType": "ServiceTask",
"previousExecution": {
"executedAt": "2024-12-19T10:30:15Z",
"executionTime": "1.2s",
"success": true
}
},
"state": {
"variables": {
"customerId": 123,
"customerName": "John Doe",
"validationStatus": "passed"
},
"completedTasks": ["StartEvent", "Task_ValidateCustomer"],
"currentNode": "Task_ValidateCustomer",
"reviewMode": true
},
"nextActions": [
{
"action": "stepForward",
"label": "Continue Forward",
"command": "StepForwardCommand",
"description": "Execute the next task"
},
{
"action": "stepBackward",
"label": "Go Back Further",
"command": "StepBackwardCommand",
"enabled": true
},
{
"action": "cancel",
"label": "Cancel Process",
"command": "CancelProcessInstanceCommand"
}
]
}
}
At Start of Process (Cannot Go Back)
{
"isSuccessful": false,
"message": "Already at the beginning of the process. Cannot step backward.",
"statusCode": "99",
"data": {
"instanceGuid": "loan-approval-supervised-001",
"status": "waiting",
"currentActivityId": "StartEvent",
"position": "start"
}
}
Error Responses
Process Not in Supervised Mode
{
"isSuccessful": false,
"message": "Process is not running in Supervised mode",
"statusCode": "99",
"data": {
"currentMode": "Unsupervised"
}
}
Process Not Found
{
"isSuccessful": false,
"message": "Process instance 'invalid-guid' not found.",
"statusCode": "99",
"data": null
}
Navigation Flow
Use Cases
1. Review Task Execution History
// Step through process, then review
await stepForward(instanceGuid); // Execute Task 1
await stepForward(instanceGuid); // Execute Task 2
await stepForward(instanceGuid); // Execute Task 3
// Oops, want to check Task 2 results
const response = await stepBackward(instanceGuid);
console.log("Previous Task:", response.data.currentTask);
console.log("Task Results:", response.data.state.variables);
console.log("Execution Time:", response.data.currentTask.previousExecution.executionTime);
2. Debug Workflow Issues
// Execute until error
let response;
do {
response = await stepForward(instanceGuid);
} while (response.data.status === "waiting");
if (response.data.status === "error") {
console.error("Error at:", response.data.error.taskName);
// Step back to see what led to the error
const previousResponse = await stepBackward(instanceGuid);
console.log("Previous task state:", previousResponse.data.state.variables);
// Step back again to check earlier state
const earlierResponse = await stepBackward(instanceGuid);
console.log("Earlier state:", earlierResponse.data.state.variables);
}
3. Interactive Workflow Navigator
class WorkflowNavigator {
constructor(instanceGuid) {
this.instanceGuid = instanceGuid;
this.history = [];
}
async forward() {
const response = await stepForward(this.instanceGuid);
if (response.isSuccessful && response.data.previousTask) {
this.history.push(response.data.previousTask);
}
return response;
}
async backward() {
const response = await stepBackward(this.instanceGuid);
if (response.isSuccessful && this.history.length > 0) {
this.history.pop();
}
return response;
}
canGoBack() {
return this.history.length > 0;
}
getHistory() {
return this.history;
}
}
// Usage
const navigator = new WorkflowNavigator("test-process-001");
await navigator.forward(); // Execute task 1
await navigator.forward(); // Execute task 2
await navigator.backward(); // Review task 1
await navigator.forward(); // Move forward again
4. Verify Variable Changes
// Capture variables at each step
const variableHistory = [];
// Step forward and capture
let response = await stepForward(instanceGuid);
variableHistory.push({ ...response.data.state.variables });
response = await stepForward(instanceGuid);
variableHistory.push({ ...response.data.state.variables });
// Step back and compare
response = await stepBackward(instanceGuid);
const currentVars = response.data.state.variables;
const previousVars = variableHistory[variableHistory.length - 2];
console.log("Variable changes:");
for (const key in currentVars) {
if (currentVars[key] !== previousVars?.[key]) {
console.log(`${key}: ${previousVars?.[key]} → ${currentVars[key]}`);
}
}
Important Behaviors
1. Review Mode vs Re-Execution
When you step backward, you are reviewing the previous task, not re-executing it:
// Initial execution
await stepForward(instanceGuid); // Task_CreditCheck executes, adds creditScore
// Step backward
await stepBackward(instanceGuid); // Back to Task_ValidateCustomer (review only)
// Step forward again
await stepForward(instanceGuid); // Moves to Task_CreditCheck (already executed)
Note: Variables set by previously executed tasks remain in the context.
2. Cannot Step Back from Start
const response = await stepBackward(instanceGuid);
if (!response.isSuccessful && response.data?.position === "start") {
console.log("Already at the beginning of the process");
// Disable backward navigation button in UI
}
3. Stepping Backward Multiple Times
// You can step back multiple times
await stepBackward(instanceGuid); // Back one step
await stepBackward(instanceGuid); // Back another step
await stepBackward(instanceGuid); // Back to start (if possible)
Best Practices
1. Track Navigation Position
class ProcessPosition {
constructor() {
this.position = 0;
this.maxPosition = 0;
}
async stepForward(instanceGuid) {
const response = await stepForward(instanceGuid);
if (response.isSuccessful) {
this.position++;
this.maxPosition = Math.max(this.maxPosition, this.position);
}
return response;
}
async stepBackward(instanceGuid) {
const response = await stepBackward(instanceGuid);
if (response.isSuccessful) {
this.position--;
}
return response;
}
canGoBack() {
return this.position > 0;
}
canGoForward() {
return this.position < this.maxPosition;
}
}
2. Disable Navigation When Appropriate
function updateNavigationButtons(response) {
const canGoBack = response.data.nextActions.some(
action => action.action === "stepBackward" && action.enabled !== false
);
document.getElementById("backButton").disabled = !canGoBack;
const atEnd = response.data.status === "completed";
document.getElementById("forwardButton").disabled = atEnd;
}
3. Show Execution History in UI
function displayExecutionHistory(completedTasks) {
return completedTasks.map((task, index) => ({
step: index + 1,
taskName: task.taskName || task,
status: "✓ Completed",
canReview: true
}));
}
// When stepping backward, highlight the current task
function highlightCurrentTask(currentTaskId, history) {
return history.map(task => ({
...task,
current: task.taskId === currentTaskId
}));
}
4. Preserve Context When Navigating
// Even when stepping backward, preserve important context
async function navigateWithContext(direction, instanceGuid, userNotes) {
const metadata = {
userNotes: userNotes,
navigationTime: new Date().toISOString(),
direction: direction
};
// Store metadata for audit
await logNavigation(instanceGuid, metadata);
// Perform navigation
if (direction === "forward") {
return await stepForward(instanceGuid);
} else {
return await stepBackward(instanceGuid);
}
}
Comparison: Step Forward vs Step Backward
| Aspect | Step Forward | Step Backward |
|---|---|---|
| Direction | Executes next task | Reviews previous task |
| Execution | Runs task logic | No re-execution (review only) |
| Variables | Updates context | Context remains unchanged |
| Use Case | Progress workflow | Review/debug previous steps |
| Limit | Stops at end | Stops at start |
| Mode | Supervised only | Supervised only |
Related Commands
- Step Forward - Execute next task
- Start Process - Start in Supervised mode
- Get Process State - Check current position
- Cancel Process - Cancel supervised process
Notes
- Only works with processes in Supervised mode
- Stepping backward does NOT re-execute tasks
- Variables set by previously executed tasks are preserved
- Cannot step backward beyond the start of the process
- Useful for reviewing task execution history
- Does not affect the process state or variables
- The
reviewModeflag indicates you're reviewing a previous task - Multiple backward steps are allowed until reaching the start
- Step forward after stepping backward continues from where you left off
- All navigation is logged for audit purposes