Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ workflows:
- PM-4478_add-ai-screening-phase-when-editing-after-launch
- review-context
- PM-4684_challenge-approval-flow
tags:
only: /^dev-.*/

- "build-qa":
context: org-global
Expand Down
4 changes: 4 additions & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ module.exports = {
.filter(Boolean)
: ["80000062"],

// The ID of the AI Only Challenge timeline template (seeded via migration)
AI_ONLY_TIMELINE_TEMPLATE_ID:
process.env.AI_ONLY_TIMELINE_TEMPLATE_ID || "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",

// health check timeout in milliseconds
HEALTH_CHECK_TIMEOUT: process.env.HEALTH_CHECK_TIMEOUT || 3000,

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"e2e:cov": "nyc --reporter=html --reporter=text npm run e2e",
"services:up": "docker-compose -f ./local/docker-compose.yml up -d",
"services:down": "docker-compose -f ./local/docker-compose.yml down",
"services:logs": "docker-compose -f ./local/docker-compose.yml logs"
"services:logs": "docker-compose -f ./local/docker-compose.yml logs",
"deploy:dev": "BRANCH=$(git rev-parse --abbrev-ref HEAD) && TAG=\"dev-${BRANCH}\" && git tag -d \"$TAG\" 2>/dev/null; git push origin \":refs/tags/$TAG\" 2>/dev/null; git tag \"$TAG\" && git push origin \"$TAG\""
},
"author": "TCSCODER",
"license": "MIT",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
-- Insert AI Review phase
INSERT INTO "Phase" (
"id",
"name",
"description",
"isOpen",
"duration",
"createdAt",
"createdBy",
"updatedAt",
"updatedBy"
) VALUES (
'c3a4d5e6-f7b8-4c9d-a0e1-2b3c4d5e6f7a',
'AI Review',
'AI Review Phase',
true,
86400,
'2025-03-10T13:08:02.378Z',
'topcoder user',
'2025-03-10T13:08:02.378Z',
'topcoder user'
)
ON CONFLICT DO NOTHING;

-- Insert AI Only Challenge timeline template
INSERT INTO "TimelineTemplate" (
"id",
"name",
"description",
"isActive",
"createdAt",
"createdBy",
"updatedAt",
"updatedBy"
) VALUES (
'b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e',
'AI Only Challenge',
'AI-Only Challenge Timeline',
true,
'2025-03-10T13:08:02.378Z',
'topcoder user',
'2025-03-10T13:08:02.378Z',
'topcoder user'
)
ON CONFLICT DO NOTHING;

-- Insert TimelineTemplatePhase entries for the AI Only Challenge template
-- Registration phase (no predecessor)
INSERT INTO "TimelineTemplatePhase" (
"id",
"timelineTemplateId",
"phaseId",
"predecessor",
"defaultDuration",
"createdAt",
"createdBy",
"updatedAt",
"updatedBy"
) VALUES (
'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
'b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e',
'a93544bc-c165-4af4-b55e-18f3593b457a',
NULL,
432000,
'2025-03-10T13:08:02.378Z',
'topcoder user',
'2025-03-10T13:08:02.378Z',
'topcoder user'
)
ON CONFLICT DO NOTHING;

-- Submission phase (predecessor: Registration)
INSERT INTO "TimelineTemplatePhase" (
"id",
"timelineTemplateId",
"phaseId",
"predecessor",
"defaultDuration",
"createdAt",
"createdBy",
"updatedAt",
"updatedBy"
) VALUES (
'b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e',
'b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e',
'6950164f-3c5e-4bdc-abc8-22aaf5a1bd49',
'a93544bc-c165-4af4-b55e-18f3593b457a',
432000,
'2025-03-10T13:08:02.378Z',
'topcoder user',
'2025-03-10T13:08:02.378Z',
'topcoder user'
)
ON CONFLICT DO NOTHING;

-- AI Review phase (predecessor: Submission)
INSERT INTO "TimelineTemplatePhase" (
"id",
"timelineTemplateId",
"phaseId",
"predecessor",
"defaultDuration",
"createdAt",
"createdBy",
"updatedAt",
"updatedBy"
) VALUES (
'c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f',
'b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e',
'c3a4d5e6-f7b8-4c9d-a0e1-2b3c4d5e6f7a',
'6950164f-3c5e-4bdc-abc8-22aaf5a1bd49',
86400,
'2025-03-10T13:08:02.378Z',
'topcoder user',
'2025-03-10T13:08:02.378Z',
'topcoder user'
)
ON CONFLICT DO NOTHING;
7 changes: 7 additions & 0 deletions src/common/challenge-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,13 @@ class ChallengeHelper {
return;
}

// If the challenge already has an AI Review phase (AI-only template), do not add AI Screening
const hasAIReviewPhase = challenge.phases.some((phase) => phase.name === "AI Review");
if (hasAIReviewPhase) {
logDebugMessage("challenge has an AI Review phase; skipping AI Screening insertion");
return;
}

// Find the regular submission phase
const submissionPhaseName = SUBMISSION_PHASE_PRIORITY.find((name) =>
challenge.phases.some((phase) => phase.name === name)
Expand Down
11 changes: 11 additions & 0 deletions src/scripts/seed/Phase.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,16 @@
"createdBy": "topcoder user",
"updatedAt": "2025-03-10T13:08:02.378Z",
"updatedBy": "topcoder user"
},
{
"id": "c3a4d5e6-f7b8-4c9d-a0e1-2b3c4d5e6f7a",
"name": "AI Review",
"description": "AI Review Phase",
"isOpen": true,
"duration": 86400,
"createdAt": "2025-03-10T13:08:02.378Z",
"createdBy": "topcoder user",
"updatedAt": "2025-03-10T13:08:02.378Z",
"updatedBy": "topcoder user"
}
]
29 changes: 29 additions & 0 deletions src/scripts/seed/TimelineTemplate.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,5 +407,34 @@
"createdBy": "topcoder user",
"updatedAt": "2025-03-10T13:08:02.378Z",
"updatedBy": "topcoder user"
},
{
"id": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
"name": "AI Only Challenge",
"description": "AI-Only Challenge Timeline",
"isActive": true,
"phases": [
{
"phaseId": "a93544bc-c165-4af4-b55e-18f3593b457a",
"defaultDuration": 432000,
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
},
{
"phaseId": "6950164f-3c5e-4bdc-abc8-22aaf5a1bd49",
"defaultDuration": 432000,
"predecessor": "a93544bc-c165-4af4-b55e-18f3593b457a",
"id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e"
},
{
"phaseId": "c3a4d5e6-f7b8-4c9d-a0e1-2b3c4d5e6f7a",
"defaultDuration": 86400,
"predecessor": "6950164f-3c5e-4bdc-abc8-22aaf5a1bd49",
"id": "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f"
}
],
"createdAt": "2025-03-10T13:08:02.378Z",
"createdBy": "topcoder user",
"updatedAt": "2025-03-10T13:08:02.378Z",
"updatedBy": "topcoder user"
}
]
12 changes: 12 additions & 0 deletions src/services/ChallengePhaseService.js
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,18 @@ async function ensureRequiredResourcesBeforeOpeningPhase(challenge, phaseName) {
return;
}

// For AI_ONLY review mode, no human Reviewer resources are required
if (normalizedPhaseName === "review") {
try {
const aiReviewConfig = await helper.getAIReviewConfigByChallengeId(challenge.id);
if (aiReviewConfig?.mode === "AI_ONLY") {
return;
}
} catch (_err) {
// non-fatal: proceed with standard check if AI config fetch fails
}
}

const challengeId = challenge.id;
const challengeResources = await helper.getChallengeResources(challengeId);
const requiredRoleNameLower = _.toLower(requiredRoleName);
Expand Down
Loading
Loading