import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { db } from "@/db/client"; import { reports } from "@/db/schema"; import { assertSameOrigin, currentUser, clientIp } from "@/lib/auth/session"; import { hit } from "@/lib/auth/ratelimit"; import { ipHash } from "@/lib/auth/crypto"; import { audit } from "@/lib/auth/audit"; import { apiError, handle, parseBody } from "@/lib/api"; export const dynamic = "force-dynamic"; const Body = z.object({ targetType: z.enum(["LISTING", "AGGREGATED_LISTING", "USER", "MESSAGE"]), targetId: z.string().min(1).max(200), reason: z.enum(["arnaque", "doublon", "contenu_inapproprie", "informations_fausses", "deja_vendu_loue", "droits_photos", "autre"]), details: z.string().trim().max(1000).optional() }); export async function POST(req: NextRequest) { try { await assertSameOrigin(); const b = await parseBody(req, Body); const u = await currentUser(); const iph = ipHash(await clientIp()); const rl = await hit(`report:${u?.id ?? iph}`, 10, 86400); if (!rl.ok) return apiError(429, "rate_limited", "Trop de signalements aujourd'hui."); const [r] = await db().insert(reports).values({ targetType: b.targetType, targetId: b.targetId, reporterId: u?.id ?? null, reason: b.reason, details: b.details ?? null }).returning({ id: reports.id }); await audit("report.create", { actorId: u?.id ?? null, objectType: b.targetType, objectId: b.targetId, ipHash: iph, meta: { reason: b.reason } }); return NextResponse.json({ ok: true, id: r.id }, { status: 201 }); } catch (e) { return handle(e); } }