Round system redesign: Phases 1-7 complete
Full pipeline/track/stage architecture replacing the legacy round system. Schema: 11 new models (Pipeline, Track, Stage, StageTransition, ProjectStageState, RoutingRule, Cohort, CohortProject, LiveProgressCursor, OverrideAction, AudienceVoter) + 8 new enums. Backend: 9 new routers (pipeline, stage, routing, stageFiltering, stageAssignment, cohort, live, decision, award) + 6 new services (stage-engine, routing-engine, stage-filtering, stage-assignment, stage-notifications, live-control). Frontend: Pipeline wizard (17 components), jury stage pages (7), applicant pipeline pages (3), public stage pages (2), admin pipeline pages (5), shared stage components (3), SSE route, live hook. Phase 6 refit: 23 routers/services migrated from roundId to stageId, all frontend components refitted. Deleted round.ts (985 lines), roundTemplate.ts, round-helpers.ts, round-settings.ts, round-type-settings.tsx, 10 legacy admin pages, 7 legacy jury pages, 3 legacy dialogs. Phase 7 validation: 36 tests (10 unit + 8 integration files) all passing, TypeScript 0 errors, Next.js build succeeds, 13 integrity checks, legacy symbol sweep clean, auto-seed on first Docker startup. 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 [
|
||||
activeRoundCount,
|
||||
totalRoundCount,
|
||||
activeStageCount,
|
||||
totalStageCount,
|
||||
projectCount,
|
||||
newProjectsThisWeek,
|
||||
totalJurors,
|
||||
activeJurors,
|
||||
evaluationStats,
|
||||
totalAssignments,
|
||||
recentRounds,
|
||||
recentStages,
|
||||
latestProjects,
|
||||
categoryBreakdown,
|
||||
oceanIssueBreakdown,
|
||||
recentActivity,
|
||||
pendingCOIs,
|
||||
draftRounds,
|
||||
draftStages,
|
||||
unassignedProjects,
|
||||
] = await Promise.all([
|
||||
ctx.prisma.round.count({
|
||||
where: { programId: editionId, status: 'ACTIVE' },
|
||||
ctx.prisma.stage.count({
|
||||
where: { track: { pipeline: { programId: editionId } }, status: 'STAGE_ACTIVE' },
|
||||
}),
|
||||
ctx.prisma.round.count({
|
||||
where: { programId: editionId },
|
||||
ctx.prisma.stage.count({
|
||||
where: { track: { pipeline: { 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: { round: { programId: editionId } } },
|
||||
assignments: { some: { stage: { track: { pipeline: { programId: editionId } } } } },
|
||||
},
|
||||
}),
|
||||
ctx.prisma.user.count({
|
||||
where: {
|
||||
role: 'JURY_MEMBER',
|
||||
status: 'ACTIVE',
|
||||
assignments: { some: { round: { programId: editionId } } },
|
||||
assignments: { some: { stage: { track: { pipeline: { programId: editionId } } } } },
|
||||
},
|
||||
}),
|
||||
ctx.prisma.evaluation.groupBy({
|
||||
by: ['status'],
|
||||
where: { assignment: { round: { programId: editionId } } },
|
||||
where: { assignment: { stage: { track: { pipeline: { programId: editionId } } } } },
|
||||
_count: true,
|
||||
}),
|
||||
ctx.prisma.assignment.count({
|
||||
where: { round: { programId: editionId } },
|
||||
where: { stage: { track: { pipeline: { programId: editionId } } } },
|
||||
}),
|
||||
ctx.prisma.round.findMany({
|
||||
where: { programId: editionId },
|
||||
ctx.prisma.stage.findMany({
|
||||
where: { track: { pipeline: { programId: editionId } } },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 5,
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
status: true,
|
||||
votingStartAt: true,
|
||||
votingEndAt: true,
|
||||
submissionEndDate: true,
|
||||
stageType: true,
|
||||
windowOpenAt: true,
|
||||
windowCloseAt: true,
|
||||
_count: {
|
||||
select: {
|
||||
projects: true,
|
||||
projectStageStates: true,
|
||||
assignments: true,
|
||||
},
|
||||
},
|
||||
@@ -115,7 +115,6 @@ export const dashboardRouter = router({
|
||||
createdAt: true,
|
||||
submittedAt: true,
|
||||
status: true,
|
||||
round: { select: { name: true } },
|
||||
},
|
||||
}),
|
||||
ctx.prisma.project.groupBy({
|
||||
@@ -146,16 +145,20 @@ export const dashboardRouter = router({
|
||||
where: {
|
||||
hasConflict: true,
|
||||
reviewedAt: null,
|
||||
assignment: { round: { programId: editionId } },
|
||||
assignment: { stage: { track: { pipeline: { programId: editionId } } } },
|
||||
},
|
||||
}),
|
||||
ctx.prisma.round.count({
|
||||
where: { programId: editionId, status: 'DRAFT' },
|
||||
ctx.prisma.stage.count({
|
||||
where: { track: { pipeline: { programId: editionId } }, status: 'STAGE_DRAFT' },
|
||||
}),
|
||||
ctx.prisma.project.count({
|
||||
where: {
|
||||
programId: editionId,
|
||||
round: { status: 'ACTIVE' },
|
||||
projectStageStates: {
|
||||
some: {
|
||||
stage: { status: 'STAGE_ACTIVE' },
|
||||
},
|
||||
},
|
||||
assignments: { none: {} },
|
||||
},
|
||||
}),
|
||||
@@ -163,21 +166,21 @@ export const dashboardRouter = router({
|
||||
|
||||
return {
|
||||
edition,
|
||||
activeRoundCount,
|
||||
totalRoundCount,
|
||||
activeStageCount,
|
||||
totalStageCount,
|
||||
projectCount,
|
||||
newProjectsThisWeek,
|
||||
totalJurors,
|
||||
activeJurors,
|
||||
evaluationStats,
|
||||
totalAssignments,
|
||||
recentRounds,
|
||||
recentStages,
|
||||
latestProjects,
|
||||
categoryBreakdown,
|
||||
oceanIssueBreakdown,
|
||||
recentActivity,
|
||||
pendingCOIs,
|
||||
draftRounds,
|
||||
draftStages,
|
||||
unassignedProjects,
|
||||
}
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user