meldestelle/docs/03_Domain/02_Reference/OETO_Regelwerk/B2-Backend-Uebergabe-Regulation-as-Data.md
Stefan Mogeritsch c696b8c50e feat(db): add regulation-as-data tables for license height and horse age matrices
- Introduced `license_height_matrix` for mapping minimum license requirements to jump heights (ÖTO § 231).
- Added `horse_min_age_matrix` for defining minimum horse ages by discipline, height, or level (ÖTO § 103, FEI GR Art. 136).
- Populated both tables with ÖTO 2026 and FEI-compliant seed data.
- Updated Flyway V008 to remove incorrect `RD4` entry and annotated corrected enum references.
- Created Flyway V009 for introducing the new tables and their seeds.
- Aligned documentation, validation rules, and roadmaps for backend implementation handover.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
2026-04-03 11:10:45 +02:00

13 KiB
Raw Blame History

type status owner last_update sprint
BACKEND_SPEC DRAFT Rulebook Expert 2026-04-03 B-2

B-2 Backend-Übergabe: Regulation-as-Data

Zweck: Vollständige Spezifikation der Lizenz-/Altersmatrix als Regulation-as-Data für das Backend ( Masterdata-SCS). Dieses Dokument ist die verbindliche Übergabe vom 📜 Rulebook Expert an 👷 Backend Developer. Nach Fachfreigabe durch das ÖTO-Fachreferat wird der Status von DRAFT auf STABLE angehoben.


1. Überblick: Was wird übergeben?

Artefakt Datei / Ort Status
LizenzKlasseE-Enum (korrigiert, R4 ergänzt) core/core-domain/.../Enums.kt Implementiert
Flyway V008 (Turnierklassen + Lizenz-Matrix + Altersklassen Reiter) masterdata-service/.../V008__Seed_OETO_2026_Data.sql Korrigiert (RD4 entfernt)
Flyway V009 (Höhen-Lizenz-Matrix + Mindestalter-Pferd-Matrix) masterdata-service/.../V009__Add_HorseAge_And_LicenseHeight_Matrix.sql Neu angelegt
Validierungsregeln v0.3 docs/03_Domain/02_Reference/Validierungsregeln.md DRAFT
Diese Spezifikation docs/.../B2-Backend-Uebergabe-Regulation-as-Data.md DRAFT

2. Enum-Korrekturen (core-domain)

2.1 LizenzKlasseE — Vollständiger Katalog

enum class LizenzKlasseE {
  LIZENZFREI,  // Keine Lizenz erforderlich (= "ohne Lizenz", CSN-C-NEU)
  R1,          // Reiter-Lizenz Klasse 1
  R2,          // Reiter-Lizenz Klasse 2
  R3,          // Reiter-Lizenz Klasse 3
  R4,          // Reiter-Lizenz Klasse 4  ← NEU ergänzt (war fehlend)
  RD1,         // Dressur-Reiter Klasse 1
  RD2,         // Dressur-Reiter Klasse 2
  RD3,         // Dressur-Reiter Klasse 3
  JN,          // Jugend/Nachwuchs
  JG,          // Junioren
  YR           // Young Rider
}

⚠️ Wichtig: RD4 existiert nicht im ÖTO-Regelwerk. Der bisherige Seed V008 enthielt RD4 fälschlicherweise — wurde in V008 korrigiert (entfernt). Höchste Dressur-Lizenz ist RD3.

2.2 Schlüssel-Konvention (SSoT)

Doku-Label Enum-Key (SSoT) Hinweis
„ohne Lizenz" / „lizenzfrei" LIZENZFREI Nicht LZF — Enum ist maßgeblich
„mit Lizenz" / „R1" R1
„R2 und höher" R2, R3, R4 Aufwärts-kompatibel

3. Datenbank-Tabellen (Regulation-as-Data)

3.1 Bestehende Tabellen (V005/V008)

Tabelle Zweck
turnierklasse Klassen-Codes (E, A, L, LM, M, S) je Sparte mit max_hoehe
license_matrix Max. Turnierklasse je Lizenz (1 Zeile pro Lizenz × Sparte)
altersklasse Altersklassen der Reiter (Kinder, Jugend, Junioren, YR, AK, Senioren)

3.2 Neue Tabellen (V009)

license_height_matrix

Granulare Höhen-Lizenz-Zuordnung für Springen (eine Zeile pro Höhenbereich × erlaubte Lizenz).

-- Abfrage: Welche Lizenzen sind für 110 cm erlaubt?
SELECT lizenz_klasse
FROM license_height_matrix
WHERE sparte = 'SPRINGEN'
  AND hoehe_von_cm <= 110
  AND hoehe_bis_cm >= 110
  AND ist_aktiv = true;
-- Ergebnis: R1, R2, R3, R4

horse_min_age_matrix

Mindestalter des Pferdes (Stichtag 1. Jänner) je Sparte + Höhenbereich oder Aufgabenniveau.

-- Abfrage: Mindestalter für Springen 125 cm?
SELECT min_alter_jahre
FROM horse_min_age_matrix
WHERE sparte = 'SPRINGEN'
  AND hoehe_von_cm <= 125
  AND hoehe_bis_cm >= 125
  AND ist_aktiv = true;
-- Ergebnis: 5

4. Lizenz × Bewerb-Tabellen (DRAFT → Fachfreigabe erforderlich)

4.1 Springen (CSN) — Lizenz-Zuordnung nach Hindernishöhe

Quelle: ÖTO 2026 § 231 | Status: DRAFT — Fachfreigabe ausstehend

Klasse Höhe (cm) Mindest-Lizenz Zugelassene Lizenzen Bemerkung
E0 (Einsteiger) 6095 LIZENZFREI LIZENZFREI, R1, R2, R3, R4 CSN-C-NEU: Zwangsteilung in Abt. „ohne Lizenz" + „mit Lizenz"
A (Anfänger) 100110 R1 R1, R2, R3, R4 Keine LIZENZFREI mehr ab 100 cm
L (Leicht) 115120 R1* R1, R2, R3, R4 *Ausschreibung kann R2 vorschreiben
LM (Leicht-Mittel) 125130 R2 R2, R3, R4
M (Mittelschwer) 135 R3 R3, R4
S (Schwer) 140160 R4 R4

Aufwärts-Kompatibilität: Eine höhere Lizenz berechtigt immer zur Teilnahme in niedrigeren Klassen.

4.2 Dressur (CDN) — Lizenz-Zuordnung nach Aufgabenniveau

Quelle: ÖTO 2026 § 103 | Status: DRAFT — Fachfreigabe ausstehend

Klasse Aufgabenniveau Mindest-Lizenz Zugelassene Lizenzen
Einsteiger E LIZENZFREI LIZENZFREI, RD1, RD2, RD3
A (Anfänger) A RD1 RD1, RD2, RD3
L (Leicht) L RD1 RD1, RD2, RD3
LM (Leicht-Mittel) LM RD2 RD2, RD3
M (Mittelschwer) M RD2 RD2, RD3
S (Schwer) S RD3 RD3

5. Mindestalter Pferd (Regulation-as-Data)

Stichtagsregel: Alter = veranstaltungsjahr - geburtsjahr (Stichtag 1. Jänner)

5.1 Springen national (ÖTO § 231)

Höhe (cm) Mindestalter Pferd (Jahre)
60100 4
101120 5
121999 6

5.2 Dressur national (ÖTO § 103)

Aufgabenniveau Mindestalter Pferd (Jahre)
E 4
A 4
L 4
LM 5
M 5
S 6

5.3 International FEI (GR Art. 136)

Disziplin Level Mindestalter Pferd
Springen 1*2* 6
Springen 3*5* 7
Dressur CDI Senior 7
Dressur CDI Young Horse 4 (gem. FEI YH-Regeln)

6. Serverseitige Validierungslogik (Pseudocode)

Das Backend soll die folgenden Prüfungen serverseitig durchführen (analog zur Frontend-Validierung):

6.1 Lizenz-Check (Springen)

fun isLicenseAllowedForHeight(hoeheCm: Int, lizenz: LizenzKlasseE): Boolean {
  // Abfrage license_height_matrix
  val allowed = licenseHeightMatrixRepo.findAllowedLicenses(
    sparte = "SPRINGEN",
    hoehe = hoeheCm
  )
  return lizenz.name in allowed
}

6.2 Lizenz-Check (Dressur)

fun isLicenseAllowedForLevel(niveau: String, lizenz: LizenzKlasseE): Boolean {
  // Abfrage license_matrix (max_turnierklasse_code Vergleich)
  val maxKlasse = licenseMatrixRepo.findMaxKlasse(sparte = "DRESSUR", lizenz = lizenz.name)
  return klasseOrdnung.indexOf(niveau) <= klasseOrdnung.indexOf(maxKlasse)
}

6.3 Mindestalter-Pferd-Check

fun isHorseOldEnough(
  geburtsjahr: Int, veranstaltungsjahr: Int,
  sparte: String, hoeheCm: Int?, niveau: String?
): Boolean {
  val alter = veranstaltungsjahr - geburtsjahr  // Stichtag 1. Jänner
  val minAlter = horseMinAgeRepo.findMinAlter(sparte, hoeheCm, niveau)
  return alter >= minAlter
}

7. REST-Endpunkte (Masterdata-SCS) — Empfehlung

Methode Pfad Beschreibung
GET /api/regulation/license-height-matrix?sparte=SPRINGEN&hoehe=110 Erlaubte Lizenzen für Höhe
GET /api/regulation/license-matrix?sparte=DRESSUR&lizenz=RD2 Max. Klasse für Lizenz
GET /api/regulation/horse-min-age?sparte=SPRINGEN&hoehe=125 Mindestalter Pferd
GET /api/regulation/horse-min-age?sparte=DRESSUR&niveau=LM Mindestalter Pferd (Dressur)
GET /api/fei/resolve/{id} FEI Legacy→Numeric Resolver (bereits implementiert )

8. Abweichungen Backend ↔ Frontend

Thema Frontend (KMP) Backend (Spring) Handlungsbedarf
Lizenz-Keys LZF (alter Key in Doku) LIZENZFREI (Enum) Doku korrigiert; Frontend-Code prüfen
R4 Vorhanden in OetoValidators Enum jetzt ergänzt Kein weiterer Bedarf
RD4 Nicht vorhanden Seed V008 korrigiert Kein weiterer Bedarf
Höhen-Matrix OetoValidators.kt (hardcoded) V009 als DB-Tabelle Backend liest aus DB; Frontend bleibt hardcoded bis Phase 2
Mindestalter Pferd OetoValidators.kt (hardcoded) V009 als DB-Tabelle Wie oben

9. Fachfreigabe-Checkliste (DRAFT → STABLE)

Folgende Punkte müssen vor Anhebung auf STABLE durch das ÖTO-Fachreferat bestätigt werden:

  • Lizenz-Zuordnungstabelle Springen (§ 231): Höhenschwellen und Mindestlizenzen korrekt?
  • Lizenz-Zuordnungstabelle Dressur (§ 103): Niveaustufen und Mindestlizenzen korrekt?
  • Mindestalter Pferd Springen (§ 231): Schwellen 4/5/6 Jahre korrekt?
  • Mindestalter Pferd Dressur (§ 103): Schwellen je Niveau korrekt?
  • Aufwärts-Kompatibilität (höhere Lizenz → niedrigere Klasse erlaubt): bestätigt?
  • Paragraphen-Nummern (§ 231, § 103) final verifiziert?
  • Sonderfall CSN-C-NEU Zwangsteilung (LIZENZFREI + R1 in E0): korrekt?

Nach Bestätigung aller Punkte:

  1. Status in dieser Datei auf STABLE setzen
  2. Validierungsregeln.mdstatus: STABLE, version: 1.0
  3. Flyway V009 → Kommentar Status: DRAFT entfernen
  4. Roadmap B-2 als abgeschlossen markieren

10. Offene Punkte

# Thema Verantwortlich Priorität
1 Fachfreigabe Lizenz×Bewerb-Tabellen einholen 📜 Rulebook Expert 🔴 Hoch
2 Backend-Endpunkte /api/regulation/* implementieren 👷 Backend 🔴 Hoch
3 Frontend LZF-Key → LIZENZFREI prüfen/angleichen 🎨 Frontend 🟠 Mittel
4 AltersklasseRechner (C-1) implementieren 👷 Backend + 📜 Rulebook 🟠 Mittel
5 FEI-Mindestalter-Tabellen aus Disziplinregelwerken finalisieren 📜 Rulebook Expert 🟡 Niedrig