Next.js 16 + Tailwind + Supabase (Auth, Postgres, Storage). Connexion par pseudo/mot de passe via email interne dérivé, RLS avec points protégés au niveau colonne, pages login/signup/leaderboard/profile. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
9.2 KiB
@AGENTS.md
Le Tribunal — Brief de démarrage V1
À l'attention de Claude Code. Ce document décrit uniquement la V1. Reste simple, ne construis rien qui n'est pas listé dans « Périmètre V1 ». Les fonctionnalités futures sont listées en fin de doc seulement pour que l'architecture reste extensible — ne les implémente pas maintenant.
1. But du projet
Application web pour un groupe d'amis (~12 personnes) qui animera un jeu et des olympiades pendant une semaine de vacances. On démarre par le socle : comptes utilisateurs + leaderboard. Tout le reste (jeu du « Tribunal », roulette, ostracisme, etc.) viendra ensuite.
2. Périmètre V1 (et seulement ça)
- Site responsive (mobile-first, propre aussi sur ordinateur).
- Création de compte : pseudo + mot de passe + photo de profil.
- Connexion / déconnexion.
- Page profil : voir et modifier son pseudo et sa photo.
- Leaderboard : liste de toutes les personnes inscrites, triée par points décroissants, affichant rang, photo, pseudo, points.
Hors périmètre V1 (ne pas coder maintenant)
Attribution de points depuis l'app, rôles admin/juges, jeu du Char, roulette, ostracisme, timer du Gardien, thèmes/éditions, temps réel. En V1, les points existent en base (défaut 0) mais il n'y a pas d'interface pour les modifier — on les ajustera plus tard (ou manuellement via la console Supabase pour tester).
3. Stack technique
Choisie pour être simple à construire, sécurisée et gratuite à héberger pour 12 utilisateurs :
- Framework : Next.js (App Router) + TypeScript
- Style : Tailwind CSS (mobile-first)
- Auth + Base de données + Stockage photos : Supabase
- Supabase Auth pour la connexion
- Postgres pour les profils
- Supabase Storage (bucket
avatars) pour les photos
- Déploiement : Vercel (front) + Supabase (managé)
Pas d'autre dépendance lourde. Composants UI faits main avec Tailwind (pas de librairie de composants pour l'instant).
4. Authentification (pseudo + mot de passe)
L'utilisateur se connecte avec un pseudo et un mot de passe — pas d'email visible.
Implémentation : on utilise Supabase Auth (email/password) en dérivant un email interne à partir du pseudo, invisible pour l'utilisateur :
const internalEmail = `${slugify(pseudo)}@letribunal.test`;
// signup: supabase.auth.signUp({ email: internalEmail, password })
// login : supabase.auth.signInWithPassword({ email: internalEmail, password })
slugify: minuscules, sans accents, espaces →-, caractères non alphanumériques retirés.- Le pseudo affiché (avec accents/casse) est stocké dans la table
profiles. - Vérifier l'unicité du pseudo au signup (le slug sert de clé technique).
- Mots de passe : gérés/hashés par Supabase Auth (ne jamais stocker de mot de passe en clair).
Règle de sécurité produit : on ne collecte pas d'email réel, c'est un cercle d'amis. Pas de reset par email en V1 (un admin pourra réinitialiser via Supabase si besoin).
5. Modèle de données
Table profiles (liée à auth.users) :
| Colonne | Type | Notes |
|---|---|---|
id |
uuid (PK) | = auth.users.id |
pseudo |
text | affiché, unique (insensible à la casse) |
slug |
text | unique, dérivé du pseudo (clé technique) |
avatar_url |
text (null) | URL publique de la photo dans Storage |
points |
int | défaut 0 |
created_at |
timestamptz | défaut now() |
Storage : bucket public avatars, un fichier par utilisateur ({user_id}.<ext>).
Row Level Security (RLS) — à activer :
SELECTsurprofiles: autorisé à tout utilisateur authentifié (nécessaire pour afficher le leaderboard de tout le monde).INSERT: un utilisateur ne peut créer que sa propre ligne (auth.uid() = id).UPDATE: un utilisateur ne peut modifier que sa propre ligne, et uniquementpseudo,slug,avatar_url— paspoints(les points seront gérés plus tard côté admin).DELETE: interdit en V1.
Fournis le SQL des tables + policies dans un fichier supabase/schema.sql versionné.
6. Pages & navigation
| Route | Contenu |
|---|---|
/ |
Redirige vers /leaderboard si connecté, sinon vers /login |
/login |
Formulaire pseudo + mot de passe ; lien vers /signup |
/signup |
Pseudo + mot de passe + upload photo ; crée le compte et le profil |
/leaderboard |
Liste triée par points ↓ : rang, photo, pseudo, points (protégée) |
/profile |
Voir/modifier son pseudo et sa photo ; bouton déconnexion (protégée) |
- Les routes
/leaderboardet/profilesont protégées : rediriger vers/loginsi non connecté (via middleware Next.js + session Supabase). - Une barre de navigation simple (Leaderboard · Profil · Déconnexion) visible une fois connecté.
7. Look & feel
Sobre, lisible, mobile-first, agréable en vidéoprojection plus tard. Définir les couleurs comme variables CSS / tokens Tailwind pour pouvoir re-thématiser facilement par la suite (un thème par édition est prévu plus tard — ne pas coder de thème « en dur » dans les composants).
Palette par défaut (tokens) :
--navy: #0F2748(fond / barres)--gold: #C9A227(accent, rang 1)--ivory: #F4ECD8(surfaces claires)--ink: #2A2116(texte sur clair)
Leaderboard : le rang 1 est mis en valeur (accent doré). Photos en avatars ronds. Fallback si pas de photo : initiales du pseudo sur fond de couleur.
Qualité minimale : responsive jusqu'au mobile, focus clavier visible, images optimisées, états de chargement et messages d'erreur clairs (« Ce pseudo est déjà pris », « Mot de passe incorrect », etc. — pas de message technique brut).
8. Plan de construction (ordre conseillé)
- Scaffolder Next.js + TypeScript + Tailwind.
- Configurer le client Supabase (
.env.local) et le middleware de session. - Écrire
supabase/schema.sql(tableprofiles+ RLS + bucketavatars). - Auth : pages
/signupet/loginavec la logique pseudo → email interne. - Upload de la photo au signup + stockage dans le bucket +
avatar_urlen base. - Page
/leaderboard(lecture de tous les profils, tri par points). - Page
/profile(édition pseudo/photo, déconnexion). - Middleware de protection des routes + redirections.
- Polissage responsive + états vides/chargement/erreurs.
README.mdavec instructions de setup et de déploiement.
9. Configuration & commandes
Variables d'environnement (.env.local) :
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
Documenter dans le README.md : création du projet Supabase, exécution de schema.sql, création du bucket avatars, lancement (npm run dev) et déploiement Vercel.
10. Definition of Done (V1)
- On peut créer un compte (pseudo + mot de passe + photo) et être connecté ensuite.
- On peut se déconnecter puis se reconnecter avec pseudo + mot de passe.
- Un pseudo déjà pris est refusé avec un message clair.
- Le leaderboard affiche tous les inscrits, triés par points, avec rang/photo/pseudo/points.
- On peut changer sa photo et son pseudo depuis
/profile. - Les routes protégées redirigent vers
/loginsi non connecté. - Le site est propre et utilisable sur téléphone et ordinateur.
- RLS activée : personne ne peut modifier les points ni le profil d'autrui.
11. Roadmap (ne pas coder maintenant — juste pour garder l'archi extensible)
Prévoir que ces éléments s'ajouteront ensuite, sans refonte :
- Rôles : juge/admin (
rolesurprofiles) → attribution de points, modération. - Notion d'édition/thème : une table
editions(année, nom du thème, mood board, vocabulaire) ; les points deviendront rattachables à une édition. - Jeu du Tribunal : le Char (zone de pénalité), batailles de cul sec, ostracisme, roulette, timer du Gardien.
- Temps réel : leaderboard et fil d'événements live via Supabase Realtime, mode « grand écran » pour vidéoprojecteur.
Garde le code modulaire (composants réutilisables, accès aux données isolé) pour que ces ajouts restent simples.
12. À reporter dans CLAUDE.md (conventions durables du repo)
- Stack : Next.js (App Router) + TS + Tailwind + Supabase.
- Auth = pseudo + mot de passe via email interne dérivé (
slug@letribunal.test). - Toujours passer par les policies RLS ; ne jamais exposer la
service_role keycôté client. - Design tokens = variables CSS (thème swappable) ; pas de couleur codée en dur dans les composants.
- Commandes :
npm run dev,npm run build,npm run lint. - Garder chaque fonctionnalité future isolée et le schéma SQL versionné dans
supabase/schema.sql.