Gå til indholdet

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 push deployer 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_version pr. 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

  1. Modul-granularitet: hvor små/store skal moduler være? (Ét stort "CRM" vs. flere små.)
  2. Afhængigheder mellem moduler (fx "Tilbud" kræver "Kontakt")? Hvordan håndteres i registret.
  3. Gratis basis-moduler vs. alt-betalt (kobler til prismodel — se forretningsmodel).
  4. 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.)
  5. Fejlet betaling → modul-suspend: entitlements skal kunne reagere på betalingsstatus (se doc 09).

7. Næste skridt

  1. Definér modul-kontrakten (interface) + registrets skema som del af Website OS-datamodellen.
  2. Byg modules + tenant_modules med RLS.
  3. Byg admin-katalogets "tilkøb modul"-flow oven på entitlements.
  4. Koordinér billing_sku med billing-motoren (doc 09).

Udarbejdet 2026-07-18 som diskussionsoplæg. Beslutninger fanges som ADR i adr/ når truffet.