97 lines
3.8 KiB
Markdown
97 lines
3.8 KiB
Markdown
# Voting App - Agent Instructions
|
|
|
|
See `~/.config/opencode/AGENTS.md` for global development principles (container-first, package managers, Dockerfile standards).
|
|
|
|
## Repo Overview
|
|
|
|
Flask backend + React TypeScript frontend. Data flow: `User → React Frontend → Flask Backend → Congress.gov v3 API`, with SQLite caching and local GPT-OSS for bill summaries. Backend source is flat under `src/` (no submodules). Vote data: House votes from Clerk XML (fast), Senate votes from senate.gov XML (slow, sequential scan).
|
|
|
|
## Lockfiles Are Gitignored — Regenerate Before Building
|
|
|
|
Both `uv.lock` and `frontend/pnpm-lock.yaml` are in `.gitignore`. Dockerfiles copy them during build, so they must exist locally first:
|
|
|
|
```bash
|
|
uv sync # generates uv.lock
|
|
cd frontend && pnpm install # generates pnpm-lock.yaml
|
|
```
|
|
|
|
Skip regeneration only if you haven't changed dependencies.
|
|
|
|
## Port Mapping
|
|
|
|
Host ports differ from container ports:
|
|
|
|
| Service | Host Port | Container Port |
|
|
|----------|-----------|----------------|
|
|
| Backend | 8001 | 8000 |
|
|
| Frontend | 5174 | 5173 |
|
|
|
|
## VITE_API_URL Is Build-Time Only
|
|
|
|
`VITE_API_URL` is passed as a Docker build arg (`http://backend:8000`) and baked into the frontend bundle at build time. It is NOT a runtime environment variable — changing `.env` after building has no effect. Rebuild the frontend container to pick up URL changes.
|
|
|
|
## Frontend: Preview Mode, No HMR
|
|
|
|
`docker-compose.yml` runs `npx vite preview`, serving the production build from `dist/`. There is no hot module reload. For active frontend development, rebuild after every change:
|
|
|
|
```bash
|
|
docker compose down frontend && docker compose up -d frontend --build
|
|
```
|
|
|
|
The `../frontend:/app/frontend` volume mount in docker-compose has no effect in preview mode (serves from baked-in `dist/`).
|
|
|
|
## Backend Entry Point
|
|
|
|
Runs as `python -m src.main --port 8000` inside the container. The `--port 8000` flag is hardcoded in docker-compose (mapped to 8001 on host).
|
|
|
|
## SQLite Cache
|
|
|
|
Backend caches Congress.gov API responses and GPT-OSS summaries in SQLite at `data/voting_app.db`. The `data/` directory is mounted as a Docker volume to `/app/data`. Not committed to git. Delete stale DB after schema changes (e.g. adding `start_date` column).
|
|
|
|
## Required External Services
|
|
|
|
- **Congress.gov API key**: Set `CONGRESS_API_KEY` in `.env`
|
|
- **Local GPT-OSS server**: Set `GPT_OSS_BASE_URL` in `.env` (e.g., LM Studio, Ollama, vLLM)
|
|
|
|
## Quality Gate Commands
|
|
|
|
Run before building any container:
|
|
|
|
```bash
|
|
# Backend
|
|
ruff format .
|
|
ruff check --fix .
|
|
|
|
# Frontend
|
|
cd frontend && pnpm lint --fix
|
|
cd frontend && tsc
|
|
```
|
|
|
|
Ruff: line-length 120, rules `E W F I N UP B SIM`.
|
|
Frontend ESLint: `@typescript-eslint/no-unused-vars` and `no-explicit-any` are `warn`.
|
|
Frontend `pnpm build` runs `tsc && vite build` — TypeScript check gates the build.
|
|
|
|
## Testing
|
|
|
|
106 tests total: 103 unit/E2E tests (mocked services) + 3 integration tests (real API). All pass.
|
|
|
|
```bash
|
|
# Unit + E2E tests (fast, mocked)
|
|
uv run pytest tests/unit/ tests/e2e/
|
|
|
|
# Integration tests (slow, real API — requires CONGRESS_API_KEY)
|
|
uv run pytest tests/integration/
|
|
|
|
# In container
|
|
docker compose exec backend python -m pytest tests/unit/ tests/e2e/
|
|
```
|
|
|
|
The `integration` pytest mark is registered in `pyproject.toml`. Integration tests require a valid `CONGRESS_API_KEY` in `.env` and skip if unset. Senate vote fetching uses XML scanning from senate.gov and can take 2-4 minutes per legislator.
|
|
|
|
## Backend Dockerfile Note
|
|
|
|
The backend Dockerfile installs `uv` via `pip` (the `python:3.12-slim` image doesn't include it). Build arg `VITE_API_URL` is set via docker-compose, not `.env`.
|
|
|
|
## Build Context
|
|
|
|
`.dockerignore` excludes `tests`, `tools`, `additionaldocs`, `data`, and `.env` from Docker build context. A `.dockerignore.backend` file exists in `docker/` but is not used by Docker (context is project root). |