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
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
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).
This commit is contained in:
@@ -13,13 +13,20 @@ import (
|
||||
)
|
||||
|
||||
type AdCampaigns struct {
|
||||
CampaignID uuid.UUID `sql:"primary_key"`
|
||||
Name string
|
||||
Weight int32
|
||||
IsDefault bool
|
||||
Enabled bool
|
||||
StartsAt *time.Time
|
||||
EndsAt *time.Time
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
CampaignID uuid.UUID `sql:"primary_key"`
|
||||
Name string
|
||||
Weight int32
|
||||
IsDefault bool
|
||||
Enabled bool
|
||||
StartsAt *time.Time
|
||||
EndsAt *time.Time
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
OverrideBg *string
|
||||
OverrideFg *string
|
||||
OverrideLink *string
|
||||
OverrideBgDark *string
|
||||
OverrideFgDark *string
|
||||
OverrideLinkDark *string
|
||||
Urgent bool
|
||||
}
|
||||
|
||||
@@ -17,15 +17,22 @@ type adCampaignsTable struct {
|
||||
postgres.Table
|
||||
|
||||
// Columns
|
||||
CampaignID postgres.ColumnString
|
||||
Name postgres.ColumnString
|
||||
Weight postgres.ColumnInteger
|
||||
IsDefault postgres.ColumnBool
|
||||
Enabled postgres.ColumnBool
|
||||
StartsAt postgres.ColumnTimestampz
|
||||
EndsAt postgres.ColumnTimestampz
|
||||
CreatedAt postgres.ColumnTimestampz
|
||||
UpdatedAt postgres.ColumnTimestampz
|
||||
CampaignID postgres.ColumnString
|
||||
Name postgres.ColumnString
|
||||
Weight postgres.ColumnInteger
|
||||
IsDefault postgres.ColumnBool
|
||||
Enabled postgres.ColumnBool
|
||||
StartsAt postgres.ColumnTimestampz
|
||||
EndsAt postgres.ColumnTimestampz
|
||||
CreatedAt postgres.ColumnTimestampz
|
||||
UpdatedAt postgres.ColumnTimestampz
|
||||
OverrideBg postgres.ColumnString
|
||||
OverrideFg postgres.ColumnString
|
||||
OverrideLink postgres.ColumnString
|
||||
OverrideBgDark postgres.ColumnString
|
||||
OverrideFgDark postgres.ColumnString
|
||||
OverrideLinkDark postgres.ColumnString
|
||||
Urgent postgres.ColumnBool
|
||||
|
||||
AllColumns postgres.ColumnList
|
||||
MutableColumns postgres.ColumnList
|
||||
@@ -67,33 +74,47 @@ func newAdCampaignsTable(schemaName, tableName, alias string) *AdCampaignsTable
|
||||
|
||||
func newAdCampaignsTableImpl(schemaName, tableName, alias string) adCampaignsTable {
|
||||
var (
|
||||
CampaignIDColumn = postgres.StringColumn("campaign_id")
|
||||
NameColumn = postgres.StringColumn("name")
|
||||
WeightColumn = postgres.IntegerColumn("weight")
|
||||
IsDefaultColumn = postgres.BoolColumn("is_default")
|
||||
EnabledColumn = postgres.BoolColumn("enabled")
|
||||
StartsAtColumn = postgres.TimestampzColumn("starts_at")
|
||||
EndsAtColumn = postgres.TimestampzColumn("ends_at")
|
||||
CreatedAtColumn = postgres.TimestampzColumn("created_at")
|
||||
UpdatedAtColumn = postgres.TimestampzColumn("updated_at")
|
||||
allColumns = postgres.ColumnList{CampaignIDColumn, NameColumn, WeightColumn, IsDefaultColumn, EnabledColumn, StartsAtColumn, EndsAtColumn, CreatedAtColumn, UpdatedAtColumn}
|
||||
mutableColumns = postgres.ColumnList{NameColumn, WeightColumn, IsDefaultColumn, EnabledColumn, StartsAtColumn, EndsAtColumn, CreatedAtColumn, UpdatedAtColumn}
|
||||
defaultColumns = postgres.ColumnList{IsDefaultColumn, EnabledColumn, CreatedAtColumn, UpdatedAtColumn}
|
||||
CampaignIDColumn = postgres.StringColumn("campaign_id")
|
||||
NameColumn = postgres.StringColumn("name")
|
||||
WeightColumn = postgres.IntegerColumn("weight")
|
||||
IsDefaultColumn = postgres.BoolColumn("is_default")
|
||||
EnabledColumn = postgres.BoolColumn("enabled")
|
||||
StartsAtColumn = postgres.TimestampzColumn("starts_at")
|
||||
EndsAtColumn = postgres.TimestampzColumn("ends_at")
|
||||
CreatedAtColumn = postgres.TimestampzColumn("created_at")
|
||||
UpdatedAtColumn = postgres.TimestampzColumn("updated_at")
|
||||
OverrideBgColumn = postgres.StringColumn("override_bg")
|
||||
OverrideFgColumn = postgres.StringColumn("override_fg")
|
||||
OverrideLinkColumn = postgres.StringColumn("override_link")
|
||||
OverrideBgDarkColumn = postgres.StringColumn("override_bg_dark")
|
||||
OverrideFgDarkColumn = postgres.StringColumn("override_fg_dark")
|
||||
OverrideLinkDarkColumn = postgres.StringColumn("override_link_dark")
|
||||
UrgentColumn = postgres.BoolColumn("urgent")
|
||||
allColumns = postgres.ColumnList{CampaignIDColumn, NameColumn, WeightColumn, IsDefaultColumn, EnabledColumn, StartsAtColumn, EndsAtColumn, CreatedAtColumn, UpdatedAtColumn, OverrideBgColumn, OverrideFgColumn, OverrideLinkColumn, OverrideBgDarkColumn, OverrideFgDarkColumn, OverrideLinkDarkColumn, UrgentColumn}
|
||||
mutableColumns = postgres.ColumnList{NameColumn, WeightColumn, IsDefaultColumn, EnabledColumn, StartsAtColumn, EndsAtColumn, CreatedAtColumn, UpdatedAtColumn, OverrideBgColumn, OverrideFgColumn, OverrideLinkColumn, OverrideBgDarkColumn, OverrideFgDarkColumn, OverrideLinkDarkColumn, UrgentColumn}
|
||||
defaultColumns = postgres.ColumnList{IsDefaultColumn, EnabledColumn, CreatedAtColumn, UpdatedAtColumn, UrgentColumn}
|
||||
)
|
||||
|
||||
return adCampaignsTable{
|
||||
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
|
||||
|
||||
//Columns
|
||||
CampaignID: CampaignIDColumn,
|
||||
Name: NameColumn,
|
||||
Weight: WeightColumn,
|
||||
IsDefault: IsDefaultColumn,
|
||||
Enabled: EnabledColumn,
|
||||
StartsAt: StartsAtColumn,
|
||||
EndsAt: EndsAtColumn,
|
||||
CreatedAt: CreatedAtColumn,
|
||||
UpdatedAt: UpdatedAtColumn,
|
||||
CampaignID: CampaignIDColumn,
|
||||
Name: NameColumn,
|
||||
Weight: WeightColumn,
|
||||
IsDefault: IsDefaultColumn,
|
||||
Enabled: EnabledColumn,
|
||||
StartsAt: StartsAtColumn,
|
||||
EndsAt: EndsAtColumn,
|
||||
CreatedAt: CreatedAtColumn,
|
||||
UpdatedAt: UpdatedAtColumn,
|
||||
OverrideBg: OverrideBgColumn,
|
||||
OverrideFg: OverrideFgColumn,
|
||||
OverrideLink: OverrideLinkColumn,
|
||||
OverrideBgDark: OverrideBgDarkColumn,
|
||||
OverrideFgDark: OverrideFgDarkColumn,
|
||||
OverrideLinkDark: OverrideLinkDarkColumn,
|
||||
Urgent: UrgentColumn,
|
||||
|
||||
AllColumns: allColumns,
|
||||
MutableColumns: mutableColumns,
|
||||
|
||||
Reference in New Issue
Block a user