CLAIR
CLAIR agrège, croise et présente de manière accessible les données publiques sur l'activité des parlementaires (députés et sénateurs), le lobbying et les votes au Parlement.
Install / Use
/learn @accelaire/CLAIRREADME
CLAIR — Citoyen Libre, Analyse, Information, République
Plateforme de transparence politique pour la jeune génération française.
CLAIR agrège, croise et présente de manière accessible les données publiques sur l'activité des parlementaires (députés et sénateurs), le lobbying et les votes au Parlement français.
Le projet est open source, apartisan et factuel : zéro opinion, uniquement des données brutes et des sources vérifiables.
Sommaire
- Objectifs
- Architecture
- Démarrage rapide
- Sources de données
- Scripts disponibles
- Structure de l'API
- Modèle de données
- Configuration
- Stack technique
- Tests
- Qualité des données
- Production
- Documentation
- Contribution
- License
- Crédits
- Contact
Objectifs
- Simplicité : Comprendre ton député ou sénateur en 30 secondes
- Factuel : Données brutes + sources vérifiables, zéro opinion
- Accessible : Interface claire et adaptée au mobile
- Exhaustif : Assemblée Nationale ET Sénat, scrutins, amendements, interventions, lobbying
Architecture
Monorepo pnpm géré par Turborepo avec trois workspaces principaux :
CLAIR/
├── apps/
│ ├── web/ # Frontend Next.js 14 (App Router)
│ └── api/ # Backend Fastify + Prisma
├── packages/
│ ├── shared/ # Types et utilitaires partagés
│ └── config/ # Configs ESLint, TypeScript
├── services/
│ └── ingestion/ # Pipeline d'ingestion des données
├── docs/ # Documentation technique
└── .github/workflows/ # CI/CD
apps/web — Frontend
Next.js 14 avec App Router. Pages principales :
| Route | Description |
|-------|-------------|
| /deputes | Liste et fiches des 577 députés |
| /senateurs | Liste et fiches des 348 sénateurs |
| /scrutins | Votes parlementaires (AN + Sénat) |
| /dossiers | Dossiers législatifs |
| /groupes | Groupes politiques et alliances |
| /lobbying | Représentants d'intérêts (HATVP) |
| /recherche | Recherche globale |
| /explorateur | Explorateur de données |
| /comprendre | Contenus pédagogiques |
| /guide | Guides utilisateur |
apps/api — Backend
Fastify avec un module pattern : src/modules/{feature}/ contenant controller, service et schema (Zod).
Plugins : Prisma, Redis, Rate limiting.
services/ingestion — Pipeline de données
CLI basée sur Commander pour synchroniser les données depuis les sources publiques. Gère le téléchargement, la transformation, le linking entre entités et le calcul des statistiques.
Démarrage rapide
Prérequis
- Node.js >= 20.0.0
- pnpm >= 8.0.0
- Docker & Docker Compose
Installation
# Cloner le repo
git clone https://github.com/accelaire/CLAIR.git
cd CLAIR
# Installer les dépendances
pnpm install
# Copier les variables d'environnement
cp .env.example .env
# Démarrer les services Docker (PostgreSQL, Redis)
pnpm docker:up
# Générer le client Prisma
pnpm db:generate
# Appliquer les migrations
pnpm db:migrate
# (Optionnel) Seed la base avec des données de test
pnpm db:seed
# Lancer en mode développement
pnpm dev
Note : Le
pnpm devlance simultanément le frontend (port 3000) et l'API (port 3001) via Turborepo.
Alimenter la base en données réelles
Pour avoir des données en local, lancer une synchronisation après l'installation :
# Build du service ingestion (nécessaire avant toute sync locale)
pnpm --filter @clair/ingestion build
# Sync incrémental de toutes les sources
pnpm ingestion:smart-sync -- --all
URLs de développement
| Service | URL |
|---------|-----|
| Frontend Web | http://localhost:3000 |
| API | http://localhost:3001 |
| API Docs (Swagger) | http://localhost:3001/docs |
| Prisma Studio | pnpm db:studio |
Sources de données
| Source | Données | Format | Auth | |--------|---------|--------|------| | Assemblée Nationale Open Data | Députés, groupes, scrutins, votes, amendements, dossiers | ZIP/JSON | Aucune | | Sénat Open Data | Sénateurs, groupes, scrutins, votes, amendements, dossiers (DOSLEG) | JSON API + HTML | Aucune | | HATVP | Représentants d'intérêts, actions de lobbying, secteurs | CSV | Aucune | | DILA | Comptes rendus intégraux des débats (interventions) | TAR/XML | Aucune |
Documentation complète : voir docs/INGESTION.md pour le guide détaillé du pipeline d'ingestion.
Scripts disponibles
Développement
pnpm dev # Lancer tous les services en dev (web + api)
pnpm dev:web # Frontend uniquement (port 3000)
pnpm dev:api # Backend uniquement (port 3001)
Build
pnpm build # Build tous les packages
pnpm build:web # Build frontend
pnpm build:api # Build backend
Base de données (Prisma)
pnpm db:generate # Générer le client Prisma
pnpm db:migrate # Appliquer les migrations
pnpm db:push # Push le schema sans migration (dev rapide)
pnpm db:seed # Seed la base avec des données de test
pnpm db:studio # Ouvrir Prisma Studio (interface visuelle)
Docker
pnpm docker:up # Démarrer PostgreSQL, Redis
pnpm docker:down # Arrêter les services
pnpm docker:logs # Suivre les logs
Ingestion des données
# Smart sync (utilisé en production — détection intelligente des changements)
pnpm ingestion:smart-sync -- --all # Toutes les sources
pnpm ingestion:smart-sync -- --force # Forcer même si source inchangée
# Sync manuel (filtres de chambre : --an pour AN, --se pour Sénat)
pnpm ingestion:sync -- -p # Parlementaires (députés + sénateurs)
pnpm ingestion:sync -- --an -p # Députés uniquement
pnpm ingestion:sync -- --se -p # Sénateurs uniquement
pnpm ingestion:sync -- -s # Scrutins AN + Sénat
pnpm ingestion:sync -- --an -s # Scrutins AN uniquement
pnpm ingestion:sync -- --in # Interventions AN + Sénat
pnpm ingestion:sync -- --am # Amendements AN + Sénat
pnpm ingestion:sync -- --an --am # Amendements AN uniquement
pnpm ingestion:sync -- --do # Dossiers législatifs AN + Sénat
pnpm ingestion:sync -- --lo # Lobbyistes + actions (HATVP)
pnpm ingestion:sync -- --lo --no-actions # Lobbyistes sans actions
pnpm ingestion:sync -- -s -l 50 # Limiter à 50 scrutins
# Enrichissement et linking
pnpm ingestion:sync -- --am --enrich # Enrichir amendements par scraping HTML
pnpm ingestion:sync -- --am --link # Lier amendements aux scrutins
pnpm ingestion:sync -- --in --link # Lier interventions aux scrutins
# Backfill complet (historique)
pnpm ingestion:backfill
# Statistiques
pnpm ingestion:calculate-stats # Recalculer toutes les stats
# Diagnostic
pnpm ingestion:status # Vérifier la fraîcheur des sources
Qualité
pnpm lint # Linter (ESLint)
pnpm lint:fix # Fix automatique
pnpm type-check # Vérification TypeScript
pnpm test # Tests unitaires (Vitest)
pnpm test:e2e # Tests E2E (Playwright)
pnpm format # Formatage (Prettier)
Qualité des données
# Validation de l'intégrité des données en base
pnpm --filter @clair/ingestion check-quality
Structure de l'API
Base URL : http://localhost:3001
Endpoints principaux
GET /health # Health check
GET /health/ready # Readiness (DB + Redis)
# Parlementaires (endpoint unifié)
GET /api/v1/parlementaires # Liste (filtrable par chambre, groupe, etc.)
GET /api/v1/parlementaires/groupes # Groupes politiques
GET /api/v1/parlementaires/compare # Comparer 2-4 parlementaires
GET /api/v1/parlementaires/:slug # Fiche détaillée
# Députés (Assemblée Nationale)
GET /api/v1/deputes # Liste des 577 députés
GET /api/v1/deputes/groupes # Groupes politiques AN
GET /api/v1/deputes/:slug # Détail d'un député
# Sénateurs (Sénat)
GET /api/v1/senateurs # Liste des 348 sénateurs
GET /api/v1/senateurs/groupes # Groupes politiques Sénat
GET /api/v1/senateurs/:slug # Détail d'un sénateur
# Groupes politiques
GET /api/v1/groupes # Tous les groupes (filtre chambre)
GET /api/v1/groupes/:chambre/:slug # Détail d'un groupe avec membres
GET /api/v1/groupes/:chambre/:slug/stats # Statistiques du groupe
# Scrutins (votes au Parlement)
GET /api/v1/scrutins # Liste (AN + Sénat, filtres avancés)
# Dossiers législatifs
GET /api/v1/dossiers # Liste avec filtres (état, chambre, procédure)
GET /api/v1/dossiers/:uid # Détail avec scrutins et amendements liés
# Lobbying (HATVP)
GET /api/v1/lobbying # Liste des représentants d'intérêts
GET /api/v1/lobbying/stats # Statistiques lobbying
GET /api/v1/lobbying/secteurs # Secteurs d'activité
# Recherche globale
GET /api/v1/search
