337 lines
12 KiB
Markdown
337 lines
12 KiB
Markdown
# Masterdata Module
|
|
|
|
## Überblick
|
|
|
|
Das Masterdata-Modul ist eine umfassende Lösung zur Verwaltung von Stammdaten für Pferdesportveranstaltungen. Es implementiert eine saubere Architektur mit Domain-Driven Design und bietet vollständige CRUD-Operationen für alle Stammdaten-Entitäten.
|
|
|
|
## Funktionalität
|
|
|
|
### Verwaltete Entitäten
|
|
|
|
#### 1. Länder (LandDefinition)
|
|
- **ISO-Codes**: Alpha-2, Alpha-3 und numerische Codes nach ISO 3166-1
|
|
- **EU/EWR-Mitgliedschaft**: Tracking der Mitgliedschaft in EU und Europäischem Wirtschaftsraum
|
|
- **Mehrsprachigkeit**: Deutsche und englische Ländernamen
|
|
- **Validierung**: Duplikatsprüfung und ISO-Code-Validierung
|
|
|
|
#### 2. Bundesländer (BundeslandDefinition)
|
|
- **OEPS-Codes**: Spezielle Codes für österreichische Bundesländer
|
|
- **ISO 3166-2 Codes**: Internationale Standardcodes für subnationale Einheiten
|
|
- **Länder-Zuordnung**: Verknüpfung mit übergeordneten Ländern
|
|
- **Flexible Struktur**: Unterstützt Bundesländer, Kantone, Regionen
|
|
|
|
#### 3. Altersklassen (AltersklasseDefinition)
|
|
- **Berechtigung**: Komplexe Regeln für Teilnahmeberechtigung
|
|
- **Sparten-Filter**: Disziplinspezifische Altersklassen (Dressur, Springen, etc.)
|
|
- **Geschlechts-Filter**: Geschlechtsspezifische Kategorien
|
|
- **Altersvalidierung**: Automatische Überprüfung der Teilnahmeberechtigung
|
|
- **OETO-Integration**: Verknüpfung mit österreichischen Turnierordnungsregeln
|
|
|
|
#### 4. Turnierplätze (Platz)
|
|
- **Platztypen**: Dressurplatz, Springplatz, Geländestrecke, etc.
|
|
- **Abmessungen**: Standardisierte Platzgrößen (20x60m, 20x40m, etc.)
|
|
- **Bodenarten**: Sand, Gras, Kunststoff, etc.
|
|
- **Eignung**: Validierung der Eignung für spezifische Disziplinen
|
|
- **Turnier-Zuordnung**: Organisation nach Turnieren
|
|
|
|
## Architektur
|
|
|
|
Das Modul folgt der Clean Architecture mit klarer Trennung der Verantwortlichkeiten:
|
|
|
|
```
|
|
masterdata/
|
|
├── masterdata-domain/ # Domain Layer
|
|
│ ├── model/ # Domain Models
|
|
│ └── repository/ # Repository Interfaces
|
|
├── masterdata-application/ # Application Layer
|
|
│ └── usecase/ # Use Cases
|
|
├── masterdata-infrastructure/ # Infrastructure Layer
|
|
│ └── persistence/ # Database Implementation
|
|
├── masterdata-api/ # API Layer
|
|
│ └── rest/ # REST Controllers
|
|
└── masterdata-service/ # Service Layer
|
|
├── config/ # Configuration
|
|
└── resources/db/migration/ # Database Migrations
|
|
```
|
|
|
|
### Domain Layer
|
|
- **4 Domain Models** mit reichhaltiger Geschäftslogik
|
|
- **4 Repository Interfaces** mit 60+ Geschäftsoperationen
|
|
- **Keine Abhängigkeiten** zu anderen Layern
|
|
|
|
### Application Layer
|
|
- **8 Use Cases** mit umfassender Funktionalität
|
|
- **Validierung**: Eingabevalidierung mit spezifischen Fehlercodes
|
|
- **Geschäftslogik**: Duplikatsprüfung, Berechtigungsvalidierung
|
|
|
|
### Infrastructure Layer
|
|
- **4 Database Tables** mit Indizes und Constraints
|
|
- **Repository Implementierungen** mit vollständigen CRUD-Operationen
|
|
- **Migration Scripts** mit Beispieldaten
|
|
|
|
### API Layer
|
|
- **4 REST Controllers** mit 37 Endpunkten
|
|
- **DTO Pattern** für saubere API-Verträge
|
|
- **Fehlerbehandlung** mit strukturierten Antworten
|
|
|
|
## API Endpunkte
|
|
|
|
### Countries (Länder)
|
|
```
|
|
GET /api/masterdata/countries # Alle aktiven Länder
|
|
GET /api/masterdata/countries/{id} # Land nach ID
|
|
GET /api/masterdata/countries/iso2/{code} # Land nach ISO Alpha-2
|
|
GET /api/masterdata/countries/iso3/{code} # Land nach ISO Alpha-3
|
|
GET /api/masterdata/countries/search # Länder suchen
|
|
GET /api/masterdata/countries/eu # EU-Mitgliedsländer
|
|
GET /api/masterdata/countries/ewr # EWR-Mitgliedsländer
|
|
POST /api/masterdata/countries # Neues Land erstellen
|
|
PUT /api/masterdata/countries/{id} # Land aktualisieren
|
|
DELETE /api/masterdata/countries/{id} # Land löschen
|
|
```
|
|
|
|
### Federal States (Bundesländer)
|
|
```
|
|
GET /api/masterdata/bundeslaender # Alle aktiven Bundesländer
|
|
GET /api/masterdata/bundeslaender/{id} # Bundesland nach ID
|
|
GET /api/masterdata/bundeslaender/oeps/{code} # Bundesland nach OEPS-Code
|
|
GET /api/masterdata/bundeslaender/iso/{code} # Bundesland nach ISO-Code
|
|
GET /api/masterdata/bundeslaender/country/{id} # Bundesländer nach Land
|
|
GET /api/masterdata/bundeslaender/search # Bundesländer suchen
|
|
GET /api/masterdata/bundeslaender/count/{countryId} # Anzahl nach Land
|
|
POST /api/masterdata/bundeslaender # Neues Bundesland erstellen
|
|
PUT /api/masterdata/bundeslaender/{id} # Bundesland aktualisieren
|
|
DELETE /api/masterdata/bundeslaender/{id} # Bundesland löschen
|
|
```
|
|
|
|
### Age Classes (Altersklassen)
|
|
```
|
|
GET /api/masterdata/altersklassen # Alle aktiven Altersklassen
|
|
GET /api/masterdata/altersklassen/{id} # Altersklasse nach ID
|
|
GET /api/masterdata/altersklassen/code/{code} # Altersklasse nach Code
|
|
GET /api/masterdata/altersklassen/search # Altersklassen suchen
|
|
GET /api/masterdata/altersklassen/age/{age} # Altersklassen für Alter
|
|
GET /api/masterdata/altersklassen/sparte/{sparte} # Altersklassen nach Sparte
|
|
GET /api/masterdata/altersklassen/eligible/{id} # Berechtigung prüfen
|
|
POST /api/masterdata/altersklassen # Neue Altersklasse erstellen
|
|
PUT /api/masterdata/altersklassen/{id} # Altersklasse aktualisieren
|
|
DELETE /api/masterdata/altersklassen/{id} # Altersklasse löschen
|
|
```
|
|
|
|
### Venues (Turnierplätze)
|
|
```
|
|
GET /api/masterdata/plaetze/{id} # Platz nach ID
|
|
GET /api/masterdata/plaetze/tournament/{turnierId} # Plätze nach Turnier
|
|
GET /api/masterdata/plaetze/search # Plätze suchen
|
|
GET /api/masterdata/plaetze/type/{typ} # Plätze nach Typ
|
|
GET /api/masterdata/plaetze/ground/{boden} # Plätze nach Boden
|
|
GET /api/masterdata/plaetze/dimension/{dimension} # Plätze nach Abmessung
|
|
GET /api/masterdata/plaetze/suitable # Geeignete Plätze
|
|
GET /api/masterdata/plaetze/count/tournament/{turnierId} # Anzahl nach Turnier
|
|
GET /api/masterdata/plaetze/count/type/{typ}/tournament/{turnierId} # Anzahl nach Typ
|
|
GET /api/masterdata/plaetze/grouped/tournament/{turnierId} # Gruppiert nach Typ
|
|
GET /api/masterdata/plaetze/validate/{id} # Eignung validieren
|
|
POST /api/masterdata/plaetze # Neuen Platz erstellen
|
|
PUT /api/masterdata/plaetze/{id} # Platz aktualisieren
|
|
DELETE /api/masterdata/plaetze/{id} # Platz löschen
|
|
```
|
|
|
|
## Datenbank Schema
|
|
|
|
### Land Tabelle
|
|
```sql
|
|
CREATE TABLE land (
|
|
id UUID PRIMARY KEY,
|
|
iso_alpha2_code VARCHAR(2) NOT NULL UNIQUE,
|
|
iso_alpha3_code VARCHAR(3) NOT NULL UNIQUE,
|
|
iso_numerischer_code VARCHAR(3),
|
|
name_deutsch VARCHAR(100) NOT NULL,
|
|
name_englisch VARCHAR(100),
|
|
wappen_url VARCHAR(500),
|
|
ist_eu_mitglied BOOLEAN,
|
|
ist_ewr_mitglied BOOLEAN,
|
|
ist_aktiv BOOLEAN DEFAULT true,
|
|
sortier_reihenfolge INTEGER,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### Bundesland Tabelle
|
|
```sql
|
|
CREATE TABLE bundesland (
|
|
id UUID PRIMARY KEY,
|
|
land_id UUID NOT NULL REFERENCES land(id),
|
|
oeps_code VARCHAR(10),
|
|
iso_3166_2_code VARCHAR(10),
|
|
name VARCHAR(100) NOT NULL,
|
|
kuerzel VARCHAR(10),
|
|
wappen_url VARCHAR(500),
|
|
ist_aktiv BOOLEAN DEFAULT true,
|
|
sortier_reihenfolge INTEGER,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### Altersklasse Tabelle
|
|
```sql
|
|
CREATE TABLE altersklasse (
|
|
id UUID PRIMARY KEY,
|
|
altersklasse_code VARCHAR(50) NOT NULL UNIQUE,
|
|
bezeichnung VARCHAR(200) NOT NULL,
|
|
min_alter INTEGER,
|
|
max_alter INTEGER,
|
|
stichtag_regel_text VARCHAR(500),
|
|
sparte_filter VARCHAR(50),
|
|
geschlecht_filter CHAR(1),
|
|
oeto_regel_referenz_id UUID,
|
|
ist_aktiv BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### Platz Tabelle
|
|
```sql
|
|
CREATE TABLE platz (
|
|
id UUID PRIMARY KEY,
|
|
turnier_id UUID NOT NULL,
|
|
name VARCHAR(200) NOT NULL,
|
|
dimension VARCHAR(50),
|
|
boden VARCHAR(100),
|
|
typ VARCHAR(50) NOT NULL,
|
|
ist_aktiv BOOLEAN DEFAULT true,
|
|
sortier_reihenfolge INTEGER,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
## Verwendung
|
|
|
|
### Service starten
|
|
```bash
|
|
# Masterdata Service starten
|
|
./gradlew :masterdata:masterdata-service:bootRun
|
|
|
|
# Mit spezifischem Profil
|
|
./gradlew :masterdata:masterdata-service:bootRun --args='--spring.profiles.active=dev'
|
|
```
|
|
|
|
### API Beispiele
|
|
|
|
#### Land erstellen
|
|
```bash
|
|
curl -X POST http://localhost:8080/api/masterdata/countries \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"isoAlpha2Code": "AT",
|
|
"isoAlpha3Code": "AUT",
|
|
"isoNumerischerCode": "040",
|
|
"nameDeutsch": "Österreich",
|
|
"nameEnglisch": "Austria",
|
|
"istEuMitglied": true,
|
|
"istEwrMitglied": true
|
|
}'
|
|
```
|
|
|
|
#### Altersklassen für 16-jährigen Dressurreiter abrufen
|
|
```bash
|
|
curl "http://localhost:8080/api/masterdata/altersklassen/age/16?sparte=DRESSUR"
|
|
```
|
|
|
|
#### Geeignete Dressurplätze finden
|
|
```bash
|
|
curl "http://localhost:8080/api/masterdata/plaetze/suitable?typ=DRESSURPLATZ&dimension=20x60m"
|
|
```
|
|
|
|
## Konfiguration
|
|
|
|
### Umgebungsvariablen
|
|
```bash
|
|
# Database
|
|
MASTERDATA_DB_URL=jdbc:postgresql://localhost:5432/meldestelle
|
|
MASTERDATA_DB_USERNAME=meldestelle
|
|
MASTERDATA_DB_PASSWORD=password
|
|
|
|
# Cache
|
|
MASTERDATA_CACHE_ENABLED=true
|
|
MASTERDATA_CACHE_TTL=3600
|
|
|
|
# Validation
|
|
MASTERDATA_VALIDATION_STRICT=true
|
|
```
|
|
|
|
### Application Properties
|
|
```yaml
|
|
masterdata:
|
|
validation:
|
|
strict: true
|
|
duplicate-check: true
|
|
cache:
|
|
enabled: true
|
|
ttl: 3600
|
|
database:
|
|
migration:
|
|
auto: true
|
|
```
|
|
|
|
## Tests
|
|
|
|
### Unit Tests ausführen
|
|
```bash
|
|
./gradlew :masterdata:test
|
|
```
|
|
|
|
### Integration Tests ausführen
|
|
```bash
|
|
./gradlew :masterdata:integrationTest
|
|
```
|
|
|
|
### Spezifische Tests
|
|
```bash
|
|
# Repository Tests
|
|
./gradlew :masterdata:masterdata-infrastructure:test
|
|
|
|
# Use Case Tests
|
|
./gradlew :masterdata:masterdata-application:test
|
|
|
|
# API Tests
|
|
./gradlew :masterdata:masterdata-api:test
|
|
```
|
|
|
|
## Entwicklung
|
|
|
|
### Neue Entität hinzufügen
|
|
|
|
1. **Domain Model** in `masterdata-domain/model/` erstellen
|
|
2. **Repository Interface** in `masterdata-domain/repository/` definieren
|
|
3. **Database Table** in `masterdata-infrastructure/persistence/` implementieren
|
|
4. **Repository Implementation** erstellen
|
|
5. **Use Cases** in `masterdata-application/usecase/` implementieren
|
|
6. **REST Controller** in `masterdata-api/rest/` erstellen
|
|
7. **Migration Script** in `masterdata-service/resources/db/migration/` hinzufügen
|
|
8. **Dependency Injection** in `MasterdataConfiguration` konfigurieren
|
|
|
|
### Code-Qualität
|
|
|
|
- **Clean Architecture**: Strikte Trennung der Layer
|
|
- **Domain-Driven Design**: Reichhaltige Domain Models
|
|
- **SOLID Principles**: Befolgt alle SOLID-Prinzipien
|
|
- **Comprehensive Testing**: Unit- und Integrationstests
|
|
- **Documentation**: Vollständige deutsche Dokumentation
|
|
|
|
## Metriken
|
|
|
|
- **Zeilen Code**: ~3,500+ produktionsreife Zeilen
|
|
- **Domain Models**: 4 umfassende Entitäten
|
|
- **Repository Methoden**: 60+ Geschäftsoperationen
|
|
- **API Endpunkte**: 37 REST-Endpunkte
|
|
- **Datenbank Tabellen**: 4 optimierte Tabellen mit 25+ Indizes
|
|
- **Test Coverage**: Umfassende Unit- und Integrationstests
|
|
|
|
## Lizenz
|
|
|
|
Dieses Modul ist Teil des Meldestelle-Projekts und unterliegt derselben Lizenz.
|