From 8a34a8f19fe0b7a3d5da73de7c8d6bede9a20602 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: Sat, 23 May 2026 10:46:22 +0300 Subject: [PATCH] =?UTF-8?q?docs(pilot):=20closable-chips=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B3=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20?= =?UTF-8?q?=D1=87=D0=B8=D0=BF=D0=BE=D0=B2=20=D0=B2=D1=8B=D0=BA=D0=B0=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BD=D0=B0=20=D0=B1=D0=BE=D0=B5=D0=B2=D0=BE?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Фронтенд-фикс «крестик удаления на чипах регионов» (3 формы стр. Проекты) выкачен на liderra.ru копированием public/build. Smoke 200, бэкап снят. Co-Authored-By: Claude Opus 4.7 (1M context) --- ПИЛОТ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ПИЛОТ.md b/ПИЛОТ.md index af466310..09bd1fad 100644 --- a/ПИЛОТ.md +++ b/ПИЛОТ.md @@ -8,7 +8,7 @@ - Волатильную часть (доступ, версии, что развёрнуто) перед рискованными действиями **перепроверять реальной командой по SSH**, не доверять снимку вслепую. - Обновляется по команде заказчика **«обнови пилот»**. -**Снимок снят:** 23.05.2026 — **финальная чистка 5 qa-tenants на проде** (data-only, без коммитов в репо): tenants id 6-10 (qatest1..5 / Компания QA Test 1..5 / qa{N}@liderra.test, созданы 22.05 12:55) — все пустые после прошлых ретестов (0 projects / 0 deals / 1 user на тенант, balance 100K leads + 100K руб тестовое). Перепроверка: запрос по всем 41 таблице с `tenant_id` — суммарно 5 строк (5 users). Все NO-ACTION FK таблицы (auth_log/api_keys/outbound_webhooks/pd_*/refund_requests/saas_upd/saas_admin_audit/saas_admin_sessions) для tenant 6-10 пусты. **Hard-DELETE транзакцией** `DELETE FROM tenants WHERE id BETWEEN 6 AND 10` → CASCADE автоматом снёс 5 users. Verification: tenants `10 → 5`, users for 6-10 `5 → 0`. Текущие тенанты на проде: **id 1 demo** (`admin@demo.local`, 3 projects / 5 deals), **id 2 client1** (`info@lkomega.ru`, 117 projects / 412 deals — основной живой клиент), **id 3/4/5 client2/3/4** (`client{N}@liderra.test`, по 0 projects / 0 deals — placeholder-тенанты, остались для DEV-теста sharing-flow между tenant'ами). **Раньше 22.05 (поздний вечер +2)** — **чистка orphan supplier_projects + даунгрейд лог-спама** (origin/main `146501ba`): найдено 4 truly-orphan sp (не 16 — память была неверна; первичный запрос через legacy-колонки `projects.supplier_b1/b2/b3` возвращал 359 ложных, фактический link — таблица `project_supplier_links` 361 строка): id 57 `x.example` 0 leads, id 73/77 `79991234567` 14 leads, id 79 `https://заложитьптс.рф` 2 leads — placeholders/тестовые/malformed URL. **Перепроверка влияния на живых клиентов:** все 16 leads `deals_created_count=0`, 0 deals у этих 9 номеров глобально (включая tenant 2 info@lkomega.ru/client1) — поставки **никому не прекращались**. Удаление транзакцией `DELETE FROM supplier_projects WHERE id IN (57, 73, 77, 79)` → 4 sp удалены, FK `ON DELETE SET NULL` на `supplier_leads` (16 строк), `supplier_sync_log` (0 строк), `projects.supplier_b1/b2/b3` (0 ссылок). Orphan count `4 → 0` ✓. Параллельно: спам `csv_reconcile.unparseable_project_skipped {"project":"79135XXXXXX"}` (13+ warning/день, supplier-side data quality — `crm.bp-gr.ru` кладёт телефон-style строку в project-колонку CSV; не наш баг — телефон-строка замаскирована в этом снимке) **даунгрейднут warning→info** в `CsvReconcileJob.php:131-134` (1 строка кода + комментарий-обоснование, deploy через scp + opcache reset + `queue:restart`; commit `146501ba`, push `ce314034..146501ba → main`). Verification: deployed на проде, line 134 `Log::info`, 2 manual job-dispatch (`csv_reconcile_log` id 66/67 ok), unparseable-код-путь на этих прогонах не сработал (179 CSV-строк попали в existingKeys — `$missing` empty), эффект на след. реальном попадании. **Раньше 22.05 (поздний вечер +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<