К содержанию
ActionPulse

Удаление пользователя и его данных

Как удалить аналитические данные конкретного человека в 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.

Из этого следуют три практических правила:

  1. Удаление работает в границах одного проекта. Если человек отслеживался в нескольких проектах, задачу нужно поставить в каждом.
  2. Искать по адресу почты или телефону нельзя — только по user_id. Если вы передавали в user_id внутренний идентификатор (а так и надо делать), то сначала найдите его в своей системе по обращению субъекта.
  3. Если человек никогда не был идентифицирован, у вас нет 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 означает применённое и проверенное удаление, а не «команда поставлена в очередь». Если в этот момент в проекте выполняется другая задача удаления, запрос завершится ошибкой — повторите его после её завершения.

Что проверить

  1. Проверьте, что в user_id у вас лежит внутренний идентификатор, а не адрес почты: иначе запрос субъекта придётся выполнять по данным, которые сами являются персональными.
  2. Один раз пройдите процедуру на тестовом идентификаторе и дождитесь статуса completed. Это единственный способ убедиться, что рабочий процесс запущен и имеет доступ к хранилищу — особенно в установке на своих серверах.
  3. Убедитесь, что ваш код умеет обрабатывать 409 privacy_job_active на идентификации и повторяет вызов позже, а не теряет его.
  4. Внесите в свою процедуру ответа субъекту: остановку отправки событий, 48-часовое окно транспортной очереди, повтор запросов после восстановления копии и перечень того, что остаётся.
  5. Если человек отслеживался в нескольких проектах — поставьте задачу в каждом и сохраните идентификаторы задач для отчёта.