Если этап кандидата изменился, а в истории нет автора, времени и причины, рекрутеры теряют доверие к воронке и не могут восстановить решение. Изменение могло пройти через API, импорт, автоматическое правило или прямой SQL, обходя общий сервис аудита. Исправление должно сделать историю частью самой операции перехода, а не необязательным побочным логом.

Для конкретного кандидата сравните updated_at, текущий stage ID, журналы API, automation runs, imports and database logs. Определите точный интервал и возможный actor. Не добавляйте вымышленную причину вручную: восстановленные сведения помечайте как реконструированные и сохраняйте источник.

Что проверить в первую очередь

Начните с одного воспроизводимого сценария. Зафиксируйте точное время, идентификатор объекта, пользователя или операции, версию приложения и последнее известное рабочее состояние. Не меняйте несколько параметров одновременно: один контролируемый шаг должен подтверждать или исключать одну гипотезу. Перед работой с данными и конфигурацией подготовьте резервную копию и проверенный способ отката.

  • Проверьте, какие endpoints and jobs могут менять stage.
  • Сравните current stage updated_at с последней строкой истории.
  • Найдите request ID, service account, import batch or automation run в тот же момент.
  • Проверьте bulk actions и интеграции, работающие вне основного интерфейса.

Почему возникает проблема

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

  • Один endpoint выполняет прямой UPDATE и забывает вызвать audit service.
  • Фоновое правило меняет этап под общим system user без контекста причины.
  • Bulk import перезаписывает stage вместе с другими полями.
  • История пишется после основной транзакции и теряется при отдельной ошибке.
  • Retention or cleanup ошибочно удаляет audit rows раньше карточки кандидата.

Пошаговая диагностика

Диагностику проводите на тестовой записи или отдельном окружении. В журналах скрывайте токены, пароли, персональные данные и содержимое документов. Для каждого шага сохраняйте измеримый результат: код ответа, версию записи, идентификатор события, состояние процесса, контрольную сумму или время выполнения. Так можно отличить подтвержденную причину от случайного совпадения.

  • Составьте карту всех writers поля stage_id по коду и database grants.
  • Проверьте transaction boundaries и сценарий ошибки после update before audit.
  • Воспроизведите переход через UI, API, импорт and automation.
  • Сравните actor propagation через очередь и фоновые worker.
  • Проверьте timezone and ordering одинаковых timestamp.

Как хранить переход этапа и его причину

Команда перехода должна одновременно проверить допустимость, изменить текущий этап и добавить неизменяемое событие. Actor, источник, причина и correlation ID передаются явно даже для системной автоматизации.

  • Stage transition имеет from, to, candidate, vacancy, actor and occurred_at.
  • Source различает UI, API, import, automation and migration.
  • Запись текущего состояния и event создаются в одной транзакции.
  • Исправление истории добавляет новое correction event, а не переписывает прошлое незаметно.

Как исправить проблему

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

  • Направьте все изменения stage через единый transition service.
  • Записывайте audit event в той же транзакции или через transactional outbox.
  • Передавайте actor and reason через API, jobs and queue messages.
  • Ограничьте прямые database permissions для приложений и интеграций.
  • Восстановите пропуски по надежным журналам, отметив confidence and source.

Безопасный порядок внедрения

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

Как проверить результат

Разовый успешный тест недостаточен. Повторите операцию, проверьте крайние значения, одновременные действия и восстановление после перезапуска или временного сбоя. Для важного сценария сохраните автоматический тест либо короткий регрессионный чек-лист. Итог должен подтверждаться не только интерфейсом, но и состоянием базы, очереди, внешнего сервиса и журналом действий.

  • Каждый переход через UI, API, import and automation создает одну строку истории.
  • Ошибка записи истории откатывает смену этапа либо гарантированно оставляет outbox event.
  • Actor and reason корректны для человека и системного правила.
  • Параллельные переходы не создают невозможную последовательность from and to.

Типичные ошибки при исправлении

  • Добавлять frontend log после успешного ответа вместо server-side audit.
  • Использовать одного system user без имени правила и run ID.
  • Редактировать старые audit rows для красивой истории.
  • Разрешать импорту безусловно перезаписывать stage.

Как предотвратить повторение

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

  • Добавьте тесты всех writers поля stage_id.
  • Контролируйте кандидатов, у которых updated_at новее последнего transition.
  • Храните audit дольше операционных логов и защищайте от обычного удаления.
  • Проводите review новых автоматизаций и интеграций на actor context.

Что контролировать после выпуска

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

Что подготовить для технического разбора

  • Описание ожидаемого и фактического поведения с точной последовательностью действий.
  • Время проблемы, идентификатор тестового объекта и версии затронутых компонентов.
  • Фрагменты журналов до и после ошибки без секретов и персональных данных.
  • Перечень последних изменений и уже выполненных проверок.
  • Безопасный доступ к тестовой среде либо способ воспроизвести сбой без влияния на клиентов.

Частые вопросы

Можно ли восстановить автора старого изменения?

Иногда по API, access log, import batch or automation run. Если доказательств недостаточно, нельзя назначать автора догадкой — укажите системное восстановление и источник.

Нужен ли database trigger?

Он может служить страховкой, но часто не знает бизнес-причину и actor. Лучше единый transition service plus outbox; trigger может выявлять обход.

Когда нужна помощь специалиста

Если ATS меняет этапы без истории, я могу найти все пути записи, внедрить атомарный audit trail и аккуратно восстановить доказуемые переходы.