CongressTracker is a full-stack congressional accountability app. It tracks Congress as a political-economic system: legislators, bills, committees, lobbying filings, elections, campaign finance, stock disclosures where available, portfolio-style disclosure summaries, influence networks, and global search. The backend is Rust on Axum backed by PostgreSQL, and the frontend is Next.js. The records that matter live in a dozen separate government systems, so the app pulls them into one normalized database and cross-references them. It never presents mock data as real data: missing source keys or empty ingests render as honest empty and setup states.
Active. Under steady development as of August 2026.
- Browse legislators with terms, committees, and identifiers from the unitedstates/congress-legislators dataset
- Follow bills with sponsors, actions, and official source URLs from the Congress.gov API
- Track member stock trades from House Clerk periodic transaction reports, with portfolio summaries and net-worth pages
- Flag potential conflicts of interest by matching traded securities against committee jurisdictions
- Read lobbying filings, clients, and issue codes from the Senate lobbying disclosure API
- Explore campaign finance: FEC receipts, committees, leadership PACs, and outside spending from FEC bulk files and OpenFEC
- Compare election candidates in dossier pages built from FEC data
- Map influence networks that link members, organizations, and financial records
- Search every entity from one global search endpoint
- Show per-source coverage and freshness so missing data is always visible
| Layer | Choice |
|---|---|
| Backend | Rust (stable toolchain), Axum, Tokio, SQLx |
| Database | PostgreSQL 16, schema managed by versioned migrations in intel_backend |
| Frontend | Next.js 14, React 18, TypeScript, Tailwind CSS, Radix UI |
| Charts | Recharts, D3 |
| Ingest clients | congress_api, openfec_api, lobbying_client, civiq_client, capitoltrades_api (legacy) |
| Analysis | ticker_resolver, trade_enricher, committee_detector, anomaly_scorer |
| CI | GitHub Actions |
- Linux or macOS. The deployment target is Linux with systemd.
- Rust stable toolchain
- Node.js 20 with pnpm 9
- PostgreSQL 16
- Free API keys: Congress.gov and OpenFEC (both issue through api.data.gov), plus a Senate LDA registration for lobbying data
From a clone of this repository:
cp .env.example .env
# Edit .env and fill in CONGRESS_GOV_API_KEY, OPENFEC_API_KEY, and SENATE_LDA_API_KEY
psql -c "CREATE USER congress_tracker WITH PASSWORD 'congress_tracker';"
psql -c "CREATE DATABASE congress_tracker OWNER congress_tracker;"
cd frontend && pnpm install && cd ..Backend variables load from .env at the repo root. .env.example documents every key with placeholders.
| Variable | Used by | Meaning | Default |
|---|---|---|---|
DATABASE_URL |
intel_backend, intel_worker |
Postgres connection string | required |
CONGRESS_GOV_API_KEY |
congress_api |
Bills, members, votes, amendments | required for ingest |
OPENFEC_API_KEY |
FEC ingest | Receipts, committees, outside spending | required for FEC ingest |
SENATE_LDA_API_KEY |
Lobbying ingest | Filings, clients, registrants | optional; without it the source reports auth_missing |
PORT |
intel_backend |
API listen port | 4020 |
INTEL_CACHE_TTL_SECONDS |
intel_backend |
API response cache TTL in seconds | 300 |
NEXT_PUBLIC_BACKEND_URL |
frontend | Backend base URL at build and dev time | http://localhost:4020 |
SENATE_EFD_ACCEPT_TERMS |
intel_worker |
Set to 1 only after accepting the Senate eFD terms; otherwise Senate discovery is skipped |
unset |
WORKER_STORAGE_DIR |
intel_worker |
Storage root for FEC archives and Senate eFD downloads | ./worker_storage under the backend working directory |
LOG_DIR |
backend logging | Log directory | ./log |
Worker diagnostics accept further knobs (FEC_CYCLES, FEC_ARCHIVE_DIR, FEC_MIN_FREE_BYTES, WORKER_RESOURCE_PROFILE, INGEST_CONTINUE_ON_ERROR, JOB_LEASE_RENEW_SECONDS, SEC_USER_AGENT); defaults live next to their use sites in backend/crates/intel_backend/src.
./run_all.shThe script checks that Postgres is reachable, frees ports 3000 and 4020, then starts the API on http://localhost:4020, the ingest worker, and the Next.js dev server on http://localhost:3000. The worker owns normal freshness for members, bills, votes, FEC, House disclosures, and derived relationships. Manual ingest subcommands remain diagnostics and targeted repair tools.
curl http://127.0.0.1:4020/api/health
curl http://127.0.0.1:4020/api/sources/status
curl 'http://127.0.0.1:4020/api/fec/receipts?cycle=2026&page=1&per_page=10'
curl 'http://127.0.0.1:4020/api/search?q=health&limit=5'Browser
|
v
Next.js frontend (:3000)
| REST
v
intel_backend (Axum API, :4020) <--> PostgreSQL 16
^
|
intel_worker (scheduled ingest and freshness)
|
+- Congress.gov API (bills, members, votes, amendments)
+- unitedstates/congress-legislators (members, committees)
+- FEC bulk files + OpenFEC API (receipts, committees, spending)
+- Senate LDA API (lobbying filings)
+- House Clerk disclosure indexes and PDFs
+- Internet Archive (PDF preservation fallback)
+- Senate eFD (terms-gated discovery, incomplete)
Backend crates under backend/crates/:
intel_backend: canonical HTTP API, migrations, read modelsintel_worker: scheduled ingestion and freshness jobscongress_api,openfec_api,lobbying_client: source API clientsciviq_client: client for CIV.IQ, a no-key alternative source for member, vote, and bill datacapitoltrades_api: legacy CapitolTrades adapter kept as a compatibility boundaryticker_resolver,trade_enricher: ticker to sector and industry resolution, then trade enrichmentcommittee_detector: committee jurisdiction conflict flagsanomaly_scorer: weighted anomaly scoring for trading activitybackend_server: older backend kept for reference; new page features targetintel_backend
The worker pulls official sources into normalized tables through versioned migrations. The API serves only canonical relational rows. Pages render missing records as unavailable; they never infer content from search or fixtures.
scripts/self-test runs the full local gate: plan lint, backend format, clippy, check, and deterministic tests, then the frontend pnpm verify (unit tests, typecheck, ESLint, oxlint, build).
CI (.github/workflows/ci.yml) runs the same commands against Postgres 16 and adds database-backed contract suites:
cd backend
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --workspace --exclude civiq_client --lib --bins
cargo test -p civiq_client test_query_builder
cd ../frontend
pnpm test:unit && pnpm typecheck && pnpm lint && pnpm lint:ox:ci && pnpm buildMigration and pipeline suites need a reachable DATABASE_URL:
scripts/verify-migrations
cd backend && cargo test -p intel_backend --test fec_bulk_pipeline_test
cd backend && cargo test -p intel_backend --test influence_financials_testIntegration tests skip themselves when DATABASE_URL is unset, so the deterministic suite runs anywhere.
The app runs on a single Linux host. cd backend && make build produces release binaries. The user units in deploy/systemd/ run the backend, frontend, and Caddy (congress-backend.service, congress-frontend.service, congress-caddy.service), and congress-backup.timer schedules database backups through scripts/db-backup. Units load secrets from the repo-root .env via EnvironmentFile; no secrets live in unit files or git. The Caddyfile in deploy/caddy/ handles TLS and reverse proxying.
- House PTR ingestion and annual asset and liability parsing are live; income, gifts, and positions parsing still need production coverage.
- Scanned-document OCR is implemented, but representative accuracy and failure recovery need live verification.
- Senate eFD discovery is staged and terms-gated; download, versioning, parsing, and member normalization are incomplete.
- FEC receipt browsing works, but the configured three-cycle window is not complete until every required cycle reaches a terminal source state.
- Member vote and sponsorship pages read only canonical relational records; missing rows show as unavailable.
- Voteview and Wikidata are registered sources but are not required for the core dataset.
- The visualizations route sits outside the required tab set and awaits a cleanup pass.
CREDITS.md documents every adapted open-source project, including poli-ticker, yfinance, FinanceDatabase, lobbyR, lobby, and CongressWatch. Data comes from the unitedstates/congress-legislators dataset, the Congress.gov API, FEC bulk files and OpenFEC, the Senate LDA API, House Clerk disclosure indexes, and the Internet Archive.
MIT.