From dbc79f15b3a562ef6a9506a2e7a66b60d95b99a5 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: Sun, 2 Aug 2026 18:20:59 +0300 Subject: [PATCH] =?UTF-8?q?docs(=D1=80=D0=B5=D0=BA=D0=BB=D0=B0=D0=BC=D0=B0?= =?UTF-8?q?):=20=D0=BF=D1=80=D0=BE=D0=BC=D1=82=20=D1=81=D0=BB=D0=B5=D0=B4?= =?UTF-8?q?=D1=83=D1=8E=D1=89=D0=B5=D0=B9=20=D1=81=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=20=E2=80=94=20=D0=BF=D0=B0=D1=87=D0=BA=D0=B0=205,=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D1=91=D0=BC=D0=BA=D0=B0=20=D0=B3=D0=BB=D0=B0=D0=B7?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20=D0=B8=20=D0=B2=D1=8B=D0=BA=D0=B0=D1=82=20?= =?UTF-8?q?=D0=BF=D1=8F=D1=82=D0=B8=20=D0=BF=D0=B0=D1=87=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Пачка 4 закрыта целиком, дальше только приёмка и выкат. Промт содержит: - 🔴 порядок «сперва глазами, потом выкат»: ни одна из пяти пачек глазами не принята, а зелёный тест этого не доказывает (30.07 при 342 зелёных тестах 15 объявлений лежали черновиками); - 9 точек приёмки телеграм-экрана и 3 яндексовского, с упором на живой счётчик охвата — его никто не видел работающим; - 🔴 ПОИМЁННЫЙ список выката: 22 файла кода (полный overlay запрещён), замер git diff --name-only 7922bffb~1..HEAD; phpstan-baseline намеренно исключён как ненужный на бою; - 🔴 предупреждение про изменение базы в пачке 1 (два необязательных столбца в client_tg_auto_rule, откат в миграции есть, журнал схемы на v9.64); - разбор, почему новая ручка оценки НЕ требует новых прав в базе: читает то же, что и создание кампании, и не пишет никуда; - метки экрана проверены поимённо командой, а не по памяти; отдельно записано, что tg-calc и tg-estimate больше НЕ существуют (ноль вхождений). Три новые ловушки этой смены: - датчик пробелов ложно срабатывает на переезде кусков кода — прежде чем чинить, смотреть diff обоих датчиков глазами; - резать файл скриптом по номерам строк опасно: так пропал открывающий тег v-tabs-window, номера успели сдвинуться между замером и правкой; - переносишь код — переноси проверки: сперва переписать на новом месте и там прогнать, только потом убирать со старого. Числа — свежие замеры: экраны 240 файлов / 1829 тестов, Яндекс 435, телеграм 292, статанализ 0, типы 6 чужих ошибок. Промт 08-05 помечен отработанным. Co-Authored-By: Claude Opus 5 (1M context) --- ...2026-08-05-PROMT-karkas-telegram-ekrana.md | 5 + ...ROMT-priyomka-i-vykat-reklamnyh-ekranov.md | 352 ++++++++++++++++++ 2 files changed, 357 insertions(+) create mode 100644 docs/superpowers/2026-08-06-PROMT-priyomka-i-vykat-reklamnyh-ekranov.md diff --git a/docs/superpowers/2026-08-05-PROMT-karkas-telegram-ekrana.md b/docs/superpowers/2026-08-05-PROMT-karkas-telegram-ekrana.md index bc5125f8..75a5ec97 100644 --- a/docs/superpowers/2026-08-05-PROMT-karkas-telegram-ekrana.md +++ b/docs/superpowers/2026-08-05-PROMT-karkas-telegram-ekrana.md @@ -1,5 +1,10 @@ # Промт следующей смене — Пачка 4: единый каркас телеграм-экрана +> ⛔ **ОТРАБОТАН 02.08.2026 — работы больше не содержит.** Пачка 4 закрыта целиком, обе +> половины (коммиты `bcbbb25b0` и `76cb44b91`). Актуальный промт следующей смене — +> [2026-08-06-PROMT-priyomka-i-vykat-reklamnyh-ekranov.md](2026-08-06-PROMT-priyomka-i-vykat-reklamnyh-ekranov.md). +> Этот файл оставлен как снимок «что было до пачки 4» и разбор двух мин. + Поставлено 02.08.2026 ночью, после закрытия пачки 3. Всё ниже — живые замеры этой смены. **Главный документ работы — [2026-08-02-ZAMECHANIYA-edinyy-vid-reklamnyh-ekranov.md](2026-08-02-ZAMECHANIYA-edinyy-vid-reklamnyh-ekranov.md).** diff --git a/docs/superpowers/2026-08-06-PROMT-priyomka-i-vykat-reklamnyh-ekranov.md b/docs/superpowers/2026-08-06-PROMT-priyomka-i-vykat-reklamnyh-ekranov.md new file mode 100644 index 00000000..42883f6e --- /dev/null +++ b/docs/superpowers/2026-08-06-PROMT-priyomka-i-vykat-reklamnyh-ekranov.md @@ -0,0 +1,352 @@ +# Промт следующей смене — Пачка 5: приёмка глазами и выкат на боевой + +Поставлено 02.08.2026 ночью, после закрытия пачки 4 (обеих половин). Всё ниже — живые замеры +этой смены, а не память. + +**Главный документ работы — [2026-08-02-ZAMECHANIYA-edinyy-vid-reklamnyh-ekranov.md](2026-08-02-ZAMECHANIYA-edinyy-vid-reklamnyh-ekranov.md).** +Там замечания владельца дословно, требования МТС к медиа и разбор всех пяти пачек. +Этот промт — вход, состояние и работа одной смены. + +--- + +## 🔴🔴🔴 Первое, что надо знать + +**Песочница ВЫКЛЮЧЕНА 02.08.2026 в 07:40 МСК — телеграм-реклама на ЖИВЫХ ДЕНЬГАХ.** +Клиент жмёт «Запустить» → списывается его баланс → робот реально платит в кабинете МТС. + +Откат: `TG_SANDBOX=true` в `.env` боевого → `sudo -u www-data php artisan config:cache` → +`sudo systemctl restart liderra-queue`. Копия настроек: +`/home/ubuntu/deploy-backups/.env.bak-pered-vyhodom-iz-pesochnicy-20260802`. + +Прочие красные линии: прод — только с явного «да» владельца, база по умолчанию **чтение**; +номера телефонов — ПДн, в задание роботу не класть; пуш **только в gitea** (GitHub мёртв); +владелец **не программист** — простым русским, короткими абзацами. + +--- + +## Работа смены — Пачка 5 + +Две части: **сперва принять глазами, потом выкатить**. Между ними — «да» владельца. + +### Часть 1. Приёмка глазами — обязательно ДО выката + +Ни одна из пяти пачек глазами не принята. Тесты зелёные, но **зелёный тест не доказывает, +что экран выглядит и ведёт себя по-человечески** — за смену 30.07 этим уже обожглись +(15 объявлений лежали черновиками при 342 зелёных тестах). + +🔴 **Демо-вход `admin@demo.local` не работает с 01.07** — тестовых учёток на бою нет, все +10 тенантов живые. **Доступ для приёмки просить у владельца.** Смотреть на локальном +`crm.bp-gr.ru` можно и нужно, но это не заменяет боевой. + +Что смотреть на **телеграм-экране** (он переделан целиком): + +1. **Карточка денег сверху.** Одна ли она? Не появилась ли рядом вторая, яндексовая? + Сумма человеческая («5 000 ₽», не «5000.00»)? Кнопка пополнения открывает пополнение + **общего** баланса, а не рекламного кошелька? +2. **Три вкладки** — «Мои кампании» / «Новая реклама» / «Авто-реклама». Открывается ли экран + на кампаниях? Не мигает ли содержимое при переключении? +3. **Карточки кампаний.** Похожи ли на яндексовые? Виден ли номер кампании рядом с текстом? + Не разъезжается ли карточка от длинного объявления? Цветной ярлык — того же цвета, что + у Яндекса для того же положения дел? +4. **Живой счётчик охвата** (шаг 1 мастера) — главное, что надо посмотреть живьём: + - не мигает ли, не «прыгает» ли число; + - успевает ли посчитать, пока человек печатает число дней (задержка 400 мс); + - что видно, пока считает, — крутилка, а не старое число; + - 🪤 **на своём списке номеров** счётчик не считает, пока список пуст — так задумано, + но глазами надо убедиться, что это не выглядит поломкой. +5. **Проход мастера целиком** на настоящем клиенте: четыре шага, «Назад»/«Дальше», сводка. + Особенно — **«Запустить» не нажимается, когда людей меньше 367**, и понятно ли объяснено. +6. **Шаг «Деньги»**: сходятся ли смета и остаток баланса с тем, что спишется на самом деле. +7. **Подсказки «?»** — как знак вопроса смотрится ВНУТРИ поля, особенно рядом с крестиком + очистки у «Картинка или видео». Тест доказал, что подсказка там есть; как она выглядит — + глазами не видел никто. + +Что смотреть на **экране Яндекса** (его трогали только пачки 2 и 3): + +- Ярлыки статусов — «Принято, показов пока нет» вместо зелёного «Крутится» при нуле; + приписка «часть объявлений отклонена — 2 из 15». +- Одинаково ли называются статусы на двух экранах, если открыть их подряд. +- Подсказки «?» в мастере Яндекса: период контактов, срок показа, частота, цена за тысячу. + +**Нашёл беду — не чини молча.** Запиши в главный документ и скажи владельцу: часть находок +может оказаться «так и задумано». + +### Часть 2. Выкат на боевой — только с отдельного «да» владельца + +🔴 **В выкате есть изменение базы.** Миграция +`app/database/migrations/2026_08_02_000001_add_headline_and_media_to_client_tg_auto_rule.php` +добавляет в таблицу `client_tg_auto_rule` два столбца: `ad_headline` (40 знаков) и +`media_path` (500). Оба **необязательные**, старые строки не ломает, откат в миграции есть. +Номер журнала схемы — последний занятый **v9.64**. + +🔴 **Полный overlay на боевой ЗАПРЕЩЁН — катить поимённым списком.** Вот он целиком, замер +`git diff --name-only 7922bffb~1..HEAD`, 24 файла (тесты не катятся): + +**Сервер (PHP), 10 файлов:** + +```text +app/app/Http/Controllers/Api/AdvertisingCampaignController.php +app/app/Http/Controllers/Api/ClientTg/AutoRuleController.php +app/app/Http/Controllers/Api/ClientTg/CampaignController.php +app/app/Models/ClientTg/AutoRule.php +app/app/Rules/ClientTg/MtsMedia.php +app/app/Services/ClientTg/TelegramAudienceService.php +app/app/Services/ClientTg/TelegramAutoAccumulator.php +app/app/Support/Mp4Probe.php +app/routes/web.php +app/database/migrations/2026_08_02_000001_add_headline_and_media_to_client_tg_auto_rule.php +``` + +**Экраны (исходники, собираются на бою), 12 файлов:** + +```text +app/resources/js/api/advertising.ts +app/resources/js/api/telegram.ts +app/resources/js/components/advertising/AdWalletHeader.vue +app/resources/js/components/advertising/CampaignList.vue +app/resources/js/components/advertising/CampaignReportDialog.vue +app/resources/js/components/advertising/CampaignWizard.vue +app/resources/js/components/advertising/TelegramBalanceHeader.vue +app/resources/js/composables/campaignStatusMeta.ts +app/resources/js/composables/podskazkiReklamy.ts +app/resources/js/views/advertising/AdvertisingTelegramView.vue +app/resources/js/views/advertising/TelegramAutoRulePanel.vue +app/resources/js/views/advertising/TelegramCampaignWizard.vue +app/resources/js/views/advertising/telegramStatusLabels.ts +``` + +**`app/phpstan-baseline.neon` на боевой НЕ нужен** — он для разработки. В списке выше его нет +намеренно, хотя в diff он есть. + +Безопасный порядок (проверен прошлыми выкатами): + +1. Позвать агента `prod-deploy-validator` — он даёт вердикт ГО/НЕ ГО и ничего не меняет. +2. Бэкап базы **до** миграции. +3. Залить файлы поимённо → `php artisan migrate` → собрать фронт. +4. Фронт собирается прямо на боевом (node 20.20.2, ~2,4 с). Собрать в `public/build-new`, + проверить, подменить `mv`, потом `chown -R www-data:www-data`. +5. 🔴 `config:cache` / `optimize` — **от `www-data`, НЕ от root**. От root портал ложился на + 18 минут. +6. Перезапустить очередь: `sudo systemctl restart liderra-queue`. +7. Пройти телеграм-экран глазами ещё раз — уже на бою. + +**Новая ручка оценки прав в базе не требует.** `POST /api/telegram/campaigns/estimate` читает +строго то же, что уже читает создание кампании (сделки, свою базу, отписки), и **не пишет +никуда**. Мина «на бою роль не смогла записать» тут не работает — записи нет вовсе. + +🪤 **Но проверить srv_bypass всё равно стоит**, если миграция добавит что-то новое под RLS: +новым RLS-таблицам мало `tenant_isolation` + GRANT, надо **пере**запускать +`db/03_service_bypass_policies.sql`. Здесь новых таблиц нет — только два столбца в +существующей, — так что скорее всего не понадобится. Но глазами свериться дешевле, чем +получить тихую правку нуля строк. + +### Чем кончается смена + +Либо «принято глазами, выкачено, вот что смотрел» — и тогда обновить `ПИЛОТ.md` и написать +промт следующей смене. Либо честное «нашёл вот это, дальше не пошёл». + +--- + +## Что уже сделано — пять пачек, все в gitea, ни одна НЕ на боевой + +### ✅ Пачка 1 — коммит `7922bffb6` + +Заголовок объявления и картинка в **авто-правиле** (раньше их не было вовсе — авто со ссылкой +на сайт сгорело бы в кабинете уже после списания денег); проверка медиа по настоящим +требованиям МТС (`app/app/Rules/ClientTg/MtsMedia.php`, длительность и кадр видео читает +`app/app/Support/Mp4Probe.php` без внешних программ); цена показа с медиа показана ДО загрузки +файла; накопитель не запускает пачку без заголовка при рекламе сайта. + +Граница честности: длительность и кадр читаются только у mp4/mov/m4v; у webm/mkv/mpeg/wmv +проверяются формат и вес. + +### ✅ Пачка 2 — коммит `a2496dfe6` + +Замечание З-6: «почему статус крутится, когда она отклонена?» Сервер отдаёт +`delivered_impressions` и счётчики объявлений одним запросом (на N+1 стоит датчик); ярлык +считается по фактам: `running` при нуле показов → «Принято, показов пока нет», часть отклонена +→ «часть объявлений отклонена — 2 из 15». + +🔴 **Правило перехода статусов НЕ тронуто** — на `rejected` висит возврат заморозки +(`AdWalletService::release`, «ВЫХОД 2»). Трогать его нельзя. + +### ✅ Пачка 3 — коммит `6ae6457b3` + +Подсказки «?» у **16 полей**. Тексты — один файл `composables/podskazkiReklamy.ts` (теперь их +14: в пачке 4а добавилась подсказка про общий баланс). На очевидные поля подсказки нет +**намеренно**, и на это стоит отдельный тест. Язык стерегут датчики: ни одной латинской буквы, +запрет жаргона, длина 40–200 знаков, два-три предложения. + +### ✅ Пачка 4а — коммит `bcbbb25b0` — каркас + +Вкладки, карточка денег сверху, панель авто-рекламы в своей вкладке, кампании карточками с +цветным ярлыком. После запуска экран сам возвращает к списку. + +🔴 **Карточка денег — ОТДЕЛЬНЫЙ компонент `TelegramBalanceHeader.vue`, не яндексовая шапка.** +Экраны берут деньги из разных мест: Яндекс — из рекламного кошелька (`ad_wallets`), телеграм — +из **общего баланса** (`tenants.balance_rub`, решение владельца, коммит `6f469fb1`). Показать +одни деньги, а списать другие — хуже, чем некрасивый экран. + +🔴 **Слова «Заморожено» на телеграм-карточке нет намеренно** — сервер отдаёт заморозку жёстким +нулём, и вечный ноль клиент прочитал бы как «деньги не резервируются». + +### ✅ Пачка 4б — коммит `76cb44b91` — мастер и счётчик + +Мастер из четырёх шагов (Кому показываем → Объявление → Деньги → Проверка и отправка), живой +счётчик охвата, **кнопки «Рассчитать» больше нет**. Смета и остаток баланса на шаге «Деньги». + +🔴 **Заведена новая серверная ручка `POST /api/telegram/campaigns/estimate`.** Живой счётчик +считает на каждое изменение поля, а охват до сих пор возвращала только `POST /campaigns` — и +она **создаёт черновик в базе**. Новая ручка **только читает**. Считает тем же кодом, что и +создание кампании; отдельный тест сверяет два ответа между собой. + +🔴 **Запуск запрещён, когда людей меньше 367** — правило площадки. Тот же предохранитель стоит +на сервере (`AudienceGateTest`). + +--- + +## Где всё стоит — замер 02.08 ночью + +**`main` = ветка `fix/tg-zagolovok-obyavleniya` = `76cb44b91`**, неотправленного 0, +рабочая папка чистая (кроме машинного `docs/observer/STATUS.md`). + +### Боевой — замеры прошлой смены, перепроверить командой + +- Заголовок объявления на разовой форме доехал (выкат 02.08 днём), приёмка глазами пройдена. +- 🟡 **Откат того выката ещё лежит:** каталог `public/build-old-zagolovok` и архив + `/tmp/front-backup-2026-08-02-zagolovok.tgz`. Сутки прошли — можно убирать. +- 🔴 **Пачки 1, 2, 3, 4а и 4б на боевой НЕ поехали.** +- Телеграм: 7 таблиц `client_tg_*`, `TG_ROBOT_TRANSPORT=poll`, **`TG_SANDBOX=false`**. + +### Робот + +Живёт на машине владельца: `C:\liderra\mts-telegram-robot`, свой Node 20 +(`C:\liderra\node20\node.exe`), профиль браузера `C:\liderra\mts-bot-profile`. Стучится в +портал раз в минуту. Баланс МТС **5 010 ₽** — фактический потолок трат. + +⛔ Не ставить робота на сервер и не покупать прокси — обе дороги закрыты навсегда. + +### Тесты и сторожа — замеры ЭТОЙ смены + +- Экраны: `cd app && npx vitest run` — **240 файлов, 1829 тестов, 0 падений**, 3 пропущено, + ~3 минуты. +- Реклама Яндекса: `cd app && DB_DATABASE=liderra_testing_zag php artisan test --filter=Advertising` + — **435, 0 падений**. +- Телеграм-модуль: то же с `--filter=ClientTg` — **292, 0 падений**. +- Статанализ: `cd app && composer stan` — **0**. Формат: `composer pint -- --dirty` — чисто. +- Проверка типов: `npm run type-check` — **6 ошибок в чужих файлах** (автоподбор, проекты, + старые спеки рекламы), они были до нас. Смотреть, не добавилось ли **своего** файла. +- Робот: `cd bots/mts-telegram-ads && npm test` + +🪤 Гонять из папки `app`, иначе «Could not open input file». + +--- + +## Опорные точки — проверены поимённо этой сменой + +Метки, по которым тесты находят живое. Ломать их = ломать проверки без пользы: + +`tg-tabs`, `tg-tab-campaigns`, `tg-tab-new`, `tg-tab-auto`, `tg-balance-header`, +`tg-balance-value`, `tg-balance-topup`, `tg-campaigns`, `tg-campaign-row`, +`tg-campaign-status-chip`, `tg-campaign-new-btn`, `tg-wizard`, `tg-wizard-steps`, +`tg-wizard-step-1…4`, `tg-reach`, `tg-reach-malo`, `tg-smeta`, `tg-svodka`, `tg-launch`, +`tg-ad-text`, `tg-ad-link`, `tg-ad-headline`, `tg-audience-days`, `tg-phones`, +`tg-budget-cap`, `tg-ord`, `tg-media`, `tg-auto-panel`, `tg-auto-*`, `tg-resubmit-*`, +`help-hint`. + +🔴 **`tg-calc` и `tg-estimate` больше НЕ существуют** — проверено, ноль вхождений. Кнопку +«Рассчитать» убрала пачка 4б, охват теперь живой. Если увидишь их в чужом старом тексте — +это устаревший источник. + +--- + +## Что остаётся за владельцем + +1. 🔴 **Стена площадки: минимум 367 номеров**, у самого крупного клиента 112. Из сделок порог + не набрать — но клиент может загрузить **свой список**, и тогда пойдут живые деньги. +2. **Чтение вердикта модерации (`read-status`) не проверено ни разу.** Вскроется на первом + живом запуске: не прочитает робот ответ МТС — кампания провисит 48 часов и уйдёт в «нужен + разбор», деньги при этом не вернутся (реклама могла показываться). +3. **Токен робота засветился в выводе команды** 02.08 (в файлы и коммиты не попал). + Перевыпустить, когда будет удобно. +4. **Решить про выкат пяти пачек** — в первой изменение базы. + +--- + +## ⏸ Отложено владельцем — НЕ поднимать + +**Портал не хранит числа показов телеграм-кампании** (колонка `actual_cost_rub` есть, но её не +пишет ни одна строка кода; доставленных показов в таблице нет вовсе). Владелец 02.08: +«показывает, надо только запустить и начнёт показывать — не обращай внимание пока». +По своей инициативе не трогать. + +--- + +## Ловушки + +### Правка кода + +- 🪤 **Причёсывалка (`prettier --write`) переписывает ВЕСЬ файл**, если он не был причёсан до + тебя. 02.08 телеграм-экран так дал 296 изменённых строк вместо 24. Датчик: сравнить + `git diff --stat` и `git diff --stat -w`; разошлись — почти всё пробелы. Лечение: + `git checkout HEAD -- <файл>` и применить только свою правку руками. +- 🪤 Проверять, был ли файл причёсан ДО тебя, надо **внутри `app/`**: + `cd app && git show HEAD:app/<путь> > proverka.vue && npx prettier --check proverka.vue && rm proverka.vue`. + Во временной папке нет `app/.prettierrc.json` — причёсывалка меряет чужой меркой и врёт. +- 🪤 **Датчик пробелов ложно срабатывает на переезде кусков кода.** Если строки удалены в + одном месте и добавлены в другом, `-w` спарит их иначе, и счётчики разойдутся на 2–3 + строки. Прежде чем чинить — посмотреть diff обоих датчиков глазами; переезд это не шум. +- 🪤 **Итоги группировки — не модели.** `groupBy` + `count(...) as total` через Eloquent даёт + строки, притворяющиеся моделью, и статанализ ругается. Лечение — `->toBase()` перед `->get()`. +- 🪤 **Тесты экранов лежат в `app/tests/Frontend/`**, а не рядом с кодом. Их 240 файлов. +- 🪤 **Имён колонок и таблиц наизусть не помнить.** Кампании Яндекса — `ad_campaigns`, + объявления — `ad_campaign_banners`, правило авто-телеграма — `client_tg_auto_rule` + (единственное число!), рекламный кошелёк — `ad_wallets`. Сперва `information_schema`. +- 🪤 **Переменные оболочки в путях временных файлов** дали мусор `app/$out` и `app/$TEMP/` + прямо в рабочей папке. Писать временное в каталог-черновик сессии. +- 🪤 **Резать куски файла скриптом по номерам строк — опасно.** 02.08 так пропал открывающий + тег ``: номера строк успели сдвинуться между замером и правкой. Резать + через Edit по точному тексту; если всё же скриптом — сразу перечитать место глазами. + +### Тесты + +- 🪤 **Тест, который ищет исчезнувшее поле, зеленеет по ложной причине.** 02.08 проверка «на + „Тексте объявления" подсказки НЕТ» прошла на экране, где этого поля не стало вовсе: + подсказки «нет» и у того, чего нет. Лечение — сперва убедиться, что поле на экране есть. +- 🪤 **Переносишь код — переноси проверки, а не выбрасывай.** Сперва переписать их на новом + месте и там прогнать, и только потом убирать со старого. Иначе «14 тестов удалено» ничем + не отличается от подгонки под зелёное. +- 🪤 **После НОВОГО тестового файла на PHP статанализ краснеет** — шум `$this` в Pest, + гасится `app/phpstan-baseline.neon`. Пересобрать: + `php vendor/bin/phpstan analyse --memory-limit=512M --generate-baseline`, потом **глазами** + сверить diff: должны добавиться только твои файлы, удалений быть не должно. + +### Гит и сторожа + +- 🪤 **Номер записи в `db/CHANGELOG_schema.md` брать как максимум по ВСЕМ веткам плюс один.** + Последняя занятая — **v9.64**. +- 🪤 **Коммитить явными путями.** Машинный `docs/observer/STATUS.md` переписывается хуком + после каждого коммита и молча уезжает в следующий. Снимать `git restore --staged`. +- 🪤 **Штатно падают два сторожа, оба не на нашей работе:** `gitleaks-full-history` и + `lychee-links`. Отключать на **один** пуш: + `LEFTHOOK_EXCLUDE=gitleaks-full-history,lychee-links git push …`. +- 🪤 Один «Errors: 1» в прогоне экранов приходит из `AutopodborManualCompetitorError.spec.ts` + — оборванный сетевой запрос в чужом наборе, был до нас. +- 🪤 Многострочное сообщение коммита — heredoc `-F -`. Коммит с хуками идёт ~12–41 секунду + (с PHP-файлами дольше: добавляются pint, larastan, deptrac). + +### Боевой + +- 🔴 **Заливку скрипта и его запуск не соединять** одной командой — виснет на две минуты. + Два отдельных вызова: залить → выполнить → прочитать файл результата. +- 🔴 **Вывод писать в файл** (`file_put_contents`); `echo` из tinker не доезжает. + **Нет файла ⇒ скрипт УПАЛ**, а не «данных нет». +- 🔴 **`config:cache` / `optimize` — от `www-data`, НЕ от root.** +- 🔴 **Полный overlay ЗАПРЕЩЁН** — катить поимённым списком (он выше). +- 🪤 `sudo -u postgres psql` на боевой машине — **СТАРАЯ копия**. Живая база — Managed PG. +- 🪤 Демо-вход `admin@demo.local` **не работает с 01.07** — для приёмки глазами просить + доступ у владельца. + +--- + +Работа идёт **пачками**: после каждой владелец делает компакт. Не хвататься за всё сразу.