All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 49s
- Added controllers for handling friendly match invitations and shared matches. - Created migration scripts for `friendly_match_invitation` and `friendly_match_shared` tables. - Developed models for `FriendlyMatchInvitation` and `FriendlyMatchShared`. - Established routes for managing invitations and shared matches. - Implemented services for business logic related to invitations and shared matches. - Documented the concept plan for the new feature including API endpoints and data models.
6.4 KiB
6.4 KiB
Konzeptplan: Vereinsuebergreifende Freundschaftsspiele
Ziel
- Ein gemeinsames Freundschaftsspiel-Objekt fuer zwei Vereine (statt zwei isolierter Eintraege).
- Auffindbarkeit bestehender Spiele ueber Name, Datum und Startzeit.
- Einladungsprozess (anbieten, annehmen, ablehnen).
- Live-Synchronisierung zwischen beiden Vereinen per Socket.
Produktumfang (MVP)
- Vereinsuebergreifendes Shared-Match-Datenmodell einfuehren.
- Match-Finder fuer Name, Datum, Startzeit implementieren.
- Einladung erstellen (Zielverein aus Vereinsliste + Freitext).
- Einladung im System speichern.
- E-Mail-Benachrichtigung an hinterlegte Personen des Zielvereins versenden.
- Einladung annehmen: Shared-Match fuer beide Vereine erstellen.
- Einladung ablehnen: Einladung loeschen.
- Socket-Sync fuer beide Vereine bei Aenderungen am Shared-Match.
Datenmodell
Neue Tabellen
friendly_match_sharedidhome_club_idguest_club_iddatestart_timematch_name(oder Home/Gast-Namenstruktur)location_*Feldermatch_system,singles_count,doubles_count,winning_setshome_participants,guest_participantsresult_details,home_match_points,guest_match_pointsis_completedcreated_by_user_idcreated_from_invitation_idcreated_at,updated_at
friendly_match_invitationidfrom_club_idto_club_idproposed_dateproposed_start_timeproposed_match_namemessage(Freitext)status(pending,accepted)created_by_user_idcreated_at,updated_at
Indizes und Constraints
- Index auf
friendly_match_shared (home_club_id, date, start_time). - Index auf
friendly_match_shared (guest_club_id, date, start_time). - Index auf
friendly_match_invitation (to_club_id, status, proposed_date). - Verhindern, dass ein Verein sich selbst einlaedt (
from_club_id != to_club_id).
Backend API
Finder
GET /api/friendly-matches/find- Query-Parameter:
clubId,name,date,startTime. - Exakt-Matches und Kandidaten mit
confidencezurueckgeben.
- Query-Parameter:
Einladungen
POST /api/friendly-match-invitations/:clubId- Payload:
toClubId,date,startTime,matchName,message.
- Payload:
GET /api/friendly-match-invitations/:clubId/incomingGET /api/friendly-match-invitations/:clubId/outgoingPOST /api/friendly-match-invitations/:clubId/:invitationId/acceptPOST /api/friendly-match-invitations/:clubId/:invitationId/decline
Shared Matches
GET /api/friendly-matches/shared/:clubIdPUT /api/friendly-matches/shared/:clubId/:matchIdPATCH /api/friendly-matches/shared/:clubId/:matchId/players- Optional:
DELETE /api/friendly-matches/shared/:clubId/:matchId
Rechte und Zugriff
- Zugriff pruefen: User muss in beteiligtem Verein freigeschaltet sein.
- Schreibrechte auf Shared-Match nur mit
schedule.write. - Einladung annehmen/ablehnen nur fuer
to_club_id.
E-Mail-Versand
- Empfaengerermittlung:
user_club(approved=true) +user.emailfuer Zielverein. - Neue Mailfunktion in
emailServicefuer Einladung. - Inhalt: einladender Verein, Matchdaten, Freitext, Aktion (annehmen/ablehnen in App).
- Fehlerbehandlung: Einladung bleibt erhalten, falls Mailversand fehlschlaegt (mit Log).
Matching-Logik (Name/Datum/Startzeit)
- Normalisierung von Namen (trim, lowercase, Sonderzeichenbereinigung).
- Datum exakt matchen.
- Startzeit exakt matchen (MVP).
- Teamnamen in beide Richtungen pruefen (home/guest vertauscht).
confidence-Stufen definieren (exact,high,medium).
Socket-Sync
- Neue Socket-Events definieren:
friendly:invitation:createdfriendly:invitation:acceptedfriendly:invitation:declinedfriendly:shared:match:updatedfriendly:shared:match:deleted
- Bei Shared-Match-Aenderung an beide Club-Raeume senden (
club-<home>,club-<guest>). - Frontend und Mobile auf neue Events subscriben.
Frontend (Web)
- Bereich "Einladungen" (Eingehend/Ausgehend) in Freundschaftsspielen.
- Dialog "Verein einladen": Zielverein aus bestehender Vereinsliste + Freitext.
- Buttons fuer annehmen/ablehnen in eingehenden Einladungen.
- Finder-UI fuer Name/Datum/Startzeit.
- Shared-Match-Kennzeichnung in Liste und Detaildialog.
- Socket-Event-Handling fuer Echtzeitupdates beider Vereine.
Mobile (Android + Shared)
- API-Endpoints in
MatchesApierweitern. - State-Manager fuer Einladungen und Shared-Matches erweitern.
- UI fuer Einladungen (eingehend/ausgehend) einbauen.
- Finder-UI fuer Name/Datum/Startzeit einbauen.
- Shared-Match-Bearbeitung fuer beide Vereine synchronisieren.
- Socket-Events fuer Friendly-Shared-Flow verarbeiten.
Migration und Abwaertskompatibilitaet
- Bestehende
friendly_match-Eintraege unveraendert weiter lesbar halten. - Schrittweise Migration/Koexistenzstrategie dokumentieren.
- Optionales Mapping alter Einzel-Eintraege auf Shared-Matches definieren.
Tests
Backend
- Unit-Tests fuer Match-Finder.
- Unit-Tests fuer Einladung (create/accept/decline).
- Integrations-Tests fuer Shared-Match-CRUD.
- Berechtigungstests (falscher Verein, fehlende Rechte).
Frontend/Mobile
- UI-Tests fuer Einladung erstellen/anzeigen/entscheiden.
- UI-Tests fuer Finder.
- Realtime-Tests mit zwei gleichzeitig eingeloggten Vereinen.
End-to-End
- Verein A laedt Verein B ein.
- E-Mail wird versendet.
- Verein B nimmt an, Shared-Match entsteht.
- Aenderung in Verein A erscheint sofort in Verein B und umgekehrt.
- Ablehnung loescht Einladung vollstaendig.
Rollout in Phasen
- Phase 1: Datenmodell + Read-APIs.
- Phase 2: Einladung + E-Mail.
- Phase 3: Accept/Decline + Shared-Match-Erzeugung.
- Phase 4: Shared-Match-Edit + Socket-Sync.
- Phase 5: Finder + UX-Polish + E2E-Hardening.
Offene Entscheidungen
- Mehrfache parallele Einladungen fuer gleiche Daten erlauben oder verhindern?
- Match-Name als einzelnes Feld oder Home/Gast getrennt fuehren?
- Konfliktstrategie bei gleichzeitiger Bearbeitung (Last-Write-Wins vs. Versionierung)?
- Ablehnung immer hard delete oder auditierbar speichern?