Every public page calls getAllItems(); it cascades through three stores so the site never returns a blank.
Supabase yb100_items is authoritative; Mongo FLEET.items and the LISTS_STATIC bundle are progressive fallbacks. content.ts is force-dynamic — no module cache means admin edits show up on the next request.
/admin and /api/admin are private. Everything else (including unknown 404 paths) is public by design.
Middleware probes the cookie + Supabase session, signs out wrong-email accounts, and lets mat@matsiems.com through. PRIVATE_PREFIXES is the allowlist; flip in src/lib/supabase/middleware.ts.
One PATCH + one PUT, three downstream writes, zero waiting on a Vercel function recycle.
upsertPage hits Supabase, mirrors to Mongo, then revalidatePath() flushes the Vercel cache for the public route. The next visitor sees the new copy on their first request.
04Data model — Supabase tables + Mongo FLEET mirror
Pages and items are the authoritative writes; versions and the publish log are append-only audit.
yb100_items mirrors to Mongo FLEET.items (app='yb100') so the public site keeps rendering when Supabase is in degraded mode. Schema lives in supabase/migrations/0001_cms.sql.
/admin is the cockpit; each console owns one upstream system.
Pages and Items write to Supabase + Mongo. Mongo and S3 are read/write browsers for the underlying stores. The dashboard pulls stats from yb100_pages, yb100_items, and yb100_publish_log.
?view= chooses one of six renderers; ViewToggle is the only thing that touches the URL.
Home and /lists default to Sections; /list/[cat] owns the rich GridMode + ListMode + MagazineMode renderers and stores selection in TweaksProvider (localStorage). Every renderer takes the same AnnotatedItem[] shape.
Four stages, one bucket, one signed-URL boundary at the admin edge.
Generation runs outside the app (Runware via cover:gen). The /admin/s3 console keeps an in-bucket _index.json snapshot. Reference rows live in AIDB.YB100 and yb100_items; the suggestions endpoint diffs them against the bucket. Cover.tsx serves through Vercel's image proxy (avif/webp/resize).
Three crawl surfaces, two metadata layers, two JSON-LD blocks.
Sitemap is dynamic — every push picks up new items via getAllItems(). generateMetadata() per route reads the CMS for OG title/description. /list/[cat] emits ItemList JSON-LD; /item/[cat]/[rank] emits BreadcrumbList.