import { NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; // GET /api/traces/[id] — Get single trace with all relations export async function GET( _request: Request, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params; if (!id || typeof id !== "string") { return NextResponse.json({ error: "Invalid trace ID" }, { status: 400 }); } const trace = await prisma.trace.findUnique({ where: { id }, include: { decisionPoints: { orderBy: { timestamp: "asc", }, }, spans: { orderBy: { startedAt: "asc", }, }, events: { orderBy: { timestamp: "asc", }, }, }, }); if (!trace) { return NextResponse.json({ error: "Trace not found" }, { status: 404 }); } // Transform data to match frontend expectations const transformedTrace = { ...trace, decisionPoints: trace.decisionPoints.map((dp) => ({ id: dp.id, type: dp.type, chosenAction: typeof dp.chosen === "string" ? dp.chosen : JSON.stringify(dp.chosen), alternatives: dp.alternatives.map((alt) => (typeof alt === "string" ? alt : JSON.stringify(alt))), reasoning: dp.reasoning, contextSnapshot: dp.contextSnapshot as Record | null, confidence: null, // Not in schema, default to null timestamp: dp.timestamp.toISOString(), parentSpanId: dp.parentSpanId, })), spans: trace.spans.map((span) => ({ id: span.id, name: span.name, type: span.type, status: span.status === "COMPLETED" ? "OK" : span.status === "ERROR" ? "ERROR" : "CANCELLED", startedAt: span.startedAt.toISOString(), endedAt: span.endedAt?.toISOString() ?? null, durationMs: span.durationMs, input: span.input, output: span.output, metadata: (span.metadata as Record) ?? {}, parentSpanId: span.parentSpanId, })), events: trace.events.map((event) => ({ id: event.id, type: event.type, name: event.name, timestamp: event.timestamp.toISOString(), metadata: (event.metadata as Record) ?? {}, spanId: event.spanId, })), }; return NextResponse.json({ trace: transformedTrace }, { status: 200 }); } catch (error) { console.error("Error retrieving trace:", error); return NextResponse.json({ error: "Internal server error" }, { status: 500 }); } }