docs(pilot): зафиксированы 2 боевых выката 09.07 — пауза→поставщик (batch, dfa14862) + audit-chain global (ADR-021, 1495cd64)
Accessibility (Pa11y live) / a11y (push) Waiting to run

Отметка в ПИЛОТ.md обоих моих выкатов: (1) SyncSupplierProjectsJob deactivateOrphanedOrders
(пауза гасит заказ у поставщика в 18:00 до снимка 21:00; бэкап .bak-20260709-023707);
(2) AuditChainConfig global (verify-chains EXIT 0, 78 партиций; бэкап .bak-20260709-060558).
NB про параллельный CSV-reconcile money-фикс (91c5a119) — уже в gitea main, дрейфа нет.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-07-09 09:12:33 +03:00
parent 91c5a119eb
commit d64aaa3e9b
+5
View File
@@ -27,6 +27,11 @@
> **(4) Кнопка «Отказаться» на актуализации** (`43012c98`+`f888c4ba`): мягкое отклонение находки нового сайта/адреса — фирма поля остаётся, находка в архив, её ключи запоминаются у фирмы поля (**новая колонка `dismissed_actualize_keys`**, миграция `2026_07_07_130000` ролью `crm_migrator` — прошла на проде), `ProposalClassifier` их вычитает → та же находка больше не всплывает. Кнопка названа «Отказаться» (не «Удалить» — чтобы клиент не путал с удалением конкурента).
> **🔴 Деньги tenant 2:** мои тестовые прогоны + баг пустых списаний = ~260₽ его баланса; владелец сказал НЕ возвращать. Баланс 499 680₽, «+499 700 ручная корректировка» — админ (id=1), НЕ Claude. **Follow-up:** живая приёмка кнопки «Отказаться» под клиентом (нужна карточка актуализации); ротация пароля crm_migrator не требовалась. Память: `project-autopodbor-post-hotfix-fixes-2026-07-07`.
> 🟢🚀 **АКТУАЛЬНО (09.07.2026) — ДВА ФИКСА (ПОСТАВЩИК + АУДИТ) НА БОЕВОМ (оба точечным файловым оверлеем; миграций/денег/данных/триггера НЕ трогали).**
> **(1) Пауза проекта теперь доходит до поставщика (batch-режим).** Прод работает в `supplier_export_mode=batch` (перебивает стейл «online» в снимке 27.06 ниже). До фикса пауза клиента НЕ гасила заказ у поставщика — заказ висел активным (галочка вкл, лимит>0), поставщик мог лить лиды и списывать за остановленный проект (подтв. живой базой: omega/tenant 2 — 19 на паузе, 57 заказов активны, 0 команд после паузы). Причина: `handleBatch` «выключить» не слал (только online-ветка). 🔑 Поставщик фиксирует завтрашнюю заливку снимком в **21:00**, поэтому гасить надо в **18:00**-прогоне ДО снимка (мгновенно бессмысленно). Фикс: ночной `SyncSupplierProjectsJob` новым проходом `deactivateOrphanedOrders` шлёт `status=paused` заказам источников без активных проектов (по слепку). **gitea main `dfa14862`**, оверлей `app/app/Jobs/Supplier/SyncSupplierProjectsJob.php` + reload php-fpm + restart `liderra-queue`. Бэкап `SyncSupplierProjectsJob.php.bak-20260709-023707`. TDD 238/238 supplier+projects. Память `project-omega-pause-not-sent-to-supplier-batch-2026-07-08`.
> **(2) audit hash-chain → «общая цепочка» (ADR-021, supersedes ADR-018).** `audit:verify-chains` ночью ложно падал по 4 журналам (вкл. денежный `balance_transactions`) → ложные «high»-инциденты + письма на kdv1@bk.ru. Проверка хешами на проде (read-only): ВСЕ 4 бывшие «per-tenant» таблицы записаны ГЛОБАЛЬНОЙ цепочкой — per-tenant изоляция ADR-018 никогда не была реализована; данные целостны. Фикс: `AuditChainConfig` `partition=''` для 4 таблиц (verify/rebuild читают конфиг → авто-global). **gitea main `1495cd64`**, оверлей `app/app/Services/Audit/AuditChainConfig.php` (рестарт НЕ нужен — verify-chains это cron-команда). Бэкап `AuditChainConfig.php.bak-20260709-060558`. **Проверено на проде: `audit:verify-chains` → EXIT 0, «All audit chains intact», 78 партиций целы** (ранее 4 ложных breach ушли). Триггер/схему/данные/деньги не трогали. Память `project-audit-chain-pdlog-cross-tenant-divergence-2026-07-09`, ADR `docs/adr/ADR-021-audit-chain-global-scope.md`.
> **NB (соседняя сессия, НЕ моё):** параллельно выкачен money-фикс CSV-reconcile (`SupplierPortalClient.php` + `CsvReconcileJob.php`, «сверка ОТДАННОГО по vid, не пул») — на 09.07 закоммичен в **gitea main `91c5a119`** (встал fast-forward ПОВЕРХ моих `1495cd64`→`dfa14862`; ничего не затёрто, история линейна). Мои два фикса этих файлов не касаются. Детали — память `project-csv-reconcile-vid-delivered-fix-2026-07-09`.
**Снимок снят:** 29.06.2026 (~11:00 UTC) — **💳🟢 ВЫКАЧЕНА фича «ОПЛАТА ПО СЧЁТУ» (Этап 1) на боевой liderra.ru.** По командам владельца «ок коммить и пуш, обнови память и деплой только со скилом». **Что выкачено (gitea main `cdfae077`, деплой `bin/deploy-source-edit.sh`):** клиент в кабинете Биллинг → отдельная вкладка **«Счета»** + в «Пополнить» способ «По счёту (для юрлиц)» → формирует **PDF-счёт** по своим реквизитам; админ **`/admin/invoices`** (новый пункт меню «Счета») отмечает оплату одной кнопкой → атомарно зачисляет баланс + формирует **Акт** (без НДС, УСН) + шлёт клиенту письмо «Счёт оплачен» **с вложением PDF-акта**; PDF открываются inline. Просрочка `invoices:expire` (cron 03:40 МСК). Наименование услуги — «**Оплата генерации рекламных лидов**». Зависимость **dompdf** установлена на проде, **«Nothing to migrate»** (схему БД не меняли — таблицы saas_invoices/items/upd уже были). **Реквизиты ИП заполнены в боевом `legal_entities` id=1** (`ip_kondratev`, is_default): банк **Филиал «Центральный» ВТБ (ПАО) Красноярск**, р/с **40802810690810008032**, корр 30101810145250000411, БИК 044525411, ОКПО 2052921109, адрес Красноярск ул.Новосибирская 5-97 (было bank=null). **Предполёт 8/8 GREEN** (prod-deploy-validator), финиш через superpowers:finishing-a-development-branch. **Проверка:** приложение live, HTTPS /login 200, новых ошибок в логе нет, **деньги целы t2 = 1 839 210 ₽ / 1019 сделок**, счетов на проде 0 (чисто, клиенты ещё не выставляли). **ЮKassa для оплаты по счёту НЕ годится** (её B2B только через Сбербанк, обе стороны в Сбере; наш ИП в ВТБ) — деньги по счёту всегда идут прямой платёжкой на р/с ВТБ. **Этап 2** (автозачисление через ВТБ API «Интеграционный Банк-Клиент», только poll, без вебхуков) — отдельно, после вопросов менеджеру ВТБ. Спека/план — `docs/superpowers/specs|plans/2026-06-29-oplata-po-schetu-*`. Память: `project-oplata-po-schetu-etap1`, `reference-ip-requisites-kondratev`.
**Снимок снят:** 28.06.2026 (~13:30 UTC) — **🔍🟢 СКВОЗНАЯ СВЕРКА БАЙТ-В-БАЙТ прод↔git↔бэкап + экран «Тенанты» на 1000 + фронт-стенд в зелёный. Прод приведён к git 1:1.** По командам владельца «сверь прод/локалку/бэкап байт-в-байт» и «да» (выкатить). **Сверка (метод: на Linux `rsync -rclni` checksum, LF без CRLF-шума, свежий клон gitea-main ↔ `/var/www/liderra/app` ↔ распакованный `/tmp/app-backup-0907.tgz`):** исходники прода = **gitea-main `84dfbc85` один-в-один** (контент-расхождений 0 после выката тест-правок); бэкап цел, разница прод↔бэкап = ровно выкат «Тенанты»; **потерянных/изменённых правок НЕТ.** На проде сверх git только не-git артефакты: `*.bak-precutover` ×2 (страховка отката Managed PG — **держать до ~03.07**), `bootstrap/cache/*` ×5 (кэш Laravel, генерится), `tests/Frontend/menuRepositionFix.spec.ts` (старый удалённый тест, висит — деплой без `--delete`; мусор, в рантайме не участвует). **Выкачено в этот заход:** (1) экран «Тенанты» на серверную пагинацию/поиск/фильтры (статус производный CASE + тариф) — демо показано владельцу локально, прод `c92d498b`; (2) фронт-тест-стенд приведён в зелёный — 22 протухших теста в 10 спеках обновлены под актуальные компоненты (только тесты, компоненты не тронуты), `84dfbc85`, выкачены чтобы прод==git. **Полный прогон фронта: 127 файлов / 992 теста зелёные.** **Деньги целы: t2 = 1 839 405 ₽ / 990 сделок** (деплои код-только, БД не тронута). Сайт 200. Рецепт сверки на будущее: rsync-checksum на проде / `git hash-object`, НЕ raw-sha с Windows (CRLF врёт). Кодовая фраза стены — «роутер-наставник».