import { NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; import { requireAdmin } from "@/lib/admin-auth"; import { cachedResponse } from "@/lib/cache"; import { serverError } from "@/lib/api-error"; export const dynamic = "force-dynamic"; export async function GET() { const authError = await requireAdmin(); if (authError) return authError; try { const data = await cachedResponse("admin:overview", 120, async () => { const [ toolCount, skillCount, publishedToolCount, publishedSkillCount, userCount, botCount, totalTopics, totalPosts, recentTaskLogs, failedTasks24h, pendingFeedback, pendingTools, pendingSkills, totalApiKeys, activeApiKeys, lastBotActivity, botMemoryCount, collectionCount, publicCollectionCount, ] = await Promise.all([ prisma.tool.count(), prisma.skill.count(), prisma.tool.count({ where: { status: "published" } }), prisma.skill.count({ where: { status: "published" } }), prisma.user.count({ where: { isBot: false } }), prisma.user.count({ where: { isBot: true } }), prisma.forumTopic.count({ where: { isHidden: false } }), prisma.forumPost.count({ where: { isHidden: false } }), prisma.taskLog.findMany({ orderBy: { startedAt: "desc" }, take: 10, select: { taskKey: true, taskName: true, status: true, startedAt: true, error: true }, }), prisma.taskLog.count({ where: { status: "failed", startedAt: { gte: new Date(Date.now() - 24 * 3600000) }, }, }), prisma.feedback.count({ where: { status: "pending" } }), prisma.pendingTool.count(), prisma.pendingSkill.count(), prisma.apiKey.count(), prisma.apiKey.count({ where: { isActive: true } }), prisma.forumTopic.findFirst({ where: { user: { isBot: true } }, orderBy: { createdAt: "desc" }, select: { createdAt: true, title: true }, }), prisma.botMemory.count(), prisma.collection.count(), prisma.collection.count({ where: { isPublic: true } }), ]); return { tools: { total: toolCount, published: publishedToolCount, pending: pendingTools }, skills: { total: skillCount, published: publishedSkillCount, pending: pendingSkills }, community: { totalTopics, totalPosts }, users: { total: userCount, bots: botCount }, tasks: { recent: recentTaskLogs, failed24h: failedTasks24h }, feedback: { pending: pendingFeedback }, apiKeys: { total: totalApiKeys, active: activeApiKeys }, bot: { lastActivity: lastBotActivity, memoryCount: botMemoryCount }, collections: { total: collectionCount, public: publicCollectionCount }, updatedAt: new Date().toISOString(), }; }); return NextResponse.json(data); } catch (error) { return serverError(error); } }