README complet + CONTRIBUTING.md

- README réécrit à partir du code : fonctionnalités réelles, stack,
  installation (dev local, build, prod), variables d'environnement
  documentées avec leur effet, références aux docs existants
- CONTRIBUTING.md créé : signalement de bug, procédure de PR,
  mention que GitHub est un miroir public du dépôt Gitea source

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 14:43:19 +02:00
parent be507cb229
commit e1620aa3c8
2 changed files with 169 additions and 115 deletions
+40
View File
@@ -0,0 +1,40 @@
# Contribuer à La Voix du Peuple
Merci de l'intérêt pour le projet. Ce document décrit comment signaler un problème ou proposer une contribution.
---
## Dépôts
Le dépôt source est hébergé sur Gitea (instance privée). GitHub est un miroir public en lecture seule. Les pull requests doivent être soumises sur le miroir GitHub — elles seront intégrées manuellement dans le dépôt source après relecture.
---
## Signaler un bug
Avant d'ouvrir une issue, vérifier qu'elle n'existe pas déjà.
Une bonne issue contient :
- La version ou le commit concerné
- Les étapes pour reproduire le problème
- Le comportement observé et le comportement attendu
- Le contexte (OS, navigateur, logs backend si disponibles)
Pour les failles de sécurité, ne pas ouvrir d'issue publique. Contacter directement l'auteur.
---
## Proposer une contribution
1. Ouvrir une issue pour discuter de la modification avant de coder, sauf pour les corrections triviales (faute d'orthographe, lien cassé).
2. Forker le dépôt et créer une branche à partir de `main`.
3. Respecter les conventions existantes : TypeScript strict côté frontend, Python 3.11+ côté backend, pas d'ORM, pas de dépendances superflues.
4. Toute modification fonctionnelle doit être testable manuellement — décrire la procédure de test dans la PR.
5. Ne pas modifier le fichier `LICENSE` ni les en-têtes de copyright.
6. Soumettre la pull request sur le miroir GitHub avec une description claire du problème résolu et de l'approche retenue.
---
## Licence des contributions
En soumettant une contribution, vous acceptez qu'elle soit distribuée sous la licence EUPL-1.2, identique à celle du projet.
+129 -115
View File
@@ -1,55 +1,62 @@
# La Voix du Peuple # La Voix du Peuple
**Plateforme civique de démocratie participative assistée par IA** Plateforme civique de participation démocratique assistée par intelligence artificielle.
> *Un espace d'expression citoyenne — pas un sondage, pas une vérité établie.* 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.
---
## Présentation
**La Voix du Peuple** permet à des citoyens de soumettre librement des propositions politiques en texte libre. Chaque contribution est automatiquement :
1. **Filtrée** par une IA selon le droit international des droits humains (DUDH, PIDCP, CEDH, Charte UE, CERD, Statut de Rome)
2. **Intégrée** à une synthèse collective structurée par thèmes
3. **Mise à disposition** des élus et décideurs sous forme lisible
La plateforme ne produit pas un consensus, ni une vérité : elle donne à voir ce que des citoyens ont choisi d'exprimer, tel quel. La démarche est portée par un auteur attaché à l'expertise et au dialogue fondé sur les preuves.
---
## Captures d'écran
### Page principale — soumission et synthèse en temps réel
![Page principale](screenshots/home.jpg)
### À propos — concept et posture éditoriale
![À propos](screenshots/about.jpg)
### Fonctionnement — parcours d'une contribution
![Fonctionnement](screenshots/transparence.jpg)
### Flyer QR — diffusion physique imprimable
![Flyer QR](screenshots/flyer.jpg)
--- ---
## Fonctionnalités ## Fonctionnalités
| Fonctionnalité | Description | **Contribution citoyenne**
|----------------|-------------| - Formulaire texte libre (10 à 1 000 caractères), pseudonyme optionnel
| Soumission libre | Formulaire texte avec 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
| Modération IA | Filtre automatique fondé sur le droit international | - Motif de rejet et base légale retournés au contributeur si la contribution est refusée
| Synthèse thématique | Résumé en temps réel par Mistral Large | - Dialogue de recueil du consentement RGPD avant soumission
| Export PDF | Synthèse mise en page, générée côté client |
| Partage horodaté | Copie dans le presse-papier ou partage natif mobile | **Synthèse collective**
| Flyer QR imprimable | Flyer A4 avec QR code configuré sur votre domaine | - Générée automatiquement à chaque nouvelle contribution acceptée (arrière-plan, non bloquant)
| Dark mode | Thème sombre pétrol | - Regroupement thématique, ton neutre et factuel, sans formule solennelle
| Accessibilité | Police dyslexie · Contraste élevé · Texte agrandi · Navigation clavier | - 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)
--- ---
@@ -57,100 +64,107 @@ La plateforme ne produit pas un consensus, ni une vérité : elle donne à voir
| Couche | Technologie | | Couche | Technologie |
|--------|-------------| |--------|-------------|
| Frontend | React 18 · TypeScript · Vite 7 · Tailwind CSS · shadcn/ui | | Frontend | React 18 · TypeScript · Vite 7 · Tailwind CSS · shadcn/ui · Wouter |
| Backend | Python 3.11 · Flask 3 · Gunicorn | | Backend | Python 3.11+ · Flask 3 · Gunicorn |
| Base de données | PostgreSQL 15 | | Base de données | PostgreSQL 15+ (psycopg2, sans ORM) |
| IA — modération | Mistral Small (`mistral-small-latest`) | | IA | Mistral AI (défaut) ou tout fournisseur compatible API OpenAI |
| IA — synthèse | Mistral Large (`mistral-large-latest`) | | Sécurité | flask-limiter · bleach · FingerprintJS · Redis (optionnel) · hCaptcha (optionnel) |
| QR code | `qrcode.react` | | Déploiement | Nginx · systemd |
--- ---
## Installation rapide (RockyLinux) ## Installation
Voir le guide complet → [`docs/INSTALL_ROCKY.md`](docs/INSTALL_ROCKY.md) ### 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 :
```bash ```bash
# Cloner le dépôt
git clone https://homegit.gyozamancave.fr/billisdead/la-voix-du-peuple.git
cd la-voix-du-peuple
# Configurer l'environnement
cp .env.example .env cp .env.example .env
vim .env # DATABASE_URL, MISTRAL_API_KEY, SESSION_SECRET chmod 600 .env
# Définir le domaine et construire le frontend
bash scripts/set-domain.sh https://votredomaine.fr
# Démarrer les services
systemctl start voix-du-peuple-api
systemctl start nginx
``` ```
Le site écoute sur le **port HTTP 8080**. Vous gérez le HTTPS en amont. **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) |
## Variables d'environnement clés **Recommandées en production :**
```env | Variable | Description |
# Base de données |----------|-------------|
DATABASE_URL=postgresql://user:pass@localhost:5432/voix_du_peuple | `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) |
# IA (Mistral recommandé — souveraineté européenne) Les modèles IA sont configurables via `FILTER_MODEL` (défaut : `mistral-small-latest`) et `SYNTHESIS_MODEL` (défaut : `mistral-large-latest`).
MISTRAL_API_KEY=sk-...
# Sécurité (obligatoire en production) ### Développement local
SECRET_KEY=une-longue-chaine-aleatoire-minimum-32-chars
ADMIN_SECRET=votre-mot-de-passe-admin
# Anti-abus (optionnel — valeurs par défaut raisonnables)
REDIS_URL=redis://localhost:6379/0
RATE_LIMIT_CONTRIBUTIONS=5 per minute;3 per hour
CONTRIBUTION_COOLDOWN_SECONDS=3600
FLOOD_THRESHOLD=10
# hCaptcha (optionnel — recommandé en production)
HCAPTCHA_SECRET_KEY=votre-cle-secrete
# Frontend
VITE_APP_URL=https://votredomaine.fr
VITE_HCAPTCHA_SITE_KEY=votre-cle-de-site # Nécessite rebuild frontend
```
---
## Changer de domaine (QR code)
```bash ```bash
bash scripts/set-domain.sh https://nouveaudomaine.fr # Prérequis : Node.js et PostgreSQL déjà installés
systemctl reload nginx 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 :
```bash
ssh -L 5173:localhost:5173 -L 8080:localhost:8080 utilisateur@votre-serveur
# Puis ouvrir http://localhost:5173
```
### Build frontend
```bash
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
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.
--- ---
## Documentation ## Contribuer
| Document | Contenu | Les contributions sont les bienvenues. Voir [CONTRIBUTING.md](CONTRIBUTING.md) pour les modalités.
|----------|---------|
| [`docs/DAT.md`](docs/DAT.md) | Architecture technique complète | ---
| [`docs/DEX.md`](docs/DEX.md) | Guide d'exploitation et maintenance |
| [`docs/WIKI.md`](docs/WIKI.md) | Page wiki — présentation générale | ## Soutenir le projet
| [`docs/INSTALL_ROCKY.md`](docs/INSTALL_ROCKY.md) | Installation sur RockyLinux 9 |
| [`docs/SECURITE_ANTI_ABUS.md`](docs/SECURITE_ANTI_ABUS.md) | Protections anti-bot, flood, rate limiting, hCaptcha | 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.
| [`docs/RGPD.md`](docs/RGPD.md) | Conformité RGPD — registre des traitements |
| [`docs/PROMPTS_IA.md`](docs/PROMPTS_IA.md) | Prompts IA intégraux (transparence algorithmique) | - Ko-fi : [LIEN_KO_FI]
- GitHub Sponsors : [LIEN_GITHUB_SPONSORS]
--- ---
## Licence ## Licence
Ce projet est publié sous **[European Union Public Licence v. 1.2 (EUPL-1.2)](LICENSE)**. EUPL-1.2 — voir fichier [LICENSE](LICENSE).
L'EUPL-1.2 est la licence open source officielle de l'Union européenne. Elle est :
- **Compatible** avec la GPL v2/v3, l'AGPL v3 et la MPL 2.0 (cf. Appendice)
- **Reconnue** par la Commission européenne et les institutions publiques de l'UE
- **Adaptée** aux projets civiques et associatifs souhaitant une réutilisation libre sous condition de réciprocité (copyleft)
- **Disponible** en 23 langues officielles de l'UE — voir [joinup.ec.europa.eu](https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12)
Ce choix est cohérent avec la posture souveraineté numérique européenne du projet et permet à toute association, mairie ou collectif de reprendre et déployer cet outil sous les mêmes conditions.