romi
Мультиарендный кабинет маркетолога на Django 5.2: расходы рекламных кабинетов, сделки из CRM и ROMI по каналам. Эксперименты ниже идут на живом сервисе — настоящие Postgres с row-level security, Celery, Redis и вымышленная рекламная сеть, которая ведёт себя как настоящие.
Ключи для API
Две демо-организации и по ключу наблюдателя (viewer: только чтение). В Swagger UI — кнопка Authorize, значение ключа. Всё, что ниже меняет данные, делает сервер сам и только с демо-данными.
Загрузка…
1. Чужие данные по id
Наблюдатель Acme пробует прочитать Globex: по чужому slug в URL и по id чужого проекта под своим slug. Правильный ответ — 404 в обоих случаях, а не 403: ответ не должен подтверждать, что такой slug или id существует. Последняя строка — контроль: владелец тех же данных тем же запросом получает 200, значит 404 выше — не опечатка в URL.
| кто | запрос | ответ |
|---|
Второй слой — сама база. Один и тот же запрос без всякого фильтра, под разными арендаторами. Строки отсекает политика row-level security, а не код. Без арендатора — ноль, а не все строки.
2. Отчёт: два запроса при любом размере
Расход, лиды, продажи, выручка и ROMI проекта Acme за 30 дней. Расходы и сделки агрегируются отдельно: один JOIN двух таблиц фактов умножил бы обе суммы. Повторный запрос приходит из кэша, пока данные не изменятся.
| расход | клики | лиды | продажи | выручка | CPL | ROMI |
|---|
Наивная версия — ModelSerializer с SerializerMethodField на
каждое число: по запросу на число на строку. Итоги у обеих одинаковые. Здесь всего
шесть кампаний; на 500 кампаниях за 90 дней бенчмарк в репозитории даёт 3251 запрос
и 4,2 с против 2 запросов и 67 мс.
3. Вебхук CRM: дважды и не по порядку
Сервер шлёт в собственный вебхук одну сделку четырьмя подписанными (HMAC) событиями: заявку, ту же доставку повторно (CRM решила, что мы не ответили), выигрыш — и опоздавшее событие из прошлого. Повтор должен быть подтверждён и выброшен, опоздавший «open» не должен отменить «won». Отчёт после этого обязан пересчитаться, а не прийти из кэша.
| событие | ответ |
|---|
4. Импорт: площадка правит прошлое
Рекламная сеть неделями правит прошлые дни: возвращает деньги за скликивание, убирает строки. Импорт каждый раз перечитывает окно в 21 день и заменяет его: исправленное перезаписывается, пропавшее удаляется. Кнопка просит сеть поправить прошлое и ставит импорт в очередь Celery; ниже — его запуск, как его видит API.