@startuml !theme vibrant title Datenbankmodell ÖTO - Service-Orientierte Modulare Struktur (Stand: 19. Mai 2025, 10:53 Uhr) ' Diagramm-Optionen skinparam linetype ortho hide empty members skinparam shadowing false skinparam defaultFontName "Segoe UI" skinparam defaultFontSize 9 ' Etwas kleiner für mehr Übersicht skinparam roundCorner 10 allow_mixing skinparam packageStyle rect ' --- Enums (mit Suffix E) --- enum SparteE { DRESSUR, SPRINGEN, VIELSEITIGKEIT, FAHREN, VOLTIGIEREN, WESTERN, DISTANZ, ISLAND, PFERDESPORT_SPIEL, SONDERPRUEFUNG, SONSTIGE, UNBEKANNT } enum RegelwerkTypE { OETO, FEI, SONSTIGE } enum PruefungsaufgabeNationE { NATIONAL_OEPS, FEI, SONSTIGE } enum PruefungsaufgabeRichtverfahrenModusE { GM, GT, NICHT_SPEZIFIZIERT } enum PruefungsaufgabeViereckE { VIERECK_20x40, VIERECK_20x60, ANDERE, UNBEKANNT } enum ArtDesStechensE { KEIN_STECHEN, FEHLER_ZEIT_NORMAL, FEHLER_ZEIT_AM3, SIEGERUNDE_SR1_MIT_UEBERNAHME_GP, SIEGERUNDE_SR2_OHNE_UEBERNAHME_GP, ZWEI_STECHEN_AM4, ZWEI_STECHEN_AM6, SONDERREGELUNG_AUSSCHREIBUNG } enum FunktionaerRolleE { RICHTER, RICHTER_VORSITZ, RICHTER_BEI_C, RICHTER_AM_ABREITEPLATZ, PARCOURSBAUER, PARCOURSBAU_ASSISTENT, STEWARD, TECHNISCHER_DELEGIERTER, TURNIERLEITER, TURNIERBEAUFTRAGTER, TIERARZT_TURNIER, HUFSCHMIED_TURNIER, MELD रात्रि, RECHENSTELLE, SPRECHER, REITERSPRECHER, ZEITNEHMER, SCHREIBER_RICHTER, HELFER_PARCOURS, SONSTIGE_FUNKTION } enum RichterPositionE { C, E, H, B, M, VORSITZ, RICHTERTURM, SONSTIGE_POSITION } enum DatenQuelleE { OEPS_ZNS, MANUELL_NATIONAL, MANUELL_INTERNATIONAL, SYSTEM_GENERIERTR } enum NennungStatusE { GEMELDET, MANUELL_ERFASST, BESTAETIGT, NACHGENANNT, BEZAHLT, STARTBERECHTIGT, ABGEMELDET_REITER, ABGEMELDET_VERANSTALTER, STORNIERT_SYSTEM } enum BeginnzeitTypE { FIX_UM, ANSCHLIESSEND, CA_UM, NACH_VORHERIGEM_BEWERB_ABTEILUNG } enum EventStatusE { IN_PLANUNG, GENEHMIGT_VERANSTALTER, OEFFENTLICH_SICHTBAR, AKTIV, ABGESCHLOSSEN, ABGESAGT } enum PlatzTypE { AUSTRAGUNG, VORBEREITUNG, LONGIEREN, SONSTIGES } enum SportfachStammdatenTypE { DRESSURAUFGABE, HINDERNISTYP_SPRINGEN, WERTUNGSVERFAHREN_SPRINGEN, WERTUNGSVERFAHREN_DRESSUR, RVK_PUNKTETABELLE, OETO_REGEL_TEXT, SONSTIGES } enum CupSerieTypE { CUP, MEISTERSCHAFT_LAND, MEISTERSCHAFT_BUND, SERIE, SONDERWERTUNG } ' ##################################################################### ' ### Service OeTO-Verwaltung (Regeln, Lizenzen, Definitionen) ### ' ##################################################################### package "Service OeTO-Verwaltung" { entity OETORegelReferenz { + oeto_regel_referenz_id : UUID <> -- paragraph_nummer : VARCHAR kapitel_titel : VARCHAR? kurzbeschreibung_regel : TEXT? oeto_version_datum : DATE url_detail : VARCHAR? regelwerk_typ : RegelwerkTypE } ' Definiert Funktionärsqualifikationen entity QualifikationsTyp { + qual_typ_code : VARCHAR(20) <> ' z.B. "R-DPF", "PB-S", "TD-NAT" -- bezeichnung : VARCHAR sparte : SparteE oeto_regel_ref_id : UUID <>? } QualifikationsTyp -- "?" OETORegelReferenz ' Globale Lizenz-/Startkartendefinitionen entity LizenzTypGlobal { + lizenz_typ_global_code : VARCHAR(10) <> ' z.B. "R1", "RS2", "F1", "S" (Startkarte) -- bezeichnung : VARCHAR sparte_primaer : SparteE? kategorie_lizenz: VARCHAR ' z.B. "Reiterlizenz", "Startkarte", "Fahrerlizenz" stufe: VARCHAR? ' z.B. "1", "2", "S" beschreibung_berechtigung : TEXT? oeto_regel_ref_id : UUID <>? } LizenzTypGlobal -- "?" OETORegelReferenz entity AltersklasseDefinition { + altersklasse_code : VARCHAR(10) <> ' z.B. "JG", "U18", "YR", "ALLG" -- bezeichnung : VARCHAR min_alter : INTEGER? max_alter : INTEGER? geschlecht_filter : CHAR(1)? oeto_regel_ref_id : UUID <>? } AltersklasseDefinition -- "?" OETORegelReferenz ' Für Dressuraufgaben, Richtverfahren etc. entity Sportfachliche_Stammdaten { + stammdatum_id : UUID <> -- typ : SportfachStammdatenTypE code : VARCHAR ' z.B. "GA02/23", "A2_OETO204" bezeichnung : VARCHAR beschreibung_details_json : TEXT ' Strukturierte Details sparte_zugehoerigkeit : SparteE nation_gueltigkeit: PruefungsaufgabeNationE? viereck_groesse: PruefungsaufgabeViereckE? richtverfahren_modus: PruefungsaufgabeRichtverfahrenModusE? istAktiv: Boolean oeto_regel_ref_id : UUID <>? } Sportfachliche_Stammdaten -- "?" OETORegelReferenz } ' ##################################################################### ' ### Service ZNS-Daten (Staging/Rohdaten von OEPS) ### ' ##################################################################### package "Service ZNS-Daten (Staging)" { entity Verein_ZNS_Staging { + oeps_vereins_nr : VARCHAR(4) <> name : VARCHAR(50) import_timestamp: TIMESTAMP } entity Person_ZNS_Staging { + oeps_satz_nr_person : VARCHAR(6) <> -- familienname : VARCHAR(50) vorname : VARCHAR(25) geburtsdatum_text : VARCHAR(8) geschlecht_code : CHAR(1) nationalitaet_code : VARCHAR(3) bundesland_code_oeps : VARCHAR(2)? vereinsname_oeps_roh : VARCHAR(50)? mitglied_nr_verein : VARCHAR(8)? fei_id_person : VARCHAR(10)? sperrliste_flag_oeps : CHAR(1)? kader_flag_oeps : CHAR(1)? telefon_roh : VARCHAR(21)? reiterlizenz_roh : VARCHAR(4)? startkarte_roh : CHAR(1)? fahrlizenz_roh : VARCHAR(2)? altersklasse_jugend_code_oeps : VARCHAR(2)? altersklasse_jungerreiter_code_oeps : CHAR(1)? jahr_letzte_zahlung_lizenz_oeps : INTEGER? lizenzinfo_raw_oeps : VARCHAR(10)? qualifikationen_raw_oeps: VARCHAR(30)? ' Aus RICHT01.dat import_timestamp: TIMESTAMP } entity Pferd_ZNS_Staging { + oeps_satz_nr_pferd : VARCHAR(10) <> -- oeps_kopf_nr : VARCHAR(4)? name : VARCHAR(30) lebensnummer : VARCHAR(9)? geburtsjahr : INTEGER? geschlecht_code : CHAR(1)? farbe : VARCHAR(15)? abstammung_vater_name_roh : VARCHAR(30)? abstammung_info_roh : VARCHAR(15)? oeps_verein_nr_pferd_roh : VARCHAR(4)? verantwortliche_person_name_roh: VARCHAR(75)? fei_pass_nr : VARCHAR(10)? letzte_zahlung_pferdegebuehr_jahr : INTEGER? import_timestamp: TIMESTAMP } } ' #################################################################################### ' ### Domänen Service: Sportler & Pferde Verwaltung (aus ZNS und manuell) ### ' #################################################################################### package "Service Sportler & Pferde Verwaltung (Domäne)" { entity DomPerson { + person_id: UUID <> -- oeps_satz_nr: VARCHAR(6) <>? nachname: VARCHAR vorname: VARCHAR geburtsdatum: DATE? geschlecht: GeschlechtE? nationalitaet_code: VARCHAR(3)? fei_id: VARCHAR(10)? telefon: VARCHAR? email: VARCHAR? stamm_verein_id: UUID <>? ist_gesperrt: BOOLEAN sperr_grund: TEXT? daten_quelle: DatenQuelleE ist_aktiv: BOOLEAN } entity DomPferd { + pferd_id: UUID <> -- oeps_satz_nr_pferd: VARCHAR(10) <>? oeps_kopf_nr: VARCHAR(4)? name: VARCHAR lebensnummer: VARCHAR? geburtsjahr: INTEGER? geschlecht_pferd: CHAR(1)? besitzer_person_id: UUID <>? verantwortlicher_person_id: UUID <>? heimat_verein_id: UUID <>? daten_quelle: DatenQuelleE ist_aktiv: BOOLEAN } entity DomVerein { + verein_id: UUID <> -- oeps_vereins_nr: VARCHAR(4) <> name: VARCHAR kuerzel: VARCHAR? bundesland_code: VARCHAR(2)? } ' Zugeordnete Lizenz/Quali einer Person entity DomLizenz { + lizenz_id: UUID <> -- person_id: UUID <> lizenz_typ_global_code: VARCHAR(10) <> ' Verweis auf Service_OeTO_Verwaltung.LizenzTypGlobal gueltig_bis_jahr: INTEGER? ist_aktiv_bezahlt_oeps: BOOLEAN } DomPerson "1" -- "0..*" DomLizenz DomLizenz -- "1" Service_OeTO_Verwaltung.LizenzTypGlobal DomPerson "0..1" -- "1" DomVerein : "hat Stammverein" DomPferd "0..1" -- "1" DomPerson : "hat Besitzer" DomPferd "0..1" -- "1" DomPerson : "hat Verantwortlichen" DomPferd "0..1" -- "1" DomVerein : "hat Heimatverein" } ' ##################################################################### ' ### Service Veranstaltungsplanung (Events, Turniere, Prüfungen) ### ' ##################################################################### package "Service Veranstaltungsplanung" { entity VeranstaltungsRahmen { + veranst_rahmen_id : UUID <> name : VARCHAR datum_von_gesamt : DATE datum_bis_gesamt : DATE hauptveranstalter_verein_id : UUID <>? ' Verweis auf DomVerein ort_text: VARCHAR status: EventStatusE } entity Turnier_OEPS { + turnier_id : UUID <> veranst_rahmen_id : UUID <> oeps_turnier_nr : VARCHAR(5) <> name_zusatz : VARCHAR? datum_von_turnier : DATE datum_bis_turnier : DATE oeto_kategorie_definition_ids: List ' FKs zu Service_OeTO_Verwaltung.BewerbsKategorieOetoDefinition regelwerk_typ : RegelwerkTypE hauptsparte: SparteE } ' Entspricht BewerbBasis entity Pruefung_OEPS { + pruefung_db_id : UUID <> turnier_id : UUID <> oeps_bewerb_nr_anzeige : INTEGER ' Deine nummerInAusschreibung name_text_uebergeordnet : VARCHAR sparte : SparteE oeps_kategorie_definition_id : UUID <> ' FK zu Service_OeTO_Verwaltung.BewerbsKategorieOetoDefinition ' Verweise auf spartenspezifische Details (1:1) ' dressur_spezifika_id: UUID <>? ' springen_spezifika_id: UUID <>? } entity Pruefung_Abteilung { + pruefung_abteilung_db_id : UUID <> pruefung_db_id : UUID <> ' FK zu Pruefung_OEPS abteilungs_kennzeichen : VARCHAR ' z.B. "1", "A" bezeichnung_abteilung : VARCHAR? ' ... strukturierte Teilungskriterien ... } entity Meisterschaft_Cup_Serie { + mcs_id : UUID <> name : VARCHAR typ : CupSerieTypE jahr : INTEGER sparte : SparteE } entity MCS_Wertungspruefung { mcs_id : UUID <> <> pruefung_abteilung_db_id : UUID <> <> faktor_fuer_wertung : DECIMAL? } entity Platz { + platz_id: UUID <> name: VARCHAR typ: PlatzTypE '.. berichtFelder .. } entity Turnier_hat_Platz { turnier_id: UUID <> <> platz_id: UUID <> <> verwendungszweck: VARCHAR? } package "Sportfachliche Details Pruefung" { entity DressurPruefungSpezifika { + pruefung_db_id : UUID <> <> ' 1:1 zu Pruefung_OEPS aufgabe_stammdatum_id : UUID <> ' Zu Service_OeTO_Verwaltung.Sportfachliche_Stammdaten klasse_definition_id : UUID <>? ' Zu Service_OeTO_Verwaltung.BewerbsKlasseDefinition richtverfahren_stammdatum_id: UUID <>? ' Zu Service_OeTO_Verwaltung.Sportfachliche_Stammdaten viereck_groesse_code : PruefungsaufgabeViereckE ' geplanteRichterPositionen: List ' oder über BewerbFunktionaerZuordnung } entity SpringPruefungSpezifika { + pruefung_db_id : UUID <> <> ' 1:1 zu Pruefung_OEPS klasse_definition_id : UUID <>? richtverfahren_stammdatum_id: UUID <>? art_des_stechens : ArtDesStechensE? '.. parcours infos .. } } VeranstaltungsRahmen "1" -- "0..*" Turnier_OEPS Turnier_OEPS "1" -- "0..*" Pruefung_OEPS Pruefung_OEPS "1" -- "1..*" Pruefung_Abteilung Pruefung_OEPS "1" o-- "0..1" Sportfachliche_Details_Pruefung.DressurPruefungSpezifika Pruefung_OEPS "1" o-- "0..1" Sportfachliche_Details_Pruefung.SpringenPruefungSpezifika Meisterschaft_Cup_Serie "1" -- "0..*" MCS_Wertungspruefung Pruefung_Abteilung "1" -- "0..*" MCS_Wertungspruefung Turnier_OEPS "1" -- "0..*" Turnier_hat_Platz Platz "1" -- "0..*" Turnier_hat_Platz Sportfachliche_Details_Pruefung.DressurPruefungSpezifika -- Service_OeTO_Verwaltung.Sportfachliche_Stammdaten Sportfachliche_Details_Pruefung.SpringenPruefungSpezifika -- Service_OeTO_Verwaltung.Sportfachliche_Stammdaten Pruefung_OEPS -- Service_OeTO_Verwaltung.BewerbsKategorieOetoDefinition Turnier_OEPS -- Service_OeTO_Verwaltung.BewerbsKategorieOetoDefinition } ' ##################################################################### ' ### Service Nennungsabwicklung (Nennungen, Startlisten, Ergebnisse) ### ' ##################################################################### package "Service Nennungsabwicklung" { entity Nennung { + nennung_id : UUID <> pruefung_abteilung_db_id : UUID <> teilnehmer_person_id : UUID <> ' Verweis auf DomPerson genanntes_pferd_id : UUID <> ' Verweis auf DomPferd genutzte_lizenz_id: UUID <>? ' Verweis auf DomLizenz nennungs_zeitpunkt : TIMESTAMP status_nennung : NennungStatusE kopf_nr_pferd_fuer_nennung : VARCHAR(4)? startgeld_bezahlt: BOOLEAN pferdepass_kontrolliert: BOOLEAN } entity NennungsTeilnehmerSnapshot { + snapshot_id: UUID <> nennung_id: UUID <> ' Gesnapshotete Daten ' person_nachname_snapshot: VARCHAR pferd_name_snapshot: VARCHAR } Nennung "1" -- "0..1" NennungsTeilnehmerSnapshot entity Startfolge { + startfolge_id: UUID <> nennung_id: UUID <> start_nummer_display: INTEGER start_zeit_geplant: TIMESTAMP? s4_kader_flag: BOOLEAN } Nennung "1" -- "0..1" Startfolge entity Ergebnis_Zeile { + ergebnis_zeile_id : UUID <> startfolge_id : UUID <> platz : INTEGER? ' Verweise auf spartenspezifische Ergebnisdetails ' } Startfolge "1" -- "0..1" Ergebnis_Zeile package "Sportfachliche Details Ergebnis" { entity DressurErgebnisSpezifika { + ergebnis_zeile_id : UUID <> <> gesamt_wertnote : DECIMAL(5,3)? gesamt_prozent : DECIMAL(5,2)? } entity SpringenErgebnisSpezifika { + ergebnis_zeile_id : UUID <> <> stilnote_gesamt : DECIMAL(3,1)? } entity SpringenUmlaufErgebnis { + umlauf_ergebnis_id : UUID <> springen_ergebnis_spezifika_id : UUID <> umlauf_oder_stechen_nr : INTEGER fehlerpunkte_hindernis : DECIMAL(4,2)? fehlerpunkte_zeit : DECIMAL(4,2)? zeit_benoetigt_sek : DECIMAL(5,2)? } SpringenErgebnisSpezifika "1" -- "0..*" SpringenUmlaufErgebnis } Ergebnis_Zeile "1" -- "0..1" Sportfachliche_Details_Ergebnis.DressurErgebnisSpezifika Ergebnis_Zeile "1" -- "0..1" Sportfachliche_Details_Ergebnis.SpringenErgebnisSpezifika } ' ##################################################################### ' ### Paketübergreifende Beziehungen (Auswahl) ### ' ##################################################################### Service_Veranstaltungsplanung.VeranstaltungsRahmen -- Service_Sportler_Pferde_Verwaltung.DomVerein : "veranstaltet von" Service_Veranstaltungsplanung.Turnier_OEPS -- Service_Veranstaltungsplanung.VeranstaltungsRahmen Service_Veranstaltungsplanung.Pruefung_OEPS -- Service_Veranstaltungsplanung.Turnier_OEPS Service_Veranstaltungsplanung.Pruefung_Abteilung -- Service_Veranstaltungsplanung.Pruefung_OEPS Service_Veranstaltungsplanung.Sportfachliche_Details_Pruefung.SpringenPruefungSpezifika -- Service_Sportler_Pferde_Verwaltung.DomPerson : "Parcoursdesigner" Service_Nennungsabwicklung.Nennung -- Service_Veranstaltungsplanung.Pruefung_Abteilung Service_Nennungsabwicklung.Nennung -- Service_Sportler_Pferde_Verwaltung.DomPerson : "Reiter" Service_Nennungsabwicklung.Nennung -- Service_Sportler_Pferde_Verwaltung.DomPferd : "Pferd" Service_Nennungsabwicklung.Nennung -- Service_Sportler_Pferde_Verwaltung.DomLizenz : "genutzte Lizenz" ' Beziehungen für Funktionärsplanung (noch konzeptionell) entity FunktionaerEinsatzPlanung { + einsatz_plan_id: UUID <> # event_id: UUID <> # turnier_id: UUID <>? # pruefung_abteilung_id: UUID <>? # funktionaer_person_id: UUID <> rolle: FunktionaerRolleE position_richter: RichterPositionE? start_zeit: TIMESTAMP ende_zeit: TIMESTAMP } Service_Veranstaltungsplanung.VeranstaltungsRahmen -- "0..*" FunktionaerEinsatzPlanung Service_Sportler_Pferde_Verwaltung.DomPerson -- "0..*" FunktionaerEinsatzPlanung @enduml