# AGENTS.md

## Zakres

Te zasady obowiązują w całym repozytorium. Projekt jest aplikacją PHP opartą na MINI3 i własnej, lekkiej implementacji MVC.

## Architektura i odpowiedzialności

- Zachowuj podział MVC i dopasowuj nowe rozwiązania do istniejącej struktury projektu.
- Kontrolery powinny być cienkie. Mogą obsługiwać wejście HTTP, uprawnienia, wybór modelu, przekierowanie oraz przekazanie danych do widoku, ale nie powinny zawierać logiki biznesowej.
- Logikę biznesową, walidację reguł domenowych i operacje na danych umieszczaj w modelach.
- Widoki odpowiadają za prezentację. Nie wykonuj w nich zapytań do bazy ani operacji biznesowych.
- Nie powielaj tej samej reguły biznesowej w kilku kontrolerach lub widokach. Utwórz jedną metodę modelu o nazwie opisującej jej intencję.
- Przy zmianie istniejącego fragmentu popraw jego podział odpowiedzialności, jeśli da się to zrobić bez nieproporcjonalnego refaktoru poza zakresem zadania.

## Język i nazewnictwo

- Nowe zmienne, właściwości, metody, funkcje, stałe i pozostałe identyfikatory techniczne nazywaj po angielsku oraz zgodnie z konwencjami już używanymi w aplikacji.
- Przed nazwaniem nowego pola lub zmiennej sprawdź analogiczne nazwy w istniejącym kodzie i schemacie danych. Nie wprowadzaj drugiej konwencji dla tego samego rodzaju wartości.
- Identyfikatory relacji w bazie i odpowiadające im nazwy w kodzie zapisuj w dominującym formacie `id_<entity>`, np. `id_user`, `id_course`, `id_payment`. Nie wprowadzaj wariantów `user_id`, `course_id` ani ogólnego `id`, gdy z kontekstu nazwy nie wynika jednoznacznie, czego jest to identyfikator.
- Komentarze, PHPDoc, opisy techniczne i komunikaty przeznaczone dla programistów zapisuj po angielsku.
- Polskie nazwy są dozwolone dla ścieżek URL, segmentów routingu i odpowiadających im nazw kontrolerów oraz akcji, ponieważ stanowią część polskiego interfejsu aplikacji. Przykładowo ścieżka `zajecia_grupowe` może być obsługiwana przez `Zajecia_grupoweController`.
- Teksty widoczne dla użytkownika zapisuj zgodnie z językiem danego interfejsu, domyślnie po polsku.
- Nie zmieniaj istniejących publicznych adresów URL ani nazw kontrolerów wyłącznie w celu przetłumaczenia ich na angielski.
- Przy edycji istniejącego kodu nie wykonuj masowego tłumaczenia nazw poza zakresem zadania. Nowy kod powinien jednak stosować powyższe zasady.
- Produkcyjny autoloader może rozróżniać wielkość liter w nazwach klas i przestrzeni nazw, nawet jeśli lokalny system plików tego nie ujawnia. Przed dodaniem importu sprawdź analogiczne użycia w działających kontrolerach i zachowaj dokładnie ten sam zapis. W szczególności bibliotekę bezpieczeństwa importuj zgodnie z konwencją projektu jako `use Mini\Libs\security as Security;`, a nie `use Mini\Libs\Security;`.

## Baza danych

- W pierwszej kolejności korzystaj z funkcjonalności `Mini\Core\Model`, w szczególności `load()`, `getSet()`, `set()` i `save()`.
- Proste odczyty oraz zapis pojedynczego modelu realizuj przez powyższe mechanizmy zamiast tworzyć pełne zapytania SQL.
- Własny SQL stosuj tylko wtedy, gdy mechanizmy modelu nie wyrażają zapytania czytelnie lub efektywnie, np. przy agregacjach, złożonych połączeniach, raportach lub operacjach obejmujących wiele rekordów.
- Własne zapytania SQL umieszczaj w modelach, nie w kontrolerach ani widokach.
- Dane dynamiczne zawsze przekazuj jako parametry przygotowanego zapytania PDO. Nie sklejaj wartości pochodzących od użytkownika z tekstem SQL.
- Nazwy tabel, kolumn i kierunek sortowania mogą być składane dynamicznie wyłącznie z kontrolowanej listy dozwolonych wartości.
- Gdy operacja biznesowa wykonuje kilka zależnych zapisów, użyj transakcji, jeśli częściowe wykonanie mogłoby pozostawić niespójne dane.
- Zmiany schematu lub danych wymagane przez wdrożenie zapisuj jako kolejne, śledzone przez Git pliki SQL w `database/migrations`, zgodnie z instrukcją w tym katalogu.
- Migracje są wykonywane automatycznie przez skrypt wdrożeniowy po utworzeniu pełnej kopii bazy. Skrypt zapisuje nazwę i sumę SHA-256 wykonanej migracji w tabeli `deployment_migration`.
- Po wdrożeniu migracji na którekolwiek środowisko nie zmieniaj jej treści. Poprawki wykonuj w nowej migracji o późniejszej nazwie.
- Migracje muszą być addytywne, możliwe do bezpiecznego ponowienia po częściowej awarii i kompatybilne z poprzednią wersją kodu. Automatyczne wdrożenie nie wykonuje destrukcyjnego rollbacku schematu.
- Nie dodawaj do automatycznych migracji operacji usuwających tabele, kolumny lub dane. Takie zmiany wymagają osobnego, ręcznie zatwierdzonego planu po potwierdzeniu, że dane nie są już potrzebne.

## Pliki wdrożeniowe

- Każde wdrożenie wymagające dodania, skopiowania, przeniesienia, zmiany nazwy lub usunięcia plików poza zwykłym wdrożeniem śledzonego kodu opisz w śledzonej dokumentacji wdrożenia w `docs/`.
- Dotyczy to w szczególności ignorowanych przez Git katalogów i plików, takich jak `Files`, danych startowych w postaci obrazów lub dokumentów, zasobów przenoszonych między katalogami oraz plików usuwanych po wdrożeniu nowego mechanizmu.
- Instrukcja plikowa musi wymieniać dokładne ścieżki źródłowe i docelowe, pliki do dodania, zastąpienia lub usunięcia, wymaganą kolejność względem migracji SQL i wdrożenia kodu, a także sposób weryfikacji i wycofania.
- Automatyczny runner migracji bazy nie wykonuje operacji na plikach serwerowych ani w `Files`.

## Konfiguracja środowiskowa

- `application/config/config.php` jest lokalny i ignorowany przez Git. Nie zapisuj w repozytorium jego pełnej treści ani sekretów.
- Każdą zmianę konfiguracji wymaganą przy wdrożeniu opisz w śledzonej dokumentacji w `docs/`, niezależnie od powiązanej migracji SQL lub operacji plikowej.
- Instrukcja konfiguracji powinna zawierać dokładną nazwę ustawienia, bezpieczne wartości lub szablony dla poszczególnych środowisk, miejsce dodania oraz sposób weryfikacji bez ujawniania sekretów.
- Najpierw zastosuj i zweryfikuj zmianę konfiguracji na środowisku testowym, a dopiero później na produkcji.

## CSS i JavaScript

- Obowiązującym frameworkiem interfejsu jest Bootstrap 5.3.8. Twórz markup, style i zachowania zgodnie z API oraz konwencjami tej wersji.
- Nie dodawaj jQuery ani kodu zależnego od jQuery. Korzystaj z natywnego JavaScriptu, Bootstrap Data API oraz klas i metod udostępnianych przez Bootstrap 5.3.8.
- Nie traktuj starszych, pozostawionych w repo zasobów Bootstrap jako wzorca, jeśli są sprzeczne z wersją 5.3.8 ładowaną przez aplikację.
- Zanim napiszesz własny komponent lub obsługę JavaScript, sprawdź, czy Bootstrap udostępnia już odpowiedni komponent albo mechanizm, np. modal, collapse, dropdown, tabs, alert lub walidację formularza.
- Nie dodawaj CSS ani JavaScript inline do plików PHP/HTML (`style`, `<style>`, obsługa zdarzeń typu `onclick` ani skrypty w `<script>`).
- Style umieszczaj w plikach SCSS w `application/Resources/css`. Preferuj klasy zamiast atrybutu `style`.
- Do układu i stylowania używaj w pierwszej kolejności komponentów, klas narzędziowych i zmiennych Bootstrap. Własny SCSS dodawaj wtedy, gdy Bootstrap nie zapewnia potrzebnego rozwiązania lub gdy jest to element identyfikacji wizualnej aplikacji.
- Własne style powinny uzupełniać Bootstrap i istniejący wygląd aplikacji, a nie tworzyć obok nich odrębny system wizualny.
- Nie używaj w widokach klas `text-muted` ani `text-body-secondary`. Teksty pomocnicze, metadane i komunikaty pustych stanów mają zachowywać zwykły kolor tekstu; hierarchię wizualną buduj rozmiarem, wagą, odstępami lub strukturą, a nie przygaszaniem koloru.
- Podobne widoki i operacje w różnych częściach aplikacji powinny mieć możliwie spójny układ oraz wygląd sekcji, kart, nagłówków, formularzy, tabel, komunikatów i przycisków. Przed zaprojektowaniem nowego widoku znajdź najbardziej zbliżony istniejący ekran i wykorzystaj jego schemat.
- JavaScript umieszczaj w osobnych plikach w `application/Resources/js` i podpinaj zachowanie za pomocą selektorów, klas lub atrybutów `data-*`.
- Jednorazowe komunikaty wyświetlane po przekierowaniu zapisuj przez `Mini\Libs\Flash`, najczęściej za pomocą `Flash::redirect()`. Nie przekazuj w adresie URL parametrów typu `success`, `alert`, `done` ani podobnych znaczników zlecających ponowne pokazanie komunikatu, ponieważ powoduje to jego powrót po odświeżeniu strony.
- Dobieraj prezentację komunikatu świadomie: zwykłe informacje i błędy pokazuj jako `Flash::ALERT`, natomiast ważne potwierdzenia zakończenia procesu, które użytkownik powinien zauważyć, jako `Flash::MODAL` z konkretnym tytułem. Błędy walidacji formularza pokazuj przy formularzu lub jako alert wraz z zachowaniem bezpiecznych danych formularza; nie używaj dla nich automatycznie modala.
- Błędów obsługi żądań użytkownika, w szczególności nieprawidłowego lub wygasłego tokena CSRF, braku uprawnień, błędnej metody HTTP, nieprawidłowych danych formularza albo konfliktu aktualnego stanu rekordu, nie kończ przez `die('...')`, `exit('...')` ani surową stronę z samym tekstem. Skieruj użytkownika do bezpiecznego, użytecznego ekranu przez `Flash::redirect()` albo pokaż błąd przy formularzu, zachowując bezpieczne dane wejściowe tam, gdzie ma to sens. Dla żądań oczekujących odpowiedzi maszynowej zwróć właściwy kod HTTP i ustrukturyzowaną odpowiedź zgodną z kontraktem endpointu. Samo `exit` lub `die` bez tekstu po poprawnym `header('Location: ...')` jest dopuszczalne w zastanym przepływie, ale w nowym kodzie preferuj `Flash::redirect()` dla przekierowań z komunikatem.
- Potwierdzenia operacji realizuj przez wspólny modal z `application/view/_templates/confirmation_modal.php`, używając `data-confirmation-modal` oraz własnego `data-confirmation-message` albo `data-confirmation-template`. Zachowuj konkretną treść i skutki danej operacji; nie zastępuj ich ogólnym pytaniem typu „Czy potwierdzasz akcję?”.
- Nie używaj natywnego `confirm()`, `window.confirm()`, inline `onclick="return confirm(...)"` ani osobnych, powielonych modalów wyłącznie do potwierdzania akcji. Dla formularzy wspólny mechanizm musi zachować standardowe wysłanie formularza, przycisk submit oraz ochronę CSRF.
- Istniejący inline CSS/JS jest kodem zastanym, a nie wzorcem do naśladowania. Przy pracy nad takim fragmentem przenieś go do odpowiedniego zasobu, jeśli mieści się to w zakresie zmiany.
- Domyślnie nie uruchamiaj kompilacji CSS po zmianie SCSS. Zakładaj, że watcher już działa albo że użytkownik uruchomi kompilację ręcznie po zakończeniu zmian.
- Plik Docker Compose obsługujący ten projekt znajduje się poza repozytorium, pod `/Users/radek/Docker/localdev/docker-compose.yml`. Repozytorium jest montowane w kontenerze `sass` jako `/var/www/sites/rollschool.localhost`, dlatego polecenia kompilacji muszą wskazywać plik przez `-f` oraz katalog roboczy przez `--workdir`.
- Jeżeli użytkownik wyraźnie poleci uruchomić watcher Sass, użyj polecenia `docker compose -f /Users/radek/Docker/localdev/docker-compose.yml run --rm --workdir /var/www/sites/rollschool.localhost sass npx sass --watch application/Resources/css/bootstrap.scss:application/Resources/css/bootstrap.min.css --style=compressed --no-source-map` i pozostaw proces działający w tle na czas pracy. Nie blokuj dalszej pracy oczekiwaniem na zakończenie watchera.
- Jeżeli użytkownik wyraźnie poleci jednorazowo zbudować CSS, uruchom polecenie `docker compose -f /Users/radek/Docker/localdev/docker-compose.yml run --rm --workdir /var/www/sites/rollschool.localhost sass npx sass application/Resources/css/bootstrap.scss application/Resources/css/bootstrap.min.css --style=compressed --no-source-map`, poczekaj na jego zakończenie i sprawdź kod wyjścia.
- Kompilację można też uruchomić na potrzeby diagnozy procesu budowania, dobierając tryb `--watch` lub jednorazowy zgodnie z zadaniem.
- Nie edytuj ręcznie wygenerowanego `application/Resources/css/bootstrap.min.css`. Źródłem prawdy są pliki SCSS; wygenerowany CSS pozostaje w repo jako gotowy artefakt wdrożeniowy.

## Pomoc i FAQ

- Przy każdej zmianie funkcjonalnej sprawdź, czy klient lub opiekun potrzebuje nowych informacji, aby skorzystać z aplikacji. Sama zmiana reguły biznesowej nie oznacza konieczności aktualizacji publicznego FAQ.
- Jeśli zmienia się sposób wykonania operacji przez klienta lub opiekuna, dostępne dla niego opcje, nazwy elementów interfejsu albo instrukcja opisana w pomocy staje się nieaktualna, zaktualizuj w tej samej zmianie odpowiednie widoki pomocy, w szczególności `application/view/home/faq.php` oraz `application/view/home/zarzadzanie_dziecmi_faq.php`.
- Nie aktualizuj FAQ przy zmianach czysto technicznych, które nie wpływają na zachowanie widoczne dla użytkownika.
- Publiczne FAQ ma zawierać krótkie, praktyczne odpowiedzi potrzebne klientowi lub opiekunowi, opisane prostym językiem. Nie jest dokumentacją techniczną ani instrukcją dla administratora.
- Nie dodawaj do publicznego FAQ wewnętrznych reguł rozliczeń, szczegółowych warunków generowania lub pomijania dokumentów, konfiguracji integracji ani technicznych przypadków brzegowych. Dotyczy to m.in. wyłączeń paragonów dla darowizn, rozliczeń technicznych i kwot zerowych, rozróżnień według źródła wpłaty oraz obsługi integracji z Fakturownią. Takie reguły opisuj w `docs/`, a potrzebne wskazówki dla obsługi — w odpowiednim panelu lub pomocy administracyjnej.
- Przed dodaniem treści do FAQ sprawdź, czy pomaga ona użytkownikowi wykonać konkretną czynność albo odpowiada na jego praktyczne pytanie. Jeśli jedynie relacjonuje zmianę w kodzie lub wewnętrzną logikę systemu, pomiń ją w publicznej pomocy.
- Jeśli użytkownik wyraźnie ograniczy zakres zmian w FAQ lub pomocy, uszanuj to ograniczenie. Nie zwalnia ono z aktualizacji wymaganej dokumentacji technicznej reguł domenowych.

## Dokumentacja funkcjonalna i techniczna

- Dokumentacja jest częścią implementacji, a nie opcjonalnym zadaniem wykonywanym po zakończeniu kodowania. Aktualizuj ją w tym samym zestawie zmian i weryfikuj przed uznaniem zadania za zakończone.
- Każda zmiana trwałej reguły biznesowej, modelu danych, sposobu wyliczania wartości, cyklu życia rekordu, rozliczeń, raportowania albo współpracy kilku modułów wymaga aktualizacji odpowiedniego śledzonego pliku w `docs/`.
- Jeżeli dla zmienianego obszaru nie istnieje dokumentacja techniczna, utwórz plik `docs/<feature>.md` zamiast pozostawiać regułę wyłącznie w kodzie, migracji, opisie commita albo rozmowie.
- Dokument funkcjonalny powinien opisywać aktualny stan końcowy, źródła konfiguracji, najważniejsze reguły i wyjątki, wpływ na dane historyczne, powiązane migracje oraz adekwatny scenariusz weryfikacji.
- Gdy kilka commitów lub etapów jednej sesji dotyczy tego samego obszaru, wykonaj przed zakończeniem audyt całego zakresu i uzupełnij dokumentację również o wcześniejsze zmiany, które nie zostały opisane na bieżąco. Nie dokumentuj jako obowiązującej reguły rozwiązania zastąpionego w późniejszym etapie; opisz stan końcowy, a historię zachowaj osobno tylko wtedy, gdy pomaga we wdrożeniu lub audycie.
- Zmiany czysto techniczne, które nie zmieniają kontraktu funkcji, nie wymagają osobnego dokumentu domenowego. Jeżeli jednak korygują istotny przypadek brzegowy istniejącej reguły, dopisz ten przypadek do dokumentacji właściwego obszaru.

## SEO i publiczne strony

- Jedynym kanonicznym hostem produkcyjnym jest `https://rollschool.pl` bez prefiksu `www`. Publiczne canonicale, adresy w sitemapie i odnośnik do sitemapy w `robots.txt` muszą używać tego hosta niezależnie od domeny, przez którą obsłużono żądanie.
- Produkcyjne hosty historyczne `www.rollschool.pl` i `zapisy.rollschool.pl` powinny wykonywać trwałe przekierowanie na `https://rollschool.pl`, zachowując ścieżkę oraz parametry zapytania.
- Hosty `rollschool.pl` i `test-next.rollschool.pl` muszą wymuszać HTTPS. Lokalny host `rollschool.localhost` nie powinien wymuszać HTTPS.
- Przy dodawaniu lub istotnej zmianie publicznej strony albo widoku zawsze sprawdź i w razie potrzeby zaktualizuj jej tytuł strony, `meta description`, `meta keywords` oraz adres kanoniczny w centralnym mechanizmie SEO.
- Tytuł, opis i słowa kluczowe muszą konkretnie opisywać zawartość danej strony. Nie kopiuj jednego ogólnego zestawu na wszystkie podstrony i nie upychaj powtarzających się słów kluczowych.
- Jeżeli nowa publiczna strona powinna być indeksowana, dodaj ją do jawnej listy publicznych adresów w sitemapie. Jeżeli strona przestaje istnieć albo staje się niepubliczna, usuń ją z tej listy.
- Nigdy nie dodawaj do sitemapy stron konta, panelu administracyjnego, płatności, akcji zapisów ani innych adresów dostępnych dopiero po zalogowaniu lub wykonujących operacje. Niepubliczne trasy powinny pozostać oznaczone jako `noindex, nofollow`.
- Dla stron szczegółowych opartych na danych, takich jak instruktor, lokalizacja, kategoria zajęć, grupa lub kurs, buduj metadane z aktualnych, bezpiecznie oczyszczonych danych rekordu, korzystając z centralnego mechanizmu zamiast składać tagi bezpośrednio w widoku.
- Nowe widoki konta i panelu zarządzania powinny otrzymać krótki, czytelny tytuł pozwalający rozpoznać kartę przeglądarki, ale nadal pozostawać bez publicznych metadanych SEO i z dyrektywą `noindex, nofollow`.

## Bezpieczeństwo i jakość

- Waliduj dane wejściowe oraz sprawdzaj uprawnienia przed wykonaniem operacji zmieniającej dane.
- Dobieraj metodę HTTP i ochronę CSRF świadomie, proporcjonalnie do ryzyka operacji oraz zgodnie z konwencją istniejącego fragmentu aplikacji. POST z tokenem CSRF stosuj przede wszystkim dla operacji destrukcyjnych, wrażliwych, przyjmujących dane użytkownika lub zmieniających istotny stan.
- Nie dodawaj formularzy POST i tokenów CSRF mechanicznie do każdej prostej akcji. W szczególności nie zamieniaj zwykłej pozycji menu w formularz tylko po to, aby dołączyć token. Prosta, ograniczona uprawnieniami akcja administracyjna może pozostać zwykłym linkiem do kontrolera, jeżeli taki sposób wywołania jest zamierzony, zakres skutków jest mały, a kontroler niezależnie sprawdza wymagany poziom uprawnień.
- Escapuj dane wyświetlane w HTML, używając `htmlspecialchars` z odpowiednim kodowaniem, chyba że wartość jest świadomie zaufanym HTML-em.
- Nie zapisuj sekretów ani lokalnej konfiguracji z `application/config/config.php` w repozytorium.
- Nie dodawaj zależności z `vendor`, `node_modules` ani danych użytkowników z `Files` do Gita.
- Zachowuj obecny styl kodu w dotykanym pliku, ale dla nowego kodu wybieraj czytelne nazwy i małe metody o jednej odpowiedzialności.
- Nie wykonuj dużych refaktorów niezwiązanych bezpośrednio z zadaniem.

## Weryfikacja zmian

- Po zmianach uruchom dostępne, adekwatne testy lub wykonaj możliwie wąską kontrolę składni i zachowania zmienionego obszaru.
- Nie uruchamiaj kompilacji Sass tylko w celu weryfikacji zwykłej zmiany stylów. Uruchom ją wyłącznie na wyraźne polecenie użytkownika albo podczas diagnozy procesu budowania, zgodnie z zasadami powyżej.
- Przed zakończeniem sprawdź `git diff` i upewnij się, że nie zostały dodane sekrety, zależności, dane z `Files` ani przypadkowe pliki środowiskowe.

## Commity Git

- Summary i Description każdego commita zapisuj po angielsku.
- Nie twórz commitów zawierających wyłącznie Summary. Description ma krótko
  wyjaśniać, co zmieniono i dlaczego.
- W GitHub Desktop zawsze wypełniaj oba pola: **Summary** i **Description**.
- W terminalu przekaż zarówno temat, jak i treść, na przykład:

```bash
git commit -m "Update deployment documentation" -m "Clarify the production workflow and migration safeguards."
```
