Zentrale `app/parteien.py` als Single Source of Truth für die Partei-
Auflösung:
- `PARTEIEN`-Tabelle mit kanonischem Key, langem Display-Namen, allen
bekannten Aliasen, optionalem `bundesland_scope` und Government-
Marker. 14 Einträge (CDU, CSU, SPD, GRÜNE, FDP, LINKE, AfD, BSW, SSW,
BiW + die Freie-Wähler-Familie BVB-FW, FW-BAYERN, FW-SL und der
generische FREIE WÄHLER-Eintrag).
- `normalize_partei(raw, *, bundesland=None)` für Single-String-Lookups
mit Government-Vorrang und FW-Familien-Disambiguierung
- `extract_fraktionen(text, *, bundesland=None)` als Funnel für die
vier alten Adapter-Helper. Kommagetrennte Listen, MdL-mit-Klammer-
partei, HTML-Reste — alles fließt durch eine Stelle, mit BL-Scope-
Filter (SSW nur in SH, BVB-FW nur in BB, etc.).
- `display_name(canonical, *, long=False)` für UI/PDF — kurze Form
bleibt der kanonische Key, lange Form ist "BÜNDNIS 90/DIE GRÜNEN"
statt "GRÜNE" etc.
Adapter-Migration in `app/parlamente.py`:
- Vier nahezu identische `_normalize_fraktion()`-Methoden in
PortalaAdapter, ParLDokAdapter, StarFinderCGIAdapter, PARLISAdapter
durch einen einzeiligen Shim ersetzt, der `extract_fraktionen` mit
`self.bundesland` aufruft. ~120 Zeilen Duplikation entfernt.
- `@staticmethod` aufgehoben, weil wir jetzt `self.bundesland` brauchen
für die FW-Disambiguierung — alle Aufrufer waren bereits `self._...`,
also keine Call-Site-Änderung nötig.
`app/embeddings.py:496` Workaround-Hack entfernt:
- `partei.upper() if partei != "GRÜNE" else "GRÜNE"` durch zentralen
`normalize_partei()`-Aufruf ersetzt — der Hack war ein Kommentarzeichen
dafür, dass die Partei-Schreibweise irgendwo zwischen Adapter und
Embedding-Lookup driften konnte. Mit dem Mapper ist die Schreibweise
überall garantiert kanonisch.
Tests:
- Neue `tests/test_parteien.py` mit 52 Cases — Single-Lookup, FW-
Disambiguierung (BVB/Bayern/Saarland/RP), Volltext-Extraktion,
Government-Marker, Tabellen-Konsistenz
- `tests/test_parlamente.py` Test-Klasse umgeschrieben: statt der 6
statischen `PortalaAdapter._normalize_fraktion(...)`-Tests jetzt 4
Roundtrip-Tests über echte Adapter-Instanzen, inkl. expliziter
BB→BVB-FW vs. RP→FREIE WÄHLER-Verifikation
157 Unit-Tests grün (105 alt + 52 neu). Backwards-kompatibel — die
kanonischen Keys sind exakt die in der DB stehenden Strings, kein
Migrations-Schritt nötig.
Refs: #55, #59 (Phase B)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>