docs: add domain workshop results and event structure diagram
- Documented outcomes of the 2026-03-17 domain workshop under `docs/03_Domain/03_Analysis/Domain_Workshop_Results_2026-03-17.md`. - Added a structural diagram visualizing events, tournaments, and competitions with their relationships under `docs/03_Domain/01_Core_Model/Entities/Event_Structure_Diagram.md`. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
parent
b6f4f43122
commit
2538be395a
|
|
@ -20,7 +20,7 @@ erDiagram
|
||||||
string id PK "UUID"
|
string id PK "UUID"
|
||||||
string event_id FK
|
string event_id FK
|
||||||
string oeps_number "z.B. 21001 (A-Satz)"
|
string oeps_number "z.B. 21001 (A-Satz)"
|
||||||
string category "z.B. CSN-A, CDN-B"
|
string category "z.B. CSN-A, CDN-B, CDN-C-NEU"
|
||||||
string ruleset "OETO oder FEI"
|
string ruleset "OETO oder FEI"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,18 +31,76 @@ erDiagram
|
||||||
string code_official "3-stellig (B-Satz Pos. 61)"
|
string code_official "3-stellig (B-Satz Pos. 61)"
|
||||||
int division_id "Abteilung (0=keine, 1=Abt. 1...)"
|
int division_id "Abteilung (0=keine, 1=Abt. 1...)"
|
||||||
string title "z.B. Standardspringprüfung"
|
string title "z.B. Standardspringprüfung"
|
||||||
string category "Klasse z.B. L, M, S*"
|
|
||||||
string discipline "S (Springen), D (Dressur), C"
|
string discipline "S (Springen), D (Dressur), C"
|
||||||
string scoring_method "Richtverfahren (z.B. A0, A2)"
|
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"
|
int start_fee "in Cent"
|
||||||
string status "OPEN, RUNNING, FINISHED"
|
string status "OPEN, RUNNING, FINISHED"
|
||||||
|
int planned_duration_per_starter_seconds "Kalkulierte Reitzeit pro Starter"
|
||||||
}
|
}
|
||||||
|
|
||||||
OFFICIALS {
|
OFFICIALS {
|
||||||
string id PK "UUID"
|
string id PK "UUID"
|
||||||
string tournament_id FK "oder competition_id"
|
string tournament_id FK "oder competition_id"
|
||||||
string actor_id FK "Richter / Parcoursbauer"
|
string actor_id FK "Richter / Parcoursbauer"
|
||||||
string role "Hauptrichter, Richter, TD"
|
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
|
%% Relationships
|
||||||
|
|
@ -50,9 +108,16 @@ erDiagram
|
||||||
TOURNAMENT ||--o{ COMPETITION: "besteht aus (B-Satz)"
|
TOURNAMENT ||--o{ COMPETITION: "besteht aus (B-Satz)"
|
||||||
TOURNAMENT ||--o{ OFFICIALS: "hat Funktionäre (C-Satz)"
|
TOURNAMENT ||--o{ OFFICIALS: "hat Funktionäre (C-Satz)"
|
||||||
COMPETITION ||--o{ OFFICIALS: "wird gerichtet von"
|
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 (Option B)
|
## Erläuterung zum Modell
|
||||||
|
|
||||||
### 1. `EVENT` (Veranstaltung)
|
### 1. `EVENT` (Veranstaltung)
|
||||||
|
|
||||||
|
|
@ -61,17 +126,17 @@ und einen Veranstalter. Es existiert unabhängig von den strikten OEPS-Regularie
|
||||||
Verwaltung (Rechnungsstellung, Anlagenplanung) wichtig.
|
Verwaltung (Rechnungsstellung, Anlagenplanung) wichtig.
|
||||||
|
|
||||||
### 2. `TOURNAMENT` (Turnier)
|
### 2. `TOURNAMENT` (Turnier)
|
||||||
|
|
||||||
Ein Event kann mehrere **Turniere** beinhalten (z.B. ein nationales CSN-B und gleichzeitig ein internationales CSI2*).
|
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:
|
Das Turnier ist die Instanz, die strikt an das Regelwerk gebunden ist:
|
||||||
|
|
||||||
* Es korrespondiert 1:1 mit dem **A-Satz** des OEPS-Pflichtenhefts.
|
* Es korrespondiert 1:1 mit dem **A-Satz** des OEPS-Pflichtenhefts.
|
||||||
* Es hat eine eindeutige 5-stellige `oeps_number`.
|
* Es hat eine eindeutige 5-stellige `oeps_number`.
|
||||||
* Es legt fest, nach welchem Regelwerk (ÖTO vs. FEI) geritten und ausgewertet wird.
|
* 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)
|
### 3. `COMPETITION` (Bewerb / Prüfung)
|
||||||
|
|
||||||
Die kleinste sportliche Einheit und das Herzstück der Ausschreibung.
|
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:
|
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)
|
* **Abteilungen (`division_id`):** Laut OEPS-Schnittstelle wird jede Abteilung (z.B. R1-Reiter getrennt von R2-Reitern)
|
||||||
|
|
@ -82,8 +147,31 @@ Hier finden wir die direkte Verbindung zum **B-Satz** der Legacy-Spezifikation:
|
||||||
`code_official` an Stelle 61).
|
`code_official` an Stelle 61).
|
||||||
* **Richtverfahren:** Entscheidet darüber, wie Fehler und Zeit (Springen) oder Wertnoten (Dressur) in ein Ranking
|
* **Richtverfahren:** Entscheidet darüber, wie Fehler und Zeit (Springen) oder Wertnoten (Dressur) in ein Ranking
|
||||||
übersetzt werden.
|
übersetzt werden.
|
||||||
|
* **Zeitplanung:** `planned_duration_per_starter_seconds` ist für die Kalkulation der Startzeiten elementar.
|
||||||
|
|
||||||
### 4. `OFFICIALS` (Funktionäre)
|
### 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
|
Dies entspricht dem **C-Satz**. Richter und Parcoursbauer müssen einem Turnier oder spezifisch einem Bewerb zugewiesen
|
||||||
werden. Deren 6-stellige OEPS-Nummer (Satznummer) wird für den Ergebnis-Export benötigt.
|
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.
|
||||||
|
|
|
||||||
101
docs/03_Domain/01_Core_Model/Processes/ZNS_Import_Process.md
Normal file
101
docs/03_Domain/01_Core_Model/Processes/ZNS_Import_Process.md
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
# Prozess: ZNS-Import (Master Data Sync)
|
||||||
|
|
||||||
|
**Status:** Draft / Konzept
|
||||||
|
**Datum:** 17.03.2026
|
||||||
|
|
||||||
|
## 1. Ausgangslage & Herausforderungen
|
||||||
|
|
||||||
|
Das OEPS stellt die Stammdaten als ZIP-Datei (`zns.zip`) bereit, die in Form von textbasierten ASCII-Dateien (Codepage
|
||||||
|
850) vorliegen. Die Struktur ist starr, nicht relational und erfahrungsgemäß oft fehlerbehaftet oder unsauber
|
||||||
|
formatiert (Legacy-Spezifikation V2.4).
|
||||||
|
|
||||||
|
Zusätzlich ändern sich Lizenzstände, Sperrlisten oder Registrierungen laufend. Weiters ist die Meldestelle oft
|
||||||
|
gezwungen, vor Ort manuelle Korrekturen vorzunehmen oder Daten aus anderen Quellen (z.B. Zuchtverbände wie AWÖ) zu
|
||||||
|
integrieren.
|
||||||
|
|
||||||
|
## 2. Architektonische Entscheidung: Event Sourcing & CQRS
|
||||||
|
|
||||||
|
Um den Anforderungen (vollständige Historie, turnierspezifischer Datenstand, fehlertoleranter Import, **manuelle
|
||||||
|
Overrides**) gerecht zu werden, wird der ZNS-Import nach Prinzipien von **Event Sourcing** und **CQRS (Command Query
|
||||||
|
Responsibility Segregation)** konzipiert.
|
||||||
|
|
||||||
|
* Wir überschreiben keine Daten einfach (`UPDATE`), sondern hängen Änderungen als Ereignisse (`EVENTS`) an.
|
||||||
|
* Dies ermöglicht es uns, den Stand einer Person oder eines Pferdes für die Ewigkeit exakt zu rekonstruieren, selbst
|
||||||
|
wenn sich die Stammdaten ändern.
|
||||||
|
|
||||||
|
### 2.1 Der Import-Ablauf (Die "Command" Seite)
|
||||||
|
|
||||||
|
1. **Ingestion:** Der User (Meldestelle) lädt die `zns.zip` hoch oder triggert einen Import aus einer anderen Quelle (
|
||||||
|
Zuchtverband).
|
||||||
|
2. **Parsing & Cleansing:** Ein dedizierter Importer-Service entpackt die ZIP, liest die Dateien zeilenweise (Codepage
|
||||||
|
850!) und konvertiert die starren ASCII-Strings in nutzbare DTOs (Data Transfer Objects). Hier greifen erste
|
||||||
|
Reinigungs-Routinen.
|
||||||
|
3. **Event Generation:** Der Service vergleicht die geparsten Daten mit dem aktuellen Stand (der "Read Model"
|
||||||
|
Datenbank).
|
||||||
|
* Findet er einen neuen Akteur (Satznummer bisher unbekannt), erzeugt er ein `ActorCreatedEvent`.
|
||||||
|
* Findet er Änderungen (z.B. Lizenz wurde von R1 auf R2 erhöht, oder Sperre wurde gesetzt), erzeugt er ein
|
||||||
|
`ActorUpdatedEvent` (bzw. spezifischer `LicenseUpgradedEvent`, `ActorLockedEvent`).
|
||||||
|
4. **Manuelle Korrekturen (Overrides):** Wenn die Meldestelle vor Ort Daten korrigiert (weil die OEPS-Daten falsch
|
||||||
|
waren), erzeugt das System ein spezielles Event, z.B. `ManualActorCorrectionEvent`. Dieses Event hat eine **höhere
|
||||||
|
Priorität** als zukünftige `ActorUpdatedEvents` aus dem ZNS-Import, solange der OEPS die Daten in seinem System nicht
|
||||||
|
korrigiert hat (Lösung z.B. über einen "Ignorier-Zeitstempel" oder Prioritäts-Flags in der Projektion).
|
||||||
|
5. **Event Log:** Diese Events werden in einem zentralen Event Log (dem "Event Store") persistiert. Dies ist die
|
||||||
|
absolute Single Source of Truth.
|
||||||
|
|
||||||
|
### 2.2 Die Datenbereitstellung (Die "Query" Seite)
|
||||||
|
|
||||||
|
1. **Projection (Projektion):** Kleine "Listener" hören auf das Event Log und bauen daraus die relationale
|
||||||
|
Lesedatenbank (SQLite / PostgreSQL) auf. Hierbei wird die Logik angewandt, dass manuelle Korrekturen der Meldestelle
|
||||||
|
Vorrang vor veralteten Verbandsdaten haben.
|
||||||
|
2. **Turnier-Snapshot:** Wenn ein Turnier konfiguriert wird oder am Vortag aktualisiert wird, zieht sich das System
|
||||||
|
einen "Snapshot" (Schnappschuss) der aktuellen Stammdaten und verknüpft diese mit der Turnier-ID.
|
||||||
|
3. **Zuchtverbands-Daten (Fremdformate):** Die Architektur erlaubt es uns leicht, neue Parser (z.B. für AWÖ-Daten) zu
|
||||||
|
schreiben. Diese lesen die fremden Formate ein und generieren die gleichen Standard-Events (`HorseCreatedEvent`, aber
|
||||||
|
evtl. mit Lebensnummer statt OEPS-Satznummer), die dann problemlos in die bestehende Projektion einfließen.
|
||||||
|
|
||||||
|
## 3. Datenhaltung (Konzeptuelles Modell)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant User
|
||||||
|
participant ImporterService as ZNS / AWÖ Importer
|
||||||
|
participant EventStore as Event Log (Append Only)
|
||||||
|
participant Projections as DB (Read Models)
|
||||||
|
User ->> ImporterService: Upload zns.zip (Freitag vor Turnier)
|
||||||
|
ImporterService ->> ImporterService: Parse & Clean
|
||||||
|
|
||||||
|
rect rgb(200, 220, 240)
|
||||||
|
Note right of ImporterService: Generierung von Import-Events
|
||||||
|
ImporterService ->> EventStore: Append: ActorUpdatedEvent(Satznummer: 123456, License: R2)
|
||||||
|
end
|
||||||
|
|
||||||
|
User ->> EventStore: Manuelle Korrektur am Turniertag
|
||||||
|
rect rgb(240, 200, 200)
|
||||||
|
Note right of User: Generierung von Override-Events
|
||||||
|
User ->> EventStore: Append: ManualActorCorrectionEvent(Satznummer: 123456, Name: "Neuer Name")
|
||||||
|
end
|
||||||
|
|
||||||
|
EventStore -->> Projections: Update Relational DB (z.B. aktueller Stand)
|
||||||
|
Note over Projections: Turniersystem liest nur <br/>aus Read Models. Manuelle Korrekturen<br/>gewinnen gegen Import-Daten.
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Vorteile dieser Architektur
|
||||||
|
|
||||||
|
* **Audit-Sicherheit:** Wir wissen exakt, *wann* sich *was* geändert hat. Nichts geht verloren.
|
||||||
|
* **Archivierung:** Ein Turnier-Archiv muss nicht mehr mühsam als riesiger PDF/Daten-Dump gesichert werden. Wir können
|
||||||
|
das Turnier einfach anhand des Timestamps gegen den Event Store abfragen.
|
||||||
|
* **Fehlertoleranz:** Wenn ein Parsing-Fehler auftritt oder der OEPS kaputte Daten liefert, machen wir einfach ein
|
||||||
|
Rollback der fehlerhaften Events und projizieren die Datenbank neu. Wir zerschießen nicht die operativen Tabellen.
|
||||||
|
* **Erweiterbarkeit (Vision):** Wenn später ein "Ergebnis-Analyse-Service" oder ein "Züchter-Portal" angebunden wird,
|
||||||
|
können diese einfach die historischen Events abonnieren (Kafka/Message Queue).
|
||||||
|
* **Integration von Drittsystemen (Zuchtverbände):** Fremddaten können durch eigene Parser in unsere Standard-Events
|
||||||
|
übersetzt und nahtlos integriert werden.
|
||||||
|
|
||||||
|
## 5. Zu klärende Details für die Implementierung
|
||||||
|
|
||||||
|
* **Sync-Mechanismus:** Wie kommen die Events vom Master-Server auf den Offline-Laptop im Plumpsklo? (Vermutlich eine
|
||||||
|
robuste Sync-Queue, Kafka könnte für den Offline-Einsatz zu schwergewichtig sein, Alternativen evaluieren).
|
||||||
|
* **Event-Payload:** Definition der JSON-Struktur für die wichtigsten Events (`zns.actor.updated`,
|
||||||
|
`zns.horse.registered`).
|
||||||
|
* **Merge-Logik:** Wie lange bleibt ein `ManualActorCorrectionEvent` gültig, bevor ein zukünftiges Update vom ZNS diesen
|
||||||
|
Wert wieder überschreiben darf?
|
||||||
|
|
@ -1,72 +1,102 @@
|
||||||
---
|
# Ergebnisse Domain Workshop (17.03.2026)
|
||||||
type: Reference
|
|
||||||
status: ACTIVE
|
|
||||||
owner: Lead Architect
|
|
||||||
date: 2026-03-17
|
|
||||||
---
|
|
||||||
|
|
||||||
# Ergebnisse: Domain Workshop vom 17.03.2026
|
**Teilnehmer:** Owner, 🏗️ [Lead Architect], 📜 [ÖTO/FEI Rulebook Expert], 👷 [Backend Developer], 🎨 [Frontend Expert],
|
||||||
|
🖌️ [UI/UX Designer]
|
||||||
|
|
||||||
**Teilnehmer:** Owner (Fachexperte), 🏗️ [Lead Architect], 📜 [ÖTO/FEI Rulebook Expert], 👷 [Backend Developer],
|
## 📜 [ÖTO/FEI Rulebook Expert] - Erkenntnisse
|
||||||
🎨 [Frontend Expert], 🖌️ [UI/UX Designer]
|
|
||||||
|
|
||||||
## 🎯 Fokus des Workshops
|
1. **Autorität des Turnierbeauftragten (TBA):**
|
||||||
|
Die Analyse der ÖTO (§ 24, § 25) bestätigt die Aussage des Owners: Der TBA ist die höchste Instanz vor Ort und kann
|
||||||
|
in Absprache mit dem Veranstalter von der Ausschreibung abweichende, für alle verbindliche Entscheidungen treffen.
|
||||||
|
Das System muss daher bei Regelkonflikten immer einen manuellen "Override" durch die Meldestelle ermöglichen.
|
||||||
|
|
||||||
* Klärung der Kompetenzen vor Ort (Turnierbeauftragter vs. Regelwerk).
|
2. **Gebührenlogik & Abrechnung (Das "Hansi"-Szenario):**
|
||||||
* Analyse der Kassenführung und komplexer Gebühren-Szenarien.
|
Die Komplexität der Gebührenstruktur wurde stark verdeutlicht. Es muss klar unterschieden werden zwischen:
|
||||||
* Management von Funktionären und deren Qualifikationen.
|
* **Nenngeld** (Grundgebühr, oft im Voraus via ZNS bezahlt)
|
||||||
* Erster Entwurf für den Workflow der Turnieranlage (UI/UX).
|
* **Startgeld** (pro Bewerb)
|
||||||
|
* **Nachnenngebühren** (Aufschlag bei später Nennung, oft verhandelbar)
|
||||||
|
* **Nebengebühren** (Sportförderbeitrag, Tierwohl-Euro - pro Start fällig)
|
||||||
|
Die Möglichkeit für den Veranstalter, auf Gebührenanteile (z.B. Nachnenngebühr) zu verzichten, muss im
|
||||||
|
Abrechnungssystem einfach abbildbar sein.
|
||||||
|
|
||||||
---
|
3. **Qualifikation von Funktionären:**
|
||||||
|
Die Qualifikationen für Richter und Parcoursbauer sind in der Datei `RICHT01.DAT` der ZNS-Daten enthalten. Diese
|
||||||
|
Qualifikationen müssen gegen die Anforderungen des jeweiligen Bewerbs (Klasse, Sparte) validiert werden.
|
||||||
|
|
||||||
## 💡 Erkenntnisse der Agents
|
## 👷 [Backend Developer] - Erkenntnisse
|
||||||
|
|
||||||
### 📜 [ÖTO/FEI Rulebook Expert]
|
1. **Bounded Context "Billing & Accounting":**
|
||||||
|
Die Kassenführung ist zu komplex und hat zu viele eigene Regeln, um sie eng mit dem sportlichen Kern (
|
||||||
|
Nennung/Ergebnis) zu koppeln. Wir werden dies als separaten Bounded Context mit eigenen Services und einem
|
||||||
|
dedizierten Datenmodell für Konten, Transaktionen und Gebühren umsetzen. Die Abrechnung muss kontobasiert pro Zahler
|
||||||
|
erfolgen (nicht nur pro Reiter).
|
||||||
|
|
||||||
1. **Autorität des Turnierbeauftragten (TBA):** Die Analyse der ÖTO (§ 24, § 25) bestätigt die Praxis-Erfahrung: Der TBA
|
2. **Implementierung "Nennungstausch":**
|
||||||
ist die höchste Instanz vor Ort und kann in Absprache mit dem Veranstalter von der Ausschreibung abweichende, für
|
Der Tausch einer Nennung (Reiter/Pferd) wird nicht als reines Storno + Neu-Buchung implementiert, sondern als *
|
||||||
alle verbindliche Entscheidungen treffen. **Das System muss daher bei Regelkonflikten immer einen manuellen "
|
*Transfer-Operation**. Bereits bezahlte Nenngelder werden als Guthaben auf dem Konto des ursprünglichen Zahlers (oder
|
||||||
Override" durch die Meldestelle ermöglichen.**
|
des Pferdes) geführt und können auf die neue Nennung angerechnet werden. Das System berechnet und verbucht
|
||||||
2. **Gebührenlogik & Abrechnung:** Das "Hansi"-Szenario (Klassenüberschreitung, Reiterwechsel, Nachnennung) hat die
|
automatisch die anfallenden Differenzen und Tauschgebühren.
|
||||||
enorme Komplexität der Gebührenstruktur verdeutlicht. Es muss zwingend unterschieden werden zwischen:
|
|
||||||
* **Nenngeld:** Grundgebühr, oft im Voraus via ZNS bezahlt.
|
|
||||||
* **Startgeld:** Gebühr pro einzelnem Bewerb.
|
|
||||||
* **Nachnenngebühren:** Strafaufschlag bei später Meldung.
|
|
||||||
* **Nebengebühren:** Sportförderbeitrag, Tierwohl-Euro (pro Start).
|
|
||||||
Die Möglichkeit für den Veranstalter, auf Gebührenanteile (z.B. Nachnenngebühr) zu verzichten, muss zwingend
|
|
||||||
abgebildet werden.
|
|
||||||
3. **Qualifikation von Funktionären:** Die Qualifikationen für Richter und Parcoursbauer sind in der Datei
|
|
||||||
`RICHT01.DAT` (ZNS-Daten) enthalten. Diese müssen beim Import ausgelesen und im System gegen die Anforderungen des
|
|
||||||
jeweiligen Bewerbs (Klasse, Sparte) validiert werden.
|
|
||||||
|
|
||||||
### 👷 [Backend Developer]
|
3. **Validierungs-Service für Funktionäre:**
|
||||||
|
Es wird eine Backend-Funktion implementiert, die bei der Zuweisung eines Richters/Parcoursbauers zu einem Bewerb
|
||||||
|
dessen Qualifikationen (aus den importierten ZNS-Daten) gegen die Anforderungen des Bewerbs prüft. Die API wird bei
|
||||||
|
einem Mismatch eine `WARNUNG` zurückgeben, aber keinen harten `FEHLER`, um den vom Rulebook Expert bestätigten "
|
||||||
|
Override" durch die Meldestelle zu ermöglichen.
|
||||||
|
|
||||||
1. **Neuer Bounded Context "Billing & Accounting":** Die Kassenführung ist zu komplex und eigenständig, um sie mit dem
|
4. **ZNS-Import, Fremddaten (Zuchtverbände) & Event Sourcing:**
|
||||||
sportlichen Kern (Nennung/Ergebnis) zu vermischen. Wir etablieren einen separaten Bounded Context mit dediziertem
|
Die unsauberen und oft wechselnden ZNS-Daten des OEPS werden nicht destruktiv in Datenbanktabellen überschrieben.
|
||||||
Datenmodell für **Konten (pro "Zahler"), Transaktionen und Gebühren**.
|
Stattdessen wird eine **Event Sourcing** Architektur gewählt.
|
||||||
2. **Architektur "Nennungstausch":** Der Tausch einer Nennung (Reiter oder Pferd) wird *nicht* als einfaches Löschen und
|
* Das Hochladen der `zns.zip` triggert einen Parser, der Änderungen (Updates bei Lizenzen, neue Akteure) als
|
||||||
Neuanlegen implementiert. Es wird als **Transfer-Operation** abgebildet. Bereits bezahlte Nenngelder verbleiben als
|
zeitgestempelte Events (z.B. `ActorUpdatedEvent`) in einem "Event Log" ablegt.
|
||||||
Guthaben auf dem Konto des ursprünglichen Zahlers (oder sind an das Pferd gebunden) und können auf die neue Nennung
|
* Fremddaten (z.B. von Zuchtverbänden wie dem AWÖ) können über dedizierte Parser eingelesen und in dieselben
|
||||||
angerechnet werden. Nur Differenzen und Tauschgebühren werden neu verbucht.
|
Standard-Events übersetzt werden.
|
||||||
3. **Validierungs-Service für Funktionäre:** Es wird ein Service implementiert, das bei der Zuweisung eines
|
* **Manuelle Korrekturen durch die Meldestelle** (wegen fehlerhafter OEPS-Daten) erzeugen "Override-Events", die
|
||||||
Richters/Parcoursbauers zu einem Bewerb dessen Qualifikationen (aus den ZNS-Daten) prüft. Wichtig: Die API liefert
|
Vorrang vor veralteten Import-Daten haben.
|
||||||
bei Mismatches nur eine `WARNUNG`, keinen blockierenden `FEHLER`, um den "Override" durch die Meldestelle (siehe
|
* Für die schnelle Anzeige und Offline-Synchronisation werden aus diesen Events saubere Projektionen ("Read Models")
|
||||||
Rulebook Expert) zu garantieren.
|
und turnierspezifische Snapshots gebaut.
|
||||||
|
|
||||||
### 🎨 [Frontend Expert] & 🖌️ [UI/UX Designer]
|
## 🎨 [Frontend Expert] & 🖌️ [UI/UX Designer] - Erkenntnisse
|
||||||
|
|
||||||
1. **Workflow-Übernahme (Don't reinvent the wheel):** Die vom Owner bereitgestellten Screenshots des Altsystems (
|
1. **Workflow-Übernahme als Grundlage:**
|
||||||
`Turnier-Transfer.PNG`, `Turnier-Richter.PNG` etc.) definieren einen praxiserprobten Workflow. Dieser wird als
|
Die vom Owner bereitgestellten Screenshots des Altsystems (`BilderSuDo/`) definieren einen praxiserprobten, schnellen
|
||||||
Blaupause für das neue UI verwendet.
|
und vom User extrem gut akzeptierten Workflow. Diese Screens dienen als absolute Blaupause für das neue UI/UX-Design.
|
||||||
2. **Modernes UI-Konzept (Wizard-Ansatz):** Anstelle vieler separater Fenster (wie im Altsystem) wird die Turnieranlage
|
|
||||||
in einem **geführten, schrittweisen Prozess** (Wizard oder übersichtliche Tab-Struktur) abgebildet.
|
|
||||||
* *Schritt 1:* Stammdaten & ZNS-Import
|
|
||||||
* *Schritt 2:* Konfiguration (Austragungsplätze, Preisliste)
|
|
||||||
* *Schritt 3:* Team (Zuweisung von Richtern, Parcoursbauern)
|
|
||||||
* *Schritt 4:* Bewerbsanlage
|
|
||||||
3. **Smart UI:** Die Oberfläche wird den vertrauten Workflow bieten, aber durch **Echtzeit-Validierung** (z.B. visuelle
|
|
||||||
Warnung bei Zuweisung eines Richters ohne passende Lizenz) und **intelligente Suchfelder** (Auto-Complete) die
|
|
||||||
Dateneingabe erheblich beschleunigen und absichern.
|
|
||||||
|
|
||||||
---
|
2. **Der "Bewerbe anlegen"-Workflow (`Bewerbe.PNG` etc.):**
|
||||||
*Nächste Schritte: Detaillierung des ZNS-Imports (Stammdaten & Akteure).*
|
* Zweigeteilte Ansicht (Master-Detail): Links Liste/Filter aller Bewerbe, Rechts Detail-Tabs.
|
||||||
|
* Detail-Tabs gliedern sich in: *Bewertung* (Richtverfahren), *Geldpreis* (Dotierung nach Platzierung), *Ort/Zeit* (
|
||||||
|
Ablaufplanung mit Zeit-pro-Starter-Logik).
|
||||||
|
* *Design-Vorgabe:* Diese Informationsarchitektur wird in moderne Compose-Layouts (z.B. List-Detail-Pane) überführt,
|
||||||
|
die Logik bleibt identisch.
|
||||||
|
|
||||||
|
3. **Die zentrale "Nennungs-Maske" (`Nennungen.PNG`):**
|
||||||
|
* Dies ist das **Herzstück der Meldestelle** ("Das Telefon läutet...").
|
||||||
|
* Extrem schnelle Suche via Kopfnummer oder Name (mit sofortiger Auto-Completion).
|
||||||
|
* Anzeige der Meta-Daten (z.B. Besitzer) für sofortige Identifikation.
|
||||||
|
* Direkte Zuweisung zu Bewerben via Klick aus einer Liste unten.
|
||||||
|
* Berücksichtigung von Startwünschen ("vorne", "hinten").
|
||||||
|
* *Design-Vorgabe:* Diese Maske muss auf **absolute Tastatur- & Schnellbedienbarkeit** optimiert werden (Hotkeys,
|
||||||
|
Tab-Flow). Sie fungiert als Dashboard (Absprung zu Startliste, Kassa).
|
||||||
|
* **Self-Service Äquivalenz:** Das Webformular für den Reiter nutzt im Hintergrund dieselbe Logik, um die Meldestelle
|
||||||
|
maximal zu entlasten.
|
||||||
|
|
||||||
|
4. **Startlisten-Erstellung (`Startlisten.PNG`):**
|
||||||
|
* Schneller Wechsel zwischen Bewerben über Nummern-Leiste oben (Tab-Ersatz).
|
||||||
|
* Berücksichtigung der beim Nennen erfassten Wünsche ("vorne", "hinten").
|
||||||
|
|
||||||
|
5. **Ergebnis-Erfassung am Richterturm (`Ergebnisliste.PNG`):**
|
||||||
|
* Schnelleingabe-Maske optimiert für den fließenden Ablauf.
|
||||||
|
* Oben: Gesamtergebnis / Unten: Startliste als Warteschlange / Mitte: Aktueller Reiter in Eingabe.
|
||||||
|
* Absoluter Fokus auf **"Enter & Tabulator"-Workflow**. Ein Mausklick darf für den Standard-Ablauf nicht nötig sein.
|
||||||
|
* Spontane Abweichungen von der Startfolge (nächster Reiter kommt früher) müssen durch simplen Doppelklick auf die
|
||||||
|
Warteschlange lösbar sein.
|
||||||
|
* Entscheidung über Anzahl der Platzierten bleibt flexibel und ist durch die Meldestelle überschreibbar (ÖTO als
|
||||||
|
Richtlinie, Veranstalter hat letztes Wort).
|
||||||
|
|
||||||
|
## 🏗️ [Lead Architect] - Strategischer Fokus (MVP Phase 1)
|
||||||
|
|
||||||
|
Um zügig einen echten Mehrwert zu generieren, wird der Scope für die erste Ausbaustufe (MVP) hart eingegrenzt:
|
||||||
|
|
||||||
|
* **Turnier-Kategorien:** Fokus auf **C-NEU** und **C**.
|
||||||
|
* **Sparten:** Fokus ausschließlich auf **Dressur (D)** und **Springen (S)**.
|
||||||
|
* *Begründung:* Diese Eingrenzung reduziert die initial benötigte Komplexität der Regelwerks-Implementierung enorm,
|
||||||
|
deckt aber gleichzeitig das absolute "Brot-und-Butter"-Geschäft für kleine bis mittlere Veranstalter ab.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user