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 last7Days = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); const last30Days = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000); // Fetch comprehensive stats const [ totalNotifications, totalSent, totalScheduled, totalDraft, sentLast24h, sentLast7Days, totalRecipients, successfulDeliveries, failedDeliveries, queuedJobs, channelStats, categoryStats, ] = await Promise.all([ // Total notifications prisma.notifications.count(), // Total sent notifications prisma.notifications.count({ where: { status: "sending" } }), // Total scheduled prisma.notifications.count({ where: { status: "scheduled" } }), // Total drafts prisma.notifications.count({ where: { status: "draft" } }), // Sent in last 24 hours prisma.notifications.count({ where: { status: "sending", sent_at: { gte: last24Hours } } }), // Sent in last 7 days prisma.notifications.count({ where: { status: "sending", sent_at: { gte: last7Days } } }), // Total recipients prisma.notification_recipients.count(), // Successful deliveries prisma.notification_recipients.count({ where: { status: "sent" } }), // Failed deliveries prisma.notification_recipients.count({ where: { status: "failed" } }), // Queued jobs prisma.notification_queue.count({ where: { status: "queued" } }), // Channel distribution prisma.notification_channels.groupBy({ by: ['channel_type'], _count: { channel_type: true } }), // Category distribution prisma.notifications.groupBy({ by: ['category_id'], _count: { category_id: true }, take: 5, orderBy: { _count: { category_id: 'desc' } } }), ]); // Calculate delivery rate const totalDeliveryAttempts = successfulDeliveries + failedDeliveries; const deliveryRate = totalDeliveryAttempts > 0 ? ((successfulDeliveries / totalDeliveryAttempts) * 100).toFixed(1) : 100; // Calculate growth rate (last 7 days vs previous 7 days) const previous7Days = new Date(last7Days.getTime() - 7 * 24 * 60 * 60 * 1000); const sentPrevious7Days = await prisma.notifications.count({ where: { status: "sending", sent_at: { gte: previous7Days, lt: last7Days } } }); const growthRate = sentPrevious7Days > 0 ? (((sentLast7Days - sentPrevious7Days) / sentPrevious7Days) * 100).toFixed(1) : 0; // Get category names const categoryIds = categoryStats.map(c => c.category_id).filter(Boolean); const categories = await prisma.notification_categories.findMany({ where: { id: { in: categoryIds } }, select: { id: true, name: true } }); const categoryMap = Object.fromEntries(categories.map(c => [c.id, c.name])); return { success: true, data: { overview: { total: totalNotifications, sent: totalSent, scheduled: totalScheduled, draft: totalDraft, sentLast24h, sentLast7Days, growthRate: parseFloat(growthRate), }, delivery: { totalRecipients, successful: successfulDeliveries, failed: failedDeliveries, deliveryRate: parseFloat(deliveryRate), queued: queuedJobs, }, channels: channelStats.map(ch => ({ channel: ch.channel_type, count: ch._count.channel_type, })), topCategories: categoryStats.map(cat => ({ categoryId: cat.category_id, categoryName: categoryMap[cat.category_id] || 'Unknown', count: cat._count.category_id, })), }, }; } catch (error) { console.error("Error fetching dashboard overview:", error); throw createError({ statusCode: 500, statusMessage: "Failed to fetch dashboard data", data: { error: error.message }, }); } finally { } });