Commit Graph

1 Commits

Author SHA1 Message Date
Дмитрий 6e29acb7af feat(смс-клиент): снимок получателей живёт 90 дней и чистится сам
Строка листа 4.12, решение владельца В-45. Снимок получателей — копия
ПЕРСОНАЛЬНЫХ данных: список номеров рассылки с пометками, кому уйдёт и кому
нет. Делается один раз при создании рассылки и больше не пересматривается
(В-39), то есть после отправки лежит мёртвым грузом. Хранить его вечно нельзя.

Что сделано:
· команда `client-sms:purge-snapshots` в расписании раз в сутки в 03:30
  (проверено schedule:list) уносит строки снимка старше 90 дней. Ходит
  служебным соединением — она кросс-клиентская и пометку клиента не ставит;
· пачками по 5 000: снимок бывает на 20 000 строк, одним DELETE по дате это
  долгая блокировка. Прибор стоит именно на цикл — 5 001 строка обязана
  уйти целиком, иначе одна строка ПДн осталась бы жить вечно;
· рассылка и её итоги НЕ трогаются: `client_sms_campaigns` и журнал
  сообщений остаются, как велел владелец. Цена этого названа вслух (В-178):
  через 90 дней уже нельзя ответить, кто из получателей ждал своего утра;
· срок живёт в коде, в админке не правится (В-177): срок зависания рассылки —
  рабочая настройка, а 90 дней — обязательство про персональные данные, одно
  для всего портала. При ручном запуске срок передать можно, нулевой
  отклоняется человеческими словами — он снёс бы снимки живых рассылок;
· про снимок НЕзакончившейся рассылки команда говорит вслух и в журнал
  сервера (В-176): в норме такого не бывает, и молчать об этом нельзя.

Право `DELETE` служебной роли — миграция 2026_08_01_100900, схема v9.21
(В-152). Номер и версию взял по каталогу: названные планом были заняты
Task 5 — третий раз этот класс (В-175). Сторож `MigrationGrantsTest`
расширен и спрашивает саму базу, а не текст миграции.

🔴 Живой прогон под боевой ролью crm_supplier_worker УТОЧНИЛ мину В-152
(В-181). На стенде разрешающих политик srv_bypass нет вовсе (В-179), поэтому
бой воспроизведён: политика поставлена тем же текстом, что в
db/03_service_bypass_policies.sql, и после прогона убрана. Тройка:
(1) политика есть, права нет — команда УПАЛА «нет доступа к таблице», строки
целы (план предсказывал «удалит ноль и отрапортует успехом» — в жизни
падение); (2) право есть, политики нет — «Удалено строк снимка: 0» с кодом
УСПЕХА, вот настоящий тихий ноль; (3) обе опоры — удалено 3 из 4, свежая
строка на месте, рассылка и её сообщение на месте, предупреждение о
незаконченной рассылке прозвучало. Вывод для выката: без права беда ВИДНА
(падение), без политики НЕ видна (успешный ноль).

Проверено: ClientSms 315/315 (12 пачек, все с первой попытки), приём лидов
17/17, phpstan 2 чужие давние, pint чисто. Фронт не трогался вовсе — vitest
и vue-tsc не гонялись, правок в экранах нет ни одной. Вырезов восемь, каждый
покраснел ровно там, где вырезан; девятый — подмена служебного соединения на
обычное — НЕ покраснел вообще (6/6 зелёных), и это честный результат: чем
ходит команда, ловится только живым прогоном. Стенд возвращён и сверен со
снимком ДО; намеренное изменение одно — миграция накатана на dev-базу.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 07:47:02 +03:00