# Turnier- & Bewerbsstruktur Diagramm

Dieses Diagramm zeigt die strukturelle Hierarchie und die Beziehungen zwischen Event, Turnier und Bewerb basierend auf
dem ÖTO-Regelwerk und den Anforderungen der OEPS-Schnittstelle.

```mermaid
erDiagram
%% Entities
  EVENT {
    string id PK "UUID"
    string name "z.B. Apropos Pferd 2026"
    date start_date
    date end_date
    string location
    string organizer_id FK "Veranstalter (Akteur)"
    string status "PLANNING, ACTIVE, ARCHIVED"
  }
  
  TOURNAMENT {
    string id PK "UUID"
    string event_id FK
    string oeps_number "z.B. 21001 (A-Satz)"
    string category "z.B. CSN-A, CDN-B, CDN-C-NEU"
    string ruleset "OETO oder FEI"
  }
  
  COMPETITION {
    string id PK "UUID"
    string tournament_id FK
    string code_internal "2-stellig (B-Satz Pos. 2)"
    string code_official "3-stellig (B-Satz Pos. 61)"
    int division_id "Abteilung (0=keine, 1=Abt. 1...)"
    string title "z.B. Standardspringprüfung"
    string discipline "S (Springen), D (Dressur), C"
    string category "Klasse z.B. A, L, M, S*, lizenzfrei"
    string scoring_method "Richtverfahren (z.B. A0, A2, AM5, Stil)"
    int start_fee "in Cent"
    string status "OPEN, RUNNING, FINISHED"
    int planned_duration_per_starter_seconds "Kalkulierte Reitzeit pro Starter"
  }
  
  OFFICIALS {
    string id PK "UUID"
    string tournament_id FK "oder competition_id"
    string actor_id FK "Richter / Parcoursbauer"
    string role "Hauptrichter, Richter, TD, Parcoursbauer"
  }
  
  ACTOR {
    string id PK "UUID"
    string oeps_id "z.B. 123456"
    string type "PERSON, ORGANIZATION"
    string name "Vollständiger Name"
    string license_code "z.B. R1"
  }
  
  QUALIFICATION {
    string id PK "UUID"
    string actor_id FK
    string discipline "S, D, V"
    string level "z.B. L, M, S"
    string role "RICHTER, PARCOURSBAUER"
  }
  
  ENTRY {
    string id PK "UUID"
    string competition_id FK
    string horse_id FK
    string rider_id FK
    string status "ACTIVE, WITHDRAWN"
    string preferred_start_position "Optional: vorne, hinten, zu"
  }
  
  START_LIST_ENTRY {
    string id PK "UUID"
    string entry_id FK
    int start_order "Nummer in der Startreihenfolge"
    string status "READY, IN_PROGRESS, FINISHED, DNS"
  }
  
  RESULT {
    string id PK "UUID"
    string start_list_entry_id FK
    int rank "Platzierung (kann manuell überschrieben werden)"
    string status "OK, EL, RET, DNS"
    float points "Fehlerpunkte / Wertnote"
    float time_seconds "Benötigte Zeit"
    int prize_money "Ausbezahltes Geld in Cent"
  }
  
  BILLING_ACCOUNT {
    string id PK "UUID"
    string event_id FK
    string payer_id FK "Akteur (Zahler)"
    int current_balance "in Cent"
  }
  
  TRANSACTION {
    string id PK "UUID"
    string account_id FK
    string entry_id FK "Optionaler Bezug zur Nennung"
    string type "NENNGELD, STARTGELD, TAUSCHGEBÜHR, NACHNENNUNG"
    int amount "in Cent"
  }

%% Relationships
  EVENT ||--o{ TOURNAMENT: "beinhaltet"
  TOURNAMENT ||--o{ COMPETITION: "besteht aus (B-Satz)"
  TOURNAMENT ||--o{ OFFICIALS: "hat Funktionäre (C-Satz)"
  COMPETITION ||--o{ OFFICIALS: "wird gerichtet von"
  OFFICIALS }o--|| ACTOR: "ist ein"
  ACTOR ||--o{ QUALIFICATION: "hat Berechtigungen"
  COMPETITION ||--o{ ENTRY: "hat Nennungen"
  ENTRY ||--o| START_LIST_ENTRY: "wird zu Starter"
  START_LIST_ENTRY ||--o| RESULT: "hat Ergebnis"
  EVENT ||--o{ BILLING_ACCOUNT: "verwaltet Kassa für"
  BILLING_ACCOUNT ||--o{ TRANSACTION: "verbucht"
```

## Erläuterung zum Modell

### 1. `EVENT` (Veranstaltung)

Das **Event** ist der übergeordnete organisatorische Rahmen (z.B. "Pferdefestival 2026"). Es hat ein Datum, einen Ort
und einen Veranstalter. Es existiert unabhängig von den strikten OEPS-Regularien und ist primär für die administrative
Verwaltung (Rechnungsstellung, Anlagenplanung) wichtig.

### 2. `TOURNAMENT` (Turnier)
Ein Event kann mehrere **Turniere** beinhalten (z.B. ein nationales CSN-B und gleichzeitig ein internationales CSI2*).
Das Turnier ist die Instanz, die strikt an das Regelwerk gebunden ist:
* Es korrespondiert 1:1 mit dem **A-Satz** des OEPS-Pflichtenhefts.
* Es hat eine eindeutige 5-stellige `oeps_number`.
* Es legt fest, nach welchem Regelwerk (ÖTO vs. FEI) geritten und ausgewertet wird. In der ersten Phase konzentrieren
  wir uns auf **C-NEU** und **C**.

### 3. `COMPETITION` (Bewerb / Prüfung)

Die kleinste sportliche Einheit und das Herzstück der Ausschreibung. Wir fokussieren uns initial auf **Dressur (D)** und
**Springen (S)**.
Hier finden wir die direkte Verbindung zum **B-Satz** der Legacy-Spezifikation:

* **Abteilungen (`division_id`):** Laut OEPS-Schnittstelle wird jede Abteilung (z.B. R1-Reiter getrennt von R2-Reitern)
  datentechnisch fast wie ein eigener Bewerb behandelt. In unserer Datenbank repräsentieren wir jede Abteilung als
  eigene Zeile in der Tabelle `competition` (oder verknüpfen sie intelligent), da jede Abteilung ihre eigene
  Ergebnisliste und ihr eigenes Preisgeld hat.
* **Nummerierung:** Intern 2-stellig (`code_internal`), für Turniere ab 100 Bewerben offiziell 3-stellig (
  `code_official` an Stelle 61).
* **Richtverfahren:** Entscheidet darüber, wie Fehler und Zeit (Springen) oder Wertnoten (Dressur) in ein Ranking
  übersetzt werden.
* **Zeitplanung:** `planned_duration_per_starter_seconds` ist für die Kalkulation der Startzeiten elementar.

### 4. `OFFICIALS` & `QUALIFICATION` (Der C-Satz & ZNS-Import)

Dies entspricht dem **C-Satz**. Richter und Parcoursbauer müssen einem Turnier oder spezifisch einem Bewerb zugewiesen
werden.

* Neu: Die Entität `QUALIFICATION` bildet die importierten Lizenzstufen aus der ZNS-Datei `RICHT01.DAT` ab. Das Backend
  gleicht diese Berechtigungen bei der Zuweisung gegen die Kategorie der `COMPETITION` ab.

### 5. `ENTRY`, `START_LIST_ENTRY` & `RESULT` (Nennung bis Ergebnis)

* **`ENTRY` (Nennung):** Die Nennung verknüpft ein Pferd und einen Reiter mit einem bestimmten Bewerb. Hier werden auch
  **Startwünsche** (vorne/hinten) erfasst, die für den Telefon-Workflow kritisch sind.
* **`START_LIST_ENTRY` (Startliste):** Generiert aus den aktiven Nennungen. Definiert die exakte Startreihenfolge.
* **`RESULT` (Ergebnis):** Hält die im "Richterturm-Workflow" erfassten Rohdaten (Punkte/Zeit) und die errechnete
  Platzierung. Die Platzierung kann bei Bedarf manuell vom Veranstalter überschrieben werden (z.B. wenn mehr Platziert
  werden sollen, als die ÖTO vorschlägt).

### 6. Billing Context (`BILLING_ACCOUNT` & `TRANSACTION`)

Die Abrechnung (Kassa) wird als separater Bereich an das `EVENT` gehängt.

* Es wird ein `BILLING_ACCOUNT` pro "Zahler" (meist ein `ACTOR`) geführt.
* Jede Gebühr (Nenngeld, Startgeld, Nachnenngebühr) wird als atomare `TRANSACTION` verbucht.
* Wenn ein **Nennungstausch** stattfindet, bleibt das Nenngeld als positive Transaktion auf dem Account erhalten,
  während für die neue Nennung lediglich eine neue Startgeld- oder Tauschgebühr-Transaktion erzeugt wird. Das ermöglicht
  maximale Flexibilität.
