feat: Autotask webhook integration, TicketNotes, Datto RMM, workflow engine, Veeam agents/alarms, AI triage, misc improvements
This commit is contained in:
parent
347cf4e298
commit
d7c3dc7168
74 changed files with 37844 additions and 322 deletions
|
|
@ -140,6 +140,19 @@ export interface Company {
|
|||
competitorID?: number;
|
||||
}
|
||||
|
||||
export interface TicketNote {
|
||||
id: number;
|
||||
ticketID: number;
|
||||
title?: string;
|
||||
description?: string;
|
||||
noteType?: number;
|
||||
publish?: number;
|
||||
creatorResourceID?: number;
|
||||
creatorType?: number;
|
||||
lastActivityDate?: string;
|
||||
createDateTime?: string;
|
||||
}
|
||||
|
||||
export interface ConfigurationItem {
|
||||
id: number;
|
||||
companyID: number;
|
||||
|
|
|
|||
|
|
@ -435,6 +435,13 @@ export interface SyncHistoryRecord {
|
|||
triggered_by?: string | null;
|
||||
}
|
||||
|
||||
// Device Lifecycle Policy entity
|
||||
export interface DeviceLifecyclePolicy extends AuditFields {
|
||||
id: number;
|
||||
device_type: string;
|
||||
expected_months: number;
|
||||
}
|
||||
|
||||
// Time Entry entity
|
||||
export interface TimeEntry extends AuditFields {
|
||||
id: number;
|
||||
|
|
@ -492,9 +499,9 @@ export type Entity =
|
|||
| IssueType
|
||||
| SubIssueType
|
||||
| WorkType
|
||||
| TimeEntry;
|
||||
| TimeEntry
|
||||
| DeviceLifecyclePolicy;
|
||||
|
||||
// Table name type
|
||||
export type TableName =
|
||||
| 'companies'
|
||||
| 'resources'
|
||||
|
|
@ -510,4 +517,5 @@ export type TableName =
|
|||
| 'sub_issue_types'
|
||||
| 'work_types'
|
||||
| 'time_entries'
|
||||
| 'sync_history';
|
||||
| 'sync_history'
|
||||
| 'device_lifecycle_policies';
|
||||
|
|
|
|||
|
|
@ -62,28 +62,72 @@ export interface DattoRMMDevice {
|
|||
}
|
||||
|
||||
export interface DattoRMMSite {
|
||||
id: string;
|
||||
id: number;
|
||||
uid: string;
|
||||
accountUid?: string;
|
||||
name: string;
|
||||
description: string;
|
||||
notes: string;
|
||||
notes: string | null;
|
||||
onDemand: boolean;
|
||||
splashtopAutoInstall?: boolean;
|
||||
proxySettings?: {
|
||||
host: string;
|
||||
port: number;
|
||||
username?: string;
|
||||
} | null;
|
||||
devicesStatus?: {
|
||||
numberOfDevices: number;
|
||||
numberOfOnlineDevices: number;
|
||||
numberOfOfflineDevices: number;
|
||||
};
|
||||
autotaskCompanyName?: string;
|
||||
autotaskCompanyId?: string;
|
||||
portalUrl?: string;
|
||||
devices?: DattoRMMDevice[];
|
||||
}
|
||||
|
||||
export interface DattoRMMAlert {
|
||||
alertUid: string;
|
||||
priority: string;
|
||||
diagnostics: string | null;
|
||||
resolved: boolean;
|
||||
resolvedBy: string | null;
|
||||
resolvedOn: number | null;
|
||||
muted: boolean;
|
||||
ticketNumber: string | null;
|
||||
timestamp: number;
|
||||
alertMonitorInfo?: {
|
||||
sendsEmails: boolean;
|
||||
createsTicket: boolean;
|
||||
};
|
||||
alertContext?: {
|
||||
'@class': string;
|
||||
[key: string]: any;
|
||||
};
|
||||
alertSourceInfo?: {
|
||||
deviceUid: string;
|
||||
deviceName: string;
|
||||
siteUid: string;
|
||||
siteName: string;
|
||||
};
|
||||
responseActions?: Array<{
|
||||
actionTime: number;
|
||||
actionType: string;
|
||||
description: string;
|
||||
actionReference: string | null;
|
||||
actionReferenceInt: string | null;
|
||||
}> | null;
|
||||
autoresolveMins?: number;
|
||||
}
|
||||
|
||||
export interface DattoRMMApiResponse<T> {
|
||||
items?: T[];
|
||||
item?: T;
|
||||
pageDetails?: {
|
||||
page: number;
|
||||
perPage: number;
|
||||
totalPages: number;
|
||||
totalItems: number;
|
||||
count: number;
|
||||
totalCount?: number;
|
||||
prevPageUrl: string | null;
|
||||
nextPageUrl: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,15 @@ export enum EntityType {
|
|||
ISSUE_TYPES = 'issue_types',
|
||||
SUB_ISSUE_TYPES = 'sub_issue_types',
|
||||
WORK_TYPES = 'work_types',
|
||||
QUEUES = 'queues',
|
||||
PRIORITIES = 'priorities',
|
||||
TICKET_CATEGORIES = 'ticket_categories',
|
||||
BILLING_ITEMS = 'billing_items',
|
||||
CONFIGURATION_ITEMS = 'configuration_items',
|
||||
CONTACTS = 'contacts',
|
||||
CONTRACTS = 'contracts',
|
||||
TIME_ENTRIES = 'time_entries',
|
||||
TICKET_NOTES = 'ticket_notes',
|
||||
}
|
||||
|
||||
// Sync operation types
|
||||
|
|
@ -151,6 +155,9 @@ export const ENTITY_DEPENDENCIES: Record<EntityType, EntityType[]> = {
|
|||
[EntityType.ISSUE_TYPES]: [], // No dependencies
|
||||
[EntityType.SUB_ISSUE_TYPES]: [], // No dependencies
|
||||
[EntityType.WORK_TYPES]: [], // No dependencies
|
||||
[EntityType.QUEUES]: [], // No dependencies
|
||||
[EntityType.PRIORITIES]: [], // No dependencies
|
||||
[EntityType.TICKET_CATEGORIES]: [], // No dependencies
|
||||
[EntityType.CONTACTS]: [EntityType.COMPANIES], // Depends on companies
|
||||
[EntityType.PROJECTS]: [EntityType.COMPANIES, EntityType.RESOURCES], // Depends on companies and resources
|
||||
[EntityType.TICKETS]: [EntityType.COMPANIES, EntityType.RESOURCES, EntityType.CONTACTS], // Depends on companies, resources, contacts
|
||||
|
|
@ -159,6 +166,7 @@ export const ENTITY_DEPENDENCIES: Record<EntityType, EntityType[]> = {
|
|||
[EntityType.CONTRACTS]: [EntityType.COMPANIES, EntityType.CONTACTS], // Depends on companies and contacts
|
||||
[EntityType.BILLING_ITEMS]: [EntityType.COMPANIES, EntityType.TASKS, EntityType.TICKETS, EntityType.PROJECTS], // Depends on multiple entities
|
||||
[EntityType.TIME_ENTRIES]: [EntityType.COMPANIES, EntityType.RESOURCES, EntityType.CONTACTS, EntityType.PROJECTS, EntityType.TASKS, EntityType.TICKETS], // Depends on many entities
|
||||
[EntityType.TICKET_NOTES]: [EntityType.TICKETS], // Depends on tickets
|
||||
};
|
||||
|
||||
// Autotask API field names (for incremental sync)
|
||||
|
|
|
|||
|
|
@ -367,3 +367,57 @@ export interface VeeamComplianceSummary {
|
|||
backedUpNotContracted: number;
|
||||
computedAt: Date | null;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// New entity types: Backup Agents + Alarms
|
||||
// ============================================================================
|
||||
|
||||
export interface VspcBackupAgent {
|
||||
instanceUid: string;
|
||||
organizationUid: string;
|
||||
siteUid?: string;
|
||||
managementAgentUid?: string;
|
||||
name: string;
|
||||
agentPlatform: string;
|
||||
status: string;
|
||||
managementAgentStatus: string;
|
||||
operationMode: string;
|
||||
guiMode?: string;
|
||||
platform?: string;
|
||||
version?: string;
|
||||
versionStatus?: string;
|
||||
managementMode?: string;
|
||||
installationType?: string;
|
||||
activationTime?: string;
|
||||
totalJobsCount: number;
|
||||
runningJobsCount: number;
|
||||
successJobsCount: number;
|
||||
}
|
||||
|
||||
export interface VspcAlarmActivation {
|
||||
instanceUid: string;
|
||||
time: string;
|
||||
status: string;
|
||||
message: string;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface VspcAlarmObject {
|
||||
instanceUid: string;
|
||||
type: string;
|
||||
organizationUid?: string;
|
||||
locationUid?: string;
|
||||
managementAgentUid?: string;
|
||||
computerName?: string;
|
||||
objectUid?: string;
|
||||
objectName?: string;
|
||||
}
|
||||
|
||||
export interface VspcAlarm {
|
||||
instanceUid: string;
|
||||
alarmTemplateUid: string;
|
||||
repeatCount: number;
|
||||
object: VspcAlarmObject;
|
||||
lastActivation: VspcAlarmActivation;
|
||||
area?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export enum WebhookEventType {
|
|||
export enum WebhookEntityType {
|
||||
COMPANIES = 'Companies',
|
||||
TICKETS = 'Tickets',
|
||||
TICKET_NOTES = 'TicketNotes',
|
||||
TASKS = 'Tasks',
|
||||
PROJECTS = 'Projects',
|
||||
TIME_ENTRIES = 'TimeEntries',
|
||||
|
|
@ -27,43 +28,125 @@ export enum WebhookEntityType {
|
|||
}
|
||||
|
||||
/**
|
||||
* Autotask webhook payload structure
|
||||
* Autotask entities that support webhooks via their REST API
|
||||
*/
|
||||
export const WEBHOOK_SUPPORTED_ENTITIES: WebhookEntityType[] = [
|
||||
WebhookEntityType.COMPANIES,
|
||||
WebhookEntityType.CONTACTS,
|
||||
WebhookEntityType.CONFIGURATION_ITEMS,
|
||||
WebhookEntityType.TICKETS,
|
||||
WebhookEntityType.TICKET_NOTES,
|
||||
];
|
||||
|
||||
/**
|
||||
* Autotask webhook registration request
|
||||
*/
|
||||
export interface AutotaskWebhookRegistration {
|
||||
IsActive: boolean;
|
||||
DeactivationUrl: string;
|
||||
IsSubscribedToCreateEvents?: boolean;
|
||||
IsSubscribedToUpdateEvents?: boolean;
|
||||
IsSubscribedToDeleteEvents?: boolean;
|
||||
Name: string;
|
||||
SecretKey: string;
|
||||
SendThresholdExceededNotification: boolean;
|
||||
WebhookUrl: string;
|
||||
NotificationEmailAddress: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autotask webhook field trigger
|
||||
*/
|
||||
export interface AutotaskWebhookFieldTrigger {
|
||||
FieldID: number;
|
||||
IsDisplayAlwaysField: boolean;
|
||||
IsSubscribedField: boolean;
|
||||
WebhookID: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autotask webhook registration result
|
||||
*/
|
||||
export interface AutotaskWebhookRegistrationResult {
|
||||
entityType: WebhookEntityType;
|
||||
webhookId: number;
|
||||
fieldsRegistered: number;
|
||||
excludedResources: number;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw Autotask webhook payload as actually sent by Autotask
|
||||
*/
|
||||
export interface AutotaskRawWebhookPayload {
|
||||
Action: string; // "Create", "Update", "Delete"
|
||||
Guid: string; // Unique event GUID
|
||||
EntityType: string; // Singular: "Ticket", "Company", "Contact", "ConfigurationItem", "TicketNote"
|
||||
Id: number; // Entity ID
|
||||
Fields?: Record<string, string>; // Changed/created fields
|
||||
EventTime: string; // ISO timestamp
|
||||
SequenceNumber?: number;
|
||||
PersonId?: number; // Resource who triggered the event
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalized webhook payload used internally
|
||||
*/
|
||||
export interface AutotaskWebhookPayload {
|
||||
/**
|
||||
* Unique identifier for the webhook event
|
||||
*/
|
||||
eventId: string;
|
||||
|
||||
/**
|
||||
* Type of event (create, update, delete)
|
||||
*/
|
||||
eventType: WebhookEventType;
|
||||
|
||||
/**
|
||||
* Entity type that triggered the webhook
|
||||
*/
|
||||
entityType: WebhookEntityType;
|
||||
|
||||
/**
|
||||
* ID of the entity that changed
|
||||
*/
|
||||
entityId: number;
|
||||
|
||||
/**
|
||||
* Timestamp when the event occurred
|
||||
*/
|
||||
eventTimestamp: string;
|
||||
|
||||
/**
|
||||
* Optional: Full entity data (if configured in webhook)
|
||||
*/
|
||||
fields?: Record<string, string>;
|
||||
entity?: Record<string, any>;
|
||||
personId?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional: Previous values for update events
|
||||
*/
|
||||
previousValues?: Record<string, any>;
|
||||
/**
|
||||
* Map Autotask singular EntityType to our WebhookEntityType enum
|
||||
*/
|
||||
const ENTITY_TYPE_MAP: Record<string, WebhookEntityType> = {
|
||||
'Company': WebhookEntityType.COMPANIES,
|
||||
'Contact': WebhookEntityType.CONTACTS,
|
||||
'ConfigurationItem': WebhookEntityType.CONFIGURATION_ITEMS,
|
||||
'Ticket': WebhookEntityType.TICKETS,
|
||||
'TicketNote': WebhookEntityType.TICKET_NOTES,
|
||||
};
|
||||
|
||||
/**
|
||||
* Map Autotask Action string to our WebhookEventType enum
|
||||
*/
|
||||
const ACTION_MAP: Record<string, WebhookEventType> = {
|
||||
'Create': WebhookEventType.CREATE,
|
||||
'Update': WebhookEventType.UPDATE,
|
||||
'Delete': WebhookEventType.DELETE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize a raw Autotask webhook payload into our internal format
|
||||
*/
|
||||
export function normalizeWebhookPayload(raw: AutotaskRawWebhookPayload): AutotaskWebhookPayload {
|
||||
const entityType = ENTITY_TYPE_MAP[raw.EntityType];
|
||||
if (!entityType) {
|
||||
throw new Error(`Unknown Autotask EntityType: ${raw.EntityType}`);
|
||||
}
|
||||
|
||||
const eventType = ACTION_MAP[raw.Action];
|
||||
if (!eventType) {
|
||||
throw new Error(`Unknown Autotask Action: ${raw.Action}`);
|
||||
}
|
||||
|
||||
return {
|
||||
eventId: raw.Guid,
|
||||
eventType,
|
||||
entityType,
|
||||
entityId: raw.Id,
|
||||
eventTimestamp: raw.EventTime,
|
||||
fields: raw.Fields,
|
||||
personId: raw.PersonId,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
427
lib/types/workflow.ts
Normal file
427
lib/types/workflow.ts
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
/**
|
||||
* Workflow Engine Types
|
||||
* TypeScript definitions for the ticket triage workflow engine
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// Enums & Constants
|
||||
// ============================================================================
|
||||
|
||||
export type RuleType =
|
||||
| 'branch_routing'
|
||||
| 'ticket_type'
|
||||
| 'issue_classification'
|
||||
| 'priority'
|
||||
| 'queue_routing';
|
||||
|
||||
export type MatchField =
|
||||
| 'title'
|
||||
| 'description'
|
||||
| 'title_or_description'
|
||||
| 'ticket_category'
|
||||
| 'policy_name'
|
||||
| 'device_name'
|
||||
| 'creator_resource_id'
|
||||
| 'priority'
|
||||
| 'ticket_type'
|
||||
| 'person_id'
|
||||
| 'company_id';
|
||||
|
||||
export type MatchOperator =
|
||||
| 'contains'
|
||||
| 'starts_with'
|
||||
| 'regex'
|
||||
| 'equals'
|
||||
| 'in'
|
||||
| 'not_in';
|
||||
|
||||
export type ConditionOperator =
|
||||
| 'equals'
|
||||
| 'not_equals'
|
||||
| 'in'
|
||||
| 'not_in'
|
||||
| 'contains'
|
||||
| 'not_contains'
|
||||
| 'regex'
|
||||
| 'gt'
|
||||
| 'lt'
|
||||
| 'is_null'
|
||||
| 'is_not_null';
|
||||
|
||||
export type ConfidenceLevel = 'high' | 'medium' | 'low';
|
||||
|
||||
export type Branch = 'service_desk' | 'noc' | 'soc';
|
||||
|
||||
export type ClassificationMethod = 'robotic' | 'ai' | 'hybrid';
|
||||
|
||||
export type ExecutionStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
|
||||
|
||||
export type StepMethod = 'robotic' | 'ai' | 'skipped';
|
||||
|
||||
export type ActionType =
|
||||
| 'set_field'
|
||||
| 'classify'
|
||||
| 'ai_enhance'
|
||||
| 'create_note'
|
||||
| 'update_autotask'
|
||||
| 'delay'
|
||||
| 'skip';
|
||||
|
||||
export type PromptPurpose =
|
||||
| 'title_cleanup'
|
||||
| 'description_rewrite'
|
||||
| 'ambiguous_classification'
|
||||
| 'troubleshooting_steps'
|
||||
| 'noc_format'
|
||||
| 'soc_analysis';
|
||||
|
||||
export type TriggerEvent = 'ticket.created' | 'ticket.updated';
|
||||
|
||||
export type StepName =
|
||||
| 'filter'
|
||||
| 'branch_routing'
|
||||
| 'ticket_type'
|
||||
| 'issue_classification'
|
||||
| 'priority'
|
||||
| 'queue_routing'
|
||||
| 'validation'
|
||||
| 'ai_title'
|
||||
| 'ai_description'
|
||||
| 'ai_classification'
|
||||
| 'ai_troubleshooting'
|
||||
| 'autotask_update'
|
||||
| 'create_note';
|
||||
|
||||
// ============================================================================
|
||||
// Database Row Types
|
||||
// ============================================================================
|
||||
|
||||
export interface ClassificationRule {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string | null;
|
||||
rule_type: RuleType;
|
||||
sort_order: number;
|
||||
is_active: boolean;
|
||||
match_field: MatchField;
|
||||
match_operator: MatchOperator;
|
||||
match_value: any; // JSONB: string | string[] | regex pattern
|
||||
match_case_sensitive: boolean;
|
||||
result_field: string;
|
||||
result_value: any; // JSONB
|
||||
result_field_2: string | null;
|
||||
result_value_2: any | null;
|
||||
confidence: ConfidenceLevel;
|
||||
stop_on_match: boolean;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
export interface WorkflowRule {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string | null;
|
||||
is_active: boolean;
|
||||
sort_order: number;
|
||||
trigger_event: TriggerEvent;
|
||||
trigger_entity: string;
|
||||
stop_processing: boolean;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
export interface WorkflowCondition {
|
||||
id: number;
|
||||
rule_id: number;
|
||||
condition_group: number;
|
||||
field: string;
|
||||
operator: ConditionOperator;
|
||||
value: any; // JSONB
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
export interface WorkflowAction {
|
||||
id: number;
|
||||
rule_id: number;
|
||||
sort_order: number;
|
||||
action_type: ActionType;
|
||||
config: Record<string, any>;
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
export interface AiPromptTemplate {
|
||||
id: number;
|
||||
name: string;
|
||||
purpose: PromptPurpose;
|
||||
system_prompt: string;
|
||||
user_prompt_template: string;
|
||||
provider: string;
|
||||
model: string;
|
||||
temperature: number;
|
||||
max_tokens: number;
|
||||
is_active: boolean;
|
||||
version: number;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
export interface WorkflowExecution {
|
||||
id: number;
|
||||
trigger_event: string;
|
||||
entity_type: string;
|
||||
entity_id: number;
|
||||
ticket_number: string | null;
|
||||
status: ExecutionStatus;
|
||||
classification_method: ClassificationMethod | null;
|
||||
branch: Branch | null;
|
||||
started_at: Date;
|
||||
completed_at: Date | null;
|
||||
duration_ms: number | null;
|
||||
error_message: string | null;
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
export interface WorkflowExecutionStep {
|
||||
id: number;
|
||||
execution_id: number;
|
||||
step_name: StepName;
|
||||
step_order: number;
|
||||
status: ExecutionStatus;
|
||||
method: StepMethod | null;
|
||||
input_data: Record<string, any> | null;
|
||||
output_data: Record<string, any> | null;
|
||||
field_changes: Record<string, { before: any; after: any }> | null;
|
||||
classification_rule_id: number | null;
|
||||
confidence: ConfidenceLevel | null;
|
||||
ai_request: Record<string, any> | null;
|
||||
ai_response: string | null;
|
||||
attempt_number: number;
|
||||
error_message: string | null;
|
||||
duration_ms: number | null;
|
||||
started_at: Date | null;
|
||||
completed_at: Date | null;
|
||||
}
|
||||
|
||||
export interface WorkflowSetting {
|
||||
key: string;
|
||||
value: any; // JSONB
|
||||
description: string | null;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Runtime Types (used during processing)
|
||||
// ============================================================================
|
||||
|
||||
/** Ticket data as consumed by the workflow engine */
|
||||
export interface TicketData {
|
||||
id: number;
|
||||
ticket_number: string | null;
|
||||
title: string;
|
||||
description: string | null;
|
||||
ticket_category: number | null;
|
||||
ticket_type: number | null;
|
||||
priority: number | null;
|
||||
queue_id: number | null;
|
||||
issue_type: number | null;
|
||||
sub_issue_type: number | null;
|
||||
company_id: number;
|
||||
contact_id: number | null;
|
||||
assigned_resource_id: number | null;
|
||||
creator_resource_id: number | null;
|
||||
person_id: number | null;
|
||||
status: number | null;
|
||||
source: number | null;
|
||||
// Computed/extracted fields for classification
|
||||
policy_name?: string | null;
|
||||
device_name?: string | null;
|
||||
}
|
||||
|
||||
/** Result from a single classification step */
|
||||
export interface ClassificationStepResult {
|
||||
field: string;
|
||||
value: any;
|
||||
field_2?: string;
|
||||
value_2?: any;
|
||||
confidence: ConfidenceLevel;
|
||||
matched_rule_id: number | null;
|
||||
matched_rule_name: string | null;
|
||||
method: StepMethod;
|
||||
}
|
||||
|
||||
/** Full classification result from robotic classifier */
|
||||
export interface ClassificationResult {
|
||||
branch: ClassificationStepResult | null;
|
||||
ticket_type: ClassificationStepResult | null;
|
||||
issue_classification: ClassificationStepResult | null;
|
||||
priority: ClassificationStepResult | null;
|
||||
queue: ClassificationStepResult | null;
|
||||
overall_confidence: ConfidenceLevel;
|
||||
needs_ai: boolean;
|
||||
ai_reasons: string[];
|
||||
}
|
||||
|
||||
/** Validation result */
|
||||
export interface ValidationResult {
|
||||
is_valid: boolean;
|
||||
errors: ValidationError[];
|
||||
}
|
||||
|
||||
export interface ValidationError {
|
||||
field: string;
|
||||
message: string;
|
||||
value: any;
|
||||
}
|
||||
|
||||
/** AI enhancement result */
|
||||
export interface AiEnhancementResult {
|
||||
title?: string;
|
||||
description?: string;
|
||||
classification?: {
|
||||
issue_type?: number;
|
||||
sub_issue_type?: number;
|
||||
ticket_type?: number;
|
||||
priority?: number;
|
||||
};
|
||||
troubleshooting_steps?: string;
|
||||
method: 'ai';
|
||||
}
|
||||
|
||||
/** Field changes to write back to Autotask */
|
||||
export interface FieldChanges {
|
||||
[field: string]: {
|
||||
before: any;
|
||||
after: any;
|
||||
};
|
||||
}
|
||||
|
||||
/** Full execution result */
|
||||
export interface ExecutionResult {
|
||||
execution_id: number;
|
||||
status: ExecutionStatus;
|
||||
classification_method: ClassificationMethod;
|
||||
branch: Branch;
|
||||
field_changes: FieldChanges;
|
||||
steps: ExecutionStepSummary[];
|
||||
duration_ms: number;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface ExecutionStepSummary {
|
||||
step_name: StepName;
|
||||
status: ExecutionStatus;
|
||||
method: StepMethod;
|
||||
confidence?: ConfidenceLevel;
|
||||
matched_rule?: string;
|
||||
duration_ms: number;
|
||||
}
|
||||
|
||||
/** Workflow event that triggers processing */
|
||||
export interface WorkflowEvent {
|
||||
trigger_event: TriggerEvent;
|
||||
entity_type: string;
|
||||
entity_id: number;
|
||||
ticket_number?: string;
|
||||
ticket_data?: TicketData;
|
||||
}
|
||||
|
||||
/** Workflow settings loaded into memory */
|
||||
export interface WorkflowSettings {
|
||||
workflow_engine_enabled: boolean;
|
||||
default_ai_provider: 'openai' | 'anthropic';
|
||||
openai_api_key: string;
|
||||
openai_model: string;
|
||||
anthropic_api_key: string;
|
||||
anthropic_model: string;
|
||||
ai_for_title_cleanup: boolean;
|
||||
ai_for_description_rewrite: boolean;
|
||||
ai_for_ambiguous_classification: boolean;
|
||||
ai_for_troubleshooting: boolean;
|
||||
autotask_update_delay_ms: number;
|
||||
max_ai_retries: number;
|
||||
classification_confidence_threshold: ConfidenceLevel;
|
||||
log_retention_days: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// API Types (request/response shapes for API routes)
|
||||
// ============================================================================
|
||||
|
||||
export interface ClassificationRuleInput {
|
||||
name: string;
|
||||
description?: string;
|
||||
rule_type: RuleType;
|
||||
sort_order?: number;
|
||||
is_active?: boolean;
|
||||
match_field: MatchField;
|
||||
match_operator: MatchOperator;
|
||||
match_value: any;
|
||||
match_case_sensitive?: boolean;
|
||||
result_field: string;
|
||||
result_value: any;
|
||||
result_field_2?: string;
|
||||
result_value_2?: any;
|
||||
confidence?: ConfidenceLevel;
|
||||
stop_on_match?: boolean;
|
||||
}
|
||||
|
||||
export interface WorkflowRuleInput {
|
||||
name: string;
|
||||
description?: string;
|
||||
is_active?: boolean;
|
||||
sort_order?: number;
|
||||
trigger_event: TriggerEvent;
|
||||
trigger_entity?: string;
|
||||
stop_processing?: boolean;
|
||||
conditions: WorkflowConditionInput[];
|
||||
actions: WorkflowActionInput[];
|
||||
}
|
||||
|
||||
export interface WorkflowConditionInput {
|
||||
condition_group?: number;
|
||||
field: string;
|
||||
operator: ConditionOperator;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export interface WorkflowActionInput {
|
||||
sort_order?: number;
|
||||
action_type: ActionType;
|
||||
config?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface AiPromptTemplateInput {
|
||||
name: string;
|
||||
purpose: PromptPurpose;
|
||||
system_prompt: string;
|
||||
user_prompt_template: string;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
temperature?: number;
|
||||
max_tokens?: number;
|
||||
is_active?: boolean;
|
||||
}
|
||||
|
||||
export interface WorkflowTestRequest {
|
||||
ticket_id: number;
|
||||
dry_run?: boolean; // default true
|
||||
}
|
||||
|
||||
export interface WorkflowTestResult {
|
||||
ticket: TicketData;
|
||||
classification: ClassificationResult;
|
||||
validation: ValidationResult;
|
||||
proposed_changes: FieldChanges;
|
||||
execution_steps: ExecutionStepSummary[];
|
||||
}
|
||||
|
||||
/** Workflow rule with its conditions and actions loaded */
|
||||
export interface WorkflowRuleWithDetails extends WorkflowRule {
|
||||
conditions: WorkflowCondition[];
|
||||
actions: WorkflowAction[];
|
||||
}
|
||||
|
||||
/** Execution with its steps loaded */
|
||||
export interface WorkflowExecutionWithSteps extends WorkflowExecution {
|
||||
steps: WorkflowExecutionStep[];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue