synops/docs/retninger/kvalitetsprinsipper.md
vegard 8681c55bc8 Kvalitetsprinsipper: gjør det riktig, én gang
Retningslinje for kode og konfigurasjon. Ti prinsipper:
ikke hardkod det dynamiske, forstå hvorfor noe fungerer,
én mekanisme per problem, konfigurer på lavest nivå,
wildcard over spesifikk, sjekkliste for nye domener,
test med andre øyne, dokumenter beslutninger, preferer
fjerning over tillegg, én fiks ikke to workarounds.

Motivert av ORIGIN-fellen ved multi-subdomain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 02:34:50 +00:00

4.3 KiB

Kvalitetsprinsipper — gjør det riktig, én gang

Motivasjon

Bedre med én komponent som fungerer perfekt enn 200 som fungerer halvveis. Gaffatape-løsninger skaper teknisk gjeld som vokser eksponentielt. Disse prinsippene gjelder all kode og konfigurasjon i Synops.

1. Ikke hardkod det som kan utledes

Hvis verdien kan leses fra konteksten (request, miljø, database), ikke hardkod den i en konfigurasjonsfil.

Feil:

ORIGIN=https://ws.synops.no  # låser hostname
DOMAIN=sidelinja.org         # låser domene
API_URL=https://api.sidelinja.org  # hardkodet URL

Riktig:

AUTH_TRUST_HOST=true  # les hostname fra request
MASKINROMMET_URL=http://127.0.0.1:3100  # intern, hostname-uavhengig

Spørsmålet å stille: "Hvis vi legger til et subdomain eller bytter domene i morgen, hva går i stykker?" Hvis svaret er noe — det er hardkodet og bør utledes dynamisk.

2. Forstå hvorfor noe fungerer

Ikke bare at det fungerer. Når du setter en konfigverdi og ting begynner å virke, forstå mekanismen. Ellers vet du ikke hva som knekker når konteksten endres.

Feil: "Jeg la til ORIGIN og da fungerte det." Riktig: "SvelteKit bruker ORIGIN for å bygge event.url. AUTH_TRUST_HOST=true lar den lese fra Host-headeren i stedet. Vi trenger ORIGIN bare hvis vi ikke stoler på proxyen — men Caddy setter riktig Host."

3. Én mekanisme per problem

Ikke to løsninger som delvis overlapper. Det skaper forvirring om hvilken som faktisk gjør jobben, og konflikter når de ikke er enige.

Feil: CSRF-beskyttelse i SvelteKit og OIDC PKCE+state. Når de konflikter (cross-origin POST) vet du ikke hvilken du skal stole på.

Riktig: OIDC eier CSRF for auth-flyten. SvelteKit sin origin-sjekk deaktiveres eksplisitt med dokumentert begrunnelse.

4. Konfigurer på lavest mulig nivå

Foretrekk infrastruktur-konfig over applikasjons-konfig. Foretrekk konvensjon over konfigurasjon.

Caddy (routing, TLS, domener)
  → SvelteKit (hostname-deteksjon, roller)
    → Komponent (viser riktig innhold)

Ikke la SvelteKit gjøre Caddy sin jobb (ruting). Ikke la komponenter gjøre SvelteKit sin jobb (auth-sjekk).

5. Wildcard over spesifikk der det er trygt

Cookie på .synops.no fremfor ws.synops.no — fordi vi eier alle subdomener. Caddy lytter på alle domener vi konfigurerer. Ikke begrens noe du må utvide senere.

Unntak: sikkerhet. CSRF-token er host-bound (__Host-). Autentisering er domeneovergripende (.synops.no).

6. Sjekkliste for nye subdomener/domener

Før du legger til et nytt domene/subdomain, sjekk:

  • Finnes det en ORIGIN-variabel som hardkoder hostname?
  • Er cookie-domene kompatibelt (.synops.no)?
  • Er OIDC redirect URI registrert i Authentik?
  • Er Caddy-blokken lagt til?
  • Finnes det hardkodede URLer i koden (https://ws.synops.no/...)?
  • Bruker koden event.url.hostname riktig?

7. Test med andre øyne

Etter implementering, tenk: "Hva skjer om..."

  • ...vi legger til et tredje subdomain?
  • ...vi bytter fra synops.no til annet domene?
  • ...en bruker har gammel cache/cookies?
  • ...Caddy restarter med nytt sertifikat?

Hvis svaret er "det går i stykker" — det er hardkodet.

8. Dokumenter beslutninger, ikke bare kode

Ikke bare hva som ble gjort, men hvorfor. Og spesielt: hva vi vurderte og valgte bort. Neste person (eller neste Claude-sesjon) som leser koden trenger å forstå intensjonen, ikke bare mekanismen.

9. Preferer fjerning over tillegg

Hvis du kan løse problemet ved å fjerne kode/konfig i stedet for å legge til, gjør det. Fjerne ORIGIN var bedre enn å legge til ORIGIN-liste med flere domener.

Mindre kode = færre feil = enklere å forstå.

10. Én fiks, ikke to workarounds

Når noe ikke fungerer, finn rotårsaken. Ikke legg på et lag med workarounds som maskerer problemet. To workarounds er verre enn én ufikset bug — fordi de interagerer uforutsigbart.

Feil:

  1. ORIGIN hardkodet → fungerer for ws
  2. adm fungerer ikke → legg til hostname-sjekk i hooks
  3. Cookie fungerer ikke → sett wildcard-domene
  4. CSRF blokkerer → deaktiver CSRF

(Fire endringer for å kompensere for én feilkonfigurert variabel)

Riktig:

  1. Fjern ORIGIN (rotårsaken)
  2. Cookie wildcard (nødvendig for multi-subdomain uansett)
  3. CSRF deaktivering (riktig når OIDC eier auth-flyten)

(Tre endringer, men hver er riktig i seg selv — ikke workarounds)