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

6.0 KiB
Raw Blame History

👷 [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

    • ADR-0021 (Architect) lesen und Strategie übernehmen
    • Tenant-Resolution-Mechanismus implementieren (wie erkennt das Backend die Ziel-Datenbank?)
      • Entries Service: TenantWebFilter liest X-Event-Id/Subdomain; TenantRegistry (In-Memory, konfigurierbar)
    • Alle Datenzugriffe mit Tenant-Kontext absichern
      • Entries Service (Exposed): tenantTransaction {} setzt SET search_path TO <schema> pro Request
    • 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):
      • JdbcTenantRegistry gegen control.tenants implementieren (inkl. Migrationen)
        • Flyway-SQL: db/control/V1__init_control_and_tenants.sql
        • Spring-JDBC JdbcTenantRegistry + Konfiguration (multitenancy.registry.type=jdbc)
      • Flyway pro Tenant-Schema (Rollout aktivierter Tenants)
        • db/tenant/V1__entries_schema.sql (Tabellen nennungen, nennungs_transfers)
        • 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)
      • Observability: tenant_id in Logs/Metrics/Traces`
        • TenantWebFilter setzt MDC["tenant_id"]
      • Tests: Unit (Resolver/Registry) + E2E (Isolation A/B)
        • Unit: JdbcTenantRegistryTest (H2)
        • 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

    • Tabelle veranstaltungen anlegen (interne ID, Tenant-Grenze)
    • Tabelle turniere anlegen (FK → veranstaltung_id, OEPS-Turniernummer als eigenes Feld)
    • Tabelle bewerbe anlegen (FK → turnier_id, Klasse, Höhe, Bezeichnung)
    • Tabelle abteilungen anlegen (FK → bewerb_id, nr, bezeichnung, typ: SEPARATE_SIEGEREHRUNG | ORGANISATORISCH)
    • Tabelle teilnehmer_konten anlegen (FK → veranstaltung_id, aggregiert Salden über Turniere)
    • Tabelle turnier_kassa anlegen (FK → turnier_id, separate Kassa pro Turnier)
    • Migrations-Skript schreiben und testen
  • 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