Files
iag-dev-evaluator/src/app/api/evaluations/[id]/route.ts

180 lines
5.8 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { Prisma } from "@prisma/client";
import { prisma } from "@/lib/db";
export async function GET(
_req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
const evaluation = await prisma.evaluation.findUnique({
where: { id },
include: {
template: {
include: {
dimensions: { orderBy: { orderIndex: "asc" } },
},
},
dimensionScores: { include: { dimension: true } },
},
});
if (!evaluation) {
return NextResponse.json({ error: "Evaluation not found" }, { status: 404 });
}
// Prisma ORM omits suggestedQuestions in some contexts — fetch via raw
const templateId = evaluation.templateId;
const dimsRaw = evaluation.template
? ((await prisma.$queryRaw(
Prisma.sql`SELECT id, slug, title, rubric, "orderIndex", "suggestedQuestions" FROM "TemplateDimension" WHERE "templateId" = ${templateId} ORDER BY "orderIndex" ASC`
)) as { id: string; slug: string; title: string; rubric: string; orderIndex: number; suggestedQuestions: string | null }[])
: [];
const dimMap = new Map(dimsRaw.map((d) => [d.id, d]));
const out = {
...evaluation,
template: evaluation.template
? {
...evaluation.template,
dimensions: evaluation.template.dimensions.map((d) => {
const raw = dimMap.get(d.id);
return {
id: d.id,
slug: d.slug,
title: d.title,
rubric: d.rubric,
orderIndex: d.orderIndex,
suggestedQuestions: raw?.suggestedQuestions ?? d.suggestedQuestions,
};
}),
}
: null,
dimensionScores: evaluation.dimensionScores.map((ds) => ({
...ds,
dimension: ds.dimension
? {
id: ds.dimension.id,
slug: ds.dimension.slug,
title: ds.dimension.title,
rubric: ds.dimension.rubric,
suggestedQuestions: dimMap.get(ds.dimension.id)?.suggestedQuestions ?? ds.dimension.suggestedQuestions,
}
: null,
})),
};
return NextResponse.json(out);
} catch (e) {
console.error(e);
return NextResponse.json({ error: "Failed to fetch evaluation" }, { status: 500 });
}
}
export async function PUT(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
const body = await req.json();
const { candidateName, candidateRole, candidateTeam, evaluatorName, evaluationDate, status, findings, recommendations, dimensionScores } = body;
const existing = await prisma.evaluation.findUnique({ where: { id } });
if (!existing) {
return NextResponse.json({ error: "Evaluation not found" }, { status: 404 });
}
const updateData: Record<string, unknown> = {};
if (candidateName != null) updateData.candidateName = candidateName;
if (candidateRole != null) updateData.candidateRole = candidateRole;
if (candidateTeam !== undefined) updateData.candidateTeam = candidateTeam || null;
if (evaluatorName != null) updateData.evaluatorName = evaluatorName;
if (evaluationDate != null) {
const d = new Date(evaluationDate);
if (!isNaN(d.getTime())) updateData.evaluationDate = d;
}
if (status != null) updateData.status = status;
if (findings != null) updateData.findings = findings;
if (recommendations != null) updateData.recommendations = recommendations;
if (Object.keys(updateData).length > 0) {
await prisma.auditLog.create({
data: {
evaluationId: id,
action: "updated",
newValue: JSON.stringify(updateData),
},
});
}
if (Object.keys(updateData).length > 0) {
await prisma.evaluation.update({
where: { id },
data: updateData as Record<string, unknown>,
});
}
if (dimensionScores && Array.isArray(dimensionScores)) {
for (const ds of dimensionScores) {
if (ds.dimensionId) {
await prisma.dimensionScore.upsert({
where: {
evaluationId_dimensionId: {
evaluationId: id,
dimensionId: ds.dimensionId,
},
},
update: {
score: ds.score,
justification: ds.justification,
examplesObserved: ds.examplesObserved,
confidence: ds.confidence,
candidateNotes: ds.candidateNotes,
},
create: {
evaluationId: id,
dimensionId: ds.dimensionId,
score: ds.score,
justification: ds.justification,
examplesObserved: ds.examplesObserved,
confidence: ds.confidence,
candidateNotes: ds.candidateNotes,
},
});
}
}
}
const updated = await prisma.evaluation.findUnique({
where: { id },
include: {
template: { include: { dimensions: { orderBy: { orderIndex: "asc" } } } },
dimensionScores: { include: { dimension: true } },
},
});
return NextResponse.json(updated);
} catch (e) {
console.error(e);
const msg = e instanceof Error ? e.message : "Failed to update evaluation";
return NextResponse.json({ error: msg }, { status: 500 });
}
}
export async function DELETE(
_req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
await prisma.evaluation.delete({ where: { id } });
return NextResponse.json({ ok: true });
} catch (e) {
console.error(e);
return NextResponse.json({ error: "Failed to delete evaluation" }, { status: 500 });
}
}