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:
@@ -0,0 +1,11 @@
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditLog_evaluationId_idx" ON "AuditLog"("evaluationId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evaluation_evaluatorId_idx" ON "Evaluation"("evaluatorId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evaluation_templateId_idx" ON "Evaluation"("templateId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EvaluationShare_userId_idx" ON "EvaluationShare"("userId");
|
||||
@@ -66,6 +66,9 @@ model Evaluation {
|
||||
isPublic Boolean @default(false) // visible par tous (ex. démo)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([evaluatorId])
|
||||
@@index([templateId])
|
||||
}
|
||||
|
||||
model EvaluationShare {
|
||||
@@ -77,6 +80,7 @@ model EvaluationShare {
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([evaluationId, userId])
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
model DimensionScore {
|
||||
@@ -106,4 +110,6 @@ model AuditLog {
|
||||
newValue String?
|
||||
userId String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([evaluationId])
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user