Die Nebenraeume haengen unter Einstellungen, nicht als eigene Reiter: Man
braucht sie selten, und eine Leiste mit zehn Reitern findet niemand mehr.
- Kategorien: anlegen, aendern, archivieren, loeschen - samt Gruppen. Eine
Kategorie oeffnet ihre Erkennungswoerter, die sich dort hinzufuegen und
entfernen lassen. Darunter steht, was sonst niemand merkt: Sie wirken nur
auf kuenftige Importe.
- Woerter, die oft korrigiert werden, stehen als Pruefmeldung in den
Einstellungen - behalten oder entfernen.
- Schlagwoerter: anlegen, umbenennen, umfaerben, loeschen. Neue bekommen
reihum eine Farbe, damit nicht alle grau sind.
- Einstellungen: Erscheinungsbild, Hauptwaehrung und Budget-Starttag lassen
sich jetzt aendern. Ohne Sichern-Knopf - es ist je Zeile genau ein Wert,
und das Backend nimmt ihn einzeln entgegen. Dazu der Hinweis, dass sie dem
Konto gehoeren und nicht dem Geraet.
- Bank: abrufen und Salden auffrischen. Verbinden bleibt am Rechner, die
Bank leitet fest dorthin zurueck. Der letzte Fehler der Verbindung steht
dabei, sonst ruft man vergeblich ab.
- Zweiter Faktor: einrichten in drei Schritten. Auf dem Telefon fuehrt der
Weg ueber die otpauth-Adresse direkt in die Authenticator-App statt ueber
einen QR-Code, den man sich selbst zeigen muesste. Die Rettungscodes
erscheinen einmal; das Blatt laesst sich nicht wegwischen und erst
schliessen, wenn man bestaetigt hat, sie gesichert zu haben.
Abschalten des zweiten Faktors bleibt bewusst draussen: Es verlangt das
Kontopasswort, und die App speichert keines. Ein Vollzugang auf diesem Geraet
soll den Schutz des Kontos nicht aufheben koennen.
59 Tests gruen. Texte in Deutsch und Englisch, zeilengleich.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ein neuer Reiter "Eingang" mit allem, worueber jemand entscheiden muss. Vier
Abschnitte, jeweils mit Anzahl im Kopf:
- Zu buchen: offene Eingangseintraege aus Kurzbefehl, Postfach oder Bank.
Buchen, als Uebertrag buchen, verwerfen - oder alle auf einmal, bei denen
das Konto feststeht. Unklare tragen einen Hinweis ueber den Knoepfen, nicht
darunter: Man soll sie ansehen, nicht wegbuchen.
- Koennten Uebertraege sein: zwei getrennte Buchungen, die zusammengehoeren
koennten. Verbinden oder ablehnen. Hat eine der beiden eine Kategorie,
steht dabei, dass sie durchs Verbinden aus dem Budget faellt.
- Ohne Kategorie: gebuchtes Geld, das in keiner Budget-Zeile mitzaehlt. Ein
Tipp, eine Kategorie - kein Formular mit zwoelf Feldern davor.
- Sieht doppelt aus: gleiches Konto, gleicher Tag, gleicher Betrag. Mit der
Kennung der Bank je Zeile, denn verschiedene Kennungen heissen, dass die
Bank sie als verschiedene Zahlungen gemeldet hat.
Alles in einem Abruf. Vier getrennte Zwischenspeicher koennten offline aus
vier verschiedenen Momenten stammen und sich widersprechen.
Hier sitzt der einzige 409-Fall der App: Beim Buchen als Uebertrag kann das
Backend Bedenken haben. Das ist eine Frage, kein Fehler - die App zeigt den
Hinweis und wiederholt den Aufruf auf Wunsch mit trotzdem=true. Ihn zu
verschlucken waere falsch, ihn als blossen Fehler zu zeigen auch.
Zwei Dinge, die die Tests festhalten: Ohne Konto laesst sich nichts buchen
(das Backend lehnt mit 400 ab, der Knopf bleibt also grau - und die Zeile sagt
auch warum). Und ein Uebertrag braucht keine Kategorie, sonst fragte die Liste
ewig nach einer, die es nie geben wird.
Die Pruefdatei deckt jetzt auch Eingang, Dubletten und Uebertragsvorschlaege
ab. Die aelteren Pruefungen zaehlten exakt und wurden dadurch rot - sie
pruefen jetzt Eigenschaften statt Mengen, damit sie das naechste Wachstum
ueberleben. 54 Tests gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Buchungen anlegen, aendern und loeschen; Budget-Zeilen setzen, fuer den Monat
oder fuer die Vorlage; Vertraege und Konten anlegen und aendern. Damit kann
die App alles, wofuer man bisher an den Rechner musste - ausser Import,
Arbeitsliste und Verwaltung.
Ein Formular je Sache, nicht zwei: Anlegen und Aendern teilen sich die Maske,
weil die Felder dieselben sind und zwei Kopien genau die Stelle waeren, an der
sie auseinanderlaufen. Was sich unterscheidet, steht in einem Zweck-Typ.
Geteilt in Bausteine/Formular.swift: ein Speichervorgang, der den Knopf sperrt
und den Fehler festhaelt (das Formular bleibt offen - zugeklappt waere die
Eingabe weg und die Meldung nutzlos), ein Betragsfeld, das an Cent gebunden
ist statt an Text, und die Auswahlfelder fuer Kategorie, Konto und
Schlagwoerter.
Drei Dinge, die stillschweigend falsch waeren:
Eine Teilaenderung schickt nur, was gesetzt ist. Ginge ein nicht angefasstes
Feld als null hinaus, loeschte jedes Speichern den Empfaenger, die Notiz und
die Kategorie gleich mit. Eine leere Tag-Liste geht dagegen sehr wohl mit -
sie bedeutet "alle abnehmen" und darf nicht mit "nicht angefasst"
zusammenfallen.
Bei einem Uebertrag wird keine Kategorie mitgeschickt: Das Geld wechselt nur
die Tasche, es wird nicht eingeordnet.
Bei Betriebsart "berechnet" bleibt planned_cents unberuehrt - das Backend
liest es dann nicht, und es zu ueberschreiben verloere den Wert, auf den ein
Zurueckschalten auf "fest" zurueckfallen soll.
Die Waehrung eines bestehenden Kontos laesst sich nicht aendern: Jeder
gespeicherte Betrag wuerde danach etwas anderes bedeuten.
49 Tests gruen. Texte in Deutsch und Englisch, zeilengleich.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die App kann jetzt lesen, wofuer man sie oeffnet. Vier neue Reiter:
- Uebersicht: Einnahmen/Ausgaben des Monats, Budget-Fortschritt je Gruppe,
Kontostaende und die letzten Buchungen. Feste Auswahl statt des
verschiebbaren Rasters der Weboberflaeche - auf Telefonbreite waere das
Arbeit ohne Gewinn. Vier Endpunkte nebeneinander in einem Abruf, damit der
Offline-Stand nicht aus vier verschiedenen Momenten stammt.
- Budget: Soll gegen Ist je Gruppe und Kategorie, blaetterbar ueber prev/next
aus der Antwort. Rot nur bei echter Ueberschreitung - wer mehr zuruecklegt
als geplant, hat nichts ueberzogen. Vertraege ohne Kategorie und fehlende
Wechselkurse stehen als Hinweis darunter, statt die Summen still zu
verfaelschen.
- Buchungen: Suche und Filter laufen im Server (Backend-Ergaenzung B), nicht
im Telefon. Gesucht wird beim Absenden, nicht je Tastendruck.
- Vertraege: Monats- und Jahressumme, Rhythmus, naechste Faelligkeit.
Zwei Dinge, die das Backend bewusst dem Client ueberlaesst:
Ein Uebertrag kommt in zwei Gestalten - am Stueck (eine Buchung mit
to_account_id) oder als zwei verknuepfte Buchungen, wie die Bank sie liefert.
Beide Beine als zwei Zeilen zu zeigen hiesse, dasselbe Geld zweimal zu zeigen.
Buchungszeile.zeilen fasst sie zusammen, aber nur wenn beide in der Liste
stehen - sonst liesse ein Kontofilter Zeilen verschwinden, die sehr wohl zu
diesem Konto gehoeren. Die Richtung kommt aus der Verknuepfung, nicht aus dem
Vorzeichen: Manche Banken liefern beide Beine positiv.
Kategorien, Schlagwoerter und Konten liegen als Nachschlagewerk im AppZustand,
einmal geladen. Je Ansicht neu zu holen waere genau das N+1, das das Backend
sich selbst verbietet.
Texte in Deutsch und Englisch, zeilengleich. 44 Tests gruen, darunter die
Uebertrags-Paarung und jedes Modell gegen eine echte Serverantwort.
Nicht geprueft: der Weg gegen ein echtes Backend. Die App laesst nur https zu,
ein lokaler Server haette eine ATS-Ausnahme gebraucht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bisher musste das Xcode-Projekt von Hand angelegt werden, und der Swift-Code
wurde blind geschrieben, ohne ihn je zu uebersetzen. ios/project.yml
beschreibt das Projekt jetzt in 50 Zeilen; xcodegen generate macht daraus
Certain.xcodeproj. Das erzeugte Projekt liegt mit im Repository, damit man es
ohne xcodegen einfach oeffnen kann - geaendert wird aber die project.yml.
Festgelegt nach dem Muster von Vorrania: Buendelkennung com.scarriffle.certain,
Team PP34X97WS3, iPhone und iPad, Entwicklungssprache Deutsch, iOS 26 als
Mindestversion. Sprachfassung Swift 5, weil der Code nicht auf die strikte
Nebenlaeufigkeitspruefung von Swift 6 hin geschrieben ist.
Stufe 1 uebersetzt damit fehlerfrei, die 28 Tests laufen durch, und die App
startet im Simulator bei der Serverabfrage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>