@@ -51,19 +51,42 @@ export const BILLBOARD_DISMISS_LOCK_MS = 10_000
5151/** A pause in typing/clicking that may open a closed panel for its billboard. */
5252export const BILLBOARD_PANEL_IDLE_MS = 3_000
5353
54+ export type BillboardFrequencyCap = {
55+ /** Whose serves share one count: the campaign's, or a single ad's. */
56+ per : 'campaign' | 'ad'
57+ /** Every limit must have room. The first is the slot's daily allowance. */
58+ limits : readonly { maxImpressions : number ; windowMs : number } [ ]
59+ }
60+
61+ const HOUR_MS = 60 * 60_000
62+ const DAY_MS = 24 * HOUR_MS
63+
5464/**
55- * The frequency cap on a billboard serve: per user, per campaign, per slot
56- * (sidebar and panel each), over a rolling day. It REPLACES the campaign's
57- * own cap and the hourly ad and advertiser caps for these serves, which count
58- * serves rather than screen time: a billboard stays up for up to
65+ * The frequency cap on each billboard slot, per user. It REPLACES the
66+ * campaign's own cap and the hourly ad and advertiser caps for these serves,
67+ * which count serves rather than screen time: a billboard stays up for up to
5968 * {@link BILLBOARD_REFRESH_MS}, so an hourly cap still let one campaign hold
6069 * the sidebar all day. Billboard serves therefore do not spend the
6170 * campaign's hourly cap on its other placements either.
71+ *
72+ * - The sidebar serves each campaign 3 times a rolling day, at most once an
73+ * hour, so a day's allowance cannot all land in one sitting.
74+ * - The panel takes over the right panel, so the same ad opens it at most
75+ * once a day.
6276 */
63- export const BILLBOARD_DAILY_FREQUENCY_CAP = {
64- maxImpressions : 5 ,
65- windowMs : 24 * 60 * 60_000 ,
66- } as const
77+ export const BILLBOARD_FREQUENCY_CAPS : Readonly < Record < string , BillboardFrequencyCap > > = {
78+ [ BILLBOARD_SIDEBAR_PLACEMENT_ID ] : {
79+ per : 'campaign' ,
80+ limits : [
81+ { maxImpressions : 3 , windowMs : DAY_MS } ,
82+ { maxImpressions : 1 , windowMs : HOUR_MS } ,
83+ ] ,
84+ } ,
85+ [ BILLBOARD_PANEL_PLACEMENT_ID ] : {
86+ per : 'ad' ,
87+ limits : [ { maxImpressions : 1 , windowMs : DAY_MS } ] ,
88+ } ,
89+ }
6790
6891export type BillboardAsset = { url : string ; width : number ; height : number }
6992export type BillboardAssets = Partial < Record < BillboardShape , BillboardAsset > >
0 commit comments