@paulovila/workflow
v1.0.1
Published
Generic workflow execution engine plugin for Vetra - provides core workflow orchestration, state management, and execution capabilities
Maintainers
Readme
@vetra/workflow
Generic workflow execution engine plugin for Vetra. Provides core workflow orchestration, state management, and execution capabilities for building complex business processes.
Features
- Generic Workflow Engine: Execute any type of workflow with flexible block-based architecture
- State Management: Track workflow state, progress, and history
- Block System: Pluggable block executors for different operations
- Error Handling: Comprehensive error handling with retry mechanisms
- Timeout Management: Configurable timeouts for workflows and blocks
- Audit Trail: Complete audit trail of all workflow actions
- Workflow Templates: Pre-built templates for common workflows
- API Endpoints: RESTful API for workflow management
Installation
npm install @vetra/workflowQuick Start
1. Initialize the Plugin
import { workflowPlugin } from '@vetra/workflow';
export default buildConfig({
plugins: [
workflowPlugin({
enabled: true,
debug: false,
engineOptions: {
timeout: 3600000, // 1 hour
maxRetries: 3,
},
}),
],
});2. Create a Workflow Configuration
import { BLOCK_TYPES } from '@vetra/workflow';
const workflowConfig = {
id: 'my-workflow',
name: 'My Workflow',
version: '1.0.0',
enabled: true,
blocks: [
{
id: 'block-1',
type: BLOCK_TYPES.FORM_INPUT,
name: 'Collect Information',
order: 1,
required: true,
enabled: true,
settings: { autoAdvance: true },
validation: { required: true, rules: [] },
},
{
id: 'block-2',
type: BLOCK_TYPES.APPROVAL,
name: 'Get Approval',
order: 2,
required: true,
enabled: true,
settings: { autoAdvance: true },
validation: { required: true, rules: [] },
},
],
settings: {
timeout: 604800000, // 7 days
retryAttempts: 3,
autoStart: false,
notifyOnCompletion: true,
},
};3. Execute a Workflow
const instance = await engine.executeWorkflow(
workflowConfig,
{
userId: 'user-123',
sessionId: 'session-456',
ipAddress: '192.168.1.1',
},
{
timeout: 3600000,
retryAttempts: 3,
}
);
console.log(instance.status); // 'completed' or 'failed'
console.log(instance.progress); // 0-100Workflow States
pending- Workflow is waiting to startin_progress- Workflow is currently executingcompleted- Workflow completed successfullyfailed- Workflow failedcancelled- Workflow was cancelledpaused- Workflow is pausedexpired- Workflow expired
Block Types
Built-in Block Types
- ACTION: Execute custom actions
- APPROVAL: Wait for approval
- CONDITION: Evaluate conditions
- DELAY: Introduce delays
- NOTIFICATION: Send notifications
- FORM_INPUT: Collect form data
- VALIDATION: Validate data
- DOCUMENT_UPLOAD: Handle document uploads
- PAYMENT: Process payments
Creating Custom Block Executors
import { BaseBlockExecutor } from '@vetra/workflow';
class CustomBlockExecutor extends BaseBlockExecutor {
async execute(block, instance, context) {
// Your custom logic here
return this.createSuccessResult(
{ customData: 'result' },
processingTime
);
}
}
// Register the executor
engine.registerBlockExecutor('custom-type', new CustomBlockExecutor());Workflow Templates
Pre-built templates are available:
import {
createApprovalWorkflowTemplate,
createDocumentVerificationTemplate,
createSignatureWorkflowTemplate,
createKYCColombiaTemplate,
} from '@vetra/workflow';
const approvalTemplate = createApprovalWorkflowTemplate();
const docTemplate = createDocumentVerificationTemplate();
const signatureTemplate = createSignatureWorkflowTemplate();
const kycTemplate = createKYCColombiaTemplate();API Endpoints
Execute Workflow
POST /api/workflows/executeRequest:
{
"templateId": "template-id",
"userId": "user-id",
"context": {
"sessionId": "session-id",
"ipAddress": "192.168.1.1"
},
"data": {}
}Response:
{
"success": true,
"workflowId": "workflow-id",
"status": "in_progress",
"progress": 0
}Get Workflow Status
GET /api/workflows/status/:idResponse:
{
"success": true,
"id": "workflow-id",
"status": "completed",
"progress": 100,
"currentBlockIndex": 2,
"errors": []
}List Workflows
GET /api/workflows/list?page=1&limit=10&userId=user-idResponse:
{
"success": true,
"workflows": [...],
"total": 50,
"page": 1,
"limit": 10
}Cancel Workflow
POST /api/workflows/cancel/:idGet Workflow History
GET /api/workflows/history/:idRetry Workflow
POST /api/workflows/retry/:idConfiguration Options
interface WorkflowPluginOptions {
enabled?: boolean;
debug?: boolean;
engineOptions?: {
timeout?: number;
maxRetries?: number;
debug?: boolean;
persistState?: boolean;
};
collections?: {
workflowDefinitions?: string;
workflowInstances?: string;
workflowTemplates?: string;
workflowLogs?: string;
};
}Database Collections
The plugin creates four collections:
- workflow-definitions: Stores workflow configurations
- workflow-instances: Stores workflow execution instances
- workflow-templates: Stores workflow templates
- workflow-logs: Stores audit trail and logs
Error Handling
The engine provides comprehensive error handling:
if (instance.status === 'failed') {
instance.errors.forEach(error => {
console.log(`Error: ${error.code} - ${error.message}`);
console.log(`Block: ${error.blockId}`);
console.log(`Recoverable: ${error.recoverable}`);
});
}Retry Mechanism
Blocks support automatic retries with exponential backoff:
{
id: 'block-1',
type: BLOCK_TYPES.ACTION,
settings: {
retryAttempts: 3,
timeout: 300000,
},
}Workflow Conditions
Blocks can have conditions that determine execution:
{
id: 'block-1',
type: BLOCK_TYPES.ACTION,
conditions: [
{
field: 'requiresApproval',
operator: 'equals',
value: true,
action: 'show',
},
],
}Supported operators:
equalsnot_equalscontainsnot_containsgreater_thanless_thangreater_than_or_equalless_than_or_equalexistsnot_existsinnot_in
Testing
Comprehensive testing guide available in TESTING_GUIDE.md.
Quick Start
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage report
npm run test:coverage
# Run specific test suite
npm run test:unit # Unit tests only
npm run test:integration # Integration tests only
npm run test:e2e # End-to-end tests only
npm run test:examples # Example tests only
# Run standalone test harness (no Payload CMS needed)
node test-harness.js
node test-harness.js --test simple-workflow
node test-harness.js --verbose
# Run tests in Docker
npm run test:docker:build
npm run test:dockerTesting Approaches
Unit Tests (
tests/unit/)- Test individual functions and components
- WorkflowEngine methods, block executors, state transitions
Integration Tests (
tests/integration/)- Test API endpoints and component interactions
- Execute workflow, get status, cancel, retry endpoints
End-to-End Tests (
tests/e2e/)- Test complete workflows from start to finish
- Simple approval, multi-step, conditional, error scenarios
Example Tests (
tests/examples/)- Practical examples demonstrating common testing patterns
- SimpleWorkflow, MultiStepWorkflow, ConditionalWorkflow, ErrorHandling
Standalone Test Harness (
test-harness.js)- Test workflows without full Payload CMS setup
- Useful for development and debugging
- Can be run from command line
Test Coverage
The project enforces >80% coverage thresholds:
- Branches: 80%
- Functions: 80%
- Lines: 80%
- Statements: 80%
View coverage report:
npm run test:coverage
open coverage/lcov-report/index.htmlWriting Custom Tests
See TESTING_GUIDE.md for:
- Test structure and naming conventions
- Common test patterns
- Test utilities and helpers
- Mock objects
- Best practices
Test Utilities
Helper functions available in tests/utils/test-helpers.ts:
createTestWorkflow()- Create test workflowscreateTestContext()- Create test contextscreateMockBlockExecutor()- Create mock executorsassertWorkflowSuccess()- Assert workflow successassertBlockSuccess()- Assert block success- And many more...
Mock Objects
Mock Payload CMS available in tests/mocks/MockPayloadCMS.ts:
import { createMockPayload } from './tests/mocks/MockPayloadCMS';
const payload = createMockPayload();
const doc = await payload.create('workflow-definitions', { ... });Architecture
The workflow engine follows a modular architecture:
WorkflowEngine
├── Block Executors
│ ├── ActionBlockExecutor
│ ├── ApprovalBlockExecutor
│ ├── ConditionBlockExecutor
│ └── ... (more executors)
├── State Management
│ ├── Workflow State
│ ├── Block State
│ └── Audit Trail
└── API Endpoints
├── Execute
├── Status
├── List
├── Cancel
├── History
└── RetryBest Practices
- Always set timeouts: Prevent workflows from running indefinitely
- Use required blocks wisely: Mark blocks as required only when necessary
- Implement proper error handling: Handle errors gracefully in custom executors
- Monitor audit trails: Use audit trails for debugging and compliance
- Test workflows: Write tests for custom block executors
- Use templates: Leverage pre-built templates for common workflows
Dependencies
payload(peer dependency)@vetra/shared(peer dependency)uuid
License
MIT
Support
For issues and questions, please refer to the main Vetra documentation.
