Files
MOPC-Portal/docs/round-redesign-architecture-docs/mixed-round-design-implementation-docs/shared/domain-model.md
Matt 331b67dae0 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>
2026-02-13 13:57:09 +01:00

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)`