# 07: SUBMISSION Round — Multi-Window Document Collection System

**Document Version**: 2.0
**Last Updated**: 2026-02-15
**Status**: Architecture Design (Redesign)

---

## Table of Contents

1. [Purpose & Position in Flow](#1-purpose--position-in-flow)
2. [Multi-Round Submission Architecture](#2-multi-round-submission-architecture)
3. [SubmissionConfig Shape](#3-submissionconfig-shape)
4. [Applicant Experience (Detailed)](#4-applicant-experience-detailed)
5. [Jury Cross-Round Visibility (Detailed)](#5-jury-cross-round-visibility-detailed)
6. [Admin Experience](#6-admin-experience)
7. [API Changes](#7-api-changes)
8. [File Promotion from Mentoring](#8-file-promotion-from-mentoring)
9. [Edge Cases](#9-edge-cases)
10. [Implementation Checklist](#10-implementation-checklist)

---

## 1. Purpose & Position in Flow

### 1.1 Core Problem Statement

**Current System Gap**: The MOPC platform currently only supports **one** submission window tied to the INTAKE round. There is no mechanism to:

1. Request **additional documents** from advancing teams mid-competition
2. **Lock previous submissions** as read-only while collecting new materials
3. Keep **Round 1 documents intact** while teams submit Round 2 materials
4. Control which **jury rounds see which documents**

**Real-World Impact**:
- Semi-finalists can't be asked for updated pitch decks without replacing Round 1 materials
- Finalists can't submit presentation materials separately from initial applications
- If teams update files, original submissions are lost (no audit trail)
- Organizers resort to email-based document collection (breaks platform integrity)

### 1.2 SUBMISSION Round Solution

The **SUBMISSION** round is a NEW round type that:

1. **Opens a second (or subsequent) submission window** for advancing projects
2. **Locks previous windows to read-only** for applicants (admin retains full control)
3. **Collects different file requirements** per competition stage
4. **Controls jury visibility** via RoundSubmissionVisibility records
5. **Maintains complete audit trail** across all submission phases

### 1.3 Position in Competition Flow

```
┌──────────────────────────────────────────────────────────────────┐
│                      FULL COMPETITION FLOW                       │
└──────────────────────────────────────────────────────────────────┘

Round 1: INTAKE
├─ Creates SubmissionWindow 1: "Application Documents"
├─ Projects submit: Pitch Deck, Budget, Team CV
├─ Window State: OPEN (Feb 1 - Mar 1)
└─ All applicants participate (150 projects)

Round 2: FILTERING
├─ Admin/AI screens applications using Window 1 documents
├─ 50 projects advance with status = PASSED
└─ Window 1 remains OPEN (teams can still edit)

Round 3: EVALUATION (Jury 1)
├─ Jury evaluates 50 projects using Window 1 documents
├─ Visibility: Window 1 ONLY
├─ 20 projects advance with status = PASSED
└─ Window 1 remains OPEN

Round 4: SUBMISSION ◄──── THIS IS THE NEW ROUND TYPE
├─ Creates SubmissionWindow 2: "Semi-finalist Materials"
├─ When Round 4 starts:
│  ├─ Window 1 LOCKS automatically (read-only for applicants)
│  ├─ Window 2 OPENS (Apr 1 - Apr 15)
│  ├─ Only 20 PASSED projects from Round 3 can submit
│  └─ Email notifications sent to eligible teams
├─ New requirements:
│  ├─ Updated Pitch Deck (required)
│  ├─ Video Pitch (required, max 100MB)
│  ├─ Financial Projections (required)
│  └─ Team Photos (optional)
└─ Deadline policy: GRACE (48 hours after Apr 15)

Round 5: EVALUATION (Jury 2)
├─ Jury evaluates 20 projects using BOTH Window 1 + Window 2
├─ Visibility: Window 1 AND Window 2
├─ UI shows two tabs: "Round 1 Docs" | "Round 2 Docs"
├─ 10 projects advance with status = PASSED
└─ Window 2 LOCKS when Round 5 starts

Round 6: SUBMISSION (Optional Third Window)
├─ Creates SubmissionWindow 3: "Finalist Presentations"
├─ Only 10 PASSED projects from Round 5 can submit
├─ New requirements:
│  ├─ Final Pitch Deck (required)
│  ├─ 3-Minute Video (required)
│  └─ Impact Report (required)
└─ Window 1 + 2 remain LOCKED, Window 3 OPEN

Round 7: LIVE_FINAL
└─ Top 10 present live using Window 3 materials
```

**Key Characteristics**:

| Feature | Behavior |
|---------|----------|
| **Multiple Windows** | Each SUBMISSION round creates exactly ONE new SubmissionWindow |
| **Sequential Locking** | When Window N opens, Window N-1 locks for applicants |
| **Eligibility Filtering** | Only projects with specific statuses from previous round can submit |
| **Independent Requirements** | Each window has its own file requirements (not shared) |
| **Cumulative Visibility** | Later EVALUATION rounds can see multiple windows simultaneously |
| **Admin Override** | Admins always have full control regardless of lock state |

### 1.4 When to Use SUBMISSION Rounds

| Scenario | Use SUBMISSION? | Explanation |
|----------|----------------|-------------|
| **Single-round competition** (one evaluation) | ❌ No | One INTAKE window is sufficient |
| **Two-stage competition** (semi-final + final) | ✅ Yes | INTAKE → EVALUATION → **SUBMISSION** → EVALUATION |
| **Three-stage competition** (screening + semi + final) | ✅ Yes (2x) | INTAKE → EVAL → **SUBMISSION** → EVAL → **SUBMISSION** → EVAL |
| **Requesting updated docs from same pool** | ❌ Maybe | Consider MENTORING with file promotion instead |
| **Post-award deliverables** (winner docs) | ✅ Yes | Create SUBMISSION round after awards announced |
| **Mid-competition clarifications** | ❌ No | Use comments or mentoring workspace |

### 1.5 Relationship to Other Round Types

**SUBMISSION vs INTAKE**:
- **INTAKE** = First submission window (all applicants, competition start)
- **SUBMISSION** = Subsequent submission windows (filtered subset, mid-competition)
- **Both create SubmissionWindow records** (INTAKE creates Window 1, SUBMISSION creates Window 2+)

**SUBMISSION vs EVALUATION**:
- **SUBMISSION** = Document collection phase (no scoring, just uploads)
- **EVALUATION** = Assessment phase (jury scores projects using submitted docs)
- **EVALUATION rounds declare which windows they can see** via RoundSubmissionVisibility

**SUBMISSION vs MENTORING**:
- **MENTORING** = Collaborative workspace (mentor + team iterate on documents)
- **SUBMISSION** = Official competition documents (locked after deadline)
- **Files can be promoted** from MENTORING → SUBMISSION (see Section 8)

**SUBMISSION vs FILTERING**:
- **FILTERING** = Automated screening using existing documents
- **SUBMISSION** = New document collection opportunity
- **FILTERING typically comes BEFORE** SUBMISSION (screen first, then request more docs)

---

## 2. Multi-Round Submission Architecture

### 2.1 Data Model Overview

```prisma
// NEW: SubmissionWindow model
model SubmissionWindow {
  id                String   @id @default(cuid())
  competitionId     String
  roundId           String   @unique  // Each round creates max ONE window
  name              String   // "Application Docs", "Semi-finalist Materials"
  description       String?  @db.Text

  // Timing
  openDate          DateTime
  closeDate         DateTime

  // Deadline policy
  latePolicy        LateSubmissionPolicy  // HARD | FLAG | GRACE
  gracePeriodHours  Int?     // If latePolicy = GRACE

  // Locking
  lockDate          DateTime? // When window becomes read-only for applicants
  isLocked          Boolean  @default(false)

  // Relations
  competition       Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
  round             Round @relation(fields: [roundId], references: [id], onDelete: Cascade)

  fileRequirements  SubmissionFileRequirement[]
  projectFiles      ProjectFile[]
  visibleToRounds   RoundSubmissionVisibility[]

  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt

  @@unique([competitionId, roundId])
  @@index([competitionId])
  @@index([openDate])
  @@index([closeDate])
}

enum LateSubmissionPolicy {
  HARD   // Reject submissions after closeDate
  FLAG   // Accept late submissions but mark as late
  GRACE  // Allow submissions during grace period, then hard reject
}

// NEW: SubmissionFileRequirement model
model SubmissionFileRequirement {
  id                  String   @id @default(cuid())
  submissionWindowId  String
  label               String   // "Pitch Deck", "Budget Spreadsheet"
  description         String?  @db.Text
  isRequired          Boolean  @default(true)
  allowedFileTypes    String[] // ["pdf", "pptx", "docx"]
  maxSizeMB           Int      @default(10)
  displayOrder        Int

  submissionWindow    SubmissionWindow @relation(fields: [submissionWindowId], references: [id], onDelete: Cascade)
  projectFiles        ProjectFile[]

  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt

  @@index([submissionWindowId])
  @@index([displayOrder])
}

// NEW: RoundSubmissionVisibility model
model RoundSubmissionVisibility {
  id                  String   @id @default(cuid())
  evaluationRoundId   String   // Which EVALUATION round can see docs
  submissionWindowId  String   // Which SubmissionWindow's docs
  displayLabel        String   // "Round 1 Documents", "Semi-final Submissions"
  displayOrder        Int

  evaluationRound     Round @relation("EvaluationRoundVisibility", fields: [evaluationRoundId], references: [id], onDelete: Cascade)
  submissionWindow    SubmissionWindow @relation(fields: [submissionWindowId], references: [id], onDelete: Cascade)

  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt

  @@unique([evaluationRoundId, submissionWindowId])
  @@index([evaluationRoundId])
  @@index([submissionWindowId])
}

// UPDATED: ProjectFile model (add submissionWindowId)
model ProjectFile {
  id                  String   @id @default(cuid())
  projectId           String
  submissionWindowId  String   // NEW: Links to SubmissionWindow
  requirementId       String?  // NEW: Links to SubmissionFileRequirement

  filename            String
  mimeType            String
  sizeBytes           BigInt
  storagePath         String
  uploadedBy          String
  uploadedAt          DateTime @default(now())

  isLate              Boolean  @default(false)

  // Versioning
  supersededBy        String?  // Points to newer version of this file
  supersededAt        DateTime?

  // Promotion from mentoring
  promotedFrom        String?  // Points to MentorFile.id
  promotedAt          DateTime?

  project             Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  submissionWindow    SubmissionWindow @relation(fields: [submissionWindowId], references: [id], onDelete: Cascade)
  requirement         SubmissionFileRequirement? @relation(fields: [requirementId], references: [id], onDelete: SetNull)
  uploadedByUser      User @relation(fields: [uploadedBy], references: [id])

  @@index([projectId])
  @@index([submissionWindowId])
  @@index([requirementId])
  @@index([uploadedBy])
}

// UPDATED: Round model (add submissionWindowId)
model Round {
  id                  String   @id @default(cuid())
  competitionId       String
  type                RoundType
  name                String
  description         String?  @db.Text
  displayOrder        Int

  // For SUBMISSION rounds
  submissionWindowId  String?  @unique  // Links to SubmissionWindow

  configJson          Json?    @db.JsonB  // Stores SubmissionConfig for SUBMISSION rounds

  // ... other fields ...

  submissionWindow    SubmissionWindow?
  visibleWindows      RoundSubmissionVisibility[] @relation("EvaluationRoundVisibility")
}
```

### 2.2 Window Lifecycle States

Each SubmissionWindow progresses through these states:

```
┌─────────────┐
│  PENDING    │ Created but openDate not reached
│             │ - Not visible to applicants
│             │ - Admin can edit requirements freely
│             │ - isLocked = false, lockDate = null
└──────┬──────┘
       │ openDate arrives (Round transitions to ACTIVE)
       ▼
┌─────────────┐
│    OPEN     │ Accepting submissions
│             │ - Applicants can upload/replace/delete files
│             │ - Admin can edit requirements (with warnings if teams already submitted)
│             │ - Previous windows may be locked
│             │ - isLocked = false
└──────┬──────┘
       │ closeDate arrives
       ▼
┌─────────────┐
│   CLOSED    │ Past deadline (policy-dependent)
│             │ - latePolicy = HARD: No uploads allowed
│             │ - latePolicy = FLAG: Uploads allowed, marked as late
│             │ - latePolicy = GRACE: Uploads allowed until lockDate
│             │ - isLocked = depends on policy
└──────┬──────┘
       │ lockDate arrives (if GRACE) OR admin manually locks
       ▼
┌─────────────┐
│   LOCKED    │ Read-only for applicants, full control for admins
│             │ - Applicants: view/download only, no uploads/deletes
│             │ - Admins: can still upload/replace/delete on behalf
│             │ - Juries: view-only (if visibility configured)
│             │ - isLocked = true
└─────────────┘
```

**State Transitions**:

| From | To | Trigger | Side Effects |
|------|----|---------| -------------|
| PENDING | OPEN | `openDate` reached | Lock previous windows (if config), notify eligible teams |
| OPEN | CLOSED | `closeDate` reached | Start grace period (if GRACE policy) |
| CLOSED | LOCKED | `lockDate` reached OR admin action | Final state, no more applicant changes |

### 2.3 Multi-Window Coordination Example

**Scenario**: MOPC 2026 with 3 evaluation rounds

```
Competition: MOPC 2026
├─ Round 1: INTAKE
│  └─ SubmissionWindow 1: "Application Documents"
│     ├─ Open: Jan 1 - Feb 1
│     ├─ Close: Feb 1
│     ├─ Late Policy: GRACE (72 hours → lock Feb 4)
│     ├─ Requirements:
│     │  ├─ Pitch Deck (PDF, required, max 10MB)
│     │  ├─ Budget (XLSX/PDF, required, max 5MB)
│     │  └─ Team CV (PDF, optional, max 5MB)
│     └─ Status: OPEN (150 projects submit)
│
├─ Round 2: FILTERING
│  └─ Screens 150 applications → 50 advance (status = PASSED)
│
├─ Round 3: EVALUATION (Jury 1)
│  ├─ Visibility: Window 1 ONLY
│  ├─ Jury sees:
│  │  └─ Tab: "Application Documents" (Pitch, Budget, CV)
│  └─ 20 projects advance (status = PASSED)
│
├─ Round 4: SUBMISSION ◄──── NEW ROUND TYPE
│  └─ SubmissionWindow 2: "Semi-finalist Materials"
│     ├─ Opens: Mar 1 (Window 1 auto-locks at this moment)
│     ├─ Close: Mar 15
│     ├─ Late Policy: HARD (no late submissions)
│     ├─ Eligible: 20 projects with status=PASSED from Round 3
│     ├─ Requirements:
│     │  ├─ Updated Pitch Deck (PDF, required, max 15MB)
│     │  ├─ Video Pitch (MP4/MOV, required, max 100MB)
│     │  ├─ Financial Projections (XLSX/PDF, required, max 10MB)
│     │  └─ Team Photos (JPG/PNG, optional, max 5MB each)
│     └─ Status: OPEN (20 eligible projects can submit)
│
├─ Round 5: EVALUATION (Jury 2)
│  ├─ Visibility: Window 1 AND Window 2
│  ├─ Jury sees:
│  │  ├─ Tab 1: "Round 1 Application" (Pitch, Budget, CV from Jan)
│  │  └─ Tab 2: "Semi-final Materials" (Updated Pitch, Video, Financials from Mar)
│  └─ 10 projects advance (status = PASSED)
│
├─ Round 6: SUBMISSION ◄──── SECOND SUBMISSION ROUND
│  └─ SubmissionWindow 3: "Finalist Presentations"
│     ├─ Opens: Apr 1 (Window 2 auto-locks)
│     ├─ Close: Apr 10
│     ├─ Late Policy: FLAG (late submissions marked)
│     ├─ Eligible: 10 projects with status=PASSED from Round 5
│     ├─ Requirements:
│     │  ├─ Final Pitch Deck (PDF/PPTX, required, max 20MB)
│     │  ├─ 3-Minute Video (MP4, required, max 150MB)
│     │  └─ Impact Report (PDF/DOCX, required, max 10MB)
│     └─ Status: OPEN (10 eligible projects can submit)
│
└─ Round 7: LIVE_FINAL
   ├─ Visibility: Window 1, Window 2, AND Window 3
   ├─ Jury sees:
   │  ├─ Tab 1: "Original Application" (Jan docs)
   │  ├─ Tab 2: "Semi-final Submission" (Mar docs)
   │  └─ Tab 3: "Finalist Presentation" (Apr docs)
   └─ 3 winners selected
```

**Key Rules**:

1. **One Window Per Round**: Each SUBMISSION/INTAKE round creates exactly ONE SubmissionWindow
2. **Never Delete Windows**: Windows persist forever (audit trail), only lock/unlock
3. **Applicant Access: One-Way Lock**: Can only go from READ-WRITE → READ-ONLY (never reverses)
4. **Admin Access: Always Full**: Admins can upload/delete in any window regardless of lock state
5. **Jury Visibility: Explicit Declaration**: Must create RoundSubmissionVisibility records

### 2.4 Locking Mechanism Implementation

**When a new SubmissionWindow opens**:

```typescript
async function openSubmissionWindow(windowId: string, ctx: Context) {
  const window = await ctx.prisma.submissionWindow.findUnique({
    where: { id: windowId },
    include: {
      round: {
        select: {
          configJson: true,
          competitionId: true
        }
      }
    }
  });

  if (!window) throw new Error("Window not found");

  const config = window.round.configJson as SubmissionConfig;

  // Step 1: Set this window's openDate to now
  await ctx.prisma.submissionWindow.update({
    where: { id: windowId },
    data: { openDate: new Date() }
  });

  // Step 2: Lock previous windows if config says so
  if (config.lockPreviousWindows) {
    const allWindows = await ctx.prisma.submissionWindow.findMany({
      where: {
        competitionId: window.competitionId,
        openDate: { lt: new Date() }  // Opened before now
      },
      select: { id: true, isLocked: true }
    });

    for (const prevWindow of allWindows) {
      if (!prevWindow.isLocked) {
        await ctx.prisma.submissionWindow.update({
          where: { id: prevWindow.id },
          data: {
            isLocked: true,
            lockDate: new Date()
          }
        });
      }
    }
  }

  // Step 3: Notify eligible teams
  if (config.notifyEligibleTeams) {
    await notifyEligibleTeams(windowId, ctx);
  }

  // Step 4: Audit log
  await ctx.prisma.decisionAuditLog.create({
    data: {
      action: "SUBMISSION_WINDOW_OPENED",
      userId: ctx.session.user.id,
      entityType: "SubmissionWindow",
      entityId: windowId,
      metadata: {
        windowName: window.name,
        openDate: new Date(),
        previousWindowsLocked: config.lockPreviousWindows
      }
    }
  });
}
```

**Upload Permission Check**:

```typescript
async function checkUploadPermission(
  projectId: string,
  windowId: string,
  userId: string,
  ctx: Context
): Promise<{ allowed: boolean; reason?: string }> {
  const user = await ctx.prisma.user.findUnique({
    where: { id: userId },
    select: { role: true }
  });

  // Admins bypass all checks
  if (user?.role === "SUPER_ADMIN" || user?.role === "PROGRAM_ADMIN") {
    return { allowed: true };
  }

  // Check 1: User is applicant for this project?
  const project = await ctx.prisma.project.findFirst({
    where: {
      id: projectId,
      applicantId: userId
    }
  });

  if (!project) {
    return { allowed: false, reason: "Unauthorized: You do not own this project" };
  }

  // Check 2: Fetch window
  const window = await ctx.prisma.submissionWindow.findUnique({
    where: { id: windowId }
  });

  if (!window) {
    return { allowed: false, reason: "Submission window not found" };
  }

  // Check 3: Window locked?
  if (window.isLocked) {
    return { allowed: false, reason: "This submission window is now closed." };
  }

  const now = new Date();

  // Check 4: Window not yet open?
  if (now < window.openDate) {
    return { allowed: false, reason: "Submission window has not opened yet." };
  }

  // Check 5: Deadline enforcement
  if (now > window.closeDate) {
    switch (window.latePolicy) {
      case "HARD":
        return { allowed: false, reason: "Submission deadline has passed. No late submissions allowed." };

      case "FLAG":
        // Allow upload, will be marked as late
        return { allowed: true };

      case "GRACE":
        if (window.lockDate && now > window.lockDate) {
          return { allowed: false, reason: "Grace period has ended. Submissions are now closed." };
        }
        // Within grace period
        return { allowed: true };
    }
  }

  // All checks passed
  return { allowed: true };
}
```

### 2.5 File Organization by Window

**Database Structure**:

```typescript
// Project: proj_abc123
// Competition with 3 submission windows

// Window 1: Application Documents (Jan)
ProjectFile {
  id: "file_001"
  projectId: "proj_abc123"
  submissionWindowId: "window_1"
  requirementId: "req_pitch_deck_w1"
  filename: "OceanCleanup_Pitch.pdf"
  uploadedAt: "2026-01-25T14:30:00Z"
  uploadedBy: "applicant_user_id"
  isLate: false
}

ProjectFile {
  id: "file_002"
  projectId: "proj_abc123"
  submissionWindowId: "window_1"
  requirementId: "req_budget_w1"
  filename: "Budget_2026.xlsx"
  uploadedAt: "2026-02-01T09:15:00Z"
  uploadedBy: "applicant_user_id"
  isLate: false
}

// Window 2: Semi-finalist Materials (Mar)
ProjectFile {
  id: "file_003"
  projectId: "proj_abc123"
  submissionWindowId: "window_2"
  requirementId: "req_video_w2"
  filename: "Pitch_Video.mp4"
  uploadedAt: "2026-03-10T16:45:00Z"
  uploadedBy: "applicant_user_id"
  isLate: false
}

ProjectFile {
  id: "file_004"
  projectId: "proj_abc123"
  submissionWindowId: "window_2"
  requirementId: "req_updated_deck_w2"
  filename: "OceanCleanup_Pitch_v2.pdf"
  uploadedAt: "2026-03-15T23:59:00Z"
  uploadedBy: "admin_user_id"  // Admin uploaded on behalf
  isLate: false
}

// Window 3: Finalist Presentation (Apr)
ProjectFile {
  id: "file_005"
  projectId: "proj_abc123"
  submissionWindowId: "window_3"
  requirementId: "req_final_deck_w3"
  filename: "OceanCleanup_Final.pdf"
  uploadedAt: "2026-04-09T18:20:00Z"
  uploadedBy: "applicant_user_id"
  isLate: false
}

ProjectFile {
  id: "file_006"
  projectId: "proj_abc123"
  submissionWindowId: "window_3"
  requirementId: "req_impact_report_w3"
  filename: "Impact_Report.pdf"
  uploadedAt: "2026-04-11T10:30:00Z"  // After deadline (Apr 10)
  uploadedBy: "applicant_user_id"
  isLate: true  // Marked late (FLAG policy)
}
```

**Query Pattern for Jury View** (EVALUATION Round 2):

```typescript
// Fetch all visible files for a project in an evaluation round
const visibleWindows = await ctx.prisma.roundSubmissionVisibility.findMany({
  where: { evaluationRoundId: "eval_round_2" },
  include: {
    submissionWindow: {
      include: {
        fileRequirements: {
          orderBy: { displayOrder: "asc" }
        }
      }
    }
  },
  orderBy: { displayOrder: "asc" }
});

// Returns:
// [
//   {
//     id: "vis_1",
//     submissionWindow: {
//       id: "window_1",
//       name: "Application Documents",
//       fileRequirements: [...]
//     },
//     displayLabel: "Round 1 Application",
//     displayOrder: 1
//   },
//   {
//     id: "vis_2",
//     submissionWindow: {
//       id: "window_2",
//       name: "Semi-finalist Materials",
//       fileRequirements: [...]
//     },
//     displayLabel: "Semi-final Submissions",
//     displayOrder: 2
//   }
// ]

const windowIds = visibleWindows.map(v => v.submissionWindowId);

const files = await ctx.prisma.projectFile.findMany({
  where: {
    projectId: "proj_abc123",
    submissionWindowId: { in: windowIds },
    supersededBy: null  // Only current versions
  },
  include: {
    requirement: true,
    submissionWindow: true,
    uploadedByUser: {
      select: { name: true, role: true }
    }
  }
});

// Group by window
const filesByWindow = visibleWindows.map(vis => ({
  windowId: vis.submissionWindowId,
  windowName: vis.displayLabel,
  displayOrder: vis.displayOrder,
  files: files.filter(f => f.submissionWindowId === vis.submissionWindowId)
}));
```

---

## 3. SubmissionConfig Shape

### 3.1 Type Definition

```typescript
/**
 * Configuration for SUBMISSION round type
 * Stored in Round.configJson for rounds with type = "SUBMISSION"
 */
type SubmissionConfig = {
  /**
   * Which project statuses from the PREVIOUS round are eligible to submit
   *
   * Common values:
   * - ["PASSED"] → Only projects that passed previous evaluation
   * - ["PASSED", "CONDITIONAL"] → Passed + conditionally advanced
   * - ["WINNER", "FINALIST"] → For post-award deliverables
   *
   * Default: ["PASSED"]
   */
  eligibleStatuses: ProjectRoundStateValue[];

  /**
   * Send email + in-app notifications when submission window opens
   *
   * If true:
   * - Sends to all eligible project applicants
   * - Includes deadline, requirements list, upload link
   * - Uses template from notificationTemplate if provided
   *
   * Default: true
   */
  notifyEligibleTeams: boolean;

  /**
   * Lock all previous submission windows when this round starts
   *
   * If true:
   * - All windows with openDate < current window's openDate
   * - Set isLocked = true, lockDate = now
   * - Applicants can no longer upload/delete (read-only)
   * - Admins retain full control
   *
   * Default: true
   */
  lockPreviousWindows: boolean;

  /**
   * Optional: Custom email template for notifications
   *
   * Variables available:
   * - {projectName}, {teamName}, {deadline}, {windowName}
   * - {requirementsList}, {uploadUrl}
   */
  notificationTemplate?: {
    subject: string;
    bodyHtml: string;
    variables: Record<string, string>;
  };

  /**
   * Optional: Submission window configuration
   * (Can also be set separately via SubmissionWindow model)
   */
  windowConfig?: {
    name: string;
    description: string;
    openDate: string;  // ISO 8601
    closeDate: string; // ISO 8601
    latePolicy: "HARD" | "FLAG" | "GRACE";
    gracePeriodHours?: number;
  };

  /**
   * Optional: File requirements
   * (Can also be set separately via SubmissionFileRequirement model)
   */
  fileRequirements?: Array<{
    label: string;
    description?: string;
    isRequired: boolean;
    allowedFileTypes: string[];  // ["pdf", "docx", "mp4"]
    maxSizeMB: number;
    displayOrder: number;
  }>;
};
```

### 3.2 Example Configurations

**Example 1: Simple Semi-Finalist Submission**

```json
{
  "eligibleStatuses": ["PASSED"],
  "notifyEligibleTeams": true,
  "lockPreviousWindows": true,
  "windowConfig": {
    "name": "Semi-Finalist Documents",
    "description": "Congratulations on advancing! Please submit the following materials.",
    "openDate": "2026-03-01T00:00:00Z",
    "closeDate": "2026-03-15T23:59:59Z",
    "latePolicy": "HARD"
  },
  "fileRequirements": [
    {
      "label": "3-Minute Video Pitch",
      "description": "MP4 format, max 100MB. Introduce your team and demonstrate your solution.",
      "isRequired": true,
      "allowedFileTypes": ["mp4", "mov"],
      "maxSizeMB": 100,
      "displayOrder": 1
    },
    {
      "label": "Updated Pitch Deck",
      "description": "PDF format. Include any updates since your initial application.",
      "isRequired": true,
      "allowedFileTypes": ["pdf"],
      "maxSizeMB": 10,
      "displayOrder": 2
    },
    {
      "label": "Financial Projections",
      "description": "Excel or PDF. 3-year revenue and cost forecast with assumptions.",
      "isRequired": true,
      "allowedFileTypes": ["xlsx", "pdf"],
      "maxSizeMB": 5,
      "displayOrder": 3
    }
  ]
}
```

**Example 2: Flexible Finalist Submission with Grace Period**

```json
{
  "eligibleStatuses": ["PASSED", "CONDITIONAL"],
  "notifyEligibleTeams": true,
  "lockPreviousWindows": true,
  "windowConfig": {
    "name": "Finalist Presentation Materials",
    "description": "Final round submissions for live presentations.",
    "openDate": "2026-04-01T00:00:00Z",
    "closeDate": "2026-04-10T23:59:59Z",
    "latePolicy": "GRACE",
    "gracePeriodHours": 48
  },
  "fileRequirements": [
    {
      "label": "Final Pitch Deck",
      "description": "PDF or PowerPoint, max 20 slides",
      "isRequired": true,
      "allowedFileTypes": ["pdf", "pptx"],
      "maxSizeMB": 15,
      "displayOrder": 1
    },
    {
      "label": "Impact Report",
      "description": "Summary of expected environmental impact (PDF or Word)",
      "isRequired": true,
      "allowedFileTypes": ["pdf", "docx"],
      "maxSizeMB": 10,
      "displayOrder": 2
    },
    {
      "label": "Team Photo",
      "description": "High-resolution team photo for program materials (optional)",
      "isRequired": false,
      "allowedFileTypes": ["jpg", "png"],
      "maxSizeMB": 5,
      "displayOrder": 3
    }
  ],
  "notificationTemplate": {
    "subject": "🎉 You're a Finalist! Submit Your Final Materials",
    "bodyHtml": "<p>Dear {teamName},</p><p>Congratulations on reaching the finals!</p><p>Please submit your materials by <strong>{deadline}</strong>.</p>",
    "variables": {
      "teamName": "project.name",
      "deadline": "window.closeDate"
    }
  }
}
```

**Example 3: Post-Award Deliverables (Don't Lock Previous Windows)**

```json
{
  "eligibleStatuses": ["WINNER", "FINALIST"],
  "notifyEligibleTeams": true,
  "lockPreviousWindows": false,
  "windowConfig": {
    "name": "Winner Deliverables",
    "description": "Required documentation for prize disbursement and program promotion.",
    "openDate": "2026-06-01T00:00:00Z",
    "closeDate": "2026-06-30T23:59:59Z",
    "latePolicy": "FLAG"
  },
  "fileRequirements": [
    {
      "label": "W-9 Tax Form",
      "description": "Required for prize payment (US teams only)",
      "isRequired": true,
      "allowedFileTypes": ["pdf"],
      "maxSizeMB": 2,
      "displayOrder": 1
    },
    {
      "label": "High-Res Logo",
      "description": "Vector format (SVG preferred) or high-res PNG (min 2000px width)",
      "isRequired": true,
      "allowedFileTypes": ["svg", "png", "ai"],
      "maxSizeMB": 10,
      "displayOrder": 2
    },
    {
      "label": "Success Story",
      "description": "500-word story about your project for our website and press releases",
      "isRequired": true,
      "allowedFileTypes": ["pdf", "docx"],
      "maxSizeMB": 2,
      "displayOrder": 3
    },
    {
      "label": "Promotional Video",
      "description": "Optional: 1-2 minute video for social media",
      "isRequired": false,
      "allowedFileTypes": ["mp4", "mov"],
      "maxSizeMB": 200,
      "displayOrder": 4
    }
  ]
}
```

### 3.3 Validation Schema

```typescript
import { z } from "zod";

const submissionConfigSchema = z.object({
  eligibleStatuses: z.array(
    z.enum([
      "DRAFT",
      "SUBMITTED",
      "UNDER_REVIEW",
      "PASSED",
      "FAILED",
      "CONDITIONAL",
      "WITHDRAWN",
      "WINNER",
      "FINALIST"
    ])
  ).min(1, "Must specify at least one eligible status"),

  notifyEligibleTeams: z.boolean(),

  lockPreviousWindows: z.boolean(),

  notificationTemplate: z.object({
    subject: z.string().min(1).max(200),
    bodyHtml: z.string().min(1),
    variables: z.record(z.string())
  }).optional(),

  windowConfig: z.object({
    name: z.string().min(1).max(100),
    description: z.string().max(1000).optional(),
    openDate: z.string().datetime(),
    closeDate: z.string().datetime(),
    latePolicy: z.enum(["HARD", "FLAG", "GRACE"]),
    gracePeriodHours: z.number().int().min(1).max(168).optional()
  }).refine(
    (data) => new Date(data.closeDate) > new Date(data.openDate),
    { message: "closeDate must be after openDate" }
  ).refine(
    (data) => data.latePolicy !== "GRACE" || data.gracePeriodHours !== undefined,
    { message: "gracePeriodHours required when latePolicy is GRACE" }
  ).optional(),

  fileRequirements: z.array(
    z.object({
      label: z.string().min(1).max(100),
      description: z.string().max(500).optional(),
      isRequired: z.boolean(),
      allowedFileTypes: z.array(z.string()).min(1),
      maxSizeMB: z.number().int().min(1).max(500),
      displayOrder: z.number().int().min(0)
    })
  ).optional()
});

type SubmissionConfig = z.infer<typeof submissionConfigSchema>;
```

---

## 4. Applicant Experience (Detailed)

### 4.1 Dashboard Before SUBMISSION Round Opens

**Applicant sees (after advancing from Round 1)**:

```
┌─────────────────────────────────────────────────────────────┐
│ Monaco Ocean Protection Challenge 2026                      │
│                                                             │
│ Project: OceanCleanup AI                                   │
│ Status: 🎉 Semi-Finalist (Advancing to Round 2)            │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 📄 Round 1: Application Documents (Submitted)              │
│                                                             │
│ ✅ Pitch Deck                                               │
│    Filename: OceanCleanup_Pitch.pdf                        │
│    Uploaded: Jan 25, 2026 at 2:30 PM                       │
│    [View] [Download] [Replace]  ← Can still edit           │
│                                                             │
│ ✅ Budget                                                   │
│    Filename: Budget_2026.xlsx                              │
│    Uploaded: Feb 1, 2026 at 9:15 AM                        │
│    [View] [Download] [Replace]                             │
│                                                             │
│ ✅ Team CV                                                  │
│    Filename: Team_Bios.pdf                                 │
│    Uploaded: Jan 25, 2026 at 2:30 PM                       │
│    [View] [Download] [Replace]                             │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ ⏳ Next Steps                                               │
│                                                             │
│ Congratulations on advancing to the semi-finals!           │
│                                                             │
│ Additional submission requirements will be announced soon.  │
│ You will receive an email notification when the next       │
│ submission window opens.                                   │
└─────────────────────────────────────────────────────────────┘
```

**Notes**:
- All Round 1 documents are **still editable** (window not locked yet)
- No indication of upcoming requirements
- "Semi-Finalist" badge visible in project status
- Replace buttons are active

### 4.2 Dashboard After SUBMISSION Round Opens

**When Window 2 opens (March 1, 2026), applicant sees**:

```
┌─────────────────────────────────────────────────────────────┐
│ Monaco Ocean Protection Challenge 2026                      │
│                                                             │
│ Project: OceanCleanup AI                                   │
│ Status: 🎉 Semi-Finalist (Round 2 Submission Open)         │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 🔒 Round 1: Application Documents (Locked)                 │
│                                                             │
│ These documents were submitted for Round 1 and are now     │
│ locked. You can view and download them, but cannot make    │
│ changes. Admins retain the ability to manage these files   │
│ on your behalf if needed.                                  │
│                                                             │
│ ✅ Pitch Deck                                               │
│    Filename: OceanCleanup_Pitch.pdf                        │
│    Uploaded: Jan 25, 2026 at 2:30 PM                       │
│    [View] [Download]  ← No Replace button                  │
│                                                             │
│ ✅ Budget                                                   │
│    Filename: Budget_2026.xlsx                              │
│    Uploaded: Feb 1, 2026 at 9:15 AM                        │
│    [View] [Download]                                       │
│                                                             │
│ ✅ Team CV                                                  │
│    Filename: Team_Bios.pdf                                 │
│    Uploaded: Jan 25, 2026 at 2:30 PM                       │
│    [View] [Download]                                       │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 📤 Round 2: Semi-Finalist Materials                        │
│    Deadline: March 15, 2026 at 11:59 PM CET                │
│    ⏰ 14 days, 15 hours remaining                           │
│                                                             │
│ Progress: 0 of 3 required files submitted                  │
│ [░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%                        │
│                                                             │
│ Congratulations on advancing! Please submit the following  │
│ materials by March 15.                                     │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ❌ 3-Minute Video Pitch (Required)                          │
│    MP4 format, max 100MB. Introduce your team and          │
│    demonstrate your solution.                              │
│                                                             │
│    Not uploaded                                            │
│    [Choose File] or Drag & Drop Here                       │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ❌ Updated Pitch Deck (Required)                            │
│    PDF format. Include any updates since your initial      │
│    application.                                            │
│                                                             │
│    Not uploaded                                            │
│    [Choose File] or Drag & Drop Here                       │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ❌ Financial Projections (Required)                         │
│    Excel or PDF. 3-year revenue and cost forecast with    │
│    assumptions.                                            │
│                                                             │
│    Not uploaded                                            │
│    [Choose File] or Drag & Drop Here                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

**UI Changes**:
1. Round 1 section shows **🔒 lock icon** in header
2. All **Replace/Delete buttons removed** for Window 1 files
3. **New Round 2 section appears** with upload slots
4. **Countdown timer** shows time remaining
5. **Progress bar** shows completion status
6. Red **❌ indicators** for missing required files

### 4.3 File Upload Flow (Detailed)

**Step 1: User clicks "Choose File" for a requirement**

```
┌─────────────────────────────────────────────────────────────┐
│ Upload: 3-Minute Video Pitch                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ Requirements:                                               │
│ • Accepted file types: MP4, MOV                            │
│ • Maximum file size: 100 MB                                │
│ • This file is REQUIRED                                    │
│                                                             │
│ ┌───────────────────────────────────────────────────────┐ │
│ │                                                       │ │
│ │        Drag and drop your file here                  │ │
│ │                   or                                 │ │
│ │              Click to Browse                         │ │
│ │                                                       │ │
│ └───────────────────────────────────────────────────────┘ │
│                                                             │
│ Description:                                               │
│ Introduce your team and demonstrate your solution. Show   │
│ how your technology works and its potential impact.       │
│                                                             │
│                        [Cancel]        [Upload]            │
└─────────────────────────────────────────────────────────────┘
```

**Step 2: File selected, validation in progress**

```
┌─────────────────────────────────────────────────────────────┐
│ Upload: 3-Minute Video Pitch                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ✅ File selected: Pitch_Video.mp4                           │
│    Size: 85.2 MB (within 100 MB limit)                     │
│    Type: video/mp4 ✓                                       │
│                                                             │
│ Validating...                                              │
│                                                             │
│ [████████████████████░░░░] 88% Uploading                   │
│                                                             │
│                      [Cancel Upload]                       │
└─────────────────────────────────────────────────────────────┘
```

**Step 3: Upload complete**

```
┌─────────────────────────────────────────────────────────────┐
│ 📤 Round 2: Semi-Finalist Materials                        │
│    Deadline: March 15, 2026 at 11:59 PM CET                │
│    ⏰ 14 days, 14 hours remaining                           │
│                                                             │
│ Progress: 1 of 3 required files submitted                  │
│ [██████████░░░░░░░░░░░░░░░░░░░░░░░] 33%                    │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ✅ 3-Minute Video Pitch (Required)                          │
│    MP4 format, max 100MB                                   │
│                                                             │
│    Filename: Pitch_Video.mp4                               │
│    Size: 85.2 MB                                           │
│    Uploaded: Mar 1, 2026 at 10:30 AM                       │
│    [View] [Download] [Replace] [Delete]                    │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ❌ Updated Pitch Deck (Required)                            │
│    PDF format                                              │
│    [Choose File] or Drag & Drop Here                       │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ❌ Financial Projections (Required)                         │
│    Excel or PDF                                            │
│    [Choose File] or Drag & Drop Here                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

**Validation Error Example** (file too large):

```
┌─────────────────────────────────────────────────────────────┐
│ ❌ Upload Failed                                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ File: Pitch_Video_HD.mp4                                   │
│ Size: 152.8 MB                                             │
│                                                             │
│ Error: File size exceeds the maximum limit of 100 MB.     │
│                                                             │
│ Please compress your video or upload a smaller version.   │
│                                                             │
│ Tip: You can use free tools like HandBrake to compress    │
│ video files while maintaining quality.                     │
│                                                             │
│                          [OK]                              │
└─────────────────────────────────────────────────────────────┘
```

**Validation Error Example** (wrong file type):

```
┌─────────────────────────────────────────────────────────────┐
│ ❌ Upload Failed                                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ File: Budget_Report.docx                                   │
│ Type: application/vnd.openxmlformats-officedocument...    │
│                                                             │
│ Error: File type not accepted for this requirement.       │
│                                                             │
│ Accepted types: PDF, Excel (XLSX)                         │
│                                                             │
│ Please convert your document to PDF or Excel format and   │
│ try again.                                                 │
│                                                             │
│                          [OK]                              │
└─────────────────────────────────────────────────────────────┘
```

### 4.4 Deadline Countdown UI States

**14 days before deadline (Normal)**:
```
⏰ 14 days, 15 hours remaining
```

**7 days before deadline (Normal)**:
```
⏰ 7 days remaining
```

**3 days before deadline (Warning)**:
```
⚠️ 3 days remaining — Please submit soon!
[Highlighted in yellow]
```

**24 hours before deadline (Urgent)**:
```
🚨 URGENT: Less than 1 day remaining
   Deadline: Tomorrow at 11:59 PM
[Highlighted in orange]
```

**6 hours before deadline (Critical)**:
```
🚨 CRITICAL: 6 hours remaining
   Deadline: Today at 11:59 PM
[Highlighted in red, pulsing animation]
```

**After deadline (HARD policy)**:
```
❌ Deadline passed: March 15, 2026 at 11:59 PM
   Submissions are no longer accepted.

   If you believe this is an error, please contact the
   program administrator.

   [Contact Admin]
```

**After deadline (FLAG policy)**:
```
⚠️ Deadline passed: March 15, 2026 at 11:59 PM
   Late submissions will be flagged and may impact your
   evaluation.

   You can still submit, but your files will be marked as
   late and the jury will be notified.

   [Upload File] (Late submission)
```

**After deadline, within grace period (GRACE policy)**:
```
⏳ Grace Period Active
   Deadline was: March 15, 2026 at 11:59 PM
   Grace period ends: March 17, 2026 at 11:59 PM

   ⏰ 1 day, 23 hours remaining in grace period

   You can still submit without penalty during this time.

   [Upload File]
```

**After grace period ends (GRACE policy)**:
```
❌ Grace period ended: March 17, 2026 at 11:59 PM
   Submissions are now closed.

   If you have extenuating circumstances, please contact
   the program administrator to request an extension.

   [Contact Admin]
```

### 4.5 Completion Status Indicators

**Incomplete (missing required files)**:
```
┌─────────────────────────────────────────────────────────────┐
│ 📤 Round 2: Semi-Finalist Materials                        │
│    Deadline: March 15, 2026 at 11:59 PM CET                │
│                                                             │
│ Status: ⚠️ INCOMPLETE                                       │
│         1 of 3 required files submitted                    │
│                                                             │
│ [██████████░░░░░░░░░░░░░░░░░░░░░░░] 33%                    │
│                                                             │
│ You still need to submit:                                  │
│ • Updated Pitch Deck (required)                            │
│ • Financial Projections (required)                         │
│                                                             │
│ ⏰ 12 days remaining                                        │
└─────────────────────────────────────────────────────────────┘
```

**Complete (all required files submitted)**:
```
┌─────────────────────────────────────────────────────────────┐
│ 📤 Round 2: Semi-Finalist Materials                        │
│    Deadline: March 15, 2026 at 11:59 PM CET                │
│                                                             │
│ Status: ✅ COMPLETE                                         │
│         3 of 3 required files submitted                    │
│                                                             │
│ [██████████████████████████████████████] 100%              │
│                                                             │
│ All required files have been submitted. You can still     │
│ update or replace files until the deadline.                │
│                                                             │
│ ⏰ 12 days remaining                                        │
└─────────────────────────────────────────────────────────────┘
```

**Complete with late submissions**:
```
┌─────────────────────────────────────────────────────────────┐
│ 📤 Round 2: Semi-Finalist Materials                        │
│    Deadline: March 15, 2026 at 11:59 PM CET (PASSED)       │
│                                                             │
│ Status: ⚠️ COMPLETE (1 file submitted late)                │
│         3 of 3 required files submitted                    │
│                                                             │
│ [██████████████████████████████████████] 100%              │
│                                                             │
│ All files submitted, but the Financial Projections file   │
│ was submitted after the deadline. This has been flagged   │
│ and the jury will be notified during evaluation.           │
│                                                             │
│ Submitted late:                                            │
│ • Financial Projections (submitted Mar 16 at 2:15 PM)     │
└─────────────────────────────────────────────────────────────┘
```

**Complete with optional files missing**:
```
┌─────────────────────────────────────────────────────────────┐
│ 📤 Round 2: Semi-Finalist Materials                        │
│    Deadline: March 15, 2026 at 11:59 PM CET                │
│                                                             │
│ Status: ✅ COMPLETE                                         │
│         3 of 3 required files submitted                    │
│         0 of 1 optional files submitted                    │
│                                                             │
│ All required files submitted. Optional:                    │
│ ○ Team Photos (optional, not submitted)                   │
│                                                             │
│ ⏰ 12 days remaining                                        │
└─────────────────────────────────────────────────────────────┘
```

### 4.6 Email Notifications

**Email 1: Window Opening Notification**

```
From: Monaco Ocean Protection Challenge <noreply@monaco-opc.com>
To: team@oceancleanup.ai
Subject: 🎉 You're a Semi-Finalist! Submit Your Round 2 Materials
Date: March 1, 2026 at 9:00 AM

───────────────────────────────────────────────────────────

Dear OceanCleanup AI Team,

Congratulations on advancing to the semi-finals of the Monaco
Ocean Protection Challenge 2026!

You have been selected from 150 applicants to advance to the
next round. We were impressed by your innovative approach to
ocean conservation.

NEXT STEPS: SUBMIT ROUND 2 MATERIALS

To continue in the competition, please submit the following
documents by:

  📅 DEADLINE: March 15, 2026 at 11:59 PM CET

Required Materials:
✓ 3-Minute Video Pitch (MP4, max 100MB)
  Introduce your team and demonstrate your solution

✓ Updated Pitch Deck (PDF, max 10MB)
  Include any updates since your initial application

✓ Financial Projections (Excel or PDF, max 5MB)
  3-year revenue and cost forecast with assumptions

──────────────────────────────────────────────────────────

[Upload Documents →]

──────────────────────────────────────────────────────────

IMPORTANT NOTES:

• Your Round 1 application documents are now locked and
  cannot be edited. They will remain available for viewing.

• You have 14 days to submit your materials.

• All required files must be submitted by the deadline.

• You can update or replace files at any time before the
  deadline.

If you have any questions or encounter technical difficulties,
please contact us at support@monaco-opc.com.

Best regards,
Monaco Ocean Protection Challenge Team

───────────────────────────────────────────────────────────
```

**Email 2: Reminder (7 days before)**

```
From: Monaco Ocean Protection Challenge <noreply@monaco-opc.com>
To: team@oceancleanup.ai
Subject: ⏰ Reminder: Semi-Finalist Materials Due in 7 Days
Date: March 8, 2026 at 9:00 AM

───────────────────────────────────────────────────────────

Dear OceanCleanup AI Team,

This is a friendly reminder that your semi-finalist materials
are due in 7 days.

DEADLINE: March 15, 2026 at 11:59 PM CET

Current Status: 1 of 3 required files submitted ⚠️

Missing Files:
❌ Updated Pitch Deck (PDF, required)
❌ Financial Projections (Excel/PDF, required)

──────────────────────────────────────────────────────────

[Complete Your Submission →]

──────────────────────────────────────────────────────────

Don't wait until the last minute! Upload your remaining
documents now to ensure you don't miss the deadline.

Best regards,
Monaco Ocean Protection Challenge Team
```

**Email 3: Urgent Reminder (24 hours before)**

```
From: Monaco Ocean Protection Challenge <noreply@monaco-opc.com>
To: team@oceancleanup.ai
Subject: 🚨 URGENT: Semi-Finalist Materials Due Tomorrow
Date: March 14, 2026 at 9:00 AM

───────────────────────────────────────────────────────────

Dear OceanCleanup AI Team,

URGENT: Your semi-finalist materials are due TOMORROW
(March 15) at 11:59 PM CET.

Current Status: 2 of 3 required files submitted ⚠️

Missing Files:
❌ Financial Projections (Excel/PDF, REQUIRED)

──────────────────────────────────────────────────────────

[Upload Missing File Now →]

──────────────────────────────────────────────────────────

PLEASE ACT IMMEDIATELY. Incomplete submissions may result
in disqualification from the competition.

If you are experiencing technical difficulties, contact us
immediately at support@monaco-opc.com or call +377 XXX XXX.

Best regards,
Monaco Ocean Protection Challenge Team
```

**Email 4: Late Submission Warning (FLAG policy)**

```
From: Monaco Ocean Protection Challenge <noreply@monaco-opc.com>
To: team@oceancleanup.ai
Subject: ⚠️ Late Submission Notice
Date: March 16, 2026 at 10:15 AM

───────────────────────────────────────────────────────────

Dear OceanCleanup AI Team,

We received your Financial Projections file on March 16 at
2:15 PM, which was after the deadline of March 15 at 11:59 PM.

Your submission has been marked as LATE and flagged in our
system. The jury will be notified of the late submission
during evaluation, which may impact your score.

While we understand that unexpected circumstances can arise,
please be mindful of deadlines in future rounds.

Your submission is now complete. Good luck in the next round!

Best regards,
Monaco Ocean Protection Challenge Team
```

---

## 5. Jury Cross-Round Visibility (Detailed)

### 5.1 RoundSubmissionVisibility Configuration

**Purpose**: Control which EVALUATION rounds can see which SubmissionWindows.

**Configuration Example**:

```typescript
// Evaluation Round 1: Jury Screening (sees only Window 1)
await prisma.roundSubmissionVisibility.create({
  data: {
    evaluationRoundId: "eval_round_1",
    submissionWindowId: "window_1",
    displayLabel: "Application Documents",
    displayOrder: 1
  }
});

// Evaluation Round 2: Jury Semi-Finals (sees Window 1 + Window 2)
await prisma.roundSubmissionVisibility.createMany({
  data: [
    {
      evaluationRoundId: "eval_round_2",
      submissionWindowId: "window_1",
      displayLabel: "Round 1 Application",
      displayOrder: 1
    },
    {
      evaluationRoundId: "eval_round_2",
      submissionWindowId: "window_2",
      displayLabel: "Semi-Final Materials",
      displayOrder: 2
    }
  ]
});

// Evaluation Round 3: Jury Finals (sees all three windows)
await prisma.roundSubmissionVisibility.createMany({
  data: [
    {
      evaluationRoundId: "eval_round_3",
      submissionWindowId: "window_1",
      displayLabel: "Original Application (Jan)",
      displayOrder: 1
    },
    {
      evaluationRoundId: "eval_round_3",
      submissionWindowId: "window_2",
      displayLabel: "Semi-Final Submission (Mar)",
      displayOrder: 2
    },
    {
      evaluationRoundId: "eval_round_3",
      submissionWindowId: "window_3",
      displayLabel: "Finalist Presentation (Apr)",
      displayOrder: 3
    }
  ]
});
```

### 5.2 Jury Evaluation View (Round 1 - Single Window)

**Jury sees ONLY Window 1**:

```
┌─────────────────────────────────────────────────────────────┐
│ Evaluating: OceanCleanup AI                                 │
│ Round: Jury Screening (Round 1)                            │
│ Assigned: Feb 10, 2026                                     │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 📄 Application Documents                                    │
│                                                             │
│ Pitch Deck                                                 │
│ Filename: OceanCleanup_Pitch.pdf                           │
│ Uploaded: Jan 25, 2026 at 2:30 PM                          │
│ Size: 2.4 MB                                               │
│ [View] [Download]                                          │
│                                                             │
│ Budget                                                     │
│ Filename: Budget_2026.xlsx                                 │
│ Uploaded: Feb 1, 2026 at 9:15 AM                           │
│ Size: 850 KB                                               │
│ [View] [Download]                                          │
│                                                             │
│ Team CV                                                    │
│ Filename: Team_Bios.pdf                                    │
│ Uploaded: Jan 25, 2026 at 2:30 PM                          │
│ Size: 1.2 MB                                               │
│ [View] [Download]                                          │
│                                                             │
│ [Download All Files (ZIP)]                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ Your Evaluation                                             │
│                                                             │
│ Impact Score (1-10): [_____]                               │
│ Feasibility Score (1-10): [_____]                          │
│ Innovation Score (1-10): [_____]                           │
│                                                             │
│ Comments:                                                  │
│ ┌───────────────────────────────────────────────────────┐ │
│ │                                                       │ │
│ │                                                       │ │
│ └───────────────────────────────────────────────────────┘ │
│                                                             │
│ Recommendation:                                            │
│ ( ) Pass  ( ) Fail  ( ) Conditional                       │
│                                                             │
│           [Save Draft]              [Submit Evaluation]    │
└─────────────────────────────────────────────────────────────┘
```

**Notes**:
- Jury does NOT see that Window 2 exists
- No indication of future submission rounds
- Clean, focused evaluation on Round 1 materials only
- UI is simple and uncluttered

### 5.3 Jury Evaluation View (Round 2 - Multi-Window)

**Jury sees BOTH Window 1 and Window 2**:

```
┌─────────────────────────────────────────────────────────────┐
│ Evaluating: OceanCleanup AI                                 │
│ Round: Semi-Final Evaluation (Round 2)                     │
│ Assigned: Mar 20, 2026                                     │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 📂 Project Documents                                        │
│                                                             │
│ ┌─────────────────────────────────────────────────────┐   │
│ │ [ Round 1 Application ] [ Semi-Final Materials ]    │   │
│ └─────────────────────────────────────────────────────┘   │
│      ▲ Active tab                                          │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ Tab 1 Active: "Round 1 Application"                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ 📄 Round 1 Application                                     │
│                                                             │
│ These documents were submitted during the initial           │
│ application phase (January 2026).                          │
│                                                             │
│ Pitch Deck                                                 │
│ Filename: OceanCleanup_Pitch.pdf                           │
│ Uploaded: Jan 25, 2026 at 2:30 PM                          │
│ Size: 2.4 MB                                               │
│ [View] [Download]                                          │
│                                                             │
│ Budget                                                     │
│ Filename: Budget_2026.xlsx                                 │
│ Uploaded: Feb 1, 2026 at 9:15 AM                           │
│ Size: 850 KB                                               │
│ [View] [Download]                                          │
│                                                             │
│ Team CV                                                    │
│ Filename: Team_Bios.pdf                                    │
│ Uploaded: Jan 25, 2026 at 2:30 PM                          │
│ Size: 1.2 MB                                               │
│ [View] [Download]                                          │
│                                                             │
│ [Download All Round 1 Files (ZIP)]                         │
└─────────────────────────────────────────────────────────────┘
```

**Click "Semi-Final Materials" tab**:

```
┌─────────────────────────────────────────────────────────────┐
│ 📂 Project Documents                                        │
│                                                             │
│ ┌─────────────────────────────────────────────────────┐   │
│ │ [ Round 1 Application ] [ Semi-Final Materials ]    │   │
│ └─────────────────────────────────────────────────────┘   │
│                               ▲ Active tab                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ Tab 2 Active: "Semi-Final Materials"                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ 📄 Semi-Final Materials                                    │
│                                                             │
│ These documents were submitted for the semi-final          │
│ evaluation round (March 2026).                             │
│                                                             │
│ 3-Minute Video Pitch                                       │
│ Filename: Pitch_Video.mp4                                  │
│ Uploaded: Mar 1, 2026 at 10:30 AM                          │
│ Size: 85.2 MB                                              │
│ [View] [Download]                                          │
│                                                             │
│ Updated Pitch Deck                                         │
│ Filename: OceanCleanup_Pitch_v2.pdf                        │
│ Uploaded: Mar 10, 2026 at 4:20 PM                          │
│ Size: 3.1 MB                                               │
│ [View] [Download]                                          │
│                                                             │
│ Financial Projections                                      │
│ Filename: Financials_2026.xlsx                             │
│ Uploaded: Mar 16, 2026 at 2:15 PM  ⚠️ LATE SUBMISSION      │
│ Size: 1.5 MB                                               │
│ [View] [Download]                                          │
│ ⚠️ This file was submitted after the deadline of Mar 15    │
│                                                             │
│ [Download All Round 2 Files (ZIP)]                         │
└─────────────────────────────────────────────────────────────┘
```

**Evaluation Form (Below Documents)**:

```
┌─────────────────────────────────────────────────────────────┐
│ Your Evaluation                                             │
│                                                             │
│ ℹ️ Please evaluate based on ALL submitted materials        │
│   (both Round 1 and Round 2 documents).                    │
│                                                             │
│ Business Model Score (1-10): [_____]                       │
│ Team Strength Score (1-10): [_____]                        │
│ Presentation Quality (1-10): [_____]                       │
│ Financial Viability (1-10): [_____]                        │
│                                                             │
│ Comments:                                                  │
│ ┌───────────────────────────────────────────────────────┐ │
│ │                                                       │ │
│ │                                                       │ │
│ └───────────────────────────────────────────────────────┘ │
│                                                             │
│ Recommendation:                                            │
│ ( ) Pass  ( ) Fail  ( ) Conditional                       │
│                                                             │
│ ⚠️ Note: Financial Projections was submitted late.        │
│                                                             │
│           [Save Draft]              [Submit Evaluation]    │
└─────────────────────────────────────────────────────────────┘
```

**UI Enhancements**:
1. **Tab Navigation**: Clear separation between submission windows
2. **Context Labels**: Each tab shows description and submission date range
3. **Late Indicators**: Flagged submissions clearly visible
4. **Download Options**: Bulk download per window or all files
5. **Submission Metadata**: Upload dates, file sizes, uploaders visible
6. **Badge Indicators**: Late submissions have ⚠️ warning badge

### 5.4 Query Implementation for Jury View

```typescript
// src/server/routers/evaluation.ts

export const evaluationRouter = router({
  /**
   * Get all visible files for a project in an evaluation round
   */
  getVisibleFilesForProject: juryProcedure
    .input(z.object({
      projectId: z.string().cuid(),
      evaluationRoundId: z.string().cuid()
    }))
    .query(async ({ input, ctx }) => {
      // Step 1: Get visible windows for this evaluation round
      const visibleWindows = await ctx.prisma.roundSubmissionVisibility.findMany({
        where: { evaluationRoundId: input.evaluationRoundId },
        include: {
          submissionWindow: {
            include: {
              fileRequirements: {
                orderBy: { displayOrder: "asc" }
              }
            }
          }
        },
        orderBy: { displayOrder: "asc" }
      });

      if (visibleWindows.length === 0) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "No submission windows configured for this evaluation round"
        });
      }

      // Step 2: Fetch files for each visible window
      const filesByWindow = await Promise.all(
        visibleWindows.map(async (visibility) => {
          const files = await ctx.prisma.projectFile.findMany({
            where: {
              projectId: input.projectId,
              submissionWindowId: visibility.submissionWindowId,
              supersededBy: null  // Only current versions
            },
            include: {
              requirement: true,
              uploadedByUser: {
                select: {
                  name: true,
                  email: true,
                  role: true
                }
              }
            },
            orderBy: { requirement: { displayOrder: "asc" } }
          });

          // Generate download URLs
          const filesWithUrls = await Promise.all(
            files.map(async (file) => ({
              id: file.id,
              filename: file.filename,
              requirementLabel: file.requirement?.label || "Untitled",
              uploadedAt: file.uploadedAt,
              uploadedBy: file.uploadedByUser.name,
              uploadedByRole: file.uploadedByUser.role,
              sizeBytes: file.sizeBytes,
              isLate: file.isLate,
              downloadUrl: await getPresignedDownloadUrl(file.id)
            }))
          );

          return {
            windowId: visibility.submissionWindowId,
            windowName: visibility.displayLabel,
            windowDescription: visibility.submissionWindow.description,
            displayOrder: visibility.displayOrder,
            files: filesWithUrls
          };
        })
      );

      return filesByWindow;
    })
});
```

**Frontend Usage**:

```tsx
// components/jury/ProjectFilesView.tsx

export function ProjectFilesView({ projectId, evaluationRoundId }: Props) {
  const { data: filesByWindow, isLoading } = trpc.evaluation.getVisibleFilesForProject.useQuery({
    projectId,
    evaluationRoundId
  });

  if (isLoading) return <LoadingSpinner />;

  return (
    <div>
      <Tabs defaultValue={filesByWindow?.[0]?.windowId}>
        <TabsList>
          {filesByWindow?.map((window) => (
            <TabsTrigger key={window.windowId} value={window.windowId}>
              {window.windowName}
            </TabsTrigger>
          ))}
        </TabsList>

        {filesByWindow?.map((window) => (
          <TabsContent key={window.windowId} value={window.windowId}>
            <div className="space-y-4">
              <p className="text-muted-foreground">{window.windowDescription}</p>

              {window.files.map((file) => (
                <FileCard
                  key={file.id}
                  file={file}
                  showLateIndicator={file.isLate}
                />
              ))}

              <Button variant="outline">
                Download All {window.windowName} Files (ZIP)
              </Button>
            </div>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  );
}
```

### 5.5 Admin Visibility Configuration UI

**Admin panel for configuring which windows Jury 2 can see**:

```
┌─────────────────────────────────────────────────────────────┐
│ Configure Document Visibility: Semi-Final Evaluation       │
└─────────────────────────────────────────────────────────────┘

Which submission windows should jury members see during this
evaluation round?

┌─────────────────────────────────────────────────────────────┐
│ Available Submission Windows:                               │
│                                                             │
│ ☑ Window 1: Application Documents                          │
│   Created: Jan 1, 2026                                     │
│   Closed: Feb 1, 2026                                      │
│                                                             │
│   Display as: [Round 1 Application______________]          │
│   Order: [1]                                               │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ☑ Window 2: Semi-Finalist Materials                        │
│   Created: Mar 1, 2026                                     │
│   Closed: Mar 15, 2026                                     │
│                                                             │
│   Display as: [Semi-Final Submissions___________]          │
│   Order: [2]                                               │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│ ☐ Window 3: Finalist Presentations                         │
│   Status: Not yet created                                  │
│   (This window will be created in a future round)          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Preview: Jury will see 2 tabs in this order:
1. Round 1 Application
2. Semi-Final Submissions

                         [Cancel]      [Save Configuration]
```

**Validation Rules**:
- At least one window must be selected
- Display labels must be unique within an evaluation round
- Display order must be positive integers
- Cannot select a window that hasn't opened yet (optional warning)
- Cannot select a window from a different competition

---

## 6. Admin Experience

(Content continues in next part due to length...)

Would you like me to continue with the rest of the document (sections 6-10)?