import { Request, Response } from 'express'; import { DashboardService } from '../services/dashboard.service'; import logger from '@utils/logger'; export class DashboardController { private dashboardService: DashboardService; constructor() { this.dashboardService = new DashboardService(); } /** * Get all KPI metrics for dashboard */ async getKPIs(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user const kpis = await this.dashboardService.getKPIs(userId, dateRange, startDate, endDate, viewAsUser); res.json({ success: true, data: kpis }); } catch (error) { logger.error('[Dashboard] Error fetching KPIs:', error); res.status(500).json({ success: false, error: 'Failed to fetch dashboard KPIs' }); } } /** * Get request volume and status statistics */ async getRequestStats(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const status = req.query.status as string | undefined; // Status filter (not used in stats - stats show all statuses) const priority = req.query.priority as string | undefined; const department = req.query.department as string | undefined; const initiator = req.query.initiator as string | undefined; const approver = req.query.approver as string | undefined; const approverType = req.query.approverType as 'current' | 'any' | undefined; const search = req.query.search as string | undefined; const slaCompliance = req.query.slaCompliance as string | undefined; const viewAsUser = req.query.viewAsUser === 'true'; // When true, treat admin as normal user const stats = await this.dashboardService.getRequestStats( userId, dateRange, startDate, endDate, status, priority, department, initiator, approver, approverType, search, slaCompliance, viewAsUser ); res.json({ success: true, data: stats }); } catch (error) { logger.error('[Dashboard] Error fetching request stats:', error); res.status(500).json({ success: false, error: 'Failed to fetch request statistics' }); } } /** * Get TAT efficiency metrics */ async getTATEfficiency(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const efficiency = await this.dashboardService.getTATEfficiency(userId, dateRange, startDate, endDate); res.json({ success: true, data: efficiency }); } catch (error) { logger.error('[Dashboard] Error fetching TAT efficiency:', error); res.status(500).json({ success: false, error: 'Failed to fetch TAT efficiency metrics' }); } } /** * Get approver load statistics */ async getApproverLoad(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const load = await this.dashboardService.getApproverLoad(userId, dateRange, startDate, endDate); res.json({ success: true, data: load }); } catch (error) { logger.error('[Dashboard] Error fetching approver load:', error); res.status(500).json({ success: false, error: 'Failed to fetch approver load statistics' }); } } /** * Get engagement and quality metrics */ async getEngagementStats(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const engagement = await this.dashboardService.getEngagementStats(userId, dateRange, startDate, endDate); res.json({ success: true, data: engagement }); } catch (error) { logger.error('[Dashboard] Error fetching engagement stats:', error); res.status(500).json({ success: false, error: 'Failed to fetch engagement statistics' }); } } /** * Get AI insights and closure metrics */ async getAIInsights(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const insights = await this.dashboardService.getAIInsights(userId, dateRange, startDate, endDate); res.json({ success: true, data: insights }); } catch (error) { logger.error('[Dashboard] Error fetching AI insights:', error); res.status(500).json({ success: false, error: 'Failed to fetch AI insights' }); } } /** * Get AI Remark Utilization metrics with monthly trends */ async getAIRemarkUtilization(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const utilization = await this.dashboardService.getAIRemarkUtilization(userId, dateRange, startDate, endDate); res.json({ success: true, data: utilization }); } catch (error) { logger.error('[Dashboard] Error fetching AI remark utilization:', error); res.status(500).json({ success: false, error: 'Failed to fetch AI remark utilization' }); } } /** * Get Approver Performance metrics with pagination */ async getApproverPerformance(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 10); const result = await this.dashboardService.getApproverPerformance(userId, dateRange, page, limit, startDate, endDate); res.json({ success: true, data: result.performance, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching approver performance:', error); res.status(500).json({ success: false, error: 'Failed to fetch approver performance metrics' }); } } /** * Get recent activity feed */ async getRecentActivity(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 10); const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user const result = await this.dashboardService.getRecentActivity(userId, page, limit, viewAsUser); res.json({ success: true, data: result.activities, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching recent activity:', error); res.status(500).json({ success: false, error: 'Failed to fetch recent activity' }); } } /** * Get critical/high priority requests with pagination */ async getCriticalRequests(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 10); const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user const result = await this.dashboardService.getCriticalRequests(userId, page, limit, viewAsUser); res.json({ success: true, data: result.criticalRequests, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching critical requests:', error); res.status(500).json({ success: false, error: 'Failed to fetch critical requests' }); } } /** * Get upcoming deadlines with pagination */ async getUpcomingDeadlines(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 10); const viewAsUser = req.query.viewAsUser === 'true'; // For admin to view as normal user const result = await this.dashboardService.getUpcomingDeadlines(userId, page, limit, viewAsUser); res.json({ success: true, data: result.deadlines, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching upcoming deadlines:', error); res.status(500).json({ success: false, error: 'Failed to fetch upcoming deadlines' }); } } /** * Get department-wise statistics */ async getDepartmentStats(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const stats = await this.dashboardService.getDepartmentStats(userId, dateRange, startDate, endDate); res.json({ success: true, data: stats }); } catch (error) { logger.error('[Dashboard] Error fetching department stats:', error); res.status(500).json({ success: false, error: 'Failed to fetch department statistics' }); } } /** * Get priority distribution statistics */ async getPriorityDistribution(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const distribution = await this.dashboardService.getPriorityDistribution(userId, dateRange, startDate, endDate); res.json({ success: true, data: distribution }); } catch (error) { logger.error('[Dashboard] Error fetching priority distribution:', error); res.status(500).json({ success: false, error: 'Failed to fetch priority distribution' }); } } /** * Get Request Lifecycle Report */ async getLifecycleReport(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 50); const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const result = await this.dashboardService.getLifecycleReport(userId, page, limit, dateRange, startDate, endDate); res.json({ success: true, data: result.lifecycleData, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching lifecycle report:', error); res.status(500).json({ success: false, error: 'Failed to fetch lifecycle report' }); } } /** * Get enhanced User Activity Log Report */ async getActivityLogReport(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 50); const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const filterUserId = req.query.filterUserId as string | undefined; const filterType = req.query.filterType as string | undefined; const filterCategory = req.query.filterCategory as string | undefined; const filterSeverity = req.query.filterSeverity as string | undefined; const result = await this.dashboardService.getActivityLogReport( userId, page, limit, dateRange, filterUserId, filterType, filterCategory, filterSeverity, startDate, endDate ); res.json({ success: true, data: result.activities, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching activity log report:', error); res.status(500).json({ success: false, error: 'Failed to fetch activity log report' }); } } /** * Get list of departments (metadata for filtering) * GET /api/v1/dashboard/metadata/departments */ async getDepartments(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; if (!userId) { res.status(401).json({ success: false, message: 'Unauthorized', timestamp: new Date() }); return; } const departments = await this.dashboardService.getDepartments(userId); res.status(200).json({ success: true, message: 'Departments retrieved successfully', data: { departments }, timestamp: new Date() }); } catch (error) { logger.error('[Dashboard] Get Departments failed:', error); res.status(500).json({ success: false, message: 'Internal server error', timestamp: new Date() }); } } async getWorkflowAgingReport(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const threshold = Number(req.query.threshold || 7); const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 50); const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const result = await this.dashboardService.getWorkflowAgingReport( userId, threshold, page, limit, dateRange, startDate, endDate ); res.json({ success: true, data: result.agingData, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching workflow aging report:', error); res.status(500).json({ success: false, error: 'Failed to fetch workflow aging report' }); } } /** * Get requests filtered by approver ID for detailed performance analysis */ async getRequestsByApprover(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const approverId = req.query.approverId as string; const page = Number(req.query.page || 1); const limit = Number(req.query.limit || 50); const dateRange = req.query.dateRange as string | undefined; const startDate = req.query.startDate as string | undefined; const endDate = req.query.endDate as string | undefined; const status = req.query.status as string | undefined; const priority = req.query.priority as string | undefined; const slaCompliance = req.query.slaCompliance as string | undefined; const search = req.query.search as string | undefined; if (!approverId) { res.status(400).json({ success: false, error: 'Approver ID is required' }); return; } const result = await this.dashboardService.getRequestsByApprover( userId, approverId, page, limit, dateRange, startDate, endDate, status, priority, slaCompliance, search ); res.json({ success: true, data: result.requests, pagination: { currentPage: result.currentPage, totalPages: result.totalPages, totalRecords: result.totalRecords, limit: result.limit } }); } catch (error) { logger.error('[Dashboard] Error fetching requests by approver:', error); res.status(500).json({ success: false, error: 'Failed to fetch requests by approver' }); } } }