fix(v2): Topbar harte Hoehe 32px + Kleine-Anfragen-Heuristik in Landtag-Suche

Topbar:
- height: 32px (statt auto), line-height: 1, alle children max 24px
- Topbar-Icons explizit auf 12x12 (statt 14)
- selects/buttons/a mit fester Hoehe 22px, padding 2px 6px

Landtag-Suche:
- search_landtag filtert jetzt Drucksachen aus, deren Titel typische
  Frage-Praefixe haben (Welche/Wie viele/Wann/Was/Hat/Ist/...)  oder mit '?'
  enden — bei NRW-OPAL liefert der Adapter alle als 'sonstige', daher
  Title-Heuristik. Server-side, damit alle Adapter profitieren.
- Neuer Helper drucksache_typen.likely_kleine_anfrage_titel()

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dotty Dotter 2026-04-25 22:23:22 +02:00
parent fa5a5b6026
commit 7f070b5e6c
3 changed files with 65 additions and 8 deletions

View File

@ -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

View File

@ -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,

View File

@ -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;