feat(ads): server-driven ad-banner backend, wire & admin console (PR1)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m12s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m12s
Turn the gated-off mock banner into a real advertising subsystem (backend + admin half; the UI rotation lands in PR2). - internal/ads: campaigns (percent weight + validity window; a perpetual, undeletable default that fills the remainder up to 100%), 1..N bilingual messages (en+ru), global display timings; ActiveSet computes the window-filtered, default-remainder, GCD-reduced, language-resolved rotation feed. Smooth-weighted-round-robin math is unit-tested. - migration 00006 (+ jetgen): ad_campaigns / ad_messages / ad_settings, seeded default campaign + house message + default timings. - eligibility = !paid_account && hint_balance==0 && !no_banner role (new role; guests qualify). The resolved feed rides the profile.get response (no new RPC, works for guests, nothing distinct to filter); language by service_language. - live update: a notify `banner` sub-kind (re-poll signal) published when an operator grants hints or grants/revokes no_banner, so the client shows/hides in place. - admin console /_gm/banners (+ /_gm/banner-settings): campaign + message CRUD with reorder, default protection, clamped timings. - wire: fbs BannerInfo/BannerCampaign on Profile; gateway transcode forwards it. - docs: ARCHITECTURE §10, FUNCTIONAL (+ _ru), backend README, PRERELEASE tracker (incl. the deferred app.load aggregator note).
This commit is contained in:
@@ -270,3 +270,26 @@ IP и вложением. Оператор может пометить сооб
|
||||
пользователя. Открытие сообщения не помечает его прочитанным — это делают только явные действия; тело
|
||||
сообщения и вложения показываются защищённо (текст экранируется, вложения отдаются на скачивание, а не
|
||||
рендерятся).
|
||||
|
||||
### Рекламный баннер
|
||||
|
||||
Однострочный баннер под навбаром показывает короткие рекламные или служебные сообщения **бесплатным
|
||||
игрокам**: всем, кто **не** оплатил пожизненный аккаунт, **не** имеет купленных подсказок и **не**
|
||||
несёт роль **`no_banner`** (она отключает баннер безусловно). Покупка платного аккаунта или подсказок —
|
||||
либо выдача `no_banner` — убирает его; гости как самые «бесплатные» пользователи баннер видят. Когда
|
||||
оператор меняет одно из этих свойств, баннер появляется или исчезает **на месте**, без перезагрузки.
|
||||
|
||||
Сообщения берутся из управляемых оператором **кампаний**, каждая из которых — заказ на размещение со
|
||||
**своим весом показа** (процент) и необязательным **окном** действия (начало/конец). Одновременно
|
||||
идущие кампании **конкурируют** за баннер пропорционально весам; постоянная **дефолтная (домашняя)**
|
||||
кампания добивает остаток, не выкупленный платными, и полностью уходит из ротации, когда те выкупают
|
||||
все 100%. Каждое сообщение написано на **двух языках** (английский + русский); игрок видит вариант для
|
||||
**бота, через которого играет**, независимо от языка интерфейса. Клиент ротирует подходящие кампании
|
||||
**честно** — каждая получает свою долю по весу за цикл, равномерно размазанную, а не случайно — а
|
||||
кампания с несколькими сообщениями показывает их по очереди.
|
||||
|
||||
Всем этим оператор управляет в админ-консоли по адресу **`/_gm/banners`**: создаёт, редактирует,
|
||||
включает/выключает и планирует кампании, пишет двуязычные сообщения кампании (переставляет и удаляет
|
||||
их) и задаёт общие **тайминги** показа (сколько держится сообщение, прокрутка слишком длинного, и
|
||||
переход fade-out → пауза → fade-in между сообщениями). Дефолтную кампанию нельзя удалить, и в ней
|
||||
всегда остаётся хотя бы одно сообщение.
|
||||
|
||||
Reference in New Issue
Block a user