# Wdrożenie Rollschool

Ten dokument opisuje obsługę istniejących środowisk Rollschool. Pełna
konfiguracja nowego projektu na OVH znajduje się poza repozytorium w
`/Users/radek/Sites/deployment-guides/ovh-github-actions.md`.

## Dokumentacja funkcjonalna

- [RollPoints](rollpoints.md) — feature flag, immutable terms PDF, payment ledger,
  migrations, request-time settlement and isolated verification.
- [Poziomy uwierzytelnienia](authentication.md) — definicje hard i soft loginu,
  domyślna ochrona tras oraz zasady przyszłych linków softloginowych.
- [Zajęcia indywidualne](individual-lessons.md) — planowanie, ceny zależne od
  terminu płatności, wymagalność, saldo, historia rozliczeń i raporty.
- [Zmiany zajęć indywidualnych z sierpnia 2026](changes/2026-08-individual-lessons.md)
  — zaległe przypisanie dokumentacji do commitów z 10–11 sierpnia.

## Model wdrożenia

Rollschool ma dwa osobne środowiska:

| Pole | Test | Produkcja |
| --- | --- | --- |
| URL | `https://test-next.rollschool.pl/` | `https://rollschool.pl/` |
| Katalog OVH | `/home/rollschomq-rg/test-next.rollschool.pl` | `/home/rollschomq-rg/zapisy` |
| Environment GitHub | `test-next` | `production` |
| Workflow | `Deploy Rollschool to test-next` | `Deploy Rollschool to production` |
| Skrypt serwerowy | `scripts/deploy-test-next.sh` | `scripts/deploy-production.sh` |
| Oczekiwane środowisko aplikacji | `DEV` | `PROD` |
| Backupy | `~/deployment-backups/test-next.rollschool.pl/` | `~/deployment-backups/rollschool.pl/` |

Test wdraża pełny SHA bieżącego `main`. Produkcja nie pobiera po prostu
najnowszego `main`: promuje dokładnie wskazany przez operatora commit z udanego
deploymentu `test-next`. Workflow testowy buduje także CSS z wersji wskazanej
przez ten SHA. Build odbywa się w osobnym jobie bez sekretów wdrożeniowych.
Gotowy plik jest zapisywany jako niezmienny artefakt GitHub Actions powiązany
z SHA; osobny job wdraża go na `test-next`, a produkcja pobiera ten sam artefakt
z udanego testu wybranego commita.

## Zwykłe wdrożenie

### 1. Sprawdź zmianę lokalnie

W katalogu projektu:

```bash
cd /Users/radek/Sites/rollschool.localhost
docker compose -f /Users/radek/Docker/localdev/docker-compose.yml exec -T \
  -w /var/www/sites/rollschool.localhost web-rollschool sh -lc \
  'git ls-files -z -- "*.php" | xargs -0 -n1 php -l'
git status --short
git diff --check
```

Jeżeli zmiana dotyczy SCSS i chcesz sprawdzić ją lokalnie, wykonaj jednorazowy
build:

```bash
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
```

`application/Resources/css/bootstrap.min.css` jest lokalnym i wdrożeniowym
artefaktem generowanym. Nie dodawaj go do commita. Commituj pliki źródłowe SCSS,
`package.json` i `package-lock.json`. Nie dodawaj konfiguracji, `Files/`,
`vendor/`, `node_modules/`, logów ani sekretów.

### 2. Wypchnij `main`

Wykonaj commit w GitHub Desktop albo w Terminalu, a następnie:

```bash
git push origin main
git status --short
```

### 3. Wdróż test

1. GitHub → repozytorium `rlschl` → `Actions`.
2. Wybierz `Deploy Rollschool to test-next`.
3. Kliknij `Run workflow`.
4. Wybierz gałąź `main`.
5. Kliknij zielone `Run workflow` i poczekaj na zielony wynik.

Workflow pobiera wskazany commit w jobie bez sekretów wdrożeniowych, konfiguruje
Node.js 22, wykonuje `npm ci --ignore-scripts` oraz `npm run sass:build` i zapisuje
wynik jako artefakt GitHub Actions oznaczony SHA commita. Osobny runner pobiera
ten artefakt, a następnie przesyła po SSH wygenerowany `bootstrap.min.css` wraz
z SHA commita i sumą SHA-256. Serwer zapisuje plik
bezpośrednio w docelowym miejscu na `test-next` i wykonuje pozostałe kontrole.
Workflow zapisuje deployment testowy wraz z dokładnym SHA. Sprawdza także
publiczny HTTPS i obecność nagłówka `X-Robots-Tag` zawierającego `noindex`.

### 4. Sprawdź test w przeglądarce

Na `https://test-next.rollschool.pl/` sprawdź:

- stronę publiczną i zmieniony fragment;
- logowanie;
- panel zarządzania;
- brak błędów w konsoli i odpowiedziach sieciowych, jeżeli zmiana dotyczy UI.

`test-next` jest współdzielony z testerami. Weryfikacja wdrożenia nie obejmuje
tworzenia, zmiany ani usuwania danych bez wyraźnej zgody na konkretną operację.
Dotyczy to także testowych nagród i promocji RollPoints. Testy wymagające zapisów
oraz przygotowanie danych testowych wykonuj lokalnie na odrębnej bazie.

Nie uruchamiaj produkcji tylko dlatego, że workflow jest zielony. Zielony wynik
potwierdza automatyczne kontrole; test przeglądarkowy potwierdza zachowanie
aplikacji.

### 5. Promuj sprawdzony commit na produkcję

1. W `Actions` wybierz `Deploy Rollschool to production`.
2. Kliknij `Run workflow` z gałęzi `main`.
3. W polu `commit_sha` wpisz pełny SHA commita sprawdzonego na `test-next`.
4. Otwórz uruchomienie i w podsumowaniu potwierdź `Selected commit`.
5. Poczekaj na zielony wynik.

Workflow odrzuci SHA, który nie ma udanego deploymentu `test-next`. Weryfikuje
też, że status deploymentu wskazuje dokładnie na zakończone sukcesem, ręczne
uruchomienie `deploy-test-next.yml` z gałęzi `main` i z tym samym SHA. Dzięki
podaniu SHA przed uruchomieniem i zatwierdzeniem produkcji nowszy deployment
testowy nie może zmienić wybranej wersji. Workflow produkcyjny pobiera
niezmienny artefakt dokładnie z tego zweryfikowanego uruchomienia i przesyła go
na serwer. Skrypt sprawdza SHA commita oraz sumę CSS; nie uruchamia ponownie
Sass ani npm.

### 6. Sprawdź produkcję

Otwórz `https://rollschool.pl/` i sprawdź stronę publiczną, logowanie, panel i
zmieniony obszar. Produkcja nie może zwracać `X-Robots-Tag: noindex`.

Szybka kontrola HTTP:

```bash
curl -fsSI https://test-next.rollschool.pl/ | grep -i '^x-robots-tag:'
curl -fsSI https://rollschool.pl/
```

## Co robią skrypty

Oba skrypty wdrożeniowe:

1. przyjmują tylko `deploy FULL_40_CHARACTER_SHA`;
2. pobierają `origin/main` i potwierdzają, że SHA do niego należy;
3. zatrzymują się, jeżeli drzewo robocze na OVH nie jest czyste;
4. odrzucają commit próbujący śledzić konfigurację, `Files/` albo wygenerowany
   `bootstrap.min.css`;
5. przełączają kod przez `git checkout --detach SHA`, bez `git clean`;
6. instalują CSS na `test-next`, a na produkcji pobierają dokładny artefakt
   zweryfikowanego uruchomienia testowego;
7. instalują zależności z `composer.lock`;
8. lintują PHP i sprawdzają konfigurację, URL, środowisko, runtime i bazę;
9. tworzą pełny backup tylko przy oczekujących migracjach i zapisują ich
   checksumy;
10. po błędzie przywracają poprzedni commit, odpowiadający mu CSS i ponownie go
    weryfikują.

Kod może zostać cofnięty, ale wykonane migracje bazy nie są cofane. Migracje
muszą być addytywne, możliwe do bezpiecznego ponowienia i kompatybilne z
poprzednią wersją kodu.

## Elementy należące do serwera

Te elementy pozostają osobne dla testu i produkcji i nie mogą trafić do Git:

```text
application/config/config.php
.deployment.env
.ovhconfig
.user.ini
Files/
application/scheduled_tasks/scheduled.log
application/Controller/p24debug.log
vendor/
application/Resources/css/bootstrap.min.css
application/Resources/css/bootstrap.min.css.sha256
```

`application/config/config.php` zawiera dane środowiska i bazy.
`.deployment.env` może zawierać wyłącznie ustawienia narzędzi wdrożeniowych,
np. ścieżkę do programu dumpującego; hasła bazy pozostają w `config.php`.

Mail identity and DEV email/SMS delivery controls also belong exclusively to
`application/config/config.php`. Follow
[environment-specific mail and SMS configuration](test-email-routing.md) for the
six required constants and optional `MAIL_TO2`, per-environment values,
configuration paths, validation,
and rollback. Configure and verify test-next first, then production, before
deploying the code that removes these settings from the administration panel.
The previous code already honors explicit constants, so preparing them in advance
takes effect immediately. Copying a database must not copy the source environment's
config file.

## Generowany CSS poza Gitem

Źródłem prawdy są pliki SCSS w `application/Resources/css`, `package.json` i
`package-lock.json`. Wygenerowany plik nie jest śledzony przez Git.

Workflow `test-next` buduje CSS w jobie bez dostępu do sekretów, a następnie
udostępnia go jobowi wdrożeniowemu jako niezmienny artefakt GitHub Actions.
Artefakt zawiera SHA commita i sumę CSS. Job wdrożeniowy przesyła go standardowym
wejściem istniejącego połączenia SSH. Skrypt zapisuje go atomowo bezpośrednio
pod ścieżkami:

```text
/home/rollschomq-rg/test-next.rollschool.pl/application/Resources/css/bootstrap.min.css
/home/rollschomq-rg/test-next.rollschool.pl/application/Resources/css/bootstrap.min.css.sha256
```

Produkcja odczytuje identyfikator uruchomienia workflow z udanego deploymentu
testowego, pobiera dokładnie jego nieprzeterminowany artefakt i przesyła go na
serwer. Serwer wymaga zgodności SHA z wdrażanym commitem i sprawdza sumę SHA-256,
a następnie zapisuje oba pliki do:

```text
/home/rollschomq-rg/zapisy/application/Resources/css/bootstrap.min.css
/home/rollschomq-rg/zapisy/application/Resources/css/bootstrap.min.css.sha256
```

Jeżeli artefakt nie pochodzi z wybranego udanego uruchomienia testowego, wygasł,
ma inne SHA, brakuje CSS albo suma się nie zgadza, wdrożenie produkcyjne
zatrzymuje się. Przy błędzie
w trakcie wdrożenia skrypt przywraca CSS obecny przed rozpoczęciem operacji.

### Pierwsze przejście na CSS generowany podczas wdrożenia

Pierwsze wdrożenie wykonaj w zwykłej kolejności: commit i push do `main`, workflow
`test-next`, kontrola w przeglądarce, a następnie workflow produkcyjny. Nie kopiuj
CSS ręcznie przed uruchomieniem workflow. Dotychczasowa komenda SSH pozostaje
`deploy FULL_40_CHARACTER_SHA`, dlatego działający na OVH starszy skrypt może
przełączyć pierwszy commit; nowy `after-deployment-pull.sh` odbierze CSS ze
standardowego wejścia tego samego połączenia.

Po pierwszym udanym wdrożeniu testowym sprawdź:

```bash
cd /home/rollschomq-rg/test-next.rollschool.pl
git check-ignore application/Resources/css/bootstrap.min.css
git check-ignore application/Resources/css/bootstrap.min.css.sha256
test -s application/Resources/css/bootstrap.min.css
php -r '$f="application/Resources/css/bootstrap.min.css"; echo hash_file("sha256", $f), PHP_EOL;'
cat application/Resources/css/bootstrap.min.css.sha256
```

Obie ostatnie komendy muszą zwrócić tę samą sumę. Po wdrożeniu produkcyjnym
wykonaj analogiczną kontrolę w `/home/rollschomq-rg/zapisy` i porównaj sumę z
`test-next`.

Przed podmianą skrypt zachowuje dotychczasowy CSS w pliku tymczasowym. Jeżeli
instalacja zależności, migracja lub weryfikacja się nie powiedzie, przywraca ten
CSS i poprzedni commit. Przy pierwszym rollbacku do starszego commita skrypt
usuwa ignorowany artefakt przed `git checkout`, dzięki czemu Git odtwarza
wcześniejszy, jeszcze śledzony `bootstrap.min.css`.

Test używa MySQL/Percona 8.4, a produkcja 8.0. Każda migracja musi działać na
obu środowiskach. Wersję serwera bazy skrypt sprawdza zapytaniem `SELECT
VERSION()` przez PDO.

## Kontrola na OVH

Test:

```bash
cd /home/rollschomq-rg/test-next.rollschool.pl
git status --short
git rev-parse HEAD
php scripts/database-migrations.php status test-next.rollschool.pl
./scripts/after-deployment-pull.sh \
  test-next.rollschool.pl https://test-next.rollschool.pl/ DEV
```

Produkcja:

```bash
cd /home/rollschomq-rg/zapisy
git status --short
git rev-parse HEAD
php scripts/database-migrations.php status rollschool.pl
./scripts/after-deployment-pull.sh rollschool.pl https://rollschool.pl/ PROD
```

`git status --short` powinien być pusty. Nie edytuj śledzonych plików na
serwerze, bo kolejne wdrożenie celowo zatrzyma się zamiast je nadpisać.

## Awaria

Jeżeli testowy workflow się nie powiedzie, nie uruchamiaj produkcji. Napraw
przyczynę, wypchnij poprawkę do `main`, ponownie wdróż test i wykonaj test
przeglądarkowy.

Jeżeli produkcja nie znajdzie udanego deploymentu `test-next`, najpierw uruchom
testowy workflow. Nie obchodź wyboru wersji przez ręczne wskazanie innego SHA.

Ręczne ponowienie wdrożenia jest możliwe tylko dla pełnego SHA należącego do
`main`. Test musi już posiadać wygenerowany CSS zgodny z bieżącym SHA, a przed
produkcją musi wskazywać ten sam SHA:

```bash
# test
cd /home/rollschomq-rg/test-next.rollschool.pl
./scripts/deploy-test-next.sh FULL_40_CHARACTER_COMMIT_SHA

# produkcja — dopiero po sprawdzeniu tego samego SHA na teście
cd /home/rollschomq-rg/zapisy
./scripts/deploy-production.sh FULL_40_CHARACTER_COMMIT_SHA
```

Nowego SHA nie można wdrożyć ręcznie przed uruchomieniem workflow testowego,
ponieważ serwer celowo nie ma npm i sam nie buduje CSS. To jest procedura
awaryjna. Standardowo używaj Actions, ponieważ buduje CSS oraz tworzy historię
deploymentów potrzebną do bezpiecznej promocji produkcyjnej.
