Политика хранения и удаления данных не реализуется одной командой DELETE. В PHP-приложении одни и те же сведения могут находиться в нескольких таблицах, файлах, кэшах, журналах и внешних сервисах. Если удалить только основную строку, могут остаться активные копии; если удалять данные, не проверив зависимости, можно нарушить работу операций или удалить сведения, которые следовало сохранить.
Практическая цель — превратить каждое правило в процесс, который определяет затронутые данные, применяет подходящее действие, обрабатывает исключения и оставляет проверяемые свидетельства выполнения. Политику следует согласовать с ответственными за продукт, технологии и данные подразделениями, а также сверить с требованиями, применимыми к бизнесу. Не следует исходить из универсальных сроков, установленных законом: они зависят от контекста, и их нужно проверить до автоматизации.
Начните с категорий данных и правил их хранения

Прежде чем проектировать удаление, классифицируйте информацию по её назначению и использованию. Для профиля, адреса, необходимого для незавершённой операции, истории активности и бухгалтерской записи могут действовать разные правила, даже если все эти сведения связаны с одной учётной записью.
Для каждой категории задокументируйте как минимум:
- Назначение и ответственное лицо: зачем хранятся данные и какая команда принимает решение об их хранении.
- Событие, запускающее правило: например, закрытие учётной записи, истечение срока действия отношений или подтверждённый запрос.
- Срок и условие: когда проверяется или выполняется действие, включая возможные обоснованные приостановки.
- Действие: удалить, обезличить, сохранить с ограниченным доступом или направить на проверку вручную.
- Зависимости: системы и процессы, которые должны быть завершены, прежде чем случай можно будет считать закрытым.
«Хранить» не означает бессрочно оставлять данные из соображений удобства. Для этого нужны обоснование, определённый охват и дата или условие пересмотра. Если часть информации необходимо сохранить для текущей операции, отделите её от остальных данных и ограничьте круг лиц, имеющих к ней доступ.
Составьте перечень копий, ссылок и подключённых систем
Инвентаризация должна учитывать реальный путь данных, а не только схему базы данных. Проверьте связанные таблицы, поля JSON, загруженные файлы, экспортированные данные, поисковые индексы, кэши, очереди, журналы приложения и интегрированные системы. Учтите также процессы, создающие копии: отчёты, инструменты поддержки, аналитику и процессы импорта.
Для каждого места хранения укажите, по какому идентификатору можно найти данные, кто за них отвечает, как их удалить или обновить и что произойдёт, если система будет недоступна. Проверьте связи через внешние ключи и логику приложения: связь в базе данных может препятствовать каскадному удалению, а каскадное удаление, наоборот, может удалить больше данных, чем предполагалось.
Резервные копии следует рассматривать отдельно. Удалить из них отдельный элемент может быть невозможно без восстановления всей копии. Определите, как ограничивается доступ к резервным копиям, как долго они хранятся и какая процедура не позволит удалённым данным вернуться в активные системы после восстановления. Задокументируйте решение и согласуйте его с ответственными за инфраструктуру и соблюдение требований.
Решите, когда удалять, обезличивать или хранить данные
Физическое удаление устраняет данные из активной системы, но не всегда подходит для каждой записи. Обезличивание может быть уместно, если необходимо сохранить статистическую информацию и можно эффективно исключить возможность связать её с конкретным человеком. Замены имени на постоянный идентификатор недостаточно, если другая таблица позволяет восстановить связь.
Хранение с ограниченным доступом может подойти для данных, всё ещё необходимых для операции или в силу подтверждённого обязательства. Храните такие сведения отдельно, задайте специальные разрешения и установите правило пересмотра. Если нельзя надёжно определить подходящее действие — например, из-за спора, неизвестной зависимости или несоответствия идентификационных данных, — направьте случай в очередь на проверку, а не принимайте решение наугад.
Также необходимо проверить функциональные последствия: что произойдёт с заказами, подписками, обращениями в поддержку, API-ключами или общими документами после удаления учётной записи. Поведение должно быть явно определено и согласовано в интерфейсе, логике PHP и подключённых сервисах.
Реализуйте идемпотентный и наблюдаемый процесс
Процесс удаления обычно выполняется в фоновом режиме — через очередь или запланированную задачу. Определите для случая явные состояния, например: запрошен, проверен, выполняется, ожидает обработки внешними системами, завершён или требует проверки. Задайте допустимые переходы между состояниями и определите, кто может повторно запустить обработку или закрыть исключение.
Идемпотентность имеет принципиальное значение: повторный запуск этапа не должен дублировать эффекты или приводить к ущербу. Перед удалением файла проверьте, существует ли он; при обработке запроса проверьте текущее состояние; при вызове внешнего сервиса используйте механизмы идемпотентности, если они доступны. Если гарантировать это невозможно, сохраните ответ и спроектируйте сверку состояния, прежде чем повторять операцию вслепую.
Концептуально в PHP оркестрацию можно отделить от действий для каждой системы:
foreach ($steps as $step) {
if ($step->isComplete($requestId)) {
continue;
}
$step->execute($subjectReference);
$step->markComplete($requestId);
}
Этот пример не решает проблему распределённых транзакций: база данных и внешний поставщик не обязательно участвуют в одной транзакции. Надёжно сохраняйте ход выполнения, обрабатывайте ошибки на каждом этапе и обеспечьте возможность возобновить работу. Если операция завершилась ошибкой на полпути, состояние должно показывать, что ещё предстоит сделать; процесс нельзя отмечать как завершённый.
Фиксируйте выполнение, не создавая ещё одну копию персональных данных
Трассировка позволяет установить, кто или какой процесс выполнил действие, когда, по какому запросу и с каким результатом. Записывайте внутренние идентификаторы операций, состояния, этапы и коды ошибок, полезные для диагностики. Не копируйте в журналы имена, адреса электронной почты, документы, содержимое файлов или полные тела API-запросов.
Псевдонимизированный идентификатор пользователя всё равно может быть чувствительной информацией, если он позволяет повторно установить личность. Ограничьте доступ к журналам, установите срок их хранения и, когда это возможно, отделяйте операционные сведения от данных о личности. Сообщения об ошибках должны помогать определить затронутую систему, не раскрывая персональные данные в средствах мониторинга.
Проверьте результат и предусмотрите исключения
Тесты должны охватывать как штатный сценарий, так и частичные сбои. Используйте тестовые данные и проверяйте все места хранения, выявленные при инвентаризации, а не только основную таблицу. Включите сценарии, в которых связь препятствует удалению, файл отсутствует, внешний поставщик недоступен, выполняется повторная попытка или возникает исключение, требующее проверки.
Полезный рабочий список вопросов: найдены ли все известные копии? Выполнено ли предусмотренное действие для каждой категории? Остались ли незавершённые этапы? Подтвердили ли внешние системы результат? Содержат ли журналы только необходимую информацию? Сохраняет ли повторная попытка безопасность процесса? Проводите периодические проверки, чтобы обнаруживать новые таблицы, интеграции и маршруты данных, не вошедшие в перечень.
Гипотетический пример: закрытие учётной записи

Предположим, человек просит закрыть свою учётную запись в PHP-приложении. Процесс проверяет запрос и применяет установленные правила к профилю, файлам, активности и сведениям, связанным с незавершёнными операциями. Профиль и подходящие для удаления файлы удаляются; некоторые записи сохраняются с ограниченным доступом, если для этого есть одобренное основание; данные для аналитики остаются только в том случае, если они эффективно обезличены.
Приложение фиксирует каждый этап, не включая адрес электронной почты или содержимое файлов. Если внешний сервис не отвечает, случай получает статус ожидания, а последующий процесс повторяет попытку или запрашивает вмешательство согласно политике. Случай отмечается как завершённый только после подтверждения всех необходимых действий либо после того, как исключение официально задокументировано и одобрено.
До внедрения определите, какие вопросы ещё не решены: в каких системах находятся данные, кто утверждает исключения, что означает «завершено» для каждого места хранения, как обрабатываются резервные копии и кто проверяет сбои. Эти решения превращают намерение удалить данные в удобный в сопровождении, проверяемый и безопасный процесс.



