docs: Uebergabe haelt B und C als erledigt fest und berichtigt den Testbefehl

Backend-Ergaenzungen B und C sind gebaut; Stufe 2 hat damit alles, was sie
braucht. Offen bleibt D, die zwei Kopier-Luecken im Budget.

Dazu berichtigt: Der Testbefehl zeigte auf einen Windows-Pfad, und die zwei
Tests, die als "vorbekannt rot" galten, laufen auf diesem Rechner durch - das
war ein Umgebungsproblem der alten Maschine. Erwartung ist jetzt: 438 Tests,
alle gruen. Wer einen roten sieht, hat ihn verursacht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-10-21 20:10:21 +02:00
co-authored by Claude Opus 5
parent 82edc29dfe
commit 3dff435156
+45 -26
View File
@@ -146,13 +146,15 @@ Die App muss sie nachbauen, das Backend hilft nicht:
nur die Summe; welche Abos dahinterstehen, ermittelt das Frontend selbst aus
`/subscriptions` nach `category_id`.
### Buchungsliste ohne Suche
### Buchungsliste
`GET /api/transactions` kennt nur `account_id`, `category_id`, `uncategorized`,
`type`, `date_from`, `date_to`, `limit` (Standard **5000**), `offset`. **Keine**
Volltextsuche, kein Tag-Filter, keine wählbare Sortierung. Die Weboberfläche
lädt alles und filtert im Browser. Auf dem Telefon ist das spürbar — daher
Backend-Ergänzung B unten.
`GET /api/transactions` kennt `account_id`, `category_id`, `uncategorized`,
`type`, `date_from`, `date_to`, `limit` (Standard **5000**), `offset` und seit
Ergänzung B auch `q`, `tag_id`, `subscription_id`. **Keine** wählbare
Sortierung — immer Datum absteigend, dann ID absteigend.
Die Weboberfläche lädt weiter alles und filtert im Browser; sie wurde nicht
umgestellt, weil sie so funktioniert. Die App soll die Filter benutzen.
### Was nicht in die App kommt
@@ -171,7 +173,7 @@ Backend-Ergänzung B unten.
## 4. Backend-Ergänzungen
Vier geplant. **A ist fertig**, B bis D stehen aus. Jede einzeln dem Nutzer
Vier geplant. **A, B und C sind fertig**, D steht aus. Jede einzeln dem Nutzer
vorlegen, bevor du sie schreibst.
### A — App-Token ✅ (Commit `8a7545b`)
@@ -192,21 +194,36 @@ Zwei Dinge, die die Tests festhalten (`backend/tests/test_app_marke.py`,
`POST /api/inbox/tokens`). Sonst stellte ein Dieb sich Ersatzschlüssel aus
und das Widerrufen liefe ins Leere.
### B — Suche und Tag-Filter auf `/transactions` (offen)
### B — Suche und Tag-Filter auf `/transactions` ✅
Drei Query-Parameter: `q` (Volltext über `payee`, `description`, `notes`),
`tag_id`, `subscription_id`. Muster für den Tag-Filter steht schon da: der
`uncategorized`-Zweig in `backend/app/routers/transactions.py` arbeitet mit
genau so einer Unterabfrage.
`tag_id`, `subscription_id`. Der Tag-Filter arbeitet mit einer Unterabfrage
wie der `uncategorized`-Zweig daneben, nicht mit einem Join — sonst käme eine
Buchung so oft zurück, wie sie Tags trägt.
Nötig für Stufe 2 — ohne das lädt das Telefon für jede Ansicht bis zu 5000
Zeilen.
Zwei Dinge, die die Tests festhalten (`backend/tests/test_buchungssuche.py`,
7 Stück):
- `%` und `_` im Suchtext sind **Zeichen, keine Platzhalter**. Sonst fände
die Eingabe „50%" alles.
- Ein fremder `tag_id` liefert **nichts**, nicht etwa alles. Der Filter
schlägt auf `TransactionTag.owner_id` an.
### C — `GET /budget/template` liefert `modus` und `zuschlag_cents` (offen)
Grenze: SQLite vergleicht bei LIKE nur ASCII ohne Rücksicht auf Gross- und
Kleinschreibung. „Müller" findet „müller" nicht. Reicht, bis jemand es meldet.
Beide fehlen heute in der Antwort (`backend/app/routers/budgets.py`), obwohl
das Modell sie führt und `PUT` sie zurückgibt. Ohne sie kann die App die
Vorlage weder richtig anzeigen noch bearbeiten. Nötig für Stufe 3.
Der lokale Name `q` im Router hiess vorher die Abfrage selbst; die heisst
jetzt `abfrage`, damit der Query-Parameter `q` heissen kann.
### C — `GET /budget/template` liefert `modus` und `zuschlag_cents` ✅
Beide fehlten in der Antwort (`backend/app/routers/budgets.py`), obwohl das
Modell sie führt und `PUT` sie zurückgibt. Jetzt stehen sie in jeder Zeile.
Test: `test_vorlage_nennt_betriebsart_und_zuschlag` in `test_budget.py`.
Das war der stillere der beiden Fehler: Ein Client, der die Vorlage so liest,
zeigt eine berechnete Zeile als feste **und schreibt sie beim nächsten
Speichern auch als feste zurück**. Die Weboberfläche traf es nicht, weil sie
die Betriebsart aus der Monatsansicht nimmt.
### D — Zwei Kopier-Lücken im Budget (offen)
@@ -276,7 +293,7 @@ nicht gegen einen laufenden Server. Siehe „Klartext-HTTP" unten.
**Stufe 2 — Lesen.** Dashboard (feste Ansicht: Kontostände, Budget-Fortschritt,
letzte Buchungen, Einnahmen/Ausgaben), Budget-Monatsansicht, Buchungsliste,
Abo-Liste. Dazu Backend-Ergänzungen **B** und **C**.
Abo-Liste. Die Backend-Ergänzungen **B** und **C**, die sie braucht, sind da.
**Stufe 3 — Schreiben.** Buchungen anlegen und ändern, Budget bearbeiten
(Monat und Vorlage, beide Betriebsarten `fest`/`berechnet`), Abos verwalten
@@ -359,14 +376,16 @@ Leicht zu übersehen, das Backend macht es an mehreren Stellen:
nicht zeigen kann. Das ganze Projekt ist so geschrieben; halte es durch.
- **Neue Swift-Datei?** Danach `cd ios && xcodegen generate`. Die Ordner stehen
einzeln in `project.yml`; ein neuer Ordner will dort eine Zeile.
- **Tests**: `cd backend && ./.venv/Scripts/python.exe -m pytest tests/ -q`
(Python 3.12 im venv; das System-Python kann nicht bauen). Dauert rund zwei
Minuten — im Hintergrund laufen lassen.
- **Vorbekannt rot**, nicht von dir verursacht:
`test_mail_import.py::test_von_hand_weitergeleitete_mail_wird_am_betreff_erkannt`
und `test_migrations.py::test_batch_migration_keeps_dependent_rows` (der
scheitert an einem Umgebungsproblem, `WinError 10106` in einem Subprozess).
Erwartung nach jedem Lauf: genau diese zwei, sonst nichts.
- **Tests**: `cd backend && .venv/bin/python -m pytest tests/ -q` (auf Windows
`./.venv/Scripts/python.exe`). Python 3.12 im venv; das System-Python kann
nicht bauen. Dauert hier rund 45 Sekunden.
- **Erwartung: alles grün**, 438 Tests. Die zwei Ausfälle, die hier früher als
„vorbekannt rot" standen, waren ein Windows-Problem der alten Maschine
(`WinError 10106` im Subprozess) und laufen auf diesem Rechner durch. Wer
einen roten Test sieht, hat ihn verursacht.
- **Fehlt dem venv ein Modul** (`ModuleNotFoundError`), einmal
`.venv/bin/python -m pip install -r requirements.txt` — es war hier nicht
auf dem Stand von `requirements.txt`.
- **Heredocs in Bash scheitern** an den deutschen Anführungszeichen („ ").
Für Dateien mit solchen Zeichen das Write-Werkzeug nehmen, nicht `cat <<EOF`.