Competition/Round architecture: full platform rewrite (Phases 1-9)
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
Replace Pipeline/Stage system with Competition/Round architecture. New schema: Competition, Round (7 types), JuryGroup, AssignmentPolicy, ProjectRoundState, DeliberationSession, ResultLock, SubmissionWindow. New services: round-engine, round-assignment, deliberation, result-lock, submission-manager, competition-context, ai-prompt-guard. Full admin/jury/applicant/mentor UI rewrite. AI prompt hardening with structured prompts, retry logic, and injection detection. All legacy pipeline/stage code removed. 4 new migrations + seed aligned. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
248
docs/unified-architecture-redesign/05-special-awards.md
Normal file
248
docs/unified-architecture-redesign/05-special-awards.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Special Awards
|
||||
|
||||
## Overview
|
||||
|
||||
Special awards run alongside the main competition flow, typically activating during or after the Jury 2 evaluation round (R5). Each award has its own jury, document requirements, review window, and selection process. Awards do NOT use the deliberation model — they are decided by their own jury/judge mechanism.
|
||||
|
||||
---
|
||||
|
||||
## Award Routing Modes
|
||||
|
||||
Every special award operates in one of two configurable modes:
|
||||
|
||||
### Mode A: SEPARATE_POOL (Pull-Out)
|
||||
|
||||
Projects are filtered into a dedicated award pool. The award may:
|
||||
- **Pull projects out** of the main competition pool, OR
|
||||
- **Keep projects in both** the main pool and the award pool
|
||||
|
||||
Pull-out requires **admin confirmation** (`routingConfirmationMode: ADMIN_CONFIRMED`). The admin reviews which projects are pulled out and approves before the pull-out takes effect.
|
||||
|
||||
```
|
||||
Main Pool ──┬──→ continues in main competition
|
||||
└──→ [admin confirms] ──→ Award Pool ──→ Award Review ──→ Award Winner
|
||||
```
|
||||
|
||||
### Mode B: STAY_IN_MAIN (Dual Track)
|
||||
|
||||
Projects remain in the main competition but are flagged as "eligible for award." The award evaluation runs in parallel with the main flow.
|
||||
|
||||
```
|
||||
Main Pool ──→ continues in main competition
|
||||
│
|
||||
└──→ flagged "eligible" ──→ Award Review ──→ Award Winner
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Award Mini-Pipeline
|
||||
|
||||
Each special award has its own mini-pipeline:
|
||||
|
||||
1. **Filtering** → AI screens eligible projects based on award criteria
|
||||
2. **Review** → Award jury evaluates eligible projects
|
||||
3. **Selection** → Winner(s) selected by jury vote or single-judge decision
|
||||
|
||||
This mini-pipeline is independent of the main competition rounds. It has its own:
|
||||
- **Jury** (or reuses judges from main juries, with overlap allowed)
|
||||
- **Document requirements** (if the award needs specific docs beyond main submissions)
|
||||
- **Review window** (own start/end dates)
|
||||
- **Selection process** (jury vote or single-judge)
|
||||
|
||||
---
|
||||
|
||||
## Data Model
|
||||
|
||||
### SpecialAward
|
||||
|
||||
```prisma
|
||||
model SpecialAward {
|
||||
id String @id @default(cuid())
|
||||
competitionId String
|
||||
name String
|
||||
description String?
|
||||
|
||||
// Routing
|
||||
routingMode AwardRoutingMode // STAY_IN_MAIN | SEPARATE_POOL
|
||||
pullOutBehavior PullOutBehavior? // REMOVE_FROM_MAIN | KEEP_IN_BOTH (only for SEPARATE_POOL)
|
||||
routingConfirmationMode RoutingConfirmation @default(ADMIN_CONFIRMED)
|
||||
|
||||
// Eligibility
|
||||
eligibilityMode AwardEligibilityMode // AI_SUGGESTED | MANUAL | ALL_ELIGIBLE | ROUND_BASED
|
||||
eligibilityCriteria Json? // AI screening criteria (if AI_SUGGESTED)
|
||||
eligibilityRoundId String? // filter from this round's output (if ROUND_BASED)
|
||||
|
||||
// Jury
|
||||
juryGroupId String? // dedicated jury group (null = single judge)
|
||||
|
||||
// Single judge mode
|
||||
winnerDecisionMode WinnerDecisionMode @default(JURY_VOTE)
|
||||
singleJudgeUserId String? // only if winnerDecisionMode = SINGLE_JUDGE
|
||||
|
||||
// Doc requirements
|
||||
requiresAdditionalDocs Boolean @default(false)
|
||||
docRequirements Json? // additional file slot definitions
|
||||
|
||||
// Review window
|
||||
reviewWindowStart DateTime?
|
||||
reviewWindowEnd DateTime?
|
||||
|
||||
// Audience voting
|
||||
audienceVotingEnabled Boolean @default(false)
|
||||
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
competition Competition @relation(...)
|
||||
juryGroup JuryGroup? @relation(...)
|
||||
winners AwardWinner[]
|
||||
|
||||
@@index([competitionId])
|
||||
}
|
||||
```
|
||||
|
||||
### AwardWinner
|
||||
|
||||
```prisma
|
||||
model AwardWinner {
|
||||
id String @id @default(cuid())
|
||||
awardId String
|
||||
projectId String
|
||||
rank Int @default(1) // 1 = winner, 2+ = runner-up
|
||||
decidedById String // judge or admin who confirmed
|
||||
decisionMode WinnerDecisionMode
|
||||
reason String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
award SpecialAward @relation(...)
|
||||
project Project @relation(...)
|
||||
|
||||
@@unique([awardId, projectId])
|
||||
}
|
||||
```
|
||||
|
||||
### Supporting Enums
|
||||
|
||||
```prisma
|
||||
enum AwardRoutingMode {
|
||||
STAY_IN_MAIN // Mode B: projects stay in main pool
|
||||
SEPARATE_POOL // Mode A: projects enter dedicated pool
|
||||
}
|
||||
|
||||
enum PullOutBehavior {
|
||||
REMOVE_FROM_MAIN // pulled out of main competition
|
||||
KEEP_IN_BOTH // in both main and award pools
|
||||
}
|
||||
|
||||
enum RoutingConfirmation {
|
||||
ADMIN_CONFIRMED // admin must approve pull-out
|
||||
AUTOMATIC // pull-out happens automatically on eligibility
|
||||
}
|
||||
|
||||
enum AwardEligibilityMode {
|
||||
AI_SUGGESTED // AI screens projects against criteria
|
||||
MANUAL // admin manually selects eligible projects
|
||||
ALL_ELIGIBLE // all projects in the competition are eligible
|
||||
ROUND_BASED // projects that passed a specific round are eligible
|
||||
}
|
||||
|
||||
enum WinnerDecisionMode {
|
||||
JURY_VOTE // jury evaluates and votes
|
||||
SINGLE_JUDGE // one designated judge decides
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Eligibility & Filtering
|
||||
|
||||
Award eligibility is determined by the `eligibilityMode`:
|
||||
|
||||
| Mode | How Projects Become Eligible |
|
||||
|------|------------------------------|
|
||||
| `AI_SUGGESTED` | AI screens all projects against the award's `eligibilityCriteria`. Uses the existing AI screening system. |
|
||||
| `MANUAL` | Admin manually flags projects as eligible for this award. |
|
||||
| `ALL_ELIGIBLE` | Every project in the competition is automatically eligible. |
|
||||
| `ROUND_BASED` | Projects that passed a specific round (e.g., filtering, Jury 1) are eligible. |
|
||||
|
||||
For `AI_SUGGESTED`, the filtering uses the same AI screening infrastructure as the main R2 filtering round, just with award-specific criteria.
|
||||
|
||||
---
|
||||
|
||||
## Per-Award Jury
|
||||
|
||||
Each award can have its own `JuryGroup`:
|
||||
- Members can overlap with main juries (same judge on Jury 2 and Innovation Award jury)
|
||||
- Independent cap and assignment configuration
|
||||
- Own scoring rubric if needed
|
||||
|
||||
For simpler awards, `SINGLE_JUDGE` mode allows one designated judge to make the decision directly.
|
||||
|
||||
---
|
||||
|
||||
## Per-Award Document Requirements
|
||||
|
||||
If `requiresAdditionalDocs` is true, the award defines additional file slots that eligible projects must submit:
|
||||
|
||||
```typescript
|
||||
type AwardDocRequirement = {
|
||||
slotKey: string // e.g., "innovation_statement"
|
||||
label: string // "Innovation Impact Statement"
|
||||
required: boolean
|
||||
maxFileSize: number // bytes
|
||||
acceptedTypes: string[] // ["application/pdf", "video/mp4"]
|
||||
}
|
||||
```
|
||||
|
||||
These are separate from the main submission windows. Award docs are uploaded through the applicant's award-specific section.
|
||||
|
||||
---
|
||||
|
||||
## Award Review Window
|
||||
|
||||
Each award has its own review window (start/end dates) that is independent of the main competition schedule. The review window:
|
||||
- Can overlap with Jury 2 evaluation or run after it
|
||||
- Shows countdown on the award jury's dashboard
|
||||
- Triggers email reminders as the deadline approaches
|
||||
|
||||
---
|
||||
|
||||
## No Deliberation for Awards
|
||||
|
||||
Special awards are decided by their own jury/judge mechanism:
|
||||
- **JURY_VOTE**: Award jury members evaluate and vote. Simple majority or highest score wins.
|
||||
- **SINGLE_JUDGE**: Designated judge reviews and selects the winner(s).
|
||||
|
||||
There is no `DeliberationSession` for awards. The award winner is confirmed by the deciding jury/judge and recorded as an `AwardWinner`.
|
||||
|
||||
---
|
||||
|
||||
## Audience Voting for Awards
|
||||
|
||||
If `audienceVotingEnabled` is true on an award:
|
||||
- Audience can vote for their preferred project within the award pool
|
||||
- Audience vote can influence the award decision (configurable weight)
|
||||
- Audience vote results are visible to the award jury during their review
|
||||
|
||||
---
|
||||
|
||||
## Admin Controls
|
||||
|
||||
- **Create/edit awards**: name, mode, eligibility, jury, doc requirements, review window
|
||||
- **Confirm pull-out**: for SEPARATE_POOL mode, admin reviews and approves which projects are pulled
|
||||
- **Override eligibility**: admin can add/remove projects from award eligibility at any time
|
||||
- **Override winner**: admin can override the jury/judge decision with audit trail
|
||||
- **View award status**: see all awards, their eligible projects, jury progress, and winners
|
||||
|
||||
All admin actions on awards are logged to `DecisionAuditLog`.
|
||||
|
||||
---
|
||||
|
||||
## Integration Points
|
||||
|
||||
- **R5 (Jury 2)**: Awards typically activate during or after Jury 2. Award filtering runs alongside Jury 2 evaluation.
|
||||
- **Live Finals (R7)**: Award winners may be announced during the live finals ceremony.
|
||||
- **Reports**: Award selections, jury decisions, and audit trails are included in competition reports.
|
||||
|
||||
See [03-competition-flow.md](./03-competition-flow.md) for how awards fit into the overall competition flow.
|
||||
Reference in New Issue
Block a user