import { NextRequest, NextResponse } from 'next/server'; import prisma from '@/lib/prisma'; export async function POST( req: NextRequest, context: { params: Promise<{ id: string }> } ) { const { id: paramId } = await context.params; const userId = req.headers.get('x-user-id'); if (!userId) { return NextResponse.json({ error: 'Utilisateur non identifié' }, { status: 401 }); } try { const { value, comment } = await req.json(); if (!value || value < 1 || value > 5) { return NextResponse.json({ error: 'Valeur de note invalide (1-5)' }, { status: 400 }); } // 1. Resolve actual Business UUID if paramId is a slug const business = await prisma.business.findFirst({ where: { OR: [ { id: paramId }, { slug: paramId } ] }, select: { id: true } }); if (!business) { return NextResponse.json({ error: "Les données de démonstration ne peuvent pas recevoir d'avis. Veuillez créer votre propre entreprise pour tester." }, { status: 403 }); } const businessId = business.id; const ownerId = (business as any).ownerId; // 2. Security: Don't allow owner to rate themselves if (userId === ownerId) { return NextResponse.json({ error: "Vous ne pouvez pas noter votre propre entreprise." }, { status: 403 }); } // 3. Fetch existing rating to check rules const existingRating = await prisma.rating.findUnique({ where: { userId_businessId: { userId, businessId } } }); if (existingRating) { // Rule: Score can only be re-evaluated UPWARDS if (value < existingRating.value) { return NextResponse.json({ error: `La note ne peut être réévaluée qu'à la hausse. Votre note actuelle est de ${existingRating.value} étoiles.` }, { status: 400 }); } // Rule: Comment is IMMUTABLE once set // We only update the value. If the comment was empty, we can set it once. await prisma.rating.update({ where: { id: existingRating.id }, data: { value, comment: existingRating.comment ? undefined : comment, // Only set if it was null status: 'PENDING' // Reset to pending for re-moderation } }); } else { // 4. Create new rating await prisma.rating.create({ data: { value, comment, userId, businessId, status: 'PENDING' } }); } // 3. Aggregate all ratings for this business const stats = await prisma.rating.aggregate({ where: { businessId }, _avg: { value: true }, _count: { value: true } }); const newRating = stats._avg.value || 0; const newRatingCount = stats._count.value || 0; // 4. Update the business const updatedBusiness = await prisma.business.update({ where: { id: businessId }, data: { rating: newRating, ratingCount: newRatingCount } }); return NextResponse.json({ rating: updatedBusiness.rating, ratingCount: updatedBusiness.ratingCount, message: 'Vote enregistré avec succès' }); } catch (error: any) { console.error('Error rating business:', error); return NextResponse.json({ error: 'Erreur serveur lors du vote' }, { status: 500 }); } }