From 6c97ce3ed9d42360c7624b50e634205e510ba368 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 25 Feb 2026 15:08:21 +0100 Subject: [PATCH] feat: server-side support for advance criterion in upsertForm and submit Co-Authored-By: Claude Opus 4.6 --- src/server/routers/evaluation.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/server/routers/evaluation.ts b/src/server/routers/evaluation.ts index 79113da..303b2cb 100644 --- a/src/server/routers/evaluation.ts +++ b/src/server/routers/evaluation.ts @@ -247,7 +247,7 @@ export const evaluationRouter = router({ if (!scores) return true const val = scores[c.id] // Boolean criteria store true/false, numeric criteria store numbers - if (c.type === 'boolean') return typeof val !== 'boolean' + if (c.type === 'boolean' || c.type === 'advance') return typeof val !== 'boolean' return typeof val !== 'number' }) if (missingCriteria.length > 0) { @@ -1255,6 +1255,15 @@ export const evaluationRouter = router({ .mutation(async ({ ctx, input }) => { const { roundId, criteria } = input + // Enforce max one advance criterion per form + const advanceCount = criteria.filter((c) => c.type === 'advance').length + if (advanceCount > 1) { + throw new TRPCError({ + code: 'BAD_REQUEST', + message: 'Only one advance criterion is allowed per evaluation form', + }) + } + // Verify round exists await ctx.prisma.round.findUniqueOrThrow({ where: { id: roundId } }) @@ -1299,6 +1308,14 @@ export const evaluationRouter = router({ falseLabel: c.falseLabel || 'No', } } + if (type === 'advance') { + return { + ...base, + required: true, // always required, override any input + trueLabel: c.trueLabel || 'Yes', + falseLabel: c.falseLabel || 'No', + } + } // section_header return base })