From 6a9bb4354eede1dd84e27762af276c09509d99ab Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 12 Nov 2025 15:23:54 +0100 Subject: [PATCH 1/3] feat: added ai workflow id to default reviewer --- .../migration.sql | 10 ++++++++++ prisma/schema.prisma | 4 ++-- src/services/ChallengeService.js | 9 +-------- .../DefaultChallengeReviewerService.js | 18 +++++++++++++----- 4 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 prisma/migrations/20251112142035_ai_workflow_id_in_def_challenge_reviewer/migration.sql diff --git a/prisma/migrations/20251112142035_ai_workflow_id_in_def_challenge_reviewer/migration.sql b/prisma/migrations/20251112142035_ai_workflow_id_in_def_challenge_reviewer/migration.sql new file mode 100644 index 0000000..9aef1b8 --- /dev/null +++ b/prisma/migrations/20251112142035_ai_workflow_id_in_def_challenge_reviewer/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `isAIReviewer` on the `DefaultChallengeReviewer` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "DefaultChallengeReviewer" DROP COLUMN "isAIReviewer", +ADD COLUMN "aiWorkflowId" TEXT, +ALTER COLUMN "scorecardId" DROP NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3de05f6..bf5c519 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -649,7 +649,7 @@ model DefaultChallengeReviewer { trackId String timelineTemplateId String? // Reviewer configuration (mirrors ChallengeReviewer) - scorecardId String + scorecardId String? isMemberReview Boolean memberReviewerCount Int? phaseName String @@ -659,7 +659,7 @@ model DefaultChallengeReviewer { baseCoefficient Float? incrementalCoefficient Float? opportunityType ReviewOpportunityTypeEnum? - isAIReviewer Boolean? + aiWorkflowId String? shouldOpenOpportunity Boolean @default(true) // Relations diff --git a/src/services/ChallengeService.js b/src/services/ChallengeService.js index a4b0d5a..057e6fb 100644 --- a/src/services/ChallengeService.js +++ b/src/services/ChallengeService.js @@ -300,7 +300,6 @@ async function getDefaultReviewers(currentUser, criteria) { incrementalCoefficient: r.incrementalCoefficient, type: r.opportunityType, aiWorkflowId: r.aiWorkflowId, - isAIReviewer: r.isAIReviewer, shouldOpenOpportunity: _.isBoolean(r.shouldOpenOpportunity) ? r.shouldOpenOpportunity : true, })); } @@ -322,7 +321,6 @@ async function setDefaultReviewers(currentUser, data) { Joi.object().keys({ scorecardId: Joi.string().required(), isMemberReview: Joi.boolean().required(), - isAIReviewer: Joi.boolean().default(false), shouldOpenOpportunity: Joi.boolean().default(true), memberReviewerCount: Joi.when("isMemberReview", { is: true, @@ -403,7 +401,7 @@ async function setDefaultReviewers(currentUser, data) { timelineTemplateId: _.isNil(value.timelineTemplateId) ? null : value.timelineTemplateId, scorecardId: String(r.scorecardId), isMemberReview: !!r.isMemberReview, - isAIReviewer: !!r.isAIReviewer, + aiWorkflowId:_.isNil(r.aiWorkflowId) ? null : r.aiWorkflowId, memberReviewerCount: _.isNil(r.memberReviewerCount) ? null : Number(r.memberReviewerCount), @@ -414,7 +412,6 @@ async function setDefaultReviewers(currentUser, data) { ? null : Number(r.incrementalCoefficient), opportunityType: r.type ? _.toUpper(r.type) : null, - aiWorkflowId: r.aiWorkflowId, shouldOpenOpportunity: _.isNil(r.shouldOpenOpportunity) ? true : !!r.shouldOpenOpportunity, @@ -1712,7 +1709,6 @@ async function createChallenge(currentUser, challenge, userToken) { incrementalCoefficient: r.incrementalCoefficient, type: r.opportunityType, aiWorkflowId: r.aiWorkflowId, - isAIReviewer: r.isAIReviewer ?? false, shouldOpenOpportunity: _.isBoolean(r.shouldOpenOpportunity) ? r.shouldOpenOpportunity : true, @@ -1880,7 +1876,6 @@ createChallenge.schema = { Joi.object().keys({ scorecardId: Joi.string().required(), isMemberReview: Joi.boolean().required(), - isAIReviewer: Joi.boolean().default(false), shouldOpenOpportunity: Joi.boolean().default(true), memberReviewerCount: Joi.when("isMemberReview", { is: true, @@ -3075,7 +3070,6 @@ updateChallenge.schema = { Joi.object().keys({ scorecardId: Joi.string().required(), isMemberReview: Joi.boolean().required(), - isAIReviewer: Joi.boolean().default(false), shouldOpenOpportunity: Joi.boolean().default(true), memberReviewerCount: Joi.when("isMemberReview", { is: true, @@ -3555,7 +3549,6 @@ function sanitizeChallenge(challenge) { _.pick(rv, [ "scorecardId", "isMemberReview", - "isAIReviewer", "memberReviewerCount", "phaseId", "fixedAmount", diff --git a/src/services/DefaultChallengeReviewerService.js b/src/services/DefaultChallengeReviewerService.js index 3a82a70..6588395 100644 --- a/src/services/DefaultChallengeReviewerService.js +++ b/src/services/DefaultChallengeReviewerService.js @@ -262,8 +262,8 @@ function normalizePayload(data = {}, isPartial = false) { } else if (!isPartial && _.isNil(data.opportunityType)) { normalized.opportunityType = null; } - if (shouldAssign(data.isAIReviewer)) { - normalized.isAIReviewer = data.isAIReviewer; + if (shouldAssign(data.aiWorkflowId)) { + normalized.aiWorkflowId = data.aiWorkflowId; } if (shouldAssign(data.shouldOpenOpportunity)) { normalized.shouldOpenOpportunity = data.shouldOpenOpportunity; @@ -338,7 +338,11 @@ createDefaultChallengeReviewer.schema = { baseCoefficient: Joi.number().min(0).max(1).allow(null), incrementalCoefficient: Joi.number().min(0).max(1).allow(null), opportunityType: Joi.string().valid(..._.values(ReviewOpportunityTypeEnum)).insensitive(), - isAIReviewer: Joi.boolean().required(), + aiWorkflowId: Joi.when("isMemberReview", { + is: false, + then: Joi.string().required(), + otherwise: Joi.valid(null), + }), shouldOpenOpportunity: Joi.boolean().required(), }) .required(), @@ -417,7 +421,11 @@ fullyUpdateDefaultChallengeReviewer.schema = { baseCoefficient: Joi.number().min(0).max(1).allow(null), incrementalCoefficient: Joi.number().min(0).max(1).allow(null), opportunityType: Joi.string().valid(..._.values(ReviewOpportunityTypeEnum)).insensitive(), - isAIReviewer: Joi.boolean().required(), + aiWorkflowId: Joi.when("isMemberReview", { + is: false, + then: Joi.string().required(), + otherwise: Joi.valid(null), + }), shouldOpenOpportunity: Joi.boolean().required(), }) .required(), @@ -516,7 +524,7 @@ partiallyUpdateDefaultChallengeReviewer.schema = { .valid(..._.values(ReviewOpportunityTypeEnum)) .insensitive() .allow(null), - isAIReviewer: Joi.boolean(), + aiWorkflowId: Joi.string(), shouldOpenOpportunity: Joi.boolean(), }) .required(), From c6c5463836f146d816f85694757375adf19208f3 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 12 Nov 2025 15:26:16 +0100 Subject: [PATCH 2/3] fix: make scorecardId optional --- src/services/DefaultChallengeReviewerService.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/DefaultChallengeReviewerService.js b/src/services/DefaultChallengeReviewerService.js index 6588395..694b2d5 100644 --- a/src/services/DefaultChallengeReviewerService.js +++ b/src/services/DefaultChallengeReviewerService.js @@ -325,7 +325,7 @@ createDefaultChallengeReviewer.schema = { typeId: Joi.id().required(), trackId: Joi.id().required(), timelineTemplateId: Joi.optionalId().allow(null), - scorecardId: Joi.string().required(), + scorecardId: Joi.string().optional(), isMemberReview: Joi.boolean().required(), memberReviewerCount: Joi.when("isMemberReview", { is: true, @@ -408,7 +408,7 @@ fullyUpdateDefaultChallengeReviewer.schema = { typeId: Joi.id().required(), trackId: Joi.id().required(), timelineTemplateId: Joi.optionalId().allow(null), - scorecardId: Joi.string().required(), + scorecardId: Joi.string().optional(), isMemberReview: Joi.boolean().required(), memberReviewerCount: Joi.when("isMemberReview", { is: true, From d8c7eef5633d57bd2b854c25c575813e677a0c9b Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 12 Nov 2025 17:25:03 +0100 Subject: [PATCH 3/3] feat: added ai workflow id to default reviewer --- .../migration.sql | 2 +- prisma/schema.prisma | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename prisma/migrations/{20251112142035_ai_workflow_id_in_def_challenge_reviewer => 20251112162335_aiworkflowid_in_def_challenge_reviewer}/migration.sql (86%) diff --git a/prisma/migrations/20251112142035_ai_workflow_id_in_def_challenge_reviewer/migration.sql b/prisma/migrations/20251112162335_aiworkflowid_in_def_challenge_reviewer/migration.sql similarity index 86% rename from prisma/migrations/20251112142035_ai_workflow_id_in_def_challenge_reviewer/migration.sql rename to prisma/migrations/20251112162335_aiworkflowid_in_def_challenge_reviewer/migration.sql index 9aef1b8..b50c0d0 100644 --- a/prisma/migrations/20251112142035_ai_workflow_id_in_def_challenge_reviewer/migration.sql +++ b/prisma/migrations/20251112162335_aiworkflowid_in_def_challenge_reviewer/migration.sql @@ -6,5 +6,5 @@ */ -- AlterTable ALTER TABLE "DefaultChallengeReviewer" DROP COLUMN "isAIReviewer", -ADD COLUMN "aiWorkflowId" TEXT, +ADD COLUMN "aiWorkflowId" VARCHAR(14), ALTER COLUMN "scorecardId" DROP NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index bf5c519..8ce74c9 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -659,7 +659,7 @@ model DefaultChallengeReviewer { baseCoefficient Float? incrementalCoefficient Float? opportunityType ReviewOpportunityTypeEnum? - aiWorkflowId String? + aiWorkflowId String? @db.VarChar(14) shouldOpenOpportunity Boolean @default(true) // Relations @@ -724,4 +724,4 @@ model TimelineTemplatePhase { @@index([timelineTemplateId]) @@index([timelineTemplateId, phaseId]) -} +} \ No newline at end of file