docs(roadmaps): add sprint execution order and detailed role-specific roadmaps
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Has been cancelled
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Has been cancelled

- Added `SPRINT_EXECUTION_ORDER.md` to define the cross-role sprint step sequence.
- Created individual roadmaps for Architect, Backend, Frontend, DevOps, Rulebook, QA, UI/UX, and Curator.
- Captured developer responsibilities, dependencies, and timelines for Sprints A–C.
- Aligned sprint planning documentation with session log agreements.
- Provided structured documentation in `docs/04_Agents/Roadmaps/`.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-04-02 14:35:40 +02:00
parent 1a695df60b
commit 7e16b3f318
15 changed files with 1588 additions and 0 deletions
@@ -0,0 +1,135 @@
🏗️ **[Lead Architect]** — Domänen-Korrektur & USB-Fallback-Präzisierung | 2. April 2026
---
### ✅ Domänen-Korrektur wird übernommen: Die vollständige Hierarchie
Danke für die wichtige Korrektur. Das Domänen-Modell wird entsprechend präzisiert:
```
Veranstaltung (interne ID, Tenant-Grenze)
└── Turnier (OEPS-Turniernummer, z.B. 26128)
└── Prüfung / Bewerb (z.B. Bewerb 3 "90cm Stilspringen")
└── Abteilung(en) ← KLEINSTE EINHEIT
├── eigene Startliste
├── eigene Ergebnisliste
└── eigene Siegerehrung
```
**Das bedeutet konkret:**
Ein Bewerb (z.B. "Springprüfung 90cm") kann in **mehrere Abteilungen** aufgeteilt werden — entweder wegen zu vieler
Starter (Teilungs-Abteilung) oder weil es regelkonform zwingend ist (z.B. im CSN-C-NEU: `ohne Lizenz` vs. `mit Lizenz`).
Die `Abteilung` ist die Einheit, die:
- eine **Startnummern-Vergabe** hat
- eine **Startliste** hat (wird an den Richter-Turm übergeben)
- ein **Ergebnis** hat (kommt vom Richter-Turm zurück)
- eine **Siegerehrung** bekommt
---
### 🔧 USB-Fallback Konzept: Korrigiert auf Abteilungs-Ebene
Das USB-Export/Import-Protokoll aus der letzten Besprechung wird auf die korrekte kleinste Einheit angepasst:
#### Korrigiertes Dateiformat
```json
{
"meldestelle_export": {
"version": "1.0",
"veranstaltung_id": "NM-2026",
"turnier_nr": "26128",
"bewerb_nr": 3,
"bewerb_bezeichnung": "Stilspringen 90cm",
"abteilung_nr": 1,
"abteilung_bezeichnung": "ohne Lizenz",
"exportiert_am": "2026-04-25T10:15:00",
"exportiert_von": "MELDESTELLE",
"typ": "STARTLISTE",
"checksum": "sha256:...",
"daten": {
...
}
}
}
```
#### Korrigierter Export-/Import-Flow
```
MELDESTELLE (Desktop) RICHTER-TURM (Desktop)
────────────────────── ──────────────────────
Bewerb 3 hat 2 Abteilungen:
[Export Startliste Abt. 1] ──USB──► [Import → Richter startet Abt. 1]
[Export Startliste Abt. 2] ──USB──► [Import → Richter startet Abt. 2]
◄──USB── [Export Ergebnis Abt. 1]
◄──USB── [Export Ergebnis Abt. 2]
[Import Ergebnis Abt. 1]
[Import Ergebnis Abt. 2]
└── Gesamtrangliste Bewerb 3
(aus beiden Abteilungen, je nach Prüfungstyp)
```
#### Wichtige Regel für zusammengeführte Ergebnisse
Nach dem Import beider Abteilungsergebnisse entscheidet der **Prüfungstyp**, ob:
- **Separate Siegerehrung** pro Abteilung (z.B. CSN-C-NEU: `ohne Lizenz` und `mit Lizenz` werden getrennt geehrt), *
*oder**
- **Gesamtrangliste** aus allen Abteilungen (bei rein organisatorischer Teilung wegen Starter-Anzahl)
Diese Unterscheidung muss beim Anlegen der Abteilung gesetzt werden (
`abteilung_typ: SEPARATE_SIEGEREHRUNG | ORGANISATORISCH`).
---
### 📄 TURNIER_KLASSEN.md Update — Konsequenzen für das System
Das aktualisierte Dokument bestätigt und formalisiert die **zwingende Abteilungs-Teilung** im C-NEU-Bereich:
| Kategorie | Höhe | Pflicht-Teilung |
|---------------|-----------|--------------------------------------------------|
| **CSN-C-NEU** | bis 95 cm | Abteilung `ohne Lizenz` ↔ Abteilung `mit Lizenz` |
| **CSN-C-NEU** | ab 100 cm | Abteilung `R1` ↔ Abteilung `R2 und höher` |
Das ist kein optionales Feature — das System **muss** beim Anlegen eines Bewerbs im CSN-C-NEU automatisch die korrekten
Abteilungen vorschlagen bzw. erzwingen.
**Arbeitsauftrag daraus (ergänzt zu Sprint A-5):**
| # | Wer | Aufgabe |
|------|-------------|----------------------------------------------------------------------------------------------------------------------------|
| A-5a | 📜 Rulebook | Vollständige Liste aller zwingenden Abteilungs-Teilungsregeln aus ÖTO 2026 spezifizieren (C-NEU bereits bekannt, weitere?) |
| A-5b | 👷 Backend | `Abteilung`-Entität ins Schema aufnehmen (FK: `bewerb_id`, Felder: `nr`, `bezeichnung`, `typ`, `siegerehrung_separat`) |
| A-5c | 🎨 Frontend | Beim Anlegen eines Bewerbs: Abteilungs-Logik als Teil des Bewerb-Dialogs (Vorschlag + Pflicht-Validierung) |
---
### 📌 Aktualisierte Domänen-Begriffe für `Ubiquitous_Language.md`
Folgende Begriffe müssen ergänzt werden (Auftrag an 🧹 Curator):
| Begriff | Definition |
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| **Abteilung** | Kleinste ausführbare Einheit eines Bewerbs/einer Prüfung. Hat eine eigene Startliste, eigene Ergebnisse und ggf. eine eigene Siegerehrung. |
| `SEPARATE_SIEGEREHRUNG` | Abteilungs-Typ: Die Abteilung hat eine eigenständige Siegerehrung (z.B. bei Lizenz-Trennung im C-NEU). |
| `ORGANISATORISCH` | Abteilungs-Typ: Rein organisatorische Aufteilung wegen Starter-Anzahl. Ergebnisse werden in einer Gesamtrangliste zusammengeführt. |
---
### 🎯 Scope-Bestätigung
| Thema | Status |
|-----------------------------------------|-------------------------------------------|
| USB-Fallback (korrigiert auf Abteilung) | ✅ Konzept präzisiert — weiter in Sprint B |
| Web-App Präsentation-Hierarchie | ⏸️ Separate Besprechung später |
| Nenn-System Web-Formular | ⏸️ Separate Besprechung später |
| Live-Ergebnisse Web-App | ⏸️ Separate Besprechung später |
| **Fokus jetzt** | 🖥️ Desktop-App (Sprint A + B) |
> ⚠️ **Wichtiger Hinweis für alle Entwickler:** Die `Abteilung` als eigenständige Domänen-Entität muss **sofort** in
> alle laufenden Arbeiten einfließen — besonders in das Backend-Schema (A-3) und das ViewModel-Design (A-2). Wer
> Startlisten oder Ergebnisse ohne Abteilungs-Bezug modelliert, baut falsch.
@@ -0,0 +1,26 @@
Meldestelle Besprechung!
Wir berufen diese Besprechung ein, um die nächsten Entwicklungsschritte zu besprechen.
Es liegen aktuellen Reports aller Entwickler von diesem Projekt vor.
Jeder Entwickler hat in seinem Report Empfehlungen priorisiert.
docs/90_Reports/2026-04-02_Architect_Report.md
docs/90_Reports/2026-04-02_Backend_Report.md
docs/90_Reports/2026-04-02_Curator_Report.md
docs/90_Reports/2026-04-02_DevOps_Report.md
docs/90_Reports/2026-04-02_Frontend_Report.md
docs/90_Reports/2026-04-02_QA_Report.md
docs/90_Reports/2026-04-02_Rulebook_Report.md
docs/90_Reports/2026-04-02_UIUX_Report.md
In dieser Besprechung wollen wir
- Übersicht bekommen
- Strategie besprechen
- Arbeitsaufträge für jeden Entwickler ausarbeiten
- genaue Reihenfolge der nächsten Entwicklungsschritte festlegen
Am Ende dieser Besprechung, soll jeder Entwickler genau wissen was er wann machen soll.
Wir wollen alle an einem Strang ziehen.
Sind alle Entwickler anwesend und vorbereitet?
@@ -0,0 +1,167 @@
🏗️ **[Lead Architect]** — Besprechungsprotokoll | Meldestelle-Biest | 2. April 2026
---
### 📋 Anwesenheit & Vorbereitung
| Agent | Anwesend | Report vorliegend |
|----------------------|----------|-------------------|
| 🏗️ Lead Architect | ✅ | ✅ |
| 👷 Backend Developer | ✅ | ✅ |
| 🎨 Frontend Expert | ✅ | ✅ |
| 🐧 DevOps Engineer | ✅ | ✅ |
| 🧐 QA Specialist | ✅ | ✅ |
| 📜 Rulebook Expert | ✅ | ✅ |
| 🖌️ UI/UX Designer | ✅ | ✅ |
| 🧹 Curator | ✅ | ✅ |
**Alle Entwickler sind anwesend und haben ihre Reports eingereicht. Die Besprechung kann beginnen.**
---
### 📊 Übersicht: Wo stehen wir?
Das Projekt hat in den letzten Tagen starken Momentum im **Frontend** (V2-Screens, Event-First-Workflow, Navigation mit
Back-Stack) aufgebaut. Die Desktop-App nimmt konkrete Form an. Gleichzeitig haben sich **drei kritische Schulden**
aufgebaut, die jetzt adressiert werden müssen, bevor wir weiter bauen:
1. **Frontend-Architektur-Schulden:** Business-Logik liegt direkt in den Composables (`StoreV2`-Aufrufe, lokaler
`remember`-State). Ohne ViewModel-Refactoring wird der Code bald unwartbar.
2. **Backend fehlt als Fundament:** Das Frontend läuft auf einem Mock-Store. Echte CRUD-Endpunkte und Tenant-Isolation
fehlen vollständig.
3. **Validierung ist ein Sicherheitsloch:** FEI-IDs, OEPS-Nummern und Lizenzklassen können aktuell als beliebige Strings
gespeichert werden — das verletzt ÖTO/FEI-Compliance.
**Kernaussage der Besprechung:** Wir müssen jetzt das Fundament stärken, bevor wir neue Features bauen.
---
### 🎯 Strategie: Die 3 Säulen des nächsten Sprints
```
SÄULE 1: FUNDAMENT SÄULE 2: VERBINDUNG SÄULE 3: QUALITÄT
───────────────────── ────────────────────── ─────────────────────
ViewModel-Architektur → CRUD-APIs Backend → ÖTO-Validierung
Tenant-Isolation → Frontend-Anbindung → Tests & QA
Dokumentation (ADR) → Desktop-Packaging → UI/UX Konsistenz
```
Wir arbeiten **in dieser Reihenfolge** — Säule 1 blockiert Säule 2, Säule 2 blockiert Säule 3.
---
### 📅 Reihenfolge der nächsten Entwicklungsschritte
#### 🔴 Sprint A — Sofort (diese Woche)
**Ziel: Das Fundament stabilisieren, damit alle anderen aufbauen können.**
| # | Wer | Aufgabe |
|-----|---------------|--------------------------------------------------------------------------------------------------------------------------|
| A-1 | 🏗️ Architect | Tenant-Resolution-Strategie entscheiden (Schema-per-Tenant vs. Tenant-ID in allen Tabellen) — **Ergebnis: ADR-0021** |
| A-2 | 🎨 Frontend | ViewModel-Architektur definieren und `VeranstalterViewModel` als Referenz-Implementierung (MVVM/UDF) umsetzen |
| A-3 | 👷 Backend | Tenant-Isolation im Datenzugriffs-Layer implementieren auf Basis von ADR-0021 |
| A-4 | 🧹 Curator | `docs/01_Architecture/` mit Event-First-Workflow, Navigation-V2 und Tenant-Konzept dokumentieren |
| A-5 | 📜 Rulebook | Validierungsregeln für OEPS-Nummern, FEI-IDs und Lizenzklassen (R1R4) schriftlich spezifizieren — als Grundlage für A-6 |
> ⚠️ **A-1 (ADR-0021) ist ein Blocker für A-3!** Der Architect liefert zuerst.
---
#### 🟠 Sprint B — Kurzfristig (nächste Woche)
**Ziel: Frontend und Backend verbinden, Validierung implementieren.**
| # | Wer | Aufgabe |
|-----|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
| B-1 | 👷 Backend | CRUD-Endpunkte für Veranstalter, Veranstaltungen, Reiter, Pferde, Vereine, Funktionäre implementieren |
| B-2 | 🎨 Frontend | ViewModels für alle V2-Screens umsetzen (`PferdProfilViewModel`, etc.) und Ktor-Clients/Repositories für Backend-Anbindung vorbereiten |
| B-3 | 📜 Rulebook + 🎨 Frontend | Validierungslogik aus Sprint A-5 als Live-Feedback in V2-Edit-Dialogen implementieren |
| B-4 | 📜 Rulebook + 👷 Backend | Dieselbe Validierungslogik serverseitig absichern |
| B-5 | 🖌️ UI/UX | UX-Konzept für Editier-Formulare überarbeiten: AlertDialog vs. dedizierter Screen / Sliding-Panel — **Ergebnis: Wireframes** |
| B-6 | 🧐 QA | Test-Suite für V2-Navigation und Back-Stack aufbauen; Edge-Cases für Onboarding/Wizard (leere Felder, schnelles Klicken, Abbrechen) |
| B-7 | 🐧 DevOps | CI/CD Pipeline für Compose-Desktop-Tests headless konfigurieren (GitHub/Gitea Actions) |
---
#### 🟡 Sprint C — Mittelfristig (in 2 Wochen)
**Ziel: Ausliefern, offline-fähig machen, aufräumen.**
| # | Wer | Aufgabe |
|-----|---------------|-------------------------------------------------------------------------------------------------------------------------|
| C-1 | 🐧 DevOps | Desktop-App-Packaging konfigurieren (`.msi` / `.deb` / `.dmg`) via `compose.desktop.nativeDistributions` |
| C-2 | 🏗️ Architect | Synchronisations-Protokoll-Konzeption starten (Event-Sourcing vs. CRDT vs. Timestamp-Sync) |
| C-3 | 👷 Backend | Testdaten-Seeder implementieren (reproduzierbare Turnier-, Nennungs- und Stammdaten) |
| C-4 | 🧐 QA | Testfälle für Mandanten-Isolation (Daten strikt zwischen Veranstaltungen getrennt) |
| C-5 | 🖌️ UI/UX | Wireframes aus B-5 implementieren; Empty States für alle Listenansichten designen und umsetzen |
| C-6 | 📜 Rulebook | `AltersklasseRechner` vollständig gegen ÖTO 2026 testen; Funktionärs-Qualifikationen auf Enum umstellen |
| C-7 | 🧹 Curator | `README.md` und Setup-Guide aktualisieren; Unterordner-Struktur für `docs/` einführen; V1-Code-Bereinigung koordinieren |
| C-8 | 🏗️ Architect | `MASTER_ROADMAP.md` aktualisieren (Desktop-Fokus, Tenant-Isolation, Offline-Sync-Meilensteine) |
| C-9 | 🐧 DevOps | Semantic Versioning Strategie einführen; koordiniertes Release-Tagging Client + Server |
---
### 📌 Individuelle Arbeitsaufträge (Zusammenfassung)
#### 🏗️ Lead Architect
1. **[A-1, sofort]** ADR-0021 schreiben: Tenant-Resolution-Strategie entscheiden
2. **[C-2]** Sync-Protokoll-Konzept starten
3. **[C-8]** MASTER_ROADMAP aktualisieren
#### 👷 Backend Developer
1. **[A-3, nach ADR-0021]** Tenant-Isolation im Datenzugriffs-Layer
2. **[B-1]** CRUD-APIs für alle Stammdaten-Entitäten
3. **[B-4]** ÖTO-Validierung serverseitig absichern
4. **[C-3]** Testdaten-Seeder
#### 🎨 Frontend Expert
1. **[A-2, sofort]** ViewModel-Referenz-Implementierung (`VeranstalterViewModel`, MVVM/UDF)
2. **[B-2]** Alle V2-ViewModels + Ktor-Client-Repositories
3. **[B-3]** Validierungs-Live-Feedback in Edit-Dialogen
#### 🐧 DevOps Engineer
1. **[B-7]** CI/CD für Compose Desktop Tests (headless)
2. **[C-1]** Desktop-App Packaging (Distributionen)
3. **[C-9]** Semantic Versioning + Release-Strategie
#### 🧐 QA Specialist
1. **[B-6, parallel zu Sprint B]** Test-Suite Navigation/Back-Stack + Onboarding-Edge-Cases
2. **[C-4]** Mandanten-Isolations-Testfälle
#### 📜 ÖTO/FEI Rulebook Expert
1. **[A-5, sofort]** Validierungsregeln schriftlich spezifizieren (OEPS, FEI-ID, Lizenzklassen)
2. **[B-3/B-4]** Implementierung der Validierung Frontend + Backend begleiten
3. **[C-6]** AltersklasseRechner vollständig testen; Funktionärs-Qualifikationen als Enum
#### 🖌️ UI/UX Designer
1. **[B-5]** Wireframes: Dialog vs. Fullscreen-Edit entscheiden
2. **[C-5]** Wireframes implementieren + Empty States designen und umsetzen
#### 🧹 Curator
1. **[A-4, sofort]** Event-First-Workflow + Navigation-V2 + Tenant-Konzept dokumentieren
2. **[C-7]** README + Setup-Guide + Docs-Struktur + V1-Code-Bereinigung koordinieren
---
### ✅ Beschlüsse dieser Besprechung
1. **ADR-0021 (Tenant-Resolution)** wird sofort vom Architect erstellt — es ist der wichtigste Blocker.
2. **ViewModel-Architektur** wird vor neuen Features eingeführt — kein weiterer Code ohne ViewModel.
3. **Kein neues Feature ohne ÖTO-Validierung** — Rulebook Expert gibt die Spezifikation vor, Backend + Frontend setzen
sie gemeinsam um.
4. **Mock-Store (`StoreV2`) ist temporär** — Ziel von Sprint B ist die vollständige Ablösung durch echte
Backend-Anbindung.
5. **MASTER_ROADMAP** wird am Ende von Sprint C durch den Architect aktualisiert.
---
> 🏁 **Alle Entwickler wissen, was sie wann zu tun haben. Wir ziehen an einem Strang. Sprint A beginnt jetzt.**
@@ -0,0 +1,42 @@
🏗️ **[Lead Architect]** — Besprechungsabschluss | 2. April 2026
---
### Abschlussfrage an alle Entwickler
Die Frage geht in die Runde — und hier die Rückmeldungen:
| Agent | Status | Offene Fragen |
|----------------------|-----------------------------------------------------------------|---------------|
| 🏗️ Lead Architect | ✅ Klar — starte sofort mit ADR-0021 | Keine |
| 👷 Backend Developer | ✅ Klar — warte auf ADR-0021, dann Schema | Keine |
| 🎨 Frontend Expert | ✅ Klar — starte ViewModel-Architektur parallel | Keine |
| 🐧 DevOps Engineer | ✅ Klar — CI/CD headless ist Sprint B Aufgabe | Keine |
| 🧐 QA Specialist | ✅ Klar — Test-Strategie-Dokument und Navigation-Tests starten | Keine |
| 📜 Rulebook Expert | ✅ Klar — Validierungsregeln-Spezifikation beginnt sofort | Keine |
| 🖌️ UI/UX Designer | ✅ Klar — Design-Inventur der V2-Screens als erster Schritt | Keine |
| 🧹 Curator | ✅ Klar — `Ubiquitous_Language.md` und Session-Log sind Sprint A | Keine |
**Alle Entwickler sind informiert. Keine offenen Fragen.**
---
### 🏁 Besprechung offiziell beendet
**Erstellt in dieser Besprechung:**
- ✅ Strategischer Sprint-Plan (A → B → C) mit klaren Verantwortlichkeiten
- ✅ 8 individuelle Schritt-für-Schritt Roadmaps (`docs/04_Agents/Roadmaps/`)
- ✅ Entwickler-übergreifende Ausführungsreihenfolge (`SPRINT_EXECUTION_ORDER.md`)
- ✅ Domänen-Modell präzisiert (`Veranstaltung → Turnier → Bewerb → Abteilung`)
- ✅ Veranstaltungs-Kassa-Konzept ausgearbeitet (Multi-Turnier-Saldo, 1 Zahlung, 2 Rechnungen)
- ✅ Zurückgestellte Themen dokumentiert (⏸️ USB-Fallback, Web-App, Nenn-System, Live-Ergebnisse)
**Der nächste Schritt liegt beim Architect:** `ADR-0021` — Tenant-Resolution-Strategie.
> 🎯 **Wir ziehen an einem Strang. Sprint A beginnt jetzt.**
---
*🧹 Curator-Hinweis: Session-Log dieser Besprechung bitte unter `docs/99_Journal/`
als `2026-04-02_Besprechung_Sprint-Planung.md` ablegen — das ist Aufgabe A-5 in der Curator Roadmap.*
@@ -0,0 +1,128 @@
🏗️ **[Lead Architect]** — Antwort auf Domänen-Fragen des Projekt-Owners | 2. April 2026
---
### 1. Ist die Hierarchie korrekt verstanden? Fast — aber wir müssen das Domain-Modell schärfen.
Dein Verständnis ist **im Kern richtig**, aber die aktuelle `Ubiquitous_Language.md` hat hier noch eine **Unschärfe**,
die wir jetzt klären müssen:
**Aktuelles Modell (wie dokumentiert):**
```
Veranstalter
└── Veranstaltung (interne ID, selbst vergeben)
├── Typ: Turnier | Reitertreffen | ...
└── [wenn Typ = Turnier]
└── Turniernummer (OEPS-vergeben, eindeutig)
```
Das aktuelle Modell impliziert **1 Veranstaltung = 1 Turnier** (eine Turniernummer je Veranstaltung).
**Das Neumarkt-Szenario bricht dieses Modell auf:**
Neumarkt ist **eine organisatorische Veranstaltung** (selber Veranstalter, selbes Gelände, selber Zeitraum), aber
besteht aus **zwei offiziellen OEPS-Turnieren** mit je eigener Turniernummer.
**Korrekte Hierarchie (erweitert):**
```
Veranstalter (OEPS-Mitgliedsverein, z.B. URV Neumarkt)
└── Veranstaltung (interne ID, z.B. "NM-2026")
│ ← Tenant-Grenze (eigene Datenbank, ADR-0020)
│ ← Örtlich & zeitlich begrenzt
├── Turnier #1 (OEPS-Turniernummer: 26128, CSN-C NEU)
│ ├── Bewerbe (114)
│ └── Turnier-Kassa
└── Turnier #2 (OEPS-Turniernummer: 26129 o.ä., z.B. CSNP-C NEU)
├── Bewerbe (1N)
└── Turnier-Kassa
```
**Antwort auf deine Frage:****Ja, genau so.** Die `Veranstaltung` ist unser interner Überbegriff mit selbst
vergebener ID und ist gleichzeitig die Tenant-Grenze (eine Datenbank). Innerhalb dieser Veranstaltung gibt es eine oder
mehrere pferdesportliche Veranstaltungen — aktuell vom Typ `Turnier` — jede mit ihrer vom Verband (OEPS/FEI) vergebenen
Turniernummer. **Diese Unterscheidung muss noch in die `Ubiquitous_Language.md` und in das Datenbankschema einfließen
** (das ist ein Arbeitsauftrag für den Curator + Backend).
---
### 2. Veranstaltungs-Kassa mit Turnier-übergreifendem Saldo: Umsetzbar?
**Ja, das ist absolut umsetzbar — und architektonisch sauber lösbar.**
#### Das Konzept: Drei Ebenen der Kassa
```
VERANSTALTUNGS-KASSA (Aggregations-Ebene)
├── TeilnehmerKonto (Reiter × Pferd, pro Veranstaltung)
│ ├── Saldo aus Turnier #1 (z.B. –€ 75,-)
│ └── Saldo aus Turnier #2 (z.B. –€ 45,-)
│ Gesamt-Offener-Betrag: –€ 120,-
└── Zahlvorgang (1× Kassagang am Ende der Veranstaltung)
├── Rechnung Turnier #1 (€ 75,-) → OEPS-Meldung Turnier 26128
└── Rechnung Turnier #2 (€ 45,-) → OEPS-Meldung Turnier 26129
```
#### Wie das funktioniert (Ablauf Neumarkt):
| Schritt | Was passiert |
|----------------------------------------------------------------|--------------------------------------------------------|
| Teilnehmer meldet sich für Bewerbe in **Turnier 1** | Forderung wird `TurnierKassa #1` verbucht |
| Derselbe Teilnehmer meldet sich für Bewerbe in **Turnier 2** | Forderung wird `TurnierKassa #2` verbucht |
| Teilnehmer kommt **einmal** zur Kassa (Ende der Veranstaltung) | System zeigt Gesamt-Saldo aus beiden Turnieren |
| Kassier nimmt **eine Zahlung** entgegen | `Zahlvorgang` wird auf `Veranstaltungs-Ebene` gebucht |
| System generiert **zwei separate Rechnungen** | Je eine pro Turnier (für OEPS-Abrechnung notwendig) |
| Turnier-Kassenabschluss | Jede `TurnierKassa` schließt separat ab (OEPS-konform) |
#### Warum zwei separate Rechnungen notwendig sind:
Das ist nicht nur ein Komfort-Feature — es ist eine **OEPS-Pflicht**. Jedes Turnier mit eigener Turniernummer muss
separat an den Verband gemeldet werden. Die Startgelder und Nenngelder sind je Turniernummer nachvollziehbar zu belegen.
Eine gemeinsame Rechnung über beide Turniere würde die ZNS-Meldung erschweren.
---
### 3. Statistiken: Separat und aggregiert
Selbe Logik, selbe Lösung:
| Ansicht | Quelle |
|------------------------------------|----------------------------------------------------|
| **Statistik Turnier #1** | Nur Daten aus `Turnier.id = 26128` |
| **Statistik Turnier #2** | Nur Daten aus `Turnier.id = 26129` |
| **Statistik Veranstaltung gesamt** | Aggregation über alle Turniere der `Veranstaltung` |
Das ist eine reine Abfrage-/Reporting-Frage. Da die `Veranstaltung` die Tenant-Grenze ist (alle Daten in einer
Datenbank), sind sowohl turnierspezifische als auch veranstaltungsweite Auswertungen mit einfachen SQL-Abfragen
realisierbar — keine aufwendige Cross-Tenant-Kommunikation nötig.
---
### 📌 Was das für unsere Arbeitsaufträge bedeutet
Deine Fragen zeigen eine **wichtige Lücke** im bisherigen Plan, die wir jetzt schließen müssen:
| Priorität | Wer | Aufgabe |
|------------------------------|---------------|-----------------------------------------------------------------------------------------------------------------------------|
| 🔴 **Sofort (vor ADR-0021)** | 🏗️ Architect | Domänen-Modell präzisieren: `Veranstaltung` 1:N `Turnier` explizit festlegen. `Ubiquitous_Language.md` anpassen. |
| 🔴 **Sprint A** | 👷 Backend | Datenbankschema: `veranstaltungen` Tabelle + `turniere` Tabelle (mit FK auf Veranstaltung, Turniernummer als OEPS-vergeben) |
| 🟠 **Sprint B** | 👷 Backend | `teilnehmer_konto` auf Veranstaltungs-Ebene; `zahlvorgang` mit Multi-Turnier-Aufteilung; Rechnungs-Generierung pro Turnier |
| 🟠 **Sprint B** | 🎨 Frontend | UI für Veranstaltungs-Kassa: Gesamtsaldo-Ansicht + Zahlvorgang + Rechnungsvorschau je Turnier |
| 🟡 **Sprint C** | 🧐 QA | Testfälle: Teilnehmer an 2 Turnieren → 1 Zahlung → 2 korrekte Rechnungen |
> ⚠️ **Wichtig:** Der Begriff `TeilnehmerKonto` auf Veranstaltungsebene (über mehrere Turniere) ist **neu** und muss in
> die `Ubiquitous_Language.md` aufgenommen werden. Das ist ein Auftrag für Curator + Rulebook Expert gemeinsam.
---
### ✅ Kurz-Zusammenfassung für den Owner
1. **Ja**`Veranstaltung` (interne ID, Tenant-Grenze) enthält ein oder mehrere `Turnier` (mit OEPS-Turniernummer). Das
Modell muss noch formal so dokumentiert werden.
2. **Ja** — Eine `Veranstaltungs-Kassa` mit Turnier-übergreifendem Saldo, einem Zahlvorgang, aber zwei separaten
Rechnungen ist architektonisch sauber umsetzbar und ist sogar die richtige Lösung für die OEPS-konforme Abrechnung.
3. **Ja** — Statistiken können auf beiden Ebenen (per Turnier und gesamt per Veranstaltung) ausgewertet werden, ohne
Mehraufwand, da alle Daten im selben Tenant (Datenbank) liegen.