Files
portal/app/database
Дмитрий 30ca789507 feat,обзвон: место под звонок — таблица попыток и единственный итог по номеру
Задача З-1.1 плана «Обзвон под клиента». До этой правки фичи в портале не было
вовсе, и звонок было некуда положить: нечего списывать, нечего показать клиенту и
нечем ответить через год на вопрос «за что вы взяли с меня деньги в августе».

Заведены две таблицы, обе с защитой по клиентам ENABLE + FORCE:

- obzvon_calls — одна попытка набора. По номеру их бывает до двенадцати, и каждая
  своя строка со своим исходом. Держит два плеча врозь: робот с человеком и
  человек с менеджером после перевода, у каждого своя длительность и свой признак
  «состоялось». Держит два срока хранения и два следа удаления: звук месяц, текст
  три месяца, дальше живут сухие итоги.
- obzvon_number_results — единственный итог на всю работу с номером. Именно он
  стоит в карточке сделки, а не последняя попытка. Замок — UNIQUE по клиенту,
  кампании и номеру: двенадцать недозвонов дают ОДИН итог, а не двенадцать.

Расшифровка лежит в той же строке звонка. Отдельного хранилища под неё нет
намеренно — решение Р50 сняло бессрочную обезличенную расшифровку.

Имя своё, а не call_recordings из закомментированного чертежа: чертёж был про
телефонию вообще и не знает ни статуса обзвона, ни сроков со следом удаления, ни
«почему звонили», ни двух плеч, ни попыток с итогом. Чертёж не тронут.

Цена звонка запоминается в строке вместе со снимком тарифа, а не вычисляется из
действующего тарифа при показе: иначе смена тарифа задним числом перепишет
вчерашние счета. Образец — lead_charges.tier_no + price_per_lead_kopecks. Деньги
целыми копейками.

Строку звонка никто не удаляет: право DELETE не выдано ни одной роли. Вместе со
строкой ушли бы деньги, а спросить «за что вы взяли» клиент вправе и через год.

Канон — db/schema_modules.sql, новый раздел 23. Тело db/schema.sql таблиц не
получает: оно исполняется первой миграцией, и таблицы дельта-миграций в него
класть нельзя — это прямо запрещает сторож канона. В db/schema.sql добавлена
только пометка над закомментированным чертежом call_recordings: чертёж не
использован и не будет, модуль живёт в obzvon_*, и перечислено, чего чертёж не
знает. Чтобы следующая смена не воскресила его по недоразумению.

Журнал схемы — запись v9.68, номер свободен, столкновения нет.

Проверено: 21 сторож, в том числе изоляция клиентов живым запросом из-под роли
crm_app_user, а не глазами по миграции; служебная роль после перезапуска
db/03_service_bypass_policies.sql правит именно ту строку, а не «успешно ноль»;
откат миграции хвостов не оставляет; squawk с конфигом проекта чист; статанализ
по новым файлам ноль. Каждый сторож показан красным.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 11:01:19 +03:00
..