/** * Update Ticket Step — writes field_changes back to Autotask. * Config: { * use_field_changes: boolean // use context.field_changes * } */ import { registerWorkflowStepExecutor } from '../ticket-workflow-engine'; import { AutotaskClient } from '../autotask-client'; import { postgresClient } from '../postgres-client'; import { TicketWorkflowStep, WorkflowStepContext, WorkflowStepResult } from '../../types/ticket-workflow'; async function executeUpdateTicket( step: TicketWorkflowStep, context: WorkflowStepContext, _executionId: number ): Promise { const fieldChanges = context.field_changes || {}; const changeKeys = Object.keys(fieldChanges); if (changeKeys.length === 0) { return { success: true, output: { skipped: true, reason: 'No field changes to apply' } }; } // Build Autotask update payload const updatePayload: any = {}; for (const [field, change] of Object.entries(fieldChanges)) { updatePayload[field] = change.after; } // Update in Autotask try { const autotaskClient = new AutotaskClient({ apiUrl: process.env.AUTOTASK_API_URL || '', username: process.env.AUTOTASK_USERNAME || '', password: process.env.AUTOTASK_SECRET || '', apiIntegrationCode: process.env.AUTOTASK_API_INTEGRATION_CODE || '', }); await autotaskClient.updateTicket(context.ticket.id, updatePayload); // Update local DB copy const setClause = Object.keys(fieldChanges) .map((field, idx) => `${field} = $${idx + 2}`) .join(', '); const values = [ context.ticket.id, ...Object.values(fieldChanges).map(c => c.after) ]; if (setClause) { await postgresClient.query( `UPDATE tickets SET ${setClause}, updated_at = NOW() WHERE id = $1`, values ); } return { success: true, output: { updated_fields: changeKeys, field_changes: fieldChanges, autotask_updated: true, local_db_updated: true } }; } catch (error) { console.error('[UPDATE-TICKET] Failed to update Autotask:', error); return { success: false, error: error instanceof Error ? error.message : String(error) }; } } registerWorkflowStepExecutor('update_ticket', executeUpdateTicket);