248 lines
13 KiB
Markdown
248 lines
13 KiB
Markdown
# 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](./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](./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**:
|
||
- `CompetitionContextResolver` service: 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 `JuryGroupMember` record when judge is invited to a jury
|
||
- `AssignmentIntent` records can be created during invite (pre-assignment)
|
||
- Onboarding page shows cap/ratio preferences when `allowOnboardingSelfService` is 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 `pipeline` references renamed to `competition` in routers, services, types, UI
|
||
- All `stage` references renamed to `round`
|
||
- All `track` references 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](./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](./11-testing-and-qa.md)). |
|
||
| Live finals concurrency | Load testing in Phase 6. See [12-observability-and-release-gates.md](./12-observability-and-release-gates.md). |
|
||
| Late requirement changes | "No Silent Contract Drift" policy enforced after Phase 0. |
|