Page /char (16:9, projetée) pour piloter les deux jeux physiques du
Tribunal : Le Char (2 colonnes de 3 emplacements côte à côte avec un
VS et une illustration de char vu du dessus, sélection en un clic,
duels, compteur et classement des passages) et Le Gardien du Silence
(tirage aléatoire parmi les Citoyens, minuteur avec reroll auto et
manuel). Banque de questions gérée séparément sur /char/questions
(pensée pour être pilotée depuis un téléphone pendant que /char est
projetée depuis un ordinateur).
Après retour d'expérience, la course de char (vue du dessus, piste
générée par jour) laisse place à un Flappy Bird grec plus simple et
plus lisible sur téléphone : Icare vole entre des colonnes de temple,
touche l'écran pour battre des ailes, échec net au premier contact
(score remis à zéro).
Record personnel all-time (plus de piste quotidienne ni de fantômes) :
les scores se figent dès que la date du Tribunal est atteinte, puis les
gloires du top 3 sont attribuées automatiquement via une tâche
planifiée pg_cron, comme pour l'ancienne Course du Char.
schema.sql nettoie explicitement l'ancienne Course du Char (tables,
RPC, tâche planifiée) avant de poser le nouveau schéma, puisqu'elle
avait déjà été appliquée en prod.
- chariot_runs : meilleur temps + tracé fantôme par joueur et par jour,
verrouillée comme points_log (écriture uniquement via RPC).
- submit_chariot_run() : calcule la date côté serveur, borne le temps,
n'écrase que si strictement meilleur.
- close_daily_chariot_race() + chariot_race_closes : clôture la journée
précédente et attribue les gloires du top 3 automatiquement, sans
intervention d'un Archonte — planifiée via pg_cron (à activer une
fois côté Dashboard Supabase).
- points_log.judge_id devient nullable (un point auto n'a pas de juge) ;
Le Crieur affiche "Le Tribunal" pour ces décrets-là.
Boutons de validation des points :
- Les icônes ✓/✕ étaient trop grandes (40px) et dupliquées entre le
podium et le reste du classement. Factorisées dans un composant
partagé PointsConfirmControls (32px, icône 16px, olive/oxblood,
aria-label + tooltip), utilisé à l'identique par JudgePointControls
sur le podium ET dans la liste.
Nouvelle page /calendrier — "Le Calendrier des Dieux" :
- Modèle de données : days (date, dieu, domaine), events (titre, type,
heure, lieu, created_by forcé par trigger), settings (ligne unique,
date du Tribunal). RLS : lecture ouverte à tout authentifié, écriture
(insert/update/delete) réservée au rôle judge par policies dédiées —
jamais un simple masquage des boutons côté client.
- 8 préréglages de divinités (Dionysos, Arès, Athéna, Aphrodite, Hermès,
Poséidon, Hadès, Zeus) avec domaine, couleur d'accent et emblème SVG ;
un Archonte peut aussi saisir une divinité libre.
- Bannière avec compte à rebours avant la date du Tribunal, éditable par
les Archontes. Journées en cartes (jour courant mis en évidence,
jours passés estompés, jour du Tribunal en accent oxblood), liste
d'événements avec icône par type (activité/défi/épreuve/tribunal).
Mode édition (ajout/modification/suppression avec confirmation)
réservé aux Archontes. Realtime sur les trois tables.
- Ajouté au menu déroulant du header, route protégée par le proxy.
Rendu des icônes dynamiques (GodEmblem, EventTypeIcon) via branchement
JSX explicite plutôt que variable de composant résolue à l'exécution,
pour respecter react-hooks/static-components.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Design & UX :
- Renomme "Administration" en "Admin" (nav, page, docs).
- Logo original (marteau de juge stylisé navy/or) en favicon (src/app/icon.svg,
remplace le favicon.ico par défaut de create-next-app) et dans la navbar
(components/logo.tsx).
- Navbar : menu hamburger sur mobile (les liens débordaient à partir de
~4 entrées sur petit écran).
- Leaderboard : lignes en deux niveaux sur mobile (infos membre / contrôles
juges) au lieu d'un seul flex-wrap qui devenait illisible.
- Contrôles de points juges (JudgePointControls) : boutons et champ montant
réduits en mode compact pour tenir dans les colonnes du podium sur petit
écran.
- Podium : scroll horizontal de secours (overflow-x-auto) si le contenu
dépasse malgré tout sur très petits écrans.
- Table admin : pseudo/avatar sur une ligne, rôle/statut/actions sur une
autre en mobile (le flex-1 sur l'input pseudo n'avait aucun effet en
layout colonne).
Correctif sécurité/fonctionnel :
- storage.objects n'avait que des policies INSERT et UPDATE pour le bucket
avatars, pas de policy SELECT. Postgres a besoin de lire la ligne
existante pour évaluer la clause USING d'un UPDATE : sans SELECT, tout
remplacement de photo (upsert) échouait avec "new row violates row-level
security policy", même si les policies INSERT/UPDATE étaient correctes.
Ajout d'une policy SELECT publique sur le bucket avatars (cohérent avec
le fait que le bucket est déjà public en lecture).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
V2 — authentification et administration :
- Authentification par email + mot de passe (email confirmé, un compte
par email), abandon de l'email interne dérivé du pseudo.
- Rôles public/judge sur profiles, section Administration (juges
uniquement, vérifiée côté serveur) pour gérer les membres.
- Verrou de pseudo : modifiable une fois par son propriétaire puis figé,
contournable par un juge.
- RLS étendue par un trigger BEFORE UPDATE (enforce_profile_update) pour
verrouiller les colonnes sensibles (role, points, pseudo_locked, pseudo
figé) — la RLS seule ne peut pas exprimer une règle par colonne.
V3 — points, journal, podium, progression, photo :
- RPC award_points() (SECURITY DEFINER) : seul point d'écriture de la
colonne points, vérifie le rôle juge côté serveur, delta signé sans
plancher à 0, trace chaque opération dans points_log.
- Leaderboard temps réel (Supabase Realtime) avec podium top 3
(égalités gérées), flèches de progression (previous_rank), et
contrôles de points juges avec confirmation explicite (plus de
debounce auto) avant envoi.
- Page /journal ("le crieur") : fil live et public des attributions de
points.
- Recadrage photo carré + compression client (react-easy-crop + canvas)
au signup et sur le profil.
- Passe de polish visuel : cartes/boutons cohérents, lien actif dans la
nav, podium retravaillé.
schema.sql, README.md et CLAUDE.md mis à jour en conséquence (schéma
idempotent, instructions SMTP/rôles/migration, conventions RLS+trigger
documentées pour les futures colonnes sensibles).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>