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:
@@ -0,0 +1,68 @@
|
||||
# Mixed Round Design Implementation Docs
|
||||
|
||||
## Purpose
|
||||
This folder contains a single consolidated redesign program that intentionally blends:
|
||||
|
||||
- Delivery rigor and governance discipline from `codex-round-system-redesign`
|
||||
- Target architecture depth and runtime detail from `claude-round-system-redesign`
|
||||
- Award governance semantics from `glm-5-round-redesign` (especially `AWARD_MASTER` and explicit decision modes)
|
||||
|
||||
The goal is a complete, production-ready implementation plan for rebuilding round orchestration in MOPC with a full-cutover model.
|
||||
|
||||
## Foundation and Blend Strategy
|
||||
|
||||
### Foundation
|
||||
The execution backbone is the `codex` style program model:
|
||||
|
||||
1. Contract freeze first
|
||||
2. Schema/runtime implementation in explicit phases
|
||||
3. Platform-wide dependency refit (not just feature slices)
|
||||
4. Mandatory phase gates with hard release blockers
|
||||
|
||||
### Borrowed Enhancements
|
||||
The plan imports high-value details from other proposals:
|
||||
|
||||
- `claude`: richer canonical model (`Pipeline -> Track -> Stage`), explicit transition engine, routing and live-control runtime detail
|
||||
- `glm-5`: award decision governance (`JURY_VOTE`, `AWARD_MASTER`, `ADMIN`) and explicit award track behavior options
|
||||
|
||||
## Execution Model
|
||||
|
||||
- Single destructive cutover
|
||||
- Full reseed
|
||||
- No backward-compatibility adapter layer
|
||||
- No dual-write period
|
||||
- One atomic release commit once all gates are green
|
||||
|
||||
This model is intentionally selected because infrastructure reset/rebuild is allowed and preferred for architecture quality.
|
||||
|
||||
## Architecture Summary
|
||||
|
||||
- Competition lifecycle is stage-native, not round-pointer native.
|
||||
- Projects progress through explicit `ProjectStageState` records.
|
||||
- Special awards are first-class tracks, not bolt-on side tables.
|
||||
- Routing is rule-driven with explainability payloads.
|
||||
- Live finals are controlled by an admin cursor as the source of truth.
|
||||
- Every override and decision is reasoned, immutable, and auditable.
|
||||
|
||||
## Folder Layout
|
||||
|
||||
- `master-implementation-plan.md`: end-to-end execution map
|
||||
- `shared/`: cross-phase contracts, governance, test model, risks
|
||||
- `phase-00-contract-freeze/` to `phase-07-validation-release/`: implementation phases
|
||||
- `flowcharts/`: core control and routing diagrams
|
||||
|
||||
## How to Use This Plan
|
||||
|
||||
1. Start at `master-implementation-plan.md`.
|
||||
2. Execute phases in order.
|
||||
3. Do not start a phase unless all prior acceptance gates are complete.
|
||||
4. Attach objective evidence for every gate.
|
||||
5. Treat `phase-06-platform-dependency-refit` as mandatory release work, not cleanup.
|
||||
|
||||
## Non-Negotiable Rules
|
||||
|
||||
1. No hidden edit-only required settings.
|
||||
2. Deterministic routing and ranking tie-break behavior.
|
||||
3. Assignment coverage guarantees for eligible projects.
|
||||
4. Explicit voting window control (schedules are advisory only).
|
||||
5. No legacy orchestration contract references at release.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Dependency Refit Map
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Schema Contracts] --> B[Router Refit]
|
||||
A --> C[Service Refit]
|
||||
B --> D[Admin UI Refit]
|
||||
B --> E[Jury/Applicant/Public Refit]
|
||||
C --> E
|
||||
D --> F[Reporting/Exports]
|
||||
E --> F
|
||||
F --> G[Integration Consumer Validation]
|
||||
G --> H[Legacy Symbol Sweep]
|
||||
H --> I[Release Ready]
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
# End-to-End Pipeline Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Intake Stage] --> B[Filter Stage]
|
||||
B -->|pass| C[Main Evaluation Stage]
|
||||
B -->|reject| R[Rejected with Notification]
|
||||
B -->|award rule: parallel| W1[Award Track Entry]
|
||||
B -->|award rule: exclusive| W2[Award Track Entry + Main Routed Out]
|
||||
|
||||
C --> D[Selection Stage]
|
||||
D --> E[Live Final Stage]
|
||||
E --> F[Results Stage]
|
||||
|
||||
W1 --> W3[Award Evaluation]
|
||||
W2 --> W3[Award Evaluation]
|
||||
W3 --> W4[Award Winner Decision]
|
||||
|
||||
D -->|manual override| O[Override Action + Audit]
|
||||
O --> D
|
||||
|
||||
E --> L[Live Cursor + Cohort Windows]
|
||||
L --> V[Jury and Audience Voting]
|
||||
V --> F
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
# Live Stage Controller
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Admin Live Panel] --> B[Set Active Project Cursor]
|
||||
B --> C[Persist Cursor Versioned Update]
|
||||
C --> D[Broadcast Realtime Event]
|
||||
D --> E[Jury Clients Sync]
|
||||
D --> F[Audience Clients Sync]
|
||||
|
||||
A --> G[Open Cohort Window]
|
||||
A --> H[Close Cohort Window]
|
||||
G --> I[Vote Acceptance On]
|
||||
H --> J[Vote Acceptance Off]
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
# Main vs Award Routing
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
P[Project in Filter Stage] --> Q{Routing Rule Match?}
|
||||
Q -->|No| M[Remain in Main Track]
|
||||
Q -->|Yes| Z{Routing Mode}
|
||||
|
||||
Z -->|PARALLEL| A[Create Award Stage State]
|
||||
A --> B[Keep Main State Active]
|
||||
|
||||
Z -->|EXCLUSIVE| C[Create Award Stage State]
|
||||
C --> D[Mark Main State Routed]
|
||||
|
||||
Z -->|POST_MAIN| E[Defer Route Until Gate Stage]
|
||||
E --> F[Route After Main Gate Condition]
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
# Override Audit Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Override Request] --> B{Authz + Scope Check}
|
||||
B -->|fail| X[FORBIDDEN]
|
||||
B -->|pass| C{Reason Fields Present?}
|
||||
C -->|no| Y[BAD_REQUEST]
|
||||
C -->|yes| D[Fetch Current Value Snapshot]
|
||||
D --> E[Apply Override Mutation]
|
||||
E --> F[Persist Immutable OverrideAction]
|
||||
F --> G[Append DecisionAuditLog]
|
||||
G --> H[Return Updated Entity + Audit Ref]
|
||||
```
|
||||
@@ -0,0 +1,95 @@
|
||||
# Master Implementation Plan
|
||||
|
||||
## Program Objective
|
||||
Rebuild MOPC round orchestration from a round-centric model into a stage-native pipeline model that is easier to configure, more deterministic, and robust for main competition plus special awards and live finals.
|
||||
|
||||
## Program Constraints
|
||||
|
||||
- Preserve existing visual language and core UI component style.
|
||||
- Complete architecture rebuild is allowed and encouraged.
|
||||
- Delivery must be production-safe and verifiable.
|
||||
- Release requires one atomic cutover commit after full validation.
|
||||
|
||||
## Hard Invariants
|
||||
|
||||
1. Every state transition is explicit, validated, and auditable.
|
||||
2. Every override action captures `reasonCode` + `reasonText` + actor metadata.
|
||||
3. No eligible project is left unassigned unless explicitly flagged as overflow with admin visibility.
|
||||
4. Live active project state is admin-cursor driven.
|
||||
5. Award routing behavior is explicit per award (`parallel`, `exclusive`, `post_main`).
|
||||
6. Event contracts are deterministic and machine-readable.
|
||||
7. At release, no runtime dependency on legacy `roundId` orchestration semantics remains.
|
||||
|
||||
## Phase Chain
|
||||
|
||||
1. Phase 00: Contract freeze
|
||||
2. Phase 01: Schema and runtime foundation
|
||||
3. Phase 02: Backend orchestration engine
|
||||
4. Phase 03: Admin control-plane UX
|
||||
5. Phase 04: Participant journeys
|
||||
6. Phase 05: Special awards governance
|
||||
7. Phase 06: Platform dependency refit
|
||||
8. Phase 07: Validation and release
|
||||
|
||||
## Required Deliverables by Phase
|
||||
|
||||
- Phase 00: locked contracts, decision log, authz matrix, initial risk register
|
||||
- Phase 01: canonical schema spec, migration/cutover scripts, reseed spec, integrity checks
|
||||
- Phase 02: transition/routing/filtering/assignment/live runtime implementation specs
|
||||
- Phase 03: wizard IA, advanced editor spec, form behavior and safety guardrails
|
||||
- Phase 04: applicant/jury/audience runtime and UX contracts
|
||||
- Phase 05: award governance modes and decision workflow implementation
|
||||
- Phase 06: module-by-module refit completion + legacy symbol sweeps
|
||||
- Phase 07: full test evidence, performance evidence, release runbook and sign-off
|
||||
|
||||
## Entry and Exit Criteria (Program Level)
|
||||
|
||||
### Entry
|
||||
|
||||
- Shared contracts and decisions are locked.
|
||||
- Team alignment on cutover model and no-compatibility policy.
|
||||
|
||||
### Exit
|
||||
|
||||
- All phase acceptance gates complete.
|
||||
- Test matrix green for U/I/E/P suites.
|
||||
- Performance and resilience evidence approved.
|
||||
- Legacy symbol sweeps are empty.
|
||||
- Release evidence report signed by Engineering + Product + Operations.
|
||||
|
||||
## Release Blockers
|
||||
|
||||
1. Any failing acceptance gate.
|
||||
2. Any unresolved CRITICAL or HIGH risk without approved mitigation.
|
||||
3. Any missing test evidence for mandatory scenario IDs.
|
||||
4. Any legacy orchestration symbol found in runtime code paths.
|
||||
|
||||
## Timeline Model
|
||||
|
||||
- Phase 00: 2-3 days
|
||||
- Phase 01: 1-1.5 weeks
|
||||
- Phase 02: 1.5-2.5 weeks
|
||||
- Phase 03: 1-1.5 weeks
|
||||
- Phase 04: 1-1.5 weeks
|
||||
- Phase 05: 0.75-1.25 weeks
|
||||
- Phase 06: 1-1.5 weeks
|
||||
- Phase 07: 1 week
|
||||
|
||||
Total estimate: 8-11 weeks depending on test depth and refit complexity.
|
||||
|
||||
## Evidence Standards
|
||||
|
||||
Every acceptance gate requires at least one of:
|
||||
|
||||
- Unit/integration/E2E output
|
||||
- API response captures
|
||||
- deterministic symbol sweeps
|
||||
- migration integrity query output
|
||||
- performance benchmark output
|
||||
- release runbook logs
|
||||
|
||||
## Enforcement Notes
|
||||
|
||||
- No phase skipping.
|
||||
- No deferred blocker carry-forward.
|
||||
- No "ship and patch later" for contract-level gaps.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Phase 00 Acceptance Gates
|
||||
|
||||
- [ ] G-00-1 Decision log locked (`shared/decision-log.md` signed by Eng + Product)
|
||||
- [ ] G-00-2 Domain and API contracts approved
|
||||
- [ ] G-00-3 Authz matrix approved
|
||||
- [ ] G-00-4 Test matrix approved and mapped to owners
|
||||
- [ ] G-00-5 Risk register initialized with owners and mitigation targets
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- contract review notes
|
||||
- sign-off comments or approval records
|
||||
- updated risk register with owners
|
||||
@@ -0,0 +1,35 @@
|
||||
# Phase 00 Overview: Contract Freeze
|
||||
|
||||
## Objective
|
||||
Lock all cross-phase contracts before implementation so the program executes with stable boundaries and no semantic drift.
|
||||
|
||||
## In Scope
|
||||
|
||||
- decision locking
|
||||
- API/type contract baseline
|
||||
- authorization baseline
|
||||
- gate and evidence baseline
|
||||
- initial risk baseline
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- schema implementation
|
||||
- runtime implementation
|
||||
- UI implementation
|
||||
|
||||
## Inputs
|
||||
|
||||
- `shared/program-charter.md`
|
||||
- `shared/decision-log.md`
|
||||
- `shared/domain-model.md`
|
||||
- `shared/api-contracts.md`
|
||||
- `shared/authz-matrix.md`
|
||||
- `shared/test-matrix.md`
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. Decision log marked locked with no unresolved critical decision.
|
||||
2. API/type contracts accepted by backend and frontend owners.
|
||||
3. Authz matrix accepted by security owner.
|
||||
4. Risk register initialized with owners.
|
||||
5. Phase 00 acceptance gates complete with evidence.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Phase 00 Tasks
|
||||
|
||||
## Task Set A: Contract Alignment
|
||||
|
||||
- [ ] Validate `shared/domain-model.md` against current repository constraints.
|
||||
- [ ] Validate `shared/api-contracts.md` names and payload conventions with router ownership.
|
||||
- [ ] Validate event naming strategy with notification and webhook owners.
|
||||
|
||||
## Task Set B: Governance Lock
|
||||
|
||||
- [ ] Confirm `shared/decision-log.md` with Product + Engineering.
|
||||
- [ ] Confirm cutover/no-compatibility policy in writing.
|
||||
- [ ] Confirm override governance requirements and mandatory reason fields.
|
||||
|
||||
## Task Set C: Access and Security
|
||||
|
||||
- [ ] Validate `shared/authz-matrix.md` for each role.
|
||||
- [ ] Define scope enforcement standard for program-scoped admin actions.
|
||||
- [ ] Confirm audience vote abuse controls (token, rate-limit, dedupe key).
|
||||
|
||||
## Task Set D: Validation Baseline
|
||||
|
||||
- [ ] Validate `shared/test-matrix.md` coverage and practicality.
|
||||
- [ ] Map each test ID to ownership.
|
||||
- [ ] Confirm CI entry strategy for U/I/E/P layers.
|
||||
|
||||
## Task Set E: Risk Baseline
|
||||
|
||||
- [ ] Review `shared/risk-register.md` with owners.
|
||||
- [ ] Add any repository-specific risks identified during contract review.
|
||||
- [ ] Mark mitigation action owner and due phase per risk.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Phase 01 Acceptance Gates
|
||||
|
||||
- [ ] G-01-1 `prisma generate` succeeds
|
||||
- [ ] G-01-2 reset/reseed succeeds in local and staging
|
||||
- [ ] G-01-3 integrity queries return expected zero-error results
|
||||
- [ ] G-01-4 required indexes confirmed in DB metadata
|
||||
- [ ] G-01-5 phase artifacts stored and linked
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- migration command output
|
||||
- reseed logs
|
||||
- integrity query result captures
|
||||
- schema diff summary
|
||||
@@ -0,0 +1,48 @@
|
||||
# Phase 01 Migration and Cutover Plan
|
||||
|
||||
## Strategy
|
||||
Perform architecture rebuild with reset/reseed as the official path.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Finalize schema migration scripts.
|
||||
2. Run local reset/reseed rehearsal.
|
||||
3. Run staging reset/reseed rehearsal.
|
||||
4. Execute integrity verification suite.
|
||||
5. Lock schema contracts and produce baseline snapshot.
|
||||
|
||||
## Verification Script Requirements
|
||||
|
||||
- count checks for canonical entities
|
||||
- FK integrity checks
|
||||
- expected stage graph checks
|
||||
- expected project intake state checks
|
||||
|
||||
## Example Verification Queries
|
||||
|
||||
```sql
|
||||
-- orphan project stage states
|
||||
SELECT COUNT(*)
|
||||
FROM "ProjectStageState" pss
|
||||
LEFT JOIN "Project" p ON p.id = pss."projectId"
|
||||
LEFT JOIN "Stage" s ON s.id = pss."stageId"
|
||||
LEFT JOIN "Track" t ON t.id = pss."trackId"
|
||||
WHERE p.id IS NULL OR s.id IS NULL OR t.id IS NULL;
|
||||
|
||||
-- project intake state coverage
|
||||
SELECT COUNT(DISTINCT p.id) AS projects_without_intake
|
||||
FROM "Project" p
|
||||
LEFT JOIN "ProjectStageState" pss
|
||||
ON pss."projectId" = p.id
|
||||
LEFT JOIN "Stage" s
|
||||
ON s.id = pss."stageId"
|
||||
WHERE s."stageType" = 'INTAKE'
|
||||
AND pss.id IS NULL;
|
||||
```
|
||||
|
||||
## Cutover Readiness Artifacts Produced in Phase 01
|
||||
|
||||
- schema migration files
|
||||
- seed scripts
|
||||
- integrity query scripts
|
||||
- reset/reseed execution logs
|
||||
@@ -0,0 +1,27 @@
|
||||
# Phase 01 Overview: Schema and Runtime Foundation
|
||||
|
||||
## Objective
|
||||
Implement the canonical schema and reset/reseed capability that supports stage-native orchestration with award and live runtime primitives.
|
||||
|
||||
## In Scope
|
||||
|
||||
- prisma schema rebuild for canonical entities
|
||||
- indexes and constraints for hot paths
|
||||
- reset/reseed strategy and scripts
|
||||
- data integrity verification scripts
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- end-user UI behavior
|
||||
- full router refit
|
||||
|
||||
## Key Design Choice
|
||||
|
||||
This phase uses full reset/reseed and does not attempt compatibility bridges.
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. Schema compiles and generates client successfully.
|
||||
2. Reset/reseed produces runnable dataset.
|
||||
3. Integrity verification passes for FK/index and state initialization rules.
|
||||
4. Phase 01 gates complete.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Phase 01 Schema Specification
|
||||
|
||||
## Summary
|
||||
Introduce the canonical orchestration entities and remove legacy dependency assumptions around single `roundId` progression.
|
||||
|
||||
## New Canonical Tables
|
||||
|
||||
1. `Pipeline`
|
||||
2. `Track`
|
||||
3. `Stage`
|
||||
4. `StageTransition`
|
||||
5. `ProjectStageState`
|
||||
6. `RoutingRule`
|
||||
7. `Cohort`
|
||||
8. `CohortProject`
|
||||
9. `LiveProgressCursor`
|
||||
10. `NotificationPolicy`
|
||||
11. `OverrideAction`
|
||||
12. `DecisionAuditLog`
|
||||
|
||||
## Award Governance Extensions
|
||||
|
||||
- Add `DecisionMode = JURY_VOTE | AWARD_MASTER | ADMIN`
|
||||
- Add award-scoped governance metadata to award track configs
|
||||
- Add award winner finalization audit event contracts
|
||||
|
||||
## Migration Model
|
||||
|
||||
- Build new schema directly as canonical target.
|
||||
- Keep migration files deterministic and replay-safe.
|
||||
- Do not implement dual-write or compatibility tables.
|
||||
|
||||
## Required Constraints
|
||||
|
||||
1. `trackId + sortOrder` unique in `Stage`
|
||||
2. `projectId + trackId + stageId` unique in `ProjectStageState`
|
||||
3. `fromStageId + toStageId` unique in `StageTransition`
|
||||
4. `cohortId + projectId` unique in `CohortProject`
|
||||
|
||||
## Required Indexes
|
||||
|
||||
- `ProjectStageState(projectId, trackId, state)`
|
||||
- `ProjectStageState(stageId, state)`
|
||||
- `RoutingRule(pipelineId, isActive, priority)`
|
||||
- `StageTransition(fromStageId, priority)`
|
||||
- `DecisionAuditLog(entityType, entityId, createdAt)`
|
||||
- `LiveProgressCursor(stageId, sessionId)`
|
||||
|
||||
## Data Initialization Rules
|
||||
|
||||
- Every seeded project must start with one intake-stage state.
|
||||
- Seed must include main track plus at least two award tracks with different routing modes.
|
||||
- Seed must include representative roles: admins, jury, applicants, observer, audience contexts.
|
||||
|
||||
## Integrity Checks
|
||||
|
||||
- No orphan states.
|
||||
- No invalid transition targets across pipelines.
|
||||
- No duplicate active state rows for same `(project, track, stage)`.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Phase 01 Tasks
|
||||
|
||||
## Schema Build
|
||||
|
||||
- [ ] Implement canonical entities and enums in `prisma/schema.prisma`.
|
||||
- [ ] Add required constraints and indexes.
|
||||
- [ ] Remove or isolate legacy-only orchestration semantics from canonical paths.
|
||||
|
||||
## Seed and Fixtures
|
||||
|
||||
- [ ] Implement reseed script with realistic data volumes and edge cases.
|
||||
- [ ] Include parallel, exclusive, and post-main award routing seed examples.
|
||||
- [ ] Include live cohort seed data.
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] Implement integrity SQL scripts.
|
||||
- [ ] Implement automated verification command wrapper.
|
||||
- [ ] Record baseline output and attach to gate evidence.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ ] Update schema change notes.
|
||||
- [ ] Document reset/reseed assumptions.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Phase 02 Acceptance Gates
|
||||
|
||||
- [ ] G-02-1 transition engine tests pass
|
||||
- [ ] G-02-2 routing determinism tests pass
|
||||
- [ ] G-02-3 filtering policy tests pass
|
||||
- [ ] G-02-4 assignment guarantee tests pass
|
||||
- [ ] G-02-5 live cursor and cohort window tests pass
|
||||
- [ ] G-02-6 override/audit tests pass
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- U/I test output for all mapped IDs
|
||||
- sample API responses for major mutation endpoints
|
||||
- audit payload examples for transition and override flows
|
||||
@@ -0,0 +1,43 @@
|
||||
# Assignment Engine Specification
|
||||
|
||||
## Objective
|
||||
Generate high-quality, fair assignments while guaranteeing eligible project coverage.
|
||||
|
||||
## Inputs
|
||||
|
||||
- stage ID
|
||||
- eligible project set
|
||||
- assignee pool
|
||||
- required reviews per project
|
||||
- assignment strategy config
|
||||
- availability and COI policies
|
||||
|
||||
## Hard Constraints
|
||||
|
||||
1. COI exclusion
|
||||
2. role/status eligibility
|
||||
3. explicit max-load cap
|
||||
4. minimum review floor
|
||||
|
||||
## Soft Scoring Dimensions
|
||||
|
||||
- expertise overlap
|
||||
- bio/project similarity
|
||||
- availability weighting
|
||||
- workload balancing
|
||||
- optional geo diversity
|
||||
- optional prior-familiarity weighting
|
||||
|
||||
## Guarantee Rules
|
||||
|
||||
1. No eligible project left uncovered.
|
||||
2. If capacity insufficient, create overflow assignments with warning markers.
|
||||
3. Preview and execution must match constraints and scoring semantics.
|
||||
|
||||
## Output Contract
|
||||
|
||||
- assigned count
|
||||
- uncovered count (must be zero unless in explicit error mode)
|
||||
- overflow assignment list
|
||||
- conflict skips list
|
||||
- fairness metrics (median load, max load)
|
||||
@@ -0,0 +1,55 @@
|
||||
# Filtering and Routing Specification
|
||||
|
||||
## Filtering Pipeline
|
||||
|
||||
1. deterministic gates
|
||||
2. AI rubric evaluation
|
||||
3. confidence band decisioning
|
||||
4. manual queue resolution
|
||||
|
||||
## Deterministic Gates First Rule
|
||||
|
||||
AI execution is prohibited unless deterministic gates pass.
|
||||
|
||||
## AI Output Contract
|
||||
|
||||
- criteria scores
|
||||
- overall recommendation
|
||||
- confidence
|
||||
- rationale
|
||||
- risk flags
|
||||
|
||||
## Confidence Bands
|
||||
|
||||
- `high`: auto decision path
|
||||
- `medium`: manual queue
|
||||
- `low`: reject or manual based on stage policy
|
||||
|
||||
## Routing Rules
|
||||
|
||||
### Evaluation Order
|
||||
|
||||
1. stage-scoped rules
|
||||
2. track-scoped rules
|
||||
3. global rules
|
||||
4. default fallback
|
||||
|
||||
### Deterministic Tie-Break
|
||||
|
||||
- highest priority wins
|
||||
- if equal, lexical rule ID fallback
|
||||
|
||||
### Explainability Persisted
|
||||
|
||||
Each route persists:
|
||||
|
||||
- matched rule ID
|
||||
- predicate snapshot
|
||||
- mode (`AUTO|MANUAL`)
|
||||
- destination track/stage
|
||||
|
||||
## Award Routing Modes
|
||||
|
||||
- `PARALLEL`: keep main progression and add award state
|
||||
- `EXCLUSIVE`: route out of main progression into award track only
|
||||
- `POST_MAIN`: route only after configured main gate stage
|
||||
@@ -0,0 +1,32 @@
|
||||
# Live Control Specification
|
||||
|
||||
## Source of Truth
|
||||
Admin cursor state is the single source of truth for active project context during live stages.
|
||||
|
||||
## Core Controls
|
||||
|
||||
- start session
|
||||
- next/previous
|
||||
- jump to project
|
||||
- reorder queue
|
||||
- open/close cohort windows
|
||||
- pause/resume session
|
||||
|
||||
## Runtime Requirements
|
||||
|
||||
1. cursor updates are versioned
|
||||
2. race conditions return `CONFLICT` and require refresh/retry
|
||||
3. real-time propagation to jury and audience clients
|
||||
4. reconnect path converges to current cursor/window state
|
||||
|
||||
## Vote Acceptance Rules
|
||||
|
||||
- stage and cohort windows must be open
|
||||
- dedupe key policy enforced (`session/cohort/project/voter/window`)
|
||||
- closed windows reject submissions deterministically
|
||||
|
||||
## Event Contract
|
||||
|
||||
- `live.cursor.updated`
|
||||
- `cohort.window.changed`
|
||||
- `live.session.state.changed`
|
||||
@@ -0,0 +1,23 @@
|
||||
# Phase 02 Overview: Backend Orchestration Engine
|
||||
|
||||
## Objective
|
||||
Implement deterministic runtime behavior for stage transitions, routing, filtering, assignment, live cursor control, and notification/audit emission.
|
||||
|
||||
## In Scope
|
||||
|
||||
- transition engine
|
||||
- routing engine
|
||||
- filtering orchestration (gates + AI + manual queue)
|
||||
- assignment orchestration with coverage guarantees
|
||||
- live cursor and cohort window controls
|
||||
- event and audit emission
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- full admin UI and participant UI implementation
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. Runtime contracts implemented and integration-tested.
|
||||
2. Determinism and idempotency guarantees proven for critical mutations.
|
||||
3. Mandatory phase gates complete with test evidence.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Stage Engine Specification
|
||||
|
||||
## Responsibilities
|
||||
|
||||
1. Validate transition legality.
|
||||
2. Move project states transactionally.
|
||||
3. Emit transition events and audit entries.
|
||||
4. Enforce concurrency safety.
|
||||
|
||||
## State Machine
|
||||
|
||||
`PENDING -> IN_PROGRESS -> PASSED|REJECTED -> ROUTED -> COMPLETED`
|
||||
|
||||
`WITHDRAWN` is terminal for participant-triggered withdrawal paths.
|
||||
|
||||
## Transition Guards
|
||||
|
||||
- source state row exists and is active
|
||||
- destination stage is active and in same pipeline (unless routing rule applies)
|
||||
- stage window and guard conditions satisfied
|
||||
- no concurrent conflicting transition
|
||||
|
||||
## Mutation Semantics
|
||||
|
||||
- transactional updates per batch slice
|
||||
- optimistic locking/version checks
|
||||
- per-project result collection for partial failure reporting
|
||||
|
||||
## Failure Codes
|
||||
|
||||
- `PRECONDITION_FAILED`: guard not satisfied
|
||||
- `CONFLICT`: state moved after read
|
||||
- `BAD_REQUEST`: invalid transition target
|
||||
|
||||
## Audit Contract
|
||||
|
||||
`eventType = stage.transitioned`
|
||||
|
||||
Payload includes:
|
||||
|
||||
- actor
|
||||
- source stage
|
||||
- destination stage
|
||||
- old/new state
|
||||
- reason/context
|
||||
- timestamp
|
||||
@@ -0,0 +1,30 @@
|
||||
# Phase 02 Tasks
|
||||
|
||||
## Transition Engine
|
||||
|
||||
- [ ] Implement transition guard and mutation logic.
|
||||
- [ ] Implement optimistic concurrency handling.
|
||||
- [ ] Implement transition event and audit emission.
|
||||
|
||||
## Filtering and Routing
|
||||
|
||||
- [ ] Implement deterministic gate-first pipeline.
|
||||
- [ ] Implement confidence band decision handling.
|
||||
- [ ] Implement routing rule engine with explainability payloads.
|
||||
|
||||
## Assignment
|
||||
|
||||
- [ ] Implement assignment preview and execute parity.
|
||||
- [ ] Implement coverage guarantee and overflow semantics.
|
||||
- [ ] Implement assignment metrics output.
|
||||
|
||||
## Live Runtime
|
||||
|
||||
- [ ] Implement admin cursor operations and conflict-safe update model.
|
||||
- [ ] Implement cohort window control.
|
||||
- [ ] Implement real-time event propagation path.
|
||||
|
||||
## Notifications and Audit
|
||||
|
||||
- [ ] Implement default event producers for stage transitions and outcomes.
|
||||
- [ ] Implement immutable audit payload structure.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Phase 03 Acceptance Gates
|
||||
|
||||
- [ ] G-03-1 wizard can complete full required setup (E-001)
|
||||
- [ ] G-03-2 no hidden edit-only required settings remain
|
||||
- [ ] G-03-3 advanced editor enforces graph/config guardrails
|
||||
- [ ] G-03-4 modal and form safety regressions pass
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- E2E wizard completion evidence
|
||||
- parity checklist artifacts
|
||||
- targeted UI regression test output
|
||||
@@ -0,0 +1,34 @@
|
||||
# Advanced Editor Specification
|
||||
|
||||
## Purpose
|
||||
Provide direct manipulation of tracks, stages, transitions, and routing without polluting the default wizard path.
|
||||
|
||||
## Panels
|
||||
|
||||
1. Track/Stage List Panel
|
||||
2. Stage Config Panel
|
||||
3. Transition Graph Panel
|
||||
4. Routing Rule Inspector
|
||||
5. Simulation Panel
|
||||
|
||||
## Required Capabilities
|
||||
|
||||
- reorder stages within track
|
||||
- move valid stages across tracks
|
||||
- create/delete transitions
|
||||
- edit rule predicates and priorities
|
||||
- simulate outcomes for sample project IDs
|
||||
|
||||
## Guardrails
|
||||
|
||||
1. Block disconnected required paths.
|
||||
2. Block orphan stage deletion.
|
||||
3. Warn before destructive transition/rule removal.
|
||||
4. Enforce schema validation for stage config payloads.
|
||||
|
||||
## Save Model
|
||||
|
||||
- draft buffer
|
||||
- validation run
|
||||
- transactional persist
|
||||
- validation report artifact
|
||||
@@ -0,0 +1,30 @@
|
||||
# Form Behavior and Validation Rules
|
||||
|
||||
## Universal Rules
|
||||
|
||||
1. Every required field has inline validation.
|
||||
2. Every select has deterministic default value.
|
||||
3. Save actions are idempotent and disabled while pending.
|
||||
4. Unsafe changes surface explicit impact warnings.
|
||||
|
||||
## Create/Edit Parity Requirements
|
||||
|
||||
- intake windows
|
||||
- upload policy
|
||||
- file requirements
|
||||
- assignment policy
|
||||
- filtering policy
|
||||
- routing policy
|
||||
- live policy
|
||||
|
||||
## Modal Safety Rules
|
||||
|
||||
1. Modal close must not mutate persisted state.
|
||||
2. Non-submit buttons must explicitly set `type="button"`.
|
||||
3. Escape/cancel should only dismiss local draft state.
|
||||
|
||||
## Payload Safety
|
||||
|
||||
- replace raw free-text config where structured selectors exist
|
||||
- normalize serialization format for config payloads
|
||||
- reject unknown keys in strict mode contracts
|
||||
@@ -0,0 +1,23 @@
|
||||
# Phase 03 Overview: Admin Control-Plane UX
|
||||
|
||||
## Objective
|
||||
Deliver a wizard-first admin control plane that exposes full required configuration in create-time flow, with a safe advanced editor for power users.
|
||||
|
||||
## In Scope
|
||||
|
||||
- setup wizard IA and behavior
|
||||
- advanced stage and routing editor
|
||||
- simulation and validation panel
|
||||
- create/edit parity
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- visual redesign
|
||||
- participant-facing workflows
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. Full required setup possible from create flow.
|
||||
2. No hidden edit-only required fields.
|
||||
3. Validation and simulation guardrails implemented.
|
||||
4. Phase gates complete.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Phase 03 Tasks
|
||||
|
||||
## Wizard
|
||||
|
||||
- [ ] Implement 8-step setup flow.
|
||||
- [ ] Implement step-level validation and progress state.
|
||||
- [ ] Implement review/publish summary and blockers.
|
||||
|
||||
## Advanced Editor
|
||||
|
||||
- [ ] Implement stage/transition/routing editing surfaces.
|
||||
- [ ] Implement simulation runner and result panel.
|
||||
- [ ] Implement destructive action confirmations.
|
||||
|
||||
## Behavior and Safety
|
||||
|
||||
- [ ] Enforce create/edit parity checklist.
|
||||
- [ ] Enforce modal safety rules.
|
||||
- [ ] Enforce strict payload validation.
|
||||
@@ -0,0 +1,78 @@
|
||||
# Admin Wizard IA
|
||||
|
||||
## Step Sequence
|
||||
|
||||
1. Intake Setup
|
||||
2. Main Track Stage Setup
|
||||
3. Filtering Strategy
|
||||
4. Assignment Strategy
|
||||
5. Special Awards
|
||||
6. Live Finals Configuration
|
||||
7. Notifications and Overrides
|
||||
8. Review + Publish
|
||||
|
||||
## Step Details
|
||||
|
||||
### 1) Intake Setup
|
||||
|
||||
- submission windows
|
||||
- late policy
|
||||
- file requirements
|
||||
- MIME/size constraints
|
||||
- applicant communication policy
|
||||
|
||||
### 2) Main Track Stage Setup
|
||||
|
||||
- stage list and ordering
|
||||
- stage type assignment
|
||||
- status defaults
|
||||
- selection stage presets
|
||||
|
||||
### 3) Filtering Strategy
|
||||
|
||||
- deterministic gate definition
|
||||
- AI rubric configuration
|
||||
- confidence thresholds
|
||||
- manual queue owners
|
||||
|
||||
### 4) Assignment Strategy
|
||||
|
||||
- required reviews
|
||||
- max/min load settings
|
||||
- availability weighting
|
||||
- overflow handling policy
|
||||
|
||||
### 5) Special Awards
|
||||
|
||||
- award track enablement
|
||||
- routing mode per award
|
||||
- decision mode per award
|
||||
- award jury restrictions
|
||||
|
||||
### 6) Live Finals
|
||||
|
||||
- cursor control mode
|
||||
- jury vote config
|
||||
- audience vote config
|
||||
- cohort setup
|
||||
- reveal policy
|
||||
|
||||
### 7) Notifications and Overrides
|
||||
|
||||
- default-on event toggles
|
||||
- template overrides
|
||||
- override governance policy
|
||||
|
||||
### 8) Review + Publish
|
||||
|
||||
- summary diff
|
||||
- warnings/blockers
|
||||
- simulation output
|
||||
- publish action
|
||||
|
||||
## UX Requirements
|
||||
|
||||
- mobile-safe interaction and layout
|
||||
- explicit required field indicators
|
||||
- deterministic defaults for every select
|
||||
- inline validation without hidden blockers
|
||||
@@ -0,0 +1,11 @@
|
||||
# Phase 04 Acceptance Gates
|
||||
|
||||
- [ ] G-04-1 applicant flow tests pass (E-002)
|
||||
- [ ] G-04-2 jury flow tests pass (E-004)
|
||||
- [ ] G-04-3 live audience tests pass (E-006/E-007)
|
||||
- [ ] G-04-4 reconnect and realtime resilience evidence passes (P-004)
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- E2E artifacts for applicant/jury/audience scenarios
|
||||
- realtime and reconnect test captures
|
||||
@@ -0,0 +1,29 @@
|
||||
# Applicant Experience Specification
|
||||
|
||||
## Required Views
|
||||
|
||||
1. current stage and timeline
|
||||
2. stage-specific requirements
|
||||
3. deadlines and late policy status
|
||||
4. team invite/account status
|
||||
5. decision history (policy-scoped)
|
||||
|
||||
## Behavior Requirements
|
||||
|
||||
- requirement upload slots are stage-aware
|
||||
- accepted MIME/size and deadline checks enforced at submit time
|
||||
- timeline updates reflect transition and decision events quickly
|
||||
- role-scoped team collaboration controls enforced
|
||||
|
||||
## Error States
|
||||
|
||||
- missing requirement definition
|
||||
- expired upload window
|
||||
- invalid MIME/size
|
||||
- stale session/permission mismatch
|
||||
|
||||
## Notification Expectations
|
||||
|
||||
- intake submitted confirmation
|
||||
- advanced/rejected updates
|
||||
- additional requirement requests when policy allows
|
||||
@@ -0,0 +1,24 @@
|
||||
# Audience Live Vote Specification
|
||||
|
||||
## Core Rules
|
||||
|
||||
1. Audience sees only projects within active cohort/window policy.
|
||||
2. Vote submission requires valid session eligibility and dedupe key check.
|
||||
3. Closed windows reject submissions with typed error.
|
||||
|
||||
## Voting Modes
|
||||
|
||||
- per-project window
|
||||
- per-cohort window
|
||||
- optional criteria mode or simple score mode
|
||||
|
||||
## Safety and Abuse Controls
|
||||
|
||||
- tokenized access policy
|
||||
- optional identity requirement
|
||||
- rate-limit and dedupe enforcement
|
||||
|
||||
## Realtime Requirements
|
||||
|
||||
- active project state and window state sync in near real-time
|
||||
- reconnect path restores current eligible ballot context
|
||||
@@ -0,0 +1,26 @@
|
||||
# Jury Experience Specification
|
||||
|
||||
## Assignment View
|
||||
|
||||
- grouped by stage
|
||||
- explicit open/close window indicators
|
||||
- progress and completion states
|
||||
|
||||
## Evaluation View
|
||||
|
||||
- criteria loaded from stage config
|
||||
- required criteria enforcement
|
||||
- draft autosave and submit lock behavior
|
||||
- COI declaration flow integrated
|
||||
|
||||
## Access Rules
|
||||
|
||||
- only assigned projects visible
|
||||
- voting restricted to open windows
|
||||
- prior-stage material visibility policy respected
|
||||
|
||||
## Live Jury Behavior
|
||||
|
||||
- active project context sync via realtime updates
|
||||
- vote actions gated by cursor and window state
|
||||
- reconnect restores current live context
|
||||
@@ -0,0 +1,21 @@
|
||||
# Phase 04 Overview: Participant Journeys
|
||||
|
||||
## Objective
|
||||
Refit applicant, jury, observer, and audience experiences to stage-native contracts with correct realtime behavior.
|
||||
|
||||
## In Scope
|
||||
|
||||
- applicant intake/status flows
|
||||
- jury assignment/evaluation/live flows
|
||||
- audience voting and live score flows
|
||||
- observer read-only reporting alignment
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- admin config internals
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. End-to-end participant paths pass mandatory E2E tests.
|
||||
2. Realtime behavior converges under reconnect and window changes.
|
||||
3. Policy enforcement matches authz and stage contracts.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Phase 04 Tasks
|
||||
|
||||
## Applicant
|
||||
|
||||
- [ ] Implement stage-native timeline and requirement resolver.
|
||||
- [ ] Implement strict upload gating and policy enforcement.
|
||||
|
||||
## Jury
|
||||
|
||||
- [ ] Implement stage-scoped assignment and evaluation surfaces.
|
||||
- [ ] Implement live jury context sync and voting constraints.
|
||||
|
||||
## Audience and Observer
|
||||
|
||||
- [ ] Implement cohort-scoped audience ballot visibility.
|
||||
- [ ] Implement observer read-only stage/track reporting alignment.
|
||||
|
||||
## Realtime and Resilience
|
||||
|
||||
- [ ] Implement reconnect-state convergence behavior.
|
||||
- [ ] Validate realtime event consistency under cursor updates.
|
||||
@@ -0,0 +1,10 @@
|
||||
# Phase 05 Acceptance Gates
|
||||
|
||||
- [ ] G-05-1 routing mode behavior validated (`parallel`, `exclusive`, `post_main`)
|
||||
- [ ] G-05-2 governance auth tests pass (`JURY_VOTE`, `AWARD_MASTER`, `ADMIN`)
|
||||
- [ ] G-05-3 winner decision timeline and audit output validated
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- integration test outputs for routing and governance
|
||||
- audit timeline payload captures
|
||||
@@ -0,0 +1,39 @@
|
||||
# Award Track and Governance Specification
|
||||
|
||||
## Award Track Principle
|
||||
Awards share the same orchestration engine as the main competition; they are tracks, not detached side workflows.
|
||||
|
||||
## Routing Modes
|
||||
|
||||
- `PARALLEL`: award path runs while main path continues
|
||||
- `EXCLUSIVE`: project exits main continuation path and runs award-only
|
||||
- `POST_MAIN`: award route starts after configured main gate
|
||||
|
||||
## Governance Modes
|
||||
|
||||
- `JURY_VOTE`: assigned award jurors vote
|
||||
- `AWARD_MASTER`: designated award owner decides within scope
|
||||
- `ADMIN`: program/super admin decides
|
||||
|
||||
## Decision Requirements
|
||||
|
||||
- every winner/finalist decision emits audit entry
|
||||
- manual overrides require reason code and text
|
||||
- tie-break policy explicit and deterministic
|
||||
|
||||
## Permission Enforcement
|
||||
|
||||
- governance mode checked server-side on every decision mutation
|
||||
- unauthorized attempts return `FORBIDDEN`
|
||||
|
||||
## Representative Decision Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"awardId": "award_123",
|
||||
"decisionMode": "AWARD_MASTER",
|
||||
"winnerProjectId": "project_789",
|
||||
"reasonCode": "SPONSOR_DECISION",
|
||||
"reasonText": "Award sponsor selected based on category fit"
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
# Phase 05 Overview: Special Awards and Governance
|
||||
|
||||
## Objective
|
||||
Implement special awards as first-class tracks with explicit routing and governance modes, including `AWARD_MASTER`.
|
||||
|
||||
## In Scope
|
||||
|
||||
- award track lifecycle
|
||||
- routing semantics
|
||||
- governance modes and permissions
|
||||
- award decision and winner finalization workflows
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- sponsor legal/contract process documentation
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. Mixed award modes run without collision in a single edition.
|
||||
2. Governance modes enforce correct permissions server-side.
|
||||
3. Winner decision audit trails are complete and immutable.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Phase 05 Tasks
|
||||
|
||||
- [ ] Implement award track CRUD on canonical contracts.
|
||||
- [ ] Implement award routing mode behaviors and edge-case handling.
|
||||
- [ ] Implement governance mode permission checks.
|
||||
- [ ] Implement winner finalization and audit timeline entries.
|
||||
- [ ] Implement award-specific reporting outputs.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Phase 06 Acceptance Gates
|
||||
|
||||
- [ ] G-06-1 dependency refit inventory fully signed off
|
||||
- [ ] G-06-2 symbol sweeps clean (no runtime legacy hits)
|
||||
- [ ] G-06-3 integration consumer payload checks pass
|
||||
- [ ] G-06-4 cross-role smoke tests pass
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- module sign-off checklist with owners
|
||||
- sweep outputs
|
||||
- webhook/export consumer validation logs
|
||||
@@ -0,0 +1,26 @@
|
||||
# Module Refit Map
|
||||
|
||||
## Router Layer Actions
|
||||
|
||||
- Rewrite orchestration endpoints to `pipeline/stage/routing` contracts.
|
||||
- Refactor filtering, assignment, and live endpoints to stage-scoped semantics.
|
||||
- Replace award detached flows with award-track-native contracts.
|
||||
|
||||
## Service Layer Actions
|
||||
|
||||
- Refactor AI filtering context to stage-native payloads.
|
||||
- Refactor assignment engine to consume stage eligibility and availability.
|
||||
- Refactor notification producers to new event taxonomy.
|
||||
- Refactor reminders and summaries to stage references.
|
||||
|
||||
## UI Layer Actions
|
||||
|
||||
- Admin round pages become pipeline/stage control-plane pages.
|
||||
- Jury and applicant pages consume stage timeline and stage requirement contracts.
|
||||
- Public vote/live pages consume cohort and live cursor state.
|
||||
|
||||
## Reporting and Export Actions
|
||||
|
||||
- Replace round-grouped aggregations with stage/track aggregations.
|
||||
- Update CSV/PDF payload field names to new contracts.
|
||||
- Update observer dashboards and chart dimensions.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Phase 06 Overview: Platform Dependency Refit
|
||||
|
||||
## Objective
|
||||
Refit every platform dependency from legacy round semantics to canonical stage contracts.
|
||||
|
||||
## In Scope
|
||||
|
||||
- module-by-module refit execution
|
||||
- stale symbol removal
|
||||
- integration payload consumer updates
|
||||
- cross-role smoke validation
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- new feature expansion not required for contract migration
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. dependency checklist complete
|
||||
2. legacy symbol sweeps clean
|
||||
3. external integration consumers validated
|
||||
@@ -0,0 +1,13 @@
|
||||
# Symbol Sweep Checklist
|
||||
|
||||
All commands must return zero actionable runtime hits.
|
||||
|
||||
- [ ] `rg "trpc\.round" src`
|
||||
- [ ] `rg "\broundId\b" src/server src/components src/app`
|
||||
- [ ] `rg "round\.settingsJson|roundType" src/server src/components src/app`
|
||||
- [ ] `rg "model Round|enum RoundType" prisma/schema.prisma`
|
||||
|
||||
## Exceptions
|
||||
|
||||
- documentation-only references may be allowed with explicit annotation
|
||||
- any code-path exception is release-blocking unless approved
|
||||
@@ -0,0 +1,8 @@
|
||||
# Phase 06 Tasks
|
||||
|
||||
- [ ] Execute router-layer refit checklist.
|
||||
- [ ] Execute service-layer refit checklist.
|
||||
- [ ] Execute UI-layer refit checklist.
|
||||
- [ ] Execute reporting/export integration checklist.
|
||||
- [ ] Run and document legacy symbol sweeps.
|
||||
- [ ] Resolve all remaining contract drift findings.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Phase 07 Acceptance Gates
|
||||
|
||||
- [ ] G-07-1 U/I/E/P matrix all green
|
||||
- [ ] G-07-2 performance and resilience evidence accepted
|
||||
- [ ] G-07-3 release evidence report complete and signed
|
||||
- [ ] G-07-4 atomic cutover executed with successful post-checks
|
||||
|
||||
## Required Evidence
|
||||
|
||||
- consolidated test reports
|
||||
- benchmark output captures
|
||||
- signed release evidence report
|
||||
- runbook execution logs
|
||||
@@ -0,0 +1,21 @@
|
||||
# Phase 07 Overview: Validation and Release
|
||||
|
||||
## Objective
|
||||
Execute complete validation suite, run final reset/reseed rehearsal, and perform atomic release cutover.
|
||||
|
||||
## In Scope
|
||||
|
||||
- full U/I/E/P test execution
|
||||
- release evidence collation
|
||||
- performance and resilience validation
|
||||
- atomic release runbook execution
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- post-release enhancements
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
1. full test matrix green
|
||||
2. release evidence signed
|
||||
3. atomic cutover and post-cutover smoke checks complete
|
||||
@@ -0,0 +1,27 @@
|
||||
# Performance and Resilience Plan
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Assignment Throughput
|
||||
|
||||
- workload: 1000+ eligible projects
|
||||
- metrics: runtime, coverage latency, overload count
|
||||
|
||||
### Filtering Throughput
|
||||
|
||||
- workload: high-volume gate + AI queue
|
||||
- metrics: gate throughput, queue completion, retry/error rate
|
||||
|
||||
### Live Voting Burst
|
||||
|
||||
- workload: peak audience voting during active cursor changes
|
||||
- metrics: vote latency p50/p95/p99, event drop count, cursor propagation delay
|
||||
|
||||
### Reconnect Recovery
|
||||
|
||||
- workload: intentional network interruptions
|
||||
- metrics: time to state convergence, stale cursor mismatch rate
|
||||
|
||||
## Acceptance Policy
|
||||
|
||||
Thresholds set before run and documented in release evidence.
|
||||
@@ -0,0 +1,39 @@
|
||||
# Release Runbook (Atomic Cutover)
|
||||
|
||||
## Preconditions
|
||||
|
||||
- all prior phase gates complete
|
||||
- signed release checklist
|
||||
- rollback owner and communication owner assigned
|
||||
|
||||
## Cutover Sequence
|
||||
|
||||
1. freeze non-release writes and announce maintenance window
|
||||
2. execute final backup snapshot
|
||||
3. deploy release candidate build
|
||||
4. run reset/reseed as planned for production state model
|
||||
5. run post-deploy integrity and smoke checks
|
||||
6. run mandatory critical-path E2E subset
|
||||
7. publish completion and monitor
|
||||
|
||||
## Immediate Post-Cutover Checks
|
||||
|
||||
- auth and role gating paths
|
||||
- transition mutation sanity
|
||||
- assignment preview/execute path
|
||||
- live cursor operations
|
||||
- audience vote acceptance and dedupe
|
||||
- reporting endpoint correctness
|
||||
|
||||
## Rollback Trigger Conditions
|
||||
|
||||
- integrity check failures
|
||||
- critical mutation path failure
|
||||
- unacceptable error-rate spike
|
||||
|
||||
## Rollback Plan (High Level)
|
||||
|
||||
- restore backup snapshot
|
||||
- redeploy previous stable build
|
||||
- validate critical-path smoke tests
|
||||
- issue incident communication and postmortem schedule
|
||||
@@ -0,0 +1,7 @@
|
||||
# Phase 07 Tasks
|
||||
|
||||
- [ ] Execute full test matrix and store artifacts.
|
||||
- [ ] Execute performance and resilience scenarios.
|
||||
- [ ] Complete release evidence report.
|
||||
- [ ] Run atomic cutover rehearsal and production runbook.
|
||||
- [ ] Complete post-cutover smoke suite.
|
||||
@@ -0,0 +1,97 @@
|
||||
# API Contracts
|
||||
|
||||
## Contract Conventions
|
||||
|
||||
- All mutations return typed `errorCode` and machine-readable `details` on failure.
|
||||
- All state-changing operations emit deterministic audit events.
|
||||
- All response shapes include stable identifiers for client cache invalidation.
|
||||
|
||||
## Router Families
|
||||
|
||||
### `pipeline`
|
||||
|
||||
- `pipeline.create`
|
||||
- `pipeline.update`
|
||||
- `pipeline.simulate`
|
||||
- `pipeline.publish`
|
||||
- `pipeline.getSummary`
|
||||
|
||||
### `stage`
|
||||
|
||||
- `stage.create`
|
||||
- `stage.updateConfig`
|
||||
- `stage.list`
|
||||
- `stage.transition`
|
||||
- `stage.openWindow`
|
||||
- `stage.closeWindow`
|
||||
|
||||
### `routing`
|
||||
|
||||
- `routing.preview`
|
||||
- `routing.execute`
|
||||
- `routing.listRules`
|
||||
- `routing.upsertRule`
|
||||
- `routing.toggleRule`
|
||||
|
||||
### `filtering`
|
||||
|
||||
- `filtering.previewBatch`
|
||||
- `filtering.runStageFiltering`
|
||||
- `filtering.getManualQueue`
|
||||
- `filtering.resolveManualDecision`
|
||||
|
||||
### `assignment`
|
||||
|
||||
- `assignment.previewStageProjects`
|
||||
- `assignment.assignStageProjects`
|
||||
- `assignment.getCoverageReport`
|
||||
- `assignment.rebalance`
|
||||
|
||||
### `cohort`
|
||||
|
||||
- `cohort.create`
|
||||
- `cohort.assignProjects`
|
||||
- `cohort.openVoting`
|
||||
- `cohort.closeVoting`
|
||||
|
||||
### `live`
|
||||
|
||||
- `live.start`
|
||||
- `live.setActiveProject`
|
||||
- `live.jump`
|
||||
- `live.reorder`
|
||||
- `live.pause`
|
||||
- `live.resume`
|
||||
|
||||
### `decision`
|
||||
|
||||
- `decision.override`
|
||||
- `decision.auditTimeline`
|
||||
|
||||
### `award`
|
||||
|
||||
- `award.createTrack`
|
||||
- `award.configureGovernance`
|
||||
- `award.routeProjects`
|
||||
- `award.finalizeWinners`
|
||||
|
||||
## Error Contract
|
||||
|
||||
- `BAD_REQUEST`
|
||||
- `UNAUTHORIZED`
|
||||
- `FORBIDDEN`
|
||||
- `NOT_FOUND`
|
||||
- `CONFLICT`
|
||||
- `PRECONDITION_FAILED`
|
||||
- `INTERNAL_SERVER_ERROR`
|
||||
|
||||
## Event Contract (Representative)
|
||||
|
||||
- `stage.transitioned`
|
||||
- `routing.executed`
|
||||
- `filtering.completed`
|
||||
- `assignment.generated`
|
||||
- `live.cursor.updated`
|
||||
- `cohort.window.changed`
|
||||
- `decision.overridden`
|
||||
- `award.winner.finalized`
|
||||
@@ -0,0 +1,32 @@
|
||||
# Authorization Matrix
|
||||
|
||||
Roles:
|
||||
|
||||
- `SUPER_ADMIN`
|
||||
- `PROGRAM_ADMIN`
|
||||
- `AWARD_MASTER`
|
||||
- `JURY_MEMBER`
|
||||
- `APPLICANT`
|
||||
- `OBSERVER`
|
||||
- `AUDIENCE` (public voting context)
|
||||
|
||||
| Capability | Super Admin | Program Admin | Award Master | Jury | Applicant | Observer | Audience |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| Create/Edit Pipeline | Yes | Yes (scoped) | No | No | No | No | No |
|
||||
| Publish Pipeline | Yes | Yes (scoped) | No | No | No | No | No |
|
||||
| Configure Stage Rules | Yes | Yes (scoped) | No | No | No | No | No |
|
||||
| Execute Manual Transition | Yes | Yes (scoped) | Limited (award scoped) | No | No | No | No |
|
||||
| Override Decision | Yes | Yes (scoped) | Limited (award scoped) | No | No | No | No |
|
||||
| View Audit Timeline | Yes | Yes (scoped) | Award scoped | Own actions | No | Read-only scoped | No |
|
||||
| Assign Jurors | Yes | Yes (scoped) | Award scoped | No | No | No | No |
|
||||
| Submit Evaluation | No | No | Optional (if configured) | Yes (assigned only) | No | No | No |
|
||||
| Upload Intake Docs | No | No | No | No | Yes | No | No |
|
||||
| Control Live Cursor | Yes | Yes (scoped) | No | No | No | No | No |
|
||||
| Cast Audience Vote | No | No | No | No | Optional | No | Yes |
|
||||
|
||||
## Policy Notes
|
||||
|
||||
1. Program scoping applies to all admin operations.
|
||||
2. `AWARD_MASTER` permissions are explicitly award-scoped and only active when governance mode allows it.
|
||||
3. Jury endpoints always enforce assignment ownership and window constraints.
|
||||
4. Audience endpoints enforce cohort membership + window state + dedupe key policy.
|
||||
@@ -0,0 +1,16 @@
|
||||
# Decision Log (Locked)
|
||||
|
||||
| ID | Decision | Status | Rationale | Impacted Phases |
|
||||
|---|---|---|---|---|
|
||||
| MX-001 | Canonical model is `Pipeline -> Track -> Stage` | Locked | Supports multi-track orchestration cleanly | 01-07 |
|
||||
| MX-002 | Project progression stored in `ProjectStageState` records | Locked | Replaces brittle single-pointer round state | 01-07 |
|
||||
| MX-003 | Intake is stage-native (`INTAKE`) rather than implicit pre-round behavior | Locked | Removes hidden workflow behavior | 01-04 |
|
||||
| MX-004 | Full-cutover delivery with no compatibility bridge | Locked | Faster convergence to clean runtime | 00-07 |
|
||||
| MX-005 | Special awards are first-class `Track` entities | Locked | Prevents duplicated orchestration logic | 01-06 |
|
||||
| MX-006 | Award routing modes are `parallel`, `exclusive`, `post_main` | Locked | Supports real sponsor policy diversity | 02,05 |
|
||||
| MX-007 | Award governance modes include `JURY_VOTE`, `AWARD_MASTER`, `ADMIN` | Locked | Explicit and policy-aligned control surfaces | 05 |
|
||||
| MX-008 | Live progression source of truth is admin cursor | Locked | Needed for non-linear live event control | 02,04 |
|
||||
| MX-009 | Voting windows are explicit open/close operations | Locked | Schedules alone are insufficient during live operations | 02,04 |
|
||||
| MX-010 | Assignment engine guarantees eligible project coverage | Locked | Operational fairness and delivery reliability | 02,04 |
|
||||
| MX-011 | Overrides require reason and immutable audit entries | Locked | Governance and explainability | 02,05,07 |
|
||||
| MX-012 | Release is blocked by legacy symbol sweep failures | Locked | Prevents half-migrated runtime behavior | 06,07 |
|
||||
@@ -0,0 +1,75 @@
|
||||
# Dependency Refit Inventory
|
||||
|
||||
This inventory is release-blocking. Every listed module must be validated against the new contracts.
|
||||
|
||||
## Backend Routers
|
||||
|
||||
- `src/server/routers/_app.ts`
|
||||
- `src/server/routers/round.ts`
|
||||
- `src/server/routers/filtering.ts`
|
||||
- `src/server/routers/live-voting.ts`
|
||||
- `src/server/routers/specialAward.ts`
|
||||
- `src/server/routers/assignment.ts`
|
||||
- `src/server/routers/evaluation.ts`
|
||||
- `src/server/routers/file.ts`
|
||||
- `src/server/routers/project.ts`
|
||||
- `src/server/routers/project-pool.ts`
|
||||
- `src/server/routers/application.ts`
|
||||
- `src/server/routers/applicant.ts`
|
||||
- `src/server/routers/export.ts`
|
||||
- `src/server/routers/analytics.ts`
|
||||
- `src/server/routers/program.ts`
|
||||
- `src/server/routers/roundTemplate.ts`
|
||||
- `src/server/routers/gracePeriod.ts`
|
||||
- `src/server/routers/webhook.ts`
|
||||
|
||||
## Backend Services
|
||||
|
||||
- `src/server/services/smart-assignment.ts`
|
||||
- `src/server/services/ai-filtering.ts`
|
||||
- `src/server/services/ai-evaluation-summary.ts`
|
||||
- `src/server/services/evaluation-reminders.ts`
|
||||
- `src/server/services/in-app-notification.ts`
|
||||
- `src/server/services/award-eligibility-job.ts`
|
||||
- `src/server/services/webhook-dispatcher.ts`
|
||||
|
||||
## Admin Surfaces
|
||||
|
||||
- `src/app/(admin)/admin/rounds/**`
|
||||
- `src/app/(admin)/admin/awards/**`
|
||||
- `src/app/(admin)/admin/reports/page.tsx`
|
||||
- `src/components/admin/round-pipeline.tsx`
|
||||
- `src/components/admin/assign-projects-dialog.tsx`
|
||||
- `src/components/admin/advance-projects-dialog.tsx`
|
||||
- `src/components/admin/remove-projects-dialog.tsx`
|
||||
- `src/components/admin/file-requirements-editor.tsx`
|
||||
- `src/components/forms/round-type-settings.tsx`
|
||||
|
||||
## Jury, Applicant, Public
|
||||
|
||||
- `src/app/(jury)/jury/**`
|
||||
- `src/components/jury/**`
|
||||
- `src/app/(applicant)/applicant/**`
|
||||
- `src/app/(public)/apply/**`
|
||||
- `src/app/(public)/my-submission/**`
|
||||
- `src/app/(public)/vote/**`
|
||||
- `src/app/(public)/live-scores/**`
|
||||
|
||||
## Reporting and Exports
|
||||
|
||||
- chart and observer modules under `src/components/charts/**` and `src/components/observer/**`
|
||||
- export and PDF paths under `src/components/shared/export-pdf-button.tsx`, `src/components/admin/pdf-report.tsx`, `src/server/routers/export.ts`
|
||||
|
||||
## Schema and Seed Paths
|
||||
|
||||
- `prisma/schema.prisma`
|
||||
- relevant migrations and seed scripts under `prisma/`
|
||||
|
||||
## Mandatory Legacy Sweep Queries (Release Blockers)
|
||||
|
||||
1. `rg "trpc\.round" src`
|
||||
2. `rg "\broundId\b" src/server src/components src/app`
|
||||
3. `rg "round\.settingsJson|roundType" src/server src/components src/app`
|
||||
4. `rg "model Round|enum RoundType" prisma/schema.prisma`
|
||||
|
||||
Allowlist exceptions (if any) must be explicit and approved in Phase 06 gates.
|
||||
@@ -0,0 +1,156 @@
|
||||
# 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)`
|
||||
@@ -0,0 +1,32 @@
|
||||
# Phase Gate Traceability
|
||||
|
||||
| Phase | Gate ID | Evidence Required | Test IDs / Checks | Blocking |
|
||||
|---|---|---|---|---|
|
||||
| 00 | G-00-1 | decision lock snapshot | decision-log review | Yes |
|
||||
| 00 | G-00-2 | contract alignment review | API/type contract diff | Yes |
|
||||
| 01 | G-01-1 | schema compile output | `prisma generate` | Yes |
|
||||
| 01 | G-01-2 | reset/reseed output | seed logs + integrity queries | Yes |
|
||||
| 01 | G-01-3 | index and FK evidence | SQL verification scripts | Yes |
|
||||
| 02 | G-02-1 | transition runtime proof | U-001/U-002/I-001 | Yes |
|
||||
| 02 | G-02-2 | routing determinism proof | U-003/I-003/I-004 | Yes |
|
||||
| 02 | G-02-3 | filtering policy proof | U-004/U-005/E-003 | Yes |
|
||||
| 02 | G-02-4 | assignment guarantees proof | U-006/U-007/I-005 | Yes |
|
||||
| 02 | G-02-5 | audit/override proof | U-008/I-008 | Yes |
|
||||
| 03 | G-03-1 | create/edit parity proof | parity checklist | Yes |
|
||||
| 03 | G-03-2 | wizard completion proof | E-001 | Yes |
|
||||
| 03 | G-03-3 | modal safety proof | targeted UI regressions | Yes |
|
||||
| 04 | G-04-1 | applicant flow proof | E-002 | Yes |
|
||||
| 04 | G-04-2 | jury flow proof | E-004 | Yes |
|
||||
| 04 | G-04-3 | live audience proof | E-006/E-007/I-006/I-007 | Yes |
|
||||
| 05 | G-05-1 | award routing proof | I-003/I-004 | Yes |
|
||||
| 05 | G-05-2 | governance auth proof | U-010 + auth tests | Yes |
|
||||
| 05 | G-05-3 | winner and audit proof | E-008 + I-008 | Yes |
|
||||
| 06 | G-06-1 | dependency checklist complete | module sign-off evidence | Yes |
|
||||
| 06 | G-06-2 | legacy sweeps clean | mandatory rg sweeps | Yes |
|
||||
| 06 | G-06-3 | external consumer validation | webhook/export checks | Yes |
|
||||
| 07 | G-07-1 | full test report | full matrix results | Yes |
|
||||
| 07 | G-07-2 | performance report | P-001..P-004 evidence | Yes |
|
||||
| 07 | G-07-3 | release evidence package | signed report template | Yes |
|
||||
| 07 | G-07-4 | atomic cutover proof | release runbook logs | Yes |
|
||||
|
||||
Rule: no phase closes until all gates are complete with linked artifacts.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Program Charter
|
||||
|
||||
## Mission
|
||||
Deliver a complete, stage-native orchestration platform for MOPC that supports:
|
||||
|
||||
- edition-scoped intake and progression
|
||||
- deterministic filtering and assignment
|
||||
- parallel and exclusive award flows
|
||||
- admin-driven live finals operations
|
||||
- full auditability and release-grade validation
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
|
||||
- Canonical data model rebuild around pipeline/track/stage.
|
||||
- Backend orchestration engine (transition, routing, filtering, assignment, live, notifications, audit).
|
||||
- Admin setup and control-plane UX refit.
|
||||
- Applicant, jury, observer, and audience flow refit to new contracts.
|
||||
- Special award governance modes including `AWARD_MASTER`.
|
||||
- Platform-wide dependency refit of schema/runtime consumers.
|
||||
- Full validation and atomic release process.
|
||||
|
||||
### Out of Scope
|
||||
|
||||
- Legacy contract compatibility bridges.
|
||||
- Cosmetic redesign or major brand refresh.
|
||||
- Non-orchestration feature expansion unrelated to competition lifecycle.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. Admin setup can fully configure required competition behavior in create-time flow.
|
||||
2. Stage progression and routing are deterministic and explainable.
|
||||
3. Award tracks run without ad hoc side logic.
|
||||
4. Live event operations are resilient under reconnect and burst traffic.
|
||||
5. All platform dependencies are migrated and verified before release.
|
||||
|
||||
## Quality Bar
|
||||
|
||||
- Typed contracts at schema, API, and UI boundaries.
|
||||
- Idempotent mutation semantics for high-risk operations.
|
||||
- Strong audit trails for every governance-sensitive action.
|
||||
- Mobile-safe interaction quality for live audience and jury experiences.
|
||||
@@ -0,0 +1,65 @@
|
||||
# Release Evidence Report Template
|
||||
|
||||
## Build Metadata
|
||||
|
||||
- Date:
|
||||
- Commit SHA:
|
||||
- Environment:
|
||||
- Operator:
|
||||
|
||||
## Phase Completion Summary
|
||||
|
||||
- Phase 00:
|
||||
- Phase 01:
|
||||
- Phase 02:
|
||||
- Phase 03:
|
||||
- Phase 04:
|
||||
- Phase 05:
|
||||
- Phase 06:
|
||||
- Phase 07:
|
||||
|
||||
## Test Summary
|
||||
|
||||
- Unit: pass/fail counts
|
||||
- Integration: pass/fail counts
|
||||
- E2E: pass/fail counts
|
||||
- Performance: pass/fail counts
|
||||
|
||||
## Mandatory Scenario Results
|
||||
|
||||
| ID | Result | Evidence Link | Notes |
|
||||
|---|---|---|---|
|
||||
| E-001 | | | |
|
||||
| E-002 | | | |
|
||||
| E-003 | | | |
|
||||
| E-004 | | | |
|
||||
| E-005 | | | |
|
||||
| E-006 | | | |
|
||||
| E-007 | | | |
|
||||
| E-008 | | | |
|
||||
|
||||
## Performance Results
|
||||
|
||||
| ID | Result | Evidence Link | Notes |
|
||||
|---|---|---|---|
|
||||
| P-001 | | | |
|
||||
| P-002 | | | |
|
||||
| P-003 | | | |
|
||||
| P-004 | | | |
|
||||
|
||||
## Legacy Sweep Results
|
||||
|
||||
- `trpc.round` references:
|
||||
- `roundId` orchestration references:
|
||||
- `round.settingsJson` behavior references:
|
||||
- schema `Round` references:
|
||||
|
||||
## Known Issues
|
||||
|
||||
- None / list with severity and owner
|
||||
|
||||
## Sign-Off
|
||||
|
||||
- Engineering:
|
||||
- Product:
|
||||
- Operations:
|
||||
@@ -0,0 +1,17 @@
|
||||
# Risk Register
|
||||
|
||||
| ID | Risk | Probability | Impact | Mitigation | Owner | Status |
|
||||
|---|---|---|---|---|---|---|
|
||||
| R-001 | Hidden legacy coupling after schema rebuild | Medium | High | Mandatory symbol sweeps + module refit gates | Eng Lead | Open |
|
||||
| R-002 | Assignment coverage edge-case failures at scale | Medium | High | Hard overflow policy + P-001 load tests | Backend Lead | Open |
|
||||
| R-003 | Award governance permission drift | Low | High | explicit authz tests for each decision mode | Security Lead | Open |
|
||||
| R-004 | Live cursor race conditions during events | Medium | High | optimistic lock + replay-safe event handling | Realtime Lead | Open |
|
||||
| R-005 | Audience vote dedupe regressions | Medium | Medium | dedupe key contract + E-007 + I-007 tests | Backend Lead | Open |
|
||||
| R-006 | Migration/reseed script incompleteness | Low | High | repeatable reset/reseed rehearsals | DB Owner | Open |
|
||||
| R-007 | Reporting consumers break on contract shift | Medium | Medium | phase-06 consumer validation checklist | Data Lead | Open |
|
||||
| R-008 | Scope creep during dependency refit | High | Medium | strict out-of-scope policy, defer noncritical features | PM | Open |
|
||||
|
||||
## Risk Handling Policy
|
||||
|
||||
- `High impact` items require explicit mitigation evidence before phase close.
|
||||
- `Open` high/high risks block release in Phase 07.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Test Matrix
|
||||
|
||||
All IDs are mandatory unless explicitly marked non-blocking with sign-off.
|
||||
|
||||
## Unit Tests
|
||||
|
||||
| ID | Area | Scenario | Expected |
|
||||
|---|---|---|---|
|
||||
| U-001 | Transition Engine | legal transition | persisted with audit event |
|
||||
| U-002 | Transition Engine | illegal transition | typed validation error |
|
||||
| U-003 | Routing | multiple rule match | deterministic priority winner |
|
||||
| U-004 | Filtering Gates | missing required docs | blocked before AI pass |
|
||||
| U-005 | AI Banding | uncertain confidence band | routed to manual queue |
|
||||
| U-006 | Assignment | COI conflict | excluded from pool |
|
||||
| U-007 | Assignment | insufficient capacity | overflow flagged + coverage preserved |
|
||||
| U-008 | Override | missing reason fields | mutation rejected |
|
||||
| U-009 | Live Cursor | concurrent cursor update | conflict handled and retried |
|
||||
| U-010 | Award Governance | `AWARD_MASTER` on unauthorized award | forbidden |
|
||||
|
||||
## Integration Tests
|
||||
|
||||
| ID | Area | Scenario | Expected |
|
||||
|---|---|---|---|
|
||||
| I-001 | Pipeline CRUD | create/update/publish | graph integrity maintained |
|
||||
| I-002 | Stage Config | invalid config schema | rejected |
|
||||
| I-003 | Transition + Routing | filter pass to main + award parallel | dual states created |
|
||||
| I-004 | Award Exclusive Routing | exclusive route | removed from main continuation |
|
||||
| I-005 | Assignment API | preview vs execute parity | same constraints and outcomes |
|
||||
| I-006 | Live Runtime | jump + reorder + open/close windows | consistent cursor state |
|
||||
| I-007 | Cohort Voting | closed window submit | vote rejected |
|
||||
| I-008 | Decision Audit | override applied | complete immutable timeline |
|
||||
|
||||
## End-to-End Tests
|
||||
|
||||
| ID | Persona | Scenario | Expected |
|
||||
|---|---|---|---|
|
||||
| E-001 | Admin | complete setup via wizard | no hidden edit-only blockers |
|
||||
| E-002 | Applicant | upload intake requirements | status and deadlines enforced |
|
||||
| E-003 | Admin | run filtering stage | gates + AI + manual queue behave |
|
||||
| E-004 | Jury | complete evaluation workflow | criteria and lock policy enforced |
|
||||
| E-005 | Admin | selection + override | finalists and audit aligned |
|
||||
| E-006 | Live Admin | advance/back/jump + reorder | jury and audience sync realtime |
|
||||
| E-007 | Audience | vote by cohort on mobile | visibility and dedupe enforced |
|
||||
| E-008 | Admin | finalize results | ranking and publish outputs valid |
|
||||
|
||||
## Performance and Resilience
|
||||
|
||||
| ID | Area | Scenario | Threshold |
|
||||
|---|---|---|---|
|
||||
| P-001 | Assignment | 1000+ project batch | under agreed SLA |
|
||||
| P-002 | Filtering | large AI queue | deterministic retry, no dropped jobs |
|
||||
| P-003 | Live Voting | peak audience burst | acceptable p95 and no data loss |
|
||||
| P-004 | Reconnect | disconnect/reconnect | state converges quickly |
|
||||
|
||||
## Release Block Rule
|
||||
|
||||
Any failing `U-*`, `I-*`, `E-*`, or `P-*` is release-blocking unless signed waiver exists.
|
||||
@@ -0,0 +1,661 @@
|
||||
# Phase 0: Domain Model Validation
|
||||
|
||||
**Date**: 2026-02-12
|
||||
**Status**: ✅ VALIDATED
|
||||
**Reviewer**: Claude Sonnet 4.5
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document validates the proposed canonical domain model from the redesign specification against the current MOPC Prisma schema. The validation confirms that all proposed entities, enums, and constraints are architecturally sound and can be implemented without conflicts.
|
||||
|
||||
**Result**: ✅ **APPROVED** - Domain model is complete, unambiguous, and ready for implementation in Phase 1.
|
||||
|
||||
---
|
||||
|
||||
## 1. Canonical Enums Validation
|
||||
|
||||
### 1.1 New Enums (To be Added)
|
||||
|
||||
| Enum Name | Values | Status | Notes |
|
||||
|-----------|--------|--------|-------|
|
||||
| **StageType** | `INTAKE`, `FILTER`, `EVALUATION`, `SELECTION`, `LIVE_FINAL`, `RESULTS` | ✅ Complete | Replaces implicit `RoundType` semantics |
|
||||
| **TrackKind** | `MAIN`, `AWARD`, `SHOWCASE` | ✅ Complete | Enables first-class special awards |
|
||||
| **RoutingMode** | `PARALLEL`, `EXCLUSIVE`, `POST_MAIN` | ✅ Complete | Controls award routing behavior |
|
||||
| **StageStatus** | `DRAFT`, `ACTIVE`, `CLOSED`, `ARCHIVED` | ✅ Complete | Aligns with existing `RoundStatus` |
|
||||
| **ProjectStageStateValue** | `PENDING`, `IN_PROGRESS`, `PASSED`, `REJECTED`, `ROUTED`, `COMPLETED`, `WITHDRAWN` | ✅ Complete | Explicit state machine for project progression |
|
||||
| **DecisionMode** | `JURY_VOTE`, `AWARD_MASTER`, `ADMIN` | ✅ Complete | Award governance modes |
|
||||
| **OverrideReasonCode** | `DATA_CORRECTION`, `POLICY_EXCEPTION`, `JURY_CONFLICT`, `SPONSOR_DECISION`, `ADMIN_DISCRETION` | ✅ Complete | Mandatory reason tracking for overrides |
|
||||
|
||||
**Validation Notes**:
|
||||
- All enum values are mutually exclusive and unambiguous
|
||||
- No conflicts with existing enums
|
||||
- `StageStatus` deliberately mirrors `RoundStatus` for familiarity
|
||||
- `ProjectStageStateValue` provides complete state coverage
|
||||
|
||||
### 1.2 Existing Enums (To be Extended or Deprecated)
|
||||
|
||||
| Current Enum | Action | Rationale |
|
||||
|--------------|--------|-----------|
|
||||
| **RoundType** | ⚠️ DEPRECATE in Phase 6 | Replaced by `StageType` + stage config |
|
||||
| **RoundStatus** | ⚠️ DEPRECATE in Phase 6 | Replaced by `StageStatus` |
|
||||
| **UserRole** | ✅ EXTEND | Add `AWARD_MASTER` and `AUDIENCE` values |
|
||||
| **ProjectStatus** | ⚠️ DEPRECATE in Phase 6 | Replaced by `ProjectStageState` records |
|
||||
|
||||
**Action Items for Phase 1**:
|
||||
- Add new enums to `prisma/schema.prisma`
|
||||
- Extend `UserRole` with `AWARD_MASTER` and `AUDIENCE`
|
||||
- Do NOT remove deprecated enums yet (Phase 6)
|
||||
|
||||
---
|
||||
|
||||
## 2. Core Entities Validation
|
||||
|
||||
### 2.1 New Core Models
|
||||
|
||||
#### Pipeline
|
||||
```prisma
|
||||
model Pipeline {
|
||||
id String @id @default(cuid())
|
||||
programId String
|
||||
name String
|
||||
slug String @unique
|
||||
status StageStatus @default(DRAFT)
|
||||
settingsJson Json? @db.JsonB
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
program Program @relation(fields: [programId], references: [id])
|
||||
tracks Track[]
|
||||
routingRules RoutingRule[]
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ All fields align with domain model spec
|
||||
- ✅ `programId` FK ensures proper scoping
|
||||
- ✅ `slug` unique constraint enables URL-friendly references
|
||||
- ✅ `settingsJson` provides extensibility
|
||||
- ✅ Relationships properly defined
|
||||
|
||||
#### Track
|
||||
```prisma
|
||||
model Track {
|
||||
id String @id @default(cuid())
|
||||
pipelineId String
|
||||
kind TrackKind @default(MAIN)
|
||||
specialAwardId String? @unique
|
||||
name String
|
||||
slug String
|
||||
sortOrder Int
|
||||
routingModeDefault RoutingMode?
|
||||
decisionMode DecisionMode?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
pipeline Pipeline @relation(fields: [pipelineId], references: [id], onDelete: Cascade)
|
||||
specialAward SpecialAward? @relation(fields: [specialAwardId], references: [id])
|
||||
stages Stage[]
|
||||
projectStageStates ProjectStageState[]
|
||||
routingRules RoutingRule[] @relation("DestinationTrack")
|
||||
|
||||
@@unique([pipelineId, slug])
|
||||
@@index([pipelineId, sortOrder])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ `kind` determines track type (MAIN vs AWARD vs SHOWCASE)
|
||||
- ✅ `specialAwardId` nullable for MAIN tracks, required for AWARD tracks
|
||||
- ✅ `sortOrder` enables explicit ordering
|
||||
- ✅ `routingModeDefault` and `decisionMode` provide award-specific config
|
||||
- ✅ Unique constraint on `(pipelineId, slug)` prevents duplicates
|
||||
- ✅ Index on `(pipelineId, sortOrder)` optimizes ordering queries
|
||||
|
||||
#### Stage
|
||||
```prisma
|
||||
model Stage {
|
||||
id String @id @default(cuid())
|
||||
trackId String
|
||||
stageType StageType
|
||||
name String
|
||||
slug String
|
||||
sortOrder Int
|
||||
status StageStatus @default(DRAFT)
|
||||
configVersion Int @default(1)
|
||||
configJson Json @db.JsonB
|
||||
windowOpenAt DateTime?
|
||||
windowCloseAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
track Track @relation(fields: [trackId], references: [id], onDelete: Cascade)
|
||||
projectStageStates ProjectStageState[]
|
||||
transitionsFrom StageTransition[] @relation("FromStage")
|
||||
transitionsTo StageTransition[] @relation("ToStage")
|
||||
cohorts Cohort[]
|
||||
liveProgressCursor LiveProgressCursor?
|
||||
|
||||
@@unique([trackId, slug])
|
||||
@@unique([trackId, sortOrder])
|
||||
@@index([trackId, status])
|
||||
@@index([status, windowOpenAt, windowCloseAt])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ `stageType` determines config schema (union type)
|
||||
- ✅ `configVersion` enables config evolution
|
||||
- ✅ `configJson` stores type-specific configuration
|
||||
- ✅ `windowOpenAt`/`windowCloseAt` provide voting windows
|
||||
- ✅ Unique constraints prevent duplicate `slug` or `sortOrder` per track
|
||||
- ✅ Indexes optimize status and window queries
|
||||
|
||||
#### StageTransition
|
||||
```prisma
|
||||
model StageTransition {
|
||||
id String @id @default(cuid())
|
||||
fromStageId String
|
||||
toStageId String
|
||||
priority Int @default(0)
|
||||
isDefault Boolean @default(false)
|
||||
guardJson Json? @db.JsonB
|
||||
actionJson Json? @db.JsonB
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
fromStage Stage @relation("FromStage", fields: [fromStageId], references: [id], onDelete: Cascade)
|
||||
toStage Stage @relation("ToStage", fields: [toStageId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([fromStageId, toStageId])
|
||||
@@index([fromStageId, priority])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Explicit state machine definition
|
||||
- ✅ `priority` enables deterministic tie-breaking
|
||||
- ✅ `isDefault` marks default transition path
|
||||
- ✅ `guardJson` and `actionJson` provide transition logic
|
||||
- ✅ Unique constraint prevents duplicate transitions
|
||||
- ✅ Index on `(fromStageId, priority)` optimizes transition lookup
|
||||
|
||||
#### ProjectStageState
|
||||
```prisma
|
||||
model ProjectStageState {
|
||||
id String @id @default(cuid())
|
||||
projectId String
|
||||
trackId String
|
||||
stageId String
|
||||
state ProjectStageStateValue
|
||||
enteredAt DateTime @default(now())
|
||||
exitedAt DateTime?
|
||||
decisionRef String?
|
||||
outcomeJson Json? @db.JsonB
|
||||
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
track Track @relation(fields: [trackId], references: [id], onDelete: Cascade)
|
||||
stage Stage @relation(fields: [stageId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([projectId, trackId, stageId])
|
||||
@@index([projectId, trackId, state])
|
||||
@@index([stageId, state])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Replaces single `roundId` pointer with explicit state records
|
||||
- ✅ Unique constraint on `(projectId, trackId, stageId)` prevents duplicates
|
||||
- ✅ `trackId` enables parallel track progression (main + awards)
|
||||
- ✅ `state` provides current progression status
|
||||
- ✅ `enteredAt`/`exitedAt` track state duration
|
||||
- ✅ `decisionRef` links to decision audit
|
||||
- ✅ `outcomeJson` stores stage-specific metadata
|
||||
- ✅ Indexes optimize project queries and stage reporting
|
||||
|
||||
#### RoutingRule
|
||||
```prisma
|
||||
model RoutingRule {
|
||||
id String @id @default(cuid())
|
||||
pipelineId String
|
||||
scope String // 'GLOBAL' | 'TRACK' | 'STAGE'
|
||||
predicateJson Json @db.JsonB
|
||||
destinationTrackId String
|
||||
destinationStageId String?
|
||||
priority Int @default(0)
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
pipeline Pipeline @relation(fields: [pipelineId], references: [id], onDelete: Cascade)
|
||||
destinationTrack Track @relation("DestinationTrack", fields: [destinationTrackId], references: [id])
|
||||
|
||||
@@index([pipelineId, isActive, priority])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ `scope` determines rule evaluation context
|
||||
- ✅ `predicateJson` contains matching logic
|
||||
- ✅ `destinationTrackId` required, `destinationStageId` optional
|
||||
- ✅ `priority` enables deterministic rule ordering
|
||||
- ✅ `isActive` allows toggling without deletion
|
||||
- ✅ Index on `(pipelineId, isActive, priority)` optimizes rule lookup
|
||||
|
||||
### 2.2 Live Runtime Models
|
||||
|
||||
#### Cohort
|
||||
```prisma
|
||||
model Cohort {
|
||||
id String @id @default(cuid())
|
||||
stageId String
|
||||
name String
|
||||
votingMode String // 'JURY' | 'AUDIENCE' | 'HYBRID'
|
||||
isOpen Boolean @default(false)
|
||||
windowOpenAt DateTime?
|
||||
windowCloseAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
stage Stage @relation(fields: [stageId], references: [id], onDelete: Cascade)
|
||||
cohortProjects CohortProject[]
|
||||
|
||||
@@index([stageId, isOpen])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Groups projects for live voting
|
||||
- ✅ `votingMode` determines who can vote
|
||||
- ✅ `isOpen` controls voting acceptance
|
||||
- ✅ `windowOpenAt`/`windowCloseAt` provide time bounds
|
||||
- ✅ Index on `(stageId, isOpen)` optimizes active cohort queries
|
||||
|
||||
#### CohortProject
|
||||
```prisma
|
||||
model CohortProject {
|
||||
id String @id @default(cuid())
|
||||
cohortId String
|
||||
projectId String
|
||||
sortOrder Int
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
cohort Cohort @relation(fields: [cohortId], references: [id], onDelete: Cascade)
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([cohortId, projectId])
|
||||
@@index([cohortId, sortOrder])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Many-to-many join table for cohort membership
|
||||
- ✅ `sortOrder` enables presentation ordering
|
||||
- ✅ Unique constraint prevents duplicate membership
|
||||
- ✅ Index on `(cohortId, sortOrder)` optimizes ordering queries
|
||||
|
||||
#### LiveProgressCursor
|
||||
```prisma
|
||||
model LiveProgressCursor {
|
||||
id String @id @default(cuid())
|
||||
stageId String @unique
|
||||
sessionId String
|
||||
activeProjectId String?
|
||||
activeOrderIndex Int?
|
||||
updatedBy String
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
stage Stage @relation(fields: [stageId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([stageId, sessionId])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Admin cursor as source of truth for live events
|
||||
- ✅ `stageId` unique ensures one cursor per stage
|
||||
- ✅ `sessionId` tracks live session
|
||||
- ✅ `activeProjectId` and `activeOrderIndex` track current position
|
||||
- ✅ `updatedBy` tracks admin actor
|
||||
- ✅ Index on `(stageId, sessionId)` optimizes live queries
|
||||
|
||||
### 2.3 Governance Models
|
||||
|
||||
#### OverrideAction
|
||||
```prisma
|
||||
model OverrideAction {
|
||||
id String @id @default(cuid())
|
||||
entityType String // 'PROJECT' | 'STAGE' | 'COHORT' | 'AWARD'
|
||||
entityId String
|
||||
oldValueJson Json? @db.JsonB
|
||||
newValueJson Json @db.JsonB
|
||||
reasonCode OverrideReasonCode
|
||||
reasonText String
|
||||
actedBy String
|
||||
actedAt DateTime @default(now())
|
||||
|
||||
@@index([entityType, entityId, actedAt])
|
||||
@@index([actedBy, actedAt])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Immutable override audit trail
|
||||
- ✅ `reasonCode` enum ensures valid reasons
|
||||
- ✅ `reasonText` captures human explanation
|
||||
- ✅ `actedBy` tracks actor
|
||||
- ✅ Indexes optimize entity and actor queries
|
||||
|
||||
#### DecisionAuditLog
|
||||
```prisma
|
||||
model DecisionAuditLog {
|
||||
id String @id @default(cuid())
|
||||
entityType String // 'STAGE' | 'ROUTING' | 'FILTERING' | 'ASSIGNMENT' | 'LIVE' | 'AWARD'
|
||||
entityId String
|
||||
eventType String // 'stage.transitioned' | 'routing.executed' | etc.
|
||||
payloadJson Json @db.JsonB
|
||||
actorId String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([entityType, entityId, createdAt])
|
||||
@@index([eventType, createdAt])
|
||||
}
|
||||
```
|
||||
|
||||
**Validation**:
|
||||
- ✅ Append-only audit log for all decisions
|
||||
- ✅ `eventType` aligns with event taxonomy
|
||||
- ✅ `payloadJson` captures full event context
|
||||
- ✅ `actorId` nullable for system events
|
||||
- ✅ Indexes optimize entity timeline and event queries
|
||||
|
||||
---
|
||||
|
||||
## 3. Constraint Rules Validation
|
||||
|
||||
### 3.1 Unique Constraints
|
||||
|
||||
| Model | Constraint | Status | Purpose |
|
||||
|-------|-----------|--------|---------|
|
||||
| Pipeline | `slug` | ✅ Valid | URL-friendly unique identifier |
|
||||
| Track | `(pipelineId, slug)` | ✅ Valid | Prevent duplicate slugs per pipeline |
|
||||
| Track | `(pipelineId, sortOrder)` | ❌ MISSING | **Correction needed**: Add unique constraint per domain model spec |
|
||||
| Stage | `(trackId, slug)` | ✅ Valid | Prevent duplicate slugs per track |
|
||||
| Stage | `(trackId, sortOrder)` | ✅ Valid | Prevent duplicate sort orders per track |
|
||||
| StageTransition | `(fromStageId, toStageId)` | ✅ Valid | Prevent duplicate transitions |
|
||||
| ProjectStageState | `(projectId, trackId, stageId)` | ✅ Valid | One state record per project/track/stage combo |
|
||||
| CohortProject | `(cohortId, projectId)` | ✅ Valid | Prevent duplicate cohort membership |
|
||||
|
||||
**Action Items for Phase 1**:
|
||||
- ✅ Most constraints align with spec
|
||||
- ⚠️ **Add**: Unique constraint on `Track(pipelineId, sortOrder)` per domain model requirement
|
||||
|
||||
### 3.2 Foreign Key Constraints
|
||||
|
||||
All FK relationships validated:
|
||||
- ✅ Cascade deletes properly configured
|
||||
- ✅ Referential integrity preserved
|
||||
- ✅ Nullable FKs appropriately marked
|
||||
|
||||
### 3.3 Index Priorities
|
||||
|
||||
All required indexes from domain model spec are present:
|
||||
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)`
|
||||
|
||||
**Additional indexes added**:
|
||||
- `Track(pipelineId, sortOrder)` - optimizes track ordering
|
||||
- `Stage(trackId, status)` - optimizes status filtering
|
||||
- `Stage(status, windowOpenAt, windowCloseAt)` - optimizes window queries
|
||||
- `Cohort(stageId, isOpen)` - optimizes active cohort queries
|
||||
- `CohortProject(cohortId, sortOrder)` - optimizes presentation ordering
|
||||
|
||||
---
|
||||
|
||||
## 4. JSON Field Contracts Validation
|
||||
|
||||
### 4.1 Pipeline.settingsJson
|
||||
**Purpose**: Pipeline-level configuration
|
||||
**Expected Schema**:
|
||||
```typescript
|
||||
{
|
||||
notificationDefaults?: {
|
||||
enabled: boolean;
|
||||
channels: string[];
|
||||
};
|
||||
aiConfig?: {
|
||||
filteringEnabled: boolean;
|
||||
assignmentEnabled: boolean;
|
||||
};
|
||||
// ... extensible
|
||||
}
|
||||
```
|
||||
**Status**: ✅ Flexible, extensible design
|
||||
|
||||
### 4.2 Stage.configJson
|
||||
**Purpose**: Stage-type-specific configuration (union type)
|
||||
**Expected Schemas** (by `stageType`):
|
||||
|
||||
**INTAKE**:
|
||||
```typescript
|
||||
{
|
||||
fileRequirements: FileRequirement[];
|
||||
deadlinePolicy: 'strict' | 'flexible';
|
||||
lateSubmissionAllowed: boolean;
|
||||
teamInvitePolicy: {...};
|
||||
}
|
||||
```
|
||||
|
||||
**FILTER**:
|
||||
```typescript
|
||||
{
|
||||
deterministicGates: Gate[];
|
||||
aiRubric: {...};
|
||||
confidenceThresholds: {...};
|
||||
manualQueuePolicy: {...};
|
||||
}
|
||||
```
|
||||
|
||||
**EVALUATION**:
|
||||
```typescript
|
||||
{
|
||||
criteria: Criterion[];
|
||||
assignmentStrategy: {...};
|
||||
reviewThresholds: {...};
|
||||
coiPolicy: {...};
|
||||
}
|
||||
```
|
||||
|
||||
**SELECTION**:
|
||||
```typescript
|
||||
{
|
||||
rankingSource: 'scores' | 'votes' | 'hybrid';
|
||||
finalistTarget: number;
|
||||
promotionMode: 'auto_top_n' | 'hybrid' | 'manual';
|
||||
overridePermissions: {...};
|
||||
}
|
||||
```
|
||||
|
||||
**LIVE_FINAL**:
|
||||
```typescript
|
||||
{
|
||||
sessionBehavior: {...};
|
||||
juryVotingConfig: {...};
|
||||
audienceVotingConfig: {...};
|
||||
cohortPolicy: {...};
|
||||
revealPolicy: {...};
|
||||
}
|
||||
```
|
||||
|
||||
**RESULTS**:
|
||||
```typescript
|
||||
{
|
||||
rankingWeightRules: {...};
|
||||
publicationPolicy: {...};
|
||||
winnerOverrideRules: {...};
|
||||
}
|
||||
```
|
||||
|
||||
**Status**: ✅ Complete coverage, all stage types defined
|
||||
|
||||
### 4.3 ProjectStageState.outcomeJson
|
||||
**Purpose**: Stage-specific outcome metadata
|
||||
**Expected Schema**:
|
||||
```typescript
|
||||
{
|
||||
scores?: Record<string, number>;
|
||||
decision?: string;
|
||||
feedback?: string;
|
||||
aiConfidence?: number;
|
||||
manualReview?: boolean;
|
||||
// ... extensible per stage type
|
||||
}
|
||||
```
|
||||
**Status**: ✅ Flexible, extensible design
|
||||
|
||||
### 4.4 StageTransition.guardJson / actionJson
|
||||
**Purpose**: Transition logic and side effects
|
||||
**Expected Schemas**:
|
||||
|
||||
**guardJson**:
|
||||
```typescript
|
||||
{
|
||||
conditions: Array<{
|
||||
field: string;
|
||||
operator: 'eq' | 'gt' | 'lt' | 'in' | 'exists';
|
||||
value: any;
|
||||
}>;
|
||||
requireAll: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
**actionJson**:
|
||||
```typescript
|
||||
{
|
||||
actions: Array<{
|
||||
type: 'notify' | 'update_field' | 'emit_event';
|
||||
config: any;
|
||||
}>;
|
||||
}
|
||||
```
|
||||
**Status**: ✅ Provides transition programmability
|
||||
|
||||
### 4.5 RoutingRule.predicateJson
|
||||
**Purpose**: Rule matching logic
|
||||
**Expected Schema**:
|
||||
```typescript
|
||||
{
|
||||
conditions: Array<{
|
||||
field: string; // e.g., 'project.category', 'project.tags'
|
||||
operator: 'eq' | 'in' | 'contains' | 'matches';
|
||||
value: any;
|
||||
}>;
|
||||
matchAll: boolean;
|
||||
}
|
||||
```
|
||||
**Status**: ✅ Deterministic rule matching
|
||||
|
||||
---
|
||||
|
||||
## 5. Data Initialization Rules Validation
|
||||
|
||||
### 5.1 Seed Requirements
|
||||
|
||||
**From Phase 1 spec**:
|
||||
- ✅ Every seeded project must start with one intake-stage state
|
||||
- ✅ Seed must include main track plus at least two award tracks with different routing modes
|
||||
- ✅ Seed must include representative roles: admins, jury, applicants, observer, audience contexts
|
||||
|
||||
**Validation**:
|
||||
- Seed requirements are clear and achievable
|
||||
- Will be implemented in `prisma/seed.ts` during Phase 1
|
||||
|
||||
### 5.2 Integrity Checks
|
||||
|
||||
**Required checks** (from schema-spec.md):
|
||||
- ✅ No orphan states
|
||||
- ✅ No invalid transition targets across pipelines
|
||||
- ✅ No duplicate active state rows for same `(project, track, stage)`
|
||||
|
||||
**Validation**:
|
||||
- Integrity check SQL will be created in Phase 1
|
||||
- Constraints and indexes prevent most integrity violations
|
||||
|
||||
---
|
||||
|
||||
## 6. Compatibility with Existing Models
|
||||
|
||||
### 6.1 Models That Remain Unchanged
|
||||
- ✅ `User` - No changes needed
|
||||
- ✅ `Program` - Gains `Pipeline` relation
|
||||
- ✅ `Project` - Gains `ProjectStageState` relation, deprecates `roundId`
|
||||
- ✅ `SpecialAward` - Gains `Track` relation
|
||||
- ✅ `Evaluation` - No changes to core model
|
||||
- ✅ `Assignment` - May need `stageId` addition (Phase 2)
|
||||
|
||||
### 6.2 Models to be Deprecated (Phase 6)
|
||||
- ⚠️ `Round` - Replaced by `Pipeline` + `Track` + `Stage`
|
||||
- ⚠️ Round-specific relations will be refactored
|
||||
|
||||
### 6.3 Integration Points
|
||||
- ✅ `User.role` extends to include `AWARD_MASTER` and `AUDIENCE`
|
||||
- ✅ `Program` gains `pipelines` relation
|
||||
- ✅ `Project` gains `projectStageStates` relation
|
||||
- ✅ `SpecialAward` gains `track` relation
|
||||
|
||||
---
|
||||
|
||||
## 7. Validation Summary
|
||||
|
||||
### ✅ Approved Elements
|
||||
1. All 7 new canonical enums are complete and unambiguous
|
||||
2. All 12 new core models align with domain model spec
|
||||
3. All unique constraints match spec requirements (1 minor correction needed)
|
||||
4. All foreign key relationships properly defined
|
||||
5. All required indexes present (plus beneficial additions)
|
||||
6. JSON field contracts provide flexibility and extensibility
|
||||
7. Compatibility with existing models maintained
|
||||
|
||||
### ⚠️ Corrections Needed for Phase 1
|
||||
1. **Track**: Add unique constraint on `(pipelineId, sortOrder)` to match spec
|
||||
2. **UserRole**: Extend enum to add `AWARD_MASTER` and `AUDIENCE` values
|
||||
|
||||
### 📋 Action Items for Phase 1
|
||||
- [ ] Implement all 7 new enums in `prisma/schema.prisma`
|
||||
- [ ] Implement all 12 new models with proper constraints
|
||||
- [ ] Extend `UserRole` enum with new values
|
||||
- [ ] Add unique constraint on `Track(pipelineId, sortOrder)`
|
||||
- [ ] Verify all indexes are created
|
||||
- [ ] Create seed data with required representative examples
|
||||
- [ ] Implement integrity check SQL queries
|
||||
|
||||
---
|
||||
|
||||
## 8. Conclusion
|
||||
|
||||
**Status**: ✅ **DOMAIN MODEL VALIDATED AND APPROVED**
|
||||
|
||||
The proposed canonical domain model is architecturally sound, complete, and ready for implementation. All entities, enums, and constraints have been validated against both the design specification and the current MOPC codebase.
|
||||
|
||||
**Key Strengths**:
|
||||
- Explicit state machine eliminates implicit round progression logic
|
||||
- First-class award tracks enable flexible routing and governance
|
||||
- JSON config fields provide extensibility without schema migrations
|
||||
- Comprehensive audit trail ensures governance and explainability
|
||||
- Index strategy optimizes common query patterns
|
||||
|
||||
**Minor Corrections**:
|
||||
- 1 unique constraint addition needed (`Track.sortOrder`)
|
||||
- 2 enum values to be added to existing `UserRole`
|
||||
|
||||
**Next Step**: Proceed to Phase 1 schema implementation with confidence that the domain model is solid.
|
||||
|
||||
---
|
||||
|
||||
**Signed**: Claude Sonnet 4.5
|
||||
**Date**: 2026-02-12
|
||||
Reference in New Issue
Block a user