A Next.js app for recording pool matches, computing Glicko ratings, and tracking streaks with Supabase auth and storage. Includes player profiles, leaderboards, pending game verification, and web push notifications.
- Record 8-ball, 2v2 8-ball, and 9-ball matches
- Separate Glicko ratings for 8-ball and 9-ball, plus streaks and rating history charts
- Leaderboard and player profile pages
- Pending game verification flow (opponent or admin)
- Optional push notifications for verification requests
- Nightly backfill endpoint for ratings
- Next.js App Router (React 19)
- Supabase (auth + Postgres)
- Prisma schema for Supabase
- Tailwind CSS
- Framer Motion
- Playwright (config only)
/Home: stats, streaks, recent games, pending verification/addAdd a match result/leaderboardGlobal ratings/profile/[username]Player profile and history/adminAdmin verification dashboard
POST /api/games/verifyVerify or reject a pending gamePOST /api/notifySend a push notificationGET /api/cron/backfillRecompute ratings (secured by cron secret)
Core tables in public schema:
gamesMatch recordsprofilesUser profiles + ratingsconfigFeature flags (ex:require_verification)push_subscriptionsWeb push subscriptions
Create a .env.local file with:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
NEXT_PUBLIC_VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
CRON_SECRET=
Optional:
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY(fallback for anon key)
npm install
npm run dev
Open http://localhost:3000.
Playwright is configured, but no tests are included by default.
npm run test:e2e
Seed local data (requires Supabase connection and local tooling):
npm run db:seed:local
- Ratings are only computed from
verifiedgames. - Admin verification requires
profiles.role = ADMIN. - Push notifications require valid VAPID keys.
app/Next.js routes and API handlerscomponents/UI and feature componentslib/domain logic (glicko, supabase, push, types)prisma/Supabase Prisma schemapublic/service worker + assetsscripts/maintenance scripts