The first baseline committed the raw YouTube API dump, which fixed clean builds but carried unused API metadata. The route fallback only needs prebuilt listing objects, so this replaces the raw seed with slug-keyed listing fallbacks and adds a refresh script that fetches the latest source data before projecting it.
Constraint: helpers/site-listings.js must work in a fresh checkout before generated static/api output exists
Rejected: Commit the full raw YouTube JSON | unnecessarily large and mostly unused by the fallback path
Rejected: Drop descriptions only | smaller but would weaken app-link and tag matching semantics
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Refresh static/api/youtube-video-listings.json via scripts/update-youtube-video-listing-fallbacks.js, not by committing static/api/youtube-videos.json
Tested: pnpm run with-env vite-node scripts/update-youtube-video-listing-fallbacks.js
Tested: pnpm run with-env vitest test/prebuild/site-listings.test.js
Tested: pnpm run netlify-prebuild:test-prebuild-functions
Tested: pnpm run netlify-prebuild
Netlify prebuild tests import the YouTube listing JSON at module load time, so a fresh checkout needs a baseline copy of that data before any generated API step runs. The fetched JSON is committed and explicitly unignored while the broader static/api output remains generated.
Constraint: Netlify runs test-prebuild before Astro generation creates generated API files
Rejected: Move all API generation before tests | broader build-order change with more external dependencies
Confidence: high
Scope-risk: narrow
Directive: Keep static/api/youtube-videos.json tracked unless helpers/site-listings.js stops importing it at module load time
Tested: pnpm run with-env vite-node /tmp/fetch-youtube-videos.mjs
Tested: pnpm run with-env vitest test/prebuild/site-listings.test.js
Tested: pnpm run netlify-prebuild:test-prebuild-functions