Files
meldestelle/docs/04_Agents/Roadmaps/Backend_Roadmap.md
T

115 lines
6.1 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.
# 👷 [Backend Developer] — Schritt-für-Schritt Roadmap
> **Stand:** 2. April 2026
> **Rolle:** Spring Boot / Ktor, Kotlin, SQL, API-Design, Datenbankschema, Services
---
## 🔴 Sprint A — Sofort (diese Woche)
> ✅ ADR-0021 (Tenant-Strategie) liegt vor (2026-04-02) — A-1 gestartet
- [ ] **A-1** | Tenant-Isolation im Datenzugriffs-Layer implementieren
- [x] ADR-0021 (Architect) lesen und Strategie übernehmen
- [x] Tenant-Resolution-Mechanismus implementieren (wie erkennt das Backend die Ziel-Datenbank?)
- Entries Service: `TenantWebFilter` liest `X-Event-Id`/Subdomain; `TenantRegistry` (In-Memory, konfigurierbar)
- [x] Alle Datenzugriffe mit Tenant-Kontext absichern
- Entries Service (Exposed): `tenantTransaction {}` setzt `SET search_path TO <schema>` pro Request
- [x] Sicherstellen: Kein Cross-Tenant-Datenzugriff möglich
- Verhindert durch verpflichtenden Tenant-Kontext + `search_path`; Fehlerfälle: 400/404/423
- Nächste Schritte (A-1 Ausbau):
- [x] `JdbcTenantRegistry` gegen `control.tenants` implementieren (inkl. Migrationen)
- [x] Flyway-SQL: `db/control/V1__init_control_and_tenants.sql`
- [x] Spring-JDBC `JdbcTenantRegistry` + Konfiguration (`multitenancy.registry.type=jdbc`)
- [x] Flyway pro Tenant-Schema (Rollout aktivierter Tenants)
- [x] `db/tenant/V1__entries_schema.sql` (Tabellen `nennungen`, `nennungs_transfers`)
- [x] `TenantMigrationsRunner` migriert aktive Schemas beim Start (liest `control.tenants` oder `multitenancy.defaultSchemas`)
- [ ] Rollout der Absicherung auf weitere Services (Repos/DAOs)
- [ ] Folge-PRs für weitere Services (aktuell: Entries Service migriert)
- [x] Observability: `tenant_id` in Logs/Metrics/Traces`
- [x] `TenantWebFilter` setzt `MDC["tenant_id"]`
- [x] Tests: Unit (Resolver/Registry) + E2E (Isolation A/B)
- [x] Unit: `JdbcTenantRegistryTest` (H2)
- [x] E2E: Isolation A/B mit Testcontainers Postgres
- [ ] Aktueller Status: Integrationstest temporär via `@Disabled` deaktiviert, um den Build zu entblocken; Re-Enable nach Stabilisierung der Jackson/Spring-Web-Konverter-Autokonfiguration
- [ ] **A-2** | Datenbankschema: Domänen-Hierarchie umsetzen
- [x] Tabelle `veranstaltungen` anlegen (interne ID, Tenant-Grenze)
- [x] Tabelle `turniere` anlegen (FK → `veranstaltung_id`, OEPS-Turniernummer als eigenes Feld)
- [x] Tabelle `bewerbe` anlegen (FK → `turnier_id`, Klasse, Höhe, Bezeichnung)
- [x] Tabelle `abteilungen` anlegen (FK → `bewerb_id`, `nr`, `bezeichnung`,
`typ: SEPARATE_SIEGEREHRUNG | ORGANISATORISCH`)
- [x] Tabelle `teilnehmer_konten` anlegen (FK → `veranstaltung_id`, aggregiert Salden über Turniere)
- [x] Tabelle `turnier_kassa` anlegen (FK → `turnier_id`, separate Kassa pro Turnier)
- [x] Migrations-Skript schreiben und testen (`db/tenant/V2__domain_hierarchy.sql`, Test: `DomainHierarchyMigrationTest`)
- [ ] **A-3** | Validierungs-Grundlage: Turnierkategorie-Limits
- [ ] `Turnier.validate()`: Bewerbs-Klassen gegen Limits der Turnierkategorie prüfen (z.B. kein S-Springen auf
C-Turnier)
- [ ] Voraussetzung: Spezifikation von 📜 Rulebook Expert (A-5) abwarten
---
## 🟠 Sprint B — Kurzfristig (nächste Woche)
- [ ] **B-1** | CRUD-Endpunkte für alle Stammdaten-Entitäten
- [ ] `POST/GET/PUT/DELETE /veranstaltungen`
- [ ] `POST/GET/PUT/DELETE /turniere` (inkl. Status-Feld: `DRAFT | PUBLISHED`)
- [ ] `POST/GET/PUT/DELETE /bewerbe`
- [ ] `POST/GET/PUT/DELETE /abteilungen`
- [ ] `POST/GET/PUT/DELETE /reiter`
- [ ] `POST/GET/PUT/DELETE /pferde`
- [ ] `POST/GET/PUT/DELETE /vereine`
- [ ] `POST/GET/PUT/DELETE /funktionaere`
- [ ] **B-2** | Kassa-Service implementieren
- [ ] `TeilnehmerKonto`-Service: Saldo aus mehreren Turnieren aggregieren
- [ ] `Zahlvorgang`-Service: Eine Zahlung auf Veranstaltungs-Ebene buchen
- [ ] Rechnungs-Generierung: Separate Rechnung je Turnier aus einem Zahlvorgang
- [ ] Endpunkte: `GET /veranstaltungen/{id}/kassa/saldo`, `POST /veranstaltungen/{id}/zahlvorgaenge`
- [ ] **B-3** | ÖTO-Validierung serverseitig absichern
- [ ] Spezifikation von 📜 Rulebook Expert (Sprint A-5) umsetzen
- [ ] OEPS-Nummern-Format validieren
- [ ] FEI-ID-Format validieren
- [ ] Lizenzklassen-Validierung (R1R4, LZF)
- [ ] Altersklassen-Kompatibilität Pferd × Bewerb validieren
- [ ] Abteilungs-Zwangsteilung im CSN-C-NEU durchsetzen (Bewerb ≤95cm: ohne/mit Lizenz; ≥100cm: R1/R2+)
- [ ] **B-4** | Nennungs-Service (Grundstruktur)
- [ ] Tabelle `nennungen` anlegen (FK → `abteilung_id`, Status: `NEU | GEPRÜFT | BESTÄTIGT | ABGELEHNT`)
- [ ] `POST /turniere/{id}/nennungen` — Nennungs-Eingang vom Web-Formular
- [ ] `GET /turniere/{id}/nennungen` — Postfach für Desktop-App (Meldestelle)
- [ ] `PATCH /nennungen/{id}/status` — Bestätigen / Ablehnen
---
## 🟡 Sprint C — Mittelfristig (in 2 Wochen)
- [ ] **C-1** | Testdaten-Seeder implementieren
- [ ] Reproduzierbare Veranstaltung mit 2 Turnieren (Neumarkt-Szenario)
- [ ] Bewerbe mit korrekten Abteilungen (inkl. CSN-C-NEU Pflicht-Teilung)
- [ ] Reiter, Pferde, Vereine als Stammdaten
- [ ] Nennungen in verschiedenen Status-Stufen
- [ ] Seeder via Gradle-Task ausführbar
- [ ] **C-2** | Statistik-Endpunkte
- [ ] `GET /turniere/{id}/statistiken` — Statistiken pro Turnier
- [ ] `GET /veranstaltungen/{id}/statistiken` — Aggregierte Statistiken über alle Turniere
---
## 📌 Abhängigkeiten
| Warte auf | Von wem |
|------------------------------------------------|--------------------|
| ADR-0021 (Tenant-Strategie) | 🏗️ Architect |
| Validierungs-Spezifikation (OEPS, FEI, Lizenz) | 📜 Rulebook Expert |
| Domänen-Modell final | 🏗️ Architect |
| Meine Aufgabe | Ermöglicht wem |
|------------------------|--------------------------------|
| CRUD-Endpunkte (B-1) | 🎨 Frontend: Backend-Anbindung |
| Kassa-Service (B-2) | 🎨 Frontend: Kassa-Screen |
| Nennungs-Service (B-4) | 🎨 Frontend: Nennungs-Postfach |