docs,передача: промт смене 14 — состояние после выката кошелька и сторожей

Задач владелец ещё не назначил, поэтому промт — про измеренное состояние и
четыре открытых вопроса, каждый из которых требует его решения: отставший
боевой «Поиск клиентов», непроверенное живьём чтение вердикта модерации,
засветившийся токен робота, копящиеся по две сборки экранов.

Записаны уроки смены: состав выката считать командой, а не по списку из
промта; причину не объявлять до замера; приёмка на живых данных вскрывает то,
чего нет в тестовых; сторожа принимать вырезанием прямо на бою через подмену
настройки только в памяти процесса.

Разметка чистая, 0 замечаний.
This commit is contained in:
Дмитрий
2026-08-03 15:11:05 +03:00
parent 2dab5f2f8d
commit 4c1fd3e92c
@@ -0,0 +1,203 @@
# ПРОМТ смене 14 — после выката кошелька телеграма и починки сторожей
**Составлен:** 03.08.2026, 15:08 по местным (красноярским) часам. Продолжает
`2026-08-03-PROMT-smena-13-operator-nomera.md` и `2026-08-03-PROMT-vykat-koshelka-telegrama.md`.
🎯 **Задачи смены владелец ещё не назначил.** Ниже — измеренное состояние и четыре открытых
вопроса, каждый из которых требует его решения. Спроси, с чего начинать, и не хватайся за всё.
---
## 0. С чего начать
1. **Перемеряй числа командой** (§1). Числа в промте протухают первыми.
2. **Прочитай §4 — открытые хвосты.** Там деньги и единственная точка отказа поиска.
3. **Спроси разрешение владельца перед любым действием на боевом.** Между шагами работай
автономно.
🪤 **Не вываливай ему этот файл.** Он его не читает — файл для тебя. Спрашивай коротко,
человеческим языком, к каждому варианту цена и выгода, и назови, что советуешь сам.
---
## 1. Сперва перемеряй
```bash
git rev-parse --abbrev-ref HEAD
git rev-list --left-right --count main...HEAD
git status --porcelain -- app/ bots/ db/ | grep -v '^??'
```
**Состояние на закрытие смены 13 (15:08 местного, 08:08 UTC 03.08.2026):**
- Рабочая ветка `feat/prospects-manual-testing-kp`: позади `main`**0**, впереди — **104**.
Своего незаписанного в коде нет.
- Последняя запись — `2dab5f2f8`.
- 🟢 **Бой и рабочая ветка совпадают байт в байт: 2629 файлов, ноль расхождений.**
- 🕘 Часы машины и владельца — **красноярские (МСК+4)**, сервер живёт в UTC. Разница 7 часов.
---
## 2. Что сделано сменой 13 — переделывать не надо
-**Модуль СМС научился определять оператора и час номера**`d4ccb5ac`, `ec026f1b`.
Бесплатный справочник Россвязи вместо одной лишь платной ДаДаты. Выкачено, покрытие
мобильных диапазонов часом **95,9 %**.
-**Кошелёк и заморозка телеграм-рекламы выкачены** — робот и портал, в правильном
порядке. Робот работает с потолком траты **1 000 ₽** (снижен с 5 000 по решению владельца).
-**Сторож рендер-виртуалки читает `ok`**`cfc2c55a`. Прежний не мог покраснеть никогда.
-**Телеграм-работа сведена в рабочую ветку**`3ea706e5`, ветка снова равна боевому.
- ✅ Снимок боевого `ПИЛОТ.md` дописан: записи «03.08 (день)» и «03.08 (вечер)».
---
## 3. 🔑 Уроки этой смены — они дороже кода
- 🔑 **Состав выката считать КОМАНДОЙ, а не по списку из промта.** Промт выката называл
12 файлов — побайтовая сверка показала **29**. По списку бой остался бы разъехавшимся.
- 🔑 **Причину не объявлять, пока не замерил.** Я дважды за смену сказал владельцу неверное:
сперва «ключа ДаДаты на бою нет» (он есть), потом принял разницу слепков робота за чужую
правку (это были переводы строк). Оба раза поправился вслух — так и надо, но лучше не
говорить до замера.
- 🔑 **Приёмка на ЖИВЫХ данных вскрывает то, чего нет в тестовых.** Тесты были зелёные, а на
бою Москва и Питер не отправлялись: в справочнике у них регион записан ПАРОЙ и кода
субъекта нет вовсе. Тестовые данные были чище жизни.
- 🔑 **Сторожа принимать только вырезанием — и это можно делать прямо на бою**, ничего там
не меняя: подменить настройку ТОЛЬКО в памяти процесса через `config([...])` в tinker и
посмотреть, покраснел ли.
- 🪤 **Своя же правка может создать перегрузку.** Справочник по одному номеру дал
**20 044 запроса и 22 секунды** на предпросмотр списка в 20 000. Поймал сторож, считающий
ЗАПРОСЫ (не время — время на стенде плавает). Пачкой стало 64 запроса и 4,6 секунды.
---
## 4. 🔴 Открытые хвосты — каждый требует решения владельца
### 4.1. Боевой «Поиск клиентов» отстаёт от ветки на 9 файлов
Замер 03.08 вечером: из 35 рабочих файлов `/opt/sales-finder` **9 расходятся**`web/app.py`,
`web/bulk.py`, `web/ui.py`, `salesfinder/rubrics.py`, `cities.py`, `models.py`, `portal.py`,
`bulkops.py`, `tools/crawl_rubricator.py`. Тесты туда не кладут, их отсутствие — не расхождение.
🔴 Боевой — это **старая основа плюс точечная заплатка рендера от 03.08**; такого дерева нет
ни в одной ветке. Слепая перезапись может сломать поиск: там невыкаченный «прогрев» от 22.07.
**Спросить владельца:** догонять боевой поиск до ветки отдельной работой или оставить.
### 4.2. Чтение вердикта модерации МТС живьём не проверено ни разу
Именно оно решает, списать деньги клиента или отпустить заморозку. Не прочитает робот ответ
МТС — кампания провиснет, деньги останутся замороженными. **Первый живой прогон
телеграм-рекламы смотреть в оба.** Живого платного прогона ещё не было.
### 4.3. Токен робота засветился в выводе команды
02.08 и снова 03.08. В файлы и коммиты не попал. **Перевыпустить.**
### 4.4. На бою копятся по две сборки каждого экрана
Распаковка старые файлы не удаляет, решает только `manifest.json`. Пока безвредно, мусор
растёт с каждым выкатом. Чистить — отдельная аккуратная работа: удалять можно только то, на
что манифест не показывает.
---
## 5. 🔴 Порядок выката — соблюдать дословно
**На этот сервер выкатывают несколько смен, каждая из своего дерева.** За сутки работу друг
друга затёрли трижды, и один раз поломка была невидимой: портал отвечал 200, журнал чист, а
экраны исчезли из сборки. Полные правила — `2026-08-03-ZAPISKA-sosednei-smene-vykat.md`.
**Перед выкладкой:** забрать чужое (`git merge` их ветки), прогнать проверки, пересобрать фронт
из дерева с ОБЕИМИ работами.
**После выкладки — сверка боя с веткой:**
```bash
git ls-tree -r HEAD --name-only -- app | ssh liderra-prod 'cd /var/www/liderra && cat > /tmp/sp.txt
&& while IFS= read -r p; do if [ -f "$p" ]; then printf "%s %s\n" "$(git hash-object "$p")" "$p";
else printf "NETFAYLA %s\n" "$p"; fi; done < /tmp/sp.txt' | sort > /tmp/boy.txt
git ls-tree -r HEAD -- app | awk '{print $3" "$4}' | sort > /tmp/vetka.txt
comm -3 /tmp/vetka.txt /tmp/boy.txt | awk '{print $NF}' | sort -u
```
🪤 **Ответ ssh может прийти пустым** — тогда «расходится всё». Сперва `wc -l`, потом выводы.
🪤 **Проверять состав сборки ПО СУЩЕСТВУ:** искать в обслуживаемом куске текст, который рисует
нужный экран, а не считать файлы. Манифест показывает, какой из кусков реально отдаётся.
🪤 **Распаковка поверх** требует `sudo tar --overwrite` — файлы уже есть, каталоги не наши.
После неё обязательно `chown ubuntu:www-data` и перезапуск `php8.3-fpm` **И** `liderra-queue`.
🪤 **Папку `db/` сверять через `tr -d '\r'`**у `app/**` в `.gitattributes` задан `eol=lf`,
у `db/**` нет.
🪤 **Файлы «есть на бою, нет в ветке»** — обычно мёртвые хвосты; проверять `git log --all -- <файл>`.
---
## 6. 🔴 Боевой: что трогать нельзя без разговора
- **`client_sms_settings.allowed_operators = ["mts"]`** — имя отправителя `liderra.ru`
подключено у МТС только на одного оператора. Снимать, когда подключат остальных.
- **Потолок робота `BUDGET_CAP_RUB=1000`** в `C:\liderra\mts-telegram-robot\.env` — решение
владельца на первый боевой прогон. Баланс кабинета МТС около 5 010 ₽.
- **`.env` боевого** — там боевые ключи, в посылку не попадает.
- **Миграции — только под `crm_migrator`**, пароль в Lockbox по **ID `e6qeooj45vqtn2fju58r`**
(по имени команда молча отдаёт пустоту). `yc` на бою лежит в
`/home/ubuntu/yandex-cloud/bin/yc`, в PATH его нет.
- 🪤 **Чтение боевой базы через `tinker` режется защитой строк.** Датчики:
`set_config('app.current_tenant_id', ...)`, `pg_stat_user_tables.n_live_tup` либо соединение
`pgsql_supplier` (политики `srv_bypass`).
- 🪤 **`php artisan tinker <файл>` на бою ЗАВИСАЕТ.** Работает только код **через stdin** с
полными именами классов.
**Откаты, лежат в `/var/www/liderra`:** `_deploy-bak-sms-20260803.tgz`,
`_deploy-bak-operator-20260803.tgz`, `_deploy-bak-para-20260803.tgz`,
`_deploy-bak-tgkoshelek-20260803.tgz`, `_bak-storozh-vm-20260803.php`.
Робот — `C:\liderra\_bak-koshelek-20260803`. Вся телеграм-реклама целиком — `TG_SANDBOX=true`.
---
## 7. Что владелец решил раньше — не переспрашивать
1. **Копий веток вне этого диска нет.** Напомнить один раз в итоге смены.
2. **Перевод `main` на рабочую ветку отклонён.** `main` отстаёт на 104 записи; кто выкатит
`main` — откатит боевой. Местная и серверная `main` вдобавок разъехались в обе стороны.
3. **Время в интерфейсе показываем по МОСКВЕ.**
4. **Описание базы остаётся в ДВУХ файлах.**
5. **Тариф МТС «Оплата по факту» + цена 5,03 ₽**; клиенту СМС считается по 9 ₽.
6. **Ограничение «только МТС»** и **потолок робота 1 000 ₽** — его решения от 03.08.
7. **След пробы СМС в боевой базе оставлен как есть** (две рассылки и контакт с его личным
номером, у которого оператор проставлен руками). Обход не снят.
8. **Шесть планов СМС вне git не забирать** — чужая папка.
---
## 8. Общие правила — их нарушение и есть источник всех бед
- 🔑 **Сначала замер, потом лечение, потом замер снова.** Числа записывать.
- 🔑 **Всё, что промт говорит о БОЕВОМ, — гипотеза, пока не замерена командой.**
- 🔑 **Зелёный тест ничего не доказывает, пока не видел его красным.**
- 🔑 **Тест, который собирает состояние руками, охраняет дыру.**
- 🔴🔑 **Есть доступ к чужой системе — открой её ГЛАЗАМИ.**
- 🪤 **Файлы править только Edit/Write.** Запись из-под Bash может молча исчезнуть;
создание, удаление и проверку делать разными вызовами.
- 🪤 **`composer stan`, а не голый phpstan** — сторож встроен в команду проекта.
- 🪤 **Статанализ может упасть не из-за кода:** `_ide_helper_models.php` лежит вне git, у
каждой рабочей папки свой. Лечение — догнать местную базу миграциями и пересобрать
`php artisan ide-helper:models -M -n`. Пересборка убирает пустую строку перед `@mixin` в
34 моделях — это косметика форматтера, откатывать.
- 🪤 **`pint` в этой ветке правит 11 давних чужих файлов** — откатывать, не записывать.
- 🪤 Тестовая база — `liderra_testing_prospects`, звать прогон с явной базой.
---
## 9. Церемония записи
- Запись делает смена сама, **попросив эскейп**: `AskUserQuestion`, где **метка опции —
ТОЧНАЯ команда**.
- Сообщение держать **в файле вне репозитория**, звать `git commit -F <файл> <пути>`.
Для новых файлов нужен `git add`. Временный файл после записи убрать.
- В командной строке **не должно быть круглых скобок**.
- Записывать **перечисленные пути**, не `-A`.
- 🪤 `docs/observer/STATUS.md` пре-стейджит хук — снимать `git restore --staged`.
- 🪤 **Слияние нельзя записать по путям**`git commit -F <файл>` без путей, поэтому сперва
проверь подготовленное: `git diff --cached --name-only`.
- 🪤 Бумаги с разметкой писать с `LEFTHOOK_EXCLUDE=markdownlint,cspell`.