Chaque Citoyen peut proposer une question pour Le Char depuis /profile
(upsert via submit_chariot_question, figée dès la date du Tribunal
comme les scores d'Icare). Les Archontes modèrent ces suggestions
directement sur /char/questions (ajouter à la banque ou rejeter).
/admin affiche maintenant l'email de chaque membre via une nouvelle
RPC admin_list_members(), seule façon d'exposer auth.users.email sans
passer par la service_role key côté client.
Corrige au passage deux bugs découverts pendant les tests : la
policy interne de admin_list_members() référençait id/role sans les
qualifier, ambigus avec les colonnes du RETURNS TABLE (erreur
Postgres 42702) ; et l'auteur d'une suggestion s'affichait toujours
comme "un Citoyen" car le embed profiles(...) avait été mal retypé en
tableau alors qu'il est retourné en objet à l'exécution.
Partage la police JetBrains Mono (déjà utilisée sur /admin) via un
module commun src/lib/fonts.ts, et l'applique à l'entrée "Admin" du
menu déroulant. Remplace son icône générique par une nouvelle icône
terminal (IconTerminal), cohérente avec la rupture volontaire de
thème sur cette page technique.
Déplace La Roulette de sa page dédiée vers une section de /char (tout
l'outillage de la soirée du Tribunal au même endroit) et retire la
route /roulette. Corrige un bug de superposition où le pointeur doré
de la roulette passait devant le menu déroulant du header (isolation
de contexte d'empilement manquante). Renomme "Le Conseil des
Archontes" en "Admin" avec une police monospace, rupture volontaire
avec le thème grec pour cette page technique.
Un seul round sur toute la semaine : plus besoin de pouvoir
réinitialiser le repère de classement depuis l'admin. La logique des
flèches de progression (previous_rank, reset_rank_reference) reste en
place, simplement plus rien ne la déclenche.
Remplace le thème générique (tokens navy/gold/ivory re-thématisables par
édition) par une direction artistique fixe et codée en dur : tribunal
égéen de nuit — marbre, or, mer sombre, sceaux de cire.
Fondations (globals.css, layout.tsx) :
- Polices next/font/google : Cinzel (titres, tracking large), Cormorant
Garamond (citations italiques), Manrope (interface).
- Nouveaux tokens couleur : ink/ink-2 (fond mer de nuit), marble/marble-2
(surfaces claires), gold/gold-bright (accents), oxblood (blâmes/erreurs),
olive (honneurs/succès), sea, text-marble/text-mut (texte sur marbre —
jamais de doré en texte courant, contraste insuffisant).
- Classes utilitaires : .marble-surface (texture par dégradés, pas
d'image de bruit), .meander-divider (frise à méandre grecque en SVG
data-URI).
Composants d'ornement (aucune image bitmap) :
- components/laurel-wreath.tsx : couronne de laurier calculée par
trigonométrie (deux arcs symétriques de feuilles), réutilisée en logo,
favicon (icon.svg régénéré avec les mêmes coordonnées) et couronne du
rang 1 du podium.
- components/diamond-divider.tsx : séparateur ◆ avec filets dégradés.
Header global (components/header.tsx, remplace nav-bar.tsx) :
- Logo laurier + "LE TRIBUNAL" à gauche (cliquable vers le leaderboard).
- Chip utilisateur à droite : avatar (bordure dorée), pseudo, badge de
rôle (Archonte/Citoyen), points de gloire, menu déroulant (Mon profil,
Le Conseil des Archontes si juge, Se déconnecter).
- Onglets L'Agora / Le Crieur, frise à méandre en séparateur.
- Responsive : nom du site et pseudo masqués sous le breakpoint sm,
l'avatar reste toujours visible.
Vocabulaire diégétique (toujours avec le terme fonctionnel à côté) :
juges → Archontes, membres → Citoyens, leaderboard → L'Agora, journal →
Le Crieur (décrets avec sceau de cire oxblood), points positifs/négatifs
→ Honneurs/Blâmes, points → gloires, section admin → Le Conseil des
Archontes.
Avatar : bordure dorée, couleur de fallback dérivée d'un hash du pseudo
(au lieu d'une couleur fixe).
Toutes les pages (login, signup, leaderboard/podium, journal, admin,
profil) sont passées sur les nouveaux tokens/polices/vocabulaire.
README.md et CLAUDE.md : section "Ré-thématisation" remplacée par
"Direction artistique" documentant la palette, les polices et les
ornements ; toute mention du système de re-thème par édition retirée.
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>