meldestelle/docs/01_Architecture/adr/0014-bounded-context-mapping-de.md
Stefan Mogeritsch c806660685 chore: remove deprecated horses, clubs, officials, and persons services
- Deleted obsolete modules related to horses, clubs, officials, and persons services, including their configurations, build files, and database provisioning scripts.
- Cleaned up associated references in the project structure (e.g., `settings.gradle.kts`).
- Removed unused database tables and Spring beans related to these domains.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
2026-03-28 16:51:08 +01:00

240 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
type: ADR
id: ADR-0014
status: ACTIVE
owner: Lead Architect
last_update: 2026-03-28
---
# 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:
1. Fehlende Ausrichtung zwischen Code-Struktur und ÖTO-Regelwerk
2. Unklare Verantwortlichkeiten bei domänenübergreifenden Operationen (z.B. Nennungs-Transfer)
3. Keine explizite Trennung zwischen Kern-Domäne (Nennungs-Workflow) und unterstützenden Domänen
4. 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 |
| `master-data-context` | Reiter, Pferde, Vereine, ZNS-Daten, ÖTO-Regelwerk | **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 Bewerb
- `DomNennungsTransfer` Transfer-Operation (kein Storno + Neu); Guthaben bleibt erhalten
- `DomAbteilung` 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`
---
#### `master-data-context` — Unterstützende Domäne (Supporting Domain)
**Verantwortlichkeit:** Stammdaten aller Akteure, Synchronisation mit dem ZNS (Zentrales Nennungs-System) sowie die "
Library of Truth" für das ÖTO/FEI Regelwerk.
**Aggregate Roots:**
- `DomReiter` Reiter mit Lizenz, Satznummer, Startkarte
- `DomPferd` Pferd mit Lebensnummer, Kopfnummer, Satznummer
- `DomFunktionär` Person mit Turnier-Rolle und Qualifikation (Richter, Parcoursbauer)
- `DomVerein` OEPS-Mitgliedsverein (Veranstalter)
- `DomRegelwerk` Richtverfahren (§ 204 Springen, § 104 Dressur etc.), Sparten, Klassen
- `DomGebührenSatz` Standard-Sätze für Sportförderbeiträge und Tierwohl-Euros
**Ubiquitous Language (Auswahl):**
- `Satznummer`, `Lebensnummer`, `Kopfnummer`, `FEI-ID`, `Lizenz`, `Startkarte`, `Gastreiter`, `Richtverfahren`,
`Paragraph`, `Sparte`, `Klasse`
**Kern-Invarianten:**
- `Satznummer` ist der primäre Schlüssel für den ZNS-Datenaustausch
- ZNS-Daten sind schreibgeschützt; Erweiterungen erfolgen über Verknüpfungen im `identity-context`
- Das Regelwerk dient als Basis für alle fachlichen Validierungen im System
- ZNS-Daten werden lokal gecacht (Offline-First)
---
#### `competition-context` — Unterstützende Domäne (Supporting Domain)
**Verantwortlichkeit:** Strukturierung von Bewerben, Erstellung von Startlisten, Erfassung von Ergebnissen. Die *
*Abteilung** ist hierbei die kleinste operative Einheit.
**Aggregate Roots:**
- `DomAbteilung` Atomare Einheit für Startlisten und Ergebnisse (ÖTO § 39). Ein Bewerb ist der organisatorische
Container.
- `DomBewerb` Klammer um eine oder mehrere Abteilungen mit gemeinsamer Bewerbsnummer, Sparte, Klasse.
- `DomStartliste` Geordnete Liste der Starter einer Abteilung.
- `DomErgebnis` Ergebnis eines Starts (Platzierung, Punkte, Zeit) innerhalb einer Abteilung.
**Ubiquitous Language (Auswahl):**
- `Abteilung`, `Abteilungsnummer`, `Bewerb`, `Prüfung`, `Startliste`, `Richtverfahren`, `Klasse/Höhe`
**Kern-Invarianten:**
- Startlisten und Ergebnislisten werden auf **Abteilungsebene** verwaltet
- Abteilungs-Schwellenwerte gemäß ÖTO § 39 lösen **Warnungen** aus (→ `Override-Event`)
- Ein Bewerb kann mehrere Abteilungen haben (z.B. Trennung nach R1/R2 Lizenzen)
---
#### `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 Turniernummer
- `DomAusschreibung` 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) sowie die Verwaltung
von erweiterten Profilen.
**Aggregate Roots:**
- `DomBenutzer` Systembenutzer mit Rollen (TBA, Veranstalter, Meldestelle, Richter)
- `DomProfil` Erweiterte Daten (Logo, Bio, Kontakt) verknüpft mit einer `Satznummer` aus dem `master-data-context`
- `DomRolle` Definierte Rolle mit Berechtigungen
**Ubiquitous Language (Auswahl):**
- `TBA`, `Veranstalter`, `Meldestelle`, `Richter`, `Profil-Link`, `Rolle`, `Berechtigung`
**Kern-Invarianten:**
- Keycloak ist der einzige Identity Provider (→ ADR-0006)
- Ein System-Benutzer kann über eine Link-Tabelle mit amtlichen ZNS-Daten verknüpft werden
- 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. Die
Umbenennung in `master-data-context` schärft das Verständnis als zentrale Library of Truth.
- **Abteilungs-Fokus:** Die Anerkennung der Abteilung als kleinste Einheit im `competition-context` löst Inkonsistenzen
bei Start- und Ergebnislisten.
- **Unabhängige Entwicklung:** P1-Contexts (`registration-context`, `master-data-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-context` kann 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](0001-modular-architecture-de.md)
- [ADR-0002: Domain-Driven Design](0002-domain-driven-design-de.md)
- [ADR-0015: Context Map](0015-context-map-de.md)
- [Ubiquitous Language](../../03_Domain/01_Glossary/Ubiquitous_Language.md)
- [Abteilungs-Trennungs-Schwellenwerte](../../03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md)
- [MASTER_ROADMAP](../MASTER_ROADMAP.md)
- ÖTO 2026, § 2 Abs. 1, § 2 Abs. 7, § 2 Abs. 8, § 39