BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2,或任何藍牙控制器搭配 MyWhoosh、Rouvy、Zwift 等。可於 iOS、Android、Windows 與 macOS 免費試用。
AI 翻譯
尚未偵測到更新。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.