diff --git a/docs/observer/STATUS.md b/docs/observer/STATUS.md index 09a75ac7..5e99b459 100644 --- a/docs/observer/STATUS.md +++ b/docs/observer/STATUS.md @@ -1,6 +1,6 @@ # Brain Status (auto-generated) -Last updated: 2026-06-28T07:23:41.603Z +Last updated: 2026-06-28T08:09:57.221Z | Контролёр | Состояние | Детали | |---|---|---| @@ -125,9 +125,9 @@ Episodes since last run: 542 / threshold: 10 | PID | Имя | CPU-время | Возраст | |---|---|---|---| -| 3440 | MsMpEng | 17.50ч | 0.0ч | -| 21928 | Code | 7.75ч | NaNч | -| 1212 | svchost | 4.46ч | 0.0ч | +| 3440 | MsMpEng | 17.61ч | NaNч | +| 21928 | Code | 7.87ч | 0.0ч | +| 1212 | svchost | 4.49ч | NaNч | ⚠️ Проверь, не «осиротевшие» ли это процессы от завершённых Claude-сессий. diff --git a/ПИЛОТ.md b/ПИЛОТ.md index adc8c1aa..ea6a0714 100644 --- a/ПИЛОТ.md +++ b/ПИЛОТ.md @@ -8,7 +8,13 @@ - Волатильную часть (доступ, версии, что развёрнуто) перед рискованными действиями **перепроверять реальной командой по SSH**, не доверять снимку вслепую. - Обновляется по команде заказчика **«обнови пилот»**. -> 🟢 **АКТУАЛЬНО (26.06.2026) — перебивает любые упоминания «ждут ООО / Б-1 / осталось подписать» в снимках ниже:** юр. лицо — **ИП, зарегистрировано** (НЕ ООО). **Договор с ЮKassa ПОДПИСАН 26.06** (№НЭК.448000.01), магазин **1392092** активен, приём платежей **включён со стороны ЮKassa**, СБП подключён, `info@liderra.ru` подтверждён. На проде заведены юрлицо+шлюз+webhook (см. снимок go-live ниже). **Остался последний шаг — включить флаг `billing_yookassa_enabled`** (+ живой тест) для перевода оплаты в боевой режим. «Регистрация ООО» как блокер — **снято, не актуально.** +> 🟢 **АКТУАЛЬНО (26.06.2026) — перебивает любые упоминания «ждут ООО / Б-1 / осталось подписать» в снимках ниже:** юр. лицо — **ИП, зарегистрировано** (НЕ ООО). **Договор с ЮKassa ПОДПИСАН 26.06** (№НЭК.448000.01), магазин **1392092** активен, приём платежей **включён со стороны ЮKassa**, СБП подключён, `info@liderra.ru` подтверждён. На проде заведены юрлицо+шлюз+webhook (см. снимок go-live ниже). **Флаг `billing_yookassa_enabled` — ВКЛЮЧЁН (подтверждено 27.06 на кластере, намеренно, штатное состояние по решению владельца).** НО **go-live онлайн-оплаты НЕ завершён:** успешной живой оплаты ещё не было (см. свежий снимок 27.06 ниже — 5 тестовых попыток 100₽ отменены на стороне ЮKassa, `paid=false`, деньги не списаны; happy-path «оплата→webhook→зачисление» в бою не проверялся; webhook IP-allowlist пуст). «Регистрация ООО» как блокер — **снято, не актуально.** + +**Снимок снят:** 28.06.2026 (~11:20 UTC) — **🔴→🟢 НАЙДЕН И ПОЧИНЕН ТИХО СЛОМАННЫЙ БИЛЛИНГ-СТОРОЖ + playwright durable + дашборд балансов/вложенности на проде.** По команде владельца «закрывай хвосты». **Главное — баг биллинга:** после переезда на Managed PG (26.06) очередь `liderra-queue` ходит в БД под ролью `crm_app_user` (RLS), и `BalancePreflightSweepJob`/`BalanceFrozenReminderJob` перебирали тенантов через `Tenant::query()` БЕЗ `app.current_tenant_id` → policy `tenants_self_isolation` отдавала **0 строк** → ночной преflight @18:00 МСК **молча стал no-op с 26.06** (heartbeat зелёный, `balance_freeze_log` пуст, ни заморозок бедных, ни снятия блоков у профинансированных). Симптом — 4 застрявших `preflight_blocked` проекта. **Фикс:** список тенантов теперь через `pgsql_supplier` (BYPASSRLS), модель грузится внутри per-tenant `SET LOCAL`. Тесты Billing 18/18, pint/phpstan чисто. **gitea/main + прод = `75dded78`** (cherry-pick поверх `cab0347f`; выкат `bin/deploy-source-edit.sh`, БД миграциями не тронута). **Прогнал sweep вручную на проде — самоисцеление подтверждено:** t25 (10090₽)→сняты блоки 2 проектов (omega/lkomega), t26 (300₽)→снят блок 1, t27 (тест example.org)→заморожен, t30 (`kaa_555@bk.ru`, 20₽ реальный)→заморожен + письмо «пополните»; `balance_freeze_log` снова пишет. **Деньги целы: t2 = 1 839 405 ₽** (до==после). **Playwright «несносимый»:** объявлен в `app/package.json → dependencies` ровно `1.59.0` (под browser chromium-1217) + lock; деплой получил шаг 6d `npm ci --omit=dev --legacy-peer-deps` (только прод-деп, без тяжёлого фронт-дерева, без скачивания браузера) → переживёт будущие чистки `node_modules` (корень падения синхрона 27.06). Поставлен на прод (3 пакета). **Дашборд (выкачено ранее 28.06):** плитка «Балансы сервисов» + «Пополнить», плитка «Клиенты», экран «Лиды» (серверная пагинация) + карточка лида (цепочка до источника), выбор периода. **🟡 Следующим заходом (решение владельца):** экран «Тенанты» на серверную пагинацию/фильтры для 1000 клиентов. **🔴 YC в минусе −606₽:** пополнить `console.yandex.cloud/billing/accounts/dn2w7fcvynjxe6elljct/payments`. Кодовая фраза стены — «роутер-наставник». + +**Снимок снят:** 27.06.2026 (~10:40 UTC) — **🟢 ВЫКАЧЕНО на боевой: (1) снят лишний лимит по ЧИСЛУ проектов, (2) подсказка «Как увеличить количество сделок» в диалоге проекта.** По команде владельца (онлайн-наблюдение за работающим клиентом + правки его затыков). **gitea/main + прод = `fa736136`** (продвинут моими выкатами `c7e015a9`→`7ac9af7c`→`fa736136`; ссылка на `c7e015a9` в снимке ~13:00 ниже — стейл/concurrent). **Что сделано:** (1) убран гейт `max_projects` в `ProjectService::create` + поле `active_projects.limit` с дашборда — **правило продукта: лимита по числу проектов НЕТ, только по балансу/заказанным лидам**; у всех тенантов `tenants.limits={}` → код брал дефолт `?? 10` и ложно блокировал tenant 2 (117 проектов) с «Достигнут лимит проектов (10)»; `max_users`/`api_rps` — мёртвые ключи (только в комментариях), колонка `limits` оставлена. (2) подсказка с tooltip в `NewProjectDialog.vue` над «Откуда собирать заявки». **Метод выката:** `bin/deploy-source-edit.sh` — **ПОЧИНЕН под кластер** (убраны DB-шаги через `sudo -u postgres` = старая rollback-база на VM; миграции теперь `php artisan migrate --force` в кластер по `.env`, для код-онли = «Nothing to migrate»); скрипт gitignored (внутри пароль gitea). **Verify:** HTTP **200** (главная+login), подсказка в живой сборке `ProjectsView-CSdkdAXR.js`, гейт лимита в боевом коде = 0 совпадений, **деньги целы tenant 2 = 1 839 600 ₽ / 999 731 лид**, миграций нет (БД не тронута). **Бэкап кода на проде** `/tmp/app-backup-2026-06-27-*.tgz`. **🔴 ОТКРЫТЫЙ БАГ (наблюдение по логам 27.06):** сессия клиента **рвётся через ~8–10 мин активной работы** (НЕ таймаут: `SESSION_LIFETIME=120` мин, Redis здоров/noeviction) + интерфейс молчит вместо «войдите заново» (сыпет 401 в фон) → клиент видит пустую страницу. Также путаница паролей у владельца (вводил пароль от `kdv1@bk.ru` на `info@lkomega.ru`; вход — `info@lkomega.ru`/`Liderra2026!`). Разбор: `docs/superpowers/findings/2026-06-27-live-client-observation.md` + `…/2026-06-27-remove-project-count-limit.md`. **Параллельная сессия** работала локально на ветке `feat/admin-command-center` (её коммит `1a92b702` в main НЕ влит — изолировал свои правки worktree+cherry-pick). Кодовая фраза стены — «роутер-наставник». + +**Снимок снят:** 27.06.2026 (~13:00 UTC) — **🔎 АУДИТ «пропавших правок» (байт-в-байт git↔прод) + РАЗБОР статуса онлайн-оплаты ЮKassa. Прод НЕ менялся — только чтение.** По запросу владельца «на проде пропала куча правок — найди всё, сверяй байт-в-байт». **Сквозная байт-в-байт сверка 1125 файлов `app/`+`db/` (git-blob-хеши ↔ `git hash-object` на проде):** код приложения `app/` — **100% идентичен git** (`c7e015a9`, он же gitea/main), ни одной пропавшей/откатившейся правки; фронт пересобран 27.06 07:51 UTC (свежий). Единственный дрейф — справочные `db/*.sql` на диске сервера заморожены на 25.06 (заголовок schema.sql v8.53), git и живая база — v8.57; **реальной потери нет** (эти файлы — исходники на диске, портал их в рантайме не читает; изменения 26.06 применены к живому кластеру и лежат в git). **Живая база-кластер (read-only через `pgsql_supplier`):** флаги фич все ВКЛ (`routing_match_by_snapshot=true`, `supplier_export_mode=online` — ничего не сбросилось при переезде), баланс клиента tenant 2 = **999 731 лид / 1016 сделок (990 актив.)** == эталон 26.06. **💳 ОБНАРУЖЕНО и РАЗОБРАНО: `billing_yookassa_enabled=true` — онлайн-оплата ВКЛ (намеренно, штатно), НО go-live НЕ завершён.** В `saas_transactions` 5 попыток пополнения 100₽ (26–27.06), все `pending`; запрос статуса у самой ЮKassa (read-only GET `verifyPayment`): все 3 с `gateway_payment_id` = **`canceled`** (оплата не завершена → не оплачено); детально проверен P6 — `paid=false`, причина **`expired_on_confirmation`** (оплату не довели до конца, через СБП). **Денег НЕ списано, баланс клиента цел.** Webhook в логах nginx — **0 обращений** (успешных платежей не было → нечего слать). **Итог: успешной живой оплаты ещё НЕ было — happy-path «оплата→webhook→зачисление» в бою не проверялся ни разу** (код под Pest-тестами, но end-to-end вживую — нет). **Хвосты go-live:** (1) `YOOKASSA_WEBHOOK_IPS` пуст (fail-open); (2) система ловит только `payment.succeeded`, `payment.canceled` не обрабатывает → отменённые висят `pending` навечно; (3) тесты гоняли на боевом `tenant 2` вместо тестового `tenant 28` «Демо-доступ для ЮKassa». **Откат оплаты:** флаг `billing_yookassa_enabled=false` — мгновенно. Кодовая фраза стены — «роутер-наставник». **Снимок снят:** 26.06.2026 (~13:40 UTC) — **💳 ЮKassa ONLINE-ОПЛАТА — НАСТРОЕНА на проде (шаги 2–4а ранбука), ФЛАГ ещё ВЫКЛ. Прод-код НЕ менялся.** По команде владельца «занимайся». **Со стороны ЮKassa всё включено:** заявка одобрена, **договор подписан** по СМС (№НЭК.448000.01 от 26.06), магазин **ShopID 1392092** (юрлицо ИП Кондратьев П.Д., ИНН 245210851872, ОГРНИП 326246800098042), **приём платежей ВКЛЮЧЁН** (письмо ЮMoney «Приём платежей включен»), **СБП подключён**, `info@liderra.ru` подтверждён. Секретный API-ключ выпущен (`live_…P8RI`). **Код интеграции 100% готов и под тестами** (драйвер/`OnlineTopupService`/`PaymentWebhookController` server-to-server+идемпотентность/админ-ввод ключей/развилка флага в `BillingController::topup()`, 12+ Pest зелёные) — ранбук `docs/superpowers/runbooks/2026-06-24-yookassa-online-payment-enable.md`. **Сделано на проде (в КЛАСТЕРНОЙ managed-базе, через Eloquent-бутстрап под www-data — НЕ через peer-psql!):** `legal_entities` ИП **id=1** (`ip_kondratev`, `vat_mode='usn_6'` — подтвердить у владельца УСН 6/15; банк/адрес позже), `payment_gateways` **yookassa id=2 is_active=true** (config зашифрован `Crypt::encrypt`, shop_id 1392092 + secret, `credentials()` roundtrip ок), webhook в кабинете ЮKassa **payment.succeeded → `https://liderra.ru/api/webhook/payment`**. **🔴 ОСТАЛОСЬ (за владельцем):** (5) включить флаг `billing_yookassa_enabled=true` в **кластере** + `cache:clear` + restart php-fpm (рубильник: пополнение у всех клиентов станет реальной оплатой; откат мгновенный — флаг в ВЫКЛ); (6) живой тест 100 ₽ с тестового тенанта (НЕ client1/tenant2); (4б, hardening) IP-allowlist `YOOKASSA_WEBHOOK_IPS` (сейчас пусто = fail-open; защита есть — сверка суммы/статуса + идемпотентность). **⚠️ GOTCHA:** на прод-VM `sudo -u postgres psql` = СТАРАЯ локальная rollback-БД (после переезда на managed), НЕ живой кластер — данные приложения менять только через app/Eloquent (`/var/www/liderra/app/`) или psql к хосту кластера; команды psql из ранбука 24.06 по этому пункту устарели. **💰 Деньги клиента ЦЕЛЫ** (добавлены лишь справочные строки юрлица/шлюза): tenant 2 = **1 838 400.00 ₽ / 1016 сделок**. Снимки кабинета/прода: `yookassa-*-2026-06-26.png` в корне. Кодовая фраза стены — «роутер-наставник».