Skip to main content

Półkolonie i zajęcia wakacyjne

Kompleksowy przewodnik po module półkolonii, w tym zarządzanie sezonami, turnusami, systemie zapisów (w tym z listą rezerwową), obsługą obecności, zniżkami oraz automatycznym filtrowaniem i ocenianiem dla klientów.

👤 Instrukcja dla pracownika (Administracja / Instruktor)

Moduł półkolonii służy do organizacji i sprzedaży cyklicznych zajęć wakacyjnych oraz zimowych dla dzieci i młodzieży. Umożliwia on pełną obsługę cyklu życia turnusu, od stworzenia oferty po kontrolę frekwencji i zebranie opinii od klientów.

Zarządzanie Sezonami i Turnusami

  • Sezony (np. "Lato 2024", "Ferie Zimowe 2025"): Stanowią główny kontener na turnusy. Definiuje się w nich bazową cenę, zasady zniżek (np. rabat na drugie dziecko lub zniżka za kolejny turnus), wymagane dokumenty (np. zgoda RODO, umowa) oraz przypisanie do miasta (Lokalizacji).
  • Turnusy: Konkretne terminy w ramach sezonu. Mogą dziedziczyć parametry z sezonu lub posiadać własną cenę (tzw. price_override). Definiowany jest dla nich maksymalny limit uczestników, data rozpoczęcia i zakończenia, a także personel instruktorski.

Prezentacja oferty klientowi (Filtrowanie według lokalizacji)

  • Rejestracja na turnus: Ścieżka dla klienta: Portal Klienta ➔ Półkolonie ➔ Wybierz turnus ➔ Kliknij "Zapisz dziecko"
  • Filtrowanie: System automatycznie zawęża listę dostępnych półkolonii, opierając się na parametrze preferowanego miasta, zdefiniowanego w ustawieniach konta klienta.
  • Użytkownik przypisany do miasta Opole, uzyskuje wgląd wyłącznie w turnusy organizowane w opolskich placówkach. Analogicznie dla innych miast (np. Legionowo).
  • Funkcjonalność ta optymalizuje proces zapisu, eliminując konieczność manualnego filtrowania obiektów przez klienta.

Nomenklatura zajęć uzależniona od miasta

System stosuje zróżnicowane nazewnictwo turnusów, adaptowane na podstawie lokalizacji klienta:

  • W standardowej konfiguracji zajęcia identyfikowane są jako "Półkolonie".
  • W jednostkach lokalnych (np. Legionowo oraz Lublin) algorytm automatycznie zmienia etykietę na "Zajęcia wakacyjne" lub "Zajęcia tenisowe".
  • Mechanizmy obsługi (zapisy, opłaty, raporty) działają identycznie niezależnie od wyświetlanej nazwy.

Proces Zapisów i Lista Rezerwowa

  • Statusy rejestracji: Każdy zapis przechodzi przez odpowiednie stany: draft (wypełnianie formularza), pending_payment (oczekiwanie na płatność wpisowego lub całości), paid (opłacono), cancelled (anulowano).
  • Lista Rezerwowa (Waitlist): Gdy turnus osiągnie maksymalną liczbę uczestników (max_participants), klienci mają możliwość zapisu na listę rezerwową. W przypadku zwolnienia się miejsca (np. z powodu rezygnacji innego uczestnika), administracja ma wgląd w kolejkę oczekujących (sortowaną według pozycji/czasu zapisu) i może zaoferować miejsce osobie rezerwowej.

Obecności i Widok Instruktora

  • Instruktorzy przypisani do turnusu (w konfiguracji sezonu/turnusu) uzyskują dostęp do dedykowanego widoku w panelu administracyjnym. Ścieżka dla instruktora: Dashboard ➔ Półkolonie ➔ (Widok Instruktora) Turnusy
  • Moduł pozwala na sprawdzanie cyfrowej Listy Obecności na każdy dzień trwania turnusu. Wprowadzone dane aktualizują się w czasie rzeczywistym, co pozwala administracji centralnej na monitorowanie frekwencji (sekcja "Lista obecności").

⭐ System oceniania turnusów (Camp Feedback)

Po zakończeniu turnusu system inicjuje procedurę pozyskiwania opinii od opiekunów:

  • W wyznaczonym terminie, system wysyła automatyczną wiadomość e-mail z przyciskiem „Podziel się opinią". Przekierowuje on do anonimowej ankiety (ocena 1-5 i komentarz).
  • Ankieta jest rejestrowana jednorazowo per opiekun na turnus (nie dubluje się przy rodzeństwie). Link zachowuje ważność przez 30 dni.
  • Ręczna wysyłka: W panelu (Półkolonie ➔ Wybierz turnus ➔ Opinie rodziców) pracownik może ponownie wysłać prośbę do osób, które jeszcze nie wypełniły ankiety (omijając zadłużonych klientów).

🛠️ Dokumentacja techniczna

Poniższa sekcja zawiera informacje dla deweloperów dotyczące struktury bazy danych, relacji i implementacji logiki.

Modele i struktury bazy danych

Główna relacyjna struktura danych modułu bazuje na tabelach (przedrostek camp_):

  • camp_season: Główna encja grupująca ofertę (np. ferie 2024). Zawiera city (miasto), default_price oraz referencje dziedziczone przez turnusy.
  • camp_term: Konkretne wydarzenie ograniczone datami. Posiada max_participants oraz status (active, full, cancelled, archived). Referencjuje season_id.
  • camp_registration: Rekord zapisu pojedynczego uczestnika na turnus. Zapisuje dane uczestnika (imię, PESEL, alergie) oraz opiekuna, preferencje fakturowe i status opłaty. Powiązany z player (jeśli klient posiada profil), payment_id oraz discount_rule_id.
  • camp_attendance: Zapisuje obecność per dzień (date), registration_id oraz is_present z dokładną informacją kto zanotował obecność (marked_by_employee_id). Zapewniona unikalność pary zapis-data na poziomie DB (UNIQUE(registration_id, date, tenant_id)).
  • camp_waitlist: Tablica na osoby oczekujące. Gwarantowana kolejność parametrem position.
  • camp_audit_log: Pełny log rewizji zmian. Dodanie do listy rezerwowej, edycja danych uczestnika, wypisanie z turnusu itp. zapisywane są z odpowiednim action, ułatwiając śledzenie modyfikacji (performed_by, old_value, new_value).
  • camp_term_instructor: Tabela łącząca (Many-to-Many) turnus z kontem pracownika (employee), dzięki czemu zdefiniowani pracownicy widzą odpowiednie trasy i dane (Route Access).
  • camp_feedback: Przechowuje wysłane tokeny i odpowiedzi ankiet (zobacz wyżej). Unikalność w relacji: turnus + opiekun.

Płatności, Linki do wpłat i Zniżki

System półkolonii korzysta z własnej siatki rabatowej (camp_discount_rule), w skład której wchodzą zniżki stałe lub procentowe (np. nth_term - za kolejny turnus, sibling - za rodzeństwo). Zastosowana logika zniżki oblicza final_price zapisywaną jako snapshot do camp_registration.

Aby ułatwić zarządzanie zaliczkami (częściową zapłatą z góry) i całościowymi płatnościami za obozy wakacyjne, moduł wykorzystuje tabelę payment_link dla wysyłki specjalnych unikalnych linków (tokenów), które pozwalają zalogowanemu (jak i w szczególnych przypadkach - niezalogowanemu) użytkownikowi przejść bezpośrednio do bramki P24 i uregulować kwotę za konkretne zapisy (odwołania do payment_id).

Logika filtrowania miast i Zabezpieczenie dostępu

  • Filtrowanie serwerowe: CampOfferPage wyciąga miasto przypisane do sesji usera Auth0 (app_metadata -> preferred_city) i filtruje SQL (odrzucając oferty przypisane do innego city).
  • Nawet jeśli użytkownik wejdzie przez link URL z ID turnusu przeznaczonego dla innej lokalizacji, w endpointach zapisu (np. CampRegisterPage) realizowana jest warstwa weryfikacyjna. Niezgodność przypisania generuje przymusowe przekierowanie (redirect) w Next.js powrotem na listę.
  • Branding wizualny: Funkcje pomocnicze w lib/utils/user-city.ts (transformText, isSpecialCity) odpowiadają za podmienianie frazy "półkolonie" na inne adekwatne terminy reklamowe z zachowaniem tej samej logiki biznesowej pod spodem.