docs: log session outcomes and apply enhancements across multiple components
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Has been cancelled
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Has been cancelled
- **Docker Fixes:** Resolved failed builds for Gateway and Ping services by switching to `eclipse-temurin:21-jdk-alpine`, correcting Gradle configurations, and fixing cache mount paths. - **ZNS-Import Consul Registration:** Enabled Consul service discovery by updating `application.yaml` and `build.gradle.kts`. - **pgAdmin Provisioning:** Preconfigured the database server in `servers.json` and updated `dc-ops.yaml` for seamless setup. - **Postman Documentation:** Added a detailed Postman test guide covering environment setup, endpoint groups, and recommended test sequences. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
# ===================================================================
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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 |
|
||||
@@ -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)
|
||||
```
|
||||
Reference in New Issue
Block a user