Docs: catch up to auth discovery, settings screen and sync fixes
Document the four features that landed on main in b44bc8c..85c790e: - AGENTS.md: post-MVP section now covers server-driven auth discovery (GET /api/config, AUTH_PASSWORD_ENABLED 403 enforcement, OIDC_GENERIC_DISPLAY_NAME), the settings screen with GET/PUT /api/me, and the critical Android sync/data-safety fixes (pull-all-lists, client HLC tick per server op, no destructive migration, ProGuard rules). Repo structure updated (httpapi config.go/me.go, ui/settings), roadmap entries added, open-points list extended with test backlog for the new endpoints. - API.md: new sections for GET /api/config (public) and GET/PUT /api/me; 403 responses documented for register/login when password auth is off. - SYNC.md: client pull loop (every tracked list, op_log pruning) and the client HLC discipline (tick per incoming server op) that keeps LWW correct across devices with skewed clocks. - README: highlights for auth discovery/OIDC-only mode and the settings screen.
This commit is contained in:
parent
67033e561c
commit
cdc0c785b9
4 changed files with 100 additions and 9 deletions
53
AGENTS.md
53
AGENTS.md
|
|
@ -46,6 +46,25 @@ Vollständiger Plan liegt als genehmigtem Plan zugrunde (siehe Abschnitt "Roadma
|
|||
Einstieg. Teilen/Beitreten erfordert aktive Server-Verbindung (App-gated).
|
||||
- **Self-Hosted Server-URL:** konfigurierbar in der App (Auth-Screen), umgesetzt
|
||||
via `DynamicBaseUrlInterceptor` (schreibt scheme/host/port pro Request um).
|
||||
- **Server-getriebene Auth-Discovery:** Öffentlicher Endpoint `GET /api/config`
|
||||
verrät der App vor dem Login die verfügbaren Methoden (`password_enabled`,
|
||||
OIDC-Provider mit `display_name`, z.B. „Authentik"). `AUTH_PASSWORD_ENABLED=false`
|
||||
→ Register/Login per Passwort → 403 (OIDC-only-Enforcement). App-Login zeigt
|
||||
nur noch die angebotenen Methoden (ConnectView → LoginView).
|
||||
- **Profil + Settings-Screen:** `GET/PUT /api/me` (aktuell `display_name`),
|
||||
`SettingsScreen` mit Account & Sync, Profil, Theme (System/Hell/Dunkel,
|
||||
persistiert in SessionManager), „Lokale Daten zurücksetzen" (nur Room-Tabellen,
|
||||
Serverdaten bleiben) und About.
|
||||
- **Kritische Sync-/Datensicherheits-Fixes (Android):** SyncWorker pullt jetzt
|
||||
**alle** getrackten Listen (nicht nur welche mit pending Outbox – vorher kamen
|
||||
Remote-Änderungen stiller Listen nie an); lokale HLC tickt mit jedem eingehenden
|
||||
Server-Op (`tick(op.hlcTs)` → LWW korrekt bei Uhr-Drift); `list_create` in
|
||||
`applyServerOpProjection` ergänzt; Projektions-Write + op_log-Insert in einer
|
||||
Room-Transaktion; `clientId`/`clientSeq` persistent in SessionManager;
|
||||
**kein** `fallbackToDestructiveMigration` mehr (Source of Truth darf nie
|
||||
gewispt werden); ProGuard-Keep-Rules für kotlinx.serialization/Retrofit
|
||||
(R8-Releases crashten sonst); `network_security_config` (Cleartext nur für
|
||||
localhost/10.0.2.2); WorkManager-Default-Initializer deaktiviert (Hilt).
|
||||
- **Authentik-OIDC:** läuft über den bestehenden Generic-OIDC-Provider
|
||||
(`provider: "generic"`); die App erlaubt manuelle id_token-Eingabe.
|
||||
- **MVP-Scope:** keine Echtzeit-Push (nur Periodic-Pull 15 min + Pull-on-Online);
|
||||
|
|
@ -106,7 +125,7 @@ mitbringsl/
|
|||
│ │ ├── auth/ # PHASE B – Password + Session + OIDC
|
||||
│ │ │ ├── password.go # Argon2id im PHC-Format (HashPassword/VerifyPassword)
|
||||
│ │ │ ├── password_test.go # PHC-Roundtrip-Tests
|
||||
│ │ │ ├── user.go # UserStore: CreateUser/GetByEmail/GetByID/GetByOIDCSubject/CreateOIDCUser
|
||||
│ │ │ ├── user.go # UserStore: CreateUser/GetByEmail/GetByID/GetByOIDCSubject/CreateOIDCUser/UpdateDisplayName
|
||||
│ │ │ ├── session.go # SessionStore: opaque Tokens, SHA-256-Hash, Create/Lookup/Revoke
|
||||
│ │ │ ├── oidc.go # OIDCService: id_token-Verifikation (JWKS/iss/aud/exp), Provider-Caching
|
||||
│ │ │ └── pgcode.go # isUniqueViolation (SQLSTATE 23505)
|
||||
|
|
@ -126,7 +145,9 @@ mitbringsl/
|
|||
│ │ ├── render.go # JSON-Render + Problem + Fehler-Sentinale + decodeJSON
|
||||
│ │ ├── middleware.go # requestID/logging/recover/cors + Chain
|
||||
│ │ ├── health.go # /healthz + /readyz
|
||||
│ │ ├── auth.go # Register/Login/Logout/OIDC-Handler + RequireAuth-Middleware
|
||||
│ │ ├── auth.go # Register/Login/Logout/OIDC-Handler + RequireAuth-Middleware (403 wenn Passwort-Login deaktiviert)
|
||||
│ │ ├── config.go # GET /api/config (öffentlich): verfügbare Auth-Methoden für die App
|
||||
│ │ ├── me.go # GET/PUT /api/me (eigenes Profil, display_name)
|
||||
│ │ ├── lists.go # GET/POST /api/lists, GET /api/lists/{id}, POST /invite, POST /join
|
||||
│ │ ├── ops.go # POST/GET /api/lists/{id}/ops (Push/Pull, Membership-Check)
|
||||
│ │ └── suggest.go # GET /api/suggestions?q=
|
||||
|
|
@ -151,15 +172,16 @@ mitbringsl/
|
|||
│ └── API.md # REST Specs (inkl. join/invite)
|
||||
└── android/ # Single-Module :app (Compose M3, Room, Hilt)
|
||||
└── app/src/main/java/com/example/mitbringsl/
|
||||
├── data/auth/ # SessionManager (Local-User-Fallback, Server-URL)
|
||||
├── data/auth/ # SessionManager (Local-User-Fallback, Server-URL, clientId/clientSeq, Theme-Pref)
|
||||
├── data/local/ # Room DB (lists, items, op_log), DAOs (LWW upsert)
|
||||
├── data/remote/ # Retrofit-API, DTOs, DynamicBaseUrlInterceptor, AuthInterceptor
|
||||
├── data/repository/ # ShoppingRepository, AuthRepository
|
||||
├── data/sync/ # HybridLogicalClock, SyncManager, SyncWorker
|
||||
├── data/sync/ # HybridLogicalClock, SyncManager, SyncWorker (pullt ALLE Listen, HLC-Tick pro Server-Op)
|
||||
├── di/ # Hilt Modules
|
||||
├── ui/auth/ # AuthScreen (Login/Register/OIDC/Server-URL)
|
||||
├── ui/lists/ # ListsScreen/ViewModel (Join-Dialog, Offline-Banner)
|
||||
├── ui/auth/ # AuthScreen (ConnectView: Server-URL + /api/config-Discovery, dann LoginView)
|
||||
├── ui/lists/ # ListsScreen/ViewModel (Join-Dialog, Offline-Banner, Settings-Zahnrad)
|
||||
├── ui/detail/ # ListDetailScreen/ViewModel (Share-Button, Autocomplete)
|
||||
├── ui/settings/ # SettingsScreen/ViewModel (Account, Profil, Theme, Reset, About)
|
||||
└── util/ # NetworkMonitor
|
||||
```
|
||||
|
||||
|
|
@ -215,6 +237,18 @@ Legende: ✅ erledigt · 🚧 in Arbeit · ⬜ offen
|
|||
(Fremde → 404 auf allen Listen-Endpoints), Cross-Member-Sync via op_log,
|
||||
401-Gating aller geschützten Routen. Beide Dateien skippen ohne
|
||||
`TEST_DATABASE_URL` (Docker-Rezept im Dateikopf).
|
||||
- ✅ **Post-MVP – Kritische Android-Fixes (Sync/Build/Data-Safety):** SyncWorker
|
||||
pullt alle getrackten Listen, HLC-Tick pro Server-Op, Room-Transaktionen um
|
||||
Projektion+Outbox, persistente clientId/clientSeq, kein destructive Migration,
|
||||
ProGuard-Rules, Network-Security-Config, Hilt-WorkManager-Init.
|
||||
- ✅ **Post-MVP – Auth-Discovery + OIDC-only:** `GET /api/config` (öffentlich),
|
||||
`AUTH_PASSWORD_ENABLED` (403-Enforcement), `OIDC_GENERIC_DISPLAY_NAME`,
|
||||
App-Connect-Flow (Server-URL → Methoden-Discovery → LoginView).
|
||||
- ✅ **Post-MVP – Settings-Screen + Profil:** `GET/PUT /api/me`
|
||||
(`UserStore.UpdateDisplayName`), `SettingsScreen`/`SettingsViewModel`
|
||||
(Account&Sync, Profil, Theme, Reset, About), Theme-Pref in SessionManager.
|
||||
- ✅ **Post-MVP – Build hinter restriktiven Proxies:** foojay-Resolver &
|
||||
jvmToolchain auskommentiert, Gradle-Wrapper 9.6.1, `.ssl-work/` ignoriert.
|
||||
|
||||
### Wo genau weitermachen?
|
||||
**MVP + Post-MVP-Features sind abgeschlossen.** Das Backend ist feature-complete
|
||||
|
|
@ -229,9 +263,12 @@ für den aktuellen Scope. Offene Punkte, geordnet nach Nutzen:
|
|||
3. **Invite-Code-Optimierung:** Codes sind UUID-Präfixe (`uuid[:8]`), nicht
|
||||
kollisionsresistent geprüft (UNIQUE-Constraint fängt es, aber CreateList kann
|
||||
dann fehlschlagen). Besser: kryptografisches Alphabet ohne Verwechslungsbuchstaben.
|
||||
4. **Echtzeit-Push (langfristig):** Periodic-Pull 15 min ist MVP; SSE/WebSocket
|
||||
4. **Tests für neuere Endpoints:** `GET /api/config`, `GET/PUT /api/me` und das
|
||||
`AUTH_PASSWORD_ENABLED=false`-Verhalten (403) haben noch keine Testabdeckung –
|
||||
das Test-Setup dafür steht in `api_test.go` bereit.
|
||||
5. **Echtzeit-Push (langfristig):** Periodic-Pull 15 min ist MVP; SSE/WebSocket
|
||||
für sofortige Updates wäre der nächste Schritt.
|
||||
5. **Android-Tests:** UI/ViewModel-Tests fehlen fast komplett (nur 2 Stock-Tests).
|
||||
6. **Android-Tests:** UI/ViewModel-Tests fehlen fast komplett (nur 2 Stock-Tests).
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue