import { ShellPage } from "@/components/page-templates"; import { TablePlaceholder } from "@/components/placeholders"; import { getSession } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { redirect } from "next/navigation"; function formatTime(date: Date | null) { if (!date) { return "-"; } return new Intl.DateTimeFormat("id-ID", { day: "2-digit", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit" }).format(date); } export default async function PlatformAlertsPage() { const session = await getSession(); if (!session || session.role !== "super_admin") { redirect("/unauthorized"); } const [channels, webhookFailures, retryStateAlerts] = await Promise.all([ prisma.channel.findMany({ include: { tenant: true }, orderBy: { updatedAt: "desc" } }), prisma.webhookEvent.findMany({ where: { processStatus: "failed" }, include: { tenant: true, channel: true }, orderBy: { createdAt: "desc" }, take: 20 }), prisma.backgroundJobState.findMany({ where: { OR: [ { lastRunStatus: "failed" }, { lastRunCompletedAt: null }, { lastRunCompletedAt: { lte: new Date(Date.now() - 60 * 60 * 1000) } } ] }, orderBy: { updatedAt: "desc" }, take: 10 }) ]); const channelAlerts = channels .filter((channel) => channel.status !== "CONNECTED") .map((channel) => ({ severity: channel.status === "DISCONNECTED" ? "High" : "Medium", tenant: channel.tenant.name, issue: `${channel.displayPhoneNumber || channel.channelName} disconnected`, triggered: formatTime(channel.lastSyncAt) })); const webhookAlerts = webhookFailures.map((event) => ({ severity: "Medium", tenant: event.tenant.name, issue: `${event.eventType} on ${event.providerEventId ?? event.channel?.channelName ?? "unknown"}`, triggered: formatTime(event.createdAt) })); const retryAlerts = retryStateAlerts.map((state) => ({ severity: state.lastRunStatus === "failed" ? "High" : "Medium", tenant: "Platform", issue: `${state.jobName} ${state.lastRunStatus === "failed" ? "failed repeatedly" : "hasn't run recently"}`, triggered: formatTime(state.lastRunCompletedAt) })); const alerts = [...channelAlerts, ...webhookAlerts, ...retryAlerts].slice(0, 30); return ( [alert.severity, alert.tenant, alert.issue, alert.triggered])} /> ); }