import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { db, recipes, ratings, eq, and } from "@epicure/db"; import { requireSession } from "@/lib/api-auth"; import { createNotification } from "@/lib/notifications"; const Schema = z.object({ score: z.number().int().min(1).max(5), reviewText: z.string().max(2000).optional(), }); type Params = { params: Promise<{ id: string }> }; export async function POST(req: NextRequest, { params }: Params) { const { session, response } = await requireSession(); if (response) return response; const { id } = await params; const recipe = await db.query.recipes.findFirst({ where: eq(recipes.id, id) }); if (!recipe || (recipe.visibility === "private" && recipe.authorId !== session!.user.id)) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } if (recipe.authorId === session!.user.id) { return NextResponse.json({ error: "Cannot rate your own recipe" }, { status: 400 }); } const body = await req.json() as unknown; const parsed = Schema.safeParse(body); if (!parsed.success) return NextResponse.json({ error: "Validation error" }, { status: 400 }); const existing = await db.query.ratings.findFirst({ where: and(eq(ratings.recipeId, id), eq(ratings.userId, session!.user.id)), }); if (existing) { await db.update(ratings) .set({ score: parsed.data.score, reviewText: parsed.data.reviewText, updatedAt: new Date() }) .where(eq(ratings.id, existing.id)); return NextResponse.json({ updated: true }); } await db.insert(ratings).values({ id: crypto.randomUUID(), recipeId: id, userId: session!.user.id, score: parsed.data.score, reviewText: parsed.data.reviewText, }); void createNotification({ userId: recipe.authorId, type: "rating", actorId: session!.user.id, recipeId: id }); return NextResponse.json({ created: true }, { status: 201 }); }