// PC7 — Endpoint proxy POST /api/chatbot // Forward la question vers CHATBOT_UPSTREAM (default : aep.trans-former.fr/api/chatbot). // Tunnel CORS (l'upstream ne sert pas de header CORS pour trans-former.fr) + timeout 25s. import type { APIRoute } from 'astro' export const prerender = false const UPSTREAM = import.meta.env.CHATBOT_UPSTREAM || 'https://aep.trans-former.fr/api/chatbot' const TIMEOUT_MS = 25_000 const jsonResponse = (status: number, payload: unknown) => new Response(JSON.stringify(payload), { status, headers: { 'Content-Type': 'application/json; charset=utf-8' }, }) export const POST: APIRoute = async ({ request }) => { let body: { question?: string; q?: string; history?: unknown } try { body = await request.json() } catch { return jsonResponse(400, { error: 'invalid_json' }) } const question = (body.question || body.q || '').toString().trim() if (!question) { return jsonResponse(400, { error: 'missing_question' }) } const ctrl = new AbortController() const timer = setTimeout(() => ctrl.abort(), TIMEOUT_MS) try { const upstream = await fetch(UPSTREAM, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ question, history: Array.isArray(body.history) ? body.history : [], }), signal: ctrl.signal, }) clearTimeout(timer) const text = await upstream.text() const contentType = upstream.headers.get('content-type') || 'application/json; charset=utf-8' return new Response(text, { status: upstream.status, headers: { 'Content-Type': contentType }, }) } catch (e) { clearTimeout(timer) const err = e as Error const aborted = err.name === 'AbortError' return jsonResponse(aborted ? 504 : 502, { error: aborted ? 'upstream_timeout' : 'upstream_failed', detail: err.message || 'unknown', }) } }