3a0be7261e
Verkstaden har redan sina avtal: Volvo-verkstaden har VIDA, VAG-verkstaden har erWin, den fria verkstaden har en fordonsdataleverantör. Kopplingarna konfigureras därför av kunden själv under Inställningar, med sina egna uppgifter — vi tillhandahåller ramen, inte kontot. Uppgifterna når aldrig webbläsaren. De krypteras med AES-256-GCM (INTEGRATION_NYCKEL) innan de skrivs till tabellen integrationer, och API:t returnerar hemliga fält maskerade. Alla uppslag görs av servern. Saknas krypteringsnyckeln sparas ingenting alls — 503 och en förklaring i gränssnittet i stället för klartext i databasen. Endast systemadministratören hanterar uppgifterna; kopplingarna är organisationsknutna som all annan ärendedata. Leverantörer är data, inte kod: URL-mall, autentiseringstyp (bearer/header/basic/query) och svarsmappning beskrivs i services/plattform/integrationer.json, utbytbar via ConfigMap (INTEGRATIONER_FIL). Nya märken läggs till utan att appen byggs om. Varje uppslag skriver senast_testad och senaste_status på kopplingen, så ett utgånget abonnemang syns i inställningarna i stället för att ge tysta tomma svar. Två latenta krascher hittade av klicktestet och åtgärdade: TextFalt och UNDANTAGSORSAKER användes utan import. vite build typkontrollerar inte, så de passerade bygget — därav nya npm-skriptet typkontroll, nu del av verifieringen. Verifierat: 80 vitest-tester, typkontroll, eslint, OpenAPI-validering, integrationstest mot riktig Postgres (rollstyrning, kryptering i vila, maskering, organisationsisolering, fail closed, borttagning) och klickgenomgång mot en körande plattform. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
87 lines
2.6 KiB
YAML
87 lines
2.6 KiB
YAML
# Plattformstjänsten: självhostad auth, händelse-API och Live Share-delning.
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: plattform
|
|
namespace: guidad-felsokning
|
|
labels: { app: plattform }
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels: { app: plattform }
|
|
template:
|
|
metadata:
|
|
labels: { app: plattform }
|
|
spec:
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
containers:
|
|
- name: plattform
|
|
image: ghcr.io/ORGANISATION/guidad-felsokning-plattform:latest # ersätt med ert registry
|
|
ports:
|
|
- containerPort: 8080
|
|
env:
|
|
- name: JWT_SECRET
|
|
valueFrom:
|
|
secretKeyRef: { name: felsokning-hemligheter, key: jwt-secret }
|
|
# Krypteringsnyckel för kundernas märkesspecifika credentials
|
|
# (32 byte hex eller base64). Saknas den sparas inga uppgifter
|
|
# alls — tjänsten failar closed i stället för att lagra i klartext.
|
|
- name: INTEGRATION_NYCKEL
|
|
valueFrom:
|
|
secretKeyRef: { name: felsokning-hemligheter, key: integration-nyckel }
|
|
- name: POSTGRES_LOSENORD
|
|
valueFrom:
|
|
secretKeyRef: { name: felsokning-hemligheter, key: postgres-losenord }
|
|
- name: DATABASE_URL
|
|
value: postgresql://plattform:$(POSTGRES_LOSENORD)@postgres:5432/felsokning
|
|
resources:
|
|
requests: { cpu: 100m, memory: 128Mi }
|
|
limits: { cpu: "1", memory: 256Mi }
|
|
readinessProbe:
|
|
httpGet: { path: /halsa, port: 8080 }
|
|
initialDelaySeconds: 3
|
|
livenessProbe:
|
|
httpGet: { path: /halsa, port: 8080 }
|
|
periodSeconds: 15
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities: { drop: [ALL] }
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: plattform
|
|
namespace: guidad-felsokning
|
|
spec:
|
|
selector: { app: plattform }
|
|
ports:
|
|
- port: 80
|
|
targetPort: 8080
|
|
---
|
|
apiVersion: autoscaling/v2
|
|
kind: HorizontalPodAutoscaler
|
|
metadata:
|
|
name: plattform
|
|
namespace: guidad-felsokning
|
|
spec:
|
|
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: plattform }
|
|
minReplicas: 2
|
|
maxReplicas: 10
|
|
metrics:
|
|
- type: Resource
|
|
resource:
|
|
name: cpu
|
|
target: { type: Utilization, averageUtilization: 70 }
|
|
---
|
|
apiVersion: policy/v1
|
|
kind: PodDisruptionBudget
|
|
metadata:
|
|
name: plattform
|
|
namespace: guidad-felsokning
|
|
spec:
|
|
minAvailable: 1
|
|
selector:
|
|
matchLabels: { app: plattform }
|