Files
simonandClaude Opus 5.5 b06f17e587 Add EP amendment and part votes, hidden from general lists by default
They come from the same responses as final votes. A sitting has over a
hundred, so they are flagged part_vote and only appear on request: the vote
lists have an option for them, feeds, counts and search chunks leave them out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 13:17:10 +01:00

101 lines
6.6 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.
# Roadmap
## Done
**Foundation (v1)** – claim/evidence model, source trust and topic filters, parliament (members,
mandates, functions, side jobs, speeches, faction votes, roll calls, immunity waivers, questions),
Wikidata (state/local offices, party membership, careers), Rechnungshof donations, news feeds and
sitemaps (headline-level, TDM-aware), entity linking, travel/meeting extraction, legal-matter detection
with review, corroboration, activity status, former politicians, calendar, timeline, REST API, MCP server,
Next.js frontend (de/en), Docker Compose for Unraid.
**Re-architecture (v2)** – see [architecture/02-comparison-and-decisions.md](architecture/02-comparison-and-decisions.md):
- [x] Adapter framework: `SourceSpec` in code, pure `parse()`, Fetcher with robots/TDM/throttle/conditional GET
- [x] Raw archive + `politrack reparse`; change detection (body hash + parser version)
- [x] Single writer (Loader), identity from resolved entities, `identifier` table, resolution hints
(roll-call surnames, office holders on a date), legal-form-insensitive organisation matching
- [x] Registry + entry points; periodic tasks generated from adapter metadata; queues scrape/social/bulk/enrich
- [x] Typed API (Pydantic) → OpenAPI → generated TypeScript; golden-fixture tests
- [x] Contributor documentation
**New data (v2)**:
- [x] Rechnungshof annual party reports (totals, public funding, loans, holdings, affiliated organisations)
- [x] Public procurement core data (contract awards, eForms)
- [x] RTR media transparency (government ads, media subsidies)
- [x] Council of Ministers minutes (agenda items per reporting minister)
- [x] U-committee hearings (who testified when)
- [x] WKStA press releases (documents for search; legal claims only after review)
- [x] European Parliament: Austrian MEPs, declarations of interests
- [x] European Commission meetings with interest representatives
- [x] Wikipedia edits from parliament/government IP ranges
- [x] Political ads: Google (bundle), Meta Ad Library (opt-in token)
- [x] Social: Bluesky, Mastodon, public Telegram channels, YouTube (key), X via official API (token);
party/institution channels; curated `social_accounts.yaml`
- [x] X deletion sync (`social.x_deletions`): posts gone from X keep a marked record without their text
- [x] EP roll-call votes of Austrian MEPs, including amendments and part votes (`europarl.votes`)
- [x] Committee memberships of the configured legislative periods (list 250, `parlament.persons`)
- [x] Draft legal pages (`/impressum`, `/datenschutz`), corrections contact, portrait proxy (`/api/img`)
- [x] Pages: organisations, money explorer, social feed, Wikipedia edits, person network ("follow the money"),
say-vs-vote on roll calls
**Design (v2)** – see [design/README.md](design/README.md):
- [x] Design concept and design system (neutral palette, light/dark, tokens with checked contrast, icons)
- [x] Redesigned pages: header with search and filter count, profiles with role timeline and key figures,
party and organisation dashboards, vote list with position chips, calendar agenda on phones
- [x] Claim permalink pages with citation (`/angaben/{id}`, `GET /api/v1/claims/{id}`)
## Next
**Data**
- [ ] Full speech texts and interjections from the protocols
- [ ] EU Council participant lists, ministries' press releases, Federal President's schedule
- [ ] Election results and candidate lists; AMA/TAM subsidy recipients (after checking bulk access and terms)
- [ ] Cabinet staff and appointments to state-owned companies (from answers to parliamentary questions)
- [ ] One adapter per Landtag (OGD where available); municipal councils and mayors
- [ ] Lobbying register – if the BMJ ever offers stable URLs or an export
**Quality**
- [ ] Golden fixtures for every adapter (the framework and first cases are in place)
- [ ] Better event dates (explicit dates in the text instead of publication dates)
- [ ] Entity resolution for donors/companies via Firmenbuch numbers from procurement notices
- [ ] Wayback Machine archiving of evidence URLs (`document.archive_url`)
**Product**
- [ ] Before going public: have `/impressum` and `/datenschutz` legally reviewed, set `POLITRACK_LEGAL_*` in `.env`,
and document the balancing test (see legal.md)
- [ ] Compare two people or parties; topic pages (`/themen/{slug}`); Open Graph share images; CSV export
- [ ] Review queue for editors in the web UI (today `politrack review`)
- [ ] Community link submissions and a corrections/right-of-reply form
- [ ] Alerts (e-mail/RSS) for followed politicians
- [ ] Optional accounts via reverse-proxy SSO using `app_user`
- [ ] Partnerships: MeineAbgeordneten, Parteispenden.at, APA (OTS full-text licence)
- [ ] Map view of trips and appearances
- [ ] Semantic search with embeddings (`POLITRACK_OLLAMA_URL`): parked by the owner on 2026-11-09, full-text search only for now
## Not yet verified (v2)
Tested so far: unit and golden tests, a live pipeline run of every adapter with `--max-requests`
against a test database, every API endpoint, the frontend type check against the generated types.
Not run yet, because PyPI/npm were unreachable on the development network (October 2026):
- [ ] Building the `backend` and `web` images (`docker compose build`), `npm run build`
- [ ] Procrastinate workers and the periodic schedule; the job-queue schema (`politrack migrate` installs it)
- [ ] The MCP server at runtime
- [ ] Mastodon (no account in the test sample), YouTube, X and Meta Ad Library (no credentials)
- [ ] GDELT (rate-limited during the test), EP declarations for MEPs whose API calls returned HTTP 500
## Known limitations
- Votes in the Nationalrat are faction-level except roll calls (an Austrian parliamentary practice).
- Split votes (factions voting differently on parts of a bill) keep the official text but no faction
positions, because the summary cannot be attributed reliably.
- Activity status: parliament and EP data are authoritative (`status_verified`). Open-ended roles from
Wikidata count as current for 15 years after their start, so some state/local politicians may show
wrong status until per-state adapters exist.
- Roll-call surnames that are ambiguous without a link in the protocol are skipped, not guessed.
- Travel/meeting extraction is rule-based; dates are publication dates of the source.
- News coverage is headline-level; mentions are linked by exact name or "office title + surname".
- Telegram: only channels with the public web preview; only the latest posts per run.
- Council of Ministers items are attributed to the office holder on that date; if the resolver cannot
find who held the office (missing role data), the item is skipped and counted.