63 lines
2.4 KiB
TypeScript
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 });
|
|
}
|
|
}
|