OpenAthlete
AGPLv3 endurance training platform: EU-oriented hosting, transparent CTL/ATL/TSB logic in code, self-hosting, and full export. Built in Grenoble.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Youth sports league scheduling SaaS — www.thefieldslate.com.
League commissioners create seasons, divisions, and teams; generate conflict-free game and practice schedules; manage venues, officials, interleague play, snack shacks, and pay tracking; and share schedules with coaches and families.檢視完整 README ↗Youth sports league scheduling SaaS — www.thefieldslate.com.
League commissioners create seasons, divisions, and teams; generate conflict-free game and practice schedules; manage venues, officials, interleague play, snack shacks, and pay tracking; and share schedules with coaches and families.
main auto-deploys to productionThis is a production-only environment — there is no staging.
npm run dev # local preview (.env.local required)
npx tsc --noEmit # required before every commit
npx eslint <paths> # required before every commit
git push origin main # deploys to production via Vercel
Database migrations live in supabase/migrations/ (numbered 00NN_name.sql) and are applied to the live project via the Supabase MCP/dashboard — the files in the repo are the record, not the applicator. Verify schema changes against the live catalog before writing code that depends on them.
leagues = seasons. archived_at IS NULL means active. Archived seasons free their plan-cap slots.org_id = the owner's profile id. Resolve with getCurrentOrgId() (src/lib/orgs/context.ts). Multi-admin orgs share via org_members; membership checks go through the SECURITY DEFINER is_org_member() — never inline its logic.profiles.plan (free | pro | elite) is the canonical tier source. UI gating via isProPlus/isElite + FeatureLockedCard/UpgradeModal; cap enforcement lives in the create RPCs (create_division_atomic, create_team, create_league…), with matching UI counters in src/lib/plan/counts.ts — the two layers must agree.umpires + official_* tables): season-scoped roster with contact info, weekly availability windows, blackout dates, certifications, a coached-team link (umpires.team_id), and normalized season roles (official_roles). Role writes are dual-format during migration: free text in game_umpires.role/umpire_role_rates.role plus role_id → official_roles; divisions.umpire_roles jsonb stays populated until a future cleanup migration.src/lib/umpires/auto-assign.ts) is best-effort and two-tier: fully-qualified first (availability, weekly cap, no blackout, no coach conflict, no overlap), then a soft tier that relaxes availability and weekly caps. Blackouts, coach conflicts, double-booking, and time overlap are always hard blocks. Division priority orders assignment. All of its date math is client-side local-timezone (src/lib/umpires/eligibility.ts) — do not call from server code without adding a timezone parameter.src/types/database.ts is hand-curated — never regenerate it wholesale. Add new tables/columns surgically and keep the Functions map empty; RPC call sites rely on the as never convention.head: true counts combined with !inner joins return wrong numbers — fetch ids first, then count with .in(). Plain single-table filtered counts are safe.app/icon.svg, apple-icon.png, opengraph-image.png — do not add metadata.icons.#0b1c39, paper #f4f5f0, green #22c55e, dark green #16a34a.Loader2 busy states, router.refresh() after client writes, modal overlay structure, 44px tap targets on mobile surfaces).