docs: Uebergabe, README und Fahrplan halten Stufe 4 fest

Neu drin: wo der einzige 409-Fall sitzt und wie er behandelt wird (eine
Frage, kein Fehler), woran man einen Uebertrag im Eingang erkennt, warum die
Dublettenliste die Kennung der Bank zeigt, und der Backend-Fehler, den die
App ans Licht brachte.

Ausserdem der Hinweis, der den naechsten sonst eine Stunde kostet: Die
Pruefdatei-Tests zaehlen keine Mengen mehr. Wer die Saat erweitert, macht
sonst die aelteren Pruefungen rot, ohne dass etwas kaputt waere.

Festgehalten, was weiter bewusst fehlt: Vertragslogo, Kontoreihenfolge und
das Loesen einer Uebertrags-Verknuepfung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-10-21 21:29:10 +02:00
co-authored by Claude Opus 5
parent 9edf610d59
commit 6c6257b8f9
3 changed files with 66 additions and 23 deletions
+1
View File
@@ -47,6 +47,7 @@ Vollzugang. Wer eine Ausnahme braucht, trägt sie bewusst in `project.yml` ein.
| `Budget/` | Soll gegen Ist, Monat für Monat |
| `Buchungen/` | Buchungsliste mit Suche, Formular zum Anlegen und Ändern |
| `Abos/` | Verträge und Abos |
| `Arbeitsliste/` | Eingang, Übertragsvorschläge, Dubletten |
| `Konten/` | Kontenliste und Konto-Formular |
| `Texte/` | Übersetzungen, Deutsch und Englisch zeilengleich |
| `Tests/` | Logiktests ohne Netz, plus die Modellprüfung gegen `Fixtures/antworten.json` |
+59 -18
View File
@@ -6,7 +6,7 @@ haben: was entschieden ist, was fertig ist, was als Nächstes dran ist, und was
ich über das Backend herausgefunden habe. Lies sie ganz, bevor du anfängst —
die Abschnitte „Was das Backend vorgibt" und „Fallen" ersparen dir Tage.
Stand: 21.10.2026, Commit `82db09e`. Alles committet und gepusht.
Stand: 21.10.2026, Commit `9edf610`. Alles committet und gepusht.
---
@@ -242,7 +242,7 @@ Drei Tests in `test_budget.py` halten beide Richtungen und die Null fest.
---
## 5. Was fertig ist — Stufen 1 bis 3 ✅
## 5. Was fertig ist — Stufen 1 bis 4 ✅
### Stufe 1 (Commit `6b86a6b`)
@@ -397,21 +397,64 @@ Gibt er nichts aus, ist nichts offen. (Ein Schlüssel, der nur in einem
Lücke des Befehls.) Dass beide Sprachfassungen dieselben Schlüssel tragen,
prüft ein `diff` der beiden `grep`-Ausgaben.
### Stufe 4 — Arbeitsliste ✅ (Commit `9edf610`)
Ein Reiter „Eingang" mit vier Abschnitten, jeder mit Anzahl im Kopf:
offene Eingangseinträge, Übertragsvorschläge, Gebuchtes ohne Kategorie,
Dubletten. `Arbeitsliste/ArbeitslisteAnsicht.swift`, dazu zwei schmale
Auswahlblätter in `AuswahlBlaetter.swift`.
**Alles in einem Abruf** (`Arbeitsstand`), aus demselben Grund wie beim
Dashboard: Vier getrennte Zwischenspeicher könnten offline aus vier
verschiedenen Momenten stammen.
#### Der 409-Fall sitzt hier, und nur hier
`POST /inbox/{id}/transfer` kann mit 409 antworten. Das ist eine **Frage**,
kein Fehler: Die App zeigt den Hinweis und wiederholt den Aufruf auf Wunsch
mit `trotzdem: true`. `bucheAlsUebertrag` fängt `APIFehler.konflikt` eigens
ab, statt ihn in den allgemeinen Fehlerweg laufen zu lassen. Wer später einen
weiteren 409-Endpunkt anbindet, macht es genauso.
#### Kleinigkeiten, die man sonst zweimal findet
- **Ohne Konto lässt sich nichts buchen** (400 vom Backend). Der Knopf bleibt
grau — und die Zeile sagt „ohne Konto", damit das nicht unerklärt wirkt.
- **Ein Übertrag braucht keine Kategorie.** Daran erkennt man ihn:
`transfer_account_id` ist gesetzt. Ohne diese Prüfung fragte die Liste ewig
nach einer Kategorie, die es nie geben wird.
- **Die Dublettenliste zeigt die Kennung der Bank.** Verschiedene Kennungen
heissen: Die Bank hat sie ausdrücklich als verschiedene Zahlungen gemeldet.
Ohne diese Spalte lässt sich die Frage nicht entscheiden.
#### Ein Backend-Fehler, den die App ans Licht brachte
`/uebertraege/vorschlaege` lieferte jedes Paar **zweimal**, einmal je
Richtung: Was verknüpft wird, fällt über `verbraucht` heraus — ein blosser
Vorschlag nicht. Die Weboberfläche zeigte den Doppeleintrag genauso.
Behoben in `services/uebertraege.py` (`schlage_vor`), mit Test.
#### Prüfdatei-Tests zählen keine Mengen mehr
Die Saat in `erzeuge_ios_fixture.py` wuchs um Eingangseintrag, Dubletten und
ein Übertragspaar — und die älteren Tests wurden rot, weil sie exakte Anzahlen
prüften. Sie prüfen jetzt Eigenschaften (`>= 2`, „enthält einen Übertrag"),
damit sie das nächste Wachstum überleben. **Daran denken, wenn du die Saat
erweiterst.**
---
## 6. Was als Nächstes dran ist
**Stufe 4 ist dran.** Alle vier Backend-Ergänzungen sind drin; von hier an
**Stufe 5 ist dran.** Alle vier Backend-Ergänzungen sind drin; von hier an
reicht die API, wie sie ist.
Was aus Stufe 3 bewusst nicht mitkam: das **Logo** eines Vertrags (Upload und
Zuschnitt, `POST /subscriptions/{id}/logo`) und die **Reihenfolge** der Konten
(`PUT /accounts/order`). Beides ist am Rechner bequemer und hielt niemanden
auf.
**Stufe 4 — Arbeitsliste.** Eingang mit Buchen, Verwerfen, Kategorie zuordnen,
Übertragsvorschlägen und Dubletten. Fachlich der Teil, der am besten aufs
Telefon gehört: eine Zeile, eine Entscheidung.
Was bewusst nicht mitkam: das **Logo** eines Vertrags (Upload und Zuschnitt,
`POST /subscriptions/{id}/logo`), die **Reihenfolge** der Konten
(`PUT /accounts/order`) und das **Lösen** einer Übertrags-Verknüpfung
(`DELETE /uebertraege/{link_id}`) — in der Arbeitsliste gibt es nur noch
nichts Verknüpftes zu lösen. Alles drei ist am Rechner bequemer und hielt
niemanden auf.
**Stufe 5 — Nebenräume.** Kategorien, Tags, Schlagwörter, Einstellungen,
Bankabruf anstossen. Hier gehört auch das **Einrichten** des zweiten Faktors
@@ -431,14 +474,12 @@ Vorlagen, Verlauf mit Rücknahme.
### Zum Umfang, ehrlich
Die Weboberfläche hat rund 8900 Zeilen JSX. Nativ wird das nicht weniger.
Stufe 2 hat rund 1800 Zeilen gebraucht, Stufe 3 rund 1200; Stufen 4 bis 6
zusammen sind grob ein bis zwei Wochen, Stufe 7 nochmal zwei bis drei.
Stufe 2 hat rund 1800 Zeilen gebraucht, Stufe 3 rund 1200, Stufe 4 rund 900;
Stufen 5 und 6 zusammen sind grob eine Woche, Stufe 7 nochmal zwei bis drei.
Der **409-Fall** („nachfragen", mit `trotzdem=true` wiederholbar) kam in
Stufe 3 nicht vor — er steckt nur an
`POST /transactions/{id}/transfer`, also in Stufe 4. Dort wird er gebraucht:
Die App muss den Hinweis zeigen und den Aufruf auf Wunsch wiederholen,
statt den Fehler bloss zu melden.
Der **409-Fall** („nachfragen", mit `trotzdem=true` wiederholbar) ist in
Stufe 4 angekommen und erledigt — siehe dort. In den Stufen 5 bis 7 kommt er
nicht mehr vor.
Stufe 7 steht bewusst am Ende. Alles davor ist für sich nutzbar. Der Ablauf
hat **keinen Server-Zustand** zwischen den Schritten: Die Datei wird bei jedem