- services/plattform/openapi.yaml dokumenterar hela ytan: auth (registrera organisation, logga in), användarhantering (admin), ärenden + append-only händelselogg (idempotent synk), arbetsledar- översikten, publik Live Share-delning och AI-orkestern — inklusive scheman för alla 15 händelsetyper, roller, JWT-anspråken och API:ts bärande principer (append-only, multi-tenant-404). - Specen serveras live av plattformstjänsten på GET /api/openapi.yaml och följer med i containern. - Verifierad i tre lager: maskinell validering (swagger-cli), paritetstest i vitest (varje dokumenterad väg finns i servern, händelsetyperna är kompletta) och integrationsteststeg som hämtar specen från den körande tjänsten. Verifierat: integrationstestets 18 kontroller gröna mot Postgres 16, 29 vitest-tester gröna, produktionsbygge ok. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
5.3 KiB
Guidad Felsökning – Drift i Kubernetes (helt självhostat)
Målarkitekturen ur Master Prompt som kod: hela stacken körbar i eget kluster — webb, AI-orkester, plattformsbackend (auth + händelse-API + Live Share) och Postgres. Inga externa tjänstberoenden utöver Anthropic-API:et för AI-anropen.
Arkitektur
flowchart LR
T[Tekniker] -->|HTTPS| I[Ingress + TLS]
T2[Kund via delningslänk] -->|HTTPS| I
I -->|/| W[web\n2–10 pods, HPA]
I -->|/api/ai| A[ai-orkester\n2–10 pods, HPA]
I -->|/api, /halsa| P[plattform\n2–10 pods, HPA]
A -->|Claude API| C[(Anthropic)]
P --> DB[(Postgres\nStatefulSet + PVC)]
K[Secret: felsokning-hemligheter] --> A & P & DB
| Komponent | Vad | Var |
|---|---|---|
web |
SPA:n bakom oprivilegierad nginx (Dockerfile, docker/nginx.conf) |
Deployment + Service + HPA + PDB |
plattform |
Självhostad backend (services/plattform): multi-tenant — registrering skapar organisation + systemadministratör, admin hanterar användare (tekniker/arbetsledare/admin), all ärendedata organisationsisolerad. Inloggning (bcrypt via pgcrypto, HS256-JWT med roll + org i anspråken), append-only händelse-API, publik delningsendpoint |
Deployment + Service + HPA + PDB |
ai-orkester |
AI-orkestern (services/ai-orkester): fyra uppgifter routade till Sonnet 5 / Opus 5 / Haiku 4.5 — verifierar plattformens JWT (delad hemlighet) |
Deployment + Service + HPA + PDB |
postgres |
Händelselogg + användare; append-only garanterat med databastriggers — historik kan inte ändras eller raderas oavsett roll | StatefulSet + PVC (10 Gi). Produktion: CloudNativePG-operatorn för backup/failover/PITR |
| Hemligheter | anthropic-api-key, jwt-secret (delas av plattform + orkester), postgres-losenord |
Secret felsokning-hemligheter — aldrig i bilder eller manifest |
Klienten har två driftlägen, valda vid bygget: med VITE_PLATTFORM_URL går inloggning, synk, Live Share och AI mot klustret (helt självhostat); utan den används Supabase-läget (edge-funktion + managerad Postgres/Auth) som tidigare. Samma händelsemodell, samma orkester — låst av paritetstester.
Driftsätta
# 1. Bygg och publicera bilderna (ersätt registry i infra/k8s/*.yaml)
docker build -t ghcr.io/ORG/guidad-felsokning-web \
--build-arg VITE_PLATTFORM_URL=https://app.exempel.se .
docker build -t ghcr.io/ORG/guidad-felsokning-ai-orkester services/ai-orkester
docker build -t ghcr.io/ORG/guidad-felsokning-plattform services/plattform
docker push ghcr.io/ORG/guidad-felsokning-web
docker push ghcr.io/ORG/guidad-felsokning-ai-orkester
docker push ghcr.io/ORG/guidad-felsokning-plattform
# 2. Skapa secret:en (eller använd External Secrets/Sealed Secrets)
kubectl create namespace guidad-felsokning
kubectl -n guidad-felsokning create secret generic felsokning-hemligheter \
--from-literal=anthropic-api-key='sk-ant-…' \
--from-literal=jwt-secret="$(openssl rand -base64 48)" \
--from-literal=postgres-losenord="$(openssl rand -base64 24)"
# 3. Applicera manifesten (Postgres initieras med schema + append-only-triggers)
kubectl apply -k infra/k8s
# 4. Verifiera
kubectl -n guidad-felsokning get pods
curl https://app.exempel.se/halsa # → {"status":"ok"} (plattformen)
curl https://app.exempel.se/api/openapi.yaml # API-first: hela API-specen
Byt domän och cert-issuer i infra/k8s/ingress.yaml. Att skapa nya organisationer är öppet i beta — stäng med REGISTRERING_OPPEN=false på plattformens Deployment; användare inom en organisation skapas alltid av dess systemadministratör.
Multi-tenant och roller
Enligt Master Prompt: varje kund är en egen tenant, ingen data blandas mellan kunder.
- Registrering skapar organisationen och gör användaren till systemadministratör.
- Admin skapar användare (tekniker/arbetsledare/admin) i sin organisation — via UI:t eller
POST /api/anvandare. - All ärendedata är organisationsknuten: ärenden skapas i användarens organisation och händelse-API:t verifierar organisationstillhörighet på varje anrop — en annan organisations ärenden ger 404.
- Rollen ligger i JWT:n och verifieras på servern; klienten anpassar bara UI:t.
Integrationstestet (services/plattform/integrationstest.sh, körs även i CI mot riktig Postgres) verifierar hela kedjan: registrering, synk, idempotens, append-only-triggern, organisationsisolering, delningsfiltrering och rollstyrning.
Säkerhet och robusthet
- Append-only i tre lager: klienten lägger bara till, API:t exponerar inga update/delete, och databastriggers avvisar ändringar även för en felkonfigurerad roll.
- JWT-flödet är verifierat tvärs tjänsterna: plattformen signerar, orkestern verifierar samma hemlighet; fel hemlighet och utgångna tokens avvisas (testat).
- Alla containrar kör non-root utan capabilities; backend-tjänsterna med read-only rotfilsystem. Båda failar closed utan sina hemligheter.
- HPA 2–10 pods per tjänst på 70 % CPU; PDB minst en pod uppe vid noddränering; readiness/liveness-prober överallt (
pg_isreadyför Postgres).
CI
.github/workflows/ci.yml kör tester + produktionsbygge och verifierar alla tre Dockerfilerna på varje push/PR. Publicering och kubectl apply läggs i ett separat behörighetsstyrt deploy-flöde (GitOps via Argo CD/Flux rekommenderas).