import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { db, chatMessages, eq, and, isNull, desc, asc, ilike } from "@epicure/db"; import { requireSession } from "@/lib/api-auth"; const Schema = z.object({ recipeId: z.string().uuid().optional(), // "general" restricts to the homepage cooking assistant (recipeId null); // omit both recipeId and scope to search across everything. scope: z.enum(["general"]).optional(), q: z.string().max(200).optional(), limit: z.coerce.number().int().min(1).max(100).default(30), }); export async function GET(req: NextRequest) { const { session, response } = await requireSession(); if (response) return response; const { searchParams } = new URL(req.url); const parsed = Schema.safeParse({ recipeId: searchParams.get("recipeId") ?? undefined, scope: searchParams.get("scope") ?? undefined, q: searchParams.get("q") ?? undefined, limit: searchParams.get("limit") ?? undefined, }); if (!parsed.success) { return NextResponse.json({ error: "Validation error" }, { status: 400 }); } const { recipeId, scope, q, limit } = parsed.data; const conditions = [eq(chatMessages.userId, session!.user.id)]; if (recipeId) conditions.push(eq(chatMessages.recipeId, recipeId)); else if (scope === "general") conditions.push(isNull(chatMessages.recipeId)); if (q?.trim()) conditions.push(ilike(chatMessages.content, `%${q.trim()}%`)); const rows = await db.query.chatMessages.findMany({ where: and(...conditions), orderBy: q?.trim() ? [desc(chatMessages.createdAt)] : [asc(chatMessages.createdAt)], limit, with: { recipe: { columns: { id: true, title: true } } }, }); return NextResponse.json({ data: rows.map((r) => ({ id: r.id, role: r.role, content: r.content, createdAt: r.createdAt.toISOString(), recipeId: r.recipeId, recipeTitle: r.recipe?.title ?? null, })), }); } const DeleteSchema = z.object({ recipeId: z.string().uuid().optional(), scope: z.enum(["general"]).optional(), }); // No `q` here on purpose — clearing is "this whole conversation" (or // everything), not "every message matching a search term". export async function DELETE(req: NextRequest) { const { session, response } = await requireSession(); if (response) return response; const { searchParams } = new URL(req.url); const parsed = DeleteSchema.safeParse({ recipeId: searchParams.get("recipeId") ?? undefined, scope: searchParams.get("scope") ?? undefined, }); if (!parsed.success) { return NextResponse.json({ error: "Validation error" }, { status: 400 }); } const { recipeId, scope } = parsed.data; const conditions = [eq(chatMessages.userId, session!.user.id)]; if (recipeId) conditions.push(eq(chatMessages.recipeId, recipeId)); else if (scope === "general") conditions.push(isNull(chatMessages.recipeId)); await db.delete(chatMessages).where(and(...conditions)); return NextResponse.json({ ok: true }); }