Files
portal/docs/Workflow_pd_subject_requests_v8_2.md
T
Дмитрий 04f38b1e57 docs(archive): add Прил. Н + CLAUDE.md, sync archive to v8.3.3
Новые файлы:
- CLAUDE.md (корень) — оперативная карта для Claude Code: приоритет правил
  (5 уровней), стек проекта, карта 28 инструментов «когда что использовать»,
  10 запретов, текущая фаза.
- docs/Tooling_v8_3.md (Прил. Н v1.0) — единый реестр 28 инструментов
  разработки, скиллов Claude Code, MCP-серверов и плагинов в 4 фазах
  (фаза 0 — текущая, +1 Laravel, +2 Vue/Vuetify, +3 pre-prod). §6 конфликты
  и решения, §7 приоритет правил, §9 что НЕ ставим (10+ запретов), §10
  процедура перехода между фазами, §11 Windows + PowerShell.

Обновления версий:
- docs/Pravila_raboty_Claude_v1_1.md → v1.2: §4.8 «Шифры приложений» —
  Н занят (12 шифров: А, Б, В, Г, Д, Е, Ж, З, И, К, М, Н).
- docs/README_АРХИВ_v8_3.md → v8.3.3: добавлена строка истории, обновлены
  таблицы состава (18 файлов в docs/+db/ + CLAUDE.md), добавлена ветка
  чтения «Claude / разработчик».
- docs/Открытые_вопросы_v8_3.md → v1.9 (через шапку, упоминание Прил. Н).

Точечные правки в архиве:
- 6 фиксов MD028 (пустые строки внутри blockquote → заменены на `>`):
  docs/Админка_SaaS_v8_2.md (1), docs/Приложение_Б_В_БД_диаграммы_v8_3.md (3),
  docs/Oferta_i_Politika_v8_2.md (2).
- 1 фикс MD056 (недостающая колонка в таблице) в
  docs/Аудит_partii_12_15_originala_v8_3.md:1085.
- 2 опечатки (русские буквы в латинских словах):
    docs/README_АРХИВ_v8_3.md: `соft-deleted` → `soft-deleted`
    docs/CRM_bp-gr_Инструкция_v8_3.md: `raтe limit` → `rate limit`
- Авто-форматирование trailing whitespace и blanks-around-lists
  через markdownlint --fix (хук .claude/settings.json).

Baseline после коммита:
- markdownlint: 0 errors
- cspell: 0 unknown words
- lychee: 24 OK / 0 errors
- stylelint: 0 errors
- gitleaks: no leaks

Архитектурных изменений: 0. Состав архива: 18 файлов в docs/+db/ + CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 04:45:22 +07:00

64 KiB
Raw Blame History

Workflow обращений субъектов ПДн (pd_subject_requests) — v8.2, Приложение Д

Версия: 8.2 от 04.05.2026 (правки после интервью с заказчиком).

Что нового в v8.2 относительно v8.1

  • OPEN-Д-1 закрыт. В таблицу pd_subject_requests добавляется новое поле processing_restricted BOOLEAN NOT NULL DEFAULT FALSE — флаг полной остановки обработки ПДн субъекта по требованию (ст.21 152-ФЗ, право на ограничение обработки). При установке этого флага все последующие операции с ПДн данного субъекта в системе должны проверять флаг и отказывать. Имплементация: if (subject.processing_restricted) throw new ProcessingRestrictedException() в сервисном слое + RLS-политика на чтение в БД-слое (опционально, для defense-in-depth).
  • OPEN-Д-5 закрыт. Создаётся таблица incidents_log для журнала инцидентов (объединена с OPEN-И-1). DDL:
CREATE TABLE incidents_log (
    id                            BIGSERIAL PRIMARY KEY,
    type                          VARCHAR(50) NOT NULL, -- 'rls_leak', 'pd_breach', 'webhook_storm', 'gateway_outage', 'cron_silence', 'manual'
    severity                      VARCHAR(20) NOT NULL, -- 'low', 'medium', 'high', 'critical'
    started_at                    TIMESTAMPTZ NOT NULL,
    detected_at                   TIMESTAMPTZ NOT NULL,
    resolved_at                   TIMESTAMPTZ,
    summary                       TEXT NOT NULL,
    root_cause                    TEXT,
    postmortem_url                VARCHAR(500),
    related_pd_subject_request_ids BIGINT[],            -- если инцидент связан с ПДн-обращениями
    created_by_admin_id           BIGINT REFERENCES saas_admin_users(id),
    created_at                    TIMESTAMPTZ DEFAULT NOW(),
    CHECK (severity IN ('low','medium','high','critical')),
    CHECK (resolved_at IS NULL OR resolved_at >= started_at)
);
CREATE INDEX idx_incidents_started ON incidents_log(started_at DESC);
CREATE INDEX idx_incidents_severity_unresolved ON incidents_log(severity) WHERE resolved_at IS NULL;

Используется в Прил. Д (раздел 7 — связь с обращениями субъектов) и в Прил. И (раздел 5 — журнал runbook).

Назначение документа: закрыть пробел 🟠 №7 из конспекта анализа v8.0 — «детали 152-ФЗ для Роскомнадзора неполные, нет workflow для pd_subject_requests». Документ — развёртка раздела 22.9.5 главного файла v8.1: добавлены детальный жизненный цикл, шаблоны писем, временна́я раскадровка внутри 30-дневного дедлайна, процедура проверки личности заявителя и фаза «уведомление вторичных операторов» в трёхзвенной цепочке ПДн.

Статус: драфт для согласования с юристом. Юридические формулировки в шаблонах писем — рабочие, подлежат финальной редактуре юристом в рамках Ю-5. Архитектурные и процедурные решения, требующие подтверждения заказчиком, помечены [?]. Открытые вопросы — в разделе 9 в конце.

Базовые ссылки на v8.1:

  • 1.5–1.6 — реселлерская модель и трёхзвенная цепочка ПДн (Ю-2)

  • 22.9 — общий блок 152-ФЗ

  • 22.9.1 — три типа согласий (tenant_consents)

  • 22.9.2 — удаление по запросу самого тенанта (отличать от обращений физлиц-лидов!)

  • 22.9.3 — журнал обработки pd_processing_log

  • 22.9.5 — таблица pd_subject_requests (определение)

  • 22.9.6 — impersonation (Ю-1)

  • Приложение А (schema.sql) — DDL pd_subject_requests, индексы, CHECK-constraints

  • Приложение Г (Админка_SaaS_v8_1_драфт.md) — экран «152-ФЗ / Compliance», роль compliance

Юридический контекст: ФЗ-152 «О персональных данных», глава 3 (права субъекта ПДн), ст. 14 (право на доступ), ст. 21 (обязанности оператора при удалении), ст. 22 (уведомление Роскомнадзора). Срок ответа на обращение — не более 30 дней с момента получения (ч. 4 ст. 20 ФЗ-152, плюс возможное продление до 30 рабочих дней при сложных запросах — мы по умолчанию работаем в 30 календарных).


0. Содержание

  1. Зачем отдельный документ
  2. Кто такие «субъекты ПДн» в нашей трёхзвенной модели
  3. Жизненный цикл обращения (state machine)
  4. Временна́я раскадровка внутри 30 дней
  5. Процедура проверки личности заявителя
  6. Уведомление вторичных операторов (особый шаг v8.1)
  7. Шаблоны писем
  8. UI / экраны в админке SaaS
  9. Открытые вопросы

1. Зачем отдельный документ

В v8.1 раздел 22.9.5 определяет таблицу pd_subject_requests и обозначает требование к workflow, но прямо помечает: «Полный workflow с шаблонами писем, сроками внутри 30-дневного дедлайна, проверкой личности заявителя — отдельный артефакт (готовится при необходимости)». Этот документ закрывает указанный пробел.

Ключевые отличия от обработки запроса самого тенанта (раздел 22.9.2):

Параметр Тенант → свои данные (22.9.2) Физлицо-лид → свои данные (этот документ)
Кто заявитель Зарегистрированный пользователь Внешнее физлицо, у нас аккаунта нет
Идентификация Через активную сессию + email-подтверждение Не очевидна — нужна отдельная процедура (раздел 5)
Канал обращения UI /account Email, форма на сайте, бумажное письмо
Объём данных Только то, что собрано про самого тенанта Лиды по разным тенантам, может быть в нескольких записях
Срок 30 дней (мягкий, реально — несколько минут) 30 дней (жёсткий по 152-ФЗ)
Уведомление третьих лиц Не нужно (тенант — конечная точка) Обязательно — crm.bp-gr.ru вверх и тенанты вниз (раздел 6)
Архитектурный объект tenants.deleted_at + cron tenants:purge-deleted pd_subject_requests + ручной workflow
Кто исполняет Автоматический cron Админ роли compliance (Приложение Г)

То есть это разные процессы, и важно их не путать. Текущий документ — про второй случай.


2. Кто такие «субъекты ПДн» в нашей трёхзвенной модели

В реселлерской модели v8.1 (Ю-2) ПДн физлица проходит цепочку:

физлицо (источник) → crm.bp-gr.ru → мы (SaaS) → тенант (наш клиент)
                          оператор-1     оператор-2   оператор-3

Каждое звено — самостоятельный оператор. Это значит:

  • Физлицо-лид имеет право обратиться в любое из трёх звеньев независимо.
  • Если обращение пришло к нам — мы обязаны ответить в части наших данных, не уклоняясь под предлогом «обратитесь к первоисточнику».
  • При удалении мы обязаны уведомить других операторов (раздел 6), но не обязаны добиваться, чтобы они тоже удалили — это уже их зона ответственности.

Какие данные физлица у нас есть:

Таблица Поля с ПДн физлица
deals phone, contact_name, comment (может содержать ПДн)
webhook_log raw_payload JSONB — копия webhook от crm.bp-gr.ru, в т.ч. ПДн
pd_processing_log subject_type='lead', subject_id — ссылка на deals.id
supplier_lead_costs только deal_id — без ПДн напрямую (но связано через FK)
Файлы (S3) экспорты с лидами, если тенант их выгружал

Какие действия мы можем выполнить по запросу:

Тип запроса (request_type) Что делаем
access (право на доступ, ст. 14) Выдаём выписку: где и когда мы получили данные, кому передавали (FK на тенанта), сроки хранения, основание обработки
deletion (право на забвение, ст. 21) Анонимизируем deals, удаляем webhook_log.raw_payload, удаляем S3-экспорты, уведомляем вторичных операторов
correction (исправление, ст. 21) Меняем deals.contact_name / deals.phone на корректные значения, фиксируем в pd_processing_log
restriction (ограничение обработки) Помечаем сделку флагом processing_restricted [?][OPEN-Д-1] нужен такой флаг или достаточно удаления

Замечание: в v8.1 поля processing_restricted в deals нет. Если решим внедрять — это +миграция в v8.2. До того момента «ограничение обработки» в нашем случае схлопывается в «удаление».


3. Жизненный цикл обращения (state machine)

Поле pd_subject_requests.status принимает значения:

received → identity_verification → identity_verified → processing → completed
    ↓              ↓                       ↓                ↓
    └──────────────┴───────────────────────┴────────────────┴──→ rejected

Состояния:

Статус Что означает Кто переводит Дедлайн от received_at
received Запрос принят, сохранён, ему присвоен id, заявителю отправлено письмо-подтверждение №1 Автомат при создании записи
identity_verification Заявителю отправлен запрос на подтверждение личности (письмо №2), ждём ответа Админ compliance до 3 дней
identity_verified Личность подтверждена, начинаем поиск данных и подготовку ответа Админ compliance до 7 дней
processing Идёт работа: формируется выписка / выполняется удаление / корректировка; параллельно идут уведомления вторичных операторов (для deletion) Админ compliance до 25 дней
completed Запрос выполнен, заявителю отправлено финальное письмо №4, запись закрыта Админ compliance до 30 дней (жёстко)
rejected Запрос отклонён (личность не подтверждена / данных у нас нет / запрос вне нашей компетенции). Заявителю отправлено письмо №5 с обоснованием Админ compliance до 30 дней (жёстко)

Невалидные переходы (контролируются CHECK-constraint в schema.sql v8.2 [OPEN-Д-2]):

  • completed → * — финальный статус, нельзя «переоткрыть» (если нужно — создаётся новый pd_subject_requests).
  • rejected → completed — нельзя реабилитировать через смену статуса, только новой записью.
  • received → completed напрямую — обязательно через identity_verified (защита от случая «админ забыл проверить личность»).

Поля состояния, которые заполняются автоматически при переходах:

Переход Что выставляется
→ received received_at = NOW(), deadline_at = NOW() + INTERVAL '30 days'
→ identity_verification identity_request_sent_at = NOW() [?] (нужно добавить поле в v8.2)
→ identity_verified identity_verified_at = NOW(), identity_verification_method (раздел 5)
→ processing processing_started_at = NOW(), assigned_admin_id (если ещё не задан — назначается на текущего)
→ completed completed_at = NOW(), заполняется result_summary (свободный текст: что именно сделано)
→ rejected completed_at = NOW(), rejection_reason VARCHAR(50) (см. enum ниже)

Enum rejection_reason [OPEN-Д-3] (предлагаю фиксировать в v8.2):

  • identity_not_confirmed — заявитель не подтвердил личность за 3 дня или подтверждение не прошло;
  • no_data_found — мы искали, в наших таблицах данных по этому контакту нет;
  • out_of_scope — запрос на действия, которые мы не можем выполнить (например, «удалите меня из всех CRM в России»);
  • duplicate — это повторное обращение от того же лица по тому же поводу, ранее уже закрытое;
  • legal_hold — на данные наложен legal hold (например, идёт судебное разбирательство, требующее их сохранения).

4. Временна́я раскадровка внутри 30 дней

30-дневный дедлайн ФЗ-152 — жёсткий. Раскадровка ниже — внутренние SLA, дающие запас на форс-мажоры.

4.1. Стандартный сценарий — deletion

День Действие Ответственный Артефакт
0 (момент received_at) Запрос автоматически создан в pd_subject_requests, статус received. Письмо №1 заявителю — подтверждение получения с request_id и сроком ответа Автомат Письмо №1 (раздел 7.1)
01 Админ compliance берёт запрос в работу, проверяет полноту данных заявителя (раздел 5.1), переводит в identity_verification, отправляет письмо №2 Админ compliance Письмо №2 (раздел 7.2)
13 Заявитель отвечает на письмо №2, подтверждает личность. Админ переводит в identity_verified Админ compliance Запись в pd_processing_log
37 Поиск всех записей по subject_email / subject_phone в deals, webhook_log, S3. Подготовка списка тенантов, которым надо уведомить (раздел 6) Админ compliance Внутренний отчёт по запросу [?][OPEN-Д-4] нужно ли поле data_inventory_json для аудита
7 Переход в processing. Параллельно стартуют (а) удаление наших данных, (б) уведомление crm.bp-gr.ru, (в) уведомление тенантов-получателей Админ compliance Письма №6, №7 (раздел 7)
725 Процесс удаления выполнен в нашей системе (анонимизация deals, удаление webhook_log.raw_payload, удаление S3-экспортов). Вторичные операторы получили уведомления, у них есть 18 дней на свои действия — мы их не ждём, но фиксируем факт уведомления Автомат + админ Записи в pd_processing_log с action='deleted', purpose='subject_request_X'
25 Финальная проверка: всё ли удалено в наших системах. Подготовка финального письма заявителю Админ compliance Письмо №4 (раздел 7.4)
30 Жёсткий дедлайн. Статус → completed, письмо №4 отправлено. Если до этого момента не успели — это нарушение 152-ФЗ, фиксируется как инцидент в incidents_log [?][OPEN-Д-5] есть такая таблица или нужна Админ compliance Алерт compliance в админке за 25, 28, 30 день

4.2. Сценарий access (право на доступ)

То же расписание до дня 7, но вместо удаления — формирование выписки:

  • Список всех deals.id с этим телефоном/email;
  • Для каждого: когда получили (через какой webhook), какому тенанту передали, текущий статус;
  • Список действий из pd_processing_log (когда смотрели, экспортировали, передавали);
  • Текущая правовая основа обработки (договор с crm.bp-gr.ru + согласие физлица, собранное на стороне crm.bp-gr.ru).

Выписка — PDF, отправляется на проверенный email заявителя. Не отправляется по неподтверждённому каналу (защита от подмены).

4.3. Сценарий correction

Аналогично access: ищем записи, проверяем что заявитель действительно тот, чьи данные исправляем (это критично — здесь высокий риск злоупотребления), вносим правки, фиксируем в pd_processing_log с action='updated', purpose='subject_request_correction_<id>'.

4.4. Алерты

В админке SaaS (роль compliance, см. Приложение Г §4) выводится лента:

  • Зелёный: received_at < NOW() - 7 days, статус ещё received или identity_verification — ничего страшного, в графике.
  • Жёлтый: deadline_at - NOW() < 5 days, статус не completed/rejected — пора заканчивать.
  • Красный: deadline_at < NOW(), статус не completed/rejectedнарушение 152-ФЗ, требуется немедленный разбор и фиксация инцидента.

Cron compliance:check-pd-deadlines (каждые 6 часов) расставляет приоритеты в очереди и шлёт email-уведомления админам compliance и super_admin.


5. Процедура проверки личности заявителя

Проблема: в отличие от тенанта (у которого есть аккаунт), физлицо-лид нам неизвестно. Нужно убедиться, что (а) заявитель действительно тот человек, чьи данные он просит, и (б) данные действительно у нас есть. Без этого — отказ (rejection_reason='identity_not_confirmed').

Принцип: заявитель должен подтвердить контроль над тем каналом связи (email/телефон), который у нас числится в deals как принадлежащий ему.

5.1. Что должно прийти в первичном обращении

Заявитель пишет нам (email на privacy@<домен>, через форму на сайте, или бумажно). Чтобы запрос вообще можно было обработать, нужны:

Поле Обязательность Зачем
ФИО Обязательно Сравнение с deals.contact_name
Контакт для связи (email или телефон) Обязательно Через него ведём переписку
Тот контакт, который мог использоваться при оставлении заявки (телефон, email) Обязательно По этому полю ищем в deals.phone / связанных полях
Тип запроса Обязательно access / deletion / correction / restriction
Конкретика для correction При request_type='correction' Что именно неверно и что записать вместо
Период (примерно когда оставлял заявку) Желательно Сужает поиск
Тематика заявки (на что подавал) Желательно Помогает идентифицировать тенанта-получателя

Если в первичном обращении не хватает данных — отправляем письмо №3 (раздел 7.3) с просьбой дополнить.

5.2. Способы подтверждения личности

Один из (в порядке надёжности):

Способ А — подтверждение через канал из deals (базовый случай).

  1. Находим запись по deals.phone или deals.contact_name.
  2. На номер телефона из deals.phone отправляем SMS с кодом [?][OPEN-Д-6] нужен SMS-провайдер для этого, у нас в v8.1 SMS не использовался; альтернатива — звонок робота.
  3. Заявитель называет код.
  4. Если совпало — identity_verification_method = 'sms_to_known_phone', переход в identity_verified.

Альтернатива на email: если в deals есть email-поле [?][OPEN-Д-7] в v8.1 у нас в deals email физлица не записывается (только phone и contact_name); если решим расширять — это поле в v8.2.

Способ Б — нотариальное заявление. Если телефон/email сменился, заявитель присылает скан нотариально заверенного заявления о том, что номер/email N был его, и он просит выполнить действия по этим данным. identity_verification_method = 'notarized_statement'. Хранится в S3 с TTL, ссылка в identity_evidence_url [?][OPEN-Д-8] нужно поле.

Способ В — личная явка. В офис заказчика с паспортом — для крупных случаев или когда юрист настаивает. identity_verification_method = 'in_person_with_passport'. Скан паспорта не сохраняем — фиксируем только серию-номер в identity_evidence_text (free-form), и факт явки.

Способ Г — Госуслуги [?][OPEN-Д-9] не на MVP, но как опция в v8.x: подтверждение через ЕСИА.

5.3. Что делаем при невозможности подтвердить

Через 3 дня после отправки письма №2 — повторное напоминание (письмо №2bis). Через 7 дней без ответа — переход в rejected с rejection_reason='identity_not_confirmed', отправка письма №5 с указанием права повторного обращения с подтверждённой личностью.

Важно: факт обращения и его отклонение сохраняем (анонимизировав сам контакт, если требуется по запросу самого заявителя). Это нужно для случая когда тот же человек обратится снова — мы должны видеть историю.

5.4. Антифрод

Чтобы конкурент или злоумышленник не смог через correction исказить данные лидов в нашей системе — жёстко:

  • Любой correction требует Способ Б, В или Г (не А).
  • Любой deletion массового масштаба (более 5 записей за раз по одному заявителю) — требует подтверждения через юриста заказчика.
  • Запрос с IP/email из чёрного списка (после ранее подтверждённого фрода) автоматически отклоняется с rejection_reason='out_of_scope' и алертом compliance + security (новая роль? [OPEN-Д-10]).

6. Уведомление вторичных операторов (особый шаг v8.1)

Контекст (Ю-2): мы — звено №2 в цепочке физлицо → crm.bp-gr.ru → мы → тенант. По 152-ФЗ ст. 21 ч. 4: «оператор обязан в течение 7 рабочих дней с даты обнаружения уведомить субъекта об устранении нарушений или удалении персональных данных». Если мы передавали данные дальше — мы обязаны уведомить тех, кому передавали.

Это касается только request_type='deletion' и request_type='correction'. Для access уведомлять никого не надо.

6.1. Уведомление crm.bp-gr.ru (вверх по цепочке)

Зачем: crm.bp-gr.ru — первоисточник. Если физлицо хочет полного забвения, оно должно обратиться и туда тоже. Но мы по 152-ФЗ обязаны уведомить их о факте обращения к нам, чтобы они синхронизировали свои данные.

Канал: официальное письмо на адрес поддержки crm.bp-gr.ru (закреплён в договоре, см. Б-1 от заказчика). Дублируется email-ом ответственному лицу.

Содержание (письмо №6, раздел 7.6): идентификатор лида в их системе (если у нас есть webhook_log.external_id), дата получения, факт удаления у нас, рекомендация рассмотреть удаление у себя, ссылка на наш request_id.

Не передаём в этом письме сами ПДн физлица — только идентификаторы и сам факт. Письмо хранится в pd_processing_log со ссылкой на request_id.

Срок: в течение 7 календарных дней после перехода запроса в processing (то есть около дня 14 от received_at в худшем случае). [?][OPEN-Д-11] уточнить с юристом, считаем «рабочие» или «календарные».

6.2. Уведомление тенантов-получателей (вниз по цепочке)

Зачем: мы передали лида тенанту через интерфейс/webhook/email (раздел 1.5 v8.1). У тенанта эти данные сейчас в его CRM-системе. Тенант — самостоятельный оператор, отвечает за свои действия, но мы как передающее звено обязаны уведомить.

Как находим тенантов: все deals с подходящим phone/contact_name имеют tenant_id. Список тенантов = SELECT DISTINCT tenant_id FROM deals WHERE phone = $1 OR contact_name = $2.

Канал: email на tenants.contact_email, дублируется в личном кабинете тенанта на странице /notifications (новый раздел? [OPEN-Д-12] — есть ли такая страница в v8.1).

Содержание (письмо №7, раздел 7.7): идентификатор сделки в нашей системе (deals.id), дата получения, факт обращения субъекта, требование тенанта удалить эти данные у себя в течение разумного срока (не более 30 дней с момента получения уведомления — это их дедлайн по 152-ФЗ как оператора), напоминание о пункте оферты Ю-8 (зеркальные гарантии).

Не передаём в этом письме повторно сами ПДн — у тенанта они уже есть, упоминаем только deals.id. Это снижает повторную циркуляцию ПДн.

Срок: в течение 7 календарных дней после перехода запроса в processing. Рассылка автоматическая через очередь pd-notifications [?][OPEN-Д-13] нужна отдельная очередь или хватит общего mailer.

6.3. Что делать, если тенант не ответил / не удалил

Это не наша проблема юридически — мы выполнили обязанность уведомить. Дальше тенант — самостоятельный оператор, отвечает перед Роскомнадзором сам.

Но репутационно это наша проблема, и есть риск, что Роскомнадзор посмотрит цепочку и предъявит претензии всем. Поэтому:

  • В оферте (Ю-5, Ю-8) фиксируется обязанность тенанта реагировать на такие уведомления в течение 30 дней под угрозой блокировки аккаунта.
  • В админке compliance есть отчёт «Тенанты с открытыми pd-уведомлениями старше 30 дней» — основание для разговора с тенантом.
  • Если тенант системно игнорирует — super_admin блокирует тенанта (tenants.status='suspended') с обоснованием в saas_admin_audit_log.

6.4. Логирование уведомлений

Каждое отправленное уведомление вторичным операторам пишется в pd_processing_log:

INSERT INTO pd_processing_log (
    tenant_id,           -- кому уведомили (или NULL если crm.bp-gr.ru)
    subject_type,        -- 'lead'
    subject_id,          -- deals.id
    action,              -- 'notified_secondary_operator'
    purpose,             -- 'subject_request_<id>_deletion'
    actor_admin_user_id, -- кто запустил
    ...
)

Это даёт возможность на любой момент собрать отчёт «кому и когда мы сказали об удалении лида X». [?][OPEN-Д-14] нужно ли отдельное поле notification_channel (email / api / postal).


7. Шаблоны писем

Юридический статус: все шаблоны — рабочие черновики, требующие финальной редактуры юристом в рамках Ю-5. Переменные в {{двойных фигурных скобках}} — подставляются автоматически. Формулировки про правовые основания (152-ФЗ ст. X) проверены по структуре закона, но точные ссылки и обороты — на юриста.

Общие переменные шаблонов:

Переменная Источник
{{operator_name}} legal_entities (наше юрлицо) — полное наименование
{{operator_short_name}} legal_entities — краткое наименование
{{operator_inn}} legal_entities.inn
{{operator_address}} legal_entities — юридический адрес
{{privacy_email}} system_settings.privacy_contact_email [?][OPEN-Д-15] нужен такой ключ
{{request_id}} pd_subject_requests.id
{{received_at_human}} pd_subject_requests.received_at в формате «дд.мм.гггг»
{{deadline_at_human}} pd_subject_requests.deadline_at в формате «дд.мм.гггг»
{{request_type_human}} Локализованное название (access → «доступ к данным», deletion → «удаление данных», и т.д.)
{{subject_email_or_phone}} subject_email или маскированный subject_phone
{{admin_signature}} Имя админа compliance, обработавшего запрос

7.1. Письмо №1 — подтверждение получения

Триггер: автоматически при INSERT INTO pd_subject_requests. Канал: email на subject_email, если есть; иначе SMS на subject_phone [?][OPEN-Д-6].

Тема: Подтверждение получения вашего обращения №{{request_id}}

Тело:

Здравствуйте,

Мы получили ваше обращение от {{received_at_human}} с запросом «{{request_type_human}}». Обращению присвоен номер №{{request_id}} — пожалуйста, указывайте его в дальнейшей переписке.

В соответствии с Федеральным законом от 27.07.2006 №152-ФЗ «О персональных данных» мы обязаны рассмотреть ваше обращение и предоставить ответ в срок до {{deadline_at_human}} (30 дней с момента получения).

Для обработки запроса нам потребуется подтвердить вашу личность. В ближайшее время вам поступит отдельное письмо с инструкциями.

Если вы не направляли нам обращение и получили это письмо ошибочно — пожалуйста, сообщите нам по адресу {{privacy_email}}.

С уважением, {{operator_short_name}} {{privacy_email}}

7.2. Письмо №2 — запрос подтверждения личности

Триггер: ручной, админ compliance после первичной проверки данных в обращении (раздел 5.1). Переход received → identity_verification.

Тема: Обращение №{{request_id}} — подтверждение личности

Тело:

Здравствуйте,

По вашему обращению №{{request_id}} от {{received_at_human}} нам необходимо подтвердить вашу личность, прежде чем мы сможем выполнить запрошенные действия с персональными данными. Это требование Федерального закона №152-ФЗ — мы должны быть уверены, что обращение поступило именно от того лица, чьи данные у нас обрабатываются.

Возможные способы подтверждения:

  1. SMS-код на номер, который вы указывали при оставлении заявки. Если этот номер у вас под контролем — ответьте на это письмо словом «SMS», и мы пришлём код на этот номер. (Способ подходит, если номер не сменился.)
  2. Нотариально заверенное заявление о том, что номер/email N принадлежал вам и вы просите выполнить действия по этим данным. Скан можно прислать в ответ на это письмо. (Способ подходит, если номер сменился.)
  3. Личная явка в офис по адресу {{operator_address}} с паспортом. Просим заранее согласовать время.

Просим выбрать удобный способ и ответить в течение 7 дней от даты этого письма. По истечении 7 дней без ответа обращение будет отклонено, и вам потребуется направить новое.

С уважением, {{admin_signature}} {{operator_short_name}} {{privacy_email}}

7.3. Письмо №3 — запрос дополнительной информации

Триггер: ручной, админ compliance, если в первичном обращении не хватает данных для поиска (нет ни email, ни телефона из deals).

Тема: Обращение №{{request_id}} — нужна дополнительная информация

Тело:

Здравствуйте,

Мы получили ваше обращение №{{request_id}} от {{received_at_human}}, но для его обработки нам не хватает данных, чтобы найти соответствующие записи в наших системах.

Просим уточнить:

  • {{missing_fields}} (подставляется списком: «телефон, по которому подавалась заявка», «примерная дата обращения», и т.п.)

Без этих данных мы не сможем гарантировать корректность исполнения вашего запроса. Просим ответить на это письмо в течение 14 дней.

С уважением, {{admin_signature}} {{operator_short_name}}

7.4. Письмо №4 — выполнено

Триггер: ручной, админ compliance, переход processing → completed.

Тема: Обращение №{{request_id}} — выполнено

Тело — для deletion:

Здравствуйте,

По вашему обращению №{{request_id}} от {{received_at_human}} мы выполнили следующие действия:

  • Найденные в наших системах записи о ваших персональных данных удалены/обезличены {{processing_completed_at_human}}.
  • В соответствии с требованиями 152-ФЗ мы уведомили {{count_secondary}} вторичных операторов о вашем обращении: первоначальный источник данных (crm.bp-gr.ru) и {{count_tenants}} получателей. Каждый из них является самостоятельным оператором и обязан рассмотреть обращение в свои сроки.
  • Отправлять им повторное обращение не обязательно: уведомление с нашей стороны они получили. Если хотите убедиться, что они выполнили удаление у себя, вы вправе обратиться к ним напрямую.

Подробный список вторичных операторов и контакты для прямых обращений — в приложении к этому письму.

С уважением, {{admin_signature}} {{operator_short_name}}

Тело — для access:

Здравствуйте,

По вашему обращению №{{request_id}} от {{received_at_human}} мы подготовили выписку о персональных данных, обрабатываемых нами в отношении вас, во вложении к этому письму (PDF, {{filesize}}).

Выписка содержит:

  • перечень собранных нами данных,
  • дату и источник получения,
  • правовое основание обработки,
  • перечень получателей (тенантов), которым данные передавались,
  • историю действий с данными.

С уважением, {{admin_signature}} {{operator_short_name}}

Тело — для correction: аналогично, с указанием конкретных полей до/после.

7.5. Письмо №5 — отклонено

Триггер: ручной, переход * → rejected.

Тема: Обращение №{{request_id}} — отказ в обработке

Тело:

Здравствуйте,

По вашему обращению №{{request_id}} от {{received_at_human}} мы вынуждены отказать в обработке по следующей причине:

{{rejection_reason_human}}

(подставляется развёрнутая формулировка, например: «Личность заявителя не была подтверждена в установленный срок», «По указанным контактным данным записей в наших системах не обнаружено», «Запрашиваемые действия выходят за рамки наших возможностей как оператора», «На данные наложено ограничение в связи с {{legal_hold_reason}}».)

Если вы считаете отказ необоснованным, вы вправе:

  • направить новое обращение, устранив указанные препятствия;
  • подать жалобу в Роскомнадзор по адресу: rkn.gov.ru.

С уважением, {{admin_signature}} {{operator_short_name}}

7.6. Письмо №6 — уведомление crm.bp-gr.ru

Триггер: автоматически при переходе запроса deletion/correction в processing. Канал: email на адрес из договора + дублирующий канал, согласованный в Б-1.

Тема: Уведомление об обращении субъекта ПДн — сделка {{external_lead_id}}

Тело:

Уважаемые коллеги,

В рамках исполнения требований Федерального закона №152-ФЗ настоящим уведомляем, что от субъекта персональных данных, чьи данные были переданы нам через ваш сервис, получено обращение с запросом «{{request_type_human}}».

Идентификатор сделки в нашей системе: {{deals_id}} Идентификатор лида в вашей системе (если есть в payload webhook): {{external_lead_id}} Дата получения данных от вас: {{webhook_received_at}} Наш внутренний номер обращения: {{request_id}}

Со своей стороны мы выполнили запрошенные действия в наших системах. В соответствии со ст. 21 ч. 4 ФЗ-152 рекомендуем вам рассмотреть аналогичные действия как оператору-первоисточнику данных.

Сами персональные данные субъекта в это уведомление не включены — в случае, если они потребуются для идентификации записи на вашей стороне, просим запрашивать их через защищённый канал, согласованный нашим договором.

С уважением, {{operator_short_name}}, оператор персональных данных {{operator_inn}}, {{operator_address}} {{privacy_email}}

7.7. Письмо №7 — уведомление тенанта

Триггер: автоматически, по списку tenant_id найденных в deals. Канал: email на tenants.contact_email + уведомление в личном кабинете.

Тема: Получено обращение субъекта ПДн по сделке №{{deals_id}}

Тело:

Здравствуйте,

В рамках исполнения требований Федерального закона №152-ФЗ настоящим уведомляем, что мы получили обращение от субъекта персональных данных по лиду, который был передан вам через нашу платформу.

Сделка в вашем интерфейсе: №{{deals_id}} Дата передачи: {{deal_transferred_at}} Тип обращения субъекта: {{request_type_human}} Наш внутренний номер обращения: {{request_id}}

Ваши действия: в соответствии с пунктом {{oferta_clause}} вашего договора с нами и требованиями ФЗ-152 как самостоятельного оператора, вы обязаны:

  • рассмотреть обращение и выполнить аналогичные действия с указанной сделкой в вашей CRM-системе и любых производных копиях/выгрузках;
  • сделать это в срок не более 30 дней с даты получения этого уведомления;
  • при необходимости — связаться с субъектом самостоятельно по контактам, имеющимся у вас.

Сами персональные данные субъекта в это уведомление не включены — у вас они уже есть в записи сделки.

Подтвердить выполнение вы можете в личном кабинете на странице «{{notifications_url}}» отметкой «Обработано». Невыполнение в срок может стать основанием для блокировки аккаунта в соответствии с офертой и для самостоятельной ответственности перед Роскомнадзором.

С уважением, {{operator_short_name}}, оператор персональных данных {{privacy_email}}


8. UI / экраны в админке SaaS

Этот раздел дополняет Приложение Г (Админка_SaaS_v8_1_драфт.md), §4 — экраны раздела «152-ФЗ / Compliance».

8.1. Экран «Обращения субъектов ПДн» (список)

Доступ: роли compliance, super_admin. Read-only для support. Полностью недоступен для finance.

Колонки таблицы:

Колонка Источник
ID pd_subject_requests.id
Получено received_at
Тип request_type (с иконкой)
Заявитель subject_email или маскированный subject_phone
Статус status (цветной чип)
Дедлайн deadline_at (с цветовой индикацией: зелёный/жёлтый/красный — раздел 4.4)
Ответственный assigned_admin_id (имя из saas_admin_users)
Тенанты-получатели количество найденных тенантов (для deletion)

Фильтры: статус, тип, период received_at, ответственный, «приближаются к дедлайну».

Сортировка по умолчанию: deadline_at ASC — приоритет тем, что горят.

Действия (bulk): массовая переуступка ответственного, экспорт списка в CSV.

8.2. Экран «Обращение №X» (карточка)

Блоки:

  1. Шапка: ID, статус, дедлайн с обратным отсчётом, кнопки переходов между статусами (только разрешённые из текущего, см. раздел 3).
  2. Заявитель: все поля из pd_subject_requests + история переходов статусов с временем и автором.
  3. Найденные данные: таблица deals.id / tenant_id / дата получения / источник; для webhook_log и S3 — список с количеством записей. Кнопка «Поиск повторно» (если данные могли появиться после первичного поиска).
  4. Связанные тенанты: список тенантов с количеством их сделок, статусом уведомления (отправлено / не отправлено / подтверждено).
  5. Уведомления вторичных операторов: статус по crm.bp-gr.ru и каждому тенанту: отправлено когда, через какой канал, есть ли подтверждение.
  6. Журнал переписки с заявителем: все отправленные шаблоны (№1-5) с датами, статус доставки. Кнопка «Отправить новое письмо» с выбором шаблона.
  7. Действия: «Перевести в processing» (запускает рассылку №6, №7), «Завершить» (processing → completed), «Отклонить» (с выбором rejection_reason).
  8. Доказательства подтверждения личности: загруженные сканы (нотариальное заявление), запись о SMS / личной явке. Каждый файл — со ссылкой на S3 и TTL.

8.3. Виджет на главной админки (для роли compliance)

  • Счётчик: открытых запросов всего / горящих (жёлтых) / просроченных (красных).
  • Лента «Последние действия» с записями из pd_processing_log по purpose LIKE 'subject_request_%'.

8.4. Отчёт «Обращения за период»

Для отчётности перед Роскомнадзором (если запросят). Таблица: за выбранный период — сколько обращений получено, по каким типам, какой % обработан в срок, причины отказов. Экспорт в PDF / CSV. Доступ: super_admin.


9. Открытые вопросы

ID Вопрос Кому Приоритет Влияние если не решить
OPEN-Д-1 Нужно ли поле processing_restricted в deals для request_type='restriction', или схлопывать в deletion? CTO + юрист P2 Без флага restriction фактически = deletion; для MVP приемлемо
OPEN-Д-2 CHECK-constraint на разрешённые переходы статусов pd_subject_requests — добавить в schema v8.2? CTO P1 Без CHECK можно обойти процесс программной ошибкой
OPEN-Д-3 Зафиксировать enum rejection_reason (5 значений предложено в разделе 3) CTO + юрист P1 Без enum — свободный текст, плохо для отчётности
OPEN-Д-4 Нужно ли поле data_inventory_json для аудита того, что было найдено? CTO + compliance P2 Без поля аудит делается через pd_processing_log — менее удобно, но возможно
OPEN-Д-5 Есть ли таблица incidents_log для фиксации нарушений сроков 152-ФЗ? CTO P1 Нужна для аудита Роскомнадзора
OPEN-Д-6 SMS-провайдер для подтверждения личности: какой выбираем? Бюджет? DevOps + бизнес P1 Без SMS остаются только нотариус и личная явка — высокий порог
OPEN-Д-7 Добавлять ли email физлица в deals как опциональное поле? CTO + юрист P2 Сейчас единственный «канал к физлицу» — телефон, для подтверждения через email недостаточно
OPEN-Д-8 Поле identity_evidence_url (S3-ссылка на сканы) и identity_verification_method enum в pd_subject_requests CTO P1 Без этих полей доказательства нигде не фиксируются
OPEN-Д-9 Подключение к Госуслугам (ЕСИА) для подтверждения личности — в какой версии? бизнес P3 Желательно, но не критично; даёт сильное упрощение UX
OPEN-Д-10 Заводить ли отдельную роль security помимо compliance? CTO + бизнес P2 Сейчас compliance совмещает обе функции, на старте приемлемо
OPEN-Д-11 «Календарные» или «рабочие» дни в сроке уведомления вторичных операторов (7 дней по ст. 21 ч. 4)? юрист P1 Влияет на SLA; берём календарные как более жёсткие до уточнения
OPEN-Д-12 Есть ли в личном кабинете тенанта страница /notifications для уведомлений о pd-запросах? CTO + дизайн P1 Без страницы — только email-канал, может быть пропущен
OPEN-Д-13 Отдельная очередь pd-notifications или общий mailer? CTO P2 Для MVP общий mailer ок; отдельная очередь даст приоритизацию
OPEN-Д-14 Поле notification_channel в pd_processing_log? CTO P2 Для аудита полезно знать канал (email/api/postal); без поля — выводится из контекста
OPEN-Д-15 Ключ system_settings.privacy_contact_email CTO P1 Нужен для подстановки {{privacy_email}} в шаблоны; +1 строка миграции
OPEN-Д-16 Где публикуется адрес privacy_email для физлиц? Отдельная страница на сайте? Раздел в Политике конфиденциальности? бизнес + юрист P1 Без публикации физлицо не знает, как обратиться — критично для соблюдения 152-ФЗ
OPEN-Д-17 Бумажные обращения: кто и как их регистрирует в pd_subject_requests? бизнес P2 Если адрес заказчика принимает бумажную почту — нужен процесс приёмки и оцифровки
OPEN-Д-18 Срок хранения записей pd_subject_requests после completed/rejected. По 152-ФЗ — 5 лет? Дольше? юрист P1 Нужно для cron'а ретеншена
OPEN-Д-19 Уведомление тенанта о повторном обращении того же физлица — нужно ли? юрист P3 Если тот же субъект обращается снова, тенант мог уже удалить; зависит от практики
OPEN-Д-20 Стоимость нотариального заявления — компенсируется заявителю или нет? юрист + бизнес P3 Юридически не обязаны, но влияет на репутацию

10. Что добавить в schema v8.2

Сводный список миграций к таблице pd_subject_requests, чтобы реализовать workflow в полном объёме:

-- v8.2 миграция: расширение pd_subject_requests до полного workflow

ALTER TABLE pd_subject_requests
    ADD COLUMN identity_request_sent_at      TIMESTAMPTZ,
    ADD COLUMN identity_verified_at          TIMESTAMPTZ,
    ADD COLUMN identity_verification_method  VARCHAR(50),  -- enum: sms_to_known_phone | notarized_statement | in_person_with_passport | esia
    ADD COLUMN identity_evidence_url         TEXT,         -- S3 ссылка на скан (для notarized)
    ADD COLUMN identity_evidence_text        TEXT,         -- free-form (для in_person)
    ADD COLUMN processing_started_at         TIMESTAMPTZ,
    ADD COLUMN result_summary                TEXT,         -- что именно сделали (для completed)
    ADD COLUMN rejection_reason              VARCHAR(50),  -- enum: см. раздел 3
    ADD COLUMN data_inventory_json           JSONB,        -- что нашли (опционально, [OPEN-Д-4])
    ADD CONSTRAINT chk_pd_request_status_transitions CHECK (
        -- черновик ограничения, точная форма — на момент миграции
        (status IN ('received','identity_verification','identity_verified','processing','completed','rejected'))
    ),
    ADD CONSTRAINT chk_pd_request_completion CHECK (
        (status NOT IN ('completed','rejected')) OR (completed_at IS NOT NULL)
    ),
    ADD CONSTRAINT chk_pd_request_rejection CHECK (
        (status <> 'rejected') OR (rejection_reason IS NOT NULL)
    );

CREATE INDEX idx_pd_requests_deadline ON pd_subject_requests(deadline_at) WHERE status NOT IN ('completed','rejected');
CREATE INDEX idx_pd_requests_assigned ON pd_subject_requests(assigned_admin_id) WHERE status NOT IN ('completed','rejected');
CREATE INDEX idx_pd_requests_subject_phone ON pd_subject_requests(subject_phone);
CREATE INDEX idx_pd_requests_subject_email ON pd_subject_requests(subject_email);

-- system_settings — новый ключ
INSERT INTO system_settings (key, value_text, description) VALUES
    ('privacy_contact_email', '<заполняется заказчиком>', 'Email для приёма обращений субъектов ПДн (152-ФЗ ст. 14)');

-- Возможно, в зависимости от OPEN-Д-5
-- CREATE TABLE incidents_log (...) — для фиксации нарушений сроков

Точная форма миграции — после ответов на P1-вопросы из раздела 9 (особенно OPEN-Д-3, Д-5, Д-15).


11. Что обновить в смежных документах

При выпуске v8.2:

Документ Что меняется
CRM_bp-gr_Инструкция_v8_1.md 22.9.5 Заменить ремарку «отдельный артефакт (готовится при необходимости)» на ссылку на это Приложение Д
CRM_bp-gr_Инструкция_v8_1.md раздел 28 Добавить шифр Д = Workflow_pd_subject_requests_v8_1.md
schema.sql Применить миграцию из раздела 10 (после ответов на P1 OPEN-Д)
Админка_SaaS_v8_1_драфт.md §4 Раскрыть §4 «152-ФЗ / Compliance» по образцу раздела 8 этого документа
Открытые_вопросы_v8_1.md Добавить блок «Адресат: compliance / юрист — OPEN-Д-1..20»
CRM_bp-gr_Инструкция_v8_1.md 27.2 Добавить пункт «privacy_contact_email» в чек-лист от заказчика, и пункт «SMS-провайдер» (OPEN-Д-6)
Шаблон оферты (Ю-5) Включить пункт о соблюдении тенантом 30-дневного дедлайна по pd-уведомлениям (раздел 6.3, 7.7) — oferta_clause для подстановки в письмо №7

Драфт v0.1 от 04.05.2026. Готовится в рамках сессии 03–04.05.2026 как Приложение Д к v8.1.