feat(horses-service): remove legacy configuration and repository classes
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 7m12s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 6m42s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Successful in 6m28s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m51s

- Deleted outdated `ApplicationConfiguration` and `HorseRepositoryImpl` classes.
- Migrated to streamlined modular Gradle configuration in `build.gradle.kts`.
- Updated domain models and dependencies to use multiplatform and serialization plugins.
- Added modular setup for `horses` namespace in `settings.gradle.kts`.
- Reorganized database configuration with minimal JDBC bindings for development.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-03-23 13:47:04 +01:00
parent 7b35831d8c
commit c53daa926a
44 changed files with 75781 additions and 530 deletions
@@ -0,0 +1,261 @@
---
type: Log
agent: Curator
date: 2026-03-23
status: COMPLETED
topics:
- ZNS-Importer
- Backend-Services
- Dev-Seeder
- Testdaten
---
# 🧹 Session Log: 23. März 2026 ZNS-Importer & Backend-Services
## Zusammenfassung
Diese Session hatte das Ziel, **echte Testdaten aus dem ZNS-System (Zentrales Nennsystem des OEPS)** für die
Frontend-Entwicklung bereitzustellen. Dazu wurden vier Backend-Services aufgebaut, die die ZNS-Rohdaten
(Fixbreiten-Flat-Files) in eine lokale PostgreSQL-Datenbank importieren.
---
## Kontext: Was ist ZNS?
Das **ZNS (Zentrales Nennsystem)** ist das Stammdaten-System des OEPS (Österreichischer Pferdesport-Verband).
Es liefert Rohdaten als **Fixbreiten-Flat-Files** (`.dat`) ein klassisches Format älterer Verbandssysteme.
Die Rohdaten liegen unter: `docs/OePS/ZNS/`
| Datei | Inhalt | Datensätze |
|----------------------|-----------------------------------|------------|
| `PFERDE01.dat` | Pferde-Stammdaten | ~tausende |
| `LIZENZ01.dat` | Reiter / Personen / Lizenzen | ~tausende |
| `VEREIN01.dat` | Vereine / Clubs | ~hunderte |
| `RICHT01.dat` | Richter / Offizielle | ~hunderte |
| `ISLANDPFERDE01.dat` | Islandpferde (separates Register) | |
| `VOLT01.dat` | Voltigier-Daten | |
---
## Was wurde gebaut?
### Strategische Entscheidung: Dev-Seeder, kein Produktions-Importer
Es wurde bewusst **kein produktiver Import-Service** gebaut, sondern ein **Dev-Seeder** (`@Profile("dev")`).
Das bedeutet:
- Der Seeder läuft **nur im `dev`-Profil** nie in Produktion
- Die Tabellen tragen das Präfix `zns_` klar erkennbar als Import-Rohdaten
- Der Seeder ist **wegwerfbar** der saubere Produktions-Importer folgt in Phase 3
### Vier neue Backend-Services
Alle Services folgen der gleichen Struktur wie der bestehende `horses`-Service:
```
backend/services/
├── horses/ ✅ Pferde (PFERDE01.dat → zns_horses)
├── persons/ ✅ Personen (LIZENZ01.dat → zns_persons)
├── clubs/ ✅ Vereine (VEREIN01.dat → zns_clubs)
└── officials/ ✅ Richter (RICHT01.dat → zns_officials)
```
Jeder Service besteht aus drei Modulen:
| Modul | Inhalt |
|--------------------|-------------------------------------------------------------------|
| `*-domain` | Domain-Modell (`DomPferd`, `DomPerson`, `DomClub`, `DomOfficial`) |
| `*-infrastructure` | Datenbank-Tabelle (`ZnsHorseTable`, `ZnsPersonTable`, etc.) |
| `*-service` | Spring Boot App + `DatabaseConfiguration` + `ZnsXxxSeeder` |
### Datenbank-Tabellen (ZNS-Präfix)
| Service | Tabelle | Quelle |
|---------------------|-----------------|----------------|
| `horses-service` | `zns_horses` | `PFERDE01.dat` |
| `persons-service` | `zns_persons` | `LIZENZ01.dat` |
| `clubs-service` | `zns_clubs` | `VEREIN01.dat` |
| `officials-service` | `zns_officials` | `RICHT01.dat` |
Das `zns_`-Präfix macht sofort klar: **Diese Daten kommen aus dem ZNS-Import** und sind noch nicht das
saubere Domain-Modell.
### Fixbreiten-Parser
Jeder Seeder enthält einen eigenen Fixbreiten-Parser für das jeweilige `.dat`-Format.
Beispiel `LIZENZ01.dat` (220 Zeichen pro Zeile):
```
[0-5] LizenzNr
[6-55] Nachname
[56-80] Vorname
[81-83] VereinsNr
[84-133] VereinsName
[134-136] Nation
[137-143] LizenzKlasse (R1, R2, RD2, ...)
[144-156] MitgliedsNr
[170] Geschlecht (M/W)
[171-178] Geburtsdatum (YYYYMMDD)
```
---
## Betriebsanleitung: So startest du die Services
### Voraussetzungen
1. **PostgreSQL läuft lokal** (via Docker Compose):
```bash
docker compose -f dc-infra.yaml up -d
```
Standard-Verbindung: `jdbc:postgresql://localhost:5432/meldestelle` (User/PW: `meldestelle`)
2. **ZNS-Dateien sind vorhanden** unter `docs/OePS/ZNS/`
```
docs/OePS/ZNS/
├── PFERDE01.dat
├── LIZENZ01.dat
├── VEREIN01.dat
└── RICHT01.dat
```
### Service starten & Daten importieren
Jeden Service **einmalig** mit dem `dev`-Profil starten. Der Seeder läuft automatisch beim Start.
```bash
# Pferde importieren (PFERDE01.dat → zns_horses)
ZNS_DATA_DIR=$(pwd)/docs/OePS/ZNS \
./gradlew :horses:horses-service:bootRun \
--args='--spring.profiles.active=dev'
# Personen/Reiter importieren (LIZENZ01.dat → zns_persons)
ZNS_DATA_DIR=$(pwd)/docs/OePS/ZNS \
./gradlew :persons:persons-service:bootRun \
--args='--spring.profiles.active=dev'
# Vereine importieren (VEREIN01.dat → zns_clubs)
ZNS_DATA_DIR=$(pwd)/docs/OePS/ZNS \
./gradlew :clubs:clubs-service:bootRun \
--args='--spring.profiles.active=dev'
# Richter importieren (RICHT01.dat → zns_officials)
ZNS_DATA_DIR=$(pwd)/docs/OePS/ZNS \
./gradlew :officials:officials-service:bootRun \
--args='--spring.profiles.active=dev'
```
> **Hinweis:** Die Services können nach dem Import wieder gestoppt werden (`Ctrl+C`).
> Die Daten bleiben in der PostgreSQL-Datenbank erhalten.
### Datenbank-Verbindung prüfen (optional)
```bash
# Direkt via psql
psql -h localhost -U meldestelle -d meldestelle -c "SELECT COUNT(*) FROM zns_horses;"
psql -h localhost -U meldestelle -d meldestelle -c "SELECT COUNT(*) FROM zns_persons;"
psql -h localhost -U meldestelle -d meldestelle -c "SELECT COUNT(*) FROM zns_clubs;"
psql -h localhost -U meldestelle -d meldestelle -c "SELECT COUNT(*) FROM zns_officials;"
```
### Datenbank zurücksetzen (neu seeden)
Falls die DB neu aufgesetzt werden muss (z.B. nach Schema-Änderungen):
```bash
# Tabellen droppen (in psql)
psql -h localhost -U meldestelle -d meldestelle -c "
DROP TABLE IF EXISTS zns_horses, zns_persons, zns_clubs, zns_officials;
"
# Dann Services neu starten (siehe oben) Tabellen werden automatisch neu angelegt
```
---
## Für das Frontend: Wie kommen die Daten an?
### Aktueller Stand (Dev-Phase)
Die Daten liegen in der **lokalen PostgreSQL-DB**. Das Frontend kann sie über die jeweiligen
Service-APIs abrufen sobald die REST-Endpoints implementiert sind.
> **Nächster Schritt für das Frontend-Team:**
> Die Services haben noch **keine REST-API** (kein `-api`-Modul aktiv).
> Für schnellen Datenzugriff kann das Frontend direkt die DB abfragen (via Backend-Gateway)
> oder die API-Module werden als nächstes aktiviert.
### Empfohlene Reihenfolge für die nächsten Schritte
| Priorität | Aufgabe | Service |
|-----------|--------------------------------|--------------------------------------|
| 🔴 Hoch | REST-API für Pferde-Abfrage | `horses-api` aktivieren |
| 🔴 Hoch | REST-API für Personen-Abfrage | `persons-api` bauen |
| 🟡 Mittel | REST-API für Vereine | `clubs-api` bauen |
| 🟡 Mittel | REST-API für Richter | `officials-api` bauen |
| 🟢 Später | Produktions-Importer (Phase 3) | `ZnsImportService` mit REST-Endpoint |
---
## Technische Details
### Gradle-Module (settings.gradle.kts)
```kotlin
// Alle vier Services sind registriert:
include(":horses:horses-domain")
include(":horses:horses-infrastructure")
include(":horses:horses-service")
include(":persons:persons-domain")
include(":persons:persons-infrastructure")
include(":persons:persons-service")
include(":clubs:clubs-domain")
include(":clubs:clubs-infrastructure")
include(":clubs:clubs-service")
include(":officials:officials-domain")
include(":officials:officials-infrastructure")
include(":officials:officials-service")
```
### Build-Verifikation
```bash
./gradlew \
:horses:horses-service:compileKotlin \
:horses:horses-infrastructure:compileKotlin \
:horses:horses-domain:compileKotlinJvm \
:persons:persons-domain:compileKotlinJvm \
:persons:persons-infrastructure:compileKotlin \
:persons:persons-service:compileKotlin \
:clubs:clubs-domain:compileKotlinJvm \
:clubs:clubs-infrastructure:compileKotlin \
:clubs:clubs-service:compileKotlin \
:officials:officials-domain:compileKotlinJvm \
:officials:officials-infrastructure:compileKotlin \
:officials:officials-service:compileKotlin
# → BUILD SUCCESSFUL ✅
```
### Bekannte Einschränkungen / ON HOLD
| Modul | Status | Grund |
|----------------------|---------|----------------------------------------|
| `horses-api` | ON HOLD | Ktor-basiert, wird separat aktiviert |
| `horses-common` | ON HOLD | Veraltete API-Referenzen |
| `entries-service` | ON HOLD | Pausiert bis Domain-Workshop (Phase 3) |
| Produktions-Importer | GEPLANT | Phase 3 nach Domain-Workshop |
---
## Erreichte Meilensteine dieser Session
- ✅ `ZnsDataSeeder` für `horses` gebaut (PFERDE01.dat → `zns_horses`)
- ✅ `ZnsPersonSeeder` für `persons` gebaut (LIZENZ01.dat → `zns_persons`)
- ✅ `ZnsClubSeeder` für `clubs` gebaut (VEREIN01.dat → `zns_clubs`)
- ✅ `ZnsOfficialSeeder` für `officials` gebaut (RICHT01.dat → `zns_officials`)
- ✅ Alle Tabellen einheitlich mit `zns_`-Präfix benannt
- ✅ Alle vier Services kompilieren erfolgreich (BUILD SUCCESSFUL)
- ✅ `settings.gradle.kts` vollständig aktualisiert