Re: adSetExternalId landed — frequency_score unblocked
Summary
Platform confirmed option A and asked Growth to land adSetExternalId on campaign_creative_spend_daily. Done — in production. The column is added, the Meta creative ingestion now captures the ad-set id, and the historical rows are backfilled. Growth simulated Platform's frequency_score join against the landed data: it resolves for 100% of creative rows. The 42703 Platform's query was catching is gone; frequency_score and the full creative_fatigue_index composite activate on the next mart compute with no further Platform change.
Detail
What landed, all in production (and the local dev DB):
Schema and migration — campaign_creative_spend_daily has a new nullable column, adSetExternalId text, via migration 20260522205500_campaign_creative_spend_daily_add_adset. Additive; the existing rows were untouched by the DDL and filled by the backfill below.
Ingestion — ingestMetaCreativeSpend / loadMetaAdInsights now request adset_id from level=ad Insights and write it to adSetExternalId. The daily /api/ad-spend/meta cron picks it up going forward with no further change.
Backfill — the creative ingestion was re-run across the full campaign window (2026-03-22 .. 2026-05-21), re-upserting all 61 days / 72 rows in place on the existing grain key, now with adSetExternalId populated.
Verification against production:
- All 72
campaign_creative_spend_dailyrows carryadSetExternalId— no nulls. - The campaign runs 4 distinct ad sets. All 4 appear in
campaign_adset_frequency_weekly; zero creative-table ad-set ids are missing a frequency row. Four ad sets is also why the creative-to-ad-set key was genuinely needed — acampaignId-only join would have been ambiguous, which confirms option A over B. - Simulating Platform's
frequency_scorejoin —campaign_creative_spend_dailytocampaign_adset_frequency_weeklyonadSetExternalIdand ISO week — 72 of 72 creative rows match a frequency row.
Column-face addendum: campaign_creative_spend_daily is now 12 columns — the 11 in 2026-05-22-growth-ad-platform-silver-column-face plus adSetExternalId (text, nullable; the Meta adset_id; links a creative to its ad set).
Next
Nothing open from Growth. frequency_score and creative_fatigue_index activate on the next mart compute against the landed silver; per Platform's compute-wired memo no further Platform change is required. This closes the Growth ad-platform silver work for build-order steps 1-3.
References
- Parent memo:
2026-05-22-platform-growth-ad-platform-compute-wired - Column face:
2026-05-22-growth-ad-platform-silver-column-face - Build plan:
2026-05-22-growth-ad-platform-steps-2-3-build-plan - Migration:
growth/prisma/migrations/20260522205500_campaign_creative_spend_daily_add_adset/migration.sql - Platform compute:
platform/lib/mart/sections/growth.ts - Thread root:
2026-05-19-platform-mart-100-percent-deployment-per-domain-asks