feat(programme): Wahlprogramm-Geltung beginnt am Wahltag (B1+B2)
Antwort auf B1 + B2 aus der Roadmap: - B1: Antrag VOR Regierungsbildung (z.B. NRW WP18-Antrag im Mai 2022, vor Vereidigung Wuest II am 29.06.2022) bekommt jetzt das passende Wahlprogramm zurueck — der Geltungsbeginn ist der Wahltag, nicht die Vereidigung. - B2: Opposition vs. Regierung wird einheitlich behandelt. Die fruehere Logik "Geltung ab Regierungsbildung" war fuer Regierungsfraktionen intuitiv (Koalitionsvertrag wird zu Politik), fuer Opposition aber willkuerlich. Programme werden zur Wahl beschlossen und sind Wahlversprechen ab dem Tag der Wahl. Implementation in programme._migrate_from_legacy: - gueltig_ab = aktuelle_legislatur(bl)["wahltermin"] (Fallback auf altes "regierungsbildung" fuer rueckwaerts-kompatible Eintraege) - ``wahl``-Feld auf Wahltag gesetzt - ``wp``-Feld aus aktuelle_legislatur ergaenzt Das ``regierungsbildung``-Feld in WAHLPROGRAMME bleibt erhalten und versorgt den Bewertungs-Kontext-Block weiterhin mit dem Anzeige-Wert "Regierung zur Antragszeit" (per legislaturen.regierung_zum_zeitpunkt laeuft das primaer ueber legislaturen.REGIERUNGEN). UI-Effekt: im Antrag-Detail liest sich z.B. ein BUND-Eintrag jetzt "gueltig seit 2025-02-23, 60 S." (BTW-Wahltag) statt "2025-05-06" (Vereidigung Merz I). Tests: 115 gruen (test_programme + test_legislaturen + test_wahlprogramme + test_embeddings). Tests test_bund_btw_2025_in_uebergangsphase und test_bund_btw_2025_vor_wahl neu, decken die geaenderte Geltungs-Logik explizit ab. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
176b7c5018
commit
b003cc1d6d
@ -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)),
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user