2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:16:18 -05:00
2026-05-15 15:15:07 -05:00

Voting App

U.S. Congress legislator voting history viewer with AI-generated bill summaries.

Features

  • Search legislators by name with autocomplete suggestions (full name, state, party)
  • View voting records with endless scroll through a legislator's entire career
  • AI-generated summaries using a local GPT-OSS model for impartial bill analysis
  • Local caching with SQLite to avoid repeated API calls and survive outages
  • Rate-limit aware with exponential back-off (stays well under 1000 req/hr limit)
  • Privacy-safe error handling that never exposes API keys

Architecture

User → React Frontend → Flask Backend → LegiScan API
                               ↕
                          SQLite Cache
                               ↕
                          Local GPT-OSS

Setup

Prerequisites

  • Docker and Docker Compose
  • LegiScan API key (sign up at https://legiscan.com)
  • Local GPT-OSS server running (e.g., LM Studio, Ollama, vLLM)

Environment Configuration

Copy .env.example to .env and fill in your values:

cp .env.example .env

Required variables:

Variable Description Default
CONGRESS_API_KEY LegiScan API key (required)
CONGRESS_API_BASE_URL LegiScan API base URL https://api.legiscan.com
GPT_OSS_BASE_URL Local GPT-OSS endpoint http://home.ms:4000/v1
GPT_OSS_API_KEY GPT-OSS API key (if required) (optional)
BACKEND_PORT Host port for backend 8001
VITE_FRONTEND_PORT Host port for frontend 5174
VITE_API_URL Backend URL for frontend http://localhost:8001

Ports 8001 and 5174 are used to avoid conflicts with other services. Change them in .env as needed.

Running

# Start all services (backend + frontend)
cd docker
docker compose up -d --build

# View logs
docker compose logs -f

# Rebuild a single service
docker compose down <service>
docker compose up -d <service> --build

# Stop all services
docker compose down

Once running:

  • Frontend: http://localhost:5174
  • Backend API: http://localhost:8001

Development (without Docker)

Backend:

uv sync
uv run python -m src.main --port 8001

Frontend:

cd frontend
pnpm install
VITE_API_URL=http://localhost:8001 pnpm dev

Project Structure

voting-app/
├── .env                    # Environment variables (not committed)
├── .env.example           # Template for required variables
├── pyproject.toml         # Python dependencies (managed by UV)
├── uv.lock                # Locked Python dependencies
├── src/                   # Backend Python code
│   ├── models.py          # Data models (Legislator, Bill, Vote, Summary)
│   ├── api_client.py      # LegiScan API client (pagination, back-off)
│   ├── gpt_oss_client.py  # GPT-OSS client for impartial bill summaries
│   ├── cache.py           # SQLite cache layer
│   ├── app.py             # Flask REST API
│   └── main.py            # CLI entry point
├── frontend/              # React TypeScript frontend
│   ├── package.json       # Frontend dependencies (managed by pnpm)
│   ├── pnpm-lock.yaml     # Locked frontend dependencies
│   ├── vite.config.ts     # Vite build configuration
│   ├── src/
│   │   ├── App.tsx        # Main app with routing
│   │   ├── components/    # UI components (Button, Input, Spinner, VoteCard, etc.)
│   │   ├── pages/         # Page components (Home, LegislatorDetail)
│   │   ├── store/         # Zustand state management
│   │   ├── services/      # API client for backend
│   │   ├── hooks/         # Custom React hooks
│   │   └── types/         # TypeScript definitions
├── tests/                 # Test suites
│   ├── unit/              # Python unit tests
│   ├── integration/       # Integration tests
│   └── e2e/               # End-to-end tests
├── docker/                # Docker configuration
│   ├── docker-compose.yml # Service orchestration
│   ├── Dockerfile.backend # Python container
│   └── Dockerfile.frontend # Node.js container
└── data/                  # Runtime data (SQLite DB, not committed)

API Endpoints

Method Endpoint Description
GET /health Health check
GET /api/search?q=<query> Search legislators
GET /api/legislators/<id> Legislator details
GET /api/legislators/<id>/votes?limit=N&offset=M Voting record with summaries
GET /api/bills/<id>/summary AI-generated bill summary
GET /api/bills/<id>/text Full bill text

Testing

# Run Python tests
uv run pytest tests/

# Run frontend linting
cd frontend && pnpm lint

License

MIT

Description
U.S. Congress voting history viewer with AI-generated bill summaries — legislator search, endless-scroll voting records, local GPT-OSS summaries.
Readme 86 KiB
Languages
Python 83.5%
TypeScript 15.3%
CSS 0.7%
JavaScript 0.3%
HTML 0.2%