# Лидерра — тест-сервер (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/` (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/`, «Апи протокол» = 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 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 --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 `. ## После теста — обязательно - **Отозвать OAuth-токен Yandex Cloud** (Яндекс ID → Безопасность → сторонние приложения). - При переходе к прод-конфигу: убрать `SAAS_ADMIN_TEST_BYPASS`, вернуть `crm_app_user` (после auth-rework).