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

@@ -1,5 +1,47 @@
# Development
## Architektur Phase 0 (abgeschlossen)
Die folgenden Punkte entsprechen **Phase 0** in `TODO.md`: festgelegte Entscheidungen und **Ist-Zustand** der Codebasis, ohne dass die App komplett neu strukturiert wird.
### Navigation
- **Single Activity**, Haupt-UI in `AppRoot.kt`: eingeloggt → `MainTabs` mit **`MainTab`** (Start, Tagebuch, Mitglieder, …).
- **Breit / schmal:** ab ca. 600dp `MainNavigationRail`, sonst `BottomNavigation` (siehe `MAIN_NAV_RAIL_MIN_WIDTH_DP`).
- **Unter-Navigation / Tiefe:** kein zentraler **Navigation-Compose**-`NavHost` für die Shell; stattdessen **expliziter Zustand** (`rememberSaveable` / `remember`), z.B. `diarySelectedEntryId`, `membersNestedOpen`, `billingOrdersSection`. **Zurück** über `BackHandler` und Tab-Wechsel, der Detailzustand zurücksetzt (`selectMainTab`).
- **Auth:** eigener Flow (`AuthFlowHost`) vor Club-Auswahl ebenfalls ohne separates Nav-Graph-Modul.
- **Begründung (kein zentraler NavHost):** geringere Migrationskosten, vorhandenes Verhalten beibehalten. Ein späterer Umstieg auf `NavHost` (z.B. pro Tab oder für Deep Links) ist möglich.
- **Start-Hub (`HomeScreen`):** Nur **Willkommen** + Vereinsinfos (Karte); keine Navigations-Kacheln mehr (vermeidet leere Abschnitte und Doppelung mit der Rail).
- **Navigation Rail (Tablet / breit):** Drei **aufklappbare Blöcke** wie die Web-Sidebar **Tagesgeschäft**, **Wettbewerb**, **Einstellungen** mit allen Einträgen inkl. Freigaben, Turnierteilnahmen (Browser), Vereinseinstellungen, Vordefinierte Aktivitäten, Team (Browser), Abrechnung, Bestellungen; oben **Start**, unten **Mehr**. Zustand der Aufklappung per `rememberSaveable`.
- **Smartphone:** Weiterhin **untere Tab-Leiste** (`visibleMainTabs`) + vollständige Einstellungen unter **Mehr**; Kurzhinweis auf der Startseite.
- **Tab-Sichtbarkeit:** Entspricht grob den Web-`v-if`-Bedingungen (`visibleMainTabs` in `AppRoot.kt`, u.a. Kalender nur bei Tagebuch-, Terminplan- oder Turnier-Leserecht).
### Feature-Paketierung (Richtlinie + Ist)
- **`shared`:** HTTP-APIs (`shared/.../api`), DTOs (`api/models`), zustandsführende **Manager** (`shared/.../state`), i18n.
- **`composeApp`:** Android-UI unter `composeApp/.../ui/` mit **dateiweise** Feature-Namen (`Diary*`, `Members*`, `Schedule*`, `CalendarScreen`, …) sowie `AppRoot.kt`, `AppDependencies.kt`.
- **Zielbild:** Neue Features als eigene Dateien/ Unterpakete `ui/<bereich>/` anlegen; keine weiteren riesigen Monolithen neben `AppRoot` anhäufen, sondern schrittweise auslagern (laufende Arbeit).
### Use-Cases / Geschäftslogik
- **Primär `shared`:** `*Manager`-Klassen kapseln API + Caching/Flow (z.B. `DiaryManager`, `ClubManager`).
- **Plattformnah Android:** reine UI-Hilfen oder `java.time`-lastige Aggregation bleiben in `composeApp` (z.B. `calendar/CalendarAggregator.kt`), angebunden über `AppDependencies`.
- **Composables:** möglichst nur Zustand, `LaunchedEffect`, Aufrufe in Manager/APIs; komplexe Ableitungen in wiederverwendbaren Funktionen/Klassen statt inline riesiger Blöcke.
### Echtzeit (optional / Web-Parität)
- **Web** nutzt u.a. Socket-Updates; **Android v1:** bewusst **ohne** parallelen Socket-Client.
- **Aktualisierung:** `LaunchedEffect` bei Screen-Fokus / `clubId` / relevanten Keys, nach Schreiboperationen (`dataGeneration++` o. ä.) oder Tabwechsel. **Polling** nur dort, wo bereits im Code nachvollziehbar (kein globales Intervall-Polling).
- **Später:** optional `socket.io`-Client im `shared` (Dependency existiert bereits) anbinden oder dokumentiertes Polling siehe `TODO.md` Backlog.
### Medien (Bilder / PDF)
- **Bilder:** **Coil** (`coil-compose`), authentifizierte Requests wo nötig (`diaryAuthHeaders` / `AuthenticatedAsyncImage`).
- **PDF / Teilen:** Generierung im App-Code, Ausgabe über **FileProvider** und System-**Intent** (`sharePdfFile` u.a. im Tagebuch-Flow).
- **Cache:** Standard Coil-/Systemverhalten; kein separates Offline-Framework in Phase 0.
---
## Backend-URL
**Standard:** `https://tt-tagebuch.de` gesetzt in `gradle.properties` (`backendBaseUrl=…`) und als Fallback in `composeApp/build.gradle.kts`.