Retour

Feuille de route

Info-Mairie — Feuille de route

v0.1 — MVP Cagnes-sur-Mer ✅

Pipeline d'ingestion ✅

  • [x] Scraper ville.cagnes.fr (122 séances, 265 PDFs)
  • [x] Téléchargement PDFs avec cache SHA-256
  • [x] Parsing PDF (PyMuPDF)
  • [x] Chunking paragraph-aware (1000 chars, 200 overlap)
  • [x] Embeddings OpenAI text-embedding-3-small (1536 dims)
  • [x] Ingestion complète : 12 118 chunks, mars 2004 → déc 2025

Backend FastAPI ✅

  • [x] API séances (liste + détail)
  • [x] API élus (OpenDataSoft)
  • [x] API recherche (pgvector)
  • [x] API chat RAG (Claude streaming SSE)
  • [x] Recherche hybride (vector + full-text, RRF)

Frontend Next.js ✅

  • [x] Page d'accueil (hero + recherche + features)
  • [x] Liste des séances (badges OJ/PV/Délib)
  • [x] Détail séance (liens PDFs)
  • [x] Chat IA (streaming, suggestions)

Infrastructure ✅

  • [x] Supabase cloud (PostgreSQL + pgvector)
  • [x] Repo GitHub privé
  • [x] Blog "Dialogue avec Jean-Claude" (9 articles)

v0.2 — Mise en ligne 🚧

Résumés IA par séance ✅

  • [x] Colonne resume sur table seances
  • [x] Script de génération batch (pipeline/summarize.py)
  • [x] Affichage résumé sur page détail séance (ReactMarkdown)
  • [x] Résumé structuré : points clés, décisions, chiffres
  • [x] Audit liens morts + nettoyage données corrompues
  • [x] Protection pipeline contre redirections HTML

Page "A propos" + Blog dev ✅

  • [x] Page /a-propos : présentation du projet par Jean-Claude (narrateur IA)
  • [x] Mention explicite "initiative citoyenne indépendante"
  • [x] Section /blog : 27 articles "Dialogue avec Jean-Claude"
  • [x] Rendu markdown statique (SSG) avec gray-matter + react-markdown
  • [x] Navigation entre articles, tags, dates
  • [x] Footer avec liens A propos + Blog dev

Déploiement Vercel ✅

  • [x] Frontend Next.js sur Vercel
  • [x] Backend FastAPI sur Vercel (serverless Python)
  • [x] Variables d'environnement en prod
  • [x] Security middleware (rate limiting, headers, request logging)
  • [x] CORS sécurisé (regex pour *.vercel.app)
  • [x] Fix env vars (.strip() contre \n parasites)
  • [ ] Domaine custom (info-mairie.fr ?)

Polish frontend ✅

  • [x] Responsive mobile (navbar, footer, cards, chat adaptés)
  • [x] SEO / meta tags / Open Graph (chaque page avec metadata unique)
  • [x] Filtrage par année sur la page séances + affichage 2004-2025
  • [x] Sources cliquables dans le chat (liens vers les séances utilisées)
  • [x] Page fiche commune (/commune)
  • [x] Loading states et error handling avancés (skeletons, ErrorBoundary, ErrorDisplay)

v0.3 — Multi-commune

Architecture

  • [ ] Sélecteur de commune dans le header
  • [ ] Scraper modulaire (strategy pattern déjà prévu)
  • [ ] Intégration Webdelib (Nice métropole = ~50 communes)

Communes cibles

  • [ ] Nice (YouTube + Webdelib)
  • [ ] Antibes, Grasse, Cannes (WordPress PDFs)
  • [ ] Communes Métropole Nice Côte d'Azur

Pipeline

  • [x] OCR pour anciens PDFs scannés (Google Vision API)
  • [x] GitHub Actions cron pour ingestion automatique
  • [x] Détection de nouvelles séances (pipeline/check_new.py)

v0.4 — Transparence & Accountability

Suivi des présences élus ✅

  • [x] Extraction automatique présents/absents/pouvoirs depuis les PV
  • [x] Table presences en base (élu × séance → statut)
  • [x] Taux de présence par élu (score global)
  • [x] Fiche élu : initiales, fonction, score présence, historique
  • [x] Page trombinoscope (tous les élus, groupés par fonction, barre présence)
  • [x] Affichage des présents sur la page détail séance (chips colorés)
  • [x] 118 séances parsées, 4 989 présences, 2 165 matchées aux élus actuels

Analyse des votes — L'opposition-mètre ✅

  • [x] Extraction des résultats de vote par délibération (unanimité, majorité, voix contre, abstentions)
  • [x] Table votes en base : délibération × élu → pour/contre/abstention/non-votant
  • [x] Vue globale par délibération : taux d'unanimité, sujets les plus contestés
  • [x] Détection automatique du type de vote (unanimité, main levée, scrutin nominatif)
  • [x] Page /votes — tableau de bord des votes avec stats
  • [ ] Vue par séance : pour chaque délibération, qui a voté quoi (tableau coloré)
  • [ ] Vue globale par élu : score de conformisme — vote-t-il toujours avec la majorité ?
  • [ ] Identifier l'opposition réelle vs le conseil "godillot" (score d'indépendance)
  • [ ] Intégration fiche élu : historique de vote, sujets sur lesquels il/elle a voté contre

Démographie du conseil ✅

  • [x] Récupérer date_de_naissance et date_debut_mandat depuis l'API OpenDataSoft
  • [x] Ancienneté au conseil : depuis combien d'années l'élu siège
  • [x] Pyramide des âges du conseil municipal (visualisation CSS)
  • [x] Âge moyen, médian, doyen, benjamin
  • [x] Parité homme/femme avec répartition par fonction (maire, adjoints, conseillers)
  • [x] Durée cumulée en poste : élus +10 ans, +20 ans

Score d'activité par élu ✅

  • [x] Score composite : présence (40%) + interventions (40%) + régularité (20%)
  • [x] Classement des élus par activité (/api/elus/ranking)
  • [x] Badge visuel sur fiche élu : "Très actif", "Actif", "Présent mais discret", "Peu impliqué", "Très peu actif"
  • [x] Composant ActivityBreakdown avec détail des 3 composantes
  • [ ] Comparaison par mandat : l'élu était-il plus actif avant/après une date ?

Analyse des interventions ✅

  • [x] Extraction automatique des interventions depuis les PV (regex speaker detection, format .-)
  • [x] 4 376 interventions extraites, 69 orateurs, 2 409 matchés aux élus actuels
  • [x] Fréquence d'intervention par élu — stats sur fiche élu
  • [x] Nombre de mots par élu (proxy du temps de parole)
  • [x] Affichage stats interventions sur fiche élu (InterventionCard, pagination)
  • [x] Top speakers API endpoint
  • [x] Intervention en contexte : page /interventions/[id] avec interventions ±5 autour
  • [x] Résumé IA caché : génération à la demande + cache en base (intervention_summaries)
  • [x] InterventionCards cliquables sur fiche élu (linkable, highlighted, showOrateur)
  • [ ] Sujets de prédilection par élu (classification Claude)
  • [ ] Nuage de mots par élu — quels thèmes reviennent le plus

Suivi des promesses/projets — Timeline thématique

  • [ ] Extraction auto des projets/sujets récurrents depuis les PV (urbanisme, écoles, budget...)
  • [x] Classification thématique automatique des délibérations (Claude) — pipeline/classify_deliberations.py
  • [ ] Timeline visuelle des projets : voir l'évolution d'un sujet à travers les séances
  • [ ] Page /projets — vue thématique plutôt que chronologique
  • [ ] Statut automatique : annoncé → budgété → en cours → terminé → abandonné ?
  • [ ] Carte des projets — géolocaliser les projets mentionnés sur un plan de la ville

Analyse budgétaire ✅

  • [x] Extraction des montants par délibération (pipeline/extract_budgets.py)
  • [x] Répartition thématique du budget sur page commune
  • [ ] Évolution annuelle — où va l'argent, quelles priorités changent

v0.5 — Recherche avancée & Engagement

Qualité de recherche & RAG 🚧

  • [x] Query expansion / reformulation LLM : Claude reformule la question avec synonymes avant recherche
  • [x] Expansion automatique dans le chat : le RAG chat utilise query expansion par défaut
  • [x] System prompt dynamique : stats live (dernière séance, nombre total, période couverte)
  • [x] Détection requêtes temporelles : "dernier conseil" → injection contexte dernière séance + présences
  • [ ] Contextual Retrieval (Anthropic) : enrichissement sémantique de chaque chunk via Haiku avant embedding (+49% recall) 🔜
  • [ ] Reranking : après la recherche hybride, re-scorer les résultats avec un modèle cross-encoder
  • [ ] Synonymes français : dictionnaire de synonymes courants injecté dans la requête full-text
  • [ ] Filtres contextuels : le LLM détecte automatiquement les filtres implicites
  • [ ] Feedback loop : si le RAG ne trouve rien, reformuler automatiquement et retenter

Recherche avancée (UI)

  • [ ] Filtres par date, type de document, thématique
  • [ ] Recherche par élu (interventions, votes)
  • [ ] Recherche par montant (budget > 100k€)

Blog citoyen auto-généré

  • [ ] Génération automatique d'articles à chaque nouvelle séance ingérée
  • [ ] Résumé vulgarisé des décisions, votes, montants
  • [ ] Fil d'actualité de la ville (pas besoin de poser des questions)
  • [ ] Ton journalistique, accessible, objectif
  • [ ] Page /actualites ou /news sur le site

Alertes & Ingestion automatique 🚧

  • [x] Cron hebdomadaire (GitHub Actions) : scrape le site de la mairie pour détecter nouvelles séances
  • [x] Ingestion automatique : download → parse → chunk → embed → présences → interventions → votes → classify → budget
  • [x] Script pipeline/check_new.py : détection + pipeline complet
  • [ ] Notification email/push aux abonnés quand une nouvelle séance est publiée
  • [ ] Dashboard admin : statut de l'ingestion, erreurs, dernières séances ajoutées

Engagement citoyen

  • [ ] Alertes email/push (nouvelle séance publiée)
  • [ ] Partage de résultats (liens profonds, Open Graph)
  • [ ] Export PDF des résumés
  • [ ] Comparaison entre communes (quand multi-commune actif)
  • [ ] Historique de recherche / favoris (localStorage, zero compte)

Ingestion réseaux sociaux

  • [ ] Scraper les pages Facebook publiques des mairies (posts, événements)
  • [ ] Stocker avec source différenciée (type = "facebook", "website", etc.)
  • [ ] Cron horaire pour détecter les nouveaux posts
  • [ ] Intégration dans le RAG : Jean-Claude cherche dans les PV ET les réseaux
  • [ ] Vision long terme : un seul site-bookmark = toute la vie de la ville

Analytics & Vie privée

  • [ ] Vercel Analytics (zero cookie, privacy-first)
  • [ ] Mention "Zéro cookie" en footer ✅
  • [ ] Aucune donnée personnelle collectée

Scraping presse locale

  • [ ] Nice-Matin / France 3 Côte d'Azur — articles mentionnant la commune
  • [ ] Ingestion avec source différenciée (type = "presse")
  • [ ] Enrichissement du RAG : Jean-Claude peut croiser PV et actualités

Revue municipale Agora

  • [ ] Scraper les numéros du magazine Agora (revue trimestrielle de Cagnes-sur-Mer)
  • [ ] Probablement hébergé sur Calameo/Issuu — extraire les PDFs
  • [ ] OCR si nécessaire, chunker et ingérer comme source différenciée (type = "agora")
  • [ ] Enrichissement du RAG : Jean-Claude peut croiser PV, presse et communication municipale

Connaissance de la ville — Contexte géographique & historique 🚧

Problème : Jean-Claude ne connaît pas la ville. Si un citoyen demande "des travaux en centre-ville", il ne sait pas que La Villette = centre-ville, que le Cros-de-Cagnes = bord de mer, que le Haut-de-Cagnes = village médiéval. Sans ce contexte, le RAG passe à côté de résultats pertinents.

Principe : zéro génération IA. Uniquement des données factuelles vérifiables, scrapées depuis des sources officielles ou communautaires fiables. Chaque chunk porte un source_type + source_url pour traçabilité.

Phase 1 — Wikipédia FR (immédiat) 🚧

  • [ ] Scraper l'article Wikipédia "Cagnes-sur-Mer" (géographie, quartiers, histoire, patrimoine, démographie, personnalités)
  • [ ] Chunker par section (chaque section = 1+ chunks avec titre de section comme métadonnée)
  • [ ] Embedder et ingérer avec source_type = "wikipedia", source_url = "https://fr.wikipedia.org/wiki/Cagnes-sur-Mer"
  • [ ] Tester : "où est La Villette ?" → Jean-Claude doit répondre avec contexte géographique

Phase 2 — Site officiel ville.cagnes.fr

  • [ ] Scraper les pages quartiers, équipements, histoire, projets en cours
  • [ ] Ingérer avec source_type = "site_officiel"
  • [ ] Enrichissement : noms de rues, écoles, parcs, équipements sportifs, marchés

Phase 3 — PLU métropolitain (gold) ⭐

  • [ ] Récupérer le PLUm de la Métropole Nice Côte d'Azur (documents publics, consultables en ligne)
  • [ ] Versionnage temporel : stocker chaque version du PLU avec sa date d'entrée en vigueur et sa date de fin
  • [ ] Ingérer le règlement par zone (UA, UB, UC, UD, AU, N, A...) avec les règles de constructibilité
  • [ ] Ingérer le PADD (Projet d'Aménagement et de Développement Durable)
  • [ ] Ingérer les OAP (Orientations d'Aménagement et de Programmation) par secteur
  • [ ] Requête temporelle : "Ce projet voté le 15/03/2023 respecte-t-il le PLU en vigueur à cette date ?"
  • [ ] Croiser délibérations urbanisme × zonage PLU × règlement applicable

Phase 4 — Données géographiques

  • [ ] OpenStreetMap : extraire quartiers, POIs, rues de Cagnes-sur-Mer (API Overpass)
  • [ ] IGN/Géoportail : toponymes officiels, relief, limites communales
  • [ ] Cadastre : parcelles, zonage (cadastre.gouv.fr)

Phase 5 — Sources complémentaires

  • [ ] Archives départementales des Alpes-Maritimes (histoire documentée)
  • [ ] Données INSEE (IRIS = découpage infra-communal avec stats socio-démographiques par quartier)
  • [ ] DREAL PACA : risques naturels (PPRI, PPR incendie) — utile pour les délibérations environnement

Architecture technique

  • Nouveau source_type dans la table documents : "wikipedia", "site_officiel", "plu", "osm", etc.
  • Chaque chunk porte : source_type, source_url, source_date (date de consultation/version)
  • Le RAG cherche dans TOUS les types de sources (PV + contexte ville) par défaut
  • Le system prompt de Jean-Claude mentionne qu'il a accès au contexte géographique et historique
  • Pour le PLU : champ date_debut et date_fin pour filtrer par période d'application

Données complémentaires

  • [ ] Budgets municipaux (extraction structurée)
  • [ ] Délibérations individuelles (pas juste les PV)
  • [ ] Liens avec data.gouv.fr quand disponible

v0.5b — Spécial Élections Municipales 2026 🗳️

Élections à Cagnes-sur-Mer : 15 et 22 mars 2026 5 candidats identifiés à ce stade

Candidats connus (Cagnes-sur-Mer)

| Candidat | Site de campagne | Notes | |----------|-----------------|-------| | Louis Nègre | louisnegre2026.fr | Maire sortant, "dernier mandat", 10 engagements | | Bryan Masson | bryanmasson2026.fr | Site Wix | | Touzeau-Menoni | À identifier | | | Pierre Piacentini | À identifier | | | Garoyan | À identifier | |

Scraping des programmes

  • [ ] Scraper les sites de campagne des candidats (textes, engagements, équipes)
  • [ ] Stocker les programmes par candidat avec source et date de scraping
  • [ ] Gérer les sites Wix/SPA : headless browser (Playwright) si nécessaire
  • [ ] Actualiser régulièrement (les programmes évoluent avant le scrutin)

Page candidats sur Info-Mairie

  • [ ] Page /elections — vue d'ensemble : date du scrutin, liste des candidats, liens vers programmes
  • [ ] Fiche par candidat (/elections/{slug}) : programme, équipe, engagements
  • [ ] Lien vers le site officiel du candidat + mention "données publiques"
  • [ ] Affichage neutre et équitable : même format pour chaque candidat

Analyse IA des programmes

  • [ ] Comparaison programme vs bilan : Jean-Claude compare les promesses d'un candidat avec ce qui a été voté/fait au conseil (20 ans de PV)
  • [ ] Détection d'incohérences : un candidat promet X mais a voté contre X au conseil ?
  • [ ] Faisabilité budgétaire : croiser les montants promis avec les budgets historiques de la commune
  • [ ] Thématiques comparées : tableau comparatif des candidats par thème (urbanisme, sécurité, culture, etc.)
  • [ ] Chat RAG enrichi : "Que propose [candidat] sur les écoles ?" → réponse sourcée depuis le programme + historique PV

Garde-fous éthiques

  • [ ] Neutralité absolue : pas de classement, pas de recommandation, pas d'opinion
  • [ ] Sources vérifiables : chaque affirmation cite la source (programme du candidat, PV de séance, vote)
  • [ ] Transparence méthodologique : page expliquant comment l'analyse est faite
  • [ ] Droit de réponse : formulaire de contact pour les candidats qui contestent une analyse
  • [ ] Mentions légales : respect de la période de réserve électorale

v0.5c — Agora citoyenne 🏛️ ✅

Espace public de dialogue entre citoyens, modéré par Jean-Claude.

Concept ✅

  • [x] Page /agora — grille de 8 catégories (Urbanisme, Budget, Vie quotidienne, Éducation, Culture & Sport, Environnement, Sécurité, Divers)
  • [x] Page /agora/[category] — liste de threads, tri récent/populaire, nouveau sujet
  • [x] Page /agora/[category]/[thread] — détail, replies, votes, formulaire réponse
  • [x] Jean-Claude auto-reply — après création d'un thread, RAG → Claude → réponse automatique avec sources
  • [x] Votes up/down anonymes (hash IP SHA-256, unique par thread/reply)
  • [x] Anti-spam : honeypot, validation longueur
  • [x] Backend : 7 endpoints CRUD (categories, threads, replies, votes)
  • [x] Migration SQL avec trigger auto-update stats

À venir

  • [ ] Jean-Claude modération temps réel (injures, diffamation)
  • [ ] Tags thématiques auto-générés par discussion
  • [ ] Résumé IA des discussions longues
  • [ ] Inscription légère (email vérifié) pour anti-abus avancé

v0.5d — Connaissance juridique française 📜

Jean-Claude cite la loi. Il sait que le maire a des obligations légales. Uniquement RAG — jamais de génération juridique sans source.

Phase 1 — CGCT (Code général des collectivités territoriales)

  • [ ] Ingestion via API Légifrance (AIFE) — articles du CGCT en vigueur
  • [ ] Chunking par article avec préfixe [CGCT — L.2121-7 — Réunion du conseil municipal]
  • [ ] source_type = "legislation", source_url = lien Légifrance
  • [ ] Le RAG croise PV + article de loi : "Le maire a-t-il le droit de..." → PV + texte de loi

Phase 2 — Code de l'urbanisme

  • [ ] Articles pertinents : PLU, permis de construire, droit de préemption (L.421-1 à L.424-9)
  • [ ] Croiser avec délibérations urbanisme

Phase 3 — CRPA (Code des relations entre le public et l'administration)

  • [ ] Droits des citoyens : accès aux documents, délais de réponse, transparence
  • [ ] Permettre "quels sont mes droits si la mairie ne répond pas ?"

Phase 4 — Code de la commande publique

  • [ ] Marchés publics, appels d'offres, seuils
  • [ ] Croiser avec délibérations budget/marchés

Architecture

  • [ ] Pipeline ingest_legifrance.py — API AIFE ou scraping Légifrance
  • [ ] Chunking par article avec métadonnées (code, section, numéro article, date version)
  • [ ] Versionnage : chaque article a une date_vigueur pour requêtes temporelles
  • [ ] source_type = "legislation" dans la table documents

v0.5e — Simplification des démarches 📋 (futur)

Jean-Claude aide les citoyens à comprendre les procédures administratives. Sources : service-public.fr (API), démarches-simplifiées, site mairie.

Concept

  • [ ] "Comment obtenir un permis de construire ?" → étapes, documents nécessaires, délais
  • [ ] Ingestion service-public.fr — fiches pratiques par démarche
  • [ ] Croiser avec contexte local : "À Cagnes, le service urbanisme est au..."
  • [ ] Page /demarches — guide des démarches courantes, filtré par commune

Un litige ? Une question ? Besoin d'aide ?

  • [ ] CTA "Prendre rendez-vous avec un avocat" — orientation vers les consultations juridiques gratuites de la ville
  • [ ] Détection automatique : si Jean-Claude identifie un litige potentiel dans la conversation → suggestion proactive
  • [ ] Annuaire des permanences juridiques gratuites (mairie, maison de justice, CDAD)
  • [ ] Liens vers les avocats du barreau local (API annuaire des barreaux si dispo)
  • [ ] Disclaimer clair : "Jean-Claude informe, il ne conseille pas. Pour un avis juridique, consultez un professionnel."

v0.6 — Intelligence & Insights

Détection d'anomalies

  • [ ] Alerter quand un montant est anormalement élevé par rapport à l'historique
  • [ ] Détecter les délibérations qui passent sans débat (unanimité silencieuse sur gros montants)
  • [ ] Identifier les élus dont le taux de présence chute brusquement

Comparaisons inter-communes

  • [ ] Benchmarking : budget/habitant, taux de présence moyen, fréquence des séances
  • [ ] Classement des communes les plus transparentes (nombre de PV publiés, délais de publication)
  • [ ] Partage de données entre communes pour enrichir le RAG

v0.7 — Monétisation & SaaS

Le produit est gratuit pour les citoyens dans sa version de base. La valeur ajoutée (juridique, multi-commune, API) peut être monétisée.

Tiers & Gating

| Tier | Cible | Prix | Inclus | |------|-------|------|--------| | Citoyen (gratuit) | Grand public | 0€ | PV, présences, interventions, élus, Wikipedia, Agora, chat (X questions/jour) | | Citoyen+ | Citoyen engagé | ~3-5€/mois | Chat illimité, recherche juridique croisée (PV + loi), alertes personnalisées, export PDF | | Élu / Candidat | Candidats municipaux | ~20€/mois | Analyse comparative programmes vs bilan, dashboard élection, données historiques complètes | | Collectivité | Mairies, interco | ~200-500€/mois | Multi-commune, API access, dashboard analytics, support, marque blanche possible | | Cabinet / Avocat | Professionnels du droit | ~50-100€/mois | Recherche juridique avancée (codes + jurisprudence), requêtes temporelles, volume illimité |

Features premium (backlog)

  • [ ] Middleware de gating : vérification du tier avant chaque endpoint (header API key ou session)
  • [ ] Compteur de questions : X questions/jour gratuit, au-delà → upgrade
  • [ ] Recherche juridique croisée : PV + article de loi + jurisprudence → tier payant
  • [ ] Requêtes temporelles historiques : "la loi en 2018 ?" → fetcher les versions anciennes des articles (articleVersions API)
  • [ ] CTA avocat : orientation vers consultations juridiques → affiliation ou partenariat barreaux
  • [ ] Export PDF : résumés de séance, fiches élu, analyses → watermarked avec tier
  • [ ] Alertes personnalisées : nouvelle séance, mot-clé détecté, élu suivi → email/push
  • [ ] API publique : endpoints documentés avec rate limiting par tier
  • [ ] Dashboard collectivité : stats d'utilisation, questions fréquentes des citoyens, insights
  • [ ] Marque blanche : le produit sous la marque de la collectivité
  • [ ] Stripe integration : paiement, abonnements, factures

Modèle de revenus potentiels

  • [ ] B2C : abonnement citoyen+ (volume = beaucoup de petits montants)
  • [ ] B2B : licence collectivité (peu de clients, gros tickets)
  • [ ] B2B2C : la collectivité paie pour que ses citoyens aient accès premium
  • [ ] Affiliation : CTA avocat / notaire / service juridique en ligne
  • [ ] Freemium : le gratuit génère du trafic, le payant génère du revenu

Dernière mise à jour : 11 février 2026 (v0.7 Monétisation + v0.5d Légifrance + Contextual Retrieval + Agora)