# La Voix du Peuple ## Vue d'ensemble Plateforme démocratique citoyenne où les citoyens soumettent leurs idées politiques, filtrées par IA selon le droit international des droits humains, puis synthétisées en un texte collectif vivant. ## Architecture ### Frontend - **React + Vite** (`artifacts/voix-du-peuple/`) - Interface bicolonne : formulaire de soumission + synthèse en direct - Auto-refresh de la synthèse toutes les 15 secondes - Hooks générés par Orval depuis l'OpenAPI spec ### Backend - **Python Flask** (`artifacts/flask-api/`) — remplace le serveur TypeScript/Express - Sert l'API sur `/api/*` - Démarre via `artifacts/flask-api/start.sh` ### IA Agentique (deux agents) 1. **Agent filtrage** (`ai_agent.py::filter_idea`) — gpt-5-mini - Filtre selon DUDH, PIDCP, CEDH, Charte UE, etc. - Double protection : filtre du proxy Azure + filtre légal IA 2. **Agent synthèse** (`ai_agent.py::synthesize_ideas`) — gpt-5.2 - Synthèse collective en français, "Nous, le peuple..." - Déclenché en arrière-plan à chaque nouvelle idée acceptée ### Base légale du filtre (`legal_framework.py`) - Déclaration universelle des droits de l'homme (DUDH, ONU 1948) - Pacte international relatif aux droits civils et politiques (PIDCP, ONU 1966) - Convention européenne des droits de l'homme (CEDH, 1950) - Charte des droits fondamentaux de l'UE (2000/2009) - Convention pour la prévention du génocide (ONU 1948) - Statut de Rome / CPI (1998) - CERD — Convention sur la discrimination raciale (ONU 1965) ### Base de données - **PostgreSQL** via `psycopg2` directement (pas d'ORM Flask) - Tables : `ideas`, `synthesis` - Drizzle ORM maintenu côté TypeScript pour compatibilité (schema dans `lib/db/`) ## Stack - **Monorepo** : pnpm workspaces - **Node.js** : 24 (pour le frontend React) - **Python** : 3.11 (pour le backend Flask) - **TypeScript** : 5.9 - **API** : OpenAPI spec → Orval codegen → React Query hooks - **IA** : Replit AI Integrations (OpenAI proxy, pas de clé API requise) ## Sécurité Flask - Rate limiting : 5 soumissions/minute, 20/heure par IP (`flask-limiter`) - Assainissement XSS : `bleach.clean()` sur toutes les entrées - En-têtes HTTP : CSP, X-Frame-Options DENY, X-Content-Type-Options, etc. - Requêtes paramétrées : `psycopg2` avec `%s` — protection injection SQL - CORS configuré - Aucun secret exposé dans les réponses d'erreur ## Commandes clés - `pnpm --filter @workspace/api-spec run codegen` — régénérer les hooks React - `pnpm --filter @workspace/db run push` — migrer le schéma DB - `pnpm --filter @workspace/voix-du-peuple run dev` — frontend dev - `sh artifacts/flask-api/start.sh` — backend Flask ## Workflows - `artifacts/api-server: API Server` → Flask (port 8080, chemin `/api`) - `artifacts/voix-du-peuple: web` → React/Vite (port 20108, chemin `/`)