Re_Backend/src/controllers/dashboard.controller.ts

602 lines
19 KiB
TypeScript

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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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'
});
}
}
}