import { getSessionUser } from "@/lib/session"; import { getTranslations } from "next-intl/server"; import { redirect } from "next/navigation"; import { listTenants } from "@/lib/k8s"; import { countPendingSkillActivationRequests } from "@/lib/db"; import { AdminPanel } from "@/components/admin/admin-panel"; export default async function AdminPage() { const user = await getSessionUser(); if (!user) redirect("/login"); const t = await getTranslations("admin"); if (!user.isPlatform) { return (

{t("noAccess")}

); } const tenants = await listTenants(); // Phase 2.5: badge counter for the skill-activation admin queue. // Cheap COUNT(*) on a partial-indexed status='pending' column — // bounded by request volume and never expected to be high. const pendingSkillCount = await countPendingSkillActivationRequests().catch( () => 0 ); return (

{t("title")}

{t("subtitle")}

{/* Sub-tools: links to other admin pages. Plain links rather than nav-shell entries — these are platform-team utilities, not main navigation. */}
0 ? "border-warning text-warning hover:bg-warning/10" : "border-border text-text-secondary hover:text-text-primary hover:border-text-secondary" }`} > {t("skillsQueueTool")} {pendingSkillCount > 0 && ( {pendingSkillCount} )} {t("billingTool")} {t("cronTool")} {t("openclawTool")}
); }