import { Request, Response } from 'express'; import type { AuthenticatedRequest } from '../types/express'; import { TemplateService } from '../services/template.service'; import { ResponseHandler } from '../utils/responseHandler'; import logger from '../utils/logger'; export class TemplateController { private templateService = new TemplateService(); /** * Create a new template * POST /api/v1/templates */ async createTemplate(req: AuthenticatedRequest, res: Response): Promise { try { const userId = req.user?.userId; if (!userId) { return ResponseHandler.error(res, 'Unauthorized', 401); } const { // New fields templateName, templateCode, templateDescription, templateCategory, workflowType, approvalLevelsConfig, defaultTatHours, formStepsConfig, userFieldMappings, dynamicApproverConfig, isActive, // Legacy fields (from frontend) name, description, category, approvers, suggestedSLA } = req.body; // Map legacy to new const finalTemplateName = templateName || name; const finalTemplateDescription = templateDescription || description; const finalTemplateCategory = templateCategory || category; const finalApprovalLevelsConfig = approvalLevelsConfig || approvers; const finalDefaultTatHours = defaultTatHours || suggestedSLA; if (!finalTemplateName) { return ResponseHandler.error(res, 'Template name is required', 400); } const template = await this.templateService.createTemplate(userId, { templateName: finalTemplateName, templateCode, templateDescription: finalTemplateDescription, templateCategory: finalTemplateCategory, workflowType, approvalLevelsConfig: finalApprovalLevelsConfig, defaultTatHours: finalDefaultTatHours ? parseFloat(finalDefaultTatHours) : undefined, formStepsConfig, userFieldMappings, dynamicApproverConfig, isActive, }); return ResponseHandler.success(res, template, 'Template created successfully', 201); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; logger.error('[TemplateController] Error creating template:', error); return ResponseHandler.error(res, 'Failed to create template', 500, errorMessage); } } /** * Get template by ID * GET /api/v1/templates/:templateId */ async getTemplate(req: Request, res: Response): Promise { try { const { templateId } = req.params; const template = await this.templateService.getTemplate(templateId); if (!template) { return ResponseHandler.error(res, 'Template not found', 404); } return ResponseHandler.success(res, template, 'Template fetched'); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; logger.error('[TemplateController] Error getting template:', error); return ResponseHandler.error(res, 'Failed to fetch template', 500, errorMessage); } } /** * List templates * GET /api/v1/templates */ async listTemplates(req: Request, res: Response): Promise { try { const { category, workflowType, isActive, isSystemTemplate, search, } = req.query; const filters: any = {}; if (category) filters.category = category as string; if (workflowType) filters.workflowType = workflowType as string; if (isActive !== undefined) filters.isActive = isActive === 'true'; if (isSystemTemplate !== undefined) filters.isSystemTemplate = isSystemTemplate === 'true'; if (search) filters.search = search as string; const templates = await this.templateService.listTemplates(filters); return ResponseHandler.success(res, templates, 'Templates fetched'); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; logger.error('[TemplateController] Error listing templates:', error); return ResponseHandler.error(res, 'Failed to fetch templates', 500, errorMessage); } } /** * Get active templates (for workflow creation) * GET /api/v1/templates/active */ async getActiveTemplates(req: Request, res: Response): Promise { try { const templates = await this.templateService.getActiveTemplates(); return ResponseHandler.success(res, templates, 'Active templates fetched'); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; logger.error('[TemplateController] Error getting active templates:', error); return ResponseHandler.error(res, 'Failed to fetch active templates', 500, errorMessage); } } /** * Update template * PUT /api/v1/templates/:templateId */ async updateTemplate(req: AuthenticatedRequest, res: Response): Promise { try { const { templateId } = req.params; const userId = req.user?.userId; if (!userId) { return ResponseHandler.error(res, 'Unauthorized', 401); } const { templateName, templateDescription, templateCategory, workflowType, // Added approvalLevelsConfig, defaultTatHours, formStepsConfig, userFieldMappings, dynamicApproverConfig, isActive, // Legacy name, description, category, approvers, suggestedSLA } = req.body; const template = await this.templateService.updateTemplate(templateId, userId, { name: templateName || name, description: templateDescription || description, department: templateCategory || category, workflowType, approvalLevelsConfig: approvalLevelsConfig || approvers, defaultTatHours: (defaultTatHours || suggestedSLA) ? parseFloat(defaultTatHours || suggestedSLA) : undefined, formStepsConfig, userFieldMappings, dynamicApproverConfig, isActive, }); return ResponseHandler.success(res, template, 'Template updated successfully'); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; logger.error('[TemplateController] Error updating template:', error); return ResponseHandler.error(res, 'Failed to update template', 500, errorMessage); } } /** * Delete template * DELETE /api/v1/templates/:templateId */ async deleteTemplate(req: AuthenticatedRequest, res: Response): Promise { try { const { templateId } = req.params; await this.templateService.deleteTemplate(templateId); return ResponseHandler.success(res, { message: 'Template deleted successfully' }, 'Template deleted'); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; logger.error('[TemplateController] Error deleting template:', error); return ResponseHandler.error(res, 'Failed to delete template', 500, errorMessage); } } }