perf: optimisations DB — batch queries et index

- createEvaluation: remplace N create() par un createMany() (N→1 requête)
- updateEvaluation: regroupe les upserts en $transaction() parallèle
- Ajout d'index sur Evaluation.evaluatorId, Evaluation.templateId,
  EvaluationShare.userId et AuditLog.evaluationId

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 13:27:57 +01:00
parent 99e1a06137
commit 27866091bf
3 changed files with 50 additions and 29 deletions

View File

@@ -72,11 +72,12 @@ export async function createEvaluation(data: {
},
});
for (const dim of template.dimensions) {
await prisma.dimensionScore.create({
data: { evaluationId: evaluation.id, dimensionId: dim.id },
});
}
await prisma.dimensionScore.createMany({
data: template.dimensions.map((dim) => ({
evaluationId: evaluation.id,
dimensionId: dim.id,
})),
});
revalidatePath("/dashboard");
return { success: true, data: { id: evaluation.id } };
@@ -177,30 +178,33 @@ export async function updateEvaluation(id: string, data: UpdateEvaluationInput):
}
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 validScores = dimensionScores.filter((ds) => ds.dimensionId);
if (validScores.length > 0) {
await prisma.$transaction(
validScores.map((ds) =>
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,
},
})
)
);
}
}