"use server"; import { db } from "@/lib/db"; import { users, youtubeVideos, detectedObjects, interestPledges, productRequests, affiliateProposals, } from "@/lib/db/schema"; import { count, eq, sql } from "drizzle-orm"; import { auth } from "@/lib/auth"; import { headers } from "next/headers"; import { redirect } from "next/navigation"; /** * Ensures the user is an authorized admin. * Uses ADMIN_EMAILS from environment variables. */ async function ensureAdmin() { const session = await auth.api.getSession({ headers: await headers() }); const adminEmails = process.env.ADMIN_EMAILS?.split(",") || []; if (!session?.user?.email || !adminEmails.includes(session.user.email)) { throw new Error("Unauthorized"); } } export async function getAdminStats() { await ensureAdmin(); const [userCount] = await db.select({ count: count() }).from(users); const [pendingAnalysis] = await db.select({ count: count() }).from(youtubeVideos).where(eq(youtubeVideos.scanStatus, 'pending_analysis')); const [awaitingApproval] = await db.select({ count: count() }).from(youtubeVideos).where(eq(youtubeVideos.scanStatus, 'awaiting_approval')); const [totalProducts] = await db.select({ count: count() }).from(detectedObjects); // Interest Items: Detections with 1+ "I want this" requests const interestCount = await db .select({ count: sql`count(distinct ${detectedObjects.id})` }) .from(detectedObjects) .innerJoin(interestPledges, eq(detectedObjects.id, interestPledges.detectedObjectId)) .groupBy(detectedObjects.id) .having(sql`count(${interestPledges.id}) >= 1`); // Pending Community Requests const [pendingRequests] = await db.select({ count: count() }) .from(productRequests) .where(eq(productRequests.status, 'PENDING')); // Pending Affiliate Proposals const [pendingProposals] = await db.select({ count: count() }) .from(affiliateProposals) .where(eq(affiliateProposals.status, 'PENDING')); return { totalUsers: Number(userCount.count), pendingAnalysis: Number(pendingAnalysis.count), awaitingApproval: Number(awaitingApproval.count), totalProducts: Number(totalProducts.count), highInterestItems: interestCount.length, pendingRequests: Number(pendingRequests.count), pendingProposals: Number(pendingProposals.count), }; }