Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d2aa1a5
fix(security): W0 — P0/P1 privacy, auth, and correctness wave
Jul 9, 2026
ffd0fd8
feat(golf): W1 — Fairway unconditional, legacy dual-tree deleted (gol…
Jul 9, 2026
84048a3
feat(baseball): W3+W4 — player nav to 8 tabs, Living Annual completion
Jul 9, 2026
5f49490
feat(golf): W2 — nav consolidated to 8 coach hubs / 8 player tabs
Jul 9, 2026
6866580
feat(baseball): W5 — Lift Lab chrome, a11y P1s, dead-code + manifest …
Jul 9, 2026
0a13f50
feat(golf+admin): W6+W9 — green ruled leaders, join-page fixes, admin…
Jul 9, 2026
3ebc803
Merge branch 'wave/w5-lift-a11y-deadcode' into integration/mission-ve…
Jul 9, 2026
c9935b6
fix(verify): Phase D round 1 — 19 adversarially-confirmed findings fixed
Jul 9, 2026
fbcac24
fix(verify): Phase D round 2 — 6 confirmed findings + follow-ups
Jul 9, 2026
2019db3
docs(matrix): W7 — truthful re-grade of all 22 readiness rows against…
Jul 9, 2026
afa2bfa
fix(verify): Phase D round 3 — final residue (glass in join/public/st…
Jul 9, 2026
70aa5da
fix: surface Signal Inbox mutation failures; unflash program-profile …
Jul 9, 2026
2f0eb19
fix: surface silent server-action failures across 7 mutation surfaces…
Jul 9, 2026
11180c5
feat: defect-sweep fixes + full taste-polish wave (Phase D mega-wave)
Jul 9, 2026
8f82063
fix: round-6 verification repairs — 26 confirmed findings across the …
Jul 10, 2026
c886c29
feat: tree-wide ink conversion + golf token sweep + Escape-bug class …
Jul 10, 2026
03e1aa8
docs: mission doc — Phase D final ledger + Phase E state (supersedes …
Jul 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 5 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,9 @@ RLS_DIAGNOSTIC_TEST_PASSWORD=
# RINI_DEMO_FILLER_PASSWORD=

# -----------------------------------------------------------------------------
# Fairway redesign feature flag
# Fairway redesign feature flag (REMOVED — Wave W1, 2026-07-09)
# -----------------------------------------------------------------------------
# Gates the "Fairway" warm-premium design system (see ui-intelligence/
# DESIGN-SYSTEM.md). Default OFF — the current app is 100% unchanged; only
# redesigned components that opt in via src/lib/redesign/flag.ts + the
# `.fairway-ds` scope consume the new tokens/fonts. Accepts 1/true/on/yes.
# NEXT_PUBLIC_REDESIGN=false
# NEXT_PUBLIC_REDESIGN used to gate the "Fairway" warm-premium design system
# (see ui-intelligence/DESIGN-SYSTEM.md). Fairway is now the only dashboard
# tree — src/lib/redesign/flag.ts's isRedesignEnabled()/useRedesign() are
# hardcoded true — so this env var no longer has any effect. No action needed.
1 change: 0 additions & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ permissions:
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL || 'https://dummy-ci-build.supabase.co' }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY || 'dummy-anon-key-ci-build-only' }}
NEXT_PUBLIC_REDESIGN: "true"
E2E_GOLF_EMAIL: ${{ secrets.E2E_GOLF_EMAIL }}
E2E_GOLF_PASSWORD: ${{ secrets.E2E_GOLF_PASSWORD }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/pr-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ permissions:
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL || 'https://dummy-ci-build.supabase.co' }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY || 'dummy-anon-key-ci-build-only' }}
NEXT_PUBLIC_REDESIGN: "true"
NODE_OPTIONS: --max-old-space-size=4096

jobs:
Expand Down
6 changes: 3 additions & 3 deletions docs/audits/PRODUCTION_READINESS_MISSION_2026-07-09.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
**Nav counts today** (primary+secondary rail destinations, Settings footer excluded):
| Surface | Today | Target |
|---|---|---|
| Baseball coach | **8 hubs** ✅ (Dashboard, Messages, Team, Stats & Performance, Development, Recruiting, Academics, Management) | keep |
| Baseball coach | **8 hubs** ✅ (8 standard: Dashboard, Messages, Team, Stats & Performance, Development, Recruiting, Academics, Management; 7 for High School — Recruiting hidden by design, `RECRUITING_PROGRAM_TYPES`; showcase variant has its own two-level org→team rail) | keep |
| Baseball player | **9** (7 primary + exposureNoun + Settings-in-rail) | **8** — move Settings to pinned footer (parity with coach shell) |
| Golf coach (Fairway, live) | **15** (7 primary + 8 secondary) | **8 hubs** |
| Golf player (Fairway, live) | **12** (8 primary + 4 secondary) | **8** |
Expand Down Expand Up @@ -101,7 +101,7 @@ policies on hot golf tables, 199 unindexed FKs, 256 unused indexes).

## Target IA (~8 tabs, owner directive)

### Baseball coach — unchanged (8 hubs) ✅
### Baseball coach — unchanged (8 hubs: 8 standard; 7 for HS — Recruiting hidden by design; showcase variant has its own two-level rail) ✅
### Baseball player — 8 (move Settings out of rail to pinned footer)
Today · Schedule · My Profile · Stats · Development · Team · Messages · [exposureNoun]

Expand All @@ -114,7 +114,7 @@ Today · Schedule · My Profile · Stats · Development · Team · Messages · [
6. **Messages** (Messages · Announcements)
7. **Operations** (Tasks · Documents)
8. **Courses**
Footer: Settings · Sign out. Mobile bottom bar: Home, CoachHelm, Roster, Calendar, Messages (unchanged).
Footer: Settings · Sign out. Mobile bottom bar: Home, CoachHelm, Team, Calendar, Messages (code renders label "Team", opening the Team hub — not "Roster"; unchanged from live behavior).

### Golf player — 8
1. **Dashboard** (merge Hub into Dashboard landing — two "homes" is duplicative)
Expand Down
16 changes: 13 additions & 3 deletions docs/baseball/ui-migration-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@
kit so the product reads as a single publication. No surface keeps a bespoke card, header,
empty state, or stat display once the kit covers it. Consistency is the deliverable.

Delivery mechanism = the existing **Fairway redesign layer** (`NEXT_PUBLIC_REDESIGN`,
`.fairway-ds` scope, `--fw-*` tokens). The Living-Annual kit is the **baseball-native
vocabulary layered on top of the Fairway tokens** — not a second design system.
Delivery mechanism = the existing **Fairway redesign layer** (`.fairway-ds` scope,
`--fw-*` tokens — unconditional, no flag). The Living-Annual kit is the
**baseball-native vocabulary layered on top of the Fairway tokens** — not a second
design system.

> **Update (2026-07-09, golf Wave W1):** `NEXT_PUBLIC_REDESIGN` no longer gates
> anything — `isRedesignEnabled()`/`useRedesign()` in `src/lib/redesign/flag.ts`
> are hardcoded `true` (the legacy `GolfDashboardShell`/`GolfSidebar` fork they
> used to gate was deleted). Setting the env var has zero effect. Baseball's
> `BaseballFairwayShell` renders unconditionally and was never flag-gated the
> way golf's dual tree was; `src/components/layout/header.tsx` still calls
> `isRedesignEnabled()` (always `true`) to suppress its own legacy chrome, but
> that is a hardcoded return, not env-driven behavior.

---

Expand Down
6 changes: 2 additions & 4 deletions e2e/course-library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,8 @@ test.describe('Cloud Course Library — authenticated flow', () => {
});

// Capture screenshots of the premium course picker for review as CI artifacts
// (uploaded by .github/workflows/playwright.yml). Requires
// NEXT_PUBLIC_REDESIGN=true so the redesign FairwayCoursePicker renders
// (otherwise this shoots the legacy TeePickerDrawer). Best-effort — the point
// is the image, not a gate; a missing affordance skips rather than fails.
// (uploaded by .github/workflows/playwright.yml). Best-effort — the point is
// the image, not a gate; a missing affordance skips rather than fails.
test('capture: premium course picker screenshots', async ({ page }) => {
const dir = 'e2e-screenshots';

Expand Down
99 changes: 60 additions & 39 deletions memory/context/golfhelm-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
3. Qualifiers ✅

**Team Management Features:**
4. Calendar & Events
4. Calendar & Events ⚠️
5. Roster Management ✅
6. Task Management ⚠️
7. Messaging ✅
Expand All @@ -43,7 +43,7 @@
18. Coaching Intelligence Settings ✅

**Player-Facing Features:**
19. Player Hub (Home) ✅
19. Player Hub (merged into Dashboard Action Center, 2026-07-09) ✅
20. Player CoachHelm Dashboard ✅
21. My Development ✅
22. My Qualifiers ✅
Expand Down Expand Up @@ -220,10 +220,10 @@ golf_qualifiers, golf_qualifier_entries

---

## 4. CALENDAR & EVENTS
## 4. CALENDAR & EVENTS ⚠️

### What It Does
Full event management with RSVP, attendance tracking, recurring events, availability polling, iCal feeds, and academic conflict detection.
Full event management with RSVP, attendance tracking, recurring events, iCal feeds, and academic conflict detection. (Availability polling is NOT built — see Sub-Features below.)

### Data Flow
```
Expand All @@ -246,7 +246,7 @@ Calendar views: MonthView, WeekView, DayView, MobileListView
### Sub-Features

**Recurring Events** ✅ — RRULE parsing, edit scopes: this | thisAndFuture | all
**Availability Polling** Coach creates polls, players vote, convert to event
**Availability Polling** NOT BUILT (backlog). No `availability-polling.ts`/`availability-locking.ts` or any poll UI exists in code; `golf_availability_polls`/`golf_poll_responses` are orphaned schema only (verified 2026-07-09, zero references in `src/`).
**iCal Feeds** ✅ — Token auth, RFC 5545 compliant, rate limited
**Event Status Lifecycle** ✅ — draft → confirmed → completed | cancelled
**Academic Conflict Detection** ✅ — Checks classes, blocked time, exclusions
Expand All @@ -258,7 +258,7 @@ Calendar views: MonthView, WeekView, DayView, MobileListView
| Wrapper | `src/components/golf/calendar/GolfCalendarWrapper.tsx` |
| Views | `MonthView.tsx`, `WeekView.tsx`, `DayView.tsx`, `MobileCalendarWrapper.tsx` |
| Actions | `event-lifecycle.ts`, `recurring-events.ts`, `attendance.ts` |
| Polling | `availability-polling.ts`, `availability-locking.ts` |
| Polling | _not built — no files exist (backlog)_ |
| Feeds | `calendar-feeds.ts`, `calendar-sync.ts`, `caldav-sync.ts` |
| Conflicts | `src/lib/calendar/conflicts.ts`, `src/lib/calendar/ical.ts` |

Expand Down Expand Up @@ -433,7 +433,7 @@ createTravelItinerary()
→ INSERT golf_travel_itineraries (transport, hotel, flight, gear list, room assignments)
→ Links to golf_events via event_id

Player view (via Player Hub):
Player view (via the Dashboard's Action Center, formerly the standalone Player Hub — see Feature 19):
→ Trip cards with destination, transport type, dates
→ Hotel info (name, address, phone, confirmation #)
→ Packing list, room assignments, uniform requirements
Expand Down Expand Up @@ -796,49 +796,70 @@ golf_coach_philosophy (all philosophy columns)

## 19. PLAYER HUB (HOME) ✅

> **2026-07-09 — merged into the Dashboard.** The standalone "Hub" front door
> described below no longer exists as its own destination. Wave W2 nav
> consolidation (Target IA, `PRODUCTION_READINESS_MISSION_2026-07-09.md`)
> folded its triage content into the Player Dashboard as an "Action Center"
> section, one home instead of two. `/golf/dashboard/hub` is now a permanent
> server-redirect to `/golf/dashboard` (old links/bookmarks still land
> somewhere real). Full create/edit/manage surfaces for tasks and travel —
> the Hub was always read-mostly for those — remain in the **Team Hub**
> (`/golf/dashboard/team-hub`, tasks + travel tabs); full RSVP/scheduling
> remains in Calendar. `PlayerHub.tsx` / `PlayerHubWrapper.tsx` were deleted
> in Wave W1 (golf legacy-tree deletion); this section documents the current
> Action Center surface that replaced them.

### What It Does
Personal action center for players. Central dashboard showing upcoming travel, assigned tasks, and event invitations with inline RSVP.
A "needs you now" triage section on the player's Dashboard: top pending
tasks, events awaiting RSVP, recent announcements, and upcoming trips —
plus the player's top CoachHelm signal. Renders only the first few items of
each (3 tasks, 3 events, 2 trips) with a link out to the Team Hub / Calendar
for the full list; renders nothing at all when there's genuinely nothing to
triage (honest-empty, not a placeholder).

### Data Flow
```
/golf/dashboard/hub → PlayerHubWrapper → PlayerHub
Section 1: TRAVEL
→ Query golf_travel_itineraries WHERE team_id = player's team
→ Display: destination, transport type (✈🚌🚐🚗), dates, hotel, packing list
→ Status: upcoming, in transit, completed, days away

Section 2: TASKS
→ Query golf_tasks + golf_task_assignments WHERE player_id
→ Display: title, due date, category, upload requirement
→ ⚠️ DUAL TABLE BUG: Hub page READS from golf_task_completions, but
completeTask() action WRITES to golf_task_assignments (status + completed_at)
These two tables can get out of sync.
→ Status: pending, overdue, completed (color-coded)

Section 3: EVENTS
→ Query golf_events WHERE team_id, start_time >= now - 24h
→ Query golf_event_attendance for RSVP status
→ Display: event name, type badge, time, location, mandatory flag, going/maybe counts
→ Action: respondToEvent(eventId, status) → UPSERT golf_event_attendance
→ RSVP buttons: Accept | Decline | Maybe
/golf/dashboard → page.tsx (Dashboard route)
→ getPlayerHubSummaryData(teamId, playerId) [player-hub-data.ts]
→ golf_travel_itineraries WHERE team_id, departure_date >= now-120d
→ golf_task_assignments WHERE player_id (status, completed_at)
joined to golf_tasks for title/description/due_date/category
(same table completeTask() writes to — no dual-table read/write
mismatch in this data path)
→ RPC get_player_hub_events(team_id, player_id, since) → golf_events +
golf_event_attendance (RSVP status, going/maybe counts)
→ getPlayerHubAnnouncements() → RPC get_player_hub_announcements()
→ getTopInsightForPlayer() → top evidence-backed CoachHelm insight
→ passed as the `actionCenter` prop into FairwayPlayerDashboard
→ <PlayerActionCenter> renders:
Tasks (top 3, "Open Team Hub" → team-hub?tab=tasks)
Awaiting RSVP (top 3, "View calendar" → /golf/dashboard/calendar)
Action: respondToEvent(eventId, status) → UPSERT golf_event_attendance
Announcements (AnnouncementsList)
Upcoming trips (top 2, "Open Team Hub" → team-hub?tab=travel)
Action: completeTask(taskId) → golf_task_assignments (optimistic)

/golf/dashboard/hub → PlayerHubRedirectPage → redirect('/golf/dashboard')
```

### Key Files
| Type | Path |
|------|------|
| Route | `src/app/golf/(dashboard)/dashboard/hub/page.tsx` |
| Components | `src/components/golf/player-hub/PlayerHub.tsx` (40KB), `PlayerHubWrapper.tsx` |
| Route (Dashboard, fetches the data) | `src/app/golf/(dashboard)/dashboard/page.tsx` |
| Redirect (former Hub route) | `src/app/golf/(dashboard)/dashboard/hub/page.tsx` |
| Data | `src/app/golf/actions/player-hub-data.ts` (`getPlayerHubSummaryData`) |
| Component | `src/components/fairway/pages/dashboard/PlayerActionCenter.tsx` |
| Host component | `src/components/fairway/pages/dashboard/FairwayPlayerDashboard.tsx` |
| Shared presentational parts | `src/components/fairway/pages/hub/hub-parts.tsx` (TaskRow, RSVPRow, TripRow, TripDetailSheet, AnnouncementsList) |
| Management surface | `src/app/golf/(dashboard)/dashboard/team-hub/**` (full tasks/travel CRUD) |

### DB Tables
golf_travel_itineraries, golf_tasks, golf_task_assignments, golf_task_completions (⚠️ read here but writes go to golf_task_assignments), golf_events, golf_event_attendance

### Known Gaps
| Gap | Severity | Details |
|-----|----------|---------|
| Task completion dual-table bug | **High** | Hub page reads `golf_task_completions` for completion status, but `completeTask()` action writes to `golf_task_assignments`. Tasks may appear incomplete in the Hub even after completion. |
golf_travel_itineraries, golf_tasks, golf_task_assignments, golf_events, golf_event_attendance, golf_announcements (via RPC)

### Dependencies
- **Depends on**: Travel, Tasks, Calendar & Events
- **Feeds into**: nothing feeds off it directly — it is a read-mostly triage
view over Team Hub / Calendar data

---

Expand Down Expand Up @@ -1278,7 +1299,7 @@ Reads from ALL major tables: users, golf_coaches, golf_players, golf_teams, golf
| 1 | Round Tracking | Both | ✅ | 95% | Auto-save | Offline shots, SG calc |
| 2 | Stats & Analytics | Both | ✅ | 90% | — | SG not populated |
| 3 | Qualifiers | Both | ✅ | 100% | ✅ | — |
| 4 | Calendar & Events | Both | | 100% | — | |
| 4 | Calendar & Events | Both | ⚠️ | 90% | — | Availability Polling not built (backlog) |
| 5 | Roster Management | Both | ✅ | 100% | — | — |
| 6 | Task Management | Both | ⚠️ | 85% | ✅ | Reminder auto-trigger |
| 7 | Messaging | Both | ✅ | 100% | ✅ | — |
Expand All @@ -1293,7 +1314,7 @@ Reads from ALL major tables: users, golf_coaches, golf_players, golf_teams, golf
| 16 | Intelligence Dashboard | Coach | ✅ | 90% | — | — |
| 17 | CoachHelm Analytics | Coach | ⚠️ | 70% | — | Effectiveness data sparse |
| 18 | Coaching Intel Settings | Coach | ✅ | 100% | — | — |
| 19 | Player Hub (Home) | Player | ✅ | 100% | — | |
| 19 | Player Hub (merged into Dashboard Action Center) | Player | ✅ | 100% | — | Standalone Hub route now redirects; management in Team Hub |
| 20 | Player CoachHelm | Player | ✅ | 95% | — | — |
| 21 | My Development | Player | ✅ | 100% | — | — |
| 22 | My Qualifiers | Player | ✅ | 100% | — | — |
Expand All @@ -1309,7 +1330,7 @@ Reads from ALL major tables: users, golf_coaches, golf_players, golf_teams, golf
## PRIORITY GAPS (by business impact)

### High Priority
1. **Player Hub task completion bug**Hub reads `golf_task_completions` but `completeTask()` writes to `golf_task_assignments`. Tasks show as incomplete in Hub after completion. Needs unified to one table.
1. ~~Player Hub task completion bug~~**RESOLVED / stale.** `golf_task_completions` does not exist in the live schema; the current Action Center data layer (`player-hub-data.ts`, post-2026-07-09 Hub→Dashboard merge) reads `golf_task_assignments`, the same table `completeTask()` writes to. No dual-table mismatch in this path.
2. **CoachHelm effectiveness tracking** — DB ready, needs server actions + UI. Without this, coaches can't measure if AI insights are working.
3. **CoachHelm outcome measurement** — No way to close the feedback loop (mark insights as improved/no_change/worsened).
4. **Strokes Gained calculation** — Framework exists, data exists (shots table), but SG columns in stats cache are null. This is the most important golf statistic.
Expand Down
8 changes: 4 additions & 4 deletions memory/registry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ features:
- src/components/golf/coachhelm/v3/IntentPill/**
- src/components/golf/coachhelm/v3/IntentDrawer/**
- src/components/golf/coachhelm/v3/StandingBar/**
- src/components/golf/coachhelm/v3/CounterfactualLine.tsx
- src/app/golf/(dashboard)/dashboard/my-standing/page.tsx
- src/components/golf/coachhelm/v3/HeroNarrativeCard.tsx
api:
- src/app/api/coachhelm/v3/**
Expand Down Expand Up @@ -720,7 +720,7 @@ features:
- src/app/golf/(dashboard)/dashboard/team/**
components:
- src/components/golf/roster/**
- src/components/golf/dashboard/team-pulse-card.tsx
- src/components/fairway/pages/dashboard/FairwayCoachDashboard.tsx
api:
- src/app/api/roster/**
- src/app/api/team/**
Expand All @@ -736,7 +736,7 @@ features:
- supabase/migrations/*coach_staff*.sql
tests:
- e2e/roster.spec.ts
- src/components/golf/dashboard/__tests__/team-pulse-card.test.tsx
- src/app/golf/actions/__tests__/dashboard-data.test.ts
integrations:
- supabase
- team_access_control
Expand Down Expand Up @@ -938,7 +938,7 @@ features:
- supabase/migrations/*task*.sql
- supabase/migrations/*event*.sql
tests:
- src/components/golf/dashboard/__tests__/team-pulse-card.test.tsx
- src/lib/golf/nav-registry.test.ts
integrations:
- team_operations
- calendar
Expand Down
Loading
Loading