Удаление пользователя и его данных
Как удалить аналитические данные конкретного человека в ActionPulse: кто может запустить задачу, по какому идентификатору, что удаляется, что остаётся и как узнать состояние.
На этой странице
Сначала о двух разных операциях, которые легко перепутать.
- Удаление участника организации — отзыв доступа человека к кабинету ActionPulse. Это про учётные записи, а не про аналитику; см. команду и роли.
- Удаление данных субъекта — удаление аналитических данных о человеке, которого вы отслеживали: его событий, атрибутов идентификации, связей идентификаторов и записей сессий. Об этом вся остальная страница.
Механизм называется «удаление данных субъекта» и работает как задача: вы указываете идентификатор, продукт ставит задачу в очередь и выполняет её фоновым рабочим процессом, а вы наблюдаете за состоянием.
Кто может запустить
| Действие | Минимальная роль |
|---|---|
| Запустить удаление | admin |
| Смотреть список задач и их состояние | admin |
Роли viewer и analyst не видят ни запуск, ни историю. В режиме поддержки
(когда сотрудник ActionPulse работает от вашего имени) запуск удаления
запрещён, как и любая другая изменяющая операция.
Как поставить задачу
В кабинете
Настройки → Данные, раздел «Удаление данных субъекта». Перед запуском экран
показывает, что именно будет удалено, и требует подтверждения — ввода слова
FORGET. Ниже на том же экране — история задач без персональных данных: только
идентификаторы задач, инициатор, стадии и результат.
По API
curl -sS -X POST "https://YOUR_ACTIONPULSE_HOST/api/v1/projects/YOUR_PROJECT_ID/gdpr/forget" \
-H "Authorization: Bearer $ACTIONPULSE_ACCESS_TOKEN" \
-H "X-Confirm-Forget: true" \
-H "Content-Type: application/json" \
-d '{"user_id": "YOUR_USER_ID"}'
Ответ — 202 Accepted и объект задачи с её идентификатором.
| Требование запроса | Значение |
|---|---|
| Заголовок подтверждения | X-Confirm-Forget: true; без него — 422 confirmation_required |
| Тело | {"user_id": "…"}, от 1 до 256 байт |
| Разбор тела | строгий: неизвестное поле — отказ всего запроса |
| Предел размера тела | 64 КиБ |
| Чужой проект или чужая задача | 404, без подсказки о существовании |
Полный перечень методов — на странице приватности в справочнике API.
По какому идентификатору
Задача принимает user_id — тот идентификатор, который вы сами передавали
при идентификации пользователя. Дальше продукт сам обходит граф идентичности
внутри выбранного проекта и находит связанные с ним анонимные
идентификаторы и actor_id.
Из этого следуют три практических правила:
- Удаление работает в границах одного проекта. Если человек отслеживался в нескольких проектах, задачу нужно поставить в каждом.
- Искать по адресу почты или телефону нельзя — только по
user_id. Если вы передавали вuser_idвнутренний идентификатор (а так и надо делать), то сначала найдите его в своей системе по обращению субъекта. - Если человек никогда не был идентифицирован, у вас нет
user_id, и удалить именно его данные нельзя: анонимные события связываются с человеком только через идентификацию. Найти нужный идентификатор помогает профиль пользователя.
Сам user_id в системе не сохраняется как часть задачи: он шифруется на время
выполнения, а в истории задач его нет — ни в списке, ни в журнале.
Что удаляется
- события, связанные с субъектом через
user_idилиactor_id, а для анонимных строк — через найденный анонимный идентификатор; - события идентификации вместе со всеми переданными атрибутами и профиль субъекта;
- связи идентификаторов проекта в основной базе и их кэш;
- записи сессий, чей
actor_idвходит в тот же граф идентичности проекта; - устаревшие строки агрегатов за затронутые дни и типы событий — агрегаты пересчитываются по оставшимся событиям.
Другие проекты и другие люди не затрагиваются. Учётная запись пользователя ActionPulse, состав организации, проекты, отчёты и сохранённые сегменты остаются на месте.
Что остаётся
Честный список — он нужен, чтобы ответ субъекту не обещал больше, чем делает продукт:
| Что остаётся | Почему |
|---|---|
| Журнал аудита и журнал выполнения задач удаления | доказательства действий; удаляемого user_id, атрибутов и свойств событий в них нет |
| Записи обслуживающих процессов, созданные вне задачи удаления | живут по собственному ограниченному сроку и могут содержать идентификаторы акторов |
| Агрегаты биллинга, счёта и платёжные документы | неперсональные суммы использования и обязательная финансовая отчётность |
| Принятые сообщения в транспортной очереди | удаляются по своему пределу: не более 48 часов события и 24 часов записи сессий |
| Вытесненные версии частей хранилища | ClickHouse удаляет их с диска вскоре после мутации — минуты, не дни |
| Резервные копии | до истечения их собственного срока хранения |
Про сроки всех перечисленных слоёв — сроки хранения данных.
Сколько идёт задача и как узнать состояние
Задачу подхватывает рабочий процесс: очередь опрашивается каждые несколько секунд, поэтому старт — почти сразу. Дальше время зависит от объёма данных субъекта и от того, не занято ли хранилище другой мутацией: задача честно ждёт своей очереди вместо того, чтобы отвечать «готово» раньше времени.
Состояние читается двумя методами:
# Последние задачи проекта: limit от 1 до 100, по умолчанию 50
curl -sS -H "Authorization: Bearer $ACTIONPULSE_ACCESS_TOKEN" \
"https://YOUR_ACTIONPULSE_HOST/api/v1/projects/YOUR_PROJECT_ID/gdpr/forget?limit=20"
# Одна задача по её идентификатору
curl -sS -H "Authorization: Bearer $ACTIONPULSE_ACCESS_TOKEN" \
"https://YOUR_ACTIONPULSE_HOST/api/v1/projects/YOUR_PROJECT_ID/gdpr/forget/42"
| Статус | Что означает |
|---|---|
queued |
задача принята и ждёт рабочего процесса |
running |
идёт разбор идентичности и удаление |
mutating |
хранилище ещё применяет удаление; часть строк может временно читаться |
completed |
проверено, что подходящих строк больше нет |
failed |
безопасные автоматические повторы исчерпаны |
Стадия (stage) уточняет, что происходит прямо сейчас: resolving_identity,
deleting_events, verifying_deletion, rebuilding_views, deleting_aliases,
deleting_replays.
Важные свойства статуса:
completedвыставляется только после проверки: подходящих событий больше не читается, агрегаты пересобраны, записей сессий не осталось, кэш очищен. Это не «команда отправлена», а «результат подтверждён».- Автоматических повторов при инфраструктурных сбоях не больше трёх. После терминальной неудачи зашифрованная цель стирается, поэтому исправление — это новый запрос, а не возобновление старого.
affected_rows— консервативный минимум подтверждённо отсутствующих строк, а не точное число перезаписанных строк хранилища. На итог это не влияет:completedтребует, чтобы не осталось ни одной строки.
Если задача уже выполняется
Повторный запрос на того же субъекта идемпотентен. Пока задача в состоянии
queued, running или mutating, повторный POST с тем же user_id в том же
проекте вернёт 202 и ту же самую задачу — с тем же
идентификатором. Второй задачи не появится, и никакой ошибки конфликта не
будет. Повтор после completed безопасен и создаёт новую проверку — это
нормальный способ убедиться, что новых данных не появилось.
А вот приём идентификации на время удаления ограждается. Пока задача
активна, запросы /v1/identify и /v1/alias для этого проекта отвечают:
{ "error": { "code": "privacy_job_active",
"message": "identify and alias writes are temporarily unavailable while privacy deletion is active",
"details": { "retryable": true } } }
Статус — 409. Причина не техническая, а смысловая: старый анонимный
идентификатор не должен быть переназначен другому человеку посреди удаления.
Клиент должен повторить вызов после того, как задача дошла до терминального
состояния. Обычная отправка событий /v1/track при этом не блокируется. Как
обрабатывать этот и другие коды — ошибки API.
Удаление собранных данных форм
Отдельный механизм для другой задачи: удалить не данные одного человека, а все собранные данные о взаимодействии с формами по проекту целиком.
curl -sS -X POST "https://YOUR_ACTIONPULSE_HOST/api/v1/projects/YOUR_PROJECT_ID/behavior/forms/purge" \
-H "Authorization: Bearer $ACTIONPULSE_ACCESS_TOKEN" \
-H "X-Confirm-Purge: true"
| Свойство | Значение |
|---|---|
| Что удаляется | ровно два управляемых события — pp.form_field и pp.form_submit |
| Роль | admin и выше, тарифом не ограничено |
| Подтверждение | X-Confirm-Purge: true; без него — 422 confirmation_required |
| Ответ | 202 с объектом задачи |
| Состояние | GET того же пути (до 50 записей) и GET …/purge/{jobID} |
Задача ждёт, пока освободится хранилище, удаляет события синхронной мутацией, проверяет, что подходящих строк не осталось, и пересобирает затронутые агрегаты. Полный бюджет одной попытки — 15 минут.
Полезно вместе: если сбор форм вам не нужен, выключите его в Настройки → Сбор и приватность, а уже собранное удалите этой задачей. Тогда данных не будет ни сейчас, ни потом.
Удаление данных всего проекта
Самый широкий инструмент — удаление проекта.
curl -sS -X DELETE "https://YOUR_ACTIONPULSE_HOST/api/v1/projects/YOUR_PROJECT_ID" \
-H "Authorization: Bearer $ACTIONPULSE_ACCESS_TOKEN"
Ответ — 204. Что происходит: каскадно удаляются записи проекта в основной базе
и явно стираются все данные проекта в хранилище аналитики — события, записи
сессий, служебные таблицы и внутренние таблицы агрегатов. Ключи приёма этого
проекта перестают действовать.
| Свойство | Значение |
|---|---|
| Роль | admin и выше |
| Режим поддержки | запрещено |
| Обратимость | нет |
Удаление в хранилище выполняется синхронно в той же операции и после него
проверяется, что по проекту не осталось ни одной строки. Поэтому 204 означает
применённое и проверенное удаление, а не «команда поставлена в очередь». Если в
этот момент в проекте выполняется другая задача удаления, запрос завершится
ошибкой — повторите его после её завершения.
Что проверить
- Проверьте, что в
user_idу вас лежит внутренний идентификатор, а не адрес почты: иначе запрос субъекта придётся выполнять по данным, которые сами являются персональными. - Один раз пройдите процедуру на тестовом идентификаторе и дождитесь статуса
completed. Это единственный способ убедиться, что рабочий процесс запущен и имеет доступ к хранилищу — особенно в установке на своих серверах. - Убедитесь, что ваш код умеет обрабатывать
409privacy_job_activeна идентификации и повторяет вызов позже, а не теряет его. - Внесите в свою процедуру ответа субъекту: остановку отправки событий, 48-часовое окно транспортной очереди, повтор запросов после восстановления копии и перечень того, что остаётся.
- Если человек отслеживался в нескольких проектах — поставьте задачу в каждом и сохраните идентификаторы задач для отчёта.