13 KiB
Implementation Roadmap
Overview
The redesign is implemented in 9 phases, progressing from contract definition through schema migration, feature implementation, and legacy decommission. Each phase has defined scope, dependencies, and rollback points.
Phase Summary
| Phase | Scope | Duration | Dependencies |
|---|---|---|---|
| 0 | Contract Freeze — type definitions, Zod schemas, feature flags, test factories | 1 week | None |
| 1 | Schema & Runtime Foundation — Prisma migration, Competition/Round/JuryGroup CRUD | 2 weeks | Phase 0 |
| 2 | Policy Engine — centralized context resolver, policy resolution, assignment policy evaluator | 1 week | Phase 1 |
| 3 | Invite/Onboarding Integration — jury memberships on invite, assignment intent, onboarding routing | 1–2 weeks | Phase 1 |
| 4 | Backend Orchestration — enhanced assignment, submission round manager, mentor workspace, deliberation service | 2 weeks | Phase 2, 3 |
| 5 | Admin Control Plane + Participant UX — competition wizard, round management, jury/applicant/mentor dashboards | 2 weeks | Phase 4 |
| 6 | Special Awards + Live Finals + Deliberation — award modes, stage manager, deliberation voting UI | 2 weeks | Phase 4, 5 |
| 7 | Platform-Wide Refit — remove Pipeline/Track/Stage references, drop old tables | 2 weeks | Phase 5, 6 |
| 8 | Cutover & Legacy Decommission — enable new contracts, deprecate legacy, burn-in period | 1 week | Phase 7 |
Total estimated duration: 14–15 weeks
Dependency Graph
Phase 0 ──→ Phase 1 ──→ Phase 2 ──→ Phase 4 ──→ Phase 5 ──→ Phase 7 ──→ Phase 8
└──→ Phase 3 ──┘ └──→ Phase 6 ──┘
- Phases 2 and 3 can run in parallel after Phase 1
- Phase 4 requires both Phase 2 and 3
- Phases 5 and 6 can partially overlap
- Phase 7 requires both Phase 5 and 6
Critical path: 0 → 1 → 2 → 4 → 5 → 7 → 8 (12 weeks minimum)
Phase Details
Phase 0: Contract Freeze (1 week)
Goal: Lock down all type definitions, schemas, and interfaces before any implementation begins.
Deliverables:
- All Prisma model definitions finalized (see 02-data-model.md)
- All 7 Zod config schemas finalized (IntakeConfig through DeliberationConfig)
- All new enum definitions finalized
- Feature flag infrastructure in place
- Test factory functions for all new models
- TypeScript type exports for all new models
Rollback: No production changes. Delete type files if needed.
Gate: All type definitions reviewed and approved. No changes to schemas after this phase without architecture sign-off (see "No Silent Contract Drift" in 13-open-questions-and-governance.md).
Phase 1: Schema & Runtime Foundation (2 weeks)
Goal: New database tables exist alongside old ones. Basic CRUD operations work.
Deliverables:
- Prisma migration: add Competition, Round, JuryGroup, JuryGroupMember, SubmissionWindow, SubmissionFileRequirement, DeliberationSession, DeliberationVote, DeliberationResult, DeliberationParticipant, ResultLock, ResultUnlockEvent, MentorMessage, AssignmentIntent, AssignmentException, SubmissionPromotionEvent tables
- New enums: RoundType, RoundStatus, CompetitionStatus, CapMode, DeadlinePolicy, DeliberationMode, DeliberationStatus, TieBreakMethod, etc.
- Basic tRPC routers:
competition.create,competition.getById,round.create,juryGroup.create,juryGroup.addMember - Admin can create a Competition with Rounds through the API (no UI yet)
Rollback: Drop new tables. No old tables modified.
Gate: All new tables exist with correct schemas. CRUD operations pass integration tests.
Phase 2: Policy Engine (1 week)
Goal: Centralized resolution of competition context and assignment policies.
Deliverables:
CompetitionContextResolverservice: given a roundId, returns the full competition context (competition, round type, config, jury group, submission windows, etc.)- Policy resolution function: 5-layer precedence chain for assignment caps, ratios, and modes
- Assignment policy evaluator:
canAssignMore(member),getEffectiveCap(member),getRemainingCapacity(member) - Unit tests for all policy combinations
Rollback: Remove new services. No data changes.
Gate: Policy resolution returns correct values for all 5 layers. Edge cases (null overrides, conflicting settings) handled correctly.
Phase 3: Invite/Onboarding Integration (1–2 weeks)
Goal: Jury memberships are created at invite time. Judges can self-service during onboarding.
Deliverables:
- Invite flow creates
JuryGroupMemberrecord when judge is invited to a jury AssignmentIntentrecords can be created during invite (pre-assignment)- Onboarding page shows cap/ratio preferences when
allowOnboardingSelfServiceis true - Judge can adjust cap and category bias during onboarding
- Admin can review and override self-service values
Rollback: Revert invite flow changes. JuryGroupMember records can be deleted.
Gate: End-to-end flow: invite judge → judge accepts → onboarding shows jury details → judge adjusts preferences → admin sees updated values.
Phase 4: Backend Orchestration (2 weeks)
Goal: All backend services for the 8-round flow are operational.
Deliverables:
- RoundEngine service: state machine for round transitions (replaces StageEngine)
- Enhanced Assignment service: hard/soft cap algorithm, category bias, unassigned queue, COI check
- SubmissionRoundManager: manages submission windows, file requirements, read-only enforcement
- MentorWorkspaceService: messaging, file upload, file comments, file promotion
- DeliberationService: session creation, vote submission, aggregation (Borda count / vote tally), tie-breaking, result lock
- AI Shortlist service: generates ranked recommendations at end of evaluation rounds
- ResultLockService: lock/unlock with audit trail
Rollback: Remove new services. Feature flags prevent activation.
Gate: All services pass unit tests. Integration test covers full R1→R8 flow with test data.
Phase 5: Admin Control Plane + Participant UX (2 weeks)
Goal: Admin can configure and run a competition through the UI. Participants see the correct experience.
Deliverables:
- Competition Wizard: create competition with rounds, configure each round type
- Round Management: view/edit round configs, manage submission windows, set deadlines
- Juries Management (NEW section): create JuryGroups, add/remove members, configure caps/ratios, view assignments
- Assignment Dashboard: view assignments, manage unassigned queue, manual override
- Jury Dashboard: countdown, assigned projects, multi-round doc viewing, scoring/feedback
- Applicant Portal: multi-round doc upload, read-only enforcement, submission status
- Mentor Dashboard: assigned teams, messaging, file management, promotion
Rollback: Revert UI pages. Backend services still work via API.
Gate: Admin can create, configure, and manage a full competition through the UI. Jury, applicant, and mentor dashboards functional.
Phase 6: Special Awards + Live Finals + Deliberation (2 weeks)
Goal: The most complex runtime features are operational.
Deliverables:
- Special Awards: create awards with routing modes, eligibility filtering, per-award jury, doc requirements, review windows, single-judge mode
- Live Finals Stage Manager: admin controls for ceremony flow, project cursor, voting windows
- Jury 3 Live Interface: real-time notes, all docs from prior rounds, prior jury data (if enabled), live scoring
- Audience Voting: optional per-category audience vote, reveal timing configuration
- Deliberation UI: session management, juror voting interface (both modes), result display, tie-breaking, admin lock
- Result Lock: admin locks results, unlock requires super-admin with reason
Rollback: Feature flags disable awards, live finals, and deliberation. Fall back to basic flow.
Gate: Full live finals ceremony simulation. Deliberation voting in both modes. Result lock and unlock. Award creation and selection.
Phase 7: Platform-Wide Refit (2 weeks)
Goal: Remove all references to Pipeline, Track, and Stage from the codebase. Estimated 120+ files, ~350 hours of work.
Sub-phases (ordered by dependency):
| Sub-Phase | Scope | Files | Est. Hours |
|---|---|---|---|
| 7a | Database: rename FKs (stageId→roundId) in AudienceVote, COIDeclaration, ProjectStatusHistory, DigestLog, PartnerAccess | 1 (schema) + migration | 8 |
| 7b | Types & libraries: rewrite pipeline-wizard.ts, wizard-config.ts, pipeline-defaults.ts, pipeline-validation.ts, stage-config-schema.ts | 6 | 32 |
| 7c | Core routers: rename pipeline.ts→competition.ts, stage.ts→round.ts, track.ts→(delete), stageAssignment.ts→roundAssignment.ts | 4 | 24 |
| 7d | Dependent routers: update all 20 routers with stageId/pipelineId references (evaluation, file, live, invite, notification, etc.) | 20 | 80 |
| 7e | Services: rename stage-engine→round-engine, stage-filtering→round-filtering, stage-assignment→round-assignment, stage-notifications→round-notifications, live-control (update refs) | 11 | 50 |
| 7f | Admin pages: rename 35+ pages referencing pipeline/stage, update breadcrumbs, wizard, config editors | 35+ | 52 |
| 7g | Jury pages: update 16 jury pages + components (stage routes→round routes, assignment queries, evaluation forms) | 16 | 18 |
| 7h | Applicant pages: update 8 pages (pipeline visualization→competition progress, stage documents→round documents) | 8 | 12 |
| 7i | Infrastructure: update Docker entrypoint, cron jobs, webhook event names, notification templates, seed data | 4 | 11 |
| 7j | Tests: update 13+ test files + helpers.ts, rename factories, update all assertions | 13+ | 45 |
Week 1: Sub-phases 7a–7e (database, types, routers, services — backend foundation) Week 2: Sub-phases 7f–7j (UI pages, infrastructure, tests — frontend + verification)
Deliverables:
- All
pipelinereferences renamed tocompetitionin routers, services, types, UI - All
stagereferences renamed toround - All
trackreferences removed - All imports, type aliases, and variable names updated
- Old database tables dropped (Pipeline, Track, Stage, ProjectStageState)
- Seed data updated to use new models
- All background jobs and webhook events using new names
Rollback: This is the point of no return for the old schema. Rollback requires restoring from backup.
Gate: grep -r "pipeline\|Pipeline\|stage\|Stage\|track\|Track" src/ returns zero results (excluding legitimate uses like "stage manager" in live finals). All tests pass. Build succeeds.
Phase 8: Cutover & Legacy Decommission (1 week)
Goal: Production system running entirely on the new architecture.
Deliverables:
- Feature flags set to new system for all subsystems
- Legacy API endpoints deprecated (return 410 Gone with migration guide)
- Burn-in period: monitor for errors, performance regressions
- Documentation updated (CLAUDE.md, README, API docs)
- Seed data updated
- Docker entrypoint updated for new migration flow
Rollback: Feature flags can revert to legacy for individual subsystems (only if old tables still exist, i.e., Phase 7 wasn't completed).
Gate: 72-hour burn-in with zero critical errors. All release gates A–F passed (see 12-observability-and-release-gates.md).
Rollback Strategy
| Phase | Rollback Method | Data Loss Risk |
|---|---|---|
| 0 | Delete type files | None |
| 1 | Drop new tables | None (old tables untouched) |
| 2 | Remove services | None |
| 3 | Revert invite flow | JuryGroupMember records deleted |
| 4 | Feature flag off | None |
| 5 | Revert UI pages | None |
| 6 | Feature flag off | None |
| 7 | Point of no return — restore from backup | Requires backup |
| 8 | Feature flags to legacy | Only if Phase 7 not completed |
Risk Mitigation
| Risk | Mitigation |
|---|---|
| Schema migration breaks existing data | Phase 1 adds tables alongside old ones. No modifications to existing tables until Phase 7. |
| Assignment algorithm incorrect | Extensive unit tests in Phase 2. Manual override always available. |
| Deliberation edge cases | Phase 6 includes deliberation test matrix (see 11-testing-and-qa.md). |
| Live finals concurrency | Load testing in Phase 6. See 12-observability-and-release-gates.md. |
| Late requirement changes | "No Silent Contract Drift" policy enforced after Phase 0. |