commit 9390bde161d23532f8e44be83eb2f5d9efa5c44f
Author: Jens Kristoffersson <jens.kristoffersson.se@gmail.com>
AuthorDate: Wed Sep 2 12:50:23 2026 +0200
Commit: Jens Kristoffersson <jens.kristoffersson.se@gmail.com>
CommitDate: Wed Sep 2 12:50:23 2026 +0200
Lägg till arkitekturunderlaget som Markdown
Samma innehåll som .docx, renderas direkt i git-webben utan nedladdning.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---
docs/Remiss-arkitekturunderlag.md | 260 ++++++++++++++++++++++++++++++++++++++
1 file changed, 260 insertions(+)
diff --git a/docs/Remiss-arkitekturunderlag.md b/docs/Remiss-arkitekturunderlag.md
new file mode 100644
index 0000000..ffd7239
--- /dev/null
+++ b/docs/Remiss-arkitekturunderlag.md
@@ -0,0 +1,260 @@
+# Automatiskt remissförsättsblad
+
+**IT-arkitekturunderlag · utkast**
+
+En liten klientapp som skapar rätt försättsblad — med mottagning och HSA-id — och
+skickar remissen vidare, utan handpåläggning.
+
+| Fält | Värde |
+|------|-------|
+| Version | 0.1 (utkast) |
+| Datum | 2026-09-02 |
+| Status | Fas 1 byggd och testad |
+| Framtagen av | Jens Kristoffersson |
+
+> Samma innehåll finns som Word-dokument i [`Remiss-arkitekturunderlag.docx`](Remiss-arkitekturunderlag.docx)
+> och som webbsida (Claude-artifact).
+
+---
+
+## 1 Sammanfattning
+
+**Vad.** När en användare skriver ut en remiss skapar appen automatiskt ett
+försättsblad med vald mottagning och dess HSA-id, slår ihop det med remissen och
+skickar allt tyst till rätt digitala skrivare. Användaren väljer bara mottagning i
+en lista — inget fylls i för hand.
+
+**Varför.** Idag skrivs försättsblad och mottagningsuppgifter manuellt. Fel uppgift
+innebär att remissen hamnar hos fel mottagning: en patientsäkerhetsrisk och ett
+återkommande merarbete.
+
+**Hur.** Standard Microsoft-stack (.NET 8), inga licenskostnader, ingen
+serverkomponent — allt körs på klienten. Själva fångsten av utskriftsjobbet sköts
+av etablerad öppen programvara (clawPDF).
+
+**Läge.** Kärnan är byggd och täckt av 19 automatiska tester. Textformatet som
+nedströmssystemet läser med OCR är fastställt. Återstår: koppla på
+utskriftsfångsten och paketera för utrullning.
+
+**Det vi behöver från IT:**
+
+1. Paketering och utrullning av clawPDF + skrivarprovisionering via Intune/SCCM.
+2. Kodsigneringscertifikat för den körbara filen.
+3. Beslut om anslutning till HSA-katalogen (Fas 3) — eller besked att en statisk lista räcker tills vidare.
+4. En pilotmottagning och kontaktväg till nedströmssystemets OCR för skarpt test.
+
+---
+
+## 2 Problembild
+
+Remisser skrivs ut från journalsystemet och ska vidare till en mottagande enhet via
+ett digitalt utskriftsflöde. För att flödet ska hitta rätt behöver varje remiss ett
+försättsblad som anger mottagning och HSA-id.
+
+Det steget görs manuellt idag. Konsekvenserna:
+
+- Fel eller utelämnad mottagning: remissen fördröjs eller hamnar fel.
+- Ingen spårbarhet på vem som skickade vad, vart och när.
+- Tidsförlust i varje enskilt ärende, i stor volym.
+
+Det finns ingen färdig produkt som gör exakt det här — mottagningsval, HSA-uppslag,
+försättsblad med OCR-ankare och tyst utskrift i ett svep. Logiken är liten och väl
+avgränsad; alternativet är fortsatt manuell hantering med de fel den för med sig.
+
+---
+
+## 3 Lösningen i korthet
+
+En virtuell skrivare som heter **»Remiss«** fångar utskriftsjobbet och gör om det
+till en PDF. Den startar sedan appen med sökvägen till PDF:en. Appen:
+
+1. visar en sökbar dialog där användaren väljer mottagning,
+2. slår upp mottagningens HSA-id,
+3. genererar ett försättsblad (sida 1),
+4. slår ihop försättsblad + remiss till en PDF,
+5. skickar den tyst till den digitala målskrivaren,
+6. loggar utfallet och raderar de temporära filerna.
+
+Avbryter användaren dialogen skrivs ingenting ut och inget lämnas kvar. Felar något
+steg får användaren ett tydligt meddelande — inget jobb försvinner tyst.
+
+---
+
+## 4 Arkitektur
+
+
+
+*Ett remissjobb från Skriv ut till utskriven försättsblad + remiss. clawPDF fångar
+jobbet, konverterar till PDF och startar appen. All egen logik ligger i Remiss.exe.
+Patientdata skrivs bara till en åtkomstskyddad temp-mapp och skrivs över och
+raderas när jobbet avslutas — även om utskriften misslyckas. Audit-loggen får bara
+metadata.*
+
+---
+
+## 5 Komponenter
+
+### Utskriftsfångst — clawPDF
+
+Öppen programvara. Registrerar den virtuella skrivaren »Remiss«, konverterar
+PostScript till PDF och startar appen med PDF-sökvägen som argument. Ersätter
+behovet av en egenutvecklad skrivardrivrutin (kernel-nära, hög risk och
+förvaltningskostnad).
+
+### Applikationen — Remiss.exe
+
+.NET 8, Windows. Uppdelad i två delar:
+
+- **Remiss.Core** — all logik, UI-oberoende: mottagningsregister,
+ försättsbladsgenerator, PDF-sammanslagning, utskriftsmodul, audit, säker
+ temp-hantering.
+- **Remiss.App** — den körbara filen och mottagningsdialogen (WinForms).
+
+Dessutom ett litet testverktyg för att förhandsgranska försättsbladets layout och
+en testsvit (19 enhetstester).
+
+### Tyst utskrift — SumatraPDF
+
+Buntad med appen. Anropas som en fristående process på kommandoraden
+(`-print-to-default` / `-print-to "namn"`, `-silent`) — den mest pålitliga vägen
+att skjuta en PDF till en namngiven skrivare utan dialoger.
+
+### Mottagningsregister
+
+I POC: en JSON-fil (namn → HSA-id). I drift: uppslag mot HSA-katalogen. Källan
+ligger bakom ett gränssnitt (`IMottagningRepository`) så att bytet inte påverkar
+resten av koden.
+
+### Konfiguration
+
+En `appsettings.json` per klient styr målskrivare (tom = Windows standardskrivare),
+sökvägar, antal omförsök vid utskriftsfel och loggplatser. Kan sättas per enhet
+eller grupp.
+
+---
+
+## 6 Teknikval och licenser
+
+Alla val är gjorda för att undvika licenskostnad och licensfällor. VGR:s omsättning
+spränger gränsen för flera "gratis för små bolag"-licenser, så de är aktivt
+bortvalda.
+
+| Behov | Val | Licens | Motivering / bortvalt |
+|-------|-----|--------|-----------------------|
+| Körmiljö | .NET 8, Windows | Gratis (Microsoft) | Native, redan i förvaltning, inga extra runtimes. |
+| Dialog | WinForms | Gratis (Microsoft) | Minsta möjliga yta för POC. WPF möjligt senare utan att röra logiken. |
+| PDF: blad + merge | PdfSharp / MigraDoc 6 | MIT | Gratis även kommersiellt. **Bortvalt:** QuestPDF (gratis endast under ~1 MUSD omsättning), iText (AGPL / kommersiell). |
+| Tyst utskrift | SumatraPDF | GPLv3 | Buntad, anropas som separat process (aggregering, ej länkning). Alternativ: Ghostscript. |
+| Utskriftsfångst | clawPDF | Öppen källkod | **Bortvalt:** egen drivrutin (kernel-nära, hög risk), CutePDF (sluten, annonsfinansierad, kan inte starta program i gratisversionen). |
+| Mottagningskälla | JSON → HSA-katalog | — | Bakom gränssnitt, byts utan omskrivning. |
+
+Nettolicenskostnad: **0 kr.** Den enda kostnaden är utvecklings- och
+förvaltningstid.
+
+---
+
+## 7 Nedströms: OCR-kontraktet
+
+Det digitala utskriftsflödet läser mottagningen från försättsbladet med
+**server-side OCR på text** — ingen streckkod, ingen separat metadatafil. Vi äger
+formatet. Sida 1 innehåller:
+
+```
+REMISS
+
+HSA-ID: SE2321000131-E000000000001
+
+Mottagning: Hudmottagningen Sahlgrenska
+```
+
+Den maskinläsbara raden står ensam, i fast teckensnitt, överst. Formatet är kodat
+som ett kontrakt ([`OcrContract`](../src/Remiss.Core/Pdf/OcrContract.cs)) med egna
+tester — en funktion skriver raden, en tolerant parser läser tillbaka den. Parsern
+tål vanligt OCR-brus: versaler/gemener, tappat kolon eller bindestreck, blanksteg
+mitt i id:t, omgivande text.
+
+Ingen kontrollsiffra i första versionen. Om pilottestet visar att OCR:n läser fel
+kan en checksumma läggas till i Fas 3, så servern kan flagga misstänkta läsningar i
+stället för att skicka fel.
+
+Detaljerat kontrakt: [`forsattsblad-ocr.md`](forsattsblad-ocr.md).
+
+---
+
+## 8 Säkerhet och dataskydd
+
+Remisser är känsliga personuppgifter. Designprincipen: patientdata rör aldrig disk
+längre än nödvändigt och hamnar aldrig i loggar eller kraschdumpar.
+
+- **Temp-filer:** en jobb-isolerad mapp under användarprofilen (inte `%TEMP%`), med
+ NTFS-ACL låst till användaren + SYSTEM + Administrators och arv brutet.
+- **Radering:** försättsblad och sammanslagen PDF skrivs över och raderas när
+ jobbet avslutas — i ett `finally`-block, så det sker även när utskriften
+ misslyckas eller appen felar. Nästa körning städar eventuella kvarvarande
+ jobbmappar.
+- **Loggar:** audit-loggen innehåller enbart metadata — vem, vilken mottagning
+ (namn + HSA-id), när, utfall, vilken skrivare. En separat teknisk logg fångar fel
+ utan filinnehåll.
+- **Ingen nätverkstrafik med patientdata.** Enda externa anropet (valfritt, Fas 3)
+ är ett uppslag mot HSA-katalogen på mottagningsnamn/HSA-id.
+- **Kodsignering** av den körbara filen inför utrullning.
+- **Spårbara utfall:** appen returnerar tydliga koder (0 ok, 1 fel i
+ generering/utskrift, 2 ogiltig indata, 3 avbrutet av användaren, 10/11
+ konfigurations-/registerfel) som driftövervakningen kan larma på.
+
+Designen är gjord för att klara en dataskyddskonsekvensbedömning (DPIA). Underlaget
+kan tas fram tidigt i projektet.
+
+---
+
+## 9 Drift och utrullning
+
+- **Ingen serverkomponent.** Appen, SumatraPDF och konfigurationen distribueras som
+ ett paket per klient.
+- **clawPDF** installeras tyst och skrivaren »Remiss« provisioneras via
+ Intune/SCCM, som kör förhöjt. Slutanvändare installerar ingenting själva. En
+ virtuell skrivare kan aldrig installeras utan administratörsrättigheter — det är
+ själva drivrutins- och portinstallationen som är privilegierad, oavsett produkt.
+- **Uppdateringar:** nytt paket via Intune.
+- **Pilot:** en mottagning, verifiera OCR-träff och hela kedjan, innan bredare
+ utrullning.
+
+---
+
+## 10 Faser och nuläge
+
+| Fas | Innehåll | Läge |
+|-----|----------|------|
+| 0 | Fastställ hur nedströms läser mottagning | Klar — text-OCR, HSA-ID-rad |
+| 1 | Fristående app: dialog → försättsblad → merge → utskrift | Byggd, 19 tester gröna — manuellt sluttest kvar |
+| 2 | Koppla på fångst (clawPDF), skrivaren »Remiss« | Ej påbörjad |
+| 3 | Härdning: HSA-katalog, audit, felflöden, temp-säkerhet | Delvis förberedd i koden |
+| 4 | Paketering, kodsignering, utrullning via Intune, pilot | Ej påbörjad |
+
+---
+
+## 11 Risker och hantering
+
+| Risk | Påverkan | Hantering |
+|------|----------|-----------|
+| OCR läser fel HSA-id | Remiss till fel mottagning | Nyckelordsankrad rad i fast teckensnitt; kontrollsiffra kan läggas till i Fas 3; pilottest mot skarp OCR före bredare utrullning. |
+| clawPDF kräver admin | Blockerar självbetjäning | Paketeras och rullas via Intune/SCCM (SYSTEM) — standardförfarande för hanterade appar. |
+| Temp-fil kvar vid krasch | Personuppgiftsincident | Åtkomstskyddad mapp; överskrivning + radering i `finally`; nästa körning städar kvarvarande jobbmappar. |
+| Buntad SumatraPDF (GPLv3) | Licensfråga | Anropas som fristående process via kommandorad (aggregering), ingen länkning. Alternativ: Ghostscript. |
+| Nedströms ändrar format | Omarbete av försättsbladet | Formatet isolerat i ett kodat kontrakt med egna tester — ändras på ett ställe. |
+| Statiskt mottagningsregister | Fel eller saknade mottagningar | Källan ligger bakom `IMottagningRepository`; byte till HSA-katalogen utan att röra resten. |
+
+---
+
+## 12 Det här behöver vi från IT
+
+1. **Paketering och utrullning** av clawPDF och skrivarprovisionering (»Remiss«) via Intune/SCCM.
+2. **Kodsigneringscertifikat** för den körbara filen.
+3. **Beslut och åtkomst** för uppslag mot HSA-katalogen (Fas 3) — eller besked att statisk lista räcker tills vidare.
+4. **En pilotmottagning** och kontaktväg mot nedströmssystemets OCR för skarpt test.
+5. **Vid behov:** stöd för dataskyddskonsekvensbedömning (DPIA).
+
+---
+
+*Utkast för diskussion. Arkitektur, teknikval och faser följer projektets
+[`Plan.md`](../Plan.md). Koden är byggd och testad mot .NET SDK 8.0.424.*