Files
simonandClaude Opus 5.5 583ccba31c Politrack: track Austrian politicians from public sources
Initial import of Politrack, a self-hosted service that tracks Austrian
politicians from federal to municipal level - roles, votes, money flows,
statements, meetings, social media and legal proceedings - with every claim
linked to its sources.

- backend: FastAPI + Postgres/pgvector; adapter framework (fetch -> parse ->
  load -> enrich) with robots.txt/TDM-aware fetching, a raw-response archive
  for reparsing, and a claim/evidence model with corroboration
- sources: Parliament, Wikidata, EU Parliament/Commission, Council of
  Ministers, Rechnungshof party reports and donations, procurement, RTR media
  transparency, political ad libraries, WKStA, news feeds, Wikipedia edits,
  Bluesky, Mastodon, public Telegram channels, YouTube and X (official API)
- web: Next.js frontend in German and English with typed API client
- mcp: MCP server for AI agents and RAG
- docs: architecture, data model, sources, legal notes, Unraid deployment and
  contributor guides; Docker Compose setup for Unraid

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 20:02:01 +01:00

46 lines
2.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Extending the API (and the MCP server)
Data flows out through three layers that are kept deliberately thin:
```
politrack/queries/<domain>.py SQL, returns dicts (shared by REST API and MCP server)
politrack/api/schemas.py Pydantic response models (the contract → OpenAPI → TypeScript)
politrack/api/main.py FastAPI endpoints (parameters, 404s, response_model)
politrack/mcp_server.py MCP tools for AI agents (same query functions)
```
## Adding an endpoint, step by step
1. **Query** – add a function to the matching module in `politrack/queries/` (people, organizations,
claims, votes, money, search, admin) and export it from `queries/__init__.py`.
* Only show visible claims: use `VISIBLE` (published, not merged) from `queries/common.py`.
* Respect the user's source filter: take a `SourceFilter` and use `evidence_json(source_sql)` to
aggregate evidence – claims whose evidence is entirely filtered out must disappear.
* Always parameterise (`%(name)s`), never format user input into SQL. `LIMIT/OFFSET` on lists.
2. **Response model** – add a class to `api/schemas.py` (inherit from `Model`). Field names = column names.
3. **Endpoint** – in `api/main.py`, with `response_model=...`. Reuse the dependencies `DB`, `Sources`,
`Limit`, `Offset`; comma-separated list parameters go through `csv_list()`.
4. **Types for the web app**:
```bash
cd backend && politrack openapi --ts ../web/src/lib/api-types.ts
```
Then add a typed function to `web/src/lib/api.ts`. Commit the regenerated `api-types.ts`.
5. **MCP tool** (if agents should use it) – a `@mcp.tool()` in `mcp_server.py` with a docstring that tells
the agent what the data means and how to cite it.
6. **Test** – extend the API smoke test (see [testing.md](testing.md)).
## Conventions
* URLs: `/api/v1/<plural noun>[/<slug>[/<sub-resource>]]`; slugs, never internal ids, for people,
parties and organisations (vote events use ids – they have no natural slug).
* Every claim-like object carries `evidence: [{url, title, source, published_at, quote, …}]` and
`source_count`.
* Legal matters always include `legal_stage`; the client decides about the presumption-of-innocence
notice (`needsInnocenceNotice` in the web app, the `instructions` in the MCP server).
* Admin endpoints require `Authorization: Bearer $POLITRACK_ADMIN_TOKEN` and are excluded from the schema.
## Read-only database access for agents and BI tools
The role `politrack_reader` (password `POLITRACK_READER_PASSWORD`) can `SELECT` everything. Useful views:
`claim_with_evidence`, `person_status`, `person_identifier`. See [../data-model.md](../data-model.md).