У нас есть автопочинка объявлений: получаем статус, исправляем текст или фото, пересобираем XML-фид и ждём следующей загрузки. На бумаге цикл замкнут. На практике два объявления из Серпухова и Солнечногорска провисели так почти два месяца.

Оба сначала получили rejected, затем перешли в blocked. Исправленный контент в базе был, а в кабинете объявления не возвращались. Мы заметили это не по алерту, а когда вручную сверили три множества:

IDs в нашей БД
∩ IDs в текущем XML-фиде
∩ IDs, которые возвращает API кабинета

Разность оказалась маленькой — две записи, — поэтому обычные метрики выглядели здоровыми. Счётчик «исправлено» рос: пайплайн действительно менял данные. Но он измерял завершение внутреннего шага, а не возврат объявления в публикационный контур.

Ошибка была в модели состояний. Мы считали rejected и blocked вариантами одной проблемы:

if status in {Status.REJECTED, Status.BLOCKED}:
    fix_content(ad)
    mark_fixed(ad)

Для rejected этого хватало, пока объявление оставалось участником загрузки. Для двух наблюдавшихся blocked — нет: к моменту исправления их ID уже отсутствовали в актуальном фиде. Получался честный, но бесполезный mark_fixed().

Исправление получилось не в промпте и не в наборе запрещённых слов. Мы разделили «контент исправлен» и «объект снова попал в контур»:

fix_content(ad)

if ad.status == Status.BLOCKED and ad.requeue_attempts == 0:
    include_in_next_feed(ad)
    request_autoload()
    ad.requeue_attempts = 1

verify_visible_in_account(ad.id)

Повтор ограничили одним. Иначе системная блокировка могла превратить починку в бесконечный цикл «добавили → отклонили → добавили». После одной неудачной попытки объект уходит человеку с исходным статусом и причиной из отчёта загрузки.

Что не сработало:

  • повторная генерация текста сама по себе — исправляла запись, но не возвращала ID в фид;

  • метрика по числу выполненных фиксов — показывала активность, а не результат;

  • сравнение только БД и кабинета — не объясняло, на каком участке исчез объект;

  • безлимитный retry — выглядел простым решением, но скрывал бы постоянные блокировки и дёргал модерацию.

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

Пока полная сверка не автоматизирована, раз в неделю строим разность трёх множеств. Такой контроль оказался полезнее ещё одного «успешного» счётчика.

А где у вас проходит граница успеха: на записи в собственной БД или на подтверждённом состоянии внешней системы?Программированиеавтоматизацияинтеграции

Комментарии (0)