Контракт хранения и очистки заявок

Текущее состояние

Публичный Supabase endpoint не подключён. Сайт работает в режиме:

lead_capture:
  mode: "web3forms"
  endpoint: ""

Политика retention подготовлена только в исходниках и после применения миграции остаётся выключенной:

enabled = false

Значения 365, 180 и 7 дней являются техническими стартовыми параметрами для тестирования. Они не считаются утверждённым юридическим сроком и не должны активироваться до отдельного решения владельца, проверки применимых требований и обновления документов сайта.

Миграция

supabase/migrations/202607140001_broker_lead_retention.sql

Миграция добавляет:

Применение миграции само по себе не запускает очистку и не создаёт Cron job.

Разрешённые terminal-статусы

Retention может учитывать только:

Настройка terminal_statuses ограничена SQL constraint. Добавить в неё new, in_progress, неизвестный или произвольный статус нельзя.

Условия обезличивания

Лид может быть обезличен только при одновременном выполнении всех условий:

  1. anonymized_at is null;
  2. retention_hold = false;
  3. статус входит и в настроенный terminal-набор, и в жёсткий SQL whitelist;
  4. notification_status равен sent или disabled;
  5. с даты заявки прошло не меньше настроенного срока;
  6. политика явно включена;
  7. оператор передал точную строку подтверждения APPLY_BROKER_RETENTION.

Заявки со статусами уведомления pending, sending или failed не обезличиваются независимо от возраста.

Любой активный, неизвестный или неутверждённый статус защищён по принципу fail-closed.

Retention hold

retention_hold = true запрещает:

Hold снимается только отдельным осознанным административным действием после проверки основания. Автоматического снятия hold нет.

Preview

broker_lead_retention_preview() возвращает только агрегаты:

Preview не возвращает UUID, request ID, имя, телефон, город, источник, комментарий или содержимое заявки.

Preview обязателен перед каждым реальным запуском.

Что удаляется при обезличивании

Очищаются контактные, содержательные и трассировочные данные:

Поле phone заменяется техническим значением [anonymized], потому что базовая схема запрещает null.

Сохраняются только минимальные технические признаки, необходимые для целостности и агрегированного аудита, включая внутренний UUID, request ID, даты, terminal-статус, статус доставки, счётчики попыток и время обезличивания.

Что не удаляется

Механизм намеренно не выполняет:

delete from public.broker_leads

Строки лидов не удаляются физически. Это защищает от удаления активной заявки из-за ошибочной настройки и сохраняет минимальную доказуемость выполненной очистки.

Hard delete может быть разработан только отдельной миграцией, отдельным контрактом и отдельным smoke-тестом.

События и rate limit

События удаляются только если:

События активных и необезличенных лидов не удаляются.

Rate-limit записи не содержат исходный IP, полный телефон или payload и очищаются существующей функцией purge_broker_lead_rate_limits по отдельному короткому сроку.

Атомарность

Один вызов retention выполняется в одной транзакции.

Если обезличивание, удаление событий, очистка rate limit или запись результата завершаются ошибкой, весь вызов откатывается. Частично очищенного набора и ложной записи completed быть не должно.

broker_lead_retention_runs получает строку только после полного успешного выполнения.

Журнал запуска содержит только:

Идентификаторы и содержимое заявок в журнал не записываются.

Доступ

Таблицы и RPC:

Функции используют фиксированный search_path = public. Публичный браузер не должен вызывать retention RPC.

Web3Forms и email

Retention Supabase не удаляет:

Сроки и удаление в этих каналах регулируются отдельными настройками и процедурами. Нельзя сообщать пользователю, что Supabase purge удалил копии в сторонних каналах.

Планировщик

Автоматический Cron job намеренно не создаётся миграцией.

После применения миграции и успешного smoke-теста допускается отдельно настроить Supabase Cron на вызов retention-функции. До этого каждый запуск выполняется вручную после preview. Cron не должен включаться одновременно с первым production-тестом.

Активационный барьер

Политика может быть включена только после:

  1. подтверждения Supabase-проекта;
  2. применения всех миграций по порядку;
  3. проверки RLS и прав RPC;
  4. утверждения terminal-статусов;
  5. утверждения сроков хранения;
  6. проверки preview на тестовых данных;
  7. проверки active, unresolved notification и hold-защит;
  8. проверки атомарного отката;
  9. утверждения ответственного и журнала запусков;
  10. обновления политики и согласия сайта перед реальным серверным хранением;
  11. отдельной проверки Web3Forms/email retention;
  12. фиксации результата в issue.

До выполнения этих условий сохраняются enabled = false, mode: web3forms и пустой публичный endpoint.

ЗаявкаПозвонитьВК