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
-
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.
-
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.
-
Anbefalet MVP (0-1.000 sites): ét Next.js-kodebase på Vercel · Neon (én delt DB,
tenant_id -
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.
-
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).
-
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).
-
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_idoveralt, Row-Level Security. Ikke projekt-pr-tenant (bryder ved ~1.000). RLS medFORCE ROW LEVEL SECURITY,SET LOCAL app.current_tenantpr. request-transaktion (aldrigSET— lækker på tværs af pooled connections), og composite-index medtenant_idsom 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 = '
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, ``
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 defaultnext/image-optimering virker ikke i statisk eksport. Kræver at hver tenants sider er enumérerbare viagenerateStaticParams(). 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:
- Config-drevet rendering (indhold i DB, kode = delt renderer). Uafhængigt af host.
- Data-adgang bag et tyndt lag (repository/query-modul), ikke Vercel-specifikke kald spredt i koden.
- 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.
- Tenant-resolution i standard middleware (Host-header → tenant), ikke bundet til Vercel-interne API'er.
- 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.
- 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.
- 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 udenBYPASSRLS+ 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
- 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.
- Hvornår Vercel → Cloudflare Workers? Bekræft crossover mod egne målte edge-requests/site.
- Enterprise-hybrid: hvilke (få, store) kunder får dedikeret Neon-projekt/isolation frem for delt DB?
- Inngest vs. Graphile Worker til orkestrering (managed + per-step-billing vs. eget/Postgres).
- Domæne-strategi: Vercel-native (MVP) → Cloudflare for SaaS (skala) — hvornår skiftes?
- Relation til doc 06: bekræft de to produktlinjer og hvilke kunder/tilbud hører til hver.
- 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).