Commit graph

970 commits

Author SHA1 Message Date
ee13b5c31d feat: afficher la citation et la source au lieu de la description de position sur la page personnalité 2026-03-01 00:15:14 +01:00
331b96a434 fix: alignement version PostgreSQL locale avec Supabase Cloud (15 → 17) 2026-02-28 09:12:32 +01:00
875e14a781 feat: page hub « Contribuer » avec lien dans le header
Remplace le lien « Mode d'emploi » par « Contribuer » dans la navigation. La page /contribuer présente le fonctionnement de la plateforme, la réputation du contributeur connecté, et un renvoi vers le mode d'emploi et le dépôt source.
2026-02-28 08:46:12 +01:00
e945c77469 chore: supabase-cli depuis nixpkgs-unstable pour avoir une version plus récente 2026-02-28 00:05:20 +01:00
080824011d feat: pré-remplissage du formulaire de contribution et CRUD sujets
Pré-remplissage du formulaire de contribution depuis les pages /s/[slug] et /p/[slug] via searchParams (initialFigure, initialSubject). Le Combobox supporte un initialItem pour afficher la sélection par défaut.

Server actions et use cases pour le CRUD sujets (create, update, delete), page /s/ajouter avec NewSubjectForm. Mise à jour de CONTRIBUTING.md : une personnalité peut changer de position au fil du temps.
2026-02-28 00:02:38 +01:00
a283c4c083 feat: système d'invitation par les contributeurs Éloquent (1000+ pts)
Permet aux contributeurs confirmés d'inviter de nouvelles personnes par email. L'invité reçoit un lien, choisit son mot de passe, et son compte est créé avec la moitié de la réputation de l'inviteur. L'inviteur reçoit +50 pts.

Domain : entité Invitation (Effect Schema), use cases inviteUser et acceptInvitation, permissions invite_user, ContributorRepository et InvitationRepository, extraction de DatabaseError dans errors.ts.

Infra : repositories Supabase, migration table invitations avec index unique partiel, RPC get_user_id_by_email, template email personnalisé.

UI : page /inviter avec formulaire, page /accepter-invitation avec choix de mot de passe (token consommé uniquement à la soumission), lien Inviter dans AuthSection, NoticeBanner pour les redirections avec message.

Correctifs issus de la revue de code : rollback de l'invitation si l'envoi d'email échoue, try/catch + Sentry dans inviteUserAction, ignoreDuplicates dans le callback auth pour ne pas écraser la réputation, exclusion de .direnv dans vitest.
2026-02-27 23:56:20 +01:00
b0c46ae393 feat: tri sidebar par date de prise de position, suppression des as any et bloc « dernières ajoutées » 2026-02-27 02:06:08 +01:00
c47ea2c368 refactor: typage des clients Supabase avec le générique Database 2026-02-27 02:05:14 +01:00
fc13ccad85 feat: formulaire unifié de contribution avec upload admin, gestion d'erreurs Sentry et validation date-fns
- Upload photo via client admin Supabase (service role, bypass RLS) avec redimensionnement sharp (800px max, JPEG q85)
- Gestion d'erreurs propre dans les 5 repositories : helper dbError + Sentry.captureException
- Formulaire : try/catch/finally pour éviter UI bloquée, validation taille photo côté client (30 Mo max)
- Validation date avec date-fns (parseISO/isFuture) au lieu de construction manuelle
- bodySizeLimit 30mb pour les server actions
- Redirections UI vers /nouvelle-prise-de-position + bouton conditionnel sur /s
- Tests contribute-statement use case (21 tests) + findByWikipediaUrl dans les mocks existants
2026-02-24 01:22:56 +01:00
0b25179b1e perf: ajout de sharp pour l'optimisation d'images next/image
Ajoute sharp, node-addon-api et node-gyp en dépendances pour permettre
la compilation de sharp sur Clever Cloud (cf. ticket support #Y8CKYN).
2026-02-22 01:15:18 +01:00
8cdcaf671a perf: optimisation des miniatures d'avatars avec next/image
Remplace le <img> brut par le composant Image de Next.js dans FigureAvatar.
Les miniatures de 40px téléchargeaient l'image JPEG originale en pleine
résolution. Désormais : redimensionnement serveur, conversion WebP/AVIF,
lazy loading et srcset automatiques.
2026-02-22 00:46:46 +01:00
4cc24db1a3 chore(deps): npm audit fix — corrige la vulnérabilité vite (vitest) 2026-02-21 17:10:22 +01:00
594992c233 feat: migration Next.js 15 → 16 (Turbopack, ESLint 9, proxy)
- Next.js 15.5.12 → 16.1.6 avec Turbopack par défaut
- ESLint 8 → 9 + migration flat config (eslint.config.mjs)
- eslint-config-next 15 → 16, eslint-config-prettier 9 → 10
- @types/node 18 → 22 (aligné avec nodejs_22 du flake.nix)
- middleware.ts → proxy.ts (nouvelle convention Next.js 16)
- global-error.tsx : import dynamique de Sentry (fix prerendering Turbopack)
- CSS : @import Google Fonts déplacé en tête de fichier (requis par Turbopack)
- .prettierignore : ajout next-env.d.ts et .clever.json (fichiers auto-générés)
2026-02-21 16:30:21 +01:00
9aa8fd80e5 chore(deps): npm audit fix 2026-02-21 12:25:56 +01:00
7350be72e8 fix(security): mise à jour Next.js 15.3.5 → 15.5.12 (CVE-2025-55182)
Corrige la faille critique RCE (CVSS 10.0) dans React Server Components
qui a permis l'exécution de code arbitraire sur le serveur de production
le 18 février (minage Monero via XMRig).
2026-02-21 12:16:38 +01:00
067123ffa5 feat: formulaire unifié « Nouvelle prise de position » avec upload photo atomique
Formulaire unique /nouvelle-prise-de-position permettant de créer une prise
de position en sélectionnant ou créant à la volée une personnalité, un sujet
et une position. L'upload de la photo se fait AVANT la création des entités
pour éviter un état incohérent, et les erreurs d'upload remontent à Sentry.
2026-02-18 13:50:46 +01:00
0047c7d840 feat: installer Sentry pour le monitoring d'erreurs
Sentry est actif uniquement en production (DSN absent en dev → SDK inerte).
Capture automatique des erreurs Server Components, server actions,
middleware (via onRequestError) et côté client (error boundary global).
2026-02-18 12:01:08 +01:00
e2d0a20b45 feat: vérifier que la page Wikipedia existe et est une biographie
Appel à l'API MediaWiki pour valider que la page existe et possède la
catégorie « Wikipédia:Article biographique ». Interface WikipediaValidator
dans domain/services (port hexagonal), implémentation dans infra/.
2026-02-17 00:16:21 +01:00
5840afa824 feat: refuser une date de preuve dans le futur 2026-02-17 00:14:44 +01:00
7f2aa066c6 feat: wizard « Nouvelle personnalité » avec premier statement obligatoire
Même logique atomique que le wizard position : on crée personnalité →
statement → evidence → réputation en une seule opération. La permission
add_personality requiert le rang Éloquent (1000+ pts).

- Use case create-public-figure-with-statement en TDD (13 tests)
- Server actions utilitaires (search-subjects, get-positions-for-subject)
- Wizard 2 étapes (personnalité + première prise de position)
- Page /p/ajouter avec auth check Éloquent
- Bouton conditionnel sur /p via le composant Button du design system
- Ajout de size="small" au composant Button
- Ajout de onSelect au Combobox pour le chargement dynamique
- Ajout de typecheck (tsc --noEmit) au script npm check
- Correction des fakes incomplets dans les tests existants
2026-02-16 23:24:11 +01:00
60cbab6f2e feat: wizard « Nouvelle position » avec premier statement obligatoire
Ajoute un parcours en 2 étapes pour créer une position et son premier
statement atomiquement : étape 1 (titre + description), étape 2
(personnalité + preuve sourcée). La soumission crée position, statement,
evidence et accorde 100 pts de réputation (2×50).
2026-02-13 13:27:51 +01:00
8be2d8f45c chore: reformater les fichiers existants avec Prettier 2026-02-13 13:24:07 +01:00
a5308a6cd9 chore: gitignorer .idea/, .claude et tsconfig.tsbuildinfo 2026-02-13 11:37:37 +01:00
db13d96add fix: ajouter les fichiers manquants et corriger les imports cassés
Ajoute get-authenticated-contributor, reputation-repository et son
implémentation Supabase qui n'avaient pas été commités. Corrige aussi
le renommage createServerSupabaseClient → createSSRSupabaseClient dans
toutes les pages. Ajoute le script npm run check (lint+format+build).
2026-02-13 11:25:50 +01:00
d7e83f95b9 feat: ajouter une prise de position sur un sujet existant
- Use case create-statement avec validation par champ (TDD, 8 tests)
- Server actions : création de statement et recherche de personnalités
- Page /s/[slug]/ajouter avec formulaire complet
- Combobox avec downshift pour la recherche async de personnalités
- PositionRepository (interface + implémentation Supabase)
- createEvidence et searchByName ajoutés aux repos existants
- Bouton conditionnel sur la page détail sujet (visible si connecté·e)
- Erreurs de validation affichées sous chaque champ concerné
- Conservation du state du formulaire en cas d'erreur
2026-02-13 11:13:57 +01:00
e16813258e feat: ajouter sitemap, robots.txt et protection TDMRep contre le crawling IA
- sitemap.ts dynamique avec pages statiques + sujets et personnalités depuis la DB
- robots.ts bloquant 22 crawlers IA (GPTBot, ClaudeBot, Google-Extended, etc.) tout en autorisant l'indexation par les moteurs de recherche
- TDMRep (W3C) : fichier .well-known/tdmrep.json + meta tags dans le layout pour réserver les droits de text/data mining (Directive européenne DSM)
2026-02-13 10:48:45 +01:00
b9d0720e41 chore: passer à React 19 et supprimer styled-components
- Mise à jour react et react-dom de 18.2 vers 19.2
- Mise à jour @types/react et @types/react-dom vers v19
- Suppression de styled-components (vestige inutilisé, 100% CSS Modules)
- Suppression du StyledComponentsRegistry et de l'option compiler.styledComponents
- Débloque useActionState et les form actions natives de React 19
2026-02-13 01:14:07 +01:00
29d1700006 feat: vue SQL subject_activity_summary pour la page d'accueil
Remplace les N+1 requêtes (1 + 4×N) par une seule requête sur une vue
PostgreSQL qui agrège sujets, stats et figures. Les sujets sont triés
par date de dernière prise de position (taken_at) décroissante.
2026-02-12 22:40:21 +01:00
05920b5608 fix: le tri par date de dernière prise de position ne fonctionnait pas sur la page d'accueil 2026-02-12 22:21:34 +01:00
72a6ba4e67 feat: tri les sujets de l’accueil par date décroissante de dernière prise de position
Utilisation de `takenAt` comme priorité sur `createdAt` pour définir la date la plus récente dans les statements.
2026-02-12 21:55:37 +01:00
c04d4fa10f feat: trier les sujets par date du dernier statement sur la page d'accueil
Les sujets avec une activité récente remontent en premier. Les sujets
sans statement sont triés par date de création en fallback.
2026-02-12 21:48:30 +01:00
bab3c0f011 feat: implémenter le système de réputation avec rangs et permissions
5 rangs (Sophiste, Métèque, Éloquent, Idéaliste, Fondateur), matrice
complète des 19 actions, barème de points pour 28 actions. Le Contributor
délègue maintenant au système de permissions via contributorCanPerform.
Hook useCurrentUser pour l'affichage conditionnel côté client.
2026-02-12 18:12:21 +01:00
938d93cee2 feat: ajouter le logo Débats dans les meta Open Graph et Twitter du layout 2026-02-12 15:49:16 +01:00
8b70eccda1 feat: ajouter la photo de la personnalité dans les meta Open Graph et Twitter 2026-02-12 15:45:48 +01:00
d53fd38d9a feat: ajouter les templates d'emails Supabase en français
6 templates versionnés dans supabase/templates/ et référencés dans config.toml :
confirmation, réinitialisation mot de passe, changement d'email, invitation,
magic link, réauthentification.
2026-02-12 15:45:00 +01:00
3e7f4acda9 fix: supprimer le label « Homme Politique » affiché en dur pour toutes les personnalités 2026-02-12 15:43:42 +01:00
414843062b feat: afficher les erreurs d'authentification dans un bandeau visuel
Le callback transmet maintenant le détail de l'erreur (message Supabase)
dans le query param auth_error. Un composant AuthErrorBanner dans le layout
lit ce param et affiche un bandeau rouge fermable en haut de toutes les pages.
2026-02-12 14:34:53 +01:00
89f46d01cb fix: renommer le titre et trier les personnalités par nombre de sujets concernés
Le titre « LES PERSONNALITÉS RÉCENTES » n'avait pas de sens pour l'utilisateur. Remplacé par « LES PERSONNALITÉS » avec un tri par nombre de sujets décroissant.
2026-02-12 13:22:56 +01:00
2b14d198df fix: utiliser x-forwarded-host pour les redirections derrière un reverse proxy 2026-02-12 10:20:20 +01:00
d5b2f89cb2 feat: trier les prises de position par date décroissante sur la page personnalité 2026-02-12 10:18:06 +01:00
5a677d9df4 feat: trier les positions par nombre de personnalités décroissant 2026-02-12 10:16:15 +01:00
64d8861a61 fix: ajouter emailRedirectTo dans le signUp pour rediriger vers le bon domaine 2026-02-12 08:53:15 +01:00
de6a82f764 feat: ajouter le script migrate et les variables d'env pour le CI/CD Supabase 2026-02-12 02:18:21 +01:00
a8c22c2945 fix: vérifier le token d'inscription côté serveur via une server action 2026-02-12 02:05:49 +01:00
ebf0b38b0b feat: authentification Supabase, entité Contributor, inscription par URL secrète
- Middleware SSR pour rafraîchir les sessions auth
- Route callback /api/auth/callback (échange code PKCE + création contributor)
- LoginModal branché sur signInWithPassword
- SignupModal + page /inscription/[token] protégée par SIGNUP_SECRET_TOKEN
- AuthSection : écoute onAuthStateChange, affiche nom + déconnexion
- Entité domaine Contributor (id, reputation) avec tests TDD
- Migration : rename user_profiles → contributors, suppression colonne name
- Tests colocated avec le code (plus de dossier __tests__/)
- Composant SwitchLink extrait dans components/ui
2026-02-12 01:59:47 +01:00
8e03d127f9 feat: proxifier le script Plausible pour éviter le blocage par les adblockers 2026-02-12 00:26:21 +01:00
56c33323cb feat: ajouter les meta OpenGraph et Twitter pour le partage sur les réseaux sociaux
Mise en place de metadataBase, title.template, openGraph et twitter dans le layout racine. Ajout de descriptions et meta OG spécifiques sur les pages dynamiques (sujets, personnalités).
2026-02-12 00:03:06 +01:00
785aaaf615 fix: ajouter des titres HTML pertinents aux pages sujets et personnalités
Les pages /s, /p, /s/[slug] et /p/[slug] utilisaient le titre générique du layout. Chaque page a maintenant un titre spécifique via metadata ou generateMetadata.
2026-02-11 23:54:14 +01:00
a07200f8cf refactor: déplacer les routes /subjects/:slug vers /s/:slug avec redirection permanente 2026-02-11 23:44:47 +01:00
399298156c feat: migrer les pages SSG vers SSR et consolider le contenu dans le script d'import
Toutes les pages (accueil, sujets, personnalités, détails) utilisent maintenant
createServerSupabaseClient() au lieu du client statique SSG. Cela permet aux mises
à jour de contenu d'être visibles immédiatement sans rebuild.

Le seed.sql est réduit au minimum (auth.users de test uniquement), tout le contenu
étant désormais géré par le script d'import idempotent (npm run import:content).

Ajout du script import:content:production pour cibler la base de production.
2026-02-11 23:29:35 +01:00