docs: massive restructuring of documentation, development guides and agent playbooks

This commit is contained in:
2026-06-15 12:54:38 +02:00
parent e4988b4397
commit ce63303b2c
686 changed files with 45423 additions and 319 deletions
@@ -0,0 +1,130 @@
# 🧹 Curator Log — Neumarkt 2026: Public Web + Desktop (Meldestelle)
Datum: 2026-03-27
Status: Arbeitsprotokoll (MVP bis 2026-04-07)
## Kontext & Ziel
- Bis Di, 07.04.2026: Öffentlich erreichbare Web-App mit Nennformular pro Turnier (26128, 26129) und Desktop-App (
offline-fähig) zur internen Steuerung (Toggles, Hinweise, Datenpflege).
- Prinzipien: Trennung Fach-Kontexte vs. TechOps/Monitoring; Offline-First; keine Annahmen ohne Rückfrage; Glossar ist
Quelle der Wahrheit.
## Begriffe & Quellen
- Glossar/UL: `docs/03_Domain/00_Glossary.md`, `docs/03_Domain/01_Glossary/Ubiquitous_Language.md`.
- Neumarkt-Referenzen: `docs/Neumarkt2026/*` (Turnierkarten, Dashboard-Skizzen).
- Kurzdefinitionen (zur Bestätigung):
- Veranstalter: Organisation (z. B. Verein Neumarkt).
- Veranstaltung: Rahmen (Ort/Zeitraum), fasst Turniere.
- Turnier: Einheit mit Bewerben/Prüfungen, Ausschreibung, Nennungen, Start-/Ergebnislisten.
- Bewerb/Prüfung: Klasse im Turnier; optional in Abteilungen.
- Abteilung: Unterteilung eines Bewerbs mit eigener Liste.
## Web-App — MVP Funktionsumfang
1) Landing www.mo-code.at
- Card-Liste der Veranstaltungen (aktuell: Neumarkt) mit Turnier-Cards (26128, 26129).
- Je Turnier-Card: Buttons „Ausschreibung (PDF)“, „Nennen“ (sichtbar, wenn `turnier.config.nennenEnabled`),
„Start-Ergebnisse“ (sichtbar, wenn `turnier.config.resultsEnabled`).
- Hinweis-Text `turnier.notice` (z. B. „Pferdepass-Kontrolle“, „Achtung Nennstopp“).
2) Prüfungs-Übersicht je Turnier
- Sortierte Liste aller Bewerbe (Datum, Uhrzeit, Platz); optional Abteilungen verschachtelt.
- Buttons je Card: „Startliste“ (geplant/laufend), „Ergebnisliste“ (abgeschlossen), „Live-Ergebnisse“ (Nice-to-have,
vorerst verborgen).
- Suche/Filter (Reiter/Pferd) Nice-to-have; nur Turnierteilnehmer.
3) Nennformular (pro Turnier generiert)
- Abschnitte: Reiter, Pferd, Bewerb, Einverständnisse.
- Client- und Server-Validierung; Bestätigungsseite; optional E-Mail-Bestätigung (abhängig Mailserver) oder
On-Screen-Referenz.
Pflichtfelder (Vorschlag, final durch 📜 Rulebook Expert):
- Reiter: Vorname, Nachname, Geburtsjahr/-datum, Nationalität, Verein/Club, E-Mail.
- Lizenz (bewerbsabhängig): Reiter-Lizenznummer (pflichtig, falls Regel verlangt).
- Pferd: Name, Jahrgang, mind. eines von UELN/Passnummer; Besitzer optional.
- Bewerbsauswahl (+ Abteilung ggf.), optional Kommentar.
- Einverständnisse: DSGVO/Teilnahmebedingungen, Tiergesundheit/Impfstatus (Checkboxen).
Öffentliche Minimal-APIs:
- GET `/api/veranstaltungen`
- GET `/api/turniere/{turnierId}`
- GET `/api/turniere/{turnierId}/bewerbe`
- GET `/api/turniere/{turnierId}/ausschreibung` (PDF)
- POST `/api/turniere/{turnierId}/nennungen`
## Desktop-App (Meldestelle) — MVP
- Offline-First: Lokale DB (z. B. SQLite) + Sync-Queue. Geräte „Meldestelle“ und „Richter-Turm“ im selben LAN.
- Statusleiste: Indikatoren „Internet erreichbar“ und „Peer verbunden“ (Heartbeat-basiert).
- Onboarding (Freischalten):
1) Gerätename setzen (z. B. „Meldestelle“, „Richter-Turm“).
2) Sicherheitsschlüssel setzen (gemeinsam, z. B. „Neumarkt2026“) für verschlüsselte LAN-Kopplung.
3) ZNS-Daten laden: automatisch via Internet/LAN oder Offline-Import `ZNS.zip` (Integritäts-/Versionsprüfung, Warnung
bei veraltetem Stand).
- Nach Freischalten: Navigation „Zu den Veranstaltern“ sichtbar.
- Geräte-Setup: Druckerauswahl (OS-Dialog), Persistenz pro Gerät.
- LAN-Kopplung: mDNS/Bonjour Discovery; Fallback manuelle IP/QR optional.
- Optional: Einfacher LAN-Chat zwischen Geräten (Store-and-forward bei kurzzeitigem Offline).
## Veranstalter Übersicht (neue Präzisierung)
- Nach Freischalten (Name + Schlüssel + ZNS vorhanden) ist „Zu den Veranstaltern“ aktiv.
- Screen-Inhalte:
- Auswahlliste bereits registrierter Veranstalter (online/LAN geladen), z. B. „Verein Neumarkt“.
- Aktion „Neuen Veranstalter anlegen“ für Fälle ohne Treffer/Neuanlage.
- Weiterer Fluss:
1) Veranstalter auswählen/neu anlegen.
2) Veranstaltung anlegen/auswählen (gemäß Glossar; falls Rahmen explizit geführt wird).
3) Turnier innerhalb der Veranstaltung anlegen (26128, 26129) und konfigurieren:
- Toggles: `nennenEnabled`, `resultsEnabled`
- Hinweis-Text (`notice`)
- Bewerbs-Regeln (Pflichtfelder-Flags), Nennstopp-Status
## TechOps-UI (separate Shell)
- Monitoring/Metriken/Logs + Ping-Service-Demo. Keine fachliche Vermischung.
- Kernmetriken (MVP): public endpoint availability, nennungen_submit_latency_p95, nennungen_submit_error_rate,
nennungen_created_count pro Turnier, pdf_delivery_success_rate.
## Qualitätsleitplanken (DoD, MVP)
- Modultrennung: Fach-Features getrennt von TechOps/Ping; keine Cross-Imports.
- Offline-First: Queue/Retry auf allen Netzwerkpfaden; klare UI-States für Offline/Sync.
- Observability: Traces, Key-Metrics, korrelierbare Request-IDs; keine PII in Logs.
- Security (MVP): gemeinsamer LAN-Schlüssel ausreichend; später erweiterbar (Pairing/QR).
- DSGVO: Minimaldatensatz; Einverständnis-Texte durch 📜 Rulebook Expert.
## Offene Punkte (für nächste Session)
1) Bestätigung/Korrektur Glossar-Definitionen.
2) Finalisierung Pflichtfelder Nennformular inkl. bewerbsabhängiger Regeln.
3) E-Mail-Bestätigung sofort vs. On-Screen-Only.
4) Gleich/abweichende Regeln zwischen 26128 und 26129.
5) LAN-Pairing-Fallback (reicht gemeinsamer Schlüssel vs. zusätzliche IP/QR-Option aktivieren).
6) UI-Details „Veranstalter Übersicht“ (Suche/Filter, Minimalfelder Neuanlage).
## Konkrete nächste Schritte (Umsetzung)
- Desktop:
- Onboarding-Checklist-Komponente (Gerätename, Schlüssel, ZNS-Status).
- Screen „Veranstalter Übersicht“: Liste (remote/LAN), „Neuen Veranstalter anlegen“.
- Formular „Veranstalter neu“: Minimalfelder, Persistenz lokal + Sync.
- Backend:
- Endpunkte Veranstalter-Query (public/internal), PDF-Auslieferung, Nennungs-Persistenz.
- Turnier-Config-API (Toggles, Notice), Bewerbs-Regel-Flags.
- Web-App:
- Landing + Turnier-Cards (26128, 26129) mit Toggles/Notice.
- Nennformular-Renderer aus Turnier-/Bewerbs-Definition; POST Nennung.
## Go/No-Go Checkliste Neumarkt
- [ ] Desktop: Onboarding (Name, Schlüssel, ZNS geladen)
- [ ] Desktop: Veranstalter sichtbar/neu anlegbar
- [ ] Backend: Turnierdaten 26128/26129 vorhanden; PDF-Links ok
- [ ] Web: Landing online; Turnier-Cards korrekt gesteuert
- [ ] Web: Nennformular 26128/26129; Validierung & Persistenz ok
- [ ] Observability: Basis-Metriken aktiv
@@ -0,0 +1,36 @@
# 🧹 Session Log — 2026-04-03
## Agent: 👷 Backend Developer
## Aufgabe
`EntriesIsolationIntegrationTest` schlägt fehl mit `ClassNotFoundException` und `No database specified`.
## Root Cause Analyse
### Problem 1: `ClassNotFoundException` (Spring Context Load)
- `springdoc-openapi` war auf Version `3.0.0` gesetzt
- Diese Version ist für Spring Boot 4.x / Spring 7 gedacht und zieht Spring Boot 4.x-Klassen transitiv rein
- Im Spring Boot 3.x-Kontext führt das zu `ClassNotFoundException` für `JacksonJsonHttpMessageConverter`
### Problem 2: `No database specified` (Exposed)
- `EntriesDatabaseConfiguration` ist mit `@Profile("!test")` annotiert → wird im Test nicht geladen
- Exposed braucht `Database.connect()` vor dem ersten `transaction {}`-Aufruf
- Im Test-Profil gab es keine Konfiguration, die Exposed mit der Spring `DataSource` (Testcontainer) verbindet
- `@ActiveProfiles("test")` fehlte am Test → `TestExposedConfiguration` wurde nicht geladen
## Änderungen
| Datei | Änderung |
|------------------------------------------------------------|----------------------------------------------------------------------------|
| `gradle/libs.versions.toml` | `springdoc` von `3.0.0``2.8.9` (Spring Boot 3.x kompatibel) |
| `entries-service/src/test/.../TestExposedConfiguration.kt` | Neu: `@Profile("test")` Bean der Exposed mit Spring `DataSource` verbindet |
| `EntriesIsolationIntegrationTest.kt` | `@ActiveProfiles("test")` hinzugefügt; Import sortiert |
| `Backend_Roadmap.md` | Bugfix dokumentiert unter A-1 |
## Ergebnis
- Alle Tests im `entries-service` grün ✅ (`BUILD SUCCESSFUL`)
- `EntriesIsolationIntegrationTest` läuft vollständig durch
@@ -0,0 +1,63 @@
# 🧹 Curator Log — Frontend B-2/B-3: Repositories & Live-Validierung
> **Datum:** 3. April 2026
> **Agent:** 🎨 Frontend Expert
> **Sprint:** B — Bewerbe-Management & Startlisten
> **Aufgaben:** B-2 BewerbRepository + AbteilungRepository; Koin-Module; B-3 Live-Validierung
---
## ✅ Erledigte Aufgaben
### B-2 — Repositories & Koin-Module
| Datei | Aktion | Beschreibung |
|-----------------------------------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------|
| `core/network/src/commonMain/.../DomainErrors.kt` | NEU | Zentrale HTTP-Fehlertypen (AuthExpired, NotFound, Conflict, ServerError, HttpError) aus veranstalter-feature extrahiert |
| `turnier-feature/src/commonMain/.../dto/TurnierDto.kt` | NEU | DTOs für Turnier, Bewerb, Abteilung (kotlinx.serialization) |
| `turnier-feature/src/commonMain/.../mapper/TurnierMapper.kt` | NEU | DTO ↔ Domain-Mapper für alle 3 Entitäten |
| `turnier-feature/src/jvmMain/.../DefaultTurnierRepository.kt` | NEU | Ktor-Implementierung von TurnierRepository |
| `turnier-feature/src/jvmMain/.../DefaultBewerbRepository.kt` | NEU | Ktor-Implementierung von BewerbRepository (inkl. `ApiRoutes.Turniere.bewerbe()`) |
| `turnier-feature/src/jvmMain/.../DefaultAbteilungRepository.kt` | NEU | Ktor-Implementierung von AbteilungRepository (inkl. `ApiRoutes.Bewerbe.abteilungen()`) |
| `turnier-feature/src/jvmMain/.../di/TurnierFeatureModule.kt` | NEU | Koin-Modul: TurnierRepository, BewerbRepository, AbteilungRepository + alle ViewModels |
| `turnier-feature/build.gradle.kts` | GEÄNDERT | `core.network` + `ktor.client.core` als Dependency ergänzt |
| `veranstalter-feature/.../DefaultVeranstalterRepository.kt` | GEÄNDERT | Lokale Fehlertypen entfernt → Import aus `core.network.*` |
### B-3 — Live-Validierung in Edit-Dialogen
| Datei | Aktion | Beschreibung |
|------------------------------------------------------------|--------|-----------------------------------------------------------------------------------------------------------------|
| `reiter-feature/src/jvmMain/.../ReiterProfilEditDialog.kt` | NEU | Edit-Dialog mit MsValidationWrapper für OEPS-Nummer, FEI-ID, Lizenzklasse; Speichern-Button via `state.isValid` |
| `pferde-feature/src/jvmMain/.../PferdProfilEditDialog.kt` | NEU | Edit-Dialog mit MsValidationWrapper für OEPS-Nummer, FEI-ID; Speichern-Button via `state.isValid` |
---
## 📐 Architektur-Entscheidungen
- **DomainErrors zentral in `core.network`**: Verhindert Duplikation über Feature-Module hinweg.
- **`toMessages()`-Extension in Feature-Modulen**: `design-system` hat keine `core.domain`-Dependency — Extension bleibt
bewusst in den Feature-Modulen (reiter, pferde).
- **Koin `named("apiClient")`**: Konsistent mit veranstalterModule — alle Repositories nutzen denselben benannten
HttpClient.
- **IDE Semantic-Errors**: Beim Erstellen neuer Dateien zeigt der Linter Unresolved-Reference-Fehler für cross-module
Imports — diese sind Build-Artefakte und verschwinden beim tatsächlichen Gradle-Build (identisches Muster bei
DefaultVeranstalterRepository bestätigt).
---
## 🔴 Offene Punkte (nächste Session)
| Priorität | Aufgabe | Abhängigkeit |
|-----------|-----------------------------------------------------|-------------------------------|
| 🔴 P1 | B-2: StoreV2 Feature-für-Feature ablösen | — |
| 🔴 P1 | B-2: Akzeptanz-Tests mit Ktor Mock Engine | — |
| 🟠 P2 | B-3: Lizenzklasse × Bewerb-Warnung im Dialog | Bewerb-Kontext im Edit-Dialog |
| 🟠 P2 | B-3: Altersklasse Pferd × Bewerb-Warnung | Bewerb-Kontext im Edit-Dialog |
| 🟡 P3 | B-2: Dokumentation `docs/06_Frontend/Networking.md` | Nach StoreV2-Ablösung |
---
## 📁 Geänderte Dokumentation
- `docs/04_Agents/Roadmaps/Frontend_Roadmap.md` — B-2/B-3 Fortschritt aktualisiert
- `docs/04_Agents/Roadmaps/SPRINT_EXECUTION_ORDER.md` — Frontend-Zeile + Aufgabenliste aktualisiert
@@ -0,0 +1,68 @@
---
type: Session Log
date: 2026-04-03
agent: 🖌️ UI/UX Designer + 🧹 Curator
sprint: B (Abschluss)
status: COMPLETED
---
# Session Log — UI/UX Sprint B Abschluss: B-1 & B-4
## Zusammenfassung
Sprint B vollständig abgeschlossen. Zwei offene Punkte bearbeitet:
- **B-1:** Finale Entscheidung Editier-Formulare — Guideline von DRAFT auf APPROVED gesetzt, Screen-Mapping ergänzt.
- **B-4:** Empty States — vollständige Design-Spezifikation neu erstellt (Typen, Texte, Icons, Composable-API).
---
## Erledigte Aufgaben
### B-1 — Finale Entscheidung Editier-Formulare
- **Analyse:** Bestehendes Dokument `Editier-Formulare_Dialog-vs-Fullscreen_v1.md` war inhaltlich vollständig (DRAFT).
- **Review:** Frontend-Implementierungen (`ReiterProfilEditDialog`, `PferdProfilEditDialog`) bestätigen das
Side-Sheet-Muster — kein Widerspruch zur Richtlinie.
- **Entscheidung festgeschrieben:**
- ≤ 3 Felder, keine Async-Lookups → **AlertDialog**
- 38 Felder, Kontext relevant → **Side Sheet** (Desktop: rechts, ~420520 px)
- > 8 Felder oder starke Abhängigkeiten → **Fullscreen Edit**
- **Mapping aller Edit-Screens** auf die drei Varianten dokumentiert.
- **Hinweis:** `PferdProfilEditDialog` überschreitet die Grenze (810 Felder, Async-Lookups) → Migration zu Fullscreen
für C-1 vorgesehen.
- **Status:** APPROVED, verbindlich ab 2026-04-03.
### B-4 — Empty States für alle Listenansichten
- **Neu erstellt:** `docs/06_Frontend/Guidelines/Empty-States_Spezifikation_v1.md`
- **Inhalt:**
- 3 Empty-State-Typen definiert: `EMPTY_LIST`, `NO_RESULTS`, `ERROR`
- Visuelle Anatomie mit Maßen, Abständen, Typografie
- Icon-Konzept: Material Symbols Outlined (kein Custom-Illustration-Set für MVP)
- Texte (Titel, Beschreibung, CTA) für 10 Screens × 3 Typen
- Composable-API `MsEmptyState` vollständig spezifiziert
- Implementierungs-Reihenfolge für Sprint C-1 festgelegt
- Abgrenzung zu `MsLoadingIndicator`, `MsValidationWrapper`, `MsStatusBadge`
- **Status:** APPROVED.
---
## Geänderte Dateien
| Datei | Aktion | Beschreibung |
|----------------------------------------------------------------------------|--------------|------------------------------------------------------------------------------------------------|
| `docs/06_Frontend/Guidelines/Editier-Formulare_Dialog-vs-Fullscreen_v1.md` | Aktualisiert | Status DRAFT → APPROVED, Screen-Mapping + Freigabe-Abschnitt ergänzt |
| `docs/06_Frontend/Guidelines/Empty-States_Spezifikation_v1.md` | Neu erstellt | Vollständige Empty-State-Spezifikation (272 Zeilen) |
| `docs/04_Agents/Roadmaps/UIUX_Roadmap.md` | Aktualisiert | Sprint B als abgeschlossen markiert, C-1 erweitert, Abhängigkeiten + Empfehlungen aktualisiert |
---
## Übergabe an 🎨 Frontend Expert (Sprint C-1)
| Aufgabe | Grundlage | Priorität |
|----------------------------------------------------|----------------------------------------------------------|-----------|
| `MsEmptyState`-Composable implementieren | `Empty-States_Spezifikation_v1.md` § 6 | 🔴 Hoch |
| Empty States in 10 Listenansichten integrieren | `Empty-States_Spezifikation_v1.md` § 7 | 🔴 Hoch |
| `PferdProfilEditDialog` → Fullscreen migrieren | `Editier-Formulare_Dialog-vs-Fullscreen_v1.md` § Mapping | 🟠 Mittel |
| Verein/Funktionär/Bewerb/Turnier Edit → Side Sheet | `Editier-Formulare_Dialog-vs-Fullscreen_v1.md` § Mapping | 🟠 Mittel |