diff --git a/backend/infrastructure/gateway/src/main/resources/application.yml b/backend/infrastructure/gateway/src/main/resources/application.yml index 595caa73..718756dc 100644 --- a/backend/infrastructure/gateway/src/main/resources/application.yml +++ b/backend/infrastructure/gateway/src/main/resources/application.yml @@ -101,6 +101,31 @@ spring: filters: - StripPrefix=1 + # ============================================================== + # --- Entries-Service-Integration (MP-27) --- + # ============================================================== + - id: entries-service-route + uri: lb://entries-service + predicates: + - Path=/api/entries/** + filters: + - StripPrefix=1 + + # Mappe das Root "/api/entries" explizit auf die Service-Root "/" + - id: entries-service-root + uri: lb://entries-service + predicates: + - Path=/api/entries + filters: + - SetPath=/ + + - id: entries-service-root-slash + uri: lb://entries-service + predicates: + - Path=/api/entries/ + filters: + - SetPath=/ + # ============================================================== # --- Members-Service-Integration (optional) --- # ============================================================== diff --git a/docs/clients/visionen/MP-20.md b/docs/clients/visionen/MP-20.md new file mode 100644 index 00000000..c4285a34 --- /dev/null +++ b/docs/clients/visionen/MP-20.md @@ -0,0 +1,188 @@ +## Frontend-Architektur + +# Frontend-Architektur + +**Architektur-Stil:** Feature-First, Clean Architecture, Kotlin Multiplatform (KMP) + +## 1. Management Summary + +Das Frontend wird als **modulare Kotlin Multiplatform (KMP) Anwendung** entwickelt. Ziel ist eine strikte Trennung von +technischer Basis (`shared`) und fachlichen Funktionen (`features`). Die Architektur ist **"Offline-Ready"** konzipiert: +Durch die konsequente Nutzung des Repository-Patterns kann die Datenquelle später transparent von "Online-Only" (API) +auf "Local-First" (Datenbank + Sync) umgestellt werden, ohne die Benutzeroberfläche (UI) anpassen zu müssen. + +## 2. Die Modul-Struktur (Gradle) + +Die Anwendung ist nicht monolithisch, sondern in fachliche Module geschnitten ("Feature-First"). + +- **`:clients:app` (Der Container)** + +- **Rolle:** Der Einstiegspunkt ("Main"). + +- **Aufgabe:** + +Initialisierung von Koin (Dependency Injection). + +Globales Theming (Material3). + +High-Level Navigation (Routing zwischen Features). + +Verbindet alle Feature-Module. + +- **`:clients:shared` (Das Fundament)** + +- **Rolle:** Die gemeinsame Bibliothek für alle Features. + +- **Inhalt:** + +**DI (Dependency Injection):** Zentrale Koin-Module (NetworkModule, CoreModule). + +**Network:** Konfigurierter HttpClient (Singleton). + +**Domain Core:** Basis-Modelle (Resource, ApiError, User). + +**UI Kit:** Gemeinsame Komponenten (LoadingSpinner, ErrorView), Typography, Colors. + +- **Regel:** Hier liegt keine Fachlogik eines spezifischen Features (keine Pferdedaten, keine Nennungen). + +- **`:clients:*-feature` (Die Fachlichkeit)** + +- **Beispiele:** `:clients:auth-feature`, `:clients:registry-feature`, `:clients:events-feature`. + +- **Rolle:** Kapselt einen kompletten fachlichen Bereich. + +- **Inhalt:** Eigene Screens, ViewModels und spezifische Use-Cases. + +## 3. Die Schichten-Architektur (Innerhalb eines Moduls) + +Jedes Modul (besonders `shared` und die Features) folgt einer strikten 3-Schichten-Architektur. Das garantiert +Testbarkeit und Austauschbarkeit. + +### 1️⃣ Presentation Layer (UI) + +- **Technologie:** Compose Multiplatform. + +- **Komponenten:** `Screen` (Composable Functions) und `ViewModel` (State-Holder). + +- **Verantwortung:** + +Zeigt Daten an (Reagiert auf State). + +Nimmt User-Input entgegen. + +**Weiß NICHT**, woher die Daten kommen (Netzwerk oder DB). + +Nutzt Repositories via Koin Injection (`koinInject()`). + +### 2️⃣ Domain Layer (Die Logik) + +- **Komponenten:** `Repository Interface`, `Models`. + +- **Verantwortung:** + +Definiert **WAS** getan werden kann (z.B. `checkSystemStatus()`). + +Ist komplett unabhängig von Frameworks (reines Kotlin). + +Nutzt `Resource` Wrapper (`Success`, `Error`, `Loading`) für den State-Transport. + +### 3️⃣ Data Layer (Die Umsetzung) + +- **Komponenten:** `Repository Implementation`, `API-DTOs`, `Database-Entities`. + +- **Verantwortung:** + +Entscheidet **WIE** Daten geholt werden. + +**Aktuell (Online):** Ruft Ktor Client auf. + +**Zukunft (Offline/LAN):** Prüft lokale SQLite DB, synchronisiert im Hintergrund. + +Mappt rohe API-Daten (DTOs) in saubere Domain-Modelle. + +### 4. Technische Kern-Konzepte + +**💉 Dependency Injection (Koin)** + +Wir nutzen Koin als "Klebstoff". + +- Module exportieren ihre Funktionalität via `val myModule = module { single { ... } }`. + +- Die `clients:app` sammelt alle Module ein und startet den Container. + +- **Vorteil:** Repositories und der HTTP-Client müssen nicht manuell herumgereicht werden. + +**🌐 Networking (Ktor)** + +Ein zentraler `HttpClient` im `NetworkModule` (`clients:shared`). + +- Konfiguriert mit JSON-Serialization. + +- Zentrale Base-URL Steuerung (via `AppConfig` umschaltbar für LAN/Dev/Prod). + +- Timeout- und Logging-Handling an einer Stelle. + +**🔄 Datenfluss (Unidirectional Data Flow)** + +1. **UI:** Trigger Event (Button Click). + +2. **ViewModel/Scope:** Ruft Repository auf (`launch { repo.getData() }`). + +3. **Repository:** Liefert `Resource.Loading` -> `Resource.Success(data)`. + +4. **UI:** Rendert den neuen State. + +### 5. Strategie für Offline & LAN-Fähigkeit (Zukunft) + +Die aktuelle Architektur ist **vorbereitet** für die Offline-Anforderungen der großen Turniere. + +**Die Transition (Schritt-für-Schritt):** + +1. **Phase 1 (Jetzt):** PingRepositoryImpl ruft direkt httpClient.get() auf. + +2. **Phase 2 (Offline):** + +Wir fügen **SQLDelight** (lokale DB) hinzu. + +Die `PingRepositoryImpl` wird geändert (ohne dass die UI es merkt!): + +```Kotlin + +fun getData() { + + val localData = db.dao.getAll() + + if (localData.isEmpty()) { + + val remote = api.getAll() + + db.dao.insert(remote) + + return remote + + } + + return localData + +} + +``` + +3. **Phase 3 (Sync):** Ein Hintergrund-Worker (`WorkManager` oder `Coroutine`) synchronisiert lokale Änderungen mit dem + Server, sobald das LAN verfügbar ist. + +### 6. Zusammenfassung für Entwickler + +Wenn du ein neues Feature (z.B. "Pferde anzeigen") baust: + +1. **Domain:** Erstelle Horse Model und HorseRepository Interface. + +2. **Data:** Erstelle HorseRepositoryImpl. Injiziere den HttpClient. + +3. **DI:** Registriere das Repository im Koin-Modul. + +4. **UI:** Erstelle HorseListScreen. Injiziere das Repository. + +5. Fertig. + +Diese Struktur ist sauber, skalierbar und bereit für den professionellen Einsatz beim OEPS. ✅ diff --git a/docs/clients/visionen/MP-21.md b/docs/clients/visionen/MP-21.md new file mode 100644 index 00000000..43ccfe3c --- /dev/null +++ b/docs/clients/visionen/MP-21.md @@ -0,0 +1,14 @@ +## Epic 1: Big‑Bang vorbereiten – Snapshot und Branching + +* Zusammenfassung: Snapshot des aktuellen Zustands, Tag setzen, Big‑Bang‑Branch erstellen +* Beschreibung: + * Ziel: Den aktuellen Projektstand einfrieren, um die anschließende große Umstrukturierung nachvollziehbar zu machen. + * Schritte: + 1. PR „chore: snapshot pre‑refactor state“ auf `main` erstellen und mergen. + 2. Git‑Tag `v0-pre-refactor` setzen. + 3. Branch `refactor/big-bang-architecture` anlegen und als Arbeitsbasis verwenden. + * Artefakte: + * PR‑Link, Tag‑Nachweis. +* Definition of Done (DoD): + * PR gemergt, Tag `v0-pre-refactor` existiert (git log / remote tags sichtbar). + * Branch `refactor/big-bang-architecture` öffentlich verfügbar. diff --git a/docs/clients/visionen/MP-22.md b/docs/clients/visionen/MP-22.md new file mode 100644 index 00000000..5d725d89 --- /dev/null +++ b/docs/clients/visionen/MP-22.md @@ -0,0 +1,27 @@ +## Epic 2: Repository‑Struktur auf Meldestellen‑Domäne umstellen + +* Zusammenfassung: Neues Skeleton und physisches Umziehen der Module/Ordner +* Beschreibung: + * Ziel: Einführen der Zielstruktur gemäß Domäne (Meldestelle, ÖTO/FEI) für Frontend, Backend und Docker. + * Soll‑Struktur (Top‑Level): + * `frontend/` (shells, features, core) + * `backend/` (gateway, discovery, services) + * `docker/` (docker-compose.yml, .env.example) + * `docs/` (adr, ARCHITECTURE.md) + * Geplanter Umzug: + * Frontend: + * `clients/app` → `frontend/shells/meldestelle-portal` + * `clients/shared/common-ui` → `frontend/core/design-system` + * `clients/shared/navigation` → `frontend/core/navigation` + * Backend: + * `services|domains|infrastructure|platform|core` → konsolidieren unter `backend/`: + * `backend/services/*` + * `backend/gateway`, `backend/discovery` + * Docker: + * `compose.yaml` → `docker/docker-compose.yml` + * Pro Service ein eigener `Dockerfile` im jeweiligen Service‑Ordner +* Definition of Done (DoD): + * Verzeichnis‑Skeleton vorhanden und committed. + * Dateien physisch verschoben; alle relativen Pfade in Gradle/Konfigurationen angepasst (oder bekannte Fehlerliste + dokumentiert). + * `docker/docker-compose.yml` vorhanden; `.env.example` erstellt. diff --git a/docs/clients/visionen/MP-23.md b/docs/clients/visionen/MP-23.md new file mode 100644 index 00000000..20d671b4 --- /dev/null +++ b/docs/clients/visionen/MP-23.md @@ -0,0 +1,14 @@ +## Epic 3: Gradle/Build Governance zentralisieren + +* Zusammenfassung: Version Catalog, Settings, Build‑Konventionen +* Beschreibung: + * Ziel: Einheitliche Build‑Basis für alle Module (KMP/JVM), zentrale Versionierung und klare Projekt‑Includes. + * Schritte: + 1. `gradle/libs.versions.toml` als Single Source of Truth etablieren. + 2. `settings.gradle.kts` an neue Struktur anpassen (Includes für Frontend‑Core, ‑Features, ‑Shells; + Backend‑Services). + 3. Build‑Konventionen konsolidieren (`buildSrc` oder `gradle/plugins`): Kotlin, Compose, Detekt, KTLint. +* Definition of Done (DoD): + * `./gradlew projects` zeigt die neue Modul‑Hierarchie ohne verwaiste Einträge. + * Alle Subprojekte beziehen Versionen aus `libs.versions.toml` (keine harten Versionsnummern in Buildskripten). + * Lint/Detekt laufen in CI lokal erfolgreich. diff --git a/docs/clients/visionen/MP-24.md b/docs/clients/visionen/MP-24.md new file mode 100644 index 00000000..a05b55f7 --- /dev/null +++ b/docs/clients/visionen/MP-24.md @@ -0,0 +1,21 @@ +## Epic 4: Frontend Core etablieren (Network, Local‑DB, Design‑System, Domain) + +* Zusammenfassung: Koin/Ktor‑Client, SQLDelight, Design‑System‑Konsolidierung, Shared Domain Models +* Beschreibung: + * Ziel: Eine stabile, wiederverwendbare Basis für alle Features/Shells schaffen. + * Deliverables: + * `frontend/core/network`: + * Ktor `HttpClient` mit Plugins: Auth, Retry, JSON, Timeouts, Logging. + * Koin‑Module mit `single(named("apiClient"))` Export. + * `frontend/core/local-db`: + * SQLDelight‑Setup (KMP), Schema‑Ordner, `1.sqm` Migration, Build‑Konfig. + * Konvention: Keine Inline‑SQL in Business‑Code; Nutzung der generierten Queries. + * `frontend/core/design-system`: + * Konsolidierte `AppTheme`, Komponenten, Tokens. + * `frontend/core/domain`: + * Gemeinsame Modelle/IDs (z. B. `Turnier`, `Pruefung`, `Start`, `ReiterId`, `PferdId`, `Lizenz` …). +* Definition of Done (DoD): + * Kein Vorkommen manueller `Authorization`‑Header im Code (nur DI‑`apiClient`). + * SQLDelight generiert Code; eine Demo‑Query kompiliert für das Web‑Target. + * Design‑System kompiliert; `AppTheme` nutzbar in Shell/Feature‑Sample. + * `core/domain` wird von Features konsumiert, ohne Feature→Feature Abhängigkeiten. diff --git a/docs/clients/visionen/MP-25.md b/docs/clients/visionen/MP-25.md new file mode 100644 index 00000000..aabc7af6 --- /dev/null +++ b/docs/clients/visionen/MP-25.md @@ -0,0 +1,17 @@ +## Epic 5: Feature‑Pilot – Nennungs‑Management (Vertical Slice) + +- Zusammenfassung: Erstes Feature in Zielstruktur mit Route, UI, Data, Domain, DI +- Beschreibung: + - Ziel: Funktionsfähiger, isolierter Slice für Nennungen (Turnier‑bezogen), inkl. Offline/Sync‑Pfad. + - Struktur: `frontend/features/nennungs-management/{api,ui,data,domain,di}` + - Funktionen (Minimum): + - Liste Nennungen für `turnierId` anzeigen (UI liest aus Local‑DB; initialer Sync). + - Anlegen/Ändern einer Nennung lokal; Sync zum Server. + - Konfliktpfad: Bei veralteter `version` → Server 409; UI Toast + automatischer Refresh. + - Navigation/Route: + - `meldestelle/nennungen/turnier/{turnierId}` als EntryPoint. +- Definition of Done (DoD): + - Shell `meldestelle-portal` kann Route aufrufen; UI rendert Daten aus Local‑DB. + - API‑Call nutzt DI‑`apiClient`. + - `lastSyncedAt` steuert Freshness‑Indikator (grün/gelb/rot) im UI. + - Konfliktfall 409 nachweisbar (Mock/Backend) und UI reagiert gemäß Guideline. diff --git a/docs/clients/visionen/MP-26.md b/docs/clients/visionen/MP-26.md new file mode 100644 index 00000000..35036374 --- /dev/null +++ b/docs/clients/visionen/MP-26.md @@ -0,0 +1,13 @@ +## Epic 6: Shell – Meldestelle‑Portal (JS/Wasm) + +- Zusammenfassung: Exekutierbare Web‑Shell mit expliziten Feature‑Dependencies +- Beschreibung: + - Ziel: Eine Shell, die nur benötigte Features bundelt (Tree‑Shaking wirksam) und die Navigation kapselt. + - Schritte: + 1. Entry Point/Bootstrap der Shell anlegen (`frontend/shells/meldestelle-portal`). + 2. Nur benötigte Features als Gradle‑Dependencies einbinden (Pilot: `nennungs-management`). + 3. Bundle‑Report aktivieren; Code‑Splitting konfigurieren. +- Definition of Done (DoD): + - `./gradlew :frontend:shells:meldestelle-portal:build` erfolgreich. + - Bundle‑Report zeigt, dass ausschließlich integrierte Features im Output sind. + - Navigation aus der Shell zu Feature‑Routen funktioniert. diff --git a/docs/clients/visionen/MP-27.md b/docs/clients/visionen/MP-27.md new file mode 100644 index 00000000..81963aeb --- /dev/null +++ b/docs/clients/visionen/MP-27.md @@ -0,0 +1,18 @@ +## Epic 7: Backend‑Konsolidierung – Services & Gateway + +- Zusammenfassung: Services domänenspezifisch schneiden, Gateway verankern, Compose lauffähig +- Beschreibung: + - Ziel: Minimales, aber kohärentes Backend gemäß Zielstruktur – startfähig via Docker Compose. + - Services (erste Iteration): + - `entries-service` (Nennungen/Validierung), + - `results-service` (Ergebnisse), + - `scheduling-service` (Zeit/Abteilungen), + - plus `gateway` (Auth/Routing). + - Anforderungen: + - Pro Service eigener `Dockerfile` im Service‑Ordner. + - Mindestens ein Endpunkt pro Service (Stub akzeptabel), 409‑Konfliktpfad im `entries-service`. + - Compose: DB + Gateway + `entries-service` startbar. +- Definition of Done (DoD): + - `docker/docker-compose.yml` gestartet → Services erreichbar (Health/HTTP 200/Stub‑Daten). + - Endpoint für 409‑Konflikt getestet (z. B. Postman/HTTP‑Test dokumentiert). + - Gateway leitet Requests korrekt weiter. diff --git a/docs/clients/visionen/MP-28.md b/docs/clients/visionen/MP-28.md new file mode 100644 index 00000000..d8d8bce3 --- /dev/null +++ b/docs/clients/visionen/MP-28.md @@ -0,0 +1,12 @@ +## Epic 8: Architektur‑Guards und CI – Regeln durchsetzen + +- Zusammenfassung: Detekt/KTLint Regeln, Dependency Checks, Bundle Budgets +- Beschreibung: + - Ziel: Die Architekturregeln technisch erzwingen, um Regressionen zu vermeiden. + - Guards: + - Verbot Feature→Feature Dependencies (nur → `frontend/core:*`). + - Verbot manueller `Authorization`‑Header im Code (nur DI‑`apiClient`). + - CI: Dependency‑Graph‑Diff, Bundle‑Size‑Budget je Shell, `docker compose config` Validierung. +- Definition of Done (DoD): + - CI bricht bei Verstößen, Berichte werden erzeugt. + - Auf `main` grüner Build mit aktiven Guards. diff --git a/docs/clients/visionen/MP-29.md b/docs/clients/visionen/MP-29.md new file mode 100644 index 00000000..838ddfc4 --- /dev/null +++ b/docs/clients/visionen/MP-29.md @@ -0,0 +1,13 @@ +## Epic 9: Dokumentation & ADRs formalisieren + +- Zusammenfassung: ADR‑Template, Entscheidungen festschreiben, Architecture Guide aktualisieren +- Beschreibung: + - Ziel: Entscheidungen nachvollziehbar machen und Onboarding erleichtern. + - Schritte: + 1. ADR‑Template `docs/adr/ADR-000-template.md` anlegen. + 2. ADRs erstellen für: Koin, SQLDelight, Optimistic Locking, Freshness‑UI, Core‑Domain, Feature‑Isolation über + Routen. + 3. `docs/ARCHITECTURE.md`: Mapping Vision ↔ Repo, Rollen, Routenbeispiele (Meldestelle, Richter, Zeitnahme). +- Definition of Done (DoD): + - Mindestens 5 ADRs vorhanden und verlinkt. + - `ARCHITECTURE.md` erlaubt Onboarding in < 30 Minuten (interner Review bestanden). diff --git a/docs/clients/visionen/MP-30.md b/docs/clients/visionen/MP-30.md new file mode 100644 index 00000000..40970825 --- /dev/null +++ b/docs/clients/visionen/MP-30.md @@ -0,0 +1,6 @@ +## Ergänzende Hinweise (Optionen) + +- Labels/Tags: `architecture`, `big-bang`, `frontend`, `backend`, `docker`, `docs`. +- Priorisierung: 1 → 9 in ungefährer Reihenfolge, wobei 2–4 parallelisierbar sind. +- Zeitbox für Epics definieren (z. B. 1–2 Wochen je Epic in früher Phase) und nach jedem Epic Zwischenrelease (Tag) + setzen.