Kolizje kortu i trenera przy zapisie zajęć
Zanim panel zapisze zmianę w grafiku, sprawdza, czy nowy termin nie nachodzi na inne zajęcia na tym samym korcie oraz czy prowadzący nie ma w tym czasie innych zajęć. Gdy sprawdzenie wypadnie negatywnie, nic nie zostaje zapisane i formularz pokazuje komunikat o kolizji.
👤 Instrukcja dla pracownika (Recepcja / Administracja)
Kiedy pojawia się komunikat o kolizji
- „Kort jest już zajęty w tym terminie" — przenosisz zajęcia na godzinę lub kort, gdzie stoi już inna aktywna rezerwacja.
- „Trener ma w tym czasie inne zajęcia" — przypisujesz prowadzącego, który w tym samym czasie prowadzi coś innego (również jako zastępstwo).
Kolizji nie tworzą zajęcia odwołane, zarchiwizowane ani niedokończone rezerwacje klienta, którym minął czas na opłacenie.
Sama zmiana trenera nie jest blokowana kortem
Jeżeli w grafiku dwa wpisy z przeszłości nachodzą na siebie na jednym korcie, nadal można edytować takie zajęcia — przypisać lub zmienić prowadzącego, poprawić notatkę czy listę uczestników. Kort jest weryfikowany dopiero wtedy, gdy faktycznie zmieniasz godzinę lub kort. Dotyczy to zarówno pojedynczych zajęć, jak i edycji całej serii cyklicznej.
Edycja serii
Przy edycji serii sprawdzane są wszystkie zmieniane wystąpienia — także między sobą. Jeśli choć jedno wystąpienie wchodzi na zajęty termin, cała operacja jest przerywana i seria pozostaje bez zmian.
🛠️ Dokumentacja techniczna
Walidacja żyje w lib/actions/game.ts:
updateGame— pojedyncze zajęcia,updateRecurringGames— edycja serii (batch).
Obie ścieżki używają tych samych fragmentów SQL z lib/utils/court-conflict.ts:
| Element | Rola |
|---|---|
GAME_OCCUPIES_SLOT_SQL | odsiewa zajęcia archived, cancelled_at oraz wygasłe game_expires_at |
COURT_TIME_OVERLAP_SQL | porównanie zakresów czasu z obsługą obu formatów start_time |
courtOverlapBindValues | parametry zapytania w wersji UTC i w czasie Europe/Warsaw |
isSameGameInstant | porównanie dwóch znaczników czasu jako punktów w czasie, niezależnie od formatu |
Warunki uruchomienia sprawdzeń
| Sprawdzenie | Uruchamiane, gdy |
|---|---|
kolizja kortu (COURT_SCHEDULE_OVERLAP) | zmienił się start_time, end_time lub court_id |
kolizja prowadzącego (INSTRUCTOR_SCHEDULE_OVERLAP) | zmienił się czas albo prowadzący (instructor_id / substitute_instructor_id) |
Zmiana samego prowadzącego nie uruchamia sprawdzenia kortu — inaczej wpis stojący na korcie razem z innym (dane sprzed wprowadzenia walidacji) byłby nieedytowalny na zawsze.
Format czasu
game.start_time występuje w bazie w dwóch formatach: ISO-UTC z Z (wiersze
tworzone przez aplikację) oraz YYYY-MM-DD HH:MM:SS w czasie lokalnym
(starsze wiersze). Porównanie tekstowe uznawało te dwa zapisy tego samego
momentu za zmianę terminu i niepotrzebnie odpalało walidację kortu, dlatego
oba warianty przechodzą przez isSameGameInstant.
Testy
lib/actions/game.employeeRemoval.test.ts → updateRecurringGames - schedule conflict guards (baza SQLite w pamięci).