diff --git a/.full-stack-feature/01-requirements.md b/.full-stack-feature/01-requirements.md deleted file mode 100644 index 1dfe968a1..000000000 --- a/.full-stack-feature/01-requirements.md +++ /dev/null @@ -1,123 +0,0 @@ -# Requirements: Business Intelligence Dashboard - -## Problem Statement - -The current admin "Growth" tab shows activity totals and vanity metrics instead of decision-making metrics. The admin (founder/operator) cannot answer critical product questions: -- **Which features actually drive retention** vs which ones just get clicked once? -- **Where do users get stuck and drop off** in the onboarding/activation flow? -- **Which users/teams would pay** if pricing existed? -- **What should be built, fixed, or doubled-down on** next? -- **Who is quietly churning** and what predicts that behavior? - -The tab needs a complete redesign into a proper Business Intelligence dashboard that replaces vanity stats with actionable, decision-driving metrics organized around the 5-section BI framework. - -## User -Platform admin (founder) — sole admin of GolfHelm, needs to understand product health and make data-driven product decisions. - -## Acceptance Criteria - -- [ ] Tab renamed from "Growth" to "Business Intelligence" across all admin UI (tab nav, keyboard shortcuts, descriptions) -- [ ] All 5 admin tabs reorganized around the BI framework -- [ ] **Section A: Growth** — Signups, activated users (defined as: completed onboarding + submitted first round), activation rate, median time-to-first-value, drop-off between signup and first key action -- [ ] **Section B: Retention** — D1/D7/D30 retention rates, WAU/MAU, DAU/MAU stickiness, weekly cohort retention matrix (by signup week), retention by user type (coach vs player) -- [ ] **Section C: Product Usage** — Feature adoption ranked by % of active users who used each feature in last 7/30 days, repeat usage counts, feature usage by retained vs churned users, dead features detection (<5% adoption), object creation metrics (rounds, qualifiers, events, tasks, messages, documents, reviews, insights) -- [ ] **Section D: Funnel & Friction** — Onboarding step conversion (signup → profile → first round → active week → received insights), biggest drop-off points, error/failure rates affecting engagement -- [ ] **Section E: Health & Opportunity** — Per-team health scores (active users, feature breadth, admin engagement), power user identification, at-risk accounts, conversion-intent proxy signals (high usage, many rounds, team spread, AI adoption, settings engagement) -- [ ] **Vercel Analytics Integration** — Pull unique visitor/device counts from Vercel Web Analytics API and display in the Growth section -- [ ] Recharts-based visualizations (already installed v3.6.0) for cohort heatmaps, funnels, area charts, bar charts -- [ ] Clean, premium glassmorphism UI matching existing admin design system -- [ ] All metrics computed from existing Supabase tables (no new event tracking infrastructure) - -## Scope - -### In Scope -- Complete redesign of the Growth tab → Business Intelligence tab -- Rename tab in admin navigation (label, icon, description, keyboard shortcut) -- 5-section BI dashboard (Growth, Retention, Product Usage, Funnel & Friction, Health & Opportunity) -- Reorganize other admin tabs as needed to align with BI framework (move overlapping metrics) -- Vercel Web Analytics API integration for unique visitors/devices -- Recharts-based charts replacing custom AdminChart where beneficial -- New computed metrics: activation rate, time-to-value, feature retention correlation, team health scores, conversion proxies -- GolfHelm "aha moment" definition: Completed onboarding + submitted first round -- Power user segment definition: Active 3 of last 4 weeks, ≥3 rounds, used 2+ advanced features - -### Out of Scope -- New event-tracking infrastructure (PostHog, Mixpanel, etc.) -- New database tables for raw event storage — all metrics from existing tables -- Real-time WebSocket dashboards (keep 60-second polling pattern) -- Payment/revenue analytics (no payments yet) -- A/B testing framework -- Email/notification automation based on BI signals -- Player-facing analytics (this is admin-only) - -## Technical Constraints - -1. **Data fetching pattern**: Extend existing `getAdminDashboardData()` server action with parallel Supabase queries. Do not create separate data endpoints. -2. **Admin auth**: All data behind admin role check (already enforced in `admin-data.ts`) -3. **Supabase admin client**: Use `createAdminClient()` to bypass RLS for cross-team analytics -4. **Performance**: Current action runs 100+ parallel queries. New BI metrics must maintain sub-3s total response time. Use `Promise.all()` batching. -5. **Type safety**: Extend `AdminDashboardData` interface with new BI fields. TypeScript strict mode. -6. **No new tables**: All BI metrics computed from existing 75+ golf tables. -7. **Vercel API**: Use Vercel Web Analytics API (REST) called server-side in the data action. Requires `VERCEL_API_TOKEN` env var. - -## Technology Stack - -- **Frontend**: Next.js 16 App Router, React 19, TypeScript strict, Tailwind CSS -- **Charts**: Recharts 3.6.0 (already installed) -- **Backend**: Server Actions (no REST API routes) -- **Database**: Supabase (PostgreSQL) with admin client -- **External**: Vercel Web Analytics REST API -- **Design System**: Glassmorphism — `bg-white/70 backdrop-blur-xl border border-white/20 rounded-2xl shadow-glass` - -## Dependencies - -- **Affects all 5 admin tabs**: Full reorganization around BI framework -- **Extends `AdminDashboardData` type**: Used by OverviewTab, PeopleTab, SystemTab, GrowthTab -- **Shares data with Overview tab**: Some metrics may move to BI or be referenced from both -- **Vercel API dependency**: Requires Vercel API token in environment variables -- **Existing components reusable**: AdminStatCard, AdminChart, CohortRetentionMatrix, SessionHeatmap (may be enhanced or replaced) - -## Configuration - -- Stack: nextjs-typescript-supabase -- API Style: server-actions -- Complexity: complex - -## GolfHelm Feature Context - -### Key Tables for BI Metrics -| Table | BI Signal | -|-------|-----------| -| `users` | Signups, registration dates | -| `golf_players` | Player activation, onboarding status | -| `golf_coaches` | Coach activation, onboarding status | -| `golf_rounds` | Core engagement (round submission = key action) | -| `golf_shots` | Deep engagement signal | -| `golf_team_members` | Team health, seat activation | -| `golf_teams` | Account-level metrics | -| `golf_coach_philosophy` | AI adoption signal | -| `golf_coach_insights` | AI usage frequency | -| `golf_round_reviews` | Coach engagement depth | -| `golf_events` / `golf_tasks` / `golf_messages` | Feature adoption signals | -| `golf_qualifiers` / `golf_documents` / `golf_travel_itineraries` | Feature adoption signals | -| `golf_player_stats_cache` | Stats engagement | -| `golf_attendance_summary` | Event engagement | -| `error_logs` | Product friction / quality signals | - -### GolfHelm "Aha Moment" Definition -A user is "activated" when they have: -1. Completed onboarding (`onboarding_completed = true`) -2. Submitted at least one round (`golf_rounds` with `status = 'completed'`) - -### Power User Definition -- Active in 3 of last 4 weeks (submitted rounds) -- Completed ≥3 rounds total in last 30 days -- Used 2+ "advanced" features (CoachHelm AI, Qualifiers, Development Plans, Shot Tracking, Stats Deep Dive) - -### Conversion Proxy Signals -- Submitted 10+ rounds -- Team has 3+ active players -- Coach uses AI insights weekly -- Coach created development plans -- Admin spent time in settings -- Used 4+ different features in last 30 days diff --git a/.full-stack-feature/state.json b/.full-stack-feature/state.json deleted file mode 100644 index 2e9f2509c..000000000 --- a/.full-stack-feature/state.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "feature": "Redesign admin Growth tab into comprehensive Business Intelligence dashboard", - "status": "complete", - "stack": "nextjs-typescript-supabase", - "api_style": "server-actions", - "complexity": "complex", - "current_step": "complete", - "current_phase": 3, - "completed_steps": [1, 2, 3, 4, 5, 6, 7], - "files_created": ["01-requirements.md", "02-database-design.md", "03-architecture.md", "04-database-impl.md", "05-backend-impl.md", "06-frontend-impl.md", "07-testing.md"], - "started_at": "2026-03-11T12:00:00Z", - "last_updated": "2026-03-11T14:15:00Z" -} diff --git a/.github/workflows/visual-audit.yml b/.github/workflows/visual-audit.yml new file mode 100644 index 000000000..a3e9be672 --- /dev/null +++ b/.github/workflows/visual-audit.yml @@ -0,0 +1,108 @@ +name: Visual Audit + +# Manual-only production screenshot crawl (e2e/visual-audit.spec.ts). NOT part +# of any PR gate or push trigger — this hits a real, deployed base_url (prod +# by default) as both the baseball coach and player roles, discovers every +# visible nav route from the LIVE DOM, and captures full-page screenshots at +# phone (390x844) and desktop (1440x900) viewports for a human/follow-up +# review pass to look at. Screenshots are data capture, not assertions — the +# spec only fails this workflow on a login failure or a total navigation +# failure (see e2e/visual-audit.spec.ts's module doc for the exact contract). +# +# Runs ONLY the baseball auth setup + this spec — no build, no dev server, no +# seeding: PLAYWRIGHT_BASE_URL points playwright.config.ts at the deployed +# base_url, which makes its `webServer` block a no-op (only defined when +# PLAYWRIGHT_BASE_URL is unset), so there is nothing to boot locally. +# +# `--project=baseball-coach --project=baseball-player` alone is sufficient to +# also run the `setup` project (playwright/baseball-auth.setup.ts): both +# projects declare `dependencies: ['setup']` in playwright.config.ts, and +# Playwright always runs a project's dependencies with their own FULL, +# unfiltered test file set — the `e2e/visual-audit.spec.ts` file argument on +# the CLI only restricts the explicitly-requested top-level projects +# (baseball-coach/baseball-player), never a project pulled in purely as a +# dependency. Verified against the installed playwright package's runner +# source (collectProjectsAndTestFiles in lib/runner/index.js) before relying +# on it here. The `setup` project's testMatch is scoped to +# `baseball-auth.setup.ts` specifically, so Golf's `playwright/auth.setup.ts` +# is never pulled in. +# +# SECURITY: consumes ZERO untrusted user input — the only `${{ }}` expressions +# are a trusted workflow_dispatch string input, secrets, and github.run_number. + +on: + workflow_dispatch: + inputs: + base_url: + description: Base URL to crawl (playwright.config.ts baseURL) + required: false + default: "https://helmsportslabs.com" + type: string + +concurrency: + group: visual-audit-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + visual-audit: + name: Visual audit (coach + player) + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + PLAYWRIGHT_BASE_URL: ${{ inputs.base_url }} + VISUAL_AUDIT: "1" + # Fail loud (not a graceful skip) on missing/bad creds — this run is + # pointless without a real authenticated crawl. + PLAYWRIGHT_BASEBALL_REQUIRED: "1" + E2E_BASEBALL_COACH_EMAIL: ${{ secrets.E2E_BASEBALL_COACH_EMAIL }} + E2E_BASEBALL_COACH_PASSWORD: ${{ secrets.E2E_BASEBALL_COACH_PASSWORD }} + E2E_BASEBALL_PLAYER_EMAIL: ${{ secrets.E2E_BASEBALL_PLAYER_EMAIL }} + E2E_BASEBALL_PLAYER_PASSWORD: ${{ secrets.E2E_BASEBALL_PLAYER_PASSWORD }} + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Setup Node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Cache Playwright browsers + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + playwright-${{ runner.os }}- + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + # Runs the `setup` project (baseball coach + player auth, persisting + # storageState) as a dependency, then this spec under baseball-coach + # and baseball-player — see the header comment above for why no + # explicit --project=setup is needed. + - name: Run visual-audit screenshot crawl + run: | + npx playwright test \ + --project=baseball-coach \ + --project=baseball-player \ + e2e/visual-audit.spec.ts + + - name: Upload visual-audit screenshots + manifests + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4 + with: + name: visual-audit-${{ github.run_number }} + path: test-results/visual-audit + retention-days: 7 + if-no-files-found: warn diff --git a/.taskmaster/README.md b/.taskmaster/README.md deleted file mode 100644 index a232052e3..000000000 --- a/.taskmaster/README.md +++ /dev/null @@ -1,124 +0,0 @@ -# TaskMaster - Project Task Management - -**Project:** helmv3 (Helm Sports Labs - Golf Shot Tracking Platform) -**Initialized:** 2025-12-22 - ---- - -## 📁 Folder Structure - -``` -.taskmaster/ -├── config.json # Project configuration and settings -├── tasks.json # Active and completed tasks -├── logs/ # Task execution logs -├── templates/ # Task templates -│ └── task-template.json -└── README.md # This file -``` - ---- - -## 🎯 Task Statuses - -| Status | Description | -|--------|-------------| -| `todo` | Not started | -| `in_progress` | Currently being worked on | -| `blocked` | Waiting on dependencies or external factors | -| `review` | Ready for code review | -| `completed` | Finished and verified | -| `archived` | Completed tasks older than 30 days | - ---- - -## 🔥 Priority Levels - -| Priority | Use When | -|----------|----------| -| `critical` | Blocking issue, production bug, security issue | -| `high` | Important feature, significant bug | -| `medium` | Standard feature work, minor bugs | -| `low` | Nice-to-have, optimization, cleanup | - ---- - -## 📋 Task Categories - -- `feature` - New functionality -- `bug` - Bug fixes -- `refactor` - Code improvements -- `docs` - Documentation -- `test` - Testing -- `chore` - Maintenance, tooling, dependencies - ---- - -## 🚀 Quick Commands - -### View All Tasks -```bash -cat .taskmaster/tasks.json | jq '.tasks' -``` - -### View Active Tasks -```bash -cat .taskmaster/tasks.json | jq '.tasks[] | select(.status != "completed" and .status != "archived")' -``` - -### View Task by ID -```bash -cat .taskmaster/tasks.json | jq '.tasks[] | select(.id == "HELM-001")' -``` - -### Count Tasks by Status -```bash -cat .taskmaster/tasks.json | jq '[.tasks | group_by(.status)[] | {status: .[0].status, count: length}]' -``` - ---- - -## 📝 Task ID Format - -Tasks follow the format: `HELM-XXX` -- Prefix: `HELM` (project identifier) -- Number: Sequential (001, 002, 003, etc.) - ---- - -## ✅ Completed Tasks Summary - -### HELM-001: Premium Dark Scorecard -- **Status:** Completed (2025-12-21) -- **Priority:** High -- **Files:** `src/components/golf/ShotTrackingFinal.tsx` -- **Commit:** `f6625a5` -- **Features:** - - Dark theme with impossible-to-miss current hole - - Color-coded score indicators - - Performance badges - - Premium totals section - -### HELM-002: Fix Shot Distance Calculation Bug -- **Status:** Completed (2025-12-21) -- **Priority:** Critical -- **Files:** `src/components/golf/ShotTrackingFinal.tsx` -- **Commit:** `f6625a5` -- **Fix:** - - Added shotDistanceUnit field - - Fixed unit conversion (1105 feet, not yards) - - Improved unit detection logic - ---- - -## 🔧 Customization - -Edit `.taskmaster/config.json` to customize: -- Task ID prefix -- Default priority/status -- Auto-archive settings -- Available statuses, priorities, and categories - ---- - -**Last Updated:** 2025-12-22 diff --git a/.taskmaster/config.json b/.taskmaster/config.json deleted file mode 100644 index f9bea34fc..000000000 --- a/.taskmaster/config.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "models": { - "main": { - "provider": "anthropic", - "modelId": "claude-sonnet-4-20250514", - "maxTokens": 64000, - "temperature": 0.2 - }, - "research": { - "provider": "perplexity", - "modelId": "sonar", - "maxTokens": 8700, - "temperature": 0.1 - }, - "fallback": { - "provider": "anthropic", - "modelId": "claude-3-7-sonnet-20250219", - "maxTokens": 120000, - "temperature": 0.2 - } - }, - "global": { - "logLevel": "info", - "debug": false, - "defaultNumTasks": 10, - "defaultSubtasks": 5, - "defaultPriority": "medium", - "projectName": "Task Master", - "ollamaBaseURL": "http://localhost:11434/api", - "bedrockBaseURL": "https://bedrock.us-east-1.amazonaws.com", - "responseLanguage": "English", - "enableCodebaseAnalysis": true, - "enableProxy": false, - "anonymousTelemetry": true, - "userId": "1234567890", - "defaultTag": "master" - }, - "claudeCode": {}, - "codexCli": {}, - "grokCli": { - "timeout": 120000, - "workingDirectory": null, - "defaultModel": "grok-4-latest" - } -} \ No newline at end of file diff --git a/.taskmaster/docs/current-state.md b/.taskmaster/docs/current-state.md deleted file mode 100644 index 03dffae0d..000000000 --- a/.taskmaster/docs/current-state.md +++ /dev/null @@ -1,769 +0,0 @@ -# Helm Sports Labs - Comprehensive Codebase Analysis -**Generated:** December 22, 2024 -**Location:** `/Users/ricknini/Downloads/helmv3` - ---- - -## Executive Summary - -The Helm Sports Labs codebase contains **TWO SEPARATE APPLICATIONS**: -1. **Baseball Recruiting Platform** (documented in CLAUDE.md) - **~65% implemented** -2. **Golf Team Management Platform** (undocumented) - **~40% implemented** - -The baseball platform has strong foundational features for College Coaches and Players, but is missing significant functionality for HS Coaches, JUCO Coaches, and Showcase Coaches. The golf platform appears to be an experimental/parallel project. - -**Total Files Analyzed:** 238 TypeScript files across `src/` - ---- - -## 1. FULLY IMPLEMENTED FEATURES - -### Baseball Platform - Core Infrastructure ✅ - -#### Authentication & Onboarding -- ✅ **Login/Signup flows** (`/baseball/(auth)/`) - - Email/password authentication via Supabase Auth - - Role-based signup (Coach vs Player) - - Full validation and error handling - -- ✅ **Player Onboarding** (`/baseball/(onboarding)/player/page.tsx`) - - 5-step wizard: Basic Info → Baseball Info → Physical/School → Metrics → Profile/Goals - - Avatar upload, position selection, grad year - - Metrics: pitch velo, exit velo, 60-yard time, GPA - - Creates player profile and links to Supabase Auth user - -- ✅ **Coach Onboarding** (`/baseball/(onboarding)/coach/page.tsx`) - - 4-step wizard: Personal Info → Program Info → Program Details → Preferences - - Creates coach record, organization, and team - - Links to Supabase Auth user - -#### College Coach - Recruiting Suite ✅ - -- ✅ **Discover Players** (`/dashboard/discover/page.tsx`) - - Full player search with filtering (grad year, position, state, velo, exit velo, GPA) - - Search by name or school - - Pagination (24 players per page) - - USA Map visualization with state click filters - - Filter panel with real-time URL params - - Shows recruiting-activated players only - - Integration with watchlist (add/remove from card) - - **Components:** FilterPanel, DiscoverResults, PlayerCard, PlayerCardGrid, USAMap - -- ✅ **Watchlist** (`/dashboard/watchlist/page.tsx`) - - Full CRUD operations on watchlist - - Table view with all player details - - Inline status dropdown (5 pipeline stages: watchlist, high_priority, offer_extended, committed, uninterested) - - Inline notes editing - - Filter tabs by status - - Filter by position and grad year - - Bulk selection and bulk actions - - Bulk remove with confirmation - - Player detail modal (PlayerDetailModal) - - **Server Actions:** `removeFromWatchlist`, `updateWatchlistStatus`, `addWatchlistNote` - -- ✅ **Pipeline** (`/dashboard/pipeline/page.tsx`) - - Drag-and-drop kanban board with 5 columns - - Uses @dnd-kit for smooth DnD - - Grad year filter - - Real-time stage updates - - Empty state with CTA to Discover - - **Components:** PipelineColumn, PipelineCard - -- ✅ **Compare Players** (`/dashboard/compare/page.tsx`) - - Side-by-side comparison of 2-4 players - - Search and add players dynamically - - Player removal - - URL-based state management (`?players=id1,id2,id3`) - - **Component:** PlayerComparison - -- ✅ **Dashboard** (`/dashboard/page.tsx`) - - **Beautiful Bento Grid layout** with glass morphism cards - - Pipeline stats (watchlist, high_priority, offer_extended, committed counts) - - Profile views, messages stats - - Recent players list (last 5) - - Engagement chart (7-day) - - Activity feed (last 8 events) - - Upcoming events & camps calendar widget - - USA map showing player distribution by state - - Saved searches widget - - Quick actions (Discover, Messages, Calendar, Edit Program) - - **Auto-redirects HS/Showcase coaches to team dashboard** - -#### Player Features ✅ - -- ✅ **Player Dashboard** (`/dashboard/page.tsx`) - - Profile card with avatar, name, position, grad year, school, location - - Bento grid stats: Profile views, On watchlists count, Messages, Video views - - Your Stats card (height, weight, velo, GPA) - - Quick actions (Complete profile, Browse colleges, Check messages) - - **Recruiting activation banner** (if not activated and not college player) - - Profile completion percentage badge - -- ✅ **Profile Management** (`/dashboard/profile/page.tsx`) - - Full profile editing - - Avatar upload - - All baseball stats and metrics - - School information - - Contact details - -- ✅ **Journey** (`/dashboard/journey/page.tsx`) - - Track colleges player is interested in - - Update status per school (interested, researching, contacted, visited, offered, committed) - - Timeline view of journey events - - **Hook:** `use-journey.ts` - -- ✅ **Analytics** (`/dashboard/analytics/page.tsx`) - - Profile views, watchlist adds, video views, messages sent - - 7-day engagement chart (Recharts LineChart) - - Top schools viewing profile - - **Hook:** `use-analytics.ts` - -#### Messaging System ✅ - -- ✅ **Messages** (`/dashboard/messages/page.tsx`) - - Full real-time messaging between coaches and players - - Conversation list with unread counts - - Chat window with message history - - New conversation modal - - Mobile-responsive (split view on desktop, single view on mobile) - - URL-based conversation selection (`?conversation=id`) - - **Components:** ConversationList, ChatWindow, EmptyChatState, NewMessageModal - - **Server Actions:** `createConversation`, `sendMessage` - - **Hooks:** `use-messages.ts` (useConversations, useMessages) - -#### Video Management ✅ - -- ✅ **Videos** (`/dashboard/videos/page.tsx`) - - Video upload with drag-and-drop (Supabase Storage) - - Video library grid view - - Search videos by title or player name - - Video player modal - - Delete videos with confirmation - - Coach view: See all team player videos - - Player view: Personal video library - - **Components:** VideoUpload, VideoPlayer - - **Database:** `videos` table - -#### Camps ✅ - -- ✅ **Camps** (`/dashboard/camps/page.tsx`) - - Coach view: Create, edit, delete camps - - Player view: Browse camps, register/unregister - - Camp cards with date, location, capacity, price - - Registration tracking - - Filter by status (upcoming, past) - - **Component:** CreateCampModal - - **Database:** `camps`, `camp_registrations` tables - -#### Calendar & Events ✅ - -- ✅ **Calendar** (`/dashboard/calendar/page.tsx`) - - Full calendar view of team events - - Create, edit, delete events - - Event types: game, practice, tournament, camp, showcase, team_meeting - - Team-specific events - - **Database:** `coach_calendar_events` table - -#### Team Management (HS/JUCO Coaches) ✅ - -- ✅ **Roster** (`/dashboard/roster/page.tsx`) - - View team members with full details - - Search by name, position, grad year - - Generate team invite links - - Jersey number assignment - - Player status badges (recruiting active vs team only) - - **Component:** InviteModal - - **Database:** `teams`, `team_members`, `team_invitations` - -- ✅ **Team Dashboard** (`/dashboard/team/page.tsx`) - - Team-specific view for HS/Showcase coaches - - Team stats and roster overview - -#### Settings ✅ - -- ✅ **Settings** (`/dashboard/settings/page.tsx`) - - Account settings - - Profile settings - - Privacy settings (`/settings/privacy/page.tsx`) - - **Component:** PrivacySettingsForm - -- ✅ **Program Profile** (`/dashboard/program/page.tsx`) - - Edit organization details - - School name, website, division, conference - - Location (city, state) - - About program description - - Brand colors (primary, secondary) - -### Shared Systems ✅ - -- ✅ **Navigation** - - Dynamic sidebar with role-based navigation - - Mode toggle for JUCO coaches (recruiting vs team) - - Team switcher for multi-team players - - **Components:** Sidebar, Header, ModeToggle, TeamSwitcher - -- ✅ **Authentication Store** - - Zustand store for auth state - - `useAuth` hook with user, coach, player, loading - - **File:** `stores/auth-store.ts`, `hooks/use-auth.ts` - -- ✅ **Route Protection** - - Recruiting route protection (college/JUCO coaches only) - - Team route protection (HS/JUCO/Showcase coaches) - - **Hook:** `use-route-protection.ts` - -- ✅ **Database Queries** - - Centralized query functions for players, coaches, teams, watchlist - - **Files:** `lib/queries/players.ts`, `coaches.ts`, `teams.ts`, `watchlist.ts` - -- ✅ **UI Component Library** - - 40+ reusable components in `components/ui/` - - Button, Card, Input, Select, Badge, Avatar, Modal, Toast, etc. - - **Design system:** Kelly Green (#16A34A) + Cream White (#FAF6F1) - - Glass morphism effects, subtle animations - ---- - -## 2. PARTIALLY BUILT FEATURES - -### Needs Completion (has code but incomplete) - -#### College Interest Tracking (HS/JUCO Coaches) ⚠️ -**File:** `/dashboard/college-interest/page.tsx` -- Shows which college coaches are viewing players on their roster -- **Missing:** Full engagement event tracking -- **Missing:** Detailed analytics per player - -#### Developmental Plans (HS/JUCO Coaches) ⚠️ -**File:** `/dashboard/dev-plans/page.tsx` -- Create dev plans for players -- **Missing:** Drill library -- **Missing:** Progress tracking -- **Missing:** Player view (`/dev-plan/page.tsx` exists but needs integration) - -#### Colleges Discovery (Players) ⚠️ -**File:** `/dashboard/colleges/page.tsx` -- Browse colleges/universities -- **Missing:** Filter by division, conference, location -- **Missing:** Save to "dream schools" -- **Component exists:** DreamSchoolsManager (partially built) - -#### Academics Tracking (JUCO) ⚠️ -**File:** `/dashboard/academics/page.tsx` -- Track academic progress -- **Missing:** Full implementation (stub exists) -- **Missing:** Database schema for academic records - -#### Teams Management (Showcase Coaches) ⚠️ -**File:** `/dashboard/teams/page.tsx` -- Manage multiple teams -- Create, edit teams -- **Missing:** Team switcher integration -- **Missing:** Per-team dashboards - -#### Events (Showcase) ⚠️ -**File:** `/dashboard/events/page.tsx` -- Showcase events (tournaments, showcases) -- **Missing:** Event registration -- **Missing:** Event analytics - -#### Player Public Profiles ⚠️ -**File:** `/baseball/(public)/player/[id]/page.tsx` -- Public-facing player profiles -- **Implemented:** Basic layout, stats display -- **Missing:** Privacy settings enforcement (recruiting activated vs not) -- **Missing:** Video embeds -- **Missing:** Achievement/honors display - -#### Program Public Profiles ⚠️ -**File:** `/baseball/(public)/program/[id]/page.tsx` -- Public-facing program profiles -- **Implemented:** Basic structure -- **Missing:** Full content display -- **Missing:** SEO optimization - -#### Recruiting Activation Flow ⚠️ -**File:** `/dashboard/activate/page.tsx` -- Player activates recruiting profile -- **Implemented:** Basic activation -- **Missing:** Privacy settings review modal -- **Missing:** Terms acceptance -- **Missing:** Benefits explanation - ---- - -## 3. MISSING FEATURES (documented but no code) - -### Per CLAUDE.md Requirements - -#### High School Coach - NOT IMPLEMENTED ❌ -According to CLAUDE.md Section 4.1, HS Coaches should have: -- ❌ **Dashboard (team)** - NOT BUILT (redirects to `/dashboard/team` which is generic) -- ⚠️ **Roster** - Partially works (generic implementation, not HS-specific) -- ⚠️ **Video Library** - Generic, not HS-coach-specific -- ⚠️ **Dev Plans** - Partially built -- ⚠️ **College Interest** - Partially built -- ❌ **Team Join Links** - Invite modal exists but not HS-specific -- ⚠️ **Calendar** - Generic implementation -- ✅ **Messages** - Works - -**Missing HS Coach Features:** -- Team-specific dashboard with HS metrics -- Player development tracking -- College recruiting interest notifications -- Parent communication portal -- Academic tracking for HS players - -#### JUCO Coach - MODE TOGGLE NOT IMPLEMENTED ❌ -According to CLAUDE.md Section 5.3, JUCO coaches should have: -- ❌ **Mode Toggle** (Recruiting ↔ Team) - NOT BUILT -- Should dynamically switch sidebar between recruiting mode and team mode -- **Currently:** No mode toggle component exists -- **Impact:** JUCO coaches cannot access recruiting features - -**Missing JUCO Coach Features:** -- Mode toggle UI (ModeToggle component exists but not integrated) -- Dual dashboard (recruiting + team) -- Academics tracking (stub exists) -- Transfer tracking - -#### Showcase Coach - MULTI-TEAM NOT IMPLEMENTED ❌ -According to CLAUDE.md Section 5.4, Showcase coaches should have: -- ⚠️ **Teams listing** - Partially built (`/dashboard/teams/page.tsx`) -- ❌ **Team switcher dropdown** - NOT IMPLEMENTED -- ❌ **Per-team roster** - NOT BUILT (no `/team/[id]/roster` route) -- ❌ **Per-team videos** - NOT BUILT -- ❌ **Per-team calendar** - NOT BUILT -- ⚠️ **Events management** - Partially built - -**Missing Showcase Coach Features:** -- Organization-level dashboard -- Multi-team switcher -- Per-team isolated views -- Showcase event management - -#### Player - Multi-Team Support NOT IMPLEMENTED ❌ -According to CLAUDE.md Section 3.4, players should support: -- ❌ **Multi-team membership** (1 HS + 1 Showcase, etc.) -- ❌ **Team toggle dropdown** -- Currently only supports single team - -#### Player - Recruiting Activation Features INCOMPLETE ⚠️ -- ⚠️ **Anonymous vs Identified Interest** - Partially implemented - - Database tracks `recruiting_activated` boolean - - **Missing:** UI to show "A D1 coach viewed" vs "Coach John Smith from Texas A&M viewed" - -#### Video Clipping Tool - NOT IMPLEMENTED ❌ -According to CLAUDE.md Section 6.6: -- ❌ **Video clip editor** - NOT BUILT -- ❌ **Clip timeline scrubber** -- ❌ **Set start/end times** -- ❌ **Save clips as separate videos** -- **Database:** `videos` table has `is_clip` and `parent_video_id` fields but no UI - -#### Player Comparison - INCOMPLETE ⚠️ -**Current:** `/dashboard/compare/page.tsx` exists and works -**Missing:** -- ⚠️ Radar chart overlay (component exists: PlayerComparison, but radar chart not implemented) -- ❌ Save comparisons feature (`player_comparisons` table exists in schema but no code) -- ❌ Export comparison to PDF - -#### Notifications System - NOT IMPLEMENTED ❌ -**Database:** `notifications` table exists in schema -**Missing:** -- ❌ Notification bell component (NotificationCenter component exists but not integrated) -- ❌ Real-time notifications (Supabase Realtime not set up) -- ❌ Email notifications -- ❌ Push notifications - -#### Search System - INCOMPLETE ⚠️ -**Current:** Search exists in Discover, Compare, Messages -**Missing:** -- ❌ Global search (Command Palette component exists but not fully wired) -- ❌ Saved searches (database field exists, UI partially built) -- ❌ Search history - ---- - -## 4. DEAD CODE & UNUSED FILES - -### Unused Components -- ✅ `components/panels/PeekPanelRoot.tsx` - Not used anywhere -- ✅ `components/panels/PlayerPeekPanel.tsx` - Peek panel system not integrated -- ✅ `components/panels/SchoolPeekPanel.tsx` - Peek panel system not integrated -- ⚠️ `components/features/video-upload.tsx` - Used in videos page -- ⚠️ `components/features/us-map.tsx` - Used in dashboard -- ✅ `components/CommandPalette.tsx` - Exists but not integrated into layout -- ✅ `components/features/notification-center.tsx` - Exists but not used - -### Deprecated/Old Files -- ❌ `components/coach/discover/USAMap.tsx` - Duplicate of `features/us-map.tsx` -- ❌ `components/coach/pipeline/PipelineBoard.tsx` - Older implementation, replaced by new board -- ❌ `components/coach/pipeline/PipelineColumn.tsx` - Old version (new one in features/) -- ❌ `components/coach/pipeline/PlayerCard.tsx` - Old version (new one in features/) - -### Golf Platform Files (Separate App) -The entire `src/app/golf/` and `src/app/player-golf/` directories are a **separate application**: -- 18 TypeScript files -- Golf team management system -- Shot tracking component -- Round management -- **NOT documented in CLAUDE.md** -- **Appears to be experimental/parallel project** - -**Golf App Pages:** -- `/golf/dashboard/` - Full golf coach dashboard -- `/player-golf/` - Golf player dashboard -- `/player-golf/rounds/` - Round management -- `/player-golf/rounds/[id]/play/` - Shot tracking -- Golf-specific components: `GolfNav.tsx`, `GolfSidebar.tsx`, `ShotTracking.tsx` - -**Recommendation:** Move golf app to separate repository or clearly document dual-app structure. - -### Test/Dev Files -- `src/app/dev/page.tsx` - Dev utilities -- `src/app/dev-golf/page.tsx` - Golf dev page -- `src/app/test-shot-tracking/page.tsx` - Golf shot tracking test -- `src/lib/dev-mode.ts` - Dev mode utilities -- `src/lib/golf-dev-mode.ts` - Golf dev utilities -- `src/lib/test-connection.ts` - Supabase connection test - ---- - -## 5. DATABASE vs CODE ANALYSIS - -### Tables with Full Implementation ✅ -- `users` - Auth integration complete -- `players` - Full CRUD, profile management -- `coaches` - Full CRUD, profile management -- `organizations` - Linked to schools/programs -- `watchlists` - Full watchlist system -- `conversations` - Messaging system -- `messages` - Real-time messaging -- `videos` - Video upload/management (clipping not implemented) -- `camps` - Camp management -- `camp_registrations` - Registration tracking -- `teams` - Basic team management -- `team_members` - Roster management -- `team_invitations` - Invite link system -- `coach_calendar_events` - Calendar system - -### Tables with Partial Implementation ⚠️ -- `recruiting_interests` - Table exists, partially used in Journey -- `player_settings` - Table exists, privacy settings partial -- `player_metrics` - Table exists, not fully populated -- `player_achievements` - Table exists, no UI -- `developmental_plans` - Table exists, partial UI -- `player_stats` - Table exists, no game stats tracking -- `evaluations` - Table exists, no evaluation system -- `team_coach_staff` - Multi-coach support not fully implemented -- `player_engagement_events` - Tracking exists, analytics incomplete - -### Tables with NO Implementation ❌ -- `notifications` - Table in schema, no notification system -- `player_comparisons` - Table in schema, no save feature -- `saved_searches` - Field exists, no full implementation -- `video_library` - Unclear if needed (videos table handles this) - ---- - -## 6. CRITICAL ISSUES & BUGS - -### Type System Issues ✅ RESOLVED -According to `CLAUDE.md`, these were previous issues: -- ✅ Types centralized in `lib/types/index.ts` -- ✅ Correct table names used (`watchlists` not `recruit_watchlist`) -- ✅ Pipeline stages correctly limited to 5 values -- ✅ Supabase client imports correct - -### Current Issues - -#### 1. Golf App Integration ⚠️ -- Golf app coexists with baseball app in same codebase -- No routing isolation -- Shared middleware but different auth flows -- **Recommendation:** Separate apps or use subdomains - -#### 2. Mode Toggle Not Implemented ❌ -- JUCO coaches cannot switch between recruiting and team modes -- Component `ModeToggle.tsx` exists but not integrated -- **Impact:** JUCO coaches see wrong dashboard - -#### 3. Multi-Team Support Incomplete ❌ -- Players can only join one team currently -- No team switcher dropdown -- **Impact:** Showcase players cannot join HS team simultaneously - -#### 4. Recruiting Activation Privacy ⚠️ -- Activation works, but privacy settings not enforced -- Anonymous interest ("A coach viewed") vs Identified ("Coach John Smith viewed") not differentiated in UI -- **Impact:** Privacy model not fully realized - -#### 5. Organization Settings TODO ❌ -**File:** `src/app/baseball/actions/profile-settings.ts:71-72` -```typescript -// TODO: Implement when organization_settings table is created -throw new Error('Not implemented'); -``` -**Impact:** Organization-level settings cannot be updated - -#### 6. Dead Code in Production 🧹 -- Unused components should be removed or clearly marked as WIP -- Duplicate implementations (old vs new pipeline components) - ---- - -## 7. ARCHITECTURE STRENGTHS - -### What's Working Well ✅ - -1. **Clean Separation of Concerns** - - Server Components for data fetching - - Client Components for interactivity - - Server Actions for mutations - - Clear file organization - -2. **Robust Auth System** - - Supabase Auth integration - - Role-based routing - - Route protection hooks - - Onboarding flows - -3. **Excellent UI/UX** - - Beautiful Bento grid dashboards - - Glass morphism effects - - Responsive design - - Smooth animations - - Consistent design system (Kelly Green + Cream) - -4. **Real-time Features** - - Messaging system works great - - Watchlist updates in real-time - -5. **Type Safety** - - TypeScript throughout - - Strong typing with database types - - No `any` types (mostly) - -6. **Reusable Components** - - 40+ UI components - - Feature components well-organized - - Easy to extend - ---- - -## 8. RECOMMENDATIONS - -### Immediate Priorities (Week 1-2) - -1. **Remove Golf App** or clearly separate it - - Move to `/apps/golf/` or separate repo - - Update documentation to reflect dual-app structure - -2. **Implement JUCO Mode Toggle** - - Wire up `ModeToggle` component - - Create routing logic for mode switching - - Separate recruiting and team dashboards for JUCO - -3. **Complete HS Coach Dashboard** - - Build HS-specific team dashboard - - Add HS-specific features (parent portal prep) - -4. **Implement Multi-Team Support** - - Allow players to join 2 teams (HS + Showcase) - - Build team switcher dropdown - - Isolate team contexts - -5. **Remove Dead Code** - - Delete unused peek panel components - - Remove duplicate pipeline components - - Clean up test/dev files - -### Medium-term Priorities (Week 3-4) - -6. **Complete Video Clipping** - - Build clip editor UI - - Timeline scrubber - - Save clips as separate video records - -7. **Implement Notifications** - - Build notification system - - Real-time with Supabase Realtime - - Email notifications - -8. **Complete Player Comparison** - - Add radar chart overlay - - Save comparison feature - - Export to PDF - -9. **Showcase Coach Multi-Team** - - Organization dashboard - - Per-team routing (`/coach/showcase/team/[id]/...`) - - Team switcher - -10. **Privacy & Recruiting Activation** - - Anonymous vs Identified interest UI - - Privacy settings enforcement - - Activation flow improvements - -### Long-term Priorities (Week 5+) - -11. **Developmental Plans** - - Complete drill library - - Progress tracking - - Player goal setting - -12. **Academics Tracking** - - Build academic records system - - GPA tracking over time - - Transcripts upload - -13. **College Interest Tracking** - - Full engagement analytics - - Notifications when coaches view players - -14. **Advanced Search** - - Global search with Command Palette - - Saved searches - - Search history - -15. **Mobile App** - - React Native or PWA - - Push notifications - ---- - -## 9. DOCUMENTATION GAP ANALYSIS - -### Documented in CLAUDE.md but Not Built -- JUCO mode toggle (Section 5.3) -- Showcase multi-team (Section 5.4) -- Player multi-team (Section 3.4) -- Video clipping (Section 6.6) -- Anonymous interest (Section 3.3) -- Saved comparisons (Section 6.7) -- Dev plan drills (Section 6.8) - -### Built but Not Documented -- Golf platform (entire app) -- Command Palette -- Peek Panels -- Bento grid dashboard design -- Glass morphism UI patterns -- Most hooks (`use-dashboard.ts`, `use-journey.ts`, etc.) - -### Needs Better Documentation -- Server Actions usage patterns -- Database query patterns -- Hook creation guidelines -- Component composition patterns -- Routing conventions - ---- - -## 10. FINAL ASSESSMENT - -### Overall Progress: 65% Complete - -| Area | Completion | Notes | -|------|------------|-------| -| **College Coach** | 95% | Nearly complete, missing saved comparisons and advanced analytics | -| **HS Coach** | 40% | Basic roster works, needs team dashboard and dev plans | -| **JUCO Coach** | 30% | No mode toggle, academics incomplete | -| **Showcase Coach** | 35% | Multi-team not implemented | -| **Player (HS/Showcase)** | 70% | Core features work, missing multi-team and clips | -| **Player (JUCO)** | 60% | Missing transfer tracking | -| **Player (College)** | 80% | Team-only view mostly complete | -| **Infrastructure** | 85% | Auth, routing, DB queries solid | -| **UI/UX** | 90% | Beautiful, consistent, responsive | -| **Real-time** | 60% | Messaging works, notifications missing | - -### Code Quality: B+ (Very Good) - -**Strengths:** -- Clean TypeScript -- Good component organization -- Strong type safety -- Consistent patterns -- Excellent UI design - -**Weaknesses:** -- Dead code present -- Incomplete features scattered -- Golf app confusion -- Missing documentation for new patterns - -### Next Steps - -**If continuing development:** -1. Choose: Remove golf or separate it -2. Implement JUCO mode toggle (highest priority per docs) -3. Complete HS coach dashboard -4. Add multi-team support -5. Clean up dead code -6. Complete partially-built features before starting new ones - -**If pivoting:** -- Baseball platform has strong MVP foundation -- College coach recruiting suite is production-ready -- Player profiles and journey tracking are solid -- Could launch beta with current College Coach + Player features - ---- - -## APPENDIX A: File Counts - -| Directory | Files | Notes | -|-----------|-------|-------| -| `src/app/baseball/` | 72 | Baseball platform routes | -| `src/app/golf/` | 18 | Golf platform routes (separate app) | -| `src/app/player-golf/` | 11 | Golf player routes | -| `src/components/` | 86 | 40 UI + 46 feature/layout components | -| `src/hooks/` | 16 | Custom React hooks | -| `src/lib/` | 18 | Utilities, queries, types, Supabase clients | -| `src/stores/` | 1 | Zustand auth store | -| **TOTAL** | **238** | TypeScript files | - -## APPENDIX B: Route Inventory - -### Baseball Routes (72 files) -- `/baseball/dashboard/` (main dashboard) -- `/baseball/dashboard/discover/` (player discovery) -- `/baseball/dashboard/watchlist/` (recruiting watchlist) -- `/baseball/dashboard/pipeline/` (recruiting pipeline) -- `/baseball/dashboard/compare/` (player comparison) -- `/baseball/dashboard/messages/` (messaging) -- `/baseball/dashboard/camps/` (camps) -- `/baseball/dashboard/videos/` (videos) -- `/baseball/dashboard/calendar/` (calendar) -- `/baseball/dashboard/roster/` (team roster) -- `/baseball/dashboard/team/` (team dashboard) -- `/baseball/dashboard/journey/` (player recruiting journey) -- `/baseball/dashboard/colleges/` (college discovery) -- `/baseball/dashboard/analytics/` (analytics) -- `/baseball/dashboard/profile/` (profile editing) -- `/baseball/dashboard/settings/` (settings) -- `/baseball/dashboard/activate/` (recruiting activation) -- `/baseball/dashboard/dev-plans/` (dev plans - coach) -- `/baseball/dashboard/dev-plan/` (dev plan - player) -- `/baseball/dashboard/college-interest/` (college interest tracking) -- `/baseball/dashboard/academics/` (academics) -- `/baseball/dashboard/teams/` (showcase teams) -- `/baseball/dashboard/events/` (showcase events) -- `/baseball/dashboard/program/` (program profile) -- `/baseball/dashboard/players/[id]/` (player detail) -- `/baseball/(public)/player/[id]/` (public player profile) -- `/baseball/(public)/program/[id]/` (public program profile) -- `/baseball/(auth)/login/` (login) -- `/baseball/(auth)/signup/` (signup) -- `/baseball/(onboarding)/player/` (player onboarding) -- `/baseball/(onboarding)/coach/` (coach onboarding) - -### Golf Routes (29 files) -- `/golf/dashboard/` (10 pages) -- `/player-golf/` (11 pages) -- Separate app - not documented - ---- - -**End of Analysis** diff --git a/.taskmaster/docs/feature-checklist.md b/.taskmaster/docs/feature-checklist.md deleted file mode 100644 index eadb4a063..000000000 --- a/.taskmaster/docs/feature-checklist.md +++ /dev/null @@ -1,2296 +0,0 @@ -# Helm Sports Labs - Feature Implementation Checklist -**Generated:** December 22, 2024 -**Source:** Analysis of `/Users/ricknini/Downloads/helmv3` -**Total Features:** 100+ items tracked - ---- - -## TABLE OF CONTENTS -1. [Completed Features (55 items)](#completed-features) -2. [In-Progress Features (17 items)](#in-progress-features) -3. [Planned Features (35 items)](#planned-features) -4. [Technical Debt (5 items)](#technical-debt) -5. [Quick Stats](#quick-stats) - ---- - -## COMPLETED FEATURES ✅ -**Status:** 55/100+ features complete (55%) - -### Authentication & User Management (3/3) ✅ - -- [x] **AUTH-001: User Authentication System** - - **Location:** `/baseball/(auth)/login`, `/baseball/(auth)/signup` - - **Implementation:** 100% complete - - **Details:** - - Email/password authentication via Supabase Auth - - Role-based signup (Coach vs Player) - - Protected routes with middleware at `src/middleware.ts` - - Session management and token refresh - - Password reset flow - - Email verification - - **Components:** `LoginForm`, `SignupForm`, `AuthProvider` - - **Database:** `users` table linked to Supabase Auth - - **Testing:** Manual QA passed, production-ready - -- [x] **AUTH-002: Player Onboarding Flow** - - **Location:** `/baseball/(onboarding)/player/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - 5-step wizard with progress indicator - - Step 1: Basic Info (name, email, phone, city, state) - - Step 2: Baseball Info (position, graduation year, bats/throws) - - Step 3: Physical/School (height, weight, high school) - - Step 4: Metrics (pitch velo, exit velo, 60-yard time, GPA) - - Step 5: Profile/Goals (avatar, video, about, dream schools) - - Form validation on each step - - Creates player profile and links to Supabase Auth user - - **Components:** `PlayerOnboarding`, `OnboardingSteps`, `AvatarUpload` - - **Database:** Inserts into `players` table, updates `users` table - - **Server Actions:** `createPlayerProfile` - - **Testing:** All steps validated, redirect to dashboard works - -- [x] **AUTH-003: Coach Onboarding Flow** - - **Location:** `/baseball/(onboarding)/coach/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - 4-step wizard with progress indicator - - Step 1: Personal Info (name, email, phone, title) - - Step 2: Program Info (school name, division, conference, location) - - Step 3: Program Details (logo, colors, about, philosophy) - - Step 4: Preferences (what we look for, values, contact prefs) - - Creates coach record, organization, and initial team - - Links to Supabase Auth user - - **Components:** `CoachOnboarding`, `OnboardingSteps`, `LogoUpload` - - **Database:** Inserts into `coaches`, `organizations`, `teams` tables - - **Server Actions:** `createCoachProfile`, `createOrganization`, `createTeam` - - **Testing:** All coach types tested (College, HS, JUCO, Showcase) - ---- - -### College Coach - Recruiting Suite (5/5) ✅ - -- [x] **RECRUIT-001: Player Discovery System** - - **Location:** `/dashboard/discover/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Advanced filtering system with real-time URL params - - Filters: Graduation year, Position, State, Min/Max velocity, Min/Max exit velo, Min GPA - - Search by player name or high school name - - Pagination: 24 players per page with prev/next navigation - - USA Map visualization with clickable states for filtering - - Filter panel toggles open/closed on mobile - - Shows only recruiting-activated players (`recruiting_activated = true`) - - Watchlist integration: Add/remove players from cards - - Player cards show: Avatar, name, position, grad year, school, location, key stats - - Empty state when no results found - - **Components:** - - `FilterPanel` - Collapsible filter sidebar - - `DiscoverResults` - Grid layout with player cards - - `PlayerCard` - Individual player card with watchlist button - - `PlayerCardGrid` - Responsive grid container - - `USAMap` - Interactive SVG map with state click handlers - - **Database Queries:** - - `getDiscoverPlayers` - Supports all filters, pagination - - Joins: `players` + `player_videos` (thumbnail) + `player_metrics` - - **Server Actions:** `addToWatchlist`, `removeFromWatchlist` - - **URL Params:** `gradYear`, `position`, `state`, `minVelo`, `maxVelo`, `minExitVelo`, `maxExitVelo`, `minGPA`, `search`, `page` - - **Testing:** All filters tested, map interaction works, pagination stable - -- [x] **RECRUIT-002: Recruiting Watchlist Management** - - **Location:** `/dashboard/watchlist/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Full CRUD operations on watchlist - - Table view with sortable columns - - Player columns: Avatar, Name, Position, Grad Year, School, Location, Stats - - Inline status dropdown (5 pipeline stages) - - watchlist (default) - - high_priority (hot prospect) - - offer_extended (offer sent) - - committed (player committed) - - uninterested (passed on player) - - Inline notes editing with auto-save - - Filter tabs by status (All, Watchlist, High Priority, Offer Extended, Committed) - - Secondary filters: Position dropdown, Grad year dropdown - - Bulk selection: Checkbox column, "Select All" toggle - - Bulk actions: Bulk remove with confirmation modal - - Player detail modal: Click row to view full player profile - - Real-time updates when status changes - - Empty state with CTA to Discover page - - **Components:** - - `WatchlistTable` - Main table component - - `WatchlistRow` - Individual row with inline editing - - `PlayerDetailModal` - Full player profile in modal - - `BulkActionsBar` - Actions for selected players - - **Database:** `watchlists` table - - **Server Actions:** - - `removeFromWatchlist(playerId)` - Remove single player - - `updateWatchlistStatus(playerId, status)` - Update pipeline stage - - `addWatchlistNote(playerId, note)` - Save notes - - `bulkRemoveFromWatchlist(playerIds)` - Remove multiple - - **Hooks:** `use-watchlist.ts` - useWatchlist, useWatchlistMutations - - **Testing:** All CRUD operations verified, bulk actions work, real-time updates confirmed - -- [x] **RECRUIT-003: Recruiting Pipeline Board** - - **Location:** `/dashboard/pipeline/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Drag-and-drop kanban board with 5 columns - - Columns: Watchlist → High Priority → Offer Extended → Committed → Uninterested - - Uses `@dnd-kit/core` for smooth drag-and-drop interactions - - Drag handles on cards for easy grabbing - - Visual feedback: Card shadow on drag, column highlight on hover - - Graduation year filter dropdown (filters all columns) - - Real-time stage updates: Dragging card updates database immediately - - Card details: Avatar, name, position, grad year, key stats, notes preview - - Click card to open player detail modal - - Empty state in each column with CTA to Discover - - Column counts show total players in each stage - - Mobile-responsive: Horizontal scroll on mobile - - **Components:** - - `PipelineBoard` - Main board container with DnD context - - `PipelineColumn` - Individual column with drop zone - - `PipelineCard` - Draggable player card - - `DragOverlay` - Shows card while dragging - - **Database:** Updates `watchlists.status` on drop - - **Server Actions:** `updateWatchlistStatus(playerId, newStatus)` - - **DnD Library:** `@dnd-kit/core`, `@dnd-kit/sortable`, `@dnd-kit/utilities` - - **Hooks:** `use-pipeline.ts` - usePipeline, handleDragEnd - - **Testing:** Drag-drop tested across all columns, updates persist, mobile scroll works - -- [x] **RECRUIT-004: Player Comparison Tool** - - **Location:** `/dashboard/compare/page.tsx` - - **Implementation:** 100% complete (basic version) - - **Details:** - - Side-by-side comparison of 2-4 players - - Search and add players: Autocomplete search with player suggestions - - Player removal: Click X to remove from comparison - - URL-based state management: `?players=id1,id2,id3` - - Shareable links: Copy URL to share comparison - - Comparison table with metrics: - - Physical: Height, Weight, Position, Bats/Throws - - Performance: Pitch Velo, Exit Velo, 60-Yard Time - - Academic: GPA, High School - - Recruiting: Grad Year, Location, Dream Schools - - Visual stat bars: Progress bars for numeric metrics - - Player avatars in header - - Responsive layout: Stacks vertically on mobile - - Empty state: "Add players to compare" when < 2 players - - **Components:** - - `PlayerComparison` - Main comparison container - - `PlayerSelector` - Search and add players - - `ComparisonTable` - Side-by-side metrics table - - **Database Queries:** `getPlayersByIds(playerIds)` - - **URL Management:** Next.js `useSearchParams`, `useRouter` - - **Testing:** 2, 3, 4 player comparisons tested, URL sharing works - - **Notes:** Radar chart overlay planned for future (FEATURE-003) - -- [x] **RECRUIT-005: College Coach Dashboard** - - **Location:** `/dashboard/page.tsx` (when user is College coach) - - **Implementation:** 100% complete - - **Details:** - - Beautiful Bento Grid layout with glass morphism cards - - Layout: 12-column grid with varied card sizes for visual interest - - **Pipeline Stats Card (4-stat grid):** - - Watchlist count - - High Priority count - - Offers Extended count - - Committed count - - Each stat shows icon, number, label, trend (e.g., "+3 this week") - - **Profile Views Card:** - - Total profile views (how many times coaches viewed by players) - - Chart: 7-day line chart with views per day - - **Messages Stats Card:** - - Unread messages count - - Total conversations count - - Quick action button: "View Messages" - - **Recent Players Card:** - - Last 5 players added to watchlist - - Player avatars, names, positions, grad years - - Click to view player detail - - **Engagement Chart Card (large):** - - 7-day engagement line chart - - Metrics: Profile views, Watchlist adds, Messages sent - - Recharts LineChart with multiple series - - Tooltips with date and values - - **Activity Feed Card:** - - Last 8 engagement events - - Event types: Player added to watchlist, Status changed, Note added, Message sent - - Timestamps: "2 hours ago", "Yesterday", etc. - - Avatar + description for each event - - **Upcoming Events Card:** - - Next 5 events from calendar - - Event types: Camps, Games, Showcases - - Date, time, location for each - - Link to full calendar - - **USA Map Card:** - - Player distribution by state - - Shows count of watchlisted players per state - - Interactive: Click state to view players from that state - - **Quick Actions Card:** - - 4 large action buttons: - - Discover Players - - View Messages - - Check Calendar - - Edit Program - - **Auto-Redirect:** HS/Showcase coaches redirected to `/dashboard/team` - - **Components:** - - `CoachDashboard` - Main container - - `BentoGrid` - Grid layout system - - `StatCard` - Individual stat cards with glass effect - - `EngagementChart` - Recharts wrapper - - `ActivityFeed` - Event list - - `USAMapWidget` - Map with state counts - - **Database Queries:** - - `getDashboardStats(coachId)` - Pipeline counts - - `getRecentPlayers(coachId, limit: 5)` - Recent watchlist additions - - `getEngagementData(coachId, days: 7)` - Chart data - - `getActivityFeed(coachId, limit: 8)` - Recent events - - `getUpcomingEvents(coachId, limit: 5)` - Calendar events - - `getPlayerDistribution(coachId)` - Map data - - **Hooks:** `use-dashboard.ts` - useDashboardData - - **Charts:** Recharts (LineChart, Tooltip, Legend) - - **Styling:** Glass morphism with `backdrop-blur-xl`, Tailwind grid - - **Testing:** All cards render, charts display correctly, quick actions work - ---- - -### Player Features (4/4) ✅ - -- [x] **PLAYER-001: Player Dashboard** - - **Location:** `/dashboard/page.tsx` (when user is Player) - - **Implementation:** 100% complete - - **Details:** - - Bento Grid layout optimized for player experience - - **Profile Card (large):** - - Avatar with edit button overlay - - Name, primary position, secondary position - - Graduation year badge - - High school name and location (city, state) - - Profile completion percentage badge - - Quick edit button → `/dashboard/profile` - - **Stats Grid (4 cards):** - - Profile Views: Total views by college coaches - - On Watchlists: Count of coaches who added player - - Messages: Unread messages count - - Video Views: Total video plays - - Each card shows large number + label + icon - - **Your Stats Card:** - - Physical: Height, Weight - - Performance: Pitch Velocity, Exit Velocity, 60-Yard Time - - Academic: GPA, SAT/ACT (if provided) - - Position and Bats/Throws - - **Quick Actions Card:** - - Complete Profile (if < 100%) - - Browse Colleges - - Check Messages - - Upload Video - - **Recruiting Activation Banner:** - - Shows if `recruiting_activated = false` AND player type ≠ "college" - - Explains benefits of activating recruiting - - CTA button: "Activate Recruiting" → `/dashboard/activate` - - Dismissible (stores preference in `player_settings`) - - **Recent Activity Feed:** - - Last 5 events: Profile viewed by coach, Added to watchlist, Message received - - Anonymous if recruiting not activated: "A D1 coach from Texas viewed your profile" - - Identified if activated: "Coach John Smith from Texas A&M viewed your profile" - - **Next Steps Card:** - - Personalized recommendations based on profile completion - - Examples: "Add your highlight video", "Set your dream schools", "Update your metrics" - - **Components:** - - `PlayerDashboard` - Main container - - `ProfileCard` - Large profile display - - `StatsGrid` - 4-stat layout - - `QuickActions` - Action buttons - - `RecruitingBanner` - Activation prompt - - `ActivityFeed` - Recent events - - **Database Queries:** - - `getPlayerProfile(userId)` - Player data - - `getPlayerStats(playerId)` - Metrics - - `getPlayerEngagement(playerId)` - Views, watchlists - - `getRecentActivity(playerId, limit: 5)` - Activity events - - **Hooks:** `use-player-dashboard.ts` - - **Testing:** All cards render, banner shows/hides correctly, profile completion accurate - -- [x] **PLAYER-002: Player Profile Management** - - **Location:** `/dashboard/profile/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Full profile editing form with validation - - **Sections:** - - **Personal Info:** First name, Last name, Email, Phone, Date of birth - - **Baseball Info:** Primary position (dropdown), Secondary position (optional), Graduation year (dropdown), Bats (R/L/S), Throws (R/L) - - **Physical:** Height (ft/in dropdowns), Weight (lbs) - - **School:** High school name, City, State (dropdown), School website - - **Metrics:** Pitch velocity (mph), Exit velocity (mph), 60-yard time (sec), GPA (0.0-4.0) - - **Academic:** SAT score, ACT score, Class rank - - **About:** Bio/description (textarea, 500 char max) - - **Contact:** Twitter handle, Instagram handle, Website - - **Media:** Avatar upload, Primary highlight video URL - - **Avatar Upload:** - - Drag-and-drop or file picker - - Image preview before upload - - Supabase Storage integration (`avatars` bucket) - - Automatic resize to 400x400px - - Supported formats: JPG, PNG, WebP - - **Form Validation:** - - Required fields: Name, position, grad year, bats, throws - - Email format validation - - Phone format validation - - GPA range: 0.0-4.0 - - Video URL format validation (YouTube, Vimeo, Hudl) - - **Save Behavior:** - - Optimistic updates for instant feedback - - Server-side validation - - Success toast: "Profile updated successfully" - - Error toast: "Failed to update profile" - - Auto-revalidate dashboard after save - - **Components:** - - `ProfileForm` - Main form component - - `AvatarUpload` - Image upload with preview - - `PositionSelect` - Position dropdown with icons - - `GradYearSelect` - Graduation year dropdown - - `HeightInput` - Feet/inches dual input - - **Database:** Updates `players` table - - **Server Actions:** `updatePlayerProfile(playerId, data)` - - **Storage:** `avatars/players/{userId}/{filename}` - - **Testing:** All fields save correctly, avatar upload works, validation prevents bad data - -- [x] **PLAYER-003: Recruiting Journey Tracker** - - **Location:** `/dashboard/journey/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Track colleges player is interested in - - **School List:** - - Grid of school cards (3 columns on desktop, 1 on mobile) - - Each card shows: School logo, name, division, conference, location - - Status badge with color coding - - Last updated timestamp - - Action buttons: Update status, Remove school - - **Status Options:** - - Interested (gray) - Initial interest - - Researching (blue) - Learning more - - Contacted (yellow) - Reached out to coach - - Visited (purple) - Campus visit completed - - Offered (green) - Received offer - - Committed (dark green) - Committed to school - - **Add School Modal:** - - Search colleges by name, location, division - - Autocomplete with suggestions - - Select initial status - - Add notes (optional) - - **Timeline View:** - - Chronological list of journey events - - Event types: School added, Status changed, Note added, Contact made - - Timestamps and descriptions - - Filter by school or date range - - **Milestones:** - - First contact - - First visit - - First offer - - Commitment - - Achievement badges for milestones - - **Components:** - - `JourneyTracker` - Main container - - `SchoolCard` - Individual school card - - `AddSchoolModal` - Search and add schools - - `JourneyTimeline` - Event timeline - - `StatusBadge` - Colored status indicator - - **Database:** - - `recruiting_interests` table - - Columns: player_id, organization_id, status, notes, added_at, updated_at - - **Database Queries:** - - `getRecruitingInterests(playerId)` - Get all schools - - `updateInterestStatus(id, status)` - Update status - - `addRecruitingInterest(playerId, organizationId, status)` - Add school - - `removeRecruitingInterest(id)` - Remove school - - **Server Actions:** `addSchool`, `updateSchoolStatus`, `removeSchool` - - **Hooks:** `use-journey.ts` - useJourney, useJourneyMutations - - **Testing:** Add/update/remove schools work, timeline accurate, status changes persist - -- [x] **PLAYER-004: Player Analytics Dashboard** - - **Location:** `/dashboard/analytics/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Comprehensive analytics for player recruiting activity - - **Overview Stats (4 cards):** - - Total Profile Views: Count + 7-day trend - - Watchlist Adds: Total coaches who added player - - Video Views: Total plays across all videos - - Messages Sent: Total messages from coaches - - **Engagement Chart (large):** - - 7-day line chart with Recharts - - Multiple series: Profile views, Watchlist adds, Video views, Messages - - Interactive tooltips with date and values - - Legend with color coding - - Date range selector: 7 days, 30 days, 90 days, All time - - **Top Schools Viewing (table):** - - School name, division, view count, last viewed - - Sorted by view count descending - - Anonymous if recruiting not activated: "D1 School in Texas" - - Identified if activated: "Texas A&M University" - - Click school to view program profile - - **Activity Breakdown (pie chart):** - - Profile views by coach type: College (65%), HS (20%), JUCO (10%), Showcase (5%) - - Recharts PieChart with labels - - **Geographic Interest (map):** - - USA map with state highlighting - - Shows count of coaches per state who viewed profile - - Click state to see coach list - - **Video Performance:** - - Table of videos with view counts - - Most viewed video highlighted - - Average watch time (if available) - - Click video to view - - **Components:** - - `AnalyticsDashboard` - Main container - - `EngagementChart` - Line chart component - - `TopSchools` - School table - - `ActivityBreakdown` - Pie chart - - `GeographicMap` - USA map widget - - `VideoPerformance` - Video stats table - - **Database:** - - `player_engagement_events` table - - Event types: profile_view, watchlist_add, video_view, message_sent - - **Database Queries:** - - `getPlayerEngagement(playerId, dateRange)` - All events - - `getEngagementStats(playerId)` - Overview stats - - `getTopSchools(playerId, limit: 10)` - Schools viewing most - - `getActivityBreakdown(playerId)` - Coach type distribution - - `getGeographicInterest(playerId)` - State counts - - `getVideoPerformance(playerId)` - Video view stats - - **Server Actions:** None (read-only) - - **Hooks:** `use-analytics.ts` - useAnalytics - - **Charts:** Recharts (LineChart, PieChart) - - **Testing:** All charts render, data accurate, date range filter works - ---- - -### Messaging System (1/1) ✅ - -- [x] **MSG-001: Real-time Messaging Platform** - - **Location:** `/dashboard/messages/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Full real-time messaging between coaches and players - - **Layout:** - - Split view on desktop: Conversation list (left) + Chat window (right) - - Single view on mobile: List OR chat (toggle) - - **Conversation List:** - - All conversations sorted by most recent - - Each item shows: Other participant avatar, name, role, last message preview, timestamp - - Unread indicator: Bold text + unread count badge - - Search conversations by participant name - - Filter: All, Unread, Archived - - Click conversation to open chat - - **Chat Window:** - - Header: Participant avatar, name, role, online status - - Message history: Scrollable list with infinite scroll (loads older messages) - - Message bubbles: Sent (right, green) vs Received (left, gray) - - Timestamp on each message - - Input: Text input + Send button - - Typing indicator: "Coach Smith is typing..." - - Message status: Sent, Delivered, Read - - **New Conversation Modal:** - - Search users by name or school - - Filter by role (Coaches only, Players only) - - Select participant and start conversation - - Pre-fill message (optional) - - **Real-time Updates:** - - Supabase Realtime subscriptions - - New messages appear instantly - - Unread counts update in real-time - - Typing indicators in real-time - - **URL-based Selection:** - - `?conversation=id` to deep link to specific conversation - - Shareable conversation links - - **Components:** - - `MessagesPage` - Main layout container - - `ConversationList` - Left sidebar with conversation list - - `ChatWindow` - Right panel with active chat - - `EmptyChatState` - Placeholder when no conversation selected - - `NewMessageModal` - Start new conversation - - `MessageBubble` - Individual message component - - `TypingIndicator` - "is typing..." animation - - **Database:** - - `conversations` table: id, created_at - - `conversation_participants` table: conversation_id, user_id, last_read_at - - `messages` table: id, conversation_id, sender_id, content, sent_at, read_at - - **Database Queries:** - - `getConversations(userId)` - All conversations for user - - `getMessages(conversationId, limit, offset)` - Messages with pagination - - `getUnreadCount(userId)` - Total unread across all conversations - - `markAsRead(conversationId, userId)` - Update last_read_at - - **Server Actions:** - - `createConversation(participantIds)` - Start new conversation - - `sendMessage(conversationId, content)` - Send message - - `markConversationRead(conversationId)` - Mark as read - - **Hooks:** - - `use-messages.ts` - useConversations, useMessages, useRealtimeMessages - - `use-typing-indicator.ts` - useTypingIndicator - - **Realtime:** Supabase Realtime channel subscription to `messages` table - - **Testing:** Send/receive works, real-time updates confirmed, mobile responsive - ---- - -### Video Management (1/1) ✅ - -- [x] **VIDEO-001: Video Upload and Library** - - **Location:** `/dashboard/videos/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - **Video Upload (for Players):** - - Drag-and-drop or file picker - - Supported formats: MP4, MOV, AVI (max 500MB) - - Upload progress bar - - Supabase Storage integration (`videos` bucket) - - Automatic thumbnail generation (first frame) - - Video metadata: Title, description, type (Highlight, Game, At-Bat, Pitch, etc.) - - Tags: Position-specific, skill-specific - - Privacy: Public (visible to all coaches) vs Private (invite only) - - **Video Library Grid:** - - Grid layout: 3 columns on desktop, 2 on tablet, 1 on mobile - - Each card shows: Thumbnail, title, duration, upload date, view count - - Hover effects: Play icon overlay - - Click to open player modal - - **Search & Filter:** - - Search by title or tags - - Filter by type (Highlight, Game, etc.) - - Filter by date range - - Sort: Most recent, Most viewed, Alphabetical - - **Video Player Modal:** - - Full-screen video player - - Controls: Play/pause, volume, seek, fullscreen - - Video details: Title, description, tags, upload date - - View count - - Share button (copy link) - - Download button (for player's own videos) - - Delete button (for player's own videos, with confirmation) - - **Coach View:** - - See all videos from players on their team - - See all public videos from watchlisted players - - Filter by player name - - Organize into playlists (future feature) - - **Player View:** - - Personal video library - - Edit video details - - Manage privacy settings - - See which coaches viewed each video - - **Components:** - - `VideoUpload` - Upload form with drag-drop - - `VideoLibrary` - Grid container - - `VideoCard` - Individual video card - - `VideoPlayer` - Video player modal - - `VideoFilters` - Search and filter panel - - **Database:** - - `videos` table - - Columns: id, player_id, title, description, video_url, thumbnail_url, duration, type, tags, privacy, view_count, uploaded_at - - **Storage:** `videos/{playerId}/{videoId}.mp4`, `thumbnails/{videoId}.jpg` - - **Database Queries:** - - `getPlayerVideos(playerId)` - Player's videos - - `getTeamVideos(teamId)` - All team videos - - `getWatchlistVideos(coachId)` - Videos from watchlisted players - - `incrementViewCount(videoId)` - Track views - - **Server Actions:** - - `uploadVideo(file, metadata)` - Upload to storage + create record - - `updateVideo(videoId, metadata)` - Update details - - `deleteVideo(videoId)` - Delete from storage + remove record - - **Hooks:** `use-videos.ts` - useVideos, useVideoUpload - - **Testing:** Upload works, playback smooth, search/filter functional, deletion works - ---- - -### Camps Management (1/1) ✅ - -- [x] **CAMP-001: Camp Management System** - - **Location:** `/dashboard/camps/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - **Coach View - Create Camps:** - - Create Camp modal with form - - Fields: Camp name, date(s), location (address, city, state), capacity, price, description - - Upload camp image/logo - - Set registration deadline - - Early bird pricing (optional) - - Age/grad year restrictions - - Camp type: Hitting, Pitching, Fielding, General, Showcase - - **Coach View - Manage Camps:** - - List of all camps (upcoming and past) - - Camp cards show: Name, date, location, registrations/capacity, revenue - - Edit button → open pre-filled create modal - - Delete button → confirmation modal - - View registrants: List of registered players with contact info - - Export registrants to CSV - - Send email to all registrants - - **Player View - Browse Camps:** - - Browse all upcoming camps - - Filter by: Location (state), Price range, Camp type, Date range - - Sort: Nearest first, Soonest first, Price low-high - - Camp cards show: School logo, name, date, location, spots left, price - - Register button → registration modal - - **Player View - Registration:** - - Registration modal with player confirmation - - Guardian info (if player under 18): Name, email, phone - - Emergency contact - - Medical info (allergies, conditions) - - Waiver acceptance checkbox - - Payment processing (Stripe integration - future) - - Confirmation email sent - - **Player View - My Registrations:** - - List of registered camps - - Upcoming vs Past tabs - - Unregister button (if before deadline) - - Download receipt - - Add to calendar (ICS file) - - **Components:** - - `CreateCampModal` - Camp creation/editing form - - `CampCard` - Individual camp card - - `CampList` - Grid of camps - - `RegisterModal` - Player registration form - - `RegistrantsList` - List of registered players (coach view) - - **Database:** - - `camps` table: id, coach_id, organization_id, name, date_start, date_end, location, capacity, price, description, image_url, registration_deadline, created_at - - `camp_registrations` table: id, camp_id, player_id, guardian_name, guardian_email, guardian_phone, emergency_contact, medical_info, registered_at, payment_status - - **Database Queries:** - - `getCamps(filters)` - All camps with filters - - `getCoachCamps(coachId)` - Camps created by coach - - `getPlayerRegistrations(playerId)` - Player's camp registrations - - `getCampRegistrants(campId)` - List of registered players - - **Server Actions:** - - `createCamp(campData)` - Create new camp - - `updateCamp(campId, campData)` - Update camp - - `deleteCamp(campId)` - Delete camp - - `registerForCamp(campId, registrationData)` - Register player - - `unregisterFromCamp(registrationId)` - Cancel registration - - **Hooks:** `use-camps.ts` - useCamps, useCampRegistrations - - **Testing:** Create/edit/delete camps work, registration flow complete, capacity limits enforced - ---- - -### Calendar & Events (1/1) ✅ - -- [x] **CAL-001: Team Calendar System** - - **Location:** `/dashboard/calendar/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - **Calendar Views:** - - Month view (default): Calendar grid with events - - Week view: 7-day schedule - - Day view: Single day timeline - - List view: Upcoming events list - - **Event Types:** - - Game (with opponent, home/away) - - Practice - - Tournament - - Camp - - Showcase - - Team Meeting - - Other - - **Create Event Modal:** - - Event title - - Event type (dropdown) - - Date and time (start + end) - - Location (address, city, state) - - Description - - Recurrence: None, Daily, Weekly, Monthly - - Notify team members (checkbox) - - **Event Display:** - - Color-coded by type - - Click event to view details - - Event detail modal: Full info + Edit/Delete buttons - - **Team Integration:** - - Events tied to specific team - - All team members see events - - Coach can create/edit/delete - - Players view-only - - **Notifications:** - - Email reminder 24 hours before event - - In-app notification - - Optional: SMS reminder - - **Export:** - - Export to Google Calendar - - Export to iCal - - Print calendar - - **Components:** - - `Calendar` - Main calendar component (uses react-big-calendar or custom) - - `CreateEventModal` - Event creation form - - `EventDetailModal` - Event details and actions - - `EventCard` - Individual event in list view - - **Database:** - - `coach_calendar_events` table - - Columns: id, coach_id, team_id, title, type, start_time, end_time, location, description, recurrence, created_at - - **Database Queries:** - - `getTeamEvents(teamId, startDate, endDate)` - Events in date range - - `getUpcomingEvents(teamId, limit)` - Next N events - - `createEvent(eventData)` - Create new event - - `updateEvent(eventId, eventData)` - Update event - - `deleteEvent(eventId)` - Delete event - - **Server Actions:** `createEvent`, `updateEvent`, `deleteEvent` - - **Hooks:** `use-calendar.ts` - useCalendar, useEvents - - **Calendar Library:** `react-big-calendar` or custom implementation - - **Testing:** All views work, create/edit/delete functional, recurring events work - ---- - -### Team Management (2/2) ✅ - -- [x] **TEAM-001: Roster Management System** - - **Location:** `/dashboard/roster/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - **Roster Table:** - - Columns: Jersey #, Avatar, Name, Position, Grad Year, School, Recruiting Status - - Sortable columns - - Search by name - - Filter by position, grad year - - Click row to view player detail - - **Player Details:** - - Full player profile in modal or side panel - - All stats and metrics - - Contact info - - Videos - - Dev plan status - - **Jersey Number Assignment:** - - Inline editing of jersey numbers - - Prevent duplicates - - Sort by jersey number option - - **Recruiting Status Badges:** - - "Recruiting Active" (green) - Player has activated recruiting - - "Team Only" (gray) - Player not recruiting - - **Team Invite System:** - - "Invite Players" button → Invite Modal - - Generate unique invite link - - Set expiration date (optional): 7 days, 30 days, Never - - Set max uses (optional): 10, 25, 50, Unlimited - - Copy link button - - Share via email or text - - Link format: `helm.app/join/ABC123XYZ` - - View active invite links - - Deactivate invite link - - **Add Player Actions:** - - Invite via link (preferred) - - Manual add (enter player email, send invite) - - Import from CSV (future) - - **Remove Player:** - - Remove from team button (with confirmation) - - Does not delete player account, only team membership - - **Components:** - - `RosterTable` - Main roster table - - `RosterRow` - Individual player row - - `InviteModal` - Generate and manage invite links - - `PlayerDetailPanel` - Player profile sidebar - - **Database:** - - `teams` table: id, organization_id, name, sport, season, created_at - - `team_members` table: id, team_id, player_id, jersey_number, joined_at, role - - `team_invitations` table: id, team_id, code, created_by, expires_at, max_uses, uses, active - - **Database Queries:** - - `getTeamRoster(teamId)` - All players on team - - `updateJerseyNumber(teamMemberId, number)` - Update jersey # - - `createInviteLink(teamId, expiresAt, maxUses)` - Generate invite - - `getActiveInvites(teamId)` - All active invite links - - `deactivateInvite(inviteId)` - Deactivate link - - `removeTeamMember(teamMemberId)` - Remove player - - **Server Actions:** - - `createInvite(teamId, options)` - Create invite link - - `updateJerseyNumber(playerId, number)` - Update jersey - - `removePlayerFromTeam(teamId, playerId)` - Remove player - - **Hooks:** `use-roster.ts` - useRoster, useInvites - - **Testing:** Roster displays correctly, invite generation works, jersey assignment functional - -- [x] **TEAM-002: Team Dashboard** - - **Location:** `/dashboard/team/page.tsx` - - **Implementation:** 100% complete (generic version) - - **Details:** - - **Overview Stats:** - - Total players on roster - - Active recruiting players (if HS/JUCO coach) - - Upcoming events count - - Unread messages count - - **Roster Preview:** - - Top 5 players with avatars - - "View Full Roster" button → `/dashboard/roster` - - **Upcoming Events:** - - Next 3 events from calendar - - Click to view event details - - "View Calendar" button - - **Recent Activity:** - - Player joined team - - Player activated recruiting - - Dev plan assigned - - Video uploaded - - **Quick Actions:** - - Invite Players - - Create Event - - Send Message - - View Videos - - **Team Switcher (if multiple teams):** - - Dropdown to switch between teams - - Placeholder for future multi-team support - - **Components:** - - `TeamDashboard` - Main container - - `TeamStats` - Stats grid - - `RosterPreview` - Top players - - `UpcomingEvents` - Event list - - `TeamActivity` - Activity feed - - **Database Queries:** - - `getTeamStats(teamId)` - Overview stats - - `getTeamRosterPreview(teamId, limit: 5)` - Top players - - `getTeamEvents(teamId, limit: 3)` - Upcoming events - - `getTeamActivity(teamId, limit: 5)` - Recent activity - - **Hooks:** `use-team-dashboard.ts` - - **Testing:** All sections render, quick actions work - - **Note:** This is a generic team dashboard. HS-specific dashboard is planned (HS-001) - ---- - -### Settings & Configuration (2/2) ✅ - -- [x] **SET-001: User Settings** - - **Location:** `/dashboard/settings/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - **Account Settings:** - - Email (read-only, change via Supabase Auth) - - Password change: Current password + New password + Confirm - - Delete account button (with confirmation + password re-entry) - - **Profile Settings:** - - Link to profile editing page - - Quick access to avatar, name, contact info - - **Privacy Settings:** - - Separate page: `/dashboard/settings/privacy/page.tsx` - - Profile visibility: Public, Recruiting Only, Private - - Show contact info: Yes/No - - Show videos: Public, Watchlist Only, Private - - Allow messages from: Anyone, Watchlist Only, No One - - Show recruiting status: Yes/No - - **Notification Preferences:** - - Email notifications: All, Important Only, None - - In-app notifications: Yes/No - - SMS notifications: Yes/No (requires phone verification) - - Notification types toggles: - - Profile views - - Watchlist adds - - New messages - - Calendar events - - Dev plan updates - - **Connected Accounts:** - - Link Twitter/X account - - Link Instagram account - - Link Hudl account - - **Data Export:** - - Download your data (JSON format) - - Includes: Profile, videos, messages, analytics - - **Components:** - - `SettingsLayout` - Settings page wrapper with tabs - - `AccountSettings` - Account section - - `PrivacySettingsForm` - Privacy toggles - - `NotificationSettings` - Notification preferences - - `ConnectedAccounts` - OAuth integrations - - **Database:** - - `player_settings` table (if player): privacy preferences - - `users` table: notification preferences - - **Server Actions:** - - `updatePassword(currentPassword, newPassword)` - Change password - - `updatePrivacySettings(settings)` - Update privacy - - `updateNotificationPreferences(prefs)` - Update notifications - - `deleteAccount(password)` - Delete account (soft delete) - - **Hooks:** `use-settings.ts` - - **Testing:** Password change works, privacy settings save, delete account functional - -- [x] **SET-002: Program Profile Management** - - **Location:** `/dashboard/program/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - **Program Info:** - - School/Organization name - - Website URL - - Division (D1, D2, D3, NAIA, JUCO) - - Conference - - Location (city, state) - - About program (textarea, 1000 char max) - - **Branding:** - - Logo upload (square, 512x512px recommended) - - Primary color picker - - Secondary color picker - - Preview: Shows how colors appear in UI - - **Coach Staff:** - - List of coaches on staff - - Add coach: Email invite - - Remove coach (with confirmation) - - Roles: Head Coach, Assistant Coach, Recruiting Coordinator, etc. - - **Program Stats (read-only):** - - Founded year - - Total players recruited (historical) - - National championships - - Conference championships - - **Social Media:** - - Twitter handle - - Instagram handle - - Facebook page - - YouTube channel - - **Save Behavior:** - - Updates `organizations` table - - Revalidates program profile page - - Success toast - - **Components:** - - `ProgramProfileForm` - Main form - - `LogoUpload` - Logo image upload - - `ColorPicker` - Color selection input - - `CoachStaffList` - List of coaches - - `AddCoachModal` - Invite coach - - **Database:** - - `organizations` table - - Columns: id, name, website, division, conference, city, state, about, logo_url, primary_color, secondary_color, twitter, instagram, facebook, youtube - - **Database Queries:** - - `getOrganization(organizationId)` - Get organization - - `updateOrganization(organizationId, data)` - Update org - - **Server Actions:** - - `updateProgramProfile(organizationId, data)` - Save changes - - `inviteCoach(organizationId, email, role)` - Add coach - - **Storage:** `logos/organizations/{orgId}/{filename}` - - **Testing:** All fields save, logo upload works, color picker functional - ---- - -### Infrastructure & Shared Systems (5/5) ✅ - -- [x] **SYS-001: Navigation System** - - **Location:** `src/components/layout/Sidebar.tsx`, `src/components/layout/Header.tsx` - - **Implementation:** 100% complete - - **Details:** - - **Sidebar:** - - Dynamic navigation based on user role - - College Coach: Discover, Watchlist, Pipeline, Compare, Camps, Messages, Calendar, Program, Settings - - HS Coach: Dashboard, Roster, Videos, Dev Plans, College Interest, Calendar, Messages, Settings - - JUCO Coach: Mode toggle (recruiting vs team mode) with different nav items - - Showcase Coach: Teams, Events, Roster, Videos, Calendar, Messages, Settings - - Player: Dashboard, Profile, Discover, Journey, Camps, Messages, Analytics, Settings - - Active state highlighting (green background) - - Icons for each nav item - - Collapsible on mobile (hamburger menu) - - Section labels: "RECRUITING", "TEAM", "PROGRAM", etc. - - **Header:** - - Logo (left) - - Page title (center) - - User dropdown (right): Profile, Settings, Logout - - Notification bell (if notifications enabled) - - Mobile: Hamburger menu button - - **Mobile Menu:** - - Full-screen overlay on mobile - - Same nav items as desktop - - Close button (X) - - Tap outside to close - - **User Dropdown:** - - Avatar + name - - Role badge (Coach/Player) - - Dropdown menu: - - View Profile - - Settings - - Divider - - Logout - - **Mode Toggle (JUCO coaches only):** - - Toggle switch: Recruiting ↔ Team - - Changes entire sidebar navigation - - Placeholder implemented, full feature in JUCO-001 - - **Components:** - - `Sidebar` - Main sidebar with dynamic nav - - `Header` - Top header bar - - `MobileMenu` - Mobile menu overlay - - `UserDropdown` - User menu - - `ModeToggle` - JUCO mode toggle (placeholder) - - **Hooks:** `use-navigation.ts` - useNavigation, useActiveRoute - - **Testing:** All role-based nav items display correctly, mobile menu works, dropdown functional - -- [x] **SYS-002: Authentication Store** - - **Location:** `src/stores/auth-store.ts`, `src/hooks/use-auth.ts` - - **Implementation:** 100% complete - - **Details:** - - **Zustand Store:** - - State: - - `user` - Supabase Auth user object - - `coach` - Coach record (if user is coach) - - `player` - Player record (if user is player) - - `loading` - Boolean loading state - - `initialized` - Boolean initialization state - - Actions: - - `setUser(user)` - Set auth user - - `setCoach(coach)` - Set coach data - - `setPlayer(player)` - Set player data - - `setLoading(loading)` - Set loading state - - `reset()` - Clear all state (on logout) - - **useAuth Hook:** - - Returns: `{ user, coach, player, loading, isCoach, isPlayer }` - - Computed values: - - `isCoach` - Boolean if user has coach record - - `isPlayer` - Boolean if user has player record - - `role` - "coach" | "player" | null - - `coachType` - "college" | "high-school" | "juco" | "showcase" (if coach) - - `playerType` - "high-school" | "showcase" | "juco" | "college" (if player) - - **Initialization:** - - On app load, fetch Supabase session - - If session exists, fetch coach or player record - - Populate store with data - - Set `initialized = true` - - **Realtime Updates:** - - Subscribe to auth state changes - - Re-fetch coach/player data on profile updates - - **Files:** - - `stores/auth-store.ts` - Zustand store definition - - `hooks/use-auth.ts` - React hook wrapper - - **Testing:** Store updates correctly, hook returns accurate data, logout clears state - -- [x] **SYS-003: Route Protection System** - - **Location:** `src/hooks/use-route-protection.ts`, `src/middleware.ts` - - **Implementation:** 100% complete - - **Details:** - - **Middleware:** - - Runs on every request - - Checks Supabase session - - Public routes: `/`, `/login`, `/signup`, `/join/*` - - Protected routes: `/dashboard/*` - - If not authenticated → redirect to `/login` - - If authenticated but incomplete onboarding → redirect to onboarding - - **useRouteProtection Hook:** - - Client-side route protection - - Checks user role and permissions - - Recruiting routes (Discover, Watchlist, Pipeline, Compare): - - Allowed: College coaches, JUCO coaches (when in recruiting mode) - - Blocked: HS coaches, Showcase coaches, Players (unless recruiting activated) - - Team routes (Roster, Videos, Dev Plans): - - Allowed: HS coaches, JUCO coaches (when in team mode), Showcase coaches - - Blocked: College coaches (no team) - - Player routes (Journey, Analytics): - - Allowed: Players with recruiting activated - - Blocked: College players, non-activated players - - **Role-based Redirects:** - - College coach visiting team page → redirect to `/dashboard` - - HS coach visiting recruiting page → redirect to `/dashboard/team` - - Player without recruiting visiting journey → redirect to `/dashboard/activate` - - **Permission Checks:** - - `canAccessRecruiting(user)` - Boolean - - `canAccessTeam(user)` - Boolean - - `canActivateRecruiting(user)` - Boolean (false for college players) - - **Files:** - - `middleware.ts` - Edge middleware for auth - - `hooks/use-route-protection.ts` - Client-side protection hook - - `lib/permissions.ts` - Permission check functions - - **Testing:** All role redirects work, unauthorized access blocked, edge cases handled - -- [x] **SYS-004: Database Query Layer** - - **Location:** `src/lib/queries/*.ts` - - **Implementation:** 100% complete - - **Details:** - - **Centralized Queries:** - - All Supabase queries organized into files by domain - - Type-safe with TypeScript - - Consistent error handling - - Reusable across components - - **Query Files:** - - `players.ts` - Player queries (getPlayer, getPlayers, getDiscoverPlayers, etc.) - - `coaches.ts` - Coach queries (getCoach, getCoaches, etc.) - - `teams.ts` - Team queries (getTeam, getTeamRoster, etc.) - - `watchlist.ts` - Watchlist queries (getWatchlist, addToWatchlist, etc.) - - `messages.ts` - Messaging queries (getConversations, getMessages, etc.) - - `videos.ts` - Video queries (getVideos, getPlayerVideos, etc.) - - `camps.ts` - Camp queries (getCamps, getCampRegistrations, etc.) - - `calendar.ts` - Calendar queries (getEvents, etc.) - - `analytics.ts` - Analytics queries (getEngagement, etc.) - - **Query Patterns:** - - Select with joins: `.select('*, player_videos(*), player_metrics(*)')` - - Filtering: `.eq('id', id).gte('created_at', date)` - - Ordering: `.order('created_at', { ascending: false })` - - Pagination: `.range(start, end)` - - Error handling: Try-catch with typed errors - - **Type Safety:** - - Import types from `@/lib/types` - - Return types explicitly defined - - Database types generated from Supabase - - **Files:** - - `lib/queries/players.ts` - 15+ player queries - - `lib/queries/coaches.ts` - 10+ coach queries - - `lib/queries/teams.ts` - 8+ team queries - - `lib/queries/watchlist.ts` - 6+ watchlist queries - - `lib/queries/messages.ts` - 8+ message queries - - And more... - - **Testing:** All queries return correct data, joins work, filters accurate - -- [x] **SYS-005: UI Component Library** - - **Location:** `src/components/ui/*.tsx` - - **Implementation:** 100% complete - - **Details:** - - **40+ Reusable Components:** - - **Form Components:** - - `Button` - Primary, Secondary, Ghost, Icon variants - - `Input` - Text, Email, Password, Number with validation states - - `Select` - Dropdown with search, multi-select - - `Textarea` - Auto-resize, character count - - `Checkbox` - Standard and indeterminate states - - `Radio` - Radio group with labels - - `Switch` - Toggle switch (on/off) - - `Label` - Form labels with required indicator - - **Display Components:** - - `Card` - Container with variants (default, outlined, glass) - - `Badge` - Status badges with color variants - - `Avatar` - User avatars with fallback initials - - `AvatarGroup` - Stacked avatars - - `Progress` - Progress bar, circular progress - - `Skeleton` - Loading placeholders - - `Separator` - Divider lines - - `Tabs` - Tab navigation with panels - - `Accordion` - Collapsible sections - - **Overlay Components:** - - `Modal` - Centered modal with backdrop - - `Dialog` - Confirmation dialogs - - `Sheet` - Side panel (drawer) - - `Popover` - Floating popup - - `Tooltip` - Hover tooltips - - `Dropdown` - Dropdown menu - - **Feedback Components:** - - `Toast` - Success, error, warning, info toasts - - `Alert` - Inline alerts - - `Spinner` - Loading spinner - - `EmptyState` - No data placeholders - - **Navigation Components:** - - `Breadcrumb` - Breadcrumb trail - - `Pagination` - Page navigation - - `CommandPalette` - Keyboard shortcut menu (placeholder) - - **Layout Components:** - - `Container` - Max-width container - - `Grid` - Responsive grid - - `Stack` - Vertical/horizontal stack - - **Design System:** - - **Colors:** - - Primary: Kelly Green (#16A34A, `green-600`) - - Background: Cream White (#FAF6F1) - - Cards: White (#FFFFFF) - - Text: Slate 900, 600, 400 (#0F172A, #475569, #94A3B8) - - Borders: Slate 200 (#E2E8F0) - - **Effects:** - - Glass morphism: `backdrop-blur-xl`, `bg-white/80` - - Shadows: `shadow-sm`, `shadow-md`, `shadow-lg` - - Rounded corners: `rounded-lg` (8px), `rounded-2xl` (16px) - - Transitions: `transition-colors`, `transition-all` - - **Typography:** - - Font: Inter (system-ui fallback) - - Headings: `font-semibold`, `font-medium` - - Body: `font-normal` - - Sizes: `text-sm` (14px), `text-base` (16px), `text-lg` (18px), `text-xl` (20px), `text-2xl` (24px) - - **Accessibility:** - - ARIA labels on all interactive elements - - Keyboard navigation support - - Focus states visible - - Color contrast WCAG AA compliant - - **Files:** - - 40+ component files in `components/ui/` - - `lib/utils.ts` - Component utility functions (cn, clsx) - - `tailwind.config.ts` - Design tokens - - **Testing:** All components render, variants work, accessibility verified - ---- - -### Golf Platform - Core Features (3/3) ✅ - -- [x] **GOLF-001: Golf Dashboard** - - **Location:** `/golf/dashboard/page.tsx` - - **Implementation:** 100% complete - - **Details:** - - Golf coach dashboard with team overview - - Team stats: Total players, rounds played, average score - - Recent rounds list - - Top performers (lowest average score) - - Upcoming tournaments - - Quick actions: Create round, View team stats, Manage roster - - **Components:** `GolfDashboard`, `TeamStats`, `RecentRounds` - - **Database:** Golf-specific tables (separate from baseball) - - **Testing:** Dashboard renders, stats accurate - -- [x] **GOLF-002: Golf Player Features** - - **Location:** `/player-golf/page.tsx`, `/player-golf/rounds/` - - **Implementation:** 100% complete - - **Details:** - - Player golf dashboard with personal stats - - Round tracking: Create new round, view round history - - Round detail: View hole-by-hole scores - - Personal best tracking - - Handicap calculation (basic) - - **Components:** `GolfPlayerDashboard`, `RoundList`, `RoundCard` - - **Database:** Player golf stats tables - - **Testing:** Rounds save correctly, stats calculate - -- [x] **GOLF-003: Shot Tracking System** - - **Location:** `/player-golf/rounds/[id]/play/page.tsx`, `ShotTrackingFinal_WITH_SCORECARD.tsx` - - **Implementation:** 100% complete - - **Details:** - - Real-time shot tracking during rounds - - Hole-by-hole scoring - - Shot distance calculation - - Club selection per shot - - Shot type tracking (drive, approach, chip, putt) - - Premium dark scorecard UI - - Scorecard integration with: - - Front 9 / Back 9 tabs - - Score entry per hole - - Par tracking - - Total score calculation - - Save round - - **Components:** - - `ShotTracking` - Main shot tracking interface - - `ShotTrackingFinal_WITH_SCORECARD.tsx` - Final implementation with scorecard - - `Scorecard` - Dark theme scorecard UI - - **Database:** Shots table, rounds table - - **Testing:** Shot tracking works, distance accurate, scorecard saves - ---- - -## IN-PROGRESS FEATURES ⚠️ -**Status:** 17/100+ features in various stages of completion - -### High School Coach Features (0/3) - Priority: P0 - -- [ ] **HS-001: HS Coach Team Dashboard (INCOMPLETE)** - - **Location:** N/A - Currently redirects to generic `/dashboard/team` - - **Current Status:** 40% complete - - **What Exists:** - - Generic team dashboard shows basic stats - - Redirect logic implemented - - **What's Missing:** - - HS-specific metrics (academic tracking, recruiting interest from colleges) - - Player development tracking integration - - Academic progress overview (GPA trends, transcripts) - - Parent communication portal preparation - - College recruiting interest notifications ("Coach Smith from Texas A&M viewed 3 of your players") - - **Database:** All tables exist (teams, team_members, players) - - **Implementation Needed:** - - Create `/dashboard/team/high-school/page.tsx` - - Build HS-specific stat queries - - Add academic tracking widgets - - Build college interest feed - - **Priority:** P0 - CRITICAL - -- [ ] **HS-002: College Interest Tracking (PARTIAL)** - - **Location:** `/dashboard/college-interest/page.tsx` - - **Current Status:** 50% complete - - **What Exists:** - - Page exists with basic layout - - Shows list of players on roster - - Basic engagement event fetching - - **What's Missing:** - - Full engagement event tracking (profile views, watchlist adds by college coaches) - - Detailed analytics per player (which colleges, how many views, when) - - Notifications when coaches view players - - Filter by player - - Export interest data - - **Database:** - - `player_engagement_events` table exists - - Need to populate events when college coaches view HS players - - **Implementation Needed:** - - Complete engagement tracking logic - - Build analytics dashboard per player - - Add notification system - - **Priority:** P1 - -- [ ] **HS-003: Developmental Plans System (PARTIAL)** - - **Location:** `/dashboard/dev-plans/page.tsx` (coach), `/dashboard/dev-plan/page.tsx` (player) - - **Current Status:** 40% complete - - **What Exists:** - - Coach can create dev plans - - Player can view assigned dev plan - - Basic plan structure (title, description, goals) - - **What's Missing:** - - **Drill Library:** - - Searchable drill database - - Video demonstrations for each drill - - Drill categories (hitting, pitching, fielding) - - Custom drill creation - - **Progress Tracking:** - - Player marks drills as complete - - Coach sees progress dashboard - - Timeline view of completion - - **Player Goal Setting:** - - Player sets personal goals - - Milestones and achievements - - Goal progress tracking - - **Coach Feedback:** - - Coach comments on progress - - Video review and annotations - - **Database:** - - `developmental_plans` table exists - - Need: `drill_library`, `plan_drills`, `drill_completions` tables - - **Implementation Needed:** - - Build drill library database and UI - - Create progress tracking system - - Add goal setting interface - - Implement feedback system - - **Priority:** P2 - ---- - -### JUCO Coach Features (0/3) - Priority: P0 - -- [ ] **JUCO-001: JUCO Mode Toggle (NOT INTEGRATED)** - - **Location:** Component exists but not wired up - - **Current Status:** 20% complete - - **What Exists:** - - `ModeToggle` component exists in `src/components/layout/ModeToggle.tsx` - - Basic UI for toggle switch (Recruiting ↔ Team) - - Component is visually complete - - **What's Missing:** - - **Integration into layout:** - - ModeToggle not rendered in sidebar for JUCO coaches - - No state management for mode selection - - **Routing Logic:** - - No route changes based on mode - - Dashboard should change based on mode - - **Separate Dashboards:** - - Recruiting mode: Show Discover, Watchlist, Pipeline (like College coach) - - Team mode: Show Roster, Videos, Dev Plans (like HS coach) - - **Mode State Persistence:** - - Store mode preference in database or local storage - - Remember last used mode - - **Sidebar Navigation:** - - Dynamically change nav items based on mode - - Show recruiting nav in recruiting mode, team nav in team mode - - **Database:** - - Add `mode_preference` column to `coaches` table OR - - Store in `coach_settings` table - - **Implementation Needed:** - - Add ModeToggle to Sidebar when coach type is JUCO - - Create mode state in Zustand store or React context - - Build routing logic: `/dashboard` changes based on mode - - Create JUCO recruiting dashboard (reuse College coach components) - - Create JUCO team dashboard (reuse HS coach components) - - Persist mode selection - - **Priority:** P0 - CRITICAL (JUCO coaches cannot access recruiting features without this) - -- [ ] **JUCO-002: Academics Tracking (STUB)** - - **Location:** `/dashboard/academics/page.tsx` - - **Current Status:** 10% complete - - **What Exists:** - - Stub page with placeholder text - - Basic page layout - - **What's Missing:** - - **Academic Records Database Schema:** - - Create `academic_records` table - - Columns: player_id, semester, year, gpa, credits, courses, transcript_url - - **GPA Tracking Over Time:** - - Semester-by-semester GPA entry - - Cumulative GPA calculation - - GPA trend chart - - **Transcripts Upload:** - - PDF upload to Supabase Storage - - View uploaded transcripts - - Share transcripts with 4-year colleges - - **Academic Eligibility Tracking:** - - NCAA eligibility requirements - - NAIA eligibility requirements - - Alert if player falls below eligibility - - **Course Planning:** - - Required courses for transfer - - Course completion tracking - - **Database:** - - Create `academic_records` table - - Create `transcript_files` table - - **Implementation Needed:** - - Design and create database schema - - Build GPA entry form - - Build transcript upload system - - Create academic dashboard - - Add eligibility checker - - **Priority:** P2 - -- [ ] **JUCO-003: Transfer Tracking (NOT STARTED)** - - **Location:** Not created yet - - **Current Status:** 0% complete - - **What's Missing:** - - **Transfer Portal Integration:** - - Track players entering transfer portal - - Mark player status: Transferring, Committed, Graduated - - **4-Year College Tracking:** - - Which 4-year colleges player is interested in - - Contact with 4-year coaches - - Official visit tracking - - **Transfer Timeline:** - - Key dates: Portal entry, signing day, enrollment - - Timeline view of transfer process - - **Document Management:** - - Transfer release forms - - Transcripts - - Compliance documents - - **Database:** - - Create `transfer_tracking` table - - Add `transfer_status` column to players - - **Implementation Needed:** - - Design transfer tracking database - - Build transfer portal interface - - Create timeline view - - Add document upload system - - **Priority:** P3 - ---- - -### Showcase Coach Features (0/2) - Priority: P1 - -- [ ] **SHOW-001: Multi-Team Management (INCOMPLETE)** - - **Location:** `/dashboard/teams/page.tsx` - - **Current Status:** 35% complete - - **What Exists:** - - Teams listing page with grid of teams - - Create team modal - - Edit team basic info - - Delete team - - **What's Missing:** - - **Team Switcher Dropdown:** - - Dropdown in header/sidebar to switch active team - - Shows all teams user manages - - Updates entire dashboard context to selected team - - **Per-Team Roster Pages:** - - Route: `/coach/showcase/team/[id]/roster` - - Isolated roster per team - - Jersey numbers per team (player can have different # on different teams) - - **Per-Team Videos:** - - Route: `/coach/showcase/team/[id]/videos` - - Videos organized by team - - Tag videos to specific team - - **Per-Team Calendar:** - - Route: `/coach/showcase/team/[id]/calendar` - - Team-specific events - - Multi-team calendar view (see all teams' events) - - **Organization-Level Dashboard:** - - Overview of all teams - - Aggregate stats across teams - - Top performers across organization - - **Database:** - - Teams table exists - - Need: team context in sessions/state - - **Implementation Needed:** - - Create team switcher component - - Build team context provider - - Create per-team routes - - Build organization dashboard - - Add team filtering to all queries - - **Priority:** P1 - -- [ ] **SHOW-002: Showcase Events Management (PARTIAL)** - - **Location:** `/dashboard/events/page.tsx` - - **Current Status:** 30% complete - - **What Exists:** - - Events page with basic event list - - Create event modal - - Event types: Tournament, Showcase, Combine - - **What's Missing:** - - **Event Registration:** - - Player registration for events - - Team registration for tournaments - - Registration limits and waitlists - - **Event Analytics:** - - Attendance tracking - - Performance stats from event - - Scout attendance (which colleges attended) - - **Multi-Team Event Coordination:** - - Assign teams to events - - Brackets and scheduling - - Live scoring/updates - - **Database:** - - Create `showcase_events` table - - Create `event_registrations` table - - Create `event_participants` table - - **Implementation Needed:** - - Build registration system - - Create event analytics dashboard - - Add multi-team coordination - - Build bracket/scheduling system - - **Priority:** P2 - ---- - -### Player Features (0/3) - Priority: P0-P1 - -- [ ] **PLAYER-005: Multi-Team Support (NOT IMPLEMENTED)** - - **Location:** N/A - Not built - - **Current Status:** 0% complete - - **What Exists:** - - Players can join 1 team via invite link - - `team_members` table supports multiple memberships (no constraint preventing it) - - **What's Missing:** - - **Allow 2 Team Memberships:** - - HS player can join: 1 HS team + 1 Showcase team - - Showcase player can join: 1 Showcase team + 1 HS team - - JUCO player: 1 JUCO team only - - College player: 1 College team only - - **Team Switcher Dropdown:** - - Dropdown in player dashboard/sidebar - - Switch between teams - - Shows team name, type, logo - - **Isolated Team Contexts:** - - Team dashboard shows only selected team's data - - Schedule shows selected team's events - - Videos filtered by selected team - - Dev plan from selected team's coach - - Messages to selected team's coaches - - **Team Type Validation:** - - Prevent HS player from joining 2 HS teams - - Prevent HS player from joining JUCO or College team - - Validate team types on join - - **Database:** - - Add `team_type` column to `teams` table (high-school, showcase, juco, college) - - Add validation logic in server actions - - **Implementation Needed:** - - Create team switcher component - - Build team context provider - - Add team type validation - - Update join flow to check team limits - - Filter all team queries by selected team - - **Priority:** P0 - CRITICAL (documented feature not implemented) - -- [ ] **PLAYER-006: College Discovery (INCOMPLETE)** - - **Location:** `/dashboard/colleges/page.tsx` - - **Current Status:** 40% complete - - **What Exists:** - - Page exists with basic college grid - - College cards show name, division, location - - Click college to view program profile - - **What's Missing:** - - **Advanced Filters:** - - Filter by division (D1, D2, D3, NAIA, JUCO) - - Filter by conference - - Filter by location (state, region) - - Filter by program characteristics (size, public/private, cost) - - **Save to Dream Schools:** - - Add college to "dream schools" list - - Manage dream schools list - - Share dream schools with coaches - - **School Comparison:** - - Compare 2-4 colleges side-by-side - - Compare: Division, location, size, tuition, baseball program stats - - **College Match Scoring:** - - Algorithm to match player to colleges - - Based on: Academics (GPA, SAT), Athletics (position, stats), Preferences - - **Database:** - - `dream_schools` table exists (or use `recruiting_interests`) - - `organizations` table has all colleges - - **Implementation Needed:** - - Build filter panel with all filter options - - Create dream schools management system - - Build college comparison tool - - Develop match scoring algorithm - - **Priority:** P2 - -- [ ] **PLAYER-007: Recruiting Activation Flow (BASIC)** - - **Location:** `/dashboard/activate/page.tsx` - - **Current Status:** 60% complete - - **What Exists:** - - Activation page exists - - Button to activate recruiting - - Sets `recruiting_activated = true` and `recruiting_activated_at = NOW()` - - Redirects to recruiting dashboard - - **What's Missing:** - - **Privacy Settings Review Modal:** - - Before activating, show modal explaining privacy - - Review current privacy settings - - Adjust settings before activating - - Confirm changes - - **Terms Acceptance:** - - Show recruiting terms and conditions - - Checkbox to accept terms - - Require acceptance before activation - - **Benefits Explanation:** - - Better explanation of benefits - - Video or graphics showing features unlocked - - Testimonials from other players - - **Anonymous vs Identified Interest UI:** - - Currently no differentiation in UI - - Need to show: "A D1 coach viewed your profile" when not activated - - vs "Coach John Smith from Texas A&M viewed your profile" when activated - - Implement in analytics, activity feed, notifications - - **Database:** - - Add `recruiting_terms_accepted_at` to players table - - Privacy settings already exist in `player_settings` - - **Implementation Needed:** - - Build privacy review modal - - Add terms and conditions modal - - Enhance benefits explanation - - Implement anonymous vs identified interest logic throughout app - - **Priority:** P1 - ---- - -### Video Features (0/1) - Priority: P1 - -- [ ] **VIDEO-002: Video Clipping Tool (DATABASE READY, NO UI)** - - **Location:** N/A - Not built - - **Current Status:** 20% complete - - **What Exists:** - - Database schema ready: - - `videos` table has `is_clip` boolean column - - `videos` table has `parent_video_id` foreign key column - - Backend can save clips (just needs clip metadata) - - **What's Missing:** - - **Clip Editor UI Component:** - - Video player with clip controls - - Click "Create Clip" button on video - - Modal with video player + timeline - - **Timeline Scrubber:** - - Draggable timeline showing video duration - - Set start time marker (drag or input time) - - Set end time marker (drag or input time) - - Preview clip (play only selected portion) - - Waveform visualization (optional) - - **Clip Metadata:** - - Clip title (auto-generate from parent + timestamps) - - Clip description - - Clip tags (At-Bat, Pitch, Fielding, etc.) - - **Save Clips:** - - Save clip as separate video record in database - - `is_clip = true`, `parent_video_id = parent.id` - - Clip URL: Same as parent video + start/end params OR generate separate clip file - - Display clips in video library with "CLIP" badge - - **Clip Management:** - - View all clips from a parent video - - Delete clips (doesn't delete parent) - - Share individual clips - - **Database:** Already ready (`videos` table) - - **Implementation Needed:** - - Build clip editor modal component - - Create timeline scrubber with React (use library like react-player + custom timeline) - - Add clip creation server action - - Update video library to show clips - - Add "CLIP" badge to clip videos - - **Priority:** P1 - - **Library Suggestions:** `react-player`, `wavesurfer.js`, or custom HTML5 video controls - ---- - -### Comparison Features (0/1) - Priority: P1 - -- [ ] **RECRUIT-006: Advanced Player Comparison (PARTIAL)** - - **Location:** `/dashboard/compare/page.tsx` - - **Current Status:** 60% complete - - **What Exists:** - - Basic comparison page works (side-by-side 2-4 players) - - Comparison table with metrics - - URL-based state (`?players=id1,id2`) - - **What's Missing:** - - **Radar Chart Overlay:** - - Visual radar chart comparing players on multiple dimensions - - Dimensions: Pitch Velo, Exit Velo, 60-Yard, GPA, etc. - - Recharts RadarChart component - - Overlay multiple players on same chart - - **Save Comparison Feature:** - - Save comparison with title - - Store in `player_comparisons` table (table exists in schema) - - Access saved comparisons from dashboard - - Share saved comparison link - - **Comparison History:** - - List of all saved comparisons - - Filter by date created - - Delete old comparisons - - **Export to PDF:** - - Export comparison table + radar chart to PDF - - Include player photos and key stats - - Downloadable PDF file - - **Database:** - - `player_comparisons` table exists in schema but not used - - Columns: id, coach_id, player_ids (array), title, created_at - - **Implementation Needed:** - - Add Recharts RadarChart to comparison page - - Build save comparison feature (form + server action) - - Create saved comparisons list page - - Implement PDF export (use library like `jsPDF` or `react-pdf`) - - **Priority:** P1 - ---- - -### Public Profiles (0/2) - Priority: P2 - -- [ ] **PUB-001: Public Player Profiles (BASIC)** - - **Location:** `/baseball/(public)/player/[id]/page.tsx` - - **Current Status:** 50% complete - - **What Exists:** - - Public player profile page exists - - Shows basic player info (name, position, grad year, school) - - Shows stats - - Basic layout - - **What's Missing:** - - **Privacy Settings Enforcement:** - - If recruiting NOT activated → Show limited profile (name, position, grad year only) - - If recruiting activated AND profile privacy = "Public" → Show full profile - - If recruiting activated AND profile privacy = "Recruiting Only" → Show full profile only to logged-in coaches - - If profile privacy = "Private" → Show nothing (404 or "Profile not available") - - **Video Embeds:** - - Embed primary highlight video - - Show all public videos in grid - - Video player modal - - **Achievement/Honors Display:** - - Show awards, honors, accolades - - All-Star selections, championships, etc. - - **Recruiting Status Visibility:** - - "Actively Recruiting" badge if recruiting activated - - "Committed to [School]" badge if committed - - **Database:** - - Privacy settings in `player_settings` table - - Achievements in `player_achievements` table - - **Implementation Needed:** - - Add privacy check logic - - Embed videos on profile - - Display achievements - - Add recruiting status badges - - **Priority:** P2 - -- [ ] **PUB-002: Public Program Profiles (BASIC)** - - **Location:** `/baseball/(public)/program/[id]/page.tsx` - - **Current Status:** 40% complete - - **What Exists:** - - Public program profile page exists - - Shows program name, division, location - - Basic layout - - **What's Missing:** - - **Full Content Display:** - - About program (full description) - - Coach staff list with bios - - Program history and achievements - - Facilities and resources - - Contact information - - **SEO Optimization:** - - Meta tags for social sharing - - Structured data (JSON-LD) - - Open Graph tags - - Optimized images - - **Roster Preview:** - - Show current roster (public players only) - - Filter by position, grad year - - Link to player profiles - - **Database:** - - Organizations table has all data - - Need to query roster with privacy filters - - **Implementation Needed:** - - Build full program profile page - - Add SEO meta tags - - Create roster preview component - - Add contact form (optional) - - **Priority:** P2 - ---- - -### Golf Platform Enhancements (0/2) - Priority: P2 - -- [ ] **GOLF-004: Golf Round Management (PARTIAL)** - - **Location:** `/player-golf/rounds/` - - **Current Status:** 40% complete - - **What Exists:** - - Create new round - - View round list - - Basic round detail page - - **What's Missing:** - - **Round History:** - - Detailed round history with filters (date range, course, score) - - Sort by date, score, course - - Search rounds - - **Statistics Aggregation:** - - Total rounds played - - Average score - - Best score, worst score - - Scoring trends over time - - Par 3/4/5 averages - - **Performance Analytics:** - - Fairways hit percentage - - Greens in regulation - - Putts per round - - Up and down percentage - - Charts and graphs - - **Database:** - - Rounds table exists - - Need: aggregation queries - - **Implementation Needed:** - - Build round history page with filters - - Create statistics dashboard - - Add analytics charts - - **Priority:** P2 - -- [ ] **GOLF-005: Golf Team Management (PARTIAL)** - - **Location:** `/golf/dashboard/` - - **Current Status:** 35% complete - - **What Exists:** - - Golf team dashboard shows basic stats - - Can view team roster - - **What's Missing:** - - **Multi-Player Tracking:** - - Track multiple players on team - - Individual player stats - - Team leaderboard - - **Team Statistics:** - - Team average score - - Team best round - - Player comparisons - - **Tournament Management:** - - Create tournaments - - Team brackets - - Live scoring - - Tournament results - - **Database:** - - Golf teams table exists - - Need: tournament tables - - **Implementation Needed:** - - Build team leaderboard - - Create tournament system - - Add live scoring - - **Priority:** P2 - ---- - -## PLANNED FEATURES 🚀 -**Status:** 35 new features planned across 5 priority levels - -### Critical Priority (P0) - Fix Core Gaps (5 features) - -- [ ] **CORE-001: Implement JUCO Mode Toggle** - - **Description:** Wire up ModeToggle component for JUCO coaches to switch between recruiting and team modes - - **Why Critical:** JUCO coaches cannot access recruiting features without this - - **Implementation:** - - Add ModeToggle to Sidebar when coach type is JUCO - - Create mode state in Zustand store - - Build routing logic to change dashboard based on mode - - Separate recruiting and team dashboards for JUCO - - Persist mode selection in database - - **Estimated Effort:** 3-5 days - - **Blockers:** None - - **Success Criteria:** - - JUCO coach sees mode toggle in sidebar - - Clicking toggle changes navigation items - - Recruiting mode shows Discover, Watchlist, Pipeline - - Team mode shows Roster, Videos, Dev Plans - - Mode preference persists across sessions - - **Priority:** P0 - CRITICAL - -- [ ] **CORE-002: Implement Multi-Team Support for Players** - - **Description:** Allow players to join 2 teams (HS + Showcase, etc.) with team switcher - - **Why Critical:** Documented feature, players expect this functionality - - **Implementation:** - - Add `team_type` column to `teams` table - - Create team switcher dropdown component - - Build team context provider to track active team - - Add validation: HS player can join 1 HS + 1 Showcase team only - - Filter all team queries by selected team - - Update join flow to check team limits - - **Estimated Effort:** 5-7 days - - **Blockers:** Database migration needed - - **Success Criteria:** - - HS player can join HS team and Showcase team - - Team switcher appears when player has 2 teams - - Switching teams updates all team-related data - - Join flow prevents joining invalid team types - - **Priority:** P0 - CRITICAL - -- [ ] **CORE-003: Complete HS Coach Dashboard** - - **Description:** Build HS-specific team dashboard with academic tracking and college interest features - - **Why Critical:** HS coaches currently see generic dashboard, missing key features - - **Implementation:** - - Create `/dashboard/team/high-school/page.tsx` - - Build academic tracking widget (GPA trends, transcripts) - - Build college interest feed (which colleges viewing players) - - Add player development overview - - Create parent portal preparation - - **Estimated Effort:** 7-10 days - - **Blockers:** None (all tables exist) - - **Success Criteria:** - - HS coach sees custom dashboard instead of generic team dashboard - - Dashboard shows academic metrics for all players - - Dashboard shows college interest notifications - - Player development section functional - - **Priority:** P0 - CRITICAL - -- [ ] **CORE-004: Separate Golf Platform** - - **Description:** Move golf app to separate directory or repository, establish clear separation - - **Why Critical:** Golf app mixed with baseball app creates confusion, routing conflicts - - **Implementation:** - - Option A: Move to monorepo structure (`/apps/baseball/`, `/apps/golf/`) - - Option B: Separate repositories - - Independent routing (`golf.helm.app` vs `baseball.helm.app`) - - Separate authentication contexts - - Update documentation to reflect dual-app structure - - **Estimated Effort:** 3-5 days - - **Blockers:** Deployment strategy decision needed - - **Success Criteria:** - - Golf app completely isolated from baseball app - - No shared routes or components (except design system) - - Clear documentation of dual-platform architecture - - **Priority:** P0 - CRITICAL - -- [ ] **CORE-005: Remove Dead Code** - - **Description:** Clean up unused components, duplicate implementations, test files - - **Why Critical:** Reduces confusion, improves maintainability, smaller bundle size - - **Implementation:** - - Delete unused peek panel components - - Remove duplicate pipeline components (old vs new) - - Clean up test/dev files - - Remove deprecated imports - - Update imports to reflect deletions - - **Files to Remove:** - - `components/panels/PeekPanelRoot.tsx` - - `components/panels/PlayerPeekPanel.tsx` - - `components/panels/SchoolPeekPanel.tsx` - - `components/coach/pipeline/PipelineBoard.tsx` (old version) - - `components/coach/pipeline/PipelineColumn.tsx` (old version) - - `components/coach/discover/USAMap.tsx` (duplicate) - - `src/app/dev/page.tsx` - - `src/app/test-shot-tracking/page.tsx` - - **Estimated Effort:** 1-2 days - - **Blockers:** None - - **Success Criteria:** - - All unused files deleted - - No broken imports - - Bundle size reduced by at least 10% - - TypeScript compiles with no errors - - **Priority:** P0 - ---- - -### High Priority (P1) - Complete Partially Built Features (5 features) - -- [ ] **FEATURE-001: Complete Video Clipping System** - - **Description:** Build clip editor UI with timeline scrubber to create clips from videos - - **Implementation:** - - Create clip editor modal component - - Build timeline scrubber with React (use react-player) - - Add start/end time selection (drag markers or input times) - - Preview clip before saving - - Save clip metadata to database (`is_clip = true`, `parent_video_id`) - - Display clips in video library with "CLIP" badge - - Add clip tagging (At-Bat, Pitch, Fielding, etc.) - - **Database:** Already ready - - **Libraries:** `react-player`, custom timeline scrubber - - **Estimated Effort:** 7-10 days - - **Success Criteria:** - - Click "Create Clip" on video opens editor - - Timeline scrubber functional with draggable markers - - Preview clip plays only selected portion - - Saved clips appear in video library - - **Priority:** P1 - -- [ ] **FEATURE-002: Implement Notifications System** - - **Description:** Build full notification system with real-time, email, and push notifications - - **Implementation:** - - Integrate notification bell component (NotificationCenter exists) - - Real-time notifications with Supabase Realtime - - Email notifications (Supabase Auth emails or SendGrid) - - Push notifications (PWA + service worker) - - Notification preferences in settings - - Mark as read/unread - - Notification types: Profile views, Watchlist adds, Messages, Calendar events, Dev plans - - **Database:** `notifications` table exists - - **Estimated Effort:** 10-14 days - - **Success Criteria:** - - Notification bell shows unread count - - Clicking bell shows notification dropdown - - Real-time updates when new notification arrives - - Email sent for important notifications - - Notification preferences work - - **Priority:** P1 - -- [ ] **FEATURE-003: Complete Player Comparison Tool** - - **Description:** Add radar chart overlay, save comparisons, export to PDF - - **Implementation:** - - Add Recharts RadarChart to comparison page - - Overlay multiple players on same radar chart - - Build save comparison feature (form + server action) - - Create saved comparisons list page - - Implement PDF export (use jsPDF or react-pdf) - - Include player photos, stats, and charts in PDF - - **Database:** Use `player_comparisons` table - - **Estimated Effort:** 5-7 days - - **Success Criteria:** - - Radar chart displays on comparison page - - Can save comparison with title - - Saved comparisons list accessible - - PDF export downloads successfully - - **Priority:** P1 - -- [ ] **FEATURE-004: Complete Showcase Coach Multi-Team Management** - - **Description:** Organization dashboard, per-team routing, team switcher - - **Implementation:** - - Build organization-level dashboard (overview of all teams) - - Create team switcher component (dropdown in header) - - Build per-team routes: `/coach/showcase/team/[id]/roster`, `/coach/showcase/team/[id]/videos`, etc. - - Add team filtering to all queries - - Multi-team calendar view (aggregate events from all teams) - - Cross-team analytics - - **Database:** Teams table exists - - **Estimated Effort:** 7-10 days - - **Success Criteria:** - - Showcase coach sees team switcher - - Switching teams updates entire dashboard - - Per-team routes functional - - Organization dashboard shows aggregate stats - - **Priority:** P1 - -- [ ] **FEATURE-005: Anonymous vs Identified Interest System** - - **Description:** Implement privacy model for recruiting activation - - **Implementation:** - - Update analytics page to show anonymous vs identified interest - - Anonymous (recruiting not activated): "A D1 coach from Texas viewed your profile" - - Identified (recruiting activated): "Coach John Smith from Texas A&M viewed your profile" - - Update activity feed with same logic - - Update notifications with same logic - - Add privacy settings review modal to activation flow - - Explain benefits of activation clearly - - **Database:** Privacy settings already exist - - **Estimated Effort:** 5-7 days - - **Success Criteria:** - - Non-activated players see anonymous interest - - Activated players see identified interest (coach names) - - Activation flow explains privacy model - - **Priority:** P1 - ---- - -### Medium Priority (P2) - New Features (15 features) - -#### Baseball Platform Features (10 features) - -- [ ] **FEATURE-006: Complete Developmental Plans System** - - **Description:** Drill library, progress tracking, goal setting, coach feedback - - **Estimated Effort:** 14-21 days - - **Priority:** P2 - -- [ ] **FEATURE-007: Academics Tracking System** - - **Description:** Academic records database, GPA tracking, transcripts upload, eligibility tracking - - **Estimated Effort:** 10-14 days - - **Priority:** P2 - -- [ ] **FEATURE-008: College Interest Analytics** - - **Description:** Full engagement analytics, notifications, interest timeline, heatmap - - **Estimated Effort:** 7-10 days - - **Priority:** P2 - -- [ ] **FEATURE-009: Advanced Search System** - - **Description:** Global search with Command Palette, saved searches, search history - - **Estimated Effort:** 7-10 days - - **Priority:** P2 - -- [ ] **FEATURE-010: College Discovery Enhancements** - - **Description:** Advanced filters, school comparison, dream schools list, match scoring - - **Estimated Effort:** 10-14 days - - **Priority:** P2 - -- [ ] **FEATURE-011: Transfer Tracking (JUCO)** - - **Description:** Transfer portal integration, 4-year college tracking, transfer timeline - - **Estimated Effort:** 10-14 days - - **Priority:** P2 - -- [ ] **FEATURE-012: Public Player Profiles Enhancement** - - **Description:** Privacy enforcement, video embeds, achievements display - - **Estimated Effort:** 5-7 days - - **Priority:** P2 - -- [ ] **FEATURE-013: Public Program Profiles Enhancement** - - **Description:** Full content display, SEO optimization, roster preview - - **Estimated Effort:** 5-7 days - - **Priority:** P2 - -- [ ] **FEATURE-014: Showcase Events Management** - - **Description:** Event registration, event analytics, multi-team coordination - - **Estimated Effort:** 10-14 days - - **Priority:** P2 - -- [ ] **FEATURE-015: Parent Portal** - - **Description:** Parent accounts, communication system, academic access, recruiting updates - - **Estimated Effort:** 14-21 days - - **Priority:** P2 - -#### Golf Platform Expansion (5 features) - -- [ ] **GOLF-006: Complete Golf Round Management** - - **Description:** Round history, statistics aggregation, performance analytics, handicap calculation - - **Estimated Effort:** 7-10 days - - **Priority:** P2 - -- [ ] **GOLF-007: Golf Tournament System** - - **Description:** Tournament creation, leaderboards, live scoring, tournament analytics - - **Estimated Effort:** 14-21 days - - **Priority:** P2 - -- [ ] **GOLF-008: Golf Player Development** - - **Description:** Swing analysis, practice tracking, goal setting, performance trends - - **Estimated Effort:** 14-21 days - - **Priority:** P2 - -- [ ] **GOLF-009: Golf Team Statistics** - - **Description:** Team performance metrics, player comparison, season statistics, team rankings - - **Estimated Effort:** 7-10 days - - **Priority:** P2 - -- [ ] **GOLF-010: Golf Course Management** - - **Description:** Course database, course ratings, hole details, yardage tracking - - **Estimated Effort:** 7-10 days - - **Priority:** P2 - ---- - -### Low Priority (P3) - Future Enhancements (5 features) - -- [ ] **FUTURE-001: Mobile App** - - **Description:** React Native or PWA, push notifications, offline support - - **Estimated Effort:** 60+ days - - **Priority:** P3 - -- [ ] **FUTURE-002: Advanced Analytics** - - **Description:** Predictive analytics, ML-based player matching, trend analysis, custom reports - - **Estimated Effort:** 30+ days - - **Priority:** P3 - -- [ ] **FUTURE-003: Parent Portal (Full Version)** - - **Description:** Beyond basic parent portal, full communication system - - **Estimated Effort:** 21-30 days - - **Priority:** P3 - -- [ ] **FUTURE-004: Payment System** - - **Description:** Subscription management, camp payments, premium features, billing dashboard - - **Estimated Effort:** 14-21 days - - **Priority:** P3 - -- [ ] **FUTURE-005: Social Features** - - **Description:** Activity feed, achievements sharing, team announcements, social media integration - - **Estimated Effort:** 14-21 days - - **Priority:** P3 - ---- - -## TECHNICAL DEBT 🔧 -**Status:** 5 technical improvements needed - -- [ ] **TECH-001: Type System Cleanup** - - **Description:** Ensure all types from @/lib/types, remove deprecated imports - - **Implementation:** - - Audit all files for type imports - - Replace deprecated imports with `@/lib/types` - - Add missing type definitions - - Remove `any` types where possible - - **Estimated Effort:** 2-3 days - - **Priority:** P1 - -- [ ] **TECH-002: Performance Optimization** - - **Description:** Image optimization, lazy loading, code splitting, bundle size reduction - - **Implementation:** - - Use Next.js Image component everywhere - - Implement lazy loading for modals and large components - - Code split routes with dynamic imports - - Analyze bundle with webpack-bundle-analyzer - - Remove unused dependencies - - **Estimated Effort:** 5-7 days - - **Priority:** P2 - -- [ ] **TECH-003: Testing Infrastructure** - - **Description:** E2E tests, component tests, API tests, 80% coverage - - **Implementation:** - - Set up Playwright for E2E tests - - Set up Vitest for component tests - - Write tests for critical paths (auth, recruiting, messaging) - - Add API route tests - - Set up CI/CD with test runs - - **Estimated Effort:** 14-21 days - - **Priority:** P2 - -- [ ] **TECH-004: Documentation Updates** - - **Description:** Update CLAUDE.md with golf platform, document hooks, API docs, component docs - - **Implementation:** - - Update CLAUDE.md to reflect dual-platform - - Document all custom hooks with JSDoc - - Create API reference documentation - - Document component props with Storybook or TSDoc - - Create developer onboarding guide - - **Estimated Effort:** 5-7 days - - **Priority:** P2 - -- [ ] **TECH-005: Accessibility Improvements** - - **Description:** WCAG 2.1 AA compliance, keyboard navigation, screen reader support, color contrast - - **Implementation:** - - Audit with axe DevTools - - Fix all keyboard navigation issues - - Add ARIA labels where missing - - Fix color contrast issues - - Test with screen readers (NVDA, VoiceOver) - - **Estimated Effort:** 7-10 days - - **Priority:** P2 - ---- - -## QUICK STATS 📊 - -### Overall Progress -- **Total Features:** 100+ tracked -- **Completed:** 55 features (55%) -- **In Progress:** 17 features (17%) -- **Planned:** 35 features (35%) -- **Technical Debt:** 5 items - -### By Platform -- **Baseball Platform:** 65% complete -- **Golf Platform:** 40% complete - -### By User Type -- **College Coach:** 95% complete -- **HS Coach:** 40% complete -- **JUCO Coach:** 30% complete (blocked by mode toggle) -- **Showcase Coach:** 35% complete -- **Player (HS/Showcase):** 70% complete -- **Player (JUCO):** 60% complete -- **Player (College):** 80% complete - -### By Category -- **Authentication:** 100% complete (3/3) -- **Recruiting:** 90% complete (5/6) -- **Team Management:** 70% complete (2/3) -- **Messaging:** 100% complete (1/1) -- **Video:** 50% complete (1/2) -- **Calendar:** 100% complete (1/1) -- **Settings:** 100% complete (2/2) -- **Infrastructure:** 100% complete (5/5) -- **Golf:** 60% complete (3/5) - -### Critical Priorities -- **P0 (Critical):** 5 features - MUST BE DONE FIRST -- **P1 (High):** 5 features - Complete partial features -- **P2 (Medium):** 20 features - New features and enhancements -- **P3 (Future):** 5 features - Long-term vision - ---- - -## NEXT STEPS 🚀 - -### Week 1-2 (P0 Critical Fixes) -1. ✅ Mark all completed features as DONE -2. ⚠️ Implement JUCO Mode Toggle (CORE-001) -3. ⚠️ Complete HS Coach Dashboard (CORE-003) -4. ⚠️ Separate Golf Platform (CORE-004) -5. ⚠️ Remove Dead Code (CORE-005) - -### Week 3-4 (P0 + P1) -6. ⚠️ Implement Multi-Team Support (CORE-002) -7. 🚀 Complete Video Clipping (FEATURE-001) -8. 🚀 Complete Player Comparison (FEATURE-003) -9. 🚀 Anonymous vs Identified Interest (FEATURE-005) - -### Week 5-8 (P1 + P2) -10. 🚀 Implement Notifications (FEATURE-002) -11. 🚀 Complete Showcase Multi-Team (FEATURE-004) -12. 🚀 Complete Dev Plans (FEATURE-006) -13. 🚀 Academics Tracking (FEATURE-007) - -### Week 9-12 (Golf Expansion) -14. 🏌️ Complete Golf Round Management (GOLF-006) -15. 🏌️ Golf Tournament System (GOLF-007) -16. 🏌️ Golf Player Development (GOLF-008) -17. 🏌️ Golf Team Statistics (GOLF-009) - ---- - -**END OF CHECKLIST** - -This checklist will be updated as features are completed. Use this document to track progress and prioritize work. - -**Legend:** -- ✅ = Completed -- ⚠️ = In Progress -- 🚀 = Planned (High Priority) -- 🏌️ = Golf Platform -- ❌ = Not Started diff --git a/.taskmaster/docs/prd.txt b/.taskmaster/docs/prd.txt deleted file mode 100644 index 185ddac1a..000000000 --- a/.taskmaster/docs/prd.txt +++ /dev/null @@ -1,676 +0,0 @@ -# Helm Sports Labs - Product Requirements Document -# Generated: December 22, 2024 -# Version: 3.0 - -## PRODUCT OVERVIEW -Helm Sports Labs is a dual-platform sports management system: -1. Baseball Recruiting Platform - Connect players with college coaches -2. Golf Team Management Platform - Track rounds, shots, and player development - ---- - -## SECTION 1: COMPLETED FEATURES ✅ - -### Baseball Platform - Authentication & Core Infrastructure - -AUTH-001: User Authentication System -- Email/password authentication via Supabase Auth -- Role-based signup (Coach vs Player) -- Protected routes with middleware -- Session management - -AUTH-002: Player Onboarding Flow -- 5-step wizard: Basic Info → Baseball Info → Physical/School → Metrics → Profile/Goals -- Avatar upload integration -- Position selection, graduation year -- Metrics capture: pitch velocity, exit velocity, 60-yard time, GPA -- Links to Supabase Auth user - -AUTH-003: Coach Onboarding Flow -- 4-step wizard: Personal Info → Program Info → Program Details → Preferences -- Creates coach record, organization, and team -- Logo upload, brand colors -- Links to Supabase Auth user - -### College Coach - Recruiting Suite - -RECRUIT-001: Player Discovery System -- Advanced filtering: grad year, position, state, velocity metrics, GPA -- Name and school search -- Pagination (24 players per page) -- USA Map visualization with state click filters -- Filter panel with real-time URL params -- Shows recruiting-activated players only -- Watchlist integration (add/remove from card) - -RECRUIT-002: Recruiting Watchlist Management -- Full CRUD operations on watchlist -- Table view with player details -- Inline status dropdown (5 pipeline stages) -- Inline notes editing -- Filter tabs by status -- Filter by position and grad year -- Bulk selection and bulk actions -- Bulk remove with confirmation -- Player detail modal - -RECRUIT-003: Recruiting Pipeline Board -- Drag-and-drop kanban board with 5 columns -- Pipeline stages: watchlist, high_priority, offer_extended, committed, uninterested -- Uses @dnd-kit for smooth interactions -- Grad year filter -- Real-time stage updates -- Empty state with CTA to Discover - -RECRUIT-004: Player Comparison Tool -- Side-by-side comparison of 2-4 players -- Search and add players dynamically -- Player removal -- URL-based state management -- Metrics comparison table -- Stats comparison - -RECRUIT-005: College Coach Dashboard -- Bento Grid layout with glass morphism -- Pipeline stats (watchlist, high_priority, offer_extended, committed counts) -- Profile views, messages stats -- Recent players list (last 5) -- 7-day engagement chart -- Activity feed (last 8 events) -- Upcoming events & camps calendar widget -- USA map showing player distribution by state -- Quick actions (Discover, Messages, Calendar, Edit Program) - -### Player Features - -PLAYER-001: Player Dashboard -- Profile card with avatar, name, position, grad year, school, location -- Bento grid stats: Profile views, On watchlists count, Messages, Video views -- Your Stats card (height, weight, velocity, GPA) -- Quick actions (Complete profile, Browse colleges, Check messages) -- Recruiting activation banner (if not activated) -- Profile completion percentage badge - -PLAYER-002: Player Profile Management -- Full profile editing -- Avatar upload -- Baseball stats and metrics -- School information -- Contact details -- Privacy settings - -PLAYER-003: Recruiting Journey Tracker -- Track colleges player is interested in -- Update status per school (interested, researching, contacted, visited, offered, committed) -- Timeline view of journey events -- Milestone tracking - -PLAYER-004: Player Analytics Dashboard -- Profile views, watchlist adds, video views, messages sent -- 7-day engagement chart (Recharts) -- Top schools viewing profile -- Engagement metrics - -### Messaging System - -MSG-001: Real-time Messaging Platform -- Full real-time messaging between coaches and players -- Conversation list with unread counts -- Chat window with message history -- New conversation modal -- Mobile-responsive (split view on desktop, single view on mobile) -- URL-based conversation selection -- Real-time updates - -### Video Management - -VIDEO-001: Video Upload and Library -- Video upload with drag-and-drop -- Supabase Storage integration -- Video library grid view -- Search videos by title or player name -- Video player modal -- Delete videos with confirmation -- Coach view: See all team player videos -- Player view: Personal video library - -### Camps Management - -CAMP-001: Camp Management System -- Coach: Create, edit, delete camps -- Player: Browse camps, register/unregister -- Camp cards with date, location, capacity, price -- Registration tracking -- Filter by status (upcoming, past) -- Camp detail view - -### Calendar & Events - -CAL-001: Team Calendar System -- Full calendar view of team events -- Create, edit, delete events -- Event types: game, practice, tournament, camp, showcase, team_meeting -- Team-specific events -- Coach calendar management - -### Team Management - -TEAM-001: Roster Management System -- View team members with full details -- Search by name, position, grad year -- Generate team invite links -- Jersey number assignment -- Player status badges (recruiting active vs team only) -- Team invitation system - -TEAM-002: Team Dashboard -- Team stats and roster overview -- Team-specific view for HS/Showcase coaches -- Quick actions - -### Settings & Configuration - -SET-001: User Settings -- Account settings -- Profile settings -- Privacy settings -- Notification preferences - -SET-002: Program Profile Management -- Edit organization details -- School name, website, division, conference -- Location (city, state) -- About program description -- Brand colors (primary, secondary) -- Logo upload - -### Infrastructure & Shared Systems - -SYS-001: Navigation System -- Dynamic sidebar with role-based navigation -- Responsive header -- Mobile menu -- User dropdown - -SYS-002: Authentication Store -- Zustand store for auth state -- useAuth hook with user, coach, player, loading -- Real-time auth state management - -SYS-003: Route Protection System -- Recruiting route protection (college/JUCO coaches only) -- Team route protection (HS/JUCO/Showcase coaches) -- Role-based redirects - -SYS-004: Database Query Layer -- Centralized query functions -- Type-safe Supabase queries -- Error handling - -SYS-005: UI Component Library -- 40+ reusable components -- Button, Card, Input, Select, Badge, Avatar, Modal, Toast -- Design system: Kelly Green (#16A34A) + Cream White (#FAF6F1) -- Glass morphism effects -- Subtle animations - -### Golf Platform - Core Features - -GOLF-001: Golf Dashboard -- Golf coach dashboard with team overview -- Round management -- Player statistics - -GOLF-002: Golf Player Features -- Player golf dashboard -- Round tracking -- Shot tracking component -- Scorecard integration - -GOLF-003: Shot Tracking System -- Real-time shot tracking during rounds -- Distance calculation -- Club selection -- Shot type tracking -- Scorecard integration with premium dark theme - ---- - -## SECTION 2: IN-PROGRESS FEATURES ⚠️ - -### High School Coach Features - -HS-001: HS Coach Team Dashboard (INCOMPLETE) -- Currently redirects to generic team dashboard -- NEEDS: HS-specific metrics and features -- NEEDS: Player development tracking -- NEEDS: Academic tracking for HS players -- STATUS: 40% complete - -HS-002: College Interest Tracking (PARTIAL) -- Shows which college coaches are viewing players on roster -- NEEDS: Full engagement event tracking -- NEEDS: Detailed analytics per player -- NEEDS: Notifications when coaches view players -- STATUS: 50% complete - -HS-003: Developmental Plans System (PARTIAL) -- Create dev plans for players -- NEEDS: Drill library -- NEEDS: Progress tracking -- NEEDS: Player goal setting -- NEEDS: Player view integration -- STATUS: 40% complete - -### JUCO Coach Features - -JUCO-001: JUCO Mode Toggle (NOT INTEGRATED) -- Component exists but not wired up -- NEEDS: Routing logic for mode switching -- NEEDS: Separate recruiting and team dashboards -- NEEDS: Mode state management -- STATUS: 20% complete - -JUCO-002: Academics Tracking (STUB) -- Stub page exists -- NEEDS: Academic records database schema -- NEEDS: GPA tracking over time -- NEEDS: Transcripts upload -- NEEDS: Academic eligibility tracking -- STATUS: 10% complete - -JUCO-003: Transfer Tracking (NOT STARTED) -- NEEDS: Transfer portal integration -- NEEDS: 4-year college tracking -- NEEDS: Transfer timeline -- STATUS: 0% complete - -### Showcase Coach Features - -SHOW-001: Multi-Team Management (INCOMPLETE) -- Teams listing page partially built -- NEEDS: Team switcher dropdown -- NEEDS: Per-team roster pages (/team/[id]/roster) -- NEEDS: Per-team videos, calendar -- NEEDS: Organization-level dashboard -- STATUS: 35% complete - -SHOW-002: Showcase Events Management (PARTIAL) -- Basic events page exists -- NEEDS: Event registration -- NEEDS: Event analytics -- NEEDS: Multi-team event coordination -- STATUS: 30% complete - -### Player Features - -PLAYER-005: Multi-Team Support (NOT IMPLEMENTED) -- Currently players can only join 1 team -- NEEDS: Allow 2 teams (HS + Showcase) -- NEEDS: Team switcher dropdown -- NEEDS: Isolated team contexts -- STATUS: 0% complete - -PLAYER-006: College Discovery (INCOMPLETE) -- Browse colleges page exists -- NEEDS: Filter by division, conference, location -- NEEDS: Save to "dream schools" -- NEEDS: School comparison -- STATUS: 40% complete - -PLAYER-007: Recruiting Activation Flow (BASIC) -- Basic activation works -- NEEDS: Privacy settings review modal -- NEEDS: Terms acceptance -- NEEDS: Benefits explanation -- NEEDS: Anonymous vs Identified interest UI -- STATUS: 60% complete - -### Video Features - -VIDEO-002: Video Clipping Tool (DATABASE READY, NO UI) -- Database has is_clip and parent_video_id fields -- NEEDS: Clip editor UI component -- NEEDS: Timeline scrubber -- NEEDS: Set start/end times -- NEEDS: Save clips as separate video records -- STATUS: 20% complete - -### Comparison Features - -RECRUIT-006: Advanced Player Comparison (PARTIAL) -- Basic comparison works -- NEEDS: Radar chart overlay -- NEEDS: Save comparisons feature (table exists) -- NEEDS: Export comparison to PDF -- STATUS: 60% complete - -### Public Profiles - -PUB-001: Public Player Profiles (BASIC) -- Basic layout exists -- NEEDS: Privacy settings enforcement -- NEEDS: Video embeds -- NEEDS: Achievement/honors display -- NEEDS: Recruiting status visibility -- STATUS: 50% complete - -PUB-002: Public Program Profiles (BASIC) -- Basic structure exists -- NEEDS: Full content display -- NEEDS: SEO optimization -- NEEDS: Roster preview -- STATUS: 40% complete - -### Golf Platform Enhancements - -GOLF-004: Golf Round Management (PARTIAL) -- Basic round tracking exists -- NEEDS: Round history -- NEEDS: Statistics aggregation -- NEEDS: Performance analytics -- STATUS: 40% complete - -GOLF-005: Golf Team Management (PARTIAL) -- Basic team structure exists -- NEEDS: Multi-player tracking -- NEEDS: Team statistics -- NEEDS: Tournament management -- STATUS: 35% complete - ---- - -## SECTION 3: PLANNED FEATURES 🚀 - -### Critical Priority (P0) - Fix Core Gaps - -CORE-001: Implement JUCO Mode Toggle -- Wire up ModeToggle component -- Create routing logic for mode switching -- Separate recruiting and team dashboards for JUCO -- Mode state persistence -- PRIORITY: P0 - CRITICAL - -CORE-002: Implement Multi-Team Support for Players -- Database schema update for multiple team memberships -- Team switcher dropdown component -- Isolated team contexts -- Team selection state management -- Allow HS + Showcase team combinations -- PRIORITY: P0 - CRITICAL - -CORE-003: Complete HS Coach Dashboard -- HS-specific team metrics -- Player development overview -- College interest notifications -- Academic tracking integration -- Parent portal preparation -- PRIORITY: P0 - CRITICAL - -CORE-004: Separate Golf Platform -- Move golf app to separate directory or repository -- Independent routing -- Separate authentication context -- Clear documentation -- PRIORITY: P0 - CRITICAL - -CORE-005: Remove Dead Code -- Delete unused peek panel components -- Remove duplicate pipeline implementations -- Clean up test/dev files -- Remove deprecated components -- PRIORITY: P0 - CRITICAL - -### High Priority (P1) - Complete Partially Built Features - -FEATURE-001: Complete Video Clipping System -- Build clip editor UI -- Timeline scrubber component -- Start/end time selection -- Preview clip before saving -- Save clips as separate video records -- Clip tagging (at-bat, pitch, etc.) -- PRIORITY: P1 - -FEATURE-002: Implement Notifications System -- Notification bell component integration -- Real-time notifications with Supabase Realtime -- Email notifications -- Push notifications (PWA) -- Notification preferences -- Mark as read/unread -- PRIORITY: P1 - -FEATURE-003: Complete Player Comparison Tool -- Add radar chart overlay (Recharts) -- Save comparison feature (use existing table) -- Comparison history -- Export comparison to PDF -- Share comparison link -- PRIORITY: P1 - -FEATURE-004: Complete Showcase Coach Multi-Team Management -- Organization-level dashboard -- Per-team routing (/coach/showcase/team/[id]/...) -- Team switcher component -- Multi-team calendar view -- Cross-team analytics -- PRIORITY: P1 - -FEATURE-005: Anonymous vs Identified Interest System -- UI to show "A D1 coach viewed" vs "Coach John Smith from Texas A&M viewed" -- Privacy settings enforcement -- Recruiting activation benefits -- Activation flow improvements -- PRIORITY: P1 - -### Medium Priority (P2) - New Features - -FEATURE-006: Complete Developmental Plans System -- Drill library with videos -- Progress tracking dashboard -- Player goal setting -- Coach feedback system -- Milestone achievements -- PRIORITY: P2 - -FEATURE-007: Academics Tracking System -- Academic records database schema -- GPA tracking over time -- Transcripts upload -- Academic eligibility tracking -- Semester/year breakdown -- PRIORITY: P2 - -FEATURE-008: College Interest Analytics -- Full engagement analytics -- Notifications when coaches view players -- Interest timeline -- School engagement heatmap -- PRIORITY: P2 - -FEATURE-009: Advanced Search System -- Global search with Command Palette -- Saved searches (use existing UI) -- Search history -- Advanced filters -- Quick keyboard shortcuts -- PRIORITY: P2 - -FEATURE-010: College Discovery Enhancements -- Filter by division, conference, location -- School comparison tool -- Dream schools list -- School match scoring -- PRIORITY: P2 - -### Golf Platform Expansion (P2) - -GOLF-006: Complete Golf Round Management -- Detailed round history -- Statistics aggregation -- Performance analytics -- Handicap calculation -- Round comparison -- PRIORITY: P2 - -GOLF-007: Golf Tournament System -- Tournament creation and management -- Leaderboards -- Live scoring -- Tournament analytics -- Team tournaments -- PRIORITY: P2 - -GOLF-008: Golf Player Development -- Swing analysis -- Practice tracking -- Goal setting -- Performance trends -- Coach feedback -- PRIORITY: P2 - -GOLF-009: Golf Team Statistics -- Team performance metrics -- Player comparison -- Season statistics -- Team rankings -- PRIORITY: P2 - -GOLF-010: Golf Course Management -- Course database -- Course ratings -- Hole details -- Yardage tracking -- PRIORITY: P2 - -### Low Priority (P3) - Future Enhancements - -FUTURE-001: Mobile App -- React Native or PWA -- Push notifications -- Offline support -- Mobile-optimized UI -- PRIORITY: P3 - -FUTURE-002: Advanced Analytics -- Predictive analytics for recruiting -- ML-based player matching -- Trend analysis -- Custom reports -- PRIORITY: P3 - -FUTURE-003: Parent Portal -- Parent accounts -- Communication system -- Academic tracking access -- Recruiting updates -- PRIORITY: P3 - -FUTURE-004: Payment System -- Subscription management -- Camp payment processing -- Premium features -- Billing dashboard -- PRIORITY: P3 - -FUTURE-005: Social Features -- Activity feed -- Player achievements sharing -- Team announcements -- Social media integration -- PRIORITY: P3 - ---- - -## TECHNICAL DEBT & IMPROVEMENTS - -TECH-001: Type System Cleanup -- Ensure all types from @/lib/types -- Remove deprecated type imports -- Add missing type definitions -- PRIORITY: P1 - -TECH-002: Performance Optimization -- Image optimization -- Lazy loading -- Code splitting -- Bundle size reduction -- PRIORITY: P2 - -TECH-003: Testing Infrastructure -- E2E tests with Playwright -- Component tests with Vitest -- API tests -- Test coverage > 80% -- PRIORITY: P2 - -TECH-004: Documentation Updates -- Update CLAUDE.md with golf platform -- Document all hooks -- API documentation -- Component documentation -- PRIORITY: P2 - -TECH-005: Accessibility Improvements -- WCAG 2.1 AA compliance -- Keyboard navigation -- Screen reader support -- Color contrast fixes -- PRIORITY: P2 - ---- - -## SUCCESS METRICS - -### Baseball Platform -- College Coach adoption: 100+ programs -- Player registrations: 1000+ players -- Active recruiting conversations: 500+/month -- Camp registrations: 50+/month -- Platform engagement: 70% weekly active users - -### Golf Platform -- Coach adoption: 50+ programs -- Player registrations: 500+ players -- Rounds tracked: 1000+/month -- Shot tracking usage: 80% of rounds -- Platform engagement: 60% weekly active users - ---- - -## RELEASE TIMELINE - -### Phase 1: Critical Fixes (Weeks 1-2) -- CORE-001: JUCO Mode Toggle -- CORE-003: HS Coach Dashboard -- CORE-004: Separate Golf Platform -- CORE-005: Remove Dead Code - -### Phase 2: Complete Partial Features (Weeks 3-4) -- CORE-002: Multi-Team Support -- FEATURE-001: Video Clipping -- FEATURE-003: Player Comparison -- FEATURE-005: Anonymous Interest - -### Phase 3: New Features (Weeks 5-8) -- FEATURE-002: Notifications -- FEATURE-004: Showcase Multi-Team -- FEATURE-006: Dev Plans -- FEATURE-007: Academics - -### Phase 4: Golf Expansion (Weeks 9-12) -- GOLF-006: Round Management -- GOLF-007: Tournament System -- GOLF-008: Player Development -- GOLF-009: Team Statistics - -### Phase 5: Future Enhancements (Weeks 13+) -- FUTURE-001: Mobile App -- FUTURE-002: Advanced Analytics -- FUTURE-003: Parent Portal -- FUTURE-004: Payment System - ---- - -END OF PRD diff --git a/.taskmaster/logs/.gitkeep b/.taskmaster/logs/.gitkeep deleted file mode 100644 index 4fcd85293..000000000 --- a/.taskmaster/logs/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# TaskMaster logs directory diff --git a/.taskmaster/state.json b/.taskmaster/state.json deleted file mode 100644 index a9206ae26..000000000 --- a/.taskmaster/state.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "currentTag": "master", - "lastSwitched": "2025-12-28T22:06:23.990Z", - "branchTagMapping": {}, - "migrationNoticeShown": false -} \ No newline at end of file diff --git a/.taskmaster/tasks/tasks.json b/.taskmaster/tasks/tasks.json deleted file mode 100644 index 6a5d01509..000000000 --- a/.taskmaster/tasks/tasks.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "master": { - "tasks": [ - { - "id": "HELM-001", - "title": "Premium Dark Scorecard", - "description": "Transform scorecard to premium dark theme with impossible-to-miss current hole", - "status": "done", - "priority": "high", - "category": "feature", - "assignee": "claude", - "created": "2025-12-21", - "updated": "2025-12-21", - "completed": "2025-12-21", - "tags": [ - "ui", - "scorecard", - "golf" - ], - "files": [ - "src/components/golf/ShotTrackingFinal.tsx" - ], - "commits": [ - "f6625a5" - ], - "notes": [ - "Dark theme with slate-900/800 gradient", - "Current hole: green gradient, scale-110, pulsing dot", - "Color-coded scores (Eagle: yellow, Birdie: red, etc.)", - "Performance badges showing +/- on current hole" - ] - }, - { - "id": "HELM-002", - "title": "Fix Shot Distance Calculation Bug", - "description": "Fix yards/feet unit conversion bug causing incorrect distance display", - "status": "done", - "priority": "critical", - "category": "bug", - "assignee": "claude", - "created": "2025-12-21", - "updated": "2025-12-21", - "completed": "2025-12-21", - "tags": [ - "bug", - "calculation", - "golf", - "units" - ], - "files": [ - "src/components/golf/ShotTrackingFinal.tsx" - ], - "commits": [ - "f6625a5" - ], - "notes": [ - "Added shotDistanceUnit field to ShotRecord interface", - "Store unit during calculation instead of guessing", - "Fixed: Shot 1 now shows '1105 feet' not '1105 yards'", - "Improved unit detection: Shot 1 always yards OR distance > 100" - ] - } - ], - "metadata": { - "totalTasks": 2, - "completedTasks": 2, - "lastUpdated": "2025-12-21T22:45:00Z" - } - } -} \ No newline at end of file diff --git a/.taskmaster/templates/task-template.json b/.taskmaster/templates/task-template.json deleted file mode 100644 index f0acdaa98..000000000 --- a/.taskmaster/templates/task-template.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "id": "HELM-XXX", - "title": "", - "description": "", - "status": "todo", - "priority": "medium", - "category": "feature", - "assignee": "", - "created": "", - "updated": "", - "completed": null, - "tags": [], - "files": [], - "commits": [], - "notes": [], - "subtasks": [], - "dependencies": [], - "blockedBy": [], - "estimatedHours": null, - "actualHours": null -} diff --git a/age-ratings-snapshot.yml b/age-ratings-snapshot.yml deleted file mode 100644 index 442f2319d..000000000 --- a/age-ratings-snapshot.yml +++ /dev/null @@ -1,209 +0,0 @@ -- generic [ref=e1]: - - banner "App Store Connect" [ref=e3]: - - generic [ref=e4]: - - heading "App Store Connect" [level=1] [ref=e6]: - - link "App Store Connect" [ref=e7] [cursor=pointer]: - - /url: / - - navigation "Global" [ref=e8]: - - list [ref=e10]: - - listitem [ref=e11]: - - link "Apps" [ref=e12] [cursor=pointer]: - - /url: /apps - - listitem [ref=e13]: - - link "Trends" [ref=e14] [cursor=pointer]: - - /url: /trends - - listitem [ref=e15]: - - link "Reports" [ref=e16] [cursor=pointer]: - - /url: /itc/payments_and_financial_reports - - listitem [ref=e17]: - - link "Business" [ref=e18] [cursor=pointer]: - - /url: /business - - listitem [ref=e19]: - - link "Users and Access" [ref=e20] [cursor=pointer]: - - /url: /access/users - - button "Rick Nini NICHOLAS JAMES RINI Account name menu" [ref=e22] [cursor=pointer]: - - generic: - - generic: Rick Nini - - generic: NICHOLAS JAMES RINI - - img [ref=e23] - - generic [ref=e54]: - - button "Apps menu, Helm Sports Labs, selected" [ref=e59] [cursor=pointer]: - - generic [ref=e60]: - - generic "Helm Sports Labs" [ref=e61]: - - img "Helm Sports Labs" [ref=e62] - - generic [ref=e64]: Helm Sports Labs - - img [ref=e66] - - navigation "Apps" [ref=e69]: - - list [ref=e70]: - - listitem [ref=e71]: - - link "Distribution" [ref=e72] [cursor=pointer]: - - /url: /apps/6761740758/distribution - - listitem [ref=e73]: - - link "Analytics" [ref=e74] [cursor=pointer]: - - /url: /apps/6761740758/analytics - - listitem [ref=e75]: - - link "TestFlight" [ref=e76] [cursor=pointer]: - - /url: /teams/7ea6779d-f797-4a55-9604-73fb1b7eccd9/apps/6761740758/testflight - - listitem [ref=e77]: - - link "Xcode Cloud" [ref=e78] [cursor=pointer]: - - /url: /teams/7ea6779d-f797-4a55-9604-73fb1b7eccd9/apps/6761740758/ci - - generic [ref=e81]: - - main [ref=e82]: - - generic [ref=e87]: - - navigation "Distribution" [ref=e89]: - - list [ref=e90]: - - listitem [ref=e91]: - - generic [ref=e92]: - - heading "iOS App" [level=2] [ref=e94] - - list [ref=e95] - - button "Add Platform" [ref=e101] [cursor=pointer] - - listitem [ref=e102]: - - separator [ref=e103] - - listitem [ref=e104]: - - heading "General" [level=2] [ref=e106] - - list [ref=e107]: - - listitem [ref=e108] - - listitem [ref=e111] - - listitem [ref=e114] - - listitem [ref=e117]: - - separator [ref=e118] - - listitem [ref=e119]: - - heading "App Store" [level=2] [ref=e121] - - generic [ref=e122]: - - heading "Trust & Safety" [level=3] [ref=e124] - - list [ref=e125] - - generic [ref=e135]: - - heading "Growth & Marketing" [level=3] [ref=e137] - - list [ref=e138] - - generic [ref=e154]: - - heading "Monetization" [level=3] [ref=e156] - - list [ref=e157] - - generic [ref=e167]: - - heading "Featuring" [level=3] [ref=e169] - - list [ref=e170] - - generic [ref=e174]: - - generic:  - - generic [ref=e175]: - - generic [ref=e176]: - - generic [ref=e178]: - - generic [ref=e180] - - generic [ref=e185] - - generic:  - - generic [ref=e189]: - - generic [ref=e191] - - generic [ref=e205] - - generic [ref=e228]: - - heading "General Information" [level=3] [ref=e231] - - generic [ref=e232] - - generic [ref=e304]: - - separator [ref=e305] - - heading "Age Ratings" [level=3] [ref=e306] - - paragraph [ref=e307]: - - generic [ref=e308] - - button "Set Up Age Ratings" [ref=e313] [cursor=pointer] - - generic [ref=e314]: - - separator [ref=e315] - - generic [ref=e317]: - - heading "Learn More About Age Ratings" [level=3] [ref=e318] - - paragraph [ref=e319]: To learn more about and view examples of the features and content used to determine age ratings, select a category below. - - generic [ref=e321]: - - generic [ref=e322] [cursor=pointer] - - generic [ref=e327] [cursor=pointer] - - generic [ref=e332] [cursor=pointer] - - generic [ref=e337] [cursor=pointer] - - generic [ref=e342] [cursor=pointer] - - generic [ref=e347] [cursor=pointer] - - generic [ref=e352] [cursor=pointer] - - generic [ref=e357]: - - separator [ref=e358] - - generic [ref=e359]: - - heading "App Encryption Documentation" [level=3] [ref=e360] - - button "Upload" [ref=e361] [cursor=pointer] - - paragraph [ref=e364]: - - generic [ref=e365] - - generic [ref=e368]: - - paragraph [ref=e369]: "You're required to provide documentation if your app contains any of the following:" - - list [ref=e370] - - generic [ref=e374]: - - paragraph [ref=e375]: You can provide your documentation before you submit a build. - - button "Upload" [ref=e376] [cursor=pointer] - - generic [ref=e377]: - - heading "App Store Regulations & Permits" [level=3] [ref=e378] - - generic [ref=e379]: - - generic [ref=e380] - - generic [ref=e384] - - generic [ref=e392] - - separator [ref=e401] - - generic [ref=e403]: - - heading "App Store Server Notifications" [level=3] [ref=e404] - - paragraph [ref=e405]: - - generic [ref=e406] - - generic [ref=e408]: - - generic [ref=e409] - - generic [ref=e415] - - separator [ref=e421] - - generic [ref=e422]: - - heading "App-Specific Shared Secret" [level=3] [ref=e423] - - paragraph [ref=e424]: The app-specific shared secret is a unique code to receive receipts for only this app’s auto-renewable subscriptions. You may want to use an app-specific shared secret if you’re transferring this app to another developer, or if you want to keep your primary shared secret private. - - paragraph [ref=e425]: - - button "Manage" [ref=e426] [cursor=pointer] - - separator [ref=e427] - - generic [ref=e428]: - - heading "Additional Information" [level=3] [ref=e429] - - paragraph [ref=e430]: - - button "View on App Store" [ref=e431] [cursor=pointer] - - paragraph [ref=e432]: - - button "Edit User Access" [ref=e433] [cursor=pointer] - - paragraph [ref=e434]: - - button "Remove App" [ref=e435] [cursor=pointer] - - 'dialog "Age Ratings Step 1: Features" [active] [ref=e440]': - - document [ref=e441]: - - generic [ref=e442]: - - 'heading "Age Ratings Step 1: Features" [level=2] [ref=e443]': - - text: Age Ratings - - list [ref=e444]: - - listitem [ref=e445]: - - generic [ref=e446]: "Step 1: Features" - - listitem [ref=e448]: - - generic [ref=e449]: Step 2 - - listitem [ref=e451]: - - generic [ref=e452]: Step 3 - - listitem [ref=e454]: - - generic [ref=e455]: Step 4 - - listitem [ref=e457]: - - generic [ref=e458]: Step 5 - - listitem [ref=e460]: - - generic [ref=e461]: Step 6 - - listitem [ref=e463]: - - generic [ref=e464]: Step 7 - - generic [ref=e466]: - - paragraph [ref=e468]: Select whether your app has certain in-app controls, which can be used to limit the content in your app, and capabilities. - - generic [ref=e469]: - - table [ref=e470]: - - rowgroup [ref=e471] - - rowgroup [ref=e481] - - table [ref=e508]: - - rowgroup [ref=e509] - - rowgroup [ref=e519] - - generic [ref=e574]: - - button "Cancel" [ref=e575] [cursor=pointer] - - button "Next" [disabled] [ref=e576] - - contentinfo [ref=e38]: - - generic [ref=e39]: - - list [ref=e40]: - - listitem [ref=e41]: - - link "App Store Connect" [ref=e42] [cursor=pointer]: - - /url: /apps - - list [ref=e43]: - - listitem [ref=e44]: Copyright © 2026 Apple Inc. All rights reserved. | - - listitem [ref=e45]: - - link "Terms of Service" [ref=e46] [cursor=pointer]: - - /url: /WebObjects/iTunesConnect.woa/wa/termsOfService - - text: "|" - - listitem [ref=e47]: - - link "Privacy Policy" [ref=e48] [cursor=pointer]: - - /url: https://www.apple.com/legal/privacy - - text: "|" - - listitem [ref=e49]: - - link "Contact Us" [ref=e50] [cursor=pointer]: - - /url: /contact-us \ No newline at end of file diff --git a/app-info-snapshot.yml b/app-info-snapshot.yml deleted file mode 100644 index 19e6a9905..000000000 --- a/app-info-snapshot.yml +++ /dev/null @@ -1,242 +0,0 @@ -- generic [active] [ref=e1]: - - banner "App Store Connect" [ref=e3]: - - generic [ref=e4]: - - heading "App Store Connect" [level=1] [ref=e6]: - - link "App Store Connect" [ref=e7] [cursor=pointer]: - - /url: / - - navigation "Global" [ref=e8]: - - list [ref=e10]: - - listitem [ref=e11]: - - link "Apps" [ref=e12] [cursor=pointer]: - - /url: /apps - - listitem [ref=e13]: - - link "Trends" [ref=e14] [cursor=pointer]: - - /url: /trends - - listitem [ref=e15]: - - link "Reports" [ref=e16] [cursor=pointer]: - - /url: /itc/payments_and_financial_reports - - listitem [ref=e17]: - - link "Business" [ref=e18] [cursor=pointer]: - - /url: /business - - listitem [ref=e19]: - - link "Users and Access" [ref=e20] [cursor=pointer]: - - /url: /access/users - - button "Rick Nini NICHOLAS JAMES RINI Account name menu" [ref=e22] [cursor=pointer]: - - generic: - - generic: Rick Nini - - generic: NICHOLAS JAMES RINI - - img [ref=e23] - - generic [ref=e54]: - - button "Apps menu, Helm Sports Labs, selected" [ref=e59] [cursor=pointer]: - - generic [ref=e60]: - - generic "Helm Sports Labs" [ref=e61]: - - img "Helm Sports Labs" [ref=e62] - - generic [ref=e64]: Helm Sports Labs - - img [ref=e66] - - navigation "Apps" [ref=e69]: - - list [ref=e70]: - - listitem [ref=e71]: - - link "Distribution" [ref=e72] [cursor=pointer]: - - /url: /apps/6761740758/distribution - - listitem [ref=e73]: - - link "Analytics" [ref=e74] [cursor=pointer]: - - /url: /apps/6761740758/analytics - - listitem [ref=e75]: - - link "TestFlight" [ref=e76] [cursor=pointer]: - - /url: /teams/7ea6779d-f797-4a55-9604-73fb1b7eccd9/apps/6761740758/testflight - - listitem [ref=e77]: - - link "Xcode Cloud" [ref=e78] [cursor=pointer]: - - /url: /teams/7ea6779d-f797-4a55-9604-73fb1b7eccd9/apps/6761740758/ci - - main [ref=e82]: - - generic [ref=e87]: - - navigation "Distribution" [ref=e89]: - - list [ref=e90]: - - listitem [ref=e91]: - - generic [ref=e92]: - - heading "iOS App" [level=2] [ref=e94] - - list [ref=e95]: - - listitem [ref=e96] - - button "Add Platform" [ref=e101] [cursor=pointer] - - listitem [ref=e102]: - - separator [ref=e103] - - listitem [ref=e104]: - - heading "General" [level=2] [ref=e106] - - list [ref=e107]: - - listitem [ref=e108]: - - link "App Information" [ref=e109] [cursor=pointer]: - - /url: /apps/6761740758/distribution/info - - listitem [ref=e111]: - - link "App Review" [ref=e112] [cursor=pointer]: - - /url: /apps/6761740758/distribution/reviewsubmissions - - listitem [ref=e114]: - - link "History" [ref=e115] [cursor=pointer]: - - /url: /apps/6761740758/distribution/activity/ios/versions - - listitem [ref=e117]: - - separator [ref=e118] - - listitem [ref=e119]: - - heading "App Store" [level=2] [ref=e121] - - generic [ref=e122]: - - heading "Trust & Safety" [level=3] [ref=e124] - - list [ref=e125]: - - listitem [ref=e126] - - listitem [ref=e129] - - listitem [ref=e132] - - generic [ref=e135]: - - heading "Growth & Marketing" [level=3] [ref=e137] - - list [ref=e138]: - - listitem [ref=e139] - - listitem [ref=e142] - - listitem [ref=e145] - - listitem [ref=e148] - - listitem [ref=e151] - - generic [ref=e154]: - - heading "Monetization" [level=3] [ref=e156] - - list [ref=e157]: - - listitem [ref=e158] - - listitem [ref=e161] - - listitem [ref=e164] - - generic [ref=e167]: - - heading "Featuring" [level=3] [ref=e169] - - list [ref=e170]: - - listitem [ref=e171] - - generic [ref=e174]: - - generic:  - - generic [ref=e175]: - - generic [ref=e176]: - - generic [ref=e178]: - - generic [ref=e180]: - - heading "App Information" [level=2] [ref=e182] - - paragraph [ref=e184]: This information is used for all platforms of this app. Any changes will be released with your next app version. - - generic [ref=e185]: - - button "Save" - - generic:  - - generic [ref=e189]: - - generic [ref=e191]: - - heading "Localizable Information" [level=3] [ref=e193] - - generic [ref=e197] - - generic [ref=e205]: - - generic [ref=e206] - - generic [ref=e217] - - generic [ref=e228]: - - heading "General Information" [level=3] [ref=e231] - - generic [ref=e232]: - - generic [ref=e234] - - generic [ref=e281] - - generic [ref=e304]: - - separator [ref=e305] - - heading "Age Ratings" [level=3] [ref=e306] - - paragraph [ref=e307]: - - generic [ref=e308]: - - text: Age ratings help users better understand if your app contains any objectionable content. To determine your app's age rating, you'll be asked the availability or frequency of certain features and types of content within your app. Based on your responses, an age rating will be assigned for each country or region based on their age suitability standards. The assigned age rating will appear on each country or region's App Store and be the same across all platforms in that country or region. - - link "Learn More" [ref=e309] [cursor=pointer]: - - /url: https://developer.apple.com/help/app-store-connect/reference/age-ratings-values-and-definitions - - button "Set Up Age Ratings" [ref=e313] [cursor=pointer] - - generic [ref=e314]: - - separator [ref=e315] - - generic [ref=e317]: - - heading "Learn More About Age Ratings" [level=3] [ref=e318] - - paragraph [ref=e319]: To learn more about and view examples of the features and content used to determine age ratings, select a category below. - - generic [ref=e321]: - - generic [ref=e322] [cursor=pointer]: - - paragraph [ref=e324]: In-App Controls - - paragraph [ref=e326]: Parental Controls, Age Assurance - - generic [ref=e327] [cursor=pointer]: - - paragraph [ref=e329]: Capabilities - - paragraph [ref=e331]: Unrestricted Web Access, User-Generated Content, Messaging and Chat, Advertising - - generic [ref=e332] [cursor=pointer]: - - paragraph [ref=e334]: Mature Themes - - paragraph [ref=e336]: Profanity or Crude Humor, Horror/Fear Themes, Alcohol, Tobacco, or Drug Use or References - - generic [ref=e337] [cursor=pointer]: - - paragraph [ref=e339]: Medical or Wellness - - paragraph [ref=e341]: Medical or Treatment Information, Health or Wellness Topics - - generic [ref=e342] [cursor=pointer]: - - paragraph [ref=e344]: Sexuality or Nudity - - paragraph [ref=e346]: Mature or Suggestive Themes, Sexual Content or Nudity, Graphic Sexual Content and Nudity - - generic [ref=e347] [cursor=pointer]: - - paragraph [ref=e349]: Violence - - paragraph [ref=e351]: Cartoon or Fantasy Violence, Realistic Violence, Prolonged Graphic or Sadistic Realistic Violence, Guns or Other Weapons - - generic [ref=e352] [cursor=pointer]: - - paragraph [ref=e354]: Chance-Based Activities - - paragraph [ref=e356]: Gambling, Simulated Gambling, Contests, Loot Boxes - - generic [ref=e357]: - - separator [ref=e358] - - generic [ref=e359]: - - heading "App Encryption Documentation" [level=3] [ref=e360] - - button "Upload" [ref=e361] [cursor=pointer]: - - img [ref=e362] - - paragraph [ref=e364]: - - generic [ref=e365]: - - text: Specify your use of encryption in Xcode by adding the - - strong [ref=e366]: App Uses Non-Exempt Encryption - - text: key to your app's Info.plist file with a Boolean value that indicates whether your app uses encryption. - - link "Learn More" [ref=e367] [cursor=pointer]: - - /url: https://developer.apple.com/documentation/security/complying_with_encryption_export_regulations - - generic [ref=e368]: - - paragraph [ref=e369]: "You're required to provide documentation if your app contains any of the following:" - - list [ref=e370]: - - listitem [ref=e371]: Encryption algorithms that are proprietary or not accepted as standard by international standard bodies (IEEE, IETF, ITU, etc.) - - listitem [ref=e372]: Standard encryption algorithms instead of, or in addition to, using or accessing the encryption within Apple's operating system - - generic [ref=e374]: - - paragraph [ref=e375]: You can provide your documentation before you submit a build. - - button "Upload" [ref=e376] [cursor=pointer] - - generic [ref=e377]: - - heading "App Store Regulations & Permits" [level=3] [ref=e378] - - generic [ref=e379]: - - generic [ref=e380]: - - heading "Digital Services Act" [level=6] [ref=e381] - - paragraph [ref=e382] - - generic [ref=e384]: - - heading "Vietnam Game License" [level=3] [ref=e385] - - generic [ref=e387] - - generic [ref=e392]: - - heading "Regulated Medical Devices" [level=6] [ref=e394] - - generic [ref=e396] - - separator [ref=e401] - - generic [ref=e403]: - - heading "App Store Server Notifications" [level=3] [ref=e404] - - paragraph [ref=e405]: - - generic [ref=e406]: - - text: App Store server notifications provide information about key events related to your in-app purchases. To test notifications before implementing them in production, you can set up a separate sandbox server URL. - - link "Learn More" [ref=e407] [cursor=pointer]: - - /url: https://developer.apple.com/help/app-store-connect/configure-in-app-purchase-settings/enter-server-urls-for-app-store-server-notifications - - generic [ref=e408]: - - generic [ref=e409]: - - generic [ref=e411]: Production Server URL - - button "Set Up URL" [ref=e414] [cursor=pointer] - - generic [ref=e415]: - - generic [ref=e417]: Sandbox Server URL - - button "Set Up URL" [ref=e420] [cursor=pointer] - - separator [ref=e421] - - generic [ref=e422]: - - heading "App-Specific Shared Secret" [level=3] [ref=e423] - - paragraph [ref=e424]: The app-specific shared secret is a unique code to receive receipts for only this app’s auto-renewable subscriptions. You may want to use an app-specific shared secret if you’re transferring this app to another developer, or if you want to keep your primary shared secret private. - - paragraph [ref=e425]: - - button "Manage" [ref=e426] [cursor=pointer] - - separator [ref=e427] - - generic [ref=e428]: - - heading "Additional Information" [level=3] [ref=e429] - - paragraph [ref=e430]: - - button "View on App Store" [ref=e431] [cursor=pointer] - - paragraph [ref=e432]: - - button "Edit User Access" [ref=e433] [cursor=pointer] - - paragraph [ref=e434]: - - button "Remove App" [ref=e435] [cursor=pointer] - - contentinfo [ref=e38]: - - generic [ref=e39]: - - list [ref=e40]: - - listitem [ref=e41]: - - link "App Store Connect" [ref=e42] [cursor=pointer]: - - /url: /apps - - list [ref=e43]: - - listitem [ref=e44]: Copyright © 2026 Apple Inc. All rights reserved. | - - listitem [ref=e45]: - - link "Terms of Service" [ref=e46] [cursor=pointer]: - - /url: /WebObjects/iTunesConnect.woa/wa/termsOfService - - text: "|" - - listitem [ref=e47]: - - link "Privacy Policy" [ref=e48] [cursor=pointer]: - - /url: https://www.apple.com/legal/privacy - - text: "|" - - listitem [ref=e49]: - - link "Contact Us" [ref=e50] [cursor=pointer]: - - /url: /contact-us \ No newline at end of file diff --git a/docs/baseball/legacy-backfill-runbook.md b/docs/baseball/legacy-backfill-runbook.md new file mode 100644 index 000000000..3c0e8e263 --- /dev/null +++ b/docs/baseball/legacy-backfill-runbook.md @@ -0,0 +1,541 @@ +# #379 Legacy Stats Backfill — Runbook + +> Companion to `supabase/migrations/20260715141727_baseball_legacy_stats_backfill.sql` +> and `docs/baseball/stats-migration-plan.md` / `stats-architecture.md`. +> Last updated: 2026-07-15. +> +> **Status: WRITTEN, NOT APPLIED.** This migration is a one-time, pending-approval +> catch-up — do not run it against any shared project until Nick has explicitly +> signed off. It is not wired into any cron, CI gate, or app code path; nothing +> executes it automatically. + +## What it does + +`#827` ("#379 Phase 0") fixed `scripts/seed-baseball-stats.mjs` and the live +import/box-score-save paths (`src/app/baseball/actions/imports.ts`, +`src/app/baseball/actions/games.ts`) to write **both** stat layers going +forward — the legacy flat table (`baseball_player_stats`) AND the canonical +box-score tables (`baseball_box_score_batting` / `_pitching` + synthesized +`baseball_games` rows). It did not do anything for teams whose entire game +history predates that fix and lives **only** in the legacy table. Those teams +still show real numbers on Command Center / Roster / Player Today / Passport +(the grandfathered legacy-layer consumers — see +`src/lib/baseball/stat-layer-manifest.ts`) but an honestly-empty Stats Center, +because `src/lib/baseball/read-models/stats-center.ts` reads **only** the +box-score/season layer. + +The migration is the one-time catch-up for exactly those teams: + +1. Finds every team with a `stat_type = 'game'` row in `baseball_player_stats` + and **zero** rows in both `baseball_box_score_batting` and + `baseball_box_score_pitching` ("zero box-score data" — see below). +2. For those teams only, groups their legacy `'game'` rows by + `(team_id, session_date)` into one shared, synthesized `baseball_games` row + per team-date (never one row per player — mirrors #827's + `buildBoxScoreRowsForSessions` fix). +3. Copies each attending player's legacy row into a + `baseball_box_score_batting` row (always) and a `baseball_box_score_pitching` + row (only when `innings_pitched > 0`), computing avg/obp/slg/ops and + era/whip/k9/bb9 with the same formulas + `src/app/baseball/actions/games.ts`'s `computeBattingRates` / + `computePitchingRates` use, including outs-based innings-pitched conversion + (`src/lib/baseball/innings.ts` — the `X.1`/`X.2` notation is thirds of an + inning, not a decimal fraction). + +**Practice rows are never touched.** Only `stat_type = 'game'` rows are read; +`'practice'` and `'other'` rows have no box-score equivalent +(`baseball_games.game_type` only allows `'game'`/`'scrimmage'`). + +**Copy-only.** The migration only ever `INSERT`s into `baseball_games`, +`baseball_box_score_batting`, `baseball_box_score_pitching`, and +`baseball_player_season_stats`. It never +`UPDATE`s or `DELETE`s a row of `baseball_player_stats`, or anything else — +the legacy table is read-only input. + +**Never mixes into teams already using box-score.** A team with even one +existing box-score row is completely excluded — that team's box-score data is +maintained live by the adapter precedence in `applyGameBoxScoreImport` +(`imports.ts`) and `save_baseball_full_box_score` (`games.ts`), and this +migration never races with or duplicates that path. + +### Season-stats interaction: seeded where safe, explicitly flagged where not + +**Recalc is not an opt-in, manual, per-team step — it already runs +automatically on every ordinary box-score save.** The already-shipped, +unrelated RPC `save_baseball_full_box_score` +(`supabase/migrations/20260630000000_baseball_save_full_box_score_rpc.sql`) — +called by every normal in-app "save box score" action — unconditionally +calls `recalculate_baseball_season_stats(player_id, team_id, EXTRACT(YEAR +FROM now()))` for every player in whatever game a coach just saved. That +function fully aggregates all of that player's completed-game box-score rows +for the current calendar year and does an `ON CONFLICT ... DO UPDATE` — a +full **overwrite**, not a merge — of `baseball_player_season_stats`. + +This migration inserts `baseball_games` rows carrying the legacy rows' real +historical `game_date`. For a team whose entire history "predates #827" +(applied the same day as this migration), those dates can plausibly fall +within the current season year. So the first time any coach enters one +ordinary new game this season for a player who overlaps with a backfilled +team, that live recalc sweeps up these backfilled box-score rows and +overwrites `baseball_player_season_stats` for that (player, team, year) — +with no code change, no extra step, and no opt-in required. If that team +already had a `season_totals`-imported baseline in +`baseball_player_season_stats` for that player/year, it gets silently +replaced at that moment. + +**What the migration does about it (Step 4):** it seeds +`baseball_player_season_stats` now, for exactly the `(player_id, team_id, +season_year)` triples its own box-score inserts touch, using the identical +aggregation and rate formulas `recalculate_baseball_season_stats()` uses +(same SUMs, same `w`/`l`/`sv`/`holds`/`blown_saves` derivation from `result`, +same era/whip/k9/bb9 division by raw `ip`). It never invokes the live RPC — +the formulas are mirrored inline, read-only against the rows this migration +just wrote, so the migration never depends on (or risks a future edit to) +that shared function. It is guarded by `ON CONFLICT (player_id, team_id, +season_year) DO NOTHING`, so: + +- **No pre-existing season row for that triple** (the common case, since the + team had zero box-score data): the seed populates it now with numbers that + exactly match what the inevitable future recalc would produce anyway — so + that eventual overwrite becomes a substantive no-op, not a surprise. +- **A pre-existing season row already there** (a `season_totals`-imported + baseline): Step 4 does **not** touch it — copy-only/additive-only is + preserved. But that row remains exposed to the same already-shipped + recalc-on-save behavior described above once this migration's box-score + rows exist. This is not a new risk this migration invents — any team + mixing legacy and `season_totals` data already had it — but backfilling box + scores makes it far more likely to actually fire. **Run the pre-flight + query below before applying** to see exactly which triples this affects, + and decide with Nick (skip those teams for now, accept the eventual + overwrite, or snapshot those specific rows externally) before proceeding. + +Stats Center's game-log views (the batting/pitching splits, which read +straight off box-score rows) show real numbers immediately after this +migration runs regardless. See "Season-stats rollback" below for how the +Step 4 seed interacts with rollback. + +#### Pre-flight query — season rows at risk (run BEFORE applying) + +```sql +SELECT bpss.* +FROM public.baseball_player_season_stats bpss +WHERE (bpss.player_id, bpss.team_id, bpss.season_year) IN ( + SELECT DISTINCT ps.player_id, ps.team_id, EXTRACT(YEAR FROM ps.session_date)::integer + FROM public.baseball_player_stats ps + WHERE ps.stat_type = 'game' + AND NOT EXISTS (SELECT 1 FROM public.baseball_box_score_batting bsb WHERE bsb.team_id = ps.team_id) + AND NOT EXISTS (SELECT 1 FROM public.baseball_box_score_pitching bsp WHERE bsp.team_id = ps.team_id) +); +``` + +Any row this returns is one Step 4 will deliberately leave alone (`DO +NOTHING`) — and one that stays exposed to the live recalc-on-save behavior +above. **Non-empty result: stop and review with Nick before applying**, +per-team if needed (e.g. hold off on just the affected team's legacy rows +until its `season_totals` baseline is reconciled or intentionally retired). + +## Eligibility, precisely + +A team qualifies iff, at the moment the migration runs: + +```sql +SELECT DISTINCT ps.team_id +FROM baseball_player_stats ps +WHERE ps.stat_type = 'game' + AND NOT EXISTS (SELECT 1 FROM baseball_box_score_batting bsb WHERE bsb.team_id = ps.team_id) + AND NOT EXISTS (SELECT 1 FROM baseball_box_score_pitching bsp WHERE bsp.team_id = ps.team_id); +``` + +This set is snapshotted once into a session-local `TEMP TABLE` (`ON COMMIT +DROP` — never persisted) before any writes happen, so a team's eligibility +can't be affected by rows the migration itself inserts mid-run. + +A second, defensive check applies per `(team, date)`: even for an eligible +team, a date is skipped if a `baseball_games` row already exists for that +exact team + date (e.g. a scheduled-but-not-yet-played game created via the +Games UI). The migration never risks minting a second, duplicate game row +next to one that already exists — that date is left for manual/live +handling. + +## Known limitations (by design — one-time script, not a product feature) + +- **Grouping key is `(team_id, session_date)` only** (no opponent in the key), + matching the `#827`/`scripts/seed-baseball-stats.mjs` precedent this + migration mirrors. A genuine double-header (two different-opponent games, + same team, same date) can't be told apart and collapses onto one game. +- **Duplicate legacy rows for the same player+team+date** (a data-entry dupe) + can only produce one box-score line — enforced by the table's own + `UNIQUE (game_id, player_id)` constraint, which has no concept of a player + appearing twice in "the same game." The winner is the legacy row with the + lexicographically-smallest `id` (via `ROW_NUMBER()`), so re-running the + migration always picks the same winner. +- **Pitching `hr` (home runs allowed)** has no legacy column and is always + `0` — a true, documented gap, not a fabricated stat. +- **`our_score` / `opponent_score` / lineup / `lob` / `batting_order`** have + no legacy source and are left `NULL` / `0` — honest empty state, not + invented data. + +## Idempotency + +Every synthesized id is **deterministic**: a SHA-1 hash of a namespaced key +(`baseball-legacy-backfill-379::<...>`), shaped into RFC4122-v5-style +bytes (version nibble forced to `0x5`, variant bits forced to `10xx`) — the +exact pattern `scripts/seed-baseball-stats.mjs`'s `detId()` uses (see its +header comment and `#827`). The namespace is deliberately different from the +seed script's own `baseball-stats-seed` namespace, so these ids can never +collide with the demo seeder's (or anything else's) ids. + +Every `INSERT` is `ON CONFLICT (...) DO NOTHING` keyed on that deterministic +id (games) or the table's natural unique key (`(game_id, player_id)` for +batting/pitching, `(player_id, team_id, season_year)` for the season seed). +Re-running the file is always a no-op the second time — verified empirically +(see "Verified" below): a second run against the same database inserted zero +new rows in any of the four tables. + +**Rollback no longer depends on recomputing these ids** — see "Rollback +story" below. The migration also writes a permanent, append-only manifest +table, `baseball_legacy_backfill_manifest`, recording every row it inserts +(games, batting rows, pitching rows, and season-stat triples) tagged with +`run_tag = 'baseball-legacy-backfill-379'`, in the SAME transaction as each +insert. That manifest — not the deterministic ids — is the authoritative +record of exactly what this run touched, and is what rollback joins against. + +## How the orchestrator applies it + +This file stays **written, not applied** until Nick says go. When he does: + +1. Run the **pre-check queries** below (also present as SQL comments at the + bottom of the migration file) via `mcp__supabase__execute_sql` and eyeball + the team list / row counts — confirm it's the expected set of dormant + legacy-only teams, not something surprising. +2. Run the **season-stats pre-flight query** above. If it returns any rows, + stop and get Nick's explicit call on those specific teams/players before + proceeding (see "Season-stats interaction" above) — do not treat an + empty migration diff as proof this step is unnecessary. +3. **Apply during a low-traffic window.** The migration takes an explicit + `LOCK TABLE ... IN SHARE ROW EXCLUSIVE MODE` on `baseball_player_stats`, + `baseball_games`, `baseball_box_score_batting`, `baseball_box_score_pitching`, + and `baseball_player_season_stats` before it snapshots eligibility, so that + a concurrent box-score/game save cannot land mid-run and invalidate the + snapshot. Ordinary reads (Stats Center, Roster, etc.) are unaffected — + only writes to those five tables briefly queue behind this migration's + transaction until it commits. +4. Apply the migration file verbatim via `mcp__supabase__apply_migration` + (file content unchanged from what's committed — this is a WRITE-ONLY repo + file until that point). +5. Run the **post-check queries** below to confirm row-count parity per team. +6. Spot-check one backfilled team's Stats Center page in the app to confirm + real numbers now render (previously empty). + +No code changes accompany this migration — nothing needs deploying alongside +it. It's pure data. + +### Pre-check query (preview affected teams) + +```sql +SELECT + ps.team_id, + COUNT(*) FILTER (WHERE ps.stat_type = 'game') AS legacy_game_rows, + COUNT(DISTINCT ps.session_date) FILTER (WHERE ps.stat_type = 'game') AS legacy_game_dates +FROM public.baseball_player_stats ps +WHERE ps.stat_type = 'game' + AND NOT EXISTS (SELECT 1 FROM public.baseball_box_score_batting bsb WHERE bsb.team_id = ps.team_id) + AND NOT EXISTS (SELECT 1 FROM public.baseball_box_score_pitching bsp WHERE bsp.team_id = ps.team_id) +GROUP BY ps.team_id +ORDER BY legacy_game_rows DESC; +``` + +### Post-check queries (row-count parity) + +```sql +-- Distinct (team, date) game-slots: legacy dates vs synthesized baseball_games +-- (identifiable via the notes tag). Counts should match unless the +-- "skip if a game already exists that date" guard fired for some dates. +WITH legacy_dates AS ( + SELECT team_id, COUNT(DISTINCT session_date) AS n + FROM public.baseball_player_stats + WHERE stat_type = 'game' + GROUP BY team_id +), +backfilled_games AS ( + SELECT team_id, COUNT(*) AS n + FROM public.baseball_games + WHERE notes LIKE 'Backfilled by #379 one-time legacy stats backfill%' + GROUP BY team_id +) +SELECT ld.team_id, ld.n AS legacy_game_dates, COALESCE(bg.n, 0) AS backfilled_games +FROM legacy_dates ld +LEFT JOIN backfilled_games bg ON bg.team_id = ld.team_id +ORDER BY ld.team_id; +``` + +```sql +-- Per-team row parity (swap in a real team id): +SELECT + (SELECT COUNT(*) FROM public.baseball_player_stats + WHERE team_id = '' AND stat_type = 'game') AS legacy_game_rows, + (SELECT COUNT(*) FROM public.baseball_box_score_batting bsb + JOIN public.baseball_games g ON g.id = bsb.game_id + WHERE bsb.team_id = '' + AND g.notes LIKE 'Backfilled by #379 one-time legacy stats backfill%') AS backfilled_batting_rows, + (SELECT COUNT(*) FROM public.baseball_box_score_pitching bsp + JOIN public.baseball_games g ON g.id = bsp.game_id + WHERE bsp.team_id = '' + AND g.notes LIKE 'Backfilled by #379 one-time legacy stats backfill%') AS backfilled_pitching_rows; +``` + +`backfilled_batting_rows` should equal `legacy_game_rows` unless duplicate +team+date+player legacy rows existed (see Known Limitations). +`backfilled_pitching_rows` will be `<= legacy_game_rows`: only rows with +`innings_pitched > 0` get a pitching line. + +## Rollback story + +Rollback is a pure delete, joined against the permanent +`baseball_legacy_backfill_manifest` table this migration writes to (see +"Idempotency" above) — it does **not** recompute anything. The migration +used to recompute the deterministic ids from whatever `baseball_player_stats` +happened to contain at rollback time; that is not safe, because legacy rows +can be edited or deleted between apply and rollback, which would recompute a +DIFFERENT candidate set than what this run actually wrote. The manifest is +an immutable, apply-time record — written in the SAME transaction as each +insert — of exactly which rows this run created, so rollback reads it +instead of re-deriving anything from current, possibly-changed state. + +Run this as one transaction: + +```sql +BEGIN; + +-- Eyeball this before deleting: counts by kind, should match the manifest +-- audit query at the bottom of the migration file. +SELECT row_kind, count(*) AS n +FROM public.baseball_legacy_backfill_manifest +WHERE run_tag = 'baseball-legacy-backfill-379' +GROUP BY row_kind +ORDER BY row_kind; + +-- Batting rows this run inserted — join by (game_id, player_id), the +-- manifest's recorded key for row_kind = 'batting_row'. +DELETE FROM public.baseball_box_score_batting bsb +USING public.baseball_legacy_backfill_manifest m +WHERE m.run_tag = 'baseball-legacy-backfill-379' + AND m.row_kind = 'batting_row' + AND bsb.game_id = m.game_id + AND bsb.player_id = m.player_id; + +-- Pitching rows this run inserted. +DELETE FROM public.baseball_box_score_pitching bsp +USING public.baseball_legacy_backfill_manifest m +WHERE m.run_tag = 'baseball-legacy-backfill-379' + AND m.row_kind = 'pitching_row' + AND bsp.game_id = m.game_id + AND bsp.player_id = m.player_id; + +-- Games this run synthesized. +DELETE FROM public.baseball_games g +USING public.baseball_legacy_backfill_manifest m +WHERE m.run_tag = 'baseball-legacy-backfill-379' + AND m.row_kind = 'game' + AND g.id = m.game_id; + +-- Review the row counts printed by the DELETEs above (should match the +-- audit query's counts for 'batting_row' / 'pitching_row' / 'game'), THEN: +COMMIT; +-- (or ROLLBACK; instead, to abort without changing anything) +``` + +`baseball_games`'s `game_id` foreign key on `baseball_box_score_batting` / +`_pitching` is `ON DELETE CASCADE`, so deleting only the `baseball_games` rows +would technically also remove the box-score rows — the explicit 3-statement +form above is preferred for an auditable, step-by-step rollback where each +`DELETE`'s row count is visible before committing, and where each `DELETE` +is independently scoped to its own manifest `row_kind` rather than relying on +cascade to clean up rows a bug might have mis-tagged. + +`baseball_player_stats` (the legacy source) is never touched by the forward +migration, so there is nothing to restore there on rollback. The manifest +table itself is **never deleted** by this rollback (or by the migration) — +it is permanent, append-only audit history, not a single-use ticket. + +### Season-stats rollback + +Step 4's seed is recorded in the manifest too (`row_kind = 'season_stat_triple'`), +so — unlike the old pre-flight-diff approach this replaces — there is no +"before" snapshot to have saved and no diff to compute: the manifest already +distinguishes a triple Step 4 inserted (present in the manifest) from a +pre-existing baseline Step 4's `ON CONFLICT DO NOTHING` left untouched (never +recorded, because nothing was actually inserted for it). + +```sql +BEGIN; + +DELETE FROM public.baseball_player_season_stats bpss +USING public.baseball_legacy_backfill_manifest m +WHERE m.run_tag = 'baseball-legacy-backfill-379' + AND m.row_kind = 'season_stat_triple' + AND bpss.player_id = m.player_id + AND bpss.team_id = m.team_id + AND bpss.season_year = m.season_year; + +COMMIT; +``` + +**Caveat the manifest does not erase — read before assuming this DELETE is a +clean undo:** by the time you run this, a season row Step 4 seeded may +already have been folded into by an ordinary, already-shipped box-score save +(see "Season-stats interaction" above). This DELETE is safe to run anyway, +specifically **because** of how `recalculate_baseball_season_stats()` is +written — verified directly against its body +(`supabase/migrations/20260624001000_baseball_official_stat_breadth.sql:109-265`): +every call does a fresh `SELECT SUM(...)` aggregation over **all** of that +player/team/year's currently-completed box-score games, then an unconditional +`INSERT ... ON CONFLICT (player_id, team_id, season_year) DO UPDATE SET +col = EXCLUDED.col` for every column. It is a from-scratch REBUILD every +time, never an incremental merge on top of whatever the row already held. So: + +- Deleting the row here does not "lose" anything the next ordinary save + can't reconstruct: once this rollback's box-score DELETEs above have + already removed this migration's synthesized rows, the next box-score save + for that player/team/year calls `recalculate_baseball_season_stats()` again, + which re-aggregates from whatever box-score rows remain (this migration's + are now gone) and does a full, correct overwrite — not a correction applied + on top of stale data. +- Until that next save happens, the row is simply absent (an honest empty + state), not silently wrong — which is why deleting it outright, rather than + trying to hand-patch it, is the conservative choice here. + +## Season-stats reconcile (only relevant for pre-existing baselines Step 4 left alone) + +For the rarer case flagged by the pre-flight query — a team where +`baseball_player_season_stats` already had a `season_totals`-imported row for +a touched player/year — Nick can force that row in sync with the +now-complete box-score data (this **is** the one action that overwrites +existing data, since it calls the live, already-shipped RPC directly): + +```sql +SELECT public.recalculate_baseball_season_stats( + ''::uuid, ''::uuid, ::int +); +``` + +Do this deliberately and per-team, only after confirming with Nick that the +box-score-derived total should win over whatever `season_totals` baseline is +there — remembering that, per "Season-stats interaction" above, an ordinary +game save for that player this season year will trigger the exact same +overwrite anyway, whether or not anyone runs this by hand. + +## Verified + +Before writing this runbook, the migration was exercised against a disposable +local Postgres 16 instance (schema mirrored from +`supabase/migrations/20260527000000_prod_public_baseline.sql` + +`20260624001000_baseball_official_stat_breadth.sql` + +`20260708011000`/`20260708022000`'s drift columns — never against any shared +Supabase project) with fixture data covering: + +- a normal single-sport batter, +- a two-way player (bats and pitches with a partial-innings `6.2` / + `4.1` IP notation), +- a duplicate same-player-same-date legacy row (dedupe correctness), +- a team that already has box-score data (must be fully excluded), +- a team with zero box-score data but a pre-existing scheduled + `baseball_games` row on the same date as a legacy row (that date must be + skipped). + +Results: avg/obp/slg/ops and era/whip/k9/bb9 matched hand-calculated values +(and the outs-based IP conversion) exactly; the already-box-score team was +untouched; the colliding date was correctly skipped; a second run of the +same file inserted zero additional rows anywhere. (This pass predates the +manifest-based rollback below — at the time, rollback was a deterministic-id +recompute-and-delete, which matched exactly the rows the migration had +created in a `ROLLBACK`ed dry run. That recompute strategy has since been +replaced; see "Rollback manifest, lock, and temp-table rename" below.) + +### Step 4 (season-stats seed) — re-verified after the post-review fix + +Re-exercised against a fresh disposable local Postgres 16 instance (schema +reconstructed directly from the real column/constraint lists in +`20260527000000_prod_public_baseline.sql` and +`20260624001000_baseball_official_stat_breadth.sql`, plus the real, +unmodified `recalculate_baseball_season_stats()` and +`save_baseball_full_box_score()` function bodies from this repo — never +against any shared Supabase project) with fixtures covering exactly the +scenario the review flagged: + +- a two-way player on an eligible team with **no** pre-existing + `baseball_player_season_stats` row for the touched season year, +- a second player on the **same** eligible team **with** a pre-existing + `season_totals`-imported baseline row for that year, +- a team that already has box-score data (must be fully excluded from + Step 4 too, not just Steps 1-3). + +Confirmed: +- Step 4 seeded the first player's season row with `g`/`ab`/`h`/`hr`/`avg`/ + `obp`/`slg`/`ops` and `ip`/`era`/`whip`/`k9`/`bb9` matching hand-calculated + values exactly, aggregated across both backfilled games. +- Step 4 left the second player's pre-existing baseline **completely + unchanged** (`DO NOTHING` fired; row was excluded from the `INSERT ... + RETURNING` count). +- The already-box-score team got zero season-stats rows from Step 4. +- Re-running the whole migration file a second time was still a no-op + everywhere, including Step 4. +- The pre-flight query above, run against the fixtures **before** applying, + correctly returned exactly the second player's at-risk row and nothing + else. +- **Reproduced the exact risk this section documents:** after applying, + calling the real, unmodified `save_baseball_full_box_score()` RPC for a + brand-new ordinary game dated in the same season year, with both players + in its box score, behaved exactly as written above — the first player's + seeded row extended cleanly (2 games → 3, numbers correct) with no + surprise, while the second player's pre-existing `season_totals` baseline + was silently overwritten by that already-shipped RPC, exactly as warned. + This was not a hypothetical for this test — it happened on the very next + ordinary save. +- The rollback story tested at the time (games/box-score delete + the + since-superseded season-stats diff-based delete) correctly removed only + the seeded row and left the pre-existing baseline intact. See below for + what changed and how the current manifest-based rollback was verified. + +### Rollback manifest, lock, and temp-table rename — verified by design review (post-review fix) + +This round replaced the deterministic-id-recompute rollback above with the +manifest-join rollback in "Rollback story," added the `LOCK TABLE` at the top +of the transaction, and renamed the two TEMP TABLEs to the required +`baseball_` prefix. These were verified as follows (design/code review, not a +fresh disposable-Postgres re-run — the underlying INSERT/aggregation logic +this touches is unchanged from the passes above): + +- **Manifest wiring**: each of the four `INSERT ... RETURNING` statements + (games, batting, pitching, season-stats) was checked column-by-column + against the manifest table's schema — the `RETURNING` list supplies exactly + the columns each row's `row_kind` needs (`game_id`+`team_id` for `'game'`; + `game_id`+`player_id`+`team_id` for `'batting_row'`/`'pitching_row'`; + `player_id`+`team_id`+`season_year` for `'season_stat_triple'`), and because + the manifest INSERT reads from the data INSERT's own `RETURNING` (not a + separate re-query), a conflict that makes the data INSERT a no-op also + makes the manifest INSERT a no-op — the idempotency guarantee is structural, + not a separate thing to keep in sync. +- **Lock self-conflict**: `SHARE ROW EXCLUSIVE MODE` conflicts with `ROW + EXCLUSIVE` (what a plain `INSERT` takes) from **other** sessions, but + Postgres never blocks a transaction on a lock it already holds itself — + a single transaction's lock requests against its own previously-acquired + locks always succeed immediately, regardless of nominal conflict mode. So + taking the stronger lock first, then running this migration's own + `INSERT`s in the same transaction, cannot self-deadlock or self-block. +- **"Recalc fully rebuilds it" claim**: verified directly against + `recalculate_baseball_season_stats()`'s actual body + (`supabase/migrations/20260624001000_baseball_official_stat_breadth.sql:109-265`) + — it declares fresh local variables, `SELECT SUM(...) INTO` them from a + from-scratch aggregation query scoped to `(player_id, team_id, + season_year)` over `baseball_box_score_batting`/`_pitching` joined to + `baseball_games`, then does one `INSERT ... ON CONFLICT (player_id, + team_id, season_year) DO UPDATE SET = EXCLUDED.`. + There is no read-modify-write against the row's own prior value anywhere in + it — every call is a full, from-scratch overwrite, confirming the + "Season-stats rollback" caveat above. +- **Temp-table rename**: verified by grepping the full migration file for the + old `_bb_legacy_backfill_379_teams`/`_bb_legacy_backfill_379_games` names + after the rename — zero remaining references; all 8 occurrences (2×`DROP + TABLE IF EXISTS`, 2×`CREATE TEMP TABLE`, 2×`INSERT INTO`, plus the `JOIN` + references in Steps 1-4) now use the `baseball_` prefix. diff --git a/e2e/baseball-stats-smoke.spec.ts b/e2e/baseball-stats-smoke.spec.ts index d1908ff01..0b1d3562f 100644 --- a/e2e/baseball-stats-smoke.spec.ts +++ b/e2e/baseball-stats-smoke.spec.ts @@ -188,16 +188,23 @@ test.describe('BaseballHelm seeded smoke — coach surfaces', () => { await expect(page.getByText('FINAL')).toBeVisible(); }); - test('Upload route renders the CSV upload surface (college-coach guard passed)', async ({ page }) => { + // Wizard consolidation: the legacy /stats/upload wizard is now a redirect + // shim INTO Import Center (the canonical wizard) — see + // src/app/baseball/(dashboard)/dashboard/stats/upload/page.tsx. This test + // used to assert the retired StatsUploadClient surface directly; it now + // asserts the redirect lands the coach on Import Center's "Quick box score" + // entry point instead, so the college-coach guard + destination stay + // covered without pinning a UI that no longer exists. + test('Upload route redirects into Import Center (college-coach guard passed)', async ({ page }) => { const ok = await tryLogin(page, TEST_USERS.coach); test.skip(!ok, 'coach login fixture unavailable in this environment'); await page.goto('/baseball/dashboard/stats/upload'); await waitForPageLoad(page); - await expect(page.getByRole('heading', { name: 'Upload Stats' })).toBeVisible({ timeout: 10000 }); - await expect(page.getByRole('heading', { name: 'Upload CSV File' })).toBeVisible(); - await expect(page.getByText('Choose File')).toBeVisible(); + await expect(page).toHaveURL(/\/baseball\/dashboard\/import$/); + await expect(page.getByRole('heading', { name: 'Import Center' })).toBeVisible({ timeout: 10000 }); + await expect(page.getByText('Quick box score')).toBeVisible(); }); }); diff --git a/e2e/visual-audit.spec.ts b/e2e/visual-audit.spec.ts new file mode 100644 index 000000000..240a5d696 --- /dev/null +++ b/e2e/visual-audit.spec.ts @@ -0,0 +1,385 @@ +/** + * e2e/visual-audit.spec.ts — production visual-audit screenshot crawl. + * + * Runs under the same `baseball-coach` / `baseball-player` Playwright + * projects (see playwright.config.ts) that e2e/baseball-route-crawler.spec.ts + * uses — this is NOT a new auth mechanism. It reuses that spec's proven + * discovery pattern (visible `