Skip to content

Commit 10b23ec

Browse files
authored
Merge pull request #184 from objectstack-ai/copilot/add-approval-workflows
2 parents d71a1ee + 65e6667 commit 10b23ec

11 files changed

Lines changed: 2346 additions & 5 deletions

File tree

packages/plugins/workflow/README.md

Lines changed: 216 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ A comprehensive workflow and state machine plugin for ObjectOS, providing finite
1010
-**Transition Actions** - Execute actions during state transitions
1111
-**Workflow Versioning** - Support for multiple versions of workflows
1212
-**Multiple Workflow Types**:
13-
- **Approval Workflows** - Multi-level approval processes
13+
- **Approval Workflows** - Multi-level approval processes with delegation and escalation 🆕
1414
- **Sequential Workflows** - Step-by-step linear processes
1515
- **Parallel Workflows** - Concurrent execution paths
1616
- **Conditional Workflows** - Dynamic branching based on conditions
17-
-**Task Management** - Create, complete, and track workflow tasks
17+
-**Task Management** - Create, complete, reject, delegate, and escalate workflow tasks 🆕
1818
-**State History** - Track all state transitions with full audit trail
1919
-**Event Integration** - Emit events for workflow lifecycle
20+
-**Multi-Channel Notifications** - Email, Slack, and Webhook notifications 🆕
21+
-**Delegation Support** - Delegate tasks with reason tracking and original assignee preservation 🆕
22+
-**Escalation Support** - Manual and automatic time-based escalation 🆕
23+
-**Approval Chains** - Multi-level approval workflows with configurable requirements 🆕
2024

2125
## Installation
2226

@@ -297,6 +301,166 @@ await api.completeTask(task.id, {
297301
const tasks = await api.getInstanceTasks(instance.id);
298302
```
299303

304+
## Advanced Approval Features 🆕
305+
306+
The workflow plugin now includes powerful approval workflow capabilities with delegation, escalation, and multi-channel notifications.
307+
308+
### Delegation
309+
310+
Delegate tasks to other users when you're unavailable:
311+
312+
```typescript
313+
// Delegate a task to another user
314+
const delegated = await api.delegateTask(
315+
taskId,
316+
'assistant@example.com', // Delegate to
317+
'manager@example.com', // Delegated by
318+
'Out of office this week' // Reason
319+
);
320+
321+
console.log(delegated.originalAssignee); // manager@example.com
322+
console.log(delegated.assignedTo); // assistant@example.com
323+
console.log(delegated.delegationReason); // Out of office this week
324+
```
325+
326+
### Escalation
327+
328+
Escalate tasks to higher authorities:
329+
330+
```typescript
331+
// Escalate a task manually
332+
const escalated = await api.escalateTask(
333+
taskId,
334+
'director@example.com', // Escalate to
335+
'Requires executive approval', // Reason
336+
'manager@example.com' // Escalated by
337+
);
338+
339+
// Auto-escalation based on due date
340+
const task = await api.createTask({
341+
instanceId: workflowId,
342+
name: 'manager_approval',
343+
assignedTo: 'manager@example.com',
344+
status: 'pending',
345+
autoEscalate: true,
346+
escalationTarget: 'director@example.com',
347+
dueDate: new Date(Date.now() + 48 * 60 * 60 * 1000), // 48 hours
348+
});
349+
```
350+
351+
### Multi-Channel Notifications
352+
353+
Send notifications via Email, Slack, or Webhooks:
354+
355+
```typescript
356+
import {
357+
NotificationService,
358+
EmailNotificationHandler,
359+
SlackNotificationHandler,
360+
} from '@objectos/plugin-workflow';
361+
362+
// Setup notification service
363+
const notificationService = new NotificationService();
364+
365+
// Register handlers
366+
const emailHandler = new EmailNotificationHandler('noreply@company.com');
367+
const slackHandler = new SlackNotificationHandler({
368+
webhookUrl: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
369+
});
370+
371+
notificationService.registerHandler('email', emailHandler);
372+
notificationService.registerHandler('slack', slackHandler);
373+
374+
// Register notification actions
375+
const engine = api.getEngine();
376+
377+
engine.registerAction('notify_manager', async (ctx) => {
378+
await notificationService.send({
379+
channel: 'email',
380+
recipients: ['manager@company.com'],
381+
subject: 'Approval Required',
382+
message: `Please review: ${ctx.getData('title')}`,
383+
data: ctx.getData(),
384+
}, ctx);
385+
});
386+
387+
engine.registerAction('notify_slack', async (ctx) => {
388+
await notificationService.send({
389+
channel: 'slack',
390+
recipients: ['#approvals'],
391+
message: `✅ Approved: ${ctx.getData('title')}`,
392+
}, ctx);
393+
});
394+
```
395+
396+
### Multi-Level Approval Chains
397+
398+
Create complex approval workflows with multiple levels:
399+
400+
```typescript
401+
import { ApprovalService } from '@objectos/plugin-workflow';
402+
403+
const approvalService = new ApprovalService(storage);
404+
405+
// Define approval chain
406+
const approvalChain = {
407+
levels: [
408+
{
409+
level: 1,
410+
approver: 'manager@company.com',
411+
description: 'Manager approval',
412+
required: true,
413+
escalationTarget: 'senior_manager@company.com',
414+
escalationTimeout: 48 * 60 * 60 * 1000, // 48 hours
415+
},
416+
{
417+
level: 2,
418+
approver: 'director@company.com',
419+
description: 'Director approval',
420+
required: true,
421+
escalationTarget: 'vp@company.com',
422+
escalationTimeout: 72 * 60 * 60 * 1000, // 72 hours
423+
},
424+
{
425+
level: 3,
426+
approver: 'cfo@company.com',
427+
description: 'CFO final approval',
428+
required: true,
429+
},
430+
],
431+
};
432+
433+
// Create approval tasks for workflow
434+
const tasks = await approvalService.createApprovalChain(
435+
instanceId,
436+
approvalChain,
437+
'purchase_order'
438+
);
439+
440+
// Check if approval chain is complete
441+
const isComplete = await approvalService.isApprovalChainComplete(instanceId);
442+
443+
// Check if any approval was rejected
444+
const hasRejection = await approvalService.hasRejectedApproval(instanceId);
445+
446+
// Get approval history
447+
const history = await approvalService.getApprovalHistory(instanceId);
448+
```
449+
450+
### Complete Example
451+
452+
See `examples/advanced-approval-example.ts` for a comprehensive example demonstrating:
453+
- Multi-level approval workflow (Manager → Director → CFO)
454+
- Task delegation with reason tracking
455+
- Task escalation (manual and automatic)
456+
- Email and Slack notifications
457+
- Complete approval history tracking
458+
459+
```bash
460+
# Run the example
461+
ts-node examples/advanced-approval-example.ts
462+
```
463+
300464
## Querying Workflows
301465

302466
```typescript
@@ -329,6 +493,7 @@ const page2 = await api.queryWorkflows({
329493

330494
### WorkflowAPI
331495

496+
**Workflow Management:**
332497
- `registerWorkflow(definition)` - Register a workflow definition
333498
- `startWorkflow(workflowId, data, startedBy?)` - Start a new workflow instance
334499
- `getWorkflowStatus(instanceId)` - Get workflow instance status
@@ -337,11 +502,54 @@ const page2 = await api.queryWorkflows({
337502
- `queryWorkflows(options)` - Query workflow instances
338503
- `getAvailableTransitions(instanceId)` - Get available transitions
339504
- `canExecuteTransition(instanceId, transition)` - Check if transition can be executed
505+
506+
**Task Management:**
340507
- `createTask(task)` - Create a workflow task
341508
- `getTask(taskId)` - Get a task
509+
- `getInstanceTasks(instanceId)` - Get all tasks for a workflow instance
342510
- `completeTask(taskId, result?)` - Complete a task
343511
- `rejectTask(taskId, result?)` - Reject a task
344512

513+
**Advanced Approval Features:** 🆕
514+
- `delegateTask(taskId, delegateTo, delegatedBy, reason?)` - Delegate a task to another user
515+
- `escalateTask(taskId, escalateTo, reason?, escalatedBy?)` - Escalate a task to higher authority
516+
517+
**Utility:**
518+
- `getEngine()` - Get the workflow engine for registering guards/actions
519+
520+
### ApprovalService 🆕
521+
522+
- `delegateTask(request)` - Delegate a task with full tracking
523+
- `escalateTask(request)` - Escalate a task with reason
524+
- `checkAutoEscalation()` - Check and process overdue tasks for auto-escalation
525+
- `createApprovalChain(instanceId, chain, workflowName)` - Create multi-level approval tasks
526+
- `isApprovalChainComplete(instanceId)` - Check if all required approvals are complete
527+
- `hasRejectedApproval(instanceId)` - Check if any approval was rejected
528+
- `getApprovalHistory(instanceId)` - Get chronological approval history
529+
530+
### NotificationService 🆕
531+
532+
- `registerHandler(channel, handler)` - Register a notification handler
533+
- `send(config, context)` - Send a notification through registered handler
534+
- `isSupported(channel)` - Check if a notification channel is supported
535+
536+
### NotificationHandlers 🆕
537+
538+
**EmailNotificationHandler:**
539+
- Sends email notifications
540+
- Supports template rendering with variable substitution
541+
- Constructor: `new EmailNotificationHandler(fromAddress, smtpConfig?)`
542+
543+
**SlackNotificationHandler:**
544+
- Sends Slack notifications
545+
- Supports webhook URL and bot token authentication
546+
- Constructor: `new SlackNotificationHandler(config?)`
547+
548+
**WebhookNotificationHandler:**
549+
- Sends HTTP webhook notifications
550+
- Supports custom payload data
551+
- Constructor: `new WebhookNotificationHandler()`
552+
345553
### WorkflowEngine
346554

347555
- `registerGuard(name, guard)` - Register a guard function
@@ -367,7 +575,9 @@ The plugin emits the following events:
367575

368576
See the `/examples` directory for complete examples:
369577

370-
- `approval-workflow.yaml` - Multi-level approval workflow
578+
- `approval-workflow.yaml` - Basic multi-level approval workflow
579+
- `multi-level-approval-workflow.yaml` - Advanced approval with delegation and escalation 🆕
580+
- `advanced-approval-example.ts` - Complete demonstration of approval features 🆕
371581
- `sequential-workflow.yaml` - Order fulfillment workflow
372582
- `parallel-workflow.yaml` - Employee onboarding workflow
373583
- `conditional-workflow.yaml` - Support ticket routing workflow
@@ -379,12 +589,14 @@ See the `/examples` directory for complete examples:
379589
npm test
380590
```
381591

382-
The plugin includes 130+ comprehensive tests covering:
592+
The plugin includes 170+ comprehensive tests covering:
383593
- FSM engine functionality
384594
- YAML parsing and validation
385595
- API operations
386596
- Storage operations
387597
- Plugin lifecycle
598+
- Approval service (delegation, escalation, approval chains) 🆕
599+
- Notification service (email, Slack, webhooks) 🆕
388600

389601
## License
390602

0 commit comments

Comments
 (0)