Competition/Round architecture: full platform rewrite (Phases 1-9)
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s

Replace Pipeline/Stage system with Competition/Round architecture.
New schema: Competition, Round (7 types), JuryGroup, AssignmentPolicy,
ProjectRoundState, DeliberationSession, ResultLock, SubmissionWindow.
New services: round-engine, round-assignment, deliberation, result-lock,
submission-manager, competition-context, ai-prompt-guard.
Full admin/jury/applicant/mentor UI rewrite. AI prompt hardening with
structured prompts, retry logic, and injection detection. All legacy
pipeline/stage code removed. 4 new migrations + seed aligned.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 23:04:15 +01:00
parent 9ab4717f96
commit 6ca39c976b
349 changed files with 69938 additions and 28767 deletions

View File

@@ -22,28 +22,28 @@ export const dashboardRouter = router({
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
const [
activeStageCount,
totalStageCount,
activeRoundCount,
totalRoundCount,
projectCount,
newProjectsThisWeek,
totalJurors,
activeJurors,
evaluationStats,
totalAssignments,
recentStages,
recentRounds,
latestProjects,
categoryBreakdown,
oceanIssueBreakdown,
recentActivity,
pendingCOIs,
draftStages,
draftRounds,
unassignedProjects,
] = await Promise.all([
ctx.prisma.stage.count({
where: { track: { pipeline: { programId: editionId } }, status: 'STAGE_ACTIVE' },
ctx.prisma.round.count({
where: { competition: { programId: editionId }, status: 'ROUND_ACTIVE' },
}),
ctx.prisma.stage.count({
where: { track: { pipeline: { programId: editionId } } },
ctx.prisma.round.count({
where: { competition: { programId: editionId } },
}),
ctx.prisma.project.count({
where: { programId: editionId },
@@ -58,38 +58,38 @@ export const dashboardRouter = router({
where: {
role: 'JURY_MEMBER',
status: { in: ['ACTIVE', 'INVITED', 'NONE'] },
assignments: { some: { stage: { track: { pipeline: { programId: editionId } } } } },
assignments: { some: { round: { competition: { programId: editionId } } } },
},
}),
ctx.prisma.user.count({
where: {
role: 'JURY_MEMBER',
status: 'ACTIVE',
assignments: { some: { stage: { track: { pipeline: { programId: editionId } } } } },
assignments: { some: { round: { competition: { programId: editionId } } } },
},
}),
ctx.prisma.evaluation.groupBy({
by: ['status'],
where: { assignment: { stage: { track: { pipeline: { programId: editionId } } } } },
where: { assignment: { round: { competition: { programId: editionId } } } },
_count: true,
}),
ctx.prisma.assignment.count({
where: { stage: { track: { pipeline: { programId: editionId } } } },
where: { round: { competition: { programId: editionId } } },
}),
ctx.prisma.stage.findMany({
where: { track: { pipeline: { programId: editionId } } },
ctx.prisma.round.findMany({
where: { competition: { programId: editionId } },
orderBy: { createdAt: 'desc' },
take: 5,
select: {
id: true,
name: true,
status: true,
stageType: true,
roundType: true,
windowOpenAt: true,
windowCloseAt: true,
_count: {
select: {
projectStageStates: true,
projectRoundStates: true,
assignments: true,
},
},
@@ -145,18 +145,18 @@ export const dashboardRouter = router({
where: {
hasConflict: true,
reviewedAt: null,
assignment: { stage: { track: { pipeline: { programId: editionId } } } },
assignment: { round: { competition: { programId: editionId } } },
},
}),
ctx.prisma.stage.count({
where: { track: { pipeline: { programId: editionId } }, status: 'STAGE_DRAFT' },
ctx.prisma.round.count({
where: { competition: { programId: editionId }, status: 'ROUND_DRAFT' },
}),
ctx.prisma.project.count({
where: {
programId: editionId,
projectStageStates: {
projectRoundStates: {
some: {
stage: { status: 'STAGE_ACTIVE' },
round: { status: 'ROUND_ACTIVE' },
},
},
assignments: { none: {} },
@@ -166,21 +166,21 @@ export const dashboardRouter = router({
return {
edition,
activeStageCount,
totalStageCount,
activeRoundCount,
totalRoundCount,
projectCount,
newProjectsThisWeek,
totalJurors,
activeJurors,
evaluationStats,
totalAssignments,
recentStages,
recentRounds,
latestProjects,
categoryBreakdown,
oceanIssueBreakdown,
recentActivity,
pendingCOIs,
draftStages,
draftRounds,
unassignedProjects,
}
}),