docs: add session log for Keycloak fixes and role-based dashboard POC
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 8m0s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 7m17s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Successful in 4m7s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m48s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 8m0s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 7m17s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Successful in 4m7s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m48s
- Logged details of the session addressing compiler warnings and roles in the dashboard POC under `docs/99_Journal/2026-03-19_Session_Log_POC_Rollen_Keycloak.md`. - Documented Keycloak realm import challenges and resolution strategy for PostgreSQL volume reset. - Verified JWT role extraction and dashboard routing logic for ADMIN and ORGANIZER roles. - Included session outcomes and next steps for further validation and testing of the POC setup. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
# Session Log: 19.03.2026 - POC Rollen-basiertes Dashboard & Keycloak-Fix
|
||||
|
||||
**Teilnehmer:** Owner, 🏗️ [Lead Architect], 🎨 [Frontend Expert], 🧹 [Curator]
|
||||
|
||||
---
|
||||
|
||||
## Ziel der Session
|
||||
|
||||
Übernahme und Weiterführung eines POC, der zuvor mit Gemini begonnen wurde. Ziel war es, die rollenbasierte
|
||||
Dashboard-Trennung (Admin vs. Veranstalter) sowohl in der Web-App als auch in der Desktop-App zum Laufen zu bringen.
|
||||
|
||||
---
|
||||
|
||||
## Ausgangslage (aus Gemini-Chat-Verlauf übernommen)
|
||||
|
||||
Der vorherige Chat-Verlauf (`docs/Neumarkt2026/Chat-Verlauf-Gemini_2026-03-19_16-30.txt`) wurde analysiert.
|
||||
Folgende Punkte waren bereits implementiert, aber noch nicht vollständig verifiziert:
|
||||
|
||||
- `LoginScreen.kt`: Tab-Navigation, `singleLine = true` für Enter/Tab-Behandlung
|
||||
- `PlatformType`: `expect/actual`-Mechanismus (`currentPlatform()`) für `WEB` vs. `DESKTOP`
|
||||
- `AppScreen.kt`: `Login` als `data class Login(val returnTo: AppScreen? = null)`
|
||||
- `MainApp.kt`: 4-Wege-Weiche für rollenbasiertes Routing
|
||||
- `AuthTokenManager.kt`: Extraktion von `realm_access.roles` aus JWT, `isAdmin()` und `isOrganizer()`
|
||||
- `meldestelle-realm.json`: Rolle `ORGANIZER`, Test-User `urfv_neumarkt` (Passwort: `Turnier#2026`)
|
||||
|
||||
---
|
||||
|
||||
## Durchgeführte Fixes
|
||||
|
||||
### Fix 1 – Compiler-Warnung behoben (`AuthTokenManager.kt`)
|
||||
|
||||
**Problem:** `Json { ignoreUnknownKeys = true }` wurde als Instanz-Variable deklariert → bei jeder Instanz neu erstellt.
|
||||
|
||||
**Warnung:**
|
||||
|
||||
```
|
||||
w: Redundant creation of Json format. Creating instances for each usage can be slow.
|
||||
```
|
||||
|
||||
**Lösung:** `jsonParser` in ein `companion object` verschoben → wird nur einmal pro Klasse erstellt.
|
||||
|
||||
```kotlin
|
||||
companion object {
|
||||
// Shared Json instance – einmalig erstellt, nicht bei jedem Aufruf
|
||||
private val jsonParser = Json { ignoreUnknownKeys = true }
|
||||
}
|
||||
```
|
||||
|
||||
### Fix 2 – Web-Sicht nach Rollen aufgeteilt (`MainApp.kt`)
|
||||
|
||||
Die 4-Wege-Weiche in `DashboardScreen` war bereits korrekt implementiert:
|
||||
|
||||
| Platform | Rolle | Dashboard |
|
||||
|----------|-------------|----------------------------------------------------------------------|
|
||||
| Desktop | `ADMIN` | Steuerungszentrale (alle Turniere, Filter, Toggles) |
|
||||
| Desktop | `ORGANIZER` | Meldestellen-Software (Turnier initialisieren) |
|
||||
| Web | `ADMIN` | Admin-Web-Portal + Download "Master-Desktop-App" |
|
||||
| Web | `ORGANIZER` | Veranstalter-Portal + Download "Meldestelle-App" + Aktivierungs-Code |
|
||||
|
||||
### Fix 3 – Keycloak-Config verifiziert (`meldestelle-realm.json`)
|
||||
|
||||
- Rolle `ORGANIZER` vorhanden ✅
|
||||
- User `urfv_neumarkt` mit Rollen `USER` + `ORGANIZER` korrekt konfiguriert ✅
|
||||
- User `admin` mit Rolle `ADMIN` korrekt konfiguriert ✅
|
||||
|
||||
---
|
||||
|
||||
## Problem: Beide User sahen dasselbe Dashboard
|
||||
|
||||
**Symptom:** Nach dem Login als `admin` und als `urfv_neumarkt` wurde immer dasselbe Dashboard angezeigt.
|
||||
|
||||
**Ursache:** Keycloak startet mit `--import-realm` und speichert alle Daten in **PostgreSQL** (`postgres-data` Volume).
|
||||
Der Realm wird **nur beim allerersten Start** importiert, wenn er noch nicht in der Datenbank existiert.
|
||||
Alle späteren Änderungen an der `meldestelle-realm.json` werden **ignoriert**, solange das PostgreSQL-Volume existiert.
|
||||
|
||||
→ Die Rollen `ADMIN` und `ORGANIZER` waren nie in Keycloak angekommen, weil das Volume noch den alten Stand enthielt.
|
||||
|
||||
---
|
||||
|
||||
## Lösung: PostgreSQL-Volume zurücksetzen
|
||||
|
||||
```bash
|
||||
# Schritt 1 – Alle Container stoppen
|
||||
docker compose down
|
||||
|
||||
# Schritt 2 – PostgreSQL-Volume löschen (⚠️ alle DB-Daten gehen verloren – für POC OK)
|
||||
docker volume rm meldestelle_postgres-data
|
||||
|
||||
# Schritt 3 – Container neu starten (Keycloak importiert Realm frisch)
|
||||
docker compose --profile infra up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verifikation nach dem Neustart
|
||||
|
||||
Nach dem Neustart muss das JWT-Token die korrekten Rollen enthalten.
|
||||
Prüfung via [jwt.io](https://jwt.io) oder Browser-DevTools → Network-Tab → Token-Request:
|
||||
|
||||
**Für `admin`:**
|
||||
|
||||
```json
|
||||
"realm_access": {
|
||||
"roles": ["ADMIN", "USER", "MELD_USER", ...]
|
||||
}
|
||||
```
|
||||
|
||||
**Für `urfv_neumarkt`:**
|
||||
|
||||
```json
|
||||
"realm_access": {
|
||||
"roles": ["USER", "ORGANIZER"]
|
||||
}
|
||||
```
|
||||
|
||||
Sobald die Rollen korrekt im JWT sind, funktioniert die Dashboard-Weiche in `DashboardScreen` automatisch.
|
||||
|
||||
---
|
||||
|
||||
## Aktualisierte Dateien
|
||||
|
||||
| Datei | Änderung |
|
||||
|-----------------------------------------------------------------------|--------------------------------------------------------------------------|
|
||||
| `frontend/core/auth/src/commonMain/kotlin/.../AuthTokenManager.kt` | `jsonParser` in `companion object` verschoben (Compiler-Warnung behoben) |
|
||||
| `config/docker/keycloak/meldestelle-realm.json` | Verifiziert – keine Änderungen notwendig |
|
||||
| `frontend/shells/meldestelle-portal/src/commonMain/kotlin/MainApp.kt` | Verifiziert – 4-Wege-Weiche korrekt implementiert |
|
||||
|
||||
---
|
||||
|
||||
## Offene Punkte / Nächste Schritte
|
||||
|
||||
- [ ] PostgreSQL-Volume zurücksetzen und Keycloak neu starten (muss vom Owner manuell durchgeführt werden)
|
||||
- [ ] JWT-Token nach Neustart verifizieren (jwt.io)
|
||||
- [ ] End-to-End-Test: Login als `admin` → Admin-Dashboard, Login als `urfv_neumarkt` → Veranstalter-Dashboard
|
||||
Reference in New Issue
Block a user