NBA Feed
팀 뉴스와 경기 정보를 제공, 점수는 직접 확인할 때까지 숨겨져 있습니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기PWA for competitive frisbee
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
StallCount is a web application for managing league and tournament operations. It provides public event information alongside authenticated tools for scorekeeping, roster management, notifications, playoff configuration, and administrative workflows.README 전문 보기 ↗StallCount is a web application for managing league and tournament operations. It provides public event information alongside authenticated tools for scorekeeping, roster management, notifications, playoff configuration, and administrative workflows.
The frontend is built as a single-page application using React 18, Vite, and React Router. Data access, authentication, and core operational workflows are backed by Supabase, with shared client and domain logic organised through the service layer in src/services/. The application is also configured as a progressive web app using vite-plugin-pwa, enabling installation on supported devices, asset caching, and improved resilience for live scoring workflows.
Production builds are generated with npm run build and deployed on Vercel, with single-page application rewrites configured in vercel.json. The repository also includes a Vercel API route at api/stb-rl-26-roster-sync.js that runs the Stellenbosch RL 2026 roster import automatically once per day at 17:00 SAST (15:00 UTC) on a Vercel cron schedule, while push notification delivery is handled separately by the Supabase Edge Function located in supabase/functions/notification-dispatcher/.
match_logs insert fires the enqueue_live_event_from_log trigger, which queues a live_events row with sent = false.notification-dispatcher Edge Function straight away (pg_net trigger on live_events) and again every minute (pg_cron sweeper), both via public.invoke_notification_dispatcher().push_subscriptions endpoint, and only marks the event sent after a successful delivery (or when there are no recipients). Failures are recorded in live_events.attempts / last_error and retried with backoff; dead endpoints (404/410) are pruned; VAPID rejections (401/403) are logged as configuration errors.Setup: apply supabase/migrations/20260912120000_notification_dispatch.sql, store stallcount_functions_url, stallcount_anon_key, and notification_dispatch_secret in Vault, and set VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, and NOTIFICATION_DISPATCH_SECRET as secrets on the Edge Function. VAPID_PUBLIC_KEY must equal the VITE_VAPID_PUBLIC_KEY baked into the Vercel build; the browser client re-subscribes automatically if it detects a key change.
Playoff brackets can fill in their own team slots at times set by the tournament director, instead of waiting for someone to open the Playoff Structure page and press a button.
/admin/playoff-structure, the TD adds release dates and ticks which games each one covers, then turns on Scheduled resolution for the event. A date covers an arbitrary group of games — it does not have to be a whole round — and an event has as many dates as it needs (2–5 is typical; nothing assumes a count). Rows live in playoff_resolve_schedules.pg_cron job runs public.invoke_playoff_resolver() every 6 hours, which net.http_posts to the api/playoff-resolve route with the shared secret.matches.team_a / team_b. It repeats until nothing more changes, so a quarterfinal → semifinal → final chain fills in one run.bracket_nodes.last_resolve_error (an unfinished pool, a tie, no linked match), which the admin page shows as a chip. Later sweeps retry automatically.The run is guarded by acquire_automation_job_lock against the playoff_resolve_sweeper row in automation_job_state, so overlapping sweeps are safe; that row is also where each run's outcome is recorded, since net.http_post is fire-and-forget and cannot observe the response. brackets.is_locked is honoured as a hard stop, and the manual Resolve playoffs button posts to the same route so both paths share one implementation.
Setup: apply supabase/migrations/20260915000000_playoff_auto_resolve.sql, then store playoff_resolver_url (https://<domain>/api/playoff-resolve) and playoff_cron_secret in Vault. playoff_cron_secret must equal the CRON_SECRET environment variable on the Vercel deployment. The timer lives in pg_cron rather than vercel.json because the Vercel Hobby plan only permits daily cron schedules.
Because the sweep runs on a 6-hour cadence (00:00, 06:00, 12:00, 18:00 UTC), a release date takes effect at the first sweep at or after it — set dates with that in mind, or press Resolve playoffs to release everything immediately.
Install dependencies with npm install, configure the required Supabase environment variables in .env, and start the development server with npm run dev.
For the automated Stellenbosch RL 2026 roster sync in production, also configure:
SUPABASE_URLSUPABASE_SERVICE_ROLE_KEYCRON_SECRETSTB_RL_26_SIGNUP_CSV_URLSTB_RL_26_SIGNUP_DOB_MODE