import prisma from '~/server/utils/prisma' export default defineEventHandler(async (event) => { try { // Check authentication const user = event.context.user; if (!user || !user.userID) { return { statusCode: 401, body: { success: false, message: 'Unauthorized' } } } // Get system status metrics const now = new Date() const oneDayAgo = new Date(now) oneDayAgo.setDate(oneDayAgo.getDate() - 1) // Get total sent in last 24 hours const totalSent = await prisma.notification_logs.count({ where: { created_at: { gte: oneDayAgo, lte: now }, status: 'Sent' } }) // Get success rate in last 24 hours const totalAttempted = await prisma.notification_logs.count({ where: { created_at: { gte: oneDayAgo, lte: now }, action: { in: ['Notification Sent', 'Delivery Attempted'] } } }) const successfulDeliveries = await prisma.notification_logs.count({ where: { created_at: { gte: oneDayAgo, lte: now }, status: 'Sent' } }) const successRate = totalAttempted > 0 ? ((successfulDeliveries / totalAttempted) * 100).toFixed(2) : 0 // Get error rate in last 24 hours const failedDeliveries = await prisma.notification_logs.count({ where: { created_at: { gte: oneDayAgo, lte: now }, status: 'Failed' } }) const errorRate = totalAttempted > 0 ? ((failedDeliveries / totalAttempted) * 100).toFixed(2) : 0 // Get average response time (mock data since we need actual measurements) const avgResponseTime = "145" // Calculate status based on metrics const getSystemStatus = (metric, thresholds) => { if (metric <= thresholds.healthy) return 'healthy' if (metric <= thresholds.warning) return 'warning' return 'critical' } // Get queue status const queueStatus = await getQueueStatus(prisma) // Get recent activity const recentActivity = await getRecentActivity(prisma) // Get performance metrics const performanceMetrics = { cpu: 23, // Mock data memory: 67, // Mock data queueLoad: calculateQueueLoad(queueStatus) } // Get error alerts (mock data) const errorAlerts = await getErrorAlerts(prisma, oneDayAgo, now) return { statusCode: 200, body: { success: true, data: { systemStatus: [ { title: "System Health", value: errorRate < 1 ? "Healthy" : errorRate < 5 ? "Warning" : "Critical", icon: "ic:outline-favorite", status: getSystemStatus(errorRate, { healthy: 1, warning: 5 }) }, { title: "Throughput", value: `${Math.round(totalSent / 24)}/hr`, icon: "ic:outline-speed", status: 'healthy' // Simplified for now }, { title: "Error Rate", value: `${errorRate}%`, icon: "ic:outline-error-outline", status: getSystemStatus(errorRate, { healthy: 1, warning: 5 }) }, { title: "Response Time", value: `${avgResponseTime}ms`, icon: "ic:outline-timer", status: getSystemStatus(parseFloat(avgResponseTime), { healthy: 100, warning: 200 }) } ], performanceMetrics, queueStatus, recentActivity, errorAlerts } } } } catch (error) { console.error('Error fetching monitoring data:', error) return { statusCode: 500, body: { success: false, message: 'Failed to fetch monitoring data', error: error.message } } } }) // Helper functions async function getQueueStatus(prisma) { const channels = ['Email', 'SMS', 'Push Notification', 'Webhook'] // In a real implementation, this would query the notification_queue table // For now, we'll use mock data return [ { name: "Email Queue", count: "1,247", description: "Pending emails", status: "active", utilization: 78 }, { name: "SMS Queue", count: "89", description: "Pending SMS", status: "active", utilization: 23 }, { name: "Push Queue", count: "3,456", description: "Pending push notifications", status: "warning", utilization: 92 }, { name: "Webhook Queue", count: "12", description: "Pending webhooks", status: "active", utilization: 8 } ] } function calculateQueueLoad(queueStatus) { // Calculate average utilization across all queues const totalUtilization = queueStatus.reduce((sum, queue) => sum + queue.utilization, 0) return Math.round(totalUtilization / queueStatus.length) } async function getRecentActivity(prisma) { // Get the most recent 5 log entries const recentLogs = await prisma.notification_logs.findMany({ orderBy: { created_at: 'desc' }, take: 5 }) // Format for the frontend return recentLogs.map(log => { const timeAgo = formatTimeAgo(log.created_at) return { action: log.action, description: log.details || 'No details provided', status: log.status ? log.status.toLowerCase() : 'unknown', time: timeAgo, source: log.channel_type || 'System' } }) } function formatTimeAgo(timestamp) { const now = new Date() const time = new Date(timestamp) const diffInMinutes = Math.floor((now - time) / (1000 * 60)) if (diffInMinutes < 1) return "Just now" if (diffInMinutes < 60) return `${diffInMinutes} minutes ago` if (diffInMinutes < 1440) return `${Math.floor(diffInMinutes / 60)} hours ago` return `${Math.floor(diffInMinutes / 1440)} days ago` } async function getErrorAlerts(prisma, startDate, endDate) { // Get recent errors const recentErrors = await prisma.notification_logs.findMany({ where: { created_at: { gte: startDate, lte: endDate }, status: 'Failed', error_message: { not: null } }, orderBy: { created_at: 'desc' }, take: 3 }) // Format for the frontend return recentErrors.map(error => { const timeAgo = formatTimeAgo(error.created_at) // Determine severity based on error code or other factors let severity = 'warning' if (error.error_code && error.error_code.startsWith('CRIT')) { severity = 'critical' } return { title: error.action || 'Error Detected', description: error.error_message || 'Unknown error occurred', timestamp: timeAgo, component: error.channel_type || 'System', severity } }) }