billisdead 67bb0095fa Add Légifrance API integration for live legal text injection
Implements a two-layer approach to ensure legal texts are accurate and current:

Option A — runtime injection (legifrance_client.py):
- LegifranceClient: OAuth2 via PISTE (oauth.piste.gouv.fr), fetches consolidated
  article text via api.piste.gouv.fr/dila/legifrance/lf-engine-app
- Redis cache with 24h TTL (in-memory fallback if no Redis)
- build_filter_prompt() injects live texts into the prompt with explicit priority
  over static descriptions — model uses official Légifrance text, not training memory
- Graceful fallback to static prompt if API is unavailable — filtering never blocks

Option B — weekly sync script (scripts/check_legal_refs.py):
- Reads legal_refs.yaml (11 tracked articles, priority critical/high/medium)
- Fetches current text from Légifrance, diffs against stored baseline
- --init: resolves LEGIARTI IDs on first run
- --check: report only; --update: saves new texts to YAML
- Exit code 2 when changes detected (CI/n8n-compatible)

Supporting changes:
- legal_refs.yaml: tracked articles with code LEGITEXT IDs, priorities, rationale
- requirements.txt: add pyyaml>=6.0.2 and requests>=2.32.0
- .env.example: document PISTE_CLIENT_ID, PISTE_CLIENT_SECRET, LEGIFRANCE_CACHE_TTL
- transparence.tsx: document the Légifrance injection for public transparency
- Fixed portal URL: piste.gouv.fr (not piste.api.gouv.fr — verified June 2026)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 09:19:23 +02:00
2026-04-02 02:36:40 +00:00
2026-05-23 18:05:46 +02:00
2026-04-02 02:36:40 +00:00
2026-04-02 02:36:40 +00:00
2026-04-02 02:36:40 +00:00

La Voix du Peuple

Plateforme civique de participation démocratique assistée par intelligence artificielle.

Les citoyens soumettent des propositions politiques en texte libre. Chaque contribution est filtrée automatiquement selon le droit international des droits humains et le droit pénal français, puis intégrée à une synthèse thématique collective générée par IA. La plateforme fonctionne en mode ouvert (contributions globales) ou en mode consultation ciblée (sujet défini, dates de début et de fin, organisateur identifié). Elle ne produit pas un consensus : elle donne à voir ce que des citoyens ont choisi d'exprimer, tel quel.

La Voix du Peuple est un projet personnel open-source. Si vous l'utilisez et voulez soutenir son développement, un don est toujours bienvenu — mais une étoile sur le dépôt et des retours concrets comptent autant.

  • Ko-fi : [LIEN_KO_FI]
  • GitHub Sponsors : [LIEN_GITHUB_SPONSORS]

Fonctionnalités

Contribution citoyenne

  • Formulaire texte libre (10 à 1 000 caractères), pseudonyme optionnel
  • Filtrage IA automatique à la soumission selon quinze textes de référence : DUDH, PIDCP, CEDH, Code pénal français, Loi du 29 juillet 1881, LCEN, SREN 2024, RGPD, et autres
  • Motif de rejet et base légale retournés au contributeur si la contribution est refusée
  • Dialogue de recueil du consentement RGPD avant soumission

Synthèse collective

  • Générée automatiquement à chaque nouvelle contribution acceptée (arrière-plan, non bloquant)
  • Regroupement thématique, ton neutre et factuel, sans formule solennelle
  • Régénération manuelle possible depuis le panel admin

Consultations ciblées

  • Création via le panel admin : slug, titre, sujet, message d'introduction, organisateur, logo, dates d'ouverture et de clôture
  • Fermeture automatique à l'échéance ou manuelle depuis l'admin
  • Webhook de clôture configurable (envoi non bloquant en arrière-plan)
  • Page publique /consultation/:slug avec formulaire de soumission, synthèse et contributions paginées
  • Index public des consultations actives et clôturées (/consultations)

Exports

  • Contributions globales : JSON et CSV (routes publiques)
  • Synthèse de consultation : rendu HTML pour impression ou export PDF navigateur
  • Export CSV complet (admin uniquement, tous champs)

Panel d'administration (protégé par ADMIN_SECRET)

  • Liste des contributions avec filtres (toutes / acceptées / rejetées / signalées), pagination, recherche plein texte
  • Suppression unitaire et en masse, override de statut (accepté/refusé), gestion des signalements
  • Création, clôture et suppression de consultations

Interface publique complémentaire

  • Page des contributions brutes paginées (/contributions-brutes)
  • Signalement de contributions par les visiteurs (limité à 3/min, 10/h par IP)
  • Flyer QR code imprimable configuré sur l'URL du déploiement (/flyer)
  • Partage de la synthèse (copie presse-papier ou partage natif mobile)
  • Pages légales : mentions légales, politique de confidentialité

Accessibilité

  • Dark mode, police dyslexie, contraste élevé, texte agrandi
  • Navigation clavier complète, lien d'évitement pour lecteurs d'écran
  • Préférences persistées dans localStorage

Sécurité et anti-abus

  • Honeypot anti-bot (champ caché côté serveur)
  • hCaptcha optionnel (activé via variables d'environnement)
  • Cooldown cookie signé HMAC-SHA256 entre deux soumissions
  • Rate limiting par IP ou fingerprint (flask-limiter, Redis recommandé en production)
  • Détection de flood (alerte log si dépassement du seuil sur 5 minutes)
  • Fingerprinting non-PII : identifiant FingerprintJS hashé SHA-256, sans cookie tiers
  • En-têtes de sécurité HTTP sur toutes les réponses (CSP, X-Frame-Options, etc.)
  • Sanitisation XSS systématique des entrées (bleach)

Stack technique

Couche Technologie
Frontend React 18 · TypeScript · Vite 7 · Tailwind CSS · shadcn/ui · Wouter
Backend Python 3.11+ · Flask 3 · Gunicorn
Base de données PostgreSQL 15+ (psycopg2, sans ORM)
IA Mistral AI (défaut) ou tout fournisseur compatible API OpenAI
Sécurité flask-limiter · bleach · FingerprintJS · Redis (optionnel) · hCaptcha (optionnel)
Déploiement Nginx · systemd

Installation

Prérequis

  • Python 3.11+
  • Node.js 20+ et pnpm
  • PostgreSQL 15+
  • Un compte Mistral AI (ou un fournisseur compatible OpenAI)

Variables d'environnement

Copier .env.example en .env et renseigner les valeurs :

cp .env.example .env
chmod 600 .env

Obligatoires :

Variable Description
DATABASE_URL Chaîne de connexion PostgreSQL — postgresql://user:pass@host:5432/db
MISTRAL_API_KEY Clé API Mistral AI (ou OPENAI_API_KEY pour un fournisseur alternatif)

Recommandées en production :

Variable Description
SECRET_KEY Active le cooldown cookie signé HMAC-SHA256 — générer avec python3 -c "import secrets; print(secrets.token_hex(32))"
ADMIN_SECRET Mot de passe Bearer token pour le panel /admin
REDIS_URL Rate limiting persistant entre workers — redis://localhost:6379/0 (sinon stockage mémoire, non partagé)
VITE_APP_URL URL publique du site, utilisée par le QR code du flyer
HCAPTCHA_SECRET_KEY Active la vérification hCaptcha côté serveur
VITE_HCAPTCHA_SITE_KEY Clé publique hCaptcha côté frontend (nécessite un rebuild)

Les modèles IA sont configurables via FILTER_MODEL (défaut : mistral-small-latest) et SYNTHESIS_MODEL (défaut : mistral-large-latest).

Développement local

# Prérequis : Node.js et PostgreSQL déjà installés
bash scripts/dev-local.sh

Le script installe automatiquement le virtualenv Python, les dépendances pip et pnpm, puis lance Flask sur le port 8080 et Vite sur le port 5173 en parallèle.

Pour accéder à l'interface depuis un poste distant :

ssh -L 5173:localhost:5173 -L 8080:localhost:8080 utilisateur@votre-serveur
# Puis ouvrir http://localhost:5173

Build frontend

cd artifacts/voix-du-peuple
pnpm install
pnpm build
# Résultat dans artifacts/voix-du-peuple/dist/public/

Pour configurer l'URL du QR code avant le build :

bash scripts/set-domain.sh https://votredomaine.fr

Déploiement en production

La procédure complète (PostgreSQL, Gunicorn, Nginx, systemd) est documentée dans docs/INSTALL_ROCKY.md pour Rocky Linux 9 / AlmaLinux 9 / RHEL 9. Les fichiers de configuration prêts à l'emploi se trouvent dans deploy/.

La base de données est initialisée automatiquement au premier démarrage du backend. Les migrations sont incrémentales et idempotentes — un redémarrage après mise à jour suffit.


Contribuer

Les contributions sont les bienvenues. Voir CONTRIBUTING.md pour les modalités.


Licence

EUPL-1.2 — voir fichier LICENSE.

S
Description
Site d'expression citoyenne
Readme EUPL-1.2 2.2 MiB
Languages
TypeScript 73.7%
Python 22.4%
CSS 2.1%
Shell 1.6%
HTML 0.2%