84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
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<string, unknown> | 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<string, unknown>) ?? {},
|
|
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<string, unknown>) ?? {},
|
|
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 });
|
|
}
|
|
}
|