Files
portal/docs/deploy/test-server-runbook.md
T

131 lines
9.2 KiB
Markdown
Raw Normal View History

# Лидерра — тест-сервер (Yandex Cloud) — runbook
**Создан:** 2026-05-21. Тестовое окружение для ручной проверки (заказчик + Claude). Не продакшен.
Спека: `docs/superpowers/specs/2026-05-21-test-deploy-yandex-cloud-design.md`.
План: `docs/superpowers/plans/2026-05-21-test-deploy-yandex-cloud.md`.
## Доступ
- **URL (HTTP, временно):** `http://111.88.246.137` — статический IP YC.
- **HTTPS / домен:** добавляется после покупки домена (см. «Включить HTTPS»).
- **Дверь сайта (HTTP Basic Auth):** логин `liderra` — пароль в `/home/ubuntu/liderra-secrets.txt` на сервере (ключ `basic_auth`).
- **Демо-вход в портал:** `admin@demo.local` / `password` (tenant `demo`, 3 проекта, демо-сделки).
- **SSH:** `ssh -i ~/.ssh/liderra_deploy ubuntu@111.88.246.137` (ключ на dev-машине; пароль входа отключён).
- **YC:** облако `cloud-sasha261185`, каталог `default`, VM `liderra-test` (ru-central1-a, 2vCPU/2GB/20%), SG `liderra-test-sg` (22/80/443).
## Состав
- Ubuntu 24.04: nginx (Basic Auth, webhook `/api/webhook/*` без auth) → PHP-FPM 8.3 → Laravel.
- PostgreSQL 16 (БД `liderra`), Redis (sessions+cache+queue, predis).
- Код в `/var/www/liderra/app`; фронтенд `public/build` (собирается на dev, заливается scp).
- Службы: `liderra-queue.service` (queue worker, systemd, enabled) + cron `/etc/cron.d/liderra-scheduler` (schedule:run). Все автозапускаются после ребута.
## Важные отклонения от прод-дизайна (на решение позже)
- **DB-роль приложения = `crm_app_user` (RLS включена)** — изоляция бизнес-данных между клиентами
**работает** (deals/projects/billing/… строгие политики). Чтобы вход работал под строгой ролью,
RLS-политики на таблицах `users` + `auth_log` сделаны «дружелюбными ко входу»: пропускают запрос,
когда tenant-контекст ещё не установлен (auth/login), и фильтруют по тенанту после. Это server-only
правка политик (не в schema.sql); для прода — кандидат в нормативную схему.
- **Админка SaaS `/admin/*` под `crm_app_user` НЕ работает** (нет доступа к saas-таблицам — REVOKE).
Для теста «от лица клиентов» не нужна. Понадобится — переключать admin-запросы на `crm_admin_user`
(connection-switch в middleware `EnsureSaasAdmin`) — отдельная доработка.
- **`SAAS_ADMIN_TEST_BYPASS=true`** — временный флаг (для будущей админки). Убрать после Yandex SSO (Б-1).
- **Почта** = `log` (письма в файл). **APP_DEBUG=false**, **APP_ENV=production**.
- Установлены dev-зависимости (faker нужен для сидов).
## Тестовые клиенты
| Логин | Пароль | Компания |
|---|---|---|
| `admin@demo.local` | `password` | Demo (3 проекта + демо-сделки) |
| `client1@liderra.test` | `password` | Компания 1 (2 проекта) |
| `client2@liderra.test` | `password` | Компания 2 (2 проекта) |
| `client3@liderra.test` | `password` | Компания 3 (2 проекта) |
| `client4@liderra.test` | `password` | Компания 4 (2 проекта) |
Изоляция проверена вживую: каждый видит только свои проекты (HTTP-логин + `/api/projects`).
## Каналы миграции с поставщиком (настроены 2026-05-21)
Все 3 канала с `crm.bp-gr.ru` подняты и проверены вживую на тест-сервере.
### Предпосылки (доустановлены сверх базового деплоя — в исходном runbook их не было)
- **Node.js 20** (NodeSource) + **Playwright** (`app/playwright/node_modules`, `npm install`) + **Chromium**
в `/var/www/.cache/ms-playwright/` (HOME у `www-data` = `/var/www`; ставить через
`sudo HOME=/var/www .../playwright install chromium` затем `chown -R www-data:www-data /var/www/.cache`,
иначе artisan от www-data не находит браузер). Без них логин к поставщику (Yii2-форма, JS) не работает
→ CSV-сверка и экспорт мертвы (`PlaywrightBridge exit code 127: node: not found`).
- `PlaywrightBridge::TIMEOUT_SECONDS` поднят **75 → 180** (`app/app/Services/Supplier/PlaywrightBridge.php`):
на 2 ГБ VM холодный старт Chromium ~65 c, в 75 не укладывался. Бэкап `*.bak.20260521`.
- `.env`: `SUPPLIER_LOGIN` / `SUPPLIER_PASSWORD` (те же, что на dev). Бэкап `.env.bak.20260521-*`.
- `system_settings.supplier_webhook_secret` — 48-hex (DemoSeeder ставит короткий → guard `<32` → webhook молча 404).
Копия в `/home/ubuntu/liderra-secrets.txt`.
- `system_settings.supplier_ip_allowlist` = `["0.0.0.0/0"]` — на `APP_ENV=production` пустой массив fail-closed (404 всем).
**TODO: сузить** до IP поставщика (в логе видели `92.53.65.242`).
### Канал 1 — приём webhook'а (вход, основной)
- POST `http://111.88.246.137/api/webhook/supplier/<secret>` (nginx `^~ /api/webhook/` без Basic Auth).
- Проверено: правильный secret → 202, дубль `vid` → 200 `already_processed`, битый secret → 404.
### Канал 2 — CSV-дочерпывание (вход, резерв)
- `CsvReconcileJob`, scheduler каждые 30 мин (cron `schedule:run` ежеминутно). Прогон вживую: 185 строк, status `ok`, drift 0.
- Ручной запуск: `sudo -u www-data php artisan tinker --execute='App\Jobs\Supplier\CsvReconcileJob::dispatchSync()'`.
### Канал 3 — экспорт проектов (выход)
- `SupplierProjectChannel::createProject` / `SupplierPortalClient::deleteProject`. Проверено: create+delete
тестового проекта (`external_id=12764235`), сверка `listProjects` — следов у поставщика нет.
### Supplier-портал
- `crm.bp-gr.ru → /admin/user/api`: «Апи ссылка» = `http://111.88.246.137/api/webhook/supplier/<secret>`,
«Апи протокол» = HTTP, «Апи статус» = Активный. Поставщик HTTP-URL принимает.
- ⚠️ Поле URL **одно** → после переключения на тест-сервер dev-машина живых лидов **не получает**.
- Сессия логина: Redis DB 1, ключ `liderra-database-liderra-cache-supplier:session` (TTL 6h, refresh-крон/`supplier:session:refresh`).
### Сделать позже
- Привязать `client1..4` к реальным каналам поставщика через pivot `project_supplier_links` (иначе лиды = ghost без сделок).
- HTTPS после покупки домена → URL у поставщика на https.
- Сузить `supplier_ip_allowlist`.
## Обновить версию
На dev-машине:
```powershell
npm --prefix app run build
git -C <repo> archive --format=tar HEAD app db -o $env:TEMP\liderra.tar
scp -i ~/.ssh/liderra_deploy $env:TEMP\liderra.tar ubuntu@111.88.246.137:/tmp/
scp -i ~/.ssh/liderra_deploy -r app\public\build ubuntu@111.88.246.137:/tmp/build
```
На сервере:
```bash
tar -xf /tmp/liderra.tar -C /var/www/liderra
rm -rf /var/www/liderra/app/public/build && cp -r /tmp/build /var/www/liderra/app/public/build
bash /var/www/liderra/redeploy.sh
```
## Включить HTTPS (после покупки домена)
1. DNS: A-запись `test.<домен>` (и/или `demo.<домен>` для subdomain-tenant) → `111.88.246.137`.
2. На сервере: в `/etc/nginx/sites-available/liderra` заменить `server_name _;` на домен, `nginx -t && systemctl reload nginx`.
3. `sudo certbot --nginx -d test.<домен> --non-interactive --agree-tos -m <email> --redirect`.
4. В `.env` обновить `APP_URL=https://test.<домен>`, затем `php artisan optimize`.
## Остановить / удалить (прекратить оплату)
- Остановить VM: `yc compute instance stop liderra-test` (диск/IP сохраняются, мелкая плата).
- Удалить совсем: `yc compute instance delete liderra-test` + `yc vpc address delete <id>`.
## После теста — обязательно
- **Отозвать OAuth-токен Yandex Cloud** (Яндекс ID → Безопасность → сторонние приложения).
- При переходе к прод-конфигу: убрать `SAAS_ADMIN_TEST_BYPASS`, вернуть `crm_app_user` (после auth-rework).