diff --git a/app/programme.py b/app/programme.py index 658b753..5411cf9 100644 --- a/app/programme.py +++ b/app/programme.py @@ -355,9 +355,20 @@ def _migrate_from_legacy() -> None: # Zirkuläre Imports vermeiden — lazy import beim Migrationszeitpunkt. from .wahlprogramme import WAHLPROGRAMME from .embeddings import PROGRAMME as _EMB_PROGRAMME + from .legislaturen import aktuelle_legislatur - # Schritt 1: Wahlprogramme aus WAHLPROGRAMME + # Schritt 1: Wahlprogramme aus WAHLPROGRAMME. + # Geltungsbeginn = Wahltag (siehe ADR 0013 Folge-Entscheidung B1+B2): + # Programme werden zur Wahl beschlossen; Opposition muss nicht auf eine + # Regierungsbildung warten, an der sie nicht beteiligt ist. Der + # ``regierungsbildung``-Wert aus WAHLPROGRAMME bleibt erhalten und wird + # vom Bewertungs-Kontext-Block separat angezeigt ("Regierung zur + # Antragszeit"), aber die Programm-Geltung selbst startet am Wahltag. for bundesland, parteien in WAHLPROGRAMME.items(): + # Wahltag aus legislaturen lookup (aktuelle WP des BL). + leg = aktuelle_legislatur(bundesland) + wahltag = leg.get("wahltermin") if leg else None + for partei, info in parteien.items(): # ID ableiten aus PDF-Stem pid = info["file"].rsplit(".", 1)[0] @@ -366,6 +377,17 @@ def _migrate_from_legacy() -> None: # Bundes-Grundsatzprogramm; Eintrag erfolgt in Schritt 2. continue + # Geltungsbeginn: bevorzugt expliziter ``wahltag``-Eintrag + # (für historische Programme aus Block 2 nötig), Fallback + # auf aktuellen Wahltag der Legislatur, letzter Fallback auf + # ``regierungsbildung`` (rückwärts-kompatibel). + gueltig_ab = ( + info.get("wahltag") + or wahltag + or info.get("regierungsbildung") + or "1900-01-01" + ) + prog: Programm = { "id": pid, "titel": info.get("titel", ""), @@ -374,9 +396,9 @@ def _migrate_from_legacy() -> None: "partei": partei, "bundesland": bundesland, "beschluss": None, - "wahl": None, - "wp": None, - "gueltig_ab": info.get("regierungsbildung") or "1900-01-01", + "wahl": gueltig_ab, + "wp": leg.get("wp") if leg else None, + "gueltig_ab": gueltig_ab, "gueltig_bis": info.get("regierungsende"), "pdf": info["file"], "seiten": int(info.get("seiten", 0)), diff --git a/tests/test_programme.py b/tests/test_programme.py index 52c1ff3..a1eb0d5 100644 --- a/tests/test_programme.py +++ b/tests/test_programme.py @@ -85,7 +85,8 @@ class TestAktuellesWahlprogramm: p = aktuelles_wahlprogramm("BUND", "CDU") assert p is not None assert p["id"] == "cdu-bund-2025" - assert p["gueltig_ab"] == "2025-05-06" + # Wahltag, nicht Regierungsbildung (B1+B2: Programme gelten ab Wahl) + assert p["gueltig_ab"] == "2025-02-23" def test_unknown_bl_returns_none(self): assert aktuelles_wahlprogramm("XX", "CDU") is None @@ -113,21 +114,28 @@ class TestWahlprogrammZumZeitpunkt: assert p is not None assert p["id"] == "cdu-nrw-2022" - def test_bund_btw_2025_nach_regierungsbildung(self): + def test_bund_btw_2025_nach_wahl(self): + # Nach Wahltag (2025-02-23) gilt das BTW-2025-Programm. p = wahlprogramm_zum_zeitpunkt("BUND", "SPD", "2025-09-01") assert p is not None assert p["id"] == "spd-bund-2025" - def test_bund_btw_2025_vor_regierungsbildung(self): - # Vor 2025-05-06 (Vereidigung Merz I) gibt es kein indiziertes - # Bund-Wahlprogramm, da BTW-2025-Programme erst ab Regierungsbildung - # gelten und vor BTW 2025 die alten Bund-Grundsatzprogramme als - # Quelle dienten (heute nur in embeddings.PROGRAMME). + def test_bund_btw_2025_in_uebergangsphase(self): + # Zwischen Wahl (2025-02-23) und Vereidigung Merz I (2025-05-06) + # gilt das BTW-2025-Programm bereits — B1+B2 (Programme gelten ab + # Wahltag). + p = wahlprogramm_zum_zeitpunkt("BUND", "SPD", "2025-04-01") + assert p is not None + assert p["id"] == "spd-bund-2025" + + def test_bund_btw_2025_vor_wahl(self): + # Vor BTW 2025 (vor 2025-02-23) kein Bund-Wahlprogramm indiziert. p = wahlprogramm_zum_zeitpunkt("BUND", "SPD", "2024-01-01") assert p is None def test_datum_vor_aktueller_wp(self): - # Antrag aus 2018 in NRW: aktuelle WP18-Programm gilt erst ab 2022. + # Antrag aus 2018 in NRW: aktuelle WP18-Programm gilt erst ab + # Wahltag 2022-05-15. p = wahlprogramm_zum_zeitpunkt("NRW", "CDU", "2018-09-01") # Heute keine WP17-Programme indiziert → erwarten None. assert p is None