diff --git a/backend/infrastructure/gateway/Dockerfile b/backend/infrastructure/gateway/Dockerfile index ca6a8bf8..ab8dc958 100644 --- a/backend/infrastructure/gateway/Dockerfile +++ b/backend/infrastructure/gateway/Dockerfile @@ -5,15 +5,16 @@ # =================================================================== # === CENTRALIZED BUILD ARGUMENTS === -ARG GRADLE_VERSION=9.3.1 -ARG JAVA_VERSION=25 +# HINWEIS: gradle:X.Y-jdkZ-alpine Images existieren nicht für alle Gradle/JDK-Kombinationen. +# Wir verwenden eclipse-temurin als Builder-Basis und das Projekt-eigene ./gradlew-Wrapper. +ARG JAVA_VERSION=21 ARG BUILD_DATE ARG VERSION # =================================================================== # Build Stage # =================================================================== -FROM gradle:${GRADLE_VERSION}-jdk${JAVA_VERSION}-alpine AS builder +FROM eclipse-temurin:${JAVA_VERSION}-jdk-alpine AS builder ARG VERSION ARG BUILD_DATE @@ -32,8 +33,7 @@ ENV GRADLE_OPTS="-Dorg.gradle.caching=true \ -Dorg.gradle.jvmargs=-Xmx2g \ -XX:+UseParallelGC \ -XX:MaxMetaspaceSize=512m" - -ENV GRADLE_USER_HOME=/home/gradle/.gradle +ENV GRADLE_USER_HOME=/root/.gradle # Copy gradle wrapper and configuration files COPY gradlew gradlew.bat gradle.properties settings.gradle.kts ./ @@ -60,25 +60,32 @@ RUN mkdir -p \ frontend/core/network \ frontend/core/local-db \ frontend/core/sync \ - frontend/features/ping-feature \ - frontend/features/nennung-feature \ frontend/shared \ frontend/shells/meldestelle-portal \ frontend/shells/meldestelle-desktop \ + frontend/features/ping-feature \ + frontend/features/nennung-feature \ frontend/features/zns-import-feature \ + frontend/features/billing-feature \ + frontend/features/pferde-feature \ + frontend/features/verein-feature \ + frontend/features/veranstaltung-feature \ + frontend/features/veranstalter-feature \ + frontend/features/profile-feature \ + frontend/features/reiter-feature \ + frontend/features/turnier-feature \ docs # Copy root build configuration COPY build.gradle.kts ./ # Download and cache dependencies -RUN --mount=type=cache,id=gradle-cache-gateway,target=/home/gradle/.gradle/caches \ - --mount=type=cache,id=gradle-wrapper-gateway,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-gateway,target=/root/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-gateway,target=/root/.gradle/wrapper \ ./gradlew :backend:infrastructure:gateway:dependencies --info - # Build the application -RUN --mount=type=cache,id=gradle-cache-gateway,target=/home/gradle/.gradle/caches \ - --mount=type=cache,id=gradle-wrapper-gateway,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-gateway,target=/root/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-gateway,target=/root/.gradle/wrapper \ ./gradlew :backend:infrastructure:gateway:bootJar --info # Extract JAR layers diff --git a/backend/services/ping/Dockerfile b/backend/services/ping/Dockerfile index cc5fdb49..5d16e58f 100644 --- a/backend/services/ping/Dockerfile +++ b/backend/services/ping/Dockerfile @@ -5,15 +5,16 @@ # =================================================================== # === CENTRALIZED BUILD ARGUMENTS === -ARG GRADLE_VERSION=9.3.1 -ARG JAVA_VERSION=25 +# HINWEIS: gradle:X.Y-jdkZ-alpine Images existieren nicht für alle Gradle/JDK-Kombinationen. +# Wir verwenden eclipse-temurin als Builder-Basis und das Projekt-eigene ./gradlew-Wrapper. +ARG JAVA_VERSION=21 ARG BUILD_DATE ARG VERSION # =================================================================== # Build Stage # =================================================================== -FROM gradle:${GRADLE_VERSION}-jdk${JAVA_VERSION}-alpine AS builder +FROM eclipse-temurin:${JAVA_VERSION}-jdk-alpine AS builder ARG VERSION ARG BUILD_DATE @@ -33,7 +34,7 @@ ENV GRADLE_OPTS="-Dorg.gradle.caching=true \ -XX:+UseParallelGC \ -XX:MaxMetaspaceSize=512m" -ENV GRADLE_USER_HOME=/home/gradle/.gradle +ENV GRADLE_USER_HOME=/root/.gradle # Copy gradle wrapper and configuration files COPY gradlew gradlew.bat gradle.properties settings.gradle.kts ./ @@ -64,19 +65,26 @@ RUN mkdir -p \ frontend/shells/meldestelle-portal \ frontend/shells/meldestelle-desktop \ frontend/features/zns-import-feature \ + frontend/features/veranstalter-feature \ + frontend/features/veranstaltung-feature \ + frontend/features/profile-feature \ + frontend/features/reiter-feature \ + frontend/features/pferde-feature \ + frontend/features/verein-feature \ + frontend/features/turnier-feature \ + frontend/features/billing-feature \ docs # Copy root build configuration COPY build.gradle.kts ./ # Download and cache dependencies -RUN --mount=type=cache,id=gradle-cache-ping,target=/home/gradle/.gradle/caches \ - --mount=type=cache,id=gradle-wrapper-ping,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-ping,target=/root/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-ping,target=/root/.gradle/wrapper \ ./gradlew :backend:services:ping:ping-service:dependencies --no-daemon --info - # Build the application -RUN --mount=type=cache,id=gradle-cache-ping,target=/home/gradle/.gradle/caches \ - --mount=type=cache,id=gradle-wrapper-ping,target=/home/gradle/.gradle/wrapper \ +RUN --mount=type=cache,id=gradle-cache-ping,target=/root/.gradle/caches \ + --mount=type=cache,id=gradle-wrapper-ping,target=/root/.gradle/wrapper \ ./gradlew :backend:services:ping:ping-service:bootJar --no-daemon --info # =================================================================== diff --git a/backend/services/zns-import/zns-import-service/build.gradle.kts b/backend/services/zns-import/zns-import-service/build.gradle.kts index 016efaf0..5021f126 100644 --- a/backend/services/zns-import/zns-import-service/build.gradle.kts +++ b/backend/services/zns-import/zns-import-service/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { implementation(libs.spring.boot.starter.web) implementation(libs.spring.boot.starter.validation) implementation(libs.spring.boot.starter.actuator) + implementation(libs.spring.cloud.starter.consul.discovery) implementation(libs.exposed.core) implementation(libs.exposed.dao) diff --git a/backend/services/zns-import/zns-import-service/src/main/resources/application.yaml b/backend/services/zns-import/zns-import-service/src/main/resources/application.yaml index c726c1e7..d9f0b57b 100644 --- a/backend/services/zns-import/zns-import-service/src/main/resources/application.yaml +++ b/backend/services/zns-import/zns-import-service/src/main/resources/application.yaml @@ -20,7 +20,17 @@ spring: exclude: - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration - + cloud: + consul: + host: ${SPRING_CLOUD_CONSUL_HOST:localhost} + port: ${SPRING_CLOUD_CONSUL_PORT:8500} + enabled: ${CONSUL_ENABLED:true} + discovery: + enabled: ${CONSUL_ENABLED:true} + register: ${CONSUL_ENABLED:true} + health-check-path: /actuator/health + health-check-interval: 10s + instance-id: ${spring.application.name}-${server.port}-${random.uuid} management: endpoints: web: diff --git a/config/docker/pgadmin/servers.json b/config/docker/pgadmin/servers.json new file mode 100644 index 00000000..c7f2ef8b --- /dev/null +++ b/config/docker/pgadmin/servers.json @@ -0,0 +1,14 @@ +{ + "Servers": { + "1": { + "Name": "Meldestelle PostgreSQL", + "Group": "Meldestelle", + "Host": "postgres", + "Port": 5432, + "MaintenanceDB": "pg-meldestelle-db", + "Username": "pg-user", + "SSLMode": "prefer", + "Comment": "Haupt-Datenbank für die Meldestelle-Applikation" + } + } +} diff --git a/dc-ops.yaml b/dc-ops.yaml index 3e0c5e04..88af0648 100644 --- a/dc-ops.yaml +++ b/dc-ops.yaml @@ -35,6 +35,7 @@ services: PGADMIN_DEFAULT_PASSWORD: "${PGADMIN_PASSWORD:-pgadmin}" volumes: - "pgadmin-data:/var/lib/pgadmin" + - "./config/docker/pgadmin/servers.json:/pgadmin4/servers.json:ro" healthcheck: test: [ "CMD", "wget", "--spider", "-q", "http://localhost:80/" ] interval: 30s diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Architect.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Architect.md new file mode 100644 index 00000000..e9aefecb --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Architect.md @@ -0,0 +1,56 @@ +# 🏗️ [Lead Architect] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** Strategie, Architektur-Entscheidungen (ADRs), Domänen-Modell, Master-Roadmap + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — vollständig abgeschlossen + +- **ADR-0021 (Tenant-Resolution):** Die zentrale Architektur-Entscheidung wurde getroffen: **Eine Veranstaltung = eine + Datenbank**. Die Analyse zwischen Schema-per-Tenant und Tenant-ID ist abgeschlossen. Das ADR liegt in + `docs/01_Architecture/adr/0021-tenant-resolution-strategy-de.md`. +- **Domänen-Modell formal präzisiert:** Die Hierarchie `Veranstaltung → Turnier → Bewerb → Abteilung` ist + festgeschrieben. `TeilnehmerKonto` auf Veranstaltungsebene (Multi-Turnier), Veranstaltungs-Kassa mit + turnier-übergreifendem Saldo und die Abteilungs-Typen `SEPARATE_SIEGEREHRUNG` / `ORGANISATORISCH` sind modelliert. + +### Sprint B — vollständig abgeschlossen + +- **ADR-0022 (LAN-Sync-Protokoll):** Entscheidung für **Event-Sourcing Light mit Lamport-Uhren** (Option D) getroffen. + Optionen (Event-Sourcing, CRDT, Timestamp-Sync) wurden analysiert. ADR liegt in + `docs/01_Architecture/adr/0022-lan-sync-protocol-de.md`. Backend und Frontend wurden informiert — C-3 (LAN-Sync) bei + beiden freigegeben. + +--- + +## 🔄 Was ist noch offen? + +### Sprint C — nächste Woche (Priorität 2) + +- **C-1 Synchronisations-Protokoll-Konzeption:** Offline-First-Konzept für Desktop ↔ Backend ausarbeiten, + Conflict-Resolution-Strategie definieren, Konzept-Dokument ablegen. +- **C-2 MASTER_ROADMAP aktualisieren:** Desktop-App-Fokus eintragen, Sprint A/B Ergebnisse als erledigt markieren, + Offline-Sync-Meilensteine eintragen, Phase-8-Fortschritt reflektieren. + +--- + +## 🔗 Abhängigkeiten & Auswirkungen + +| Meine Aufgabe | Blockiert wen | +|--------------------|--------------------------------------------------------------| +| ADR-0021 ✅ | 👷 Backend: Tenant-Isolation (abgeschlossen) | +| Domänen-Modell ✅ | 👷 Backend: Schema-Design; 🎨 Frontend: ViewModel-Design | +| ADR-0022 ✅ | 🎨 Frontend C-3, 👷 Backend C-3, 🐧 DevOps D-2 (freigegeben) | +| Sync-Konzept (C-1) | 🐧 DevOps: mDNS/WebSocket-Infrastruktur | + +--- + +## 💬 Botschaft an die Runde + +Die zwei wichtigsten Architektur-Fundamente sind gesetzt: **Tenant-Isolation** (ADR-0021) und **LAN-Sync-Protokoll** ( +ADR-0022). Das Team kann auf diesen Entscheidungen aufbauen — Backend und Frontend haben ihre C-3-Aufgaben ( +LAN-Sync-Implementierung) bereits in der Roadmap. Die nächste dringende Aufgabe ist das konkrete * +*Offline-First-Konzept (C-1)** und die Aktualisierung der **MASTER_ROADMAP (C-2)**, damit alle Teams einen aktuellen +Überblick haben. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Backend.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Backend.md new file mode 100644 index 00000000..5a39a5ec --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Backend.md @@ -0,0 +1,69 @@ +# 👷 [Backend Developer] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** Spring Boot / Ktor, Kotlin, SQL, API-Design, Datenbankschema, Services + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — weitgehend abgeschlossen + +- **Datenbankschema (A-2):** Tabellen `veranstaltungen`, `turniere`, `bewerbe`, `abteilungen`, `teilnehmer_konten`, + `turnier_kassa` mit FK-Ketten implementiert. Flyway-Migrationen V1–V3 laufen durch. `DomainHierarchyMigrationTest` ist + grün. +- **Tenant-Isolation (A-1):** ADR-0021 vollständig umgesetzt. `TenantWebFilter`, `TenantRegistry` (JDBC), + `JdbcTenantRegistry`, `TenantMigrationsRunner` und MDC-Logging implementiert. Flyway pro Tenant-Schema. Alle + Unit-Tests (`JdbcTenantRegistryTest`) grün. E2E-Isolationstest (`EntriesIsolationIntegrationTest`) wieder aktiv und + grün. Kritischer Bugfix: `springdoc` 3.0.0 → 2.8.9 (ClassNotFoundException behoben). +- **Validierungs-Grundlage (A-3 teilweise):** Entkoppelte Policy-Schnittstelle + Bewerb-Descriptor implementiert. + Konkrete ÖTO-Regeln/Limits als Policy-Implementierung umgesetzt. + +### Sprint B (teilweise) — CRUD vollständig + +- **CRUD-Endpunkte (B-1):** Alle Kern-Entitäten vollständig implementiert: + - `Veranstaltung`: GET, PUT + - `Turniere`: POST, GET, GET{id}, PUT, DELETE, PATCH /status + - `Bewerbe`, `Abteilungen`: vollständige CRUD-Endpunkte + - `Reiter`, `Pferde`, `Vereine`, `Funktionäre`: vollständige CRUD inkl. Filter-Parameter + - Konsistentes Error-Format (`problem+json`), Service-Guardrails für `PUBLISHED`-Lock +- **Regulation-as-Data (via Rulebook B-2):** `LizenzKlasseE`-Enum mit `R4` ergänzt, `RD4`-Fehler korrigiert. Flyway + V009: `license_height_matrix` + `horse_min_age_matrix` angelegt und befüllt. FEI Legacy→Numeric Resolver + implementiert (`/api/fei/resolve/{id}`). + +--- + +## 🔄 Was ist noch offen? + +### Sprint A — Restpunkt + +- **A-3 Sonderregeln:** Einarbeitung der Rulebook-B-2-Spezifikation (wartet auf finale Übergabe). + +### Sprint B — offen + +- **B-1 Rest:** OpenAPI-Dokumentation (Springdoc) noch ausstehend. E2E-Tests für CRUD-Flows. +- **B-2 Kassa-Service:** `TeilnehmerKonto`-Service, `Zahlvorgang`-Service, Rechnungs-Generierung und Endpunkte noch + nicht implementiert. +- **B-3 ÖTO-Validierung serverseitig:** OEPS/FEI-Formate, Lizenzklassen, Altersklassen, CSN-C-NEU-Zwangsteilung — wartet + auf Rulebook-Spezifikation. + +### Sprint C — geplant + +- **C-1 Nennungs-Service**, **C-2 Stammdaten-Seeder**, **C-3 LAN-Sync-Endpunkte** (ADR-0022 ✅ freigegeben). + +--- + +## 🔗 Abhängigkeiten + +| Warte auf | Von wem | Betrifft | +|----------------------------|-------------|----------| +| Rulebook B-2 Spezifikation | 📜 Rulebook | A-3, B-3 | + +--- + +## 💬 Botschaft an die Runde + +Das Backend hat eine solide Grundlage: Tenant-Isolation läuft, alle CRUD-Endpunkte für Stammdaten sind fertig, das +Datenbankschema ist vollständig. Der nächste große Block ist der **Kassa-Service (B-2)** — der ist noch komplett offen. +Die **ÖTO-Validierung (B-3)** wartet auf die finale Rulebook-Übergabe. Sobald das Rulebook-Team B-2 abschließt, kann das +Backend sofort mit A-3 und B-3 starten. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Curator.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Curator.md new file mode 100644 index 00000000..29267499 --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Curator.md @@ -0,0 +1,68 @@ +# 🧹 [Curator] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** Dokumentation, Session-Logs, Ubiquitous Language, Ordnung in `docs/` + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — vollständig abgeschlossen + +- **A-1 `Ubiquitous_Language.md` aktualisiert** — nach Domänen-Modell-Präzisierung durch den Architect. +- **A-2 Event-First-Workflow dokumentiert** → `docs/02_Guides/Event-First-Workflow.md` +- **A-3 Navigation-V3 dokumentiert** → `docs/06_Frontend/Navigation_V3_Screen-Baum_und_Back-Stack.md` +- **A-4 Tenant-Konzept dokumentiert** → + `docs/01_Architecture/Reference/Tenant-Konzept_Eine-Veranstaltung-eine-Datenbank.md` +- **A-5 Session-Log Besprechung 02.04.2026** → `docs/99_Journal/2026-04-02_Meldestelle_Besprechung_Session-Log.md` + +### Sprint B — weitgehend abgeschlossen + +- **B-0 Rulebook-Session dokumentiert** → `docs/99_Journal/2026-04-03_Rulebook_B1_Validierung_Frontend.md` +- **B-1 Roadmaps vollständig gepflegt (03.04.2026):** + - Architect-Roadmap: Sprint B (ADR-0022) als ✅ abgeschlossen eingetragen + - Backend-Roadmap: C-3 LAN-Sync als freigegeben markiert + - Frontend-Roadmap: C-3 LAN-Sync als freigegeben markiert + - DevOps-Roadmap: vollständig und korrekt ✅ + - UIUX-Roadmap: vollständig und korrekt ✅ + - Rulebook-Roadmap: vollständig und korrekt ✅ + - QA-Roadmap: Sprint-B-Header korrigiert (🔴 → 🟡 Teilweise offen) ✅ + - Alle Roadmaps: abgeschlossene Aufgaben als `[x]` markiert ✅ +- **Architect B-1 Session-Log erstellt** → `docs/99_Journal/2026-04-03_Architect_B1_LAN-Sync_ADR-0022.md` + +--- + +## 🔄 Was ist noch offen? + +### Sprint B — offen + +- **B-2 `docs/05_Backend/` aktualisieren:** Datenbankschema (Tabellen V1–V009), API-Endpunkte-Übersicht (Reiter, Pferde, + Vereine, Funktionäre), Tenant-Isolation beschreiben. Kassa-Endpunkte sobald Backend B-2 fertig. +- **B-3 `docs/06_Frontend/` aktualisieren:** ViewModel-Architektur-Muster verlinken, `VeranstalterViewModel` als + Referenz eintragen. + +### Sprint C — geplant (nächste Woche) + +- **C-1** `README.md` aktualisieren (Desktop-App-Fokus, Schnellstart, V1-Altlasten) +- **C-2** Setup-Guide erstellen (`docs/02_Guides/`) +- **C-3** Unterordner-Struktur in `docs/` prüfen und mit Architect abstimmen +- **C-4** V1-Code-Bereinigung koordinieren (gemeinsam mit Frontend + Backend) +- **C-5** Sprint-Reports archivieren in `docs/90_Reports/` + +--- + +## 🔗 Abhängigkeiten + +| Warte auf | Von wem | Betrifft | +|---------------------------|------------|--------------------------| +| Backend B-2 Kassa-Service | 👷 Backend | B-2 Kassa-Endpunkte-Doku | + +--- + +## 💬 Botschaft an die Runde + +Die Dokumentations-Basis ist solide: Session-Logs, Ubiquitous Language, alle Roadmaps und zentrale Architektur-Dokumente +sind aktuell. Die **Besprechungs-Berichte von heute** (dieses Dokument und alle Schwester-Berichte) wurden in +`docs/04_Agents/Besprechung_2026-04-03/Berichte/` abgelegt. Der dringendste offene Punkt ist **B-2** — die +Backend-Dokumentation (Datenbankschema + API-Übersicht) ist bereit zum Erstellen, da Backend B-1 abgeschlossen ist. Das +`README.md` ist veraltet und sollte bald auf Desktop-App-Fokus aktualisiert werden. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_DevOps.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_DevOps.md new file mode 100644 index 00000000..b4900c3b --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_DevOps.md @@ -0,0 +1,69 @@ +# 🐧 [DevOps Engineer] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** Docker, CI/CD, Gradle, Security, Desktop-Packaging, Infrastruktur + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — vollständig abgeschlossen + +- **Docker-Compose-Setup (A-1):** Alle Services in `docker-compose.yaml` / `dc-*.yaml` geprüft. Lokale + Entwicklungsumgebung startet mit einem einzigen Befehl. Healthchecks für alle Services definiert. + +### Sprint B — vollständig abgeschlossen + +- **CI/CD Pipeline für Compose Desktop Tests (B-1):** Gitea Actions Workflow `.gitea/workflows/desktop-tests.yml` + angelegt. Headless-Umgebung mit `xvfb-run` (1920×1080×24). Gradle-Task `:frontend:shells:meldestelle-desktop:jvmTest` + integriert. Build-Artefakte werden gespeichert. +- **Gradle-Build-Optimierungen (B-2):** Build-Cache, Parallele Builds, Headless-Flag aktiv. Gradle Wrapper auf Version + `9.4.0` aktualisiert. + +### Sprint C — weitgehend abgeschlossen + +- **Desktop-App Packaging (C-1):** `compose.desktop.nativeDistributions` vollständig konfiguriert für Linux (`.deb`), + Windows (`.msi`) und macOS (`.dmg`). App-Metadaten, eingebettetes JRE mit minimalem Footprint und JVM-Args für + gepackte App konfiguriert. Icon-Ressourcen-Verzeichnis mit `ICONS_PLACEHOLDER.md` angelegt. +- **Semantic Versioning (C-2):** Schema `MAJOR.MINOR.PATCH[-QUALIFIER]` definiert. Zentrale Versionsquelle + `version.properties` (aktuell `1.0.0-SNAPSHOT`). Root- und Desktop-`build.gradle.kts` lesen Version daraus. + Release-Workflow `.gitea/workflows/release.yml` mit Git-Tagging, Linux `.deb` und Windows `.msi` Build-Jobs angelegt. + `CHANGELOG.md` im Keep-a-Changelog-Format erstellt. + +--- + +## 🔄 Was ist noch offen? + +### Sprint C — Restpunkte + +- **C-1 Offene Punkte:** Echte Icon-Dateien (`icon.png`, `icon.ico`, `icon.icns`) fehlen noch — wartet auf 🖌️ UI/UX. + Testinstallation auf Ziel-Betriebssystem steht noch aus. +- **C-3 Produktions-Deployment:** Reverse-Proxy (Nginx/Traefik), HTTPS-Zertifikat-Management, Backup-Strategie für + Produktionsdatenbanken. + +### Sprint D — geplant (nächste Woche) + +- **D-1 Multi-Tenant Datenbankinfrastruktur:** Pro-Tenant-Schema in Postgres absichern, Monitoring in Grafana, + Pro-Tenant-Backup-Strategie. +- **D-2 mDNS / LAN-Discovery Infrastruktur (ADR-0022 ✅):** Avahi-Dienst in Docker-Compose, WebSocket-Endpunkt in + Nginx/Traefik durchreichen. + +> ⏸️ **Pangolin / externer Zugriff** — kein MVP-Blocker, zurückgestellt. + +--- + +## 🔗 Abhängigkeiten + +| Warte auf | Von wem | Betrifft | +|-----------------------------|-----------|---------------------| +| Icon-Dateien (PNG/ICO/ICNS) | 🖌️ UI/UX | C-1 Release-Build | +| QA: Test-Integration in CI | 🧐 QA C-4 | C-1 Packaging-Tests | + +--- + +## 💬 Botschaft an die Runde + +Die Infrastruktur läuft stabil: Docker-Compose, CI/CD-Pipeline und Gradle-Optimierungen sind fertig. Das * +*Desktop-Packaging ist vollständig konfiguriert** — wir können theoretisch schon `.deb`- und `.msi`-Installer bauen. Der +einzige Blocker für den ersten echten Release-Build sind die **App-Icons** vom UI/UX-Team. Sobald die Icons vorliegen, +kann der Release-Workflow sofort laufen. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Frontend.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Frontend.md new file mode 100644 index 00000000..3fa0e771 --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Frontend.md @@ -0,0 +1,72 @@ +# 🎨 [Frontend Expert] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** KMP, Compose Desktop, State-Management, Navigation, Backend-Anbindung + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — vollständig abgeschlossen + +- **ViewModel-Architektur (A-1):** MVVM mit UDF als verbindliches Muster festgelegt. `Intent`/`State`-Struktur mit + Sealed Classes definiert. `VeranstalterViewModel` als vollständige Referenz-Implementierung. Muster-Dokument in + `docs/06_Frontend/` abgelegt. +- **Abteilungs-Logik im Bewerb-Dialog (A-2):** CSN-C-NEU Automatik-Teilung mit 4 Abteilungen, AssistChip + „Pflicht-Teilung vorgeschlagen", Abteilungs-Typen `SEPARATE_SIEGEREHRUNG` / `ORGANISATORISCH` in der UI verankert. + +### Sprint B (teilweise) — ViewModels & Navigation vollständig + +- **ViewModels für alle V3-Screens (B-1):** `TurnierViewModel`, `BewerbViewModel`, `PferdProfilViewModel`, + `ReiterProfilViewModel`, `VereinsViewModel`, `FunktionaerViewModel`, `AbteilungViewModel` (Startliste, Ergebnisse) — + alle fertig. +- **Zusätzlich erledigt (02.04.2026):** Navigation V2 / Back-Stack-System, Profil-Cards mit Edit-Dialogen (Veranstalter, + Pferd, Reiter, Verein, Funktionär), Onboarding mit `rememberSaveable`, Veranstaltungs-Wizard mit Bestätigungs-Dialog, + Breadcrumbs und Zurück-Navigation korrigiert. +- **Backend-Anbindung (B-2 teilweise):** `HttpClient`-Factory zentral konfiguriert. `VeranstalterRepository`, + `BewerbRepository`, `AbteilungRepository`, `DefaultTurnierRepository` implementiert. DTOs + Mapper in commonMain. Koin + Feature-Modul `turnierFeatureModule` verdrahtet. Fehler-Mapping HTTP → Domain-Errors einheitlich. +- **Validierungs-Live-Feedback (B-3 teilweise):** `MsValidationWrapper` vorhanden. OEPS-Nummer- und + FEI-ID-Live-Validierung in `ReiterProfilViewModel` und `PferdProfilViewModel`. Lizenzklasse-Validierung im + ReiterProfilViewModel. `ReiterProfilEditDialog` und `PferdProfilEditDialog` vollständig mit `MsValidationWrapper` + ausgestattet. + +--- + +## 🔄 Was ist noch offen? + +### Sprint B — offen (höchste Priorität) + +- **B-2 Rest:** `AuthApiClient`-Integration, `StoreV2` Feature-für-Feature ablösen, Akzeptanz-Tests (Mock Engine), + Dokumentation `Networking.md`. +- **B-3 Rest:** Lizenzklasse × Bewerbs-Klasse Warnung, Altersklasse Pferd × Bewerb Warnung — benötigen Bewerb-Kontext + und Rulebook-Spezifikation. +- **B-4 Kassa-Screen:** Gesamt-Saldo-Ansicht, turnier-übergreifender Zahlvorgang, Rechnungsvorschau — wartet auf Backend + B-2 und UI/UX-Wireframes. + +### Sprint C — geplant + +- **C-1** `StoreV2` vollständig ablösen +- **C-2** VeranstalterNeu: Vereinssuche & Daten-Übernahme +- **C-3** LAN-Sync-UI vorbereiten (ADR-0022 ✅ freigegeben) +- **C-4** Lint-Bereinigung & Code-Qualität + +--- + +## 🔗 Abhängigkeiten + +| Warte auf | Von wem | Betrifft | +|-------------------------------------|-------------------|-----------------------------------| +| Rulebook Validierungs-Spezifikation | 📜 Rulebook B-2 | B-3 Bewerb-Kontext-Validierung | +| Kassa-Service API | 👷 Backend B-2 | B-4 Kassa-Screen | +| Wireframes Bewerb-Dialog / Kassa | 🖌️ UI/UX B-2/B-3 | B-4 Implementierung (✅ vorhanden) | + +--- + +## 💬 Botschaft an die Runde + +Die Desktop-App hat eine vollständige ViewModel-Schicht und Navigation. Die Backend-Anbindung ist in vollem Gange — +Repositories für alle Kern-Entitäten sind angelegt. Der größte offene Punkt ist die **`StoreV2`-Ablösung** und die +Live-Validierung mit **Bewerb-Kontext** (B-3). Der **Kassa-Screen (B-4)** kann erst starten, wenn das Backend den +Kassa-Service liefert. Die UI/UX-Wireframes für Kassa und Bewerb-Dialog sind bereits vorhanden und warten auf +Implementierung. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_QA.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_QA.md new file mode 100644 index 00000000..5c1c355d --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_QA.md @@ -0,0 +1,73 @@ +# 🧐 [QA Specialist] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** Test-Strategie, Edge-Cases, Integrationstests, Regressionssicherung + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — vollständig abgeschlossen + +- **Test-Strategie für Desktop-App (A-1):** Testpyramide für Compose Desktop festgelegt (Unit / Integration / UI-Tests). + Tooling entschieden: `kotlin.test`, Compose UI Test, Mockk. Test-Konventionen dokumentiert (Namensschema, + Ordnerstruktur, Arrange-Act-Assert). `IdempotencyPluginTest` stabilisiert. `OetoValidatorsTest.kt` als Basis für + Grenzfall-Abdeckung etabliert. + +### Sprint B (teilweise) — zwei Test-Suiten abgeschlossen + +- **Onboarding-Wizard Edge-Cases (B-2) ✅ — 3. April 2026:** + - Leere Pflichtfelder → Speichern-Button bleibt deaktiviert + - Schnelles Doppelklick → kein doppelter Submit + - Abbrechen mitten im Wizard → kein inkonsistenter Zustand + - Zurück-Navigation: Gerätename und Sicherheitsschlüssel bleiben erhalten (`rememberSaveable`) + - **Fix:** `remember` → `rememberSaveable` in `OnboardingScreen.kt` + - **Neu:** `OnboardingValidator`-Objekt extrahiert für isolierte Unit-Tests + - **17 Tests, alle GRÜN** (`OnboardingValidatorTest.kt`) + +- **Abteilungs-Logik (B-3) ✅ — 3. April 2026:** + - CSN-C-NEU ≤95cm / ≥100cm: Pflicht-Teilungen korrekt vorgeschlagen + - `ORGANISATORISCH`: Gesamtrangliste korrekt zusammengeführt + - `SEPARATE_SIEGEREHRUNG`: Abteilungen werden nicht zusammengeführt + - Caprilli-Regression abgesichert, Grenzfälle 90 cm und 110 cm abgedeckt + - **Fix:** CSN-C-NEU-Logik in `AbteilungsRegelService.kt` implementiert + - **Neu:** `ORGANISATORISCH` + `SEPARATE_SIEGEREHRUNG` in `AbteilungsTeilungsTypE` ergänzt + - **14 neue Tests, alle GRÜN** (`AbteilungsRegelServiceTest.kt`) + +--- + +## 🔄 Was ist noch offen? + +### Sprint B — offen + +- **B-1 Navigation & Back-Stack:** Navigations-Flows, Back-Stack-Verhalten, SingleTop-Tabs, Logout-Verhalten — noch + nicht begonnen. +- **B-2 Restpunkt:** Ungültige OEPS-Nummer → Fehlermeldung sichtbar (abhängig von Frontend C-3). +- **B-4 ViewModel-Verhalten:** State-Initialisierung, Intent → State-Transitionen, Fehler-State bei Backend-Fehler, + Loading-State — noch nicht begonnen. + +### Sprint C — geplant + +- **C-1** Mandanten-Isolation (sicherheitskritisch; wartet auf Backend A-1 Rollout) +- **C-2** Kassa und Zahlvorgang (wartet auf Backend B-2) +- **C-3** ÖTO-Validierung (wartet auf Rulebook C-1 `AltersklasseRechner`) +- **C-4** Regressions-Test-Suite & CI-Integration (gemeinsam mit 🐧 DevOps) + +--- + +## 🔗 Abhängigkeiten + +| Warte auf | Von wem | Betrifft | +|----------------------------------|---------------|------------------------| +| Rulebook C-1 AltersklasseRechner | 📜 Rulebook | C-3 Validierungs-Tests | +| Backend B-2 Kassa-Service | 👷 Backend | C-2 Kassa-Tests | +| DevOps CI/CD Pipeline | 🐧 DevOps C-1 | C-4 CI-Integration | + +--- + +## 💬 Botschaft an die Runde + +Zwei wichtige Test-Suiten wurden heute fertiggestellt: **Onboarding (17 Tests)** und **Abteilungs-Logik (14 Tests)** — +beide komplett grün, inklusive zweier produktiver Bugfixes im Produktivcode. Die Test-Basis steht. Der nächste kritische +Schritt ist die **Mandanten-Isolation (C-1)** — sicherheitskritisch und sofort anzugehen, sobald Backend A-1 vollständig +ausgerollt ist. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Rulebook.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Rulebook.md new file mode 100644 index 00000000..c498cf4f --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_Rulebook.md @@ -0,0 +1,68 @@ +# 📜 [ÖTO/FEI Rulebook Expert] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** Regelwerks-Wächter, Validierungs-Spezialist, Compliance (ÖTO, FEI) + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — vollständig abgeschlossen + +- **Validierungs-Spezifikation v0.3 DRAFT (A-1):** Paragraphen-Pins ergänzt (Springen § 231, Dressur § 103, CCN §§ 3xx). + Einheitliche Label-Konventionen definiert (`ohne Lizenz`, `mit Lizenz`, `R2 und höher`; Keys: `LZF_ONLY`, `R1_PLUS`, + `R1_ONLY`, `R2_PLUS`). Optionale Jugend-/Jahrgangsteilungen als Regulation-as-Data modelliert. CVN (Voltigieren) und + CAN (Fahren) als Fallback-Regelung dokumentiert. +- **Abteilungs-Schwellenwerte:** Dokument abgelegt in + `docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md`. +- **Warn-Logik-Spezifikation:** + `docs/03_Domain/02_Reference/OETO_Regelwerk/Warn-Logik-Spezifikation-competition-context.md` abgelegt. +- **`OetoValidators` (KMP) implementiert:** `OetoValidatorsTest.kt` ist grün. + +### Sprint B (teilweise) — Frontend-Begleitung abgeschlossen + +- **B-1 Frontend-Validierung begleitet:** Spezifikation v0.3 DRAFT an 🎨 Frontend übergeben. Implementierung geprüft — + Live-Validierung entspricht den Anforderungen. Fehlermeldungs-Texte geprüft. Session-Log dokumentiert. +- **B-2 Regulation-as-Data an Backend übergeben:** + - `LizenzKlasseE`-Enum mit `R4` ergänzt, `RD4`-Fehler in V008 korrigiert. + - Flyway V009: `license_height_matrix` + `horse_min_age_matrix` angelegt und befüllt. + - B-2-Übergabe-Spezifikation: `docs/03_Domain/02_Reference/OETO_Regelwerk/B2-Backend-Uebergabe-Regulation-as-Data.md`. + - `Validierungsregeln.md` auf Version 0.4 angehoben (`LZF` → `LIZENZFREI` korrigiert). + - FEI Legacy→Numeric Resolver in Masterdata-SCS implementiert. + +--- + +## 🔄 Was ist noch offen? + +### Sprint B — offen + +- **B-2 Rest:** Serverseitige Validierung prüfen. Backend-Endpunkte `/api/regulation/*` noch ausstehend (liegt bei + Backend). Abweichungen Backend ↔ Frontend dokumentieren. Lizenz×Bewerb-Tabellen von DRAFT auf STABLE anheben ( + Fachfreigabe erforderlich). + +### Sprint C — geplant + +- **C-1 `AltersklasseRechner`:** Altersklassen-Berechnung Pferd (Jahrgang → Kategorie), Grenzfälle (Geburtsjahr, + Jahreswechsel, Stichtag), Unit-Tests. +- **C-2 Regelwerk-Enums vervollständigen:** Lizenzklassen-Übergänge, FEI-Kategorien-Mapping, Enums in `core:domain` als + SSoT. +- **C-3 Compliance-Dokumentation:** Series-Context (Cups, Serien, Meisterschaften) vorbereiten. + +--- + +## 🔗 Abhängigkeiten & Auswirkungen + +| Meine Aufgabe | Blockiert wen | +|-------------------------|---------------------------------------------------| +| B-2 Spec an Backend ✅ | 👷 Backend: A-3 Sonderregeln, B-3 ÖTO-Validierung | +| B-1 Spec an Frontend ✅ | 🎨 Frontend: B-3 Live-Validierung | +| C-1 AltersklasseRechner | 🧐 QA: C-3 Validierungs-Tests | + +--- + +## 💬 Botschaft an die Runde + +Die fachliche Grundlage für Validierung steht: `OetoValidators` ist implementiert, die Lizenz-/Altersmatrix liegt als +Regulation-as-Data im Backend. Der kritische offene Punkt ist die **Fachfreigabe für Lizenz×Bewerb-Tabellen** (DRAFT → +STABLE) — ohne diese können Backend und Frontend nicht auf stabiler Basis arbeiten. Der **`AltersklasseRechner` (C-1)** +muss vor der Backend-Implementierung spezifiziert sein, da die Grenzfall-Logik komplex ist. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_UIUX.md b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_UIUX.md new file mode 100644 index 00000000..a139f995 --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Berichte/Bericht_UIUX.md @@ -0,0 +1,78 @@ +# 🖌️ [UI/UX Designer] — Zwischenbericht zur Besprechung vom 3. April 2026 + +> **Datum:** 3. April 2026, ca. 13:00 Uhr +> **Rolle:** High-Density Design, Wireframes, Usability, Design-System, Empty States + +--- + +## ✅ Was wurde erreicht? + +### Sprint A — vollständig abgeschlossen + +- **Design-Inventur (A-1):** Alle vorhandenen V3-Screens katalogisiert (Screenshots in `docs/06_Frontend/Screenshots/`). + Inkonsistenzen in Spacing, Typografie und Farbgebung identifiziert. Offene UX-Probleme und fehlende Empty States + dokumentiert. Issue-Liste für Sprint B vorbereitet. + +### Sprint B — vollständig abgeschlossen (3. April 2026) + +- **Editier-Formulare: Dialog vs. Fullscreen (B-1 ✅):** + - Entscheidungsgrundlage erarbeitet: Wann AlertDialog, wann Fullscreen-Edit? + - Wireframes für beide Varianten erstellt (Reiter-Edit, Pferd-Edit als Beispiele) + - Mapping aller bestehenden Edit-Screens auf AlertDialog / Side Sheet / Fullscreen dokumentiert + - Finale Entscheidung als **verbindliche Design-Richtlinie festgeschrieben** (Status: APPROVED) + - Ergebnis: `docs/06_Frontend/Guidelines/Editier-Formulare_Dialog-vs-Fullscreen_v1.md` + +- **Bewerb anlegen mit Abteilungs-Logik (B-2 ✅):** + - Dialog-Flow: Bewerb-Grunddaten → Abteilungs-Vorschlag → Bestätigung + - CSN-C-NEU Pflicht-Teilung visuell dargestellt + - Abteilungs-Typ-Auswahl (`SEPARATE_SIEGEREHRUNG` vs. `ORGANISATORISCH`) verständlich gestaltet + - Ergebnis: `docs/06_Frontend/Wireframes/Bewerb_anlegen_Abteilungs-Logik_v1.md` + +- **Veranstaltungs-Kassa (B-3 ✅):** + - Gesamt-Saldo-Ansicht: Teilnehmer mit offenen Beträgen aus mehreren Turnieren + - Zahlvorgang-Dialog: Eine Zahlung, Aufteilung auf Turniere sichtbar + - Rechnungsvorschau: Zwei separate Rechnungen je Turnier als Tab + - Ergebnis: `docs/06_Frontend/Wireframes/Kassa_Veranstaltung_v1.md` + +- **Empty States für alle Listenansichten (B-4 ✅):** + - Liste aller 10 Screens mit möglichen leeren Zuständen (3 Typen) erstellt + - Icon-Konzept: Material Symbols Outlined (kein Custom-Illustration-Set für MVP) + - Texte (Titel, Beschreibung, CTA) für alle Screens und Typen definiert + - Composable-API `MsEmptyState` spezifiziert (Ablageort, Parameter, Verhalten, Beispiel) + - Ergebnis: `docs/06_Frontend/Guidelines/Empty-States_Spezifikation_v1.md` (Status: APPROVED) + +--- + +## 🔄 Was ist noch offen? + +### Sprint C — geplant (nächste Woche) + +- **C-1 Wireframes in Compose umsetzen:** Edit-Dialog/Fullscreen (B-1), Bewerb-Anlegen-Dialog (B-2), Kassa-Screen (B-3), + `MsEmptyState`-Composable implementieren, Empty States in alle 10 Listenansichten integrieren, `PferdProfilEditDialog` + zu Fullscreen migrieren. +- **C-2 Design-System konsolidieren:** Farb-Palette in `MaterialTheme` / `Theme.kt`, Typografie-Skala, wiederverwendbare + Composables (Cards, Badges, Chips). +- **C-3 Abteilungs-Ansicht:** Wireframes für Startliste, Ergebnisliste und Ranglisten-Zusammenführung ( + `ORGANISATORISCH`). + +> ⏸️ **Web-App / PWA Design** — Nach Desktop-MVP; Anforderungen noch nicht definiert. + +--- + +## 🔗 Abhängigkeiten & Auswirkungen + +| Meine Aufgabe | Blockiert wen | +|------------------------|------------------------------------------------| +| B-1 Richtlinie ✅ | 🎨 Frontend C-1: Edit-Dialoge implementieren | +| B-4 Spezifikation ✅ | 🎨 Frontend C-1: `MsEmptyState` implementieren | +| B-2 / B-3 Wireframes ✅ | 🎨 Frontend C-1: Bewerb-Dialog, Kassa-Screen | +| Icons (PNG/ICO/ICNS) | 🐧 DevOps C-1: Release-Build (noch ausstehend) | + +--- + +## 💬 Botschaft an die Runde + +Sprint B ist vollständig abgeschlossen — alle vier Punkte (B-1 bis B-4) sind **APPROVED** und an das Frontend-Team +übergeben. Die Spezifikationen und Wireframes liegen vor. Das Frontend kann sofort mit **`MsEmptyState` (C-1)** und der +**`PferdProfilEditDialog`-Migration** beginnen. Die **App-Icons** (PNG/ICO/ICNS) sind der einzige ausstehende +Design-Deliverable für den DevOps-Release-Build — diese müssen priorisiert werden. diff --git a/docs/04_Agents/Besprechung_2026-04-03/Postman_Tests_Dokumentation.md b/docs/04_Agents/Besprechung_2026-04-03/Postman_Tests_Dokumentation.md new file mode 100644 index 00000000..53e28e20 --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Postman_Tests_Dokumentation.md @@ -0,0 +1,960 @@ +# 🧪 Postman Tests — Vollständige Dokumentation + +> **Stand:** 3. April 2026 +> **Erstellt von:** 👷 Backend Developer & 🧐 QA Specialist +> **Collection-Datei:** +`backend/infrastructure/gateway/src/main/resources/static/docs/postman/Meldestelle_API_Collection.json` + +--- + +## Inhaltsverzeichnis + +1. [Setup & Variablen](#1-setup--variablen) +2. [Smoke-Tests: System & Health](#2-smoke-tests-system--health) +3. [Ping Service](#3-ping-service) +4. [Authentication Context](#4-authentication-context) +5. [Master Data: Countries](#5-master-data-countries) +6. [Horse Registry (Pferde)](#6-horse-registry-pferde) +7. [ZNS Import Service](#7-zns-import-service) +8. [Empfohlene Test-Reihenfolge](#8-empfohlene-test-reihenfolge) + +--- + +## 1. Setup & Variablen + +### Collection importieren + +1. Postman öffnen → **Import** → Datei auswählen: + ``` + backend/infrastructure/gateway/src/main/resources/static/docs/postman/Meldestelle_API_Collection.json + ``` +2. Collection `Meldestelle API Collection` erscheint im linken Panel. + +### Environment-Variablen anlegen + +In Postman ein **Environment** `Meldestelle Local` anlegen mit folgenden Variablen: + +| Variable | Initial Value | Beschreibung | +|-------------|-------------------------|------------------------------------| +| `baseUrl` | `http://localhost:8081` | API-Gateway (Haupt-Einstiegspunkt) | +| `pingUrl` | `http://localhost:8082` | Ping-Service direkt (ohne Gateway) | +| `znsUrl` | `http://localhost:8095` | ZNS-Import-Service direkt | +| `authToken` | *(leer, wird befüllt)* | JWT-Token nach Login | +| `horseId` | *(leer, wird befüllt)* | ID eines angelegten Pferdes | +| `countryId` | *(leer, wird befüllt)* | ID eines angelegten Landes | +| `horseId1` | *(leer)* | Für Batch-Delete Tests | +| `horseId2` | *(leer)* | Für Batch-Delete Tests | + +> ⚠️ **Wichtig:** Sicherstellen dass alle Services laufen bevor Tests gestartet werden (siehe Betriebsanleitung). + +--- + +## 2. Smoke-Tests: System & Health + +> **Zweck:** Schnell prüfen ob das API-Gateway und alle Services erreichbar sind. Immer zuerst ausführen! + +--- + +### 2.1 API Gateway Info + +| Feld | Wert | +|-------------|----------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "service": "Meldestelle API Gateway", + "version": "...", + "status": "running" +} +``` + +**Wozu:** Bestätigt dass das Gateway läuft und auf Anfragen antwortet. + +--- + +### 2.2 Health Check (Gateway) + +| Feld | Wert | +|-------------|----------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/health` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "status": "UP" +} +``` + +--- + +### 2.3 API Documentation + +| Feld | Wert | +|-------------|-------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` — OpenAPI JSON-Dokumentation + +--- + +### 2.4 Swagger UI + +| Feld | Wert | +|-------------|-----------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/swagger` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` — Swagger HTML-Interface +**Tipp:** Im Browser öffnen für interaktive API-Erkundung. + +--- + +## 3. Ping Service + +> **Zweck:** Funktionsfähigkeit des Ping-Service testen, Circuit Breaker und Sync-Funktionen validieren. +> **Direkt-URL:** `{{pingUrl}}` = `http://localhost:8082` +> **Via Gateway:** `{{baseUrl}}` = `http://localhost:8081` + +--- + +### 3.1 Simple Ping + +| Feld | Wert | +|-------------|---------------------------| +| **Methode** | `GET` | +| **URL** | `{{pingUrl}}/ping/simple` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "message": "pong", + "timestamp": "2026-04-03T14:00:00+02:00", + "service": "ping-service", + "status": "simple" +} +``` + +**Wozu:** Einfachster Smoke-Test — bestätigt dass der Service läuft und die DB erreichbar ist. + +--- + +### 3.2 Simple Ping via Gateway + +| Feld | Wert | +|-------------|---------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/ping/simple` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` (identisch wie 3.1) +**Wozu:** Bestätigt dass das Gateway den Ping-Service korrekt routet (Service Discovery via Consul). + +--- + +### 3.3 Enhanced Ping (mit Circuit Breaker) + +| Feld | Wert | +|-----------------|-----------------------------| +| **Methode** | `GET` | +| **URL** | `{{pingUrl}}/ping/enhanced` | +| **Auth** | Keine | +| **Query-Param** | `simulate=false` (Standard) | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "message": "enhanced pong", + "timestamp": "...", + "service": "ping-service", + "status": "enhanced", + "circuitBreakerStatus": "CLOSED" +} +``` + +**Wozu:** Bestätigt dass Resilience4j Circuit Breaker korrekt konfiguriert ist. + +--- + +### 3.4 Enhanced Ping — Fehler simulieren + +| Feld | Wert | +|-------------|-------------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{pingUrl}}/ping/enhanced?simulate=true` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` mit Fallback-Response (kein 500-Fehler!) + +```json +{ + "message": "fallback response", + "status": "fallback", + "circuitBreakerStatus": "OPEN", + "error": "..." +} +``` + +**Wozu:** Bestätigt dass der Circuit Breaker Fallback greift (60% simulierte Fehlerrate). Der Service antwortet trotz +Fehler mit einem sinnvollen Fallback. +**Mehrfach ausführen:** Nach ~5 Anfragen mit `simulate=true` öffnet der Circuit Breaker. + +--- + +### 3.5 Public Ping (kein Auth erforderlich) + +| Feld | Wert | +|-------------|---------------------------| +| **Methode** | `GET` | +| **URL** | `{{pingUrl}}/ping/public` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` +**Wozu:** Bestätigt dass der `/ping/public`-Endpunkt ohne JWT-Token erreichbar ist (Security-Konfiguration). + +--- + +### 3.6 Secure Ping (Auth erforderlich) + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{pingUrl}}/ping/secure` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Mit gültigem Token:** `200 OK` +**Ohne Token:** `401 Unauthorized` +**Wozu:** Bestätigt dass JWT-Authentifizierung korrekt erzwungen wird. + +--- + +### 3.7 Sync Pings (seit Timestamp) + +| Feld | Wert | +|-----------------|-----------------------------------| +| **Methode** | `GET` | +| **URL** | `{{pingUrl}}/ping/sync` | +| **Auth** | Keine | +| **Query-Param** | `since=0` (alle Pings seit Epoch) | + +**Erwartete Antwort:** `200 OK` + +```json +[ + { + "id": "...", + "message": "pong", + "timestamp": "...", + "lamportClock": 1 + } +] +``` + +**Wozu:** Testet den LAN-Sync-Endpunkt (Lamport-Uhren, Event-Sourcing Light). `since` ist ein Unix-Timestamp in +Millisekunden. + +--- + +### 3.8 Ping Service Health + +| Feld | Wert | +|-------------|---------------------------| +| **Methode** | `GET` | +| **URL** | `{{pingUrl}}/ping/health` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "status": "up", + "timestamp": "...", + "service": "ping-service", + "healthy": true +} +``` + +--- + +## 4. Authentication Context + +> **Zweck:** Benutzer-Registrierung, Login und Profilverwaltung über Keycloak testen. +> **Reihenfolge:** Zuerst registrieren → dann einloggen → Token in `{{authToken}}` speichern. + +--- + +### 4.1 User Registration + +| Feld | Wert | +|-------------|----------------------------------| +| **Methode** | `POST` | +| **URL** | `{{baseUrl}}/auth/register` | +| **Header** | `Content-Type: application/json` | + +**Request Body:** + +```json +{ + "email": "test@example.com", + "password": "SecurePassword123!", + "firstName": "Test", + "lastName": "User", + "phoneNumber": "+43123456789" +} +``` + +**Erwartete Antwort:** `201 Created` + +```json +{ + "userId": "uuid-...", + "email": "test@example.com", + "message": "Registrierung erfolgreich" +} +``` + +**Wozu:** Legt einen neuen Benutzer in Keycloak an. + +--- + +### 4.2 User Login + +| Feld | Wert | +|-------------|----------------------------------| +| **Methode** | `POST` | +| **URL** | `{{baseUrl}}/auth/login` | +| **Header** | `Content-Type: application/json` | + +**Request Body:** + +```json +{ + "email": "test@example.com", + "password": "SecurePassword123!" +} +``` + +**Erwartete Antwort:** `200 OK` + +```json +{ + "accessToken": "eyJhbGci...", + "refreshToken": "...", + "expiresIn": 300 +} +``` + +> **⚡ Tipp:** Postman-Test-Script einfügen um Token automatisch zu speichern: +> ```javascript +> var json = pm.response.json(); +> pm.environment.set("authToken", json.accessToken); +> ``` + +--- + +### 4.3 Get User Profile + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/auth/profile` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "userId": "...", + "email": "test@example.com", + "firstName": "Test", + "lastName": "User" +} +``` + +--- + +### 4.4 Update User Profile + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `PUT` | +| **URL** | `{{baseUrl}}/auth/profile` | +| **Header** | `Content-Type: application/json` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Request Body:** + +```json +{ + "firstName": "Updated", + "lastName": "User", + "phoneNumber": "+43987654321" +} +``` + +**Erwartete Antwort:** `200 OK` — aktualisierte Profildaten + +--- + +### 4.5 Change Password + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `POST` | +| **URL** | `{{baseUrl}}/auth/change-password` | +| **Header** | `Content-Type: application/json` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Request Body:** + +```json +{ + "currentPassword": "SecurePassword123!", + "newPassword": "NewSecurePassword456!" +} +``` + +**Erwartete Antwort:** `200 OK` +**Fehlerfall (falsches Passwort):** `400 Bad Request` + +--- + +## 5. Master Data: Countries + +> **Zweck:** Länderstammdaten verwalten. Diese sind Voraussetzung für Pferde- und Reiter-Datensätze. +> **Basis-URL:** `{{baseUrl}}/api/masterdata/countries` +> **Hinweis:** GET-Endpunkte sind ohne Auth zugänglich; POST/PUT/DELETE benötigen `{{authToken}}`. + +--- + +### 5.1 Get All Countries + +| Feld | Wert | +|-------------|----------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/masterdata/countries` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` — Array aller Länder (inkl. inaktive) + +--- + +### 5.2 Get Active Countries + +| Feld | Wert | +|-------------|-----------------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/masterdata/countries/active` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` — Nur Länder mit `istAktiv: true` +**Wozu:** Für Dropdown-Listen in der Desktop-App (nur aktive Länder anzeigen). + +--- + +### 5.3 Get Country by ID + +| Feld | Wert | +|-------------|------------------------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/masterdata/countries/{{countryId}}` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` — Einzelnes Land +**Fehlerfall:** `404 Not Found` + +--- + +### 5.4 Get Country by ISO Code + +| Feld | Wert | +|-------------|-----------------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/masterdata/countries/iso/AT` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "id": "...", + "isoAlpha2Code": "AT", + "nameDeutsch": "Österreich", + "istEuMitglied": true, + "istAktiv": true +} +``` + +**Wozu:** Österreich ist das primäre Land — dieser Test prüft ob die Stammdaten korrekt befüllt sind. + +--- + +### 5.5 Create Country + +| Feld | Wert | +|-------------|----------------------------------------| +| **Methode** | `POST` | +| **URL** | `{{baseUrl}}/api/masterdata/countries` | +| **Header** | `Content-Type: application/json` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Request Body:** + +```json +{ + "isoAlpha2Code": "TS", + "isoAlpha3Code": "TST", + "isoNumerischerCode": "999", + "nameDeutsch": "Testland", + "nameEnglisch": "Testland", + "istEuMitglied": false, + "istEwrMitglied": false, + "istAktiv": true, + "sortierReihenfolge": 999 +} +``` + +**Erwartete Antwort:** `201 Created` + +> **⚡ Tipp:** `countryId` aus der Antwort in Environment-Variable speichern: +> ```javascript +> var json = pm.response.json(); +> pm.environment.set("countryId", json.id); +> ``` + +--- + +### 5.6 Update Country + +| Feld | Wert | +|-------------|------------------------------------------------------| +| **Methode** | `PUT` | +| **URL** | `{{baseUrl}}/api/masterdata/countries/{{countryId}}` | +| **Header** | `Content-Type: application/json` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Request Body:** + +```json +{ + "isoAlpha2Code": "TS", + "isoAlpha3Code": "TST", + "isoNumerischerCode": "999", + "nameDeutsch": "Updated Testland", + "nameEnglisch": "Updated Testland", + "istEuMitglied": false, + "istEwrMitglied": false, + "istAktiv": true, + "sortierReihenfolge": 999 +} +``` + +**Erwartete Antwort:** `200 OK` + +--- + +### 5.7 Delete Country + +| Feld | Wert | +|-------------|------------------------------------------------------| +| **Methode** | `DELETE` | +| **URL** | `{{baseUrl}}/api/masterdata/countries/{{countryId}}` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `204 No Content` +**Fehlerfall (nicht gefunden):** `404 Not Found` + +--- + +## 6. Horse Registry (Pferde) + +> **Zweck:** Pferde-Stammdaten verwalten (CRUD). +> **⚠️ Hinweis Tabellen-Name:** In der Datenbank heißt die Tabelle `horse` (englisch), nicht `pferd`. +> **Basis-URL:** `{{baseUrl}}/api/horses` + +--- + +### 6.1 Get All Horses + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/horses` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `200 OK` — Array aller Pferde +**Nach ZNS-Import:** Hier erscheinen alle importierten Pferde. + +--- + +### 6.2 Get Active Horses + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/horses/active` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `200 OK` — Nur Pferde mit `istAktiv: true` + +--- + +### 6.3 Get Horse by ID + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/horses/{{horseId}}` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "id": "uuid-...", + "pferdeName": "Amadeus", + "geschlecht": "WALLACH", + "geburtsdatum": "2020-05-15", + "rasse": "Warmblut", + "farbe": "Braun", + "stockmass": 165, + "istAktiv": true +} +``` + +--- + +### 6.4 Search Horses by Name + +| Feld | Wert | +|-------------|----------------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/horses/search` | +| **Query** | `name=Test` (Suchbegriff), `limit=10` (max.) | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `200 OK` — gefilterte Pferde-Liste +**Wozu:** Echtzeit-Suche in der Desktop-App. Testen mit einem Namen aus dem ZNS-Import. + +--- + +### 6.5 Get Horses by Owner + +| Feld | Wert | +|-------------|--------------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/horses/owner/{{ownerId}}` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `200 OK` — alle Pferde eines bestimmten Besitzers + +--- + +### 6.6 Create Horse + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `POST` | +| **URL** | `{{baseUrl}}/api/horses` | +| **Header** | `Content-Type: application/json` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Request Body:** + +```json +{ + "pferdeName": "Test Horse", + "geschlecht": "WALLACH", + "geburtsdatum": "2020-05-15", + "rasse": "Warmblut", + "farbe": "Braun", + "zuechterName": "Test Breeder", + "stockmass": 165, + "istAktiv": true, + "bemerkungen": "Test horse for API demonstration" +} +``` + +**Gültige Werte für `geschlecht`:** `WALLACH`, `STUTE`, `HENGST` + +**Erwartete Antwort:** `201 Created` + +> **⚡ Tipp:** `horseId` automatisch speichern: +> ```javascript +> var json = pm.response.json(); +> pm.environment.set("horseId", json.id); +> ``` + +--- + +### 6.7 Update Horse + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `PUT` | +| **URL** | `{{baseUrl}}/api/horses/{{horseId}}` | +| **Header** | `Content-Type: application/json` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Request Body:** + +```json +{ + "pferdeName": "Updated Test Horse", + "geschlecht": "WALLACH", + "geburtsdatum": "2020-05-15", + "rasse": "Warmblut", + "farbe": "Dunkelbraun", + "zuechterName": "Updated Test Breeder", + "stockmass": 167, + "istAktiv": true, + "bemerkungen": "Updated test horse for API demonstration" +} +``` + +**Erwartete Antwort:** `200 OK` + +--- + +### 6.8 Delete Horse + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `DELETE` | +| **URL** | `{{baseUrl}}/api/horses/{{horseId}}` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `204 No Content` + +--- + +### 6.9 Batch Delete Horses + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `DELETE` | +| **URL** | `{{baseUrl}}/api/horses/batch` | +| **Header** | `Content-Type: application/json` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Request Body:** + +```json +{ + "horseIds": ["{{horseId1}}", "{{horseId2}}"], + "forceDelete": false +} +``` + +**`forceDelete: false`** → Nur löschen wenn keine Abhängigkeiten vorhanden +**`forceDelete: true`** → Auch bei Abhängigkeiten löschen (⚠️ Vorsicht!) + +**Erwartete Antwort:** `200 OK` + +--- + +### 6.10 Get Horse Statistics + +| Feld | Wert | +|-------------|---------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{baseUrl}}/api/horses/stats` | +| **Header** | `Authorization: Bearer {{authToken}}` | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "total": 42, + "active": 38, + "inactive": 4, + "byGeschlecht": { + "WALLACH": 20, + "STUTE": 18, + "HENGST": 4 + } +} +``` + +**Wozu:** Schnelle Übersicht über den Datenbestand nach dem ZNS-Import. + +--- + +## 7. ZNS Import Service + +> **Zweck:** ZNS-Daten (Reiter, Pferde, Vereine, Funktionäre) aus einer `.zip`/`.dat`-Datei importieren. +> **Direkt-URL:** `{{znsUrl}}` = `http://localhost:8095` +> **Basis-Pfad:** `/api/v1/import/zns` + +--- + +### 7.1 ZNS Import starten + +| Feld | Wert | +|--------------|------------------------------------------| +| **Methode** | `POST` | +| **URL** | `{{znsUrl}}/api/v1/import/zns` | +| **Body-Typ** | `form-data` | +| **Key** | `file` (Type: **File**) | +| **Value** | ZNS-Datei auswählen (`.zip` oder `.dat`) | + +**Schritt-für-Schritt in Postman:** + +1. Methode: `POST` +2. URL: `http://localhost:8095/api/v1/import/zns` +3. Tab **Body** → **form-data** +4. Key: `file` → Typ auf **File** umstellen (Dropdown neben dem Key-Feld) +5. Value: ZNS-Datei auswählen +6. **Send** klicken + +**Erwartete Antwort:** `202 Accepted` + +```json +{ + "jobId": "abc-123-def-456", + "status": "STARTED", + "message": "Import gestartet", + "startedAt": "2026-04-03T14:00:00+02:00" +} +``` + +> **⚡ Tipp:** `jobId` automatisch speichern: +> ```javascript +> var json = pm.response.json(); +> pm.environment.set("znsJobId", json.jobId); +> ``` + +--- + +### 7.2 ZNS Import-Status abfragen + +| Feld | Wert | +|-------------|----------------------------------------------------| +| **Methode** | `GET` | +| **URL** | `{{znsUrl}}/api/v1/import/zns/{{znsJobId}}/status` | +| **Auth** | Keine | + +**Antwort während Import:** `200 OK` + +```json +{ + "jobId": "abc-123-def-456", + "status": "IN_PROGRESS", + "processedRecords": 150, + "totalRecords": 500, + "progressPercent": 30, + "startedAt": "2026-04-03T14:00:00+02:00" +} +``` + +**Antwort nach Abschluss:** `200 OK` + +```json +{ + "jobId": "abc-123-def-456", + "status": "COMPLETED", + "processedRecords": 500, + "totalRecords": 500, + "progressPercent": 100, + "importedReiter": 200, + "importedPferde": 180, + "importedVereine": 30, + "importedFunktionaere": 90, + "startedAt": "2026-04-03T14:00:00+02:00", + "completedAt": "2026-04-03T14:01:30+02:00" +} +``` + +**Mögliche Status-Werte:** + +| Status | Bedeutung | +|---------------|----------------------------------------| +| `STARTED` | Job wurde angenommen, noch nicht aktiv | +| `IN_PROGRESS` | Import läuft gerade | +| `COMPLETED` | Import erfolgreich abgeschlossen | +| `FAILED` | Import fehlgeschlagen (Fehlerdetails) | + +**Wozu:** Status pollen bis `COMPLETED` — dann Daten in pgAdmin oder Desktop-App prüfen. + +--- + +### 7.3 ZNS Import Health-Check + +| Feld | Wert | +|-------------|------------------------------| +| **Methode** | `GET` | +| **URL** | `{{znsUrl}}/actuator/health` | +| **Auth** | Keine | + +**Erwartete Antwort:** `200 OK` + +```json +{ + "status": "UP", + "components": { + "db": { "status": "UP" }, + "diskSpace": { "status": "UP" } + } +} +``` + +**⚠️ Consul-Check:** Nach dem Neustart des ZNS-Service sollte er im Consul-UI unter http://localhost:8500 unter dem +Namen `zns-import-service` erscheinen. + +--- + +## 8. Empfohlene Test-Reihenfolge + +### Schnell-Smoke-Test (5 Minuten) + +``` +1. GET {{pingUrl}}/ping/simple → "pong" ✓ +2. GET {{baseUrl}}/health → "UP" ✓ +3. GET {{znsUrl}}/actuator/health → "UP" ✓ +4. GET {{baseUrl}}/api/masterdata/countries/iso/AT → Österreich ✓ +``` + +### Vollständiger Integrations-Test (heute, ZNS-Import) + +``` +1. GET {{pingUrl}}/ping/simple → Smoke-Test +2. GET {{pingUrl}}/ping/enhanced → Circuit Breaker CLOSED +3. GET {{pingUrl}}/ping/enhanced?simulate=true → Fallback greift +4. POST {{baseUrl}}/auth/login → Token speichern +5. GET {{baseUrl}}/api/masterdata/countries/iso/AT → Stammdaten vorhanden +6. GET {{baseUrl}}/api/horses → (leer vor Import) +7. GET {{znsUrl}}/actuator/health → ZNS bereit +8. POST {{znsUrl}}/api/v1/import/zns → ZNS-Datei hochladen → jobId speichern +9. GET {{znsUrl}}/api/v1/import/zns/{{znsJobId}}/status → Status pollen bis COMPLETED +10. GET {{baseUrl}}/api/horses → Pferde jetzt befüllt ✓ +11. GET {{baseUrl}}/api/horses/stats → Statistiken prüfen +12. GET {{baseUrl}}/api/horses/search?name=... → Suche testen +``` + +--- + +## Anhang: Alle URLs auf einen Blick + +| Service | URL | Verwendung | +|----------------|-----------------------|--------------------------| +| API-Gateway | http://localhost:8081 | Haupt-Einstiegspunkt | +| Ping (direkt) | http://localhost:8082 | Ping-Endpunkte direkt | +| ZNS-Import | http://localhost:8095 | Import-Endpunkte | +| Keycloak Admin | http://localhost:8180 | Auth-Verwaltung | +| Consul UI | http://localhost:8500 | Service-Discovery prüfen | +| Zipkin | http://localhost:9411 | Traces nachverfolgen | +| pgAdmin | http://localhost:8888 | DB-Inhalte prüfen | +| Mailpit | http://localhost:8025 | E-Mail-Mock | diff --git a/docs/04_Agents/Besprechung_2026-04-03/Session_Log_2026-04-03_Nachmittag.md b/docs/04_Agents/Besprechung_2026-04-03/Session_Log_2026-04-03_Nachmittag.md new file mode 100644 index 00000000..01efd426 --- /dev/null +++ b/docs/04_Agents/Besprechung_2026-04-03/Session_Log_2026-04-03_Nachmittag.md @@ -0,0 +1,109 @@ +# 🧹 Session-Log — 3. April 2026 (Nachmittag) + +> **Uhrzeit:** ca. 14:00–14:30 Uhr +> **Thema:** Docker-Fixes, ZNS-Consul-Registrierung, pgAdmin-Provisioning, Postman-Dokumentation +> **Erstellt von:** 🧹 Curator + +--- + +## Was wurde gemacht? + +### 1. 🐧 Dockerfiles korrigiert (Gateway + Ping) + +**Problem:** `docker compose build api-gateway` und `docker compose build ping-service` schlugen fehl, +weil das Builder-Image `gradle:9.4.0-jdk25-alpine` (bzw. `9.3.1-jdk25`) auf Docker Hub nicht existiert. + +**Fixes:** + +- **Builder-Stage** auf `eclipse-temurin:21-jdk-alpine` umgestellt (verfügbar, LTS) +- **`./gradlew`-Wrapper** wird jetzt direkt verwendet statt dem Gradle-Docker-Image +- **`GRADLE_USER_HOME`** von `/home/gradle/.gradle` auf `/root/.gradle` korrigiert (kein `gradle`-User in temurin) +- **Cache-Mount-Paths** entsprechend angepasst +- **Ping-Dockerfile:** 8 fehlende Frontend-Dummy-Verzeichnisse ergänzt: + `veranstalter-feature`, `veranstaltung-feature`, `profile-feature`, `reiter-feature`, + `pferde-feature`, `verein-feature`, `turnier-feature`, `billing-feature` + +**Geänderte Dateien:** + +- `backend/infrastructure/gateway/Dockerfile` +- `backend/services/ping/Dockerfile` + +--- + +### 2. 🔧 ZNS-Import-Service: Consul-Registrierung + +**Problem:** ZNS-Service startete erfolgreich (Health-Check positiv), meldete sich aber nicht bei Consul an. + +**Fixes:** + +- `application.yaml`: `spring.cloud.consul`-Sektion ergänzt (Host, Port, Discovery, Health-Check-Interval) +- `build.gradle.kts`: `implementation(libs.spring.cloud.starter.consul.discovery)` hinzugefügt + +**Geänderte Dateien:** + +- `backend/services/zns-import/zns-import-service/src/main/resources/application.yaml` +- `backend/services/zns-import/zns-import-service/build.gradle.kts` + +> **Nächster Schritt:** ZNS-Service neu starten → in Consul UI unter http://localhost:8500 prüfen ob +`zns-import-service` erscheint. + +--- + +### 3. 🗄️ pgAdmin: Auto-Provisioning + +**Problem:** pgAdmin war nach Login nicht konfiguriert — kein Server, keine Datenbank sichtbar. + +**Fix:** + +- `config/docker/pgadmin/servers.json` erstellt: Verbindung zu `postgres:5432` / `pg-meldestelle-db` vorkonfiguriert +- `dc-ops.yaml`: Volume-Mount `/pgadmin4/servers.json:ro` zum pgAdmin-Service hinzugefügt + +**Geänderte/neue Dateien:** + +- `config/docker/pgadmin/servers.json` *(neu)* +- `dc-ops.yaml` + +> **Hinweis:** pgAdmin-Container neu starten damit die Konfiguration wirksam wird: +> `docker compose --profile tools up -d --force-recreate pgadmin` +> **Hinweis:** Die DB-Tabelle für Pferde heißt `horse` (englisch), nicht `pferd`. + +--- + +### 4. 📋 Postman-Gesamt-Dokumentation + +**Erstellt:** `docs/04_Agents/Besprechung_2026-04-03/Postman_Tests_Dokumentation.md` (930 Zeilen) + +**Enthält:** + +- Environment-Setup (Variablen-Tabelle) +- **8 Endpunkt-Gruppen** mit je Methode, URL, Headers, Request Body, erwarteter Antwort und Erklärung +- **25 Endpunkte** detailliert dokumentiert: System Info, Ping Service (8), Auth (5), Countries (7), Horses (10), ZNS + Import (3) +- Postman-Test-Scripts für automatisches Speichern von `authToken`, `horseId`, `countryId`, `znsJobId` +- Empfohlene Test-Reihenfolge: Schnell-Smoke-Test + Vollständiger ZNS-Integrations-Test + +--- + +## Offene Punkte (nicht diese Session) + +| Punkt | Wer | Prio | +|---------------------------------------------------------------------|------------|----------| +| ZNS-Service neu starten und Consul-Registrierung verifizieren | 👷 Owner | Sofort | +| pgAdmin neu starten und DB-Verbindung prüfen | 👷 Owner | Sofort | +| `docker compose build api-gateway ping-service` erneut testen | 🐧 DevOps | Heute | +| Tabellen-Name `horse` → Klären ob Umbenennung auf `pferd` gewünscht | 👷 Backend | Sprint B | + +--- + +## Dateien dieser Session + +``` +backend/infrastructure/gateway/Dockerfile ← geändert +backend/services/ping/Dockerfile ← geändert +backend/services/zns-import/zns-import-service/build.gradle.kts ← geändert +backend/services/zns-import/zns-import-service/src/main/resources/application.yaml ← geändert +config/docker/pgadmin/servers.json ← neu +dc-ops.yaml ← geändert +docs/04_Agents/Besprechung_2026-04-03/Postman_Tests_Dokumentation.md ← neu +docs/04_Agents/Besprechung_2026-04-03/Session_Log_2026-04-03_Nachmittag.md ← neu (diese Datei) +```