Gå til indholdet

07 — Website OS: multi-tenant arkitektur (beslutningsgrundlag)

Formål: Svar på den vedhæftede "Architecture Research Brief: AI-First Multi-Tenant Website Platform". Briefen beskriver en delt multi-tenant "Website OS" — ét kodebase der server tusindvis af små kunde-websites — hvor 1-2 mennesker + AI-agenter driver det hele. Dette dokument validerer briefens antagelser, udfordrer dem hvor nødvendigt, og leverer en MVP- + skala-arkitektur.

Vigtigt — læs sammen med 06-isolation-hosting-og-overdragelse.md. Doc 06 og dette dokument beskriver to forskellige produktlinjer med to modsatte arkitekturer. Det er ikke en modsigelse — det er den centrale indsigt (se §2).

Bygger på webresearch juli 2026 (priser/kapabiliteter verificeret mod leverandørernes egne sider 2026-07-18). Feltet skifter hurtigt — verificér før endelige beslutninger. USD ≈ 7 DKK.


1. TL;DR

  1. Briefens kerneprincip er RIGTIGT: byg en delt "Website OS", ikke tusindvis af kodebaser. 90-95 % delt platform + 5-10 % tenant-config er præcis vejen til dine fire mål (1-2 mennesker → tusindvis af sites, minimal drift, nem skalering, central modul-opdatering → alle kunder på én gang). Dette er en ægte multi-tenant SaaS, ikke et bureau.

  2. Denne model er det STIK MODSATTE af doc 06's "container/miljø pr. kunde". Og det skal den være. Doc 06 handler om skræddersyede SaaS-leverancer man skal kunne sælge/overdrage som kode. Website OS handler om volumen: samme kode for alle, opdatér ét sted → virker for alle. Du kan ikke få begge egenskaber i samme system — se §2. De er to produktlinjer.

  3. Anbefalet MVP (0-1.000 sites): ét Next.js-kodebase på Vercel · Neon (én delt DB, tenant_id

  4. Row-Level Security) · Payload CMS som admin-shell med eget block-JSON som kanonisk model · Inngest til durable agent-workflows + human-approval · agenter via AI SDK 6 / Mastra (Claude Sonnet som arbejdshest). Kundedomæner: Vercel-native (gratis, ubegrænset) ved start.

  5. Anbefalet skala (≈10k+ sites): migrér hosting til Cloudflare Workers (én delt Worker) + Cloudflare for SaaS (kunde-hostnames, delegated DCV) + Neon. Omkostningsmodellen viser 60 %+ besparelse her (infra falder fra ~$5.600 til ~$2.230/md ved 10k). Migration er billig hvis du bygger Workers-kompatibelt fra dag ét (§10).

  6. Central modul-deploy til 200+ kunder (dit fjerde fokuspunkt) løses af arkitekturen, ikke af værktøj: rendering skal være config-drevet (indhold/struktur som data i DB, kode som delt komponent-bibliotek). Så er "nyt contact-modul til alle" = ét git-push + en feature-flag. Faldgruben ("én ændring brækker alle") styres med versionerede moduler + feature-flags + canary/QA-gate (§7, §8).

  7. Portabilitet ændrer form: i en delt platform kan du ikke udlevere "koden". Du udleverer domæne + data-eksport + statisk HTML-eksport — præcis som briefen foreslår (§9). Det er en anden overdragelse end doc 06's "flyt containeren", og briefens model er korrekt.


2. Den centrale reconciliation: to produktlinjer, to arkitekturer

Dette er det vigtigste afsnit. Doc 06 anbefalede isoleret miljø/container pr. kunde (for at kunne skalere, domæne-tilknytte og sælge koden videre). Denne brief anbefaler én delt multi-tenant platform. De ser modstridende ud. De er det ikke — de tjener to forskellige produkter:

Doc 06 — Isoleret pr. kunde Doc 07 — Delt Website OS (denne)
Produkt Skræddersyet SaaS/app til nichekunde Website-produkt i volumen (CVR/SMV-sites)
Kode pr. kunde Egen container/deployment Én delt kodebase for alle
Antal kunder Få–snese Hundrede–hundredtusinder
"Nyt modul til alle 200" Redeploy 200 containere (tungt) Ét git-push → alle får det
Overdragelse Flyt container + IaC + DB (kunden ejer alt) Domæne + data-eksport + statisk site (kunden ejer sit, ikke platformen)
Drift pr. kunde Lav, men ×N Nær-nul marginal (delt)
Isolation Hård (fysisk) Logisk (row-level, RLS)

Hvorfor Website OS SKAL være delt multi-tenant (og dermed hvorfor doc 06's model er forkert her): dine fire fokuspunkter peger alle samme vej. "1-2 mennesker bygger tusindvis", "minimal drift", "nem skalering" og især "udvikl contact-modul centralt → deploy til 200+ kunder" er definitionen på delt multi-tenancy. Med container-pr-kunde ville central modul-opdatering betyde 200 redeploys, 200 miljøer at overvåge, 200 databaser at migrere — det modsatte af "nemt for 2 personer".

Konsekvens: brug doc 06-modellen til de skræddersyede niche-SaaS-leverancer (hvor "sælg koden" er et krav), og doc 07-modellen (denne) til website-fabrikken. CVR-produktet (../produkter/cvr-leads-hjemmesider/) er den første konkrete instans af Website OS.


3. Validering af briefens antagelser (svar på briefens punkt A)

# Antagelse i briefen Dom Begrundelse
1 Delt platform-kode + tenant-config frem for kodebase-pr-kunde VALID Kernen i det hele; eneste vej til dine 4 mål.
2 Ingen AI-genereret vilkårlig kunde-kode (kun struktureret config/indhold) VALID Forhindrer "1.000 subtilt forskellige kodebaser". Agenter genererer data, ikke app-kode.
3 Vercel + Neon + Cloudflare til MVP VALID MED FORBEHOLD Se §4. Cloudflare-for-SaaS foran Vercel er akavet (Vercel fraråder reverse proxy) — brug Vercel-native domæner ved MVP; CF for SaaS bliver relevant ved Workers-migration/scale.
4 "Vercel Postgres = nu Neon via marketplace" VALID Bekræftet; Vercel og Neon er komplementære, ikke konkurrenter.
5 Neon (Postgres) som primær system-of-record, ikke Convex VALID Data er stærkt relationel; Postgres = portabilitet + moden RLS. Convex' reaktivitet retfærdiggør ikke to datasystemer (se §6).
6 Convex evt. til realtids-/agent-dashboard VALID MED FORBEHOLD Kun hvis du får et tungt realtids-agent-kontrollag. Start uden; undgå to datasystemer tidligt.
7 (Implicit) tenant-isolation via Postgres QUESTIONABLE hvis projekt/DB-pr-tenant Neon-projekt-pr-tenant BRYDER ved ~1.000 (hårdt projektloft på Scale). Ved 10k-100k SKAL det være én delt DB + tenant_id + RLS. Se §8.
8 Cloudflare Workers + Neon som langsigtet konsolidering VALID Omkostningsmodellen bekræfter 60 %+ besparelse ved ≥10k sites (§11).
9 Struktureret indhold → renderer → live + statisk eksport VALID MED FORBEHOLD Korrekt mønster, men Next.js output: export kan ikke ISR/server actions; kræver delt renderer + generateStaticParams + "anti-divergens"-regel (§9).
10 Ikke automatisk PHP/full-app-eksport; kun statisk + data VALID Full-app-eksport = at vedligeholde en anden platform. WordPress-migration som betalt service er rigtigt.
11 AWS/Azure nedprioriteret til MVP (drift-kompleksitet) VALID Enig; optimér for operationel gearing først. Se §6 + doc 06 §11.
12 Netlify som troværdigt Vercel-alternativ VALID Men Vercel mere naturlig for Next.js + AI-økosystem.
13 Agenter uden fri produktionsadgang; propose→preview→QA→gate→deploy VALID Industri-konsensus 2026. Konkret model i §7.

4. Anbefalet MVP-arkitektur — 0-1.000 sites (svar på punkt B)

Prioriteret efter: fart-til-marked, lav driftskompleksitet, AI-integration, sikkerhed, portabilitet.

Kunde-domæner (kunde.dk) │ Vercel-native custom domains (gratis, ubegrænset) │ ┌─────────────────────────────┐ │ ÉT delt Next.js-kodebase │ middleware: Host → tenant-resolution (cachet) │ på Vercel │ config-drevet <BlockRenderer/> │ ISR + on-demand revalidation│ └─────────────────────────────┘ │ ┌────────────────────┼─────────────────────┐ │ │ │ Payload CMS Neon Postgres Inngest (admin-shell) (én delt DB) (durable agent-workflows eget block-JSON tenant_id + RLS + human-approval gate = kanonisk model pgvector (RAG) + provider-rate-limits) │ Agenter: AI SDK 6 / Mastra (Claude Sonnet)

Komponentvalg og hvorfor:

  • Hosting: Vercel. Lavest friktion for Next.js multi-tenant: wildcard + custom domains, ISR og deploy-propagering ud af boksen. Byg dog Workers-kompatibelt fra dag ét (§10).
  • Data: Neon, én delt database, shared schema, tenant_id overalt, Row-Level Security. Ikke projekt-pr-tenant (bryder ved ~1.000). RLS med FORCE ROW LEVEL SECURITY, SET LOCAL app.current_tenant pr. request-transaktion (aldrig SET — lækker på tværs af pooled connections), og composite-index med tenant_id som ledende kolonne (uden det er RLS ~2 størrelsesordener langsommere; med det kun ~2-6 % overhead). pgvector til RAG i samme DB.
  • CMS/indhold: Payload CMS (MIT, Next.js-native) som operationel shell — men eget block-JSON som kanonisk, portabel model, renderet gennem eget delt komponent-bibliotek. Payload giver admin-UI, versionering, kladder, autosave og en officiel multi-tenant-plugin gratis, så I ikke bygger det selv. Men I ejer render-/eksport-motoren (afgørende for portabilitet). Forbehold: Payload blev opkøbt af Figma (2025) — licensen er MIT og sikker i dag, men følg roadmap; approval-workflows er en Enterprise-feature (byg selv som state-maskine hvis nødvendigt).
  • Agent-orkestrering: Inngest som samlet durable-workflow + kø + human-approval-lag. step.run() gør hvert LLM/billede-kald til en durable, retry-bar enhed; step.waitForEvent() suspenderer pipelinen ved nul compute til en godkendelse ankommer. Ingen infrastruktur at drive. (Alternativ hvis I vil eje data / undgå per-step-billing: Graphile Worker på jeres egen Postgres — men så bygger I selv approval-gaten.)
  • Agenter: AI SDK 6 (GA) + Mastra (TS-native; Mastra bygger selv oven på Inngest). Claude Sonnet som arbejdshest, Opus kun til reasoning-tunge trin, Batch API + prompt caching til site-builds.
  • Domæner ved MVP: Vercel-native (gratis, ubegrænset). Standardisér onboarding på www + CNAME; håndtér apex/bar-domæne som undtagelse (CNAME kan ikke ligge på apex → A-record).
  • Ændringshåndtering: agent → branch → PR → preview-deploy → automatiseret QA → risiko-gate → deploy. Se §7.

MVP-omkostning: ~$35/md (100 sites) → ~$540/md (1.000 sites) infra, + ~$5/site engangs AI-build (§11).


5. Anbefalet skala-arkitektur — 1.000-100.000 sites (svar på punkt C)

Udviklingen sker i klart afgrænsede spring, ikke som omskrivning:

≈1.000-3.000 sites — planlæg migration. Vercels edge-request-meter begynder at dominere regningen. Besparelsen ved Workers er $200-800/md og voksende — begynd at flytte Workers-inkompatible mønstre nu.

≈10.000 sites — migrér hosting til Cloudflare. Skift: Kunde-domæner ──▶ Cloudflare for SaaS (custom hostnames, delegated DCV, auto-SSL) │ Én delt Cloudflare Worker (Next.js via OpenNext) ← hostname → tenant │ Neon Postgres (delt DB + RLS; partitionér på tenant_id) - Cloudflare for SaaS løser tusindvis af kunde-ejede domæner: 100 gratis, derefter $0,10/hostname/md, kunden beholder sin egen DNS, delegated DCV = sæt-og-glem cert-fornyelse, fuldt API-/Terraform-styrbart. Hårdt loft på 50.000 hostnames pr. konto → Enterprise (eller multi-zone) derover. - Én delt Worker (ikke Workers for Platforms — det er kun til kunde-medbragt kode; du har ét delt kodebase, så $5-Workers-Paid-planen rækker). - Data uændret: samme delte Neon-DB + RLS. Dediker kun et separat Neon-projekt til de få enterprise-kunder der betaler for fysisk isolation (hybrid). - Rendering ved skala: du kan ikke statisk bygge 100k sider ved deploy. ISR + on-demand, tag-baseret revalidation (revalidateTag('tenant:123')) er obligatorisk, ikke valgfrit. Byg ~0 sider ved deploy; generér on-demand ved første besøg. På Cloudflare styrer du selv ISR-cache-backend (OpenNext) — reelt driftsarbejde du overtager fra Vercel.

≈100.000 sites. Infra ~$20.400/md på Workers-stakken (mod ~$55.000 listepris på Vercel). Her dominerer Neon-compute + domæne-linjen (~$10k + ~$10k), ikke længere compute — så optimeringsindsatsen flytter til Neon-pooling/scale-to-zero og domæne-pooling/Enterprise-forhandling.

Hvornår skift retfærdiggøres: knyttet til edge-requests, ikke sites — crossover ved ca. 500-1.000 aktive sites; migrér decisivt ved ~10k (60 %+ besparelse). Under ~1.000 sites: bliv på Vercel (forskellen er < $200/md og opvejer ikke migrations-/DX-omkostningen).


6. Teknologi-beslutningsmatrix (svar på punkt D)

Vurdering i multi-tenant Website OS-kontekst (1 = svag, 5 = stærk).

Rolle Pris v. skala Skalerbarhed Lock-in DX AI-integration Multi-tenancy Custom domæner Portabilitet Drift
Vercel App-host (MVP) 2 4 3 5 5 4 4 (native, gratis) 4 5
Netlify App-host (alt.) 3 4 3 4 4 3 4 4 4
Cloudflare App-host (skala) + domæner/SSL/CDN/WAF 5 5 3 3 4 4 5 (for SaaS) 3 (Workers-runtime) 3
Neon Primær DB (system-of-record) 4 4 5 (std. Postgres) 4 4 (pgvector, MCP) 4 (RLS) 5 (pg_dump) 4
Convex (Valgfrit) realtids-/agent-lag 3 4 2 4 5 3 3 4
AWS (Senere/enterprise) 4 5 2 2 3 4 4 3 2
Azure (Microsoft-/enterprise-kunder) 3 5 2 3 4 4 4 3 2

Konklusioner: Vercel + Neon til MVP (DX + AI + portabilitet), Cloudflare + Neon ved skala (pris + domæner + edge). Convex kun hvis et tungt realtids-agent-kontrollag opstår — ikke som primær DB (svarer på briefens eksplicitte Convex-spørgsmål: merværdien retfærdiggør ikke to datasystemer + synk-kompleksitet tidligt). AWS/Azure reserveret til enterprise/compliance (og til doc 06's isolerede leverancer), ikke website-fabrikken.


7. AI-agent-arkitektur (svar på punkt E)

Onboarding-pipelinen (research → SEO → builder → indhold → billeder → QA → godkendelse → deploy) er en lærebogs-durable workflow med en wait-gate:

  • Orkestrering: Inngest. Hvert trin = step.run() (durable, retry pr. trin med backoff). Godkendelse = step.waitForEvent("site/approved", { timeout: "7d" }) — pipelinen suspenderer ved nul compute til et godkendelses-event ankommer fra dit dashboard. Provider-rate-limits håndteres med Inngests throttling (non-lossy kø, fx OpenAI/billede-API'er) og account-scoped concurrency.
  • Event/kø-lag: Inngest ér køen ved MVP (ingen separat produkt nødvendigt — jobmængden er tusindvis, ikke tusindvis/sek). Ved høj fan-out (billedgenerering på tværs af tusindvis af sider) tilføj Cloudflare Queues (5k msg/s) med Workers.
  • Agent-memory/RAG: pgvector i den delte Neon-DB — ét datasystem, tenant-scoped via RLS.
  • Permission-model: agenter har ingen produktionscredentials. Read-only default; scoped writes til bestemte tabeller; høj-risiko kræver human-godkendelse. Agent = "en untrusted bidragyder med kraftige værktøjer" → samme branch-protection/PR/preview-gates som menneskekode.
  • Risiko-gradueret godkendelse (konkret): en PR/ændring auto-kvalificerer som low-risk kun hvis ALLE: < ~1.000 ændrede linjer · ingen DB-migration · ingen infra/CI-ændring · ingen authN/authZ-ændring · ingen ændring af audit/logging · (for os) rammer < X tenants. Forfatteren må ikke selv-klassificere — et automatisk system vurderer, og et menneske klikker altid merge ved medium/high. Encode reglerne som et GitHub Actions-check først; OPA/Rego kun hvis policy vokser.
  • Automatiseret QA-gate (mod preview-URL'en): Playwright visuel-regression + Lighthouse CI (perf/SEO) + axe (a11y) + link-/console-fejl-crawl + LLM-as-judge til indholdskvalitet. Ved tusindvis af sites: gate på templates/komponenter, ikke hvert renderet site, + per-site smoke-checks.
  • Audit/trace: git-historik + Vercels immutable deployments giver meget gratis; læg et append-only (hash-chained) agent-handlings-event-log ovenpå til godkendelser/deploys/rollbacks + "authority lineage" (hvem autoriserede agenten). EU AI Act art. 12 kræver ≥6 mdrs. log-retention for høj-risiko-systemer.
  • Rollback: Vercel Instant Rollback (~1 sek, routing-lag) + indholds-versionering i DB + feature-flag kill-switch = tre uafhængige rollback-håndtag.
  • Idempotens: kør agent-handlinger gennem Inngest med deterministiske idempotens-nøgler (run-id + trin, eller indholds-hash) — aldrig genereret i udførelsesøjeblikket.

8. Data-arkitektur & multi-tenancy (svar på punkt F)

Tenant-model: shared database + shared schema + tenant_id + Row-Level Security. De tre mønstre og hvorfor dette vinder:

Mønster Isolation Bryder sammen ved Egnet?
Shared DB + tenant_id + RLS Logisk (row) Skalerer længst (mio. rækker) ✅ Standard
Schema-per-tenant Namespace ~1.000-2.000 schemas (migrations, catalog-bloat) ❌ ved skala
DB/projekt-per-tenant Fysisk Neon-loft ~1.000; drift ×N for 2 personer ❌ (kun enterprise-hybrid)

RLS-implementering (sikker + skalerbar): ```sql -- pr. request (transaktion): BEGIN; SET LOCAL app.current_tenant = ''; / ...queries... / COMMIT;

CREATE POLICY tenant_isolation ON contacts USING (tenant_id = current_setting('app.current_tenant')::uuid); ALTER TABLE contacts FORCE ROW LEVEL SECURITY; -- gælder også table-owner CREATE INDEX ON contacts (tenant_id, ); -- kritisk for performance `` App-rollen må **aldrig** haveBYPASSRLSeller være superuser. Neons pooler kører transaction-mode (op til 10.000 pooled connections/projekt) — kompatibel medSET LOCAL`.

Modul-model (dit fjerde fokuspunkt): moduler er config, ikke kode-forks. En tenant_modules-tabel (feature-flags) styrer hvad der renderes. Et nyt "contact-management-modul" = ny komponent i det delte bibliotek + ny block-type i config-skemaet → ét git-push deployer til alle, og tenants der har modulet slået til begynder at rendere det. Faldgruber og modtræk: - "Én ændring brækker N tenants" → canary/preview + smoke-tests mod repræsentativt tenant-udsnit før promotion; feature-flags til gradvis udrulning (1 %→10 %→100 %), ikke big-bang. - Breaking modul-ændringer → versionér modul-schemaet; gør ændringer additive/bagudkompatible; gem module_version i tenant-config. - Config-drift → validér tenant-config mod et schema (Zod) ved render med graceful fallback.

Indholds-model: kanonisk block-JSON (fx {page, sections:[{type, ...}]}) i Postgres, versioneret (immutable version-rækker + published-pointer + draft), godkendelses-state-maskine.

Backup/restore: Neon point-in-time + regelmæssig pg_dump. Per-kunde-eksport (se §9) bygges som RLS-filtreret job, ikke rå pg_dump (der ville lække alle tenants).


9. Portabilitet & eksport (svar på punkt G)

Briefens model — struktureret indhold → renderer → live-site + statisk eksport — er valid, med én kritisk regel og nogle grænser:

  • Anti-divergens-reglen (den vigtigste): hold én kanonisk struktureret model (block-JSON) og ét delt render-lag (samme React-komponenter, block-type → komponent). Både live-SSR og statisk eksport importerer samme renderer; kun data-kanten adskiller sig (live DB-query vs. build-time-fetch). Fork aldrig rendereren pr. mål — det er den klassiske kilde til at live og eksport driver fra hinanden.
  • Statisk eksport (Next.js output: 'export'): producerer én HTML-fil pr. route ved build → kan hostes hvor som helst (Cloudflare Pages, S3, GitHub Pages, alm. webhotel). Grænser: ISR, server actions, request-tid-features og default next/image-optimering virker ikke i statisk eksport. Kræver at hver tenants sider er enumérerbare via generateStaticParams(). Payloads Local API er ideel her (læs indhold in-process i både SSR og eksport-build uden HTTP-hop).
  • Data-eksport pr. kunde (delt DB): byg "Download alle mine data" ind i produktet fra dag 1 — RLS-filtreret job der pakker CSV/JSON pr. tabel (pages, news, SEO, leads, contacts, bookings). Dette er både GDPR-dataportabilitet og en salgsfordel. Bevidst trade-off: med shared schema får du ikke en ren pg_dump-per-kunde gratis — eksport bliver applikations-ansvar. Det er prisen for at kunne drive tusindvis billigt.
  • Kommerciel positionering: "Du ejer dit indhold, dine data og dit domæne. Vi driver teknologien." Kunden ejer domæne/indhold/media/kundedata/SEO-værdi; platformen ejer CMS-motor, komponent-framework, AI-/automations-motorer. Ved opsigelse: domæne beholdes, indhold/data/statisk site eksporteres, SaaS-funktioner stopper. Kræver juridisk validering før kontraktlige ejerskabs-påstande.
  • Ikke PHP-eksport: korrekt fravalgt — der er ingen naturlig 1:1 fra Next.js/Neon/agenter til index.php. WordPress-migration som betalt service (delvist AI-automatiseret) er den rigtige model.

10. Migration Vercel → Cloudflare Workers uden omskrivning (svar på punkt H)

Målet: kunne skifte hosting-lag ved ~10k sites uden platform-rewrite. Abstraktioner der SKAL findes fra dag ét:

  1. Config-drevet rendering (indhold i DB, kode = delt renderer). Uafhængigt af host.
  2. Data-adgang bag et tyndt lag (repository/query-modul), ikke Vercel-specifikke kald spredt i koden.
  3. Undgå Vercel-only-primitiver som bærende: Vercel KV, Blob, Edge Config og Vercel-specifikke middleware-/ISR-tricks. Brug portable ækvivalenter, eller wrap dem bag et interface.
  4. Tenant-resolution i standard middleware (Host-header → tenant), ikke bundet til Vercel-interne API'er.
  5. ISR-cache bag et interface — på Vercel er den håndteret; på Workers/OpenNext vælger du selv backend (R2 + regional cache). Hold cache-invalidering tag-baseret og host-agnostisk.
  6. Domæne-styring via API/Terraform — så skift fra Vercel-native domæner til Cloudflare for SaaS er en provider-udskiftning i ét modul, ikke en omskrivning.
  7. Deploy/CI portabelt (GitHub Actions), ikke Vercel-only build-hooks.

Med disse er migration = skift hosting-adapter (Next.js → OpenNext på Workers), flyt domæne-laget til CF for SaaS, peg samme Neon-DB. Ingen ændring i data-model, indholds-model, agent-lag eller renderer.


11. Omkostningsmodel ved skala (briefens eksplicitte krav)

Model, ikke tilbud. Antagelser pr. lav-trafik SMV-site: ~3.000 besøg/md, ~100.000 edge-requests/md, ~1 GB transfer/md, delt Neon-DB. Den mest følsomme antagelse er edge-requests/site (±2-3× ændrer hele Vercel-billedet — mål på 5-10 rigtige sites).

Skala Stak 1: Vercel $/md $/tenant Stak 2: Cloudflare Workers $/md $/tenant AI-build (engangs)
100 ~$35 $0,35 ~$20 $0,20 ~$500
1.000 ~$540 $0,54 ~$345 $0,35 ~$5.000
10.000 ~$5.600 $0,56 ~$2.230 $0,22 ~$50.000
100.000 ~$55.000 (listepris) $0,55 ~$20.400 $0,20 (pr. nye sites)

Dominerende omkostning: På Vercel-stakken dominerer edge-requests + data transfer fra ~1.000 sites (60-70 % ved skala). På Workers-stakken er compute nær-gratis, så Neon-compute + domæner ($0,10/site) bliver co-dominerende ved skala. I opbygningsfaser dominerer AI-tokens likviditeten (fx $50k for 10k builds). Amortiseret over en sites levetid (~2-3 år) er AI-build ~$0,15-0,25/site/md — samme størrelsesorden som infra pr. tenant. Enhedsøkonomien er sund: infra ~$0,2-0,6/site/md giver enorm margin mod selv en lav abonnementspris (jf. markedsanalysen: konkurrenter 89-695 kr/md).

Migrations-signal: ~500-1.000 sites → planlæg; ~10.000 → migrér (60 %+ / $3.000+/md besparelse).


12. Risici & blinde vinkler (svar på punkt I)

  • RLS er et enkelt-punkts-svigt for isolation. Én forkert policy/manglende SET LOCAL = cross-tenant datalæk. Modtræk: FORCE RLS + app-rolle uden BYPASSRLS + automatiserede isolations-tests (forsøg cross-tenant-read i CI) + code-review-gate på alt der rører data-laget.
  • "Én deploy brækker alle tenants." Delt kode = delt blast-radius. Modtræk: canary + smoke-tests mod tenant-udsnit + feature-flags + instant rollback (§7). Dette er den største operationelle risiko ved modellen.
  • Payload/Figma strategisk risiko. Motoren I læner jer op ad kan ændre retning. Modtræk: hold block-JSON som jeres kanoniske model + egen renderer → Payload er udskifteligt (admin-shell), ikke fundamentet.
  • Neon-projektloft + delt-DB-compute er de blødeste tal. Verificér limit-forhøjelse for enterprise-hybrid; lasttest delt-DB-compute (den kan blive dyrere end modelleret).
  • DNS-apex-friktion. Kunder der vil bruge bar-domæne (uden www) kan ikke bruge CNAME → A-record eller nameserver-skift. Standardisér på www + CNAME; apex som undtagelse.
  • GDPR/compliance (EU-kunder, persondata). DPA'er med kunder, subprocessor-liste (hver AI-udbyder er en subprocessor!), data-residency (EU-hosting — Neon/Vercel EU-region), right-to-deletion (RLS-scoped sletning), AI-udbyderes databehandling. Jf. doc 06 §K8 + interne-systemer. Kræver rådgiver.
  • SEO ved tusindvis af sites: risiko for "thin content"/duplicate-content-straf hvis AI genererer for ensartet. Modtræk: reel lokal/branche-differentiering (matcher markedsanalysens pointe om GBP + lokal SEO).
  • Misbrug/abuse: delt platform → én kundes spam/malware kan ramme delte IP'er/omdømme. WAF + rate-limiting
  • indholds-scanning.
  • Billing/provisionering: Stripe (abonnement + moduler + usage), failed-payment-håndtering, automatisk de-provisionering. Ikke i denne brief — hører sammen med interne-systemer.md.
  • Support-load ved skala: tusindvis af SMV'er = supporthenvendelser. Support-agent + selvbetjening er en forudsætning, ikke en luksus, for "1-2 mennesker"-målet.
  • Manglende i briefen: billing-arkitektur, support-model, abuse-håndtering, SEO-differentierings-strategi, og en eksplicit enhedsøkonomi pr. plan (pris vs. infra+AI+support pr. site).

13. Åbne spørgsmål → afgøres som ADR

  1. Payload CMS vs. fuldt eget content-lag? Payload = fart nu (accepter Figma-risiko); eget = fuld kontrol, mere at bygge. Anbefaling: Payload som shell + eget block-JSON.
  2. Hvornår Vercel → Cloudflare Workers? Bekræft crossover mod egne målte edge-requests/site.
  3. Enterprise-hybrid: hvilke (få, store) kunder får dedikeret Neon-projekt/isolation frem for delt DB?
  4. Inngest vs. Graphile Worker til orkestrering (managed + per-step-billing vs. eget/Postgres).
  5. Domæne-strategi: Vercel-native (MVP) → Cloudflare for SaaS (skala) — hvornår skiftes?
  6. Relation til doc 06: bekræft de to produktlinjer og hvilke kunder/tilbud hører til hver.
  7. Enhedsøkonomi pr. abonnement: fastlæg pris vs. infra+AI+support pr. site før lancering.

Når truffet: fang som ADR i adr/ (fx ADR-0002 — Website OS platform-stak og ADR-0003 — Multi-tenant data-isolation).


Kilder

Verificeret mod leverandørernes egne sider 2026-07-18; enkelte tal fra sekundære kilder er markeret i teksten.

Hosting & multi-tenant: - Vercel — pricing · Multi-tenant limits · Next.js multi-tenant guide · Platforms Starter Kit - Cloudflare for SaaS — plans · Delegated DCV · Custom origin · Cloudflare in front of Vercel? - Cloudflare Workers — pricing · Workers for Platforms pricing · Next.js on Vercel vs Cloudflare - Next.js — static exports

Data & multi-tenancy: - Neon — pricing · Neon — plans/limits · Postgres-kompatibel eksport - PlanetScale — tenancy in Postgres · AWS — RLS multi-tenant · Azure/Citus — SaaS-design

CMS/indhold: - Payload CMS · Payload multi-tenant plugin · Payload versions · Payload joins Figma

Agent-orkestrering, sikkerhed & ændringshåndtering: - Inngest — wait-for-event · concurrency · throttling · pricing · idempotency - Vercel Workflows · AI SDK 6 · Mastra · Cloudflare Workflows GA · Temporal pricing - Vercel — instant rollback · managing deployments · Ona — auto-approving low-risk PRs · Port.io — HITL for coding agents · OPA docs - Cloudflare Queues — limits · Graphile Worker — scaling

AI-priser: - Claude API — pricing


Udarbejdet 2026-07-18 fra parallel webresearch + den vedhæftede research-brief. Beslutninger fanges som ADR i adr/ når truffet. Læs sammen med 06-isolation-hosting-og-overdragelse.md (den anden produktlinje).