Files

63 lines
2.4 KiB
TypeScript

import { NextResponse } from "next/server";
export const runtime = "nodejs";
// RAG never goes through api-gateway. The gateway proxies `/auth/*` only --
// apps/api-gateway/src/proxy/ holds a single AuthProxyController -- so
// preferring AI_SERVICE_URL here pointed every RAG call at a service with no
// such route the moment apiGateway was enabled, breaking chat, suggest,
// history, sections, section-text and feedback at once. Resolve ai-service
// directly and let AI_SERVICE_URL mean what its name says: auth only.
const AI_SERVICE_URL = process.env.AI_SERVICE_URL ?? "http://localhost:8000";
export async function POST(request: Request) {
let traceId: string;
let rating: "helpful" | "not_helpful";
let comment: string | null;
let conversationId: string | null;
try {
const body = await request.json();
traceId = typeof body?.traceId === "string" ? body.traceId.trim() : "";
rating = body?.rating;
comment = typeof body?.comment === "string" ? body.comment.trim() || null : null;
conversationId =
typeof body?.conversationId === "string" ? body.conversationId.trim() || null : null;
} catch {
return NextResponse.json({ error: "invalid_body" }, { status: 400 });
}
if (!/^[0-9a-f-]{36}$/i.test(traceId)) {
return NextResponse.json({ error: "invalid_trace_id" }, { status: 400 });
}
if (rating !== "helpful" && rating !== "not_helpful") {
return NextResponse.json({ error: "invalid_rating" }, { status: 400 });
}
if (comment && comment.length > 2000) {
return NextResponse.json({ error: "comment_too_long" }, { status: 400 });
}
if (conversationId && conversationId.length > 128) {
return NextResponse.json({ error: "conversation_id_too_long" }, { status: 400 });
}
const base = AI_SERVICE_URL.replace(/\/v1\/rag(?:\/query)?\/?$/, "");
try {
const upstream = await fetch(`${base}/v1/rag/feedback`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
trace_id: traceId,
rating,
comment,
conversation_id: conversationId,
}),
cache: "no-store",
signal: AbortSignal.timeout(8_000),
});
const payload = await upstream.json().catch(() => ({}));
return NextResponse.json(payload, { status: upstream.status });
} catch {
return NextResponse.json({ error: "feedback_upstream_unavailable" }, { status: 503 });
}
}