# 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)