Competition/Round architecture: full platform rewrite (Phases 1-9)
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
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:
@@ -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,
|
||||
}
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user