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
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
190 lines
6.8 KiB
Markdown
190 lines
6.8 KiB
Markdown
# Inbound Ticket Defaults Implementation Plan ✅ COMPLETED
|
|
|
|
## Table of Contents
|
|
|
|
1. [Problem Summary](#problem-summary)
|
|
2. [Solution Architecture](#solution-architecture)
|
|
3. [Implementation Phases](#implementation-phases)
|
|
- [Phase 1: Database Schema](#phase-1-database-schema)
|
|
- [Phase 2: Backend API Development](#phase-2-backend-api-development)
|
|
- [Phase 3: Workflow Integration](#phase-3-workflow-integration)
|
|
- [Phase 4: UI Components](#phase-4-ui-components)
|
|
4. [Database Schema Details](#database-schema-details)
|
|
5. [TypeScript Interfaces](#typescript-interfaces)
|
|
6. [File Changes Summary](#file-changes-summary)
|
|
|
|
## Problem Summary
|
|
|
|
The email-to-ticket workflow is failing with validation errors because required ticket fields (`channel_id`, `company_id`, `status_id`, `priority_id`, `entered_by`, etc.) are not being provided. The workflow receives email data but cannot create tickets without these mandatory database fields.
|
|
|
|
## Solution Architecture
|
|
|
|
Create a flexible `inbound_ticket_defaults` table with named default configurations that can be referenced by email providers. This design allows for reusable default configurations and enables future domain-based routing capabilities.
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1: Database Schema ✅
|
|
|
|
- [x] Create `inbound_ticket_defaults` table migration
|
|
- [x] Add reference column to `email_providers` table
|
|
- [x] Create default inbound ticket defaults seed data
|
|
|
|
### Phase 2: Backend API Development ✅
|
|
|
|
- [x] Create inbound ticket defaults actions (CRUD operations)
|
|
- [x] Create ticket field options actions (for dropdowns)
|
|
- [x] Update email provider actions to handle defaults reference
|
|
- [x] Add TypeScript interfaces for new types
|
|
- [x] Update TicketModel to allow null `entered_by` for system-generated tickets
|
|
|
|
### Phase 3: Workflow Integration ✅
|
|
|
|
- [x] Update `createTicketFromEmail()` to accept default field values
|
|
- [x] Create helper function to resolve email provider's ticket defaults
|
|
- [x] Update email processing workflow to retrieve and use defaults
|
|
- [x] Validate workflow execution with configured defaults
|
|
|
|
### Phase 4: UI Components ✅
|
|
|
|
- [x] Create InboundTicketDefaultsManager component
|
|
- [x] Create InboundTicketDefaultsForm component
|
|
- [x] Update provider forms to select from existing defaults
|
|
- [x] Integrate defaults management into EmailProviderConfiguration
|
|
|
|
## Database Schema Details
|
|
|
|
### New Table: `inbound_ticket_defaults`
|
|
|
|
```sql
|
|
CREATE TABLE inbound_ticket_defaults (
|
|
id UUID NOT NULL,
|
|
tenant UUID NOT NULL,
|
|
short_name VARCHAR(100) NOT NULL,
|
|
display_name VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
defaults JSONB NOT NULL DEFAULT '{}',
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (id, tenant),
|
|
FOREIGN KEY (tenant) REFERENCES tenants(tenant),
|
|
UNIQUE (tenant, short_name)
|
|
);
|
|
```
|
|
|
|
### Email Providers Table Update
|
|
|
|
```sql
|
|
ALTER TABLE email_providers
|
|
ADD COLUMN inbound_ticket_defaults_id UUID;
|
|
```
|
|
|
|
### Default JSON Structure
|
|
|
|
```json
|
|
{
|
|
"channel_id": "uuid",
|
|
"status_id": "uuid",
|
|
"priority_id": "uuid",
|
|
"company_id": "uuid",
|
|
"entered_by": null,
|
|
"category_id": "uuid",
|
|
"subcategory_id": "uuid",
|
|
"location_id": "uuid"
|
|
}
|
|
```
|
|
|
|
## TypeScript Interfaces
|
|
|
|
```typescript
|
|
interface InboundTicketDefaults {
|
|
id: string;
|
|
tenant: string;
|
|
short_name: string;
|
|
display_name: string;
|
|
description?: string;
|
|
defaults: {
|
|
channel_id: string;
|
|
status_id: string;
|
|
priority_id: string;
|
|
company_id?: string;
|
|
entered_by?: string | null;
|
|
category_id?: string;
|
|
subcategory_id?: string;
|
|
location_id?: string;
|
|
};
|
|
is_active: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
interface TicketFieldOptions {
|
|
channels: Array<{ id: string; name: string; is_default: boolean }>;
|
|
statuses: Array<{ id: string; name: string }>;
|
|
priorities: Array<{ id: string; name: string }>;
|
|
categories: Array<{ id: string; name: string; parent_id?: string }>;
|
|
users: Array<{ id: string; name: string; username: string }>;
|
|
}
|
|
```
|
|
|
|
## File Changes Summary
|
|
|
|
### New Files ✅
|
|
- `/server/migrations/20250713002000_create_inbound_ticket_defaults_table.cjs` ✅
|
|
- `/server/migrations/20250713002001_add_defaults_ref_to_email_providers.cjs` ✅
|
|
- `/server/seeds/dev/005_default_inbound_ticket_defaults.cjs` ✅
|
|
- `/server/src/lib/actions/email-actions/inboundTicketDefaultsActions.ts` ✅
|
|
- `/server/src/lib/actions/email-actions/ticketFieldOptionsActions.ts` ✅
|
|
- `/server/src/components/admin/InboundTicketDefaultsManager.tsx` ✅
|
|
- `/server/src/components/forms/InboundTicketDefaultsForm.tsx` ✅
|
|
|
|
### Modified Files ✅
|
|
- `/server/src/lib/actions/email-actions/emailProviderActions.ts` ✅
|
|
- `/server/src/components/EmailProviderConfiguration.tsx` ✅
|
|
- `/server/src/components/MicrosoftProviderForm.tsx` ✅
|
|
- `/server/src/components/GmailProviderForm.tsx` ⏳ (Pending - similar changes as Microsoft)
|
|
- `/shared/workflow/actions/emailWorkflowActions.ts` ✅
|
|
- `/shared/models/ticketModel.ts` - Update validation to allow null `entered_by` ✅
|
|
- `/server/seeds/dev/004_email_processing_workflow_from_source.cjs` ✅
|
|
- `/server/src/types/email.types.ts` ✅
|
|
|
|
### Key Implementation Details
|
|
|
|
#### Database Migration Strategy
|
|
1. Create `inbound_ticket_defaults` table with tenant partitioning
|
|
2. Add foreign key reference from `email_providers`
|
|
3. Seed with default "email-general" configuration
|
|
|
|
#### Backend API Pattern
|
|
- Follow existing email actions pattern with tenant isolation
|
|
- Use consistent error handling and validation
|
|
- Return structured responses with proper TypeScript types
|
|
- Update TicketModel validation to allow `entered_by: null` for system tickets
|
|
|
|
#### Workflow Integration Points
|
|
- Resolve email provider → inbound ticket defaults in workflow
|
|
- Pass defaults as additional parameters to ticket creation
|
|
- Merge email data with configured defaults before validation
|
|
|
|
#### UI Component Architecture
|
|
- Reusable form components for ticket field selection
|
|
- Manager component for CRUD operations on defaults
|
|
- Integration into existing email provider configuration flow
|
|
|
|
#### System-Generated Ticket Handling
|
|
For tickets created from email processing, `entered_by` will be `null` to indicate system generation:
|
|
- Update TicketModel validation schema to allow `entered_by: null`
|
|
- Modify ticket creation logic to handle null `entered_by` gracefully
|
|
- UI components should display "System" when `entered_by` is null
|
|
- Audit logs should show system-generated entries appropriately
|
|
|
|
#### TicketModel Changes Required
|
|
```typescript
|
|
// Update validation to allow null for system tickets
|
|
entered_by: z.string().uuid().nullable().optional()
|
|
|
|
// In createTicket logic:
|
|
const auditUser = data.entered_by || 'system';
|
|
```
|
|
|
|
This implementation focuses strictly on solving the immediate validation issue while providing a solid foundation for the email-to-ticket workflow. |