Hoppa till innehållet
ErsviaErsviaSystemarkitekturdokument

8. Tvärgående koncept

8.1 Domänmodell#

Kärnan i domänen följer TestVioras informationsmodell (Figur 4 i uppsatsen). Den använder de 24 begreppen i verksamhetsmodellen (ADR 0009). Den är utbyggd för GVR, ListOn, kontroll och flera regioner. Klassdiagrammen visar varje del. ER-diagrammen visar hur delarna lagras per schema. Tabellen visar vem som äger varje mängd data och om den har personuppgifter. Den visar också hur skyddad den är, var den lagras och om den ska sparas eller gallras (tas bort efter en tid).

ArchiMateArchiMate: informationsobjekt och klassningLadda ned SVG: ArchiMate: informationsobjekt och klassningLadda ned PUML: ArchiMate: informationsobjekt och klassning

Informationsmängd (TestViora) Ägare Personuppgifter Klassning Schema Bevarande
1 Överenskommelser Avtalsansvarig på HSF Nej Intern overenskommelse Bevaras
2 Vårdhändelser HSF Känsliga Skyddad vardhandelser, vantande Gallras enligt dokumenthanteringsplanen
3 Listning HSF Ja Skyddad listning Gallras enligt dokumenthanteringsplanen
4 Kodverk och masterdata Systemförvaltningen Nej Öppen kodverk, masterdata Bevaras
5 Ersättningsregelverk Controller på HSF Nej Intern regelverk Bevaras
6 Ersättningsunderlag Controller på HSF Nej (pseudonym) Intern berakning, granskning Bevaras
7 Kvalitetsdata och ansökningar Controller på HSF Nej Intern malrelaterad Bevaras
8 Fakturaunderlag och utbetalningar Ekonomifunktionen Nej Intern fakturering Gallras efter 10 år (bokföringslagen)
9 Avstämningsinformation HSF Känsliga (via vårdhändelsenummer) Skyddad avstamning Gallras enligt dokumenthanteringsplanen
10 Loggar Systemförvaltningen Ja Skyddad drift Gallras enligt dokumenthanteringsplanen

Överenskommelse, vårdgivare och vårdenhet#

Huvudman (tenant, den region som äger datat) har överenskommelser genom en Bestallarnamnd. Overenskommelse är abstrakt. Den är antingen ett Avtal (avtalsnummer, vårdval, LfU-avtalsområde, lagrum LOV/LOU) eller ett Uppdrag (beslutsreferens, egen regi). Den gäller en Vardgivare (organisationsnummer, driftform) med Vardenheter. Den har ett Vardutbud och använder en eller flera Ersattningsgrunder. Typen är en av Kapitering, Uppdrag, Produktion och Målrelaterad, med legacyModellnummer mot ERSMO. Huvudman, vårdgivare och vårdenhet är typer av NIM:s Organisation.

Id-modell (ADR 0011, kontroll 3 Ä5). Ersvias egna id ändras aldrig och är primärnycklar: vg- (vårdgivare), ve- (vårdenhet), ok- (överenskommelse), eg- (ersättningsgrund), bn- (beställarnämnd) och fm- (fakturamottagare). HSA-id och Avtalat uppdrags-id (NVID) är de viktigaste externa id. De lagras som alias med versioner och två tidsaxlar (bitemporalt) i masterdata.alias_version. Där finns också vårdgivarnummer och kombika. Kombika används bara för kompatibilitetsfasaden och historiken, och den ska bort. GET /vardenheter/sok-alias slår upp ett internt id från ett alias, så som det var vid en viss tid (as-of). HSA-id valideras mot ^SE[0-9]{10}-[A-Za-z0-9]{1,24}$. Fakturamottagare tas fram ur län, basområde och hemvist.

KlassKlassdiagram: överenskommelse, avtal och uppdrag, vårdgivare och vårdenhetLadda ned SVG: Klassdiagram: överenskommelse, avtal och uppdrag, vårdgivare och vårdenhetLadda ned PUML: Klassdiagram: överenskommelse, avtal och uppdrag, vårdgivare och vårdenhet

Vårdhändelse#

Vardhandelse (termbankens vårdkontakt, TestVioras Rapport om utförd vård) är abstrakt med underklasserna Besok, Inskrivning/Vardtillfalle, Aktivitet, Vardperiod och Kontakt. Varje ändring blir en ny VardhandelseVersion. Patienten refereras med Patientreferens (personnummer, samordningsnummer eller reservnummer), som utanför patientdatazonen bara är en Pseudonym.

KlassKlassdiagram: vårdhändelse och väntandeLadda ned SVG: Klassdiagram: vårdhändelse och väntandeLadda ned PUML: Klassdiagram: vårdhändelse och väntande

Listning#

KlassKlassdiagram: listning (ListOn-ersättaren)Ladda ned SVG: Klassdiagram: listning (ListOn-ersättaren)Ladda ned PUML: Klassdiagram: listning (ListOn-ersättaren)

Regelverk#

KlassKlassdiagram: regelverk med Bitemporal, versioner, manifest, primitiver och mallarLadda ned SVG: Klassdiagram: regelverk med Bitemporal, versioner, manifest, primitiver och mallarLadda ned PUML: Klassdiagram: regelverk med Bitemporal, versioner, manifest, primitiver och mallar

Beräkning och ersättningsrad#

Berakningskorning har ett Manifest och ett Underlagssnapshot och producerar EkonomiskErsattning per vårdgivare, period och ersättningsslag, uppdelad i Ersattningsrader med Traceposter. Justeringar är egna rader. Differensunderlag refererar den ursprungliga körningen.

KlassKlassdiagram: beräkning och ersättningsradLadda ned SVG: Klassdiagram: beräkning och ersättningsradLadda ned PUML: Klassdiagram: beräkning och ersättningsrad

Fakturering och utbetalning#

KlassKlassdiagram: fakturering och utbetalningLadda ned SVG: Klassdiagram: fakturering och utbetalningLadda ned PUML: Klassdiagram: fakturering och utbetalning

Mål och vite#

KlassKlassdiagram: målrelaterad ersättning och viteLadda ned SVG: Klassdiagram: målrelaterad ersättning och viteLadda ned PUML: Klassdiagram: målrelaterad ersättning och vite

Kontroll och ärende#

KlassKlassdiagram: kontroll, ärende och återkravLadda ned SVG: Klassdiagram: kontroll, ärende och återkravLadda ned PUML: Klassdiagram: kontroll, ärende och återkrav

Databasscheman#

Varje modul har ett eget schema med egen historik för migreringar. Den har också tabellerna outbox och dokument. Data med versioner lagras i en tabell per bitemporal entitetstyp (<entitet>_version). Tabellen har giltig daterange, registrerad tstzrange, data jsonb och en hashkedja per nyckel. SchemaSql.BitemporalTabell skapar den (ADR 0011). Alla tabeller har huvudman och säkerhet på radnivå. Diagrammet e04 visar de byggda schemana med det allmänna mönstret (F2–F5). Vårdhändelser (F4) har i stället en egen tabell med partitioner, för att klara volymen (e01, ADR 0012). e01 visar det som är byggt i patientdatazonen, och e02 visar regelverk och identitet. e05 visar beräkning, simulering, FUMS/FUL, kompatibilitet och rapportering (F6 och F9a). e03 visar malrelaterad och granskning (F7) och uppfoljning, migrering och drift (F10). Fakturering och avstämning (F8) finns också i e03.

ERER-diagram: byggda scheman F2–F5 med generiskt bitemporalt mönsterLadda ned SVG: ER-diagram: byggda scheman F2–F5 med generiskt bitemporalt mönsterLadda ned PUML: ER-diagram: byggda scheman F2–F5 med generiskt bitemporalt mönster

ERER-diagram: byggda scheman i patientdatazonen (F2–F5)Ladda ned SVG: ER-diagram: byggda scheman i patientdatazonen (F2–F5)Ladda ned PUML: ER-diagram: byggda scheman i patientdatazonen (F2–F5)

ERER-diagram: regelverk och identitet (byggda F3)Ladda ned SVG: ER-diagram: regelverk och identitet (byggda F3)Ladda ned PUML: ER-diagram: regelverk och identitet (byggda F3)

ERER-diagram: byggda scheman för beräkning (F6) och kompatibilitet och rapportering (F9a)Ladda ned SVG: ER-diagram: byggda scheman för beräkning (F6) och kompatibilitet och rapportering (F9a)Ladda ned PUML: ER-diagram: byggda scheman för beräkning (F6) och kompatibilitet och rapportering (F9a)

ERER-diagram: malrelaterad och granskning (F7), uppfoljning, migrering och drift (F10); fakturering och avstamning målbild (F8)Ladda ned SVG: ER-diagram: malrelaterad och granskning (F7), uppfoljning, migrering och drift (F10); fakturering och avstamning målbild (F8)Ladda ned PUML: ER-diagram: malrelaterad och granskning (F7), uppfoljning, migrering och drift (F10); fakturering och avstamning målbild (F8)

8.2 Bitemporal versionering och manifest#

Vad som versioneras: allt som påverkar ett belopp. Det omfattar ersättningsmodeller och regler, parametertabeller (ACG, CNI, DRG-viktlista och poängpris, utomlänsprislista, taxekoder, glesbygdszoner, prisbasbelopp, LPIK), överenskommelser, kodverk, masterdata (vårdenheter, kombika och HSA-giltighet), faktureringskalendrar och källdokumenten själva med SHA-256 (ADR 0004).

Två tidsaxlar:

Axel Fält i koden Kolumn Betydelse
Giltighetstid (valid time) Giltighet.GiltigFran, Giltighet.GiltigTill (halvöppet, null = tills vidare) giltig När versionen gäller i verksamheten
Registreringstid (transaction time) Bitemporal<T>.RegistreradTid, Bitemporal<T>.ErsattTid registrerad När Ersvia kände till versionen

Bitemporal<T>.GallerAsOf(giltigVid, kandVid) svarar på frågan för en version, och BitemporalHistorik<T> garanterar att högst en version gäller för varje par (giltigVid, kandVid). GiltighetsAnalys hittar luckor och överlapp. IBitemporalLager<T> har två implementationer med samma semantik: in-memory (InMemoryBitemporalLager) och PostgreSQL (PostgresBitemporalLager, EF Core med NpgsqlRange och rådgivande lås per nyckel). Samma FsCheck-modell körs mot båda. I PostgreSQL förhindrar en exclusion constraint (EXCLUDE USING gist (huvudman WITH =, nyckel WITH =, giltig WITH &&) WHERE (upper_inf(registrerad)), btree_gist) överlappande giltighet bland aktuella versioner, och triggern skydda_version gör raderna oföränderliga: bara ersattTid får sättas, en gång, och DELETE är förbjudet (ADR 0011).

Känd svaghet (kontroll 3 R1): en rättelse som bara täcker en del av en tidigare giltighet kräver att den gamla versionen stängs i transaktionstid och att resterna läggs in på nytt, och ersattTid omfattas inte av hashkedjan. Åtgärd: rättelsen görs som en enda operation i lagret (Minus på Giltighet), och stängningen kedjas som en egen händelse.

Prestanda (kontroll 3 R2): manifestet kompileras vid körningens start till en oföränderlig ögonblicksbild i minnet. Motorn läser aldrig bitemporala tabeller per vårdhändelse.

Regler:

  • En publicerad version ändras aldrig. En ändring skapar en ny version.
  • Ett fel rättas med en ny version med samma giltighet och senare registreringstid. Den gamla får ErsattTid och finns kvar.
  • Versionerna kedjas med hash (Hashkedja<T>).
  • Varje version har beslutsreferens, källdokument med hash, skapare och godkännare, status och ändringsbeskrivning med diff.

Portalens sida Vad gällde när? (F11a) visar samma fråga för användare, med tidslinje per ersättningsgrund:

Portalen (GUI v2): Vad gällde när? med regelversion, testbevis och tidslinjeLadda ned SVG: Portalen (GUI v2): Vad gällde när? med regelversion, testbevis och tidslinje

Exempel (kapitering 75+ och 85+):

DriftsättningBitemporal tidslinje: kapitering 75+ och 85+, giltighetstid mot registreringstidLadda ned SVG: Bitemporal tidslinje: kapitering 75+ och 85+, giltighetstid mot registreringstidLadda ned PUML: Bitemporal tidslinje: kapitering 75+ och 85+, giltighetstid mot registreringstid

Version Värde Giltighet Registrerad Ersatt
A 75+ 1 535 kr/år [2025-01-01, 2026-03-01) 2024-12
B 75+ 2 100 kr/år [2026-03-01, tills vidare) 2026-02
C 85+ 3 100 kr/år [2026-07-01, tills vidare) 2026-06
D (rättelse) retroaktiv rättelse efter nämndbeslut samma som rättad version 2026-08-20 ersätter tidigare version från 2026-08-20
  • "Vad gällde för vård utförd 2026-05-15?" → giltigVid=2026-05-15, kandVid=nu → version B (eller D efter rättelsen).
  • "Vad trodde vi gällde för maj när vi räknade 2026-06-03?" → giltigVid=2026-05-15, kandVid=2026-06-03 → version B.
  • Majkörningen 2026-06-03 reproduceras exakt ur sitt manifest. Omräkningen 2026-08-25 får ett nytt manifest och ett differensunderlag.

Manifest (ADR 0005): Manifest.Skapa(motorversion, underlagSnapshot, poster) sorterar posterna ordinalt på nyckel och beräknar SHA-256 över kanonisk JSON (KanoniskJson: sorterade nycklar, inga blanksteg, normaliserade tal). Hashen är oberoende av i vilken ordning posterna lades till. Manifest.Id = mf- + de första 16 hexadecimala tecknen och följer med varje ersättningsrad, fakturaunderlag och avstämningsrad. Nycklarna i Beräkningens manifest (F6) är regel/{ersattningsgrund}/{giltigFrån}, parametertabell/{id}, masterdata/vardgivare/{id}, masterdata/vardenhet/{id}, kodverk/{kodverk}, overenskommelse/{id}, konfiguration/berakning, underlag/vardhandelser/{period}, underlag/listning/…, underlag/fums/{period}, underlag/ful/{period}, tidigareKorning/{period} och motor/version. Varje post har versions-id eller referens och hash.

API: alla läs-API:er för versionerad data tar ?giltigVid=<datum>&kandVid=<tidpunkt>. Historik: GET /regelverk/ersattningsgrunder/{id}/historik. Jämförelse: GET /regelverk/jamfor?fran=&till=. MCP: vad_gallde(ersattningsgrund, datum, kand_vid?).

Tester: egenskapsbaserade tester (BitemporalEgenskaper) visar att det inte finns luckor eller överlapp och att as-of-frågan ger högst en version. Ett golden-test kör maj 2026, gör en retroaktiv ändring, kör igen och reproducerar den första körningen bit för bit.

8.3 Regelmotorns primitiver och mallar#

Motorn byggs av primitiver (åtta grundprimitiver nedan, elva i den byggda motorn). De 42 regeltyperna i katalogen (docs/underlag/modeller/00-katalog.md) blir mallar som sätts samman av primitiver. Regionpaketen innehåller bara parametrar och sammansättningar (ADR 0003, ADR 0010). En ny ersättningsform byggs alltså av befintliga primitiver i stället för ny kod (mål 2).

Primitiv Signatur (förenklad) Exempel
Urval mängd × predikat → delmängd Listade sista dagen och folkbokförda i länet; besök med yrkeskategori läkare
Tabelluppslag nyckel(ar) × tabell → värde Åldersklass → belopp; produktkod × yrke × kanal → pris
Trappa värde × intervall → utfall CNI 1,0–1,199 → 10 kr; volym 100–104 % → 50 %
Tak belopp eller volym × gräns → begränsat värde 1 125 000 kr per fysioterapeut och år; tak 1 i LOL
Andel belopp × procent → belopp Momskompensation 6 %; delat kostnadsansvar 20 %; 75 % över 12 000 kr
Tidsfonster händelser × fönster → delmängd 90 dagars förfall; reoperation inom 2 år; ACG 18/36 månader; 2 omlistningar per 12 månader
Aggregering mängd × gruppering × funktion → värde Antal listade per vårdenhet; kvot besök/listade
Fordelning belopp × nyckel → delbelopp Tolftedelar; 1/365; sjättedelar; fördelning efter kapacitetsandel

Byggt i F3 (ADR 0013). Regelschemat (contracts/schemas/regel/) och Ersvia.Regelmotor har elva primitiver: de åtta ovan plus villkor, schablon och episod (tillstånd över händelser, tillagd i primitiver.schema.json). Det finns 34 mallar (33 ur schemat plus körsteget clearing för clearing mellan vårdgivare). Alla 42 regeltyper är uttryckta som mall eller variant av mall, utan kodad specialmall; mappningen med facit per typ finns i docs/plan/regelmappning.yaml, och facitfilerna (51 st.) i tests/Golden. Nya ersättningsformer byggs med sammansatt (kedja av primitiver).

Körfaser och beroenden (kontroll 3 Ä11 och R10). Motorn har nio körfaser i ordning – urval, klassificering, prissättning, tillägg/avdrag, tak/målvolym, periodavstämning, pooler/clearing, justering och resultat – grupperade i fyra körnivåer: händelse, vårdgivare och period, pool över vårdgivare och avstämning. Varje mall planeras till namngivna steg, och beroendena bildar en DAG som sorteras topologiskt med fas, regelordning och stegordning som deterministisk prioritet. Ett steg får inte bero på ett steg i en senare fas. Avrundning sker bara med avrunda och en explicit metod (halvUpp, bankavrundning, nedåt, uppåt), per rad eller per summa (nar: perSumma). Belopp är kronor som decimal i motorn och öre i gränssnitten. Varje primitivanrop skriver en tracepost, och resultatet har en SHA-256 över rader, flaggor och trace (KRAV-36). Se f03.

Beslutstabeller med explicit träffpolicy (planen 4k). Varje beslutstabell anger träffpolicy enligt DMN: unik (UNIQUE), forsta (FIRST), prioritet (PRIORITY), alla (COLLECT) och summa (COLLECT-SUM). Överlapp är fel vid publicering för UNIQUE och för PRIORITY med samma prioritet, och luckor är fel när tabellen saknar standardutfall. Uttryck kan skrivas som JSON-träd eller som formel ({"formel": "max(0, x - $troskel) * 0.75"}). Bevis vid publicering: Regelverk kräver minst ett godkänt facitfall och sparar ett hashat testbevis (regelhash, motorversion, fallens utfall) med versionen.

Uttrycken körs i en sandlåda utan I/O, klocka eller slump. Belopp räknas med Belopp och avrundas bara med en explicit Avrundningsregel.

Mallar (42 regeltyper)#

# Mall Primitiver
1 Pris per produktkod Urval, Tabelluppslag
2 Tilläggsersättning ovanpå bas Urval, Tabelluppslag
3 Åldersviktad kapitering per listad Urval, Tabelluppslag, Aggregering, Fordelning
4 Indexjusterad kapitering eller fast ersättning (CNI/ACG) Tabelluppslag, Andel, Fordelning
5 Indextrappa per besök Tabelluppslag, Trappa
6 Geografiskt tillägg (zoner) Tabelluppslag
7 Avståndstrappa Trappa
8 DRG × poängpris Tabelluppslag, Andel
9 Målvolym med reducerat pris eller trappa Aggregering, Trappa, Andel
10 Avdragstrappa vid underproduktion Aggregering, Trappa, Andel
11 Fast uppdrag i tolftedelar Fordelning
12 Fast ersättning med villkor och återkrav Aggregering, Trappa, Fordelning
13 Bemanningsavdrag Andel, Fordelning
14 Episod- och periodersättning Tidsfonster, Tabelluppslag
15 Vårdtillfälle med vårddygnstrappa Trappa, Tak
16 Dagersättning per patient Aggregering, Tabelluppslag
17 Ersättningstak i kronor Aggregering, Tak, Fordelning
18 Volymtak och kvottak Aggregering, Trappa, Andel
19 Andelsgolv och andelstak per delmängd Urval, Aggregering, Tak
20 Kostnadsgräns med vidarefakturering Trappa, Andel
21 Bonus per mål Tabelluppslag, Fordelning
22 Kvalitetsandel innehållen ur pris Andel
23 Indikatorformel (resultat − min)/(mål − min) Aggregering, Trappa, Andel
24 Bonus och vite i procent av årsersättning Aggregering, Andel
25 Vite per händelse Urval, Tabelluppslag
26 Avtalsvite på vitesgrundande belopp Tidsfonster, Aggregering, Andel, Tak
27 Innehållande och återbetalning Andel, Tidsfonster
28 Patientavgiftsavdrag Tabelluppslag, Urval
29 Schablonavdrag för ej folkbokförda Urval, Tabelluppslag
30 Delat kostnadsansvar i procent Andel
31 Undantagslista med kostnadsersättning Urval, Tabelluppslag
32 Prisindexering Tabelluppslag, Andel
33 Prisbrytpunkt Tabelluppslag (nyckel = styrande datum)
34 Preskription och frister Tidsfonster
35 Patientkategori styr prislista och mottagare Urval, Tabelluppslag
36 Frekvensregler per patient och period Tidsfonster, Aggregering
37 Förhandsbedömning eller ansökan som villkor Urval
38 Kapitering per vårdbehovsområde Tabelluppslag, Aggregering, Fordelning
39 Nationell taxa med takbelopp Tabelluppslag, Aggregering, Tak, Trappa
40 Tillfällig fast ersättning fördelad efter andel Fordelning
41 Moms- och engångsbelopp Andel
42 Momentan avräkning (kvittning) Aggregering

Det finns också mallar för de regeltyper som finns i ersättningsbilagorna:

  • tillägg för uppdrag med villkor och kontroll per period
  • fast och rörligt led
  • ersättning efter tid
  • beslut om ersättning varje halvår, i sjättedelar
  • tillägg som gäller en viss tid
  • volymtrappor som höjer den fasta delen
  • pris efter triage (bedömning av hur brådskande vården är)
  • målvolym i flera steg
  • ersättning i proportion till hur väl målet nås, med villkor om täckning
  • mätning vid flera tidpunkter
  • viten enligt klausul 10.1, 10.2 och 10.4.2
  • egen regi med budget för uppdraget.

Varje mall har ett facittest med ett verkligt exempel ur katalogen. Ett facittest jämför resultatet med ett känt rätt svar.

8.4 Säkerhet#

Zoner#

Zon Data Åtkomst Skydd
Patientdatazon Personnummer, samordningsnummer, reservnummer i klartext Bara modulerna Vardhandelser, Vantande, Listning, Rapportering, Kompatibilitet, Personuppgifter (värd Ersvia.Patientdata) Egen process och deploybar enhet, egen namnrymd, egen databasinstans och DB-roll utan grants mellan zonerna, nätpolicy, arkitekturtest, åtkomstloggning, återidentifiering och utlämningsexport bara här
Ersättningszon Pseudonym, ålder, kön, län, kommun, basområde Övriga moduler, Portal, MCP RLS per huvudman, behörighet per roll och vårdgivare
AI-zon Pseudonymiserade eller aggregerade data Bara från ersättningszonen Egen namnrymd, ingen utgående trafik som standard

Zonbrygga, personnummervakt och nycklar (byggt i F12a, ADR 0020)#

Skydd Hur det fungerar
Zonbrygga Portar som går över zongränsen ersätts av proxyer som anropar POST /intern/zon/v1/{port}/{metod} hos den andra zonen över HTTPS med ömsesidig TLS. Klientcertifikatet (cert-manager, zonernas interna CA) valideras mot tillåtna namn. Bara portar på vitlistan (Zonkopplingar) exponeras: patientdatazonen ger pseudonym och härledda fält, ersättningszonen referensdata. Arkitekturtester kontrollerar att portarna saknar personnummerfält och att ersättningszonen inte beror på patientdatazonen.
Personnummervakt Svar från patientdatazonen kontrolleras på båda sidor av bryggan. Allt som liknar ett personnummer (giltigt datum och kontrollsiffra) stoppas och loggas som säkerhetshändelse, och mätvärdet ersvia.zon.personnummerstopp ska alltid vara 0. Loggarna tvättas dessutom från personnummer, samordningsnummer och reservnummer (Personnummertvatt).
Databasroller Applikations- och gallringsroll per zon, grants bara till zonens scheman, uttryckligt nekande av andra zoners scheman, inget för PUBLIC (Zonroller).
Nycklar Pseudonymnyckeln per huvudman och ändamål läses via INyckelkalla: konfiguration (utveckling), Kubernetes Secret som volym eller KMS via IKmsKlient (HashiCorp Vault KV v2 eller stubbe). Bara patientdatazonen har nyckeln.
CSP Portalen skickar Content-Security-Policy med nonce per svar; axe kördes om mot CSP-värdarna med 0 överträdelser.
Hastighetsbegränsning AddErsviaWebbskydd (Ersvia.Hosting/Webbskydd): fast fönster per minut och anropare, 600 anrop för användare och 6 000 för system med certifikat (konfigurerbart under Ratebegransning); hälsokontroller undantas; 429 vid överskridande loggas som säkerhetshändelse.
Säkerhetsloggar Varje HTTP-anrop, nekade anrop, zonanrop, hastighetsbegränsningar och driftåtgärder loggas som säkerhetshändelser till en separat sink med minst 5 års bevarande (HSLF-FS 2016:40).

Autentisering#

Part Mekanism
System-till-system (journalsystem, Inera, leverantörer) mTLS med SITHS funktionscertifikat (byggt i F9a för GVR-fasaden): ASP.NET Core-certifikatautentisering mot regionens rot, HSA-id ur certifikatets SERIALNUMBER (2.5.4.5) mappas till vårdgivare via Identitet eller Kompatibilitet:Systemkonton. TLS kan termineras i ingressen med vidarebefordrat certifikat (kap. 7.2). Spärrkontroll kan slås på. SNOD: HTTPS och Basic auth.
Regionens användare (Avtalsansvarig, Controller, Attestant, Ekonomifunktionen, Systemförvaltare) OIDC/SAML mot regionens identitetstjänst (SLL IDP), med SITHS-kort eller e-legitimation. Flerfaktor krävs (HSLF-FS 2016:40) och tillitsnivå 3 för kritiska system (RS 2025-0418).
Vårdgivarens användare OIDC med e-legitimation (BankID, Freja) eller SITHS. Behörigheten kopplas till vårdgivare via HSA-uppdrag eller regionens behörighetsadministration.
AI-klienter OIDC-token med samma roller. MCP-verktygen filtreras på roll.
Dev och test Keycloak och en dev-CA

Behörighet#

Behörigheten har tre delar. Den första är roll (TestVioras sex roller). Den andra är vårdgivare, alltså vilka av dem som användaren får se. Den tredje är beloppsgräns (för attest). Identitet översätter claims (uppgifter i inloggningen) till behörigheter. Varje endpoint (adress i API:et) har en policy, en regel för vem som får anropa den. Tabellen över behörigheter följer TestVioras roller:

Roll Läsa Skapa och ändra Godkänna
Avtalsansvarig Överenskommelser, ersättningsunderlag, kodverk Överenskommelser
Controller Allt i ersättningszonen Regelverk, indikatorer, justeringar, simuleringar Regelversioner som någon annan har skapat
Attestant Ersättningsunderlag, fakturaunderlag Attest steg 2 upp till beloppsgränsen
Vårdgivare Egna överenskommelser, avstämning, fakturaunderlag Vårdhändelser, invändningar, ansökningar Eget fakturaunderlag
Ekonomifunktionen Fakturaunderlag och utbetalningar Kvittens
Systemförvaltare Integrationsstatus, loggar, kodverk och masterdata Kodverk och masterdata, behörigheter

Delegations- och attestmatris#

Beslutsrätten är konfigurerbar per regionpaket och versionerad bitemporalt, och Identitet kontrollerar den vid varje beslut (planen 4j). Systemet kontrollerar både vem (roll och delegation) och hur mycket (beloppsnivå).

Delegationsmatris (Region Stockholm, gällande delegationer HSN 2026-0052 och PVN 2026-0005):

Beslut Beslutsfattare Gräns
Avtal om vård Avdelningschef Under 25 mnkr
Avtal om övrigt Avdelningschef Under 5 mnkr
Avtal HS-direktören Under 50 mnkr
Upphandling Nämnden Över 50 mnkr
Avtal inom psykiatri Psykiatriutskottet Under 1 500 mnkr per år
Godkännande och uppsägning enligt LOV HSN:s avtalsutskott (primärvård: PVN)
Rapporteringsanvisningar som påverkar ersättningen Avdelningschef
Avskrivning av fordringar Avdelningschef / direktören Upp till 30 000 kr / upp till 100 000 kr

Attestmatris: beloppsnivåer, utanordnare och attestanter. Egenattest spärras, och över en konfigurerad gräns krävs två personer (GR-5002). Inget attestreglemente är publicerat, så regionen fyller i värdena från HSN:s beslutsordning 2024-0105 och ekonomihandboken. Ändringar i attestanter rapporteras till nämnden varje kvartal. Behörigheter tilldelas utifrån en dokumenterad behovs- och riskanalys per roll och följs upp årligen (NK20, RS 2025-0418).

Pseudonymisering och dataminimering#

  • Pseudonym (ett ersättningsnamn i stället för personnummer) = HMAC-SHA-256 av person-id med en nyckel. Nyckeln är unik per tenant och ändamål och ligger i KMS eller HSM (i F2 per huvudman i konfigurationen). Den finns bara i patientdatazonen.
  • Återidentifiering, att ta fram personnumret igen, sker bara i patientdatazonen. Ändamålet kontrolleras och allt loggas (NK19). Det behövs för drill-down och utlämningsexport.
  • Data med pseudonym är ändå personuppgifter, till exempel vid små celler och ovanliga diagnoser. Därför görs en DPIA (en analys av hur integriteten påverkas). Data slås ihop med k-anonymitet innan de går till AI, så att ingen kan pekas ut (kontroll 3 R5).
  • Ersättningszonen får bara ålder på mätdagen, kön, län, kommun och basområde (KRAV-18).
  • Inga personnummer i fakturaunderlag till vårdgivare eller i interna fakturor. De använder vårdhändelsenummer eller pseudonym. Vissa utlämnanden kräver identitet enligt regelverk (riksavtalet 8.9, Försäkringskassan EU/EES, Migrationsverket). De skapas av utlämningsexporten i patientdatazonen. Skyddad identitet sköts av sig själv.
  • VAL (rättat krav, ADR 0020 tillägg): VAL gör pseudonymer själv och får därför vårdhändelser och listning med personnummer i klartext. Valexporttjanst i patientdatazonen gör leveransen (POST /api/uppfoljning/v1/val/leveranser, som ingressen skickar dit). Ändamålet kontrolleras mot regionpaketets uppfoljning/exporter.json (annars UP-5005). Varje person läses via Personuppgifter med ändamålet. Varje uttag loggas i revisionsloggen och säkerhetsloggen. Leveransen har ett manifest med pseudonymiserad: false. Kontrollen av personnummer, UP-5003, är en uttrycklig inställning per export. Den är avslagen bara för val-vardhandelser och val-listning och påslagen för allt annat. Utfallsexporten innehåller inga personer och ligger kvar i Uppföljning.
  • Väntetidsdatabasen, KPP, patientregistret och statsbidragen får underlag med pseudonym, och underlagen kontrolleras mot personnummer. Patientregistret får personnumret när underlaget lämnas in. Det är utlämningsexporten som kopplar på det.

Loggning#

  • IRevisionslogg loggar LasningAvPersonuppgifter, Skapad, Andrad, Godkand, Avslagen, Publicerad, Justerad, Attesterad och Inloggning (KRAV-67).
  • Loggen är append-only och hashkedjad per tenant (Hashkedja<Revisionspost>). VerifieraAsync hittar den första trasiga posten.
  • Loggen lagras per schema i <schema>.revisionslogg(huvudman, sekvens, tid, aktor, handling, objekt, detalj, foregaende_hash, hash) med triggern endast_tillagg och RLS (ADR 0011). Personuppgifter loggar varje läsning med pseudonym, aldrig personnummer i klartext.
  • Säkerhets- och åtkomstloggar sparas i minst 5 år (HSLF-FS 2016:40, BG-plan). Stickprov i loggarna dokumenteras.
  • Loggarna kan levereras till regionens SIEM och e-arkiv. Säkerhetshändelser tidsstämplas så att regionen kan lämna tidig varning inom 24 timmar, incidentanmälan inom 72 timmar och slutrapport inom 1 månad (NIS 2, NK24).

Säkerhetsdrift och NIS 2#

Ersvia omfattas som del av regionens verksamhet av cybersäkerhetslagen (2025:1506). En leverantör som driver Ersvia som tjänst blir själv verksamhetsutövare (förvaltade tjänster). Arkitekturen stöder därför: SBOM per release (CycloneDX i CI, byggt i F12a), Trivy-skanning per image, signerade images, SIEM-export (separat säkerhetslogg-sink), incidentflöde med tidsstämplar (nis2-incidentrutin.md), säkerhetskopiering varje dygn med återläsningstest, revisionsrätt och NIS 2-ansvar i leverantörsavtalet, och säkerhetsskyddsanalys före upphandling (NK25). En ADR om säkerhetsdrift tas fram i F12 (kontroll 3 R7).

8.5 Multi-tenant och regionpaket#

Huvudman är tenant (ADR 0010). ITenantKontext.Huvudman (HuvudmanId, t.ex. exempel eller stockholm) sätts per anrop från token eller certifikat, eller per jobb. Alla tabeller har kolumnen huvudman och RLS-policyer (ENABLE + FORCE) som jämför med current_setting('app.huvudman'). En interceptor sätter värdet med set_config på varje anslutning. Applikationsrollen saknar BYPASSRLS och superanvändare, och lagren filtrerar dessutom explicit på huvudman som försvar på djupet (ADR 0011). Integrationstesterna visar att stockholm och exempel inte ser varandras data. Kvarstående risk (kontroll 3 R9): läckage via poolade anslutningar, bakgrundsjobb och outbox utan tenant. Åtgärd: SET LOCAL per transaktion och ett test som misslyckas om tenant saknas. KSON (kommunalförbund) passar inte modellen "huvudman = region" och modelleras som beställare inom regionens tenant tills vidare. Nycklar för pseudonymisering och kryptering är separata per tenant.

Regionpaketen för stockholm och exempel finns som seed i packages/region-stockholm/ och packages/region-exempel/ från F2.

Driftform Beskrivning
En installation per region Vanligast i offentlig sektor. FastTenantKontext.
Multi-tenant SaaS Flera regioner i samma kluster, med RLS och nycklar per tenant.

Regionpaket (packages/region-<namn>/) innehåller allt som är unikt för en region, som versionerad och bitemporal data: regelsammansättningar och parametrar, Kodserver-tabeller, faktureringskalendrar, roller, fakturamottagare med Peppol-adresser, ekonomisystemsadapter, portaltexter och profil (white-label) och begreppsalias. Paketen kan exporteras och importeras i öppet format (KRAV-79). Ett startpaket med nationellt gemensamma regler ingår: riksavtalet, patientavgifter, LOL/LOF-taxan, asyl och EU.

Variation som paketen ska kunna uttrycka: viktlistor med 2–101 åldersgrupper med eller utan kön, ACG-fönster på 15, 18 eller 24 månader, CNI med tröskel och avstämningsrytm, mätdag (1:a, 15:e, 28:e, sista dagen eller dag för dag), utbetalningsdag (5:e, 15:e, 19:e, 20:e eller sista vardagen, ibland förskott) och momskompensation (3,5, 5 eller 6 %).

Verifiering: arkitekturtestet söker efter regionspecifika namn ("Stockholm", "SLL", "HSF") i src/ utanför src/Integrations/. E2E-scenariot körs också mot det fiktiva paketet "Region Exempel". Varje paket levereras med ett körbart scenariobibliotek, eftersom upphandlingar utvärderar på scenarier (till exempel Örebro och Västernorrland med 12 scenarier).

8.6 AI-arkitektur och skydd#

Ersvia är AI-först, men AI påverkar aldrig belopp och ser aldrig personuppgifter (ADR 0007).

Förmåga Var Indata Utdata Mål eller krav
Regelassistent Ersvia.Ai via Ersvia.Mcp och Portal Avtalsbilaga eller rapporteringsanvisning (källdokument med hash), gällande regel Regelutkast i regel-JSON-schemat, diff, simulering Mål 2, KRAV-20
"Förklara min ersättning" Portal Trace för en ersättningsrad (pseudonymiserad) Förklaring med hänvisning till regelrader. Beloppen kommer från motorn. Mål 4, KRAV-59
Avvisningshjälp Vardhandelser → Ersvia.Ai Felkod, fält och regel, utan personuppgifter Förklaring och rättningsförslag KRAV-7, B4
Avvikelseanalys Granskning Aggregerade avvikelser och kontrollflaggor Hypoteser, prioritering och förslag på stickprov KRAV-47
Handläggningsstöd för ansökningar Malrelaterad Ansökan om målrelaterad ersättning Sammanfattning och bedömningsstöd KRAV-45
Förklaring av skillnader vid parallellkörning Migrering Skillnader per vårdgivare Förklaringar KRAV-72, risk 1

MCP-verktyg (byggda i F11a, officiella C#-SDK:t ModelContextProtocol 2.4): vad_gallde, sok_overenskommelse, hamta_regelversion, vardhandelsestatus, listning_ogonblicksbild och forklara_felkod (läsande) samt skapa_regelutkast (skapar bara utkast med status utkast). Autentisering per huvudman med SHA-256-lagrade nycklar; alla svar maskeras mot personnummer, och listning ges bara som aggregat.

Skydd:

  1. All AI går via Microsoft.Extensions.AI.IChatClient. Standard i regionpaketet är en lokal eller svensk modell. Anthropics C#-SDK (claude-opus-5-5) eller en annan extern leverantör kräver explicit aktivering per miljö. FakeChatClient används i CI.
  2. AI körs bara i AI-zonen och får bara pseudonymiserade eller aggregerade data. En utgående filter-mellanvara avvisar anrop som innehåller mönster för personnummer.
  3. AI räknar aldrig belopp. Allt AI-genererat är utkast, märks "AI-genererat" och kräver mänskligt godkännande.
  4. Varje anrop loggas med modell, prompt-hash, verktyg, användare och resultat.
  5. AI kan stängas av per miljö och per förmåga.
  6. En eval-svit (tests/Evals) mäter schematräffsäkerhet, korrekthet mot facit och läckage. Den körs vid byte av modell.
  7. Structured outputs valideras mot regel-JSON-schemat innan utkastet sparas (RV-5002 vid fel).
  8. En extern LLM klassas som tredjelandsöverföring och biträde och är avstängd tills beslut finns (kontroll 3 R5).

AI-register och klassning enligt AI-förordningen#

AI-registret är byggt i F11a och ligger i docs/plan/ai-register.yaml (version 1.0.0, uppdaterad 2026-11-11). Filen bäddas in i Ersvia.Ai och serveras av AI-tjänsten (GET /ai/register) och portalens sida /ai-register. Ersvia.Ai stänger av en funktion som saknas i registret eller är avstängd, och en högriskfunktion kan inte slås på utan FRIA-referens (art. 27). Förordning: (EU) 2024/1689, ändrad genom (EU) 2026/1744; högriskkraven gäller från 2027-12-02. Regelbaserad beräkning är inte AI, och AI fastställer aldrig belopp eller rätt (NK40).

Riskklasserna är minimal (AI-kunnighet enligt art. 4), transparens (upplysning enligt art. 50) och hög (bilaga III p. 5 a: bedömer fysiska personers rätt till vård eller förmån eller profilerar fysiska personer; kräver FRIA, mänsklig kontroll, loggning och dokumenterad bedömning; avstängd som standard).

Id AI-funktion Riskklass Artiklar Mänsklig kontroll Standard
regelassistent Regelassistent transparens 4, 50 Utkast → granskning av controller → publicering av annan person (fyra ögon). Ingen automatisk publicering. på
forklara-vardhandelsestatus Förklara vårdhändelsestatus transparens 4, 50 Förklaringen är information; status sätts av valideringen och kan bara ändras genom rättelse. på
forklara-ersattningsrad Förklara ersättningsrad transparens 4, 50 Förklaringen är information; invändningar hanteras av handläggare. på
avvisningshjalp Avvisningshjälp transparens 4, 50 Vårdgivaren rättar själv och skickar in på nytt; valideringen avgör. på
avvikelseanalys Avvikelseanalys och granskningsurval transparens 4, 50 Handläggare beslutar om granskning och återkrav. av
riskpoang-enskild-naringsidkare Riskpoäng för enskilda näringsidkare (LOL/LOF) hög 6, 26, 27, 50 Krävs men är inte utformad; funktionen är avstängd. av
bedomning-patientavgift-och-ratt-till-vard AI-bedömning av patientavgift, frikort eller rätt till vård hög 6, 26, 27, 50 Krävs men är inte utformad; funktionen är avstängd. av

Varje svar bär upplysningen: "AI-genererad förklaring (art. 50 AI-förordningen). Kontrollera mot regelrad och orsakskod; belopp och beslut kommer alltid från Ersvias regelmotor och handläggare."

Skydd i varje anrop (F11a): registret, pseudonymiseringsfiltret (personnummer blockerar anropet, namn, e-post och telefon maskeras), beloppsvakten (belopp som inte finns i underlaget tas bort), art. 50-upplysningen och en hashkedjad AI-revisionslogg med prompt, svar, modell, syfte och användare. Loggen är en JSON Lines-fil tills Drift (F12) flyttar den till revisionsloggen i PostgreSQL. Adaptrar: Anthropic (claude-opus-5-5, structured outputs, server-side fallback), lokal OpenAI-kompatibel (svensk drift) och FakeChatClient (CI). Profilen per regionpaket (packages/region-*/ai/ai-profil.json) är av som standard; paketen väljer lokal drift, och extern LLM kräver dessutom Ersvia:Ai:TillatExtern i miljön. Anthropic-adaptern är ännu inte testad mot API:t.

Avvikelseanalys (avvikelseanalys) är registrerad men avstängd; Granskningens deterministiska kontrollregler och riskpoäng (F7) är inte AI.

8.7 Felkodskatalog och kompatibilitet#

Fel returneras som ProblemDetails (RFC 9457) med Ersvias stabila felkod felkod (<PREFIX>-<nnnn>) och legacyFelkod (system, kod), så att vårdgivare och servicedesk känner igen felen (ADR 0002). Katalogen ligger i contracts/legacy/felkoder.yaml.

Prefix Modul Prefix Modul
GEN Generella (400, 401, 403, 404, 409, 500) GR Granskning
MD Masterdata FA Fakturering
KV Kodverk AV Avstamning
OK Overenskommelse UP Uppfoljning
VH Vardhandelser MS MedicinskService
VA Vantande LM Lakemedel
LI Listning DR Drift
RA Rapportering SI Simulering
RV Regelverk MR Malrelaterad
BE Berakning
Legacysystem Dagens koder Mappning
GVR (AF v1.4) 0000–0950 VH-* med legacyFelkod.system = GVR
GVR REST v2 147 errorCode i intervallet 0–1099 GvrProblemDetail.errorCode i fasaden
ERSMO AF100–AF330 BE-*
HEJ H0xx–H1xx BE-*
VF 0000–4225 och 9999 FA-*
CVR, ListOn, RAPP Respektive specifikation VA-*, LI-*, RA-*

Katalogen contracts/legacy/felkoder.yaml (F1) har 438 koder och följer numreringen: 0000–1099 har samma nummer som GVR errorCode (GEN, VH, VA), BE-0100–BE-0330 motsvarar ERSMO AFnnn, BE-1000–BE-1999 HEJ Hnnn, FA-0001–FA-0046 VF:s statuskoder, AV-0000/1111/2222/9999 avstämningsstatus OK, Prel, Mak och BeEj, och 5000 och uppåt är Ersvias egna koder.

Felkoderna i SAD:ens körningsvy är synkade mot katalogen:

Felkod Titel i felkoder.yaml Används i Status
GEN-0409 Konflikt (idempotensnyckel med annat innehåll) s01, 8.9 Finns
GEN-0010 Pseudonymiseringsnyckel saknas för huvudmannen Personuppgifter (F2) Finns, används i koden
VH-0202 Personnummer/reservnummer saknas i CFU/SPAR (GVR errorCode 202) s01, s02 Finns, används i F4
VH-0313 Dubblett av X-Resource-Id/externtId s01 Finns, används i F4
VH-5001 Rapporterad efter brytpunkt (KRAV-9) s04 Finns
VH-5002 Rätten till ersättning har förfallit (KRAV-10) t01 Finns
VH-5003 Vårdhändelsen är för gammal för att bearbetas (30 månader) t01 Finns
LI-5001 Omlistning inte tillåten s03 Finns (tidigare LI-2001 i SAD v1)
LI-5002 Listningstaket är nått s03 Finns
RV-5001 Godkännande kräver en annan person (KRAV-21) s06 Finns (tidigare RV-2001)
RV-5002 Regeldokumentet är ogiltigt (mot regelschemat) s10 Finns (tidigare RV-2101)
RV-5003 Överlappande giltighet s06 Finns
GR-5001 Justering kräver motivering (KRAV-48) s08 Finns
GR-5002 Attest kräver en annan person med attesträtt (KRAV-49) s07 Finns (tidigare GR-3001)
FA-5002 Invändningsfristen har passerat (KRAV-51) s08 Finns
FA-5003 Beslut om tillägg kan inte ändras (KRAV-52) s08 Finns
FA-5006 LMA- eller dossiernummer saknas (KRAV-38) s07, t03 Finns, används i F8
FA-5018, FA-5019, FA-5021 Självfakturering kräver godkännande; egenattest spärrad; utomlänskrav bestrids efter fristen s07, s09 Finns, används i F8
KP-5003, KP-5004 Ogiltigt billing:claim-underlag; ändamål saknas för utlämning s09, s15 Finns, används i F8
UP-5003, UP-5004, UP-5005 Personnummer i nationell fil; VAL-typer levereras från patientdatazonen; ändamål saknas för VAL-uttag s15 Finns, används i F10/F12a
AV-5001 Avstämning 5.3 Finns, används i F8
FA-5101 Utomlänsunderlag äldre än 6 månader (riksavtalet) s09 Planerad, läggs in i katalogen i F8
BE-5004 Stängd period: torrkörning krävs, och genomförandet måste ha samma manifesthash s05 Finns, används i F6
RA-5002–RA-5012, KP-5001–KP-5002 Rapportering och kompatibilitetsfasaden 5.2 Finns, används i F9a

Orsakskoder (planen 4k): katalogen byggs ut till en publik och versionerad katalog över orsakskoder, i stil med CARC/RARC. Varje kod anger vem som bär beloppet (vårdgivaren, regionen, annan huvudman), vilken åtgärd som krävs (rätta, komplettera, ingen) och är kopplad till den regelrad som gav anmärkningen. Katalogen publiceras tillsammans med kontrakten och versioneras bitemporalt.

Kompatibilitetsregler för kontrakt: OpenAPI-diff i CI. Brytande ändringar kräver ny version (/api/<modul>/v2). Händelsetyper har versionssuffix (.v1). Gamla versioner stöds i minst 12 månader. Legacykontrakten (GVR v1.9.5 och v2.0.0, SNOD-XML, CVR, VF) testas med paritetstester som genereras direkt ur specifikationerna.

8.8 Händelser och outbox#

ArchiMateArchiMate: applikationssamverkan och gränssnittLadda ned SVG: ArchiMate: applikationssamverkan och gränssnittLadda ned PUML: ArchiMate: applikationssamverkan och gränssnitt

  • Integrationshändelser (IIntegrationshandelse.HandelseTyp) namnges ersvia.<Handelse>.v<n> (t.ex. ersvia.VardenhetRegistrerad.v1) enligt AsyncAPI-kontraktet contracts/asyncapi/ersvia-events.yaml (23 händelser i F1). Kanalerna heter ersvia.{huvudman}.<modul>.v1. ADR 0006 är reviderad och anger nu samma form. Interna jobb som inte lämnar modulen har prefixet ersvia.intern. (t.ex. ersvia.intern.ValideringBegard.v1). Händelserna skrivs till modulens outbox i samma transaktion som domänändringen (IOutbox.LaggTillAsync).
  • OutboxBearbetare publicerar via IHandelsePublicerare med minst en gång-leverans. Mottagarna är idempotenta, med händelse-id som dedupliceringsnyckel.
  • I MVP sker publiceringen in-process. Publiceraren kan bytas mot Kafka eller regionens integrationstjänst utan att modulerna ändras.
  • Händelser från patientdatazonen till ersättningszonen pseudonymiseras innan de lämnar zonen.
  • Outboxen är persistent per schema (<schema>.outbox) från F2, och händelsen skrivs i samma transaktion som versionen (ADR 0011).
  • Händelser som saknas i AsyncAPI-kontraktet och är planerade: ersvia.InsamlingsperiodStangd.v1, ersvia.FolkbokforingAndrad.v1, ersvia.DifferensunderlagSkapat.v1, ersvia.AvvikelseFlaggad.v1, ersvia.KontrollarendeOppnat.v1, ersvia.AterkravBeslutat.v1, ersvia.FakturaunderlagSkapat.v1 och ersvia.AvstamningsfilKlar.v1. De läggs in i kontraktet i den fas som bygger utgivaren.
Händelse Utgivare Mottagare
ersvia.VardgivareRegistrerad.v1, ersvia.VardenhetRegistrerad.v1 (byggda F2) Masterdata Vardhandelser, Listning, Overenskommelse
ersvia.KodverksversionPublicerad.v1 (byggd F2) Kodverk Vardhandelser, Berakning
ersvia.OverenskommelseAndrad.v1 (byggd F2) Overenskommelse Vardhandelser, Berakning
ersvia.VardhandelseMottagen.v1, …Avvisad.v1, …Rattad.v1, …Makulerad.v1, …StatusAndrad.v1 (byggda F4) Vardhandelser Berakning, Avstamning, Uppfoljning, Granskning
ersvia.VantandeRapporterat.v1 (byggd F4) Vantande Uppfoljning
ersvia.ListningAndrad.v1 (byggd F5) Listning Malrelaterad, Uppfoljning
ersvia.InsamlingsperiodStangd.v1 Vardhandelser Berakning
ersvia.ListningsunderlagFaststallt.v1 (byggd F5) Listning Berakning, Malrelaterad, Uppfoljning
ersvia.RegelversionPublicerad.v1, ersvia.ParametertabellPublicerad.v1 (byggda F3) Regelverk Berakning (retroaktiv kontroll), Simulering
ersvia.BerakningKlar.v1 (byggd F6, bara ordinarie körning) Berakning Granskning, Avstamning
ersvia.SimuleringKlar.v1 (byggd F6) Simulering Portal
ersvia.DifferensunderlagSkapat.v1 Berakning Fakturering
ersvia.UnderlagAttesterat.v1 Granskning Fakturering
ersvia.AterkravBeslutat.v1 Granskning Fakturering
ersvia.FakturaforslagSkapat.v1, ersvia.UnderlagGodkant.v1, ersvia.UnderlagInvandning.v1, ersvia.FakturaSkickad.v1, ersvia.BudgetjusteringBokford.v1 (byggda F8) Fakturering Avstamning, Portal (aviseringar), Uppfoljning
ersvia.UtbetalningKvitterad.v1 (byggd F8) Fakturering Avstamning, Uppfoljning, Portal

8.9 API-konventioner#

  • REST under /api/<modul>/v1/... (t.ex. /api/masterdata/v1/vardgivare), med en OpenAPI-fil och en server-URL per modul, och svenska resursnamn utan å/ä/ö. JSON i camelCase.
  • ?giltigVid=&kandVid= på alla läs-API:er för versionerad data.
  • Offsetpaginering med offset och grans (högst 1000), samt X-Totalt-Antal.
  • Idempotens med headern Idempotens-Nyckel (UUID) för skrivningar. Samma nyckel och samma innehåll ger samma svar, och samma nyckel med annat innehåll ger 409 (GEN-0409).
  • Optimistisk låsning med ETag och If-Match.
  • X-Korrelations-Id följer med genom hela kedjan och i OpenTelemetry.
  • Långa körningar returnerar 202 Accepted med en Jobb-resurs.
  • OpenAPI publiceras på /openapi/v1.json och i regionens API-portal (Anypoint Exchange eller motsvarande).

8.10 Observability#

Signal Innehåll Mål
Spår (OpenTelemetry traces) Anrop från gateway genom modul, outbox och adapter, med X-Korrelations-Id och huvudman Felsökning över modulgränser
Mått Kölängd och ålder på äldsta meddelande per kö (validering ≤ 1 h), körningstid per beräkning (≤ 4 h), antal avvisade per felkod, outbox-eftersläpning, integrationsstatus Larm och kapacitetsplanering
Loggar Strukturerade loggar utan personuppgifter. Personuppgifter loggas bara i revisionsloggen. Drift
Integrationsstatus GET /drift/integrationer: senaste lyckade körning, antal poster och fel per integration (drift.integrationskorning) KRAV-68
Datakvalitet Andel LF och RF per vårdgivare och felkod, sena rättelser Risk 4

Telemetrin skickas med OTLP till regionens observabilitetsplattform. Lokalt visas den i Aspire-dashboarden.

8.11 Arkiv, gallring och export#

Byggt i F10 och F12a (ADR 0018, 0020). Detaljerna finns i docs/drift/earkiv-och-gallring.md.

E-arkiv enligt FGS Paketstruktur 2.0#

Jobbet --jobb earkiv --period <år|månad> (CronJob den 15 januari för föregående år) bygger ett informationspaket (SIP) med Ersvia.Arkiv.FgsPaket enligt E-ARK CSIP:

Del i paketet Innehåll
METS.xml (rot) CSIP-profil, OBJID, TYPE, innehållstyp, metsHdr med SIP, agenter (ARCHIVIST, CREATOR, OTHER), altRecordID (leveransöverenskommelse, start- och slutdatum, åtkomstbegränsning, gallringsinformation), dmdSec, amdSec/digiprovMD, fileSec och structMap
metadata/descriptive/arkivbeskrivning.xml Arkivbildare, arkiv, period, informationsmängder
metadata/preservation/premis.xml PREMIS 3: objekt med SHA-256 och storlek, skapandehändelse, agent
representations/rep1/ Representationens METS och data i öppna format (JSON, CSV) med manifest.json
schemas/, documentation/gallringsinformation.json JSON Schema för manifestet och gällande gallringsfrister

Inte validerat ännu: paketet har inte körts genom Riksarkivets eller E-ARK:s valideringsverktyg. METS- och PREMIS-XSD bäddas inte in, och arkivbeskrivningen är en förenklad XML i stället för EAD. Detta stäms av med Regionarkivet.

Gallring per regionpaket#

Gallringsfristerna ligger versionerade per informationsmängd i packages/region-*/drift/gallring.json med värden ur Regionarkivets BG-planer:

Informationsmängd Frist (Region Stockholm, förslag)
Verifikationer, filöverföringar till ekonomisystem, reskontra och momsunderlag 7 år (LKBR, t.o.m. sjunde året efter räkenskapsåret)
Fakturaunderlag 7 år om obligatoriska uppgifter ingår, annars 2 år
Transaktions- och ändringsloggar i ärendesystem 10 år
Behandlingshistorik för redovisning, ersättningsunderlag och manifest Bevaras eller 10 år
Säkerhets- och åtkomstloggar Minst 5 år (kortare frist avvisas)
Regelversioner, beslut, källdokument, överenskommelser, godkända LOV-ansökningar, viten Bevaras
Ej godkända LOV-ansökningar 2 år

Gallringsjobbet (--jobb gallring [--torr], CronJob per zon) följer fyra regler:

  1. Arkivbevarande går först. En källa som ingår i en informationsmängd som ska bevaras spärras helt, och finns den i flera mängder gäller den längsta fristen.
  2. Bitemporal gallring. En nyckels versioner gallras bara tillsammans: när alla gällande versioner har upphört att gälla före gränsen och ingen version registrerades eller ersattes efter gränsen. Det som finns kvar har därför alltid hel historik och obruten hashkedja, så att "vad gällde när" fortsatt kan besvaras.
  3. Egen roll. Jobbet kör som zonens gallringsroll med DELETE-behörighet; skyddstriggern tillåter DELETE bara när ersvia.gallring = 'pagar' är satt i transaktionen och rollen är medlem. Applikationsrollen kan aldrig radera versionerad data.
  4. Spårbarhet. Varje åtgärd loggas som säkerhetshändelse med informationsmängd, frist, fristversion, beslutsreferens, gräns och antal.

Samråd med Regionarkivet krävs före införandet; kopplingen mellan källor och tabeller i gallring.json är ett förslag till det samrådet.

Full export (KRAV-79)#

--jobb export och POST /api/drift/v1/exporter skriver varje informationsmängd som JSON och CSV (RFC 4180, semikolon, UTF-8 utan BOM) med manifest.json (SHA-256, storlek och antal poster per fil). Portalen visar 15 månaders historik; resten finns i arkivet.

8.12 Test och kravspårning#

Testnivå Katalog Exempel
Enhet och egenskaper tests/Ersvia.Tests.Unit BitemporalEgenskaper, BeloppTester, IntegritetTester (manifest, hashkedja)
Arkitektur tests/Ersvia.Tests.Architecture ModulgransTester (KRAV-71, KRAV-78), RegionoberoendeTester (KRAV-76)
Kontrakt tests/Ersvia.Tests.Kontrakt OpenAPI, AsyncAPI, regelschema och legacykontrakt; alla OpenAPI-exempel valideras mot sina scheman; route-test jämför endpoints med kontraktens operationer
Integration tests/Ersvia.Tests.Integration Testcontainers med PostgreSQL: as-of, rättelse, exclusion constraint, triggrar, RLS mellan stockholm och exempel, outbox, åtkomstlogg (F2)
Golden (facit) tests/Golden En golden file per mall, majkörningen 2026
Kompatibilitet tests/Compatibility Paritet mot GVR v2.0.0/v1.9.5, CVR, VF-fil, AF-rapport, paritetsmatris
E2E tests/E2E Månadsscenariot i planen avsnitt 9, även mot "Region Exempel"
Tillgänglighet tests/Accessibility axe mot Portal (KRAV-69)
Last tests/Load NBomber: validering ≤ 1 h, månadsberäkning ≤ 4 h
AI-eval tests/Evals Regelassistent mot facit, läckagetest

Tester taggas med [Krav("KRAV-n")]. CI exporterar JUnit-resultat som laddas upp till TestViora, så att kravtäckningen syns där.

8.13 Användbarhet och tillgänglighet#

Portalen (se kapitel 5.5) är en Blazor Web App med server-rendering och följer WCAG 2.2 AA (KRAV-69): tangentbordsnavigering, synlig fokus, kontrast, skärmläsarstöd och felmeddelanden i klartext. Automatiska axe-tester körs i CI, och manuella tester görs med skärmläsare. Användartest före driftstart visar att controllers och vårdgivare klarar en regeländring och en månadsgranskning efter högst en dags utbildning (KRAV-77). Portalen kan märkas med regionens profil (white-label) och har svenska som grundspråk.

8.14 Begrepp och informationsmodell (NIM, VOK och termbanken)#

Planen avsnitt 4h styr hur Ersvias domänmodell förhåller sig till nationella begrepps- och informationsmodeller.

Termbanken som referensdata. Socialstyrelsens termbank 4.3.6 (TBX, CC0) importeras som referensdata i Kodverk. Varje begrepp i domänen har ett termbankTid med stabil länk, och mappningen underhålls i begreppsmappning.csv. Begreppen delas in i fyra grupper (se kapitel 12):

Grupp Begrepp Hantering
Används direkt vårdgivare, vårdenhet, vårdkontakt, vårdtillfälle, patient, reservnummer Termbankens definition och termbankTid
Avviker eller avråds "sjukvårdsinrättning" (avrådd term) används inte. "Hälso- och sjukvårdsutbud" betyder i termbanken själva utbudet, inte överenskommelsen. Vardutbud används bara om utbudet. Överenskommelsen heter Overenskommelse.
Ersvias egna definitioner patientavgift, frikort, högkostnadsskydd Termbankens versioner gäller läkemedel eller är föråldrade. Definieras utifrån HSL 17 kap.
Egna begrepp som saknas i termbanken huvudman, avtal, uppdrag, DRG, kapitering och ekonomibegreppen Ersvias ordlista är källan och markerar dem som "egna"

Informationsmodellen följer NIM (E-hälsomyndighetens nationella informationsmodell, informationsstruktur.ehalsomyndigheten.se, JSON-API) och VOK (informationsspecifikationen Organisation och verksamhet):

NIM/VOK-begrepp Ersvia Kommentar
Organisation Huvudman, Vardgivare och Vardenhet är typer av en gemensam Organisation Påverkar d01 och masterdata
Avtal, Uppdrag (VOK) Avtal och Uppdrag (i egen regi) med VOK-attribut Mappas mot FHIR-profilerna HVOContract och HVOOrganizationAffiliation
Vårdkontakt, aktiviteter, diagnoser, deltagande Vardhandelse är en sammanställning av dessa Patientregistrets variabel AVTAL och DRG, MDC och RTC ingår, så att Ersvia kan leverera till patientregistret (HSLF-FS 2023:33 och 2026:27)
Aktivitet Aktivitet (åtgärd) ersätter "Hälso- och sjukvårdsåtgärd" Byter inte status och lagras oföränderlig
(saknas) Ersattningsprodukt ersätter "Produktkod"
Nya begrepp DrgResultat (med RTC och versioner), väntetid som två separata mått, Vardepisod, KostnadsansvarigHuvudman, Listningsko Läggs in i klassdiagrammen d02, d03 och d05 när F3–F7 byggs
Vårdkontakt och Vårdbegäran (utkast i NIM) Följs, men mappningen versioneras Ändringar i NIM blir nya mappningsversioner

Diagrammen d01–d08 visar F0/F1-läget. Ändringarna ovan förs in i diagrammen efter F2 och F3 (öppen punkt C.4).

8.15 Förädlingar efter benchmark (planen 4k)#

Benchmarken jämförde Ersvia med 13 lösningar (bland andra NitCore, Privera, Vera Asyl, LOGEX, KUHR, LUNA, KBV Prüfmodul, SUS+, LAMDA/T2A och CMS PRICER) på 33 förmågor. Ingen av dem har bitemporal versionering med transaktionstid, så Ersvia behåller sin egen motor och lånar DMN:s semantik. Följande läggs in i MVP:n:

# Förädling Förebild Arkitektur i Ersvia Fas
1 Inskickets livscykel: mottagen → kontrollerad → beslutad → utbetald, asynkron och idempotent, med anmärkningskoder per rad, webhooks och tre statusdimensioner (teknisk, kontroll, ekonomisk) KUHR Vardhandelser och Rapportering (status), Avstamning (vy), webhooks från outboxen. Diagram t05. F4, F8
2 Publik och versionerad katalog över orsakskoder: vem som bär beloppet, vilken åtgärd som krävs, koppling till regelraden CARC/RARC Utbyggnad av contracts/legacy/felkoder.yaml (kap. 8.7) F4–F8
3 Torrkörning före inskick: POST /…/validera validerar utan att spara. I R2 ett inbäddbart valideringspaket med certifieringssvit. KBV Prüfmodul Vardhandelser (/vardhandelser/{id}/validering och torrkörning), samma Valideringskedja F4
4 Konsultationsversion av nästa års regelpaket, som vårdgivare och nämnd kan simulera mot NPK, IHACPA Regelpaket med status konsultation och egen giltighet, körs i Simulering F7
5 Frysdatum och namngivna ögonblicksbilder: aktuell, avstämd och slutlig per period SUS+ Berakning (underlagssnapshot med namn och frysdatum i faktureringskalendern). Manifestet refererar ögonblicksbildens hash. F6
6 Riskbaserad efterkontroll med regler, riskpoäng och ärenden. AI-stöd och spårbar ROI i R2. Granskning (kap. 5.4, s11) F7
7 Beslutstabeller med explicit hit policy och kontroll av luckor och överlapp DMN Regelverk (kap. 8.3) F3
8 Skuggkörning: en ny regelversion och ERSMO/HEJ körs mot samma underlag, och skillnader förklaras Simulering och Migrering. Legacyutfall importeras som legacy-manifest med källsystem och hash (kontroll 3 R11). F7, F10
9 KPI-jämförelse av simuleringar som underlag för nämnden Simulering, Uppfoljning F7
10 Portal med drill-down och export. Rättelse per rad med frist, och ostridiga belopp betalas ut även när andra rader är bestridda. Portal, Fakturering (delbetalning av ostridiga rader), Avstamning F8, F11
11 Korrigering av stängda perioder: rättelsen värderas som skillnaden mot tidigare utfall och torrkörs innan den genomförs LAMDA Berakning (Differensberaknare) och Fakturering (differensunderlag), s05 F6, F8
12 Bevis vid publicering: testkörningen mot facit hashas och sparas med regelversionen Regelverk (Facittestkorare) F3

TillståndTillstånd: inskickets livscykel med tre statusdimensioner (4k)Ladda ned SVG: Tillstånd: inskickets livscykel med tre statusdimensioner (4k)Ladda ned PUML: Tillstånd: inskickets livscykel med tre statusdimensioner (4k)

R2 och senare: vårdgivarprognos ("vad får jag?"), inbäddbar validering, DMN-export med Drools som testorakel, en publik referenskalkylator per region och en förvaltningsmodell för flera regioner.

Positionering: modulpaket som kan offereras för 4–6 MSEK (till exempel utbetalning till privata vårdgivare, där Ersvia konkurrerar med NitCore och Privera), en asylmodul (Vera Asyl är i praktiken ensam, och Migrationsverket ställer om sin e-tjänst 2026) och ett körbart scenariobibliotek per anbud. Avtal att bevaka: NitCore Örebro 2028-10-31, Vera Asyl Skåne 2027-12-17 och VGR asyl 2028-04-22.

Ersvia SAD · version b706ca6 (2026-11-11) (med ändringar som inte är incheckade) · byggd 2026-11-11 · Ändringslogg · Diagramgalleri · Källa: docs/arkitektur/kapitel/08-tvargaende-koncept.md

Sök i dokumentet

100 % Ladda ned SVG