Author: David Marleau License: MIT License Status: 🚧 DEMO VERSION - FUNCTIONAL BUT INCOMPLETE 🚧
📖 Lire en Français | 🇬🇧 English Version
A production-grade distributed electronic voting system engineered to handle 8 million concurrent voters across Canada. This system supports both direct democracy referendums (law voting) and electoral elections with single-choice and ranked-choice voting capabilities.
- High Performance: Designed to process 8M+ votes with RabbitMQ queue buffering and horizontal scaling
- Secure: Offline hash validation, zero PII storage, complete audit trails
- Scalable: Microservices architecture ready for Kubernetes deployment
- Real-time: Live results with auto-refresh dashboards
- Monitored: Comprehensive Prometheus + Grafana observability stack
| Metric | Value |
|---|---|
| Target Capacity | 8 million voters |
| Throughput | ~1,000 votes/sec (production target) |
| Current Performance | 150-250 votes/sec (local Docker) |
| Latency (p95) | <100ms |
| Architecture | Microservices + Message Queue |
| Security | Hash-based authentication, no PII |
This is a learning project and proof-of-concept built to share an idea for modernizing democratic voting systems.
Important Context:
- Built by a non-developer as a learning exercise ("vibe coding")
- Demonstrates architecture concepts, not production-ready code
- Functional demo that shows the idea works at scale
- Needs significant work before real-world use
Why Share This?
This project aims to contribute an idea to the democratic technology community. If you're a security professional, experienced developer, or electoral systems expert:
- 🔍 Review the architecture - does the concept have merit?
- 🔧 Fork and improve - make it production-ready
- 💡 Use as inspiration - build something better
- 🤝 Contribute fixes - all improvements welcome
📋 Security Assessment: See SECURITY.md for honest assessment of current limitations and what would be needed for production use.
🎯 Goal: Advance democratic participation technology, whether through this implementation or by inspiring better solutions.
This voting infrastructure could be deployed in various democratic scenarios:
The system supports standard electoral processes:
- Single-choice voting for simple elections
- Ranked-choice voting (RCV) for preferential ballots
- Regional representation with national aggregation
- Real-time results with audit trails
The same infrastructure could enable direct democracy votes on legislation. Examples where referendum mechanisms have been discussed:
-
Parliamentary Salary Adjustments (Canada, April 2024)
- MPs received 4.4% increase (MPs: $203,100/year, PM: $406,200)
- Polling showed 80% public opposition
- Currently automatic with no citizen input mechanism
-
Healthcare Policy Reforms (Quebec, October 2024)
- Bill 2 imposed physician compensation changes
- Some doctors faced salary reductions up to $145,000
- Minister Lionel Carmant resigned; medical associations filed legal challenges
- Passed under closure vote without extended consultation
-
Global Trend Toward Direct Democracy
- 700+ citizen protests in 147+ countries (2023-2024)
- Growing demand for referendum mechanisms on major policy decisions
- Technology enabling real-time citizen participation at scale
This system provides:
- Scalability: Designed for 8M concurrent voters
- Flexibility: Law voting OR elections OR both
- Security: Hash-based authentication, zero PII storage
- Transparency: Open source, auditable results
- Performance: 1,000 votes/sec production target
Organizations could deploy this for:
- Municipal/provincial elections
- Union votes or organizational ballots
- Legislative referendums (if legally enabled)
- Pilot programs testing direct democracy models
- Academic research on voting systems
- Features
- Quick Start
- Architecture Overview
- System Components
- Election System
- Testing
- Deployment
- Security
- Performance & Scaling
- Troubleshooting
- Project Structure
- ✅ Law Voting (Referendums): Direct democracy with Oui/Non choices
- ✅ Electoral Elections: Regional representative elections
- Single-choice voting support
- Ranked-choice voting (RCV) support
- Multi-candidate races with party affiliations
- Election timing controls (start/end datetime)
- Real-time results tracking
- ✅ High Performance: RabbitMQ queue buffering for 8M+ concurrent users
- ✅ Security: Offline hash validation, no PII storage, complete audit trail
- ✅ Scalability: Kubernetes-ready microservices architecture
- ✅ Monitoring: Prometheus + Grafana dashboards with alerting
- ✅ Duplicate Detection: Redis-based deduplication with attempt tracking
- ✅ Real-time Results: Auto-refreshing dashboard (5-second intervals)
- ✅ National Aggregation: "All Regions" view for nationwide totals
- ✅ Load Testing: Comprehensive test suite with 8M vote capacity
./quick-start.shThis script automatically starts all services in ~20 seconds! 🚀
- Docker & Docker Compose
- Python 3.11+
- kubectl (for production deployment)
- Start Docker services:
docker-compose up -d- Start the monitor dashboard:
python3 monitor_dashboard/server.py &- Start the voting interface:
cd demo_ui && python3 app.py &- Access the services:
- Voting UI: http://localhost:3000
- Law voting tab
- Election voting tab
- Results pages
- Admin Panel: http://localhost:8501
- Create elections
- Configure voting methods (single-choice / ranked-choice)
- Set election timing
- Manage candidates
- Monitor Dashboard: http://localhost:4000/monitor.html
- Live election results (auto-refresh every 5s)
- 📊 "All Regions" aggregation - National totals by default
- Region-specific breakdowns available
- Law voting results table
- Vote statistics
- Vote API: http://localhost:8000
- RabbitMQ Management: http://localhost:15672 (guest/guest)
- Grafana: http://localhost:3001 (admin/admin)
- Prometheus: http://localhost:9090
Law Vote:
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"
}'Election Vote:
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"
}'Law Results:
curl http://localhost:8000/api/v1/results/L2025-001Election Results:
curl http://localhost:8000/api/v1/elections/1/regions/1/resultsThe system uses a microservices architecture with message queue buffering to handle high-volume concurrent traffic while maintaining data integrity.
Voter → Ingestion API (FastAPI)
↓
RabbitMQ Queue (BUFFER) ← Handles burst traffic
↓
Validation Workers (Scalable)
├─→ Redis (Hash Validation + Deduplication)
└─→ PostgreSQL (Audit Log)
↓
Aggregation Service
↓
PostgreSQL (Vote Results)
↓
Real-time Dashboard
- Message Queue Buffer: RabbitMQ absorbs traffic spikes (8M voters over 24 hours)
- Stateless Workers: Validation workers can scale horizontally without coordination
- Redis for Speed: Fast hash lookups (8M hashes) and duplicate detection
- PostgreSQL for Persistence: Reliable storage for votes and audit trails
- Batch Aggregation: Efficient vote counting with 100-vote batches
- Ingestion API: FastAPI vote submission endpoint
- RabbitMQ: Message queue buffer (handles burst traffic)
- Redis: Fast hash lookup (8M hashes) and duplicate detection
- PostgreSQL: Persistent storage for votes, elections, candidates, results
- Prometheus + Grafana: Metrics collection and visualization
- Validation Workers: Scalable workers for hash validation (horizontal scaling)
- Aggregation Service: Batch processing for vote counting
Location: services/ingestion_api/
The FastAPI-based entry point for all vote submissions.
Responsibilities:
- Accept HTTP POST requests with vote data
- Perform basic input validation (format, required fields)
- Publish messages to RabbitMQ validation queue
- Return 202 Accepted response immediately (async processing)
- Expose health check and metrics endpoints
Endpoints:
POST /api/v1/vote- Submit law votePOST /api/v1/elections/vote- Submit election voteGET /api/v1/results/{law_id}- Get law resultsGET /api/v1/elections/{election_id}/regions/{region_id}/results- Get election resultsGET /health- Health check
Performance:
- Current: ~250 votes/second (local Docker)
- Target: ~1,000 votes/second (production Kubernetes)
Configuration:
- Rate limiting enabled
- Request/response validation
- CORS support for web UI
- Prometheus metrics export
Location: services/validation_worker/
Scalable workers that process votes from the RabbitMQ validation queue.
Processing Flow:
- Consume from
votes.validationqueue - Validate Hash: Check if hash exists in
valid_hashesRedis SET- If invalid → publish to
votes.reviewqueue with status='invalid'
- If invalid → publish to
- Check Duplicate: Check if hash exists in
voted_hashesRedis SET- If duplicate:
- Increment
duplicate_count:{hash}counter - Publish to
votes.reviewqueue with status='duplicate' and attempt count
- Increment
- If duplicate:
- Process Valid Vote:
- Add hash to
voted_hashesSET - Insert audit log into PostgreSQL
vote_audittable - Publish to
votes.aggregationqueue - ACK message
- Add hash to
Key Features:
- Vote validation against Redis hash database
- Duplicate detection with attempt counting
- Audit logging in PostgreSQL
- Graceful error handling with message requeuing
- Prometheus metrics for monitoring
- Horizontal scaling support
Scaling:
# Scale to 8 workers
docker-compose up -d --scale validation-worker=8Metrics:
validation_votes_processed_total{status}: Total votes by statusvalidation_processing_latency_seconds: Processing timevalidation_errors_total{error_type}: Errors by typeredis_operations_total{operation,status}: Redis operationsdatabase_operations_total{operation,status}: DB operations
Location: services/aggregation/
Consumes validated votes from RabbitMQ and updates PostgreSQL with aggregated vote counts.
How It Works:
The aggregation service uses intelligent batching for efficiency:
- Size-based batching: Processes when batch reaches 100 votes
- Time-based batching: Processes every 1 second if votes are pending
- Shutdown batching: Processes all remaining votes on graceful shutdown
Database Operations:
- Uses
INSERT ... ON CONFLICT UPDATE(UPSERT) for efficiency - Batch updates minimize database connections
- Connection pooling for performance
- Automatic retry with exponential backoff
Database Schema:
vote_results - Primary aggregation table:
law_id(PK): Law identifieroui_count: Count of "oui" votesnon_count: Count of "non" votesupdated_at: Last update timestamp
vote_audit - Individual vote audit log:
vote_hash(UNIQUE): Hash of the votecitizen_id: Voter identifierlaw_id: Law identifierchoice: Vote choice (oui/non)timestamp: Vote timestamp
Performance:
- Processes ~10,000 votes/second (hardware dependent)
- Batch size tunable for throughput vs latency
- Horizontal scaling supported
Prometheus Metrics:
votes_aggregated_total{law_id, choice}: Total votes aggregatedcurrent_vote_totals{law_id, choice}: Current vote countsbatch_processing_duration_seconds: Processing timebatch_size_processed_total: Votes per batchaggregation_errors_total{error_type}: Aggregation errors
Location: services/hash_generator/
A containerized utility for generating cryptographic hashes for voter authentication.
Purpose: Create unique authentication credentials for testing and deployment.
Hash Format:
Each hash is computed as: SHA-256(f"{nas}|{code.upper()}|{law_id}")
Generated Data:
{
"nas": "123456789", // 9-digit random number
"code": "ABC123", // 6-character uppercase alphanumeric
"law_id": "L2025-001", // Law identifier
"hash": "a1b2c3d4e5f6...", // SHA-256 hash
"vote": "oui" // Random vote (oui/non)
}Usage:
# Generate 1 million hashes
python generator.py --count 1000000 --output ./output
# Generate 5 million hashes for a specific law
python generator.py --count 5000000 --output ./output --law-id L2025-042
# Docker usage
docker run -v $(pwd)/output:/output hash-generator \
--count 1000000 \
--output /outputOutput:
- Sharded JSON files (
hashes_shard_0000.json,hashes_shard_0001.json, etc.) - Default: 1 million hashes per shard
- Progress bar with real-time generation status
- Summary statistics (vote distribution, file sizes)
Performance:
- Generation speed: ~100,000-500,000 hashes per second
- Memory efficient with sharded output
- Can generate 8M hashes in under 2 minutes
Integration:
- Load hashes into Redis for validation
- Distribute shard files to voting nodes
- Use for load testing and simulation
Location: demo_ui/
A Flask-based web interface for the electronic voting system with real-time results display.
Features:
- Voting Form: Submit votes with NAS, validation code, law selection, and vote choice
- Real-time Validation: Client-side form validation with instant feedback
- Results Display: Live results with auto-refresh every 5 seconds
- Interactive Charts: Visual representation using Chart.js
- Responsive Design: Mobile-friendly Bootstrap 5 interface
- Dark Theme: Professional dark color scheme
- Error Handling: Comprehensive error messages for all scenarios
Routes:
GET /- Main voting page with form and current resultsPOST /vote- Submit a vote (AJAX endpoint)GET /results- Full results page with charts and tablesGET /api/results- JSON API for fetching current resultsGET /health- Health check endpoint
Technologies:
- Backend: Flask 3.0
- Frontend: Bootstrap 5, Chart.js
- HTTP Client: Requests library
- Styling: Custom CSS with dark theme
- JavaScript: Vanilla JS with AJAX
Running Locally:
cd demo_ui
pip install -r requirements.txt
python app.py
# Access at http://localhost:3000Production Deployment:
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:3000 app:appLocation: monitoring/
Comprehensive observability with Prometheus metrics collection and Grafana visualization.
Components:
- Prometheus: Time-series database and alerting engine
- Grafana: Visualization and dashboard platform
- Exporters: Specialized exporters for Redis, PostgreSQL, and RabbitMQ
Access:
- Grafana: http://localhost:3001 (admin/admin)
- Main dashboard: "Election Voting System - Overview"
- Prometheus: http://localhost:9090
- Query interface and alert status
Key Dashboards:
- Votes Per Second - Time series showing vote ingestion rate
- Total Votes by Law - Gauge showing cumulative votes per law
- Validation Status Breakdown - Pie chart of valid/invalid/duplicate votes
- Queue Depth - Time series of message queue depths
- API Latency (p50/p95/p99) - Percentile latencies
- Duplicate Attempt Rate - Percentage of duplicate attempts
- Active Workers - Number of running validation workers
- Redis Memory Usage - Memory consumption gauge
- Database Connections - DB connection pool utilization
- HTTP Requests by Status Code - Stacked area chart
Alert Rules:
Critical Alerts (Immediate Action Required):
IngestionAPIDown- API unreachable for 1 minuteValidationWorkerDown- Less than 2 workers for 2 minutesRabbitMQDown- RabbitMQ unreachable for 1 minuteRedisDown- Redis unreachable for 1 minutePostgresDown- PostgreSQL unreachable for 1 minuteCriticalValidationQueueDepth- >50,000 messages for 2 minutesCriticalDuplicateRate- >15% duplicate rate for 5 minutesAPICriticalLatency- p95 latency >500ms for 2 minutesCriticalAPIErrorRate- >15% error rate for 2 minutes
Warning Alerts (Action Recommended):
HighValidationQueueDepth- >10,000 messages for 5 minutesHighDuplicateRate- >5% duplicate rate for 10 minutesAPIHighLatency- p95 latency >200ms for 5 minutesHighAPIErrorRate- >5% error rate for 5 minutes
Metrics Categories:
Application Metrics:
votes_received_total- Counter of votes receivedvotes_by_law_total- Counter per law/referendumvotes_validation_processed_total- Counter of validated votesvotes_aggregated_total- Counter of aggregated voteshttp_requests_total- HTTP requests by status code
Infrastructure Metrics:
rabbitmq_queue_messages- Messages in queueredis_memory_used_bytes- Memory usagepg_stat_database_numbackends- Active connectionsvalidation_duration_seconds- Processing time histogram
Elections Table:
election_code,election_name,election_typestart_datetime,end_datetime- Voting window controlvoting_method-single_choiceorranked_choicestatus-draft,active,completed
Candidates Table:
- Links to elections, regions, and political parties
first_name,last_name,bio- Party affiliations with colors and branding
Election Results:
- Real-time aggregation in
election_resultstable - Vote counts and percentages per candidate/region
- National aggregation across all regions
- ✅ Ranked-choice voting toggle in Admin Panel
- ✅ Election timing (start/end datetime)
- ✅ Vote cutoff validation (no votes after deadline)
- ✅ Election results on monitor dashboard with "All Regions" aggregation
- ✅ National election totals (automatic aggregation across all regions)
- ✅ Region-specific result breakdowns
- ✅ RabbitMQ pipeline: API → Queue → Workers → PostgreSQL
- ✅ Multi-candidate elections working
- ✅ Party colors and branding
- ✅ Real-time auto-refresh (5-second intervals)
Location: tests/
Comprehensive integration and load testing suite.
- Total Integration Tests: 40+
- Test Coverage Target: >80%
- Performance Targets:
- Throughput: 1000 votes/second
- Latency: p95 < 100ms
- Success Rate: >99.9%
# Run all integration tests
cd tests/
pytest integration/ -v
# With coverage report
pytest integration/ -v --cov --cov-report=html
# Run specific test files
pytest integration/test_vote_flow.py -v
pytest integration/test_api.py -v
pytest integration/test_duplicate_detection.py -vGenerate 8 million test credentials:
python3 scripts/preload_test_hashes.py 8000000This creates:
test_votes.txt(251MB, 8M lines)- Loads all hashes into Redis for validation
Run load tests:
# Standard load test (with valid credentials)
python3 -u tests/load_test.py --votes 100000 --rate 1000
# Direct DB test (elections, 30k votes)
python3 tests/test_election_simple.py
# Using Locust (web UI)
locust -f tests/load_test.py --host=http://localhost:8000
# Open browser to http://localhost:8089Performance Results:
- Direct DB: 3,558 votes/sec
- API Load Test: 160-265 votes/sec (with full validation pipeline)
- System Capacity: Designed for 8M votes in 24 hours (~92 votes/sec average)
- Integration Tests - End-to-end testing of complete voting pipeline
- API Tests - REST API endpoint validation
- Duplicate Detection Tests - Vote deduplication logic verification
- Load Tests - Performance and scalability testing
# Start all services
docker-compose up -d
# Scale validation workers
docker-compose up -d --scale validation-worker=5
# Check status
docker-compose ps
# View logs
docker-compose logs -f validation-worker# Apply base configuration
kubectl apply -k k8s/overlays/prod/
# Scale workers
kubectl scale deployment validation-worker --replicas=20
# Check status
kubectl get pods
# View logs
kubectl logs -f deployment/validation-workerDevelopment (docker-compose):
- Current performance: ~250 votes/second via API
- Direct DB: 3,500+ votes/second
- Good for testing and demos
Production (Kubernetes):
- 10x Ingestion API replicas
- 20x Validation Workers
- 3x Aggregation Service
- Redis Cluster (3 nodes)
- PostgreSQL with read replicas
- Target: 1000 votes/second sustained
- ✅ No PII Storage: Only hashes stored, no personally identifiable information
- ✅ Offline Hash Database: Prevents fake votes, hashes generated offline
- ✅ Duplicate Detection: Redis-based deduplication with attempt tracking
- ✅ Complete Audit Trail: Every vote logged in PostgreSQL
- ✅ Rate Limiting: API rate limiting to prevent abuse
- ✅ Election Timing Enforcement: No early/late votes accepted
- ✅ TLS Communication: Inter-service communication encrypted (production)
The system uses SHA-256 hashes for voter authentication:
Hash = SHA-256(NAS | Code | Law_ID)
Benefits:
- No personal information stored in the system
- Offline hash generation ensures vote credential integrity
- Cannot reverse-engineer voter identity from hash
- Each hash is unique to voter + law combination
Redis:
- Valid hashes stored in
valid_hashesSET (8M hashes) - Voted hashes stored in
voted_hashesSET (deduplication) - Duplicate attempt counters:
duplicate_count:{hash} - TTL set on all keys for automatic cleanup
PostgreSQL:
- Audit log:
vote_audittable (immutable record) - Results:
vote_resultstable (aggregated counts) - Elections:
elections,candidates,election_resultstables - All tables indexed for performance and security queries
| Metric | Value |
|---|---|
| Peak Throughput (API) | ~250 votes/sec |
| Peak Throughput (Direct DB) | ~3,500 votes/sec |
| p95 Latency | 80ms |
| Success Rate | 99.5% |
| Metric | Target |
|---|---|
| Peak Throughput | 1,000 votes/sec |
| p95 Latency | <100ms |
| Success Rate | >99.9% |
| Availability | 99.9% |
Scenario: 8 million voters over 24-hour voting period
Average Load: 8,000,000 / (24 * 3600) = ~92 votes/second
Peak Load (assuming 10x spike): ~920 votes/second
Scaling Strategy:
-
Horizontal Scaling:
- 10x Ingestion API instances (load balanced)
- 20x Validation Workers (parallel processing)
- 3x Aggregation Services (batch processing)
-
Infrastructure Scaling:
- Redis Cluster (3 nodes, sharded)
- PostgreSQL with read replicas (1 primary, 2 replicas)
- RabbitMQ Cluster (3 nodes, mirrored queues)
-
Performance Optimizations:
- Connection pooling (PostgreSQL)
- Batch operations (Aggregation)
- Prefetch count tuning (RabbitMQ)
- Redis pipelining
Capacity Planning:
| Component | Min | Medium Load | High Load |
|---|---|---|---|
| API Instances | 2 | 4 | 10 |
| Validation Workers | 4 | 8 | 20 |
| Aggregation Services | 1 | 2 | 3 |
| Expected Throughput | ~200/sec | ~500/sec | ~1000/sec |
Symptoms: Votes submitted but not appearing in results
Diagnostic Steps:
- Check RabbitMQ queue depth:
curl -u guest:guest http://localhost:15672/api/queues - Check validation worker logs:
docker-compose logs validation-worker - Verify Redis has hashes:
docker-compose exec redis redis-cli SCARD valid_hashes
Solutions:
- Scale validation workers:
docker-compose up -d --scale validation-worker=8 - Load hashes into Redis:
python3 scripts/load_hashes_to_redis.py - Restart workers:
docker-compose restart validation-worker
Diagnostic Steps:
- Check election_results table:
docker-compose exec postgres psql -U voting_user -d voting -c "SELECT * FROM election_results;"
- Verify candidates exist in admin panel
- Check monitor dashboard for live results
- Verify election is active and within time window
Solutions:
- Verify election status: Check admin panel Tab 7
- Check aggregation service logs:
docker-compose logs aggregation - Verify time window: Ensure current time is between start_datetime and end_datetime
Symptoms: Messages accumulating in validation or aggregation queues
Possible Causes:
- Insufficient worker capacity
- Worker crashes or deadlocks
- Database performance issues
- Network connectivity problems
Solutions:
- Scale up workers:
docker-compose up -d --scale validation-worker=8 - Restart stuck workers:
docker-compose restart validation-worker - Check database performance: Monitor connection count and query times
- Monitor Grafana dashboard for bottlenecks
Diagnostic Steps:
- Check Prometheus metrics: http://localhost:9090
- Monitor Redis memory:
docker-compose exec redis redis-cli INFO memory - Check database connections:
docker-compose exec postgres psql -U voting_user -d voting -c "SELECT count(*) FROM pg_stat_activity;"
Solutions:
- Scale validation workers:
docker-compose up -d --scale validation-worker=5 - Increase Redis memory limit in docker-compose.yml
- Optimize database queries or add indexes
If tests or system are failing unexpectedly:
# Stop and remove all containers, volumes, networks
docker-compose down -v
# Remove test artifacts
rm -rf htmlcov/ .coverage .pytest_cache/
# Restart fresh
docker-compose up -d
sleep 30
# Reload hashes
python3 scripts/load_hashes_to_redis.py --sampleelectionscriptanalyse/
├── services/ # Microservices
│ ├── ingestion_api/ # Vote submission API (FastAPI)
│ │ ├── main.py # API endpoints
│ │ ├── requirements.txt # Dependencies
│ │ └── Dockerfile # Container config
│ ├── validation_worker/ # Hash validation & deduplication
│ │ ├── worker.py # Main worker logic
│ │ ├── redis_client.py # Redis operations
│ │ ├── rabbitmq_client.py # RabbitMQ consumer
│ │ ├── database.py # PostgreSQL client
│ │ ├── config.py # Configuration
│ │ ├── requirements.txt # Dependencies
│ │ ├── Dockerfile # Container config
│ │ └── README.md # Service documentation
│ ├── aggregation/ # Vote counting & aggregation
│ │ ├── aggregator.py # Main aggregation logic
│ │ ├── requirements.txt # Dependencies
│ │ ├── Dockerfile # Container config
│ │ └── README.md # Service documentation
│ ├── hash_generator/ # Hash generation utility
│ │ ├── generator.py # Hash generator script
│ │ ├── requirements.txt # Dependencies
│ │ ├── Dockerfile # Container config
│ │ └── README.md # Service documentation
│ └── shared/ # Shared utilities & models
│ ├── models.py # Data models
│ └── utils.py # Common utilities
├── demo_ui/ # Web-based voting interface
│ ├── app.py # Flask application
│ ├── config.py # Configuration
│ ├── requirements.txt # Dependencies
│ ├── Dockerfile # Container config
│ ├── README.md # UI documentation
│ ├── templates/ # HTML templates
│ │ ├── index.html # Voting page
│ │ └── results.html # Results page
│ └── static/ # Static assets
│ ├── style.css # Custom styling
│ └── script.js # Client-side logic
├── tests/ # Test suites
│ ├── integration/ # Integration tests
│ │ ├── conftest.py # Pytest fixtures
│ │ ├── test_vote_flow.py # End-to-end vote flow tests
│ │ ├── test_api.py # API endpoint tests
│ │ └── test_duplicate_detection.py # Duplicate handling tests
│ ├── unit/ # Unit tests
│ ├── load_test.py # Load testing script (8M votes)
│ ├── voting_test_gui.py # Streamlit admin panel
│ ├── test_election_simple.py # Direct DB election test (30k votes)
│ ├── small_rabbitmq_test.py # Small-scale RabbitMQ test (17 votes)
│ ├── small_election_test.py # Small-scale election test (17 votes)
│ ├── requirements.txt # Test dependencies
│ └── README.md # Testing documentation
├── monitor_dashboard/ # Real-time results dashboard
│ ├── server.py # Python HTTP server
│ └── monitor.html # Live election results UI
├── monitoring/ # Prometheus & Grafana
│ ├── prometheus/ # Prometheus configuration
│ │ ├── prometheus.yml # Main config
│ │ └── alerts.yml # Alert rules
│ ├── grafana/ # Grafana configuration
│ │ ├── dashboards/ # Dashboard JSON files
│ │ │ └── voting_overview.json # Main dashboard
│ │ └── provisioning/ # Auto-provisioning
│ │ ├── datasources/ # Datasource config
│ │ │ └── prometheus.yml # Prometheus datasource
│ │ └── dashboards/ # Dashboard provisioning
│ │ └── dashboards.yml # Dashboard config
│ └── README.md # Monitoring documentation
├── scripts/ # Utility scripts
│ ├── preload_test_hashes.py # Generate 8M test vote credentials
│ ├── load_hashes_to_redis.py # Load hash database
│ └── quick-start.sh # One-command startup script
├── k8s/ # Kubernetes manifests
│ ├── base/ # Base configurations
│ └── overlays/ # Environment-specific configs
│ ├── dev/ # Development
│ └── prod/ # Production
├── test_results/ # Load test results (organized)
├── data/ # Data directory
│ └── init_db.sql # Database schema & sample data
├── docker-compose.yml # Local development stack
├── ARCHITECTURE.md # System architecture documentation
├── QUICKSTART.md # Getting started guide
├── README.md # Main README (original)
└── readme2.md # This comprehensive README
- ✅ Added "All Regions" aggregation to monitor dashboard
- National election totals shown by default
- Automatic vote aggregation across all regions
- Seamless switching between national and regional views
- ✅ Created small-scale testing scripts (17 votes)
tests/small_rabbitmq_test.py- Test RabbitMQ pipelinetests/small_election_test.py- Test election voting- Fast debugging without loading 8M votes
- ✅ Created quick-start.sh - One-command system startup
- ✅ Removed redundant law chart from monitor dashboard
- ✅ Successfully tested complete RabbitMQ pipeline:
- API → RabbitMQ → Validation Workers → PostgreSQL
- All 17/17 votes processed correctly
- ✅ Updated README with improved quick-start guide
- ✅ Generated 8 million test vote credentials (251MB file)
- ✅ Loaded 8M hashes into Redis (~2 min load time)
- ✅ Cleaned up 154 Zone.Identifier files
- ✅ Organized test results into
test_results/folder - ✅ Updated documentation (README + GEMINI.md)
This is a demo/prototype project. For production use, additional development required:
-
Security Hardening:
- Implement rate limiting per IP
- Add API authentication/authorization
- Enable TLS/SSL for all communications
- Implement intrusion detection
-
Scalability Enhancements:
- Redis Cluster implementation
- PostgreSQL read replicas
- RabbitMQ clustering
- CDN for static assets
-
Operational Improvements:
- Automated backups
- Disaster recovery procedures
- Blue-green deployment
- Canary releases
-
Compliance:
- GDPR compliance audit
- Accessibility (WCAG 2.1 AA)
- Security audit
- Penetration testing
For issues and questions:
- Check Troubleshooting section
- Review ARCHITECTURE.md for system design
- See component-specific READMEs:
- Check service logs:
docker-compose logs <service-name> - Monitor system health: http://localhost:3001 (Grafana)
MIT License
Copyright (c) 2025 David Marleau
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Built with ❤️ for democratic participation at scale