# 2026-08-22

- TODOs vom KSB-Gespräch (2026-08-21) abgearbeitet:

  - Fallback-E-Mail: Zahlungsinfo ohne Kurszuordnung greift nicht mehr global; neutrale
    System-Fallback-Vorschau + klarere Hilfe unter `/admin/event-center/email-templates/`.
  - Workshops getrennt: Workshop-Gruppen außerhalb des Menüs als eigene Cards in
    Event-Center Step 1 (`workshopGroup`, Deep-Link `?group=`).
  - Alte Kurse: Filter in Kursbuchungen nur aktive Kurse ohne abgelaufenes `endDate`.
  - Warteliste Nachrutschen: BZ-Umwandlung → `pending` + confirmation-Mail; Schwimmen
    „In Termin umwandeln“ legt Termin an + Validierungs-Mail.
  - Wartelisten-Layout BZ an Schwimmen angeglichen (Stats, Suche, Detail-Modal, Löschen).
  - Manuelles Löschen dokumentiert/implementiert (BZ); bei Angebot → Nachrücken.
  - BZ Detail-Link: Modal statt Kursbuchungs-Liste.
  - Manuelle Buchung: Auto-Mails (Checkbox).
  - BZ Zahlung erst nach Umwandlung aus Warteliste.
  - BZ-Pflichtfelder: Kind-Formular (analog Ferienspiele) für **alle** BZ-Kurse;
    Familien-Bewegungszeit behält eigenes Formular inkl. Adresse/Bild-Video.
    Gesundheit nur bei Ferienspielen Pflicht, sonst optional.
  - JS `selectCourse`: Null-Check für fehlendes `continueBtn`.
  - Pflichtfelder: Speicherung + Detailmodal + CSV-Export bestätigt; Erziehungsberechtigte
    werden jetzt auch in `guardianFirstName`/`guardianLastName` gespeichert (für Export/Anzeige).
  - Admin-UI: Dashboard bleibt; Systeme (Swim/BZ/Fisch/KSB) im Menü getrennt mit eigenen
    Farben und System-Switcher; Platzhalter-Seiten für Fisch/KSB.

- Betroffene Dateien u. a.: `SendCourseBookingEmailMessageHandler`, `Course`,
  `CourseBookingController`, `CourseBookingAdminController`, `AppointmentWaitlistService`,
  `WaitingListController`, `EventCenterBookingController`, `PublicLandingController`,
  `AdminSystemController`, `AdminSystemRequestListener`, `admin_base.html.twig`,
  Templates Warteliste/Kursbuchung/E-Mail/Hub/Step1/Step3/Step4.

- Admin-Dashboard Performance (`MainDashboardController`):
  - Stats per `COUNT` statt kompletter Entity-Listen (Warteliste, Standorte, Kurse).
  - Freie Plätze: eine Aggregat-Query statt N+1 über `getAppointments()`.
  - Zielgruppen-Stats per `GROUP BY` statt zweitem Voll-Load.
  - Buchungstabelle: nur neueste 50 mit Eager-Joins; Gesamtzahl separat.
  - Template: Hinweis + Link zur Vollansicht bei Limit.

- BZ-Dashboard 1:1 zum Schwimm-Dashboard: `BzDashboardController` +
  `templates/admin/bz_dashboard/index.html.twig`; Menü-Eintrag; System-Home
  `admin_bz_dashboard` in `AdminSystemController`.

- Fallback-E-Mails & Warteliste (Volltest):
  - `SystemFallbackEmailCatalog` + Vorschau in Swim- und BZ-E-Mail-Template-Admin
    (exakter HTML-Inhalt, der ohne Template-Match rausgeht).
  - DB ohne `course_booking_waitlist` / `appointment_waitlist_*` Templates → Fallbacks aktiv.
  - Bugs: Familien-Bewegungszeit ging trotz Warteliste-Flag nicht auf Warteliste;
    SMTP-Fehler brach Angebot/Claim ab; Swim-Wartelisten-Mails waren async (ohne Worker
    keine Mail) → jetzt sync; BZ Zahlungsbestätigung ohne Template war stiller Abbruch → Fallback.
  - E2E: `php bin/console app:waitlist:e2e-test --system=both` (BZ + Swim OK).
  - Docs: `docs/CRONJOBS.md` (E2E-Command).

- Buchung Step 3 „keine Termine“ (Location 5, Kinder 6–8):
  - Ursache: JS rief `/public/appointments/available-slots-range` auf (Document-Root-
    Verwechslung); Admin-API ignorierte `courses=` und lud 365 Tage × alle Kurse.
  - Fix: Twig-`path('public_appointments_available_slots_range')`; API lädt nur
    angefragte Kurse im Datumsfenster; `courses=` auch in AppointmentController.
  - Verifiziert: Kurse 292/295/298/299/303 liefern Sept-Slots (API 15 Termine).

- Step 3 „Weiter“ bei monatsübergreifenden Kursen: `selectCourse` nahm per
  `querySelector` oft die versteckte Duplikat-Karte (Kurs in Aug + Sep). Auswahl
  jetzt über die angeklickte Karte; Terminzeile wählt Kurs + zeigt „Weiter“.
