| 0001 Modulär monolit med zoner |
En deploybar Api-host med moduler (IModul), ett projekt och ett schema per modul, två zoner |
Beslutad (F0) |
KRAV-71, KRAV-78 |
Mikrotjänster från start (för dyr drift för ett litet team); en monolit utan gränser (blir ny teknisk skuld) |
En modul kan brytas ut till egen tjänst utan att kontrakten ändras. Zonerna körs som separata driftsättningar av samma image. |
ModulgransTester |
| 0002 Kontrakt först |
OpenAPI 3.1 och AsyncAPI i contracts/, kompatibilitetsfasad för legacyformat, ProblemDetails med stabil felkod |
Beslutad (F0), genomförs i F1 |
KRAV-71 |
Kod först med genererad OpenAPI (instabila kontrakt) |
Brytande ändringar kräver ny version. Kontrakten publiceras i API-portalen. |
tests/Ersvia.Tests.Kontrakt, OpenAPI-diff |
| 0003 Regler är versionerad data |
Beslutstabeller, åtta primitiver, 42 mallar, fyra ögon, facittest |
Beslutad (F0), genomförs i F6–F7 |
KRAV-19 till KRAV-23 |
Regler i kod (mål 2 nås inte); en generell regelmotor av BRMS-typ som Drools (svår att förstå för verksamheten, risk 2) |
Belopp med Belopp och explicit Avrundningsregel. Regionpaket innehåller bara parametrar och sammansättningar. |
Golden-tester per mall, FsCheck |
| 0004 Bitemporal versionering |
Valid time och transaction time på allt som styr ersättningen, giltigVid och kandVid i API:erna |
Beslutad (F0) |
KRAV-3, KRAV-22, KRAV-36, KRAV-55, KRAV-73 |
Bara giltighetstid (kan inte svara på "vad visste vi?"); händelselogg med event sourcing överallt (för komplext) |
Historiken växer append-only. Exclusion constraints i PostgreSQL. |
BitemporalTester, BitemporalEgenskaper |
| 0005 Reproducerbarhet med manifest och hashkedja |
Manifest med versions-id, motorversion och underlagssnapshot. SHA-256 över kanonisk JSON. Hashkedja. |
Beslutad (F0) |
KRAV-22, KRAV-36, KRAV-55, KRAV-67 |
Spara bara resultat (kan inte reproduceras) |
Samma manifest och underlag ger samma resultat. All tid från IKlocka. |
IntegritetTester |
| 0006 Händelsedrivet med transactional outbox |
Outbox per modulschema, minst en gång-leverans, idempotenta mottagare. Händelsenamn ersvia.<Handelse>.v<n>, kanaler ersvia.{huvudman}.<modul>.v<n>, interna jobb ersvia.intern.* |
Beslutad (F0), reviderad 2026-11-11 |
KRAV-71 |
Direkta anrop mellan moduler (stark koppling); meddelandekö utan outbox (förlorade händelser) |
Händelsetyper med versionssuffix. Publiceraren kan bytas mot Kafka eller Integrationstjänsten. |
OutboxOchRevisionTester |
| 0007 AI-gränser |
IChatClient, bara ersättningszonen, pseudonymiserade data, aldrig belopp, alltid utkast, avstängningsbart, eval-svit |
Beslutad (F0), genomförs i F10 |
Mål 2 och 4, KRAV-7, KRAV-45, KRAV-47 |
AI som beräknar eller beslutar; leverantörsbundet SDK i modulerna |
MCP-verktygen är läsande eller skapar utkast. Lokal modell är standard. |
tests/Evals |
| 0008 Säkerhet och revisionslogg |
mTLS med SITHS, OIDC/SAML, roll och vårdgivare, hashkedjad revisionslogg per tenant |
Beslutad (F0) |
KRAV-6, KRAV-66, KRAV-67, TV-regel 12 |
Loggning bara i applikationsloggar (går att manipulera) |
Persistent logg och e-arkivleverans kommer i F2 och F12. |
OutboxOchRevisionTester.Revisionsloggen_ar_hashkedjad |
| 0009 Enhetlig domän och öppna standarder |
Overenskommelse = Avtal | Uppdrag, termbankens begrepp, HSA-id och NVID som externa identiteter (primärnyckeln preciseras i ADR 0011), Peppol, FGS |
Beslutad (F0) |
KRAV-1, KRAV-37, KRAV-75, KRAV-76, KRAV-79 |
Separata flöden för egen regi |
Egen regi får budgetjustering. Identifierare utan å/ä/ö. InvariantGlobalization. |
HsaIdTester |
| 0010 Produkt för flera regioner |
Huvudman är tenant, regionpaket, adaptrar per region, gemensamt regelbibliotek |
Beslutad (F0) |
KRAV-76, KRAV-79 |
Ett Stockholmsunikt system |
Standardhuvudman i konfigurationen är exempel. E2E körs mot "Region Exempel". |
RegionoberoendeTester |
| 0011 Bitemporal persistens, outbox per schema och radnivåsäkerhet |
Ersvia.BuildingBlocks.Persistens: en tabell per bitemporal entitetstyp (giltig daterange, registrerad tstzrange, data jsonb, hashkedja), exclusion constraint med btree_gist, oföränderlighetstrigger, IBitemporalLager<T> i minne och PostgreSQL, outbox och revisionslogg per schema, RLS med app.huvudman, EF-migrationer per modul. Id-modell: vg-, ve-, ok-, bn-, fm-, eg- primära, HSA-id och övriga som bitemporala alias. |
Beslutad (F2) |
KRAV-3, KRAV-16, KRAV-17, KRAV-18, KRAV-22, KRAV-36, KRAV-67, KRAV-76 |
En tabell per entitet med egna kolumner (fler migrationer per regeländring); event sourcing |
Samma FsCheck-modell mot båda lagren. Listfrågor filtrerar i minnet (räcker för masterdata och avtal, inte för vårdhändelser). Idempotensnycklar i processens minne i MVP. |
Integrationstester med Testcontainers (as-of, rättelse, constraint, triggrar, RLS, outbox, åtkomstlogg) |
| 0012 Vårdhändelser med partitionering, inskickslivscykel och portar |
vardhandelse en rad per version, PARTITION BY RANGE (period); oföränderlighetstrigger; idempotens i samma transaktion; tre statusdimensioner; asynkron validering med FOR UPDATE SKIP LOCKED; faktureringsmånad med brytpunkt och frysning; portar via kompositionsroten |
Beslutad (F4) |
KRAV-6 till KRAV-10, KRAV-14, KRAV-15, KRAV-61, KRAV-67 |
Generiska _version-tabeller (för långsamt för 25 miljoner per år) |
Väntande som dokument. GVR v2-fasaden i F9 mappar mot IVardhandelser. |
VardhandelseIntegrationTester, VardhandelseLasttest (4,2 min för 70 000) |
| 0013 Regelmotorn som rent bibliotek |
Ersvia.Regelmotor utan I/O; elva primitiver inklusive episod; beslutstabeller med träffpolicy (unik, forsta, prioritet, alla, summa); uttryck som JSON eller formel; nio körfaser i fyra körnivåer med DAG; trace och resultathash; 34 mallar som täcker alla 42 regeltyper; facit och testbevis |
Beslutad (F3) |
KRAV-19 till KRAV-23, KRAV-36; NK1, NK40 |
Generell BRMS (Drools) som motor; kodade specialmallar per regeltyp |
Nya former med sammansatt. Kvar till F6/F7: mätning vid flera tidpunkter, riskpott i tandvård, LOL-undantag över tak 2, arvoden som passerar tak 1 mitt i ett besök. |
tests/Golden (51 facitfiler), tests/Ersvia.Tests.Unit/Regelmotor |
| 0014 Listning med intervall-lagring och regler per regionpaket |
Listning som bitemporalt intervall ({pseudonym}|{listningstyp}), låst ögonblicksbild med SHA-256, listningsregler som data per regionpaket bakom IListningsregelkalla, portar i kompositionsroten, ICarelistingProducent och IStatligListningstjanst |
Beslutad (F5) |
KRAV-12, KRAV-18, KRAV-22, KRAV-24, KRAV-36, KRAV-67, KRAV-76; NK17–NK19, NK22 |
Listning per vårdgivare och dag (cirka 900 miljoner rader per år) |
Listfrågor och aggregering i minnet; ögonblicksbildens poster som dokument; flyttas vid lasttestet i F6 |
ListningIntegrationTester, tests/Ersvia.Tests.Unit/Listning |
| 0015 Beräkning med låst manifest, ackumulerade regler och fakturamottagare som regionpaketsdata |
Portar i Berakning.Kontrakt (regler, masterdata, överenskommelser, vårdhändelsebild, listningsbild, FUMS/FUL) med adaptrar i BerakningKopplingar; manifest med versions-id och hash för regler, tabeller, masterdata, överenskommelser, kodverk, konfiguration, vårdhändelsebild, listningsbild, kostnadsunderlag, tidigare körningar och motorversion; regelval per vårdgivare via ersättningsgrund och omfattning, avtalsparametrar som JSON merge patch; ackumulerade regler i ett andra pass; fakturamottagare med beslutstabell (FIRST) i regionpaketet; omräkning med differensrader, torrkörning krävs för stängd period (BE-5004); skuggkörning och simulering sparas inte som gällande |
Beslutad (F6) |
KRAV-24 till KRAV-38, KRAV-40, KRAV-55, KRAV-64, KRAV-65; NK19, NK27 |
Läsa bitemporala tabeller per rad; specialkod per avtal |
Körningen är synkron (202 med avslutat jobb); efterregistrerade händelser räknas inte i inkommande faktureringsmånad (F8); momskompensation omfattar inte ackumulerade regler; rader och trace som dokument |
BerakningLasttest (4,5 min för 2 miljoner händelser), facit maj 2026, Region Exempel i CI |
| 0016 Portal, AI-tjänst och MCP-server |
Tre värdar (Ersvia.Api, Ersvia.Mcp med MCP och /ai/*, Ersvia.Portal); portal och AI-tjänst anropar Api via Ersvia.Klient; tema per regionpaket; OIDC med roller; IErsviaAi ovanpå IChatClient med Anthropic, lokal och Fake; AI-register, pseudonymiseringsfilter, beloppsvakt, art. 50 och hashkedjad AI-revisionslogg; regelassistent som bara skapar utkast; MCP med läsverktyg och ett utkastverktyg |
Beslutad (F11a) |
KRAV-5, KRAV-69, KRAV-77; NK26, NK40 |
AI i portalen; AI-leverantörens SDK direkt i modulerna |
AI-revisionslogg som fil tills F12; portalsidor för Beräkning, Granskning, Fakturering och Avstämning är platshållare (F11b); axe-tester utanför dotnet test |
tests/Ersvia.Tests.Ai (37), portaltester (25), PortalOchAiTester |
| 0017 Målrelaterad ersättning och Granskning som moduler ovanpå Beräkning |
Indikatorer och kontrollregler versioneras som regler (bitemporalt, fyra ögon, facit) men i egna moduler; måluppfyllelse, årsavstämning och ansökningar; bokföring via BokforTillaggAsync; deterministiska kontrollregler; riskpoäng som profilering, av som standard; ärenden med återkrav, ränta, preskription och kvittning; justeringar och attest i två steg; riskregister och årsrapport |
Beslutad (F7; numrerad om från 0016) |
KRAV-41 till KRAV-49, KRAV-21 till KRAV-23, KRAV-67; NK3–NK7, NK26, NK27 |
Indikatorer i Regelverk; AI för urval |
Beloppsnivåer i matriserna och referensräntor är exempelvärden; kvittning verkställs i F8 |
Enhets- och integrationstester för Malrelaterad och Granskning |
| 0018 Uppföljning, exporter, parallellkörning och skuggning |
Modulerna Uppfoljning, Migrering och Drift; exportpaket med manifest (CSV, Parquet, JSON); personnummerkontroll före utlämnande; bitemporal budget; publicering med cellundertryckning; parallellkörning med deterministisk klassning; legacy-körningar med eget manifest; skuggning via GVR-fasaden; integrationslogg |
Beslutad (F10) |
KRAV-62, KRAV-63, KRAV-67, KRAV-68, KRAV-72, KRAV-73, KRAV-75, KRAV-79 |
Direktläsning av vårdhändelser i Uppföljning; synkron skuggning i drift |
Skuggningskön i minnet tappar anrop vid omstart; leveranser som base64-dokument; KPP- och patientregisterlayout tolkad |
Golden-test för fördelningen, integrationstester |
| 0019 Fakturering, avstämning och utlämningsexport |
Underlag per vårdgivare × fakturamottagare × faktureringsmånad; MOMSK-AVTAL på allt fakturerat; förslag → godkännande/invändning → attest i två steg → Peppol BIS 3 med kvittens; ostridiga rader betalas ut; faktureringsmånad = mottagningsmånad; utlämningsexport i patientdatazonen bakom IIdentitetsutlamning; billing:claim som avsändare och mottagare; avstämning med drill-down via trace; VF-.prn och AF-Excel i Kompatibilitet |
Beslutad (F8, F9b) |
KRAV-38, KRAV-39, KRAV-50 till KRAV-61; NK8, NK9, NK21, NK33 |
Personnummer i fakturaunderlag; egen kopia av raderna i Avstämning |
Regionspecifika namn och Peppol-adresser i regionpaketet; belopp per vårdhändelse är en fördelning; .prn och billing:claim-XML ska verifieras mot verkliga filer och XSD |
Enhets-, kontrakts- och integrationstester; paritet VF och AF |
| 0020 Fysisk zonseparation och drift |
IModul.Zon och Ersvia:Zon med värdarna Ersvia.Patientdata och Ersvia.Api; zonbrygga med mTLS, vitlista och personnummervakt; databasroller per zon; INyckelkalla/KMS; Docker-images och Helm (OpenShift restricted SCC, nätpolicyer, cert-manager, Route, HPA, PDB, CronJobs); OTel; WAL/PITR med RPO ≤ 5 min och återläsningstest; FGS-paket, export och bitemporal gallring. Tillägg F12a: VAL-export med personnummer i klartext från patientdatazonen. Tillägg F12b: F8-adaptrarna uppdelade per zon med de nya portarna IVardhandelsestatusunderlag (patientdata → ersättning, orsakstexter tvättade), IAfUnderlag, IKompatibilitetFakturering och IKompatibilitetReferens (ersättning → patientdata); personnummervakten gäller åt båda håll (422 GEN-0503); vårdhändelsebildens hash avser indata, så att reproduktionen blir bit för bit; låst listningsbild återanvänds (LI-5013) |
Beslutad (F12a), tillägg F12b |
KRAV-18, KRAV-67, KRAV-68, KRAV-70, KRAV-75, KRAV-79; NK19, NK22, NK24 |
Bara logiska zoner; en databasroll |
Zonbryggan är synkron HTTP (kan ersättas av händelsebuss); AF-rapporten gör zonhopp patientdata → ersättning → patientdata; i compose går zonbryggan utan mTLS |
Arkitekturtester för zonportar, ArgumentvaktTester, ZonvardTester, E2E i delat zonläge (24/24), fullstack-smoke (15/15), återläsningstest, Trivy och SBOM i CI |
| 0021 GUI v2: designriktning |
Appskal med smalt toppfält, Ctrl+K, rollväljare och sidomeny per arbetsflöde; startsidor per roll (kakan ersvia.roll, bara visning); tokens v2 med neutrala ytor och accent bara för åtgärder, Inter från design/fonts; komponentbibliotek (Kpikort, Datatabell, Dialog, toasts m.fl.); WCAG 2.2 AA utan inline-skript; SAD-sajten i samma riktning |
Beslutad (GUI v2) |
KRAV-5, KRAV-69, KRAV-77 |
Färgat sidhuvud per region; ett skal utan arbetsflödesgrupper |
Tilläggsbeslutet (K52) bekräftas i en modal dialog; regionpaket som vill ha färgat sidhuvud avråds |
axe 67 granskningar, 0 överträdelser; sad-sajt.mjs; 54 bUnit-tester |
| 0022 Vertical slices i enkla moduler, DDD-lager i rika |
Modulär monolit, portar och adaptrar och ren regelmotor behålls. DDD-lager i Regelverk, Berakning, Fakturering, Granskning, Listning, Vardhandelser, Malrelaterad och Overenskommelse; vertical slices (Features/<Namn>/ med request, handler, validering och endpoint) i Kodverk, Masterdata, Uppfoljning, Rapportering, Simulering och Drift. Kodverk är omgjord som mönster |
Beslutad (efter SAD v7) |
KRAV-71, KRAV-78 |
Samma fyra lager i alla moduler; vertical slices överallt (rika domäner tappar sitt skydd) |
Routes, operationId och kontrakt oförändrade; delad kod i Infrastructure/, Domain/ och Kontrakt/; övriga slice-moduler görs om en i taget |
ModulstilTester, ModulgransTester, RouteKontraktTester |