CLAIR DocsCLAIR Docs
  • clair.vote
  • GitHub
  • Nous soutenir
Nous soutenir
  • Accueil
  • Plateforme & Guide
  • Données & Base de Données
  • Explorateur API
CLAIR

Plateforme citoyenne de transparence politique. Données 100% publiques, 0% d'opinion.

Explorer

  • Députés
  • Sénateurs
  • Groupes politiques
  • Sujets
  • Dossiers législatifs
  • Scrutins
  • Agenda
  • Lobbying

Ressources

  • Nous soutenir
  • À propos
  • Méthodologie
  • Contact
  • Comprendre
  • Guide pratique
  • API ouverte

Légal

  • Mentions légales
  • Confidentialité
  • CGU

© 2026 CLAIR. Sources : Assemblée nationale · Sénat · HATVP · Ministère de l'Intérieur · DILA

Vue d'ensembleCommandes CLIEnrichissement IAModèle PrismaOrchestrateur d'IngestionQualité des DonnéesSchémas ERDSources Open DataSuivi des Modifications
Données & Base de Données

Commandes CLI & Scripts d'Ingestion

🛠️ Scripts du monorepo

TerminalCode
# Développement pnpm dev # tous les workspaces en mode dev (web :3000, API :3001, docs :3002) pnpm dev:web # frontend seul pnpm dev:api # API seule pnpm dev:docs # documentation seule # Build pnpm build # tous les workspaces pnpm build:web pnpm build:api pnpm build:docs pnpm --filter @clair/ingestion build # CLI d'ingestion (tsup → services/ingestion/dist) # Base de données (Prisma, exécuté dans apps/api) pnpm db:generate # prisma generate pnpm db:push # prisma db push (schéma sans migration), puis les triggers pnpm db:triggers # rejoue seulement apps/api/prisma/triggers.sql pnpm db:migrate # prisma migrate dev : échoue, voir plus bas pnpm db:seed # données de test (apps/api/prisma/seed.ts) pnpm db:studio # Prisma Studio # Docker (PostgreSQL + Redis locaux) pnpm docker:up pnpm docker:down pnpm docker:logs # Qualité du code pnpm lint # ESLint sur tous les workspaces, plus scripts/ et apps/api/prisma pnpm lint:fix pnpm type-check # tsc --noEmit pnpm test # Vitest (API, ingestion, proxy /api/v1 du frontend) pnpm format # Prettier # Documentation pnpm docs:nav # régénère la navigation après ajout, renommage ou suppression d'une page pnpm docs:validate # syntaxe MDX et liens internes pnpm docs:erd # régénère les diagrammes de la base depuis le schéma Prisma

pnpm test:e2e est déclaré dans turbo.json, mais aucun workspace ne définit de script test:e2e : la commande ne lance rien.

pnpm db:migrate lance prisma migrate dev, qui rejoue l'historique des migrations dans une base fantôme : il échoue (erreur P3006 sur 20260313_add_sujets), car cet historique ne se rejoue pas depuis une base vide. Pour créer ou appliquer une migration, voir Modèle Prisma.


⚙️ La CLI d'ingestion

Point d'entrée : services/ingestion/src/cli.ts. Six commandes ont un raccourci à la racine ; toutes les autres se lancent par exec :

TerminalCode
pnpm ingestion:sync ... # = sync pnpm ingestion:smart-sync ... # = smart-sync pnpm ingestion:backfill # = backfill pnpm ingestion:status # = status pnpm ingestion:calculate-stats ... # = calculate-stats pnpm ingestion:schedule # = schedule pnpm --filter @clair/ingestion check-quality pnpm --filter @clair/ingestion exec tsx src/cli.ts <commande> [options]

Les options se passent directement (pnpm ingestion:sync -p) ou après -- (pnpm ingestion:sync -- -p) : la CLI retire elle-même le -- que pnpm transmet.

En production, la CLI tourne depuis le build : node services/ingestion/dist/cli.js <commande>. En local, lancer pnpm --filter @clair/ingestion build avant toute synchronisation.


🚀 smart-sync : synchronisation par fraîcheur

C'est la commande du batch nocturne. Son déroulé complet est sur la page Orchestrateur d'ingestion.

TerminalCode
pnpm ingestion:smart-sync -a # tout, dans l'ordre de production pnpm ingestion:smart-sync -a --force # sans tenir compte des ETag / Last-Modified pnpm ingestion:smart-sync -a --skip-stats # sans recalcul des statistiques pnpm ingestion:smart-sync -a -l 100 # limite appliquée à chaque type de données pnpm ingestion:smart-sync --sources senat:agenda,senat:videos # clés de sources explicites

Sans -a ni --sources, la commande traite assemblee_nationale:deputes et senat:senateurs, plus les familles demandées : -s (scrutins), --am (amendements), --do (dossiers), --in (interventions), --lo (lobbying), --co (commissions), --re (réunions AN), --seances-odj, --senat-histo, --gouvernements, --senat-agenda, --senat-reunions, --senat-fonctions, --senat-dossier-commissions, --senat-videos, --an-videos, --candidatures.


🎯 sync : synchronisation manuelle d'un type de données

Filtre de chambre : --an (Assemblée), --se (Sénat), rien pour les deux. Un seul type de données est traité par appel.

TerminalCode
pnpm ingestion:sync # sans option : députés + sénateurs pnpm ingestion:sync -p # parlementaires pnpm ingestion:sync -p --an --legislature 16 # députés d'une législature passée (15, 16 ou 17) pnpm ingestion:sync -g # groupes politiques pnpm ingestion:sync -s # scrutins et votes pnpm ingestion:sync -s --an --legislature 16 pnpm ingestion:sync -s --se --sessions 2006,2007 # scrutins du Sénat par sessions pnpm ingestion:sync --am # amendements pnpm ingestion:sync --am --an --legislature 15 --archive <chemin> # amendements AN d'une législature passée pnpm ingestion:sync --do # dossiers législatifs (--do --an --legislature 16 pour le passé) pnpm ingestion:sync --in --se # interventions du Sénat (deux dernières années par défaut) pnpm ingestion:sync --in --se --depuis-annee 2017 --rattrapage pnpm ingestion:sync --lo # lobbyistes et actions (HATVP) pnpm ingestion:sync --lo --no-actions # lobbyistes sans les actions pnpm ingestion:sync --de # déclarations HATVP des parlementaires pnpm ingestion:sync --co # commissions et organes pnpm ingestion:sync --re # réunions et agenda pnpm ingestion:sync --seances-odj # ordre du jour des séances publiques (AN) pnpm ingestion:sync -s -l 50 # limiter le nombre d'éléments pnpm ingestion:sync -f # synchronisation complète des députés et sénateurs # Rattachement scrutins ↔ amendements pnpm ingestion:sync --am --enrich # lecture des pages de scrutin sans lien (--an / --se) pnpm ingestion:sync --am --enrich --an --only <idScrutin...> pnpm ingestion:sync --am --link # rapprochement par numéro, contraint par le dossier pnpm ingestion:sync --am --link --reset # efface les liens avant de les recréer

sync --in sans --se lit la source DILA, où plus rien n'est publié depuis janvier 2026. Les débats de l'Assemblée s'ingèrent désormais avec sync-debats-an (ou le smart-sync).

L'aide de --link mentionne les interventions, mais seul --am --link est implémenté : sync --in --link relance une synchronisation des interventions. Le rattachement des débats aux scrutins se fait avec link-debats-scrutins et link-debats-scrutins-senat.

Autres options de sync : --dry-run, --reset, -c (circonscriptions, avec -p --an), --ameli et --texte-ids (mode AMELI des amendements du Sénat), --archive (archive des amendements AN déjà téléchargée).


🔁 backfill

TerminalCode
pnpm ingestion:backfill

Synchronisation complète des députés et sénateurs uniquement (la même chose que sync -f). Ce n'est pas un rechargement de l'historique : pour cela, voir la section suivante.


🕰️ Rattrapage de l'historique

Le batch nocturne ne lit que la législature courante de l'Assemblée et une fenêtre récente du Sénat. L'historique se rattrape par des commandes ponctuelles :

TerminalCode
# Assemblée, législatures 15 et 16 pnpm ingestion:sync -p --an --legislature 16 pnpm ingestion:sync -s --an --legislature 16 pnpm ingestion:sync --do --an --legislature 16 pnpm ingestion:sync --am --an --legislature 16 # Sénat : annuaire des anciens sénateurs AVANT les scrutins (les votes ont besoin du roster) pnpm --filter @clair/ingestion exec tsx src/cli.ts sync-senateurs-histo --depuis 2006-10-01 pnpm ingestion:sync -s --se --sessions 2006,2007 # puis tranche par tranche # Relancer ensuite la synchronisation courante des parlementaires, puis les stats des législatures figées pnpm ingestion:sync -p pnpm ingestion:calculate-stats --include-frozen

Le chargement d'une législature passée met à jour la chambre des personnes ayant siégé dans les deux assemblées ; la synchronisation courante sync -p, relancée en dernier, la rétablit.

Le rapprochement scrutins ↔ amendements (sync --am --link) s'appuie sur le dossier des amendements : après le chargement d'amendements anciens, lancer link-amendements-dossiers avant lui.


📊 Statistiques

TerminalCode
pnpm ingestion:calculate-stats # parlementaires puis groupes pnpm ingestion:calculate-stats --parlementaires-only pnpm ingestion:calculate-stats --groupes-only pnpm ingestion:calculate-stats -c assemblee # ou senat pnpm ingestion:calculate-stats --include-frozen # recalcule aussi les législatures passées

Calcule la présence (hors scrutins où l'élu ne pouvait pas voter : présidence de l'assemblée, présidence de séance, gouvernement), la présence aux scrutins solennels (au Sénat, un vote par délégation y compte comme une absence), la loyauté au groupe, la participation, les compteurs d'interventions et d'amendements, les stats de carrière, les stats par mandat, puis les stats de groupes, les alliances entre groupes et les positions par thématique. reconcile-actif réaligne parlementaires.actif sur l'existence d'un mandat en cours.

Les scrutins où l'élu ne pouvait pas voter viennent du statut publié sur la ligne du vote (votes.statut_votant), des présidences datées (bureau du Sénat dans mandats, presidences_assemblee pour l'Assemblée) et des postes ministériels (postes_ministeriels) : un membre du Gouvernement ne vote pas, même quand son mandat reste ouvert dans la source. Les législatures révolues ne sont recalculées qu'avec --include-frozen. Le calcul enregistre aussi le nombre de scrutins sur lequel porte chaque présence (stats_scrutins, stats_carriere_scrutins) et si ce nombre atteint le seuil des classements, 50 scrutins (stats_classable, stats_carriere_classable ; SEUIL_SCRUTINS_CLASSEMENT). Le seuil vaut pour la loyauté et la présence des députés ; celle des sénateurs se classe sur les scrutins solennels, sans seuil. Sans aucun scrutin à évaluer, la présence et la loyauté valent null, jamais 0 : l'API les rend null et les classements les placent en fin de liste dans les deux sens de tri. Le compteur de questions posées écarte les réponses des membres du Gouvernement (type reponse_gouvernement, reconnu à la qualité imprimée de l'orateur, dans les deux chambres).


🤖 Enrichissement IA

Voir Enrichissement IA.

TerminalCode
pnpm --filter @clair/ingestion exec tsx src/cli.ts enrich-ia # tout, en cascade pnpm --filter @clair/ingestion exec tsx src/cli.ts enrich-ia --scrutins # ou --dossiers, --sujets, # --groupe-amendements, --parlementaires
OptionEffet
-l, --limit <n>Nombre maximum d'entités régénérées (les entités inchangées ne comptent pas)
--dry-runCalcule sans écrire
--previewGénère et affiche les textes sans rien écrire, pour valider un prompt (avec --only et --force)
--forceIgnore l'empreinte et régénère
--only <ids...>Cible des entités précises : id de scrutin, uid de dossier, slug de sujet ou de parlementaire
--rehashRecalcule et stocke l'empreinte sans appeler le LLM (après un changement de formule d'empreinte)
--random <n>Parlementaires : régénère un échantillon aléatoire de N fiches
--skip-recent-days <n>Avec --random : exclut les fiches rafraîchies depuis moins de N jours (défaut 3)
--perimees <n>Parlementaires : régénère au plus N fiches devenues périmées, les plus anciennes d'abord
-c, --concurrency <n>Appels LLM en parallèle (défaut 3)

✅ Qualité

TerminalCode
pnpm --filter @clair/ingestion test # tests unitaires pnpm --filter @clair/ingestion check-quality # contrôles de la base, code de sortie 1 si échec pnpm --filter @clair/ingestion exec tsx src/cli.ts check-ia-quality # contrôles des résumés IA pnpm ingestion:status # fraîcheur des sources

Détail des contrôles : Qualité des données.


📚 Toutes les commandes

CommandeRôle
syncSynchronisation manuelle d'un type de données (voir plus haut)
smart-syncSynchronisation par fraîcheur, utilisée par le batch nocturne
sync-intradayAgenda du Sénat du jour et vidéos AN + Sénat (batch intraday)
backfillSynchronisation complète des députés et sénateurs
statusFraîcheur de chaque source
testTeste la connexion aux sources
schedulePlanificateur node-cron dans le processus (-d pour afficher les horaires sans exécuter). Non utilisé en production
calculate-statsStatistiques des parlementaires et des groupes
reconcile-actifRéaligne parlementaires.actif sur « a un mandat en cours »
backfill-mandatsInitialisation des mandats parlementaires multi-législatures (idempotent)
backfill-nature-voteClasse la nature des scrutins (--force pour tout reclasser)
sync-senateurs-histoAnciens sénateurs depuis l'open data ODSEN (--depuis <date>)
sync-senat-fonctionsFonctions datées des sénateurs depuis export_sens.zip (--archive <chemin> pour un zip déjà téléchargé)
sync-gouvernementsGouvernements depuis 2007, postes ministériels, présidences de la République et de l'Assemblée, lus dans l'archive AMO30 de l'Assemblée ; rattache chacun à sa fiche parlementaire
clore-mandats-anClôt les mandats de député des sortants (élus sénateurs compris) et les mandats d'organe AN qui survivent au mandat de député (--dry-run)
sync-debats-anComptes rendus de séance de l'Assemblée (source syceron). Options : --legislature (défaut 17), --max-seances, --repertoire, --reingerer
sync-debats-commissionComptes rendus de commission de l'Assemblée (PDF). Options : --depuis, --max-reunions, --seulement, --reingerer, --dry-run
sync-avis-commissionAvis de commission sur les amendements. Mêmes options que ci-dessus
sync-textes-articlesTexte des articles des textes de l'Assemblée. Options : --texte, --limit, --force, --dry-run
sync-index-legiIndex de la base LEGI de la DILA (legi_textes, legi_articles). Le premier passage charge le dump global (1,1 Go à télécharger), puis rejoue tous ses incréments ; les suivants n'appliquent que les incréments nouveaux. Options : --limite <n> (incréments appliqués), --reinitialiser (vide l'index et repart du dernier dump global, à lancer si la DILA en publie un nouveau)
sync-renvois-legiRepère dans le dispositif des amendements les textes et articles de loi cités, et les rattache à l'index LEGI, dans la version en vigueur à la date de dépôt (amendements_renvois). Ne traite que les amendements nouveaux, modifiés ou récents. Options : --tout (tout recalculer), --limite <n>, --uid <uid>, --dry-run
fill-article-vise-senatComble l'article visé des amendements du Sénat depuis le dump AMELI, sans écraser une valeur existante (--depuis-annee, --dry-run)
fill-metadonnees-senatAligne discussions, numéro d'alinéa et parent des sous-amendements du Sénat sur le dump AMELI, sur tout l'historique (--dry-run)
sync-agenda-senatAgenda du Sénat sur une fenêtre (--jours-avant, défaut 45 ; --jours-apres, défaut 30)
sync-videos-anVidéos de l'Assemblée (--jours-avant <n> pour remonter l'historique)
sync-videos-commission-senatVidéos des réunions de commission du Sénat
sync-evenementsListe curée des événements institutionnels
sync-candidaturesCandidatures depuis les fichiers du ministère (--fichier obligatoire, répétable ; --scrutin, --simulation, --forcer-chute)
sync-resultats-senatorialesRésultats lus sur le site du ministère (--departement, --a-blanc pour lire sans écrire, --boucle <secondes> pour relancer en continu, --dossier-local pour un site simulé, --base-url). Sort en erreur sur une page 404
sync-mandats-locauxMandats locaux des candidats depuis le Répertoire national des élus (--simulation, --dossier-local)
generer-reference-hemicycleComposition du Sénat par nuance à l'élection précédente de chaque série (--sortie <fichier> obligatoire)
simuler-soiree-senatorialesFabrique un faux site de résultats, aux chiffres fictifs, pour tester la chaîne en local (--etape matin|midi|soir|complet, --dossier)
link-debats-scrutinsRattache les débats de l'Assemblée aux scrutins (--legislature, --refaire-tout, --dry-run, --sortie)
link-debats-scrutins-senatRattache les débats du Sénat aux scrutins (--depuis-annee, défaut 2024 ; --remplacer-journees, --refaire-tout, --dry-run)
segmenter-debats-senatSitue les interventions du Sénat dans la structure du débat (--depuis-annee, défaut 2024)
link-interventions-dossiersRattache les prises de parole à leur dossier
link-scrutins-dossiersScrutins AN orphelins → dossiers, par le titre
link-scrutins-tfidfScrutins orphelins → dossiers, par similarité TF-IDF des titres
link-by-texte-numeroScrutins orphelins → dossiers, par numéro de texte partagé
link-by-loi-titreScrutins orphelins → dossiers, par titre de la loi promulguée
link-amendements-dossiersRattache les amendements à leur dossier : texte de la source d'abord, puis scrutins et amendements voisins
unlink-wrong-legislatureSupprime les liens scrutin AN → dossier d'une autre législature
unlink-procedure-incompatibleSupprime les liens scrutin → dossier incompatibles avec la procédure du dossier : rapport ou mission d'information, 49.3 hors motion de censure
separer-homonyme <slug> <matricule ou PA>Rend à l'homonyme de l'autre chambre sa fiche, avec ses mandats et ses votes de cette chambre (--appliquer, sinon simulation)
lier-identifiant <slug> <chambre> <id>Range sur la fiche l'identifiant de l'autre chambre d'un élu passé de l'une à l'autre (--appliquer)
relink-voterefsRattache chaque scrutin AN au dossier qui le référence (voteRefs de la source), en corrigeant les liens contraires
verifier-amendements-scrutins-anFiabilise les liens scrutin AN → amendement : efface les impossibles, revérifie les douteux sur la page de l'Assemblée, puis aligne leur dossier (--dry-run, --concurrence, --articles)
generate-sujetsGénère les sujets (--reset, --dry-run)
relabel-sujetsRecalcule le libellé des sujets restés sur un identifiant technique
reslug-sujetsRecalcule leur slug. Change les URLs publiques : purger ensuite le cache Redis (sujets:*, sitemap:*)
generate-sujet-linksLiens « construction » des sujets (--no-validate, --dry-run)
generate-sujet-contextLiens « contexte » des sujets (--incremental, -l, -c, --dry-run)
enrich-iaEnrichissement IA
check-qualityContrôles de qualité de la base
check-ia-qualityContrôles des résumés IA
Vue d'ensembleEnrichissement IA
On this page
  • 🛠️ Scripts du monorepo
  • ⚙️ La CLI d'ingestion
  • 🚀 smart-sync : synchronisation par fraîcheur
  • 🎯 sync : synchronisation manuelle d'un type de données
  • 🔁 backfill
  • 🕰️ Rattrapage de l'historique
  • 📊 Statistiques
  • 🤖 Enrichissement IA
  • ✅ Qualité
  • 📚 Toutes les commandes