Architektur: Multi-Bundesland-Abstraktion #5

Closed
opened 2026-03-31 00:50:20 +02:00 by tobias · 3 comments
Owner

Beschreibung

Um weitere Bundesländer effizient anzubinden, braucht es eine saubere Abstraktionsschicht.

Benötigte Komponenten pro Bundesland

  1. Datenquelle/Adapter — Anträge laden (API, Scraper, Open Data)
  2. Wahlprogramm — Grünes Wahlprogramm als Referenzdokument
  3. Prompt-Kontext — Bundesland-spezifische Anpassungen (Themen, Akteure)
  4. Frontend — Bundesland-Wähler aktivieren

Parlamentsdokumentationssysteme in Deutschland

System Bundesländer Zugang
StarWeb BB, HB, HE, NI, SH, TH, ST Form-basierte Suche, Scraping
OPAL NRW Proprietär, kein API
PARDOK/Portala BE, BW Elasticsearch-ähnlich, POST-Queries
ParLDok MV, SN Tcl-basiert, kein API
Eigensysteme BY, HH, SL Unterschiedlich

Vorhandene Scraper (Dokukratie, OKF)

https://github.com/okfde/dokukratie

Kürzel Land Backend
bb Brandenburg StarWeb
be Berlin Portala
bw Baden-Württemberg Portala
by Bayern Eigensystem
hb Bremen StarWeb
he Hessen StarWeb
hh Hamburg ParLDok
mv Mecklenburg-Vorp. ParLDok
ni Niedersachsen StarWeb
nw Nordrhein-Westfalen OPAL
rp Rheinland-Pfalz StarWeb
sh Schleswig-Holstein StarWeb
sl Saarland StarWeb
sn Sachsen Eigensystem (EDAS)
st Sachsen-Anhalt StarWeb
th Thüringen StarWeb

Alternatives Vorgehen: Parlamentsspiegel

https://www.parlamentsspiegel.de/suche

  • Alle 16 Landtage zentral durchsuchbar
  • Kein bekanntes API, aber Web-Scraping möglich
  • Könnte als einheitlicher Adapter dienen

Berlin Sonderfall: Open Data

https://www.parlament-berlin.de/dokumente/open-data

  • Metadaten als XML seit 11. WP (1989)
  • Maschinenlesbar — kein Scraping nötig!

Architektur-Vorschlag

class LandtagAdapter(ABC):
    @abstractmethod
    def fetch_documents(self, since: date) -> List[Document]: ...
    @abstractmethod
    def get_wahlprogramm(self) -> str: ...
    @abstractmethod  
    def get_bundesland_context(self) -> str: ...

class NRWAdapter(LandtagAdapter):  # Besteht bereits (Live-Suche)
class BerlinAdapter(LandtagAdapter):  # Open Data XML
class DokukratieAdapter(LandtagAdapter):  # Für StarWeb/ParLDok-Länder
class ParlamentsspiegelAdapter(LandtagAdapter):  # Fallback für alle

Priorisierung

  1. Sachsen-Anhalt (06.09.2026) → #2
  2. Berlin (20.09.2026) → #3 (Open Data = einfachster Zugang!)
  3. Mecklenburg-Vorpommern (20.09.2026) → #4
## Beschreibung Um weitere Bundesländer effizient anzubinden, braucht es eine saubere Abstraktionsschicht. ## Benötigte Komponenten pro Bundesland 1. **Datenquelle/Adapter** — Anträge laden (API, Scraper, Open Data) 2. **Wahlprogramm** — Grünes Wahlprogramm als Referenzdokument 3. **Prompt-Kontext** — Bundesland-spezifische Anpassungen (Themen, Akteure) 4. **Frontend** — Bundesland-Wähler aktivieren ## Parlamentsdokumentationssysteme in Deutschland | System | Bundesländer | Zugang | |--------|-------------|--------| | **StarWeb** | BB, HB, HE, NI, SH, TH, ST | Form-basierte Suche, Scraping | | **OPAL** | NRW | Proprietär, kein API | | **PARDOK/Portala** | BE, BW | Elasticsearch-ähnlich, POST-Queries | | **ParLDok** | MV, SN | Tcl-basiert, kein API | | **Eigensysteme** | BY, HH, SL | Unterschiedlich | ## Vorhandene Scraper (Dokukratie, OKF) https://github.com/okfde/dokukratie | Kürzel | Land | Backend | |--------|------|--------| | `bb` | Brandenburg | StarWeb | | `be` | Berlin | Portala | | `bw` | Baden-Württemberg | Portala | | `by` | Bayern | Eigensystem | | `hb` | Bremen | StarWeb | | `he` | Hessen | StarWeb | | `hh` | Hamburg | ParLDok | | `mv` | Mecklenburg-Vorp. | ParLDok | | `ni` | Niedersachsen | StarWeb | | `nw` | Nordrhein-Westfalen | OPAL | | `rp` | Rheinland-Pfalz | StarWeb | | `sh` | Schleswig-Holstein | StarWeb | | `sl` | Saarland | StarWeb | | `sn` | Sachsen | Eigensystem (EDAS) | | `st` | Sachsen-Anhalt | StarWeb | | `th` | Thüringen | StarWeb | ## Alternatives Vorgehen: Parlamentsspiegel https://www.parlamentsspiegel.de/suche - Alle 16 Landtage zentral durchsuchbar - Kein bekanntes API, aber Web-Scraping möglich - Könnte als einheitlicher Adapter dienen ## Berlin Sonderfall: Open Data https://www.parlament-berlin.de/dokumente/open-data - Metadaten als XML seit 11. WP (1989) - Maschinenlesbar — kein Scraping nötig! ## Architektur-Vorschlag ```python class LandtagAdapter(ABC): @abstractmethod def fetch_documents(self, since: date) -> List[Document]: ... @abstractmethod def get_wahlprogramm(self) -> str: ... @abstractmethod def get_bundesland_context(self) -> str: ... class NRWAdapter(LandtagAdapter): # Besteht bereits (Live-Suche) class BerlinAdapter(LandtagAdapter): # Open Data XML class DokukratieAdapter(LandtagAdapter): # Für StarWeb/ParLDok-Länder class ParlamentsspiegelAdapter(LandtagAdapter): # Fallback für alle ``` ## Priorisierung 1. **Sachsen-Anhalt** (06.09.2026) → #2 2. **Berlin** (20.09.2026) → #3 (Open Data = einfachster Zugang!) 3. **Mecklenburg-Vorpommern** (20.09.2026) → #4
Author
Owner

Scope-Erweiterung: Langfristig soll der Prüfer auch Bundestagsanträge können.

Bedeutet für die Architektur:

  • Adapter-Interface muss auch DIP-API (Bundestag) abdecken: https://dip.bundestag.de/
  • DIP hat eine echte REST-API mit API-Key! Einfachster Zugang überhaupt.
  • Wahlprogramm-Referenz = Bundestagswahlprogramm statt Landeswahlprogramm
  • GWÖ-Matrix bleibt gleich, aber Prompt-Kontext unterscheidet Bundes- vs. Landespolitik

→ Im Adapter-Interface berücksichtigen: level = land | bund

**Scope-Erweiterung:** Langfristig soll der Prüfer auch Bundestagsanträge können. Bedeutet für die Architektur: - Adapter-Interface muss auch DIP-API (Bundestag) abdecken: https://dip.bundestag.de/ - DIP hat eine echte REST-API mit API-Key! Einfachster Zugang überhaupt. - Wahlprogramm-Referenz = Bundestagswahlprogramm statt Landeswahlprogramm - GWÖ-Matrix bleibt gleich, aber Prompt-Kontext unterscheidet Bundes- vs. Landespolitik → Im Adapter-Interface berücksichtigen: `level` = `land` | `bund`
tobias added a new dependency 2026-04-07 13:56:49 +02:00
tobias added a new dependency 2026-04-07 13:56:49 +02:00
tobias added a new dependency 2026-04-07 13:56:49 +02:00
tobias added a new dependency 2026-04-07 14:14:56 +02:00
Author
Owner

Scope-Aufteilung zur besseren Reversibilität

Dieses Issue wird in zwei aufeinanderfolgende Issues geteilt:

  • #7 — Zentrale Bundesländer-Konfiguration (app/bundeslaender.py). Eigenständig deploybar, keine funktionale Änderung. Voraussetzung für dieses Issue.
  • #5 (dieses Issue) — Verbleibender Refactor von wahlprogramme.py, embeddings.py, analyzer.py auf Bundesland-Bewusstsein. Atomar, weil die drei Module sich gegenseitig referenzieren.

Reihenfolge: #7#5 → #2/#3/#4. Jeder Schritt mit eigenem Commit/Deploy/Rollback-Punkt.

## Scope-Aufteilung zur besseren Reversibilität Dieses Issue wird in zwei aufeinanderfolgende Issues geteilt: - **#7** — Zentrale Bundesländer-Konfiguration (`app/bundeslaender.py`). Eigenständig deploybar, keine funktionale Änderung. Voraussetzung für dieses Issue. - **#5** (dieses Issue) — Verbleibender Refactor von `wahlprogramme.py`, `embeddings.py`, `analyzer.py` auf Bundesland-Bewusstsein. Atomar, weil die drei Module sich gegenseitig referenzieren. Reihenfolge: #7 → #5 → #2/#3/#4. Jeder Schritt mit eigenem Commit/Deploy/Rollback-Punkt.
Author
Owner

Erledigt

Commit ee0218b deployed auf https://gwoe.toppyr.de.

Refactor-Umfang (3 Module, atomar):

  • wahlprogramme.pyWAHLPROGRAMME[bundesland][partei], find_relevant_quotes(text, fraktionen, bundesland)
  • embeddings.py → Schema-Migration bundesland-Spalte + Backfill, Filter in find_relevant_chunks (NULL = global), get_relevant_quotes_for_antrag(text, fraktionen, bundesland)
  • analyzer.pyget_bundesland_context aus BUNDESLAENDER, silent NRW-Fallback abgeschafft, Fraktionen-Heuristik nutzt jetzt landtagsfraktionen

Live-Verifikation im Produktiv-Container:

  • DB-Migration sauber: chunks hat jetzt bundesland-Spalte; Backfill 775 NRW-Chunks + 335 NULL (Grundsatzprogramme) — wie geplant
  • get_bundesland_context("NRW") liefert 17 KB Kontext, beginnt mit Landtag Nordrhein-Westfalen (WP 18, seit 2022-06-01) aus zentraler Konfig
  • get_bundesland_context("XYZ") → ValueError
  • get_bundesland_context("LSA") → ValueError (LSA noch inaktiv)
  • Keyword-Suche und semantische Suche liefern für SPD-Sample beide jeweils CDU + GRÜNE + SPD (Antragsteller + Regierungsfraktionen NRW)
  • API: /api/assessments 25 Einträge, /api/assessment?drucksache=18/18100 Detail unverändert

Damit entblockt: #2 (LSA), #3 (Berlin), #4 (MV).

## Erledigt Commit `ee0218b` deployed auf https://gwoe.toppyr.de. **Refactor-Umfang (3 Module, atomar):** - `wahlprogramme.py` → `WAHLPROGRAMME[bundesland][partei]`, `find_relevant_quotes(text, fraktionen, bundesland)` - `embeddings.py` → Schema-Migration `bundesland`-Spalte + Backfill, Filter in `find_relevant_chunks` (NULL = global), `get_relevant_quotes_for_antrag(text, fraktionen, bundesland)` - `analyzer.py` → `get_bundesland_context` aus `BUNDESLAENDER`, **silent NRW-Fallback abgeschafft**, Fraktionen-Heuristik nutzt jetzt `landtagsfraktionen` **Live-Verifikation im Produktiv-Container:** - DB-Migration sauber: `chunks` hat jetzt `bundesland`-Spalte; Backfill 775 NRW-Chunks + 335 NULL (Grundsatzprogramme) — wie geplant - `get_bundesland_context("NRW")` liefert 17 KB Kontext, beginnt mit `Landtag Nordrhein-Westfalen (WP 18, seit 2022-06-01)` aus zentraler Konfig - `get_bundesland_context("XYZ")` → ValueError - `get_bundesland_context("LSA")` → ValueError (LSA noch inaktiv) - Keyword-Suche und semantische Suche liefern für SPD-Sample beide jeweils CDU + GRÜNE + SPD (Antragsteller + Regierungsfraktionen NRW) - API: `/api/assessments` 25 Einträge, `/api/assessment?drucksache=18/18100` Detail unverändert **Damit entblockt:** #2 (LSA), #3 (Berlin), #4 (MV).
Sign in to join this conversation.
No description provided.