Bouton flottant « Votre avis » sur toutes les pages, modal avec type/message/email optionnel. Envoi d'un email à contact@debats.co via Nodemailer (SMTP Infomaniak). Composant Select extrait dans le design system, styles de champs de formulaire mutualisés via CSS Modules composes. Modal amélioré pour le responsive (overlay scrollable, padding mobile).
Remonter l'erreur à Sentry avec le contexte (email, status) et afficher un message générique à l'utilisateur quand le message d'erreur est absent au lieu d'afficher {}.
Le token OTP Supabase expire après 24h (max autorisé) mais l'invitation applicative reste valide 7 jours. Quand le lien est expiré, l'invité peut maintenant demander un nouveau lien en un clic au lieu d'être bloqué. L'email est inclus dans l'URL d'invitation (urlquery-encodé) pour éviter de le redemander.
Remplace l'usage dangereux de supabase config push (qui écrase la prod avec les valeurs locales) par un script dédié qui pousse des valeurs explicites via l'API Management. Le script affiche un diff avant/après et demande confirmation.
Remplace les wizards multi-étapes par des formulaires créant une seule entité chacun.
Supprime les use cases composés (create-public-figure-with-statement, contribute-statement,
create-position-with-statement) et leurs actions/composants associés.
Ajoute FormSuccess, CSS partagé form-with-guide, types partagés domain/use-cases/types.
Ajoute le bouton « Ajouter une position » sur la page sujet.
Le use case createSubjectUseCase retournait un message générique « Données invalides » au lieu de FieldErrors par champ. Alignement sur le pattern des autres use cases (create-public-figure, create-position) avec propagation des erreurs dans l'action et le formulaire.
La création de personnalité accepte désormais soit une URL Wikipedia, soit 2+ sources de notoriété (URLs valides). Le formulaire affiche conditionnellement les champs de sources quand Wikipedia est vide, avec des guides UX sur chaque champ.
Remplace le findAll() + getStats() par personnalité (843 requêtes) par une vue SQL v_public_figure_activity_summary (2-3 requêtes). La page affiche maintenant 4 sections : recherche, top 10 actives, activité récente, et index alphabétique. Renomme aussi subject_activity_summary en v_subject_activity_summary pour uniformiser la convention de nommage des vues.
Le critère de notoriété accepte désormais soit une page Wikipedia, soit deux sources indépendantes (notoriety_sources). Cela permet d'ajouter des personnalités publiques notables qui n'ont pas de page Wikipedia.
- Page /s/[slug]/modifier avec formulaire pré-rempli et vérification des permissions
- Composant SubjectActions avec boutons Modifier/Supprimer sur la page détail
- Dialog de confirmation de suppression avec gestion d'erreur et Sentry
- Formulaire partagé SubjectForm avec guides intégrés (nommage, présentation, problématique)
- Composant FormPageHeader pour factoriser les en-têtes de formulaire
- Variantes secondary et danger ajoutées au composant Button
- Server actions : retour de résultats au lieu de redirect(), navigation côté client
- Server actions : client admin pour reputationRepo (contournement RLS sécurisé)
- Identité (nom, email) avec bouton Inviter
- Carte réputation avec score, rang, barre de progression vers le prochain rang
- Lien vers l'historique de réputation
- Le nom dans le header devient un lien vers /me
- Ajout getNextRankThreshold dans permissions
Remplace le pattern addReputation (fetch+update non atomique) par un INSERT dans reputation_events avec trigger PostgreSQL qui maintient le cache contributors.reputation.
- Entité ReputationEvent avec types RewardableAction et RelatedEntityType
- Interface recordEvent + getHistory dans ReputationRepository
- Migration SQL : table, index, trigger, RLS
- Migration des 7 use cases vers recordEvent
- Ajout invitation_bonus dans les récompenses
Page protégée affichant le score, le rang et la liste chronologique des mouvements de réputation du contributeur connecté. Ajout d'un lien « Réputation » dans le header.