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
|
Stufe 1 ✅: Gerüst, Netzwerkschicht, Anmeldung samt zweitem Faktor und
|
||||||
Pflicht-Passwortwechsel, Kontenliste. Stufe 2 ✅: Übersicht, Budget-Monat,
|
Pflicht-Passwortwechsel, Kontenliste. Stufe 2 ✅: Übersicht, Budget-Monat,
|
||||||
Buchungsliste mit Suche, Vertragsliste. Übersetzt fehlerfrei, 44 Tests grün,
|
Buchungsliste mit Suche, Vertragsliste. Stufe 3 ✅: Buchungen, Budget-Zeilen,
|
||||||
läuft im Simulator; das Xcode-Projekt entsteht aus `ios/project.yml`, die
|
Verträge und Konten anlegen, ändern und löschen. Übersetzt fehlerfrei,
|
||||||
Modelle werden gegen echte Serverantworten geprüft.
|
49 Tests grün, läuft im Simulator; das Xcode-Projekt entsteht aus
|
||||||
Stufen 3–7 (Schreiben, Arbeitsliste, Nebenräume, Erweiterungen, voller
|
`ios/project.yml`, die Modelle werden gegen echte Serverantworten geprüft.
|
||||||
CSV-Import) stehen aus.
|
Stufen 4–7 (Arbeitsliste, Nebenräume, Erweiterungen, voller CSV-Import)
|
||||||
|
stehen aus.
|
||||||
|
|
||||||
**Stand, Entscheidungen und offene Punkte: `ios/UEBERGABE.md`.**
|
**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 |
|
| `App/` | Einstiegspunkt, Navigation, globaler Zustand |
|
||||||
| `Netzwerk/` | Client, Endpunkte, Fehler, Offline-Ablage |
|
| `Netzwerk/` | Client, Endpunkte, Fehler, Offline-Ablage |
|
||||||
| `Modelle/` | Codable-Typen, eins zu eins zu den Backend-Schemas |
|
| `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 |
|
| `Anmeldung/` | Server-Adresse, Anmeldung, zweiter Faktor, Passwortwechsel |
|
||||||
| `Dashboard/` | Die Übersicht: vier feste Karten |
|
| `Dashboard/` | Die Übersicht: vier feste Karten |
|
||||||
| `Budget/` | Soll gegen Ist, Monat für Monat |
|
| `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 |
|
| `Abos/` | Verträge und Abos |
|
||||||
| `Konten/` | Kontenliste |
|
| `Konten/` | Kontenliste und Konto-Formular |
|
||||||
| `Texte/` | Übersetzungen, Deutsch und Englisch zeilengleich |
|
| `Texte/` | Übersetzungen, Deutsch und Englisch zeilengleich |
|
||||||
| `Tests/` | Logiktests ohne Netz, plus die Modellprüfung gegen `Fixtures/antworten.json` |
|
| `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 —
|
ich über das Backend herausgefunden habe. Lies sie ganz, bevor du anfängst —
|
||||||
die Abschnitte „Was das Backend vorgibt" und „Fallen" ersparen dir Tage.
|
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
|
## 4. Backend-Ergänzungen
|
||||||
|
|
||||||
Vier geplant. **A, B und C sind fertig**, D steht aus. Jede einzeln dem Nutzer
|
Vier geplant, **alle vier sind fertig**. Falls du eine fünfte brauchst: einzeln
|
||||||
vorlegen, bevor du sie schreibst.
|
dem Nutzer vorlegen, bevor du sie schreibst.
|
||||||
|
|
||||||
### A — App-Token ✅ (Commit `8a7545b`)
|
### 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
|
Speichern auch als feste zurück**. Die Weboberfläche traf es nicht, weil sie
|
||||||
die Betriebsart aus der Monatsansicht nimmt.
|
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
|
`copy_template_to_month` und `copy_month_to_template` in
|
||||||
`backend/app/services/budget.py` übernehmen nur `planned_cents`. Ein
|
`backend/app/services/budget.py` übernahmen nur `planned_cents`. Ein
|
||||||
„berechneter" Eintrag fällt beim Kopieren still auf „fest" zurück. Das ist ein
|
„berechneter" Eintrag fiel beim Kopieren still auf „fest" zurück — mit der
|
||||||
**bestehender Fehler**, kein App-Thema — aber die App macht ihn sichtbar, weil
|
Zahl, die zufällig zuletzt in `planned_cents` stand.
|
||||||
sie beide Richtungen anbietet. Nötig für Stufe 3.
|
|
||||||
|
`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`)
|
### Stufe 1 (Commit `6b86a6b`)
|
||||||
|
|
||||||
@@ -335,20 +342,72 @@ committen:
|
|||||||
cd backend && .venv/bin/python -m scripts.erzeuge_ios_fixture
|
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
|
Wer ein Modell ergänzt, nimmt seinen Endpunkt in `PFADE` auf und schreibt eine
|
||||||
schreibt eine Zeile im Test dazu. Das ist die einzige Prüfung, die einen
|
Zeile im Test dazu. Das ist die einzige Prüfung, die einen vertippten
|
||||||
vertippten Feldnamen fängt — der übersetzt anstandslos.
|
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
|
## 6. Was als Nächstes dran ist
|
||||||
|
|
||||||
**Stufe 3 ist dran.** Davor liegt nur noch Backend-Ergänzung **D** (unten),
|
**Stufe 4 ist dran.** Alle vier Backend-Ergänzungen sind drin; von hier an
|
||||||
die zwei Kopier-Lücken im Budget.
|
reicht die API, wie sie ist.
|
||||||
|
|
||||||
**Stufe 3 — Schreiben.** Buchungen anlegen und ändern, Budget bearbeiten
|
Was aus Stufe 3 bewusst nicht mitkam: das **Logo** eines Vertrags (Upload und
|
||||||
(Monat und Vorlage, beide Betriebsarten `fest`/`berechnet`), Abos verwalten
|
Zuschnitt, `POST /subscriptions/{id}/logo`) und die **Reihenfolge** der Konten
|
||||||
samt Logo, Konten bearbeiten. Dazu Backend-Ergänzung **D**.
|
(`PUT /accounts/order`). Beides ist am Rechner bequemer und hielt niemanden
|
||||||
|
auf.
|
||||||
|
|
||||||
**Stufe 4 — Arbeitsliste.** Eingang mit Buchen, Verwerfen, Kategorie zuordnen,
|
**Stufe 4 — Arbeitsliste.** Eingang mit Buchen, Verwerfen, Kategorie zuordnen,
|
||||||
Übertragsvorschlägen und Dubletten. Fachlich der Teil, der am besten aufs
|
Übertragsvorschlägen und Dubletten. Fachlich der Teil, der am besten aufs
|
||||||
@@ -372,12 +431,14 @@ Vorlagen, Verlauf mit Rücknahme.
|
|||||||
### Zum Umfang, ehrlich
|
### Zum Umfang, ehrlich
|
||||||
|
|
||||||
Die Weboberfläche hat rund 8900 Zeilen JSX. Nativ wird das nicht weniger.
|
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
|
Stufe 2 hat rund 1800 Zeilen gebraucht, Stufe 3 rund 1200; Stufen 4 bis 6
|
||||||
zwei bis drei Wochen, Stufe 7 nochmal zwei bis drei.
|
zusammen sind grob ein bis zwei Wochen, Stufe 7 nochmal zwei bis drei.
|
||||||
|
|
||||||
Stufe 3 wird die aufwendigste der verbliebenen: Schreiben heisst Formulare,
|
Der **409-Fall** („nachfragen", mit `trotzdem=true` wiederholbar) kam in
|
||||||
Fehlerbehandlung je Feld und der 409-Fall („nachfragen", oft mit
|
Stufe 3 nicht vor — er steckt nur an
|
||||||
`trotzdem=true` wiederholbar). Lesen war dagegen geradeaus.
|
`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
|
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
|
hat **keinen Server-Zustand** zwischen den Schritten: Die Datei wird bei jedem
|
||||||
|
|||||||
Reference in New Issue
Block a user