VC LABКейсыКейс: агентство перфоманс-маркетинга

Агентство перфоманс-маркетинга: деньги и данные под контролем кода

Заказчика не раскрываем по условиям договора: агентство перфоманс-маркетинга, которое ведёт клиентские кампании в нескольких рекламных сетях и работает с MMP-платформой. Здесь выстроена система контроля качества денег и данных. Сверка открута с пополнениями, автотесты внутренних инструментов, мониторинг с алертами и аудит доступов работают кодом и по расписанию: то, что раньше проверялось руками и на глаз, теперь проверяется автоматически и до цента.

Результат в цифрах

  • Более десятка задач по расписанию: синк спенда несколько раз в час, глубокий ночной синк, сверка, дайджест, бэкапы, проверка здоровья ботов, клиентские книги, ежедневная выгрузка из MMP.
  • Около двухсот автопроверок на pytest.
  • Десятки тысяч строк собственного кода.
  • Все рекламные кабинеты сверены с партнёрами до цента: у каждого пополнения в книге сверки есть хеш транзакции или подтверждение из биллинга.
  • Все рабочие таблицы баеров исправлены одним прогоном скрипта вместе с шаблоном.
  • Около половины лишних доступов к MMP закрыто, ни один сотрудник не потерял нужный доступ.

Дефекты, найденные и закрытые

Ошибки, которые никто не видел, пока данные не начали проверять системно. Каждая влияла на деньги или на решения по клиентам; каждая после исправления стала правилом проверки.

  • Кампания, переименованная за день, давала две строки с одним ключом, и запись затирала одну из них: панель теряла заметную часть спенда и завышала остатки. Строки с одним ключом суммируются, на случай написан регрессионный тест.
  • Пополнения привязывались к номеру строки журнала: при вставке строки деньги уезжали на чужой кабинет. Привязка перенесена на хеш транзакции с двухфазным матчингом и проверена прогоном на копии базы со сдвигом строк.
  • Выгрузка из MMP складывала события сервера и SDK: регистрации и FTD клиента завышались примерно вдвое. Считается только серверный постбэк, правило записано в самой выгрузке.
  • Итог в шаблоне таблицы баера обрывался на середине списка офферов, и сводная занижала затраты. Исправлено скриптом во всех таблицах и в шаблоне.
  • Сводки читали оборванные ссылки на чужие таблицы и месяцами показывали нули. Данные читаются из исходных таблиц, сводка пересобирается каждый час.
  • Формы панели молча теряли поля при сохранении. Проведён аудит четырёх классов потерь, на каждый — исправление и тест.
  • База панели в контейнере была смонтирована файлом в режиме WAL, и записи терялись. Монтирование переведено на каталог, после ручных правок делается чекпойнт.
  • Сверка по одному из кабинетов учитывала неуспешный платёж, и расхождение с партнёром было ровно на его сумму. Правило подсчёта: только завершённые платежи, счёт за открут не считается пополнением.

Сверка денег до цента

Сверка с партнёрами идёт по каждому кабинету: открут, крипто-пополнения и карточные заливы. Карточные пополнения рекламная сеть через API не отдаёт: проверка десятков адресов и разница в ответах 403 и 404 показали, что дело не в правах доступа. Источник нашёлся в интерфейсе биллинга вместе с правилами подсчёта, и карточные платежи вошли и в книгу сверки, и в панель.

Сверка встроена в рабочий инструмент: остатки кабинетов в панели совпадают с книгой до цента, а при закрытии кабинета история открута выгружается автоматически — партнёры отзывают ключи без предупреждения.

Автотесты и инварианты

Тесты описывают поведение, а не код. Для закрытия кабинета проверяется, что правка активной карточки не запускает выгрузку истории, закрытие запускает, повторное сохранение не дублирует, а сбой Google не мешает закрыть кабинет и уходит алертом в чат. Покрыты сохранение карточек, привязка денег, уведомления о низком балансе, экспорт, режим наблюдателя и обработка лимитов API.

  1. Перед любой массовой правкой денег или доступов делается бэкап.
  2. Правка выполняется с инвариантом: суммы до и после обязаны совпасть.
  3. Результат перечитывается из системы, а не берётся из ответа скрипта.
  4. Если инвариант не выполнен, изменение откатывается.
Пример из журнала проверок: деньги не тронуты, число пополнений и суммы до и после правки совпадают. Так выглядит каждая массовая операция.

Мониторинг, лимиты и диагностика API

Сбой любой задачи уходит в админ-чат через общий алерт-модуль: проблема видна в момент возникновения, а не когда клиент спросит про остаток. Лимиты внешних API обрабатываются, а не роняют процесс. У одной из сетей лимит общий на все кабинеты, и ожидание доходит до получаса. У MMP он частотный: замерено, какая пауза между запросами пропускает весь поток, а при отказе выгрузка подставляет последнюю удачную и явно это помечает.

Методика диагностики интеграций — контрольный запрос с заведомо неверным токеном и разбор кодов 401, 403 и 404, каждый из которых означает своё. Так установлено, что агентским аккаунтам часть API платформы недоступна, и найден рабочий обходной путь. Проверка пропавших приложений по одной стране давала больше половины ложных срабатываний и переведена на проверку по нескольким гео; блеклисты кампаний ведутся через API.

Аудит доступов

Несколько аккаунтов MMP, десятки пользователей, права на сотни приложений: роль, последний вход и сопоставление со штатом. Закрыты доступы давно неактивных, ни разу не заходивших и внешних пользователей без входа. Админы и учётки интеграций защищены от удаления, перед удалением сохраняется бэкап прав, после — результат проверяется повторным запросом. Сотрудники на почтах партнёрского домена распознаются по рабочему адресу из штатного списка, а не по имени в системе.

Стек и интеграции

  • Код: Python, FastAPI, SQLite, pytest, gspread, Google Apps Script.
  • Инфраструктура: Podman, systemd timers, nginx и Caddy.
  • Рекламные сети и MMP: API статистики и управления кампаниями, API выгрузок и управления пользователями MMP.
  • Рабочие инструменты: Google Sheets, Drive и Apps Script, Asana, Telegram Bot API — панель спенда с обновлением каждые 15 минут, клиентский бот с остатками по кабинетам, журнал пополнений, который дозаполняется по хешу транзакции.

Принципы

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

Цифры и названия систем обобщены по условиям договора о конфиденциальности.

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

Чем это отличается от обычного тестирования?
Объект проверки — не интерфейс, а деньги и данные: сверка двух независимых источников до цента, инвариант на каждую правку, регрессионный тест на каждый найденный дефект.
Почему сверка по двум источникам, а не по одному?
Одной цифре на слово не верим: открут и пополнения сверяются минимум по двум системам — данным сети и книге сверки с хешами транзакций. Расхождение считается дефектом, пока не доказано обратное.
Как работать с лимитами API рекламных сетей?
Измерять и обрабатывать, а не ронять процесс: у одной сети лимит общий на все кабинеты с долгим ожиданием, у MMP — частотный, и подобранная пауза пропускает весь поток. При отказе выгрузка подставляет последнюю удачную и явно это помечает.
Можно ли повторить такую систему в другом агентстве?
Да: подход переносится — книга сверки, инварианты, тесты на поведение, мониторинг с алертами, аудит доступов. Интеграции собираются под ваши сети и MMP.

Расскажите о задаче

Ответим в течение одного рабочего дня, оценку пришлём за 1–2 дня. Бесплатно.

Обновлено: 2026-10-02