import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { db, collections, eq, desc, sql } from "@epicure/db"; import { requireSessionOrApiKey } from "@/lib/api-auth"; const Schema = z.object({ name: z.string().min(1).max(100), description: z.string().max(500).optional(), visibility: z.enum(["private", "unlisted", "public", "followers"]).default("private"), }); export async function GET(req: NextRequest) { const { session, response } = await requireSessionOrApiKey(req); if (response) return response; const { searchParams } = req.nextUrl; const limitRaw = searchParams.get("limit"); const limit = Math.min( limitRaw !== null && !Number.isNaN(Number(limitRaw)) ? Math.max(1, Number(limitRaw)) : 20, 50 ); const offsetRaw = searchParams.get("offset"); const offset = offsetRaw !== null && !Number.isNaN(Number(offsetRaw)) ? Math.max(0, Number(offsetRaw)) : 0; const where = eq(collections.userId, session!.user.id); const [rows, countResult] = await Promise.all([ db.query.collections.findMany({ where, orderBy: desc(collections.updatedAt), with: { recipes: { limit: 4, with: { recipe: { with: { photos: true } } } } }, limit, offset, }), db.select({ total: sql`count(*)::int` }).from(collections).where(where), ]); const total = countResult[0]?.total ?? 0; return NextResponse.json({ data: rows, total, limit, offset }); } export async function POST(req: NextRequest) { const { session, response } = await requireSessionOrApiKey(req); if (response) return response; const body = await req.json() as unknown; const parsed = Schema.safeParse(body); if (!parsed.success) return NextResponse.json({ error: "Validation error" }, { status: 400 }); const id = crypto.randomUUID(); await db.insert(collections).values({ id, userId: session!.user.id, name: parsed.data.name, description: parsed.data.description, visibility: parsed.data.visibility, }); return NextResponse.json({ id }, { status: 201 }); }