f99bc54d6a
Часть 2 из 6. Живая смета медийной кампании «за показы»: из аудитории (окно дней) и частоты → показы × 120₽/1000 = сумма клиенту (наценка не видна). - CampaignEstimateService: size×частота=показы, сумма по ad_settings.client_cpm_rub через AdImpressionPricing (bcmath, вверх до копейки); порог MIN_AUDIENCE=100. - AdvertisingCampaignController::audienceSize — при переданной frequency добавляет в ответ impressions/cpm_rub/cost_rub; без частоты ответ прежний (обратная совместимость). - Аудитория (deals за N дней + свой список, дедуп, RLS) и порог 100 уже были в модуле. - Тест сметы обёрнут в DatabaseTransactions (мутация глобальной ad_settings не утекает). Тесты: 17/17 зелёные (вкл. проверку отсутствия утечки цены + регресс). Spec: docs/superpowers/specs/2026-07-25-yandex-reklama-medijnaya-pokazy-design.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>