@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) 1. **Site responsive** (mobile-first, propre aussi sur ordinateur). 2. **Création de compte** : pseudo + mot de passe + photo de profil. 3. **Connexion / déconnexion**. 4. **Page profil** : voir et modifier son pseudo et sa photo. 5. **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 : ```ts 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}.`). **Row Level Security (RLS) — à activer :** - `SELECT` sur `profiles` : 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 **uniquement** `pseudo`, `slug`, `avatar_url` — **pas `points`** (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 `/leaderboard` et `/profile` sont **protégées** : rediriger vers `/login` si 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é) 1. Scaffolder Next.js + TypeScript + Tailwind. 2. Configurer le client Supabase (`.env.local`) et le middleware de session. 3. Écrire `supabase/schema.sql` (table `profiles` + RLS + bucket `avatars`). 4. Auth : pages `/signup` et `/login` avec la logique pseudo → email interne. 5. Upload de la photo au signup + stockage dans le bucket + `avatar_url` en base. 6. Page `/leaderboard` (lecture de tous les profils, tri par points). 7. Page `/profile` (édition pseudo/photo, déconnexion). 8. Middleware de protection des routes + redirections. 9. Polissage responsive + états vides/chargement/erreurs. 10. `README.md` avec 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 `/login` si 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 (`role` sur `profiles`) → 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 key` cô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`.