feat(banner): per-campaign colour overrides and urgent alerts #182

Merged
developer merged 1 commits from feature/banner-colors-urgent into development 2026-07-05 13:57:32 +00:00
Owner

Two banner additions for non-default campaigns.

Colour override (per campaign)

Background / text / link, in two sets — one for every theme, one for the dark theme only. The wire carries six trailing FlatBuffers strings on BannerCampaign (backward-compatible); the client resolves the cascade (dark ← dark ?? all, light ← all) against the rendered theme and derives the strip border from the background in JS (no CSS color-mix, for the old Android WebView floor). AdBanner applies them as inline CSS vars scoped to the strip, so nothing leaks past it.

Urgent (per campaign)

Shown to everyone — bypassing paid / hint-wallet / no_banner — and, while live, the only thing the strip shows (ordinary campaigns + the house default step aside). Resolved entirely server-side (computeActiveSet preempt + bannerFor eligibility skip); no wire field. No instant broadcast (per-user notify) — it lands on each viewer's next profile.get.

Admin console (/_gm/banners)

Native colour pickers + a live light/dark preview of the strip, and an urgent toggle. The default campaign stays plain (no colours, never urgent) — enforced by the service and a DB CHECK.

Safety

Migration 00009 is additive (nullable colour columns + bool DEFAULT false + all-or-nothing / hex / default-plain CHECKs) — expand-contract, image-rollback-safe.

Tests

ads unit (urgent preempt + colour validation), codec + resolver unit, gateway transcode, integration (colour round-trip + urgent bypass vs real Postgres). Docs: ARCHITECTURE §10, UI_DESIGN, FUNCTIONAL (+ru).

Review focus: visual sign-off of the strip colours (light + dark) and the console preview on the test contour once it deploys.

Two banner additions for non-default campaigns. ## Colour override (per campaign) Background / text / link, in **two sets** — one for every theme, one for the **dark theme only**. The wire carries six trailing FlatBuffers strings on `BannerCampaign` (backward-compatible); the client resolves the cascade (dark ← dark ?? all, light ← all) against the rendered theme and derives the strip border from the background in JS (no CSS `color-mix`, for the old Android WebView floor). AdBanner applies them as inline CSS vars scoped to the strip, so nothing leaks past it. ## Urgent (per campaign) Shown to **everyone** — bypassing paid / hint-wallet / `no_banner` — and, while live, the **only** thing the strip shows (ordinary campaigns + the house default step aside). Resolved **entirely server-side** (`computeActiveSet` preempt + `bannerFor` eligibility skip); no wire field. No instant broadcast (per-user notify) — it lands on each viewer's next `profile.get`. ## Admin console (`/_gm/banners`) Native colour pickers + a **live light/dark preview** of the strip, and an urgent toggle. The default campaign stays plain (no colours, never urgent) — enforced by the service and a DB CHECK. ## Safety Migration **00009** is additive (nullable colour columns + `bool DEFAULT false` + all-or-nothing / hex / default-plain CHECKs) — expand-contract, image-rollback-safe. ## Tests ads unit (urgent preempt + colour validation), codec + resolver unit, gateway transcode, integration (colour round-trip + urgent bypass vs real Postgres). Docs: ARCHITECTURE §10, UI_DESIGN, FUNCTIONAL (+ru). **Review focus:** visual sign-off of the strip colours (light + dark) and the console preview on the test contour once it deploys.
developer added 1 commit 2026-07-05 13:37:00 +00:00
feat(banner): per-campaign colour overrides and urgent alerts
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 1m8s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m50s
6db9178449
Non-default campaigns gain an optional colour override (background / text /
link) in two sets — one for every theme, one for the dark theme only — and an
"urgent" flag.

- Colours ride profile.get as six trailing FlatBuffers strings on
  BannerCampaign (backward-compatible). The client resolves the cascade
  (dark <- dark ?? all, light <- all) per rendered theme and derives the strip
  border from the background in JS (no CSS color-mix, for the old Android
  WebView floor); AdBanner applies them as inline vars scoped to the strip.
- Urgent is resolved entirely server-side: while any enabled, in-window urgent
  campaign exists, computeActiveSet returns only the urgent campaigns and
  bannerFor skips the eligibility gate — so a system notice reaches every viewer
  (paid / hint-holding / no_banner included) and preempts the ordinary feed. No
  wire field; it appears on each viewer's next profile.get.
- Admin console (/_gm/banners): native colour pickers + a live light/dark
  preview of the strip, and an urgent toggle. The default campaign stays plain,
  enforced by the service and a DB CHECK.

Migration 00009 is additive (nullable colour columns + a bool default +
all-or-nothing / hex / default-plain CHECKs) — expand-contract, rollback-safe.

Docs: ARCHITECTURE §10, UI_DESIGN, FUNCTIONAL (+ru). Tests: ads unit (urgent
preempt + colour validation), codec + resolver unit, gateway transcode, and
integration (colour round-trip + urgent bypass against real Postgres).
owner approved these changes 2026-07-05 13:56:56 +00:00
developer merged commit d61ba68e9b into development 2026-07-05 13:57:32 +00:00
developer deleted branch feature/banner-colors-urgent 2026-07-05 13:57:32 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#182