diff --git a/docs/superpowers/2026-07-28-STATE-okno-peredachi.md b/docs/superpowers/2026-07-28-STATE-okno-peredachi.md index 0fa189e4..2ff4f73f 100644 --- a/docs/superpowers/2026-07-28-STATE-okno-peredachi.md +++ b/docs/superpowers/2026-07-28-STATE-okno-peredachi.md @@ -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 с разрешения владельца** — и прогон окупился