import { Request, Response } from 'express'; import ActivityService from '../services/activity.service'; import { ActivityCategory, ActivityAction } from '../model/userActivity.model'; /** * Get user's activity timeline */ export const getUserActivityTimeline = async (req: Request, res: Response) => { try { const { limit = 50, skip = 0, startDate, endDate, category, action, userId: queryUserId, // Admin can request specific user role // Admin can filter by role } = req.query; let targetUserId: string | undefined = req.user!._id; let targetRole: string | undefined = undefined; // If admin, allow viewing other users' logs or all logs if (req.user!.role === 'admin') { if (queryUserId) { targetUserId = queryUserId as string; } else { // If no specific user requested, fetch for all (or filtered by role) targetUserId = undefined; } if (role) { targetRole = role as string; } } const result = await ActivityService.getUserActivityTimeline(targetUserId, { limit: Number(limit), skip: Number(skip), startDate: startDate ? new Date(startDate as string) : undefined, endDate: endDate ? new Date(endDate as string) : undefined, category: category as ActivityCategory, action: action as ActivityAction, role: targetRole }); res.status(200).json({ success: true, data: result }); } catch (error: any) { console.error('Error fetching activity timeline:', error); res.status(500).json({ success: false, message: 'Failed to fetch activity timeline', error: error.message }); } }; /** * Get user statistics */ export const getUserStats = async (req: Request, res: Response) => { try { const userId = req.params.userId || req.user!._id; // If requesting another user's stats, ensure permission if (userId !== req.user!._id && req.user!.role !== 'admin') { return res.status(403).json({ success: false, message: 'Not authorized to view this user\'s statistics' }); } const stats = await ActivityService.getUserStats(userId); res.status(200).json({ success: true, data: stats }); } catch (error: any) { console.error('Error fetching user stats:', error); res.status(500).json({ success: false, message: 'Failed to fetch user statistics', error: error.message }); } }; /** * Get activity breakdown by category */ export const getActivityBreakdown = async (req: Request, res: Response) => { try { const userId = req.user!._id; const { startDate, endDate } = req.query; const breakdown = await ActivityService.getActivityBreakdown( userId, startDate ? new Date(startDate as string) : undefined, endDate ? new Date(endDate as string) : undefined ); res.status(200).json({ success: true, data: breakdown }); } catch (error: any) { console.error('Error fetching activity breakdown:', error); res.status(500).json({ success: false, message: 'Failed to fetch activity breakdown', error: error.message }); } }; /** * Get daily activity counts (for charts) */ export const getDailyActivityCounts = async (req: Request, res: Response) => { try { const userId = req.user!._id; const days = Number(req.query.days) || 30; const dailyStats = await ActivityService.getDailyActivityCounts(userId, days); res.status(200).json({ success: true, data: dailyStats }); } catch (error: any) { console.error('Error fetching daily activity counts:', error); res.status(500).json({ success: false, message: 'Failed to fetch daily activity counts', error: error.message }); } }; /** * Get active users leaderboard */ export const getActiveUsersLeaderboard = async (req: Request, res: Response) => { try { const { criteria = 'eventsCreated', limit = 10 } = req.query; const validCriteria = ['eventsCreated', 'eventsJoined', 'loginCount', 'totalOnlineTime']; if (!validCriteria.includes(criteria as string)) { return res.status(400).json({ success: false, message: `Invalid criteria. Must be one of: ${validCriteria.join(', ')}` }); } const leaderboard = await ActivityService.getActiveUsersLeaderboard( criteria as any, Number(limit) ); res.status(200).json({ success: true, data: leaderboard }); } catch (error: any) { console.error('Error fetching leaderboard:', error); res.status(500).json({ success: false, message: 'Failed to fetch leaderboard', error: error.message }); } }; /** * Get event participation history */ export const getEventParticipationHistory = async (req: Request, res: Response) => { try { const userId = req.user!._id; const history = await ActivityService.getEventParticipationHistory(userId); res.status(200).json({ success: true, data: history }); } catch (error: any) { console.error('Error fetching event participation history:', error); res.status(500).json({ success: false, message: 'Failed to fetch event participation history', error: error.message }); } }; /** * Get form submission history */ export const getFormSubmissionHistory = async (req: Request, res: Response) => { try { const userId = req.user!._id; const history = await ActivityService.getFormSubmissionHistory(userId); res.status(200).json({ success: true, data: history }); } catch (error: any) { console.error('Error fetching form submission history:', error); res.status(500).json({ success: false, message: 'Failed to fetch form submission history', error: error.message }); } }; /** * Get verification activity (for organizations and admins) */ export const getVerificationActivity = async (req: Request, res: Response) => { try { const userId = req.user!._id; // Only organizations and admins can access this if (req.user!.role !== 'organization' && req.user!.role !== 'admin') { return res.status(403).json({ success: false, message: 'Not authorized to view verification activity' }); } const activity = await ActivityService.getVerificationActivity(userId); res.status(200).json({ success: true, data: activity }); } catch (error: any) { console.error('Error fetching verification activity:', error); res.status(500).json({ success: false, message: 'Failed to fetch verification activity', error: error.message }); } }; /** * Export user activity to CSV */ export const exportUserActivityToCSV = async (req: Request, res: Response) => { try { const userId = req.user!._id; const { startDate, endDate } = req.query; const csvContent = await ActivityService.exportUserActivityToCSV( userId, startDate ? new Date(startDate as string) : undefined, endDate ? new Date(endDate as string) : undefined ); res.setHeader('Content-Type', 'text/csv'); res.setHeader('Content-Disposition', `attachment; filename="activity-log-${userId}-${Date.now()}.csv"`); res.status(200).send(csvContent); } catch (error: any) { console.error('Error exporting activity to CSV:', error); res.status(500).json({ success: false, message: 'Failed to export activity to CSV', error: error.message }); } }; /** * Get security alerts */ export const getSecurityAlerts = async (req: Request, res: Response) => { try { const userId = req.user!._id; const days = Number(req.query.days) || 7; const alerts = await ActivityService.getSecurityAlerts(userId, days); res.status(200).json({ success: true, data: alerts }); } catch (error: any) { console.error('Error fetching security alerts:', error); res.status(500).json({ success: false, message: 'Failed to fetch security alerts', error: error.message }); } }; /** * Generate comprehensive user report */ export const generateUserReport = async (req: Request, res: Response) => { try { const userId = req.params.userId || req.user!._id; // If requesting another user's report, ensure permission if (userId !== req.user!._id && req.user!.role !== 'admin') { return res.status(403).json({ success: false, message: 'Not authorized to view this user\'s report' }); } const report = await ActivityService.generateUserReport(userId); res.status(200).json({ success: true, data: report }); } catch (error: any) { console.error('Error generating user report:', error); res.status(500).json({ success: false, message: 'Failed to generate user report', error: error.message }); } }; /** * Calculate and update session online time */ export const updateSessionOnlineTime = async (req: Request, res: Response) => { try { const userId = req.user!._id; const { sessionId } = req.body; if (!sessionId) { return res.status(400).json({ success: false, message: 'Session ID is required' }); } const duration = await ActivityService.calculateOnlineTime(userId, sessionId); res.status(200).json({ success: true, data: { sessionDuration: duration, message: `Session duration: ${duration.toFixed(2)} minutes` } }); } catch (error: any) { console.error('Error updating session online time:', error); res.status(500).json({ success: false, message: 'Failed to update session online time', error: error.message }); } }; /** * Get system-wide recent activities (admin only) */ export const getSystemRecentActivities = async (req: Request, res: Response) => { try { // Only admins can access system-wide activities if (req.user!.role !== 'admin') { return res.status(403).json({ success: false, message: 'Not authorized to view system activities' }); } const { limit = 20, skip = 0 } = req.query; const result = await ActivityService.getSystemRecentActivities({ limit: Number(limit), skip: Number(skip) }); res.status(200).json({ success: true, data: result }); } catch (error: any) { console.error('Error fetching system recent activities:', error); res.status(500).json({ success: false, message: 'Failed to fetch system activities', error: error.message }); } };