# Wdrożenie na hosting OVH

Konfiguracja Capistrano jest taka sama jak w projekcie `fpl`, który stoi na tym
samym klastrze. Samo wdrożenie uruchamiasz ręcznie — nic tu nie robi tego za
Ciebie.

## Dwie rzeczy, które musisz potwierdzić przed pierwszym uruchomieniem

Wpisałem wartości przez analogię do `fpl`. Jeśli u Ciebie jest inaczej, popraw
je, zanim odpalisz wdrożenie:

- `config/deploy.rb` → `repo_url` zakłada `git@github.com:kubagladki/ucl.git`;
- `config/deploy/production.rb` → użytkownik SSH `gladits-ucl` na
  `ssh.cluster127.hosting.ovh.net`.

## Czego brakuje, zanim pierwsze wdrożenie w ogóle ruszy

Trzy rzeczy trzeba załatwić raz. Bez nich Capistrano przerwie na pierwszym kroku.

### 1. Zdalne repozytorium

Capistrano klonuje kod na serwerze z adresu git — nie wysyła plików z Twojego
dysku. Ten projekt nie ma jeszcze zdalnego repozytorium:

```
git remote add origin https://github.com/kubagladki/ucl.git
git push -u origin master:main
```

Z laptopa pchasz przez **HTTPS** (tak samo jak w `fpl` — nie masz klucza SSH na
GitHubie), a serwer pobiera kod przez **SSH** własnym deploy keyem. To dwie różne
drogi do tego samego repozytorium i tak ma być.

Repozytorium jest prywatne, więc serwer potrzebuje własnego klucza. Wygeneruj go
na serwerze i dodaj jako **Deploy key** w ustawieniach repozytorium, bez prawa
zapisu:

```
ssh-keygen -t ed25519 -C "gladits-ucl@ovh" -N "" -f ~/.ssh/id_ed25519_ucl
printf 'Host github-ucl\n  HostName github.com\n  IdentityFile ~/.ssh/id_ed25519_ucl\n  IdentitiesOnly yes\n' >> ~/.ssh/config
chmod 600 ~/.ssh/config
ssh -T git@github-ucl
```

**Dlaczego alias `github-ucl`, a nie `github.com`.** Katalog domowy na OVH jest
wspólny dla wszystkich projektów, więc `~/.ssh/config` trzyma już wpis dla `fpl`.
Drugi wpis `Host github.com` nigdy by nie zadziałał — SSH bierze pierwszy pasujący
i sięgnąłby po klucz `fpl`, a ten jest ważny wyłącznie dla repozytorium `fpl`.
Każdy projekt ma więc własny klucz pod własnym aliasem; `repo_url`
w `config/deploy.rb` używa tego aliasu.

Klucza nie da się współdzielić: GitHub przyjmuje dany deploy key tylko w jednym
repozytorium.

Przekazywanie klucza z laptopa (`ssh-add`) tu nie pomoże — lokalny `id_rsa` jest
zabezpieczony hasłem i wymagałby odblokowania przy każdym wdrożeniu.

### 2. Composer na serwerze

Composer leży w katalogu domowym: `/homez.1951/gladits/composer.phar`. Jest
wspólny dla wszystkich użytkowników tego hostingu, więc stoi tam już od
poprzednich projektów. Gdyby go zabrakło:

```
curl -sS https://getcomposer.org/installer | php -- --install-dir=/homez.1951/gladits --filename=composer.phar
```

### 3. Plik `.env.local` na serwerze

Trzyma hasło do bazy i sekret aplikacji, więc nigdy nie trafia do repozytorium.
Utwórz go raz w katalogu współdzielonym — Capistrano dowiąże go do każdego
wydania:

```
mkdir -p /homez.1951/gladits/ucl/shared
cat > /homez.1951/gladits/ucl/shared/.env.local <<'EOF'
APP_ENV=prod
APP_DEBUG=0
APP_SECRET=<wygeneruj: openssl rand -hex 16>
DATABASE_URL="mysql://uzytkownik:haslo@serwer-bazy:3306/nazwa?serverVersion=5.7&charset=utf8mb4"
EOF
chmod 600 /homez.1951/gladits/ucl/shared/.env.local
```

Dane bazy weź z panelu OVH. Sprawdź tam też wersję MySQL i dopasuj
`serverVersion` — lokalnie stoi 5.7.

## Baza danych

### Założenie bazy

Bazę zakładasz w panelu OVH — Capistrano jej nie utworzy, a wdrożenie przerwie
się na migracjach, jeśli baza nie istnieje albo dane dostępowe się nie zgadzają.

Dwie rzeczy muszą się zgadzać, inaczej wysypie się dopiero na danych:

- **MySQL 5.7.8 lub nowszy** (albo MariaDB 10.2+). Dwie kolumny są typu `JSON`:
  role użytkownika i wylosowana trójka klubów przy kodzie zaproszenia. Starsze
  MySQL nie zna tego typu.
- **Kodowanie `utf8mb4`.** Migracje zakładają je wprost na każdej tabeli, ale
  ustaw je też jako domyślne dla bazy. Bez tego polegną nazwy w rodzaju
  `Bodø/Glimt`, `Fenerbahçe` czy `Slovan Bratysława`.

Wersję z panelu OVH przepisz do `serverVersion` w `DATABASE_URL`:

```
DATABASE_URL="mysql://uzytkownik:haslo@serwer-bazy:3306/nazwa?serverVersion=5.7&charset=utf8mb4"
```

### Schemat

Schematu nie wgrywasz ręcznie i nie zrzucasz z lokalnej bazy. Tworzą go
migracje, które Capistrano uruchamia **przy każdym wdrożeniu**, zaraz po
wgraniu kodu (`symfony:migrate`). Pierwsze wdrożenie zakłada komplet tabel na
pustej bazie, kolejne dokładają tylko to, co doszło.

Sprawdzenie stanu po wdrożeniu:

```
php bin/console doctrine:migrations:status --env=prod
```

### Danych z lokalnej bazy nie przenosisz

Sezon zakładasz na produkcji od nowa: rozgrywki, kluby, terminarz, kody. Lokalne
dane demonstracyjne zostają lokalnie — nie ma tu żadnego zrzutu do przeniesienia.

### Co warto backupować

Odtwarzalne bez kopii zapasowej są: **kluby** (przycisk „Wstaw skład"),
**terminarz** (przycisk „Pobierz terminarz") i **cała tabela** — ta liczy się od
zera z punktów uczestników przy każdym przeliczeniu.

Nie do odtworzenia są trzy rzeczy i tylko o nie chodzi w kopii zapasowej:

- **punkty uczestników za kolejki** (`manager_round_score`) — to jedyne źródło
  prawdy o przebiegu sezonu;
- **uczestnicy i ich przypisanie do klubów** (`manager`);
- **kody zaproszeń** wraz z informacją, który jest zużyty (`invite_code`).

Kopie zapasowe włączasz w panelu OVH. Przed zamknięciem sezonu warto zrobić
zrzut ręcznie.

## Wdrożenie

```
bundle install
bundle exec cap production deploy
```

Po wydaniu Capistrano sam uruchamia migracje i przygotowuje pamięć podręczną.
Aplikacja nie ma budowania frontendu: Tabler przychodzi z pakietem (composer
sam robi `assets:install`), a herby klubów leżą w repozytorium.

## Konfiguracja domeny

Aplikacja stoi pod `ucl.glad-it.pl`.

**Katalog domeny musi wskazywać na `public/` wewnątrz bieżącego wydania.** W
panelu OVH katalog główny podaje się względem katalogu domowego, więc wpisz:

```
ucl/current/public
```

Przepisywanie adresów zapewnia `public/.htaccess` w repozytorium. Bez niego
działa wyłącznie strona główna, a każdy inny adres zwraca 404.

Ustawienie katalogu na korzeń projektu wystawiłoby na świat kod źródłowy i plik
`.env.local` z hasłem do bazy.

**Włącz HTTPS.** Hasło administratora leci w formularzu tekstem jawnym, a kody
zaproszeń rozsyłasz linkiem. OVH daje darmowy certyfikat.

## Pierwsze uruchomienie na czystej bazie

Po pierwszym wdrożeniu baza ma sam schemat. Załóż konto administratora:

```
php bin/console app:admin:create twoj@email.pl twoje-haslo --env=prod
```

Resztę robisz przez przeglądarkę, w panelu:

1. **Nowe rozgrywki** — nazwa, sezon, tryb (1 vs 1 albo pary).
2. **Kluby** → „Wstaw skład Ligi Mistrzów" — 36 klubów bieżącej edycji.
3. **Terminarz** → „Pobierz terminarz Ligi Mistrzów" — oryginalny terminarz fazy
   ligowej, sprawdzany przed zapisem.
4. **Kody** → „Wygeneruj" — po jednym kodzie na wolne miejsce; uczestnicy wchodzą
   na `https://ucl.glad-it.pl/<slug>/dolacz`.

## Ruch wychodzący: tylko z przeglądarki, nie z konsoli

**Hosting współdzielony OVH blokuje ruch wychodzący z linii poleceń.** Komendy
`app:schedule:import` i `app:clubs:logos` uruchomione przez SSH albo przez
zadanie cykliczne OVH nie dosięgną internetu i skończą się błędem połączenia.
Z poziomu Apache ruch wychodzący działa normalnie, więc **te same operacje
wykonane przyciskiem w panelu przechodzą bez przeszkód**. Tej blokady nie da się
zdjąć — to ograniczenie platformy.

Punktów uczestników i tak nie da się pobrać automatycznie: `gaming.uefa.com` nie
ma publicznego API, więc leaderboard wkleja się ręcznie w panelu.

## Herby klubów

36 herbów leży w repozytorium (`public/images/clubs`), więc każde wydanie ma je
od razu. Katalog nie jest współdzielony między wydaniami — herby pobrane
przyciskiem na serwerze zniknęłyby przy następnym wdrożeniu. Po zmianie składu na
nowy sezon pobierz je **lokalnie** i zacommituj:

```
php bin/console app:clubs:logos <slug>
git add public/images/clubs && git commit -m "herby nowego sezonu"
```

## Nowy sezon

Skład klubów, ich identyfikatory UEFA i adres strony z terminarzem siedzą w
jednym pliku: `src/Uefa/ClubCatalogue.php`. Podmieniasz go raz na sezon i tyle.
