From 1154c9752b61ba7b147a5725b471a5af7d61db56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 22 May 2026 20:09:43 +0300 Subject: [PATCH] =?UTF-8?q?docs(pilot):=20orphan=20sp=20cleanup=20+=20csv?= =?UTF-8?q?=5Freconcile=20warning=E2=86=92info=20(146501ba)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Снимок «поздний вечер +2»: 4 truly-orphan supplier_projects удалены (id 57/73/77/79 — placeholders/тестовые/malformed URL), параллельный log-спам csv_reconcile.unparseable_project_skipped даунгрейднут до info. Поставки клиентов не затронуты (16 leads → 0 deals, info@lkomega.ru ok). --- docs/observer/STATUS.md | 6 +++--- ПИЛОТ.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/observer/STATUS.md b/docs/observer/STATUS.md index 898a83a5..00aeda6c 100644 --- a/docs/observer/STATUS.md +++ b/docs/observer/STATUS.md @@ -1,6 +1,6 @@ # Brain Status (auto-generated) -Last updated: 2026-05-22T16:47:17.889Z +Last updated: 2026-05-22T17:08:02.684Z | Контролёр | Состояние | Детали | |---|---|---| @@ -8,12 +8,12 @@ Last updated: 2026-05-22T16:47:17.889Z | C2 Cross-ref consistency | ✅ | [cross-ref-checker] OK — 0 drift in 4 files | | C3 Observer-of-observer | ✅ | [observer-of-observer] OK — last read 0 week(s) ago | | C4 Сигнальный статус | ✅ | This file (self-reference) | -| C5 Observer-coverage | ⚠️ | 84 episode(s) this month · Stop-hook + post-commit OK · 30 missed activation(s) — see /brain-retro | +| C5 Observer-coverage | ⚠️ | 85 episode(s) this month · Stop-hook + post-commit OK · 30 missed activation(s) — see /brain-retro | | C6 Chain map sync | 🔴 | В .md есть цепочки без записи в JSON: L16 — добавьте узлы в tools/observer-chain-map.json | ## Метрики (информационные, не алерты) -- Observer evidence: 84 episodes this month, 0 observer_error markers, 14 PII matches before filter +- Observer evidence: 85 episodes this month, 0 observer_error markers, 14 PII matches before filter - Legacy v1 episodes (not in factor analysis): 5 - Last /brain-retro: 3 day(s) ago - Использование узлов: см. `/brain-retro` (раз в спринт). missed_activations: 30. **Неиспользованные узлы — не алерт, если профильной задачи не было** (Pravila §16.4 v1.36; capability-readiness; см. memory `feedback_brain_unused_tools_not_problem` — outside-repo memory store). diff --git a/ПИЛОТ.md b/ПИЛОТ.md index 1a7b8326..51e38f1e 100644 --- a/ПИЛОТ.md +++ b/ПИЛОТ.md @@ -8,7 +8,7 @@ - Волатильную часть (доступ, версии, что развёрнуто) перед рискованными действиями **перепроверять реальной командой по SSH**, не доверять снимку вслепую. - Обновляется по команде заказчика **«обнови пилот»**. -**Снимок снят:** 22.05.2026 (поздний вечер +1) — выкачены на боевой **UI-замечания #4-#7 (П12-П15)** страницы «Проекты» (origin/main `0e5ab345`): #4 правая панель и галочка теперь исчезают после Save/Pause/Delete (drawer.onPause +emit close, ProjectsView.onDrawerSaved +clearSelection); #5 отступ от тёмных границ выровнен с KanbanView (24 px со всех сторон, scoped CSS вместо Vuetify `pa-6` чтобы `has-drawer` мог перекрыть правый отступ); #6 селектор «Показывать по 20/50/100/200» (паттерн как у DealsView, v-btn-toggle) + v-pagination когда total>per_page + серверный max per_page 100→200; #7 фильтры **регион** (89 субъектов; проекты с пустым `regions[]` = «вся РФ» попадают в любой фильтр через `regions @> ARRAY[?]::int[] OR regions='{}'/NULL`) и **день приёма** (bitwise `delivery_days_mask & (1<per_page + серверный max per_page 100→200; #7 фильтры **регион** (89 субъектов; проекты с пустым `regions[]` = «вся РФ» попадают в любой фильтр через `regions @> ARRAY[?]::int[] OR regions='{}'/NULL`) и **день приёма** (bitwise `delivery_days_mask & (1<` внизу страницы — клиент с >20 проектов теперь видит все, листая по страницам); ✅ **backfill 348 пред-проектных лидов выполнен 22.05 вечер**: они приходили от поставщика 21.05 (до создания проектов tenant 2) → молча сохранились в `supplier_leads` без сделок. После деплоя кода: balance Клиент 1 поднят 194→1 000 000 (страховка от исчерпания при массовой конверсии), `failed_webhook_jobs` 25 445→0 (исторический шторм зачищен, backup `/home/ubuntu/deploy-backups/failed_webhook_jobs_pre_truncate_*.csv.gz`), `supplier:backfill-root-links` добавил 9 root-связок к 32 site-проектам, потом `processed_at` 348 лидов сброшен в NULL и `RouteSupplierLeadJob` re-enqueue'нут — результат: **deals 6→412 у Клиента 1** (275 лидов сделали по 1 сделке, 90 silent-no-deal — поставщик шлёт на бренды без подписчиков; 73 разошлись cap=3 распределением), balance: 1 000 000→999 731 (269 lead-credits списано). Все проверены на проде. Бэкапы выкаток — `/home/ubuntu/deploy-backups/`. ✅ **Backend supplier group-sync fix (22.05 поздний вечер, on main `d3197095`):** online-синхронизация (`SyncSupplierProjectJob::handleOnline`) теперь считает агрегат по всей группе источника (active projects with same `buildUniqueKeyAgnostic`) — union regions/workdays, `computeOrder(eligible)` + `distributeForPlatform`, `status=paused` когда вся группа неактивна; `ProjectService::update` при смене `signal_identifier`/`sms_*` отвязывает старые `supplier_projects` (pivot + legacy FK) и dispatches `DeleteSupplierProjectJob` для чистки у поставщика; `ProjectController::toggleActive` + `ProjectService::bulkPauseResume` диспатчат `SyncSupplierProjectJob` (раньше пауза локальной была, до поставщика не доходила); fallback `order=computeOrder(groupProjects)` если eligible-tomorrow пуст (Mon-Fri проект синканный в пятницу вечером); pause-limit `max(1, sp.current_limit)` (portal не принимает `limit=0` даже при `status=false`). Перенесена автолинковка корня (`SupplierIdentifier::extractRootDomain`) — раньше была только в ветке `feat/root-domain-auto-link`. 5 файлов задеплоены копированием в `/var/www/liderra/app/` (бэкап `/home/ubuntu/deploy-backups/2026-05-22-supplier-group-fix.tar.gz`, hash-сверка ✓, pre-flight 15/15 ✓), `config:cache` + `route:cache` + `systemctl restart liderra-queue` + `reload php8.3-fpm`. Проверено вживую qa-проектами через `tinker sudo -u www-data`: создание `lim=20 → 7/7/6`, `Service::update lim=30 → 10/10/10` (#1 при изменении), убрать пятницу `wd=1-4`, убрать регион `reg=21`, пауза `status=false lim=10`, возобновление `status=true reg=21`, multi-client union `reg=21;72`. Чистка после ре-теста: `portal_total → 444+` (мои qa-проекты удалены, бэкапов нет). NB: ре-тест смены источника на проде упал на RLS (`Service::update` требует tenant-GUC, в tinker под www-data не ставится) — функционально покрыт локальным TDD-тестом (`Queue::assertPushed DeleteSupplierProjectJob` + pivot detach + FK null); первый реальный HTTP-запрос клиента даст полный flow. Не сделано (отложено): чистка 16 осиротевших `supplier_projects` + спам `csv_reconcile: 79135191264` каждые ~1 мин в `laravel.log`, П12-П15 UI (#4/#5/#6/#7 страница «Проекты»), финальная чистка 5 qa-tenant'ов 6-10. +- **Развёрнутый прикладной код (22.05):** ✅ регистрация по коду на email + обязательный телефон (E2E live: `POST /api/auth/register/start` → 200 + реальная отправка); ✅ деление лимита лидов B1/B2/B3 (денежный фикс `distributeForPlatform`, on main `e6beff6`; **re-split существующих проектов ВЫПОЛНЕН 22.05 форсом** — все активные поделены: 50→17/17/16, 30→10/10/10, 24→8/8/8, 18→6/6/6, 15→5/5/5; переплата ×N остановлена. NB: уже-`ok` проекты со старыми ×N батч сам не перечинивает → нужен force per-project online-синк); ✅ RLS-фикс admin-impersonation (`pgsql_supplier` BYPASSRLS, on main `b32dfbc`); ✅ **автолинковка субдомен→корень** (ветка `feat/root-domain-auto-link`, 22.05 вечер): `SyncSupplierProjectJob`/`SyncSupplierProjectsJob` при синке проекта-субдомена (`krasnoyarsk.carmoney.ru`) автоматически добавляют ещё один линк к корневому supplier_project (`carmoney.ru`), если он есть в `supplier_projects`. Закрывает класс «поставщик шлёт корень `carmoney.ru` — подписчики на субдомены не получают». Утилита `App\Support\SupplierIdentifier::extractRootDomain` + артизан-команда `supplier:backfill-root-links` (идемпотентна, --dry-run); ✅ **пагинация «Проектов»** (`` внизу страницы — клиент с >20 проектов теперь видит все, листая по страницам); ✅ **backfill 348 пред-проектных лидов выполнен 22.05 вечер**: они приходили от поставщика 21.05 (до создания проектов tenant 2) → молча сохранились в `supplier_leads` без сделок. После деплоя кода: balance Клиент 1 поднят 194→1 000 000 (страховка от исчерпания при массовой конверсии), `failed_webhook_jobs` 25 445→0 (исторический шторм зачищен, backup `/home/ubuntu/deploy-backups/failed_webhook_jobs_pre_truncate_*.csv.gz`), `supplier:backfill-root-links` добавил 9 root-связок к 32 site-проектам, потом `processed_at` 348 лидов сброшен в NULL и `RouteSupplierLeadJob` re-enqueue'нут — результат: **deals 6→412 у Клиента 1** (275 лидов сделали по 1 сделке, 90 silent-no-deal — поставщик шлёт на бренды без подписчиков; 73 разошлись cap=3 распределением), balance: 1 000 000→999 731 (269 lead-credits списано). Все проверены на проде. Бэкапы выкаток — `/home/ubuntu/deploy-backups/`. ✅ **Backend supplier group-sync fix (22.05 поздний вечер, on main `d3197095`):** online-синхронизация (`SyncSupplierProjectJob::handleOnline`) теперь считает агрегат по всей группе источника (active projects with same `buildUniqueKeyAgnostic`) — union regions/workdays, `computeOrder(eligible)` + `distributeForPlatform`, `status=paused` когда вся группа неактивна; `ProjectService::update` при смене `signal_identifier`/`sms_*` отвязывает старые `supplier_projects` (pivot + legacy FK) и dispatches `DeleteSupplierProjectJob` для чистки у поставщика; `ProjectController::toggleActive` + `ProjectService::bulkPauseResume` диспатчат `SyncSupplierProjectJob` (раньше пауза локальной была, до поставщика не доходила); fallback `order=computeOrder(groupProjects)` если eligible-tomorrow пуст (Mon-Fri проект синканный в пятницу вечером); pause-limit `max(1, sp.current_limit)` (portal не принимает `limit=0` даже при `status=false`). Перенесена автолинковка корня (`SupplierIdentifier::extractRootDomain`) — раньше была только в ветке `feat/root-domain-auto-link`. 5 файлов задеплоены копированием в `/var/www/liderra/app/` (бэкап `/home/ubuntu/deploy-backups/2026-05-22-supplier-group-fix.tar.gz`, hash-сверка ✓, pre-flight 15/15 ✓), `config:cache` + `route:cache` + `systemctl restart liderra-queue` + `reload php8.3-fpm`. Проверено вживую qa-проектами через `tinker sudo -u www-data`: создание `lim=20 → 7/7/6`, `Service::update lim=30 → 10/10/10` (#1 при изменении), убрать пятницу `wd=1-4`, убрать регион `reg=21`, пауза `status=false lim=10`, возобновление `status=true reg=21`, multi-client union `reg=21;72`. Чистка после ре-теста: `portal_total → 444+` (мои qa-проекты удалены, бэкапов нет). NB: ре-тест смены источника на проде упал на RLS (`Service::update` требует tenant-GUC, в tinker под www-data не ставится) — функционально покрыт локальным TDD-тестом (`Queue::assertPushed DeleteSupplierProjectJob` + pivot detach + FK null); первый реальный HTTP-запрос клиента даст полный flow. Не сделано (отложено): финальная чистка 5 qa-tenant'ов 6-10. (Закрыто 22.05 поздний вечер +1/+2: П12-П15 UI #4-#7 выкачены `0e5ab345`; 4 truly-orphan supplier_projects удалены — память про «16 осиротевших» была неверна, фактически было 4; спам `csv_reconcile: 79135191264` даунгрейднут warning→info `146501ba`.) ## 3. База данных