A transparency platform that publishes neutral child safety voting records for U.S. lawmakers using public data from the Congress.gov API. Each recorded floor vote is shown with how the member voted and whether that vote is consistent with Operation Child Shield board-adopted policy positions. The site does not publish letter grades, rankings, or scorecards.
Production: https://operationchildshield.org
| Resource | Link |
|---|---|
| Latest SquidScanner report (operationchildshield.org) | View full security report |
Independent agentic recon + AI analysis of the production site (headers, surface, findings). Open the report for grades, issues, and remediation detail.
| Route | Description |
|---|---|
/ |
Member directory with search, party/state filters, lazy-loaded voting records, policy badges per vote, Yes/No pie charts, and infinite scroll |
/member/[bioguideId] |
Full voting record: vote breakdown, policy badges, summary stats, Yes/No pie chart, Congress.gov links, social share |
/bills |
30 tracked bills in three sections: House roll-call (scored), floor action (tracked only), introduced |
/metrics |
Bill-level roll-call statistics, state heat map, state policy-consistency table, charts |
/states/[code] |
State overview: House policy-consistency KPIs and member list for that state |
/learn |
Education for people seeking help/clarity and people who want to take action |
/get-involved |
Signup form for volunteers, advocates, media, and partners |
/the-facts |
The Facts — neutral bill bullets with Congress.gov deep links |
/about |
Policy positions and methodology (links to The Facts) |
/board |
Board of directors (enabled via ENABLE_BOARD_PAGE) |
/disclaimer |
Legal disclaimer (entertainment purposes, public data sources, contact) |
/partners |
Partner organizations |
/directory |
Alternate member listing |
Hidden pages (feature-flagged off)
These routes return 404 until enabled in frontend/src/lib/feature-flags.ts:
| Route | Flag | Description |
|---|---|---|
/donate |
ENABLE_DONATE_PAGE |
Donation UI with suggested amounts (no payment processor wired yet) |
Set ENABLE_DONATE_PAGE to true, add nav links in Header.tsx / Footer.tsx if desired, and rebuild. The board page is already enabled (ENABLE_BOARD_PAGE = true) with nav links in the header and footer.
| Endpoint | Description |
|---|---|
GET /api/health |
Service health, congress session, API key configured |
GET /api/members |
Member directory (search, chamber, state, party, limit, offset) |
GET /api/members/{bioguideId}/report-card |
Member voting record (key_votes, policy_consistent per vote; no letter grades) |
GET /api/bills |
Tracked legislation with floor-status metadata |
GET /api/metrics |
Bill-level roll-call aggregates plus byState House policy-consistency totals (no grades/rankings) |
GET /api/metrics/export |
CSV export of per-bill roll-call summaries |
POST /api/involve |
Volunteer/advocate signup (JSON body; stored as JSONL under CACHE_DIR) |
POST /api/analytics/event |
Ingest only — records a page view into server-side SQLite (analytics.db). No public read API or UI. Inspect via SSH + a SQLite browser. |
Interactive API docs: http://localhost:8000/docs (local).
- Only House roll-call votes on verified bills produce per-member vote records with policy-consistency indicators.
- Senate members and voice-vote bills are tracked for context but do not produce individual House roll-call records (Congress.gov limitation).
- Each scored vote includes
vote_cast, bill metadata, Congress.gov links, andpolicy_consistent(compared to board-adopted bill stances). - Pro-protection bills: Aye aligns with OCS policy; Nay does not. Anti-protection bills: Nay aligns; Aye does not.
- Present and Not Voting are recorded factually and marked not consistent with policy where applicable.
- Letter grades, percentage scores, and member rankings are computed internally for policy alignment only and are stripped from all public API responses.
- Bills are verified against Congress.gov titles at backend startup.
- Responses use a stale-while-revalidate file cache (24-hour TTL by default): expired cache is served immediately while fresh data rebuilds in the background.
Full explanation: in-app /about page (Policy Positions).
- Docker and Docker Compose (recommended), or
- Python 3.12+, Node.js 24+, npm
- A free Congress.gov API key (required for the backend)
-
Complete the sign-up form with your name and email.
-
Congress.gov will email you an API key (usually within minutes to one business day).
-
Copy the key into your
.envfile:CONGRESS_API_KEY=your_key_here
- Congress.gov publishes a rate limit of 5,000 requests per hour per key (confirm current limits on their site).
- This app caches all Congress.gov responses on disk for 24 hours to minimize API usage.
- The heaviest operations are building member report cards and the metrics dashboard (first request after cache expiry). Steady-state traffic is mostly cache hits with background revalidation.
- Never commit your API key. Keep it only in
.env(gitignored) or your deployment secrets.
curl "https://api.congress.gov/v3/member/congress/119?api_key=YOUR_KEY&format=json&limit=1"You should receive JSON with a members array.
git clone <repo-url> OperationChildShield
cd OperationChildShield
cp .env.example .env
# Edit .env — set CONGRESS_API_KEY
docker compose up --build| Service | URL |
|---|---|
| Frontend | http://localhost:3000 |
| Backend API | http://localhost:8000 |
| API docs | http://localhost:8000/docs |
Use the helper script for backend + frontend together:
./scripts/dev-local.sh start # start both services
./scripts/dev-local.sh status # check PIDs / ports
./scripts/dev-local.sh stop # stop both
./scripts/dev-local.sh restart # restart both| Service | URL |
|---|---|
| Frontend | http://localhost:3000 |
| Backend API | http://localhost:8000 |
Logs: data/backend-dev.log, data/frontend-dev.log
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
export CONGRESS_API_KEY=your_key
export CONGRESS_NUMBER=119
export CACHE_TTL_SECONDS=86400
export CORS_ORIGINS=http://localhost:3000
uvicorn app.main:app --reload --port 8000cd frontend
npm install
NEXT_PUBLIC_API_URL=http://localhost:8000 npm run dev| Variable | Default | Description |
|---|---|---|
CONGRESS_API_KEY |
(required) | Congress.gov API key |
CONGRESS_NUMBER |
119 |
Congress session to query |
CACHE_TTL_SECONDS |
86400 |
File cache TTL (24 hours) |
CORS_ORIGINS |
http://localhost:3000 |
Comma-separated allowed origins |
NEXT_PUBLIC_API_URL |
— | Browser-facing API URL (frontend) |
API_URL |
— | Server-side API URL inside Docker network |
NEXT_PUBLIC_SITE_URL |
https://operationchildshield.org |
Canonical site URL for Open Graph metadata |
See .env.example for a template.
OperationChildShield/
├── AGENTS.md # Agent notes (deployment sensitivity, roadmap pointer)
├── backend/
│ ├── app/
│ │ ├── bills.py # Curated tracked legislation
│ │ ├── bill_verification.py # Startup Congress.gov title checks
│ │ ├── cache.py # File cache with stale-while-revalidate
│ │ ├── cache_refresh.py # Background cache revalidation
│ │ ├── congress_client.py # Congress.gov HTTP client + cache
│ │ ├── scoring.py # Vote scoring, policy_consistent, internal grades (not exposed)
│ │ ├── services.py # Report cards, directory, API serialization
│ │ ├── metrics.py # Bill-level roll-call aggregation (no member rankings)
│ │ └── routes/ # FastAPI routers
│ └── tests/ # 97 pytest unit tests (no live API calls)
├── frontend/
│ └── src/
│ ├── app/ # Next.js App Router pages
│ ├── components/
│ │ ├── charts/ # SVG pie and bar charts (metrics + member cards)
│ │ ├── metrics/ # Metrics page chart sections
│ │ ├── PolicyBadge.tsx # Per-vote policy consistency badges
│ │ └── PolicyLegend.tsx # Badge legend (landing + member pages)
│ └── lib/ # API client, types, vote-count helpers + Vitest tests
├── .github/workflows/ci.yml # Backend + frontend test CI on push/PR
├── scripts/
│ ├── deploy-prod.example.sh # Production deploy template (copy → deploy-prod.sh)
│ ├── dev-local.sh # Local backend + frontend without Docker
│ ├── verify_bills.py # Manual bill verification
│ └── test.sh # Run backend + frontend tests
├── docker-compose.yml # Local development stack
├── docker-compose.prod.example.yml # Production template (copy → docker-compose.prod.yml)
├── Caddyfile.example # Reverse proxy template (copy → Caddyfile)
└── Makefile # Common dev commands
Deployment scripts and production configs (deploy-prod.sh, docker-compose.prod.yml, Caddyfile, deploy_paramiko.py, etc.) are gitignored — copy from the *.example templates locally. See AGENTS.md.
132 unit tests total — 97 backend (pytest) + 35 frontend (Vitest). CI runs both suites on every push and pull request to main (.github/workflows/ci.yml).
# All tests (recommended — uses backend venv via scripts/test.sh)
make test
# Backend only
make test-backend
# Frontend only
make test-frontend
# Lint frontend
make lint
# Verify tracked bills against Congress.gov (requires API key)
make verify-bills| Module | Tests |
|---|---|
scoring, bills, utils |
Vote normalization, policy consistency, bill catalog, member parsing |
services, metrics |
Report-card serialization, bill-level metrics aggregation |
cache, config, rate_limit |
File cache TTL, stale-while-revalidate, settings, concurrency limits |
bill_verification |
Congress.gov title verification (mocked client) |
routes/health |
Health endpoint (isolated FastAPI app) |
Backend tests do not call Congress.gov — pure logic, mocked async clients, and an isolated health route.
| Module | Tests |
|---|---|
format, party, states |
Member labels, policy consistency helpers, state codes |
vote-counts |
Yes/No vote counting, bill roll-call aggregation for charts |
share, fetch-queue, theme |
Social sharing URLs, API request concurrency, dark/light theme |
Production runs with Docker Compose behind Caddy (TLS + reverse proxy: /api/* → backend, everything else → frontend).
Deployment configs are gitignored so server hosts and credentials stay out of version control.
If deploy-prod.sh, docker-compose.prod.yml, or Caddyfile were committed before, remove them from the index (local copies are kept):
git rm --cached scripts/deploy-prod.sh docker-compose.prod.yml Caddyfile .env 2>/dev/null || trueCopy the example files locally:
cp scripts/deploy-prod.example.sh scripts/deploy-prod.sh
cp docker-compose.prod.example.yml docker-compose.prod.yml
cp Caddyfile.example Caddyfile
chmod +x scripts/deploy-prod.sh
# Edit the three files for your domain, server, and CORS origins# From your machine (requires SSH access to the server)
DEPLOY_REMOTE=user@your-server ./scripts/deploy-prod.shBefore deploying:
- Ensure
.envon the server hasCONGRESS_API_KEYand productionCORS_ORIGINS. - Run
make verify-billslocally or let the deploy script verify bill mappings. - Run
make testlocally.
- First request after cache expiry can take 30–60+ seconds while report cards or metrics are built; stale cache is served during background refresh when available.
- Backend startup verifies all 30 tracked bills against Congress.gov; mismatches prevent the server from starting.
- Senate members appear in the directory but House roll-call votes drive per-member records; Senate floor votes are not available per-member via Congress.gov today.
- Metrics page aggregates bill-level roll-call statistics only — no member leaderboards or grade distributions.
- Board page is live (
ENABLE_BOARD_PAGE = true). Donate page remains disabled untilENABLE_DONATE_PAGEis enabled and a payment processor is integrated.
Priorities below focus on launch readiness, production hardening, and sustainable growth. Timelines are estimates.
- Current MVP: Development Docker Compose setup (single VPS or local). Caddy handles TLS and reverse proxy.
- Target production: Dedicated server (e.g., Linode, DigitalOcean, Hetzner, or AWS Lightsail). Docker Compose for consistency, with secrets via Docker secrets or
.env+ systemd. - Benefits: Better uptime, isolated services, easier scaling, automated backups, monitoring, and compliance (e.g., for donations).
- Timeline: 1–3 days for a basic migration when following
deploy-prod.example.sh/docker-compose.prod.example.yml.
Focus on stability and launch readiness before deeper work.
-
Polish Board of Directors page (live — flag and nav enabled)
- Refine bios, images, and content.
- Continue QA and accessibility review.
-
Enable and implement donation page
- Enable feature flag (
ENABLE_DONATE_PAGE). - Integrate Stripe (primary) with PayPal fallback: forms with suggested/recurring amounts, fee coverage, impact messaging.
- Add receipt/thank-you flows and basic donor logging.
- Test thoroughly (sandbox first).
- Enable feature flag (
-
Migrate to production server environment (do this immediately after or alongside #1/#2)
- Prep: Copy and customize
docker-compose.prod.example.yml,Caddyfile.example, andscripts/deploy-prod.example.sh. Set production env vars (CORS,NEXT_PUBLIC_SITE_URL, API keys). Use secrets management — never commit keys. Runmake verify-billsandmake test. - Server setup: Provision a clean VPS (Ubuntu/Debian; 2–4 CPU, 4+ GB RAM). Install Docker and Docker Compose. Configure firewall (UFW: 80/443, SSH), fail2ban, automatic security updates. Set up Caddy for HTTPS and reverse proxy (
/api/*→ backend, static → frontend). Deploy viaDEPLOY_REMOTE=user@prod-server ./scripts/deploy-prod.sh. - Migration: Copy cached files/DB if any. Point DNS (
operationchildshield.org) to the new server. Preserve URLs; add 301 redirects if needed. Harden with rate limiting, WAF (e.g., CrowdSec), monitoring (UptimeRobot or Prometheus/Grafana), and automated offsite backups. Post-deploy: verify health endpoint, full site functionality, donation test transaction, cache warming. - Rollback: Keep MVP accessible temporarily; use blue-green or backup containers.
- Prep: Copy and customize
Milestone: Live production site with board and donate pages functional, secure, and performant. Monitor the first 24–48 hours.
Build on the stable production foundation.
- Donor and engagement: Stripe webhooks → Zapier/Mailchimp automation, donor portal.
- Advocacy tools: Bill alerts, analytics (GA4). (State heat map, learn/get-involved, and share-to-platform links shipped.)
- Tech: CI/CD improvements, performance tuning, accessibility audit.
- Security review: Full penetration test once production is live.
- Fundraising campaigns, advanced features (e.g., AI summaries), reporting, marketing.
- Scale hosting as traffic and donations grow.
- Member and vote data from the Congress.gov API
- Site provided for entertainment purposes — see /disclaimer
- Disputes or concerns: Contact@OperationChildShield.com
- Not affiliated with the U.S. Government
- Always verify official records at congress.gov
Provided for public transparency and educational purposes.