You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 4e5ccef
Browse filesBrowse the repository at this point in the historyBrowse files
Register the five-second streaming pre-roll format (work package A) (#272)
Schema and format registration for Crawlproof video pre-roll ads. No
rendering, selection or serving — those are packages B and D. The exit
condition this carries is the narrow one from the spec: existing formats
still work, and an unrendered video cannot serve.
Registering a media format in AD_FORMATS is not enough on its own, and is
actively unsafe: creativesFromCopy() fanned out over the whole registry
into one common design object, so the format would have minted a
video_preroll_5s creative carrying a headline and a palette, marked ready
beside its siblings, and handed an HTML renderer something it would draw
as a banner. So the fan-out is now DESIGN_FORMAT_IDS — the complement of
the new STREAMING_FORMAT_IDS — and the dashboard preview strips and format
editors iterate DESIGN_FORMATS for the same reason. They skip formats with
no creative row today, which hides the problem only until the render
pipeline lands.
Three places now refuse video rather than relying on configuration:
* fitAdFormat(), the single gate in front of serveAd(), refuses any
streaming format outright — so the refusal holds even for a slot that
has somehow been given one.
* cleanCreative()'s allowlist is the design formats, so a crafted
updateCreatives payload cannot write a medialess video creative. The
DB would have refused the write anyway; this makes it a clean
rejection rather than a constraint violation.
* ad_creatives.published_revision is null until ffprobe has validated an
encode, so a video creative is unservable by construction rather than
by remembering to check.
The migration deliberately breaks from the terminal_ascii and feed_item
precedents: it widens the creative CHECK but adds nothing to slot
inventory and backfills no creatives. A backfill can clone a headline; it
cannot clone a 150-frame H.264 encode.
Adds ad_video_jobs, ad_video_assets, ad_streaming_properties,
ad_video_decisions and ad_video_events. The decision table's unique
(property, session, placement) key is the whole per-session pre-roll rule:
a reconnect, a playlist reload or a retry returns the row that exists
instead of stacking a second ad.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: app/(marketing)/ads/page.tsx
+2-1Lines changed: 2 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -11,6 +11,7 @@ import {
11
11
}from"@/lib/ads/pricing";
12
12
import{
13
13
AD_FORMATS,
14
+
DESIGN_FORMATS,
14
15
PUBLISHER_FORMAT_IDS,
15
16
TERMINAL_FORMAT_ID,
16
17
TERMINAL_COLS_LABEL,
@@ -102,7 +103,7 @@ export default async function AdsMarketingPage() {
102
103
/>
103
104
<Card
104
105
title="Every size at once"
105
-
body={`${AD_FORMATS.length} formats from one campaign: the standard display sizes, a borderless text link that reads as part of the page, an ASCII unit for terminals, and a syndication item for RSS and Atom feeds.`}
106
+
body={`${DESIGN_FORMATS.length} formats from one campaign: the standard display sizes, a borderless text link that reads as part of the page, an ASCII unit for terminals, and a syndication item for RSS and Atom feeds.`}
0 commit comments