import { NextResponse } from "next/server" import { auth } from "@/lib/auth" import { prisma } from "@/lib/prisma" import { recipeCreateSchema } from "@/lib/validators" import { fuzzyMatchIngredients, recalculateMissingCount } from "@/lib/ingredient-matcher" import type { Prisma } from "@prisma/client" export async function GET() { try { const session = await auth() if (!session?.user?.id) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) } const [recipes, barItems] = await Promise.all([ prisma.recipe.findMany({ where: { userId: session.user.id }, orderBy: { createdAt: "desc" }, include: { sourceDrink: { select: { name: true, type: true }, }, }, }), prisma.barItem.findMany({ where: { userId: session.user.id, quantity: { not: "EMPTY" }, }, select: { name: true }, }), ]) // Re-process ingredient availability against current bar inventory const processedRecipes = recipes.map((recipe) => { if (barItems.length > 0 && Array.isArray(recipe.ingredients)) { const ingredients = recipe.ingredients as { name: string; amount: string; available: boolean }[] const matched = fuzzyMatchIngredients(ingredients, barItems) return { ...recipe, ingredients: matched, missingCount: recalculateMissingCount(matched), } } return recipe }) return NextResponse.json({ recipes: processedRecipes }) } catch (error) { console.error("GET /api/recipes error:", error) return NextResponse.json( { error: "Internal server error" }, { status: 500 } ) } } export async function POST(request: Request) { try { const session = await auth() if (!session?.user?.id) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) } const body = await request.json() const parsed = recipeCreateSchema.safeParse(body) if (!parsed.success) { return NextResponse.json( { error: "Validation failed", issues: parsed.error.issues }, { status: 400 } ) } // sourceDrinkId comes from the client and is a foreign key onto Drink. Without // this check a user could attach a recipe to someone else's drink, where it // would render on their drink page and they could not delete it. if (parsed.data.sourceDrinkId) { const ownsDrink = await prisma.drink.findFirst({ where: { id: parsed.data.sourceDrinkId, userId: session.user.id }, select: { id: true }, }) if (!ownsDrink) { return NextResponse.json({ error: "Drink not found" }, { status: 404 }) } } const recipe = await prisma.recipe.create({ data: { userId: session.user.id, title: parsed.data.title, ingredients: parsed.data.ingredients as unknown as Prisma.InputJsonValue, steps: parsed.data.steps as unknown as Prisma.InputJsonValue, garnish: parsed.data.garnish || null, glassware: parsed.data.glassware || null, sourceDrinkId: parsed.data.sourceDrinkId || null, notes: parsed.data.notes || null, }, }) return NextResponse.json(recipe, { status: 201 }) } catch (error) { console.error("POST /api/recipes error:", error) return NextResponse.json( { error: "Internal server error" }, { status: 500 } ) } }