--- type: RULE_SPEC status: DRAFT owner: Rulebook Expert last_update: 2026-04-02 --- # Turnier-Klassen und Abteilungs-Zwangsteilung (ÖTO) Ziel: Einheitliche, maschinenlesbare Spezifikation der Klassensystematik und der verpflichtenden Abteilungs-Teilungsregeln ("Zwangsteilung") gemäß ÖTO. Diese Regeln steuern Backend-Validierungen, Frontend-UX (Hinweise/Warnungen) und Exportlogik. Quellen/Verweise: - Roadmap: `docs/04_Agents/Roadmaps/Rulebook_Roadmap.md` (A-2) - Domänen‑Modell: `docs/03_Domain/01_Core_Model/Domain_Model_Veranstaltung_Turnier_Bewerb_Abteilung.md` - Validierungsregeln (Lizenz/Alter): `docs/03_Domain/02_Reference/Validierungsregeln.md` - ÖTO Referenzstellen (Paragraphen‑Pins zur Nachverfolgung): - Springen: ÖTO 2026, Kapitel „Springen“, § 231 Abs. 1–3 (CSN‑C‑NEU Teilungsregeln) [PIN: OETO-SPR-231] - Dressur: ÖTO 2026, Kapitel „Dressur“, § 103 Abs. 2–5 (Teilnahme/Leistungsstufen) [PIN: OETO-DRS-103] - Vielseitigkeit: ÖTO 2026, Kapitel „Vielseitigkeit“, §§ 3xx (Teilnahme/Abteilungen) [PIN: OETO-VS-3XX] Hinweis Rechtslage: Die obigen „Paragraphen‑Pins“ verankern die Stellen im ÖTO. Exakte Absatz-/Ziffernangaben werden nach juristischer Finalisierung ergänzt. Inhaltliche Logik entspricht dem Stand der Praxis (CSN‑C‑NEU) und wird bei Abweichungen angepasst. --- ## 1. Begriffe (Auszug) - Bewerb: Sportliche Ausschreibungseinheit innerhalb eines Turniers (z. B. Springen 95 cm, Stilspringen). Enthält 1..N Abteilungen. - Abteilung: Startgruppe innerhalb eines Bewerbs. Kann organisatorische oder regelbedingte Gründe haben (Zwangsteilung, Lizenz, Jugend usw.). - Zwangsteilung: Verpflichtende Abteilungsbildung anhand lizenz-/leistungsbezogener Kriterien gemäß ÖTO. --- ## 2. CSN (Springen national) — Zwangsteilung C‑NEU Gültig für Bewerbe der Kategorie „CSN‑C‑NEU“. ### 2.1 Regelübersicht (Zwangsteilung) - Rechtsgrundlage: ÖTO § 231 (vgl. [PIN: OETO-SPR-231]) - Bewerbe mit Höhe ≤ 95 cm: - Abteilung A: Label: „ohne Lizenz“ — Key: `LZF_ONLY` — Allowed: `LZF` - Abteilung B: Label: „mit Lizenz“ — Key: `R1_PLUS` — Allowed: `R1|R2|R3|R4` - Bewerbe mit Höhe ≥ 100 cm: - Abteilung A: Label: „R1“ — Key: `R1_ONLY` — Allowed: `R1` - Abteilung B: Label: „R2 und höher“ — Key: `R2_PLUS` — Allowed: `R2|R3|R4` Erläuterungen: - Die Abteilungsbezeichnungen dienen dem Frontend (Label) und der Preisgeld-/Siegerehrungslogik. Technisch werden die Abteilungen per Attribut „Lizenz‑Gruppe“ markiert. - Veranstalter dürfen enger teilen (z. B. zusätzliche Jugendabteilungen), nicht jedoch lockern (Pflicht‑Zweiteilung muss bestehen bleiben). ### 2.2 Maschinenlesbare Spezifikation Tabelle: CSN‑C‑NEU Zwangsteilung nach Höhe | Höhe (cm) | Abteilung 1 (Label · Key) | Abteilung 2 (Label · Key) | Bemerkung | |---|---|---|---| | ≤ 95 | „ohne Lizenz“ · `LZF_ONLY` | „mit Lizenz“ · `R1_PLUS` | `R1_PLUS` umfasst `R1|R2|R3|R4` | | ≥ 100 | „R1“ · `R1_ONLY` | „R2 und höher“ · `R2_PLUS` | `R2_PLUS` umfasst `R2|R3|R4` | Pseudocode (Ableitung der Pflicht‑Abteilungen): ```kotlin data class ForcedDivision(val label: String, val allowedLicenses: Set) fun forcedDivisionsCsnCNeu(heightCm: Int): List = if (heightCm <= 95) listOf( ForcedDivision(label = DivisionLabels.OHNE_LIZENZ, allowedLicenses = setOf("LZF")), ForcedDivision(label = DivisionLabels.MIT_LIZENZ, allowedLicenses = setOf("R1","R2","R3","R4")) ) else listOf( ForcedDivision(label = DivisionLabels.R1, allowedLicenses = setOf("R1")), ForcedDivision(label = DivisionLabels.R2_UND_HOEHER, allowedLicenses = setOf("R2","R3","R4")) ) ``` Validierung (vereinfachte Regel): - Wenn Bewerbskategorie = `CSN-C-NEU`, dann müssen genau zwei Abteilungen gemäß obiger Ableitung vorhanden sein. Jede Nennung muss in einer Abteilung landen, deren `allowedLicenses` die Lizenz des Reiters enthält. Fehlermeldungen (UX): - „Für CSN‑C‑NEU Bewerbe ist eine Zwangsteilung nach Lizenz vorgeschrieben (ÖTO § 231). Bitte beide Abteilungen anlegen.“ - „Die Abteilung ‚R2 und höher‘ darf nur Lizenzen R2/R3/R4 enthalten.“ - Hinweistext (Quelle): „Rechtsgrundlage: ÖTO § 231 (CSN‑C‑NEU).“ --- ## 3. CDN (Dressur national) — Prüfung weiterer Zwangsteilungen Status: geprüft. Nach aktuellem Stand bestehen in den Einsteiger‑/Niedrig‑Klassen keine zwingenden Lizenz‑Zwangsteilungen analog zu CSN‑C‑NEU. Übliche Praxis ist die optionale Teilung nach Leistungsklassen/Jahrgängen (z. B. Jugendliche), jedoch keine verpflichtende Zweiteilung „ohne/mit Lizenz“. - Ergebnis: Keine allgemeine, disziplinweite Zwangsteilung identifiziert. Veranstalter können freiwillig teilen (z. B. RD1 vs. RD2+), sofern ÖTO konform. Bezug: ÖTO § 103 (vgl. [PIN: OETO-DRS-103]). Folgeaktion: Bei Veröffentlichung der finalen Dressur‑Abschnitte erneut prüfen. Bis dahin: Keine systemweite Pflichtregel hinterlegen. --- ## 4. CCN (Vielseitigkeit national) — Prüfung weiterer Zwangsteilungen Status: vorläufig geprüft. In den nationalen Vielseitigkeitsklassen (CCN) ist keine generische Zwangsteilung nach Lizenzgruppen („ohne/mit“ bzw. `R1` vs. `R2+`) als Pflicht verankert. Teilungen erfolgen eher nach Leistungsniveau, Altersklassen oder organisatorischen Gründen. - Ergebnis: Keine disziplinweiten Pflicht‑Teilungsregeln identifiziert. Konkrete Ausnahmen sind turnierspezifisch. Bezug: ÖTO Kapitel „Vielseitigkeit“, §§ 3xx (vgl. [PIN: OETO-VS-3XX]); exakte Absätze folgen nach Finalisierung. --- ## 5. Implementierungshinweise (Backend/Frontend) - Backend: - Regel „CSN‑C‑NEU → Pflicht‑Abteilungen“ als Regulation‑as‑Data hinterlegen (z. B. `reg_forced_divisions` mit Feldern: `category`, `height_threshold`, `division_key`, `allowed_licenses`). - Serverseitige Validierung beim Anlegen/Bearbeiten eines CSN‑C‑NEU Bewerbs: genau zwei Abteilungen erzwingen, Labels/Allowed‑Sets prüfen. - Nennvalidierung: Lizenz des Reiters ∈ `allowedLicenses` der Zielabteilung. - Frontend: - Wizard/Editor legt bei CSN‑C‑NEU automatisch beide Abteilungen an (konfigurierbare Labels). - Live‑Hinweis, wenn eine Abteilung fehlt oder falsche Lizenzen zugeordnet sind. --- ## 6. Einheitliche Label‑Konventionen für Abteilungen Ziel: Einheitliche, i18n‑fähige Benennung in UI, Exporten und Validierung. Deutsche Standard‑Labels und technische Keys: - DivisionLabels (Deutsch): - OHNE_LIZENZ → „ohne Lizenz“ (Key: `LZF_ONLY`) - MIT_LIZENZ → „mit Lizenz“ (Key: `R1_PLUS`) - R1 → „R1“ (Key: `R1_ONLY`) - R2_UND_HOEHER → „R2 und höher“ (Key: `R2_PLUS`) Richtlinien: - Labels in UI exakt wie oben; keine Varianten („R2+“ nur in Klammern/Hinweisen, offizielles Label: „R2 und höher“). - Keys sind stabil und werden in Datenpersistenz/Exports verwendet. Übersetzungen erfolgen per i18n. Pseudocode (Konstanten): ```kotlin object DivisionLabels { const val OHNE_LIZENZ = "ohne Lizenz" // key: LZF_ONLY const val MIT_LIZENZ = "mit Lizenz" // key: R1_PLUS const val R1 = "R1" // key: R1_ONLY const val R2_UND_HOEHER = "R2 und höher" // key: R2_PLUS } ``` --- ## 7. Erweiterungen: Jugend‑/Jahrgangsteilungen (optional) Status: Optionales Regel‑Set, kein ÖTO‑Pflichtumfang wie bei CSN‑C‑NEU. Veranstalter können zusätzlich nach Jahrgängen/Jugendklassen teilen, sofern ÖTO‑konform (vgl. Dressur § 103 und disziplin‑spezifische Jugendbestimmungen). Modellierung als optionale Regeln: - Datenmodell (Beispiel als Regulation‑as‑Data): - Tabelle `reg_optional_divisions`: - `category` (z. B. `CSN`, `CDN`) - `discipline` (SPRINGEN, DRESSUR, VIELSEITIGKEIT) - `division_key` (z. B. `U16`, `U18`, `U25`, `AMATEURE`) - `label` (z. B. „Jugend U16“, „Jugend U18“) - `age_range` (z. B. `14-16` Jahre, berechnet gem. Stichtag 1.1.; vgl. Validierungsregeln § „Altersklassen Pferd/Reiter“) - `license_filter` (optional, Menge erlaubter Lizenzen) - `notes` (Freitext/Paragraphen‑Bezug) Beispiel (Pseudocode): ```kotlin data class OptionalDivisionRule( val category: String, // CSN, CDN val discipline: String, // SPRINGEN, DRESSUR val divisionKey: String, // U16, U18 val label: String, // "Jugend U16" val ageFrom: Int, val ageTo: Int?, // inklusiv, To=null = open ended val allowedLicenses: Set? = null // null = alle ) fun applies(rule: OptionalDivisionRule, athleteAge: Int, license: String): Boolean = (athleteAge >= rule.ageFrom) && (rule.ageTo?.let { athleteAge <= it } ?: true) && (rule.allowedLicenses?.contains(license) ?: true) ``` UX‑Hinweistexte: - „Optionale Jugendabteilung aktiv: Nur Athlet:innen des Jahrgangsbereichs {label} werden hier gewertet.“ - „Diese Abteilung ist optional; Pflicht‑Zwangsteilung (falls vorhanden) bleibt unberührt.“ --- ## 8. Offene Punkte / ToDos - Juristische Finalisierung: Exakte Absatz-/Ziffernangaben zu [PIN: OETO-SPR-231], [PIN: OETO-DRS-103], [PIN: OETO-VS-3XX] nachtragen. - Backend‑Seed: `reg_forced_divisions` und `reg_optional_divisions` befüllen; Keys/Labels gemäß Abschnitt 6 verwenden. - FE/UX: i18n‑Mapping für DivisionLabels bereitstellen; Editor‑Presets für CSN‑C‑NEU und optionale Jugendabteilungen.