Корпоративный импорт не должен заставлять выбирать между отменой всего пакета из-за одной некорректной строки и загрузкой сомнительных данных. Карантин данных при импорте в PHP предлагает третий вариант: принять корректные записи, изолировать те, которые требуют внимания, и сохранить достаточно контекста для их безопасного разрешения.
Карантин — это не просто папка с ошибками и не таблица для хранения неудачно обработанных строк. Это операционный процесс с правилами классификации, явными статусами, контролируемым исправлением и повторной обработкой без дублирования эффектов. Чтобы спроектировать его, сначала договоритесь, что бизнес считает «корректными» данными и какие действия доступны каждой роли.
Классифицируйте ошибки, прежде чем решать, что делать с каждой строкой

При импорте обычно выполняются разные проверки. Разделение этих проверок позволяет объяснить результат и определить, может ли запись продолжить обработку, должна ли быть отклонена или требует проверки человеком.
- Структурная валидация: проверяет формат и базовое содержимое: наличие столбцов, типы данных, корректность интерпретации дат, обязательные поля и разумные ограничения. Нечитаемый файл может помешать обработать пакет; некорректная дата в одной строке обычно не должна этому препятствовать.
- Бизнес-правила: проверяют условия предметной области, например неотрицательную цену, активность клиента или допустимую категорию. Некоторые нарушения можно отклонить; другие могут требовать операционного решения.
- Конфликты с существующими данными: обнаруживают, например, внешний идентификатор, уже связанный с другой записью, или обновление на основе устаревшей версии. Такие проблемы не всегда решаются исправлением файла: может потребоваться сверка или проверка.
Определите политику для каждого типа ошибки. Для отсутствующего необязательного поля может подойти значение по умолчанию; неоднозначную идентификацию записи не следует разрешать произвольным выбором записи. Избегайте как чрезмерно мягких правил, так и классификации любого дефекта как фатальной ошибки. Решение должно учитывать последствия принятия данных и стоимость остановки пакета.
Моделируйте явные статусы и переходы
Используйте статусы с операционным смыслом, а не выводите состояние из пустых полей или текстовых сообщений. Начальная модель может включать pending, accepted, rejected и needs_review. Добавляйте статусы вроде processing или resolved, только если они соответствуют реальным переходам в вашем процессе.
Документируйте, какие переходы разрешены. Например, ожидающая обработки строка проходит валидацию; если она удовлетворяет правилам, ее принимают, а при конфликте, требующем проверки, оставляют на рассмотрение. Исправленную строку можно проверить повторно, но принятую не следует обрабатывать снова как новую. Учитывайте статус пакета отдельно: пакет может завершиться с принятыми строками и другими строками в карантине, поэтому «завершен частично» точнее описывает результат, чем единый признак успеха или неудачи.
Статусы должны соответствовать проверяемым решениям. «Отклонена» должна означать, что бизнес-изменение не было применено; «требует проверки» означает, что решение должен принять человек. Если разрешена перезапись существующих данных, укажите, кто может ее выполнять и при каких условиях.
Сохраняйте оригинал и объясняйте каждое решение
Сохраняйте исходные входные данные строки отдельно от нормализованных значений и результата валидации. Это позволяет расследовать расхождения — например, различия между полученной датой и ее интерпретацией, — не превращая преобразованную версию в единственное доступное свидетельство.
Структура хранения может включать идентификатор пакета, номер строки, источник, ссылку на файл, исходное содержимое, статус, обнаруженные ошибки, даты создания и разрешения проблемы, а также ответственного участника. Фиксируйте причины в виде стабильных кодов и понятных сообщений: код вроде customer_id_ambiguous упрощает фильтрацию и подсчет случаев; сообщение должно объяснять, какие данные нужно проверить. Не используйте произвольный текст как единственную основу классификации.
Сохраняйте также контекст, необходимый для воспроизведения анализа: версию или идентификатор использованных правил, внешний идентификатор и данные, значимые для конфликта. Не храните секреты и ненужные персональные данные в технических логах. Определите контроль доступа и срок хранения с учетом чувствительности данных и применимых обязательств. Если весь файл может содержать сведения, не нужные для разрешения проблемы в отдельной строке, ограничьте доступ к нему.
Исправляйте данные и повторяйте обработку без дублирования эффектов
Безопасная повторная обработка начинается с различения самой строки и попытки ее обработать. Назначьте каждой строке стабильный идентификатор в пределах ее области, например комбинацию пакета и индекса строки или проверенный внешний ключ. Для повторяемого импорта также определите ключ идемпотентности, позволяющий распознать ту же операцию. Выбор зависит от того, должно ли повторное чтение того же файла обновлять данные, игнорировать их или создавать новую версию.
При обработке строки по возможности выполняйте бизнес-запись и изменение статуса атомарно: либо подтверждаются обе операции, либо ни одна. В PHP транзакция базы данных может защищать изменения, использующие то же соединение; сама по себе она не делает атомарным вызов внешнего API. Для внешних эффектов используйте стратегию, совместимую с принимающей системой, например ключи идемпотентности, транзакционную таблицу исходящих сообщений или компенсацию, спроектированную для данного случая.
После исправления заново выполните соответствующие проверки и сохраните предыдущую историю. Не удаляйте исходную ошибку: добавьте новую попытку и ее результат. Если правила или справочные данные изменились, укажите примененную версию и не допускайте, чтобы повторная обработка незаметно изменила уже принятое решение. Повторная обработка должна затрагивать только выбранные записи, а не без разбора запускать обработку всего пакета заново.
Спроектируйте операционную проверку и аудит
Интерфейс проверки должен помогать принимать решения, а не просто показывать техническое исключение. Показывайте полученное значение, причину, затронутое поле, соответствующий контекст и, если это безопасно, предлагаемое исправление. Позволяйте фильтровать записи по статусу, пакету, типу ошибки и давности; ясно показывайте, для каких строк эффекты уже наступили, а для каких — нет.
Фиксируйте, кто проверил случай, когда это произошло, какое значение было изменено, какое решение принято и по какой причине. Различайте исправление оператором и автоматическое преобразование. Назначайте права с учетом обязанностей: пользователь, которому разрешен импорт файла, не обязательно должен иметь право утверждать конфликты или изменять принятые записи. Для изменений с серьезными последствиями рассмотрите дополнительное утверждение.
Не допускайте, чтобы инструмент позволял перезаписывать данные без предупреждения. Перед принятием исправления повторно проверьте уникальность, права доступа и текущее состояние записи. Если с момента обнаружения конфликта другой пользователь изменил данные, покажите это состояние для разрешения, а не применяйте устаревшее обновление.
Тестируйте частичные сбои и восстановление

Тесты должны проверять как правила, так и поведение процесса. Включите файлы со смешанными корректными и некорректными строками, неожиданными форматами, конфликтами, временными сбоями базы данных и повторными попытками. Убедитесь, что отклоненная строка не мешает принять остальные, если такова согласованная политика, а сбой внутри транзакции не оставляет частичных эффектов.
- Повторная обработка строки с тем же ключом идемпотентности не дублирует записи и внешние действия.
- Исправление поля позволяет выполнить валидацию заново, не удаляя оригинал и историю.
- Повторная обработка другой строки не приводит к повторному применению уже принятой строки.
- Конфликты, обнаруженные между проверкой и разрешением, не перезаписываются незаметно.
- Сообщения об ошибках позволяют принять меры, не раскрывая лишние чувствительные данные.
В рабочей среде отслеживайте объем и давность записей в карантине, наиболее частые причины, долю разрешенных случаев и сбои повторной обработки. Устойчивый рост показателей может указывать на изменение исходной системы, устаревшее правило или недостаточно ясные инструкции по загрузке. Карантин работает тогда, когда делает причины видимыми и позволяет контролируемо устранять их, а не превращается в бессрочное хранилище исключений.



