From cdde864414227a4d11f404faa32a58a7e3999cfb Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Thu, 27 Nov 2025 17:03:52 +1100 Subject: [PATCH] Add scorecard and phase ID checks to the reviewer checks --- src/services/ChallengeService.js | 24 ++++++++++++++++++++++ test/unit/ChallengeService.test.js | 32 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/services/ChallengeService.js b/src/services/ChallengeService.js index 9323037..7a30d85 100644 --- a/src/services/ChallengeService.js +++ b/src/services/ChallengeService.js @@ -2816,6 +2816,30 @@ async function updateChallenge(currentUser, challengeId, data, options = {}) { : Array.isArray(challenge.reviewers) ? challenge.reviewers : []; + + const reviewersMissingFields = []; + effectiveReviewers.forEach((reviewer, index) => { + const hasScorecardId = + reviewer && !_.isNil(reviewer.scorecardId) && String(reviewer.scorecardId).trim() !== ""; + const hasPhaseId = + reviewer && !_.isNil(reviewer.phaseId) && String(reviewer.phaseId).trim() !== ""; + + if (!hasScorecardId || !hasPhaseId) { + const missing = []; + if (!hasScorecardId) missing.push("scorecardId"); + if (!hasPhaseId) missing.push("phaseId"); + reviewersMissingFields.push(`reviewer[${index}] missing ${missing.join(" and ")}`); + } + }); + + if (reviewersMissingFields.length > 0) { + throw new errors.BadRequestError( + `Cannot activate challenge; reviewers are missing required fields: ${reviewersMissingFields.join( + "; " + )}` + ); + } + const reviewerPhaseIds = new Set( effectiveReviewers .filter((reviewer) => reviewer && reviewer.phaseId) diff --git a/test/unit/ChallengeService.test.js b/test/unit/ChallengeService.test.js index 36ee35f..a6d6b71 100644 --- a/test/unit/ChallengeService.test.js +++ b/test/unit/ChallengeService.test.js @@ -1316,6 +1316,38 @@ describe('challenge service unit tests', () => { } }) + it('update challenge - prevent activating when reviewer is missing required fields', async () => { + const activationChallenge = await createActivationChallenge() + await prisma.challengeReviewer.create({ + data: { + id: uuid(), + challengeId: activationChallenge.id, + scorecardId: '', + isMemberReview: false, + phaseId: data.phase.id, + aiWorkflowId: 'wf-missing', + createdBy: 'activation-test', + updatedBy: 'activation-test' + } + }) + + try { + await service.updateChallenge( + { isMachine: true, sub: 'sub-activate', userId: 22838965 }, + activationChallenge.id, + { + status: ChallengeStatusEnum.ACTIVE + } + ) + } catch (e) { + should.equal(e.message.indexOf('reviewers are missing required fields') >= 0, true) + return + } finally { + await prisma.challenge.delete({ where: { id: activationChallenge.id } }) + } + throw new Error('should not reach here') + }) + it('update challenge - enforce reviewers for required phases', async () => { const setup = await createChallengeWithRequiredReviewPhases() try {