Files
alva/docs/moduler/markesspecifika-kopplingar.md
T
Claude 3a0be7261e Märkesspecifika kopplingar — kunden lägger in sina egna credentials
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
2026-08-03 12:50:44 +00:00

4.2 KiB

Märkesspecifika kopplingar

Verkstaden har redan sina avtal. Volvo-verkstaden har VIDA, VAG-verkstaden har erWin, den fria verkstaden har en fordonsdataleverantör. Ingen av dem vill att vi ska vara mellanhand för deras abonnemang — och ingen av dem har samma uppsättning som grannen.

Därför konfigurerar kunden själv sina kopplingar under Inställningar → Märkesspecifika kopplingar, med sina egna credentials. Vi tillhandahåller ramen, inte kontot.

Principer

Uppgifterna når aldrig webbläsaren. Samma regel som för plattformens egna API-nycklar: hemligheter bor på servern. Credentials krypteras med AES-256-GCM innan de skrivs till databasen, och API:t returnerar hemliga fält maskerade (••••3456). Klienten kan se att en koppling finns och när den senast fungerade — aldrig vad nyckeln är.

Alla uppslag görs av servern. Klienten skickar en identifierare (VIN eller regnr); servern hämtar uppgifterna, dekrypterar dem i minnet, anropar leverantören och returnerar bara de mappade fordonsfälten.

Fail closed. Saknas krypteringsnyckeln (INTEGRATION_NYCKEL) sparas ingenting — API:t svarar 503 och inställningssidan förklarar varför. Alternativet, att lagra i klartext "så länge", finns inte.

Endast systemadministratören. Att lägga till, ändra och ta bort kopplingar kräver rollen admin. Teknikern kan läsa registret över tillgängliga leverantörer (annars kan inställningssidan inte visa dem) men aldrig någon organisations uppgifter.

Organisationsknutet. Kopplingarna hör till organisationen, precis som ärendedata. Ingen tenant ser en annans.

Leverantörer är data, inte kod

Registret ligger i services/plattform/integrationer.json och kan bytas mot en ConfigMap-mount via INTEGRATIONER_FIL. En leverantör beskrivs helt deklarativt:

{
  "id": "volvo_vida",
  "namn": "Volvo VIDA",
  "falt": [
    { "nyckel": "bas_url", "etikett": "Bas-URL (använd {vin} som platshållare)", "hemlig": false },
    { "nyckel": "api_nyckel", "etikett": "API-nyckel", "hemlig": true }
  ],
  "uppslag": {
    "urlFalt": "bas_url",
    "auth": "header",
    "authHeader": "X-Api-Key",
    "authFalt": "api_nyckel",
    "svarsfalt": { "marke": "make", "modell": "model", "arsmodell": "year" }
  }
}
  • falt — vad administratören ska fylla i. hemlig: true styr både kryptering och maskering.
  • uppslag.authbearer, header, basic eller query. Inga leverantörsspecifika kodgrenar; all variation ligger i registret.
  • svarsfalt — mappning från leverantörens JSON (punktnotation stöds) till våra fordonsfält.
  • nyckeltyp: "regnr" — uppslaget sker på registreringsnummer i stället för VIN. {vin}/{regnr} i URL-mallen ersätts URL-kodat.

Ett nytt märke läggs alltså till genom att beskriva det — inte genom att bygga om applikationen.

Vad ett uppslag gör och inte gör

Uppslaget fyller i fordonsbeskrivningen (märke, modell, årsmodell, motor, växellåda). Det är kontextdata, inte evidens: ett svar från en leverantör är aldrig en utförd kontroll och räknas inte i evidensmotorn. Returnerar leverantören inga kända fält säger systemet det rakt ut i stället för att visa tomma rader.

Varje uppslag skriver senast_testad och senaste_status på kopplingen. Ett utgånget abonnemang syns därför i inställningarna som ett felmeddelande från leverantören, inte som tysta tomma svar.

API

Väg Metod Roll Vad
/api/integrationer/leverantorer GET inloggad Registret (fältdefinitioner, inga uppgifter)
/api/integrationer GET admin Organisationens kopplingar, hemligheter maskerade
/api/integrationer POST admin Spara/uppdatera credentials (krypteras)
/api/integrationer/{leverantor} DELETE admin Ta bort
/api/integrationer/{leverantor}/uppslag POST inloggad Slå upp VIN/regnr via servern

Fullständigt dokumenterat i services/plattform/openapi.yaml.

Drift

INTEGRATION_NYCKEL är 32 byte hex eller base64 (openssl rand -hex 32), levererad via secret:en felsokning-hemligheter — se DRIFT.md. Byts nyckeln måste kopplingarna sparas om; tjänsten visar då inga värden i stället för att gissa.