Агентство перфоманс-маркетинга: деньги и данные под контролем кода
Заказчика не раскрываем по условиям договора: агентство перфоманс-маркетинга, которое ведёт клиентские кампании в нескольких рекламных сетях и работает с MMP-платформой. Здесь выстроена система контроля качества денег и данных. Сверка открута с пополнениями, автотесты внутренних инструментов, мониторинг с алертами и аудит доступов работают кодом и по расписанию: то, что раньше проверялось руками и на глаз, теперь проверяется автоматически и до цента.
Результат в цифрах
- Более десятка задач по расписанию: синк спенда несколько раз в час, глубокий ночной синк, сверка, дайджест, бэкапы, проверка здоровья ботов, клиентские книги, ежедневная выгрузка из MMP.
- Около двухсот автопроверок на pytest.
- Десятки тысяч строк собственного кода.
- Все рекламные кабинеты сверены с партнёрами до цента: у каждого пополнения в книге сверки есть хеш транзакции или подтверждение из биллинга.
- Все рабочие таблицы баеров исправлены одним прогоном скрипта вместе с шаблоном.
- Около половины лишних доступов к MMP закрыто, ни один сотрудник не потерял нужный доступ.
Дефекты, найденные и закрытые
Ошибки, которые никто не видел, пока данные не начали проверять системно. Каждая влияла на деньги или на решения по клиентам; каждая после исправления стала правилом проверки.
- Кампания, переименованная за день, давала две строки с одним ключом, и запись затирала одну из них: панель теряла заметную часть спенда и завышала остатки. Строки с одним ключом суммируются, на случай написан регрессионный тест.
- Пополнения привязывались к номеру строки журнала: при вставке строки деньги уезжали на чужой кабинет. Привязка перенесена на хеш транзакции с двухфазным матчингом и проверена прогоном на копии базы со сдвигом строк.
- Выгрузка из MMP складывала события сервера и SDK: регистрации и FTD клиента завышались примерно вдвое. Считается только серверный постбэк, правило записано в самой выгрузке.
- Итог в шаблоне таблицы баера обрывался на середине списка офферов, и сводная занижала затраты. Исправлено скриптом во всех таблицах и в шаблоне.
- Сводки читали оборванные ссылки на чужие таблицы и месяцами показывали нули. Данные читаются из исходных таблиц, сводка пересобирается каждый час.
- Формы панели молча теряли поля при сохранении. Проведён аудит четырёх классов потерь, на каждый — исправление и тест.
- База панели в контейнере была смонтирована файлом в режиме WAL, и записи терялись. Монтирование переведено на каталог, после ручных правок делается чекпойнт.
- Сверка по одному из кабинетов учитывала неуспешный платёж, и расхождение с партнёром было ровно на его сумму. Правило подсчёта: только завершённые платежи, счёт за открут не считается пополнением.
Сверка денег до цента
Сверка с партнёрами идёт по каждому кабинету: открут, крипто-пополнения и карточные заливы. Карточные пополнения рекламная сеть через API не отдаёт: проверка десятков адресов и разница в ответах 403 и 404 показали, что дело не в правах доступа. Источник нашёлся в интерфейсе биллинга вместе с правилами подсчёта, и карточные платежи вошли и в книгу сверки, и в панель.
Сверка встроена в рабочий инструмент: остатки кабинетов в панели совпадают с книгой до цента, а при закрытии кабинета история открута выгружается автоматически — партнёры отзывают ключи без предупреждения.
Автотесты и инварианты
Тесты описывают поведение, а не код. Для закрытия кабинета проверяется, что правка активной карточки не запускает выгрузку истории, закрытие запускает, повторное сохранение не дублирует, а сбой Google не мешает закрыть кабинет и уходит алертом в чат. Покрыты сохранение карточек, привязка денег, уведомления о низком балансе, экспорт, режим наблюдателя и обработка лимитов API.
- Перед любой массовой правкой денег или доступов делается бэкап.
- Правка выполняется с инвариантом: суммы до и после обязаны совпасть.
- Результат перечитывается из системы, а не берётся из ответа скрипта.
- Если инвариант не выполнен, изменение откатывается.
Мониторинг, лимиты и диагностика 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 рекламных сетей?
Можно ли повторить такую систему в другом агентстве?
Расскажите о задаче
Ответим в течение одного рабочего дня, оценку пришлём за 1–2 дня. Бесплатно.