Database-backed election result explorer, public API, and ETL platform for
civicresultmaps.org.
This repository is the long-term home for the Civic Result Maps platform. The
older Camreyn/wisconsin-2024-election-mapper project remains the legacy static
GitHub Pages app and a source of migration knowledge for state configs, parser
patterns, generated state registries, and validation expectations.
- Next.js App Router and React for the frontend and public read API.
- Neon Postgres, modeled through Drizzle, for normalized election data.
- Python ETL tooling for config-driven source imports, validation, staging, and reviewed promotion.
- GitHub Actions and Vercel preview deployments for CI/CD.
GET /api/statesGET /api/jurisdictions?state=<STATE>&fips=<GEOID>GET /api/elections?year=2024&office=presidentGET /api/results?state=WI&year=2024&level=countyGET /api/sources?state=WI&year=2024GET /api/coverage?state=WI&year=2024GET /api/security-incidents?state=GA&year=2024(unit-aware response schema2.0.0)
Public reads are enabled. Admin writes, source updates, and production data promotion are intentionally private and CI-gated.
npm install
npm run devThe app uses built-in seed data when DATABASE_URL is not set. After Neon is
provisioned, set DATABASE_URL and run:
npm run db:push
npm run db:seed
npm run build
npm testnpm run db:seed loads starter WI/MN/WA records into Postgres so the public API
switches from seed fallback mode to database-backed reads immediately.
The database scripts read .env.local and accept either DATABASE_URL or the
Vercel Neon-provided POSTGRES_URL.
This repo is intended to be pushed to:
https://github.com/Camreyn/civicresultmaps
After the GitHub repo exists and the first commit is pushed:
- Create a Vercel project from
Camreyn/civicresultmaps. - Provision Neon through Vercel Marketplace.
- Pull or set
DATABASE_URL. - Run
npm run db:pushandnpm run db:seed. - Add
civicresultmaps.organdwww.civicresultmaps.orgto the Vercel project. - Point DNS to Vercel and wait for certificate issuance.
Validate the Wisconsin starter config:
npm run etl:validateCreate a reviewed staging artifact:
npm run etl:importThe v1 ETL package keeps agents advisory only. Agents can propose parser mappings, summarize source pages, and flag validation gaps, but production data writes remain human-reviewed.
Historical 2016/2020 advisory evaluation requires official same-grain presidential and comparison-contest rows. See docs/historical-advisory-indicators.md for the candidate-neutral row contract, evaluated/not-evaluated semantics, broad-signal warning, and promotion safeguards.