Auteur: David Marleau Licence: Licence MIT Statut: 🚧 VERSION DÉMO - FONCTIONNELLE MAIS INCOMPLÈTE 🚧
🇬🇧 Read in English | 📖 Version Française
Un système de vote électronique distribué de qualité production conçu pour gérer 8 millions d'électeurs simultanés à travers le Canada. Ce système prend en charge les référendums de démocratie directe (vote de lois) et les élections électorales avec des capacités de vote à choix unique et de vote par classement.
- Haute Performance: Conçu pour traiter 8M+ votes avec mise en file d'attente RabbitMQ et mise à l'échelle horizontale
- Sécurisé: Validation de hachage hors ligne, aucun stockage de données personnelles, pistes d'audit complètes
- Évolutif: Architecture de microservices prête pour le déploiement Kubernetes
- Temps Réel: Résultats en direct avec tableaux de bord à actualisation automatique
- Surveillé: Pile d'observabilité complète Prometheus + Grafana
| Métrique | Valeur |
|---|---|
| Capacité Cible | 8 millions d'électeurs |
| Débit | ~1 000 votes/sec (cible production) |
| Performance Actuelle | 150-250 votes/sec (Docker local) |
| Latence (p95) | <100ms |
| Architecture | Microservices + File de Messages |
| Sécurité | Authentification par hachage, aucune donnée personnelle |
Ceci est un projet d'apprentissage et une preuve de concept construit pour partager une idée de modernisation des systèmes de vote démocratiques.
Contexte Important:
- Construit par un non-développeur comme exercice d'apprentissage ("vibe coding")
- Démontre des concepts d'architecture, pas du code prêt pour production
- Démo fonctionnelle qui montre que l'idée fonctionne à grande échelle
- Nécessite un travail significatif avant utilisation réelle
Pourquoi Partager Ceci?
Ce projet vise à contribuer une idée à la communauté technologique démocratique. Si vous êtes un professionnel de la sécurité, développeur expérimenté, ou expert en systèmes électoraux:
- 🔍 Évaluez l'architecture - le concept a-t-il du mérite?
- 🔧 Forkez et améliorez - rendez-le prêt pour production
- 💡 Utilisez comme inspiration - construisez quelque chose de meilleur
- 🤝 Contribuez des corrections - toutes améliorations bienvenues
📋 Évaluation Sécurité: Voir SECURITY.md pour une évaluation honnête des limitations actuelles et de ce qui serait nécessaire pour un usage en production.
🎯 Objectif: Faire avancer la technologie de participation démocratique, que ce soit par cette implémentation ou en inspirant de meilleures solutions.
Cette infrastructure de vote pourrait être déployée dans divers scénarios démocratiques:
Le système prend en charge les processus électoraux standards:
- Vote à choix unique pour élections simples
- Vote par classement (RCV) pour scrutins préférentiels
- Représentation régionale avec agrégation nationale
- Résultats en temps réel avec pistes d'audit
La même infrastructure pourrait permettre des votes de démocratie directe sur la législation. Exemples où des mécanismes de référendum ont été discutés:
-
Ajustements Salariaux Parlementaires (Canada, avril 2024)
- Députés ont reçu augmentation de 4,4% (Députés: 203 100$/an, PM: 406 200$)
- Sondages montraient 80% d'opposition publique
- Actuellement automatique sans mécanisme de consultation citoyenne
-
Réformes Politiques de Santé (Québec, octobre 2024)
- Loi 2 a imposé changements de rémunération des médecins
- Certains médecins confrontés à réductions salariales jusqu'à 145 000$
- Le ministre Lionel Carmant a démissionné; associations médicales ont déposé recours judiciaires
- Adoptée sous vote de clôture sans consultation étendue
-
Tendance Mondiale Vers la Démocratie Directe
- 700+ protestations citoyennes dans 147+ pays (2023-2024)
- Demande croissante pour mécanismes de référendum sur décisions politiques majeures
- Technologie permettant participation citoyenne en temps réel à grande échelle
Ce système fournit:
- Évolutivité: Conçu pour 8M électeurs simultanés
- Flexibilité: Vote de lois OU élections OU les deux
- Sécurité: Authentification par hachage, aucune donnée personnelle stockée
- Transparence: Code source ouvert, résultats vérifiables
- Performance: Cible de 1 000 votes/sec en production
Les organisations pourraient déployer ceci pour:
- Élections municipales/provinciales
- Votes syndicaux ou scrutins organisationnels
- Référendums législatifs (si légalement autorisés)
- Programmes pilotes testant modèles de démocratie directe
- Recherche académique sur systèmes de vote
- Fonctionnalités
- Démarrage Rapide
- Aperçu de l'Architecture
- Composants du Système
- Système Électoral
- Tests
- Déploiement
- Sécurité
- Performance & Mise à l'Échelle
- Dépannage
- Structure du Projet
- ✅ Vote de Lois (Référendums): Démocratie directe avec choix Oui/Non
- ✅ Élections Électorales: Élections de représentants régionaux
- Support du vote à choix unique
- Support du vote par classement (RCV)
- Courses multi-candidats avec affiliations de parti
- Contrôles de timing d'élection (date/heure début/fin)
- Suivi des résultats en temps réel
- ✅ Haute Performance: Mise en mémoire tampon de file RabbitMQ pour 8M+ utilisateurs simultanés
- ✅ Sécurité: Validation de hachage hors ligne, aucun stockage de données personnelles, piste d'audit complète
- ✅ Évolutivité: Architecture de microservices prête pour Kubernetes
- ✅ Surveillance: Tableaux de bord Prometheus + Grafana avec alertes
- ✅ Détection de Doublons: Déduplication basée sur Redis avec suivi des tentatives
- ✅ Résultats en Temps Réel: Tableau de bord à actualisation automatique (intervalles de 5 secondes)
- ✅ Agrégation Nationale: Vue "Toutes Régions" pour les totaux nationaux
- ✅ Tests de Charge: Suite de tests complète avec capacité de 8M votes
./quick-start.shCe script démarre automatiquement tous les services en ~20 secondes! 🚀
- Docker & Docker Compose
- Python 3.11+
- kubectl (pour le déploiement en production)
- Démarrer les services Docker:
docker-compose up -d- Démarrer le tableau de bord de surveillance:
python3 monitor_dashboard/server.py &- Démarrer l'interface de vote:
cd demo_ui && python3 app.py &- Accéder aux services:
- Interface de Vote: http://localhost:3000
- Onglet vote de lois
- Onglet vote électoral
- Pages de résultats
- Panneau d'Administration: http://localhost:8501
- Créer des élections
- Configurer les méthodes de vote (choix unique / classement)
- Définir le timing d'élection
- Gérer les candidats
- Tableau de Bord de Surveillance: http://localhost:4000/monitor.html
- Résultats d'élection en direct (actualisation automatique toutes les 5s)
- 📊 Agrégation "Toutes Régions" - Totaux nationaux par défaut
- Ventilations par région disponibles
- Tableau des résultats de vote de lois
- Statistiques de vote
- API de Vote: http://localhost:8000
- Gestion RabbitMQ: http://localhost:15672 (guest/guest)
- Grafana: http://localhost:3001 (admin/admin)
- Prometheus: http://localhost:9090
Vote de Loi:
curl -X POST http://localhost:8000/api/v1/vote \
-H "Content-Type: application/json" \
-d '{
"nas": "123456789",
"code": "ABC123",
"law_id": "L2025-001",
"vote": "oui"
}'Vote Électoral:
curl -X POST http://localhost:8000/api/v1/elections/vote \
-H "Content-Type: application/json" \
-d '{
"nas": "123456789",
"code": "ABC123",
"election_id": 1,
"region_id": 1,
"candidate_id": 1,
"voting_method": "single_choice"
}'Résultats de Loi:
curl http://localhost:8000/api/v1/results/L2025-001Résultats Électoraux:
curl http://localhost:8000/api/v1/elections/1/regions/1/resultsLe système utilise une architecture de microservices avec mise en mémoire tampon de file de messages pour gérer le trafic simultané à haut volume tout en maintenant l'intégrité des données.
Électeur → API d'Ingestion (FastAPI)
↓
File RabbitMQ (TAMPON) ← Gère le trafic en rafales
↓
Workers de Validation (Évolutifs)
├─→ Redis (Validation de Hachage + Déduplication)
└─→ PostgreSQL (Journal d'Audit)
↓
Service d'Agrégation
↓
PostgreSQL (Résultats de Vote)
↓
Tableau de Bord Temps Réel
- Tampon de File de Messages: RabbitMQ absorbe les pics de trafic (8M électeurs sur 24 heures)
- Workers Sans État: Les workers de validation peuvent s'étendre horizontalement sans coordination
- Redis pour la Vitesse: Recherches de hachage rapides (8M hachages) et détection de doublons
- PostgreSQL pour la Persistance: Stockage fiable pour les votes et pistes d'audit
- Agrégation par Lots: Comptage efficace des votes avec lots de 100 votes
- API d'Ingestion: Point de terminaison de soumission de votes FastAPI
- RabbitMQ: Tampon de file de messages (gère le trafic en rafales)
- Redis: Recherche de hachage rapide (8M hachages) et détection de doublons
- PostgreSQL: Stockage persistant pour votes, élections, candidats, résultats
- Prometheus + Grafana: Collection de métriques et visualisation
- Workers de Validation: Workers évolutifs pour la validation de hachage (mise à l'échelle horizontale)
- Service d'Agrégation: Traitement par lots pour le comptage des votes
Emplacement: services/ingestion_api/
Le point d'entrée basé sur FastAPI pour toutes les soumissions de votes.
Responsabilités:
- Accepter les requêtes HTTP POST avec les données de vote
- Effectuer la validation de base des entrées (format, champs requis)
- Publier les messages dans la file de validation RabbitMQ
- Retourner une réponse 202 Accepted immédiatement (traitement asynchrone)
- Exposer les points de terminaison de vérification de santé et de métriques
Points de Terminaison:
POST /api/v1/vote- Soumettre un vote de loiPOST /api/v1/elections/vote- Soumettre un vote électoralGET /api/v1/results/{law_id}- Obtenir les résultats de loiGET /api/v1/elections/{election_id}/regions/{region_id}/results- Obtenir les résultats électorauxGET /health- Vérification de santé
Performance:
- Actuel: ~250 votes/seconde (Docker local)
- Cible: ~1 000 votes/seconde (Kubernetes production)
Configuration:
- Limitation de débit activée
- Validation requête/réponse
- Support CORS pour l'interface web
- Export de métriques Prometheus
Emplacement: services/validation_worker/
Workers évolutifs qui traitent les votes depuis la file de validation RabbitMQ.
Flux de Traitement:
- Consommer depuis la file
votes.validation - Valider le Hachage: Vérifier si le hachage existe dans le SET Redis
valid_hashes- Si invalide → publier dans la file
votes.reviewavec status='invalid'
- Si invalide → publier dans la file
- Vérifier les Doublons: Vérifier si le hachage existe dans le SET Redis
voted_hashes- Si doublon:
- Incrémenter le compteur
duplicate_count:{hash} - Publier dans la file
votes.reviewavec status='duplicate' et nombre de tentatives
- Incrémenter le compteur
- Si doublon:
- Traiter le Vote Valide:
- Ajouter le hachage au SET
voted_hashes - Insérer le journal d'audit dans la table PostgreSQL
vote_audit - Publier dans la file
votes.aggregation - ACK du message
- Ajouter le hachage au SET
Fonctionnalités Clés:
- Validation des votes contre la base de données de hachage Redis
- Détection de doublons avec comptage des tentatives
- Journalisation d'audit dans PostgreSQL
- Gestion d'erreurs gracieuse avec remise en file
- Métriques Prometheus pour la surveillance
- Support de mise à l'échelle horizontale
Mise à l'Échelle:
# Passer à 8 workers
docker-compose up -d --scale validation-worker=8Métriques:
validation_votes_processed_total{status}: Total des votes par statutvalidation_processing_latency_seconds: Temps de traitementvalidation_errors_total{error_type}: Erreurs par typeredis_operations_total{operation,status}: Opérations Redisdatabase_operations_total{operation,status}: Opérations BD
Emplacement: services/aggregation/
Consomme les votes validés depuis RabbitMQ et met à jour PostgreSQL avec les comptages de votes agrégés.
Fonctionnement:
Le service d'agrégation utilise le traitement par lots intelligent pour l'efficacité:
- Traitement par lots basé sur la taille: Traite lorsque le lot atteint 100 votes
- Traitement par lots basé sur le temps: Traite toutes les 1 seconde si des votes sont en attente
- Traitement par lots à l'arrêt: Traite tous les votes restants lors de l'arrêt gracieux
Opérations de Base de Données:
- Utilise
INSERT ... ON CONFLICT UPDATE(UPSERT) pour l'efficacité - Les mises à jour par lots minimisent les connexions à la base de données
- Pool de connexions pour la performance
- Réessai automatique avec backoff exponentiel
Schéma de Base de Données:
vote_results - Table d'agrégation principale:
law_id(PK): Identifiant de loioui_count: Nombre de votes "oui"non_count: Nombre de votes "non"updated_at: Horodatage de dernière mise à jour
vote_audit - Journal d'audit des votes individuels:
vote_hash(UNIQUE): Hachage du votecitizen_id: Identifiant de l'électeurlaw_id: Identifiant de loichoice: Choix de vote (oui/non)timestamp: Horodatage du vote
Performance:
- Traite ~10 000 votes/seconde (dépendant du matériel)
- Taille de lot réglable pour débit vs latence
- Mise à l'échelle horizontale supportée
Métriques Prometheus:
votes_aggregated_total{law_id, choice}: Total des votes agrégéscurrent_vote_totals{law_id, choice}: Comptages de votes actuelsbatch_processing_duration_seconds: Temps de traitementbatch_size_processed_total: Votes par lotaggregation_errors_total{error_type}: Erreurs d'agrégation
Emplacement: services/hash_generator/
Un utilitaire conteneurisé pour générer des hachages cryptographiques pour l'authentification des électeurs.
Objectif: Créer des identifiants d'authentification uniques pour les tests et le déploiement.
Format de Hachage:
Chaque hachage est calculé comme: SHA-256(f"{nas}|{code.upper()}|{law_id}")
Données Générées:
{
"nas": "123456789", // Nombre aléatoire à 9 chiffres
"code": "ABC123", // Alphanumérique majuscule à 6 caractères
"law_id": "L2025-001", // Identifiant de loi
"hash": "a1b2c3d4e5f6...", // Hachage SHA-256
"vote": "oui" // Vote aléatoire (oui/non)
}Utilisation:
# Générer 1 million de hachages
python generator.py --count 1000000 --output ./output
# Générer 5 millions de hachages pour une loi spécifique
python generator.py --count 5000000 --output ./output --law-id L2025-042
# Utilisation Docker
docker run -v $(pwd)/output:/output hash-generator \
--count 1000000 \
--output /outputSortie:
- Fichiers JSON fragmentés (
hashes_shard_0000.json,hashes_shard_0001.json, etc.) - Par défaut: 1 million de hachages par fragment
- Barre de progression avec statut de génération en temps réel
- Statistiques récapitulatives (distribution des votes, tailles de fichiers)
Performance:
- Vitesse de génération: ~100 000-500 000 hachages par seconde
- Économe en mémoire avec sortie fragmentée
- Peut générer 8M hachages en moins de 2 minutes
Intégration:
- Charger les hachages dans Redis pour validation
- Distribuer les fichiers fragmentés aux nœuds de vote
- Utiliser pour les tests de charge et la simulation
Emplacement: demo_ui/
Une interface web basée sur Flask pour le système de vote électronique avec affichage des résultats en temps réel.
Fonctionnalités:
- Formulaire de Vote: Soumettre des votes avec NAS, code de validation, sélection de loi et choix de vote
- Validation en Temps Réel: Validation de formulaire côté client avec retour instantané
- Affichage des Résultats: Résultats en direct avec actualisation automatique toutes les 5 secondes
- Graphiques Interactifs: Représentation visuelle utilisant Chart.js
- Design Responsive: Interface Bootstrap 5 compatible mobile
- Thème Sombre: Schéma de couleurs sombre professionnel
- Gestion d'Erreurs: Messages d'erreur complets pour tous les scénarios
Routes:
GET /- Page de vote principale avec formulaire et résultats actuelsPOST /vote- Soumettre un vote (point de terminaison AJAX)GET /results- Page de résultats complète avec graphiques et tableauxGET /api/results- API JSON pour récupérer les résultats actuelsGET /health- Point de terminaison de vérification de santé
Technologies:
- Backend: Flask 3.0
- Frontend: Bootstrap 5, Chart.js
- Client HTTP: Bibliothèque Requests
- Style: CSS personnalisé avec thème sombre
- JavaScript: JS vanilla avec AJAX
Exécution Locale:
cd demo_ui
pip install -r requirements.txt
python app.py
# Accès à http://localhost:3000Déploiement en Production:
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:3000 app:appEmplacement: monitoring/
Observabilité complète avec collecte de métriques Prometheus et visualisation Grafana.
Composants:
- Prometheus: Base de données de séries temporelles et moteur d'alerte
- Grafana: Plateforme de visualisation et tableaux de bord
- Exportateurs: Exportateurs spécialisés pour Redis, PostgreSQL et RabbitMQ
Accès:
- Grafana: http://localhost:3001 (admin/admin)
- Tableau de bord principal: "Election Voting System - Overview"
- Prometheus: http://localhost:9090
- Interface de requête et statut d'alerte
Tableaux de Bord Clés:
- Votes Par Seconde - Série temporelle montrant le taux d'ingestion de votes
- Total des Votes par Loi - Jauge montrant les votes cumulatifs par loi
- Répartition du Statut de Validation - Diagramme circulaire des votes valides/invalides/doublons
- Profondeur de File - Série temporelle des profondeurs de files de messages
- Latence API (p50/p95/p99) - Latences en percentiles
- Taux de Tentatives de Doublons - Pourcentage de tentatives de doublons
- Workers Actifs - Nombre de workers de validation en cours d'exécution
- Utilisation Mémoire Redis - Jauge de consommation mémoire
- Connexions Base de Données - Utilisation du pool de connexions BD
- Requêtes HTTP par Code de Statut - Graphique en aires empilées
Règles d'Alerte:
Alertes Critiques (Action Immédiate Requise):
IngestionAPIDown- API inaccessible pendant 1 minuteValidationWorkerDown- Moins de 2 workers pendant 2 minutesRabbitMQDown- RabbitMQ inaccessible pendant 1 minuteRedisDown- Redis inaccessible pendant 1 minutePostgresDown- PostgreSQL inaccessible pendant 1 minuteCriticalValidationQueueDepth- >50 000 messages pendant 2 minutesCriticalDuplicateRate- >15% taux de doublons pendant 5 minutesAPICriticalLatency- latence p95 >500ms pendant 2 minutesCriticalAPIErrorRate- >15% taux d'erreur pendant 2 minutes
Alertes d'Avertissement (Action Recommandée):
HighValidationQueueDepth- >10 000 messages pendant 5 minutesHighDuplicateRate- >5% taux de doublons pendant 10 minutesAPIHighLatency- latence p95 >200ms pendant 5 minutesHighAPIErrorRate- >5% taux d'erreur pendant 5 minutes
Catégories de Métriques:
Métriques d'Application:
votes_received_total- Compteur de votes reçusvotes_by_law_total- Compteur par loi/référendumvotes_validation_processed_total- Compteur de votes validésvotes_aggregated_total- Compteur de votes agrégéshttp_requests_total- Requêtes HTTP par code de statut
Métriques d'Infrastructure:
rabbitmq_queue_messages- Messages dans la fileredis_memory_used_bytes- Utilisation mémoirepg_stat_database_numbackends- Connexions activesvalidation_duration_seconds- Histogramme du temps de traitement
Table Elections:
election_code,election_name,election_typestart_datetime,end_datetime- Contrôle de la fenêtre de votevoting_method-single_choiceouranked_choicestatus-draft,active,completed
Table Candidats:
- Liens vers élections, régions et partis politiques
first_name,last_name,bio- Affiliations de parti avec couleurs et branding
Résultats Électoraux:
- Agrégation en temps réel dans la table
election_results - Comptages de votes et pourcentages par candidat/région
- Agrégation nationale à travers toutes les régions
- ✅ Bascule de vote par classement dans le panneau d'administration
- ✅ Timing d'élection (date/heure début/fin)
- ✅ Validation de coupure de vote (pas de votes après la date limite)
- ✅ Résultats d'élection sur le tableau de bord de surveillance avec agrégation "Toutes Régions"
- ✅ Totaux électoraux nationaux (agrégation automatique à travers toutes les régions)
- ✅ Ventilations de résultats par région
- ✅ Pipeline RabbitMQ: API → File → Workers → PostgreSQL
- ✅ Élections multi-candidats fonctionnelles
- ✅ Couleurs et branding de parti
- ✅ Actualisation automatique en temps réel (intervalles de 5 secondes)
Emplacement: tests/
Suite complète de tests d'intégration et de charge.
- Total des Tests d'Intégration: 40+
- Cible de Couverture de Tests: >80%
- Cibles de Performance:
- Débit: 1000 votes/seconde
- Latence: p95 < 100ms
- Taux de Réussite: >99.9%
# Exécuter tous les tests d'intégration
cd tests/
pytest integration/ -v
# Avec rapport de couverture
pytest integration/ -v --cov --cov-report=html
# Exécuter des fichiers de tests spécifiques
pytest integration/test_vote_flow.py -v
pytest integration/test_api.py -v
pytest integration/test_duplicate_detection.py -vGénérer 8 millions d'identifiants de test:
python3 scripts/preload_test_hashes.py 8000000Cela crée:
test_votes.txt(251MB, 8M lignes)- Charge tous les hachages dans Redis pour validation
Exécuter les tests de charge:
# Test de charge standard (avec identifiants valides)
python3 -u tests/load_test.py --votes 100000 --rate 1000
# Test BD direct (élections, 30k votes)
python3 tests/test_election_simple.py
# Utilisation de Locust (interface web)
locust -f tests/load_test.py --host=http://localhost:8000
# Ouvrir le navigateur à http://localhost:8089Résultats de Performance:
- BD Direct: 3 558 votes/sec
- Test de Charge API: 160-265 votes/sec (avec pipeline de validation complet)
- Capacité Système: Conçu pour 8M votes en 24 heures (~92 votes/sec moyenne)
- Tests d'Intégration - Tests de bout en bout du pipeline de vote complet
- Tests API - Validation des points de terminaison REST API
- Tests de Détection de Doublons - Vérification de la logique de déduplication de vote
- Tests de Charge - Tests de performance et d'évolutivité
# Démarrer tous les services
docker-compose up -d
# Mettre à l'échelle les workers de validation
docker-compose up -d --scale validation-worker=5
# Vérifier le statut
docker-compose ps
# Voir les journaux
docker-compose logs -f validation-worker# Appliquer la configuration de base
kubectl apply -k k8s/overlays/prod/
# Mettre à l'échelle les workers
kubectl scale deployment validation-worker --replicas=20
# Vérifier le statut
kubectl get pods
# Voir les journaux
kubectl logs -f deployment/validation-workerDéveloppement (docker-compose):
- Performance actuelle: ~250 votes/seconde via API
- BD direct: 3 500+ votes/seconde
- Bon pour les tests et démos
Production (Kubernetes):
- 10x Répliques API d'Ingestion
- 20x Workers de Validation
- 3x Service d'Agrégation
- Cluster Redis (3 nœuds)
- PostgreSQL avec répliques en lecture
- Cible: 1000 votes/seconde soutenue
- ✅ Aucun Stockage de Données Personnelles: Seuls les hachages stockés, aucune information personnellement identifiable
- ✅ Base de Données de Hachage Hors Ligne: Empêche les faux votes, hachages générés hors ligne
- ✅ Détection de Doublons: Déduplication basée sur Redis avec suivi des tentatives
- ✅ Piste d'Audit Complète: Chaque vote enregistré dans PostgreSQL
- ✅ Limitation de Débit: Limitation de débit API pour prévenir les abus
- ✅ Respect du Timing Électoral: Aucun vote précoce/tardif accepté
- ✅ Communication TLS: Communication inter-services chiffrée (production)
Le système utilise des hachages SHA-256 pour l'authentification des électeurs:
Hachage = SHA-256(NAS | Code | Law_ID)
Avantages:
- Aucune information personnelle stockée dans le système
- La génération de hachage hors ligne assure l'intégrité des identifiants de vote
- Impossible de rétro-ingénierie de l'identité de l'électeur à partir du hachage
- Chaque hachage est unique à la combinaison électeur + loi
Redis:
- Hachages valides stockés dans le SET
valid_hashes(8M hachages) - Hachages votés stockés dans le SET
voted_hashes(déduplication) - Compteurs de tentatives de doublons:
duplicate_count:{hash} - TTL défini sur toutes les clés pour nettoyage automatique
PostgreSQL:
- Journal d'audit: table
vote_audit(enregistrement immuable) - Résultats: table
vote_results(comptages agrégés) - Élections: tables
elections,candidates,election_results - Toutes les tables indexées pour performance et requêtes de sécurité
| Métrique | Valeur |
|---|---|
| Débit de Pointe (API) | ~250 votes/sec |
| Débit de Pointe (BD Direct) | ~3 500 votes/sec |
| Latence p95 | 80ms |
| Taux de Réussite | 99.5% |
| Métrique | Cible |
|---|---|
| Débit de Pointe | 1 000 votes/sec |
| Latence p95 | <100ms |
| Taux de Réussite | >99.9% |
| Disponibilité | 99.9% |
Scénario: 8 millions d'électeurs sur une période de vote de 24 heures
Charge Moyenne: 8 000 000 / (24 * 3600) = ~92 votes/seconde
Charge de Pointe (en supposant un pic de 10x): ~920 votes/seconde
Stratégie de Mise à l'Échelle:
-
Mise à l'Échelle Horizontale:
- 10x instances API d'Ingestion (équilibrées en charge)
- 20x Workers de Validation (traitement parallèle)
- 3x Services d'Agrégation (traitement par lots)
-
Mise à l'Échelle d'Infrastructure:
- Cluster Redis (3 nœuds, fragmentés)
- PostgreSQL avec répliques en lecture (1 primaire, 2 répliques)
- Cluster RabbitMQ (3 nœuds, files en miroir)
-
Optimisations de Performance:
- Pool de connexions (PostgreSQL)
- Opérations par lots (Agrégation)
- Réglage du comptage de prérécupération (RabbitMQ)
- Pipeline Redis
Planification de Capacité:
| Composant | Min | Charge Moyenne | Charge Élevée |
|---|---|---|---|
| Instances API | 2 | 4 | 10 |
| Workers de Validation | 4 | 8 | 20 |
| Services d'Agrégation | 1 | 2 | 3 |
| Débit Attendu | ~200/sec | ~500/sec | ~1000/sec |
Symptômes: Votes soumis mais n'apparaissant pas dans les résultats
Étapes de Diagnostic:
- Vérifier la profondeur de file RabbitMQ:
curl -u guest:guest http://localhost:15672/api/queues - Vérifier les journaux des workers de validation:
docker-compose logs validation-worker - Vérifier que Redis a des hachages:
docker-compose exec redis redis-cli SCARD valid_hashes
Solutions:
- Mettre à l'échelle les workers de validation:
docker-compose up -d --scale validation-worker=8 - Charger les hachages dans Redis:
python3 scripts/load_hashes_to_redis.py - Redémarrer les workers:
docker-compose restart validation-worker
Étapes de Diagnostic:
- Vérifier la table election_results:
docker-compose exec postgres psql -U voting_user -d voting -c "SELECT * FROM election_results;"
- Vérifier que les candidats existent dans le panneau d'administration
- Vérifier le tableau de bord de surveillance pour les résultats en direct
- Vérifier que l'élection est active et dans la fenêtre de temps
Solutions:
- Vérifier le statut de l'élection: Vérifier le panneau d'administration Onglet 7
- Vérifier les journaux du service d'agrégation:
docker-compose logs aggregation - Vérifier la fenêtre de temps: S'assurer que l'heure actuelle est entre start_datetime et end_datetime
Symptômes: Messages s'accumulant dans les files de validation ou d'agrégation
Causes Possibles:
- Capacité de workers insuffisante
- Plantages ou blocages de workers
- Problèmes de performance de base de données
- Problèmes de connectivité réseau
Solutions:
- Augmenter les workers:
docker-compose up -d --scale validation-worker=8 - Redémarrer les workers bloqués:
docker-compose restart validation-worker - Vérifier la performance de la base de données: Surveiller le nombre de connexions et les temps de requête
- Surveiller le tableau de bord Grafana pour les goulots d'étranglement
Étapes de Diagnostic:
- Vérifier les métriques Prometheus: http://localhost:9090
- Surveiller la mémoire Redis:
docker-compose exec redis redis-cli INFO memory - Vérifier les connexions de base de données:
docker-compose exec postgres psql -U voting_user -d voting -c "SELECT count(*) FROM pg_stat_activity;"
Solutions:
- Mettre à l'échelle les workers de validation:
docker-compose up -d --scale validation-worker=5 - Augmenter la limite de mémoire Redis dans docker-compose.yml
- Optimiser les requêtes de base de données ou ajouter des index
Si les tests ou le système échouent de manière inattendue:
# Arrêter et supprimer tous les conteneurs, volumes, réseaux
docker-compose down -v
# Supprimer les artefacts de test
rm -rf htmlcov/ .coverage .pytest_cache/
# Redémarrer à neuf
docker-compose up -d
sleep 30
# Recharger les hachages
python3 scripts/load_hashes_to_redis.py --sampleelectionscriptanalyse/
├── services/ # Microservices
│ ├── ingestion_api/ # API de soumission de votes (FastAPI)
│ │ ├── main.py # Points de terminaison API
│ │ ├── requirements.txt # Dépendances
│ │ └── Dockerfile # Config conteneur
│ ├── validation_worker/ # Validation de hachage & déduplication
│ │ ├── worker.py # Logique principale du worker
│ │ ├── redis_client.py # Opérations Redis
│ │ ├── rabbitmq_client.py # Consommateur RabbitMQ
│ │ ├── database.py # Client PostgreSQL
│ │ ├── config.py # Configuration
│ │ ├── requirements.txt # Dépendances
│ │ ├── Dockerfile # Config conteneur
│ │ └── README.md # Documentation du service
│ ├── aggregation/ # Comptage & agrégation de votes
│ │ ├── aggregator.py # Logique principale d'agrégation
│ │ ├── requirements.txt # Dépendances
│ │ ├── Dockerfile # Config conteneur
│ │ └── README.md # Documentation du service
│ ├── hash_generator/ # Utilitaire de génération de hachage
│ │ ├── generator.py # Script générateur de hachage
│ │ ├── requirements.txt # Dépendances
│ │ ├── Dockerfile # Config conteneur
│ │ └── README.md # Documentation du service
│ └── shared/ # Utilitaires & modèles partagés
│ ├── models.py # Modèles de données
│ └── utils.py # Utilitaires communs
├── demo_ui/ # Interface de vote basée sur le web
│ ├── app.py # Application Flask
│ ├── config.py # Configuration
│ ├── requirements.txt # Dépendances
│ ├── Dockerfile # Config conteneur
│ ├── README.md # Documentation UI
│ ├── templates/ # Modèles HTML
│ │ ├── index.html # Page de vote
│ │ └── results.html # Page de résultats
│ └── static/ # Ressources statiques
│ ├── style.css # Style personnalisé
│ └── script.js # Logique côté client
├── tests/ # Suites de tests
│ ├── integration/ # Tests d'intégration
│ │ ├── conftest.py # Fixtures Pytest
│ │ ├── test_vote_flow.py # Tests de flux de vote bout en bout
│ │ ├── test_api.py # Tests de points de terminaison API
│ │ └── test_duplicate_detection.py # Tests de gestion de doublons
│ ├── unit/ # Tests unitaires
│ ├── load_test.py # Script de test de charge (8M votes)
│ ├── voting_test_gui.py # Panneau d'administration Streamlit
│ ├── test_election_simple.py # Test d'élection BD direct (30k votes)
│ ├── small_rabbitmq_test.py # Test RabbitMQ petite échelle (17 votes)
│ ├── small_election_test.py # Test d'élection petite échelle (17 votes)
│ ├── requirements.txt # Dépendances de tests
│ └── README.md # Documentation des tests
├── monitor_dashboard/ # Tableau de bord de résultats en temps réel
│ ├── server.py # Serveur HTTP Python
│ └── monitor.html # Interface résultats élection en direct
├── monitoring/ # Prometheus & Grafana
│ ├── prometheus/ # Configuration Prometheus
│ │ ├── prometheus.yml # Config principale
│ │ └── alerts.yml # Règles d'alerte
│ ├── grafana/ # Configuration Grafana
│ │ ├── dashboards/ # Fichiers JSON de tableau de bord
│ │ │ └── voting_overview.json # Tableau de bord principal
│ │ └── provisioning/ # Auto-provisionnement
│ │ ├── datasources/ # Config source de données
│ │ │ └── prometheus.yml # Source de données Prometheus
│ │ └── dashboards/ # Provisionnement tableau de bord
│ │ └── dashboards.yml # Config tableau de bord
│ └── README.md # Documentation surveillance
├── scripts/ # Scripts utilitaires
│ ├── preload_test_hashes.py # Générer 8M identifiants de vote de test
│ ├── load_hashes_to_redis.py # Charger base de données de hachage
│ └── quick-start.sh # Script de démarrage une commande
├── k8s/ # Manifestes Kubernetes
│ ├── base/ # Configurations de base
│ └── overlays/ # Configs spécifiques environnement
│ ├── dev/ # Développement
│ └── prod/ # Production
├── test_results/ # Résultats de tests de charge (organisés)
├── data/ # Répertoire de données
│ └── init_db.sql # Schéma de base de données & données d'exemple
├── docker-compose.yml # Pile de développement local
├── ARCHITECTURE.md # Documentation architecture système
├── QUICKSTART.md # Guide de démarrage
├── README.md # README principal (original)
├── readme2.md # README complet (anglais)
└── READMEFR.md # Ce README complet (français)
- ✅ Ajout de l'agrégation "Toutes Régions" au tableau de bord de surveillance
- Totaux électoraux nationaux affichés par défaut
- Agrégation automatique des votes à travers toutes les régions
- Changement transparent entre vues nationales et régionales
- ✅ Création de scripts de test à petite échelle (17 votes)
tests/small_rabbitmq_test.py- Test pipeline RabbitMQtests/small_election_test.py- Test vote électoral- Débogage rapide sans charger 8M votes
- ✅ Création de quick-start.sh - Démarrage système une commande
- ✅ Suppression du graphique de loi redondant du tableau de bord de surveillance
- ✅ Test réussi du pipeline RabbitMQ complet:
- API → RabbitMQ → Workers de Validation → PostgreSQL
- Tous les 17/17 votes traités correctement
- ✅ Mise à jour du README avec guide de démarrage amélioré
- ✅ Généré 8 millions d'identifiants de vote de test (fichier 251MB)
- ✅ Chargé 8M hachages dans Redis (~2 min temps de chargement)
- ✅ Nettoyé 154 fichiers Zone.Identifier
- ✅ Organisé les résultats de tests dans le dossier
test_results/ - ✅ Mise à jour de la documentation (README + GEMINI.md)
Ceci est un projet de démo/prototype. Pour une utilisation en production, développement additionnel requis:
-
Renforcement de la Sécurité:
- Implémenter la limitation de débit par IP
- Ajouter l'authentification/autorisation API
- Activer TLS/SSL pour toutes les communications
- Implémenter la détection d'intrusion
-
Améliorations d'Évolutivité:
- Implémentation de Cluster Redis
- Répliques en lecture PostgreSQL
- Clustering RabbitMQ
- CDN pour les ressources statiques
-
Améliorations Opérationnelles:
- Sauvegardes automatisées
- Procédures de récupération après sinistre
- Déploiement bleu-vert
- Versions canari
-
Conformité:
- Audit de conformité RGPD
- Accessibilité (WCAG 2.1 AA)
- Audit de sécurité
- Tests de pénétration
Pour les problèmes et questions:
- Consulter la section Dépannage
- Revoir ARCHITECTURE.md pour la conception du système
- Voir les README spécifiques aux composants:
- Vérifier les journaux des services:
docker-compose logs <nom-service> - Surveiller la santé du système: http://localhost:3001 (Grafana)
Licence MIT
Copyright (c) 2025 David Marleau
La permission est accordée, gratuitement, à toute personne obtenant une copie de ce logiciel et des fichiers de documentation associés (le "Logiciel"), de traiter le Logiciel sans restriction, y compris sans limitation les droits d'utiliser, copier, modifier, fusionner, publier, distribuer, sous-licencier et/ou vendre des copies du Logiciel, et de permettre aux personnes à qui le Logiciel est fourni de le faire, sous réserve des conditions suivantes:
L'avis de droit d'auteur ci-dessus et cet avis de permission doivent être inclus dans toutes les copies ou parties substantielles du Logiciel.
LE LOGICIEL EST FOURNI "TEL QUEL", SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS MAIS SANS S'Y LIMITER LES GARANTIES DE QUALITÉ MARCHANDE, D'ADÉQUATION À UN USAGE PARTICULIER ET D'ABSENCE DE CONTREFAÇON. EN AUCUN CAS LES AUTEURS OU TITULAIRES DU DROIT D'AUTEUR NE SERONT RESPONSABLES DE TOUTE RÉCLAMATION, DOMMAGE OU AUTRE RESPONSABILITÉ, QUE CE SOIT DANS UNE ACTION CONTRACTUELLE, DÉLICTUELLE OU AUTRE, DÉCOULANT DE, HORS DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU D'AUTRES TRANSACTIONS DANS LE LOGICIEL.
Construit avec ❤️ pour la participation démocratique à grande échelle