Commit Graph

2 Commits

Author SHA1 Message Date
Дмитрий d26716ed90 fix реклама за показы: срок показа закрывает кампанию, отчёт робота только по заданию в работе, гонка выдачи заданий
Р1. Кампания, не добравшая смету показов, оставалась running навсегда, а заморозка
денег клиента - ACTIVE навсегда: единственным переходом в completed было
delivered >= paid_impressions, а задачи, закрывающей кампанию по истечении срока
показа, не существовало вовсе. Для медийки по списку телефонов недокрут сметы -
типовой исход, а не редкий случай.

Новая колонка ad_campaigns.shows_until хранит последний день показа - ровно тот,
что уходит в Директ параметром EndDate. Пишется вместе с yandex_campaign_id, то
есть в момент, когда дату начинает держать Яндекс; возобновляемый запуск
переиспользует уже записанную дату, чтобы портал и Директ считали срок одинаково.
У выхода 1 в CampaignImpressionCharger появилось второе условие - новых мест
вызова AdWalletService::release не добавилось, их по-прежнему ровно четыре.
Запись v9.07 в журнале схемы, rls-reviewer GO.

Р2. Отчёт робота принимался по любому заданию в любом состоянии: номер брался из
адреса как есть. Готово по чужому ещё не выданному заданию разложило бы номера
креативов чужой кампании по её баннерам - картинка одного клиента уехала бы в
объявление другого; сбой по уже закрытому заданию переписал бы правильный
результат на failed. Теперь done принимает отчёт только по заданию в статусе
taken - 409 в остальных случаях, та же проверка продублирована в сервисе.

Р3, первая половина. Проверка «в работе никого» в takeNext не блокировала строку:
две одновременные выдачи обе её проходили и уносили разные задания. Слепки
creatives.get перемешивались, а размеры блоков у всех клиентов одинаковые, поэтому
итог - тихая привязка чужого номера креатива. Гарантию даёт частичный уникальный
индекс uq_creative_job_single_taken, плюс advisory-замок первой строкой транзакции,
чтобы штатный путь спокойно отвечал роботу «работы нет».

Осталось по Р3: привязать выдачу файла к номеру задания, rls-reviewer по индексу,
запись v9.08 в журнал схемы. Ход работы - в файле PROGRESS рядом с промтом v12.

Тесты, прогнаны в одиночку: портал 256/256, робот 35/35. Все девять новых тестов
были красными до правок, каждая защита проверена вырезанием.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 19:36:03 +03:00
Дмитрий 9234a9c2bc feat реклама показы: очередь заданий робота-грузчика, служебный канал и постановка при запуске
Портал ставит роботу задание, когда у баннеров ещё нет номеров креативов: вместо
ошибки клиент видит «готовим картинки», кампания остаётся черновиком, деньги не
морозятся. Робот берёт задания строго по одному — иначе слепки креативов до и
после перемешаются, и опознать их будет нельзя.

Канал робота закрыт своим сервис-токеном, внесён в исключения проверки CSRF и
отдаёт файл только того задания, которое сейчас в работе. Постановка задания
стоит внутри проверки рубильника Директа — при выключенном рубильнике портал в
Яндекс не ходит.

Права на новую таблицу выданы роли crm_admin_user: канал идёт через посредник
admin-db, подменяющий подключение. Нумератор выдан crm_app_user — он единственный
вставляет строки. Журнал схемы — запись v9.06.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 17:13:02 +03:00