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。 以下为已保存的摘录。
Outil de désignation des arbitres pour le CD45. Next.js (App Router) + TypeScript + Supabase (Postgres + Auth), via @supabase/supabase-js.查看完整 README ↗
Outil de désignation des arbitres pour le CD45. Next.js (App Router) +
TypeScript + Supabase (Postgres + Auth), via @supabase/supabase-js.
/admin/import, réservé ADMIN) :
colonnes Équipe domicile / Équipe extérieur / Date / Heure / Lieu / Niveau,
avec alias reconnus (Equipe 1/Equipe 2, Salle, Code) pour être compatible
directement avec l'export "Recherche désignation" de FFBB Compet.
Idempotent - un match déjà présent (même date, mêmes équipes, même niveau)
est complété/mis à jour plutôt que dupliqué, donc le même fichier peut être
réimporté sans risque. Les niveaux de compétition inconnus sont créés
automatiquement./matchs/nouveau, /matchs/[id]/modifier) et des
arbitres (/arbitres/nouveau, /arbitres/[id]/modifier) : créer, modifier,
annuler/désactiver, supprimer/admin/utilisateurs, réservé ADMIN)/matchs/incomplets) : sélection de matchs via
cases à cocher, assigne directement la meilleure suggestion à chaque
créneau vacant sans écran de confirmation intermédiairesrc/lib/designation-rules.ts, page /reglement) :
quotas par arbitre (max 3 désignations/semaine, max 3/week-end) vérifiés
avant toute désignation (manuelle ou auto), avec pop-up d'alerte en cas de
blocage. Liste vouée à être complétée au fur et à mesure des règles du CD45Le projet parle directement à Supabase via @supabase/supabase-js (pas
d'ORM). Deux clients :
src/lib/supabase/server.ts : client lié à la session du visiteur
(cookies), utilisé uniquement pour l'authentification (login/signup/
session Supabase Auth)src/lib/supabase/admin.ts : client "service_role", utilisé pour toutes
les données applicatives (matchs, arbitres, désignations...). Contourne
volontairement les policies RLS - l'autorisation (qui peut faire quoi)
est vérifiée par notre propre code (getCurrentUser() + rôle), jamais
par la basesupabase/schema.sql et supabase/seed.sql documentent le schéma et les
données de référence (déjà appliqués sur le projet). Ce ne sont pas des
migrations exécutées automatiquement : toute évolution de schéma se fait
en SQL direct sur le projet Supabase (dashboard > SQL editor, ou les
outils MCP Supabase), puis en mettant à jour supabase/schema.sql.
L'authentification passe entièrement par le service Auth natif de Supabase
(GoTrue), via @supabase/ssr. Deux pages : /login et /signup
(inscription libre, ouverte à qui a l'URL - pas de code d'invitation).
Un nouveau compte créé via /signup obtient le rôle REPARTITEUR par
défaut ; à évaluer si un contrôle d'accès plus strict devient nécessaire
(code d'invitation, validation manuelle...).
Table Profile (schéma public) : id = auth.users.id, email, name,
role (ADMIN ou REPARTITEUR, défaut REPARTITEUR). Un trigger Postgres
(handle_new_user, voir supabase/schema.sql) crée automatiquement la
ligne Profile à chaque nouvelle inscription dans auth.users, que ce
soit via /signup ou créée manuellement depuis le dashboard Supabase.
Créer un compte manuellement (alternative à /signup) : dashboard
Supabase > Authentication > Users > Add user (cocher "Auto Confirm User"
pour se connecter immédiatement sans email de confirmation).
Promouvoir un compte en ADMIN (accès à /admin/niveaux) :
UPDATE "Profile" SET role = 'ADMIN' WHERE email = '[email protected]';
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY : URL et clé
publique du projet Supabase (Project Settings > API)SUPABASE_SERVICE_ROLE_KEY : clé secrète (même page, section
"service_role") - ne jamais l'exposer côté client, uniquement utilisée
dans du code serveur (src/lib/supabase/admin.ts)GOOGLE_MAPS_API_KEY (optionnelle) : clé API Google Cloud avec la
Geocoding API activée. Sert à convertir l'adresse d'un arbitre et
l'adresse d'un gymnase en coordonnées GPS, pour prioriser les
suggestions par proximité et estimer la rémunération (40€/match +
0,35€/km aller-retour). Sans cette variable, l'app fonctionne
normalement, juste sans ce tri par distance ni cette estimation.Piège fréquent en collant une valeur dans les Environment Variables de
Vercel : ne pas inclure les guillemets (le format .env en a, Vercel
non) - une URL du genre "https://...supabase.co" avec les guillemets
inclus est invalide et fait planter toutes les pages (500 générique). Le
code tente de nettoyer ça automatiquement (src/lib/supabase/env.ts),
mais autant coller la valeur propre dès le départ.
npm install
npm run dev
Créer ensuite un compte via /signup ou le dashboard Supabase (voir
section Authentification ci-dessus) pour pouvoir te connecter.
claude/referee-assignment-system-zy1i9t (ou main une fois mergé),
renseigner les trois variables d'environnement ci-dessus (cocher
Production + Preview pour chacune), puis déployer.