docs: Uebergabe, README und Fahrplan halten Stufe 3 fest
Neu drin: die vier Regeln, die man nicht sieht, aber merkt, wenn sie fehlen
(Teilaenderung schickt nur Gesetztes, leere Tag-Liste bedeutet etwas, kein
Kategorie beim Uebertrag, planned_cents bleibt bei "berechnet" unberuehrt),
und warum die Waehrung eines bestehenden Kontos nicht aenderbar ist.
Dazu der Befehl, mit dem man fehlende Uebersetzungen findet - ein unbekannter
Schluessel uebersetzt anstandslos und zeigt dem Nutzer den Schluessel.
Festgehalten, was aus Stufe 3 bewusst nicht mitkam: Vertragslogo und
Kontoreihenfolge. Und wo der 409-Fall wartet: an POST
/transactions/{id}/transfer, also in Stufe 4.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+6
-5
@@ -52,10 +52,11 @@ zweispaltig, offline der letzte Stand mit Datum.
|
||||
|
||||
Stufe 1 ✅: Gerüst, Netzwerkschicht, Anmeldung samt zweitem Faktor und
|
||||
Pflicht-Passwortwechsel, Kontenliste. Stufe 2 ✅: Übersicht, Budget-Monat,
|
||||
Buchungsliste mit Suche, Vertragsliste. Übersetzt fehlerfrei, 44 Tests grün,
|
||||
läuft im Simulator; das Xcode-Projekt entsteht aus `ios/project.yml`, die
|
||||
Modelle werden gegen echte Serverantworten geprüft.
|
||||
Stufen 3–7 (Schreiben, Arbeitsliste, Nebenräume, Erweiterungen, voller
|
||||
CSV-Import) stehen aus.
|
||||
Buchungsliste mit Suche, Vertragsliste. Stufe 3 ✅: Buchungen, Budget-Zeilen,
|
||||
Verträge und Konten anlegen, ändern und löschen. Übersetzt fehlerfrei,
|
||||
49 Tests grün, läuft im Simulator; das Xcode-Projekt entsteht aus
|
||||
`ios/project.yml`, die Modelle werden gegen echte Serverantworten geprüft.
|
||||
Stufen 4–7 (Arbeitsliste, Nebenräume, Erweiterungen, voller CSV-Import)
|
||||
stehen aus.
|
||||
|
||||
**Stand, Entscheidungen und offene Punkte: `ios/UEBERGABE.md`.**
|
||||
|
||||
+3
-3
@@ -41,13 +41,13 @@ Vollzugang. Wer eine Ausnahme braucht, trägt sie bewusst in `project.yml` ein.
|
||||
| `App/` | Einstiegspunkt, Navigation, globaler Zustand |
|
||||
| `Netzwerk/` | Client, Endpunkte, Fehler, Offline-Ablage |
|
||||
| `Modelle/` | Codable-Typen, eins zu eins zu den Backend-Schemas |
|
||||
| `Bausteine/` | Wiederverwendetes: Geld, Farben, Symbole, Zustandsansichten |
|
||||
| `Bausteine/` | Wiederverwendetes: Geld, Farben, Symbole, Zustandsansichten, Formularfelder |
|
||||
| `Anmeldung/` | Server-Adresse, Anmeldung, zweiter Faktor, Passwortwechsel |
|
||||
| `Dashboard/` | Die Übersicht: vier feste Karten |
|
||||
| `Budget/` | Soll gegen Ist, Monat für Monat |
|
||||
| `Buchungen/` | Buchungsliste mit Suche und Filtern |
|
||||
| `Buchungen/` | Buchungsliste mit Suche, Formular zum Anlegen und Ändern |
|
||||
| `Abos/` | Verträge und Abos |
|
||||
| `Konten/` | Kontenliste |
|
||||
| `Konten/` | Kontenliste und Konto-Formular |
|
||||
| `Texte/` | Übersetzungen, Deutsch und Englisch zeilengleich |
|
||||
| `Tests/` | Logiktests ohne Netz, plus die Modellprüfung gegen `Fixtures/antworten.json` |
|
||||
|
||||
|
||||
+84
-23
@@ -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 `ffe1870`. Alles committet und gepusht.
|
||||
Stand: 21.10.2026, Commit `82db09e`. Alles committet und gepusht.
|
||||
|
||||
---
|
||||
|
||||
@@ -173,8 +173,8 @@ umgestellt, weil sie so funktioniert. Die App soll die Filter benutzen.
|
||||
|
||||
## 4. Backend-Ergänzungen
|
||||
|
||||
Vier geplant. **A, B und C sind fertig**, D steht aus. Jede einzeln dem Nutzer
|
||||
vorlegen, bevor du sie schreibst.
|
||||
Vier geplant, **alle vier sind fertig**. Falls du eine fünfte brauchst: einzeln
|
||||
dem Nutzer vorlegen, bevor du sie schreibst.
|
||||
|
||||
### A — App-Token ✅ (Commit `8a7545b`)
|
||||
|
||||
@@ -225,17 +225,24 @@ 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)
|
||||
### D — Zwei Kopier-Lücken im Budget ✅
|
||||
|
||||
`copy_template_to_month` und `template_from_month` in
|
||||
`backend/app/services/budget.py` übernehmen nur `planned_cents`. Ein
|
||||
„berechneter" Eintrag fällt beim Kopieren still auf „fest" zurück. Das ist ein
|
||||
**bestehender Fehler**, kein App-Thema — aber die App macht ihn sichtbar, weil
|
||||
sie beide Richtungen anbietet. Nötig für Stufe 3.
|
||||
`copy_template_to_month` und `copy_month_to_template` in
|
||||
`backend/app/services/budget.py` übernahmen nur `planned_cents`. Ein
|
||||
„berechneter" Eintrag fiel beim Kopieren still auf „fest" zurück — mit der
|
||||
Zahl, die zufällig zuletzt in `planned_cents` stand.
|
||||
|
||||
`ensure_customized` nebenan machte es längst richtig; die zwei Kopierer ziehen
|
||||
jetzt nach. Dabei kam eine Frage auf, die vorher niemand stellen musste: Eine
|
||||
**berechnete** Zeile gehört auch mit `planned_cents == 0` in die Vorlage, ihre
|
||||
Zahl steht ja in den Verträgen. Eine **feste** Null bleibt draussen, sonst
|
||||
füllte sich die Vorlage mit Nullzeilen für jede je berührte Kategorie.
|
||||
|
||||
Drei Tests in `test_budget.py` halten beide Richtungen und die Null fest.
|
||||
|
||||
---
|
||||
|
||||
## 5. Was fertig ist — Stufen 1 und 2 ✅
|
||||
## 5. Was fertig ist — Stufen 1 bis 3 ✅
|
||||
|
||||
### Stufe 1 (Commit `6b86a6b`)
|
||||
|
||||
@@ -335,20 +342,72 @@ committen:
|
||||
cd backend && .venv/bin/python -m scripts.erzeuge_ios_fixture
|
||||
```
|
||||
|
||||
Wer ein Modell für Stufe 3 ergänzt, nimmt seinen Endpunkt in `PFADE` auf und
|
||||
schreibt eine Zeile im Test dazu. Das ist die einzige Prüfung, die einen
|
||||
vertippten Feldnamen fängt — der übersetzt anstandslos.
|
||||
Wer ein Modell ergänzt, nimmt seinen Endpunkt in `PFADE` auf und schreibt eine
|
||||
Zeile im Test dazu. Das ist die einzige Prüfung, die einen vertippten
|
||||
Feldnamen fängt — der übersetzt anstandslos.
|
||||
|
||||
### Stufe 3 — Schreiben ✅ (Commit `82db09e`)
|
||||
|
||||
Buchungen, Budget-Zeilen, Verträge und Konten lassen sich anlegen, ändern und
|
||||
löschen.
|
||||
|
||||
| Datei | Inhalt |
|
||||
|---|---|
|
||||
| `Modelle/Eingaben.swift` | Was zum Server hinausgeht |
|
||||
| `Bausteine/Formular.swift` | Speichervorgang, Betragsfeld, Auswahlfelder |
|
||||
| `Buchungen/BuchungFormular.swift` | Anlegen **und** Ändern in einer Maske |
|
||||
| `Budget/BudgetZeileBearbeiten.swift` | Monat oder Vorlage, dieselbe Maske |
|
||||
| `Abos/AboFormular.swift`, `Konten/KontoFormular.swift` | ebenso |
|
||||
|
||||
**Ein Formular je Sache, nicht zwei.** Anlegen und Ändern teilen sich die
|
||||
Maske; was sich unterscheidet, steht in einem `Zweck`-Typ. Zwei Masken
|
||||
nebeneinander wären genau die Stelle, an der sie auseinanderlaufen.
|
||||
|
||||
#### Vier Regeln, die man nicht sieht, aber merkt, wenn sie fehlen
|
||||
|
||||
1. **Eine Teiländerung schickt nur, was gesetzt ist.** Ginge ein nicht
|
||||
angefasstes Feld als `null` hinaus, löschte jedes Speichern den Empfänger,
|
||||
die Notiz und die Kategorie gleich mit. Swift macht das von selbst
|
||||
(`encodeIfPresent` für Optionals) — der Test dazu bleibt trotzdem stehen,
|
||||
die Eigenschaft ist zu wichtig für eine ungeprüfte Spracheigenheit.
|
||||
2. **Eine leere Tag-Liste geht sehr wohl mit.** Sie heisst „alle abnehmen" und
|
||||
darf nicht mit „nicht angefasst" zusammenfallen.
|
||||
3. **Ein Übertrag bekommt keine Kategorie.** Das Geld wechselt nur die Tasche.
|
||||
4. **Bei „berechnet" bleibt `planned_cents` unberührt.** Das Backend liest es
|
||||
dann nicht, und es zu überschreiben verlöre den Wert, auf den ein
|
||||
Zurückschalten auf „fest" zurückfallen soll.
|
||||
|
||||
Die **Währung eines bestehenden Kontos** lässt sich nicht ändern — jeder
|
||||
gespeicherte Betrag würde danach etwas anderes bedeuten. Das Backend erlaubt
|
||||
es; die App nicht.
|
||||
|
||||
#### Fehlende Texte findet dieser Befehl
|
||||
|
||||
`String(localized:)` mit unbekanntem Schlüssel übersetzt anstandslos und zeigt
|
||||
dem Nutzer den Schlüssel. Vor dem Committen:
|
||||
|
||||
```
|
||||
cd ios && comm -23 \
|
||||
<(grep -rhoE 'localized: "[a-zA-Z0-9._]+"' --include="*.swift" . | sed 's/localized: "//; s/"//' | sort -u) \
|
||||
<(grep -oE '^"[a-zA-Z0-9._]+"' Texte/de.lproj/Localizable.strings | tr -d '"' | sort -u)
|
||||
```
|
||||
|
||||
Gibt er nichts aus, ist nichts offen. (Ein Schlüssel, der nur in einem
|
||||
`? :` steckt, taucht fälschlich als „fehlend" nicht auf — das ist die eine
|
||||
Lücke des Befehls.) Dass beide Sprachfassungen dieselben Schlüssel tragen,
|
||||
prüft ein `diff` der beiden `grep`-Ausgaben.
|
||||
|
||||
---
|
||||
|
||||
## 6. Was als Nächstes dran ist
|
||||
|
||||
**Stufe 3 ist dran.** Davor liegt nur noch Backend-Ergänzung **D** (unten),
|
||||
die zwei Kopier-Lücken im Budget.
|
||||
**Stufe 4 ist dran.** Alle vier Backend-Ergänzungen sind drin; von hier an
|
||||
reicht die API, wie sie ist.
|
||||
|
||||
**Stufe 3 — Schreiben.** Buchungen anlegen und ändern, Budget bearbeiten
|
||||
(Monat und Vorlage, beide Betriebsarten `fest`/`berechnet`), Abos verwalten
|
||||
samt Logo, Konten bearbeiten. Dazu Backend-Ergänzung **D**.
|
||||
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
|
||||
@@ -372,12 +431,14 @@ 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; Stufen 3 bis 6 zusammen sind grob
|
||||
zwei bis drei Wochen, Stufe 7 nochmal zwei bis drei.
|
||||
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 3 wird die aufwendigste der verbliebenen: Schreiben heisst Formulare,
|
||||
Fehlerbehandlung je Feld und der 409-Fall („nachfragen", oft mit
|
||||
`trotzdem=true` wiederholbar). Lesen war dagegen geradeaus.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user