From b6c837e28af7a14f32fa503ad1fc55d8b8f7dee2 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: Thu, 30 Jul 2026 15:05:08 +0300 Subject: [PATCH] =?UTF-8?q?chore(=D1=81=D0=BC=D1=81-=D0=BA=D0=BB=D0=B8?= =?UTF-8?q?=D0=B5=D0=BD=D1=82):=20=D0=BF=D1=80=D0=B8=D1=91=D0=BC=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=AD=D1=82=D0=B0=D0=BF=D0=B0=204=20=E2=80=94=20?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=20=D0=BF=D0=BE=20=D0=B2?= =?UTF-8?q?=D1=81=D0=B5=D0=B9=20=D0=BE=D0=B1=D0=BB=D0=B0=D1=81=D1=82=D0=B8?= =?UTF-8?q?=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8F,=20=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=BE=20=D1=81=D0=B2=D0=B5=D0=B6=D0=B8=D0=BC=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task 8, приёмка Этапа 4. Кода она не приносит по замыслу: все двенадцать строк листа (4.1–4.8, 4.11–4.14) закрыты ДВУМЯ доказательствами каждая — тест И живой прогон, — экранные строки отдельно посмотрены глазами в браузере. Итоговая таблица Этапа 4 заполнена в приёмочном листе (лист в git не лежит). В git уходит ровно одна правка — порядок импортов в шести файлах тестов (В-192). Причина, по которой она вообще нашлась: три этапа подряд `pint` гонялся ТОЛЬКО по свежим файлам, а по всей области модуля не гонялся ни разу. Заодно выяснено, что жалобы `line_ending` чинить не надо — это виндовые переводы строк рабочей копии, в git их нет вовсе (pint «исправил», git не увидел ни одного изменения). Перегнаны тесты этих шести файлов: 41/41 зелено. 🔴 ДЕНЕЖНАЯ МИНА СВЕРХ ПОСТРОЕННОГО (В-190). Права спросил у самой базы матрицей по всем таблицам модуля — и увидел, что у рабочей роли crm_app_user есть право писать в таблицу заморозок, а на её счётчик номеров ad_wallet_holds_id_seq права нет. Живой прогон парно: без права заморозка денег под боевой ролью ПАДАЕТ («нет доступа к последовательности»), с правом идёт. Заморозка делается при КАЖДОМ заказе рассылки, при заказе имени и при запуске рекламной кампании Яндекса. Промах был мой: в В-142 я привёл стенд к эталону двумя точечными командами по именам из плана вместо `ON ALL SEQUENCES`, как делает сам db/02_grants.sql. Памятка выката переписана: вместо списка имён счётчиков — запрос, который САМ находит все счётчики без права. На бою проверить (косвенно там всё в порядке — рекламные кампании запускаются тем же кодом, но довод косвенный). 🔴 И ПЕРВЫЙ ЗАХОД ПРИЁМКИ ПРОШЁЛ «ЗЕЛЕНО», НЕ ДОКАЗАВ НИ ОДНОЙ ДЕНЕЖНОЙ СТРОКИ (В-191): песочница гасит и возврат заморозки при срыве, и ночного работника целиком. Датчик на будущее — не сдвинулась ни одна копейка, значит прогон не доказал ничего, даже когда всё зелено. Ещё три промаха своих же приборов: В-193 и В-194 (прогон не доходил до состояния — сторож законно даёт попытке дожать её срок, а имя без отметки согласования кнопка законно не включает: правда была в коде), В-195 (браузерный замер читал таблицу рассылок вместо базы и «доказал» поломку, которой нет — класс В-121, соврал прибор). Живьём под боевой ролью crm_app_user: сторож зависших тремя заходами (пометка → выдержка срока → срыв, заморозка 17.00 → 0.00); имя за долг вернулось и списало ровно 100 ₽, отключённое владельцем осталось выключенным при 5 000 ₽; кнопка включения отказала числами, без пометки клиента 404, с пометкой списала 600 ₽; номера руками легли пятью видами записи; продолжение довело 5 из 5 за 42.50 ₽. Под служебной ролью — чистка снимка тройкой (без права падение, без политики srv_bypass «успешный ноль», с обоими удалено 3). Прогоны: ClientSms 320/320 (13 пачек, все с первой попытки), приём лидов 17/17, фронт 1700 + 3 пропущенных (одна чужая давняя ошибка, В-57), phpstan ровно 2 чужие давние, vue-tsc ровно 5 чужих давних в 5 файлах (git blame: от 25.07), pint чисто. Стенд сверен со снимком «до» поле за полем и совпал. Намеренное изменение одно: рабочей роли выданы права на ВСЕ счётчики схемы, как в эталоне db/02_grants.sql. 🟡 Открытый вопрос владельцу — В-182: номера в журнале сообщений живут без срока, обязательство «90 дней» закрывает только снимок получателей. Ветка НЕ влита в main и НЕ выкачена. Порядок выката: миграции → db/03_service_bypass_policies.sql → подсчёт политик srv_bypass (+8) → права → контрольный запуск чистки снимка. Co-Authored-By: Claude Opus 5 --- app/tests/Feature/ClientSms/AutoSmsTest.php | 2 +- app/tests/Feature/ClientSms/CancelCampaignTest.php | 2 +- app/tests/Feature/ClientSms/NoFundsStopTest.php | 2 +- app/tests/Feature/ClientSms/SendJobTest.php | 2 +- app/tests/Feature/ClientSms/SnapshotTest.php | 2 +- app/tests/Feature/ClientSms/WindowCampaignTest.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/tests/Feature/ClientSms/AutoSmsTest.php b/app/tests/Feature/ClientSms/AutoSmsTest.php index 7d6eb6fe..e33c019a 100644 --- a/app/tests/Feature/ClientSms/AutoSmsTest.php +++ b/app/tests/Feature/ClientSms/AutoSmsTest.php @@ -11,8 +11,8 @@ use App\Models\Deal; use App\Models\Tenant; use App\Models\User; use App\Services\Advertising\AdWalletService; -use App\Services\ClientSms\ClientSmsPricing; use App\Services\ClientSms\AllowedSmsOperators; +use App\Services\ClientSms\ClientSmsPricing; use App\Services\ClientSms\ClientSmsRecipientSelector; use App\Services\ClientSms\SmsQuietHours; use App\Services\DaData\DaDataBudgetGuard; diff --git a/app/tests/Feature/ClientSms/CancelCampaignTest.php b/app/tests/Feature/ClientSms/CancelCampaignTest.php index 828d3141..e7c6e28a 100644 --- a/app/tests/Feature/ClientSms/CancelCampaignTest.php +++ b/app/tests/Feature/ClientSms/CancelCampaignTest.php @@ -10,9 +10,9 @@ use App\Models\ClientSmsMessage; use App\Models\Tenant; use App\Models\User; use App\Services\Advertising\AdWalletService; +use App\Services\ClientSms\AllowedSmsOperators; use App\Services\ClientSms\ClientSmsAudienceBuilder; use App\Services\ClientSms\ClientSmsPricing; -use App\Services\ClientSms\AllowedSmsOperators; use App\Services\ClientSms\ClientSmsRecipientSelector; use App\Services\ClientSms\ClientSmsSnapshotReader; use App\Services\ClientSms\ClientSmsSnapshotWriter; diff --git a/app/tests/Feature/ClientSms/NoFundsStopTest.php b/app/tests/Feature/ClientSms/NoFundsStopTest.php index a8cc1561..037cd118 100644 --- a/app/tests/Feature/ClientSms/NoFundsStopTest.php +++ b/app/tests/Feature/ClientSms/NoFundsStopTest.php @@ -9,9 +9,9 @@ use App\Models\ClientSmsContact; use App\Models\ClientSmsMessage; use App\Models\Tenant; use App\Services\Advertising\AdWalletService; +use App\Services\ClientSms\AllowedSmsOperators; use App\Services\ClientSms\ClientSmsAudienceBuilder; use App\Services\ClientSms\ClientSmsPricing; -use App\Services\ClientSms\AllowedSmsOperators; use App\Services\ClientSms\ClientSmsRecipientSelector; use App\Services\ClientSms\ClientSmsSnapshotReader; use App\Services\ClientSms\ClientSmsSnapshotWriter; diff --git a/app/tests/Feature/ClientSms/SendJobTest.php b/app/tests/Feature/ClientSms/SendJobTest.php index 6494e995..10d22334 100644 --- a/app/tests/Feature/ClientSms/SendJobTest.php +++ b/app/tests/Feature/ClientSms/SendJobTest.php @@ -10,9 +10,9 @@ use App\Models\ClientSmsMessage; use App\Models\ClientSmsOptout; use App\Models\Tenant; use App\Services\Advertising\AdWalletService; +use App\Services\ClientSms\AllowedSmsOperators; use App\Services\ClientSms\ClientSmsAudienceBuilder; use App\Services\ClientSms\ClientSmsPricing; -use App\Services\ClientSms\AllowedSmsOperators; use App\Services\ClientSms\ClientSmsRecipientSelector; use App\Services\ClientSms\ClientSmsSnapshotReader; use App\Services\ClientSms\ClientSmsSnapshotWriter; diff --git a/app/tests/Feature/ClientSms/SnapshotTest.php b/app/tests/Feature/ClientSms/SnapshotTest.php index 14459db3..94931d6a 100644 --- a/app/tests/Feature/ClientSms/SnapshotTest.php +++ b/app/tests/Feature/ClientSms/SnapshotTest.php @@ -12,8 +12,8 @@ use App\Models\ClientSmsOptout; use App\Models\Tenant; use App\Models\User; use App\Services\Advertising\AdWalletService; -use App\Services\ClientSms\ClientSmsPricing; use App\Services\ClientSms\AllowedSmsOperators; +use App\Services\ClientSms\ClientSmsPricing; use App\Services\ClientSms\ClientSmsRecipientSelector; use App\Services\ClientSms\ClientSmsSnapshotReader; use App\Services\Sms\OperatorNormalizer; diff --git a/app/tests/Feature/ClientSms/WindowCampaignTest.php b/app/tests/Feature/ClientSms/WindowCampaignTest.php index 33237ccb..8e6056ee 100644 --- a/app/tests/Feature/ClientSms/WindowCampaignTest.php +++ b/app/tests/Feature/ClientSms/WindowCampaignTest.php @@ -11,8 +11,8 @@ use App\Models\Deal; use App\Models\Tenant; use App\Models\User; use App\Services\Advertising\AdWalletService; -use App\Services\ClientSms\ClientSmsPricing; use App\Services\ClientSms\AllowedSmsOperators; +use App\Services\ClientSms\ClientSmsPricing; use App\Services\ClientSms\ClientSmsRecipientSelector; use App\Services\ClientSms\ClientSmsSnapshotReader; use App\Services\Sms\OperatorNormalizer;