import { count, desc, eq, gte } from "drizzle-orm"; import { AlertTriangle, Database, HeartPulse, Server } from "lucide-react"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import Link from "@/components/link"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { fetchOpsHealth } from "@/lib/admin/ops-health"; import { db, EmulatorErrors, EmulatorSettings } from "@/lib/db"; import { canAccess, getAdminContext, PERMS } from "@/lib/permissions"; import { HealthCheckClient } from "./health-check-client"; async function getDevOpsData() { const now = Math.floor(Date.now() / 1000); const dayAgo = now - 86400; const [health, recentErrors, errorsTodayRows, emuVersionRows] = await Promise.all([ fetchOpsHealth(), db .select() .from(EmulatorErrors) .orderBy(desc(EmulatorErrors.id)) .limit(20), db .select({ total: count() }) .from(EmulatorErrors) .where(gte(EmulatorErrors.timestamp, dayAgo)), db .select({ value: EmulatorSettings.value }) .from(EmulatorSettings) .where(eq(EmulatorSettings.key, "version")) .limit(1), ]); return { dbStatus: health.dbOk ? ("healthy" as const) : ("error" as const), dbLatency: health.dbLatencyMs, redisOk: health.redisOk, recentErrors, errorsToday: Number(errorsTodayRows[0]?.total ?? 0), emuVersion: emuVersionRows[0]?.value ?? "Unknown", onlineUsers: health.onlineUsers, }; } export default async function DevOpsPage() { const { session, permissions } = await getAdminContext(); if (!canAccess(permissions, PERMS.DEVOPS_VIEW, session.user.rank)) { redirect("/admin"); } const t = await getTranslations("pages.admin.devops"); const data = await getDevOpsData(); return (
{/* Status cards */}
Database {data.dbStatus === "healthy" ? "Healthy" : "Error"}

Latency: {data.dbLatency}ms

Redis {data.redisOk === true ? "Healthy" : data.redisOk === false ? "Error" : "Not configured"}

Cache / rate limits / sessions

Emulator

Version: {data.emuVersion}

Online Users
{data.onlineUsers}

Live roster in CommandoCentrum

Errors (24h)
{data.errorsToday}

Emulator errors today

{/* Recent errors */} Recent Emulator Errors {data.recentErrors.length === 0 ? (
{t("noRecentErrors")}
) : (
{data.recentErrors.map((error) => (
#{error.id} {new Date(error.timestamp * 1000).toLocaleString()}
										{Buffer.from(error.stacktrace).toString("utf-8")}
									
))}
)}
); }