import { type NextRequest, NextResponse } from 'next/server'; import { createDb, skills, categories, sql } from '@skillhub/db'; import { getCached, setCache, cacheKeys, cacheTTL } from '@/lib/cache'; import { withRateLimit, createRateLimitResponse, createRateLimitHeaders } from '@/lib/rate-limit'; const db = createDb(); interface StatsData { totalSkills: number; totalDownloads: number; totalCategories: number; totalContributors: number; platforms: number; } export async function GET(request: NextRequest) { // Rate limiting const rateLimitResult = await withRateLimit(request, 'anonymous'); if (!rateLimitResult.allowed) { return createRateLimitResponse(rateLimitResult); } try { // Try to get from cache first const cacheKey = cacheKeys.stats(); const cached = await getCached(cacheKey); if (cached) { return NextResponse.json(cached, { headers: { 'X-Cache': 'HIT', 'Cache-Control': 'public, max-age=3600, stale-while-revalidate=7200', ...createRateLimitHeaders(rateLimitResult), }, }); } // Consolidate all skill stats into a single query for better performance const statsResult = await db .select({ totalSkills: sql`count(*)::int`, totalDownloads: sql`coalesce(sum(${skills.downloadCount}), 0)::int`, totalContributors: sql`count(distinct ${skills.githubOwner})::int`, }) .from(skills); // Get category count in separate query (different table) const categoryResult = await db .select({ count: sql`count(*)::int` }) .from(categories); const stats = statsResult[0]; const totalCategories = categoryResult[0]?.count ?? 0; const data: StatsData = { totalSkills: stats?.totalSkills ?? 0, totalDownloads: stats?.totalDownloads ?? 0, totalCategories, totalContributors: stats?.totalContributors ?? 0, platforms: 5, // Claude, Codex, Copilot, Cursor, Windsurf }; // Cache the result await setCache(cacheKey, data, cacheTTL.stats); return NextResponse.json(data, { headers: { 'X-Cache': 'MISS', 'Cache-Control': 'public, max-age=3600, stale-while-revalidate=7200', ...createRateLimitHeaders(rateLimitResult), }, }); } catch (error) { console.error('Error fetching stats:', error); return NextResponse.json( { error: 'Failed to fetch stats' }, { status: 500 } ); } }