feat(docs): expand masterdata documentation with Reiter- and Pferdeprüfungen

- Added `REITER_PRUEFUNGEN.md` and `PFERDEPRUEFUNGEN_BEWERTUNG.md` to document evaluation criteria, scoring logic, and system requirements for dressage and show jumping.
- Updated `README.md` with links to new documentation on rider- and horse-specific regulations.
- Created database schemas for `TurnierklasseTable`, `RichtverfahrenTable`, `GebuehrTable`, `LicenseTable`, and `RegulationConfigTable`, aligning with ÖTO 2026.
- Logged architectural decisions and analysis in `session-logs` and created ADRs `0017-masterdata-importer-worker` and `0019-api-ingestion-layers`.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-03-30 14:29:55 +02:00
parent 6375ec23c3
commit e8757c5c32
29 changed files with 1663 additions and 18 deletions
+7
View File
@@ -59,8 +59,15 @@ Die APIs sind unter `/api/v1/masterdata/...` erreichbar.
Sämtliche Stammdaten (insbesondere Altersklassen und Sparten) sind strikt nach dem **ÖTO (Österreichische
Turnierordnung)** Regelwerk modelliert. Detaillierte Aufstellungen der verwendeten Definitionen finden sich hier:
* [Strategische Roadmap](docs/ROADMAP.md) (Phasen, Meilensteine, Verantwortlichkeiten)
* [ÖTO-Stammdaten Dokumentation](docs/OETO_STAMMDATEN.md) (Fachliche Logik)
* [Turnier-Sparten & Klassen](docs/TURNIER_KLASSEN.md) (Detaillierte Übersicht Springen/Dressur & C-NEU)
* [Reiter-Lizenzen & Startberechtigungen](docs/REITER_LIZENZEN.md) (Lizenzstufen & Sportliche Relevanz)
* [Richter & Parcoursbauer Qualifikationen](docs/FUNKTIONAERE_QUALIFIKATIONEN.md) (Befugnisse & Einsatzvorgaben)
* [Gebührenordnung ÖTO 2026](docs/GEBUEHRENORDNUNG.md) (Nenn-/Startgelder & Geldpreise)
* [Pferdeprüfungen (Jungpferde)](docs/PFERDEPRUEFUNGEN.md) (Dressur-/Springpferdeprotokolle)
* [Pferdeprüfungen (Bewertungssystem)](docs/PFERDEPRUEFUNGEN_BEWERTUNG.md) (Abzugslogik & qualitative Noten)
* [Reiter-Prüfungen (Dressur & Stilspringen)](docs/REITER_PRUEFUNGEN.md) (Fokus auf Sitz & Einwirkung)
* [ZNS-Schnittstellen Spezifikation](docs/ZNS_SCHNITTSTELLE.md) (Technisches Transfer-Format)
Änderungen am Regelwerk müssen hier zentral eingepflegt werden, damit sie
@@ -0,0 +1,96 @@
# 🧐 Qualifikationen: Richter & Parcoursbauer (Funktionäre)
Diese Dokumentation beschreibt die Qualifikationsstufen und technischen Anforderungen für Funktionäre (Richter,
Parcoursbauer, Stewards) basierend auf der ÖTO 2026 und dem ZNS-Pflichtenheft v2.4.
---
## 1. Fachliche Qualifikationsstufen
Die Befugnisse der Funktionäre richten sich nach der offiziellen Richterliste des OEPS (§ 48 A-Teil).
### 1.1 Richter (Sparte Dressur & Springen)
Richter werden in unterschiedliche Klassen eingeteilt, die festlegen, bis zu welcher Kategorie und Klasse sie richten
dürfen.
| Kürzel | Bezeichnung | Befugnis (Beispiel) |
|:--------|:--------------|:--------------------------------------------|
| **D** | Dressur | Allgemeine Dressurbewerbe |
| **S** | Springen | Allgemeine Springbewerbe |
| **DPF** | Dressurpferde | Zusatzqualifikation für Jungpferdeprüfungen |
| **SPF** | Springpferde | Zusatzqualifikation für Jungpferdeprüfungen |
| **G** | Gelände | Vielseitigkeit (CCN) |
| **STW** | Steward | Aufsicht am Abreiteplatz |
### 1.2 Parcoursbauer (Sparte Springen)
Die Qualifikation der Parcoursbauer wird in Level (P) angegeben (§ 1965 B-Teil).
| Level | Bezeichnung | Einsatzbereich |
|:-------|:----------------|:----------------------------------------------|
| **P1** | Einsteiger | Verpflichtend für CSN-C-NEU Turniere |
| **P2** | Fortgeschritten | Turniere der Kategorie C und B |
| **P3** | National | Turniere der Kategorie B* und A |
| **P4** | Grand Prix | Turniere der Kategorie A* und Meisterschaften |
---
## 2. Einsatzvorgaben (Regelwerk)
### 2.1 Mindestbesetzung (§ 50 A-Teil)
* **Standard:** Mindestens zwei Richter pro Bewerb.
* **Ausnahme (CDN Kl. A / CSN bis 120 cm):** Ein Richter zulässig (bei Kat. B/C).
* **CSN-C-NEU:**
* Mindestens zwei Richter.
* Mindestens ein Parcoursbauer Level **P1**.
* **Pferdeprüfungen:** Mindestens ein Richter der Gruppe muss die Zusatzqualifikation **SPF** (Springen) oder **DPF** (
Dressur) besitzen.
### 2.2 Zeitlimits (§ 50 Abs. 7 A-Teil)
* Maximal **10 Stunden** Einsatz pro Tag.
* Nach 4 Stunden: Mindestens **45 Minuten Pause**.
* Bei beurteilendem Richtverfahren (Dressur): Maximal **7 Stunden** reine Richtzeit.
---
## 3. Technische Umsetzung (ZNS-Schnittstelle)
Die Daten werden über die Datei `RICHT01.dat` (Teil der `ZNS.zip`) importiert.
### 3.1 Dateistruktur (RICHT01.dat)
#### Richter (X-Satz)
| Feld | Stelle | Länge | Typ | Beschreibung |
|:--------------------|:-------|:------|:------|:---------------------------------------|
| **ID** | 1 | 1 | Alpha | Wert "X" |
| **SATZNUMMER** | 2 | 6 | Num | Eindeutige OEPS-ID (000000) |
| **NAME** | 8 | 75 | Alpha | Familienname, Vorname |
| **QUALIFIKATIONEN** | 83 | 30 | Alpha | Komma-getrennte Codes (z.B. "D,S,SPF") |
#### Parcoursbauer (Y-Satz)
| Feld | Stelle | Länge | Typ | Beschreibung |
|:--------------------|:-------|:------|:------|:-------------------------------------|
| **ID** | 1 | 1 | Alpha | Wert "Y" |
| **SATZNUMMER** | 2 | 6 | Num | Eindeutige OEPS-ID (000000) |
| **NAME** | 8 | 75 | Alpha | Familienname, Vorname |
| **QUALIFIKATIONEN** | 83 | 30 | Alpha | Komma-getrennte Codes (z.B. "P1,P2") |
---
## 4. Validierungs-Logik im System
Der `masterdata` Service muss beim Import und bei der Turnierplanung folgende Prüfungen ermöglichen:
1. **Existenzprüfung:** Ist die Satznummer in der aktuellen ZNS-Liste vorhanden?
2. **Qualifikations-Check:** Verfügt der Richter über die für den Bewerb erforderliche Kennung (z.B. SPF für
Springpferdeprüfungen)?
3. **Level-Check:** Erfüllt der Parcoursbauer das Mindestlevel (P1) für C-NEU Turniere?
---
> 📜 **Rulebook Expert Hinweis:** Die Qualifikations-Codes in `RICHT01.dat` sind der Primärschlüssel für die
> automatisierte Prüfung der Richtereinteilung in der Ausschreibung.
@@ -0,0 +1,117 @@
# 💰 Gebührenordnung (ÖTO 2026) Dressur & Springen
Dieses Dokument fasst die für die Sparten **Dressur (CDN)** und **Springen (CSN)** relevanten Gebühren,
Nenn-/Startgelder sowie Mindest-Geldpreise basierend auf der **ÖTO 2026 (Teil E)** zusammen.
---
## 1. Nenn- und Startgelder (§ 5 Gebührenordnung)
Die Gebühren setzen sich aus einem Nenngeld (pro Pferd/Turnier) und einem Startgeld (pro Bewerb) zusammen.
### 1.1 Nenngeld (Fixe Gebühr pro Turnier)
| Kategorie | Typ | Gebühr (EUR) |
|:------------------------|:----------|:----------------|
| **Bewerbe ohne Lizenz** | - | *Kein Nenngeld* |
| **Eintages-Turniere** | Alle | 16,00 |
| **Kat. C / C-NEU** | Mehrtägig | 25,00 30,00 |
| **Kat. B / B*** | Mehrtägig | 25,00 35,00 |
| **Kat. A / A*** | Mehrtägig | 25,00 50,00 |
| **Meisterschaften** | Mehrtägig | 25,00 35,00 |
### 1.2 Startgeld (Pro Bewerb)
| Bewerbstyp | Kategorie | Max. Startgeld (EUR) |
|:------------------------------------------|:-----------------|:-------------------------------------------|
| **Bewerbe ohne Geldpreis** | Alle | 20,00 |
| **Bewerbe für Reiter ohne Lizenz** | Alle | 20,00 |
| **Bewerbe mit Geldpreis** | Alle | max. 50% des letztausgezahlten Geldpreises |
| **C-NEU Turniere** | Dressur/Springen | max. 20,00 |
| **Dressur-Aufpreis (getrenntes Richten)** | 3 Richter | + max. 8,00 |
| **Dressur-Aufpreis (getrenntes Richten)** | > 3 Richter | + max. 12,00 |
| **Springen Warmup** | Vortag | max. 15,00 |
| **Pony/Führzügel/First Ridden** | - | max. 15,00 |
### 1.3 Zusatzabgaben pro Start
* **Tierwohleuro:** 1,00 EUR (nur bei Springen/Vielseitigkeit/Fahren/Distanz).
* **Sportförderbeitrag:** 1,00 EUR (NICHT bei C-NEU, Pony, Führzügel, First Ridden).
---
## 2. Mindest-Geldpreise & Startgelder (§ 7 Gebührenordnung)
Geldpreise sind in den Kategorien A und B verpflichtend (sofern ausgeschrieben). Bei Kat. C sind Mindestwerte
festgelegt.
### 2.1 Dressur (CDN) Mindest-Geldpreise (EUR)
*Werte für Platz 1 bis 6 und das restliche erste Viertel.*
| Kategorie | Klasse | 1. | 2. | 3. | 4. | 5. | 6. | ab 7. | Max. Startgeld |
|:-----------|:-------|:----|:----|:----|:----|:---|:---|:------|:---------------|
| **Kat. A** | L | 105 | 80 | 65 | 50 | 42 | 42 | 42 | 21 |
| **Kat. A** | LM | 150 | 115 | 90 | 70 | 50 | 42 | 42 | 21 |
| **Kat. A** | M | 220 | 175 | 140 | 105 | 70 | 50 | 42 | 21 |
| **Kat. A** | S | 250 | 210 | 140 | 105 | 80 | 60 | 42 | 21 |
| **Kat. B** | A | 70 | 55 | 40 | 36 | 36 | 36 | 36 | 21 |
| **Kat. B** | L | 85 | 65 | 55 | 42 | 42 | 42 | 42 | 21 |
| **Kat. B** | LM | 125 | 100 | 80 | 60 | 42 | 42 | 42 | 21 |
| **Kat. B** | M | 165 | 135 | 110 | 80 | 55 | 42 | 42 | - |
| **Kat. B** | S | 220 | 175 | 140 | 105 | 70 | 50 | 42 | - |
| **Kat. C** | A | 40 | 35 | 30 | 26 | 26 | 26 | 26 | 13 |
| **Kat. C** | L | 65 | 55 | 40 | 36 | 36 | 36 | 36 | 18 |
| **Kat. C** | LM | 85 | 70 | 55 | 42 | 42 | 42 | 42 | 21 |
### 2.2 Springen (CSN) Mindest-Geldpreise (EUR)
*Werte basierend auf der Hindernishöhe.*
| Kategorie | Höhe (cm) | 1. | 2. | 3. | 4. | 5. | 6. | ab 7. | Max. Startgeld |
|:-----------|:----------|:----|:----|:----|:----|:----|:----|:------|:---------------|
| **Kat. A** | 115/120 | 160 | 140 | 115 | 90 | 70 | 45 | 42 | 21 |
| **Kat. A** | 125/130 | 185 | 160 | 140 | 115 | 70 | 46 | 46 | 23 |
| **Kat. A** | 135 | 250 | 210 | 160 | 115 | 90 | 70 | 46 | 23 |
| **Kat. A** | 140 | 380 | 310 | 210 | 155 | 120 | 85 | 58 | 29 |
| **Kat. A** | 145 | 450 | 345 | 275 | 210 | 140 | 86 | 58 | 29 |
| **Kat. A** | 150/160 | 520 | 400 | 310 | 240 | 170 | 120 | 58 | 29 |
| **Kat. B** | 105/110 | 70 | 55 | 40 | 36 | 36 | 36 | 36 | 18 |
| **Kat. B** | 115/120 | 140 | 115 | 90 | 70 | 45 | 42 | 42 | 21 |
| **Kat. B** | 125/130 | 160 | 140 | 115 | 90 | 70 | 46 | 46 | 23 |
| **Kat. B** | 135 | 185 | 160 | 140 | 115 | 70 | 46 | 46 | 23 |
| **Kat. B** | 140 | 255 | 205 | 160 | 115 | 90 | 70 | 46 | 23 |
---
## 3. Aufwendungen für Funktionäre (§ 8 Gebührenordnung)
Vergütungen für Richter, Stewards und Parcoursbauer.
### 3.1 Tagessätze (Richtsätze)
* **Standard-Tagessatz:** 120,00 EUR (Steward, Richter, Parcoursbauer).
* **Sonderprüfungen (Abzeichen):** 100,00 EUR.
* **Halbtagessatz (bis 4 Std.):** 60,00 EUR.
* **Unkostenbeitrag Turnierbeauftragter:** 30,00 EUR / Tag.
* **Unkostenbeitrag Parcoursbauer (Kat. B/C):** 22,00 EUR / Tag.
* **Unkostenbeitrag Parcoursbauer (Kat. A+):** 30,00 EUR / Tag.
* **Turniertierarzt:** 350,00 EUR / Tag (exkl. MwSt.).
* **Assistent Parcoursbauer:** 50,00 EUR / Tag (inkl. Reisekosten).
### 3.2 Reise- und Aufenthaltskosten
* **PKW-Kilometergeld:** 0,50 EUR / km.
* **Bahnfahrt:** 1. Klasse Ticket.
* **Unterkunft:** Zimmer mit Dusche/WC inklusive Frühstück.
---
## 4. Sonstige Gebühren
* **Nachnenngebühr (an OEPS):** 25,00 EUR.
* **Tausch Nennung (Pferd/Reiter):** 15,00 EUR.
* **ZNS-Gebühr pro Pferd:** 5,00 EUR.
* **Boxengebühr (bei Boxenpflicht):** max. 130,00 EUR.
* **Endreinigung Box:** max. 30,00 EUR.
* **Reinigungsgebühr (Tagesgäste ohne Box):** max. 10,00 EUR / Pferd.
@@ -29,13 +29,13 @@ Die Klassen definieren die maximale Hindernishöhe (§ 200 B-Teil).
| Klasse | Bezeichnung | Höhe (cm) | Zulässige Turnier-Kategorien |
|:--------|:--------------------|:----------|:-----------------------------|
| **E0** | Einsteiger | 60 95 | C-NEU, C, B |
| **A** | Leicht | 105 110 | Alle (A erst ab Kat. B/A) |
| **L** | Mittelleicht | 115 120 | Alle |
| **LM** | Leicht-Mittelschwer | 125 130 | Alle |
| **M** | Mittelschwer | 135 | B, B*, A, A* |
| **S*** | Schwer | 140 145 | B*, A, A* |
| **S**** | Schwer (GP) | 150 160 | A* |
| **E0** | Einsteiger | 60 95 | C-NEU, C, B | Inkl. lizenzfrei (Reiterpass) |
| **A** | Leicht | 105 110 | Alle (A erst ab Kat. B/A) | - |
| **L** | Mittelleicht | 115 120 | Alle | - |
| **LM** | Leicht-Mittelschwer | 125 130 | Alle | - |
| **M** | Mittelschwer | 135 | B, B*, A, A* | - |
| **S*** | Schwer | 140 145 | B*, A, A* | - |
| **S**** | Schwer (GP) | 150 160 | A* | - |
### 2.2 Dressur (CDN) Aufgabenniveau
@@ -43,6 +43,7 @@ Dressurprüfungen werden nach offiziellen Aufgabenheften geritten (§ 100 B-Teil
| Klasse | Niveau | Besonderheiten |
|:-------|:--------------------|:-------------------------------------------------------|
| **LF** | Lizenzfrei | Reiterpass/Reiternadel-Aufgaben (C-NEU) |
| **A** | Leicht | Grundlagen, 20x40m oder 20x60m Viereck |
| **L** | Mittelleicht | Beginnende Versammlung |
| **LM** | Leicht-Mittelschwer | Wahlweise Trense oder Kandare |
@@ -59,8 +60,11 @@ Dressurprüfungen werden nach offiziellen Aufgabenheften geritten (§ 100 B-Teil
* **Lizenzprüfung:** Getrennt nach R2/RD2 und R3/RD3.
* **Pferdeprüfungen:** Zwingend nach **Alter der Pferde** (z.B. 4-jährige vs. 5-6-jährige).
* **CSN-C-NEU:**
* Bis 95 cm: Abt. 1 (ohne Lizenz) / Abt. 2 (mit Lizenz).
* Bis 95 cm: Abt. 1 (ohne Lizenz) / Abt. 2 (R1) / Abt. 3 (R2 und höher).
* Ab 100 cm: Abt. 1 (R1) / Abt. 2 (R2 und höher).
* **CDN-C-NEU:**
* Reiterpass/Reiternadel-Aufgaben: Keine Lizenzinhaber startberechtigt.
* Inkl. First Ridden und Führzügelbewerbe.
### 3.2 Kapazitive Teilung (MUSS-Grenzen)
@@ -0,0 +1,94 @@
# 🐴 Pferdeprüfungen (Jungpferde) Dressur & Springen
Diese Dokumentation beschreibt die spezifischen Anforderungen und Richtverfahren für Pferdeprüfungen (Dressurpferde,
Springpferde) gemäß ÖTO 2026. Diese Prüfungen dienen der Beurteilung von jungen Pferden und weisen eine höhere
Komplexität in der Bewertung auf als Standardprüfungen.
## 1. Übersicht & Altersklassen (§ 100 & § 200 B-Teil)
Stichtag für das Alter des Pferdes ist der **1. Januar** des Geburtsjahres (Pferde altern immer zum Jahreswechsel).
| Sparte | Klasse | Pferdealter | Besonderheiten |
|:-------------|:------------|:------------|:-------------------------------|
| **Dressur** | **A** | 4 6 Jahre | Pflicht-Teilung: 4j. vs. 5-6j. |
| **Dressur** | **L** | 5 6 Jahre | Keine Teilung vorgeschrieben |
| **Dressur** | **M** | 6 7 Jahre | Keine Teilung vorgeschrieben |
| **Dressur** | **S** | 7 8 Jahre | Spezielles Richtverfahren |
| **Springen** | **95-110** | 4 6 Jahre | - |
| **Springen** | **115-130** | 5 7 Jahre | - |
| **Springen** | **135** | 6 8 Jahre | - |
---
## 2. Dressurpferdeprüfungen (§ 103, § 104 B-Teil)
### 2.1 Bewertungskriterien
Im Gegensatz zu Standard-Dressurprüfungen wird nicht jede Lektion einzeln benotet, sondern es erfolgt eine qualitative
Bewertung in folgenden Blöcken:
1. **Schritt**
2. **Trab**
3. **Galopp**
4. **Durchlässigkeit / Rittigkeit**
5. **Gesamteindruck / Perspektive**
### 2.2 Richtverfahren
* **Klassen A bis M:** In der Regel **Richtverfahren A** (Gemeinsames Richten). Es wird eine schriftlich begründete
Wertnote (0-10, eine Dezimale) vergeben.
* **Klasse S:** Kombiniertes Verfahren:
* 1 Richter bei C für die **technische Bewertung** (Sitz, Einwirkung, Korrektheit).
* 2 Richter bei B oder E (gemeinsam) für das **Dressurpferdeprotokoll** (Qualität der Grundgangarten).
### 2.3 Abzüge (Verreiten)
* Erstes Mal: **- 0,1 Punkte** von der Gesamtnote.
* Zweites Mal: **- 0,2 Punkte** von der Gesamtnote.
* Drittes Mal: **Ausschluss**.
---
## 3. Springpferdeprüfungen (§ 203, § 204 B-Teil)
### 3.1 Bewertungskriterien
Es wird eine Wertnote zwischen 0 und 10 (Zehntelnoten zulässig) vergeben. Beurteilt werden:
* **Rittigkeit**
* **Springmanier**
* **Einhaltung des Tempos**
### 3.2 Abzüge (Fehler im Parcours)
Vom Grundurteil (z.B. 8,5) werden folgende Fehler abgezogen:
* **Hindernisfehler:** - 0,5 Punkte.
* **Erster Ungehorsam:** - 0,5 Punkte.
* **Zweiter Ungehorsam:** - 1,0 Punkte.
* **Dritter Ungehorsam:** Ausschluss.
* **Zeitüberschreitung:** - 0,1 Punkte pro angefangene Sekunde.
* **Sturz (Reiter/Pferd):** Ausschluss.
**Besonderheit:** Ergibt die Endnote nach Abzügen **4,9 oder weniger**, wird das Ergebnis als **"ohne Bewertung"** in
die Liste aufgenommen (reihungstechnisch zwischen platzierten Reitern und Ausgeschiedenen).
---
## 4. Reitpferdeprüfungen (§ 1102 B-Teil)
Spezielle Form für 3- und 4-jährige Pferde zur Beurteilung der Grundgangarten und des Gebäudes.
* Finden oft in Gruppen (3-4 Pferde) statt.
* Bewertung analog zu Dressurpferdeprüfungen (Schritt, Trab, Galopp, Ausbildung, Gebäude).
---
## 5. System-Anforderungen (Backend/UI)
* **Noteneingabe:** Das System muss die Eingabe von Einzelnoten für die qualitativen Merkmale (Grundgangarten etc.)
unterstützen und daraus die Endnote berechnen.
* **Abzugs-Logik:** Automatische Subtraktion von Fehlern bei Springpferdeprüfungen.
* **Ergebnisliste:** Korrekte Handhabung von "ohne Bewertung" (< 5,0) in der Reihung.
* **Pferdealter-Validierung:** Prüfung beim Nennvorgang, ob das Pferd für die ausgeschriebene Pferdeprüfung
startberechtigt ist (Geburtsjahr-Check).
@@ -0,0 +1,92 @@
# 🐴 Pferdeprüfungen & Stilspringen: Bewertungssystem (ÖTO 2026)
Dieses Dokument beschreibt das spezifische Bewertungssystem für **Pferdeprüfungen** (Jungpferde) und *
*Stilspringprüfungen**, da diese über die einfache Ergebniserfassung hinausgehen und automatisierte Berechnungslogik im
System erfordern.
---
## 1. Dressurpferdeprüfungen (§ 103 & § 104 B-Teil)
Dressurpferdeprüfungen dienen der Beurteilung der Ausbildung und Qualität junger Pferde. Anstelle von Einzelnoten pro
Lektion werden qualitative Merkmale bewertet.
### 1.1 Bewertungsskala (0 10)
Es werden Noten in Zehntelschritten (z.B. 7,4) für folgende fünf Kriterien vergeben:
1. **Schritt:** Takt, Fleiß und Raumgriff.
2. **Trab:** Schwung, Elastizität und Ausdruck.
3. **Galopp:** Durchsprung, Bergauftendenz und Balance.
4. **Durchlässigkeit:** Rittigkeit, Gehorsam und Akzeptanz der Hilfen.
5. **Gesamteindruck:** Perspektive des Pferdes als Dressurpferd.
### 1.2 Ergebniserfassung & Berechnung
* **Gemeinsames Richten (RV A):** Die Richtergruppe vergibt eine gemeinsame Note pro Kriterium. Die Endnote ist das
arithmetische Mittel dieser fünf Noten.
* **Abzüge für Verreiten:**
*
1. Mal: - 0,1 Punkte vom Gesamtergebnis.
*
2. Mal: - 0,2 Punkte vom Gesamtergebnis.
*
3. Mal: Ausschluss.
---
## 2. Springpferdeprüfungen (§ 203 & § 204 B-Teil)
Hier steht die Springmanier und Rittigkeit im Vordergrund. Das Ergebnis basiert auf einer Grundnote, von der Fehler
abgezogen werden.
### 2.1 Grundnote (0 10)
Die Richter vergeben eine Wertnote für:
* Springmanier (Beintechnik, Bascule).
* Rittigkeit und Einhalten des korrekten Tempos.
### 2.2 Abzugslogik (Punkteabzug von der Grundnote)
| Fehlerart | Abzug (Punkte) |
|:-----------------------------------|:--------------------------------------------|
| **Hindernisfehler (Abwurf)** | - 0,5 |
| **Erster Ungehorsam (Verweigern)** | - 0,5 |
| **Zweiter Ungehorsam** | - 1,0 |
| **Dritter Ungehorsam** | Ausschluss |
| **Zeitfehler** | - 0,1 pro angef. Sekunde Zeitüberschreitung |
| **Sturz (Reiter/Pferd)** | Ausschluss |
### 2.3 Besonderheit: „Ohne Bewertung“ (§ 204 Abs. 4.2)
* Beträgt die **Endnote 4,9 oder weniger** (nach Abzügen), wird das Pferd als **„ohne Bewertung“** (o.B.) geführt.
* **Reihung:** Diese Teilnehmer werden in der Ergebnisliste hinter den platzierten/bewerteten Reitern, aber vor den
Ausgeschiedenen gereiht.
---
## 3. Stilspringprüfungen (§ 204 Abs. 4)
Stilspringprüfungen bewerten primär den Reiter (Sitz, Einwirkung, Wegführung).
### 3.1 Kriterien
* Sitz und Einwirkung des Reiters.
* Wahl des korrekten Tempos und harmonische Bewältigung der Aufgabe.
### 3.2 Abzüge & Idealzeit
* Die **Abzugslogik** ist identisch zu den Springpferdeprüfungen (siehe 2.2).
* **Idealzeit (§ 204 Abs. 4.3):** Bei Punktegleichheit entscheidet die geringere Zeitdifferenz zur Idealzeit.
* **Berechnung Idealzeit:** Erlaubte Zeit (EZ) minus 10%.
---
## 4. System-Anforderungen (Meldestelle)
1. **Eingabemaske:** Das UI muss für diese Prüfungsarten dedizierte Felder für die Kriterien (Dressur) bzw. die
Grundnote und die Fehler (Springen) bieten.
2. **Echtzeit-Berechnung:** Die Endnote muss während der Eingabe automatisch berechnet werden.
3. **Validierung:** Warnung, wenn eine Note > 10 eingegeben wird.
4. **Ergebnisliste:** Korrekte Kennzeichnung von „o.B.“ Ergebnissen und deren spezifische Reihung gemäß ÖTO.
@@ -0,0 +1,79 @@
# 🏇 Reiter-Prüfungen (Dressur & Stilspringen)
In diesem Dokument werden die Stammdaten und Regelwerke für Prüfungen aufbereitet, bei denen der Fokus primär auf der
Einwirkung und dem Sitz des Reiters liegt. Dies ist besonders relevant für Nachwuchsbewerbe und C-NEU Turniere.
## 1. Dressurreiterprüfungen (§ 103 Abs. 5 ÖTO)
Im Gegensatz zur Standard-Dressurprüfung, bei der die Durchlässigkeit und Gangqualität des Pferdes im Vordergrund
stehen, wird hier der Reiter bewertet.
### 1.1 Beurteilungskriterien
Die Bewertung erfolgt nach **Richtverfahren A (Gemeinsames Richten)** mit einer Wertnote von 0 bis 10 (eine Dezimale
zulässig).
* **Sitz:** Korrektheit, Geschmeidigkeit, Balance.
* **Einwirkung:** Effektivität der Hilfengebung, Harmonie mit dem Pferd.
* **Hufschlaglinien:** Exakte Ausführung der Wendungen und Linien.
* **Übergänge:** Fließende und korrekte Übergänge zwischen den Gangarten.
* **Tempo:** Einhalten gleichmäßiger und unterscheidbarer Tempi.
### 1.2 Besonderheiten für C-NEU
* Oft als **lizenzfreie Bewerbe (LF)** ausgeschrieben.
* Viereck-Maße: Meist 20x40m.
* Ausrüstung: Trense verpflichtend (Kandare in Reiterprüfungen nicht üblich).
---
## 2. Stilspringprüfungen (§ 204 Abs. 2 ÖTO)
Stilspringprüfungen dienen der Überprüfung der reiterlichen Ausbildung im Parcours.
### 2.1 Bewertungslogik
Es wird mit einer **Grundnote (0-10)** gestartet, von der Fehler (Abwürfe/Ungehorsam) und Stil-Mängel abgezogen werden.
| Vorfall | Abzug |
|:-------------------------------|:--------------------------------------------------------------|
| **Hindernisfehler (Abwurf)** | - 0,5 Punkte |
| **1. Ungehorsam (Verweigern)** | - 0,5 Punkte |
| **2. Ungehorsam** | - 1,0 Punkte |
| **3. Ungehorsam** | **Ausschluss** |
| **Sturz (Reiter/Pferd)** | **Ausschluss** |
| **Zeitfehler** | - 0,1 Punkte pro angefangene Sekunde (bei Zeitüberschreitung) |
### 2.2 Reihung bei Punktgleichheit
Bei gleicher Endnote im Stilspringen entscheidet laut ÖTO:
1. Die bessere **Stilnote** (bevor Abzüge für Hindernisfehler erfolgten).
2. Bei weiterhin gleicher Note: Ex aequo Platzierung (oder Stechen, falls ausgeschrieben).
---
## 3. System-Anforderungen für die Meldestelle
### 3.1 Ergebniserfassung (UI)
* **Dressurreiter:** Einfaches Eingabefeld für die Gesamtnote (z.B. 7,2).
* **Stilspringen:** Maske mit Grundnote und Auswahlfeldern für Fehler (Abwürfe, Verweigerungen), um die Endnote
automatisch zu berechnen.
### 3.2 Validierung
* Prüfung der **Lizenzklasse**: Stilspringprüfungen sind oft auf Reiter mit niedrigeren Lizenzen (R1) oder ohne Lizenz
beschränkt.
* **Altersklassen**: Kombination mit Jugend/Junioren-Bewerben prüfen.
---
## 4. ZNS-Mapping
Reiterprüfungen werden in den ZNS-Dateien (`*.dat`) meist über spezifische Prüfungsart-Codes identifiziert:
* `DR` -> Dressurreiterprüfung
* `ST` -> Stilspringprüfung
Diese Codes müssen im `zns-parser` korrekt auf die oben beschriebene Logik gemappt werden.
+140
View File
@@ -0,0 +1,140 @@
# Strategische Roadmap: Masterdata (Stammdaten) 2026 H1H2
🏗️ [Lead Architect]
## Leitbild und Scope
- Ziel: ÖTO-konforme, offline-fähige Stammdaten-Plattform für Dressur & Springen als SelfContained System mit eigener
DB, klaren APIs und einem wiederverwendbaren Frontend-Feature (Compose MPP).
- Ergebnis: Lesekanal (REST-API), Schreibkanal (ZNS-Ingestion), datengesteuerte Regel-Engine (Versionierung von
ÖTO-Regeln), vollständige Observability und Betrieb.
- Nicht-Ziele (Phase 1): FEI-Integration, weitere Sparten (VS, Western), komplexe Serien-/Cup-Reglements.
---
## Phasenüberblick und Meilensteine
### 1) Foundation & Governance (WK 12)
- Architektur-Entscheide (ADRs) finalisieren: Database-per-Service, Rule-Engine als Datenmodell, Importer als Worker im
Masterdata-SCS.
- Versionierungs-Strategie: `valid_from/valid_to` auf Regel-Datensätzen; „Regel-Set 2026“ als Seed.
- Security/Cross-Cutting: API-Schlüssel/Service-Tokens, CORS, Ratelimits, Idempotency-Policies dokumentieren und
aktivieren.
- Deliverables:
- [x] ADR-Set im Repo (Rules, DB, Import, API) → ADR-0017, ADR-0018, ADR-0019
- Operative Runbooks (Backup/Restore, Re-Import, Rollback)
### 2) Datenmodell & Persistenz (WK 24)
- Tabellenkatalog vervollständigen und migrieren (Exposed + Flyway/Liquibase): Reiter, Pferde, Vereine, Funktionäre,
Altersklassen, Lizenzen, Turnierklassen, Gebührenordnung, Richtverfahren, Regelkonfiguration.
- Indizes/Keys: Eindeutige Schlüssel gemäß ZNS (Satz-/Lizenznummern), Suchindizes für Name/Teilstrings.
- Deliverables:
- Migrationsskripte v1.0
- Repository-Impls mit Upsert-Semantik
- Test-Datasets (Mini-ZNS, ÖTO-Seeds)
### 3) Rule-Engine (WK 46)
- Domänenlogik kapseln: Altersklassenrechner, Lizenz-zu-Klasse-Matrix, Abteilungsregeln,
Pferde-/Reiterprüfungs-Scoring (Stilspringen/Dressurpferde), Gebühren-Lookups.
- Datengesteuerte Konfiguration: Tabellen „RegulationConfig“, „LicenseMatrix“, „ClassDefinitions“ mit Versionen.
- Deliverables:
- UseCases im `masterdata-common` (pure Kotlin) + Unit-Tests
- Admin-Seed für „ÖTO 2026“
### 4) ZNS-Ingestion als Worker (WK 57)
- Import-Pipeline (ASCII CP850) als Masterdata-Submodul/Worker: Validierung, Deduplikation (Idempotenz),
Fehlerreporting.
- Re-Import & Delta-Regeln; Konfliktstrategien (last-write-wins vs. checksumbased skip).
- Deliverables:
- Batch-Job + CLI/HTTP Trigger
- Import-Report (persistiert + JSON-Export)
### 5) API-Fassade (WK 68)
- Read-APIs (v1):
- GET /reiter?search=…
- GET /horses?search=…
- GET /vereine?bundesland=…
- GET /altersklassen, /turnierklassen, /lizenzmatrix, /richtverfahren, /gebuehrenordnung
- Admin/Tech-APIs: GET /rulesets, GET /health, GET /metrics
- DTOs mit Kotlinx Serialization; Paginierung & ETags.
- Deliverables: OpenAPI 3 Spec, Contract-Tests
### 6) Frontend-Feature „masterdata“ (WK 79)
- KMP-Feature-Modul: Such-/Detail-Views für Reiter, Pferde, Vereine; Readonly Rule-Explorer.
- State-Management, OfflineCache (Local DB) für Desktop; Fehler-/Konfliktanzeigen beim Import.
- Deliverables: Integrations-Demo in Desktop-Shell, UI-Snippets für Web-Shell
### 7) Observability & Operations (WK 59, parallel)
- Logging-Konzepte (strukturierte Logs), Metriken (Importdauer, Records/s, API Latenzen), Tracing (optional).
- Dashboards/Alerts: Import-Fehlerquote, API 5xx, DBWachstum, Regel-Set-Mismatch.
- Backups/Restore-Runbooks, DR-Test.
### 8) Quality Gate & GoLive (WK 910)
- Test-Strategie:
- Unit: Rule-Engine, UseCases
- Integration: Repos + API + Importer (Mini-ZNS)
- EndtoEnd: Desktop-Feature → API → DB
- Security Review, Performance Smoke (100k Reiter, 50k Pferde, 2k Vereine), Data Quality Checks.
- GoLive Checklist und Staged Rollout.
---
## Verantwortlichkeiten (Agents)
- 🏗️ Lead Architect: ADRs, Architektur-Governance, Phasenabnahme
- 👷 Backend Developer: DB/Repositories, UseCases, API, Importer
- 🎨 Frontend Expert: KMP-Feature, Offline-Cache, API-Integration
- 🐧 DevOps Engineer: CI/CD, Deploy, Observability, Backups
- 🧐 QA Specialist: Test-Strategie, Abdeckung, E2E
- 📜 Rulebook Expert: Daten-Seeds, Regel-Validierung, Review der Matrix
- 🧹 Curator: Docs-as-Code, Changelogs, Runbooks, Session Logs
---
## Architekturprinzipien (Wartbarkeit)
- Hexagonale Architektur strikt einhalten; UseCases sind framework-frei und testbar.
- Regeln im Datenmodell versionieren; Code nutzt nur „aktives Regel-Set“ je Turnier/Datum.
- Importer ist ein Worker des Masterdata-SCS (Schreibkanal), API ist der Lesekanal.
- Idempotenz konsequent: Upserts, ETags, Import-Footprint (checksum, source_id, imported_at).
---
## Abhängigkeiten & Risiken
- Abhängigkeiten: Postgres-Verfügbarkeit, ZNS-Dateiqualität, Identity (Token) für gesicherte Admin-Routen, Desktop-App
Shell.
- Risiken & Gegenmaßnahmen:
- Regeländerungen kurz vor Saisonstart → Versionierte Rulesets + Blue/Green Umschaltung per Config.
- Datenqualität ZNS (Inkonsistenzen) → strikte Validierung + Fehlerreport + manuelle Korrekturrouten (später).
- Performance bei Erstimport → Batchgrößen, Indizes, COPY/Batch-Insert, Profiling.
- ScopeCreep (weitere Sparten) → Phasen-Governance, ADRs, FeatureFlags.
---
## Erfolgskriterien (Messbar)
- T0 Import: Komplettes ZNS-Paket < 10 Minuten, Fehlerrate < 0,5% pro Datei, 100% idempotent.
- API: P95 Latenz < 150 ms bei 500 RPS Burst (ReadOnly Endpunkte), Fehlerquote < 0,1%.
- Rule-Engine: 100% Übereinstimmung mit dokumentierten Beispielen (Golden Files) und ÖTO-Referenzen.
- Observability: 4 zentrale Dashboards + 6 Alarm-Regeln aktiv; Backup/Restore in < 30 Minuten validiert.
---
## Nächste konkrete Schritte (2Wochen SprintPlan)
1. [x] ADRs für ImporterEinbettung, RuleVersionierung, API-Schichten abschließen (🏗️)
2. Exposed-Tabellen vervollständigen und in `SchemaUtils.create`/Migrationen registrieren (👷)
3. UseCases: Altersklasse, LizenzMatrix, AbteilungsRegeln inkl. UnitTests (👷🧐)
4. ZNSImporter an Repositories anbinden, Idempotenz-Checks ergänzen, MiniZNS Testlauf (👷🧐)
5. API v1 Endpunkte + OpenAPI, ContractTests (👷🧐)
6. Observability-Grundlagen (Metriken + Dashboards) (🐧)
7. Curator: Docs aktualisieren, Runbooks und Changelogs pflegen (🧹)
@@ -0,0 +1,82 @@
# 📜 Turnier-Sparten, Klassen & Startberechtigungen
Diese Dokumentation bietet eine detaillierte Übersicht über die Klassen der Hauptsparten **Dressur (CDN)** und *
*Springen (CSN)** sowie die jeweiligen Startberechtigungen basierend auf der ÖTO 2026.
---
## 1. Sparte Springen (CSN)
### 1.1 Klasseneinteilung (Großpferde)
Die Klassen richten sich primär nach der maximalen Hindernishöhe (§ 200 B-Teil).
| Klasse | Bezeichnung | Höhe (cm) | Startberechtigung (Lizenz) |
|:--------|:--------------------|:----------|:----------------------------|
| **E0** | Einsteiger | 60 95 | LZF (Startkarte/Reiterpass) |
| **A** | Leicht | 105 110 | R1 oder höher |
| **L** | Mittelleicht | 115 120 | R1 oder höher |
| **LM** | Leicht-Mittelschwer | 125 130 | R2 oder höher |
| **M** | Mittelschwer | 135 | R3 oder höher |
| **S*** | Schwer | 140 145 | R3 oder höher |
| **S**** | Schwer (GP) | 150 160 | R4 |
### 1.2 Besonderheiten CSN-C NEU
* **Höhen:** 60 cm bis 115 cm.
* **Registrierung:** Pferde bis 90 cm müssen nicht beim OEPS registriert sein.
* **Ergebniserfassung:** Erst ab 95 cm (für Lizenzerhalt) bzw. ab 105 cm (für Höherreihung).
* **Startlimit:** Ein Pferd darf maximal 3-mal pro Tag starten.
### 1.3 Abteilungsbildung (Pflicht)
* **Bis 95 cm:**
1. Abt.: Ohne Lizenz (LZF)
2. Abt.: R1-Reiter
3. Abt.: R2-Reiter und höher
* **Ab 100 cm:**
1. Abt.: R1-Reiter
2. Abt.: R2-Reiter und höher
---
## 2. Sparte Dressur (CDN)
### 2.1 Klasseneinteilung & Aufgabenniveau
Die Dressur wird nach offiziellen Aufgabenheften geritten (§ 100 B-Teil).
| Klasse | Niveau | Erforderliche Lizenz | Besonderheiten |
|:-------|:--------------------|:---------------------|:-------------------------------------------|
| **LF** | Lizenzfrei | LZF (Reiterpass) | First Ridden, Führzügel, Aufgaben R1/Nadel |
| **A** | Leicht | R1 / RD1 oder höher | Grundausbildung |
| **L** | Mittelleicht | R1 / RD1 oder höher | Beginnende Versammlung |
| **LM** | Leicht-Mittelschwer | R2 / RD2 oder höher | Wahlweise Trense/Kandare |
| **M** | Mittelschwer | R2 / RD2 oder höher | Kandarenpflicht |
| **S** | Schwer | R3 / RD3 oder höher | St. Georg bis Grand Prix |
### 2.2 Besonderheiten CDN-C NEU
* **Ausschreibbare Bewerbe:** Kl. A & L, lizenzfreie Aufgaben, Reiterpass/Reiternadel.
* **Einschränkung:** In Reiterpass/Reiternadel-Aufgaben sind Lizenzinhaber **nicht** startberechtigt.
* **Ergebniserfassung:** Ergebnisse in Kl. A und L werden für Lizenzen gewertet. Reiterpass-Aufgaben werden nicht
erfasst.
---
## 3. Zusammenfassende Startberechtigungs-Matrix
| Lizenzstufe | Springen (max. Klasse) | Dressur (max. Klasse) |
|:-------------|:-----------------------|:----------------------|
| **LZF** (RP) | E0 (95 cm) | LF / lizenzfrei |
| **R1** | L (120 cm) | L |
| **RD1** | E0 (95 cm) | L |
| **R2** | LM (130 cm) | M |
| **RD2** | E0 (95 cm) | M |
| **R3** | S* (145 cm) | S |
| **RD3** | E0 (95 cm) | S |
| **R4** | S**** (160 cm) | S |
---
> 📜 **Rulebook Expert Hinweis:** Diese Matrix dient der automatischen Validierung von Nennungen. Bei Rasse-Spezifischen
> Bewerben (Haflinger/Noriker) können Sonderregelungen gemäß `REITER_LIZENZEN.md` greifen.
@@ -0,0 +1,29 @@
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
package at.mocode.masterdata.infrastructure.persistence
import org.jetbrains.exposed.v1.core.Table
import org.jetbrains.exposed.v1.datetime.CurrentTimestamp
import org.jetbrains.exposed.v1.datetime.timestamp
/**
* Exposed-Tabellendefinition für die Gebührenordnung.
* Basierend auf ÖTO 2026.
*/
object GebuehrTable : Table("gebuehr") {
val id = uuid("gebuehr_id")
val bezeichnung = varchar("bezeichnung", 200)
val typ = varchar("typ", 50) // NENNUNG, STARTGELD, BOX, STALLGELD, SONSTIGES
val betrag = decimal("betrag", 10, 2)
val waehrung = varchar("waehrung", 3).default("EUR")
// Versionierung gemäß ADR-0018
val validFrom = timestamp("valid_from").defaultExpression(CurrentTimestamp)
val validTo = timestamp("valid_to").nullable()
val istAktiv = bool("ist_aktiv").default(true)
val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp)
val updatedAt = timestamp("updated_at").defaultExpression(CurrentTimestamp)
override val primaryKey = PrimaryKey(id)
}
@@ -303,7 +303,7 @@ class HorseRepositoryImpl : HorseRepository {
it[verantwortlichePersonId] = toUpdate.verantwortlichePersonId
it[zuechterName] = toUpdate.zuechterName
it[zuchtbuchNummer] = toUpdate.zuchtbuchNummer
it[lebensnummer] = toUpdate.lebensnummer
it[HorseTable.lebensnummer] = toUpdate.lebensnummer
it[chipNummer] = toUpdate.chipNummer
it[passNummer] = toUpdate.passNummer
it[oepsNummer] = toUpdate.oepsNummer
@@ -12,7 +12,7 @@ import org.jetbrains.exposed.v1.datetime.timestamp
*/
object HorseTable : Table("horse") {
val id = uuid("horse_id")
val pferdeName = varchar("pferde_name", 200)
val pferdeName = varchar("pferde_name", 200).index()
val geschlecht = varchar("geschlecht", 20)
val geburtsdatum = date("geburtsdatum").nullable()
val rasse = varchar("rasse", 100).nullable()
@@ -21,7 +21,7 @@ object HorseTable : Table("horse") {
val verantwortlichePersonId = uuid("verantwortliche_person_id").nullable()
val zuechterName = varchar("zuechter_name", 200).nullable()
val zuchtbuchNummer = varchar("zuchtbuch_nummer", 50).nullable()
val lebensnummer = varchar("lebensnummer", 50).nullable()
val lebensnummer = varchar("lebensnummer", 50).nullable().index()
val chipNummer = varchar("chip_nummer", 50).nullable()
val passNummer = varchar("pass_nummer", 50).nullable()
val oepsNummer = varchar("oeps_nummer", 50).nullable()
@@ -37,9 +37,4 @@ object HorseTable : Table("horse") {
val updatedAt = timestamp("updated_at").defaultExpression(CurrentTimestamp)
override val primaryKey = PrimaryKey(id)
init {
index("idx_horse_lebensnummer", isUnique = false, lebensnummer)
index("idx_horse_name", isUnique = false, pferdeName)
}
}
@@ -0,0 +1,32 @@
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
package at.mocode.masterdata.infrastructure.persistence
import org.jetbrains.exposed.v1.core.Table
import org.jetbrains.exposed.v1.datetime.CurrentTimestamp
import org.jetbrains.exposed.v1.datetime.timestamp
/**
* Exposed-Tabellendefinition für die Lizenz-Matrix (Reiter-Lizenz vs. Turnierklasse).
* Basierend auf ÖTO 2026.
*/
object LicenseTable : Table("license_matrix") {
val id = uuid("license_id")
val sparte = varchar("sparte", 20) // DRESSUR, SPRINGEN, ALLGEMEIN
val lizenzKlasse = varchar("lizenz_klasse", 20) // R1, R2, R3, RD1, RD2, RD3, LF
val maxTurnierklasseCode = varchar("max_turnierklasse_code", 10) // E, A, L, LM, M, S
// Versionierung gemäß ADR-0018
val validFrom = timestamp("valid_from").defaultExpression(CurrentTimestamp)
val validTo = timestamp("valid_to").nullable()
val istAktiv = bool("ist_aktiv").default(true)
val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp)
val updatedAt = timestamp("updated_at").defaultExpression(CurrentTimestamp)
override val primaryKey = PrimaryKey(id)
init {
index("idx_license_sparte_klasse", false, sparte, lizenzKlasse)
}
}
@@ -0,0 +1,32 @@
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
package at.mocode.masterdata.infrastructure.persistence
import org.jetbrains.exposed.v1.core.Table
import org.jetbrains.exposed.v1.datetime.CurrentTimestamp
import org.jetbrains.exposed.v1.datetime.timestamp
/**
* Exposed-Tabellendefinition für die allgemeine Regelkonfiguration.
* Basierend auf ADR-0018.
*/
object RegulationConfigTable : Table("regulation_config") {
val id = uuid("config_id")
val key = varchar("config_key", 100)
val value = text("config_value") // JSON oder einfacher String
val beschreibung = varchar("beschreibung", 255).nullable()
// Versionierung gemäß ADR-0018
val validFrom = timestamp("valid_from").defaultExpression(CurrentTimestamp)
val validTo = timestamp("valid_to").nullable()
val istAktiv = bool("ist_aktiv").default(true)
val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp)
val updatedAt = timestamp("updated_at").defaultExpression(CurrentTimestamp)
override val primaryKey = PrimaryKey(id)
init {
index("idx_regulation_config_key", false, key)
}
}
@@ -0,0 +1,33 @@
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
package at.mocode.masterdata.infrastructure.persistence
import org.jetbrains.exposed.v1.core.Table
import org.jetbrains.exposed.v1.datetime.CurrentTimestamp
import org.jetbrains.exposed.v1.datetime.timestamp
/**
* Exposed-Tabellendefinition für Richtverfahren.
* Basierend auf ÖTO 2026.
*/
object RichtverfahrenTable : Table("richtverfahren") {
val id = uuid("richtverfahren_id")
val sparte = varchar("sparte", 20) // DRESSUR, SPRINGEN
val code = varchar("code", 10) // A1, A2, AM5, RV_A, RV_B
val bezeichnung = varchar("bezeichnung", 200)
val beschreibung = text("beschreibung").nullable()
// Versionierung gemäß ADR-0018
val validFrom = timestamp("valid_from").defaultExpression(CurrentTimestamp)
val validTo = timestamp("valid_to").nullable()
val istAktiv = bool("ist_aktiv").default(true)
val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp)
val updatedAt = timestamp("updated_at").defaultExpression(CurrentTimestamp)
override val primaryKey = PrimaryKey(id)
init {
index("idx_richtverfahren_sparte_code", false, sparte, code)
}
}
@@ -0,0 +1,34 @@
@file:OptIn(kotlin.uuid.ExperimentalUuidApi::class)
package at.mocode.masterdata.infrastructure.persistence
import org.jetbrains.exposed.v1.core.Table
import org.jetbrains.exposed.v1.datetime.CurrentTimestamp
import org.jetbrains.exposed.v1.datetime.timestamp
/**
* Exposed-Tabellendefinition für Turnierklassen (Springen/Dressur).
* Basierend auf ÖTO 2026.
*/
object TurnierklasseTable : Table("turnierklasse") {
val id = uuid("turnierklasse_id")
val sparte = varchar("sparte", 20) // DRESSUR, SPRINGEN
val code = varchar("code", 10) // E, A, L, LM, M, S
val bezeichnung = varchar("bezeichnung", 100)
val maxHoehe = integer("max_hoehe").nullable() // in cm (Springen)
val aufgabenNiveau = varchar("aufgaben_niveau", 100).nullable() // (Dressur)
// Versionierung gemäß ADR-0018
val validFrom = timestamp("valid_from").defaultExpression(CurrentTimestamp)
val validTo = timestamp("valid_to").nullable()
val istAktiv = bool("ist_aktiv").default(true)
val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp)
val updatedAt = timestamp("updated_at").defaultExpression(CurrentTimestamp)
override val primaryKey = PrimaryKey(id)
init {
index("idx_turnierklasse_sparte_code", false, sparte, code)
}
}
@@ -37,7 +37,12 @@ class MasterdataDatabaseConfiguration {
ReiterTable,
HorseTable,
VereinTable,
FunktionaerTable
FunktionaerTable,
TurnierklasseTable,
LicenseTable,
RichtverfahrenTable,
GebuehrTable,
RegulationConfigTable
)
log.info("Masterdata database schema initialized successfully")
}
@@ -77,7 +82,12 @@ class MasterdataTestDatabaseConfiguration {
ReiterTable,
HorseTable,
VereinTable,
FunktionaerTable
FunktionaerTable,
TurnierklasseTable,
LicenseTable,
RichtverfahrenTable,
GebuehrTable,
RegulationConfigTable
)
log.info("Test masterdata database schema initialized successfully")
}
@@ -0,0 +1,148 @@
-- V005: Create Turnierklasse, License, Richtverfahren, Gebuehr, RegulationConfig Tables
-- Basierend auf ÖTO 2026 und ADR-0018
CREATE TABLE IF NOT EXISTS turnierklasse
(
turnierklasse_id
UUID
PRIMARY
KEY,
sparte
VARCHAR
(
20
) NOT NULL,
code VARCHAR
(
10
) NOT NULL,
bezeichnung VARCHAR
(
100
) NOT NULL,
max_hoehe INTEGER,
aufgaben_niveau VARCHAR
(
100
),
valid_from TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
valid_to TIMESTAMP WITH TIME ZONE,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_turnierklasse_sparte_code ON turnierklasse (sparte, code);
CREATE TABLE IF NOT EXISTS license_matrix
(
license_id
UUID
PRIMARY
KEY,
sparte
VARCHAR
(
20
) NOT NULL,
lizenz_klasse VARCHAR
(
20
) NOT NULL,
max_turnierklasse_code VARCHAR
(
10
) NOT NULL,
valid_from TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
valid_to TIMESTAMP WITH TIME ZONE,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_license_sparte_klasse ON license_matrix (sparte, lizenz_klasse);
CREATE TABLE IF NOT EXISTS richtverfahren
(
richtverfahren_id
UUID
PRIMARY
KEY,
sparte
VARCHAR
(
20
) NOT NULL,
code VARCHAR
(
10
) NOT NULL,
bezeichnung VARCHAR
(
200
) NOT NULL,
beschreibung TEXT,
valid_from TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
valid_to TIMESTAMP WITH TIME ZONE,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_richtverfahren_sparte_code ON richtverfahren (sparte, code);
CREATE TABLE IF NOT EXISTS gebuehr
(
gebuehr_id
UUID
PRIMARY
KEY,
bezeichnung
VARCHAR
(
200
) NOT NULL,
typ VARCHAR
(
50
) NOT NULL,
betrag DECIMAL
(
10,
2
) NOT NULL,
waehrung VARCHAR
(
3
) NOT NULL DEFAULT 'EUR',
valid_from TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
valid_to TIMESTAMP WITH TIME ZONE,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS regulation_config
(
config_id
UUID
PRIMARY
KEY,
config_key
VARCHAR
(
100
) NOT NULL,
config_value TEXT NOT NULL,
beschreibung VARCHAR
(
255
),
valid_from TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
valid_to TIMESTAMP WITH TIME ZONE,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_regulation_config_key ON regulation_config (config_key);
@@ -0,0 +1,248 @@
-- V006: Missing Core Masterdata Tables (Reiter, Horse, Verein, Funktionaer)
-- Diese Tabellen wurden in V1 (Initial) teilweise unter anderen Namen angelegt (dom_verein, dom_person).
-- Um konsistent mit den Exposed-Tabellen (ReiterTable, HorseTable, etc.) zu sein, legen wir sie hier final an.
CREATE TABLE IF NOT EXISTS reiter
(
reiter_id
UUID
PRIMARY
KEY,
person_id
UUID,
satznummer
VARCHAR
(
10
) UNIQUE NOT NULL,
lizenz_nummer VARCHAR
(
20
),
lizenz_klasse VARCHAR
(
20
) NOT NULL,
startkart_aktiv BOOLEAN NOT NULL DEFAULT false,
startkart_saison INTEGER,
fei_id VARCHAR
(
20
),
nation VARCHAR
(
3
),
nachname VARCHAR
(
100
) NOT NULL,
vorname VARCHAR
(
100
) NOT NULL,
geburtsdatum DATE,
vereins_nummer VARCHAR
(
10
),
vereins_name VARCHAR
(
200
),
ist_gastreiter BOOLEAN NOT NULL DEFAULT false,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
daten_quelle VARCHAR
(
50
) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_reiter_satznummer ON reiter (satznummer);
CREATE INDEX idx_reiter_name ON reiter (nachname, vorname);
CREATE TABLE IF NOT EXISTS horse
(
horse_id
UUID
PRIMARY
KEY,
pferde_name
VARCHAR
(
200
) NOT NULL,
geschlecht VARCHAR
(
20
) NOT NULL,
geburtsdatum DATE,
rasse VARCHAR
(
100
),
farbe VARCHAR
(
100
),
besitzer_id UUID,
verantwortliche_person_id UUID,
zuechter_name VARCHAR
(
200
),
zuchtbuch_nummer VARCHAR
(
50
),
lebensnummer VARCHAR
(
50
),
chip_nummer VARCHAR
(
50
),
pass_nummer VARCHAR
(
50
),
oeps_nummer VARCHAR
(
50
),
fei_nummer VARCHAR
(
50
),
vater_name VARCHAR
(
200
),
mutter_name VARCHAR
(
200
),
mutter_vater_name VARCHAR
(
200
),
stockmass INTEGER,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
bemerkungen TEXT,
daten_quelle VARCHAR
(
50
) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_horse_lebensnummer ON horse (lebensnummer);
CREATE INDEX idx_horse_name ON horse (pferde_name);
CREATE TABLE IF NOT EXISTS verein
(
verein_id
UUID
PRIMARY
KEY,
vereins_nummer
VARCHAR
(
10
) UNIQUE NOT NULL,
name VARCHAR
(
200
) NOT NULL,
kurzname VARCHAR
(
100
),
bundesland VARCHAR
(
100
),
ort VARCHAR
(
100
),
plz VARCHAR
(
10
),
strasse VARCHAR
(
200
),
email VARCHAR
(
200
),
telefon VARCHAR
(
50
),
website VARCHAR
(
255
),
oeps_region_nummer VARCHAR
(
10
),
ist_veranstalter BOOLEAN NOT NULL DEFAULT false,
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
bemerkungen TEXT,
daten_quelle VARCHAR
(
50
) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS funktionaer
(
funktionaer_id
UUID
PRIMARY
KEY,
richter_nummer
VARCHAR
(
10
) UNIQUE,
vorname VARCHAR
(
100
) NOT NULL,
nachname VARCHAR
(
100
) NOT NULL,
geburtsdatum DATE,
email VARCHAR
(
200
),
telefon VARCHAR
(
50
),
vereins_nummer VARCHAR
(
10
),
ist_aktiv BOOLEAN NOT NULL DEFAULT true,
bemerkungen TEXT,
daten_quelle VARCHAR
(
50
) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
+3
View File
@@ -203,6 +203,9 @@ und über definierte Schnittstellen kommunizieren.
| 8 | 6 Bounded Contexts: Mapping & Aggregate Roots | ✅ | ADR-0014 |
| 9 | Context Map: Integration Patterns & ACL-Strategie | ✅ | ADR-0015 |
| 10 | API-Design & ACL: Ports, DTOs, REST-Endpunkte, Domain Events | ✅ | ADR-0016 |
| 11 | Masterdata: Importer-Einbettung als Worker | ✅ | ADR-0017 |
| 12 | Masterdata: Rule-Versionierung (Regulation-as-Data) | ✅ | ADR-0018 |
| 13 | Masterdata: API-Schichten (REST vs. Ingestion) | ✅ | ADR-0019 |
---
@@ -0,0 +1,58 @@
---
type: ADR
status: AKZEPTIERT
owner: Lead Architect
date: 2026-03-30
---
# ADR-0017: Einbettung des ZNS-Importers als Worker im Masterdata-SCS
## Status
Akzeptiert
## Kontext
Das Zentrale Nennungs-System (ZNS) liefert Stammdaten (Reiter, Pferde, Vereine, Funktionäre) in Form von ASCII-Dateien (
CP850). Diese Daten müssen regelmäßig importiert und aktualisiert werden.
Bisher gab es die Überlegung, den Importer als eigenständigen Dienst oder als Teil des Backends zu betreiben. Da die
Stammdaten jedoch das primäre Domänenmodell des `masterdata`-SCS sind, stellt sich die Frage nach der optimalen
architektonischen Einbettung.
## Entscheidung
Der ZNS-Importer wird als **dedizierter Worker-Thread/Service innerhalb des Masterdata-SCS** implementiert.
Details:
1. **Modul-Struktur**: Der `core:zns-parser` bleibt ein KMP-Modul für die reine Dateianalyse. Die Import-Logik (Mapping
auf Domänen-Entitäten, Upserts in die DB) wird im `masterdata`-SCS angesiedelt.
2. **Ausführung**: Der Import läuft asynchron als Hintergrund-Task (Worker), um die API-Reaktionszeit nicht zu
beeinträchtigen.
3. **Trigger**: Der Import kann über einen REST-Endpunkt (für Datei-Uploads) oder manuell via CLI/Trigger gestartet
werden.
4. **Schreibkanal**: Der Importer ist der primäre Schreibkanal für Stammdaten im System. Direkte API-Schreibzugriffe auf
Stammdaten sind in Phase 1 nicht vorgesehen (Read-Only API für externe Konsumenten).
## Konsequenzen
- **Positiv**: Starke Kohäsion, da die Datenhoheit und die Importlogik im selben SCS liegen.
- **Positiv**: Vereinfachte Persistenz, da der Worker direkt auf die Masterdata-DB zugreifen kann (kein
Remote-API-Overhead).
- **Negativ**: Ressourcenverbrauch des Workers (CPU/RAM beim Parsen großer Dateien) teilt sich die Ressourcen mit der
REST-API innerhalb des Containers. Dies muss über Limits (Docker/K8s) oder Task-Scheduling gesteuert werden.
- **Neutral**: Erfordert eine robuste Idempotenz-Logik, da Importe wiederholbar sein müssen (Checksum-Checks,
Upsert-Semantik).
## Betrachtete Alternativen
- **Eigenständiger Microservice**: Wurde verworfen, um die Anzahl der zu betreibenden Dienste gering zu halten und "
Database-per-Service" nicht durch geteilte Datenbankzugriffe zu verletzen (oder teure API-Synchronisation zu
benötigen).
- **Integration in die GUI (Client-seitig)**: Verworfen, da die Datenhoheit im Server liegen muss und große Importe (
100k+ Records) im Hintergrund auf dem Server stabiler laufen.
## Referenzen
- [Roadmap_ZNS_Importer.md](../../../docs/01_Architecture/Roadmap_ZNS_Importer.md)
- [ROADMAP.md](../ROADMAP.md)
@@ -0,0 +1,53 @@
---
type: ADR
status: AKZEPTIERT
owner: Lead Architect
date: 2026-03-30
---
# ADR-0018: Rule-Versionierung und -Management (ÖTO-Regeln)
## Status
Akzeptiert
## Kontext
Die ÖTO-Regeln (Österreichische Turnierordnung) für Dressur, Springen und andere Sparten ändern sich regelmäßig (
jährlich oder bei Bedarf). Das System muss in der Lage sein, Stammdaten (Altersklassen, Lizenzen, Richtverfahren,
Gebühren) für ein Turnier basierend auf dem zum Turnierzeitpunkt gültigen Regelwerk zu validieren und anzuzeigen. Eine
rein Code-basierte Regelverwaltung (Hardcoding) ist aufgrund der Dynamik und Offline-Fähigkeit nicht praktikabel.
## Entscheidung
ÖTO-Regeln werden als **versionierte Datensätze in der Datenbank** verwaltet (Regulation-as-Data).
Details:
1. **Versionierungs-Schema**: Alle Regel-Datensätze (z.B. Lizenz-Klasse-Matrix, Altersklassen-Berechnung) erhalten
`valid_from` und `valid_to` Zeitstempel.
2. **Aktives Regel-Set**: Die Applikationslogik ermittelt zur Laufzeit (z.B. basierend auf dem Turnierdatum) das jeweils
aktive Regel-Set aus der Datenbank.
3. **Seed-Strategie**: Zu Beginn jeder Saison (oder bei Major-Updates) wird ein neues Regel-Set als Seed in die
Datenbank eingespielt. Das "Regel-Set 2026" dient als Basis.
4. **Unveränderlichkeit (Immutability)**: Bestehende, in Turnieren verwendete Regeln dürfen nicht überschrieben werden.
Bei Änderungen wird ein neuer Datensatz mit neuem Gültigkeitsbereich angelegt (SCD Type 2 Pattern).
## Konsequenzen
- **Positiv**: Hohe Flexibilität ohne Code-Deployments (Config-over-Code).
- **Positiv**: Historische Turniere bleiben nachvollziehbar, da sie auf das damals gültige Regelwerk verweisen.
- **Negativ**: Erhöhte Komplexität bei Datenbank-Abfragen (immer Zeitbezug erforderlich).
- **Negativ**: Notwendigkeit für robuste Administrations-Schnittstellen oder SQL-Seeds zur Regelpflege.
## Betrachtete Alternativen
- **Hardcoding in Kotlin-Use-Cases**: Schneller zu implementieren, aber unflexibel bei unterjährigen Regeländerungen und
historischer Auswertung schwierig.
- **Git-basierte Konfiguration (YAML/JSON)**: Gut für CI/CD, aber schwierig für Offline-Szenarien ohne vollen
Repository-Sync; Datenbank-Integration für Abfragen komplexer.
## Referenzen
- [ROADMAP.md](../ROADMAP.md)
- [Abteilungs-Trennungs-Schwellenwerte.md](../../../docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md)
@@ -0,0 +1,55 @@
---
type: ADR
status: AKZEPTIERT
owner: Lead Architect
date: 2026-03-30
---
# ADR-0019: API-Schichten und Ingestion-Pattern im Masterdata-SCS
## Status
Akzeptiert
## Kontext
Das Masterdata-SCS (Stammdaten) dient als zentrale Informationsquelle für alle anderen Bounded Contexts (z.B.
Registration, Competition). Es muss sowohl Massendaten aus dem ZNS (Zentrales Nennungs-System) aufnehmen (Schreibkanal)
als auch hochperformante Lesezugriffe (Lesekanal) für die Suche und Validierung ermöglichen. Dabei ist die Trennung
zwischen internen Ingestion-Prozessen und externen Client-APIs entscheidend für die Stabilität und Sicherheit.
## Entscheidung
Die API-Architektur wird in **klare Schichten für Ingestion (Schreiben) und REST (Lesen)** unterteilt.
Details:
1. **Lesekanal (Public REST API)**: Bietet Endpunkte für die Suche (Reiter, Pferde, Vereine) und den Abruf von
Regelwerken. Diese API ist optimiert für Performance (Indizes, Paging, ETags) und nutzt DTOs mit Kotlinx
Serialization.
2. **Schreibkanal (Ingestion API/Worker)**: Dieser Kanal ist internen Prozessen (ZNS-Importer) vorbehalten. Direkte
Schreibzugriffe von Clients auf Stammdaten sind in der ersten Phase unterbunden. Der Schreibkanal nutzt ein
Ingestion-Pattern, das auf Idempotenz (Upserts) und Validierung (Checksum-Checks) basiert.
3. **Internal API (Core Interfaces)**: Innerhalb des Masterdata-SCS werden klare Interfaces für Repositories und
UseCases genutzt, die von Ingestion und REST gemeinsam verwendet werden.
4. **Versioning**: Alle APIs werden versioniert (v1, v2), um zukünftige Schema-Änderungen ohne Breaking Changes zu
ermöglichen.
## Konsequenzen
- **Positiv**: Klare Trennung der Verantwortlichkeiten (Separation of Concerns).
- **Positiv**: Höhere Sicherheit, da Stammdaten nicht versehentlich durch die Public-API manipuliert werden können.
- **Positiv**: Bessere Skalierbarkeit: Lesekanal kann unabhängig vom Schreibkanal optimiert werden.
- **Negativ**: Erhöhter Implementierungsaufwand durch getrennte DTOs und Validierungslogik für die Ingestion-Phase.
## Betrachtete Alternativen
- **Einheitliche CRUD-API**: Alle Zugriffe über die gleiche API-Schicht. Verworfen wegen mangelnder Sicherheit bei
sensiblen Stammdaten und Performance-Problemen bei Massen-Imports.
- **GraphQL**: Bietet hohe Flexibilität beim Lesen, wurde jedoch für die erste Phase als zu komplex für die einfache
Suche in Stammdaten angesehen. REST ist für Offline-Szenarien und Caching (ETags) einfacher zu handhaben.
## Referenzen
- [ADR-0017: Importer-Einbettung](./0017-masterdata-importer-worker-de.md)
- [ROADMAP.md](../ROADMAP.md)
@@ -0,0 +1,47 @@
# Session Log: Einarbeitung C-NEU Bestimmungen & Turnier-Sparten
**Datum:** 2026-03-30
**Agent:** 📜 [ÖTO/FEI Rulebook Expert] / 🧹 [Curator]
## Zielsetzung
Integration der spezifischen Bestimmungen für C-NEU Turniere (CDN-C NEU / CSN-C NEU) in die Stammdaten-Dokumentation des
`masterdata` Services. Aufbereitung einer detaillierten Übersicht über Turnier-Sparten (Dressur & Springen), deren
Klassen und die korrespondierenden Startberechtigungen (Lizenz-Matrix).
## Durchgeführte Änderungen
### 1. Erweiterung der zentralen Stammdaten (`OETO_STAMMDATEN.md`)
* **Abteilungslogik:** Spezifikation der 3-Abteilungs-Regel für CSN-C NEU bis 95 cm (Abt. 1: ohne Lizenz, Abt. 2: R1,
Abt. 3: R2+).
* **Dressur-Klassen:** Ergänzung der Klasse `LF` (Lizenzfrei) für Reiterpass-/Reiternadel-Aufgaben im C-NEU Bereich.
* **C-NEU Spezifika:** Dokumentation der Einschränkung, dass Lizenzinhaber in RP/Nadel-Bewerben nicht startberechtigt
sind.
### 2. Neue Fachdokumentation (`TURNIER_KLASSEN.md`)
* Erstellung einer detaillierten Übersicht für **Springen (CSN)**:
* Höhenstufen (E0 bis S****).
* C-NEU Besonderheiten (Registrierungspflicht erst ab 95 cm, Startlimits).
* Strukturelle Abteilungs-Vorgaben.
* Erstellung einer detaillierten Übersicht für **Dressur (CDN)**:
* Aufgabenniveau (LF bis S).
* Startberechtigungen pro Klasse.
* **Startberechtigungs-Matrix:** Zentrale Gegenüberstellung von Lizenzstufen (LZF, R1-R4, RD1-RD3) und den maximal
zulässigen Klassen in beiden Sparten.
### 3. Service-Integration (`README.md`)
* Verlinkung der neuen `TURNIER_KLASSEN.md` in der zentralen Dokumentations-Übersicht des `masterdata` Services.
## Verifizierung
* Abgleich der Daten mit `Bestimmungen_CSN-C_NEU.md` und `Bestimmungen_CDN-C_NEU.md`.
* Validierung der Lizenzstufen gegen `REITER_LIZENZEN.md` und die ÖTO 2026.
* Prüfung der Konsistenz mit den Abteilungs-Schwellenwerten aus der Master-Referenz.
## Nächste Schritte
* Implementierung der `Validation-Engine` Logik basierend auf der erstellten Startberechtigungs-Matrix.
* Erweiterung des `zns-import` Moduls zur Berücksichtigung der C-NEU Registrierungs-Ausnahmen für Pferde.
@@ -0,0 +1,36 @@
# Session Log: Masterdata Funktionär-Qualifikationen
**Datum:** 2026-03-30
**Agent:** 📜 [ÖTO/FEI Rulebook Expert]
## 🎯 Ziel
Aufbereitung der Qualifikationen für Richter und Parcoursbauer basierend auf der ÖTO 2026 und dem ZNS-Pflichtenheft v2.4
zur Integration in den `masterdata` Service.
## 🛠️ Änderungen
### 1. Neue Dokumentation: `FUNKTIONAERE_QUALIFIKATIONEN.md`
* **Fachlich:** Zusammenfassung der Richtergruppen (Dressur, Springen, Vielseitigkeit) und Zusatzqualifikationen (SPF,
DPF).
* **Level:** Dokumentation der Parcoursbauer-Level (P1-P4) inklusive der spezifischen Anforderung für C-NEU (mind. P1).
* **Regelwerk:** Integration der Einsatzvorgaben (§ 50 A-Teil) wie Mindestbesetzung und Zeitlimits.
* **Technisch:** Detaillierung der ZNS-Satzarten (X-Satz für Richter, Y-Satz für Parcoursbauer) mit Felddefinitionen (
Stelle/Länge).
### 2. README-Update
* Verlinkung der neuen Dokumentation in der zentralen `README.md` des `masterdata` Services.
## 🔍 Validierung
* Abgleich der Felddefinitionen mit dem Original-Pflichtenheft v2.4.
* Prüfung der fachlichen Anforderungen gegen die ÖTO 2026 (A- und B-Teil).
* Verifizierung der Pfade und Verlinkungen innerhalb des Service-Kontexts.
## 📌 Nächste Schritte
* Implementierung der `Funktionaer`-Entity in `masterdata-domain` (erledigt).
* Ausbau des `ExposedFunktionaerRepository` zur Unterstützung des ZNS-Imports der X- und Y-Sätze.
* Integration der Qualifikations-Validierung in die Turnier-Ausschreibung (Validation Engine).
@@ -0,0 +1,41 @@
# Session Log: Masterdata Gebührenordnung (ÖTO 2026)
**Datum:** 2026-03-30
**Agent:** 🧹 [Curator] & 📜 [ÖTO/FEI Rulebook Expert]
## 🎯 Ziel
Aufbereitung der offiziellen ÖTO-Gebührenordnung 2026 für die Sparten Dressur und Springen zur späteren Implementierung
in die Berechnungs- und Validierungs-Logik des Masterdata-Services.
## 📝 Durchgeführte Änderungen
### 1. Fachdokumentation erstellt
* **Datei:** `backend/services/masterdata/docs/GEBUEHRENORDNUNG.md`
* **Inhalt:**
* **Nenn- und Startgelder:** Strukturierte Übersicht über Nenngelder nach Kategorie (A/B/C) und
Startgeld-Obergrenzen (mit/ohne Geldpreis, C-NEU, getrenntes Richten).
* **Zusatzabgaben:** Dokumentation von Tierwohleuro (1,00 €) und Sportförderbeitrag (1,00 €).
* **Geldpreise:** Tabellarische Aufbereitung der Mindest-Geldpreise für Dressur (Klassen A bis S) und Springen (
Höhenstufen 105 cm bis 160 cm) für alle Turnierkategorien.
* **Funktionärsvergütung:** Festhalten der Tagessätze (120 € / 100 €), Kilometergelder (0,50 €) und
Unterkunftsvorgaben.
### 2. Integration & Verlinkung
* Aktualisierung der `backend/services/masterdata/README.md`, um die neue Gebührenordnung als Referenz für die
ÖTO-Konformität aufzunehmen.
## 🔍 Validierung
* Abgleich der Daten mit dem Originaldokument
`docs/03_Domain/02_Reference/OETO_Regelwerk/OETO-2026_E-Teil-Gebuehrenordnung_18-12-2025.md`.
* Sicherstellung, dass spartenrelevante Ausnahmen (z.B. Tierwohleuro nur bei Springen) korrekt markiert sind.
## 💡 Nächste Schritte
* Überführung der Gebührensätze in Domänen-Konstanten (`masterdata-domain`).
* Implementierung einer `AccountingEngine` oder eines `FeeCalculator` Services im `competition-context`, der auf diese
Stammdaten zugreift.
* Erweiterung der Ausschreibungs-Validierung um die Prüfung der Mindest-Geldpreis-Summen.
@@ -0,0 +1,29 @@
### Summary
- Aufbereitung und Dokumentation der spezifischen Anforderungen für Pferdeprüfungen (Jungpferde) in Dressur und Springen
gemäß ÖTO 2026.
- Integration der komplexeren Bewertungslogik (Qualitative Noten, Abzüge bei Springpferdeprüfungen) in den `masterdata`
Service-Kontext.
### Changes
- **Neue Fachdokumentation:** `backend/services/masterdata/docs/PFERDEPRUEFUNGEN.md` erstellt, die Altersklassen,
Richtverfahren und Bewertungskriterien für Dressur-, Spring- und Reitpferdeprüfungen beschreibt.
- **Bewertungs-Logik:** Detaillierung der qualitativen Merkmale (Grundgangarten, Rittigkeit, Perspektive) und der
spezifischen Abzugs-Regeln für Springpferdeprüfungen.
- **README-Update:** Die zentrale `README.md` des `masterdata` Services wurde um die Verlinkung der neuen
Pferdeprüfungs-Dokumentation ergänzt.
- **Journaling:** Erstellung eines detaillierten Session Logs zur Dokumentation der Aufbereitung für
Jungpferdeprüfungen.
### Verification
- Abgleich der Altersklassen und Richtverfahren mit den ÖTO-Regelwerken 2026 (Abschnitt B I und B II).
- Validierung der Abzugs-Logik (§ 204 Abs. 4) für Springpferdeprüfungen.
- Prüfung der internen Verlinkung innerhalb der Service-Struktur.
### Notes
- Die Dokumentation dient als Grundlage für die Implementierung der Notenerfassung im UI (Einzelnoten-Eingabe vs.
Gesamtnote).
- Die Pferdealter-Validierung muss beim Nennungsprozess strikt auf dem Geburtsjahr (Stichtag 1.1.) basieren.
@@ -0,0 +1,24 @@
### Summary
- Aufbereitung und Dokumentation des spezifischen Bewertungssystems für Pferdeprüfungen (Dressur-/Springpferde) und
Stilspringprüfungen gemäß ÖTO 2026.
- Integration der qualitativen Bewertungskriterien und der automatisierten Abzugslogik in den `masterdata`
Service-Kontext.
### Changes
- **Neue Fachdokumentation:** `backend/services/masterdata/docs/PFERDEPRUEFUNGEN_BEWERTUNG.md` erstellt, die
Einzelnoten-Kriterien für Dressurpferdeprüfungen (Schritt, Trab, Galopp etc.) und die Abzugslogik für
Springpferde/Stilspringen (-0,5/-1,0) detailliert beschreibt.
- **Spezialregelung:** Dokumentation der „ohne Bewertung“ (o.B.) Logik für Endnoten <= 4,9 inklusive deren spezifischer
Reihung in Ergebnislisten.
- **System-Anforderungen:** Definition der UI- und Berechnungs-Anforderungen für die Meldestellen-Software (
Echtzeit-Kalkulation der Endnoten).
- **README-Update:** Die zentrale `README.md` des `masterdata` Services wurde um die Verlinkung der neuen
Bewertungs-Dokumentation erweitert.
### Verification
- Abgleich der Kriterien und Abzugswerte mit den ÖTO-Regelwerken 2026 (Abschnitt B, § 103, § 104, § 203, § 204).
- Validierung der Konsistenz zwischen fachlichen Anforderungen und den zuvor erstellten allgemeinen
Pferdeprüfungs-Stammdaten.
@@ -0,0 +1,27 @@
# Session Log: Masterdata Reiter-Prüfungen (Dressur & Stilspringen)
## 📋 Zusammenfassung
- Aufbereitung der Stammdaten für Dressurreiter- und Stilspringprüfungen gemäß ÖTO 2026.
- Fokus auf die spezifische Bewertungslogik (Wertnoten vs. Abzüge) und deren Anforderungen an das System.
## 🛠 Änderungen
- **Neue Fachdokumentation:** `backend/services/masterdata/docs/REITER_PRUEFUNGEN.md` erstellt.
- **Inhalt:**
- Definition Dressurreiterprüfung (Sitz, Einwirkung, Hufschlaglinien).
- Detaillierte Abzugslogik für Stilspringprüfungen (Hindernisfehler, Ungehorsam, Sturz).
- System-Anforderungen für die UI (Erfassungsmasken) und Validierung (Lizenzprüfung).
- **README-Update:** Verlinkung der neuen Dokumentation in der zentralen `README.md` des Masterdata-Services.
## ✅ Verifizierung
- Abgleich der Abzugswerte (z.B. -0,5 für Abwurf im Stilspringen) mit der ÖTO 2026.
- Prüfung der Reihungsregeln bei Punktgleichheit (Stilnote vor Abzügen).
- Validierung der Konsistenz mit dem bestehenden ZNS-Schnittstellen-Mapping.
## 📝 Notizen
- Diese Daten sind besonders für die Umsetzung von Nachwuchsbewerben und C-NEU Turnieren (lizenzfrei) von hoher
Bedeutung.
- Der `Score-Service` muss im Backend die Logik zur automatischen Berechnung der Endnoten im Stilspringen bereitstellen.