PSA/docs/workflow/task-inbox-integration.md
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

492 lines
20 KiB
Markdown

# Task Inbox Integration Technical Specification
## Overview
This document outlines the technical implementation for integrating a Task Inbox system with our distributed workflow engine. The integration will enable human interactions to be seamlessly incorporated into automated workflows through an event-driven architecture.
## Core Architecture Principles
1. **Event-Driven Integration** - All human tasks are driven by the event sourcing system
2. **Form-Based Interactions** - Human interactions are structured around form submissions
3. **Workflow Continuity** - Workflows continue execution after human tasks complete
4. **Metadata-Driven UI** - UI components are dynamically generated from schema definitions
## System Components
### 1. Task Inbox Data Model
The Task Inbox requires these primary data structures:
#### Task Definition
Metadata that describes a type of human task. Task definitions can be system-wide or tenant-specific:
- **System Task Definitions (`system_workflow_task_definitions` table):**
- `task_type` (TEXT, Primary Key): Identifier for the kind of system task (e.g., 'qbo_mapping_error').
- Name and description.
- `form_id` (TEXT): Name of the form definition (usually a system form).
- `form_type` (TEXT): Indicates if the form is 'system' or 'tenant'. For system task definitions, this is typically 'system'.
- Default assignment rules, priority, SLA/due date calculations.
- No `tenant` column, as these are global.
- **Tenant-Specific Task Definitions (`workflow_task_definitions` table):**
- `task_definition_id` (UUID, Primary Key): Unique identifier for this tenant's custom task definition.
- `tenant` (UUID): Tenant identifier.
- `task_type` (TEXT): A type identifier, which could overlap with system task types if a tenant overrides a system behavior (though linkage is distinct).
- Name and description.
- `form_id` (TEXT): Name of the form definition (can be a system form or a tenant-specific form).
- `form_type` (TEXT): Indicates if the form is 'system' or 'tenant'.
- Default assignment rules, priority, SLA/due date calculations.
#### Task Instance (`workflow_tasks` table)
A specific task assigned to a user:
- Task ID (unique identifier)
- Execution ID (reference to workflow execution)
- **Task Definition Linkage:**
- `task_definition_type` (TEXT): Stores 'system' or 'tenant', indicating which type of definition this task instance uses.
- `tenant_task_definition_id` (UUID, NULLABLE): Foreign key to `workflow_task_definitions.task_definition_id`. Populated if `task_definition_type` is 'tenant'.
- `system_task_definition_task_type` (TEXT, NULLABLE): Foreign key to `system_workflow_task_definitions.task_type`. Populated if `task_definition_type` is 'system'.
- Status (pending, claimed, completed, canceled)
- Assignment information
- Due date
- Priority
- Context data (information from the workflow)
- Response data (form submission data)
### 2. Workflow Integration Points
#### Creating Tasks from Workflows
Workflows create human tasks by executing a task creation action:
```typescript
// Within a workflow definition
async function approvalWorkflow(context) {
// Create a human task
const { taskId } = await context.actions.createHumanTask({
taskType: 'approval',
title: 'Approve Request',
description: 'Please review and approve this request',
priority: 'high',
dueDate: '2 days', // Relative due date
assignTo: {
roles: ['manager'],
users: [] // Optionally assign to specific users
},
contextData: {
requestId: context.data.get('requestId'),
amount: context.data.get('amount'),
customerId: context.data.get('customerId')
}
});
// Track the task ID for future reference
context.data.set('approvalTaskId', taskId);
// Wait for the task to be completed
const taskComplete = await context.events.waitFor(`Task:${taskId}:Complete`);
// Process the form submission data
const { approved, comments } = taskComplete.payload;
if (approved) {
// Handle approval
context.setState('approved');
} else {
// Handle rejection
context.setState('rejected');
context.data.set('rejectionReason', comments);
}
}
```
#### Processing Form Submissions
When a user submits a form in the Task Inbox, it triggers this flow:
1. Validate form data against schema
2. Mark task as completed
3. Create a workflow event with form data as payload
4. Submit event to workflow engine
5. Workflow resumes execution
```typescript
// Task completion process (pseudocode)
async function completeTask(taskId, formData, userId) {
// Start transaction
const trx = await startTransaction();
try {
// Get task details
const task = await getTaskById(taskId, trx); // task will have tenant_task_definition_id, system_task_definition_task_type, and task_definition_type
// Get form schema
let taskDef;
if (task.task_definition_type === 'tenant') {
taskDef = await getTenantTaskDefinition(task.tenant_task_definition_id, trx);
} else if (task.task_definition_type === 'system') {
taskDef = await getSystemTaskDefinition(task.system_task_definition_task_type, trx);
}
if (!taskDef) {
throw new Error('Task definition not found for the task.');
}
// The taskDef object (from either system or tenant table) contains form_id and form_type
const formSchema = await getFormSchema(taskDef.form_id, taskDef.form_type, task.tenant, trx); // getFormSchema might need tenant for tenant-specific forms
// Validate form data
const isValid = validateFormData(formSchema.jsonSchema, formData);
if (!isValid) {
throw new Error('Form data validation failed');
}
// Update task status
await updateTaskStatus(taskId, 'completed', userId, trx);
// Create workflow event
const event = {
execution_id: task.executionId,
event_name: `Task:${taskId}:Complete`,
event_type: 'task_completed',
payload: formData,
user_id: userId,
tenant: task.tenant
};
// Create event in database
await createWorkflowEvent(event, trx);
// Publish to event stream
await publishToEventStream(event, trx);
// Commit transaction
await trx.commit();
return { success: true };
} catch (error) {
// Rollback transaction
await trx.rollback();
throw error;
}
}
```
### 3. Extension to Workflow Interfaces
#### Task Action Result
Extend the existing `IWorkflowActionResult` to include task-specific properties:
```typescript
export interface ITaskActionResult extends IWorkflowActionResult {
task_id: string;
task_status: string;
form_id: string;
assignment: {
roles?: string[];
users?: string[];
};
}
```
#### Task Related Events
Extend the workflow event system to recognize task-related events:
```typescript
// Example of task event types
export enum WorkflowTaskEventType {
TASK_CREATED = 'task_created',
TASK_CLAIMED = 'task_claimed',
TASK_UNCLAIMED = 'task_unclaimed',
TASK_COMPLETED = 'task_completed',
TASK_CANCELED = 'task_canceled',
TASK_EXPIRED = 'task_expired'
}
```
### 4. User Interface Components
#### Task Inbox Dashboard
The main interface showing tasks assigned to or available to the user:
- List of tasks with filters for status, priority, due date
- Grouping by workflow type, task type, or assignment
- Quick actions for claiming, completing, or delegating tasks
- Search and sort capabilities
- **Integration with User Activities Screen**: The Task Inbox will be embedded within the new "user activities" screen, providing a centralized location for users to view and interact with their workflow tasks
- **Dual Mode Support**: The component will support both standalone mode (full-featured) and embedded mode (compact view for the activities dashboard)
#### Task Detail View
Displays comprehensive information about a task:
- Task metadata (title, description, priority, due date)
- Context information from the workflow
- Form for user input
- Task history (claim/unclaim actions, previous submissions)
- Related workflow information
#### Form Renderer
Dynamic form generation based on JSON Schema:
- Uses React JSONSchema Form (RJSF)
- Custom widgets for specialized inputs
- Validation based on schema
- Conditional display logic
- File attachment handling
##### Dynamic Content and Templating in Forms
To support dynamic information within forms (e.g., pre-filling fields with context-specific default values or displaying dynamic instructional text), the system utilizes a templating mechanism. This is particularly relevant for how `defaultValues` in form schemas or `default` properties of individual schema fields are processed.
The templating engine has been enhanced to use Parsimmon for parsing and safely evaluating a limited set of JavaScript-like expressions within `${...}` syntax. This allows for more sophisticated dynamic content, such as:
* Accessing `contextData` variables (e.g., `${contextData.userName}`).
* Using logical OR for fallbacks (e.g., `${contextData.optionalValue || 'Default Text'}`).
* Formatting dates (e.g., `${new Date(contextData.eventTime).toLocaleString()}`).
This capability is leveraged by the Form Renderer when preparing forms for display, using the `contextData` associated with the task instance. The implementation ensures that only whitelisted expressions and operations are permitted, maintaining security even with user-influenced template expressions.
For a detailed technical design of this Parsimmon-based templating engine, refer to "[`docs/technical/parsimmon_templating_engine.md`](../technical/parsimmon_templating_engine.md)".
### 5. Database Schema
```sql
-- System Task Definitions table
CREATE TABLE system_workflow_task_definitions (
task_type TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
form_id TEXT NOT NULL, -- Refers to system_workflow_form_definitions.name
form_type TEXT NOT NULL DEFAULT 'system', -- Indicates the form is a system form
default_priority TEXT DEFAULT 'medium',
default_sla_days INTEGER DEFAULT 3,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
-- No tenant column
-- FOREIGN KEY (form_id) REFERENCES system_workflow_form_definitions(name) -- If desired, though form_id is a name string
);
-- Tenant-Specific Task Definitions table
CREATE TABLE workflow_task_definitions (
task_definition_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Changed to UUID
tenant UUID NOT NULL, -- Changed to UUID
task_type TEXT NOT NULL,
name TEXT NOT NULL,
description TEXT,
form_id TEXT NOT NULL, -- Can refer to system_workflow_form_definitions.name or workflow_form_definitions.name
form_type TEXT NOT NULL, -- 'system' or 'tenant'
default_priority TEXT DEFAULT 'medium',
default_sla_days INTEGER DEFAULT 3,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(tenant, task_type)
-- FOREIGN KEY (form_id) ... depends on how you resolve form_id/form_type logic for FKs
);
-- Task Instances table
CREATE TABLE workflow_tasks (
task_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Changed to UUID
tenant UUID NOT NULL, -- Changed to UUID
execution_id UUID NOT NULL, -- Assuming this is also UUID
-- event_id VARCHAR(255) NOT NULL, -- Consider if this is still needed or how it relates
task_definition_type TEXT NOT NULL, -- 'system' or 'tenant'
tenant_task_definition_id UUID NULL,
system_task_definition_task_type TEXT NULL,
title TEXT NOT NULL,
description TEXT,
status VARCHAR(50) NOT NULL DEFAULT 'pending',
priority VARCHAR(50) NOT NULL DEFAULT 'medium',
due_date TIMESTAMPTZ,
context_data JSONB,
assigned_roles JSONB,
assigned_users JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by UUID, -- Assuming user IDs are UUIDs
claimed_at TIMESTAMPTZ,
claimed_by UUID,
completed_at TIMESTAMPTZ,
completed_by UUID,
response_data JSONB,
FOREIGN KEY (tenant_task_definition_id) REFERENCES workflow_task_definitions(task_definition_id),
FOREIGN KEY (system_task_definition_task_type) REFERENCES system_workflow_task_definitions(task_type),
CONSTRAINT chk_task_def_type CHECK
((task_definition_type = 'tenant' AND tenant_task_definition_id IS NOT NULL AND system_task_definition_task_type IS NULL) OR
(task_definition_type = 'system' AND system_task_definition_task_type IS NOT NULL AND tenant_task_definition_id IS NULL))
);
-- Task history table for audit trail
CREATE TABLE workflow_task_history (
history_id VARCHAR(255) PRIMARY KEY,
task_id VARCHAR(255) NOT NULL,
tenant VARCHAR(255) NOT NULL,
action VARCHAR(50) NOT NULL,
from_status VARCHAR(50),
to_status VARCHAR(50),
user_id VARCHAR(255),
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
details JSONB,
FOREIGN KEY (task_id) REFERENCES workflow_tasks(task_id)
);
```
## Implementation Strategy
### Handling Tasks with Inline Forms
While the primary mechanism described above involves tasks linked to pre-registered form definitions via `taskType`, the system also supports tasks created with "inline forms." Inline forms are defined directly within the workflow code at the point of task creation (e.g., using actions like `create_task_with_inline_form` or `createInlineTaskAndWaitForResult`).
Here's how these are integrated into the Task Inbox:
1. **Dynamic Definition Creation**: When a task is initiated with an inline form:
* The system dynamically creates a temporary, tenant-specific form definition in the `workflow_form_definitions` table. This definition is flagged (e.g., `is_temporary: true`).
* The JSON and UI schemas provided inline are stored in `workflow_form_schemas`, linked to this temporary form definition.
* A corresponding temporary, tenant-specific task definition is created in `workflow_task_definitions`. This task definition links to the temporary form ID and specifies `form_type: 'tenant'`.
2. **Task Instance Linking**: The actual task instance created in `workflow_tasks` is then linked to this temporary tenant-specific task definition using:
* `task_definition_type: 'tenant'`
* `tenant_task_definition_id`: The ID of the dynamically created temporary task definition.
3. **Schema Retrieval by Task Inbox**: Because the task instance points to a standard (though temporary) tenant-specific task definition, the Task Inbox can retrieve its form schema using the same logic as for pre-registered forms:
* The inbox identifies the `task_definition_type` as 'tenant'.
* It uses `tenant_task_definition_id` to fetch the temporary task definition.
* This definition provides the `form_id` (of the temporary form) and `form_type` ('tenant').
* The Form Registry service (or similar logic) then retrieves the schemas from `workflow_form_definitions` and `workflow_form_schemas`.
4. **Lifecycle and Cleanup**: These temporary definitions are typically cleaned up by a background job, as detailed in the inline forms documentation (see `docs/workflow/inline-form-example.md`).
This approach allows workflows to flexibly define ad-hoc forms while ensuring the Task Inbox can consistently render and manage them without requiring separate logic for inline versus pre-registered forms at the retrieval stage.
### Phase 1: Core Infrastructure
1. **Database Schema Implementation**
- Create database tables for task definitions and instances
- Add indexes for query optimization
- Implement database migration scripts
2. **Task Inbox Service**
- Develop core service for task management
- Implement task creation, claiming, and completion
- Create event integration with workflow engine
3. **Form Integration**
- Integrate Form Registry with Task Inbox
- Implement form validation and submission
- Connect form submission to event creation
### Phase 2: UI Development
1. **Task Inbox Dashboard**
- Build list view of tasks with filtering
- Implement task sorting and pagination
- Create task action buttons (claim, complete)
- Develop both standalone and embedded modes for the component
- Create responsive design that adapts to the user activities screen context
2. **User Activities Screen Integration**
- Implement embedded version of Task Inbox for the user activities screen
- Create compact view for the activities dashboard
- Ensure consistent styling and interaction patterns with other activity types
- Implement drawer-based navigation for task details within the activities context
3. **Task Detail View**
- Create task detail display
- Integrate dynamic form renderer
- Implement form submission handling
- Support viewing task details both standalone and within the activities drawer system
4. **Notification System**
- Add real-time updates for new tasks
- Implement due date notifications
- Create alert system for high priority tasks
- Ensure notifications work in both standalone and embedded contexts
- Create alert system for high priority tasks
### Phase 3: Workflow Integration
1. **Action Registry Extension**
- Add task-related actions to workflow action registry
- Implement task creation action
- Add task query and update actions
2. **Event Processing**
- Enhance event processing for task events
- Implement event replay for task-related events
- Create task status synchronization
3. **Workflow Runtime Updates**
- Update workflow runtime to process task events
- Implement waiting for task completion
- Add task timeout handling
## Security Considerations
1. **Authorization**
- Task visibility based on user roles and permissions
- Task claiming restrictions based on assignment rules
- Form field visibility control based on user role
2. **Audit Trail**
- Comprehensive logging of all task interactions
- Record of form submissions and task status changes
- Timestamps and user information for all actions
3. **Data Protection**
- Encryption of sensitive form data
- Tenant isolation for multi-tenant deployments
- Proper validation to prevent injection attacks
## Performance Optimization
1. **Indexing Strategy**
- Optimized indexes for task queries
- Efficient filtering by status, priority, and assignment
2. **Caching Layer**
- Cache task definitions and form schemas
- Implement result caching for frequent queries
3. **Batch Processing**
- Batch notifications for task updates
- Optimized query patterns for task listing
## Monitoring and Observability
1. **Metrics Collection**
- Task completion time tracking
- SLA compliance monitoring
- User efficiency metrics
2. **Logging**
- Structured logging for task operations
- Error tracking for form validation issues
- Performance logging for slow operations
3. **Alerting**
- Alerts for tasks approaching SLA deadlines
- Notification for stalled workflows
- System health monitoring
## Future Enhancements
1. **Task Delegation and Reassignment**
- Allow users to delegate tasks to others
- Implement task reassignment workflows
- Add delegation history tracking
2. **Advanced Form Features**
- Multi-step forms with wizard interface
- Conditional section visibility
- Dynamic field generation based on context
3. **Collaborative Features**
- Comments and discussions on tasks
- Shared editing of responses
- Activity feed for task interactions
4. **Mobile Support**
- Responsive design for mobile devices
- Push notifications for task assignments
- Simplified mobile form interfaces