feat(docs): expand masterdata documentation with Reiter- and Pferdeprüfungen
- Added `REITER_PRUEFUNGEN.md` and `PFERDEPRUEFUNGEN_BEWERTUNG.md` to document evaluation criteria, scoring logic, and system requirements for dressage and show jumping. - Updated `README.md` with links to new documentation on rider- and horse-specific regulations. - Created database schemas for `TurnierklasseTable`, `RichtverfahrenTable`, `GebuehrTable`, `LicenseTable`, and `RegulationConfigTable`, aligning with ÖTO 2026. - Logged architectural decisions and analysis in `session-logs` and created ADRs `0017-masterdata-importer-worker` and `0019-api-ingestion-layers`. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
---
|
||||
type: ADR
|
||||
status: AKZEPTIERT
|
||||
owner: Lead Architect
|
||||
date: 2026-03-30
|
||||
---
|
||||
|
||||
# ADR-0017: Einbettung des ZNS-Importers als Worker im Masterdata-SCS
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Das Zentrale Nennungs-System (ZNS) liefert Stammdaten (Reiter, Pferde, Vereine, Funktionäre) in Form von ASCII-Dateien (
|
||||
CP850). Diese Daten müssen regelmäßig importiert und aktualisiert werden.
|
||||
Bisher gab es die Überlegung, den Importer als eigenständigen Dienst oder als Teil des Backends zu betreiben. Da die
|
||||
Stammdaten jedoch das primäre Domänenmodell des `masterdata`-SCS sind, stellt sich die Frage nach der optimalen
|
||||
architektonischen Einbettung.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Der ZNS-Importer wird als **dedizierter Worker-Thread/Service innerhalb des Masterdata-SCS** implementiert.
|
||||
|
||||
Details:
|
||||
|
||||
1. **Modul-Struktur**: Der `core:zns-parser` bleibt ein KMP-Modul für die reine Dateianalyse. Die Import-Logik (Mapping
|
||||
auf Domänen-Entitäten, Upserts in die DB) wird im `masterdata`-SCS angesiedelt.
|
||||
2. **Ausführung**: Der Import läuft asynchron als Hintergrund-Task (Worker), um die API-Reaktionszeit nicht zu
|
||||
beeinträchtigen.
|
||||
3. **Trigger**: Der Import kann über einen REST-Endpunkt (für Datei-Uploads) oder manuell via CLI/Trigger gestartet
|
||||
werden.
|
||||
4. **Schreibkanal**: Der Importer ist der primäre Schreibkanal für Stammdaten im System. Direkte API-Schreibzugriffe auf
|
||||
Stammdaten sind in Phase 1 nicht vorgesehen (Read-Only API für externe Konsumenten).
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
- **Positiv**: Starke Kohäsion, da die Datenhoheit und die Importlogik im selben SCS liegen.
|
||||
- **Positiv**: Vereinfachte Persistenz, da der Worker direkt auf die Masterdata-DB zugreifen kann (kein
|
||||
Remote-API-Overhead).
|
||||
- **Negativ**: Ressourcenverbrauch des Workers (CPU/RAM beim Parsen großer Dateien) teilt sich die Ressourcen mit der
|
||||
REST-API innerhalb des Containers. Dies muss über Limits (Docker/K8s) oder Task-Scheduling gesteuert werden.
|
||||
- **Neutral**: Erfordert eine robuste Idempotenz-Logik, da Importe wiederholbar sein müssen (Checksum-Checks,
|
||||
Upsert-Semantik).
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
- **Eigenständiger Microservice**: Wurde verworfen, um die Anzahl der zu betreibenden Dienste gering zu halten und "
|
||||
Database-per-Service" nicht durch geteilte Datenbankzugriffe zu verletzen (oder teure API-Synchronisation zu
|
||||
benötigen).
|
||||
- **Integration in die GUI (Client-seitig)**: Verworfen, da die Datenhoheit im Server liegen muss und große Importe (
|
||||
100k+ Records) im Hintergrund auf dem Server stabiler laufen.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Roadmap_ZNS_Importer.md](../../../docs/01_Architecture/Roadmap_ZNS_Importer.md)
|
||||
- [ROADMAP.md](../ROADMAP.md)
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
type: ADR
|
||||
status: AKZEPTIERT
|
||||
owner: Lead Architect
|
||||
date: 2026-03-30
|
||||
---
|
||||
|
||||
# ADR-0018: Rule-Versionierung und -Management (ÖTO-Regeln)
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Die ÖTO-Regeln (Österreichische Turnierordnung) für Dressur, Springen und andere Sparten ändern sich regelmäßig (
|
||||
jährlich oder bei Bedarf). Das System muss in der Lage sein, Stammdaten (Altersklassen, Lizenzen, Richtverfahren,
|
||||
Gebühren) für ein Turnier basierend auf dem zum Turnierzeitpunkt gültigen Regelwerk zu validieren und anzuzeigen. Eine
|
||||
rein Code-basierte Regelverwaltung (Hardcoding) ist aufgrund der Dynamik und Offline-Fähigkeit nicht praktikabel.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
ÖTO-Regeln werden als **versionierte Datensätze in der Datenbank** verwaltet (Regulation-as-Data).
|
||||
|
||||
Details:
|
||||
|
||||
1. **Versionierungs-Schema**: Alle Regel-Datensätze (z.B. Lizenz-Klasse-Matrix, Altersklassen-Berechnung) erhalten
|
||||
`valid_from` und `valid_to` Zeitstempel.
|
||||
2. **Aktives Regel-Set**: Die Applikationslogik ermittelt zur Laufzeit (z.B. basierend auf dem Turnierdatum) das jeweils
|
||||
aktive Regel-Set aus der Datenbank.
|
||||
3. **Seed-Strategie**: Zu Beginn jeder Saison (oder bei Major-Updates) wird ein neues Regel-Set als Seed in die
|
||||
Datenbank eingespielt. Das "Regel-Set 2026" dient als Basis.
|
||||
4. **Unveränderlichkeit (Immutability)**: Bestehende, in Turnieren verwendete Regeln dürfen nicht überschrieben werden.
|
||||
Bei Änderungen wird ein neuer Datensatz mit neuem Gültigkeitsbereich angelegt (SCD Type 2 Pattern).
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
- **Positiv**: Hohe Flexibilität ohne Code-Deployments (Config-over-Code).
|
||||
- **Positiv**: Historische Turniere bleiben nachvollziehbar, da sie auf das damals gültige Regelwerk verweisen.
|
||||
- **Negativ**: Erhöhte Komplexität bei Datenbank-Abfragen (immer Zeitbezug erforderlich).
|
||||
- **Negativ**: Notwendigkeit für robuste Administrations-Schnittstellen oder SQL-Seeds zur Regelpflege.
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
- **Hardcoding in Kotlin-Use-Cases**: Schneller zu implementieren, aber unflexibel bei unterjährigen Regeländerungen und
|
||||
historischer Auswertung schwierig.
|
||||
- **Git-basierte Konfiguration (YAML/JSON)**: Gut für CI/CD, aber schwierig für Offline-Szenarien ohne vollen
|
||||
Repository-Sync; Datenbank-Integration für Abfragen komplexer.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [ROADMAP.md](../ROADMAP.md)
|
||||
- [Abteilungs-Trennungs-Schwellenwerte.md](../../../docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md)
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
type: ADR
|
||||
status: AKZEPTIERT
|
||||
owner: Lead Architect
|
||||
date: 2026-03-30
|
||||
---
|
||||
|
||||
# ADR-0019: API-Schichten und Ingestion-Pattern im Masterdata-SCS
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Das Masterdata-SCS (Stammdaten) dient als zentrale Informationsquelle für alle anderen Bounded Contexts (z.B.
|
||||
Registration, Competition). Es muss sowohl Massendaten aus dem ZNS (Zentrales Nennungs-System) aufnehmen (Schreibkanal)
|
||||
als auch hochperformante Lesezugriffe (Lesekanal) für die Suche und Validierung ermöglichen. Dabei ist die Trennung
|
||||
zwischen internen Ingestion-Prozessen und externen Client-APIs entscheidend für die Stabilität und Sicherheit.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Die API-Architektur wird in **klare Schichten für Ingestion (Schreiben) und REST (Lesen)** unterteilt.
|
||||
|
||||
Details:
|
||||
|
||||
1. **Lesekanal (Public REST API)**: Bietet Endpunkte für die Suche (Reiter, Pferde, Vereine) und den Abruf von
|
||||
Regelwerken. Diese API ist optimiert für Performance (Indizes, Paging, ETags) und nutzt DTOs mit Kotlinx
|
||||
Serialization.
|
||||
2. **Schreibkanal (Ingestion API/Worker)**: Dieser Kanal ist internen Prozessen (ZNS-Importer) vorbehalten. Direkte
|
||||
Schreibzugriffe von Clients auf Stammdaten sind in der ersten Phase unterbunden. Der Schreibkanal nutzt ein
|
||||
Ingestion-Pattern, das auf Idempotenz (Upserts) und Validierung (Checksum-Checks) basiert.
|
||||
3. **Internal API (Core Interfaces)**: Innerhalb des Masterdata-SCS werden klare Interfaces für Repositories und
|
||||
UseCases genutzt, die von Ingestion und REST gemeinsam verwendet werden.
|
||||
4. **Versioning**: Alle APIs werden versioniert (v1, v2), um zukünftige Schema-Änderungen ohne Breaking Changes zu
|
||||
ermöglichen.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
- **Positiv**: Klare Trennung der Verantwortlichkeiten (Separation of Concerns).
|
||||
- **Positiv**: Höhere Sicherheit, da Stammdaten nicht versehentlich durch die Public-API manipuliert werden können.
|
||||
- **Positiv**: Bessere Skalierbarkeit: Lesekanal kann unabhängig vom Schreibkanal optimiert werden.
|
||||
- **Negativ**: Erhöhter Implementierungsaufwand durch getrennte DTOs und Validierungslogik für die Ingestion-Phase.
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
- **Einheitliche CRUD-API**: Alle Zugriffe über die gleiche API-Schicht. Verworfen wegen mangelnder Sicherheit bei
|
||||
sensiblen Stammdaten und Performance-Problemen bei Massen-Imports.
|
||||
- **GraphQL**: Bietet hohe Flexibilität beim Lesen, wurde jedoch für die erste Phase als zu komplex für die einfache
|
||||
Suche in Stammdaten angesehen. REST ist für Offline-Szenarien und Caching (ETags) einfacher zu handhaben.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [ADR-0017: Importer-Einbettung](./0017-masterdata-importer-worker-de.md)
|
||||
- [ROADMAP.md](../ROADMAP.md)
|
||||
Reference in New Issue
Block a user