Skip to content

fix: pilot-readiness audit fixes, demo mode removed - #78

Open
brianle423 wants to merge 1 commit into
mainfrom
fix/2026-09-09-pilot-readiness
Open

fix: pilot-readiness audit fixes, demo mode removed#78
brianle423 wants to merge 1 commit into
mainfrom
fix/2026-09-09-pilot-readiness

Conversation

@brianle423

Copy link
Copy Markdown
Collaborator

Summary

Closes every P0 and P1 from the 2026-09-09 pilot-readiness audit (record: JarvisEA/projects/CourtCheck/2026-09-09-pilot-readiness-audit.md). Implemented by Codex (gpt-6-astra, xhigh) from a 38-step plan; reviewed, patched, and verified by Claude against a local production build and live production data.

Coach-visible

  • Report totals are measured only: In bounds (percent, n of total), Rallies, Avg rally length, Longest rally. The invented Winners / Unforced errors formulas are gone.
  • Timed notes save and read back. Two bugs: the poll effect cleanup cancelled the debounce, and three live rows hold notes as JSON strings, which the API now parses.
  • Upload rejects wrong files, oversize files, and recordings over 15 minutes with a visible sentence.
  • Recording header names its player (linked) or says Unassigned; failed recordings can reach Reprocess.
  • Demo mode removed entirely (toggle, fixtures, sample diagrams, sample-analysis link).
  • Login shows auth-link errors; password recovery can reach the update form; phone nav has an Account tab; error boundary, not-found, and error routes; per-route page titles; "Recording date" and "Serve/Overhead" labels.

API / security

  • trigger-process ignores client file_key and derives it from the owned row; dispatch failures mark the recording failed instead of stranding it in processing.
  • create-upload checks player_id ownership and the insert result before handing out an upload URL.
  • Player name/handedness lookups are owner-filtered; schema fallbacks keep the owner predicate.
  • Anonymous /api/* gets JSON 401 from the proxy; redirects keep refreshed cookies.
  • PATCH /api/recordings/[id] returns 404 when nothing was updated; notes/keypoints validated and capped.
  • Onboarding POST is replay-safe (409 once a roster exists).
  • Image proxy limit 120 → 1200/hour and its responses may cache (a 9-player roster exhausted 120 in minutes).

Backend (needs modal deploy backend/app.py)

  • process_video validates match_id is a UUID and file_key starts with <match_id>/, and writes a failed status if startup throws.
  • A lost processed-video upload fails the recording instead of marking it done with no video.

Data

  • backend/tools/claim_template_players.py (dry-run default) already applied for the owner account: 9 owned player rows, 1 recording remapped, onboarding_template set. Handedness PATCH now returns 200 on production.
  • supabase/migrations/20260910_players_cascade_on_user_delete.sql: apply in the Supabase SQL editor.

Audit harness at frontend/web/scripts/audit/functional/ (84 checks; --skip-upload, --only, --qa-recording).

Test plan

  • tsc, next build (24 routes), verify-dashboard-metrics.cjs, verify-viz-data.cjs, py_compile on the four Python files
  • Harness against a local production build with the live database: tile format, notes save/readback, player name in header, handedness save, upload rejection copy, 401 contract, demo removal all pass
  • Production probe after the data repair: 9 owned players, fixture recording remapped, PATCH handedness 200
  • After merge: CC_AUDIT_BASE=https://courtcheck-rho.vercel.app node scripts/audit/functional/run.mjs --skip-upload from frontend/web
  • After merge: one real upload end to end (drop --skip-upload), then modal deploy backend/app.py if not already done
  • Apply the cascade migration in the SQL editor

Frontend: measured report totals (no invented Winners/Unforced errors), timed notes that
persist (debounce no longer cancelled by the poll effect; jsonb strings parsed on read),
visible upload rejections, JSON 401 for anonymous API calls, login shows callback errors,
password recovery reaches the update form, recording header names its player, error
boundary + not-found + error routes, per-route titles, mobile Account tab, demo mode
removed entirely.

API: trigger-process derives the storage key server-side; create-upload validates player
ownership and insert errors; owner-filtered player lookups and fail-closed fallbacks;
PATCH returns 404 on zero rows; onboarding is replay-safe; image proxy limit raised to
1200/h and its responses may cache.

Backend: Modal entrypoint validates match_id/file_key binding and writes a failed status
when startup fails; a lost processed-video upload no longer marks a recording done.

Data: backend/tools/claim_template_players.py (applied for the owner account) and a
cascade migration for players.user_id (apply in the SQL editor).

Audit harness: frontend/web/scripts/audit/functional (84 checks, resume and skip-upload flags).
@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
courtcheck Ready Ready Preview Sep 10, 2026 7:07am UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant