Full-stack application to visualize Costa Rica's electoral registry (Padron Electoral) data.
- Frontend: React + Vite + Tailwind CSS + shadcn/ui + Recharts
- Backend: AWS Lambda (Node.js 20) with 13 AWS services orchestrated via MiniStack
- Database: DynamoDB (single-table design with pre-aggregated data)
- Local Dev: MiniStack (LocalStack alternative) on port 4566
- Docker
- Node.js 20+
- AWS CLI v2
make runThis starts MiniStack, creates all AWS resources, and launches both the API server and frontend.
Open http://localhost:5173, click the gear icon (Admin), go to the Import tab, and drop padron_completo.zip to load electoral data.
frontend/src/components/ React UI components (dashboard, admin, maps)
backend/src/ Lambda handler (DynamoDB queries)
scripts/ Dev server, data loader, cache module
infra/ CDK infrastructure (DynamoDB, S3, CloudFront, Lambda)
| Service | Purpose |
|---|---|
| DynamoDB | Primary database (single-table design) |
| S3 | Raw data storage, static hosting |
| CloudFront | CDN for frontend assets |
| Lambda | API handler |
| SQS | Import job queue and event delivery |
| SNS | Notifications (import progress, completion) |
| Step Functions | Import pipeline orchestration |
| Athena | Ad-hoc SQL queries over electoral data |
| OpenSearch | Full-text search (voter records) |
| ElastiCache | API response caching (in-memory LRU locally) |
| Cognito | Authentication (mock in local dev) |
| IAM | Service permissions |
| CloudWatch | Logging and monitoring |
| Method | Path | Description |
|---|---|---|
| GET | /api/stats | Total voters, province counts |
| GET | /api/provinces | All provinces with voter counts |
| GET | /api/provinces/:code/cantons | Cantons for a province |
| GET | /api/provinces/:code/surnames | Top surnames in a province |
| GET | /api/cantons/:code/districts | Districts for a canton |
| GET | /api/districts/:code/voters | Paginated voter records for a district |
| GET | /api/expirations | ID expiration year distribution |
| GET | /api/surnames | Top 50 surnames nationally |
| GET | /api/firstnames | Top 50 first names nationally |
| GET | /api/search | Full-text search across voter records |
| GET | /api/filter | Aggregated stats for matching voters |
| POST | /api/import | Upload zip file, stores in S3, starts processing |
| GET | /api/import/status | Current import job progress |
| POST | /api/import/cancel | Cancel a running import |
| GET | /api/events | SSE stream for real-time push notifications |
| GET | /api/admin/services | Health status of all AWS services |
| GET | /api/admin/notifications | Notification history |
| POST | /api/athena | Execute SQL query via Athena |
| GET | /api/pipeline/status | Step Functions execution history |
| POST | /api/pipeline/start | Start import pipeline execution |
Single table design with composite keys:
| PK | SK | Description |
|---|---|---|
| STATS | TOTAL | Overall totals |
| STATS | BY_PROVINCE | All province counts in one item |
| STATS | EXPIRATION_YEAR#YYYY | Count per expiration year |
| STATS | TOP_SURNAMES | Top 50 surnames nationally |
| STATS | TOP_FIRSTNAMES | Top 50 first names nationally |
| PROVINCE#N | SUMMARY | Province summary |
| PROVINCE#N | TOP_SURNAMES | Top surnames for that province |
| CANTON#NNN | SUMMARY | Canton summary |
| DISTRICT#NNNNNN | SUMMARY | District summary with name |
| DISTRICT#NNNNNN | VOTER#cedula | Individual voter record |
| SYSTEM | IMPORT_JOB | Persisted import job state |
| SYSTEM | NOTIFICATION#timestamp | Notification log entry |
GSI gsi-province: PK=province, SK=canton (for querying cantons/districts by province).
This project uses mock authentication for local development (POC mode). The AuthProvider accepts any credentials without validation.
To enable real Cognito authentication:
- Uncomment the Cognito authorizer in the CDK stack (
infra/) - Set the
USER_POOL_IDenvironment variable to your Cognito User Pool ID - The frontend AuthGate component will enforce login before accessing the dashboard
| Command | Description |
|---|---|
| make run | Start everything (MiniStack + API + Frontend) |
| make stop | Stop all services and clean up |
| make dev | Start frontend only (localhost:5173) |
| make dev-api | Start API only (localhost:3001) |
| make deploy | Start MiniStack and create AWS resources |
| make build | Build backend and frontend |
| make up | Start MiniStack container |
| make down | Stop MiniStack container |
| make destroy | Delete table and remove containers/volumes |
| make clean | Remove all node_modules and build artifacts |
| make install | Install all dependencies |
| make help | Show available commands |
Tribunal Supremo de Elecciones (TSE) de Costa Rica - Padron Nacional Electoral. Approximately 3.7 million registered voters across 7 provinces and 84 cantons.