import { ApiRequestOptions } from '../hooks/useApi'; // ============================================================================ // TYPES & INTERFACES // ============================================================================ export interface Automation { id: string; mandateId: string; featureInstanceId: string; label: string; template: string | object; placeholders: Record; schedule: string; active: boolean; status?: string; lastExecution?: number; nextExecution?: number; executionLogs?: AutomationLog[]; allowedProviders?: string[]; sysCreatedAt?: number; _updatedAt?: number; sysCreatedByUserName?: string; mandateName?: string; featureInstanceName?: string; [key: string]: any; } export interface AutomationLog { id: string; timestamp: number; status: string; workflowId?: string; messages?: string[]; } // Multilingual text type (matches backend TextMultilingual) export interface TextMultilingual { en: string; ge?: string; fr?: string; it?: string; } // AutomationTemplate from DB export interface AutomationTemplate { id: string; label: TextMultilingual; overview?: TextMultilingual; template: string; // JSON string with {{KEY:...}} placeholders sysCreatedAt?: number; sysCreatedBy?: string; sysCreatedByUserName?: string; } // Workflow action definition from backend export interface WorkflowAction { method: string; action: string; actionId: string; description: string; category?: string; parameters: WorkflowActionParameter[]; exampleJson: { execMethod: string; execAction: string; execParameters: Record; execResultLabel: string; }; } export interface WorkflowActionParameter { name: string; type: string; frontendType: string; required: boolean; default?: any; description: string; frontendOptions?: string | string[]; } export interface CreateAutomationRequest { label: string; template: string; placeholders?: Record; schedule?: string; active?: boolean; mandateId?: string; featureInstanceId?: string; } export interface UpdateAutomationRequest { label?: string; template?: string; placeholders?: Record; schedule?: string; active?: boolean; } export interface ExecuteAutomationResponse { id: string; status: string; workflowId?: string; [key: string]: any; } // Type for the request function passed to API functions export type ApiRequestFunction = (options: ApiRequestOptions) => Promise; // ============================================================================ // API REQUEST FUNCTIONS // ============================================================================ /** * Fetch all automations for the current mandate * Endpoint: GET /api/automations */ export async function fetchAutomations(request: ApiRequestFunction): Promise { console.log('📤 fetchAutomations: Making API request to /api/automations'); try { const data = await request({ url: '/api/automations', method: 'get' }); console.log('📥 fetchAutomations: API response:', data); // Handle different response formats let automations: Automation[] = []; if (Array.isArray(data)) { automations = data; } else if (data && typeof data === 'object') { if (Array.isArray(data.automations)) { automations = data.automations; } else if (Array.isArray(data.items)) { automations = data.items; } else if (Array.isArray(data.data)) { automations = data.data; } } console.log(`✅ fetchAutomations: Returning ${automations.length} automations`); return automations; } catch (error) { console.error('❌ fetchAutomations: Error fetching automations:', error); throw error; } } /** * Fetch a single automation by ID * Endpoint: GET /api/automations/{automationId} */ export async function fetchAutomation( request: ApiRequestFunction, automationId: string ): Promise { return await request({ url: `/api/automations/${automationId}`, method: 'get' }); } /** * Create a new automation * Endpoint: POST /api/automations */ export async function createAutomationApi( request: ApiRequestFunction, automationData: CreateAutomationRequest ): Promise { return await request({ url: '/api/automations', method: 'post', data: automationData }); } /** * Update an existing automation * Endpoint: PUT /api/automations/{automationId} */ export async function updateAutomationApi( request: ApiRequestFunction, automationId: string, updateData: UpdateAutomationRequest ): Promise { return await request({ url: `/api/automations/${automationId}`, method: 'put', data: updateData }); } /** * Delete an automation * Endpoint: DELETE /api/automations/{automationId} */ export async function deleteAutomationApi( request: ApiRequestFunction, automationId: string ): Promise { await request({ url: `/api/automations/${automationId}`, method: 'delete' }); } /** * Execute an automation (test mode) * Endpoint: POST /api/automations/{automationId}/execute */ export async function executeAutomationApi( request: ApiRequestFunction, automationId: string ): Promise { return await request({ url: `/api/automations/${automationId}/execute`, method: 'post' }); } /** * Fetch automation attributes for dynamic form generation * Endpoint: GET /api/attributes/AutomationDefinition */ export async function fetchAutomationAttributes( request: ApiRequestFunction ): Promise { const data = await request({ url: '/api/attributes/AutomationDefinition', method: 'get' }); if (data?.attributes && Array.isArray(data.attributes)) { return data.attributes; } if (Array.isArray(data)) { return data; } return []; } // ============================================================================ // AUTOMATION TEMPLATES API // ============================================================================ /** * Fetch all automation templates (RBAC-filtered: own templates) * Endpoint: GET /api/automation-templates */ export async function fetchAutomationTemplates( request: ApiRequestFunction, params?: any ): Promise { const requestParams: Record = {}; if (params && typeof params === 'object') { const paginationObj: any = {}; if (params.page !== undefined) paginationObj.page = params.page; if (params.pageSize !== undefined) paginationObj.pageSize = params.pageSize; if (params.sort) paginationObj.sort = params.sort; if (params.filters) paginationObj.filters = params.filters; if (params.search) paginationObj.search = params.search; if (Object.keys(paginationObj).length > 0) { requestParams.pagination = JSON.stringify(paginationObj); } } return await request({ url: '/api/automation-templates', method: 'get', params: requestParams, }); } /** * Fetch single automation template by ID * Endpoint: GET /api/automation-templates/{templateId} */ export async function fetchAutomationTemplateById( request: ApiRequestFunction, templateId: string ): Promise { try { return await request({ url: `/api/automation-templates/${templateId}`, method: 'get' }); } catch (error) { console.error('Error fetching template:', error); return null; } } /** * Create new automation template * Endpoint: POST /api/automation-templates */ export async function createAutomationTemplateApi( request: ApiRequestFunction, templateData: Omit ): Promise { return await request({ url: '/api/automation-templates', method: 'post', data: templateData }); } /** * Update automation template * Endpoint: PUT /api/automation-templates/{templateId} */ export async function updateAutomationTemplateApi( request: ApiRequestFunction, templateId: string, templateData: Partial ): Promise { return await request({ url: `/api/automation-templates/${templateId}`, method: 'put', data: templateData }); } /** * Delete automation template * Endpoint: DELETE /api/automation-templates/{templateId} */ export async function deleteAutomationTemplateApi( request: ApiRequestFunction, templateId: string ): Promise { await request({ url: `/api/automation-templates/${templateId}`, method: 'delete' }); } /** * Fetch automation template attributes for dynamic form generation * Endpoint: GET /api/automation-templates/attributes */ export async function fetchAutomationTemplateAttributes( request: ApiRequestFunction ): Promise { const data = await request({ url: '/api/automation-templates/attributes', method: 'get' }); // Backend returns: { attributes: { model: "...", attributes: [...] } } if (data?.attributes?.attributes && Array.isArray(data.attributes.attributes)) { return data.attributes.attributes; } // Fallback: direct attributes array if (data?.attributes && Array.isArray(data.attributes)) { return data.attributes; } return Array.isArray(data) ? data : []; } // ============================================================================ // WORKFLOW ACTIONS API // ============================================================================ /** * Fetch available workflow actions (RBAC-filtered) * Endpoint: GET /api/automations/actions */ export async function fetchWorkflowActions( request: ApiRequestFunction ): Promise { const data = await request({ url: '/api/automations/actions', method: 'get' }); return data?.actions || []; }