import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { askAssistant } from "@/lib/assistant"; import { dbAvailable } from "@/lib/db"; export const dynamic = "force-dynamic"; export const maxDuration = 60; const Body = z.object({ messages: z.array(z.object({ role: z.enum(["user", "assistant"]), content: z.string().min(1).max(4000) })).min(1).max(30), context: z.object({ uid: z.string().max(200).optional() }).optional() }); // Limitation simple par IP (anti-abus) : 30 requêtes / 10 min, en mémoire du processus. const hits = new Map(); function limited(ip: string) { const now = Date.now(); const arr = (hits.get(ip) ?? []).filter((t) => now - t < 600000); arr.push(now); hits.set(ip, arr); return arr.length > 30; } export async function POST(req: NextRequest) { const ip = req.headers.get("x-forwarded-for")?.split(",")[0].trim() ?? "local"; if (limited(ip)) return NextResponse.json({ error: "Trop de requêtes, réessayez dans quelques minutes." }, { status: 429 }); if (!dbAvailable()) return NextResponse.json({ error: "Données indisponibles" }, { status: 503 }); const parsed = Body.safeParse(await req.json().catch(() => null)); if (!parsed.success) return NextResponse.json({ error: "Requête invalide" }, { status: 400 }); try { return NextResponse.json(await askAssistant(parsed.data.messages, parsed.data.context)); } catch (e) { console.error("[assistant]", (e as Error).message); return NextResponse.json({ error: "L'assistant est momentanément indisponible." }, { status: 502 }); } }