import { NextRequest, NextResponse } from "next/server"; import { db, recipes, users, favorites, eq, desc, sql, and, gte } from "@epicure/db"; export async function GET(req: NextRequest) { const { searchParams } = new URL(req.url); const limitRaw = parseInt(searchParams.get("limit") ?? "20"); const limit = Math.min(Number.isNaN(limitRaw) ? 20 : Math.max(1, limitRaw), 50); const offsetRaw = parseInt(searchParams.get("offset") ?? "0"); const offset = Number.isNaN(offsetRaw) ? 0 : Math.max(0, offsetRaw); const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); const [trending, totalRow] = await Promise.all([ db .select({ id: recipes.id, title: recipes.title, description: recipes.description, baseServings: recipes.baseServings, prepMins: recipes.prepMins, cookMins: recipes.cookMins, difficulty: recipes.difficulty, visibility: recipes.visibility, aiGenerated: recipes.aiGenerated, createdAt: recipes.createdAt, authorId: recipes.authorId, authorName: users.name, authorUsername: users.username, authorAvatarUrl: users.avatarUrl, favoriteCount: sql`cast(count(${favorites.recipeId}) as int)`, }) .from(recipes) .innerJoin(users, eq(recipes.authorId, users.id)) .leftJoin( favorites, and(eq(favorites.recipeId, recipes.id), gte(favorites.createdAt, sevenDaysAgo)) ) .where(eq(recipes.visibility, "public")) .groupBy(recipes.id, users.id) .orderBy(desc(sql`count(${favorites.recipeId})`), desc(recipes.createdAt)) .limit(limit) .offset(offset), db .select({ total: sql`count(*)::int` }) .from(recipes) .where(eq(recipes.visibility, "public")), ]); const total = totalRow[0]?.total ?? 0; return NextResponse.json({ data: trending.map((r) => ({ ...r, createdAt: r.createdAt.toISOString() })), total, limit, offset, }); }