feat(Calendar): integrate CalendarEvent model and enhance calendar functionality
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 43s

- Added CalendarEvent model to the backend, establishing relationships with the Club model for better event management.
- Updated server.js to include calendarEventRoutes, enabling API access for calendar events.
- Enhanced CalendarView.vue to support custom event creation and management, improving user interaction with the calendar.
- Refactored various components to streamline event handling and improve overall user experience in the calendar interface.
- Updated TODO and DEVELOPMENT documentation to reflect new calendar features and architectural decisions.
This commit is contained in:
Torsten Schulz (local)
2026-05-13 10:21:30 +02:00
parent 9be5f50ede
commit 004801b1a6
33 changed files with 2715 additions and 632 deletions

View File

@@ -26,12 +26,12 @@ Dieses Dokument ist die **Arbeitsliste**, um die **funktionale Abdeckung der Web
## Phase 0 Architektur & Grundlagen für Vollausbau
- [ ] **Navigation:** Zentraler Nav-Graph (z. B. Navigation Compose) mit Back-Stack pro Tab oder einheitlichem Stack; Tiefe: Club → Modul → Unterseiten
- [ ] **Feature-Paketierung:** UI/API pro Bereich trennen (`diary`, `members`, `schedule`, …), Composables entschlacken
- [ ] **Use-Cases:** Geschäftslogik aus Composables in testbare Funktionen/Klassen im `shared`
- [x] **Navigation:** Single-Activity-Modell mit `MainTab` + zustandsbasierter Tiefe (Tagebuch-Tag, Mitglieder-Details, Einstellungen-Unterseiten); Rail/Bottom-Nav; **kein** zentraler Navigation-Compose-`NavHost` für die Shell (bewusste Entscheidung, später migrierbar) siehe `DEVELOPMENT.md` § Architektur Phase 0, Umsetzung `AppRoot.kt`
- [x] **Feature-Paketierung:** Richtlinie und Ist: APIs/DTOs/Manager im `shared`, UI in `composeApp/.../ui/` mit featurebezogenen Dateien; schrittweise Entschlackung großer Dateien `DEVELOPMENT.md` § Architektur Phase 0
- [x] **Use-Cases:** Geschäftslogik überwiegend in `shared/state/*Manager` und gezielt in plattformnahen Helfern (`CalendarAggregator` o. ä.); Composables orchestrieren `DEVELOPMENT.md` § Architektur Phase 0
- [x] **Fehlerbild (Basis):** JSON-Fehlerbody (`error` / `message`) aus API-Antworten → [ApiException]-Text (`ApiErrorMessage.kt`, authed + public Client); bekannte Tokens (`alreadyexists`, …) → Deutsch; Retries bewusst noch offen
- [ ] **Echtzeit (optional):** Socket-Events wie Web (`socketService`) oder dokumentiertes Polling nach Schreiboperationen
- [ ] **Medien:** Entscheidung Bilder/PDF (Coil, Cache, Download, Intents)
- [x] **Echtzeit (optional):** v1 ohne Web-Socket; Aktualisierung über `LaunchedEffect` / manuelles Neuladen dokumentiert; optional Socket/Polling später `DEVELOPMENT.md` § Architektur Phase 0
- [x] **Medien:** Coil für Bilder, FileProvider + Share-Intents für PDF; dokumentiert in `DEVELOPMENT.md` § Architektur Phase 0
- [x] **Öffentlicher HTTP-Client** ohne Auth-Header (`PublicHttpClient`, `PublicAuthApi` im `shared`)
---
@@ -199,15 +199,24 @@ Web: `DiaryView.vue` (sehr groß). API-Cluster (Auszug in Web nach `apiClien
Web-Route: `/calendar` · Referenz: `CalendarView.vue` (Aggregation mehrerer Datenquellen in einer Monatsansicht).
- [ ] **Navigation & Shell:** Tab oder Hub-Eintrag (Berechtigungen klären), Monat vor/zurück, „Heute“, Monatsüberschrift
- [ ] **Monatsgitter:** 7×6 wie Web, Kennzeichnung „außerhalb Monat / heute, Wochentagskopf
- [ ] **Legende / Filter:** Eventtypen einblendbar (Training, Turnier, Teilnahme offiziell, Punktspiel, Feiertag, Ferien, Trainingsausfall) inkl. Zähler
- [ ] **Daten laden (parallel, teilfehlertolerant):** gleiche Quellen wie Web u. a. Tagebuch-Trainingstage, `GET /api/training-times/:clubId`, Trainingsausfälle, Vereins-Turniere, offizielle Teilnahmen, Punktspiele (`MatchesApi`/League-Endpoints), Feiertage/Ferien (Kalenderregion Verein); Fehler pro Quelle wie `sourceWarnings` optional anzeigen
- [ ] **Logik:** wiederkehrende Trainingszeiten expandieren, Zusammenführen von Slots (`mergeRecurringTrainingSlots`), Ausfälle blenden wiederkehrende Slots aus Verhalten an Web angleichen
- [ ] **Trainingsausfall:** Formular (Datum, optional Bis, Grund), Liste im Monat, Speichern/Löschen API wie Web (`CalendarView` / Backend-Routen zu `training_cancellations` verifizieren)
- [ ] **Agenda:** sortierte Liste „Termine im Monat“ unter dem Grid
- [ ] **Event-Aktion:** Klick → sinnvolle Ziel-Navigation (Tagebuch-Tag, Turnier-Detail, Spiel-Detail, externer Link o. ä.) wie `openEvent` im Web
- [ ] **i18n:** Texte über `MobileStrings` / Keys abstimmen mit Web-`$t` wo sinnvoll
- [x] **Navigation & Shell:** Haupt-Tab `MainTab.Calendar` + Start-Hub-Kachel (`AppRoot.kt`), Monat vor/zurück, „Heute“, Monatsüberschrift (`CalendarScreen.kt`)
- [x] **Monatsgitter:** 7×6, außerhalb Monat / heute, Wochentagskopf (`CalendarScreen.kt`, `CalendarAggregator.kt`)
- [x] **Legende / Filter:** Eventtypen mit Schalter und Zähler (`CalendarScreen.kt`)
- [x] **Daten laden (parallel, teilfehlertolerant):** `supervisorScope` + `async` in `CalendarScreen.kt`; Quellen: `DiaryManager.listDates`, Trainingszeiten, `TrainingCancellationApi`, `TournamentsApi`, `MatchesApi`, `OfficialTournamentsReadManager`, `CalendarHolidayApi` (`CalendarDtos.kt`, APIs in `shared`)
- [x] **Logik:** `CalendarAggregator.kt` (wiederkehrende Zeiten, Merge, Ausfälle) an Web angelehnt
- [x] **Trainingsausfall:** Formular + Liste im Monat + API (`TrainingCancellationApi`, `CalendarScreen.kt`)
- [x] **Agenda:** sortierte Monatsliste (`CalendarAggregator.eventsInMonth`, `CalendarScreen.kt`)
- [x] **Event-Aktion:** `CalendarEventAction` → Tagebuch-Tag/Tab, Terminplan, Turniere, Web `/tournament-participations` (`calendar/CalendarAggregator.kt` / `CalendarScreen.kt`, Verdrahtung `AppRoot.kt`)
- [x] **i18n:** `MobileStrings`-Keys mit Fallback in `CalendarScreen.kt` / `AppRoot.kt` (`navigation.calendar`, `home.tileCalendar`, `mobile.calendar*`)
- [x] **Web-Parität (Detail):** Meldung wenn **alle** Kalender-Quellen fehlschlagen; Legenden-Zähler aus **allen** Events (unabhängig von den Schaltern); Agenda-Datum **kurz/lokalisiert**; Ausfall-Liste nur wenn **Startdatum im Monat** liegt (wie `CalendarView.vue`) `CalendarScreen.kt`
### Phase 12 Backlog / offen
- [ ] **iOS:** Kalender-UI + Tab (derzeit nur Android `composeApp` / `MainTab.Calendar`)
- [ ] **i18n:** Kalender-Keys in `MobileStrings.kt` für alle unterstützten Sprachen ergänzen (nicht nur Fallback im Code)
- [ ] **Kalender vs. Web:** Offizielle Teilnahmen mobil per Browser vs. Web in-app bewusst lassen oder später angleichen
- [ ] **Release:** Bei `isMinifyEnabled = true` ProGuard/R8 für Ktor, `kotlinx.serialization`, ggf. Koin (`composeApp/proguard-rules.pro`)
- [x] **Turniere (Produktiv-Crash):** `LazyColumn` mit eindeutigen Keys (`itemsIndexed` für Vereins-Turniere, offizielle Liste, Teilnahmen-Zeilen), vermeidet Duplicate-Key-Abstürze; zudem tolerante Deserialisierung für `allowsExternal` / `isDoublesTournament` (0/1, Strings) `TournamentsScreen.kt`, `FlexibleBooleanSerializers.kt`, `TournamentDtos.kt`
---