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>
157 lines
3.3 KiB
Markdown
157 lines
3.3 KiB
Markdown
# Domain Model and Contracts
|
|
|
|
## Canonical Enums
|
|
|
|
- `StageType = INTAKE | FILTER | EVALUATION | SELECTION | LIVE_FINAL | RESULTS`
|
|
- `TrackKind = MAIN | AWARD | SHOWCASE`
|
|
- `RoutingMode = PARALLEL | EXCLUSIVE | POST_MAIN`
|
|
- `StageStatus = DRAFT | ACTIVE | CLOSED | ARCHIVED`
|
|
- `ProjectStageStateValue = PENDING | IN_PROGRESS | PASSED | REJECTED | ROUTED | COMPLETED | WITHDRAWN`
|
|
- `DecisionMode = JURY_VOTE | AWARD_MASTER | ADMIN`
|
|
- `OverrideReasonCode = DATA_CORRECTION | POLICY_EXCEPTION | JURY_CONFLICT | SPONSOR_DECISION | ADMIN_DISCRETION`
|
|
|
|
## Core Entities
|
|
|
|
### Pipeline
|
|
|
|
- `id`
|
|
- `programId`
|
|
- `name`
|
|
- `slug`
|
|
- `status`
|
|
- `settingsJson`
|
|
- `createdAt`, `updatedAt`
|
|
|
|
### Track
|
|
|
|
- `id`
|
|
- `pipelineId`
|
|
- `kind`
|
|
- `specialAwardId?`
|
|
- `name`
|
|
- `slug`
|
|
- `sortOrder`
|
|
- `routingModeDefault?`
|
|
- `decisionMode?`
|
|
|
|
### Stage
|
|
|
|
- `id`
|
|
- `trackId`
|
|
- `stageType`
|
|
- `name`
|
|
- `slug`
|
|
- `sortOrder`
|
|
- `status`
|
|
- `configVersion`
|
|
- `configJson`
|
|
- `windowOpenAt?`, `windowCloseAt?`
|
|
|
|
### StageTransition
|
|
|
|
- `id`
|
|
- `fromStageId`
|
|
- `toStageId`
|
|
- `priority`
|
|
- `isDefault`
|
|
- `guardJson`
|
|
- `actionJson`
|
|
|
|
### ProjectStageState
|
|
|
|
- `id`
|
|
- `projectId`
|
|
- `trackId`
|
|
- `stageId`
|
|
- `state`
|
|
- `enteredAt`, `exitedAt`
|
|
- `decisionRef?`
|
|
- `outcomeJson`
|
|
|
|
### RoutingRule
|
|
|
|
- `id`
|
|
- `pipelineId`
|
|
- `scope` (`GLOBAL|TRACK|STAGE`)
|
|
- `predicateJson`
|
|
- `destinationTrackId`
|
|
- `destinationStageId?`
|
|
- `priority`
|
|
- `isActive`
|
|
|
|
### Cohort and Live Runtime
|
|
|
|
- `Cohort(id, stageId, name, votingMode, isOpen, windowOpenAt?, windowCloseAt?)`
|
|
- `CohortProject(cohortId, projectId, sortOrder)`
|
|
- `LiveProgressCursor(id, stageId, sessionId, activeProjectId?, activeOrderIndex?, updatedBy, updatedAt)`
|
|
|
|
### Governance Entities
|
|
|
|
- `OverrideAction(id, entityType, entityId, oldValueJson, newValueJson, reasonCode, reasonText, actedBy, actedAt)`
|
|
- `DecisionAuditLog(id, entityType, entityId, eventType, payloadJson, actorId?, createdAt)`
|
|
|
|
## Stage Config Union Contracts
|
|
|
|
### IntakeConfig
|
|
|
|
- file requirements
|
|
- accepted MIME and size constraints
|
|
- deadline and late policy
|
|
- team invite policy
|
|
|
|
### FilterConfig
|
|
|
|
- deterministic gates
|
|
- AI rubric
|
|
- confidence thresholds
|
|
- manual queue policy
|
|
- rejection notification policy
|
|
|
|
### EvaluationConfig
|
|
|
|
- criteria schema
|
|
- assignment strategy
|
|
- review thresholds
|
|
- COI policy
|
|
- visibility rules
|
|
|
|
### SelectionConfig
|
|
|
|
- ranking source
|
|
- finalist target
|
|
- override permissions
|
|
- promotion mode (`auto_top_n`, `hybrid`, `manual`)
|
|
|
|
### LiveFinalConfig
|
|
|
|
- session behavior
|
|
- jury voting config
|
|
- audience voting config
|
|
- cohort policy
|
|
- reveal policy
|
|
- schedule hints (advisory)
|
|
|
|
### ResultsConfig
|
|
|
|
- ranking weight rules
|
|
- publication policy
|
|
- winner override rules
|
|
|
|
## Constraint Rules
|
|
|
|
1. Stage ordering unique per track (`trackId + sortOrder`).
|
|
2. `ProjectStageState` unique on (`projectId`, `trackId`, `stageId`).
|
|
3. `StageTransition` unique on (`fromStageId`, `toStageId`).
|
|
4. Transition destination must remain in same pipeline unless explicit routing rule applies.
|
|
5. Override records immutable after insert.
|
|
6. Decision audit log append-only.
|
|
|
|
## Index Priorities
|
|
|
|
1. `ProjectStageState(projectId, trackId, state)`
|
|
2. `ProjectStageState(stageId, state)`
|
|
3. `RoutingRule(pipelineId, isActive, priority)`
|
|
4. `StageTransition(fromStageId, priority)`
|
|
5. `LiveProgressCursor(stageId, sessionId)`
|
|
6. `DecisionAuditLog(entityType, entityId, createdAt)`
|