- Added `meldestelle-desktop` module using JVM/Compose Desktop, registered in `settings.gradle.kts`. - Integrated new screens and desktop navigation into core: `Veranstaltungen`, `TurnierDetail`, etc. - Expanded backend with `ExposedFunktionaerRepository` in `officials-infrastructure`. - Completed ADRs for bounded context mapping (`ADR-0014`) and context map (`ADR-0015`). - Updated and extended project documentation with session logs and architecture decisions. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
9.2 KiB
| type | id | status | owner | last_update |
|---|---|---|---|---|
| ADR | ADR-0014 | ACTIVE | Lead Architect | 2026-03-24 |
ADR-0014: Bounded Context Mapping (SCS-Architektur)
Status
Akzeptiert
Kontext
Mit der Entscheidung für Domain-Driven Design (→ ADR-0002) und der modularen Architektur (→ ADR-0001) war es
notwendig, die fachlichen Grenzen des Systems explizit zu definieren. Die ursprünglichen Module (masterdata,
members, horses, events) spiegelten technische Kategorien wider, nicht die tatsächlichen Fachdomänen des
österreichischen Turniersports.
Folgende Probleme wurden identifiziert:
- Fehlende Ausrichtung zwischen Code-Struktur und ÖTO-Regelwerk
- Unklare Verantwortlichkeiten bei domänenübergreifenden Operationen (z.B. Nennungs-Transfer)
- Keine explizite Trennung zwischen Kern-Domäne (Nennungs-Workflow) und unterstützenden Domänen
- Fehlende Grundlage für eine skalierbare, offline-fähige Desktop-Architektur
Entscheidung
Das System wird in 6 Bounded Contexts aufgeteilt, die als Self-Contained Systems (SCS) implementiert werden. Jeder Context ist fachlich eigenständig, besitzt seine eigene Ubiquitous Language und kommuniziert über definierte Schnittstellen.
Übersicht der 6 Bounded Contexts
| Context | Verantwortlichkeit | Priorität | Phase |
|---|---|---|---|
registration-context |
Nennungs-Workflow (Herzstück des Systems) | P1 | Phase 4 |
actor-context |
Reiter, Pferde, Funktionäre, Vereine, ZNS-Stammdaten | P1 | Phase 4 |
competition-context |
Bewerbe, Startlisten, Ergebnisse, Abteilungs-Logik | P2 | Phase 5 |
event-management-context |
Veranstaltung, Turnier, Ausschreibung, Genehmigungen | P2 | Phase 5 |
billing-context |
Abrechnung, Kassa, Gebühren, Konten | P3 | Phase 6 |
identity-context |
Authentifizierung, Rollen, Berechtigungen (Keycloak) | P3 | Phase 6 |
Hinweis
series-context: Cups, Serien und Meisterschaften werden in Phase 2+ als eigenständiger Context implementiert. Die Architektur ist von Anfang an dafür vorbereitet (pluggable Berechnungsmodell, konfigurierbare Paar-Bindung). Kein Hard-Coding von Serien-Logik in anderen Contexts.
Context-Beschreibungen
registration-context — Kern-Domäne (Core Domain)
Verantwortlichkeit: Der gesamte Lebenszyklus einer Nennung – von der Erstanmeldung bis zur Stornierung.
Aggregate Roots:
DomNennung– Verbindliche Anmeldung eines Paares (Reiter & Pferd) zu einem BewerbDomNennungsTransfer– Transfer-Operation (kein Storno + Neu); Guthaben bleibt erhaltenDomAbteilung– Kleinste Einheit für Startlisten und Ergebnisse (mit Warn-Logik)
Ubiquitous Language (Auswahl):
Nennung,Nennschluss,Nachnenngebühr,Nennungs-Transfer,Override-Event,Startwunsch
Kern-Invarianten:
- Eine Nennung ist immer einem Paar (Reiter + Pferd) zugeordnet
- Nennungs-Transfer ist eine atomare Operation – kein Zwischenzustand ohne gültiges Paar
- Regelwerk-Verstöße erzeugen Warnungen (niemals harte Fehler) +
Override-Event
actor-context — Unterstützende Domäne (Supporting Domain)
Verantwortlichkeit: Stammdaten aller Akteure und Synchronisation mit dem ZNS (Zentrales Nennungs-System).
Aggregate Roots:
DomReiter– Reiter mit Lizenz, Satznummer, StartkarteDomPferd– Pferd mit Lebensnummer, Kopfnummer, SatznummerDomFunktionär– Person mit Turnier-Rolle und QualifikationDomVerein– OEPS-Mitgliedsverein (Veranstalter)
Ubiquitous Language (Auswahl):
Satznummer,Lebensnummer,Kopfnummer,FEI-ID,Lizenz,Startkarte,Sperrliste,Gastreiter
Kern-Invarianten:
Satznummerist der primäre Schlüssel für den ZNS-DatenaustauschLebensnummerundKopfnummersind nicht als Datenbankschlüssel geeignet (ZNS-Inkonsistenzen)- ZNS-Daten werden lokal gecacht (Offline-First); Synchronisation im Hintergrund
competition-context — Unterstützende Domäne (Supporting Domain)
Verantwortlichkeit: Strukturierung von Bewerben, Erstellung von Startlisten, Erfassung von Ergebnissen.
Aggregate Roots:
DomBewerb– Einzelne sportliche Prüfung mit Bewerbsnummer, Sparte, Klasse, RichtverfahrenDomAbteilung– Untereinheit eines Bewerbs mit eigenem Teilnehmerkreis und PlatzierungDomStartliste– Geordnete Liste der Starter einer AbteilungDomErgebnis– Ergebnis eines Starts (Platzierung, Punkte, Zeit)
Ubiquitous Language (Auswahl):
Bewerb,Prüfung,Abteilung,Abteilungsnummer,Startliste,Richtverfahren,Klasse/Höhe
Kern-Invarianten:
- Abteilungs-Schwellenwerte gemäß ÖTO § 39 lösen Warnungen aus (→
Override-Event) - Vollständige Schwellenwert-Tabellen:
docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md
event-management-context — Unterstützende Domäne (Supporting Domain)
Verantwortlichkeit: Verwaltung von Veranstaltungen und Turnieren, Ausschreibungs-Generierung, Genehmigungsprozesse.
Aggregate Roots:
DomVeranstaltung– Interne Organisationseinheit des Veranstalters (selbst vergebene ID)DomTurnier– Offizielles Turnier mit OEPS-vergebener TurniernummerDomAusschreibung– Offizielles Dokument mit Pflichtfeldern gemäß ÖTO (A-Satz ZNS)
Ubiquitous Language (Auswahl):
Veranstaltung,Turnier,Turniernummer,Turnierkategorie,Ausschreibung,Kombination,TBA
Kern-Invarianten:
Veranstaltung≠Turnier(→ ADR-0002, ÖTO § 2 Abs. 1): Eine Veranstaltung kann mehrere Turniere umfassen- Turniernummern werden von der OEPS vergeben, nicht selbst generiert
- Kombinations-Turniere behalten je eigene Turniernummer
billing-context — Generische Domäne (Generic Domain)
Verantwortlichkeit: Gebührenberechnung, Kassenführung, Abrechnung mit Reitern und dem Verband.
Aggregate Roots:
DomKonto– Kontobasierte Abrechnung pro Zahler (Basis für „Hansi-Szenario")DomGebühr– Einzelgebühr (Nenngeld, Nachnenngebühr, Sportförderbeitrag, Tierwohl-Euro)DomAbrechnung– Zusammenfassung aller Gebühren einer Veranstaltung
Ubiquitous Language (Auswahl):
Konto,Nenngeld,Nachnenngebühr,Sportförderbeitrag,Tierwohl-Euro,Gebühren-Verzicht
Kern-Invarianten:
- Sportförderbeitrag und Tierwohl-Euro fallen pro Start an (nicht pro Nennung)
- Gebühren-Verzicht wird als explizites Event gespeichert (Audit-Trail)
identity-context — Generische Domäne (Generic Domain)
Verantwortlichkeit: Authentifizierung, Rollen-Management, Berechtigungsprüfung (via Keycloak).
Aggregate Roots:
DomBenutzer– Systembenutzer mit Rollen (TBA, Veranstalter, Meldestelle, Richter)DomRolle– Definierte Rolle mit Berechtigungen
Ubiquitous Language (Auswahl):
TBA,Veranstalter,Meldestelle,Richter,Rolle,Berechtigung
Kern-Invarianten:
- Keycloak ist der einzige Identity Provider (→ ADR-0006)
- Rollen sind turnierbezogen (ein Benutzer kann bei Turnier A TBA und bei Turnier B Richter sein)
Konsequenzen
Positive
- Fachliche Klarheit: Jeder Context hat eine klar definierte Verantwortlichkeit und eigene Ubiquitous Language
- Unabhängige Entwicklung: P1-Contexts (
registration-context,actor-context) können ohne P2/P3 entwickelt werden - Offline-First: Jeder Context kann seinen eigenen lokalen Cache verwalten (SQLDelight)
- ÖTO-Konformität: Die Context-Grenzen spiegeln die Struktur des ÖTO-Regelwerks wider
- Erweiterbarkeit:
series-contextkann in Phase 2+ ohne Änderungen an bestehenden Contexts hinzugefügt werden
Negative
- Koordinationsaufwand: Domänenübergreifende Use-Cases (z.B. Nennungs-Workflow) erfordern explizite Integration
- Datenkonsistenz: Eventual Consistency zwischen Contexts muss bewusst gehandhabt werden
- Initialer Aufwand: Vollständige Context-Implementierung erfordert mehr Vorabdesign
Neutral
- Die Context-Grenzen können sich mit wachsendem Domänenwissen verschieben (Living Architecture)
Betrachtete Alternativen
Technische Modulaufteilung (abgelehnt)
Die ursprüngliche Aufteilung in masterdata, members, horses, events wurde verworfen, da sie technische
Kategorien statt fachliche Domänen widerspiegelt und keine klare Heimat für den Nennungs-Workflow bietet.
Monolithische Domäne (abgelehnt)
Ein einzelner großer Domänen-Context würde die Komplexität des ÖTO-Regelwerks nicht beherrschbar machen und die Offline-First-Strategie erschweren.
Referenzen
- ADR-0001: Modulare Architektur
- ADR-0002: Domain-Driven Design
- ADR-0015: Context Map
- Ubiquitous Language
- Abteilungs-Trennungs-Schwellenwerte
- MASTER_ROADMAP
- ÖTO 2026, § 2 Abs. 1, § 2 Abs. 7, § 2 Abs. 8, § 39