# Розгортання GameMarket на хостингу (cPanel + консоль)

Інструкція розрахована на хостинг, де є **і cPanel, і доступ по SSH/термінал** (власний SSH-клієнт або вбудований «Terminal» в cPanel → Advanced). Стек: Laravel 12, Filament v3, Laravel Breeze, MariaDB/MySQL.

## 0. Вимоги до хостингу

Перевір у cPanel → **Select PHP Version**:
- PHP **8.3+** (в проєкті `"php": "^8.3"` у `composer.json`)
- Розширення: `bcmath`, `ctype`, `curl`, `fileinfo`, `json`, `mbstring`, `openssl`, `pdo_mysql`, `tokenizer`, `xml`, `gd` або `imagick` (для обробки зображень акаунтів), `zip`

Також потрібні:
- MySQL/MariaDB база (cPanel → **MySQL Databases**)
- `composer` в SSH (у більшості cPanel-хостингів вже є `composer` як команда; якщо ні — `curl -sS https://getcomposer.org/installer | php`)

На цьому хостингу **немає ні Redis, ні Node.js** — обидва пункти нижче написані саме під цю реальність (без «якщо»/альтернатив): фронтенд збирається локально (крок 1), черга йде через MySQL + cron (крок 11).

## 1. Підготовка коду локально

На сервері Node.js немає, тож збірка Vite-асетів (Tailwind/Alpine) робиться **лише локально**, перед кожним деплоєм:

```bash
# в проєкті, локально (через Sail або напряму)
npm install
npm run build
```

Це створить `public/build/`. На відміну від `public/css`/`public/js` (Filament-асети, регенеруються на сервері через `php artisan filament:assets`, без Node.js), `public/build/` **закомічена в git** — сервер без Node.js сам її зібрати не може, тому готові файли їдуть разом із кодом. Після кожної зміни в Blade/CSS/JS: збери локально й закомить `public/build/` разом з рештою змін, перш ніж робити `git push`.

## 2. Завантаження файлів на сервер

**Варіант А — через git (рекомендовано, якщо є GitHub/GitLab-репозиторій):**
```bash
ssh username@yourhost.com
cd ~
git clone <URL_репозиторію> gamemarket
cd gamemarket
```

**Варіант Б — без git:** заархівувати проєкт (без `vendor/`, `node_modules/`, `.git/`) і залити через File Manager або `scp`, розпакувати в SSH:
```bash
unzip gamemarket.zip -d ~/gamemarket
```

## 3. Структура папок і document root

Laravel очікує, що веб-сервер дивиться на папку `public/`, а не на корінь проєкту — це найважливіший cPanel-специфічний момент.

**Якщо домен — не головний (аддон-домен/піддомен):**
У cPanel → **Domains** знайди домен і встанови **Document Root** одразу на:
```
/home/username/gamemarket/public
```
Тоді решта проєкту (`app/`, `.env`, `vendor/` тощо) лишається поза публічним доступом — найбезпечніший варіант, більше нічого робити не треба.

**Якщо домен головний і document root змінити не можна (лишається `public_html`):**
1. Перенеси весь проєкт в `~/gamemarket` (поза `public_html`)
2. Скопіюй вміст `~/gamemarket/public/*` у `public_html/`
3. Відредагуй `public_html/index.php` — заміни два рядки:
```php
require __DIR__.'/../vendor/autoload.php';
// на:
require __DIR__.'/../gamemarket/vendor/autoload.php';

$app = require_once __DIR__.'/../bootstrap/app.php';
// на:
$app = require_once __DIR__.'/../gamemarket/bootstrap/app.php';
```

## 4. База даних

cPanel → **MySQL® Databases**:
1. Створи базу (наприклад `username_gamemarket`)
2. Створи користувача з паролем
3. Додай користувача до бази з **усіма правами (ALL PRIVILEGES)**

cPanel завжди додає префікс `username_` до імені бази й користувача — врахуй це в `.env`.

## 5. Файл `.env`

В корені проєкту (НЕ в `public_html`, якщо розділяли папки):
```bash
cp .env.example .env
php artisan key:generate
```

Відредагуй `.env`:
```env
APP_NAME=GameMarket
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=username_gamemarket
DB_USERNAME=username_dbuser
DB_PASSWORD=пароль_з_кроку_4

# Черги — на shared-хостингу зазвичай немає Redis,
# тому переходимо на MySQL-чергу (таблиця jobs вже є в міграціях)
QUEUE_CONNECTION=database
CACHE_STORE=database
SESSION_DRIVER=database

# Реальна пошта замість MAIL_MAILER=log (див. крок 8)
MAIL_MAILER=smtp
MAIL_HOST=mail.yourdomain.com
MAIL_PORT=465
MAIL_USERNAME=noreply@yourdomain.com
MAIL_PASSWORD=пароль_поштової_скриньки
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=noreply@yourdomain.com
MAIL_FROM_NAME="${APP_NAME}"

TELEGRAM_BOT_TOKEN=8533708631:AAE-YezBdBKUkZPqHcb9NZrl5jljyCDh4qI
```

**Важливо:** `APP_KEY` генерується один раз під час першого деплою і більше НЕ змінюється — від нього залежить розшифрування `login`/`password`/`credentials_note` акаунтів (`encrypted`-каст у `App\Models\Account`). Втратиш ключ — втратиш усі виданні дані акаунтів, як це вже сталось локально (див. пам'ять проєкту про інцидент з OneDrive).

## 6. Встановлення залежностей

```bash
composer install --optimize-autoloader --no-dev
```

`--no-dev` пропускає PHPUnit, Faker, Pail — вони не потрібні на проді.

## 7. Filament-асети

`public/css` і `public/js` навмисно в `.gitignore` (регенеруються, не мають сенсу в git) — тому їх треба опублікувати на сервері одразу після `composer install`:
```bash
php artisan filament:assets
```

## 8. Права доступу

```bash
chmod -R 775 storage bootstrap/cache
```
На більшості cPanel-хостингів PHP виконується від того ж юзера, що й файли (suPHP/CloudLinux MPM), тому власника міняти не потрібно.

## 9. Symlink для завантажених файлів

Скріншоти акаунтів та логотипи ігор віддаються через `public/storage` → `storage/app/public`:
```bash
php artisan storage:link
```
Якщо хостинг забороняє symlink (рідко, але буває на дешевих shared-тарифах) — альтернатива: скопіювати вміст руками й додати cron, що синхронізує папку, або звернутись у підтримку хостингу з проханням дозволити `symlink()`.

## 10. Міграції та адмін

```bash
php artisan migrate --force
```

Створити адміністратора (сідер створює `admin@gamemarket.test`/`password` — обов'язково зміни пароль одразу після деплою, або створи адміна вручну):
```bash
php artisan tinker
>>> \App\Models\User::create(['name' => 'Admin', 'email' => 'you@real-email.com', 'password' => bcrypt('надійний-пароль'), 'is_admin' => true, 'email_verified_at' => now()]);
```

Демо-акаунти (`AccountSeeder`) на проді краще НЕ запускати — це тестові дані для розробки.

## 11. Черги (queue) через Cron

Redis тут немає, тому в `.env` — `QUEUE_CONNECTION=database` (крок 5, таблиця `jobs` вже є в міграціях). Постійний воркер (`queue:work`, як сервіс `queue` в `compose.yaml`) тут не піднімеш — shared-хостинг вбиває довгі процеси. Замість цього — cPanel **Cron Jobs** щохвилини:

```
* * * * * cd /home/username/gamemarket && php artisan queue:work --stop-when-empty --tries=3 >> /dev/null 2>&1
```

Це стосується листа `OrderDelivered` (видача даних акаунта після оплати) — він іде через чергу, тому без цього cron не надішлеться взагалі. `EmailVerificationCode` (код підтвердження email) навпаки надсилається синхронно — прийде одразу, окремого крону не потребує.

## 12. Пошта (SMTP)

cPanel → **Email Accounts** → створи скриньку (наприклад `noreply@yourdomain.com`). Дані з неї — в `.env` (крок 5). Без цього кроку `MAIL_MAILER=log` писатиме коди підтвердження й листи про видачу акаунтів лише в `storage/logs/laravel.log`, і реальні користувачі нічого не отримають.

## 13. SSL

cPanel → **SSL/TLS Status** → **AutoSSL** (безкоштовний Let's Encrypt, зазвичай уже увімкнений за замовчуванням). Перевір, що `APP_URL` в `.env` — з `https://`.

## 14. Фінальна оптимізація

```bash
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
```

**Увага:** після будь-якої зміни `.env` треба перевиконати `php artisan config:cache` (при кешованому конфігу зміни `.env` НЕ підхоплюються автоматично).

## 15. Перевірка після деплою

- [ ] Головна сторінка відкривається, вітрина показує акаунти
- [ ] `/admin` — логін адміністратора працює
- [ ] Реєстрація нового користувача → приходить лист з кодом підтвердження на реальну пошту
- [ ] Гостьове оформлення замовлення → сторінка трекінгу відкривається
- [ ] В адмінці «Позначити оплаченим» → приходить лист з даними акаунта (перевіряє і крок 11, і крок 12 разом)
- [ ] Чат-віджет відкривається, повідомлення надсилається, приходить сповіщення в Telegram
- [ ] Завантаження скріншота нового акаунта (форма «Продати акаунт») — фото відображається (перевіряє крок 9)

## 16. Оновлення проєкту в майбутньому

Локально, перед пушем — якщо міняв Blade/CSS/JS:
```bash
npm run build
git add public/build
git commit -m "Rebuild frontend assets"
git push
```

На сервері:
```bash
cd ~/gamemarket
git pull
composer install --optimize-autoloader --no-dev
php artisan filament:assets
php artisan migrate --force
php artisan optimize:clear && php artisan config:cache && php artisan route:cache && php artisan view:cache
```
