docs: restructure domain documentation and update references

Implemented a standardized folder structure for domain documentation to improve clarity and maintainability. Migrated existing files to the new structure, updated links in related documentation, and added README files for navigation and guidance.
This commit is contained in:
2026-01-15 13:44:49 +01:00
parent 7d71ca9a48
commit a454e6c97a
66 changed files with 881 additions and 693 deletions
+39
View File
@@ -0,0 +1,39 @@
# Frontend-Architektur "Meldestelle Portal"
Dieses Verzeichnis dokumentiert die Architektur und die technischen Details des KMP-Frontends "Meldestelle Portal".
## Übersicht
Das Frontend ist eine **Kotlin Multiplatform (KMP)**-Anwendung, die für die folgenden Ziele entwickelt wird:
* **Desktop (JVM):** Eine eigenständige Desktop-Anwendung.
* **Web (JS/Wasm):** Eine moderne Web-Anwendung, die im Browser läuft.
Die Architektur ist auf **Offline-Fähigkeit** und eine reaktive UI ausgelegt.
## Modul-Struktur
Das `frontend`-Verzeichnis ist wie folgt strukturiert, um eine klare Trennung der Verantwortlichkeiten zu gewährleisten:
* `shells/`: Die ausführbaren Anwendungen (Assembler-Module), die die App für eine bestimmte Plattform (Desktop, Web) zusammenbauen.
* `features/`: Vertikale Slices der Anwendung. Jedes Feature-Modul kapselt eine bestimmte Funktionalität (z.B. `auth-feature`, `ping-feature`). Wichtig: Ein Feature-Modul darf niemals von einem anderen Feature-Modul abhängen.
* `core/`: Gemeinsame Basis-Module, die von allen Features genutzt werden. Dazu gehören:
* `design-system/`: Compose-Komponenten, Themes, Farben.
* `domain/`: Fachliche Kernlogik und Datenmodelle des Frontends.
* `local-db/`: SQLDelight-Datenbank-Setup und Queries.
* `navigation/`: Navigations-Logik und Routen-Definitionen.
* `network/`: Ktor-Client und API-Definitionen.
## Kerntechnologien
* **UI:** [Compose Multiplatform](https://www.jetbrains.com/lp/compose-multiplatform/) für eine deklarative, plattformübergreifende UI.
* **Persistenz (Offline-First):** [SQLDelight](https://cashapp.github.io/sqldelight/) für die lokale Speicherung von Daten.
* **State Management:** Kotlin Coroutines und Flow in Kombination mit ViewModels.
* **Dependency Injection:** [Koin](https://insert-koin.io/) für die lose Kopplung von Komponenten.
* **Netzwerk:** [Ktor Client](https://ktor.io/docs/client-introduction.html) für die Kommunikation mit dem Backend.
## Wichtige Dokumente
* **[ADR-0010: SQLDelight für Cross-Platform-Persistenz](../01_Architecture/adr/0010-sqldelight-for-cross-platform-persistence.md):** Beschreibt die Entscheidung für SQLDelight.
* **[ADR-0011: Koin für Dependency Injection](../01_Architecture/adr/0011-koin-for-dependency-injection.md):** Beschreibt die Entscheidung für Koin.
* **[Offline-First-Architektur](offline-first-architecture.md):** Detaillierte Beschreibung der Offline-First-Strategie.
* **[Web-Setup (Webpack & Worker)](web-setup.md):** Details zur Konfiguration des Web-Targets.
@@ -0,0 +1,71 @@
# Offline-First-Architektur
Dieses Dokument beschreibt die **Zielarchitektur** für die Offline-First-Strategie im KMP-Frontend.
---
## Status Quo (Stand: 13.01.2026)
**WICHTIG:** Dieses Dokument beschreibt die **geplante Zielarchitektur**. Die aktuelle Implementierung ist ein erster Schritt in diese Richtung.
* **SQLDelight-Modul (`:frontend:core:local-db`):** Das Modul ist konfiguriert und nutzt `generateAsync = true` für eine asynchrone API.
* **Datenbank-Schema:** Aktuell ist nur eine einfache Tabelle `LocalSettings` implementiert, die zum Speichern von lokalen Schlüssel-Wert-Paaren dient.
* Siehe: `frontend/core/local-db/src/commonMain/sqldelight/at/mocode/frontend/core/localdb/MeldestelleDb.sq`
* **Komplexe Entitäten & Sync:** Die im Folgenden beschriebenen Repositories für Fachdaten, die `Flow`-basierte Datenflüsse und die Delta-Sync-Logik sind **noch nicht implementiert**.
---
## Zielarchitektur
### Grundprinzip
Die Anwendung soll auch ohne eine aktive Netzwerkverbindung voll funktionsfähig sein. Alle Daten, die der Benutzer sieht und bearbeitet, werden in einer lokalen Datenbank auf dem Gerät gespeichert. Die Synchronisation mit dem Backend erfolgt im Hintergrund, sobald eine Netzwerkverbindung verfügbar ist.
**Single Source of Truth (für die UI):** Die lokale SQLDelight-Datenbank ist die alleinige Quelle der Wahrheit für die Benutzeroberfläche. Die UI liest niemals direkt aus dem Netzwerk.
### Komponenten
1. **Lokale Datenbank (SQLDelight):**
* Hält eine Kopie der relevanten Backend-Daten.
* Verwendet plattformspezifische Treiber:
* **Web (JS/Wasm):** `WebWorkerDriver` mit OPFS (Origin Private File System) für persistente Speicherung im Browser.
* **Desktop (JVM):** `JdbcSqliteDriver` für die Speicherung in einer lokalen SQLite-Datei.
* Bietet eine asynchrone API (`suspend`-Funktionen), wie bereits durch `generateAsync` sichergestellt.
2. **Repositories:**
* Kapseln den Zugriff auf die lokale Datenbank.
* Bieten `Flow`-basierte APIs, um die UI über Datenänderungen zu informieren.
* Beispiel: `fun getHorses(): Flow<List<Horse>>`
3. **ViewModels:**
* Sammeln die Daten-Flows von den Repositories und transformieren sie in einen UI-Zustand (`StateFlow`).
* Leiten Benutzerinteraktionen an die entsprechenden Use Cases oder Repositories weiter.
4. **Sync-Logik:**
* Ein separater Mechanismus, der für den Datenabgleich zwischen der lokalen Datenbank und dem Backend verantwortlich ist.
* **Delta-Sync:** Um die Netzwerklast zu minimieren, werden nur die Änderungen seit der letzten Synchronisation übertragen. Dies wird durch die Verwendung von Zeitstempeln oder Versionsnummern (z.B. UUIDv7) in den Datenmodellen ermöglicht.
* **Konfliktlösung:** Bei gleichzeitigen Änderungen auf dem Client und im Backend muss eine Konfliktlösungsstrategie implementiert werden (z.B. "Last-Write-Wins" oder eine manuelle Auflösung durch den Benutzer).
### Datenfluss (Lesen)
1. Die UI (Composable) beobachtet einen `StateFlow` im ViewModel.
2. Das ViewModel sammelt einen `Flow` aus einem Repository.
3. Das Repository fragt die lokale SQLDelight-Datenbank ab und gibt einen `Flow` zurück.
4. Jede Änderung in der lokalen Datenbank wird automatisch an die UI weitergegeben.
### Datenfluss (Schreiben)
1. Der Benutzer löst eine Aktion in der UI aus (z.B. Klick auf "Speichern").
2. Die UI ruft eine Funktion im ViewModel auf.
3. Das ViewModel ruft eine `suspend`-Funktion in einem Repository auf.
4. Das Repository schreibt die Änderung in die lokale SQLDelight-Datenbank.
5. Die Änderung wird (ggf. in einer separaten "outbox"-Tabelle) für die nächste Synchronisation vorgemerkt.
6. Die UI wird durch den Lese-Datenfluss automatisch aktualisiert.
### Synchronisations-Prozess
1. Ein Hintergrund-Job (z.B. ein Coroutine-Worker) wird periodisch oder bei Netzwerkverfügbarkeit gestartet.
2. Der Sync-Worker sendet die vorgemerkten lokalen Änderungen an das Backend.
3. Der Sync-Worker fragt das Backend nach neuen Änderungen seit der letzten Synchronisation ab.
4. Die neuen Daten vom Backend werden in die lokale Datenbank geschrieben.
5. Die UI wird durch den Lese-Datenfluss automatisch aktualisiert.
+34
View File
@@ -0,0 +1,34 @@
# Web-Setup (Webpack & Worker)
Dieses Dokument beschreibt die spezifische Konfiguration für das Web-Target (JS/Wasm) des KMP-Frontends.
## OPFS (Origin Private File System)
Um eine performante und persistente Speicherung der SQLDelight-Datenbank im Browser zu ermöglichen, verwenden wir das **Origin Private File System (OPFS)**. Die Nutzung von OPFS erfordert, dass die Webseite in einem "cross-origin isolated"-Kontext läuft.
### HTTP-Header
Dazu müssen die folgenden HTTP-Header vom Webserver ausgeliefert werden:
* `Cross-Origin-Opener-Policy: same-origin`
* `Cross-Origin-Embedder-Policy: require-corp`
### Webpack Dev Server
Für die lokale Entwicklung wird der Webpack Dev Server verwendet. Um die erforderlichen Header zu setzen, wurde die `webpack.config.d/opfs-headers.js`-Datei erstellt, die die Header zur Konfiguration des Dev Servers hinzufügt.
## Web Worker für SQLDelight
Um die UI nicht zu blockieren, werden alle Datenbank-Operationen in einem separaten **Web Worker** ausgeführt.
* **`sqlite.worker.js`:** Ein benutzerdefinierter Worker, der die SQLDelight-Datenbank initialisiert und die Anfragen vom Haupt-Thread entgegennimmt.
* **`WebWorkerDriver`:** Der SQLDelight-Treiber, der die Kommunikation zwischen dem Haupt-Thread und dem Worker-Thread managed.
## Build-Konfiguration
* **`build.gradle.kts`:** Im `build.gradle.kts` des `meldestelle-portal`-Moduls wird das `wasmJs` oder `js` Target entsprechend konfiguriert, um die Web-Anwendung zu bauen.
* **Webpack-Integration:** Die Gradle-Plugins für KMP/JS und Compose for Web kümmern sich um die Integration mit Webpack und die Erstellung des finalen JavaScript-Bundles.
## Aktueller Blocker (Januar 2026)
Derzeit ist der Build für das `wasmJs`-Target aufgrund von Compiler-Fehlern im Zusammenhang mit dem JS-Interop und fehlenden DOM-API-Referenzen blockiert. Die Behebung dieses Problems hat höchste Priorität.