import { NextRequest, NextResponse } from "next/server"; import { db, recipes } from "@epicure/db"; import { eq, and, or, ne } from "@epicure/db"; import { requireSessionOrApiKey } from "@/lib/api-auth"; import { applyRateLimit } from "@/lib/rate-limit"; import { withAiQuota } from "@/lib/ai/ai-error"; import { estimateNutrition } from "@/lib/ai/features/estimate-nutrition"; type Params = { params: Promise<{ id: string }> }; export async function GET(req: NextRequest, { params }: Params) { const { session, response } = await requireSessionOrApiKey(req); if (response) return response; const { id } = await params; const recipe = await db.query.recipes.findFirst({ where: and( eq(recipes.id, id), or( eq(recipes.authorId, session!.user.id), ne(recipes.visibility, "private") ) ), }); if (!recipe) return NextResponse.json({ error: "Not found" }, { status: 404 }); return NextResponse.json({ nutrition: recipe.nutritionData ?? null, manual: recipe.nutritionManual }); } export async function POST(req: NextRequest, { params }: Params) { const { session, response } = await requireSessionOrApiKey(req); if (response) return response; const { id } = await params; const limited = await applyRateLimit(`rl:ai:${session!.user.id}`, 10, 60); if (limited) return limited; // Only the recipe author may trigger a (paid) nutrition estimate const recipe = await db.query.recipes.findFirst({ where: and(eq(recipes.id, id), eq(recipes.authorId, session!.user.id)), with: { ingredients: { orderBy: (t, { asc }) => asc(t.order) }, }, }); if (!recipe) return NextResponse.json({ error: "Not found" }, { status: 404 }); const result = await withAiQuota(session!.user.id, session!.user.tier as "free" | "pro" | "team", () => estimateNutrition({ title: recipe.title, baseServings: recipe.baseServings, ingredients: recipe.ingredients.map((i) => ({ rawName: i.rawName, quantity: i.quantity, unit: i.unit, })), }) ); if (!result.ok) return result.response; await db.update(recipes).set({ nutritionData: result.data, nutritionManual: false }).where(and(eq(recipes.id, id), eq(recipes.authorId, session!.user.id))); return NextResponse.json({ nutrition: result.data }); }