docs реклама за показы: снимок состояния — заход 7, карта швов с веткой телеграм-рекламы

Числа обновлены: портал 393 из 393 при 1249 проверках, было 391.

Добавлен разбор захода 7: поломка денег на шве пауза-возобновление, датчик класса
"каждая половинка честна, шов между ними голый", и карта швов с веткой телеграма
для той смены, которая будет её забирать.

Порядок выбран владельцем: сначала выкат показов, телеграм следом.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-07-29 06:53:25 +03:00
parent 7d8c32bb53
commit 2abd6e73b7
@@ -3,7 +3,15 @@
Файл пишется в конце каждого захода. Читать его **первым делом** после компакта: всё,
что нужно следующей сессии, лежит здесь, а не в переписке.
🟢 **Обновлено: 28.07.2026, заход 6 — РАЗВЕДКА ПРОГНАНА ЖИВЬЁМ, с разрешения владельца.**
🔴 **Обновлено: 29.07.2026, заход 7 — РАЗБОР ШВА С ВЕТКОЙ ТЕЛЕГРАМ-РЕКЛАМЫ. Найдена и
починена поломка денег в ЭТОЙ ветке.** Пауза кампании и следом возобновление падали
на дубле брони: клиент не мог включить свою кампанию обратно. Ни один из 391 зелёного
теста этого не видел — шов между двумя честными половинками остался голым. Доказано
прогоном, починка взята у ветки телеграма, оба сторожа проверены вырезанием.
Портал теперь **393/393, 1249 проверок**. Коммит `7d8c32bb`. Разбор — раздел
«Заход 7» ниже. На боевой по-прежнему не выкатывалось.
Прежняя запись: 28.07.2026, заход 6 — **РАЗВЕДКА ПРОГНАНА ЖИВЬЁМ, с разрешения владельца.**
Прогон вскрыл **две поломки**, невидимые для 74 зелёных тестов, обе починены и перепроверены
живым кабинетом. Робот приносит причину целиком: 792 знака по финансовым услугам, 621 —
по медицине. Замеры — `cabinet-flow.md` §7.8, разбор — ниже раздел «Живой прогон разведки».
@@ -59,8 +67,8 @@ abb3941e feat реклама за показы: удаление отклонё
## Зелёные числа на этом коммите
- портал: **391/391, 1244 проверки, ~69 с**`cd app && DB_DATABASE=liderra_testing_reklama php artisan test --filter=Advertising`
(было 361 — разведка, честность про документ и разбор собственных ошибок)
- портал: **393/393, 1249 проверок, ~65 с**`cd app && DB_DATABASE=liderra_testing_reklama php artisan test --filter=Advertising`
(было 391 — плюс два сторожа на шов «пауза и следом возобновление», см. заход 7)
- админский список «ждёт разбора»: **9/9**`--filter="AdminRobotStuck|AdminAdCampaignCreative"`
- фронт на затронутых наборах: **52/52**`npx vitest run tests/Frontend/admin-advertising-view.spec.ts tests/Frontend/advertising-campaign-messages.spec.ts tests/Frontend/advertising-campaign-list.spec.ts tests/Frontend/advertising-api.spec.ts`
- фронт: **227 файлов, 1671 тест**`cd app && npx vitest run`
@@ -431,6 +439,64 @@ Playwright на **копии** профиля браузера MCP, вход в
обнаружился **в третий раз за два дня**, и снова его не увидел ни один зелёный тест.
Живой прогон нашёл за десять минут то, чего 74 теста не видели вовсе.
## Заход 7 — 29.07.2026: шов с веткой телеграм-рекламы вскрыл поломку денег у нас
Владелец попросил забрать себе телеграм-модуль, подготовленный другой сессией, и особо
смотреть **швы** — места, где две ветки пересекаются. Шов и дал результат.
**Поломка.** Снятие заморозки не удаляет строку брони, а метит её снятой. На броне
висит запрет двух одинаковых записей по четвёрке `tenant_id, channel, source_type,
source_id`. Повторная заморозка той же кампании заводила строку заново — база отказывала.
По-человечески: **клиент ставил кампанию на паузу и больше не мог её включить.**
Та же дорога на новом пути «отказ модерации → Исправить → отправить заново».
**Почему 391 зелёный тест этого не видел** — датчик класса, запомнить:
| Тест | Что делает | Итог |
|---|---|---|
| «пауза возвращает заморозку» | морозит → снимает | зелёный, честный |
| «возобновление снова морозит» | берёт кампанию, которую **никогда не морозили** → морозит | зелёный, честный |
| пауза **и следом** возобновление | не проверял никто | ← падало здесь |
🔑 **Каждая половинка честна, шов между ними голый.** Когда тест начинает с состояния,
собранного руками, он пропускает всё, что оставила после себя настоящая предыстория.
Искать такие дыры: где тест **создаёт** состояние вместо того, чтобы **дойти** до него.
**Доказано прогоном, не рассуждением:** `SQLSTATE 23505 ... ad_wallet_holds_tenant_id_
channel_source_type_source_id_unique, ключ (yandex, campaign, 1) уже существует`.
**Починка** взята у ветки телеграма, которая наткнулась на то же самое: не заводить
бронь заново, а оживлять снятую — `AdWalletHold::updateOrCreate` по четвёрке ключа.
Оба сторожа написаны до починки и **проверены вырезанием**: без починки падают.
### Карта швов с веткой `feat/client-telegram-ads` — для захода, который будет забирать
Порядок выбран владельцем: **сначала выкат показов, телеграм следом.** Тогда телеграм
обновляют на свежий main и разбирают швы уже там.
- Пробное слияние даёт **9 конфликтов** с main и **10** с нашей веткой. Восемь из них
механические: боковое меню, витрина каналов рекламы и два их фронт-теста, расписание
задач, словарь орфографии, журнал схемы, файл-образец настроек.
- 🔴🔴 **Десятый — деньги, `AdWalletService.php`.** Обе ветки создали этот файл
независимо, общего предка у него нет, поэтому слияние отдаёт его целиком на разбор
руками. 🪤 **Копия телеграма СТАРШЕ нашей на две починки** — таяние заморозки при
списании и терпимость к отсутствию кошелька. Взять их файл «как есть» значит молча
потерять обе. **Наша версия главная**, из их — только `updateOrCreate` в заморозке,
и он уже у нас.
- **Спорить о деньгах не придётся:** телеграм последним коммитом **ушёл с рекламного
кошелька на общий баланс клиента**, как за СМС. Их копия кошелька и три теста к ней
(`WalletChannelTest`, `WalletReFreezeTest`, `ConservativeReleaseTest`) — мёртвый груз
от брошенной модели. Их место — под нож, а не в наш денежный код.
- **Миграции не столкнутся** — проверено поимённо: телеграм нумерует `2026_07_2X_0000NN`,
мы `2026_07_2X_1000NN`.
- **Роботы не подерутся** — у каждого свой профиль браузера: `MTS_BROWSER_PROFILE_DIR`
против `YC_BROWSER_PROFILE_DIR`.
- 🪤 Ветка телеграма **отстала от main на 59 коммитов** — почти на весь рекламный модуль
Яндекса. Наша отстала на 2. Обновлять телеграм на main, а не наоборот.
- 🔴 У робота МТС **та же нерешённая беда**, что у нашего: ему нужен живой браузер
с входом в кабинет, а на боевом сервере браузера нет.
## Что осталось незакрытым
-**Разведка ПРОГНАНА живьём 28.07.2026 с разрешения владельца** — и прогон окупился