Tag 1: initiale Extraktion aus memoro-native. Tag 2: Reifung zu v1.5.0 (Account-Lifecycle, Guest-Mode + Refresh-Resilience, 2FA, ProfileInfo). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.5 KiB
4.5 KiB
| date | day | view | weekday | commits | review |
|---|---|---|---|---|---|
| 2026-05-13 | 2 | macher | Mittwoch | 8 | written |
Mittwoch, 2026-05-13 — Tag 2 (Macher-Sicht)
Reifung von v1.0.0 zu v1.5.0 in einer Schicht. Sechs Sinn-Abschnitte (Transport-Fix, Account-Lifecycle, Session-Token-Auth, Guest-Mode + Refresh-Resilience, 2FA-Login, 2FA-Enrollment, Profile) plus ein chore-Cleanup. Build-Verzeichnis war versehentlich committet — am Ende des Tages aufgeräumt.
Stats
8 Commits, +5 427 / −2 895 LoC, 408 Files. Achtung: 2 682 der
Deletions kamen aus chore: untrack build/ — der eigentliche
Code-Delta ist eher +2 700 / −200. Top-Dirs sind irreführend (alle
build/-Sub-Dirs), weil der Initial-Push das build/ mit hatte.
Tags: transport. Session 15:18 → 01:08, 62 aktive Minuten in
4 Blöcken, längster Fokus 48 Min.
Versions-Schritte
- Transport-Fix — URL-Konstruktion encoded
?-Query nicht mehr. Klassischer Bug: Path-Encoding lief gegen Query-String, dadurch?from=…als%3Ffrom%3D…rausgeschickt. 9 / −1 Zeilen. - v1.1.0 — Account-Lifecycle. Change-Email, Change-Password, Account-Delete als public API in ManaCore. ViewModels in mana-swift-ui ziehen morgen nach.
- v1.1.1 — Session-Token statt JWT für Account-Calls. Account-Operationen sind sensibel, brauchen frischen Re-Auth-Token, nicht den allgemeinen JWT.
- v1.2.0 — Guest-Mode + Refresh-Resilience. Wenn ein Refresh
mit transienten Errors fehlschlägt (Netz-Timeout, 503), bleibt
die Session aktiv und retried. Wenn der Refresh hart 401 macht,
fällt der State auf
.guestzurück statt blind alle Tokens zu wipen. Das war der wichtigste Fix — vorher hat mobiles Netz Memoro-User regelmäßig rausgeworfen. - v1.3.0 — 2FA-Login-Challenge. Wenn Login
requires_2fa: truezurückgibt, dann zweiter Round-Trip mit Code. - v1.4.0 — 2FA-Enrollment. Enroll-Init (QR-Secret) + Enroll- Verify + Disable mit Passwort + Backup-Code-Regenerate.
- v1.5.0 — getProfile() + ProfileInfo. Name, E-Mail, Mitgliedsstatus, Tier. +2 876 LoC — viel davon vendored swift- jose-Updates, die für RS256-JWKS-Verify nötig waren.
- chore: untrack build/ —
.gitignorefürbuild/, vorhandene Tracked-Files raus.
Architektur-Entscheidungen
- Session-Token (kurze TTL) für Account-Calls, nicht der allgemeine JWT. Begründung: bei Account-Delete oder Email-Change wäre ein gestohlener JWT katastrophal; frischer Session-Token begrenzt das Schaden-Fenster.
- Refresh-Resilience: transient vs. permanent. Transiente
Errors (Netz, 503, Timeout) halten Session, retry mit Backoff.
Permanente Errors (401, invalid_grant) führen zu
.guest. Vorher: jede Refresh-Failure → Wipe. - Guest-Mode als eigener State, nicht „signed-out". Apps können Inhalt anzeigen, der Read-Only ist, ohne dass sie eine Login-Wand zeigen müssen.
- 2FA-API additiv, kein Breaking-Change. Apps, die kein 2FA
unterstützen, ignorieren
requires_2fa-Field. - ProfileInfo als eigenes DTO, nicht in AuthClient verbaut. Profile ist datenzentriert, AuthClient ist State-zentriert.
- swift-jose vendored, statt SPM-Dependency. Public-API- Invariante „keine externen Dependencies" (Compliance-Direktive) bleibt.
Trade-offs
- +2 876 LoC für v1.5.0 klingt monströs, ist aber zu 80 % vendored swift-jose. Eigentliche Profile-API ist klein.
- Sechs Tags an einem Tag ist viel — bei strikter Semver wäre das eine Tagesserie, kein Sprint. Akzeptiert, weil jeder Tag einen klar abgegrenzten Sinn-Abschnitt hat.
- build/-Verzeichnis untracken nachträglich war Aufwand
(2 682 deletions in einem Commit). Ursache: SwiftPM-CLI legt
build/ im Repo-Root an, statt unter DerivedData —
.gitignorehätte Tag 1 schon gehört. - Session-Token-Mechanik in v1.1.1 nachgeschoben, weil v1.1.0 das nicht hatte. Hätte v1.1.0 direkt richtig machen sollen; akzeptiert als „erste Lernzyklen".
Offene Punkte
- Refresh-Resilience Test-Coverage: Unit-Tests für transiente vs. permanente Fehler-Pfade existieren, aber kein Real-World-Test (instabiles Netz simulieren).
- 2FA-Backup-Codes-Storage: ManaCore liefert sie als Strings zurück; UI muss sie sicher anzeigen + kopierbar machen. Liegt bei mana-swift-ui.
- getProfile() Cache-Politik: derzeit kein Cache. Bei häufigen Calls hilft eine kurze TTL.
- Schema-Drift gegen mana-auth: wenn der Server
ProfileInfo- Schema ändert, gibt's keinen Wire-Check. Pre-Live-Smoke wäre sinnvoll.