diff --git a/app/drucksache_typen.py b/app/drucksache_typen.py index e6941f4..dc9f3fe 100644 --- a/app/drucksache_typen.py +++ b/app/drucksache_typen.py @@ -86,3 +86,45 @@ def ist_abstimmbar(typ_normiert: str) -> bool: def ist_abstimmbar_original(original: str) -> bool: """Convenience: prüft direkt am Original-Typ-String.""" return ist_abstimmbar(normalize_typ(original)) + + +# Frage-Präfixe die typisch für Kleine Anfragen sind. Wird genutzt wenn der +# Adapter (z.B. NRW) den Typ nur als "Drucksache" liefert — wir versuchen +# anhand des Titels eine bessere Klassifikation, damit Search-Ergebnisse +# nicht voll mit nicht-abstimmbaren Anfragen sind. +_FRAGE_PRAEFIXE = ( + "welche ", "wie viele ", "wieviel", "wie viel ", "wie hoch ", "wie ", + "wann ", "warum ", "weshalb ", "wo ", "wer ", "wie steht ", "wie weit ", + "ist es ", "ist der ", "ist die ", "ist das ", "sind ", + "trifft es ", "kann ", "wird ", "wieso ", "was ", + "hat ", "hat der ", "hat die ", "hat das ", + "haben ", "war ", "waren ", +) + + +def likely_kleine_anfrage_titel(title: str) -> bool: + """Heuristik: erkennt Kleine Anfragen am Titel-Format. + + Wenn der Titel mit einem typischen Frage-Präfix beginnt oder mit "?" endet, + behandeln wir die Drucksache als Kleine Anfrage. NRW-OPAL klassifiziert + alle Drucksachen als "Drucksache" → ohne diese Heuristik landen Anfragen + in den Search-Ergebnissen, was den User verwirrt (#149 Folge). + + Args: + title: Drucksachen-Titel inkl. evtl. Nummer-Präfix wie "1Welche...". + + Returns: + True wenn der Titel wie eine Kleine Anfrage aussieht. + """ + if not title: + return False + t = title.strip() + # Manche Adapter prefixen mit Nummerierung wie "1Welche..." — strippen + while t and (t[0].isdigit() or t[0] in " .-"): + t = t[1:] + t_low = t.lower() + if t_low.startswith(_FRAGE_PRAEFIXE): + return True + if t.rstrip().endswith("?"): + return True + return False diff --git a/app/main.py b/app/main.py index d7f5b1d..cda8b91 100644 --- a/app/main.py +++ b/app/main.py @@ -1333,8 +1333,13 @@ async def search_landtag( try: external = adapter._filter_abstimmbar(await adapter.search(q, limit)) + # Zusätzliche Title-Heuristik: bei Adaptern die Typ='Drucksache' liefern + # (NRW), Kleine-Anfrage-Frage-Pattern erkennen und ausfiltern. + from .drucksache_typen import likely_kleine_anfrage_titel, KLEINE_ANFRAGE results = [] for doc in external: + if doc.typ_normiert == "sonstige" and likely_kleine_anfrage_titel(doc.title): + continue # höchstwahrscheinlich Kleine Anfrage results.append({ "drucksache": doc.drucksache, "title": doc.title, diff --git a/app/static/v2/v2.css b/app/static/v2/v2.css index 318cb6b..be9feb9 100644 --- a/app/static/v2/v2.css +++ b/app/static/v2/v2.css @@ -66,22 +66,32 @@ body.v2 :focus-visible { grid-area: topbar; background: var(--paper); border-bottom: 1px solid var(--hairline); - padding: 2px 24px; + padding: 0 24px; + height: 32px; /* harte Höhe statt min-height */ display: flex; align-items: center; gap: var(--space-4); font-family: var(--font-mono); font-size: 11px; - line-height: 1.2; + line-height: 1; color: var(--ecg-dark); } -.v2-topbar select, -.v2-topbar button { - padding-top: 1px; - padding-bottom: 1px; - margin: 0; +.v2-topbar > * { + height: auto; + max-height: 24px; /* nichts darin höher als 24 px */ } -.v2-topbar a { padding: 0; } +.v2-topbar select, +.v2-topbar button, +.v2-topbar a { + padding: 2px 6px; + margin: 0; + line-height: 1; + height: 22px; + display: inline-flex; + align-items: center; +} +.v2-topbar .v2-icon { width: 12px !important; height: 12px !important; } +.v2-topbar .v2-icon svg { width: 12px; height: 12px; } .v2-topbar-spacer { flex: 1;