From c2afa5860664982f2ce9c27a2c58dc7e15fa7b48 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 9 Jun 2026 14:49:26 +0200 Subject: [PATCH] docs(grand-final): 4-doc set (PDF-only), thin dedicated judge page rationale Confirmed document set: Final Presentation, Final Business Plan, 1-min Video, Executive Summary (all required, PDF-only docs), same for both categories. Judge page stays a thin dedicated page reusing the existing doc viewer because the finale has 0 assignments / empty jury group (group-based, not assignment-based). Co-Authored-By: Claude Opus 4.8 (1M context) --- ...2026-06-09-grand-final-documents-design.md | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/docs/superpowers/specs/2026-06-09-grand-final-documents-design.md b/docs/superpowers/specs/2026-06-09-grand-final-documents-design.md index f7cd133..e452453 100644 --- a/docs/superpowers/specs/2026-06-09-grand-final-documents-design.md +++ b/docs/superpowers/specs/2026-06-09-grand-final-documents-design.md @@ -13,7 +13,7 @@ Nine finalist teams must submit two final deliverables ahead of the Grand Final The data layer already exists and is correctly set up: - **"Grand Final" (LIVE_FINAL) round is `ROUND_ACTIVE`** with `windowCloseAt = 2026-06-11 21:00 UTC` and the empty **"Finals Jury"** group attached (`juryGroupId` set, **0 members**). -- **Two `FileRequirement` rows already exist on the Grand Final round** (legacy per-round system): **"PDF presentation support"** (`application/pdf`) and **"1 minute video"** (`video/*`). Both currently `required = false`, `maxSizeMB = null`, **0 files uploaded**. +- **Two `FileRequirement` rows already exist on the Grand Final round** (legacy per-round system): **"PDF presentation support"** (`application/pdf`) and **"1 minute video"** (`video/*`). Both currently `required = false`, `maxSizeMB = null`, **0 files uploaded**. This set is being expanded to the confirmed 4-document set below. - **All 9 finalist teams are correctly enrolled**: each has a `ProjectRoundState` in both the (closed) Mentoring round and the (active) Grand Final round, and all 9 have `FinalistConfirmation.status = CONFIRMED`. No mismatches (confirmed↔enrolled↔in-mentor all aligned). All 9 share one mentor, **Camille Lopez**. Attendee counts 1–4 (program `defaultAttendeeCap = 4`). - Auto-enroll (confirmed + in mentor round → Grand Final round) is working via `finalist.enrollFinalists`; the **admin override already exists** (`finalist.adminConfirm` to mark attending without a token; `finalist.unenroll` to remove) in the `/admin/logistics` **Confirmations tab** + attendance dialog. @@ -30,6 +30,17 @@ The gaps are therefore: **discoverability** (no banner/notification), **judge re 3. Surface the final documents (and a pre-deadline cue) inside **the mentor section**, on both the team's and the mentor's views. 4. Add **email + in-app notifications**, triggered **automatically** (pre-deadline reminder cron) and **manually** (admin blast). +## Document set (confirmed) + +The Grand Final round's `FileRequirement` rows are reconfigured to **four required documents**, identical for both categories (STARTUP and BUSINESS_CONCEPT) — the per-round `FileRequirement` model already applies one set to all teams in the round: + +1. **Final Presentation** — `application/pdf` (rename of the existing "PDF presentation support" row) +2. **Final Business Plan** — `application/pdf` (new) +3. **1-minute Video** — `video/*` (existing "1 minute video" row) +4. **Executive Summary** — `application/pdf` (new) + +All four `required = true`. PDF-only for the three document slots (no Word). This is an additive/safe prod data change (0 files currently uploaded). If per-category document sets are ever needed, that is out of scope here (the per-round model does not support it without extra work). + ## Non-goals (YAGNI) - Admin approve / needs-changes review workflow on documents. @@ -63,7 +74,7 @@ A new service centralizes the logic, wrapped by thin tRPC procedures: - New auto-hiding banner component (pattern of `LunchBanner`/`MyLogisticsCard`: returns `null` when not applicable) on `src/app/(applicant)/applicant/page.tsx`. - Backed by a new query **`applicant.getFinalDocumentStatus`** (wraps `getFinalDocumentStatusForProject` for the caller's project). -- Shows: heading ("Upload your Grand Final documents"), the two deliverables each with a ✓ / empty state, deadline in browser-local time + zone, and a CTA button → `/applicant/documents`. Collapses to a "✓ Submitted" confirmation once all required documents are uploaded. Non-dismissible while incomplete. +- Shows: heading ("Upload your Grand Final documents"), each required document with a ✓ / empty state (e.g. "2 of 4 uploaded"), deadline in browser-local time + zone, and a CTA button → `/applicant/documents`. Collapses to a "✓ Submitted" confirmation once all required documents are uploaded. Non-dismissible while incomplete. ### 2. Mentor-section "Final Documents" panel (team + mentor) @@ -74,9 +85,13 @@ A new read-only `FinalDocumentsPanel` component rendered on **both** mentor surf Behavior: before upload + as the deadline nears, a **visual cue** ("Final grand-final documents due [date] — upload now", with an upload CTA on the team view); after upload, the PDF + video appear as the team's read-only "final documents" (inline preview / video player / download), visible to both the team and their mentor. Same underlying `ProjectFile`s — no duplicate storage. -### 3. Judge review page +### 3. Judge review page (thin dedicated page, reusing existing components) -- New read-only page (e.g. `src/app/(jury)/jury/finals-documents/page.tsx`) listing all finalist teams grouped by category, each with its two documents: PDF via inline `FilePreview`, video via inline `