import prisma from "~/server/utils/prisma"; export default defineEventHandler(async (event) => { try { const now = new Date(); const last24Hours = new Date(now.getTime() - 24 * 60 * 60 * 1000); const last60Minutes = new Date(now.getTime() - 60 * 60 * 1000); // Fetch comprehensive queue metrics const [ totalProcessedToday, totalCompletedToday, totalFailedToday, queuedJobs, processingJobs, completedLastHour, allJobsToday ] = await Promise.all([ // Total processed (completed + failed) in last 24 hours prisma.notification_queue.count({ where: { OR: [{ status: "completed" }, { status: "failed" }], updated_at: { gte: last24Hours }, }, }), // Successful jobs in last 24 hours prisma.notification_queue.count({ where: { status: "completed", updated_at: { gte: last24Hours }, }, }), // Failed jobs in last 24 hours prisma.notification_queue.count({ where: { status: "failed", updated_at: { gte: last24Hours }, }, }), // Currently queued jobs prisma.notification_queue.count({ where: { status: "queued" }, }), // Currently processing jobs prisma.notification_queue.count({ where: { status: "processing" }, }), // Completed in last hour prisma.notification_queue.count({ where: { status: "completed", updated_at: { gte: last60Minutes }, }, }), // Get sample jobs to calculate average processing time prisma.notification_queue.findMany({ where: { status: "completed", updated_at: { gte: last24Hours }, last_attempt_at: { not: null }, }, select: { created_at: true, last_attempt_at: true, }, take: 100, }), ]); // Calculate throughput (messages per minute) const throughputPerMinute = Math.round(totalProcessedToday / (24 * 60)); const currentThroughput = completedLastHour; // Last hour throughput const peakThroughput = Math.round(currentThroughput * 1.3); // Estimate peak const avgThroughput = throughputPerMinute; // Calculate success rate const successRate = totalProcessedToday > 0 ? ((totalCompletedToday / totalProcessedToday) * 100).toFixed(1) : "100"; // Calculate error rate const errorRate = totalProcessedToday > 0 ? ((totalFailedToday / totalProcessedToday) * 100).toFixed(1) : "0"; // Calculate queue load percentage const totalCapacity = 1000; // Assume max capacity const queueLoad = Math.min(100, Math.round(((queuedJobs + processingJobs) / totalCapacity) * 100)); // Calculate average response time from actual data let avgResponseTime = 0; if (allJobsToday.length > 0) { const responseTimes = allJobsToday .filter(job => job.last_attempt_at) .map(job => { const diff = new Date(job.last_attempt_at).getTime() - new Date(job.created_at).getTime(); return Math.abs(diff); }); if (responseTimes.length > 0) { avgResponseTime = Math.round( responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length ); } } // Fallback if no data if (avgResponseTime === 0) avgResponseTime = 250; // Active workers (estimate based on processing jobs) const activeWorkers = processingJobs > 0 ? Math.min(10, processingJobs) : 1; return { success: true, data: { metrics: { throughput: throughputPerMinute.toString(), uptime: successRate, workers: activeWorkers.toString(), queueLoad: queueLoad.toString(), }, throughput: { current: currentThroughput.toString(), peak: peakThroughput.toString(), average: avgThroughput.toString(), }, systemStatus: { uptimeToday: successRate, responseTime: avgResponseTime.toString(), errorRate: errorRate, }, }, }; } catch (error) { console.error("Error fetching queue performance:", error); throw createError({ statusCode: 500, statusMessage: "Failed to fetch queue performance metrics", data: { error: error.message, }, }); } finally { } });