08 — Modul-system: central styring af moduler
Status: DISKUSSIONSOPLÆG — til fælles gennemgang. Ingen beslutning truffet.
Hvor det hører til (lag): delsystem under Website OS (
07-website-os-multi-tenant-arkitektur.md). Dette dokument dækker hvordan moduler bygges, styres og udrulles centralt. Selve faktureringen af tilkøbte moduler er et særskilt dokument:09-billing-og-betaling.md(de to holdes adskilt, så de kan opdateres uafhængigt).Bygger på Website OS-arkitekturen (multi-tenant, config-drevet rendering, RLS).
1. Udfordringen
Moduler (fx "Kontakt", "Tilbud", "Booking", "Nyhedsbrev") skal være ét centralt software-/service-modul: core-koden styres ét sted, så vi kan opdatere, opgradere og gøre nye moduler tilgængelige for alle kunder fra et centralt sted — uden at vedligeholde kunde-specifikke kodebaser.
2. Princip: delt kode + entitlements, aldrig forks
Alt bygger på Website OS-princippet: én delt kodebase + config-drevet rendering + entitlements pr. tenant. Et modul er delt kode; hvilke moduler en kunde har, er data. Så bliver "udvikl ét sted → virk for alle" en egenskab ved arkitekturen, ikke en manuel proces.
3. Byggeklodser
- Et modul = en versioneret pakke i monorepoet. Hver modul-mappe indeholder alt sit: komponenter, DB-skema/migrationer (namespacede tabeller), config-schema (Zod), admin-UI, og pris-/SKU-metadata (bruges af billing — se doc 09).
- Modul-register (det "ene sted"): et centralt manifest — kode + en
modules-tabel i den delte Neon-DB — der lister hvert tilgængeligt modul:key, navn,version,price,billing_sku, afhængigheder,status(beta / GA / udfaset). Her styres hvad der overhovedet findes. - Entitlements pr. kunde:
tenant_modules(tenant_id,module_key,enabled,version,activated_at). Én række = ét aktivt modul for én tenant. Det er feature-flag-laget. - Modul-kontrakt: hvert modul implementerer samme interface (fx
register(),schema,components,adminPanel,migrations,billingSku) → det gør dem plug-bare og centralt styrbare.
sql
-- centralt register (hvad findes)
modules(key PK, name, version, price_dkk, billing_sku, status, depends_on[])
-- entitlements (hvem har hvad)
tenant_modules(tenant_id, module_key, enabled, version, activated_at,
PRIMARY KEY (tenant_id, module_key))
-- RLS som i doc 07: tenant_id + FORCE ROW LEVEL SECURITY
4. Livscyklus — hvordan "ét sted → alle kunder" virker
- Nyt modul tilgængeligt for alle: tilføj pakken + registrér i
modules→ modulet dukker automatisk op i hver kundes "tilkøb modul"-katalog. Ingen udrulning pr. kunde. - Opdatér/opgradér: ét
git pushdeployer ny modul-kode til alle tenants på én gang (config-drevet rendering). De der har modulet slået til, får opdateringen straks. - Sikkerhed mod "én ændring brækker alle": versionerede moduler + additive/bagudkompatible ændringer +
module_versionpr. tenant + feature-flag canary (1 %→10 %→100 %) + automatiseret QA-gate på preview + instant rollback + kill-switch pr. modul. - AI-vinkel: fordi moduler er deklarative pakker med en fast kontrakt, kan en AI-agent skabe et nyt modul fra en skabelon → central review → publicér til registret.
5. Grænsefladen til billing (kobling til doc 09)
tenant_modules er den fælles kilde til sandhed mellem modul-system og billing. Når en kunde til-/fravælger
et modul i admin, gør ét toggle to ting samtidig:
1. flipper feature-flaggen → modulet virker/forsvinder for den tenant (dette dokument), og
2. udsender et billing-event → tilføj/fjern abonnementslinje (09-billing-og-betaling.md).
Registret leverer billing_sku + pris, så modul og faktura altid matcher.
6. Åbne spørgsmål — til diskussion
- Modul-granularitet: hvor små/store skal moduler være? (Ét stort "CRM" vs. flere små.)
- Afhængigheder mellem moduler (fx "Tilbud" kræver "Kontakt")? Hvordan håndteres i registret.
- Gratis basis-moduler vs. alt-betalt (kobler til prismodel — se forretningsmodel).
- Data ved fravalg: når et modul slås fra, hvad sker der med dets data? (Bevar/eksportér/slet — kobler til GDPR + overdragelse i doc 07.)
- Fejlet betaling → modul-suspend: entitlements skal kunne reagere på betalingsstatus (se doc 09).
7. Næste skridt
- Definér modul-kontrakten (interface) + registrets skema som del af Website OS-datamodellen.
- Byg
modules+tenant_modulesmed RLS. - Byg admin-katalogets "tilkøb modul"-flow oven på entitlements.
- Koordinér
billing_skumed billing-motoren (doc 09).
Udarbejdet 2026-07-18 som diskussionsoplæg. Beslutninger fanges som ADR i adr/ når truffet.