Tennis League
Workplace tennis league scoring, scheduling, and standings.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A daily tennis roll game inspired by RNGdle. Roll a random season (1990–2026) and a random year-end top-100 player from it. Their real stats earn badges, and the badges add up to your score: around 50k for a typical roll, and up to ~100 million for an all-time great season.
See SPEC.md for the product and technical spec, and docs/balance-report.md for the current score distribution.
npm install
npm run dev # http://localhost:3000 (daily roll) and /sandbox (unlimited)
npm test # unit + data regression tests
npm run balance # regenerate docs/balance-report.md after badge changes
The built season data (data/seasons/) is committed, so the app runs without
the raw CSVs. To rebuild it from source:
npm run data:fetch # sparse clone of the source CSVs into data/raw/, plus the live season
npm run data:build # writes data/seasons/*.json
The 2026 season is live: a GitHub Actions workflow
(.github/workflows/refresh-data.yml) runs those two commands every day and
commits the result, and the push redeploys the app. See "Live season" in
SPEC.md for how the sources are merged.
The daily roll, guests and sign-in need a Supabase project. /sandbox works
without one.
.env.example to .env.local and fill in the project URL and keys.supabase/migrations/, oldest file first. Either paste
each file into the dashboard's SQL Editor and run it, or use the CLI (stick
to one of the two, since the CLI keeps its own record of applied migrations):
npx supabase db push --db-url "$SUPABASE_DB_URL"
npm run data:build):
npm run db:seed
http://localhost:3000/auth/callback (and the production
https://<domain>/auth/callback) to the redirect URLs.Production branch. Vercel deploys the repository's default branch, and
GitHub only runs scheduled workflows there. Make the branch with the latest
code the default (or merge it into main and make that the default).
Import the project. In Vercel, go to Add New → Project and import the repository. The framework (Next.js) is detected automatically. Add these environment variables for Production and Preview:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYSUPABASE_SERVICE_ROLE_KEY (the sb_secret_… key)NEXT_PUBLIC_SITE_URL (optional): your custom domain, for link previewsThen deploy.
Supabase URLs. In Authentication → URL Configuration, set the Site URL
to the production URL and add https://<domain>/auth/callback to the
redirect URLs. Add https://*-<team>.vercel.app/auth/callback too if you
want sign-in on preview deployments.
Guest cleanup. Apply supabase/migrations/20261025000000_guest_cleanup.sql
if you haven't already. Integrations → Cron should then list
acedle-delete-stale-guests.
Daily refresh. On GitHub, under Settings → Secrets and variables →
Actions, add NEXT_PUBLIC_SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY so the
workflow can reseed Supabase. These are optional: rolls add missing players
by themselves. Then run "Refresh live data" once from the Actions tab.
ATP match and ranking data was collected and compiled by Jeff Sackmann
(originally github.com/JeffSackmann/tennis_atp, now preserved at
Aneeshers/tennis-sackmann-archive).
It's licensed under CC BY-NC-SA 4.0,
and so is the derived data in data/seasons/. The live 2026 season adds
results from Tennis My Life
and the current ranking list from Tennis Abstract.
Acedle is a non-commercial fan project and isn't affiliated with the ATP Tour.
The link preview images (opengraph-image.tsx files, styled in src/lib/og.tsx)
use Alfa Slab One and Courier Prime from assets/fonts/, under the SIL Open
Font License (assets/fonts/OFL-*.txt).
Player photos come from Wikimedia Commons
(npm run data:photos, also run monthly by .github/workflows/photos.yml);
each card credits its photo's author and license. Players without one get
illustrated art in their country's colors. Signed-in players can suggest a
Commons photo for any card (/photos/suggest/<player>/<year>); suggestions
wait in /admin/photos until an admin approves them. Admins are the user ids
in the admins table (insert into public.admins (user_id) values ('…')).