Files
la-voix-du-peuple/docs/DAT.md
T
pironantoine 213a67e612 Create documentation for project architecture, deployment, and usage
Add DAT, DEX, GITEA_TUTO, and WIKI markdown files to the docs directory, and update agent_assets_metadata.toml to include these new documents.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 923ae0e3-a363-4db8-b04a-e8baca2a1330
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 4bb1a658-d577-451e-965c-fa15e2c21ca9
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8af7d2ec-2cc3-4ece-8af3-9f071488d072/923ae0e3-a363-4db8-b04a-e8baca2a1330/RusmVRz
Replit-Helium-Checkpoint-Created: true
2026-04-04 06:56:49 +00:00

8.5 KiB
Raw Blame History

Document d'Architecture Technique — La Voix du Peuple

Version : 1.0
Date : Avril 2026
Statut : En production (Replit), prêt pour auto-hébergement


1. Présentation générale

La Voix du Peuple est une plateforme civique permettant à des citoyens de soumettre des propositions politiques. Ces contributions sont :

  1. Filtrées par un agent IA selon le droit international des droits humains
  2. Synthétisées automatiquement en un résumé clair par thème
  3. Affichées en temps réel à destination d'élus ou de décideurs

2. Architecture globale

┌─────────────────────────────────────────────────────────┐
│                     Navigateur client                   │
│              React + Vite (TypeScript)                  │
└────────────────────────┬────────────────────────────────┘
                         │ HTTP/REST (JSON)
                         ▼
┌─────────────────────────────────────────────────────────┐
│              Reverse Proxy — Nginx / HAProxy            │
│         (rate limiting, TLS, X-Forwarded-For)           │
└────────────────────────┬────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────┐
│              Backend API — Flask (Python)               │
│                      Port 8080                          │
│                                                         │
│  ┌──────────────┐   ┌─────────────┐  ┌──────────────┐  │
│  │  app.py      │   │ ai_agent.py │  │ database.py  │  │
│  │  (routes)    │──▶│ (filtre +   │  │ (PostgreSQL) │  │
│  │              │   │  synthèse)  │  │              │  │
│  └──────────────┘   └──────┬──────┘  └──────┬───────┘  │
└─────────────────────────────┼───────────────┼──────────┘
                              │               │
                              ▼               ▼
               ┌──────────────────┐   ┌──────────────┐
               │  Mistral AI API  │   │  PostgreSQL   │
               │ api.mistral.ai   │   │   (base DB)   │
               └──────────────────┘   └──────────────┘

3. Composants

3.1 Frontend — React + Vite

Élément Détail
Framework React 18 + TypeScript
Build Vite 7
Styles Tailwind CSS + shadcn/ui
Routing Wouter
État serveur TanStack Query
Client API @workspace/api-client-react (généré depuis OpenAPI)
Police Bahnschrift (titres), Inter (corps)

Pages :

  • / — Page principale (formulaire + fil + synthèse)
  • /about — À propos et fondements juridiques
  • /transparence — Fonctionnement technique et données collectées

Variables d'environnement :

  • BASE_URL — Préfixe de chemin (injecté par Vite)
  • PORT — Port du serveur de développement (assigné par Replit)

3.2 Backend — Flask

Élément Détail
Framework Flask 3 (Python 3.11+)
Serveur WSGI Gunicorn (production)
CORS flask-cors
Rate limiting flask-limiter (5 req/min par IP sur POST /api/ideas)
ORM psycopg2-binary (requêtes SQL directes)

Endpoints :

Méthode Route Description
GET /api/ideas Liste des contributions acceptées
POST /api/ideas Soumet une nouvelle contribution
GET /api/ideas/stats Statistiques (acceptées/refusées)
GET /api/synthesis Texte de synthèse actuel
GET /health Health check

Réponses : JSON camelCase, statuts HTTP standard.


3.3 Agent IA

Deux appels distincts à l'API Mistral (compatible OpenAI SDK) :

Filtre de modération

  • Modèle : mistral-small-latest (configurable via FILTER_MODEL)
  • Entrée : Texte brut de la contribution
  • Sortie : JSON {"accepted": bool, "reason"?: string, "legal_basis"?: string}
  • Référentiel : DUDH, PIDCP, CEDH, Charte UE, CERD, Statut de Rome
  • Max tokens : 300

Synthèse collective

  • Modèle : mistral-large-latest (configurable via SYNTHESIS_MODEL)
  • Entrée : Liste de toutes les contributions acceptées
  • Sortie : Texte libre structuré par thèmes, destiné aux élus
  • Max tokens : 1200
  • Déclencheur : À chaque nouvelle contribution acceptée (asynchrone)

Priorité de configuration du client IA :

  1. MISTRAL_API_KEYhttps://api.mistral.ai/v1
  2. OPENAI_API_KEY → API OpenAI standard
  3. AI_INTEGRATIONS_OPENAI_* → Proxy Replit (intégration native)

3.4 Base de données — PostgreSQL

Table ideas :

Colonne Type Description
id SERIAL PK Identifiant
content TEXT Texte de la contribution
author VARCHAR(100) Pseudonyme (nullable)
accepted BOOLEAN Résultat du filtre
rejection_reason TEXT Motif de refus (nullable)
legal_basis TEXT Base légale du refus (nullable)
created_at TIMESTAMPTZ Horodatage de soumission

Table synthesis :

Colonne Type Description
id SERIAL PK (toujours 1 — ligne unique)
text TEXT Dernier texte de synthèse
idea_count INTEGER Nombre de contributions intégrées
updated_at TIMESTAMPTZ Dernière mise à jour

4. Variables d'environnement

Variable Obligatoire Description
DATABASE_URL URL PostgreSQL complète
MISTRAL_API_KEY (ou OpenAI) Clé API Mistral
SESSION_SECRET Secret Flask (sessions)
FILTER_MODEL Modèle de filtrage (défaut : mistral-small-latest)
SYNTHESIS_MODEL Modèle de synthèse (défaut : mistral-large-latest)
OPENAI_API_KEY Alternative à Mistral
MISTRAL_BASE_URL URL custom Mistral (défaut : https://api.mistral.ai/v1)

5. Infrastructure de déploiement (auto-hébergement)

Internet ──▶ HAProxy (TLS, load balancing)
               └──▶ Nginx (reverse proxy, rate limiting IP)
                      └──▶ Gunicorn × N workers (Flask)
                      └──▶ Fichiers statiques Vite (build)
                                    │
                             PostgreSQL (local ou RDS)

Fichiers fournis :

  • deploy/nginx.conf — Configuration Nginx avec HAProxy support
  • deploy/voix-du-peuple-api.service — Unité systemd pour Gunicorn
  • artifacts/voix-du-peuple/vite.config.selfhost.ts — Build sans plugins Replit

6. Sécurité

Mesure Implémentation
Rate limiting 5 POST/min par IP (flask-limiter)
Sanitisation bleach sur le contenu avant stockage
CORS Origines configurées explicitement
SQL injection Requêtes paramétrées (psycopg2)
Secrets Variables d'environnement uniquement, jamais dans le code
Données personnelles Aucune IP stockée, pseudonyme facultatif

7. Flux de traitement d'une contribution

POST /api/ideas
  │
  ├─ Validation (longueur 101000 chars)
  ├─ Sanitisation (bleach)
  ├─ INSERT en base (statut pending)
  │
  ├─ Appel Mistral (filtre)
  │     ├─ accepted=true  → UPDATE idea, déclenche synthèse async
  │     └─ accepted=false → UPDATE idea avec motif
  │
  ├─ [async] Appel Mistral (synthèse) sur toutes contributions acceptées
  │     └─ UPSERT table synthesis
  │
  └─ Réponse JSON 201