Files
tribunal-app/CLAUDE.md
T
Valentin ROBIN 87cd286e5a Scaffold V1: auth, profils et leaderboard
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>
2026-07-11 14:52:18 +02:00

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)

  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 :

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 :

  • 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_urlpas 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.