fix: "Keine Treffer" sagt jetzt, woran es liegt

Bei der Bank-Suche kam nur "Keine Treffer" – das hiess zweierlei: Die
Schnittstelle lieferte gar keine Liste, oder sie lieferte eine und der
Suchbegriff passte nicht. Beides sieht gleich aus, fuehrt aber an ganz
verschiedene Stellen. Genau diese Verwechslung hat heute schon zweimal Zeit
gekostet.

Die Antwort traegt jetzt die Gesamtzahl mit. Kam nichts, steht der
wahrscheinliche Grund dabei: Die Anwendung bei Enable Banking wird erst
aktiv, wenn man dort die eigenen Konten verknuepft hat.

Ausserdem wird breiter gesucht – auch in BIC und Gruppenname, weil Banken in
so einer Liste nicht immer so heissen wie im Alltag – und die Antwort wird
defensiv gelesen, falls die Liste ohne Schluessel kommt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-26 21:48:59 +02:00
co-authored by Claude Opus 5
parent 71e8419634
commit 9a0c607e8c
7 changed files with 84 additions and 20 deletions
+1 -1
View File
@@ -58,7 +58,7 @@ def delete_app(db: Session = Depends(get_db), user: User = Depends(get_current_u
@router.get("/banks")
def list_banks(country: str | None = None, search: str | None = None,
db: Session = Depends(get_db),
user: User = Depends(get_current_user)) -> list[dict]:
user: User = Depends(get_current_user)) -> dict:
"""Banken suchen – in einem Land oder über alle hinweg.
Ohne ``country`` wird überall gesucht. Das braucht es, weil die IBAN nicht
+7 -1
View File
@@ -116,7 +116,13 @@ class BankClient:
Revolut gibt deutsche IBANs aus, ist aber in Litauen ansässig.
"""
pfad = f"/aspsps?country={land.upper()}" if land else "/aspsps"
return self._anfrage("GET", pfad).get("aspsps", [])
daten = self._anfrage("GET", pfad)
# Defensiv: manche Fassungen liefern die Liste direkt statt unter
# einem Schlüssel. Eine leere Antwort stillschweigend als „keine
# Treffer" auszugeben hat schon genug Zeit gekostet.
if isinstance(daten, list):
return daten
return daten.get("aspsps") or daten.get("data") or []
def starte_autorisierung(self, aspsp_name: str, land: str, redirect_url: str,
state: str, tage: int, psu_type: str = "personal") -> dict:
+12 -4
View File
@@ -66,7 +66,7 @@ MAX_TREFFER = 200
def banken(db: Session, user: User, land: str | None = None,
suche: str | None = None) -> list[dict]:
suche: str | None = None) -> dict:
"""Banken suchen – in einem Land oder über alle hinweg.
Die Suche über alle Länder ist kein Luxus: Das Sitzland einer Bank steht
@@ -80,12 +80,20 @@ def banken(db: Session, user: User, land: str | None = None,
name = b.get("name")
if not name:
continue
if begriff and begriff not in name.lower():
# Auch im BIC und im Gruppennamen suchen: Banken heissen in der Liste
# nicht immer so wie im Alltag.
heu = " ".join(str(x) for x in (name, b.get("bic"), b.get("group")) if x).lower()
if begriff and begriff not in heu:
continue
treffer.append({"name": name, "country": b.get("country"),
"logo": b.get("logo"), "psu_types": b.get("psu_types", [])})
"logo": b.get("logo"), "psu_types": b.get("psu_types", []),
"beta": bool(b.get("beta"))})
treffer.sort(key=lambda b: (b["name"].lower(), b.get("country") or ""))
return treffer[:MAX_TREFFER]
# „gesamt" mitliefern: Sonst sieht „keine Treffer" gleich aus, egal ob die
# Liste leer kam oder der Suchbegriff nicht passte – und man sucht den
# Fehler an der falschen Stelle.
return {"gesamt": len(roh), "treffer": treffer[:MAX_TREFFER],
"gekuerzt": len(treffer) > MAX_TREFFER}
def starte_verbindung(db: Session, user: User, aspsp_name: str, land: str,