API-Vertrag auf snake_case umstellen (ADR 0036) #126
Labels
No labels
Kind
Bug
Kind
Enhancement
Kind
Maintenance
Priority
P1
Priority
P2
Priority
P3
Status
In Progress
Status
Need More Info
Status
Zur Abnahme
Änderungen Wettspielreglement
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sffs-tt-basel/sffs-tt-issues#126
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Entschieden am 22.10.2026, siehe
docs/adr/0036-feldnamen-in-snake-case.md.Ziel
JSON-Feldnamen und Query-Parameter stehen auf der Leitung in snake_case (Zalando-Regeln 118 und 130):
phase_datesstattphaseDates,?season_id=statt?seasonId=./phase-dates), das verlangt Zalando-Regel 129 so.REGISTRATION_OPEN).Für den Nutzer ändert sich nichts Sichtbares. Die Abnahme ist darum technisch.
Umfang
quarkus.jackson.property-naming-strategy=SNAKE_CASEfür die Antworten und Anfragen.mp.openapi.extensions.smallrye.property-naming-strategyfür das Schema. Ohne sie bliebeopenapi.jsonin camelCase, und die generierten Typen würden nicht mehr stimmen.categoryId,seasonId,validFrom→category_id,season_id,valid_from(im@QueryParamund bei allen Aufrufern).body("phaseDates…"), Maps).openapi.jsonneu mitmvn -B clean verify, danach die Typen neu erzeugen. In portal, content und shared meldettscjeden Zugriff auf ein umbenanntes Feld. Für die Homepage prüfen, wie weitastro checkreicht.apiGet<{ phaseDates: … }>), und die Anfragekörper.{ phase: target, date: … }im PhaseDialog.scripts/, die die API aufrufen: unter anderemmatchblatt-import.py,import-ttvp-termine.py,import-doppel-handicap.py,seed-saison-2025-2026.sh,import-ttvp-*.sh,e2e-run.sh,preview-baseline.sh,staging-restore-prod.sh..claude/skills/matchblaetter,verify,project-review/metrics.py(liestopenapi.json).localStorage.authhält dieLoginResponse, darinclubId. Nach dem Deploy liest der Codeclub_id, und Vereinsverantwortliche, die noch angemeldet sind, sähen ihren Verein nicht mehr.getStoredAuthinpackages/shared/src/auth.tsxverwirft darum die alte Form und erzwingt ein neues Login, so wie schon beim Umbau vonroleaufroles.Nicht betroffen:
Hinweis zum Zeitpunkt
Der Umbau berührt fast jede Frontend-Datei. Er sollte darum laufen, wenn kein anderer Branch Frontend-Code offen hat. Sonst gibt es Konflikte in jeder Datei.
Abnahme
mvn -B clean verify, die drei Frontend-Builds, E2E undmetrics.py diffsind grün.openapi.jsonsteht kein Feldname mehr mit Grossbuchstaben (grep -E '"[a-z]+[A-Z]').matchblatt-import.pyläuft einmal gegen Staging.Ergänzung zu Punkt 3 (Backend-Tests), aus der Analyse der unbekannten Felder vom 23.10.2026.
Anfragekörper als Records statt als Text
Die Backend-Tests schicken ihre Anfragekörper heute fast immer als handgeschriebenes JSON:
.body("{\"vorname\": …}")String.formatMap.ofnew CreatePlayerRequest(…)Die ersten drei Arten müssen mit der Umstellung auf snake_case ohnehin angefasst werden, weil jeder Feldname darin camelCase ist. Dabei werden sie zu Request-Records. Dann übersetzt die zentrale Einstellung die Namen auch in den Tests, und ein Feld, das der Vertrag nicht kennt, lässt schon der Compiler nicht durch.
Vorher prüfen: Nimmt RestAssured in den
@QuarkusTest-Klassen denselben ObjectMapper wie Quarkus? Sonst schicken die Records nach der Umstellung weiter camelCase. Die Gegenprobe ist ein Test, der einen Record mit einem zweiwortigen Feld schickt und dessen Wert in der Antwort wiederfindet.Die strenge Einstellung hilft beim Umbau
Seit
feature/unbekannte-felderstehtquarkus.jackson.fail-on-unknown-properties=true. Ein Feld, das der Vertrag nicht kennt, gibt 400. Für diesen Umbau heisst das: Ein Anfragekörper, der nach der Umstellung nochseasonIdstattseason_idschickt, fällt in Tests, E2E und Skripten als 400 auf, statt dass der Wert stillschweigend nicht ankommt. Für die Antworten gilt das nicht, dort bleibt es beitscund der Durchsicht unter Punkt 5.Gesichert aus
logs/endpunkte/werte.md(von Git ignoriert, lag nur auf der Devbox). Ollis Entscheide vom 23.10. zu Aufzählungswerten und Feldnamen, die mit diesem Issue englisch werden. Bis dahin gilt im URL-Umbau: vorhandene Werte bleiben, neue Werte ohne Vorbild sind gleich englisch (Plan Etappe 2, ADR 0038 Abschnitt „Etappe 2“).Aufzählungswerte auf der Leitung (Olli 23.10.)
Englisch im selben Zug wie snake_case (#126): Java-Konstante, Leitung, gespeicherter Wert per Migration.
Bleiben: Halbserie VORRUNDE RUECKRUNDE, CMS-Bereich BASLER SCHWEIZER TURNIER KURS.
OPENnur noch fuer "nicht fixiert" (Spielplan- und Spielwochen-Status, Gegenstueck FINALIZED).Nur intern, nicht auf der Leitung: MatchSide HEIM GAST BEIDE, Side A B UNENTSCHIEDEN.
scope (users/self/tasks, users/self/team-matches): OWN_TEAMS CLUB ALL (nicht VERBAND).
Feldnamen (Olli 23.10.)
Englisch im selben Zug wie snake_case (#126):
Bleiben (Regel 5, in CLAUDE.md ergaenzt): Person/Kontakt/Adresse inkl. natel, telefon_geschaeftlich, email_geschaeftlich, hausnummer, venue_hausnummer, captain_vorname/-nachname; CMS inkl. datum_bis; Fachbegriffe klassierung…, halbserie, spielleiter, sektionsleiter, saison….