Fix criteria validation using wrong form + fix reports page null crash
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m38s

1. Evaluation submit: The requireAllCriteriaScored validation was
   querying findFirst({ roundId, isActive: true }) to get the form
   criteria, instead of using the evaluation's stored formId. If an
   admin ever re-saved the evaluation form (creating a new version
   with new criterion IDs), jurors who started evaluating before the
   re-save had scores keyed to old IDs that didn't match the new
   form. Now uses evaluation.form (the form assigned at start time).

2. Observer reports page: Two .map() calls on p.stages lacked null
   guards, causing "Cannot read properties of null (reading 'map')"
   crash. Added (p.stages || []) guards matching the pattern already
   used in CrossStageTab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt
2026-02-20 13:16:09 +01:00
parent bf02684736
commit 4519bc6080
2 changed files with 7 additions and 6 deletions

View File

@@ -146,6 +146,7 @@ export const evaluationRouter = router({
where: { id },
include: {
assignment: true,
form: { select: { criteriaJson: true } },
},
})
@@ -231,11 +232,11 @@ export const evaluationRouter = router({
}
// Fix 5: requireAllCriteriaScored validation
// Use the form the juror was assigned (evaluation.form), NOT the current active form.
// If the admin re-saves the form, criterion IDs change — jurors who started before
// the re-save would have scores keyed to old IDs that don't match the new form.
if (config.requireAllCriteriaScored && scoringMode === 'criteria') {
const evalForm = await ctx.prisma.evaluationForm.findFirst({
where: { roundId: round.id, isActive: true },
select: { criteriaJson: true },
})
const evalForm = evaluation.form
if (evalForm?.criteriaJson) {
const criteria = evalForm.criteriaJson as Array<{ id: string; label?: string; type?: string; required?: boolean }>
const scorableCriteria = criteria.filter(