Replaces the Phase-0 fakeReply mock with the real v1 API. Deployment-agnostic: one binary, one Authorization: Bearer contract, server-URL field switches between the official instance and any self-host. - auth/LoginScreen: server-URL + email + password -> POST /api/v1/auth/token - net/SecureStore: kzn_ token in EncryptedSharedPreferences (KeyStore AES-256-GCM) - net/SessionViewModel: snapshot-state login/logout routing, restores on launch - net/KaizenApi: POST /api/v1/chat streaming + GET /api/v1/me for the default model - net/StreamConsumer: Kotlin port of lib/chat/stream-consumer.ts (JVM-unit-tested) - deps: okhttp, kotlinx-serialization, security-crypto; INTERNET permission Code-complete; not yet built/run on device (no Android SDK on the dev Mac).
2.3 KiB
Kaizen — Android
Native Android-App für Kaizen (Jetpack Compose + Kotlin). Kein WebView, kein Tauri.
Phase 1 — echtes Backend (aktiv)
Der Feel-Prototyp redet jetzt mit dem echten Kaizen-Backend — echte, gestreamte
Antworten statt fakeReply. Die App ist deployment-agnostisch: ein Binary, das auf
die offizielle Instanz ODER jeden Self-Host zeigt, über einen einheitlichen
Authorization: Bearer-Contract. SaaS vs. Self-Host ist nur „welche Base-URL".
Drin:
- In-App-Login (
auth/LoginScreen.kt): Server-URL (Default = offizielle Instanz, editierbar = die „offiziell/Self-Host"-Adresse) + E-Mail + Passwort →POST {baseUrl}/api/v1/auth/token→kzn_-Token. Kein Token-Copy-Paste. - Sichere Token-Ablage (
net/SecureStore.kt):EncryptedSharedPreferences(AES-256-GCM, Schlüssel im Android-KeyStore/StrongBox) — der Token liegt nie im Klartext, auch nicht auf gerooteten Geräten. - Modell vom Server (
net/SessionViewModel.kt): nach dem Login holt die App perGET /api/v1/medas vom Nutzer unter/settings/modelsgewählte Default-Modell — kein hartgecodetes Modell. - Echtes Streaming (
net/KaizenApi.kt+net/StreamConsumer.kt):POST /api/v1/chat, liest dentext/plain-Chunked-Stream inkrementell und strippt die Sentinels (Port vonlib/chat/stream-consumer.tsaus dem Backend, JVM-unit-getestet). - Design + Haptik + Orb unverändert — nur die Datenquelle hat sich geändert.
Bewusst noch nicht drin (siehe LATER.md): Conversation-History vom Server,
Passkey-Login nativ, Bild/Video, Biometric-Lock, WebSocket-Streaming.
Bauen & laufen
Wichtig: Auf dem echten S25 Ultra laufen lassen, nicht im Emulator — der Emulator kann keine echte Haptik, und genau die wollen wir fühlen.
- Projekt in Android Studio öffnen, Gradle syncen (neue Deps: OkHttp, kotlinx-serialization, security-crypto + INTERNET-Permission).
- S25 Ultra per Wireless Debugging oder USB verbinden.
- Run ▶ auf das Gerät → Login-Screen erscheint. Server-URL prüfen, einloggen.
DEFAULT_BASE_URL (net/ServerConfig.kt) ist die vorausgefüllte Instanz-Adresse —
bei Domainwechsel hier anpassen.
Der Test
Eine Woche nutzen. Geht der Finger anfangen hierher statt zu Gemini → wir bauen voll aus (History, Passkey, Medien = Phase 2). Wenn nicht → wir wissen billig, woran's liegt.