1 Introduktion
Perfuse flytter kliniske meddelelser mellem systemer, der aldrig var designede til at tale med hinanden. Et laboratorium sender resultater i HL7 v2; praksisstyringssystemet forventer dem med forskellige feltpositioner, en anden patientidentifikator og en bekræftelse inden for fem sekunder. Noget må sidde i midten, og det noget er en integrationsmotor.
Denne manual beskriver, hvad Perfuse gør, hver enkelt mulighed det accepterer, og - hvor en beslutning ikke er åbenlys - hvorfor det fungerer på den måde, det gør.
1.1 Hvad Perfuse er til
En enkelt grænseflade mellem to kliniske systemer koster ofte ti tusinder, med femten til tyve procent af det igen hvert år i vedligehold. Meget af denne omkostning er ikke arbejdet; det er, at arbejdet kræver nogen, der har arbejdet med HL7 før, og de fleste praksisser har ikke ansat en sådan person.
Perfuse er bygget på antagelsen, at personen, der konfigurerer det, har et problem at løse og ingen forudgående HL7-erfaring. Denne antagelse viser sig på bestemte steder:
- Alt kan konfigureres fra webgrænsefladen. En funktion, der kun kan nås fra en terminal eller en manuelt redigeret fil, behandles som en fejl, ikke en designvalg.
- Meddelelser kan spores ét transformation ad gangen, og det viser, hvad hver trin læste, hvad det ændrede, og hvad det sprang over og hvorfor.
- Testtrafik kan genereres, der matcher formen på en reel feed uden at indeholde nogen af dens data.
- En kanal kan foreslås fra en enkelt eksempelmeddelelse, med en eksplizit udtalelse om, hvad eksemplet ikke kan fortælle dig.
- Før en eksisterende motor erstattes, kan dens output og Perfuse's sammenlignes meddelelse for meddelelse, med forskellene grupperet efter felt.
1.2 Hvad der er i det
Alt nedenfor er i den ene binær fil. Hver linje navngiver kapitlet, der dækker det.
- Formater. HL7 v2, FHIR R4, R4B og R5, DICOM, X12 (837, 835, 270/271, 276/277, 834, 278, 275), C-CDA og CDA, HL7 v3,
NCPDP Telecommunication og SCRIPT, SMART Health Links og Cards, afgrænsede og rå. Se meddelelsesformater.
- Forbindelser. 28 kilde-typer og 32 destination-typer, blandt andet MLLP, filer, SFTP, databases, DICOM, Kafka, AMQP 1.0,
MQTT, IBM MQ og AWS, Azure og Google Cloud-lagring og meddelelsesformidling. Se kildehenvisning og destinationhenvisning.
- Ændring af meddelelser. Filter, elleve deklarative transformations-trin, JavaScript (Mirth's dialekt inkluderet) og Lua, fælles
mapping-tabeller og kode-sæt, og mapping-forslag. Se filter og transformation.
- Levering af dem. En varig, sorteret kø per destination, gentagelser, døde breve, der gemmer meddelelsen, og kvitteringer
sendt efter levering. Se levering og kvitteringer.
- Overvågning af kørslen. Dashboards, team-dashboards, en flow-kort, elleve typer advarsler, målinger, sporing og en meddelelse-lager,
der finder en patients meddelelser på tværs af formater. Se advarsel, meddelelse-lager og fejlfinding.
- Ændring af en live-grænseflade sikkert. Skygge-tilstand, feed-kontrakter, kanal-test og motor-sammenligning. Se test.
- Forlade Mirth. Mirth, Open Integration Engine og BridgeLink-kanaler forklaret, oversat og eksporteret tilbage. Se
- Betalere og offentlig sundhed. De fire CMS-0057 API'er, Da Vinci CRD, DTR, PAS, PDex og Plan-Net, CARIN Blue Button, et valgfrit
beslutningstjeneste, eCR og ELR. Da Vinci CRD, DTR og PAS besvarer både deres 2.2.x og deres 2.1.0-udgaver. Se CMS-0057.
- Hvem kan gøre hvad. SAML, OpenID Connect, LDAP, passkeys, SCIM, gensidig TLS, seks roller, kanal-grupper med en rol i hver,
lejere, en SMART-authorization-server, TEFCA og UDAP, og en revisionslog. Se sikkerhed.
- Kørsel af det. En enkelt statisk binær fil til Linux, macOS og Windows, som en tjeneste, med en flåde-visning af flere servere. Se
operationer, web-grænsefladen, kommando-linjen og server-indstillinger.
1.3 Standarder og versioner
Hvilken udgave af hver standard Perfuse implementerer, og hvordan det blev kontrolleret. "Kontrolleret" navngiver det eksterne værktøj eller reference, der dømte resultatet; hvor intet eksternt har dømt det, siger det så. Resultaterne kommer fra testdata, ikke fra en produktionssted.
1.3.1 Meddelelser og dokumenter
| Standard | Udgave | Kontrolleret |
|---|---|---|
| HL7 v2 | enhver version: meddelelser læses af deres egne separatorer, ikke en versions-skema; kvitteringer som standard til 2.5.1 | NIST HL7 v2-validator; rigtig Mirth og OIE-trafik |
| HL7 v2 til FHIR | HL7's V2-til-FHIR-mapping (ADT, ORU, SIU, MDM, VXU og segmenterne i dem) | HL7 FHIR-validator mod US Core, UK Core, FR Core, ISiK, nl-core og HL7 Europa |
| FHIR | R4 (4.0.1), med R4B og R5 læst og skrevet | HL7 FHIR-validator; Inferno |
| C-CDA og CDA | C-CDA 2.1 | ONC SITE (C-CDA-eksempler sendt og modtaget over XDR); ikke af en CDA-schematron |
| HL7 v3 | PIX og PDQ (IHE ITI-44, 45, 47) | IHE's NE2008-skemaer og eksempel-meddelelser |
| DICOM og DICOMweb | DIMSE C-STORE, C-FIND, C-MOVE, C-GET, C-ECHO; QIDO-RS, WADO-RS, WADO-URI, STOW-RS | Orthanc |
| X12 (HIPAA) | 005010: 837, 835, 270/271 (X279A1), 276/277 (X212), 834, 278-anmodning (X217) og forespørgsel (X215); 275 i 006020 (X314) | payernes offentliggjorte companion-guides; CMS esMD-eksempler |
| CAQH CORE-forbindelse | vC2.2.0 SOAP og MIME, vC4.0.0 med MTOM | en stand-in UM-system skrevet fra CAQH's regler |
| NCPDP | Telekommunikation D.0; SCRIPT 2023011 (og 2017071) med ePA; Real-Time Prescription Benefit v13 | skrevet fra de offentlige Surescripts companion-guides og deres eksempler; ikke mod NCPDP's licenserede skemaer |
| UN/EDIFACT | syntaks 3 og 4, CONTRL | pydifact 0.1.8 |
| IHE-dokumentdeling | XDS.b, XCA, XDR, MHD 4.2.2, PIXm, PDQm, XDM | NIST XDS Toolkit; ONC SITE |
| Direkte sikker meddelelse | Applicability Statement 1.2, XDR og XDM til Direkte, DNS og LDAP-certifikat-opdagelse | ONC SITE; ONC's Certificate Discovery Tool (18 af 18) |
| AS2 | RFC 4130, komprimering RFC 5402 | pyas2lib |
| Signerede vedhæftninger | HL7 DSDR, XAdES-X-L | xmlsec1, OpenSSL |
1.3.2 FHIR-implementeringsvejledninger
| Guide | Udgivelse | Kontrolleret |
|---|---|---|
| US Core | konverteringer til 9.0.0 (USCDI v6); FHIR-server mod 6.1.0 og 7.0.0 | HL7-valideringsværktøjet; Inferno US Core |
| SMART App Launch | 2.2 | Inferno: 80 af 80 (offentlig app) |
| Bulk Data Access | 2.0.0 | Inferno: 48 af 48 |
| Subscriptions R5 Backport | til R4 | en rigtig HTTP-modtager; PAS-kittens meddelelsestests |
| Da Vinci CRD | 2.2.1 og 2.1.0 | Inferno 2.2.1: 92 passerer, ingen fejl; 2.1.0 efter vejledningens egne eksempler |
| Da Vinci DTR | 2.2.0 og 2.1.0 | Inferno 2.2.0: 43 passerer, 2 fejl (en kit-fejl); 2.1.0 efter vejledningens egne eksempler |
| Da Vinci PAS | 2.2.1 og 2.1.0 | Inferno 2.2.1: 82 af 84; 2.1.0 efter vejledningens egne eksempler |
| Da Vinci PAS, afsendelse (udbyder-side) | 2.2.1 | HL7 Da Vinci PAS-betalingreferencenimplementering; ikke en produktionsbetaler |
| Da Vinci PDex | 2.2.0 | Inferno PDex 2.0: betaler-til-betaler 19 af 19 |
Da Vinci HRex $member-match | 1.2.0 | Inferno PDex betaler-til-betaler |
| Da Vinci ATR | 2.1.0 | ikke kontrolleret af et eksternt værktøj |
Da Vinci CDex $submit-attachment | 2.1 | ikke kontrolleret af et eksternt værktøj |
| Da Vinci Plan-Net | 1.1.0 | Inferno: 199 passerer, 10 fejl (en kit-fejl) |
| Da Vinci US Drug Formulary | 2.1.0 | HL7-valideringsværktøjet |
| ISiK (tyske hospitaler), FHIR-server | Stufe 5, Basis-modul | gematik's ISiK-testsuite 3.0.9: 421 af 421 |
| PACIO Transitions of Care, Medication Profile, Advance Directives, Functioning | 1.0.0, 1.0.0, 2.0.0-ballot, 2.0.0 | PACIO's Inferno-kits med PACIO's egne data: hver fejl i dens data eller kit. C-CDA til TOC-dokument: HL7-valideringsværktøjet på HL7's eksempler, en fejl tilbage, vejledningens egne |
| CARIN Blue Button | 2.2.0 | HL7-valideringsværktøjet |
| eCR | 2.1.2 | HL7-valideringsværktøjet |
| ELR | HL7 2.5.1 ELR Release 1 med dets errata | ONC's ELR-værktøj: 28 af 28 |
| International Patient Summary | 2.0.0 | HL7-valideringsværktøjet |
| DEQM | 5.0.0 | HL7-valideringsværktøjet |
| SQL på FHIR | v2 | det officielle testværktøj: 144 af 144 |
| SMART Health Cards og Links | Kort 1.4, Links STU 1 | specifikationernes egne eksempekort; et offentliggjort SMART Health Links-bibliotek |
| UDAP Sikkerhed | STU 1 | en rigtig autorisationsserver og trust-samfund |
| TEFCA Facilitated FHIR | SOP v2.0 | ikke kontrolleret mod en rigtig QHIN |
1.3.3 Nationale og europæiske profiler
Kontrolleret ved at konvertere offentliggjorte eller opfundne HL7 v2-meddelelser og validering af hver ressource; de fulde resultater og årsagerne til hver fejl er i repositorys conformance/national-mappe.
| Profil | Udgave | Gyldige ressourcer |
|---|---|---|
| UK Core | STU2 2.0.2 | 185 af 187 |
| FR Core | 2.2.0 | 138 af 156 |
| ISiK Basismodul | 4.0.3 (Stufe 4) | 18 af 47; 42 af 47 med hospitalets eget bundle-script |
| Nictiz nl-core | 0.12.1-beta.1 (zib 2020) | 12 af 24; 18 af 24 med hospitalets eget bundle-script |
| HL7 Europe Laboratory Report | 2.1.0 | 106 af 426 (vejledningen forventer et dokument, en v2-resultat er ikke) |
| HL7 Europe Hospital Discharge Report | 1.0.0 | 68 af 69 |
Ingen af dette er en certificering. Perfuse er ikke blevet certificeret af ONC, CMS, gematik, Nictiz, NHS England eller nogen anden.
1.4 Hvad det erstatter
Perfuse dækker den grund, der tidligere var besat af Mirth Connect, og kan importere Mirth-kanal-eksportérer direkte. Kapitlet om migration beskriver, hvad der oversættes renligt, hvad der kræver en beslutning, og hvordan man kan bevise, at resultatet matcher før overgangen.
Forskellene, der betyder noget i daglig brug, er fejlfinding og tavshed. I Mirth betyder at se, hvad en transformer gjorde med en meddelelse, generelt at geninstallere kanalen med logning tilføjet. I Perfuse kan enhver optaget meddelelse afspilles gennem den aktuelle konfiguration og inspiceres trin for trin, uden at røre den kørende kanal. Og hvor en Mirth-advarsel om "ingen trafik" er en fast grænse, der er værdiløs på enhver feed, der er stille om natten, lærer Perfuse, hvordan hver feed's normale uge ser ud, og advarer mod det.
1.5 Hvordan man læser denne manual
De første kapitler er konceptuelle og er værd at læse i rækkefølge: kanaler, meddelelse-flow, derefter transformation. Alt efter det kan læses efter behov.
Reference-kapitlerne nær slutningen lister hver konfigurationsnøgle, dens type, om den er påkrævet og dens standardværdi. Disse kapitler er genereret fra kilden, så de kan ikke beskrive en mulighed, der ikke findes, eller udelade en, der gør. Hvis en nøgle vises i en konfigurationsfil og ikke i indeks, er det ikke en Perfuse-nøgle.
1.6 Konventioner
Konfigurationen er YAML. De fleste nøgler er snake_case på ledningen — max_message_size, idle_timeout — og denne vejledning giver altid wire-formen, fordi det er det, du skriver. Der er en enkelt undtagelse, dataType på en kanal, som er camelCase; det er dokumenteret på den måde i kanal-referencen og accepteres kun i den staving.
Feltreferencer i HL7 bruger den sædvanlige notation: PID-5 er det femte felt i PID-segmentet, PID-5.1 er dets første komponent, og PID-3(2) er den anden gentagelse af det tredje felt. En sti skrevet uden en gentagelse adresserer hver gentagelse (se paths).
Varigheder skrives som et tal og en enhed — 30s, 5m, 2h. Et nøgent tal er ikke en varighed og vil blive afvist i stedet for at gættes.
2 Kom i gang
Perfuse er en enkelt binær fil med en indbygget webinterface. Der er ingen applikationsserver at installere, ingen database at konfigurere og ingen separat administrationskonsol.
2.1 Kører det
perfuse serve -channels ./channels -db ./perfuse.db -addr 0.0.0.0:8443 \
-tls-cert ./cert.pem -tls-key ./key.pem
-channels er en mappe med YAML-filer, en per kanal. -db er en SQLite-fil, der indeholder optagede meddelelser, brugere og revisionshistorik; den oprettes, hvis den ikke findes.
Ved første start med ingen brugere konfigureret, oprettes en administrator-konto, og dens adgangskode skrives til loggen en gang. Den adgangskode kan ikke genskabes herefter.
-tls-cert og -tls-key betjener plain HTTP. Dette er acceptabelt på en loopback-adresse til en første oversigt og er ikke acceptabelt andre steder: web-grænsefladen indeholder legitimationsoplysninger og meddelelse-indhold, begge er læselige på ledningen uden TLS. Se sikkerhed.2.2 Den første kanal
En kanal har brug for et navn, en kilde og mindst en destination. Den mindste nyttige kanal modtager HL7 over MLLP og skriver hver meddelelse til en fil:
name: first-feed
dataType: hl7
source:
type: mllp
listen: "0.0.0.0:6661"
destinations:
- name: to-disk
type: file
file:
root: /var/spool/perfuse
dir: incoming
Gem det som channels/first-feed.yaml, og det bliver taget op uden genstart.
Tre ting om den fil er værd at bemærke, fordi de er formen på hver kanal:
- Kilde-blokken er flad for MLLP.
listensidder direkte påsource, ikke inde i ensource.mllp-blok. Transporter, der kræver mere end en adresse — HTTP, SOAP, DICOM — har deres eget under-blok, og disse er listet i kildereferencen. - En fil-destination kræver både
rootogdir.rooter grænsen, som stier er løst op imod, og kan ikke undslippe;direr, hvor meddelelser lander inden for den. - Der er ingen transformation og ingen filter. Begge er valgfrie, og en kanal med ingen af delene sender blot meddelelser videre.
2.3 Bygning af en kanal fra interfacen
Alt ovenfor kan gøres fra webinterfacen i stedet, og til en første kanal er det den bedre rute, fordi formen ikke vil lade dig producere en fil, der ikke kan indlæses.
Byggeren tilbyder tre måder at komme ind:
- Fra en meddelelse, nogen har sendt dig. Indsæt eksemplet, laboratoriet eller leverandøren har e-mailet. Perfuse læser det og foreslår en kanal, sammen med tre separate lister: hvad eksemplet viser, hvad der er gættet, og hvad ingen eksempel kan fortælle dig. Dette beskrives i testing.
- Fra noget, der allerede virker. En samling komplette kanaler, der kun behøver deres adresser udfyldt.
- Fra intet. En tom formular. Tilgængelig, men det er den langsomste af de tre og den letteste at få forkert.
2.4 Verificering af, at det virker, før noget bliver forbundet
To ting kan gøres, før sendesystemet eksisterer.
Send en meddelelse for hånd fra interfacen — meddelelsesafsenderen accepterer indhæftet tekst og rapporterer, hvad der skete med den, herunder hvilke destinationer accepterede den og hvad hver transformation gjorde.
Eller generer test-trafik. Hvis kanalen har behandlet nogen meddelelser overhovedet, kan Perfuse lære deres form og producere flere meddelelser ligesom dem, i samme proportioner, uden noget af det originale indhold. Se testing.
2.5 Hvad du skal gøre herefter
- Kanaler forklarer, hvad en kanal er, og hvordan dens dele passer sammen.
- Meddelelse-flow følger en meddelelse fra ankomst til levering, hvilket er den hurtigste måde at forstå, hvor du skal indsætte en ændring.
- Advarsler er værd at konfigurere, før en feed går live, snarere end efter den første incident.
3 Webgrænsefladen
Perfuse er bygget på antagelsen af, at alt kan gøres fra browseren, og en funktion, der kun kan nås ved at redigere en fil, behandles som en fejl. Dette kapitel er en tur gennem, hvad der ligger bag hver del af navigationen, organiseret på samme måde som grænsefladen: efter spørgsmålet, du stiller.
Baren viser Dashboard og Kanaler direkte, fordi de er, hvor de fleste sessioner starter og slutter. Alt andet er grupperet, og grupperne er navngivet efter spørgsmål snarere end efter undersystemer — du går ikke til "revisionssystemet", du går og finder ud af, hvem ændrede noget.
3.1 Læsning af headeren
Fem ting i headeren er lette at overse.
Hver visning har en adresse. Adresselinjen følger visningen — #/channels, #/messages, #/settings — så en genindlæsning returnerer til den, et bogmærke åbner den, en link sendt til en kollega åbner den samme side, og tilbage-knappen bevæger sig mellem visninger i stedet for at forlade konsollen. En adresse, der navngiver en visning over din rolle, åbner i stedet dashboardet.
Søgning, eller ⌘K. Den søger på tværs af kanaler, indstillinger, meddelelser og manualen, hvilket betyder, at det er som regel hurtigere end navigation — især for en indstilling, hvis navn du kun delvist husker.
Tema. Tre af dem: Midnight, Dark og Light. Midnight er næsten sort og er, hvad en vægvisning i et serverrum som regel ønsker; Dark er en blød neutral grå; Light er til en bærbar computer ved siden af et vindue. Valget gemmes i browseren snarere end mod kontoen, fordi et tema er en egenskab ved, hvor nogen sidder, snarere end hvem de er — samme operatør ønsker Midnight på væggen og Light på en tog.
Sprog. Konsollen er på engelsk (UK eller US datoorden), tysk, fransk, hollandsk, spansk, italiensk, portugisisk, polsk, svensk, dansk, norsk eller finsk, med datoer og numre skrevet på den måde, som locale skriver dem. Valget gemmes i browseren, og browserens eget sprog bruges, indtil et valg er gjort. Oversættelserne er lavet af maskine og er endnu ikke gennemgået af modersmålstalere; engelsk er reference, og vælgeren siger det. Kode, meddelelser, payload, kanalnavne og alt, der skrives, oversættes aldrig. Manualen udgives på samme sprog på https://perfuse.health/manual/<language>/ (denne servers eget Manual er det engelske).
Manual. Dokumentet, du læser, serveret af den kørende server. Det er samme fil, binær kan skrive til disk, så det altid beskriver versionen foran dig snarere end den seneste udgivelse.
3.2 Overvågning — om det fungerer, og hvad der skete
3.2.1 Dashboard
Status for hver kanal, gennemløb og alt, der i øjeblikket er galt. Dette er skærmen, der skal forblive åben.
3.2.2 Meddelelser
Hver meddelelse, der ankom, hvad den blev transformeret til, pr. destination, og hvad der skete med den. Søgbart, herunder efter et filterudtryk, så "vis mig dem fra denne afsender, der blev afvist" er en forespørgsel snarere end en eftermiddag.
En besked kan afspilles herfra, og genbearbejdes gennem den *nuværende* konfiguration i stedet for den, der var aktiv på det tidspunkt - hvilket er, hvordan du bekræfter, at en løsning virker mod den trafik, der brød den. Se beskedlagret for, hvad der gemmes og for hvor længe.
3.2.3 Kø
Hvad der venter på at blive leveret, og hvorfor. En kø, der ikke tømmes, er den eneste mest nyttige tidlige advarsel, en integrationsmotor producerer, og det er værd at parre med en advarselregel, så ingen behøver at overvåge. Se levering.
3.2.4 Advarsler
Hvad der er udløst og hvilke regler, der er. Regler redigeres her i stedet for i en fil. Se advarsel.
3.2.5 Målinger
Gennemløb, forsinkelse og fejlrate over tid. Nyttigt til kapacitets-spørgsmål og, oftere, til bestyrelsespakker — hvilket er, hvorfor webstedets eget logo vises på det, hvis et er uploadet.
3.2.6 SQL på FHIR
SQL på FHIR-visninger: Vælg et eksempel eller en gemt visning, eller skriv en, kørende over denne servers FHIR-lager (alle patienter eller en) eller over ressourcer, der er indssat. Se rækkerne med deres typer og download CSV, NDJSON eller Parquet. Gem gemmer det til FHIR-endpointets $sql-run. Se meddelelsesformater.
3.2.7 Kvalitetsmål
Digitale kvalitetsmål: Vælg et eksempel eller et mål i FHIR-lageret, eller skriv et med FHIRPath-kriterier. Vælg en målingsperiode og en rapport (samlet, samlet med patientlister eller en patient) og vurder det over FHIR-lageret eller indsattede ressourcer. Skærmen viser hver populations antal og patienter, scoren og strata. Download MeasureReport gemmer FHIR-resultatet, og Gem til FHIR-lageret gemmer målet til Measure/$evaluate-measure. Mål i CQL afvises: Perfuse har ingen CQL-motor. Se digitale kvalitetsmål.
3.2.8 Flowskema
Et billede af, hvordan meddelelser faktisk flytter: hvilke kilder føder hvilke kanaler, og hvilke destinationer de når.
Dens værdi er ikke pynt. Hver ejendom akkumulerer en kanal, som ingen husker at have bestilt, og en destination, som ingen indså var stadig modtagende, og begge er synlige her på en måde, de ikke er i en liste over kanal-filer.
3.2.9 Team-dashboard
En dashboard for hver type person, der overvåger grænserne: Drift, Forbindelser, Grænseanalytiker, Prioritetsgodkendelse, Billeddiagnostik, Økonomicyklus, Laboratorium, Privatliv og sikkerhed og en almindelig afdelingsopsomming. Fliser viser antal, tilstande og tider, aldrig en meddelelse eller en patient, så en dashboard kan gå til en leder eller en vægskærm uden at udvide, hvem der ser patientdata.
Hver person åbner dashboardet for deres directory-gruppe eller rolle. -dashboards dashboards.yaml mapper dem:
groups: {PACS-Admins: imaging, Network-Team: connections}
roles: {viewer: manager}
En gruppe sejrer over en rolle, og enhver, der ikke er matchet, åbner på Drift. Arrangér fliser skjuler og omarrangerer fliser, kanalvælgeren filterer dem, og Gem som min visning gemmer det som din egen dashboard, indtil Nulstil.
Eksport til Grafana downloader dashboardet som Grafana JSON over /metrics, med en datakildevariabel og en kanalfilter, for alle, der har brug for mere end let konfiguration. Fliser uden en metrik bag dem udelades, og eksportbeskrivelsen navngiver dem.
Den Forbindelser-flise kontrollerer hver netværksforbindelse i lag. Den søger navnet op, åbner en TCP-forbindelse, fuldfører TLS, hvor det bruges, og læser destinationens sidste levering og fejl fra rigtig trafik. Hver fejl siger, hvad det betyder, f.eks. "afvist: partnerens motor er sandsynligvis stoppet", "tidsudløbet: en brandmur eller en VPN-tunnel, der er nede", eller "et certifikat fra en myndighed, som denne server ikke stole på". Intet sendes til partneren, med en undtagelse: en vaccinationsregister, der ikke har haft nogen trafik i syv dage, bedes om dets CDC connectivityTest, som indsender intet. Med -vpn tunnels.yaml læser VPN-tunneler-flisen ved siden af hver partner-tunnels tilstand fra AWS Site-to-Site VPN, en Azure VPN Gateway-forbindelse eller strongSwan på denne vært, så et tidsudløb kan adskilles fra en tunnel, der er nede. Den sammenligner også beggesiders IKE- og IPsec-indstillinger, da skyen rapporterer vores, og filen nævner deres, og siger, hvor de ikke kan være enige. Forbindelsesark downloader en partners indstillinger side om side som Markdown til at sende dem; den holder aldrig en foruddelingsnøgle. Figurer, der kræves af en dashboard, der ikke er optaget endnu, er nævnt under Ikke målt endnu i stedet for at blive tegnet som tomme fliser.
Afdelingsdashboardene beregner deres egne figurer på serveren, og hver enkelt siger, hvilket vindue og kilde den dækker:
- Prioritetsgodkendelse: PAS-anmodninger afgjort inden for CMS-0057's 72 timer (hastet) eller 7 dage (standard), afgjort for sent, ventende og forfaldne nu, med median-tiden til at afgøre. Også, hvordan de tjenester, der blev anmodet om, blev besvaret (godkendt, ændret, afvist, udsat), da hver står nu, over 30 dage.
- Billeddiagnostik: objekter modtaget af C-STORE pr. modalitet og dem, der ikke blev leveret. Også routingsforsinkelsen pr. kanal (median og 95. percentil), C-FIND-forespørgsler og fejl pr. forespørgskanal og billeddiagnostikrapporter (en ORU, hvis OBR-24 er en billeddiagnostikafsnit, eller en MDM), der ikke nåede hver destination.
- Økonomicyklus: 999-transaktionssæt accepteret, accepteret med fejl og afvist, og 277CA-krav accepteret og afvist (A3, A4, A6, A7, A8). Også 835-krav, der er matchet med patientkontonummer til 837'er, der er sendt gennem denne server, og de hyppigste afvisningsårsager.
- Laboratorium: resultattid, fra modtagelse til den sidste destinations bekræftelse, og kritiske resultater (OBX-8 HH, LL, AA, > eller <), der ikke nåede hver destination.
- Privatliv og sikkerhed: hvem åbnede meddelelser, søgte efter patienter eller læste prioriteringsgodkendelser i konsollen over 7 dage, fra revisionsloggen (åbning af en meddelelse er revisioneret som
message.read). Også hver levende API-nøgle og hvornår den sidst blev brugt; en nøgle, der ikke er brugt i 90 dage, er markeret.
3.2.10 Deling af, hvad en feed faktisk indeholder
Profiler denne feed rapporterer, hvad der faktisk ankommer: hvilke udløsende begivenheder, hvilke felter er befolket og hvor ofte, hvilke former værdierne tager, og hvilke koder en afsender faktisk bruger. Det sidste er normalt den mest nyttige enkeltstående faktum i det.
Et profil kan downloades og sendes til en anden. Det kræver et navn og — påkrævet — hvilket system, der producerer feeden, fordi spørgsmålet, en fremmed stiller til et delt profil, er, om det beskriver deres system, og et valgfrit felt ville gøre "Unknown" til det hyppigste svar i enhver delt samling.
Det indeholder ingen patientdata, og det kontrolleres snarere end antages. Et profil er statistisk: antal, hastigheder, længder, former. Værdier gemmes kun for felter, som standarden definerer som kodetabeller, fordi en kodetabelværdi ikke er identificerende. Identifikatorværdier er aldrig nævnt.
To følgende ting følger af, at det er et løfte og ikke et håb. Serveren genopbygger profilen fra de gemte meddelelser, når du eksporterer den, i stedet for at sende den, der vises på din skærm — så det, der forlader bygningen, er sammensat af profileren, som har en test, der beviser denne egenskab, og ikke af en browser. Og eksporten afviser pure, hvis en profil nogensinde listar værdier for et felt, der ikke er en kode tabel, og nævner feltet, men ikke værdierne.
En profil, der ankommer fra et andet sted, kontrolleres på samme måde på vej ind, af en anden grund: Den er produceret af nogen, hvis omhu er ukendt, og visning af deres patientidentifikatorer ville være en afsløring fra denne server. At importere en ændrer intet — en profil beskriver en feed, og hvad man skal gøre ved den er en separat beslutning.
3.3 Byg — ændr, hvad en kanal gør, og prøv det, før det er live
3.3.1 Kanaler
Kanalbyggeren. Kilder, destinationer, filtre, transformationer, scripts og tests, med den genererede YAML vist ved siden af skemaet, mens du arbejder — så filen aldrig er en mysterium, og enhver, der foretrer filen, kan følge med.
Se kanaler for, hvilke dele der er tale om, og transformation for, hvad trinnene gør.
3.3.2 Scripts
En arbejdsplads for scripts, adskilt fra byggeren, fordi skrivning af et script og tilkobling af et script er forskellige aktiviteter.
Alle syv pladser tilbydes — filter, transformer, preprocessor, postprocessor, writer, lifecycle og reader — og valg af den rigtige plads er vigtigt, fordi pladsen afgør, hvad scriptet modtager og hvad det forventes at returnere. Kontrol af et script som det forkerte er ikke en workaround; det compilerer en anden ting.
JavaScript, Lua og WebAssembly er alle tilgængelige. Se transformation.
3.3.3 Kontrakter
Forventninger om, hvordan en feed skal se ud, oprettes og kontrolleres her samt fra perfuse contract. Se kommandolinjen.
3.3.4 Tabeller
Opslagstabeller og kode-sæt: de mappinger, der omdanner et systems koder til et andet systems. Redigerbar her, så tilføjelse af en kode ikke er en installation.
3.3.5 AI Mapper
Forslår felttilknytninger med en tillidsvurdering for hver, og afstår fra at gætte. Trods navnet bruger den ingen sprogmodel og foretager ingen netværksopkald: forslagene kommer fra regler, felt navne og samples indhold, på denne server. Den foreslår også en kanal fra en enkelt samplesmeddelelse og angiver udtrykkeligt, hvad samples ikke kan fortælle den. Den anden halvdel er den del, der gør den troværdig — et forslag, der så ud til at være komplet, ville invitere dig til at tro ting, meddelelsen aldrig sagde.
3.3.6 Legeplads
En skitseplads for meddelelser og transformationer. Indsæt en meddelelse, anvend trin, se resultatet.
Ingenting sendes noget sted, når siden er indlæst, hvilket er grunden til, at den findes i denne form: Det er sikkert at indsætte noget virkeligt i, på forståelsen af, at det bliver i browseren.
3.3.7 Skygge
Kører trafik gennem en kandidatkonfiguration sammen med den live-konfiguration og rapporterer om forskellene, så en ændring kan dokumenteres, før den er godkendt. Samme idé som perfuse compare, anvendt på en ændring i stedet for en migration. Se testing.
3.4 Udveksling — standarderne denne server taler til andre organisationer
3.4.1 FHIR lab
Konverter HL7 v2 til FHIR, valider en ressource og inspicér resultatet. Eksemplerne dækker indlæggelser, laboratorie-resultater, aftaler, kliniske noter, vaccinationer og en rapporterbar besøg. Valideringen inkluderer US Core, som er profilen, amerikansk regulering er skrevet imod, så dette svarer på "er det, de sendte os, faktisk konformt" uden at antage noget.
Offentlig sundheds-sag-rapport bygger eCR eICR en sag-rapport-destination ville sende for meddelelsen. Den viser, hvilken udløser-kode gjorde besøget rapporterbar, hvad rapporten skulle markere som manglende, og dokumentet selv. En meddelelse med intet rapporterbar får årsagen i stedet. Ingenting sendes fra her.
3.4.2 Abonnementer
FHIR-abonnementer og om deres meddelelser ankommer: begivenheder, accepterede, ventende og den sidste grund til, at en blev afvist. Abonnementer oprettes af FHIR-klienter via FHIR-API'en, ikke fra denne side, og de legitimationsoplysninger, de gav serveren, vises aldrig. Se meddelelsesformater.
3.4.3 Dokumenter
Kliniske dokumenter — CDA og den udskrivbare form af et dokument. Nyttigt, når det, der udveksles, er en udskrivningssammenfatning i stedet for en meddelelse.
3.4.4 Dokumentdeling
IHE XDS.b-registret og lageret startede med -xds: hvor mange dokumenter, patienter og indsætningssett det indeholder og hvor mange blev erstattet; adresserne på lageret, registret, XCA-gatewayen og MHD; en søgning efter en patients dokumenter i dette register eller et andet fællesskabs (et ITI-18-register eller en ITI-38-gateway, med en token til det); og offentliggørelse af et CDA-dokument manuelt, med facilitetstypen og praksisindstillingen, et dokument ikke siger. Se meddelelsesformater.
3.4.5 Direkte
Direkte sikker beskedsformidling. Denne servers Direct-adresser listar hver adresse, som en kanal sender eller modtager som, med dens certifikat, når det udløber, de anchors det stole på, og alt, der er galt (en manglende fil, et udløbet certifikat). Adresserbogen holder styr på korrespondenter og de certifikater, deres mail er krypteret til: indsæt ét fra deres HISP, eller Gem med certifikatet fra DNS; et certifikat, der ikke er til adressen eller dets domæne, afvises. Find et certifikat i DNS spørger uden at gemme. Se beskedformater.
3.4.6 Sundhedslink
SMART Sundhedslinks og -kort, til CMS's *Kill the Clipboard*. Modtag et SMART Sundhedslink læser linket eller QR-koden, en patient viser ved indtjekning, verificerer sundhedskortene inde i og sender det videre til en kanal. Del en besøgsrapport laver et link, som denne server hoster, eventuelt med en adgangskode, og en QR-kode til patienten; Brug deres patientopsummering udfylder det med patientens International Patient Summary fra denne servers FHIR-lager. Links, som denne server hoster, listar dem med, hvor ofte hver blev hentet, når den udløber og antallet af adgangskodeforsøg, og annullerer en. Verificér et SMART Sundheds-kort checker et korts signatur og udsteder på eget initiativ. Se CMS-0057 for serverindstillingerne, det kræver.
3.4.7 Billeddiagnostik
Arkivet, som denne server opbevarer, når den køres med -dicomweb-archive: optællinger af studier, serier, eksemplarer og den brugte plads, DICOMweb-adressen og datakildeblokken til en OHIF-viewer, samt en studiesøgning efter patientnavn, ID, accession og dato gjort med samme QIDO-RS-anmodning, som en viewer gør. Et studie åbner til dets serier og eksemplarer, og et eksemplar downloades som en DICOM-fil. Intet renderes: Perfuse flytter billeder, og en viewer viser dem. Uden et arkiv siger skærmen, hvordan man tænder et til. Se DICOMweb.
3.4.8 TEFCA
Revisionsstien for udveksling via et Kvalificeret Sundhedsoplysningssystem, og formålet med brugen af regler, der styrer det.
To transportmidler, der er på virkelig forskellige stadier, og skærmen siger, hvilket der er hvilket. Et flag, der dækker begge, ville være forkert i den retning, det var afrundet.
Faciliteret FHIR er implementeret og har aldrig talt med et rigtigt QHIN. Den følger Sequoia Project Standard Operating Procedure, der trådte i kraft den 8. marts 2026: opdag partnerens UDAP-metadata, verificér det, registrér dynamisk, få en adgangstoken, der bærer formålet med brugen, og forespørg. UDAP er en offentlig nøgleinfrastruktur over OAuth 2.0 — en tillidsfællesskab udsteder X.509-certifikater til dets medlemmer, og et medlem autentificerer ved at signere JWT'er med den private nøgle og vedhæfte certifikatkæden.
Sikkerhedslaget verificeres mod en anden persons implementering, som er den eneste verificering, der er noget værd her. En registrering, der er signeret af denne version, blev sendt til en live tredjepartsreferencserver og afvist med unapproved_software_statement — Untrusted: Certificate is not a member of community. For at producere dette svar dekodede serveren anmodningen, parsede software-erklæringen som en JWT, kontrollerede dens signatur, gennemgik certifikatkæden og nåede en beslutning om medlemskab. Det er forskellen på at blive afvist ved døren og at få returneret et uforståeligt brev.
Hvad der er tilbage, kan ikke gøres her. Certifikatet, der beviser fællesskabsmedlemskab, kommer ud af QHIN-onboarding og er ikke noget, software producerer. Indtil et eksisterer, fuldføres ingen udveksling med en rigtig partner.
Hvordan en kanal beder om noget. En destination af typen tefca beder det facilitatede FHIR-partnersæt i Indstillinger, TEFCA (tefca.partnerFHIRBase) om hver beskeds patient: ved identifikator, når beskeden har en (PID-3 eller en FHIR-patients identifikator), ellers ved efternavn med fødselsdato, og aldrig kun ved navn, fordi en forkert match på et navn returnerer en anden persons record uden en fejl. Destinationen angiver formålet med brugen (behandling, betaling, drift, folkesundhed, adgang til enkeltpersoner); et formål, som deltageren ikke erklærer, afvises, før noget sendes. Formål sendes som TEFCA-udvekslingsformålscoder (T-TRTMNT, T-PYMNT, T-HCO, T-PH, T-IAS, system urn:oid:2.16.840.1.113883.3.7204.1.5.2.1), eller med tefca.purposeCodes: hl7 som HL7-formålscoder for samfund, der bruger dem. Bundlen, der findes, er destinationens svar og kan overføres til en anden kanal med results_to. Hver forespørgsel, herunder afviste, er i sporet på dette skærmbillede, som navngiver partneren.
Hele vejen, fra opdagelse til en token, som partnerens FHIR-server accepterer, testes mod udap-dotnet-referenceserveren (se verificering).
Den ældre QHIN-til-QHIN-udveksling, der er bygget på IHE-profilerne, er ikke implementeret. Et forsøg afvises med en fejl, der siger det, og afvisningen auditeres som en fejl. Det er bevidst og ikke noget, der er under oprensning: en stubbet udveksling, der rapporterer succes, ville indsætte poster i revisionsstien for udvekslinger, der aldrig skete, og en sti, der er uenig med, hvad der skete, er værre end ingen, fordi stien er, hvad der bliver troet.
Gennem hele, kommer de endepunkter, der bruges til udveksling, fra den signerede del af en partners metadata, aldrig dokumentkroppen. At verificere en signatur og derefter læse endepunkterne fra den usignerede kopi ville være en omsværmet måde at stole på netværket: en angriber, der kan omskrive svaret, lader den signerede del være alene, peger token-endepunktet mod deres egen server og indsamler klientpåstande fra alle, der kontrollerede signaturen og derefter ignorerede, hvad den dækkede.
Et tillidsanker-bundle er påkrævet, og dets fravær afvises ved opstart. Kontrol af en samarbejdspartners signeret metadata mod certifikatet, der ankommer inde i det, beviser kun, at en part har lavet begge - en fejl, som denne kodebase har begået før, i SAML, hvor verificatoreren foretrak det indlejrede certifikat og godkendte en angriber som administrator, mens alle tests passede. Inkluder de mellemcertifikater i bundlen: en UDAP-server behøver kun at sende sit bladcertifikat, og den offentlige reference-server gør netop det.
3.5 Betalere - krav, forhåndsgodkendelse, lægemidler og CMS-betaleregler
3.5.1 Krav & godkendelse
Byg en X12 275 krav-vedhæftning i 006020-formen CMS-0053-F antager, fra en indklæbet C-CDA eller en uploaded PDF, TIFF eller JPEG, og se det læst tilbage. Læs en 275 og download dokumentet inde i. Konverter en X12 278 beslutning til en Da Vinci PAS ClaimResponse. Intet på denne side bliver gemt eller sendt. Se beskedformater for, hvad 275 er bygget af og hvad den ikke gør.
3.5.2 Lægemidler
Lægemiddelformulareren, der indlæses med -formulary, og de to NCPDP-standarder, der besvares fra den. Formulary listar planerne og lægemidlerne med deres niveau og krav, og hvor den offentlige Da Vinci US Drug Formulary API og NCPDP-endpoints er. Priskontrol (RTPB) priser et lægemiddel til en medlem som en lægers Real-Time Prescription Benefit-anmodning ville: dækningstilstanden, begrænsningerne i ord med deres koder, medlemmets andel og planens, og de billigere alternativer. Prior godkendelse (ePA) sender en SCRIPT-initiering til denne servers eget endpoint, viser spørgsmålet som en form, sender svarene og viser beslutningen; nedenfor, hver sag med, hvor den står, og om lægen er blevet underrettet, sagens svar, en knap til at sende en usendt beslutning igen, og lægemiddeltallene, som CMS-0062-P foreslår. Se CMS-0057.
3.5.3 CMS-0057
Betalersiden af CMS Interoperability og Forhåndsgodkendelsesreglen, som fem værktøjer:
- De fire API'er: om Patient Access, Provider Access, Payer-to-Payer og Prior Authorization er klar på denne instans, og hvad hver stadig mangler.
- Reviewer-kø: PAS-anmodningerne, der venter på en person, nærmest udløb først, med dokumenterne, der er sendt for hver; godkend, afvis eller godkend færre enheder. Se reviewer-køen.
- Krav til CARIN BB: en 837 og dens 835 konverteret til CARIN Blue Button-bundter.
- Prioritetsgodkendelse til PDex: en PAS-respons konverteret til en PDex-prioritetsgodkendelse.
- Prioritetsgodkendelses-målinger: den årlige offentlige prioritetsgodkendelses-målinger-side, forhåndsvist fra en CSV over beslutninger.
Konverteringerne gemmer intet og sender intet.
3.5.4 CMS-Aligned Network
Klarhed til CMS Interoperability Framework: hver af dets 26 kriterier, grupperet som CMS grupperer dem, med, hvad Perfuse leverer, om det er aktiveret her, indstillingen, der tænder det til, og hvad organisationen skal gøre. Antallene øverst filter listen. Se CMS-0057.
3.6 Administrer - hvem kan gøre hvad, og hvordan denne server er konfigureret
3.6.1 Brugere
Konti, roller (overvåger, viser, operatør, redaktør, admin) og kanalgrupper. Hver persons kanalgrupper redigeres på stedet i listen; tom betyder alle kanaler, og lab=editor, adt giver en anden rolle i en gruppe. En administrator, der er begrænset til nogle grupper, ser kun personerne i disse grupper. Headeren viser dine egne grupper ved siden af din rolle, når du har nogen. Se sikkerhed.
Maskinlegitimationer er også her. En token er til en maskine snarere end en person: den udløber ikke og påvirkes ikke af nogen, der logger af, hvilket er, hvad en server, der afhører sin nabo, har brug for. Kun en hash gemmes, så en token vises én gang, når den oprettes, og kan ikke genskabes - en stjålet database giver ingen brugbar token. Giv den laveste rolle, der gør jobbet.
Med MCP aktiveret, viser sektionen også adressen, en AI-agent tilslutter sig, en klientkonfiguration til at kopiere og hvert værktøj med den rolle, det har brug for; udstedelse af en token med Lad en AI-agent handle med det giver det mcp:write-omfang. Se sikkerhed.
3.6.2 Lejere
På en delt server, platform-operatørens liste over organisationer: hver organisations kanalantal og lagrede størrelse ved siden af dets begrænsninger (kanaler, beskeder per minut, lagring), som er indstillet på stedet. Vises kun til platform-rollen. Se sikkerhed for, hvad hver begrænsning gør.
3.6.3 Certifikater
De TLS-certifikater, der er i brug, og når de udløber. Udløbsdatoerne er det væsentlige: et certifikat, der udløb på en søndag, er en klasse af nedbrud, der helt kan undgås og rutinemæssigt ikke undgås.
3.6.4 Aktivitet
Hvem ændrede hvad, og hvornår. Hver konfigurationsændring bliver optaget, hvilket er, hvad gør "det begyndte at fejle på tirsdag" besvarligt.
3.6.5 Databeskyttelse
En persons anmodninger under GDPR og UK GDPR, juridiske retentioner, sletningsregister, retention og optegnelse over behandlingsaktiviteter; kun administratorer. Se databeskyttelse.
3.6.6 Flåde
Hver Perfuse-forekomst på én side.
Mirth sælger dette som et separat produkt; her er det en konfigurationsfil og et skrivebeskyttet token. Grunden til, at det er værd at have, er snæver og vigtig: en død server ligner ikke en stille en. En enkelt instances dashboard kan ikke fortælle dig, at en anden side har ophørt med at rapportere, og en flådebillede kan ikke heller.
3.6.7 Migrer
Drop en Mirth- eller OIE-kanal-eksport og se, hvor mange af dine kanaler ville køre her uændret. Den samme analyse som perfuse explain og perfuse translate, uden at du behøver en terminal. Se migration.
3.6.8 Indstillinger
Hver indstilling, serveren har, med en kontrol for hver — herunder de, der traditionelt kun lever i en fil. Hver angiver, om den træder i kraft med det samme eller kræver en genstart, og om den er sat eksplizit eller sidder på sin standardværdi.
Indstillingerne dækker hver perfuse serve-mulighed, der aktiverer en funktion: FHIR-endpointet og dets version, payer-API'erne, PAS og CRD-reglerne, X12 278-broen, eCR, SMART-autorisationsserveren, TLS og signering, målinger, flåde og VPN. De er grupperet som FHIR, Payers, Offentlig sundhed, SMART, Sikkerhed og så videre. Hver vises også med flaget, det svarer til.
Genstart fra console. En indstilling markeret *Kræver genstart* gemmes med det samme, men læses kun, når serveren starter. Mens nogen venter, viser en banner øverst i Indstillinger dem med en Genstart server-knap (logon-editoren og indstillingsfilerne tilbyder samme knap efter en gemning). Den spørger først, fordi hver kanal standser i få sekunder: hver afslutter meddelelsen, den behandler, som den gør, når tjenesten stoppes, og afsendere gensender, hvad der ankommer imens. Console-værktøjet venter herefter på, at serveren svare igen, og læser indstillingerne på ny. Kun en administrator kan genstarte, og each genstart registreres i aktivitetsloggen som server.restart.
På Linux og macOS erstatter processen sig selv med en frisk kopi af samme program og argumenter, mens den beholder sin proces-id, så systemd, launchd eller en container-runtime ikke ser noget ske. På Windows genstartes serveren inden for samme proces, der beholder en Windows-tjeneste under tjenestemanageren. Hvis serveren ikke har svaret efter to minutter, siger konsollen det; årsagen er i serverens log.
Flag og indstillingsfil. Første gang serveren starter, skrives flagene, den fik, ind i indstillingsfilen. Herefter vinder filen over flagene, så ændring af en indstilling sker i konsollen (eller filen), ikke ved at redigere tjenestens kommandolinje. Et flag, filen endnu ikke nævner, optages, når serveren starter med det. Fjernelse af et flag fra kommandolinjen senere slukker ikke funktionen: sluk det i Indstillinger.
SNMP har et panel under indstillingerne: om agenten besvarer og på hvilken adresse, de netværk det besvarer, hvor mange advarselstraps der er sendt eller mislykkedes, og Download MIB for den basis-OID, der er i brug. Værdierne indstilles under Overvågning, SNMP.
Branding er her også: et websted kan indstille produktets navn, en tagline, en accentfarve og uploade et logo. Logoen vises herefter i headeren, på loginsiden, på dashboardet og på rapporteringsskærmbillederne. Hvis ingen er uploaded, erstattes intet — en ikke-brændt installation forbliver ikke-brændt i stedet for at tilegne sig udsmykning.
3.7 Hvad farverne betyder
Fire registre, og hver siger noget andet. Forskellen er værd at nævne, fordi det er forskellen på et skærmbillede, du kan læse på et øjeblik, og et, hvor alt konkurrerer om opmærksomhed.
Almindelig tekst er en kendsgerning om, hvordan Perfuse fungerer. Størstedelen af grænsefladen. Intet er farvet for at fortælle dig, det er vigtigt.
Grøn betyder, noget lykkedes lige nu, fordi af noget, du gjorde. Den vises efter en handling og består ikke.
Gul er en advarsel: værd at vide, før du handler, og ikke en fejl. En funktion, der ikke er slået til, en indstilling, hvis ændringer er revisioner, en konvertering, der approksimerer i stedet for reproducerer, en transport Perfuse håndterer, men ikke kan fuldt verificere. Gul er farven på "læs dette, før du fortsætter".
Rød betyder, noget er galt lige nu. En værdi, der blev afvist, en anmodning, der mislykkedes, et certifikat, der er udløbet, en kritisk alert, der udløses. Intet andet bruger den.
Den sidste regel er derfor, hvorfor et skærmbillede ikke åbner rødt. Rød er den eneste farve, der bærer en instruks — stop, og det kan være noget, du gjorde — og et skærmbillede, der bruger den til udsmykning, har intet tilbage at sige, når input virkelig er forkert. Dette var ikke altid sandt: brugerens skærmbillede åbnede tidligere med "serveren sendte en respons, der ikke kunne læses" på hver installation, der ikke havde konfigureret passkeys, og indstillings-skærmbilledet markerede revisionerede værdier med samme farve som en afvist. En test i web/src/RedMeansWrong.test.ts fejler nu, hvis en frase, der beskriver noget fraværende eller approksimativt, gives en rød stil.
Inden for en kodeboks er vokabularet anderledes. Der er rød en token-type — et HL7-segmentnavn, et XML-element — og bærer ingen dom at alle.
4 Kanaler
En kanal er én strøm af meddelelser: et sted, hvor de kommer fra, valgfrie ændringer og ét eller flere steder, hvor de går hen. Det er konfigurationsenheden, overvågningsenheden og installationsenheden. Alt andet i Perfuse eksisterer for at betjene kanaler.
4.1 Anatomi
En kanal-fil har følgende dele, i den rækkefølge, de træder i kraft:
| Del | Nøgle | Påkrævet | Hvad den gør |
|---|---|---|---|
| Identitet | name | ja | Navngiver kanalen. Skal være unik. |
| Data-type | dataType | nej | Hvordan meddelelser skal fortolkes. Standard er HL7 v2. |
| Kilde | source | ja | Hvor meddelelser ankommer fra. Præcis én. |
| Filter | filter | nej | Beslutter, hvilke meddelelser der skal accepteres. |
| Transformationer | transformations | nej | Ordenede ændringer af meddelelsen. |
| Destinationer | destinations | ja | Hvor meddelelserne går hen. Ét eller flere. |
Plus flere, der gælder for hele kanalen: scripts, shadow, contract, tables, attachments, group og enabled. Hver er beskrevet i kanal-reference.
4.2 Én kilde, mange destinationer
Denne asymmetri er bevidst og værd at forstå tidligt, fordi det er den mest almindelige kilde til forvirring, når man kommer fra en anden motor.
En kanal har præcis én kilde. Hvis meddelelser ankommer fra to steder, er det to kanaler. At forsøge at udtrykke det som én kanal resulterer i en konfiguration, hvor en fejl i enten transport ser ens ud udefra, og hvor de to feeds' trafik er blandet sammen i statistikken — så et fald i den ene bliver skjult af den anden.
En kanal har et vilkårligt antal destinationer, og de er uafhængige. Én, der fejler, stopper ikke de andre, og hver har sin egen kø, sin egen gentagningspolitik og sin egen leveringspost. En meddelelse, der nåede tre af fire destinationer, bliver optaget som netop det, og ikke som en succes eller en fejl.
4.3 Destinationer er ikke en kæde
Hver destination modtager meddelelsen, som den var efter kanalens transformationer. En destination modtager ikke outputtet fra destinationen før den.
Det betyder noget, når en destination har sine egne transformationer, hvilket den måske har. Disse gælder kun for den destination's kopi. En almindelig fejl er at placere en ændring på den første destination og forvente, at den anden ser den.
Hvis du virkelig har brug for en kæde — outputtet fra én strøm, der føder ind i en anden — brug en kanal-destination, der sender til en anden kanal ved navn. Det er eksplicit, viser sig i meddelelseshistorikken som to kanaler og kan overvåges som to ting, hvilket en skjult kæde ikke kan.
4.4 Navngivning
Navnet er kanalens identitet overalt: i filen, i meddelelselageret, i alarmer, i revisionsloggen og i URL'en. At ændre det er ikke en omdøbning; det er en ny kanal, og den gamle kanal's historik bliver under det gamle navn.
group er separat og findes til at organisere grænsefladen. En gruppe har ingen effekt på opførslen, og at gruppere kanaler gør dem ikke til at dele noget.
adt-inbound.4.5 Aktivering og deaktivering
enabled: false stopper en kanal fra at starte uden at slette den. Dens konfiguration, historik og statistik bliver.
En deaktiveret kanal er ikke en pause. Dens kilde lytter ikke, så en afsender, der forsøger at forbinde, får en afvist forbindelse i stedet for en hængt. Til MLLP er det det rigtige opførsel — afsenderen vil køe og gentage — men det betyder, at afsenderens egen fejllog bliver fyldt op, så en deaktiveret kanal er ikke en erstatning for at arrangere en nedtid med hvem der sender.
4.6 Hvor kanaler bor
Én YAML-fil per kanal, i den mappe, der er givet af -channels. Filnavnet er ikke kanalnavnet; name-nøglen er. At holde dem ens er stærkt rådet og intet tvinger det.
Filer genlæses uden genstart. En fil, der ikke kan parses, rapporteres, og den tidligere indlæste version fortsætter med at køre, så en syntaksfejl kan ikke tage en fungerende feed af luften.
4.7 Kryptering af en kanals egen lytter
En kanal, der lytter på en port, er sin egen server, og dens TLS er separat fra TLS på Perfuses webinterface. At indstille den ene betyder ikke, at den anden indstilles. For en HTTP-kilde er indstillingerne under TLS og begrænsninger på kilde.
At aktivere TLS beder om et certifikat og en privat nøgle. At kræve et klientcertifikat omdanner det til gensidig TLS: afsenderen skal præsentere et certifikat, der er underskrevet af en myndighed, som du navngiver, hvilket er en autentificering, så en lytter med det aktiveret ikke også behøver en fælles token — selvom det ikke er forkert at have begge dele.
Myndigheden bedes kun om én gang, en klientcertifikat kræves, og den udelades fra filen, indtil da. En kanal, der navngiver en myndighed, der aldrig konsulteres, læser som om afsendere verificeres, når de ikke er det.
En MLLP-lytter har de samme indstillinger under Kryptér denne lytter, med én væsentlig forskel: på MLLP er et klientcertifikat den eneste tilgængelige autentificering. Der er ingen token og ingen header, så en lytter uden et accepterer beskeder fra enhver vært, der kan nå porten.
To begrænsninger sidder ved siden af den. Give op efter en varighed, fordi en afsender, der åbner en forbindelse og stopper med at skrive, ellers holder den åben. Og største accepterede meddelelse, i byte, fordi nul betyder ingen begrænsning, og begrænsningen er så hukommelsen — en afsender, der posterer en gigabyte, afvises i stedet for at blive absorberet.
4.8 Validering
En kanal valideres, når den indlæses, og valideringerne er afvisninger snarere end advarsler, hvor alternativet ville være en kanal, der kører og gør noget forkert.
Eksempler på ting, der afvises direkte: en destination uden type, en transformation, der henvender sig til en sti, der ikke kan eksistere i den erklærede datatype, en anerkendelsesmode, som kilde-transporten ikke kan levere, og en Schedule II-recept med genopfyldninger.
Forskellen Perfuse forsøger at fastholde er, at alt, der kan producere et plausibelt forkert resultat, afvises, og alt, der blot er usædvanligt, tillades og rapporteres. En kanal, der ikke kan være forkert, er mere værdifuld end en kanal, der starter.
5 Meddelelsesflow
Dette kapitel følger en meddelelse fra det øjeblik, den ankommer, til det øjeblik, den leveres eller opgives. At kende denne rækkefølge er den hurtigste måde at finde ud af, hvor en ændring hører til, og hvorfor noget ikke sker.
5.1 Rækkefølgen af begivenheder
- Ankomst. Kilden accepterer byte. For en streamtransport inkluderer dette de-framing - finde ud af, hvor en besked slutter og den næste begynder.
- Parse. Byte bliver til et træ i overensstemmelse med kanalens
dataType. En besked, der ikke kan parses, stopper her og registreres som en parse-fejl. - Optegn. Beskeden skrives til beskedlagret, som modtaget, før noget ændrer det. Dette er, hvad der gør replay og genbearbejdning mulig.
- Filter. Hvis kanalen har et
filter, beslutter det, om at acceptere beskeden. En afvist besked registreres som filtreret, hvilket er en normal udfald og ikke en fejl. - Transform. Kanalens
transformationskøres i rækkefølge, hver mod resultatet af den sidste. - Fan out. Hver destination får en kopi af den transformede besked, anvender sine egne transformationer, hvis den har nogen, og leverer.
- Optegn resultatet. For hver destination: leveret, køet, fejlet eller filtreret.
- Bekræft. Hvis kilden forventer en bekræftelse, genereres og sendes den. Som standard sker dette her, efter levering - se nedenfor.
5.2 Når anerkendelsen sendes
Dette er den mest konsekvensfulde indstilling i en kanal, fordi det beslutter, hvad afsenderen lovet. Det er ack.when, og det har to værdier.
on_delivery er standard. Anerkendelsen sendes kun efter, at hver aktiveret destination har accepteret meddelelsen. En positiv anerkendelse betyder derfor, at data faktisk ankom et sted, hvilket er den stærkeste påstand, en motor i midten kan ærligt gøre.
on_receipt anerkender, så snart meddelelsen er parsed og køet, før nogen destination er skrevet.
Perfuse standardiserer til on_delivery, fordi at love levering og derefter miste meddelelsen er værre end at være langsom. Under on_receipt kan en meddelelse, der er anerkendt, stadig gå tabt, hvis processen dør med arbejde i køen — afsenderen tror, det er leveret, intet ovenfor vil gensende det, og den eneste registrering af, at det eksisterede, er i Perfuses egen butik.
5.3 Når man skal vælge on_receipt
Tilfældet for det er reel, og det er tidsgrænser. En MLLP-afsender, der ikke får en anerkendelse inden for få sekunder, vil typisk gensende, så en langsom destination under on_delivery producerer duplikater i stedet for forsinkelse. Hvis en destination er en langsom arkiv eller et system, der jævnligt er utilgængeligt, on_delivery kobler afsenderens tidsgrænse til den destinationens værste tilfælde.
Handelen er utvetydigt: on_receipt overfører risikoen fra duplikater til tab. At vælge det betyder, at man accepterer, at en bekræftet besked kan gå tabt i tilfælde af en fejl, og det er værd at kombinere med varsel om kø-dybde, så en kø, der er stoppet med at afvikle, bliver bemærket. Se alerting.
5.4 Hvor meddelelsen registreres
Før filteret og derfor før nogen transformation. Tre konsekvenser:
- En besked, som filteret afviste, er stadig i lagret. Du kan se, hvad der ankom, og bekræfte, at filteret havde ret.
- Afspilning og genbearbejdning starter altid fra det, der faktisk ankom, og ikke fra en delvist transformeret version.
- En ændring af transformationerne kan testes mod virkelig historisk trafik, fordi den originale er stadig der. Se testing.
Den transformerende form er også optaget, pr. destination, sammen med resultatet. Så lagret indeholder, hvad der ankom, hvad der blev sendt, og hvad der skete — hvilket er, hvad en undersøgelse har brug for.
5.5 Fejl ved hver fase
| Fase | Hvad fejl ser ud som | Hvad sker |
|---|---|---|
| Ankomst | Ramme-fejl, forbindelse lukket midt i en besked | Optaget, forbindelse lukket, afsender forsøger igen |
| Parse | Ikke gyldig for den erklærede type | Optaget som parse-fejl, negativ bekræftelse, hvis kilden forventer en |
| Filter | Filteret selv fejler | Behandles som en afvisning, optaget med fejlen |
| Transform | En proces fejler | Afhænger af procesens on_error; se transformation |
| Levering | Destination er utilgængelig eller afviser | Køer og forsøger igen efter destinationens politik; se levering-køring og forsøg |
Den vigtige asymmetri: en parse-fejl er permanent, og en leveringsfejl er det normalt ikke. Genforsøg af en uparsbar besked vil aldrig hjælpe, så den genforsøges ikke. Genforsøg af en utilgængelig destination vil normalt hjælpe, så den genforsøges.
5.6 Orden
Inden for en destination leveres beskederne i den rækkefølge, de ankom, og en besked, der fejler og kommer ind i køen, holder sin plads — senere beskeder venter bag den, i stedet for at overhale.
Dette er den rette standard for kliniske data, hvor en indlæggelse efterfulgt af en udskrivning, der leveres i forkert rækkefølge, er værre end, at begge er forsinkede. Det betyder også, at en forgiftet besked kan holde en kø op, hvilket er, hvorfor kø-dybde er værd at alarmere over.
På tværs af destinationer er der ingen garant for orden, fordi de er uafhængige. To destinationer modtager ikke nødvendigvis den samme besked på samme tid, og en hurtig kan være flere beskeder foran en langsom.
5.7 Samtidighed
En kilde kan håndtere flere forbindelser på én gang, begrænset af max_connections. Beskeder fra forskellige forbindelser bearbejdes samtidigt.
Dette betyder, at ankomst-rækkefølgen af to beskeder, der sendes samtidigt ned ad to forbindelser, ikke er defineret, og kan ikke defineres — de ankom faktisk på samme tid. En afsender, der har brug for orden, skal bruge en forbindelse, hvilket er, hvad de fleste af dem gør.
6 Transformation
Transformationer ændrer en besked. De er en liste, de køres i rækkefølge, og hver enkelt ser resultatet af den foregående.
Perfuses transformationer er deklarative: hver proces navngiver en operation og feltet, den anvendes på. Der er ingen script-sprog i den almindelige vej. Dette er en bevidst begrænsning, og begrundelsen er i why not a script nedenfor.
6.1 Processerne
| Proces | Hvad den gør |
|---|---|
set | Skriver en litteral værdi til en sti, og opretter den, hvis den mangler. |
copy | Kopierer en sti til en anden, med en valgfri standard, når kilde-stien er fraværende. |
clear | Tømmer et felt, og lader det være til stede. |
remove | Fjerner et felt helt. |
map | Søger den aktuelle værdi op i en tabel og erstatter den. |
replace | Regulær udtryks-erstatning inden for et felt. |
pad | Udfylder en værdi til en fast bredde. |
date | Konverterer en dato eller tidsstempel mellem formater. |
trim | Fjerner omgivende mellemrum. |
case | Konverterer til upper eller lower case. |
Hver proces accepterer også description, som vises i sporet og i grænsefladen, og when, som gør processen betinget.
En proces skrives som procesnavnet med sin egen blok:
transformations:
- description: Our record number, not theirs
set:
path: PID-3.4
value: RIVERSIDE
- copy:
from: PID-19
to: PID-3.1
default: UNKNOWN
- map:
path: PID-8
table:
M: Male
F: Female
set og value er ikke søskende. set tager en blok, der indeholder path og value. At skrive set: PID-3.4 med value: ved siden af det er den hyppigste fejl i en håndskrevet kanal og resulterer i en load-fejl i stedet for en stille mis-konfiguration.6.2 Tydelig, fjern og forskellen
clear lader feltet være til stede og tomt. remove fjerner det helt.
For HL7 er denne forskel reel, og den når modtageren. Et tomt felt siger "Jeg har dette felt, og det har ingen værdi". Et fraværende felt siger intet overhovedet. Nogle modtagende systemer behandler den første som en instruks om at slette deres gemte værdi, og den anden som en instruks om at lade den være alene — hvilket er forskellen på at slette en patients registrerede allergi og ikke at nævne den.
Hvis du ikke ved, hvilken modtageren ønsker, skal du spørge. At gætte har en 50 procents chance for at ødelægge data på den anden side uden varsel.
6.3 Betingelser
when tager et udtryk, og trinnet køres kun, hvis det er sandt:
- when: MSH-9.2 == "A08"
set:
path: EVN-1
value: A08
Et trin, hvis betingelse er falsk, registreres som skipped, og dette rapporteres separat fra et trin, der kørte og ændrede intet. Denne forskel er pointen med trin-for-trin-fejlsøgeren og er dækket i fejlsøgning: en falsk betingelse og et fraværende felt ser identiske ud udefra og betyder modsatte ting.
6.4 Stier
En sti adresserer et felt: PID-5 er det femte felt i PID, PID-5.1 er dets første komponent, PID-3(2) er den anden gentagelse af PID-3 og OBX(3)-5 er det femte felt i det tredje OBX-segment.
To beteender, der er værd at kende:
setopretter den sti, den adresserer, herunder mellemliggende struktur. Dette er bekvemt, og det betyder, atsetaldrig kan demonstrere, at et felt var fraværende — efter trinnet findes det. For at teste, hvad der sker, når et felt mangler, skal du brugecopyfra en sti, der ikke er der.- En sti uden en indeks adresserer hver gentagelse og hver forekomst, som den gør i en filter (hvor
PID-3.5 == "SS"er sandt, når nogen gentagelse er). På en besked med fem OBX-segmenter ændrersetpåOBX-5alle fem, ogsetpåPID-3.4omlægger hver identifikator i PID-3, herunder det nationale nummer. For at ændre en, skal du give dens indeks:PID-3(1).4,OBX(2)-5.
6.5 Fejl
De fleste trin har intet at fejle på. At sætte en værdi, rydde et felt eller kopiere fra en fraværende sti med en standardværdi er alle defineret for enhver indtastning.
date er undtagelsen, fordi en værdi, der ikke er en dato, den genkender, har ingen korrekt konvertering. Den tager on_error:
fail— standardværdien. Meddelelsen stopper og registreres som en transformationsfejl.keep— lad den oprindelige værdi være uforandret.clear— tøm feltet.
Standardværdien er fail, fordi en tidsstempel, der stille ikke konverterer, er værre end en meddelelse, der ikke ankom. En dato i forkert format ligner stadig en dato, så den passerer modtagerens validering og lander i optegnelsen som den forkerte dag.
keep er legitimitet, når modtageren tolererer begge formater, og når den bruges, markerer sporet ændringen som bevidst, så den ikke læser som et trin, der fejlede stille.
6.6 Rækkefølgen betyder noget, og sporet viser det
Hvert trin ser det foregående trins output. To konsekvenser, der fanger folk:
- En
mapefter encaseser den case-konverterede værdi, så dens tabelnøgler skal matche den konverterede form. En tabel overM/Fefter et lille-tilfælde-trin matcher intet, stille, fordi en værdi, der ikke er i tabellen, bliver stående uforandret. - En
copyfra et felt, som et senere trin fjerner, virker stadig, fordi det kørte først. Omvendt gør det ikke.
Begge er synlige i trin-for-trin-visningen, som viser hele meddelelsen efter hvert trin i stedet for kun ændringen. Se fejlsøgning.
6.7 Forslag til tilknytninger og hvad man skal gøre med et forslag
Den AI Mapper foreslår tilknytninger mellem en samling kildefelter og en samling mål. Dens definerende adfærd er, at den afstår: under dens tillidsniveau afstår den fra at gætte, fordi en selvbevidst forkert tilknytning i et klinisk system er værre end ingen tilknytning overhovedet.
6.7.1 Giv det noget at være selvbevidst om
Et navn alene er svagt bevis, selv når det matcher nøjagtigt. PatientMRN mod PatientMRN scorer 68, hvilket afstår ved standardtillidsniveauet på 70.
The engine knows what an HL7 path means — it will tell you PID-7 is Date/Time of Birth and score your field name against that rather than against the string PID-7, which shares no characters with anything. A locally defined Z segment means whatever your site decided, so nothing is claimed about it.
Det får en tilknytning næsten på plads. For at fuldføre den skal du leverer begge halvdele:
- Eksempelværdier for et kildefelt, efter et ligegyldigt tegn:
ZPI-1 = MRN00412, MRN00998 - Den type værdi, et målfelt holder, på samme måde:
PID-3.1 = mrn. Typerne ermrn,npi,ssn,phone,dateogemail.
Med dem kan motoren se, at værdierne er enige med målets type, og et forslag hviler på mere end et navn.
6.7.2 Godkendelse sker ét til ét-mapping ad gangen
Hver forslag har sin egen godkendelsesboks. Der er ingen "accepter alt over 80%", bevidst: motoren har allerede brugt tilliden til at afgøre, om den skal tilbyde mappingen, og hvad der er tilbage, er en vurdering om dette felt i denne feed. Et tal er ikke den vurdering.
En afstemning kan ikke godkendes overhovedet. Den har ingen boks, ikke engang en deaktiveret en, og skærmen siger, at motoren ikke kender svaret. Hvis du kender svaret, kortlæg det manuelt - det er en anden handling end at være enig i et forslag.
Et forslag under din grænseværdi vises uden en boks også, markeret som under den. Værd at læse - en næsten-miss er ofte den ønskede mapping, og at skjule den ville efterlade dig med at undre dig over, om motoren overhovedet havde overvejet den - men ikke godkendelig, fordi din grænseværdi er den linje, du har tegnet.
6.7.3 To ting at gøre med, hvad du har godkendt
Tilføj dem til en kanal omdanner hver mapping til en kopi-trin. Dette fungerer kun, hvor kilden er en sti i meddelelsen, såsom ZPI-1, fordi et trin kopierer fra ét sted i en meddelelse til et andet. Trinnene kommer ind i kanal-filen og træder i kraft, når den næste gang indlæses - intet ændrer sig i trafikken, før da. Hver trins beskrivelse optegner den tillid, det blev foreslået med, og at en person har godkendt det, hvilket er det, der gør det ansvarligt seks måneder senere.
Hent som en opskrift er det rigtige svar for den mere almindelige sag: en mapping fra en kolonne-navn, en JSON-nøgle eller en leverandørs eget felt-navn. Disse er reelle mappings, og en kanal kan ikke læse sådanne felter direkte, så et trin kan ikke udtrykke dem. Opskriften optegner dem som godkendt og kan deles.
6.8 Hvorfor ikke et script
Mirth placerer en JavaScript-omdanner i centrum af hver kanal, og det er den mest fleksible design, der er tilgængelig. Perfuse tilbyder scripting - se scripts-nøglen i kanal-referencen - men gør det ikke til den almindelige vej, af tre grunde, der kommer fra, hvad der går galt i praksis.
Et deklarativt trin kan inspiceres. Perfuse kan fortælle dig, at et trin læser PID-5 og skriver PID-8, før det køres, og kan derfor vise en felt-niveau-sporing, advare om, at et trin adresserer en sti, som den erklærede datatyp ikke kan indeholde, og generere en per-trin-gengivelse. Ingen af disse ting er mulige for arbitrær kode.
Et deklarativt trin kan forstås af grænsefladen. Byggeren kan tilbyde de felter, der findes i denne kanals trafik, og en ændring af et trin kan kontrolleres mod virkelige historiske meddelelser, før det gemmes.
Og et deklarativt trin kan ikke gøre noget, der ikke er relateret til meddelelsen. Et script kan ringe til nettet, læse filsystemet eller afhænge af dagen. Når en kanal, der har fungeret i to år, begynder at producere forkert output, er årsagen uden for meddelelsen den sværeste sag at diagnosticere, og fjernelse af muligheden er værdigere end den fleksibilitet, det koster.
Hvor en ægte transformation ikke kan udtrykkes deklarativt, brug et script og accepter, at sporingen vil vise det som ét uigennemsigtigt trin.
6.9 Hvad et script er tilladt at gøre
Et script afvises alt uden for meddelelsen, medmindre det er tilladt, og tilladelserne er på Scripts-sektionen af byggeren. Dette er bevidst anderledes end Mirth, der giver hvert script alle disse - så der kan en omdanner stille læse filsystemet efter en kopier-og-indsæt.
Der er tre.
Læs og skriv filer kræver, at du navngiver de mapper, det må bruge, og en kanal, der giver filadgang uden dem, afvises under indlæsning. Denne krav er den eneste forskel på filadgang og ubegrænset filadgang: at give den uden mapper en gang nåede hele filsystemet, herunder Perfuses egen database, der indeholder adgangskode-hashes, LDAP-servicekonto-adgangskoden og OIDC-klient-hemmeligheden. At oprette en kanal kræver kun redaktør-rollen, så eskaleringen blev fuldendt, øjeblikket en administrator startede kanalen.
Forespørg en database bruger de forbindelser, der er konfigureret på kanalen. Et script med denne kan læse alt, hvad disse legitimationsoplysninger kan.
Rute meddelelser til andre kanaler lader et script sende en meddelelse ind i en anden kanal, hvilket er, hvordan en løkke mellem to kanaler bliver mulig.
At give en funktion til en kanal med ingen script gør intet, og den genererede fil udelader hele blokket i dette tilfælde.
6.10 Håndtering af en dato, der ikke matcher dens format
Et dato-trin konverterer fra ét format til et andet, og det interessante spørgsmål er, hvad der sker, når en værdi ikke matcher formatet, det påstår.
Standarden er at stoppe meddelelsen, og det er den rigtige standard: en tidsstempel, der stille ikke konverterer, accepteres downstream og læses derefter forkert, hvilket er værre end en meddelelse, der fejler højlydt og sidder, hvor nogen kan se det.
Lad værdien være, som den er sender den videre i dens oprindelige format. Downstream ser derefter to formater i ét felt, hvilket er fejlen, trinet eksisterer for at forhindre - men det er det rigtige valg, hvor feltet er valgfrit, og en partner sender det inkonsekvent.
Tøm feltet er ærligt og bedre end et forkert format, men en modtager, der kræver feltet, afviser derefter meddelelsen i stedet.
6.11 Skriptsprogene
Tre er accepterede, og hvilket man vælger afhænger mest af, om man migrerer. Værdien indsættes i en scripts language-nøgle:
| Værdi | Hvad det er |
|---|---|
javascript | Standard. Et uspecificeret script er JavaScript. |
lua | Det bedre valg, når ingen migrerer. |
wasm | Byte fra et kompilteret WebAssembly-modul, ikke kilde. |
JavaScript er standard, og et uspecificeret script behandles som JavaScript. Det er her som en kompatibilitetsforpligtelse snarere end en præference: Mirths scripts er JavaScript, og et websted, der flytter over, har tusinder af linjer med det. Det inkluderer understøttelse for E4X, en længe død udvidelse af sproget, som Mirth-scripts bruger til XML, og som må oversættes, før noget kan parse det.
Lua (lua) er det bedre valg for alle, der ikke migrerer. En mindre runtime, ingen prototype-kæde at misbruge, og integer-indekserede tabeller, der matcher segment- og feltadressering mere naturligt end JavaScripts gør. Dets standardbibliotek er småt nok til at opremse, hvilket er det, der gør dets sandbox lettere at være sikker på.
WebAssembly (wasm) er ikke et sprog, men et kompilteret modul, og feltet ønsker byte fra en .wasm-fil snarere end kilde. Brug det, når transformationen allerede findes i et kompilteret sprog, eller når det er tungt nok til, at runtime-omkostningerne er vigtige.
Dets kontrakt er bevidst den enkleste tilgængelige: et modul læser meddelelsen på standardindgang og skriver dens resultat til standardudgang. Byte ind, byte ud - hvilket er, hvad hver værktøjskæde allerede gør, og hvad nogen, der tester et modul på deres eget kommandolinje, allerede har. Alternativet var en eksporteret funktion over lineær hukommelse, som er hurtigere og kræver, at hver modulforfatter er enig om allokerings-, strengkodnings- og frigøringsspørgsmål; til noget, der køres kun én gang per meddelelse, er den handel ikke værd at gøre.
Alt, et modul skriver til standardfejl, bliver loglinjer, så det kan forklare sig selv på samme måde, som et script, der kalder logger, kan.
true eller false på standardudgang. At sammenblande de to ville gøre et crashende modul uadskilleligt fra et, der bevidst dropper trafik.6.11.1 Hvad output betyder
Reglerne er de samme for alle tre sprog snarere end nye per runtime, så et scripts iagttagelige adfærd - hvad det kan se, hvad det må gøre, hvor lang tid det må tage, hvad en filterdom betyder - er defineret én gang.
Til en transformer, preprocessor eller writer, tom output betyder, at meddelelsen er uændret. At falde ud af slutningen af et script efterlader meddelelsen alene; at behandle ingen output som "meddelelsen er nu tom" ville kaste trafik på en tekniskitet.
WebAssembly-moduler er kompilteret, når kanalen indlæses, ikke på den første meddelelse. Kompilering er ikke gratis - et modul bygget fra et sprog, der bringer sin egen runtime, kan tage hundredvis af millisekunder - og at betale det på indlæsningstidspunktet betyder, at den første meddelelse gennem en kanal ikke er mystisk langsommere end resten.
6.12 Fælles korttabeller
Den anden halvdel af det samme problem: en sides kønskoder og patientklasser oversættes identisk i hver kanal, der berører dem, og en tabel inde i en kanal er en tabel, som kun kan bruges af den kanal.
# codes.codeset.yaml
tables:
- name: sex-to-lab
describes: the hospital's sex codes into the numeric codes the lab expects
decided_by: Dave, during the 2019 migration
decided_on: 2019-04-11
source: the lab's interface specification, version 3
entries:
- from: M
to: "1"
- from: U
to: "9"
why: the lab has no 'unknown', and 9 is its 'not stated'
# in the channel
tables:
- codes.codeset.yaml
transformations:
- map:
path: PID-8
use: sex-to-lab
Provenansen er pointen. Det meste af, hvad der gør en grænseflade svær at vedligeholde, er, at ingen ved *hvorfor* en mapping er, som den er, og personen, der vidste, er gået. En mapping med en grund kan diskuteres; en uden bliver noget, som ingen tør ændre og ingen tør slette.
Tabeller oprettes og ændres på Byg → Tabeller samt i filen. Gemning af en tabel, der er i kraft, genstarter de kørende kanaler, der indlæser filen, så den næste besked bruger den; en kladde genstarter intet.
6.12.1 Versioner og effektive datoer
En tabel kan holde flere udgaver under ét navn, hver med sin egen version. Udgaven en besked bruger, vælges, når beskeden ankommer: af de godkendte udgaver, hvis datoer dækker den dag (UTC), den som startede senest. Så en kodeændring, der er aftalt til første dag i næste måned, indtastes nu og overtager på egen hånd.
tables:
- name: sex-to-lab
version: "3"
effective_from: 2026-11-01 # optional; empty means from the start
effective_until: 2027-10-31 # optional; the last day it applies
source_system: urn:local:hospital-sex
target_system: http://terminology.hl7.org/CodeSystem/v2-0001
entries: [...]
statuserapproved(standard),draft(bruges af ingenting) ellerretired(gemt for posteritetens skyld, bruges af ingenting).
(bevaret for optegnelser, bruges af ingenting).
- To udgaver af ét navn med samme version, eller to godkendte udgaver
der starter samme dag, afvises, når filen indlæses.
- Ved at gemme en ny version uden startdato, mens en anden er godkendt,
dateres den fra i dag, så den erstatter den gældende. En, der kun startede i dag, pensioneres, da to udgaver der starter samme dag, ikke kan have nogen regel.
- En kortingstrins egne
defaultogstrictbruges, når trinet angiver dem;
ellers bruges tabelens.
- På Skærmen Tables, viser Vis versioner alle udgaver med deres status,
hvem der har gemt og hvem der har godkendt den, og Sammenlign med den gældende version viser, hvad en udgave tilføjer, fjerner og ændrer.
6.12.2 Godkendelse
Med Indstillinger → Data → Mappingstabeller "Ændringer i en mappingtabel kræver en anden persons godkendelse" (data.tableApproval) aktiveret, er hver gemning en kladde, og personen, der gemte den, kan ikke godkende den: en anden person gør det, eventuelt med angivelse af den dag, det træder i kraft. En godkendt udgave kan ikke redigeres på stedet; Ny version fra denne kopierer den til den næste version. Godkendelse, pensionering og sletning af en kladde skrives til revisionsloggen, og godkendelse genstarter de kørende kanaler, der indlæser filen.
6.12.3 Værdier ingen tabel tilordner
Hver værdi, en mappefase ledte efter og ikke fandt, tælles, pr. tabel, med de kanaler, den kom gennem, og hvornår den først og sidst blev set. Tabellens skærm viser dem, flest først. Tilføj det åbner tabellen med den værdi allerede tilføjet som en række; Afvis fjerner det, indtil det ses igen. Værdier længere end 64 tegn registreres ikke (de er ikke koder), og listen holder, hvad der blev set inden for beskedbeholdningsperioden. Listen gemmes i terminology.db ved siden af hoveddatabasen.
6.12.4 Kodesystemer
Offentliggjorte kodesystemer kan importeres fra deres udgivere egne filer under Kodesystemer på Tabelskærmen (admin) eller med POST /api/terminology/import?format=… og filen som brødteksten:
| Format | Fil | System |
|---|---|---|
loinc | Loinc.csv fra LOINC-tabeludgivelsen | http://loinc.org |
icd10cm | CMS-ordrefilen (icd10cm_order_*.txt) eller kodefilen | http://hl7.org/fhir/sid/icd-10-cm |
rxnorm | RXNCONSO.RRF fra RxNorm-fulludgivelsen | http://www.nlm.nih.gov/research/umls/rxnorm |
snomed | RF2-beskrivelsessnapshot (sct2_Description_Snapshot-en_*.txt) | http://snomed.info/sct |
snomed-rf2 | en hel SNOMED CT RF2-udgivelsespakke (zip-filen, som en national udgivelsescenter offentliggør) | http://snomed.info/sct, version http://snomed.info/sct/{module}/version/{date} |
claml | en ClaML-fil: WHO ICD-10, ICD-10-GM og OPS (BfArM), CIM-10 FR (ATIH) | fra filens titel eller det angivne system |
icd11 | WHO ICD-11 MMS-simpletabulering (tab-separeret, med Code- og Title-kolonner) | http://id.who.int/icd/release/11/mms |
csv | enhver afgrænset fil med system, codeColumn og displayColumn (CPT, HCPCS, lokale koder, nationale tabeller) | det angivne system |
Ingen følger med Perfuse: LOINC, SNOMED CT, RxNorm og CPT har hver deres licens, og skærmen beder importøren bekræfte, at organisationen har den (optaget med importen). Importerede koder bruges på tre måder:
- en tabel, der navngiver
source_systemellertarget_system, har sine poster kontrolleret, når
den gemmes, og koder, der ikke er i systemet, vises på udgaven;
- Find en kode søger efter kode eller efter ord i navnet;
- FHIR-serveren besvarer
CodeSystem/$lookupogCodeSystem/$validate-code
for dem (se FHIR-serverindstillingerne). ICD-10-CM-koder accepteres med eller uden punktum.
Nationale udgaver og klassificeringer. En SNOMED CT-udgave importeres fra dens hele RF2-pakke: begreber med deres reelle status, hver aktiv beskrivelse og sprogreference-sæt. Udgaven findes fra pakken (den nationale modul med flest begreber; edition navngiver den i stedet) og bliver versionens URI. language vælger, hvis foretrukne term hvert begreb vises som (sv, da, nl, de, fr, en-GB, en-US ...; engelsk ellers), og hver sprogs foretrukne term og fuldt specificerede navn gemmes som betegnelser: $lookup returnerer dem, og dens displayLanguage vælger en (de-CH falder tilbage til de). De udgaver, som Perfuse navngiver (International, UK, Tyskland, Nederlandene, Sverige, Danmark, Belgien, Irland, Norge, Schweiz, Estland, Spanien), er listet af GET /api/terminology/editions, module-ID'erne ikke kontrolleret mod en offentlig kilde markeret som sådan; enhver anden udgave importeres også, navngivet efter dets modul.
ClaML-filer læses i UTF-8, ISO-8859-1, ISO-8859-15 eller Windows-1252, som deres XML-erklæring siger. Hver kategoris titel er dens foretrukne rubrik (indrede termer inkluderet); en modifier (en femte karakter for stedet for en fraktur, for eksempel) gør de koder, den tilføjer, med modificatorens titel efter kategorititlen, medmindre kategorien ekskluderer den; blocks=true importerer kapitler og blokke også. ICD-11-tabellens kolonner findes ved navn, da deres rækkefølge er ændret mellem udgaver, og stregerne, der viser dybde, fjernes fra titlerne. En afgrænset fil tager delimiter (, ; | eller tab), encoding (utf-8, iso-8859-1, iso-8859-15, windows-1252) og noHeader=true, med kolonner, der derefter er nummereret fra 1. Konsollen tilbyder indstillinger for Storbritanniens ICD-10 5. udgave og OPCS-4-filer (TRUD), Frankrigs CIM-10 FR-tabel over etiketter (ATIH) og en ICD-10-BE-eksport; deres udgivere dokumenterer ikke alle deres kolonner, så check dem mod filens header.
Effektive datoer. effective=YYYY-MM-DD importerer en version nu og bruger den fra den dag (ICD-10-GM, siger, hver 1. januar): indtil da besvarer en opslag, der navngiver ingen version, versionen, der allerede er i kraft, og skærmen viser datoen.
ICD-11 fra WHO. Med en klient registreret på icd.who.int (Indstillinger → Data → Kodesystemer, serve -icd11-client-id og -icd11-client-secret; -icd11-release, 2025-01 som standard), ICD-11-koder, der ikke er importeret, søges i WHO's ICD-API (codeinfo, derefter entitetens titel) og gemmes i en dag. En postkoordineret kode (NC72.2&XK9K) kontrolleres som helhed, så en kombination ICD-11 ikke tillader, afvises, og dens visningsnavne for hver del ("Fraktur af lårhals (Højre)").
ICD-11 uden at sende koder ud. WHO udgiver samme API som en container (whoicd/icd-api, gratis, Intel og Arm). Kør det på dit eget netværk og angiv dets adresse (serve -icd11-url http://icd-api.local, eller ICD API-adresse i samme indstillinger); intet klient er nødvendigt, og ingen kode forlader dit netværk. Testet mod denne container (version 2.6.0, udgivelse 2025-01 på engelsk og fransk).
7 Filtrering
Et filter afgør, hvilke beskeder en kanal accepterer. Det er en udtryk på kanalen, der evalueres efter, at beskeden er blevet parseret og optaget, før nogen transformation.
filter: MSH-9.1 == "ADT" && MSH-9.2 in ("A01", "A03", "A08")
En besked, som filteret afviser, registreres med resultatet filtered. Det er et normalt resultat, ikke en fejl, og det udløser ikke en advarsel eller producerer en negativ bekræftelse.
7.1 Filtreret er ikke det samme som fejlet
Denne forskel er værd at være fast om, fordi at blande dem sammen er, hvordan et rigtigt problem bliver skjult.
En filtreret besked blev korrekt afvist: den var ikke til denne kanal. En fejlet besked var en, som denne kanal skulle have behandlet, men ikke kunne. Hvis begge blev registreret på samme måde, ville en kanal, der starter med at fejle hver besked, se ud som en kanal, der filtrerer størstedelen af sin trafik, hvilket er den normale tilstand for mange kanaler.
Sådan tæller statistikken dem separat, advarselreglerne behandler dem forskelligt, og grænsefladen viser dem i forskellige farver. En stigning i filtrerede beskeder kan betyde, at afsenderen er begyndt at sende noget nyt; en stigning i fejl betyder, at noget er brudt.
7.2 Hvad et filter kan læse
Ethvert felt i den parsede besked, ad samme stier som transformationer bruger. Filteret køres før transformationer, så det ser beskeden, som den ankom - ikke som den vil blive sendt.
Denne rækkefølge er bevidst. Et filter, der læser værdier efter transformation, ville afgøre, om at acceptere en besked på basis af ændringer, der er lavet under antagelse af, at den blev accepteret, hvilket er cirkulært og producerer kanaler, hvis opførsel afhænger af rækkefølgen af to ting, der ser uafhængige ud.
7.3 Udtryk
Sammenligninger: ==, !=, og for tal <, <=, >, >=.
Medlemskab: in ("A01", "A03"), som er klarere end en kæde af || og er den form, byggeren producerer.
Kombination: &&, ||, og parenteser. Negation med !.
Fravær: en sti, der ikke er til stede, sammenlignes ulige med enhver værdi, herunder den tomme streng. For at teste for fravær eksplitt skal sammenlignes med absent. Dette er vigtigt, fordi et fraværende felt og et tomt felt er forskellige, som beskrevet i transformation, og et filter, der behandler dem på samme måde, vil acceptere beskeder, det var skrevet til at udelukke.
7.4 En fejl i filteret er en afvisning
Hvis filteret selv fejler under evaluering - et forkert udtryk, der slap igennem validering, eller en sammenligning, der ikke kan laves - afvises beskeden, og fejlen registreres mod den.
At afvise i stedet for at acceptere er det sikrere af de to, men ingen af delene er godt, og resultatet registreres forskelligt fra en almindelig filterafvisning, så det kan varsles om. Et filter, der fejler på hver besked, dropper stille hele feeden, og det må ikke se ud som et filter, der fungerer.
7.5 Filtrér ved kilde, hvor du kan
Et filter køres efter, at beskeden har krydset netværket og er blevet parsed. Nogle kilder kan filtrere tidligere og billigere:
- En broker-kilde tager en
selector, der filtrerer på brokeren. Beskeder, denne kanal ikke ønsker, krydser aldrig netværket overhovedet. På en delt kø er det forskellen på at læse hundredvis af beskeder om dagen og hundredtusindvis. - En databasekilde bestemmer, hvad den returnerer, ved sin forespørgsel.
- En filkilde bestemmer, hvilke filer den tager, ved sin mønster.
At filtrere ved kilde er en performancesbeslutning, ikke en korrekthedsbeslutning, og det har en omkostning: en besked, der filtreres på brokeren, registreres aldrig af Perfuse, så den vises ikke i beskedlagret og kan ikke inspiceres senere. Hvis du har brug for at kunne bevise, hvad afsenderen sendte, filtrér her i stedet for der.
7.6 Test af et filter
Et filter kan kontrolleres mod rigtige historiske trafikdata, før det gemmes. Grænsefladen rapporterer, hvor mange af de sidste N registrerede beskeder filteret ville acceptere, afvise og fejle på - hvilket er den hurtigste måde at opdage, at et udtryk, der ser rigtigt ud, accepterer intet.
Sporet viser også, pr. besked, hvilke felter filteret læste og hvilke værdier det fandt. Et filter, der uventet afviser alt, læser normalt en sti, der ikke findes i denne feed, og sporet navngiver den.
8 Beskedformater
En kanals dataType afgør, hvordan bytes bliver til en besked. Det påvirker parsing, hvad stier betyder, hvordan beskeden skrives tilbage ud, og hvilke transformationer er gyldige.
| Værdi | Format |
|---|---|
hl7 | HL7 v2, den pipe-adskilte standard. Standardværdien. |
hl7v3 | HL7 v3 og CDA-dokumenter, som er XML. |
x12 | ASC X12, bruges til berettigelse og krav. |
ncpdp | NCPDP Telecommunication Standard D.0 apotekkrav. |
script | NCPDP SCRIPT, elektroniske recepter. XML. |
dicom | DICOM-billedeobjekter. |
delimited | CSV og andre adskilte tekstformater. |
raw | Ingen parsing. Bytes ind, bytes ud. |
8.1 HL7 v2
Standardværdien og det, som de fleste af denne manuals eksempler bruger. Segmenter afsluttes med carriage return, felter med |, komponenter med ^, gentagelser med ~.
To ting om kodningen er værd at vide, fordi de forårsager stille fejl.
Adskillerne er ikke faste. De erklæres i MSH-1 og MSH-2 i hver besked, og Perfuse læser dem derfra i stedet for at antage pipes. En afsender, der bruger en anden feltadskiller, parses korrekt.
Konsekvensen er, at en besked, hvis adskillere er erstattet — oftest af en tekstbehandler eller mailklient, der erstatter typografiske look-alikes — parses perfekt ind i felter, der er helt forkerte. Ingen fejl opstår. Dette er hvorfor den eksempel-læser, der er beskrevet i testing, rapporterer, hvilken adskille-tegn den fandt, og nægter at udtrykke tillid, når det er usædvanligt.
8.2 HL7 v3 og CDA
XML i stedet for adskilt. Stier er element- og attributstier i stedet for feltpositioner.
I v3 er en værdi næsten altid et attribut i stedet for elementtekst. En sammenligning, der kun læser elementtekst, vil rapportere, at to dokumenter er identiske, når fødselsdatoen, kønnet og hver identifikator adskiller sig. Perfuses sammenligning læser både, og det er derfor: alternativet lykkes stille.
hl7v3-indstillinger er i format-referencen.
8.3 X12
Segmenter afsluttes med ~ konventionelt, med adskillere erklæret i ISA-segmentet. Ligesom HL7 læses de fra beskeden i stedet for at antages.
X12's struktur er konvolutter inden i konvolutter — interchange, funktionel gruppe, transaktionssæt — og en enkelt interchange kan indeholde mange transaktioner.
Som standard er en interchange én besked. Hele filen får én post, én udfald og én række i grænsefladen, uanset hvor mange transaktioner den indeholder.
8.3.1 Mirths X12-XML
Mirth Connect og Open Integration Engine viser X12 som XML: en rod X12Transaction (eller EDIMessage, når input ikke starter med ISA) med afgrænsere som attributter og ét element per segment og element med navn ISA.01, NM1.03.1 osv. Kanaler og modtagere bygget til Mirth læser og skriver denne form. Perfuse læser og skriver også samme form:
x12: { arrives_as: xml }on an X12 channel takes that XML in and handles it as the X12 it stands for (the builder's It arrives as choice);x12_as: xmlon a destination sends the X12 on as that XML (the builder's Send it as Mirth's X12 XML);perfuse x12 xml [file]andperfuse x12 from-xml [file]convert at the command line.
Formatet blev skrevet fra Open Integration Engine 4.6's observerede output og publiceret format og kontrolleres mod det: 25 genererede interchange og 4 beholdte eksempler kommer ud byte for byte, som OIE skriver dem, og tilbage (se verificering). Et DOCTYPE afvisses, som i hver XML, Perfuse læser.
8.3.2 Splitning af en interchange
Indstilling af split gør hver transaktionssæt til en besked i sin egen ret, med sin egen post, sin egen måling og sin egen række. En operatør, der søger efter én krav, finder så én krav i stedet for en fil med fire hundrede.
Det er slået fra som standard, fordi aktivering af det multiplicerer alt nedstrøms — beskedstællinger, rækker, alarmgrænser — og en grænse, der er indstillet til filer, som pludselig tæller krav, vil ikke betyde, hvad den tidligere gjorde. Det bør være en beslutning, nogen har truffet, i stedet for en standard, de har arvet.
split og acknowledge kan ikke begge være indstillet, og en kanal med begge nægtes under indlæsning. En anerkendelse er en udtalelse om en hel interchange, så splitning ville sende én per transaktionssæt, og en partner, der modtager flere 999'er, der navngiver den samme funktionelle gruppe, har ingen måde at afklare dem på.8.3.3 Når tællingerne ikke stemmer overens
X12 erklærer sine egne tællinger — hvor mange segmenter, hvor mange transaktioner — og envelope-nøglen siger, hvad der skal gøres, når de ikke stemmer overens med, hvad der faktisk er til stede. Disse tællinger er den eneste mekanisme, X12 har til at opdage, at halvdelen af en kravfil ankom.
| Værdi | Adfærd |
|---|---|
require | Afvis interchange. Standardværdien. |
warn | Behandle det, og optegn fejlen mod beskeden. |
ignore | Tjek ikke overhovedet. |
warn findes for en reel situation: nogle partnere's software har genereret forkerte tællinger i år i ellers komplette filer, og et websted, der skal behandle dem, har brug for en måde at sige det højt i konfigurationen i stedet for at slå validering af helt.
ignore er navngivet for at være ubehageligt. Indstilling af det smider den eneste måde, X12 giver dig, til at bemærke en afkortet fil, og en afkortet kravfil er ikke til at skelne fra en lille en.8.3.4 Transaktioner Perfuse læser som struktureret data
Ethvert X12-interchange kan rutes, filtreres og adresseres efter sti. Disse transaktioner parses desuden til navngivne felter, så en kanal kan spørge, hvad en betaler besluttede, snarere end hvilket element sidder på position fire.
| Transaktion | Hvad den transporterer |
|---|---|
835 | Refusionsråd: hvad der blev betalt, hvad der blev afvist, og justeringsårsagerne. |
275 | Kravvedhæftninger: klinisk dokumentation til støtte for et krav. |
277 | Kravstatus, herunder en betalers anmodning om yderligere dokumentation. |
278 | Forhåndsgodkendelse: anmodningen om gennemgang, og betalerens beslutning. |
999 | Funktionsbekræftelse, som Perfuse også genererer. |
271 | Berettigelse: om en patient er dækket, og deres selvbetaling, selvbetalingssats, fradrag og udgifter udenfor nettet, inden for og uden for nettet. |
|---|---|
834 | Tilmelding: medlemmer tilføjet, ændret og afsluttet, med hver dækningssætning og dens datoer. |
837 | Krav, professionelle og institutionelle (læs for CMS-0057's CARIN-konvertering). |
Perfuse opbygger også 270-berettigelsesanmodning og 276-kravanmodning om status, under Betalere → Krav & godkendelse eller via POST /api/x12/eligibility/build og /api/x12/claimstatus/build. Begge er HIPAA 5010-versioner (005010X279A1, 005010X212), læst tilbage og kontrolleret, før de vises, og ingen af dem sendes fra denne side: levering af en af dem er en kanals opgave, hvor handelspartnern og dets legitimationsoplysninger er.
8.3.5 Berettigelse og CAQH CORE-dataindholdsregel
En 271 er en liste over EB-segmenter, hver en enkelt faktum: aktiv dækning eller en $25-selvbetaling for servicetype 30 i netværk eller $800 af den enkelte fradragsbeløb, der er tilbage. Læseren samler dem til svaret, en receptionsdesk ønsker - "dækning aktiv under Gold PPO 2000; selvbetaling i netværk $25; enkelt fradragsbeløb tilbage i netværk $800" - og navngiver en afvisning (et AAA-segment) i ord, med hvad betaleren siger, man skal gøre herefter.
Den checker også svaret mod CAQH CORE Eligibility & Benefits dataindholdsregel: for en anmodning om sundhedsforsikringsdækning (servicetype 30), skal en aktiv respons medføre plan datoer, plan navn, selvbetaling, coinsurance, fradragsbeløb og tilbageværende fradragsbeløb både i og uden for netværk, og grundlæggende servicetyper (1, 33, 35, 47, 48, 50, 86, 88, 98, AL, MH, UC). Hver af dem er opført som opfyldt eller manglende. Dette er Perfuses læsning af reglen, nyttig for "hvorfor fortæller denne betaler os aldrig fradragsbeløbet?" - det er ikke CORE-certificering, som CAQH's autoriserede testleverandører udfører.
8.3.6 Forhåndsgodkendelse
Perfuse implementerer forhåndsgodkendelse to gange, med vilje.
Den FHIR-side er, hvad CMS-0057-F kræver, at betalere udstiller pr. 1. januar 2027. Den 278 er, hvad betalere accepterer i dag, og reglen erstatter den ikke — Da Vinci PAS er i praksis en afbildning af denne transaktion, fordi en 278 er, hvad et udnyttelsesstyringssystem taler. En motor, der kun læser den FHIR-halvdel, kan tale med de systemer, der vil eksistere, og ikke med dem, der gør.
En 278-respons medfører godkendelsesnummer, og det er feltet, hele transaktionen eksisterer for at levere. Uden det er en certificeret service ikke regningsfør: kravet kommer ind med ingen godkendelsesnummer og afvises på grund af manglen på en, hvilket læser nedad som en klinisk afvisning.
En afvisning og en afvisning af at overveje er ikke det samme
Dette er den dyreste forvirring i transaktionen, og Perfuse rapporterer de to separat.
| Hvad ankom | Hvad det betyder | Hvad at gøre |
|---|---|---|
HCR med handling A3 | Betalere overvejede anmodningen og vil ikke godkende den. | Appel, eller ændre behandlingsplanen. |
Et AAA-segment | Betalere ville ikke overveje det — patient ikke fundet, anmoder ikke genkendt, gennemgang ikke dækket. Intet blev besluttet. | Korrigér anmodningen og send den igen. |
Begge læses som "ikke godkendt" for enhver, der scannrer, og de korrekte handlinger er modsatte. At anke noget, som ingen har truffet beslutning om, fører ikke til noget; genindsendelse af en afvisning resulterer i samme afvisning. De parsede resultatnavne, der skete — denied mod not-considered — og AAA04 indeholder betalerens eget råd om, hvorvidt anmodningen overhovedet er tilgængelig.
Delvis certificering rapporteres som partially-certified i stedet for at blive foldet ind i godkendelse. Der er et autorisationsnummer at fakturere imod, så det tælles som godkendt, men den certificerede mængde er ikke den anmodede mængde - og en praksis, der booker seks sessioner imod tre godkendte, opdager det ved den fjerde krav.
En handlingkode, som Perfuse ikke genkender, rapporteres som unknown og ikke som pending. Pending læses som "vent", og venten er den forkerte handling for det meste af, hvad en ikke-genkendt kode kunne være.
En kanal kan rute på beslutningen direkte:
filter: HCR-1 == "A3"
Konvertering mellem de to
Perfuse konverterer en parsed 278 til en Da Vinci PAS ClaimResponse og rapporterer hver vurdering, konverteringen havde brug for, snarere end kun resultatet. Konverteringen følger tre regler:
- Ingen beslut opgraderes. Delvis certificering forbliver delvis, og en anmodning, som betaleren har afvist at overveje, bliver ikke til et afslag. Begge sammenfald er tilgængelige i den åbenlyse mapping, og begge er forkerte i den dyre retning.
- Ingenting opfindes for at udfylde et påkrævet felt. Et certificeret begivenhed uden en autorisationsnummer rapporteres som sådan, og ikke tildelt et plausibelt nummer — et fabrikeret nummer producerer en krav, der afvisses senere af en grund, som ingen kan spore.
- Et beslutning, der kun er båret på linjeniveau, bruges. En betaler, der besvarer per service, kan lade begivenheden uden et beslutning af sin egen; læsning kun på begivenhedsniveau ville rapportere det som afventende, og en praksis venter på et svar, den allerede har, mens godkendelsen udløber. Hvor linjerne er uenige, vinder den mindst gunstige, fordi en begivenhed med en afvist linje ikke er en godkendelse.
Indsnævring til en tre-tilstands-vokabular — godkendt, afvist, afventende — er tilgængelig og udtrykkeligt om, hvad den afviser. Indsnævring af en afvisning af overvejelse giver "afvist" og siger i ord, at den korrekte handling er en korrektet genindsendelse snarere end en appel.
Kontrolleret mod PAS 2.2.1, ikke kun mod sig selv
Den ClaimResponse er formet til Da Vinci PAS 2.2.1-profilen og blev kontrolleret med den officielle HL7-validerer, der er indlæst med den offentliggjorte PAS-pakke. Den første version var kun blevet kontrolleret af Perfuses egne tests, og validereren afviste den med seks til otte fejl per ressource. Hver enkelt af dem er noget, en payers PAS-endpoint også ville have afvist:
| Hvad var forkert | Hvor PAS placerer det |
|---|---|
Beslutningen var i adjudication.category og reason. | reviewAction-udvidelsen, på en adjudikation, hvis kategori er submitted. |
| Årsagskoden med navnet X12-element 1034. | X12 ekstern kode liste 886. |
En afventende anmodning svarede outcome: queued. | outcome handler om behandling, og PAS tillader kun complete, error og partial. En afventende er complete, med review-handling A4. |
processNote.type var en CodeableConcept. | R4 har en kode: print. |
patient, created, insurer og request manglede. | Alle fire er påkrævede. De gives som identifier-referencer, fordi svaret står alene snarere end i en samling. |
Den korrekte output validerer med ingen fejl for en certificering, et afslag og en afventende. Advarslerne, der forbliver, er validereren, der siger, at den ikke kan indlæse X12's kode systemer, som X12 licenserer. Autorisationsnummeret medføres i reviewAction.number, hvor vejledningens eget eksempel placerer det, og i preAuthRef, når svaret kun har én.
Validereren er ikke en del af make check, fordi den kræver Java og en download af vejledningen og dens afhængigheder. Hvad den fandt, holdes af en test i stedet: hver regel, den pålagde, påstås, så en ændring, der genindfører en af disse fejl, mislykkes.
Den Krav & auth-visning konverterer en indklæbet 278 og viser beslutningerne, noterne og ressourcen.
8.3.7 Vedhæftninger og hvorfor de kræver speciel behandling
CMS-0053-F gør 275 til en HIPAA-standard for krav-vedhæftninger, med overholdelse påkrævet pr. 26. maj 2028. Den medfører et dokument — en operativ note, en billedrapport, en scannet formular — knyttet til kravet, det understøtter.
Den 277 er den anden halvdel af den samme samtale. En betaler modtager et krav, beslutter, at det kræver dokumentation, og sender en 277, der anmoder om det; udbyderen besvarer med en 275.
En kanal kan rute på statuskoden direkte, fordi STC01 er en sammensat og dens anden komponent er status. Skrevet i kanonisk form, fordi en komponent adresseres med en punktum, og de to notationer ikke kan blandes — STC-1.2 er element 1, komponent 2:
filter: STC-1.2 in ("227", "233", "252", "287")
Det er koderne, der ubestridt betyder, at et dokument ønskes. Status kategori i STC-1.1 bruges ikke bevidst alene: R4 betyder en dokumentanmodning i visse implementeringsvejledninger og "videresendt andre steder" i andre, så en filter på kategorien alene ville placere færdiggjorte krav i køen til nogen at forfølge.
To identifikatorer afgør, om en vedhæftning nogensinde associeres med sit krav, og begge rapporteres: den vedhæftningskontrolnummer, som udbyderen placerede på det oprindelige krav for at sige, at dokumentation ville følge, og den spornummer, som matcher payers anmodning. En vedhæftning, der ankommer med ingen af dem, arkiveres og kobles aldrig til noget, mens kravet ældes.
275 fortolkes ikke. Perfuse rapporterer dets bytes og hvad afsenderen siger, de er. En vedhæftning kan være en PDF, en TIFF, en CDA-dokument eller en HL7-besked, og en kanal, der behøver indholdet, kan overdrage disse bytes til formatet, der læser det.Den 006020-form, som er den, reglen antager
CMS-0053-F antager version 006020, og dens 275 adskiller sig fra 005010-formen på to måder, der betyder noget.
- Payloaden er i
BDS, ikkeBIN.BDS01navngiver en filter,ASCellerB64.BDS02er længden, ogBDS03er data. - Payloaden er en MIME-enhed, med overskrifter, der siger, hvad dokumentet er, og en base64-krop. Med
B64er enheden selv base64 også.
Perfuse afpakker enheden og rapporterer dokumentet inde i den, med dets indholdstype og filnavn. De bytes, den rapporterer, er nøjagtig de samme, som afsenderen indpakket. En enhed, der ikke kan afpakkes, efterlader den rå payload på plads, med en note om, hvorfor.
Opbygning af en 275. Perfuse opbygger også 006020X314-vedhæftninger: en uanmodet til at ledsage en krav, eller en respons til en betalers 277-anmodning. Forskellen ligger i BGN01 02 mod 11, og om TRN02 bærer kravets PWK06 eller 277's TRN02. Hver opbygget interchange parses tilbage, før den returneres, og responsen siger, om dokumentet inde er det samme, der gik ind.
Strukturen kommer fra de to offentliggjorte ledsagende vejledninger for 006020X314: CMS esMD-vejledningen og UnitedHealthcares. Den kommer ikke fra X12-teknisk rapport, som X12 licenserer og som dette projekt ikke ejer.
- Hvor de to vejledninger er enige, følger Perfuse dem.
- Hvor de forskellige, tilfredsstiller den begge, hvis det er muligt.
CAT02erHLfor et HL7-dokument, som esMD bruger, ogIAfor et billede, som UnitedHealthcare bruger. - Ellers sender den kun det valgfrie segment, når den får værdien: esMD's
REF*X1krav-identifikator og UnitedHealthcaresDTP*472service-dato.
Der er ingen validering mod den tekniske rapport. Partnerens ledsagende vejledning styrer.
8.3.8 Elektroniske signaturer på vedhæftninger
CMS-0053-F antager også en signaturstandard, i 45 CFR 162.2002(e): HL7 Implementation Guide for CDA Release 2, Digital Signatures and Delegation of Rights, Release 1. Den gælder for signaturer, der lægges på vedhæftningsinformation, når den sendes i en HIPAA-vedhæftningstransaktion, fra den 26. maj 2028. En betaler kan ikke bede om mere end vejledningen gør.
Perfuse signerer en C-CDA på den måde på vej ind i en 275, og checker signaturerne på hver C-CDA i en 275, den læser.
- Hvad der signeres. Hele dokumentet undtagen dets
legalAuthenticatorogauthenticator-deltagere, så hver senere signer efterlader de tidligere signaturer intakte. Signaturerne siger det med en XPath Filter 2.0-transformation, som ethvert XML-signaturbibliotek kan evaluere. - Hvor den går. Base64 i
sdtc:signatureTextpå den signerede deltager, med en enkelt linje plain-text-beskrivelse. Signeren er dokumentets juridiske authenticator, hvis det har en usigneret, ellers en nyauthenticator. - Hvad den erklærer. Signerens certifikat, tiden i UTC, en rolle fra NUCC-provider-taxonomien og et formål fra ASTM E1762. Formålet standardiserer til *Forfatterens signatur* for en juridisk authenticator og *Medforfatterens signatur* ellers, som i vejledningens eget eksempel.
- Hvor længe den varer. Vejledningen beder om XAdES-X-L, som bærer alt, en betaler behøver for at verificere signatur årevis senere uden at nå nettet. Det er certifikatstien, en OCSP-respons eller CRL fra CA'en og to tidsstempel fra en tidsstempelmyndighed. Perfuse henter revokationsdata fra adresserne i certifikatet og tidsstempel fra
-tsa-url.
Hvis noget af det er utilgængeligt, laves signatur alligevel og holder. Resultatet navngiver XAdES-formen, den nåede, og siger, hvad der standsede den kort af X-L: for eksempel et selvsigneret certifikat (ingen CA at spørge) eller ingen tidsstempelmyndighed.
Nøglen er -signing-cert og -signing-key. Sæt CA-certifikaterne efter signatoren i samme fil, så stien rejser med signatur. Til en signatur, der betyder, hvad DSDR betyder, skal certifikatet navngive klinikerne, med deres NPI, snarere end serveren. Signering er en admin-handling, som signering af ethvert dokument er.
Vejledningen navngiver ikke et navneområde for dens egne elementer. Perfuse sætter digitalSignature, authorizedSigner og SignaturePurpose i urn:hl7-org:sdtc. Den angiver også formålet som en XAdES-forpligtelsestype med ASTM-OID, som XAdES-værktøjer forstår. Delegering af rettigheder, hvor en delegat signerer med en SAML-påstand fra den autoriserede signer, produceres ikke, og en modtaget rapporteres som ikke verificeret.
Provider-NPI kontrolleres mod dets kontrollécifre. En betaler matcher en vedhæftning til dets krav delvist på grund af dette nummer, og et forkert nummer efterlader vedhæftningen umatchet, mens kravet afvises på grund af manglende dokumentation.
Den Krav & auth-visning opbygger en 275 fra en indklæbet C-CDA eller en uploaded fil, valgfrit signering af C-CDA, og læser en tilbage med hver signaturs fund. Intet på den side sender noget: interchangen overdrages til at blive leveret gennem en kanal, som er, hvor partneren, legitimationsoplysningerne og revisionsstien hører til.
8.3.9 Binære segmenter
Et BIN-segment bærer rå bytes, og rå bytes indeholder afgrænsere. Hvert andet X12-segment slutter ved segment-terminatoren, så en almindelig parser finder segmenter ved at søge efter én byte; en vedhæftning kan ikke findes på den måde. En PDF, der indeholder en ~, ville blive delt i stykker, og hvert stykke er et strukturelt gyldigt segment — så dokumentet afkortes, og hvert segment derefter er misaligneret, og intet rapporterer en fejl.
Perfuse læser byte-tællingen, segmentet erklærer, og tager nøjagtig det antal bytes. To konsekvenser, der er værd at vide:
- En erklæret længde, der ikke matcher data, afvises, og begge numre nævnes. Den relevante spørgsmål er, om afsenderens tælling var forkert eller filen blev afkortet under overførslen, og kun de to numre besvarer det.
BDS, den binære segment006020, gemmer sin tælling iBDS02og dens data iBDS03. Det blev afvist, indtil det kunne bekræftes fra en offentliggjort kilde snarere end fra hukommelsen, og to kilder bekræfter det nu: CMS esMD companion guidesBDS-tabel og UnitedHealthcares guide.
esMD-vejledningens egen eksempel på udveksling erklærer 16 byte for den samme 53-byte-payload, som dens tabel korrekt tæller som 53. Perfuse afviser dette eksempel, som det skal. En test holder både tabelens eksempel og eksemplets fejl, så en ændring i enten retning bliver bemærket.
8.4 FHIR
8.4.1 Hvad en HL7 v2-meddelelse bliver til
Meddelelses typen afgør, hvad der produceres, og hver konvertering rapporterer de vurderinger, der var nødvendige som noter ved siden af bundten.
| v2 | FHIR |
|---|---|
ADT | Patient, et Encounter når der er et besøg, en Condition per DG1-diagnose (også nævnt i Encounter's diagnosis, en indlæggelse som AD), en Procedure per PR1 og en AllergyIntolerance per AL1. A28, A31, A29 og A24 handler om personen, så de producerer ingen Encounter eller diagnoser, men bærer på allergier. |
ORU | DiagnosticReport per OBR, med dets Observationer og Specimen, og ordren det svarer på som en ServiceRequest (dets anmoder OBR-16 eller ORC-12, dets status ORC-5); OBR-32 er resultattolkningen, OBR-34 og OBR-35 udførerne. Resultaterne er grupperet under OBR før dem efter position, fordi OBX-4 ikke er pålidelig. |
ORM, OML, OMG | ServiceRequest. |
SIU | Appointment, med patienten, praktikerne fra AIP og lokaliteternes fra AIL. |
MDM | DocumentReference med dokumentet. |
VXU | Immunization, en per RXA. |
Alt andet producerer Patient og en advarsel, der nævner typen, der ikke blev kortlagt.
Scheduling. En booking, en ombooking, en aflysning og en ikke-møde lander alle på samme Appointment. Dets identitet kommer fra appointments egne numre i SCH-1 og SCH-2, aldrig fra meddelelsen, så en aflysning opdaterer bookingen. Alternativet ville være en anden, aflyst appointment ved siden af en live en, hvilket viser, at patienten har booket en plads, der ikke længere eksisterer.
- Status. Fyldningsstatus i
SCH-25afgør det, og udløsende begivenhed bruges kun, når det er tomt. - Blokerede pladser. En blokeret plads er ikke en appointment med en patient og producerer ingen.
- Starttid. Den læses fra
AIS,AIG,AILellerAIPførst, derefterSCH-11, fordi version 2.5 flyttede den, og feeds ikke alle fulgte med. - Varigheder. En varighed i en enhed, som Perfuse ikke genkender, udelades, ikke gættet.
Dokumenter. Tekstnoter (TX, FT, ST) beholder deres linjeskift, herunder tomme linjer, fordi en tom gentagelse i en note er en afbrydelse af en paragraf.
- Indlejrede dokumenter. Et indlejret PDF, TIFF eller JPEG (
ED) medføres byte for byte. Base64, der ikke er gyldig base64, afvises snarere end videregive. - Typer. Dokumenttypen i
TXA-2beholdes, som den blev sendt, og hvor der er en klar ekvivalent, gives LOINC-koden, som US Core bruger. - Underskrivelse. En note, som ingen har underskrevet, er
preliminary, ogT11gør dokumentetentered-in-error. - Ingen indhold. En meddelelse med intet indhold (
T01,T03og andre ulige nummererede begivenheder) producerer ingen DocumentReference. FHIR kræver indhold, og en tom vedhæftning ville se ud som noten, mens den intet siger.
Dette er, hvad CMS Interoperability Framework-kriterium 14 beder om: chartnoter og kliniske dokumenter returneret som FHIR-vedhæftninger.
Immuniseringer. En dosis rapporteres aldrig som givet, når meddelelsen siger noget andet.
- Afviste doser. En afvist eller ikke-administreret dosis (
RXA-20REellerNA) ernot-done, med årsagen fraRXA-18. - Sletninger. En slettet dosis (
RXA-21D) erentered-in-error. - Historiske optegnelser. En optegnelse, der er transskriberet fra et andet sted (
RXA-9andet end00), er ikke en primær kilde. - Ukendte mængder. En mængde på
999betyder ukendt, ikke 999. - Ruter og steder. Hver dosis tager ruten og stedet fra
RXRefter den, så en meddelelse med to doser ikke giver den anden dosis den første dosis' rute.
Ubehageligt input. Hver af disse rapporteres i noterne snarere end besluttet stille:
- Identifikatorer.
PID-2ogPID-4, trukket tilbage efter v2.7, men stadig sendt, behandles somPID-3.CX.7ogCX.8bliver
Identifier.period. En tildelende myndighed, der bærer en ISO OID (AUSHIC&2.16.840.1.113883.3.879&ISO), bliver urn:oid:. En typekode uden for HL7-tabel 0203 behandles som tekst, ikke markeret som sådan.
- Fusioner.
MRGpå en fusionshændelse (A40og dens slægtninge) sender den pensionerede post også, inaktiv, medPatient.linki begge retninger. Ved enhver
anden hændelse, såsom en A08, fusioneres intet, og en advarsel siger, at den forrige identifikator stadig er aktiv.
- Tider. En fødselsdato i
PID-7går tilpatient-birthTime-udvidelsen. En tidsstempel uden forskydning tager den konfigurerede
tidszone, ellers forskydningen på MSH-7 (v2 antager afsenderens lokale tid), ellers UTC. En fødselsdato er undtagelsen: uden forskydning fra nogen af de tre efterlades den, snarere end at blive markeret som UTC, fordi en forkert forskydning kan flytte en fødsel til en anden dag. birthDate behandles, og en advarsel siger, at tiden blev droppet, og at indstilling af en tidszone for feeden beholder den.
- Resultater. Gentagelser af et tekstresultat samles med linjeskift. Et
ED-resultat eller et kodet resultat, hvis værdi åbenlyst er Base64, bliver en
DocumentReference, som Observationen peger på i derivedFrom, da en R4-Observation ikke har en vedhæftningsværdi. En SN komparator på = droppes som overflødig; <> beholder teksten, fordi ingen kvantitet kan sige "ikke lig med".
- Besøg. En
A08med en udskrivningsdato (PV1-45) er et afsluttet møde. En manglende eller ukendt patientklasse er den
tomme smag UNK, fordi R4 kræver en klasse.
- Z-segmenter navngives i en advarsel, da der ikke findes en standardkortlægning for dem.
- Navne. Når afsenderen splitter et efternavn (
XPN.1,XCN.2) i dets dele - et efternavnspræfiks og et efternavn, personens eget og en partners, som hollandske og flamske navne sendes - erfamilydet hele navn og delene går i HL7's efternavnsudvidelser (humanname-own-prefix,-own-name,-partner-prefix,-partner-name). - Procedurer.
PR1bliver en Procedure med statusunknown, da en ADT ikke siger, om den blev udført eller planlagt; anæstesisten (PR1-8) og kirurgen (PR1-11) er udførere med SNOMED CT-roller. En OPS-kode får også sin SNOMED CT-kategori fra dets kapitel via HL7 DeutschlandsOPS-SNOMED-Category-kort, som ISiK kræver.
8.4.2 Hvad et websted tilføjer: bundt-scriptet
En national profil ønsker ofte, hvad en HL7 v2-meddelelse ikke indeholder: et hospitals IK-nummer eller ODS-kode, hvilket kontakt niveau et besøg er (ISiK), om et givet navn er et fornavn eller en initial (den hollandske nl-core). Perfuse gætter ikke på dem. Et fhir-mål bundle_script er, hvor et websted skriver dem: JavaScript, der køres på hver konverteret Bundle, som bundle, før det valideres og sendes. Hvad scriptet efterlader, er, hvad der sendes, kontrolleret som enhver konvertering, og et script, der kaster, mislykkes meddelelsen, som enhver transformerer. Konsollen har det under målets *Tilføj, hvad dine systemer ved*.
destinations:
- name: kis
type: fhir
fhir:
url: https://fhir.klinikum.example/fhir
version: "4.0.1"
identifier_systems: {KLINIKUM-MUSTERSTADT: "https://fhir.klinikum-musterstadt.example/sid/patientennummer"}
bundle_script: |
bundle.entry.forEach(function (e) {
if (e.resource.resourceType === "Organization" && e.resource.name === "KLINIKUM-MUSTERSTADT") {
e.resource.identifier = [{system: "http://fhir.de/sid/arge-ik/iknr", value: "260326822"}];
}
});
perfuse fhir convert -bundle-script FILE runs the same script, so a site can try it on its own messages first. Two worked examples are in the repository: examples/isik/bundle-script.js (IKNR, Kontaktebene, MR-typed patient number, Diagnosetyp) and examples/nictiz/bundle-script.js (first names and initials). With them the invented German and Dutch messages in conformance/national go from 18 to 42 of 47 resources valid against ISiK and from 12 to 18 of 24 against nl-core; what is left is in the messages or the terminology server, and is listed there.
Bundlen går gennem Perfuses model på vej tilbage, så et scripts ændringer kontrolleres og skrives i målets FHIR-version. Medlemmer, som modellen ikke har nogen felt for, behandles, som scriptet skrev dem, inden for data typer også.
8.4.3 US Core 9.0.0 og USCDI v6
-us-core (og claim_us_core på en fhir-destination) indsætter et US Core-profil i meta.profile, men kun på en ressource, der er blevet kontrolleret mod dette profil og erklæret for at overholde det. En, der ikke lever op til kravene, konverteres og sendes stadig uden krav, og en note giver årsagen, såsom "US Core kræver en møde-type, og denne Encounter har ingen". Kontrollerne er gengivet fra US Core 9.0.0, den version, som ONC's 2026 Standards Version Advancement Process godkender til USCDI v6. De dækker Patient, Encounter, laboratorie-Observation og DiagnosticReport, Specimen, Practitioner, Organization, Location, Immunization, DocumentReference, møde-diagnose Condition og AllergyIntolerance.
Hvad konverteren transporterer, efter USCDI v6 dataklasse:
| USCDI v6 | Fra | Som |
|---|---|---|
| Patient Demographics | PID | Navn, fødselsdato, køn, adresse, telefon og email, identifikatorer. Race og etnicitet (PID-10, PID-22) i US Core's udvidelser, når de er kodet i CDC Race and Ethnicity. Foretrukket sprog (PID-15) som BCP 47 |
| Encounter Information | PV1 | Encounter med type, klasse, periode, lokalitet og deltagere |
| Facility Information | PV1-3 | Lokalitet, med faciliteten som dens ledende Organisation |
| Problems, Date of Onset | DG1 | Condition (encounter diagnose). DG1-5 er starten, som HL7 v2-til-FHIR-kort har det |
| Allergies and Intolerances, Reaction | AL1 | AllergyIntolerance med kategori, kritikalitet og reaktion |
| Laboratory | ORU | DiagnosticReport, Observationer, Specimen (fra SPM), ServiceRequest |
| Orders | ORM, OML | ServiceRequest |
| Immunizations | VXU | Immunization |
| Clinical Notes | MDM | DocumentReference |
| Care Team Members | PV1, TXA, DG1 | Practitioner |
Ikke medtaget, fordi v2-beskedninger af disse typer ikke indeholder dem, eller Perfuse ikke kortlægger dem: Medications, Procedures, Goals og Preferences, Health Status Assessments, Care Plan, Family Health History, Medical Devices (UDI), Health Insurance Information, Vital Signs som en distinkt profil, og Provenance.
8.4.4 R4 i begge retninger
En FHIR-server, der erklærer R4, accepterer R4. Det var ikke sandt for Encounters, før denne version. Serveren konverterede, hvad den serverede, til R4, men læste, hvad den modtog, som om det allerede var i dens interne form, så en R4-Encounter blev afvist med en 400. Det samme var hver bundle, som Perfuses egen ADT-konvertering producerede, fordi hver af dem indeholder Encounter.class, som R4 skriver som en enkelt kodning.
Det blev opdaget første gang, noget postede en konverteret ADT til Perfuses egen R4-server. En test gør nu det for hver af de kortlagte beskedtyper, og en anden checker, at alt, der skrives som R4, læses tilbage uændret.
8.4.5 International Patient Summary
GET /fhir/Patient/{id}/$summary, eller GET /fhir/Patient/$summary?identifier=system|value, returnerer en International Patient Summary (HL7 IPS 2.0.0): en FHIR document-Bundle, der listar patientens aktive problemer, allergier, mediciner, vaccinationer, resultater, vitaltegn, procedurer, enheder, tidligere sygdomme, sociale historie og plejeplaner, hver med en læselig narrative. Det er den korte post, en kliniker, der aldrig har mødt patienten, læser først, og den samling, der udveksles mellem lande fra 2029 i det europæiske sundhedsdatarum.
Det er bygget fra, hvad FHIR-lageret indeholder, og intet opfindes:
- Poster, der er markeret
entered-in-error, udelades. - En løst tilstand går under tidligere sygdom, ikke problemer.
- En medicinordre, der blev stoppet eller afsluttet, er historie, ikke en nuværende medicin.
- De tre afsnit, IPS kræver (problemer, allergier, mediciner), er altid til stede. Når en af dem ikke har noget i sig, bærer afsnittet den kodede tomme årsag
unavailableog siger, at serveren ikke har nogen information, "hvilket ikke betyder, at der ikke er nogen". En tom allergiliste må aldrig læses som "ingen kendte allergier". - De praktiserende, organisationer, mediciner og lokaliteter, posterne peger på, er inkluderet, så dokumentet kan læses på egen hånd.
Adgang følger $everything: en token, der er begrænset til en patient, får en 403 for en anden, og en identifikator, der matcher to patienter, afvises snarere end gættet. Kun IPS-profilen bygges; at bede om en anden profile afvises. Dokumentet, som Perfuse producerer fra sine testposter, validerer mod IPS 2.0.0 Bundle-profilen med HL7-valideringen, uden fejl. En post bygget fra rigtige feeds kan stadig fejle, hvor feedens egne koder gør (en displaynavn, som codesystemet ikke bruger, for eksempel), fordi sammenfattningen videregive data, som den modtager.
Udveksling → Sundhedslinks → Del udfylder indholdet med en patients sammenfattelse: skriv patientens FHIR-id og vælg Brug deres patient-sammenfattelse, læs derefter og opret linket. Bygningen af det auditeres som fhir.summary.
8.4.6 Overførselsopsummeringer til efterbehandling (PACIO)
Når en patient forlader hospital for et plejehjem, en rehabiliteringsenhed eller hjemmepleje, sender hospitalets EHR en C-CDA: en overførselsopsummering, en udskrivningsopsummering eller en CCD. Perfuse omdanner dette dokument til overførselsopsummeringen i PACIO's Transitions of Care-vejledning (hl7.fhir.us.pacio-toc 1.0.0): en FHIR R4 document-samling, US Core 8.0.1 indeholdt, som modtagende institutions system kan arkivere uden at nogen læser XML.
- Hvert af guidens femten afsnit er til stede, hver med sin egen tekst, i guidens rækkefølge: forudgående direktiver, allergier, adfærdssundhed, funktionel status, vaccinationer, udskrivningsinstruktioner, medicinske apparater, medicin, behandlingsplan, problemer, procedurer, årsag til henvisning, resultater, social historie og vitaltegn.
- Et afsnit, som dokumentet ikke havde, siges at mangle, og er aldrig udfyldt. Det sendes tomme, med den kodede årsag
unavailableog sætningen "Det sendende dokument havde ingen ... afsnit". Et tomt allergi-afsnit må ikke lyde som "ingen kendte allergier". - Et afsnit, der transporteres som alene tekst, beholder sin tekst og får ingen poster. Prosa konverteres ikke til kodet data. Funktionel status, adfærdssundhed (C-CDAs mentale status-afsnit), forudgående direktiver, medicinske apparater, behandlingsplan, udskrivningsinstruktioner, årsag til henvisning og social historie sendes på denne måde i dag; noterne siger det for hvert.
- Kodet indtastning bliver ressourcer efter de samme regler som den almindelige konvertering: allergier (US Core AllergyIntolerance), problemer og udskrivningsdiagnoser (US Core Condition, problemliste eller mødediagnose), procedurer, vaccinationer, resultater, vitaltegn og medicin som en PACIO-medicinliste af MedicationStatements (
104204-3, udskrevne medicinliste, fra et udskrevet medicin-afsnit;104202-7, aktiv medicinliste, ellers). - Vitaltegn i FHIRs form. Et systolisk og et diastolisk tryk, der tages sammen, bliver ét blodtrykspanel (
85354-9) med to komponenter, og en mere specifik kode (kropsvægt målt,3141-9) bærer også koden FHIRs vital-signs-profiler fikser (29463-7), ved siden af den oprindelige. - Hvem og fra hvor. Dokumentets forfatter bliver Compositions forfatter (en Practitioner, med NPI, når dens kontrollciffer er gyldigt), dets formynder den formynderskabs-organisation, dets omfattende møde det ophold, som sammenfattningen lukker. Et dokument uden person som forfatter eller uden formynder, afvises: guiden kræver begge, og Perfuse vil ikke sætte et navn på en klinisk optegnelse, som ingen har givet.
- Negation beholder sin betydning. "Ingen kendte allergier" (en negation af en allergi over for nogen substans) sendes som SNOMED CT
716186003; en negation af en allergi over for ét lægemiddel afvises, fordi FHIR ikke kan sige det, og ressourcen ville sige det modsatte; en negation af et problem errefuted.
Tre måder at lave en:
- En kanal: en
cdadestination medwrite: transferposter hver enkelt documents overførselsopsummering til FHIR-serversBundleendpoint (url), eller skriver<document>.transfer.jsontildir. I kanalbyggeren: Emit › En PACIO overførselsopsummering. - Kommandolinjen:
perfuse fhir transfer [-authority OID=URI] [-out dir] <document.xml>.... - Konsollen: Dokumenter, aktiver Også lav en PACIO overførselsopsummering, og læs dokumentet.
Kontrolleret med den officielle FHIR-validering mod TOC 1.0.0 Bundle-profilen, på HL7's egne C-CDA-eksempler (en overførselsopsummering, en udskrivningsopsummering og en CCD). Den eneste fejl, den rapporterer, er i guiden: hver vitaltegn matcher både dens simple-observation og dens vital-signs Bundle-indslice, så det ikke kan undgås af nogen afsender. Ikke gjort endnu: omdannelse af tekst kun-sektionernes poster (funktionsstatus, mental status, plejeplan, apparater) til kodificerede ressourcer og guidens TOC DocumentReference, der indekserer en gemt overførselsopsummering.
8.4.7 Abonnementer
Med -fhir-subscriptions sender FHIR-endpointen meddelelser, når en Encounter eller en Appointment er oprettet eller ændret. Den følger FHIR Subscriptions R5 Backport IG for R4, som er, hvad CMS Interoperability Framework-kriterium 15 og TEFCA's FHIR-vejviser bruger til appointments- og encounter-meddelelser.
En klient opretter en Subscription, der navngiver et emne, og valgfrit et filter, såsom Encounter?patient=Patient/123. Emnerne er listet i kapacitetsudtalelsen:
| Emne | Udløser på | Filter |
|---|---|---|
https://perfuse.health/fhir/SubscriptionTopic/encounter | Encounter oprettet eller opdateret | patient, status, class |
https://perfuse.health/fhir/SubscriptionTopic/appointment | Appointment oprettet eller opdateret | patient, status |
Et filter, der navngiver noget andet, afvisses, ikke ignoreret. Et ignoreret filter er en abonnement, der underretter om hver patient, når klienten bad om en.
Egenskaberne, implementationen er bygget omkring:
- En anerkendt ændring er aldrig en tabt meddelelse. Meddelelsen optages i samme database-transaktion som den ændring, den beskriver, og leveres derefter, så den overlever en genstart. En test skriver en Encounter, starter en ny server på samme database og checker, at meddelelsen ankommer.
- Meddelelser ankommer i rækkefølge, og huller er synlige. Begivenhed 2 sendes ikke før begivenhed 1 er accepteret, og hver meddelelse bærer det løbende antal, så en modtager kan se, når den har mistet en.
- Serveren afgør, når en abonnement er aktivt. Et nyt abonnement er
requested, og bliver kunactive, når slutpunktet accepterer en håndtryk. En klient, der beder omactive, fårrequested. Et afvist håndtryk prøves igen fire gange over cirka femten sekunder, før abonnementet er eterror: det udsendes i samme øjeblik, abonnementet gemmes, ofte før klienten, der oprettede det, lytter. - En fuld-resurs-meddelelse bærer den version, der ændredes. En udskrivningsmeddelelse bærer udskrivningen, ikke det, Encounter havde blevet til på det tidspunkt, leveringen lykkedes.
- Fejl er begrænsede. En afvist levering prøves igen med en voksende forsinkelse. Efter ti på hinanden følgende fejl går abonnementet til
error: senere ændringer tælles, men ikke køer, og opdatering af abonnementet genoptager leveringen fra den ældste meddelelse, der er holdt. Antallet viser derefter, hvor mange der blev mistet.
Hvad en klient kan få serveren til at gøre, er begrænset med vilje:
- Endpoints skal være
https, medmindre operatøren passerer-fhir-subscriptions-allow-http, som er til en testmodtager. - Udgangsreglen anvendes, når et abonnement oprettes, igen ved hver levering og på den adresse, hver forbindelse faktisk når (så et navn, der ændrer, hvad det opløser til mellem kontrollen og forbindelsen, afvisses stadig); omdirigeringer følges ikke.
- Payloaden standarder til
id-only, som siger, hvad der ændredes, og lader modtageren hente det med sine egne legitimationsoplysninger. - Intet, en modtager sender tilbage, vises for nogen, kun dets statuskode.
Det er slået fra, medmindre det bedes om, fordi når det er slået til, kan en FHIR-klient få denne server til at sende patientdata til en URL, som klienten vælger. Det kræver en R4-endpoint, der accepterer skrivning, og afvister at starte, hvis ikke.
Ikke implementeret, så ingen behøver at finde ud af det ved at prøve:
- kanaler andre end
rest-hook - hjerteslag
- meddelelser ved sletning
$status- og$events-operationer
Visningen Abonnementer viser hvert abonnements emne, filter og endpoint, hvor mange begivenheder det har haft, hvor mange der er accepteret og hvor mange venter, og den sidste årsag, en af dem blev afvist. Header-værdier og endpointets forespørgselsstreng holdes tilbage, fordi det er, hvor en abonnents legitimationsoplysninger bor.
8.5 NCPDP Telekommunikationsstandard
Apotekkrav. Fast breddeheader efterfulgt af variable segmenter.
To detaljer, der er vigtige, begge af dem er lette at gøre forkert og producere plausibele resultater:
Headeren er nøjagtig 56 bytes og fast bredde. En kort header kan ikke detekteres ved længde alene, fordi en afkortet header plus de følgende segmenter stadig overstiger 56 bytes. Detektion er, at en korrekt header aldrig indeholder en separatorbyte, så headeren scannes efter en, og en besked, der har en, afvises med antallet af bytes, det er forkortet med.
0x1E og 0x1C er gruppe- og felt-startmarkører, ikke separatorer. At behandle dem som separatorer flytter hver felt én plads til venstre, og de fleste af de resulterende værdier forbliver plausible — en mængde lander, hvor en dags forsyning var forventet, og begge er numre.
0x1C, som er MLLP's egen slut-blok-byte, så rammning af et krav ville afkorte det ved det første feltmarkør.8.6 NCPDP SCRIPT
Elektroniske recepter i XML. Den interne pakke kaldes eprescribe, fordi script var optaget af JavaScript-motoren.
Den centrale sikkerhedsbekymring er erstatningsflaget, og det læses baglæns fra intuitionen: på ledningen, betyder 0, at erstatning er tilladt, og 1 betyder udlever som skrevet.
Et fraværende erstatningsflag afvises snarere end standardiseres. Begge mulige standarder når patienten — den ene kan udlevere en generisk, hvor lægen krævede mærkevaren, den anden forhindrer en erstatning, som lægen tillod — så der er ingen sikker antagelse, og beskeden stopper.
En Schedule II-recept med genopfyldninger afvises, og byggeren vil ikke producere en.
Afvigelser og advarsler opbevares som separate lister snarere end en liste med severity-mærkning, fordi en læser, der skal kontrollere en alvorlighedsfelt for at vide, om beskeden blev sendt, til sidst ikke kontrollerer det.
Elektronisk forudgående autorisation (PAInitiationRequest, PARequest, PAAppealRequest, PACancelRequest) og Real-Time Prescription Benefit besvares af betalerens side på /ncpdp/script og /ncpdp/rtpb, fra lægemiddelformulariet; se CMS-0057.
8.7 DICOM
Billeddiagnostik. Perfuse kan modtage DICOM-objekter, forespørge en fjernarkiv og gemme til en, over de klassiske DICOM-netværkstjenester eller over DICOMweb, og den kan opretholde et arkiv af sin egen for visere.
DICOM er ikke en meddelelsesformat på samme måde som de andre — objekter er store, og associationshåndtrykket er vigtigere end payload-parsing. De called_ae og calling_ae titler er den hyppigste årsag til, at en første forbindelse mislykkes, og fejlen ligner et netværksproblem snarere end et konfigurationsproblem.
8.7.1 Hvad en C-STORE-lytter accepterer
Ladt åben, accepterer en DICOM-lytter alt fra nogen, der kan nå porten. Fire indstillinger under Hvad denne lytter accepterer indsnævrer dette, og den første er den, der er værd at forstå.
Kun acceptér disse ringende AE-titler er begrænsningen. Den *kaldte* AE-titel — den, der står ved siden af adressen — er navnet, en afsender ringer, så den identificerer denne lytter snarere end afsenderen, og det er ikke en begrænsning. Enhver, der kan nå porten, kan bruge den korrekte kaldte AE-titel, fordi den offentliggøres til dem. Uden en liste over tilladte kaldere, kan enhver vært på netværket pushe billeder ind i en klinisk kanal.
Kun acceptér disse SOP-klasser og kun acceptér disse overførselssyntakser tager komma-separerede UIDs. Tom accepterer hver type objekt og forhandler, hvad som helst kompression afsenderen tilbyder, hvilket inkluderer typer, denne kanals destinationer ikke kan håndtere. At afvise ved associationsdannelsen er klart for afsenderen snarere end at acceptere objektet og fejle herefter.
Største objekt accepteret er i bytes, og nul betyder ingen begrænsning. Hel-side-billeder og lange serier løber op i gigabyte, så begrænsningen er ellers hukommelse.
8.7.2 DICOMweb
DICOMweb er DICOM over HTTP: QIDO-RS-søgninger, WADO-RS- og WADO-URI-hentninger, STOW-RS-gemninger. Browser-visningsprogrammer som OHIF kunne kun tale DICOMweb, og det gør sky-billedtjenesterne (Google Cloud Healthcare, Azure Health Data Services, AWS HealthImaging) også. Perfuse bruger det på tre steder.
Billeddatabasen. Start serveren med -dicomweb-archive DIR (Indstillinger › Data › Billeddatabase) og den gemmer objekter i den mappe, indekseret i SQLite, og serverer dem på /dicomweb på konsollens egen adresse: QIDO-RS på studie-, serieniveauer og instansniveau, WADO-RS til objekter, metadata, billeder og bulkdata, WADO-URI på /dicomweb/wado og STOW-RS. Læsning kræver seerrollen og lagring operatørrollen, med en session eller en API-nøgle; hver læsning og lagring er i Aktivitet som dicomweb.read eller dicomweb.store. En konto, der er begrænset til en lejer eller kanalgrupper, afvises, fordi arkivet tilhører hele serveren. Objekter gemmes nøjagtig, som de modtages, så hvad en seer henter er bit for bit, hvad der blev gemt. Billeder returneres i den overførselssyntaks, de blev gemt i; en anmodning, der kræver omkodning, svarer 406 i stedet for et konverteret billede.
En søgning på et attribut, arkivet ikke indekserer, svarer 400 i stedet for at ignorere betingelsen og returnere flere studier, end der blev bedt om. Indekseret: patientnavn (jokertegn og fuzzy-matching med fuzzymatching=true), patient-ID, fødselsdato, køn, studiedato og -tid (intervaller), accession-nummer, studie-ID, beskrivelse, henvisende læge, studie-, serie- og SOP-instans-UID'er (lister), modalitet, kropsdel, serienummer og -beskrivelse, SOP-klasse, instansnummer, rækker, kolonner og antal billeder.
Kilden. type: dicomweb lytter efter STOW-RS, på /dicom-web/studies som standard (den sti, Orthanc og dcm4chee bruger), og sender hver objekt gennem kanalen som en DICOM-besked. Kanalen kræver dataType: dicom. Angiv en bærertoken eller brugernavn og adgangskode: uden en, kan hvem som helst, der kan nå porten, sende billeder ind i kanalen. Svaret lister hver objekt som gemt eller mislykket, med DICOM-fejlårsagen, så afsenderen ved, hvilke der skal sendes igen.
name: imaging-from-viewers
dataType: dicom
source:
type: dicomweb
dicomweb:
listen: 0.0.0.0:8043
token: ${STOW_TOKEN}
tls: { enabled: true, cert_file: /etc/perfuse/imaging.crt, key_file: /etc/perfuse/imaging.key }
destinations:
- name: archive
type: dicomweb
dicomweb:
url: https://perfuse.example/dicomweb
token: ${ARCHIVE_TOKEN}
Destinationen er under levering, under DICOMweb-arkiver.
At pege OHIF mod arkivet
Brug en DICOMweb-datakilde med qidoRoot og wadoRoot sat til arkivets adresse (skærmen Billeder viser den, med den hele datakildeblok til at kopiere), wadoUriRoot til den adresse efterfulgt af /wado, imageRendering og thumbnailRendering til wadors, og supportsFuzzyMatching sand. En seer på en anden oprindelse kræver, at oprindelsen er i -dicomweb-cors (Tilladte browseroprindelser), og dens anmodninger kræver en API-nøgle i Authorization-headeren, fordi en browser på en anden oprindelse ikke sender konsollens sessionscookie. At servere OHIF fra samme oprindelse gennem en omvendt proxy undgår begge.
Testet mod Orthanc med dets DICOMweb-plugin, i begge retninger: destinationen gemmer i Orthanc, og Orthancs DICOMweb-klient søger Perfuses arkiv og henter en studie, der er byte-identisk med den, der blev gemt. OHIF 3 listar arkivets studier og viser deres rammer med indstillingerne ovenfor. OHIF og flere andre klienter sender type= uquoteret i Accept- og Content-Type-headers, hvilket RFC 2045 ikke tillader; Perfuse accepterer det.
8.8 IHE-dokumentdeling: XDS.b, XCA, XDR, MHD, PIXm og PDQm
Kliniske dokumenter, der deles mellem organisationer på samme måde som sundhedsoplysningstjenester, Carequality og eHealth Exchange: et repository holder dem, et register indekserer deres metadata, og et fællesskab besvarer andre fællesskabers forespørgsler gennem en gateway. Start serveren med -xds REPOSITORY-OID (Indstillinger › Data › Dokumentdeling) og den er alle træ, i denne servers database, på følgende adresser, hver med en API-nøgle som bærertoken (seerrollen til forespørgsler og hentning, operatørrollen til indsendelse; de fleste affinitetsdomæner tilføjer gensidig TLS foran):
| Adresse | Skuespiller | Transaktioner |
|---|---|---|
/xds/repository | Dokumentarkiv | ITI-41 Tilføj og registrér dokument-sæt-b, ITI-43 Hent dokument-sæt |
/xds/registry | Dokumentregister | ITI-18 Register-lagret forespørgsel (alle tretten lagrede forespørgsler), ITI-42 Registrér dokument-sæt-b |
/xca/gateway | XCA-svar-gateway | ITI-38 Tværgateway-forespørgsel, ITI-39 Tværgateway-hent, med -xds-home-community urn:oid:... |
/mhd | MHD-dokumentmodtager og svarer | ITI-65 Tilføj dokument-bundle, ITI-66 Find lister, ITI-67 Find dokumenthenvisninger, ITI-68 Hent dokument |
/mhd/Patient | PDQm-leverandør og PIXm-manager | ITI-78 Patientdemografisk forespørgsel, ITI-83 Patient/$ihe-pix, fra FHIR-lagrets patienter |
/pixv3 | PIX-manager (HL7 v3) | ITI-44 Patientidentitetsfeed HL7 V3, ITI-45 PIXV3-forespørgsel, fra patientindekset (-mpi) |
/pdqv3 | PDQ-leverandør (HL7 v3) | ITI-47 PDQV3-forespørgsel, med fortsættelse og annullering, fra patientindekset |
SOAP-transaktionerne er SOAP 1.2 med WS-Addressing og MTOM/XOP, hvor dokumenter rejser (et dokument inline som base64 accepteres også). En mislykket transaktion besvares med en RegistryResponse med IHE-fejlkoder, ikke en SOAP-fejl: XDSDuplicateUniqueIdInRegistry, XDSNonIdenticalHash, XDSPatientIdDoesNotMatch, XDSMissingDocument, XDSRegistryMetadataError (med feltet, der mangler), XDSStoredQueryMissingParam, XDSUnknownStoredQuery, XDSUnknownRepositoryId, XDSUnknownCommunity og UnresolvedReferenceException. En erstatning (RPLC, XFRM_RPLC) gør dokumentet, det erstatter, forældet, som herefter kun besvarer forespørgsler, der beder om forældede dokumenter; APND, XFRM og signs gemmes som associationer. Hash og størrelse beregnes af repository og kontrolleres imod, hvad indsendelsen siger. Dokumenter og metadataopdatering på forespørgsel (ITI-57) understøttes ikke, og en indsendelse, som beder om dem, afvises med årsagen.
MHD er samme register i FHIR: et dokument, der leveres via MHD, findes af ITI-18 og via XCA, og et dokument, der leveres via XDS.b, findes af ITI-67. En DocumentReferences id er postens UUID, dens masterIdentifier den unikke id, og dens attachments url er ITI-68-adressen på dokumentet. Patienter løses til affinitetsdomænets identifikator fra FHIR-lageret: den første identifikator, hvis system er urn:oid:, eller Patienten i Bundlen. PIXm besvarer hver anden identifikator af Patienten med den givne (sourceIdentifier=system|value, indsnævret af targetSystem), og 404 for en, den ikke kender; PDQm søger efter identifikator, navn, fødselsdato, køn, adresse og telecom.
Publicering. En kanals xds-destination publicerer hvert klinisk dokument, det modtager, et CDA-dokument eller et, der medfølger en HL7 v2-besked, til ethvert XDS.b-repository med ITI-41. Metadata læses fra dokumentet: patienten (identifikatoren i patient_domain, affinitetsdomænets tildelende myndighed), titel, type (som typeCode og, medmindre angivet, classCode), oplukket og servicetid, forfatter, fortrolighed, sprog og format (C-CDA 2.1 eller 1.1-struktureret brødtekst, XDS-SD eller mimeTypeSufficient, fra dets skabeloner); og fuldendt fra, hvad et dokument ikke siger: afsenderens source_id, facility_type og practice_setting hver register kræver. Repositorys RegistryResponse afgør leveringen: en fejl eller en fejl i en PartialSuccess er en mislykket levering med registerets fejlkoder.
destinations:
- name: hie
type: xds
xds:
url: https://hie.example/xds/repository
source_id: 1.2.840.114350.1.13.99
patient_domain: 1.2.840.114350.1.13.99.2.7.5.737384.14
facility_type: { code: "225732001", scheme: 2.16.840.1.113883.6.96, display: Community hospital }
practice_setting: { code: "394802001", scheme: 2.16.840.1.113883.6.96, display: General medicine }
tls: { enabled: true, cert_file: /etc/perfuse/hie.crt, key_file: /etc/perfuse/hie.key }
XDR. Add direct_from (your Direct address) and direct_to (the recipients') and the same destination sends XDR as Direct's transport, as the Direct Project's *XDR and XDM for Direct Messaging* describes it: a Direct addressing block (urn:direct:addressing) in the SOAP header names sender and recipients, and the submission's intendedRecipient names each recipient (||^^Internet^address). Point url at the recipient's XDR endpoint or a HISP that takes XDR. XDR travels over TLS, usually with a client certificate (tls), and is not S/MIME. A direct source takes XDR too (see Direct below).
xds:
url: https://xdr.hisp.example/xdr
source_id: 1.2.840.114350.1.13.99
patient_domain: 1.2.840.114350.1.13.99.2.7.5.737384.14
facility_type: { code: "225732001", scheme: 2.16.840.1.113883.6.96, display: Community hospital }
practice_setting: { code: "394802001", scheme: 2.16.840.1.113883.6.96, display: General medicine }
direct_from: referrals@direct.hospital.example
direct_to: ["intake@direct.clinic.example"]
tls: { enabled: true, cert_file: /etc/perfuse/xdr.crt, key_file: /etc/perfuse/xdr.key }
PIX og PDQ i HL7-version 3. Med patientindekset aktiveret (-mpi), er /pixv3 en PIX-manager og /pdqv3 en PDQ-leverandør over SOAP 1.2, til hospitaler og udvekslinger, der stadig taler IHE's v3-profiler. En kilde føder patienter med ITI-44 (rekord tilføjet PRPA_IN201301UV02, revideret PRPA_IN201302UV02, duplikater løst PRPA_IN201304UV02): patientens første identifikator er dens rekord, de andre og dem i asOtherIDs er identifikatorer, den bærer, og en sammenlægning folder den forrige rekoords identifikator ind i den overlevende, som en HL7 v2 A40 gør. ITI-45 (PRPA_IN201309UV02) besvarer de andre identifikatorer for personen, der holder en, indsnævret af dataSource, i Patient.id; den forespurgte identifikator kommer kun tilbage i den gentagne forespørgsel. ITI-47 (PRPA_IN201305UV02) matcher demografi (navn, køn, fødselstidspunkt, identifikator, adresse, telecom) med indeksets egen matcher, minimumDegreeMatch som en score ud af 100, otherIDsScopingOrganization begrænsning af domænerne, og initialQuantity paginering af svaret: resten kommer med QUQI_IN000003UV01 i ti minutter, eller er droppet af dens annullering. Svarene følger transaktionernes tilfælde: en ukendt patient eller domæne er AE med fejl 204 og placeringen af parameteren, en kendt patient med intet i de domæner, der er bedt om, er NF. v3 navngiver en myndighed kun ved OID, så en identifikator, hvis system er en URL med ingen OID bagved (nogle nationale numre), er udeladt af v3-svar og givet over FHIR; indstil virksomhedsidentifikatorens system til en OID (urn:oid:..., i indeksets indstillinger) til EUID og den ansvarlige at fremgå. Visningsrollen forespørger og operatørrollen føder; hver transaktion er revisioneret med en identifikator, aldrig et navn. Et nøgent v3-meddelelse, der er publiceret som application/xml, besvares på samme måde, hvilket er praktisk til testning med hånden.
Udveksling › Dokumentdeling viser, hvad registeret indeholder, og hvor det nås, finder en patients dokumenter i dette register eller et andet (et registers ITI-18 eller en gateways ITI-38), henter et, og publicerer et CDA-dokument manuelt med den metadata, en destination ville give det.
Verificeret mod NIST XDS Toolkit 7.13.0, den IHE-referenceimplementering: Perfuses ITI-41, ITI-18 og ITI-43 mod dens Registry/Repository-simulator (accepteret uden valideringsfejl, dokumentet hentet byte-identisk), og dens Initiating Gateway-simulator, der forespørger og henter fra Perfuses Responding Gateway over XCA, uden fejl i dens log. Hver SOAP-besked Perfuse skriver validerer mod ebXML Registry 3.0 og XDS.b-schemas, og MHD DocumentReference og SubmissionSet mod IHE MHD 4.2.2 med HL7 FHIR-validereren. XDR fra en xds-destination med en Direct-adresseringsblok blev accepteret af værktøjets Document Recipient-simulator, hvis metadata-validering fandt den ene fejl beskrevet i docs/verification.md, og af ONC SITES XDR-validerer, Direct XDR-checklisten (h)(2)-certificeringstesten anvender. PIX og PDQ v3-svar validerer mod IHEs HL7 V3-schemas (NE2008 multicacheschemas), og IHEs egne eksempelbeskeder (ITI-44-feed, merge, ITI-45-forespørgsel, ITI-47-forespørgsel, fortsættelse og annullering) besvares, som deres offentliggjorte svar viser. Endnu ikke kontrolleret mod en uafhængig PIX eller PDQ v3-implementering, Gazelle eller en Connectathon.
8.9 Direkte sikker beskedsformidling
Direct er, hvordan US-udbydere sender hinanden henvisninger, sammenfattende og resultater via sikker e-mail: hver meddelelse er signeret med afsenderens certifikat og krypteret til modtagerens (S/MIME), og rejser mellem HISPer (Health Information Service-udbydere), der udsteder adresserne og garanterer for dem. Perfuse er kantsystemet ved siden af din HISP, ikke en HISP: HISP udsteder din adresse, dens certifikat og dens nøgle, og du holder dens trust-bundle (såsom DirectTrusts). Det følger Direct Applicability Statement for Secure Health Transport 1.2, Implementation Guide for Delivery Notification, IHE XDM (ITI TF-1 Annex 15) til dokumenter med metadata, Certificate Discovery for Direct Project Implementation Guide (DNS og LDAP), og XDR og XDM til Direct Messaging.
Sending. A direct destination signs each message as your address (SHA-256, RSA), encrypts it to every recipient's certificate and your own (AES-256-CBC, RSA key transport), and submits it to the HISP by SMTP with STARTTLS required. The message travels as an attachment named by its content (document.xml, message.hl7, resource.json), or, with xdm: true, a CDA document travels as an IHE XDM package (IHE_XDM/SUBSET01/METADATA.XML with the document and its hash and size, plus INDEX.HTM and README.TXT) that receiving EHRs import with its metadata. Recipient certificates come from the Direct address book (below), then from DNS, where Direct publishes them as CERT records (RFC 4398): under the address with its @ made a dot, else under its domain; then from the recipient domain's LDAP directory, which its _ldap._tcp SRV record names (or ldap: host:port; ldap: off never asks one): each naming context is searched anonymously for an entry whose mail is the address, then the domain, and its userSMIMECertificate or userCertificate read. A certificate is used only when it is for the address or its domain, has not expired, and chains to one of your anchors, fetching any intermediate issuer its Authority Information Access extension names; and it is refused when its issuer's revocation list (from its CRL distribution point, signed by that issuer) lists it. A list that cannot be fetched does not stop delivery. A recipient with no such certificate is a failed delivery, never plain e-mail. to and subject take field references such as {PV1-8.1}, and request_mdn asks the recipient for a delivery notification.
destinations:
- name: referrals
type: direct
direct:
address: referrals@direct.hospital.example
cert_file: /etc/perfuse/direct/referrals.crt # with its chain after it
key_file: /etc/perfuse/direct/referrals.key
anchors_file: /etc/perfuse/direct/anchors.pem
to: ["intake@direct.clinic.example"]
subject: "Referral for {PID-5.1}"
text: "Please see the attached summary."
xdm: true
xdm_source_id: 1.2.840.114350.1.13.99
smtp_host: smtp.hisp.example:587
username: referrals
password: ${DIRECT_HISP_PASSWORD}
request_mdn: true
Modtagning. En direct kilde er SMTP-serveren, som HISP leverer din adresses mail til. Den tager imod mail for den adresse alene (alt andet afvistes ved RCPT), kræver STARTTLS, når der gives et certifikat, og åbner hver besked, før noget læser den: dekrypterer den med din nøgle, verificerer signaturerne mod dine anchors, og kontrollerer, at signaturcertifikatet er for afsenderadressen eller dets domæne. En besked, der ikke er krypteret S/MIME, er signeret af en afsender, du ikke stoler på, eller er signeret af et certifikat for en anden, afvistes ved DATA med årsagen, så HISP beholder den og rapporterer den til afsenderen; Perfuse accepterer aldrig, hvad den derefter dropper. En XDM-pakkes dokumenter bliver hver til en besked (kontrolleret mod hashene i dets metadata); ellers bliver hver vedhæftning til en besked, eller teksten, når der ikke er nogen. Med smtp_host sat, besvares hver besked, der modtages, med en signeret, krypteret "behandlet"-meddelelse (MDN), og meddelelser, der ankommer for det, du sendte, logges.
source:
type: direct
direct:
address: intake@direct.clinic.example
cert_file: /etc/perfuse/direct/intake.crt
key_file: /etc/perfuse/direct/intake.key
anchors_file: /etc/perfuse/direct/anchors.pem
listen: 0.0.0.0:2525
tls_cert: /etc/perfuse/tls/server.crt
tls_key: /etc/perfuse/tls/server.key
smtp_host: smtp.hisp.example:587
Fra HISP's mailbox. En HISP, der holder mail i stedet for at levere den, giver adressen en IMAP-mailbox: imap læser den (TLS eller STARTTLS, hver afstemning en frisk session), åbner hver besked som ovenfor, flytter hvad der blev taget til move_to (eller sletter det) og hvad der ikke kunne åbnes til error_folder, så intet læses to gange. listen kan derefter lægges fra. En HISP, hvis mailserver har et privat certifikat, tillids med tls.ca_file (dets certifikat eller dets myndigheds) og tls.server_name; verificering kan ikke slås fra.
imap:
host: imap.hisp.example
username: intake@direct.clinic.example
password: ${DIRECT_MAILBOX_PASSWORD}
move_to: Processed
XDR. xdr tager XDR på /xdr på sin egen HTTPS-adresse, som en HISP sender Direct, der er konverteret til SOAP eller en partner sender punkt-til-punkt: en ITI-41 Provide and Register-anmodning, hvis dokumenter hver bliver en besked. En indsendelse, hvis Direct-adresseringsblok navngiver en anden adresse, afvises, og en, som kanalen ikke tager, besvares med en RegistryResponse-fejl, der forklarer hvorfor. client_ca_file kræver et klientcertifikat fra disse myndigheder. XDR er beskyttet af TLS, ikke S/MIME, så en kilde, der kun tager XDR, behøver kun adressen, men ikke dets certifikat, nøgle eller anchors. Hvert dokument bliver en besked af kanalens dataType: CDA-dokumenter kræver raw (videregive, som de er) eller hl7v3, da standarden, hl7, forventer HL7 v2 og afviser dem.
xdr:
listen: 0.0.0.0:8445
tls_cert: /etc/perfuse/tls/server.crt
tls_key: /etc/perfuse/tls/server.key
client_ca_file: /etc/perfuse/direct/hisp-clients.pem
Udveksling › Direct listar de Direct-adresser, dine kanaler sender og modtager som, med deres certifikater, udløb og anchors; opbevarer adresserbogen over korrespondenter (navn, organisation, noter og certifikat, indklippet fra deres HISP eller fundet i DNS eller LDAP, og afvist, når det ikke er til den adresse eller domæne); og søger op en adresses certifikater i DNS eller LDAP uden at gemme dem. Bogen er direktøren direct-certs ved siden af databasen, en PEM-fil per adresse eller domæne, som en destination læser, medmindre den navngiver sin egen recipient_certs_dir.
Verificeret mod OpenSSL 4.0's cms og smime i begge retninger: hvad Perfuse signerer og krypterer, verificerer og dekrypterer OpenSSL (PKCS#1 v1.5 og OAEP-nøgletransport), og Perfuse åbner, hvad OpenSSL signerer og krypterer (AES-128 og AES-256). En besked lavet med openssl smime og leveret over SMTP modtages, åbnes og gemmes af en kanal, og en som Perfuse sender en besked til en anden gennem en HISP-stedfortræder, som besvarer med en MDN, som afsenderen åbner. Certifikater findes i OpenLDAP 2.4 (adressebundne og domænebundne, skrevet af OpenLDAP's egen ldapadd); en Direct-besked læses fra en GreenMail IMAP-mailbox og åbnes, og en, der ikke er Direct, flyttes til fejl-mappen; XDR fra en xds-destination tages af en direct-kilde og afvises, når den er adresseret til nogen anden, og accepteres af NIST XDS Toolkit's Document Recipient og ONC SITE's XDR-validator; SITE's Direct XDR Edge Test Tool sendte både dens minimale og fulde metadata-beskeder til en direct-kilde, som tog dem. Mod ONC's Direct Certificate Discovery Tool vælger en Direct-destination det rigtige certifikat eller intet i alle 18 af dets opdagelsessager (D1 til D18: udløbede, annullerede og AIA-udstedte certifikater, SRV-prioritet og vægt, en utilgængelig katalog). En Direct-kilde læser en besked fra SITE's egen HISP (Apache James) over IMAP med STARTTLS. Endnu ikke testet: SMTP-udveksling med SITE's HISP (AWS holder udgående mail på port 25 for nye konti) eller med en akkrediteret HISP.
8.10 SQL på FHIR-visninger
En ViewDefinition (HL7 SQL på FHIR v2) omdanner hver FHIR-resurs af en type til rækker af navngivne kolonner, hver kolonne en FHIRPath-udtryk, så FHIR-data kan læses som tabeller af DuckDB, Athena, Spark, et datawarehouse eller en regneark. Perfuse kører dem med sin egen FHIRPath-motor: column, nestede select, forEach, forEachOrNull, repeat og unionAll, where, constant (hver value[x]-type), collection-kolonner, %rowIndex og getResourceKey() og getReferenceKey(type) join-nøgler.
{
"resourceType": "ViewDefinition",
"name": "blood_pressure",
"resource": "Observation",
"constant": [{ "name": "systolic", "valueCode": "8480-6" }],
"where": [{ "path": "code.coding.exists(system = 'http://loinc.org' and code = '85354-9')" }],
"select": [{ "column": [
{ "name": "id", "path": "getResourceKey()", "type": "id" },
{ "name": "patient_id", "path": "subject.getReferenceKey(Patient)", "type": "id" },
{ "name": "systolic", "path": "component.where(code.coding.code = %systolic).value.ofType(Quantity).value.first()", "type": "decimal" }
]}]
}
Overvågning › SQL på FHIR kører en visning over denne servers FHIR-lager (en patient eller alle) eller over ressourcer, der er indklæbet (NDJSON fra en bulk-eksport, en Bundle, en JSON-matrix), viser rækkerne og downloader dem som CSV, NDJSON eller Parquet. Den starter fra fem eksempelvisninger (patientdemografi, observationer med en værdi, blodtryk, tilstande, møder) og gemmer visninger i views-mappen ved siden af databasen, en JSON-fil hver.
FHIR-endpointet besvarer specifikationens $sql-run på systemniveau, ved GET eller POST, for en ViewDefinition-emne angivet inline (subjectResource), ved subjectReference (ViewDefinition/<name>, en gemt visning) eller ved subjectCanonical (en gemt visnings url), med _format (csv, ndjson (standard), json eller parquet), header, patient, _since, _limit og resource for at køre over ressourcer, der sendes med anmodningen i stedet for butikken. Det er en læsning: en SMART-token kræver læseomfang for visningens ressourcetype, en token bundet til en patient får kun den patients rækker, og granulerede omfang snævrer ressourcerne, som de gør i en søgning. Mere end en million rækker kræver _limit, patient eller _since.
perfuse sof -view v.json [-format csv|ndjson|json|parquet] [-o out] files... kører en visning over FHIR-filer uden en server: NDJSON-filerne fra en bulk-eksport, Bundles eller arrays.
perfuse sof -view blood_pressure.json -format parquet -o bp.parquet export/Observation.ndjson
duckdb -c "SELECT patient_id, avg(systolic) FROM 'bp.parquet' GROUP BY 1"
Parquet-filer har en rækkegruppe og upakkede PLAIN-sider; booleans er BOOLEAN, heltalstyper INT64, decimaler DOUBLE og alt andet UTF-8-streng (en samlingkolonne som dens JSON).
Verificeret med det officielle SQL på FHIR-testsuite (de 144 tests i sql-on-fhir.js-repositoriets tests/, kørt på hver bygning: alle passerer), og Parquet-udgangen læst tilbage af DuckDB 1.5.6 med de rigtige typer og værdier. Ikke understøttet: SQLQuery og SQLView-biblioteker (SQL over visningstabellerne), $sql-export, _format=fhir og source- og group-parametrene; hver afvises med en grund.
8.11 Digitale kvalitetsmål
En digital kvalitetsmåling tæller patienterne i hver befolkning af en FHIR Measure over en måleperiode (initial befolkning, tæller, tæller-undtagelser og -undtagelser, nævner, nævner-undtagelser) og scorer resultatet. Svaret er en FHIR MeasureReport, formet som Da Vinci Data Exchange for Quality Measures (DEQM)-vejledningen beder om. Dette er, hvor CMS's eCQM-programmer og NCQA's digitale HEDIS er på vej.
I Perfuse er populationskriterierne FHIRPath ("language": "text/fhirpath"), kørt af samme motor som SQL på FHIR. Hvert kriterium vurderes én gang per patient. Dets fokus er en Bundle af patientens record (Patient-kompartmentet), og det har disse variable: %subject (Patient), %periodStart og %periodEnd (perioden, som dateTimes) og %"Measurement Period". Et kriterium giver sandt eller falsk; en enkelt værdi, der findes, tæller som sandt.
{
"code": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/measure-population", "code": "numerator" }] },
"criteria": {
"language": "text/fhirpath",
"expression": "entry.resource.ofType(Observation).where(code.coding.where(system = 'http://loinc.org' and code = '4548-4').exists() and effective.ofType(dateTime) >= %periodStart and effective.ofType(dateTime) <= %periodEnd).exists()"
}
}
Populationskriterierne er nestede, som Measure-specifikationen siger. En patient er kun i tælleren, hvis de er i den initielle population. En tæller-undtagelse fjerner patienten, før tælleren vurderes. En tæller-undtagelse tælles kun for en patient, der ikke er i tælleren. En proportions score er (tæller - tæller-undtagelser) / (tæller - undtagelser - undtagelser); en ratios score er tæller / tæller; en kohort har tællinger og ingen score. Enkeltkriterie-stratificatorer splitter hver population efter deres værdi (køn, fx).
Perfuse har ingen CQL-motor. De offentliggjorte CMS eCQMs og HEDIS-digitale målinger er skrevet i CQL, så de kan ikke køres, som de er. En Måling, hvis kriterier er CQL, afvises med denne årsag. Skriv logikken som FHIRPath i stedet. Kontinuerlig-variabel-scoring, multi-komponent-stratificatorer og Gruppe eller Praktiker-emner afvises på samme måde.
Overvågning › Kvalitetsmål evaluerer et mål over denne servers FHIR-lager eller over indsatte ressourcer, for en periode. Den tilbyder tre rapporter: en sammenfatning, en sammenfatning med patienterne i hver befolkning, eller en patient. Skærmen viser befolkningerne, scoren og lagdelene, og downloader MeasureReporten. Den starter fra tre eksempler: blodtryk under kontrol, diabetes med en HbA1c-test, og patienter set i perioden. De er illustrative, skrevet til denne manual, og er ikke CMS eCQMs eller HEDIS-mål. Gem til FHIR-lageret kontrollerer målet og gemmer det som en Measure-ressource.
FHIR-endpointet besvarer Measure/[id]/$evaluate-measure og Measure/$evaluate-measure?measure=<url>, ved GET eller POST af en Parameters-ressource. Parametre:
periodStartogperiodEnd: påkrævet. En dato betyder hele dagen.reportType:summary,subjectellersubject-list.subject:Patient/<id>.reporter:Organization/<id>. Når det er fraværende, indeholder rapporten en Organisation navngivet afserve -measure-reporter.measure: Et Mål sendt inline, som en POST-parameter.
Rapporten returneres, ikke gemt. Operationen er en læsning, så en SMART-token behøver læseadgang til Måling og Patient. En token bundet til en patient får en individuel rapport om den patient og ingen andre.
perfuse measure -measure m.json -period-start 2026-01-01 -period-end 2026-12-31 [-type summary|subject|subject-list] [-subject Patient/ID] [-o out] files... vurderer en måling over FHIR-filer (en bulk-eksports NDJSON, Bundles, arrays) uden en server. -measure example:example-bp-control kører et medfølgende eksempel, og -examples lister dem.
Verificeret. HL7 FHIR-valideren kontrollerer de medfølgende Målinger mod FHIR R4, uden fejl. Den kontrollerer en samlet, en individuel og en emne-liste Målingsrapport mod DEQM 5.0.0-samlet, individuel og emne-liste-profiler, også uden fejl. Ikke verificeret: ækvivalens med nogen offentliggjort eCQM, da ingen kan køres her uden CQL.
8.12 Patientindekset (MPI)
En master-patient-indeks kobler de poster, som hver system holder for en person (hospitalets MRN, klinikken, laboratoriet), sammen til en virksomheds-identifikator, EUID. Den er slået fra, indtil nogen beslutter at opretholde den, fordi den er en tabel over patienters navne, fødselsdatoer og identifikatorer: slå Indstillinger → Data → Patientindeks (eller serve -mpi) til og genstart. Den bor i mpi.db ved siden af den primære database.
Fodring. Tilføj en destination af typen mpi (Patientindekset i byggeren) til kanalerne, der bærer registreringer. Den læser PID'en af hver HL7 v2-besked eller en FHIR-Patient på en rå kanal. Postens eget id er PID-3-repetitionen af typen MR (id_type ændrer det); de andre og PID-19 bliver dens andre id'er. En tildelingsmyndighed med et universelt id (PID-3.4.2 med type ISO) bliver urn:oid:...; en med kun et navnerum bliver kortlagt af authorities eller bliver urn:perfuse:aa:<namespace>. En A40, A34, A18 eller A39 sammenfører personen, der holder MRG-1's id, med personen, der holder PID-3's (no_merge ignorerer dem).
destinations:
- name: index
type: mpi
mpi:
authorities: { HOSP: "urn:oid:1.2.840.114350.1.13.1" }
Matching. En ny post bliver koblet i denne rækkefølge:
- Tillidsidentifikatorer. En post, der deler en identifikator fra et system, der er listet som tillidt (en national identifikator, et virksomhedsnummer), er den samme person, uden scoring. List aldrig et system, som en familie deler, såsom en betalers abonnentnummer.
- Score. Ellers findes personer, hvis poster kunne matche, ved blokering (samme lydende efternavn og fødselsår, samme fødselsdato eller samme telefonnummer) og scores med Fellegi-Sunter-vægte over efternavn og fornavn (Jaro-Winkler og Soundex, accenter og punktuation ignoreret, navne omvendt), fødselsdato (en dag og måned omvendt er delvis enighed), køn, postnummer, telefon og adresse. Kun felter, som begge poster har, tælles med. Scoringen er beviset fundet som en andel af det mulige bevis. Blokering bruger fem nøgler, så en fejl ikke skjuler en person: efternavnslyd og fødselsår, fødselsdato, telefon, begge navnes lyd (i enhver rækkefølge) og postnummer med fornavnets lyd.
- Beslutning. Som standard kobles intet på en score alene. En post, der scorer på eller over gennemgangstrinnet (60%), bliver en ny person, og den mulige match venter på gennemgangskøen; de, der er på eller over automatisk trin (90%) med efternavn og fødselsdato, der begge er enige, markeres som *sikker*. At kobbe to personer sammen (et overlay) sætter en patients resultater i en anden patients tegn, så automatisk kobling er en skifter, en administrator kan aktivere (Kobl sikre matcher uden at spørge nogen) én gang køen har vist, at de sikre er korrekte. Med den aktiveret kobles en sikker match, når ingen anden person scorer så højt. Under gennemgangstrinnet er posten en ny person.
Nationalnumre. NHS-nummeret (og Skotlands CHI og Nordirlands sundheds- og plejenummer), Irlands PPSN og IHI, Tysklands KVNR, Østrigs SVNR, Schweiz' AHV-nummer, Hollands BSN, Belgiens nationalt registernummer, Luxembourgs matricule, Frankrigs INS (NIR og NIA), Italiens codice fiscale, Spaniens DNI/NIE og CIP-SNS, Portugals SNS-nummer, de nordiske personnumre (Sverige, Danmark, Norge med d-nummer, Finland, Island), de baltiske koder, Polens PESEL, de tjekkiske og slovakiske fødselsnumre og de ungarske, rumænske, bulgarske, kroatiske, slovenske og græske numre er kendt af indekset. Hver er gemt på én måde: under dets systemsystem, med mellemrum og punktum fjernet, så NHS-nummeret sendt som urn:oid:2.16.840.1.113883.2.1.4.1|999 000 0018 af et system og som https://fhir.nhs.uk/Id/nhs-number|9990000018 af et andet er én identifikator. En HL7 v2 PID-3-repetition, hvis identifikatortype er NN og et lands trebogstavs-kode (NNDEU, NNNLD), læses som det landes hovednummer, og type NH fra NHS-myndigheden som NHS-nummeret. Hvert nummers kontrollciffer testes: ét, der fejler, gemmes på dets post, rapporteres (maskeret) i svaret og bruges aldrig til at kobbe eller finde nogen, da et forkert tastet ciffer normalt gør en anden persons nummer. Danmarks CPR kontrolleres kun for dets dato, da numre udstedt siden 2007 ikke behøver at opfylde den gamle modulus 11.
Indstillingslisten viser hver scheme med dets format, dets kontrol og systemet, det gemmes under. Systemer, der tages fra landets egen FHIR-vejledning (UK Core, fhir.de, Nictiz, CH Core, ANS, HL7 Italia, MedCom, de svenske, norske og finske OID-registre), er markeret som sådanne; de andre er standardværdier, der kan ændres til den nationale værdi, som en side kan gøre pr. scheme (den gamle er stadig genkendt). At stole på en scheme er ét tick. Nationalnumre vises i fuld udstrækning til redaktører og højere som standard og maskeres (de sidste få tegn) til alle andre; Hvem ser numre i fuld udstrækning ændrer dette, ned til seere eller op til administratorer alene. Hvor et lands lovgivning begrænser en nummers brug (Frankrigs Référentiel INS, Irlands PPSN, Belgiens nationalt registernummer, Tysklands §290 SGB V), siger indstillingerne det. GET /api/mpi/schemes lister schemerne, og POST /api/mpi/check kontrollerer ét nummer uden at gemme det. FHIR $match og PIXm besvarer autoriserede klienter med numre i fuld udstrækning.
En dato skrevet dag- eller måned-først (08/15/1972) gemmes, som den er skrevet, og matcher ikke en år-først én: USA's og Europas ordrer er uenige, og gætning ville kobbe forkert personer.
Patientindeksskærmen (Byg) viser antallene, finder personer efter navn, nummer, EUID eller fødselsdato og åbner hver person: deres poster, hver identifikator og historien om, hvad der skete med dem, og hvem gjorde det. Redaktører beslutter gennemgang (Samme person kobler dem; Forskellige personer holder dem adskilt for altid), flytter en post til en anden person, tager en post ud (Ikke denne person) og sammenfører to personer. Administratorer indstiller trinnene, de tillidssystemer, de nationalnumre og EUID's system. Hver søgning og hver person, der læses, skrives til revisionsloggen.
At besvare andre. POST /fhir/Patient/$match (FHIR's operation, som IHE PDQm ITI-119 bruger) tager en Patient og returnerer personerne, der kunne være det, bedst først, hver en Patient, hvis id er EUID, med hver identifier, search.score, og match-grade-udvidelsen (certain, probable, possible); onlyCertainMatches og count respekteres. PIXm (/mhd/Patient/$ihe-pix, ITI-83) besvarer fra indekset: hver identifier for hver post, der er knyttet til personen, og EUID. Det gør PIX og PDQ i HL7 v3 (/pixv3, /pdqv3; se IHE-dokumentdeling) også, som også føder det.
API'et er /api/mpi (samlet visning og søgning), /api/mpi/persons/{euid}, /api/mpi/find, /api/mpi/reviews, /api/mpi/records (register, link, unlink), /api/mpi/merge og /api/mpi/settings.
Vægte. De standard Fellegi-Sunter-vægte kommer fra litteraturen om record-linkage for hospitalregistreringsdata. Estimer fra vores poster (i indstillingerne, administratorer; POST /api/mpi/estimate) tilpasser dem til webstedets egen indeks med forventning-maximering, ingen gennemgåede par nødvendigt: m (enighed blandt sande matches) fra parrene, der blokerer sammen, u (enighed ved tilfældighed) fra 20.000 par trukket tilfældigt, da blokerede par er enige om navne og datoer ved konstruktion. Estimaten vises ved siden af de anvendte vægte og ændrer intet, før den anvendes og gemmes. Et felt, der sammenlignes på for få par, beholder sin standardværdi. Tilpasningen antager, at felterne er uafhængige, givet klassen, hvilket de ikke helt er, så behandl en stor ændring med mistanke.
Målt. På FEBRL-datasæt 3 (5.000 syntetiske poster over 2.000 personer, hvor duplikaterne indeholder tastefejl, ombyttede felter, manglende værdier og kælenavne; PERFUSE_TEST_FEBRL), registreret i filrækkefølge med en gennemgående, der besvarer hvert køet par korrekt:
| Linket på egen hånd | Sat foran en gennemgående med den rigtige person | Missede | Forkerte links | |
|---|---|---|---|---|
| Automatisk linking af (standard) | 0 | 2.649 af 3.000 | 351 | 0 |
| Til, standardvægte | 1.637 | 1.012 | 351 | 0 |
| Til, vægte estimeret fra posterne | 1.622 | 1.070 | 308 | 0 |
Ingen post blev nogensinde koblet til den forkerte person, og ingen af de 2.000 nye personer blev unødigt køet. De manglende afviger næsten på hvert felt (en fødselsdato og en adresse, der begge er forkert, for eksempel) og scorer under gennemgangstrinnet. FEBRL er syntetisk og har få navnelignende; en rigtig indeks har flere, så dens gennemgangskø vil være længere, og disse tal er en bund på omsorg, ikke et løfte.
8.13 Afgrænset
CSV og dets beslægtede. Mulighederne er på kilde i byggeren, og formatreferencen listar filnøglerne.
Stier adresserer kolonner. En navngivet kolonne er tilgængelig, når en header-række er erklæret eller navnene er givet; ellers er kolonner positionelle.
8.13.1 Navngivning af kolonner
Der er to måder, og de er eksklusive. Enten navngiver den første række i filen kolonnerne — den første række navngiver kolonnerne — eller du listar dem selv i rækkefølge. Erklæring af en header betyder, at rækken ikke behandles som data.
Hvis ingen af delene er angivet, kan kolonner kun adresseres positionelt, så et filter skrevet mod et navn har intet at matche. Aktivering af headeren fjerner listen over navne i stedet for at beholde begge: med en header kommer navnene fra filen, så en liste, der er tilbage, vil blive ignoreret, og en kanal, der læser, som om den valgte navnene, når filen valgte dem, er sværere at fejlfinde end en, der nægter.
8.13.2 Hvad et filter eller et script ser
En afgrænset dokument bliver mange meddelelser, så dette skal fastlægges, før du skriver enten.
Med opdeling på, kører alt per række. Declarative trin, filteret og transformerings-scriptet ser alle en række, og en sti betyder *denne* rækkens kolonne. Et filter, der afviser en række, afviser kun den række, og modtagne tæller er rækker i stedet for dokumenter.
Med opdeling af, er meddelelsen hele dokumentet og en skrivning, der krydser rækker, afvises i stedet for at blive anvendt på den første. Denne afvisning er bevidst: stille skrivning til række ét er det beteende, der producerer en fil, der ser transformeret ud og ikke er.
8.13.3 De tre, der ændrer, hvad der tæller som en fejl
Acceptér rækker med forkert antal kolonner er slået fra som standard. En række med for mange eller for få kolonner er herefter en fejl, hvilket er, hvad der fanger en fil, hvis form ændrer sig uden varsel. At slå det til accepterer rækken og efterlader de manglende kolonner tomme.
Klip ledige mellemrum omkring hver værdi fikserer det almindelige tilfælde af en værdi, der er fyldt op til en kolonnebredde. Lad det være slået fra, hvor efterfølgende mellemrum er vigtige, hvilket de lejlighedsvis er i en identifier.
Behold blanke linjer som rækker er slået fra som standard og bør det normalt. Til, bliver en blank linje en række med tomme kolonner, hvilket kun er vigtigt, når en tæller skal matche filen nøjagtigt.
8.14 Rå
Ingen parsing overhovedet. Meddelelsen er bytes.
Brug dette, når indholdet ikke er noget, Perfuse forstår, og ikke har brug for at: en PDF, der flyttes mellem systemer, et proprietært format, et allerede dannede dokument, der videreges uændret.
Omkkosten er, at intet, der afhænger af struktur, fungerer — ingen felt-niveau-transformation, intet filter på et felt, ingen felt-niveau-sammenligning i paritetskontrollen. En rå kanal er en rørledning, og den er ærlig om at være det.
8.15 Vælge
Hvis meddelelsen er HL7 v2, skal du bruge hl7, selvom du kun har til hensigt at videregive den uændret. Parsing giver dig sporet, felt-niveau-statistik, mulighed for at filtrere senere og mulighed for at sammenligne. raw på parsebart indhold giver intet og mister alt dette.
Brug raw, når parsing ville fejle eller ville være en løgn om indholdet.
8.16 SMART Sundhedslinks og -kort
CMS's *Kill the Clipboard* beder leverandører om at acceptere en patients poster fra en QR-kode ved indtjekning og at aflevere besøgsposten på samme måde. QR-koden indeholder en SMART Health Link (shlink:/...): en adresse, en 256-bit-nøgle og, hvis ønsket, en label, en udløbsdato og en adgangskodeflag. Udveksling → Sundhedslinks læser en.
Modtagelse. Indsæt linket eller scan det med kameraet, hvor browseren kan (Chrome og Edge). Perfuse henter manifestet, dekrypterer hver fil med nøglen fra linket, sammenfatter enhver FHIR-bundle - hvem patienten er, hvor mange af hver ressource - og kontrollerer enhver SMART Health Card inde mod udgivarens offentliggjorte nøgle. *Lever til kanalen* afleverer FHIR-indholdet til en kanal som en besked, hvilket er, hvordan det når EHR. Hentningen begrænses til udgangspolitikken ved tilslutningstidspunktet, ren HTTP afvisses, og svaret fra en server, der ikke er en manifestserver, vises aldrig, fordi adressen kom fra en fremmeds QR-kode.
Deling. *Del* krypterer en FHIR-bundle, hoster den og viser linket og dets QR-kode én gang. Serveren gemmer ciphertexten og ikke nøglen - den kan ikke åbne, hvad den hoster, og kan ikke vise linket igen. En adgangskode hashes; ti forkerte deaktiverer linket. Links uddør efter 30 dage som standard, kan tilbagekaldes og liste, hvor ofte og af hvem de er hentet. Start serveren med -public-url sat til https-adressen, patienternes telefoner når; manifest-URL'en, der opbygges, skal være inden for specifikationens 128 tegn.
Verificering af et kort. *Verificer et kort* tager et numerisk shc:/ QR (en klump eller flere), en .smart-health-card-fil eller en JWS og siger, om signaturerne matcher udgivarens nøgle.
8.17 UN/EDIFACT
dataType: edifact læser UN/EDIFACT-interchanges (ISO 9735): ORDERS, INVOIC, DESADV, IFTSTA og resten, herunder det europæiske sundhedskrav og laboratoriebeskeder. Tjenestestringsråd (UNA) overholdes, med frigørelses tegn og, for syntaks version 4, gentagelsesadskillelse; funktionelle grupper (UNG/UNE) er valgfrie. Interchange leveres præcis, som afsenderen skrev det.
name: supplier-orders
dataType: edifact
edifact:
envelope: require # require (default), warn, or ignore
split: false # true: one interchange per message
acknowledge: contrl # none (default) or contrl
filter: 'UNB-2.1 == "5412345000013"'
source:
type: as2 # or http, sftp, file, email ...
# ...
destinations:
- name: orders
type: file
dir: /data/orders
filter: 'UNH-2.1 == "ORDERS"'
Konvolutten. UNT's segmentantal og reference, UNE's meddelelsesantal og reference og UNZ's antal og reference sammenlignes med, hvad interchange indeholder. Med require, standard, afviser en mislighed interchange (det er, hvordan en overførsel, der er afbrudt, vises); warn accepterer det og logger en advarsel; ignore kontrollerer ikke.
Stier, for kanal- og destinationsfilter, tæller elementer og komponenter fra 1 i den rækkefølge, segmentet skrives, som implementeringsvejledninger nummerer dem: BGM-2 (dokumentnummer), BGM-1.1, NAD(2)-2.1 (den anden NAD's part), LIN-3(2).1 (en gentagelse), UNB-2.1 (afsenderen), UNH-2.1 (meddelelstypen). En sti uden en forekomst adresserer hver enkelt.
Splitning leverer en interchange pr. meddelelse, hver med den oprindelige UNB (og gruppeheader) og trailers, der tæller en, så en ordre kan filtreres, søges og genprøves på egen hånd. Destinationsfilter ser hver del. En fildestination navngiver filer efter meddelelstype (ORDERS_INVOIC-20261017.edi), og ${control_id} er interchange-referencen.
CONTRL. Med acknowledge: contrl giver en afsender, der poster over HTTP, svar med CONTRL-syntaks og service-rapport: UCI-handling 7 når udvekslingen blev læst og leveret, 4 når den blev afvist eller ikke kunne leveres (HTTP 400 eller 502 derefter). Det kan ikke kombineres med split, da et CONTRL besvarer en hel udveksling. Over AS2 er modpartens kvittering bekræftelsen.
Ikke tilbudt: meddelelsesdirectory (hvori segmenter ORDERS D.96A tillader), så strukturen kontrolleres, ikke indholdet; transformationer, der ville omskrive en partners dokument; og filter- eller transformer-skripter (en preprocessor køres, før parsing). Kontrolleret mod pydifact 0.1.8, en uafhængig parser, i begge retninger.
9 Bekræftelser
En bekræftelse fortæller afsenderen, hvad der skete. For HL7 v2 over MLLP er det en ACK-meddelelse; afsenderen vil ikke sende den næste meddelelse, før den ankommer, og vil normalt gensende, hvis den ikke gør.
At få bekræftelser forkert er den mest almindelige måde, en integration stille taber data, fordi en afsender, der bliver bekræftet, har ingen grund til at klage.
9.1 Tidsplan
Dækket i meddelelsesflow, og sammenfattende er: ack.when er on_delivery som standard, hvilket betyder, at bekræftelsen sendes kun efter, at hver aktiveret destination har accepteret meddelelsen. on_receipt sender det, så snart meddelelsen er parsed og køet.
9.2 Hvad Perfuse sender
En AA, når meddelelsen blev accepteret, en AE, når den blev afvist af en grund, afsenderen kunne handle på, og en AR, når den blev afvist af en grund, afsenderen ikke kan.
Forskellen på AE og AR er, hvem der skal gøre noget. AE betyder, at meddelelsen havde et problem — et felt, der ikke kunne fortolkes som en dato, eller et påkrævet segment mangler — og afsenderen kan korrigere det og sende det igen. AR betyder, at Perfuse ikke kunne acceptere det uanset indhold, hvilket normalt betyder et konfigurations- eller tilgængelighedsproblem her. En afsender, der gensender efter et AR, vil få samme svar.
9.3 Identificering af denne motor
ack.application og ack.facility udfylder MSH-3 og MSH-4 i bekræftelsen.
Når begge er tomme, spejler bekræftelsen den oprindelige modtager — den bruger det samme, som den indgående besked havde i MSH-5 og MSH-6. Det er, hvad de fleste sendere forventer, og det er standard på grund af det.
Angiv dem eksplicit, når afsenderen validerer dem, eller når flere Perfuse-eksemplarer behandler den samme feed, og du har brug for at vide, hvilken der svarede.
9.4 Udløsningsbegivenheden
ack.include_trigger_event sender ACK^A01 i stedet for en bare ACK.
Nogle modtagere kræver det, og andre afviser det, hvilket er hvorfor det er en eksplicit mulighed uden en intelligent standard. Hvis en afsender afviser din bekræftelser, og indholdet ser rigtigt ud, er dette det første, du skal prøve.
9.5 Negative bekræftelser er ikke fejl, der skal skjules
En NACK behandlet som en succes er en af de mest skadelige miskonfigurationer, der er mulige, og det er almindeligt nok til at være værd at nævne. Det sker, når en destination sender tilbage en negativ bekræftelse, og afsenderen optegner *overførslen* som succesfuld, fordi byte kom ud, og noget kom tilbage.
Perfuse læser bekræftelsen, den modtager fra en MLLP-destination, og optegner resultatet derefter. En AE eller AR fra et downstream-system er en leveringsfejl, der gensendes i overensstemmelse med destinationens politik og bidrager til fejlrate, der udløser alarmer.
9.6 Tidsgrænser
At vente på en bekræftelse er begrænset. Når den ikke ankommer i tide, er leveringen en fejl og køes for gensendelse.
En tidsgrænse er ikke det samme som en afvisning og optegnes anderledes. En afvisning betyder, at den fjerne side overvejede beskeden og afviste den; en tidsgrænse betyder, at du ikke ved, om den blev behandlet. Den forskel afgør, om en gensendelse er sikker: at gensende efter en afvisning er meningsløst, og at gensende efter en tidsgrænse risikerer en duplikat. Perfuse gensender efter en tidsgrænse, fordi en manglende klinisk besked generelt er værre end en duplikat, og modtagersystemet generelt kan registrere en gentaget beskedkontrol-ID.
Om den handel er rigtig for en given feed er en vurdering, og det er værd at gøre bevidst for alt, hvor en duplikat har en klinisk konsekvens — en ordre, en medicinadministration — i stedet for at acceptere standardværdien tavst.
9.7 Kilder, der ikke bekræfter
Ikke hver transport har bekræftelsesbegrebet. En filkilde har ingen sted at sende en bekræftelse; en brokerkilde bekræfter til brokeren i stedet for til den oprindelige afsender; en HTTP-kilde besvarer med en statuskode.
Hvor kilden ikke kan levere bekræftelsesmåden, en kanal beder om, afvises kanalen ved indlæsning i stedet for at starte og tavst ikke at bekræfte. En kanal, der tror, den bekræfter, og ikke gør det, er værre end en, der ikke starter.
9.8 X12-bekræftelser
Alt ovenfor handler om HL7 v2. X12 har sine egne bekræftelser, og til forskel fra v2 er de fra som standard: en tom indstilling betyder ingen.
Den standard er den sikre, fordi en handelspartner, der ikke forventer en bekræftelse og modtager en, kan behandle den som en unsolicited interchange. acknowledge-nøglen på en X12-kanal tager en af fire værdier:
| Værdi | Hvad der sendes |
|---|---|
none | Intet. Standardværdien. |
999 | Implementeringsbekræftelse. Erstatter 997 for HIPAA-transaktioner. |
997 | Funktionsbekræftelse. Ældre og stadig, hvad mange betalingsforbindelser forventer. |
ta1 | Interchange-bekræftelse, om omslaget i stedet for dets indhold. |
Hvilken af dem, der skal sendes, er en egenskab ved handelspartnerforholdet i stedet for beskeden, hvilket er hvorfor det skal konfigureres og ikke kan sluttes. En 999 erstatter en 997 for HIPAA-transaktioner, men mange partnere — især ældre betalingsforbindelser — er konfigureret til at forvente en 997 og vil behandle en 999 som en ukendt fil.
9.9 HL7 v3-bekræftelser
En HL7 v3-kanal sender en bekræftelse som standard, hvilket er modsat X12 og værd at vide.
Årsagen er transporten snarere end standarden: en v3-interaktion ankommer generelt over en synkron forbindelse, hvor afsenderapplikationen venter på en besked, og en afsender, der ikke modtager noget, vil normalt gentage forsøget. Det er således, at en patient bliver registreret tre gange.
At slå det fra er muligt og skal gøres eksplitt. "Ikke angivet" og "sat til falsk" er bevidst forskellige, så standardindstillingen står, medmindre nogen har sagt noget andet.
10 Levering, køning og gentagelse
En destination, der ikke kan nås, er det normale tilfælde, ikke undtagelsen. Systemer genstartes, netværk lukkes, og et hospitals interface-engine er utilgængeligt under sin egen vedligeholdelsesvindue. Levering er bygget op omkring det.
10.1 Kø per destination
Hver destination har sin egen kø. En destination, der fejler, påvirker ikke de andre, og hver har sin egen dybde, alder og gentagelsesstatus.
Køning sker per destination snarere end per kanal, fordi fejlen er per destination. En kanalbred kø ville forsinke leveringen til tre fungerende systemer, fordi en fjerde er nede, og de to situationer - en destination utilgængelig, alle fire utilgængelige - ville se ens ud i statistikken.
10.2 Køindstillinger
queue on a destination:
| Nøgle | Hvad den gør |
|---|---|
enabled | Om fejlede meddelelser køes overhovedet. |
max_attempts | Hvormange gange at forsøge, før man giver op. |
backoff | Vent før første gentagelse. |
max_backoff | Loft på den voksende ventetid. |
max_depth | De fleste meddelelser at holde. Ikke angivet betyder ingen begrænsning. |
retain_hours | Hvordan længe en leveret meddelelse holdes. Ikke angivet holder den uendeligt. |
De to sidste manglede i denne tabel og i byggeren, og de er det par, der forhindrer, at en disk bliver fyldt. En kø uden nogen af dem vokser, indtil filsystemet er fuldt, og fejlen ankommer som noget, der ikke er relateret til at bryde - en skrivning, der fejler et andet sted helt - snarere end som et køproblem.
Backoff vokser mellem forsøg op til max_backoff. Voksende snarere end fast, fordi en destination, der er nede, normalt er nede i minutter snarere end sekunder, og gentagelse hvert sekund i ti minutter producerer flere hundrede logindgange, der begravér den, der betyder noget.
10.3 Ordenen bevares
Inden for en destination leveres meddelelser i ankomstorden, og en meddelelse, der fejler, holder sin plads. Senere meddelelser venter bag den snarere end overhaler.
Dette er den rigtige standard for kliniske data - en indlæggelse og en udskrivning, der anvendes i forkert orden, er værre end begge, der er forsinkede - og det har en konsekvens, der er værd at forstå: en meddelelse, der altid fejler, vil holde alt bag den tilbage.
Det er derfor, kødybde og køalder er separate varslingstilstande. En dyb kø, der afvandes, er et beskæftiget system. En kø, hvor den ældste besked bliver ældre og ældre, er fastlåst, og advarselskategorierne queue-depth, queue-age og queue-stuck skelner mellem dem.
max_attempts er, hvad der begrænser skaden: efter det, bliver meddelelsen optaget som fejlet, og køen fortsætter. At indstille max_attempts meget højt i håb om eventuel succes omgør en enkelt fejlet meddelelse til en stoppet feed.10.4 Når køning er deaktiveret
Med queue.enabled falsk, er en fejlet levering en fejlet levering. Den bliver optaget og ikke gentaget.
Det er det rigtige valg, når forsinket data er værre end ingen data - en realtidsvisning, en pagingsystem, noget, hvor en meddelelse, der leveres fyrre minutter efter begivenheden, ville være misvisende snarere end blot forsinket.
Det er det forkerte valg for alt, der går ind i en optegnelse, hvor meddelelsen er lige så gyldig en time senere.
10.5 Gentagelse versus kø
Der er to mekanismer, og de fungerer på forskellige niveauer.
retry på en destination regulerer umiddelbare forsøg inden for en levering - en forbindelse, der fejler, prøves igen efter en kort pause, uden at forlade leveringsstien. Dette håndterer transient fejl: en dropped forbindelse, en øjebliksvist afvisning.
queue regulerer, hvad der sker, når disse umiddelbare forsøg er udtømt. Meddelelsen forlader leveringsstien og gentages senere på en længere tidsplan.
Begge eksisterer, fordi de to fejl er forskellige. En forbindelsesnulstilling på det første forsøg er normalt væk på andet forsøg, og at gå gennem køen for det ville tilføje minutters forsinkelse til en fejl, der varede millisekunder. En destination, der er slukket for vedligeholdelse, vil ikke komme tilbage inden for tre umiddelbare forsøg, og at hamre på den er meningsløst.
10.6 Hvad en HTTP-endpoint regner som leveret
En HTTP-destination har tre indstillinger, der afgør, om en besked behandles som sendt, og alle tre er på destinationen i builderen.
Statuskoder, der betyder leveret. Tomt betyder enhver 2xx. Nogle endepunkter returnerer 202 Accepted for noget, de endnu ikke har behandlet, og nogle returnerer 200 med en fejl i brødteksten — sidstnævnte er, hvad *Behandl som mislykket, hvis svaret indeholder* er til. At angive en ekspllicit liste er værd at gøre, når en partner har fortalt dig, hvilken kode der betyder hvad, fordi alternativet er at opdage forskellen fra en besked, der aldrig blev leveret og aldrig køet.
Følg omdirigeringer. Slået fra som standard, og med overlæg. En omdirigering kan pege på en anden vært, så at følge en sender beskeden et sted, som ingen har konfigureret, og rapporterer succes.
Bearer-token. Sendes som en Authorization-header. Den gemmes med kanalen og vises aldrig igen, så lad feltet være tomt, når du redigerer en eksisterende kanal, for at beholde tokenet, der allerede er gemt, i stedet for at slette det.
10.7 Navngivning og beskæring af et arkivmappe
En fildestination føjer til en fil pr. dag og meddelelstype som standard (20261012-ADT_A01.hl7), MLLP-rammet, så filen kan afspilles med perfuse send. Fire indstillinger på destinationen ændrer dette.
Filnavn (file_name) laver en fil pr. meddelelse i stedet, navngivet fra ${date}, ${timestamp}, ${control_id}, ${message_type} og ${destination}. Et navn, der allerede er taget (samme kontrol-id to gange), får et unikt suffiks i stedet for at overskrive meddelelsen der.
Føj til (append: true) skriver hver meddelelse ind i filen, som Filnavn navner, så ${date}.hl7 er en fil per dag for hver type.
Suffix under skrivning (temp_suffix, en fil per besked kun) har som standard .part og fjernes ved omnavning, når filen er fuldstændig. Den, der indsamler disse filer, skal ikke hente en halvt skrevet fil, og en omnavning i en mappe er atomar. Ændr det kun, hvis indsamleren filtrerer på en anden filendelse.
Slet efter (retain_hours) beskærer filer i mappen, der er ældre end det angivne antal timer, kontrolleret som højest hver tiende minut, mens meddelelser ankommer. Kun almindelige filer direkte i mappen slettes aldrig, en undermappe. Tom eller nul bevarer dem for evigt, hvilket er standard og er en beslutning snarere end en oversigt - men et arkiv, der aldrig beskæres, fylder disken, og en fuld disk stopper kanalen snarere end arkiveringen.
10.8 Send til en FHIR-server
Tre indstillinger afgør, hvor meget der kontrolleres, før en samling forlader.
Kræv US Core-overensstemmelse tilføjer profilen til hver ressource. Kræv det kun, når ressourcen indeholder, hvad profilen kræver, fordi en modtager kan validere mod kravet og afvise en samling, der ellers ville være accepteret.
Valider før sending kontrollerer hver ressource her snarere end at lære fra modtageren. Et afslag i den fjerne ende fortæller dig mindre, senere og ofte kun i en log, du ikke kan læse.
Behandle advarsler som afslag har kun en effekt, når validering er aktiveret, og kontrollen er utilgængelig, indtil det er. Det er strengt nok til at stoppe en samling, en modtager ville acceptere, så det hører hjemme på en feed, der bringes op, snarere end en i service.
10.8.1 VærtsFHIR-tjenester
En fhir-destinations auth-blok logger ind på de værtsbaserede tjenester, hvor et indhæftet bearer-token ophører med at virke inden for timen:
fhir:
url: https://healthlake.us-east-1.amazonaws.com/datastore/<id>/r4/
auth: {type: aws, access_key_id: ${AWS_ACCESS_KEY_ID}, secret_access_key: ${AWS_SECRET_ACCESS_KEY}}
aws signer hver anmodning om AWS HealthLake med Signature Version 4, med regionen læst fra URL'en. azure får en Microsoft Entra-ID-token til Azure Health Data Services fra tenant_id, client_id og client_secret - en app-registrering, der indeholder FHIR Data Contributor-rollen - med FHIR-service-URL'en som dens publikum. client_credentials gør det samme mod enhver OAuth 2.0 token_url. Tokens genbruges, indtil de udløber om en minut. De samme valgmuligheder findes under destinationens Hosted service sign-in i kanalbyggeren.
10.8.2 Offentlig sundhedsrapportering
Afmarkér Rapportér rapporteringsbare tilstande til offentlig sundhed på en FHIR-destination, og den sender sagrapporter i stedet for bundles. Hver besked kontrolleres for en rapporteringsbare tilstand-udløserkode: en diagnose, en laboratorieprøve eller en kodet resultat. Hvis den har en, bliver beskeden en HL7 eCR 2.1.2 eICR, indpakket i en eCR-besked og sendt til URL'ens $process-message. Hvis den ikke har nogen, sendes intet, og intet fejler; destinationen tæller det som ikke-rapporteringsbart.
fhir:
url: https://ecr.agency.example/fhir
ecr:
rctc: /etc/perfuse/rctc.json
source: https://fhir.springfield-general.example/fhir
facility: {name: Springfield General Hospital, phone: +1-217-555-0100, city: Springfield, state: IL}
rctc er Reportable Conditions Trigger Codes, som en FHIR ValueSet eller eRSD-bundle. Den kræver en UMLS-licens, så den er ikke inkluderet; uden den bruges en kort indbygget eksempel til testformål kun. source er, hvor agenturet sender sin Reportability-svar. Faciliteten er påkrævet, fordi eCR beder om dets telefonnummer og adresse, og en v2-besked har ingen af delene.
En rapport siger, hvad beskeden manglede, i stedet for at opfinde det, og hver lukke logges. Prøv en besked i FHIR-labets Offentlig sundheds sagrapport-panel, før du pejer en live-feed på et agentur.
10.8.3 Laboratorieresultater til offentlig sundhed: ELR
perfuse elr -config elr.yaml results.hl7 omdanner et laboratoriums resultater til HL7 2.5.1 ELR-besked, som statens sundhedsafdelinger modtager, en for hver besked med et rapporteringsbart resultat, og kun de ordrer, der bærer et: en komplet blodprøve ved siden af en positiv SARS-CoV-2-test er ikke offentlig sundheds sag. Udløserkoderne er de samme som sagrapporteringens, RCTC, du indlæser, eller den indbyggede eksempel.
ELR navner alle ved OID eller CLIA-nummer, som ingen laboratoriefeed medfører for afsender og modtager, så de kommer fra filen:
sending_application: {namespace: Perfuse, id: 2.16.840.1.113883.19.5.9, type: ISO}
sending_facility: {namespace: Springfield Lab, id: 2.16.840.1.113883.19.5, type: ISO}
receiving_application: {namespace: ELR, id: 2.16.840.1.113883.19.6.1, type: ISO}
receiving_facility: {namespace: State DOH, id: 2.16.840.1.113883.19.6, type: ISO}
processing: T
ordering_facility: {name: Springfield Clinic, phone: "+1 217 555 0100", line: 1 Main St, city: Springfield, state: IL, postalCode: "62701"}
performing_lab: {name: Springfield Lab, line: 2 Lab Rd, city: Springfield, state: IL, postalCode: "62701"}
performing_lab_clia: 14D0000000
placer_authority: {namespace: SPRINGFIELD-EHR, id: 2.16.840.1.113883.19.5.1, type: ISO}
filler_authority: {namespace: SPRINGFIELD-LAB, id: 2.16.840.1.113883.19.5.2, type: ISO}
Den bestillende facilitet, udførende laboratorium og tildelingsmyndigheder bruges kun, hvor laboratoriets besked udelader dem, og hver brug er en note. Hvad laboratoriet alene ved, udfyldes aldrig: et resultat uden prøvetype følger med SPM-4 tom og en note, der siger det, fordi en gættet prøve i en rapport til offentlig sundhed er værre end en lukke, som staten kan spørge om. Start med processing: T, mens statens onboardningsteam tester feeden.
Hvad laboratoriet fik ret er bevaret, som det blev sendt. En underordnet ordre (en følsomhedspanel eller en reflextest, der navngiver sin forælder og som ikke har nogen ORC af sin egen) følger med, som modtaget, uden nogen ORC eller prøve opfundet til den, og en underordnet uden nogen rapporteringsbart resultat følger med sin forælder, da en følsomhed ikke betyder noget uden den kultur, den tilhører. En note efter PID bliver hos patienten, og ORC-14, den telefonnummer, der skal ringes tilbage, kopieres fra OBR-17, når laboratoriet kun har sat det der. Alle 28 eksempelbeskeder, som ONC offentliggør til sin ELR-certificeringstool, kommer ud gyldige uden fejl.
MSH-2 skrives som ^~\&#, de fem tegn, som ELR Release 1's errata kræver, og som ONC's certificeringstool kontrollerer. Hvis din statsvejledning viser de ældre fire, tilføj encoding_characters: "^~\\&" til filen.
For at sende dem fra en kanal i stedet for fra kommandolinjen, give destinationen, der når staten, en elr-blok, der navngiver den samme fil. Hver laboratorieresultat omformes på vej ud, og en med intet rapporteringsbart sendes ikke overhovedet, hvilket tælles som leveret, ikke fejlet: staten bad om rapporteringsbare resultater kun.
destinations:
- name: state-elr
type: mllp # or http, sftp, file: whatever the state's onboarding team gives you
address: elr.health.state.example:6661
tls: {enabled: true}
elr:
config: elr.yaml # beside this channel file
rctc: rctc.json # optional; the built-in sample is for testing only
Blokkeringen gælder på en HL7 v2-kanal, til destinationer, der leverer beskeden selv (mllp, http, tcp, fil, sftp, ftp, S3, Azure Blob, soap, messagebrokere eller en anden kanal); kanalen nægter at indlæse ellers, og når filen mangler eller manglede sendende facilitet, modtagende program eller modtagende facilitet. Noterne skrives til loggen med beskedens kontrol-ID.
ELR-filen er kanalen ledsager, ikke en kanal: perfuse check og Kanaler-skærmen springer den over i stedet for at rapportere en kanal, der ikke kan indlæses. I kanalbyggeren er de samme to indstillinger under destinationen, i Laboratorierapportering (ELR 2.5.1); feltet for udløserkoder åbnes, når en ELR-fil er navngivet, og gemning afviser en fil, der ikke er ved siden af kanalen.
10.8.4 DICOMweb-arkiver
type: dicomweb gemmer hver objekt med STOW-RS: Orthanc, dcm4chee, sky-billedtjenester eller en Perfuse-servers egen arkiv. Giv serviceroden (https://pacs.example/dicom-web); /studies føjes til, og en URL, der allerede slutter med /studies, afvises i stedet for at poste til /studies/studies. Godkend med token (en bærertoken) eller username og password; headers føjer andre til, såsom en sky-tjenestes projekt-header. Kanalen har brug for dataType: dicom.
Serverens svar afgør udfaldet, ikke kun dets statuskode. Et objekt, som svaret nævner som fejlet, er en fejlet levering med DICOM-fejlårsagen, og det samme gælder en 202, der ikke nævner noget som gemt: serveren modtog anmodningen og beholdt ingen af den. Timeout standard er to minutter, fordi en stor serie er langsom.
10.8.5 Dokumentarkiver (IHE XDS.b)
type: xds publicerer hver klinisk dokument til et XDS.b-repositorium med ITI-41 Provide and Register: et CDA-dokument eller en HL7 v2-meddelelse (MDM, ORU), der bæres. Metadata kommer fra dokumentet og destinationens indstillinger (source_id, patient_domain, facility_type, practice_setting), og repositorys RegistryResponse afgør leveringen. Se IHE dokumentdeling.
10.8.6 Vaccinationsregistre
Hver amerikansk stat immunisationsregister (IIS) accepterer HL7 2.5.1-meddelelser på samme SOAP-grænseflade, som CDC offentliggjorde i 2011 (navnerum urn:cdc:iisb:2011). Den har to operationer: connectivityTest, som beviser endpointet, og submitSingleMessage, som bærer meddelelsen. En VXU^V04-rapport om en vaccination kommer tilbage som en ACK; en QBP^Q11-anmodning om en patients historik og prognose kommer tilbage som en RSP^K11.
Vælg Vaccinationsregister (CDC IIS web service) som tjenesten for en SOAP-destination, eller skriv profile: cdc-iis:
destinations:
- name: state-registry
type: soap
soap:
profile: cdc-iis
url: https://iis.state.example/iis-ws/cdc
username: clinic-submitter # the registry account for this submitter
password: "..."
facility_id: FAC-1234 # optional in the WSDL; many registries require it
queue: {enabled: true}
Perfuse opbygger kuverten, så der er ingen brødtekst at skrive. Brugernavn og adgangskode kommer indenfor anmodningen, hvor CDC WSDL placerer dem, og ikke i HTTP-autentificering. Versionen er SOAP 1.2, WSDL's binding, medmindre du angiver version: "1.1" for et register, hvis vejledning kræver det. Hvor et register kræver en klientcertifikat, skal destinationens tls indstilles som for enhver HTTPS-opkald.
Registerets bekræftelse afgør, om meddelelsen blev leveret, og ikke HTTP-status. Et register svarer på en afvist vaccination med HTTP 200 og en AR indeni, så en destination, der stolede på status, ville rapportere en tabt vaccination som leveret.
| Registrets svar | Perfuse-optegnelser |
|---|---|
| AA (eller CA) | Leveret. |
AE hvis ERR-segmenter alle er advarsler (ERR-4 W eller I) | Leveret. Advarslerne er i svaret. |
AE med nogen ERR-4 E, eller en ERR uden alvorlighed | Fejlet, med hver ERR's placering, kode og tekst i fejlen. |
| AR eller CR | Fejlet, på samme måde. |
| En SOAP-fejl (forkert adgangskode, for stor besked) | Fejlet, med registrets årsag. |
| Noget, der ikke er en HL7-besked | Fejlet. |
warnings_are_errors: true (Behandle advarsler som fejl) får hver AE til at vente på en person. Svaret, som respons-skripter og en HTTP-opkald, der venter på kanalen, læser, er registrets HL7-besked: ACK eller RSP med historik og prognose. examples/iis indeholder tre kanaler at starte fra: VXU fra en EHR over MLLP, QBP-forespørgsler over HTTP og en lokal stand-in for et register.
The Connections-dashboard spørger et register om dets connectivityTest, når intet er blevet sendt i syv dage. Denne operation findes til dette formål og sender intet, så det er den eneste applikationsniveau-tjek, Perfuse udfører. Den beviser adressen, TLS og SOAP-bindingen, ikke brugernavn og adgangskode; kun en rigtig indsendelse tester disse.
En SOAP-kilde kan svare på samme måde: Svar som et vaccinationsregister, eller profile: cdc-iis på kilde. Den gentager connectivityTest, tager beskeden fra submitSingleMessage, returnerer kanalens bekræftelse i return og serverer CDC WSDL på ?wsdl. Et brugernavn og adgangskode, når de er angivet, kontrolleres mod dem i anmodningen, og et forkert par får WSDL's SecurityFault. En besked, som kanalen afviser, returneres som en NAK, aldrig som en fejl, som CDC-vejledningen siger. Brug det som en test-dobbelt, eller til at modtage indsendelser på samme måde som et register.
Ikke dækket: de statsspecifikke dele af onboarding. Hvert register har sin egen endpoint, konto-proces og lokal profil af 2.5.1-vejledningen (krævede RXA- og OBX-felter, VFC-berettigelse, afvisningskoder). Disse er meddelelsernes indhold, som kanalens transformationer former; ingen stats endpoint er bygget ind. Perfuse er testet mod sig selv og mod optagede register-svar, men ikke mod et live statsregister.
10.9 Når transporten siger ja, og beskeden ikke ankom
"Ankom denne" er ofte ikke et spørgsmål, transporten kan besvare. En MLLP-modtager returnerer en applikationsbekræftelse, hvis betydning er i dens tekst. En HTTP-modtager returnerer 200 med en fejldokument. I begge tilfælde lykkedes transporten, og beskeden ankom ikke.
Inspectér svaret på en destination tager et script givet modtagerens svar. Returner false eller kast, og leveringen markeres fejlet — hvilket betyder, at den genprøver, køer og vises i fejltællingen i stedet for at blive stille regnet som leveret.
Det tilbydes kun på destinationer, der modtager et svar. På en, der ikke kan, afvisses det ved indlæsning i stedet for at blive efterladt uden at køre.
10.10 Hvad en leveringsresultat betyder
| Udfald | Betydning |
|---|---|
Delivered | Destinationen accepterede meddelelsen. For MLLP, modtog en positiv bekræftelse. |
Queued | Levering mislykkedes, og meddelelsen vil blive genprøvet. |
Failed | Levering mislykkedes og vil ikke blive genprøvet, enten fordi køen er slået fra eller forsøg er udtømt. |
Filtered | Destinationen afviste meddelelsen ved sin egen filter. Ikke en fejl. |
Disse optegnes pr. destination pr. besked, så en besked, der nåede tre af fire destinationer, optegnes som netop det. Der er ingen kanal-niveau "succes", fordi det ikke ville betyde noget.
10.11 Langsom levering
En destination, der accepterer beskeder, men tager lang tid om det, er et distinkt problem fra en, der fejler, og det er let at overse, fordi hver resultat er en succes.
The slow-delivery-alert findes til dette. Det er værd at indstille på alt, hvor afsenderens bekræftelse venter på levering, fordi en destinations svar-tid, der stille og roligt er fordoblet, vil til sidst krydse afsenderens timeout og begynde at producere gensendelser — og på det tidspunkt viser symptomet sig upstream, i et system, du måske ikke administrerer.
10.12 Skrivning til en database
type: database kører en erklæring pr. besked med værdier bundet fra beskeden.
Pladsholdere er driverens egne — $1 for postgres, ? for mysql og sqlite, @p1 for sqlserver — og Perfuse omskriver dem ikke. Det er bevidst: en oversættelseslag, der fik en pladsholder forkert, ville binde en patients navn til den forkerte kolonne, og resultatet ville se ud som gyldig data i stedet for en fejl.
En erklæring skrevet i den forkerte dialekt afvisses, når den gemmes, og navnet på den stil, driveren ønsker. Før denne tjek eksisterede, dukkede fejlen op som syntax error at or near "," fra serveren, når en besked ankom, hvilket navngav en erklæring, du skrev, og sendte dig på jagt efter en stavefejl i stedet for at se på dialekten.
destinations:
- name: warehouse
type: database
database:
driver: postgres
dsn: ${WAREHOUSE_DSN}
statement: INSERT INTO messages (mrn, family_name, birth_date) VALUES ($1, $2, $3)
params:
- PID-3.1
- PID-5.1
- PID-7
En anført parameter er en konstant i stedet for en sti, hvilket er, hvordan en kanal skriver sit eget navn eller en kilde-system-kode ind i en række ved siden af beskedens data.
Værdier er altid bundet som parametre. En ${...}-reference inde i erklæringen afvisses: et navn, der indeholder en apostrof, ville bryde erklæringen, og en fjendtlig værdi ville omskrive den.
10.13 Send til en rå sok
type: tcp skriver til en socket med det valgte ramme, hvilket er hvad en enhed eller et laboratorieinstrument normalt ønsker. MLLP er en ramme blandt flere; denne destination tilbyder de andre.
destinations:
- name: instrument
type: tcp
tcp:
address: instrument.lab:9100
framing: delimited
delimiter: \r
expect_reply: true
timeout: 30s
Ramme har ingen standardværdi, med vilje. Skrivning med forkert ramme mislykkes ikke. Den fjerne ende læser meddelelser, der er splittet på forkerte steder, eller venter på en terminator, der aldrig kommer, og symptomet viser sig i modtagelsessystemet snarere end her.
framing | Hvad der skrives |
|---|---|
mllp | 0x0b før, 0x1c 0x0d efter. Samme ramning som en MLLP-destination bruger. |
delimited | En delimiter efter hver meddelelse, og en valgfri start_block før den. |
fixed | Poster udjævnes eller afkortes til record_length. |
length | En length_bytes-præfiks. big_endian og length_includes_header har begge to konventioner i det vilde, og forskellen er tavs. |
whole | En meddelelse per forbindelse, lukket for at markere slutningen. |
Kun indstillingerne, som den valgte ramme bruger, accepteres. En postlængde på en adskilt strøm afvisses snarere end ignoreret, fordi en indstilling, der ignoreres stille, er en, som nogen tror er i kraft.
expect_reply ændrer, hvad der betyder leveret. Uden det betyder succes, at byte nåede operativsystemets sendebuffert — hvilket en peer, der crashede et øjeblik senere, aldrig læste.
10.14 Amazon S3, SQS og SNS
En kanal kan læse fra en SQS-kø eller en S3-bucketpræfiks, og levere til SQS, SNS eller S3. Alle fem er signeret HTTP med ingen AWS SDK i binærfilen, og alle fem tager samme adgangsindstillinger: region, access_key_id, secret_access_key (skriv ${AWS_SECRET_ACCESS_KEY} for at læse miljøvariablen), et valgfrit session_token og endpoint til LocalStack, MinIO eller et VPC- endpoint. Under Kanaler → Ny kanal, vælg *Vi læser fra en Amazon SQS-kø*, *Vi indsamler objekter fra en Amazon S3- bucket*, eller SQS-, SNS- og S3-destinationstyperne.
Ingenting bekræftes til AWS, før kanalen har behandlet det. En SQS-meddelelse slettes herefter og kommer ellers tilbage, når dens synlighedstidsløb er slut, så en køs genkørselspolitik er, hvad flytter en, der fortsætter med at fejle, til en dødsbrevkø. En S3-objekt flyttes til processed/ herefter, eller til error/, hvis det ikke kunne behandles, så en dårlig fil ikke stopper resten.
På en FIFO-kø eller -emne, grupperes meddelelser efter patient som standard - SQS opretholder rækkefølgen inden for en gruppe og ingen andre steder - og deduplikeres efter indhold, så en gentagelse ikke leveres to gange.
En S3-arkiv kan skrives direkte til Glacier med storage_class, og som JSON-linjer til Amazon Athena med format: ndjson; perfuse athena udskriver tabellen. Reference har alle indstillinger.
10.15 AMQP 1.0 og Azure
AMQP 1.0 er, hvad Azure Service Bus og Event Hubs taler, og RabbitMQ 4, ActiveMQ og Artemis ud over deres andre protokoller. En amqp-kilde modtager fra en kø eller en abonnement og accepterer hver besked kun én gang, kanalen har behandlet den; en besked, der ikke kunne behandles, frigøres som en fejllevering, så brokeren leverer den igen og, forbi køens grænse, dead-letter den. En amqp-destination rapporterer kun succes, når brokeren accepterer beskeden. Til Service Bus: addr er <namespace>.servicebus.windows.net:5671 med tls, username er den delte adgangspolitiks navn, password er dens nøgle, og address er kønavnet, eller <topic>/subscriptions/<name> for at modtage.
Azure Blob Storage: en azure_blob-destination skriver en blob per meddelelse i den valgte adgangsniveau - Hot, Cool, Cold eller Arkiv - og en azure_blob-kilde henter blobs op fra et præfiks, flytter dem til processed/ eller error/ som S3-kilden gør. Foretræk en SAS-token begrænset til containeren over konto-nøglen.
10.16 MQTT
En mqtt kilde abonnerer på et emnefilter (+ matcher ét niveau, # ethvert niveau under) på enhver MQTT 3.1.1-broker: Mosquitto, EMQX, HiveMQ, AWS IoT Core, Azure Event Grid. Ved QoS 1, standardværdien, bliver hver besked kun bekræftet, når kanalen har behandlet den. MQTT har ingen måde at afvise en enkelt besked på, så en, der ikke kan behandles, bliver stående uden bekræftelse, og forbindelsen genoprettes; brokeren beholder sessionen under client-id (perfuse-<channel>, medmindre client_id siger noget andet) og sender den igen, først i kø. QoS 0 er højst én gang: alt, der sendes, mens Perfuse er nede, går tabt. En mqtt destination offentliggør og rapporterer, ved QoS 1, succes, når brokeren har modtaget beskeden.
source:
type: mqtt
mqtt:
addr: broker.hospital.local:8883
topic: hl7/+/adt
username: perfuse
password: ${MQTT_PASSWORD}
tls: {enabled: true, ca_file: /etc/perfuse/broker-ca.pem}
AWS IoT Core ønsker en klientcertifikat: giv tls.cert_file og tls.key_file.
10.17 IBM MQ
ibm_mq læser og skriver IBM MQ-køer via kømanagers messaging REST-API (mqweb), som IBM MQ 9.1.5 og senere medfølger på hver platform, herunder z/OS, så der ikke er behov for en MQ-klient ved siden af Perfuse. Brugeren har brug for MQWebUser-rollen og put, get og browse-myndighed på køen. En kilde gennemser den første besked, overdrager den til kanalen og fjerner den ved dens besked-id kun én gang, efter at den er blevet behandlet; en besked, der fejler, bliver først i køen. Kør en læser per kø. En destination indsætter bestandige beskeder (medmindre non_persistent), med HL7-kontrollen som korrelations-id.
destinations:
- name: to-mainframe
type: ibm_mq
ibm_mq:
url: https://mq.hospital.local:9443
queue_manager: QM1
queue: HL7.ADT.OUT
username: perfuse
password: ${IBM_MQ_PASSWORD}
tls: {enabled: true, ca_file: /etc/perfuse/mq-ca.pem}
api_version er v3 for MQ 9.3 og senere (standard), v2 for 9.1.5 til 9.2. En kø-manager med en AMQP-kanal kan også nås med amqp-connector.
10.18 Google Cloud Pub/Sub og Cloud Storage
En pubsub-kilde trækker fra et abonnement og bekræfter hver besked én gang, den er behandlet; en besked, der fejler, gives tilbage med det samme (dens bekræftelsesfrist sat til nul), med resten af dens batch, så Pub/Sub leverer den igen og, forbi abonnements dead-letter-politik, dead-letter den. En pubsub-destination offentliggør med HL7-beskedtypen og kontrol-id'et som attributter; order_by: patient sætter ordningsnøglen fra PID-3.1, så et abonnement med besked-orden holder hver patients beskeder i orden.
En gcs-destination skriver et objekt per meddelelse, navngivet som en S3-nøgle, i den valgte lagringsklasse (STANDARD, NEARLINE, COLDLINE, ARCHIVE). En gcs-kilde henter objekter op fra et præfiks og flytter dem til processed/ eller error/ som S3-kilden gør.
Begge logger ind som en service-konto: credentials_file er dens JSON-nøgle. Lad den være tom på Google Cloud (en VM, GKE eller Cloud Run) for at bruge service-konten, der er knyttet dér. endpoint navngiver en emulator (Pub/Sub-emulator, fake-gcs-server), som ikke kræver legitimationsoplysninger.
source:
type: pubsub
pubsub:
project: hospital-integration
subscription: adt-to-perfuse
credentials_file: /etc/perfuse/gcp-key.json
10.19 Læsning af en postkasse (IMAP og POP3)
En email kilde læser en postkasse og omdanner, hvad den finder, til meddelelser: hver vedhæftning (take: attachments, standard, indsnævret af attachment_names mønstre), emailens tekst (take: body), eller den hele email (take: raw) til et script at tage fra hinanden. Laboratorier, billedecentre og små praksisser sender stadig resultater på denne måde.
Hver check logger ind, læser den ældste ulæste post først og logger ud. Over IMAP hentes en email uden at blive markeret som læst, overdraget til kanalen, og kun én gang, efter at hver besked fra den er accepteret, flyttes den til move_to (Behandlet), markeres som læst (after_read: flag) eller slettes. Email, der fejlede eller ikke blev taget (en afsender uden for allowed_senders, ingen vedhæftning, der matcher attachment_names, større end max_message_size), flyttes til error_folder (Fejl) med årsagen i loggen. Begge mapper oprettes, når de mangler. POP3 har ingen mapper eller flags, så det sletter: sletninger er committeret af QUIT'en ved slutningen af checken, så en session, der afbrydes, sletter intet, og en behandlet email kan læses igen (aldrig tabt). POP3-email, der ikke bliver taget, bliver på serveren og rapporteres én gang.
Log-in er en adgangskode (${MAIL_PASSWORD}; en app-adgangskode til Gmail) eller OAuth 2.0 over SASL XOAUTH2, som Microsoft 365 kræver (det har slukket for adgangskode-log-in) og Gmail foretrækker:
source:
type: email
email:
host: outlook.office365.com # imap.gmail.com, pop.gmail.com, or your server
username: results-feed@hospital.example
oauth:
provider: microsoft # microsoft, google or custom (with token_url)
tenant: hospital.onmicrosoft.com
client_id: 00000000-0000-0000-0000-000000000000
client_secret: ${MAIL_CLIENT_SECRET}
attachment_names: ["*.hl7"]
allowed_senders: [lab.example, results@partner.example]
Med client_secret og uden refresh_token bruges Microsoft 365 app-kun-adgang (client-credentials grant, omfang https://outlook.office365.com/.default): en administrator registrerer appen, giver den IMAP.AccessAsApp og begrænser den til én postkasse med en Exchange service principal. Med en refresh_token (en persons samtykke) bruges den delegatede omfang IMAP.AccessAsUser.All eller POP.AccessAsUser.All, og en roteret refresh token gemmes for processens levetid. Gmail kræver en refresh_token: Google tilbyder ingen app-kun-adgang til en postkasse.
allowed_senders tager adresser og domæner. Fra-linjen i en e-mail kan forfalskes, så det holder uheld og tilfældig post ude, ikke en angriber; en feed, der skal være betroet, hører hjemme på Direct (S/MIME-signeret), SFTP eller et VPN. security er tls (993 eller 995, standard), starttls (143 eller 110) eller none, som kun er tilladt til localhost. Kontroller er mindst 10 sekunder apart (60 som standard), fordi mailtjenester begrænser kontoer, der kontrollerer hurtigere.
Testet mod GreenMail 2.1.3 (IMAPS, IMAP, POP3S og POP3: log-in afvist med en forkert adgangskode, hent uden at markere som læst, FLYT, flag, slet, en for stor e-mail afvist, før den læses) og mod Gmails IMAP med en app-adgangskode (opret en mappe, tilføj, hent, FLYT, slet). OAuth er testet mod en stand-in token-endpoint kun: ikke mod Microsoft eller Google.
10.20 AS2
AS2 (RFC 4130) er, hvordan mange betalere, clearinghouses og leverandører udveksler EDI: en HTTP POST, hvis brødtekst er signeret med afsenderens certifikat og krypteret til modtagerens, svaret med en kvittering (en MDN), der navngiver en digest af, hvad der ankom. S/MIME er den samme kode, der bruges til Direct messaging. Begge ender er på kanalbyggeren: Handelspartnere sender os EDI over AS2 som kilde, En handelspartner over AS2 som destination.
# receive: partners post here
source:
type: as2
as2:
listen: ":4080" # path /as2 by default
id: HOSPITAL-AS2 # our AS2 identifier (AS2-To)
cert_file: as2/ours.crt # partners encrypt to this
key_file: as2/ours.key # and receipts are signed with it
tls: { enabled: true, cert_file: tls.crt, key_file: tls.key }
partners:
- id: PAYER-AS2
cert_file: as2/payer.crt
dataType: x12
# send
destinations:
- name: payer
type: as2
as2:
url: https://as2.payer.example/as2
from: HOSPITAL-AS2
to: PAYER-AS2
cert_file: as2/ours.crt
key_file: as2/ours.key
partner_cert_file: as2/payer.crt
file_name: "${control_id}.x12"
Modtagelse. En besked til enhver anden AS2-To eller fra en afsender, der ikke er i partners, afvises med 403 og ingen kvittering. En partners besked skal være signeret og krypteret, medmindre dens post angiver allow_unsigned eller allow_unencrypted. Payloaden dekrypteres, dens signatur kontrolleres mod partnerens certifikat (partnere udveksler normalt selvsignerede, hvilket er i orden: certifikatet er tilliden), og overdraget til kanalen som dens meddelelsesformat siger. Partneren får den kvittering, det bad om: i svaret eller postede til dets Receipt-Delivery-Option URL; signeret, når det bad om en signeret. En besked, der fejler, får en kvittering, der navngiver hvorfor (decryption-failed, authentication-failed, insufficient-message-security, unexpected-processing-error).
Sendning. Hver besked er signeret (SHA-256) og krypteret (AES-256-CBC). Med receipt: sync, som er standard, regnes det kun som leveret, når kvitteringen verificeres mod partner_cert_file, siger processed og indeholder samme digest (MIC) som what der blev sendt; noget andet er en mislykket levering og bliver genprøvet. receipt: async beder om kvittering på receipt_url, som skal være en AS2-kilde på denne server som nævner partneren: beskeden regnes som leveret, så snart partneren accepterer anmodningen, og en kvittering, der senere er uenig, logges som en fejl. receipt: none beder om intet. unsigned, unencrypted og unsigned_receipt afvikler hver del for en aftale, der siger det; username og password tilføjer HTTP-basisk godkendelse for gateways, der kræver det. Indholdstypen følger kanalens format (application/edi-x12 for X12) medmindre content_type angiver en anden.
Triple DES, AES-128 og AES-192 læses også, samt AES-256, da partnere stadig sender dem, og også er streaming BER (uendelige længder) som Java-gateways skriver.
Komprimering (RFC 5402). En komprimeret besked læses på samme måde, som den blev bygget: komprimeret før signering eller kryptering, eller en signeret besked komprimeret som helhed. Kvitteringens MIC følger RFC: over, hvad der blev signeret, når det er signeret, over den ukomprimerede indhold, når det ikke er. En besked, der ville udvide sig til mere end ti gange kildeens max_message_size, afvises med decompression-failed, så få kilobytes ikke kan kræve gigabytes af hukommelse. En destination komprimerer med compress: true, før signering og kryptering, som de fleste gateways gør; spørg partneren først.
En besked sendt to gange. En partner, der aldrig fik vores kvittering, sender beskeden igen med samme Message-ID (RFC 4130 sektion 7.5). Kilden husker hver partners Message-IDs for duplicate_window (standard 720h, 30 dage; en time mindst) og svarer en gensendelse med en processed kvittering uden at overdrage den igen. Optegnelsen opbevares i databasen, så en genstart glemmer den ikke. En besked, hvis behandling fejlede, huskes ikke, så partnerens gentagelse går igennem. Kopier, der ankommer på samme tidspunkt, venter på hinanden, og kun den første overdrages. Hvis optegnelsen ikke kan læses, afvises beskeden med unexpected-processing-error og partneren prøver igen senere, snarere end at risikere en anden kopi. En besked uden Message-ID kan ikke genkendes og logges som sådan.
Interoperabilitet testes mod pyas2lib 1.4.3 i begge retninger, med Triple DES og AES-256, komprimeret og ikke, signeret synkron kvittering inkluderet.
10.21 OpenPGP
Betalere, clearinghouses og statlige myndigheder tager ofte og sender filer kun under OpenPGP. En pgp-blok på en kilde åbner, hvad der ankommer; en på en destination beskytter, hvad der forlader. Begge er på kanalbyggeren: Open PGP-krypterede beskeder under kilden, Kryptér med OpenPGP på hver destination.
source:
type: sftp
sftp: { host: sftp.payer.example, user: hospital, key_file: keys/id_ed25519, dir: outbound }
pgp:
decrypt_with: keys/our-secret.asc # our secret key, armored or binary
passphrase: ${PGP_PASSPHRASE}
verify_with: [keys/payer.asc] # the senders' public keys
require_signature: true
destinations:
- name: claims
type: sftp
sftp: { host: sftp.payer.example, user: hospital, key_file: keys/id_ed25519, dir: inbound,
file_name: "${date}-${control_id}.x12.pgp" }
pgp:
encrypt_to: [keys/payer.asc]
sign_with: keys/our-secret.asc
passphrase: ${PGP_PASSPHRASE}
Nøglefiler læses relativt til kanal-filen og læses og låses op, når kanalen indlæses: en manglende nøgle eller en forkert adgangskode stopper kanalen der, ikke på den første fil.
- På en kilde, åbnes hele filen, objektet, email-vedhæftningen eller anmodningens brødtekst først og
derefter opdelt i beskeder, så en batch, der er krypteret som en fil, fungerer. En, der ikke kan åbnes, afvises: en fil-kilde flytter den til dens fejl-mappe, en HTTP-afsender besvares 400 med årsagen. require_signature afviser en besked, der ikke er signeret af en af verify_with; allow_unencrypted accepterer en, der kun er signeret; pass_plain lader en besked, der slet ikke er PGP, gå igennem uændret, til en mappe, der modtager begge.
- På en destination, hvad der ville have været leveret, krypteres (til en af
encrypt_to) og signeres (med sign_with), efter hver anden trin. En fil-, SFTP-, FTP-, S3-, Azure Blob- eller GCS-destination navngiver stadig filen fra den rene besked, så ${control_id} fungerer, og enhver ramme er inde i krypteringen. armor: true skriver .asc-tekst i stedet for binær; no_compress slår komprimering fra; file_name er navnet, der medfølger i beskeden.
Beskeder skrives med AES-256 i RFC 4880-formatet, som ældre modtagere kan læse, og det nyere RFC 9580-format læses også. Kryptografien er ProtonMail/go-crypto; Perfuse implementerer ingen primitiv. Samarbejdsevnen testes mod GnuPG i begge retninger: gpg dekrypterer og verificerer, hvad Perfuse skriver, og Perfuse åbner og verificerer, hvad gpg skriver.
10.22 Levering til en anden kanal
En kanaldestination overdrager beskeden til en anden kanal ved navn. Den modtagende kanal behandler den som enhver anden ankomst: den optegner den, filtrerer den, transformerer den og spreder den ud.
Dette er den understøttede måde at bygge en kæde. Den er bevidst synlig — to kanaler, to sæt statistikker, to poster i beskedhistorikken — fordi en kæde, der er skjult inde i en kanal, er en kæde, som ingen kan overvåge.
Beskeden overdrages i hukommelse i stedet for over et netværk, så der er ingen ramme, ingen bekræftelse og ingen timeout mellem de to.
10.23 Hvad der sker, når processen afbrydes
Spørgsmålet, som enhver, der har kørt en interface-motor, spørger først, og det, som sjældent besvares, fordi det ærlige svar ofte er pinligt.
Det blev besvaret ved at afbryde processen med SIGKILL midt igennem en batch — hvilket er, hvad en strømafbrydelse, en ud-af-hukommelse-dræbning og en hypervisor-genstart alle ligner fra indersiden — og tælle, hvad der overlevede, mod hvad der var lovet.
Egenskaben, der testes, er ikke "intet går tabt". Det er ikke opnåeligt og at hævde det ville være en løgn. Det er den snævrere løfte, en afsender faktisk afhænger af: en besked, der blev positivt bekræftet, er en besked, der ankom.
Med ack.when: on_delivery, som er standard, skrives hver destination før bekræftelsen sendes ud, så et AA er en udtalelse om destinationen snarere end om en kø. En besked, der dræbes før dens bekræftelse, kan meget vel gå tabt, og det er correct: afsenderen blev aldrig lovet noget og vil sende det igen.
10.23.1 Bekræftelse ved levering
Fem kørsler, dræbt efter 5, 25, 40, 75 og 110 meddelelser af 120.
| Bekræftet | Til stede nedstrøms herefter | Bekræftet men mangler |
|---|---|---|
| 255 | 255 | 0 |
Løftet holdes ved hver afbrydelsespunkt, og intet blev duplikeret. En duplikat ville have været acceptabelt, og et tab ville ikke have været: en gensendt A08 er en gener for modtagere, der absorberer den, og et laboratorie-resultat, der stille og roligt aldrig ankom, er en patient-sikkerhedshændelse.
10.23.2 Bekræftelse ved modtag
on_receipt svarer, så snart beskeden er køet, før nogen destination er skrevet. Dette kapitel har altid sagt, en bekræftet besked kan stadig gå tabt på den måde. Her er størrelsen af det.
| Dræbt efter | Bekræftet | Til stede nedstrøms | Tabt |
|---|---|---|---|
| 5 | 5 | 1 | 4 |
| 25 | 25 | 1 | 24 |
| 75 | 75 | 2 | 73 |
| 110 | 110 | 2 | 108 |
Virtuelt alt, der er under transmission. Indstillingen er ikke en fejl, og der er feeds, hvor det er det rigtige valg, men det skal vælges med vidende om, at et crash vil forkaste hvad der er blevet bekræftet og endnu ikke skrevet, og at dette er næsten alt i en burst.
Intet gendannet ved genstart, fordi perfuse run ikke har en varig lagring. En destination, der ikke må tabe beskeder under et udfald, har brug for queue.enabled, som har brug for den database, perfuse serve giver — og perfuse run afviser nu en sådan kanal, snarere end at starte den uden køen.
10.23.3 En afsender, der dør halvvejs gennem en meddelelse
Den farligste af disse fejl, fordi en afkortet HL7-besked normalt stadig parser. Segmenterne før afbrydelsen er komplette og velformede, så en modtager har ingen måde at vide, om PID og PV1 ankom og OBX-segmenterne med resultaterne ikke gjorde.
En ramme åbnedes, seks tiendedele af en besked sendtes, og forbindelsen nulrettes snarere end lukket. Den delvise besked blev ikke leveret, lytteren overlevede, og en velformet besked sendt straks efter blev accepteret normalt, så fragmentet ikke blev ført over i den næste besked.
Forbindelsesloggen rapporterer nu, hvor mange bytes af en ufærdig ramme blev opgivet, for hvert fejltilfælde snarere end kun en ren lukning. Tidligere loggede en crashed afsender, en killed proces og en trukket kabel alle messages=0 og intet andet, hvilket ikke kan skelne en tom sundhedscheck fra et laboratorie-resultat, der blev smidt væk ni tiendedele af vejen igennem.
10.23.4 En fuld disk
Pladsmangel detekteres og logges i stedet for at blive gulet. To ting om det er værd at vide.
Afsenderen får ikke en prompt afvisning. Leveringen gentages på det normale schedule — en sekund, to, fire, otte — og den negative bekræftelse ankommer omkring femten sekunder senere. En afsender, hvis egen timeout er kortere end det, ser en stillestående forbindelse snarere end en AE, og vil konkludere, at netværket er skyld i det, snarere end disken.
Og en volumen, der rapporterer nul bytes fri, kan stadig acceptere små tilføjelser i en periode, fordi tilføjelse af et par hundrede bytes til en fil, hvis sidste blok har plads, ikke kræver nogen ny allokering. Den første skrivefejl sker senere end det øjeblik, disken blev fyldt.
10.23.5 Hvad der ikke blev testet
En destinationsmappe, der mister skriveadgang. Den kan ikke injiceres med chmod: motoren holder outputfilen åben, og ændring af en fil's tilladelse påvirker ikke en allerede åbnet beskrivelse. Testning af det kræver, at volumenet genmonteres som skrivebeskyttet eller fjernes under processen, hvilket ikke er blevet gjort. Den er nævnt her i stedet for at udelades, fordi et hul, som ingen nævner, læser som et hul, som ingen har kigget efter.
11 Alarm
Ingenting uden for Perfuse vil fortælle dig, at en feed er stoppet. Afsenderen bliver bekræftet og er tilfreds; modtageren har ingen måde at vide, om en meddelelse blev sendt. Alarm er det eneste, der står mellem en brudt grænseflade og nogen, der lægger mærke til det uger senere.
11.1 Alarmtyperne
| Type | Udløser når |
|---|---|
error-rate | Fejl overskrider en proportion af trafik. |
queue-depth | En kø har mere end N meddelelser i venteposition. |
queue-age | Den ældste ventende meddelelse er ældre end en varighed. |
queue-stuck | En kø afvikler ikke overhovedet. |
no-traffic | Intet er ankommet i en fast periode. |
below-rhythm | Trafikken er langt under, hvad denne feed normalt gør *på denne tid på ugen*. |
channel-down | En kanal, der skal køre, er ikke i gang. |
script-errors | Et script fejler. |
rows-quarantined | En databasekilde sætter rækker til side. |
slow-delivery | Leveringerne lykkes, men tager for lang tid. |
contract | En meddelelse krænker kanalens erklærede kontrakt. |
phi-volume | En kanal transporterer flere gange sin normale rate for timen. |
phi-after-hours | En kanal, der kun transporterer dagtrafik, transporterer nogen om natten. |
phi-new-destination | En kanal leverer til en adresse, den ikke har sendt til før. |
phi-bulk-reads | En person læser mere end N forskellige patienters poster inden for et minut. |
De sidste fire overvåger adgang til patientdata og beskrives nedenfor.
11.2 Stilhed er det sværeste at registrere
En kanal, der har ophørt med at modtage data, producerer ingen fejl. Der er intet at tælle. Det er derfor, no-traffic findes, og hvorfor det ikke er nok i sig selv.
no-traffic er en fast grænseværdi: alarmér, hvis intet er ankommet i, sagen, to timer. På en feed, der aldrig går stille, virker det. På en kliniks laboratoriefeed er det værdiløst — feeden er stille hver nat og hele weekenden, så en to-timers grænseværdi vækker nogen kl. 1 om natten hver nat, og en grænseværdi, der er lang nok til at overleve weekenden, vil ikke bemærke en afbrydelse tirsdag morgen, før tirsdag eftermiddag.
Der findes ikke ét tal, der er begge dele. Det er ikke et tilpasningsproblem; det er, at spørgsmålet "har denne feed ophørt" ikke kan besvares af en konstant, når feedens norm varierer med en faktor på hundred over ugen.
11.3 Rytmebevidst registrering
below-rhythm sammenligner den aktuelle trafik med, hvad denne kanal normalt gør i denne time på denne dag i ugen.
Perfuse lærer hver kanals uge fra dens egen registrerede historik: 168 timebåse, mandag først, så en arbejdsuge er sammenhængende. For hver bås holder den en median, en lav og en høj, en gulv, og hvor mange observationer det er baseret på.
Grænsen er en andel af normalt, som standardiserer til 0.8 (80 procent i konsollen) — alarm, når trafikken falder under fire femtedele af, hvad der er normalt for denne time.
11.3.1 Median, ikke gennemsnit
En enkelt backlog-udløsning af fyrre tusinde meddelelser mod en normal på tre hundrede flytter et gennemsnit langt nok, så feeden kan gå helt stille herefter, uden nogensinde at falde under det. Medianen påvirkes ikke af en enkelt ekstraordinær time, hvilket er præcis den egenskab, der er nødvendig.
11.3.2 Gulvet er en percentile, ikke minimum
Om en kanals rytme er pålidelig nok til at alarmere på, afgøres af dens laveste ende, ikke dens højeste ende. En alarm for manglende trafik udløses, når trafikken er *lav*, så kun laveste ende kan fortælle, om det vil producere falske positiver. En tidlig version af dette sammenlignede højeste mod medianen og fik det forkert i begge retninger på én gang: det diskvalificerede en perfekt stabil feed i en måned efter en backlog, og det godkendte en virkelig erratisk feed, der svingede mellem to og ni hundrede meddelelser i samme time, fordi dens højeste var kun tre gange dens median.
Gulvet er den tyvende percentile og ikke minimum, fordi minimum trækkes ned til nul af en enkelt bankferie. Og percentilen er ikke interpoleret — hvert tal i en alarm kl. 2 om natten skal være et tal, feeden faktisk producerede, ikke en gennemsnit af to tal, det ikke gjorde.
11.3.3 Den vil sige, når den ikke kan afgøre
En kanal med ingen historik overhovedet udelades helt i stedet for at behandles som en, der er stoppet. En ny kanal må ikke se ud som en, der er brudt.
Hvor historikken er for tynd eller for erratisk til at understøtte en dom, afviser reglen at udløse i stedet for at gætte. "Jeg kan ikke ærligt sige" er et førsteklasses svar her, og det er at foretrække frem for en alarm, der er rigtig lidt oftere end tilfældigt.
Fraværende timer inden for læringsvinduet registreres som virkelige nulle, ikke som manglende data. Halvdelen af signalet i en klinikfeed er *når den er berettiget stille*, og hvis man behandler disse timer som ukendte, ville det kaste det væk.
11.4 Konfiguration af alarmer
Fra grænsefladen, under Beskeder, pr. kanal eller på tværs af alle. Hver regel har en type, en grænseværdi og hvor beskeden skal sendes. Reglerne gemmes i alerts.yaml ved siden af databasen (eller filen -alerts navne) og træder i kraft med det samme; indtil den første gemme anvendes de indbyggede regler. Filen kan også redigeres manuelt: ændringen høstes inden for tredive sekunder, og en fil, der ikke længere kan indlæses, rapporteres i loggen, og reglerne i kraft opretholdes.
Værd at gøre før en feed går live i stedet for efter den første incident. Den specifikke samling, der er værd at have på enhver klinisk feed:
below-rhythm— feeden er gået stille, når den ikke burde være stille.error-rate— meddelelser ankommer og fejler.queue-age— noget er fastnet i stedet for blot at være beskæftiget.channel-down— kanalen kører ikke overhovedet.
Den første er den, der fanger fejlen, som ingen andre vil rapportere.
11.5 Overvågning af adgang til patientdata
En overtrædelse annoncerer sig sjældent. Det ligner en feed, der transporterer mere end normalt, trafik klokken tre om natten på en kanal, der kun fungerer på kontortid, en destination, der ikke er sat op, eller en person, der åbner patient efter patient. Perfuse overvåger disse fire, som standard ( serve -watch-access=false slår det fra), og rapporterer, hvad den ser, gennem de ovennævnte beskedregler, så det er konfigureret, anerkendt og leveret som enhver anden besked.
- Bursts (
phi-volume). Hver kanals hastighed sammenlignes med dens egen historik på samme tidspunkt på dagen, så en travl morgen er ikke noget nyt. Grænsen er en multiplum af den normale hastighed, tre som standard. En burst er normalt en opgang af en venteliste efter en afbrydelse, og det er også, hvordan poster, der hentes gennem en feed, ser ud. - Nattrafik på en dagkanal (
phi-after-hours). En kanal tælles som kun dagtid, når under 2 procent af, hvad den har transporteret, faldt uden for 07:00 til 19:00, i serverens tidszone. - En ny destination (
phi-new-destination). Adresse er, hvad destinationen navngiver: en vært og port, en URL, en mappe. Omnavning af en destination er ikke noget nyt; at pege en på en ny vært er det. De adresser, hver kanal har sendt til, gemmes iaccess-watch.jsonved siden af databasen, så en destination, der er ændret, mens serveren var nede, rapporteres stadig. - Bulk-læs (
phi-bulk-reads). Tælles fra revisionsstien: beskeder åbnet, patienter søgt efter eller set op (PDQm, PIXm, identitetssøgning), dokumenter og billeder læst (XDS, MHD, DICOMweb), forhåndsgodkendelser læst, sammenfattninger og visninger kørt. At læse den samme post igen tælles ikke to gange. Grænsen er, hvor mange forskellige poster i et minut, ti som standard, af en konto fra en adresse.
Ingenting bedømmes for en kanal, før den har transporteret 200 meddelelser, fordi "usædvanligt" ikke betyder noget uden en mønster. Mønstret lærer fra de sidste fjorten dages meddelelselagring, når serveren starter, så en genstart gør ikke hver kanal ny igen. Alt, der ses, holdes i femten minutter, derefter rydder beskeden sig selv.
Det overvåger og rapporterer kun. Det holder aldrig en meddelelse tilbage eller afviser en læsning: disse er heuristikker, og en feed, der stoppes, fordi en gæt var forkert, er et klinisk problem. Hver besked siger, hvad der er set, og hvad det uskyldigt kan være, fordi de fleste af dem vil være uskyldige.
Administratorene ser, hvad overvågningen har lært på Beskedsskærmen, under Overvågning af adgang til patientdata: hver kanals mønster (stadig lærer, kun dagtid eller dag og nat), hvor mange destinationer den kender, og alt, der er set i de sidste femten minutter, herunder hvad der er under en regels grænseværdi.
11.6 Hvor alarmer går hen
Advarsler kan sendes som JSON til en webhook (-alert-webhook: Slack, Teams, Mattermost, PagerDuty, Alertmanager eller noget, der accepterer en POST), sendes som SNMPv2-fælder til SNMP-managere (-snmp-traps, se SNMP), eller skrives til loggen, så en samler kan hente dem. Der er ingen e-mail-aflevering af sig selv: peg webhook'et mod en relay, hvis advarsler skal ankomme som e-mail.
En alarm, der kun skrives til en log, som ingen læser, er ikke en alarm. Hvis Perfuse er det eneste, der vil bemærke en stoppet feed, må alarmen nå en person.
12 Beskeden Gemmes
Hver besked Perfuse modtager bliver optaget, som modtaget, før noget ændrer den. Det samme gælder for hvad der blev sendt til hver destination og hvad der skete med den. Gemmet er en SQLite-fil angivet af -db.
12.1 Hvad der gemmes
Pr. besked: de rå bytes som de ankom, hvornår de ankom, hvilken kanal, den parsede beskedtype og triggerbegivenhed, og filterresultatet.
Pr. destination pr. besked: de bytes der blev sendt, resultatet, den tid det tog, og eventuelle fejl eller negative bekræftelser der blev modtaget.
Dette er formen en undersøgelse har brug for. "Hvad sendte de os", "hvad sendte vi dem" og "hvad sagde de om det" er tre forskellige spørgsmål, og hver af dem bliver stillet.
12.2 Søgning
Efter kanal, efter tidsinterval, efter resultat, efter beskedtype og triggerbegivenhed, og efter feltværdi.
Feltsøgning fungerer på den parsede besked, så søgning efter en journalnummer finder det, uanset hvor i beskeden feltet befinder sig, snarere end at matche cifrene et sted i teksten. En tekst-søgning efter 12345 i en besked, der indeholder en mængde på 12345, finder en besked, der intet har at gøre med den patient, du leder efter.
12.3 Afspilning og genbearbejdning
Fordi originalen gemmes, kan en besked køres gennem den aktuelle konfiguration igen.
Sporing tager en optaget besked og viser, hvad kanalen ville gøre med den nu, uden at sende noget. Dækkes i fejlfinding.
Genbearbejd kører den faktisk igen, herunder levering. Dette er, hvad fikser en batch af beskeder, der fejlede, fordi en destination var forkert konfigureret: ret konfigurationen, vælg de berørte beskeder, genbearbejd.
12.4 Uaktualitet
En sporing af en gammel besked mod den aktuelle konfiguration besvarer en hypotetisk: hvad *ville* ske nu. Det er normalt, hvad du vil have, men ikke altid — hvis du undersøger, hvad gik galt sidste tirsdag, kan kanalen være ændret siden.
Perfuse registrerer dette og siger det. En sporing af en besked, der ankom før kanalen sidst blev redigeret, markeres som sådan, så svaret ikke tages for en rekonstruktion af, hvad der faktisk skete.
12.5 Opbevaring
Gemmet vokser. cleanup.periodDays kontrollerer, hvor længe beskeder gemmes.
To ting at veje. Kliniske beskeder kan falde under opbevaringskrav, der er længere end noget, du ville vælge af operative årsager, og gemmet er ikke systemet af record — modtagersystemet er. Perfuses kopi findes for at diagnosticere og genbearbejde, og begge disse behov aftager skarpt efter få uger.
Retentionsperioden afgør også, hvor meget historik rhythm learneren har at arbejde med. Se alerting: en retentionsperiode kortere end få uger gør det umuligt for den at skelne mellem en stille søndag og en stoppet feed.
12.6 Gemmet indeholder kliniske data
Dette er den del af Perfuse, der indeholder patientinformation, og den skal behandles derefter: på krypteret lagring, sikkerhedskopieret som klinisk data og adgangskontrolleret. Se sikkerhed.
De genererede testbeskeder, der beskrives i testing, findes delvist sådan, at denne data ikke behøver at forlade miljøet for at reproducere et problem et andet sted.
13 Fejlfinding
Spørgsmålet er næsten altid det samme: denne besked kom ind, noget gik galt ud, hvor ændrede det sig? Perfuse besvarer det ved at afspille en optaget besked gennem den aktuelle konfiguration og vise hvert trin.
Ingenting sendes under tracing. Kanalen kører ubeskåret, og ingen genudlevering er nødvendig.
13.1 Tracing af en besked
Vælg en hvilken som helst optaget besked og tracing den. Resultatet viser, i rækkefølge:
- Hvad filteret læste. Hvilke felter det kiggede på og hvad det fandt. Et filter, der afviser alt, læser normalt en sti, der ikke findes i denne feed, og dette navngiver det.
- Hver transformation. Hvad det ændrede, fra hvad til hvad.
- Hvad hver destination besluttede. Om den ville acceptere beskeden og hvorfor ikke, hvis den ikke ville.
- Udgangen. Beskeden, som hver destination ville sende den.
13.2 Trin for trin
Step-through-visningen kører hver transformation for sig og tager et snapshot af hele beskeden efter det. En nummereret rail af trin, farvet efter hvad der skete, og beskeden, som den stod ved hvert punkt.
Hele beskeden i stedet for kun ændringen, fordi ændringen ofte ikke er, hvor problemet er — et trin, der korrekt ændrede feltet, det var rettet mod, på en besked, hvor et tidligere trin allerede havde sat det forkerte der, ser perfekt korrekt ud i isolation.
13.3 Fire resultater og den forskel, der betyder noget
| Resultat | Betydning |
|---|---|
changed | Trinet kørte og ændrede beskeden. |
no-effect | Trinet kørte, og beskeden er uændret. |
skipped | Trinets when-betingelse var falsk, så det kørte ikke. |
failed | Trinet fejlede. |
no-effect og skipped rapporteres separat, og dette er pointen med hele funktionen.
Udefra er de identiske: beskeden er den samme bagefter på begge måder. De betyder modsatte ting. skipped betyder, at betingelsen fungerede, som den var skrevet, og denne besked var ikke en, den gjaldt for — normalt korrekt. no-effect betyder, at trinet kørte og fandt intet at gøre, hvilket normalt betyder, at det er rettet mod et felt, der ikke er der.
En motor, der rapporterer begge som "intet skete", efterlader dig ude af stand til at skelne mellem en arbejdende betingelse og en brudt sti, og det er den mest almindelige transformation-fejl, der findes.
no-effect på hver besked, er næsten altid en forkert sti. Step-through-headeren tæller, hvor mange trin fandt intet, hvilket er den hurtigste måde at spotte det på: en kanal med tre trin og tre no-effect-resultater transformerer intet overhovedet.13.4 Test af en ændring, før den gemmes
Byggeren kan køre en kandidat-konfiguration mod optaget trafik og rapportere, hvad der ville være forskelligt. Dette er den sikreste måde at ændre en live-kanal: lav ændringen, se hvad den gør ved de sidste få hundrede rigtige beskeder, og gem derefter.
Det er også, hvordan man finder ud af, at en ændring, der ser åbenlyst korrekt ud, påvirker beskeder, man ikke havde tænkt på — et trin, der er betinget af ét trigger-arrangement, på en feed, der viser sig at bære fire.
13.5 Hvad tracing ikke kan fortælle dig
Det kører den aktuelle konfiguration. Hvis kanalen er redigeret, siden beskeden ankom, er tracingen en hypotese snarere end en rekonstruktion, og Perfuse markerer det som sådan snarere end at lade forskellen passere stille.
Det øver heller ikke transporten. En tracing viser, hvad der ville blive sendt, ikke om destinationen ville acceptere det — en besked, der er korrekt, og en destination, der afviser forbindelser, producerer en ren tracing og en mislykket levering. Disse er synlige i leveringsposten i stedet.
13.6 Scripts
Et script er ét uigennemsigtigt trin i tracingen. Perfuse kan vise, hvad der gik ind og hvad der kom ud, og kan ikke vise, hvad der skete imellem eller hvilke felter der blev læst.
Dette er den konkrete pris for at bruge et script i stedet for deklarative trin, og det er værd at veje, når man vælger. Se transformation.
14 Test
Standardråd for test af et interface er at bygge eksempel-beskeder, der afspejler jeres egen miljø — jeres laboratoriets koder, jeres sagblandning, jeres afsenders vaner — og at fjerne patientdataene ved hånden. Det er langsomt, og at gøre det ufuldstændigt er det normale resultat.
Perfuse tilbyder tre ting i stedet: genereret trafik, der matcher en feeds form uden dens indhold, en kanal, der er foreslået fra en eksempel, nogen har sendt dig, og en sammenligning mod motoren, du erstatter.
14.1 Genereret testtrafik
Hvis en kanal har behandlet meddelelser, kan Perfuse producere flere meddelelser ligesom dem.
Hvad der er trofast:
- Udløser begivenheder i de proportioner, der faktisk er observeret, med mindst én af hver, så en sjælden begivenhed stadig vises.
- Felter udfyldt i de hastigheder, de faktisk er — så tilfældet, hvor et felt er *fraværende*, bliver testet, hvilket er tilfældet, der bryder ting.
- Gentagelser, hvor gentagelser forekommer, sammensat struktur, hvor det forekommer.
- Koder trukket fra de kode-tabeller, der faktisk er set.
Hvad der ikke er trofast, og dette er angivet udtrykkeligt snarere end antydet: klinisk sammenhæng. En genereret patient har et ikke-relateret journalnummer, en navn-lignende streng og en diagnose med ingen relation til observationen. Disse meddelelser øver en grænseflade. De er ikke en klinisk test-sæt og kan ikke bruges til at validere klinisk logik.
14.1.1 Hvorfor den indeholder ingen rigtige data
Argumentet er strukturelt snarere end en påstand om indsats. Generatorens eneste input er kanalens trafik profil, og en profil indeholder udfyldningshastigheder, former, længder, gentagelsesantal og segmentfrekvenser. Den indeholder ingen værdier.
Den eneste undtagelse er kode-felter, og en kode identificerer ingen.
Dette er en stærkere garanti end at anonymisere rigtige meddelelser, hvilket er en proces, der kan udføres ufuldstændigt og normalt er det. Her er der ingen vej, hvorved et navn kunne nå output, fordi navnet aldrig var i input.
Hver genereret meddelelse parses, før den returneres — en uparsbar korpus ville sende nogen på jagt efter en fejl i deres grænseflade, der faktisk er en fejl i generator — og hver enkelt er markeret T i MSH-11, med en bevidst syntetisk afsender og facilitet.
T og den syntetiske afsender er ikke kosmetisk.14.2 Bygning af en kanal fra et eksempel
Indsæt meddelelsen en laboratorie, hospital eller leverandør har sendt dig, og Perfuse foreslår en kanal til det. Ingen behøver at køre først.
Den håndterer, hvad folk faktisk indsætter: flere meddelelser i én blok, enhver linjeafslutning, MLLP-rammer, der overlevede kopieringen, og den dækkende note ovenfor meddelelsen. At afvise et eksempel, fordi det ankom med Windows-linjeafslutninger, ville være en hindring snarere end en check.
14.2.1 Tre lister
Forslaget kommer med, hvad eksemplet viser, hvad der er gættet, og hvad eksemplet ikke kan fortælle dig — tre separate lister, vægtet lige i grænsefladen.
De er separate, fordi en læser, der ikke kan se, hvilken af dem er hvilken, må verificere alt eller stole på alt, og begge er værre end at vide, hvor man skal se.
Fra en enkelt meddelelse er grænserne navngivet specifikt snarere end generelt: hvilke felter er valgfrie, hvilke segmenter gentages, hvilke koder findes ud over dem her, om afsenderen nogensinde sender en anden udløser-begivenhed. En generel advarsel er en advarsel, folk skimrer.
Tillid er et ord — lav, moderat, rimelig — aldrig en procent. En procent antyder en beregning, og dette er en vurdering af, hvor mange eksempler der er.
Z-segmenter kaldes ved navn, fordi et lokalt segment er det, ingen specifikation nævner, og den hyppigste grund til, at en kanal bygget fra en standard-skabelon ikke virker.
14.2.2 Advarsel om separator
Hvis eksemplets feltseparator ikke er den sædvanlige |, vises det først, og tilliden falder til lav.
Grunden er en ægte stille fejl. HL7 tager sin feltseparator fra meddelelsen selv, så et eksempel, hvis pipes er erstattet af typografiske look-alikes — hvilket er, hvad en tekstbehandler gør — parser perfekt til felter, der er helt forkerte. Ingen fejl vises noget sted.
At afvise et sådant eksempel ville være forkert, fordi en afsender måske legitimer kan bruge en anden separator. Så det markeres, og tegnet navngives, og det foreslås at bede om en plain tekst-vedhæftning.
14.3 Sammenligning med den gamle motor
Før en live-feed flyttes, er spørgsmålet, om Perfuse producerer samme output som det, der har kørt i år. Ingen mængde designkvalitet kan besvare det. Se migration.
14.4 Verificering mod den virkelige ting, i containere
Tre kontroller køres mod virkelige implementeringer i stedet for mod Perfuses egen idé om et protokol. De lever uden for make check, fordi de kræver en container-kørsel, og en kontrol, der kræver Docker, er en kontrol, som folk stopper med at køre.
scripts/interop-up.sh starter alle og printer, hvad hver enkelt låser op.
| Container | Kontroller | Hvad den fandt |
|---|---|---|
| Keycloak 26 | web/e2e-saml/, og internal/saml fixtures | En fejl. Den kanoniske form, en signatur dækker, blev beregnet med namespace-præfikser droppet, så ingen virkelig identitetsudbyder nogensinde kunne have logget nogen ind |
| Microsoft Entra | internal/saml live-tests og fixtures | To fejl, begge i, hvad der omgiver protokollen. En konto blev oprettet under Enträs uigennemsigtige NameID, fordi den læselige-navn-logik ønskede en email-krav og Entra sender ingen. Og en SAML-konto blev registreret som OIDC, fordi butikken afledte protokollen fra en udsteder, der ligner begge |
| HAPI FHIR | go test ./internal/engine/ -run HAPI | En fejl. En unmapped tildelingsmyndighed producerede en identifikator-system, der annoncerede en OID og bar et ord, som HAPI accepterede uden klage |
| ActiveMQ | go test ./internal/engine/ -run RealBroker | Korrekt, herunder null-byte-rammefærdtilfældet. Hævdet gennem brokerens egen administrationsgrænseflade i stedet for gennem en funktion, der returnerer nil |
| nginx, client-certifikater | go test ./internal/engine/ -run ClientCertificate | Korrekt |
| Orthanc (en rigtig PACS) | go test ./internal/engine/ -run RealPACS | Korrekt. En C-STORE ankommer, og patientnavnet, identifikatoren, studie-datoen, modaliteten og SOP-klassen overlever alle |
| PostgreSQL | go test ./internal/engine/ -run RealPostgres | Korrekt, og det fremkaldte en bedre fejl: en erklæring i den forkerte dialekt's placeringer er nu afvist, når den gemmes, i stedet for at blive en syntaksfejl på serveren, når en besked ankommer |
| OpenSSH sftp-server | go test ./internal/engine/ -run OpenSSHServer | Korrekt. De eksisterende SFTP-tests bruger samme Go-bibliotek på begge sider; OpenSSH er en anden implementering og den, der er på den fjerne ende af næsten hver rigtig feed |
| Mirth 4.5.2 | go test ./internal/mirth/ -run RealMirth | Korrekt nu. Den eneste fixture, der blev brugt, var håndskrevet, og Mirth ville ikke indlæse den; scripts/mirth-author-channel.sh har Mirth skabt en i stedet, og Perfuse læser den |
Hver enkelt springer over i stedet for at fejle, når dens container er fraværende, så make check passerer på en maskine med ingen Docker.
Hvorfor dette er adskilt fra resten af suiten. Hver anden test af disse funktioner havde begge halvdele skrevet her: et dokument, denne kodebase underskrev, læst tilbage af koden, der underskrev det. Det er enighed med sig selv, og det er værd mindre, end det ser ud til.
SAML-kanonisereren er det tilfælde, der beviser pointen. Den bar tusind linjer tests, fem af dem specifikt om kanonisering, og alle af dem passede, mens ingen virkelig identitetsudbyder nogensinde kunne have logget nogen ind — den kanoniske form, en signatur dækker, blev beregnet med namespace-præfikser droppet, og den eneste måde at finde det på var at give det et dokument Perfuse ikke havde skrevet.
To af de otte kontroller fandt fejl direkte, og en tredje fremkaldte en rigtig forbedring. Tre fandt intet galt. Denne forhold er argumentet for at holde alle af dem: en kontrol, der passerer, har fortalt dig noget, du ikke kunne have vidst på anden måde, og der var ingen måde at vide på forhånd, hvilke de ville være.
En mønster, der er værd at navne, fordi den optrådte i begge fejl: accept er ikke verificering. HAPI accepterede den forkerte identifikator-system og gemte den; fejlen optrådte kun, da ressourcen blev læst tilbage. En modtager, der tolererer noget, er ikke bevis for, at det er rigtigt, kun for, at denne modtager var mild.
To fanget påstand er begge begået, på internal/saml/testdata/keycloak-assertion.xml og entra-response.xml, med tests over begge — så denne specifikke regression bliver fanget uden en container.
Begge er nødvendige i stedet for, at en af dem er reserve. Keycloak præfikserer sin påstand og signatur, Entra gør ikke, og disse er de to modsatte tilfælde i kanonisering — hvilket præcis er, hvor fejlen var. En test påstår, at hver dokument stadig dækker sin egen sag, fordi en erstatning, der skete at være præfikseret, ville stille stille halvere dækningen uden at fejle noget. Den generelle lære generaliserer ikke så billigt: for alt andet er containeren kontrollen.
14.5 Diagnose af en test, der fejler en gang og aldrig igen
En test, der fejler i en fuld kørsel og passerer alene seksten gange, er ikke en ustabil test. Det er en test, der delte noget med kørslen, og måden at finde ud af, hvad det er, er at måle den delte ting i stedet for testen.
To instrumenter findes til dette, og begge er ment til at køre sammen med en fuld suite:
./scripts/e2e-watchdog.sh /tmp/watchdog.log # the HTTP server and the shared session
./scripts/e2e-mllp-probe.py /tmp/mllp.log # the fixture channel's listener
Hver af dem opdager kørslen's porte fra setup'ets egen tilstandsfil og sampler hver 500 millisekunder, indtil serveren lukker. De logger hver prøve i stedet for kun fejlene, hvilket er, hvad der gør dem nyttige: en blip viser sig i en kørsel, hvor intet fejlede, så en fejl, der optræder en gang i tre kørsler, bliver målbart på hver enkelt.
Sæt PERFUSE_E2E_KEEP=1 for at beholde den midlertidige mappe, der indeholder databasen, som den blev efterladt, og serverloggen for hele kørslen. Serverloggen er normalt svaret. I en undersøgt sag registrerede den en kanal, der stoppede, og dens lytter genbindede 421 millisekunder senere, og sondens ene afviste forbindelse faldt inden for dette vindue.
Læs sporet i stedet for error-context.md, der har været tom på mere end én lejlighed, hvor sporet indeholdt den virkelige besked.
Kopier artefakterne ud, før du genkører noget. En succesfuld kørsel sletter test-results, så sporet af fejlen, du undersøger, forsvinder i samme øjeblik, du forsøger at reproducere den. Når den først er tabt, kan spørgsmålet, det ville have svaret, ikke besvares.
Stop interop-beholdere først. Stop dem, før en fuld browserkørsel, og start dem med ./scripts/interop-up.sh herefter, hvis du stadig har brug for dem.
Otte beholdere holder omkring 9,8 GB hukommelse, og på en maskine uden meget mere end det er der for lidt tilbage til Chromums processer, node og Go-værktøjskæden sammen. Det, det producerer, er ikke en out-of-memory-fejl, men en renderer, der ophører med at blive planlagt: en registreret spor viser et 60,2 sekunders hul med ingen rammer overhovedet, under hvilket Playwright ventede på, at en knap blev "synlig, aktiveret og stabil" og ikke kunne få to på hinanden følgende animationsrammer til sammenligning. Serveren var sund hele vejen igennem, den langsomste anmodning i hele kørslen var 154 millisekunder.
Den fejl læser som en defekt i hvilket som helst test, der tilfældigvis kørte. Det er værd at kende formen på den: hver anmodning hurtig, siden visuelt frosset, gentagelsessløjfen nåede aldrig anden iteration, og hele sagen passerer i isolation.
Kun én kørsel ad gangen. Suiten deler én server, én logget-ind session i web/e2e/.auth/admin.json, og én tilstandsfil, der navngiver serverprocessen. Ingen af disse er per-kørsel, så en anden kørsel, der starter, mens den første er i gang, overskriver tilstandsfilen, og hvilken som helst afvikling, der afsluttes først, dræber den anden kørsels server og sletter dens session.
Det, det ligner, er ikke det samme som årsagen. Det producerede en række på 279 fejl, hvis første besked var ENOENT: no such file or directory, open './e2e/.auth/admin.json', en række, der stoppede tidligt og rapporterede 217 gennemført, og to tests, der fejlede med bind: address already in use — ingen af dem antyder to kørsler, der kæmper. Suiten tager nu en lås og nægter at starte, navngivende processen, der holder den. En lås, der er efterladt af en afbrudt kørsel, overtages i stedet for at blokere for evigt, fordi en sikkerhedsforanstaltning, der blokerer suiten, er noget, nogen sletter sammen med sikkerheden.
En relateret fælde, der nu er fikset: to specifikationer navngav deres lytterporte direkte, så en server, der var efterladt af en afbrudt kørsel, fik dem til at fejle på noget, de ikke havde noget at gøre med. Porterne bedes nu om af operativsystemet.
Besvar ikke noget af dette med gentagelser. En test, der passerer på anden forsøg, fandt en rigtig kapløb og skjulte det, og playwright.config.ts sætter retries: 0 af denne grund.
En advarsel: sampling hver 100 millisekunder spawnete tyve processer per sekund, strakte en kørsel med halvdelen, og fejlede to tests på tidsgrænser, der ikke havde noget galt med dem. Et instrument, der ændrer, hvad det måler, producerer resultater om sig selv.
14.6 Hvad der stadig har brug for rigtig infrastruktur
Flere dele af Perfuse er implementeret og er aldrig blevet testet mod den rigtige sag. De er nævnt her i stedet for at blive opdaget:
- SMB mod en rigtig Windows-del — protokolkoden er komplet og testet for stisikkerhed og argumentbehandling, men ingen test åbner en socket til en domain-tilsluttet server.
- En rigtig serieport.
- Mirth-importøren mod XML, en rigtig Mirth producerede. Testet mod Mirth 4.5.2 i en beholder, og fundet var omkring dette repository: den eneste migrationsfikstur her blev skrevet hånd i hånd og Mirth vil ikke indlæse den — den gemmer kanalen som ugyldig og smider hver connector væk. Det, der blev afklaret, er, at
version-attributterne, en rigtig Mirth skriver på hvert element, parser til den samme kanal, så de er ikke en fare; det, der ikke er afklaret, er alt andet, en rigtig eksport indeholder. - SAML mod en vært kommerciel identitetsudbyder. Keycloak er verificeret; en udbyder beviser, at en implementering matcher en udbyder.
- En NCPDP-krav via en rigtig apoteksskifter.
- En SCRIPT-besked via Surescripts, hvor certificering er en kommerciel proces i stedet for en teknisk.
Funktionerne i dette kapitel og det næste findes, så du kan samle dine egne beviser i stedet for at tage nogen andens ord.
14.7 Målt mod offentlige overenskomstkorpusser
En test-suite, hvis fiksturer blev skrevet her, beviser overensstemmelse med sig selv. Disse er andres data.
14.7.1 FHIR R4, specifikationens egne eksempler
Alle 2.912 eksempelfiler, der er offentliggjort med FHIR R4-specifikationen — hver enkelt eksempel, som standardforfatterne skrev.
| Resultat | Antal |
|---|---|
| Ressourcer valideret med ingen fund | 13.723 |
| Ressourcer rapporteret ugyldige | 0 |
| Filer afvist som en uimplementeret ressourcetype | 753 |
| Bundlens poster sprunget over som en uimplementeret type | 1.348 |
Ingen enkelt ressource blev valideret forkert. Hver fejl er en eksplicit afvisning, der navngiver typen, den ikke kan læse — 672 ValueSet, 80 ConceptMap og en Parameters. En validator, der stille passerer, hvad den ikke forstår, er værre end en, der siger det.
Korpusset fandt en fejl, som er årsagen til, at det kører. Validering af en samling udskrev "Validering af en samling fra en fil er endnu ikke understøttet" og fortsatte. Dette var forkert i begge retninger: samlinger, hvis poster tilfældigvis var typer, parseren kunne håndtere, blev allerede valideret, og en samling, der virkelig var ugyldig, producerede samme linje, tællede intet og afsluttede med nul — inklusive under -strict, som findes, så dette kan afgøre en bygge. Toogfyrre af specifikationens egne samlinger blev oversprunget.
Bundles valideres nu indgang for indgang, med tre resultater holdt adskilt: en indgang, der er forkert, fejler og navngiver feltet, en indgang af en type, som denne build ikke kan læse, tælles som sprunget over og rapporteres, og en bundle, der ikke indeholder nogen ressourcekroppe, er ingen af delene. Det samme korpus gik fra 2.100 ressourcer, der blev kontrolleret, til 13.723.
14.7.2 HL7 v2, HAPI-testkorpusset
Meddelelsesfikserne fra HAPI, den reference Java HL7 v2-implementering — bevidst besværligt materiale, herunder uuencoded payload, escaped delimitere og gentagne grupper.
59 meddelelser, 59 parsede, intet afvist. Syv meddelelsestyper i et korpus, som ethvert enkelt system ville beskrive som én ting, hvilket er pointen med perfuse profile, der eksisterer for at gøre.
14.7.3 Hvad der ikke er kørt
DICOM mod en offentlig overensstemmelsessæt og X12 mod en offentliggjort korpus. Ingen af delene er blevet gjort, og ingen af delene bør sluttes af de to ovenstående.
15 Migration fra Mirth
To ting er nødvendige for at erstatte en fungerende motor: kanalerne skal komme over, og nogen skal kunne vise, at erstatningen producerer det samme output. Perfuse gør det første ved at importere Mirths egne eksporteringer, og det andet ved at sammenligne de to motorer på din egen trafik.
Alt i dette kapitel gælder ligeledes for Open Integration Engine og BridgeLink. Mirth Connect ophørte med at være open source ved 4.6 i marts 2025; OIE (vært af Eclipse Foundation) og BridgeLink (Innovar Healthcare) er forgreningerne, der fortsætter den open-source-linje, og begge skriver de samme eksportformater. Importøren er testet mod alle tre nedenfor.
15.1 Import af kanaler
Perfuse læser hver eksport, disse motorer skriver:
| Eksportér | Fra Administrator | Hvad der kommer over |
|---|---|---|
| En kanal | Eksportér Kanal | Kanalen |
| En kanalgruppe | Eksportér Gruppe | Hver kanal i den, hver med behold af gruppen |
| Kode-skabeloner | Eksportér Kode-skabeloner | Hver bibliotek som én script-fil |
| En server-sikkerhedskopi | Backup Konfiguration, eller GET /api/server/configuration | Alt ovenfor på én gang |
Peg perfuse translate på noget af det, eller slip en på Administrer → Migrer:
perfuse translate -o ./channels server-backup.xml
En kode skabelonbibliotek bliver lib/<library>.js ved siden af kanalerne, og hver kanal, som Mirth havde biblioteket aktiveret for, får scripts.include: [lib/<library>.js] — så en transformer, der kalder en sidefunktion som f.eks. formatMRN(), stadig kan finde den. En kanal, som biblioteket ikke var aktiveret for, inkluderer det ikke, fordi dets scripts ikke kunne se det i Mirth. Drag-and-drop-udklips er udeladt: Mirth limede dem kun ind i et trin manuelt, så de ikke er kode, der kører på egen hånd. I browseren gemmer import af en kanal først de biblioteker, den inkluderer.
En Channel Writer navner kanalen, den leverer til, ved id. I en gruppe eller en backup er målet i samme dokument, så det bliver en channel destination, der navner denne kanal; fra en enkelt-kanal-eksport rapporteres det til dig at udfylde. Server-wide globale scripts har ingen Perfuse-mæssig pendant og rapporteres i stedet for at blive droppet.
Rapporten siger, pr. kanal, om den blev oversat ren, oversat med advarsler eller ikke kunne læses.
Overskriften er en brøk med dens nævner — "37 af 40 klar" — fordi "37 klar" fortæller dig intet om, hvad du stadig har at gøre.
En kanal, der ikke kan læses, er et andet problem end en, der ikke kan oversættes. Førstnævnte betyder, at XML selv ikke blev parsed og er normalt en afkortet eller delvis eksport; sidstnævnte betyder, at kanalen indholder noget uden en Perfuse-ækvivalent. Importen adskiller dem.
15.2 Hvad der oversættes og hvad der kræver en beslutning
Kilder, destinationer, filtre og de almindelige transformertrin oversættes direkte. Forbindelserne, der oversættes: TCP/MLLP (og rå TCP med dets rammer), HTTP, fil, database, JavaScript, DICOM, webtjeneste (SOAP), SMTP og kanal-forfatter/læser. JMS og dokument-forfatteren oversættes ikke og rapporteres som blokeringsfaktorer.
Et Mapper-trin, der angiver en variabel, placerer den i kortet over dens navngivne omfang — channelMap som standard — præcis som Mirth gør, så senere trin kan læse den med $('name') og finde den.
JavaScript-transformatorer gør det ikke generelt. Mirth-kanaler indeholder ofte betydelig kode i en transformer, og der er ingen automatisk konvertering fra arbitrær JavaScript til deklarative trin. Importøren rapporterer dem i stedet for at forsøge en oversættelse, der måske er subtilt forkert: en fejloversat transformer er værre end en, der er markeret for en menneskelig, fordi den vil køre.
Hvor et script virkelig skal forblive et script, kan Perfuse køre det — se scripts-nøglen i kanalreferencen — til en pris for trin-niveau-sporingen beskrevet i fejlfinding.
15.3 Hvad importøren er testet imod
Fem motorer, hver med sin egen dokumentation: Mirth 4.5.2, OIE 4.5.2, 4.6.0 og 4.7.0, og BridgeLink 26.9.0. scripts/mirth-engine-corpus.sh kompilerer et lille program mod hver motors egne jar-filer og har sin egen serialiser skrive tre almindelige kanaler — en MLLP-feed med en mapper, et script, der kalder en kodebibliotek og en filter; en HTTP-feed ind i en database; en fil-polling ud over MLLP — plus biblioteket og en kanalgruppe. Det indlæser dem i den kørende motor og downloader motorens egen serverbackup. Resultaterne er committet under internal/mirth/testdata/engines/, og testssuitten holder importøren til hver af dem på hver build: hver backup læses, oversættes, indlæses, og ADT-kanalen køres med to beskeder for at kontrollere, at biblioteket fylder rekordnumre og filteret dropper resultatet.
Perfuses egne eksport går den modsatte vej — Perfuse-kanaler importeret til hver kørende motor og kontrolleret, at motoren ikke gemmer dem som ugyldige. Alle fem accepterer hver transport, som Perfuse eksporterer. Open Integration Engine 4.7.0 tilføjede to HTTP-indstillinger uden nogen tilsvarende her: en HTTP-afsender bundet til en valgt lokal adresse rapporteres som en advarsel, og en HTTP-lytter-anmodning om headergrænse kun, når den er over 1 MB, som Perfuse accepterer.
Den første kørsel mod denne samling fandt fire fejl, der alle er blevet fikset: oversætteren afviste HTTP- og filkilder som "kun MLLP er understøttet" lang tid efter, at Perfuse havde begge; den læste en HTTP-afsenders adresse fra et felt, som ingen af motorerne skriver; den oversatte Mirths socket-bufferstørrelse som en 64 KB-begrænsning for meddelelser; og en Mappers variabel blev en JavaScript-global, som $('mrn') aldrig så, så biblioteket udfyldte en tom streng.
The single-channel fixture that started this was also exported by Mirth 4.5.2, authored by Mirth itself rather than written here. That distinction earned its place: the only fixture in this repository used to be hand-written, and a real Mirth will not load it — the API accepts the POST and then stores the channel as This channel is invalid. Verify all required extensions are loaded correctly, with every destination connector discarded.
At skrive en hånd i hånd var aldrig gået, og årsagen er værd at kende, hvis du producerer eksport af din egen. Mirths serialisering ignorerer elementer, den ikke genkender, så et forkert elementnavn giver ingen fejl overhovedet — connectoren er bare ikke der herefter. Der er intet at læse og intet at korrigere imod.
scripts/mirth-author-channel.sh bygger en kanal ved hjælp af Mirths egne modelklasser og sin egen serialisering, derefter poster den til en kørende server og fejler, hvis serveren afviser den. Perfuses importør læser resultatet: navn, kilde-transport og destinationer overlever alle.
15.4 At bevise, at det matcher
Dette er den del, der afgør, om en migration sker, og det kræver beviser i stedet for tillid.
Perfuse sammenligner sin egen output med den gamle motors, meddelelse for meddelelse, på din trafik. Hvad den behøver, er par: meddelelsen, som den ankom, og meddelelsen, den gamle motor producerede fra den. Begge er i Mirths egen meddelelse-lager og kan eksporteres fra dens meddelelse-browser.
15.4.1 Fire tal, ikke en beståelsesprocent
| Resultat | Betydning |
|---|---|
| Identisk | Byte for byte det samme. |
| Kosmetisk forskel | Forskellen ligger i måder, der ikke bærer nogen information — efterfølgende tomme felter, en slut-terminator. |
| Forskel | Et felts værdi er forskellig. |
| Kunne ikke køre | Perfuse kunne ikke behandle meddelelsen overhovedet. |
De er fire tal, fordi de betyder fire forskellige ting, og at kombinere dem skjuler de, der kræver en beslutning.
Identisk betyder byte for byte, ikke ækvivalent. En svagere test ville lade forskelle i segmentorden eller efterfølgende separatorer glide igennem, og det er netop, hvad et krævende downstream-system afviser.
Kosmetiske forskelle tælles separat i stedet for at blive kombineret med den gode kolonne. De bærer virkelig ingen information, så at behandle dem som fejl ville begrave virkelige fund under tusinder af intet — men de er ikke identiske heller, og en modtager, der udfører sin egen strenge parsing, kan være uenig.
"Kunne ikke køre" er separat fra "forskel", fordi det ofte er et konfigurationsgap, som importøren ikke kunne udfylde, og ikke en afbildningsbeslutning. Hvis alt er i den kolonne, siger dommen det og beder dig om at se på konfigurationen, før du læser noget andet.
15.4.2 Forskelle er grupperet efter felt
En kørsel over 50.000 meddelelser, der rapporterer 4.000 forskelle, har fortalt dig intet, du kan handle på. Den samme kørsel, der rapporterer, at PID-8 forskelligt i hver meddelelse, fordi den gamle motor skrev Male, hvor Perfuse skriver M, har fortalt dig præcis én ting at beslutte.
Så hver fund er et felt med en tælling, og det siger, om forskellen er systematisk — samme værdipar hver gang — eller om feltets indhold forskelligt.
Denne distinktion er det mest nyttige i rapporten. Et enkelt værdipar på tværs af 4.000 meddelelser er en enkelt afbildningsbeslutning. 4.000 forskellige par er indhold, der forskelligt, og det er et andet og meget værre problem, og de to må ikke lyde ens.
Fund er sorteret efter, hvor mange meddelelser de påvirker, så den største enkeltårsag er først.
15.4.3 Dommen afrunder ikke
Den giver præcise tællinger: 49.993 af 50.000, ikke "over 99%". De syv er hele pointen med at køre det.
Det er skrevet, så det kan citeres i en ændringsanmodning, fordi det er der, nummeret ender.
15.5 En foreslået sekvens
- Importér kanalerne og løs eventuelle problemer, der rapporteres som ulæselige.
- Gennemgå advarslerne for hver kanal. De fleste vil være script.
- Eksporter et par tusinde meddelelsespar fra Mirth for den travleste kanal og kørende sammenligningen.
- Arbejd igennem resultaterne. Systematiske fejl er én beslutning hver.
- Kør igen, indtil de eneste forskelle er dem, du har besluttet er korrekte.
- Kør Perfuse i skygge sammen med Mirth på live-trafik, levering til ingen steder, og sammenlign igen over en periode, der omfatter en weekend og en månedsslutning.
- Skift en kanal, ikke alle sammen.
15.6 Det, der kun køre på én leverandørs software
Migrations-skærmen besvarer et andet spørgsmål, og det er værd at spørge, før du har nogen mening om Perfuse: hvor meget af din integrationslogik kan kun køre på den software, du har.
Hver kanal får en Portabilitets-dom, fra den samme scan, der producerer migrationsnoter. Den køre mod en kanal-eksport, så den har brug for intet installeret og ændrer intet.
15.6.1 Forskellen er hele pointen
De fleste Java i Mirth-script er ikke låst fast. SimpleDateFormat, HashMap, Apache Commons — alt sammen arbejder rundt om en JavaScript-motor fra 2009, alt sammen almindeligt, alt sammen med direkte ekvivalenter. En kanal med tre hundrede af disse referencer er fuldt portabel, og et værktøj, der rapporterede "300 Java-referencer, du er fanget" ville lyve for dig.
Låst fast er specifikt de opkald, der har brug for leverandørens egen server: com.mirth.connect.* og leverandørens jars. Fem af dem, og du er fast. Fem hundrede af den anden type, og du er fri.
Så dommen starter med det tal, der betyder noget, og siger i samme sætning, at det større tal ikke er det. Hvor der er leverandør-opkald, er de opført ved navn — en tælling er en påstand, og en liste er noget, din egen ingeniør kan gå og kontrollere.
En tredje kategori holdes adskilt: en funktion, der findes, men ikke fra et script. At starte en kanal fra JavaScript har ingen ekvivalent her, og der er et API-endpoint, der gør nøjagtig det samme. At kalde det låst fast ville overdrage fundet.
15.6.2 Java-opkald, der køre uændret
De fleste af disse Java-klasser køres, som de er skrevet. Perfuse har ingen Java-runtime, så disse er JavaScript-klasser med samme navne og metoder, nok til den måde, kanal-skripter bruger dem på; importPackage(java.util) og importClass(...) bringer dem ind i omfang med deres korte navne, som i Rhino (JavaScript's egen Date, Map, Set, Math, String og Boolean erstattes aldrig: Java-udgaverne er stadig der med fuldt navn). Migration-rapporten tæller hver af disse opkald som allerede understøttet.
| Pakke | Klasser |
|---|---|
java.util | ArrayList, LinkedList, Vector, List, Collection, HashMap, LinkedHashMap, Hashtable, TreeMap, Properties, HashSet, LinkedHashSet, TreeSet, Arrays, Collections, Date, Calendar, GregorianCalendar, UUID, Base64, regex.Pattern (med Matcher), concurrent.ConcurrentHashMap |
java.lang | String, StringBuilder, StringBuffer, Integer, Long, Short, Byte, Double, Float, Boolean, Math, System (tid og linjeseparator kun) |
java.text, java.math, java.net, java.nio | SimpleDateFormat og DateFormat (Mirth's mønsterbogstaver), BigDecimal (som en double), URLEncoder, URLDecoder, StandardCharsets |
| Apache Commons | lang3.StringUtils og lang.StringUtils (omkring tres metoder), StringEscapeUtils, codec.binary.Base64 |
De opfører sig som Java, hvor skripter afhænger af det: Integer.parseInt("x") kaster NumberFormatException, String.replaceAll og split tager regulære udtryk, mens replace er bogstavelig, kort over nøgle-strengene efter værdi, TreeMap og TreeSet itererer i orden, og SimpleDateFormat.parse returnerer en dato, som getTime() virker på. En metode, som et skript kalder, og som den tilsvarende mangler, fejler på den linje, og navngiver den; enhver anden Java-klasse fejler ved navn, som før. BigDecimal er en dobbelt her, så den holder ikke Java's præcise decimal-aritmetik: tjek skripter, der bruger den til penge.
15.6.3 Eksterne script rapporteres som ukendte
Et trin, der køre et eksternt scriptfil, henviser til en sti på den gamle server, og filen er ikke i eksporten. Intet kan siges om, hvad den indeholder, så den tælles som ukendt i stedet for antaget enten vej. Hent disse filer, før du konkluderer noget — i begge retninger.
15.6.4 Perfuses egen låst fast, erklæret i samme åndedrag
Dette afsnit ville være uærligt uden det.
Perfuse er Apache 2.0, som er uigenkaldeligt for kode, der allerede er udgivet. Du kan forkere, hvad der eksisterer i dag, og ingen kan tilbagekalde det. Kanaler er YAML-filer, og script er almindeligt JavaScript, så der er ingen proprietær overflade at kalde — Mirth's smag af Java-afhængighed er strukturelt utilgængelig her, hvilket er det eneste sted, en begrænsning virkelig er en funktion.
Hvad det ikke lover: at en fremtidig version forbliver åben, at en værtstjeneste findes til en pris, du kan lide, eller at at migrere væk fra Perfuse koster ingenting. At flytte enhver integrationslag betyder, at du gen-tester hver kanal mod rigtig trafik. Det, du vælger, er, om de artefakter, du bygger, er læselige og portable, og om udgangen afhænger af en licens, en anden person kontrollerer.
15.6.5 Opsætning af trin 6
Afsnittet Skygge starter en sammenligning. Vælg kanalen, der kører, vælg den kandidat, du skal sammenligne med fra listen, og start.
Tre ting om det er værd at vide, før du kan stole på tal
Kandidaten vælges fra en liste, ikke skrevet. En skygge navngiver en kanal-fil, og et navn, der ikke kan løses, gør den *aktive* kanal ugyldig — Perfuse afviser en kanal som helhed, når noget det refererer til er brudt. Så et trykfejl producerer ikke en advarsel, det gør den kørende kanal forsvinde.
Andelen er en procentdel. Lav den kun på en travl feed, og vid, hvad det koster: stikprøver reducerer arbejdet og tilliden i samme proportion, og meddelelsen, der ville have vist forskellen, er den usædvanlige.
Felter, der skal ignoreres, er normalt nødvendige. En kanal, der stæmpler en tidsstempel eller en sekvensnummer, adskiller sig på hver enkelt meddelelse, hvilket rapporterer en forskelsrate på 100% og fortæller dig ingenting. MSH-7 og MSH-10 er det almindelige par.
En sammenligning skrives til kanal-filen, så snart du starter den, og begynder at observere, når kanalen næste gang indlæses — skærmen siger det i stedet for at hævde, at det allerede kører. At stoppe en sammenligning efterlader kandidat-kanalen på plads, fordi kandidaten er det, der skal gå live.
Trin 6 er det, der ikke kan forkortes. De forskelle, der betyder noget, er normalt i trafik, der kun optræder lejlighedsvis — en sjælden udløsende begivenhed, en månedslang batch, en afsender, der opfører sig anderledes ved midnat — og en stikprøve taget over en eftermiddag vil ikke indeholde dem.
15.7 At gå tilbage den anden vej
En kanal kan eksporteres som en Mirth-kanal-fil fra browseren: Kanaler, derefter Til Mirth på den kanal, du ønsker.
Dette eksisterer, fordi indvendingen mod at erstatte en fungerende motor sjældent er, om erstatningen er nogen god. Det er, hvad der sker, hvis beslutningen viser sig at være forkert, og en eksport, der går tilbage den vej, det kom, er det billigste svar på det.
Læs, hvad dialogen fortæller dig, før du tager filen. Mirths format har ingen sted at placere en Perfuse-filter, en transformations-kæde, en kontrakt eller en skygge-sammenligning, så en eksporteret kanal gør mindre end den, det kom fra. Transporterne og deres adresser konverterer; logikken gør det ikke. Hver tab listeves før filen tilbydes, og den samme liste kommer ind i kanalens beskrivelse, så den, der importerer den, ser det også.
En kanal, som Mirth ikke kan udtrykke, afvises i stedet for at blive approksimeret. En S3-destination har ingen Mirth-mæssig pendant, og en kanal, der importerede renligt, mens den leverede et andet sted end bucket, ville være værre end ingen fil overhovedet. Afvisningen navngiver destinationen, der er skyld i fejlen.
Connector-definitionerne er ikke skrevet fra en læsning af Mirths format. scripts/mirth-dump-connector-templates.sh har Mirths egen serialisator producerer standardværdierne for hver connector-klasse, og Perfuse erstatter værdier i disse dokumenter — afviser enhver indstilling, skabelonen ikke allerede indeholder. Dette betyder noget på grund af, hvordan Mirth besvarer en kanal, den ikke kan parse: den afviser ikke importen. Den gemmer en kanal, hvis beskrivelse er blevet erstattet med "Denne kanal er ugyldig. Verificér, at alle nødvendige udvidelser er indlæst korrekt" og hvis destinationer er blevet stille og roligt kasseret. En eksportør, der er kontrolleret mod sin egen output i stedet for mod en server, består hver test, mens den producerer dokumenter, der bliver smidt væk, hvilket er præcis, hvad der skete her, før eksporten blev prøvet mod en kørende Mirth.
Hvad krydser i dag: MLLP og TCP i begge retninger, HTTP i begge retninger, fil-læsning og -skrivning, database-læsning og -skrivning, DICOM i begge retninger, og SMTP, SOAP og JavaScript-destinationer. Hver par er verificeret ved at importere til en rigtig Mirth 4.5.2 og kontrollere, at serveren ikke stille og roligt erstattede kanalen.
16 CMS-0057 for betalere
CMS Interoperability og Prior Authorization slutregel (CMS-0057-F) kræver, at berørte betalere — Medicare Advantage-organisationer, statlige Medicaid- og CHIP-programmer og deres managed care-planer, og QHP-udgivere på de føderale exchanges — skal køre fire FHIR-API'er fra 1. januar 2027, og skal offentliggøre prior autorisations-metrikker på deres offentlige website hvert år fra 2026.
Perfuse tilbyder de fire API'er på sin FHIR-endpoint og konverteringerne, der udfylder dem: afregnede krav som CARIN Blue Button, prior autorisationer som Da Vinci PDex, og de årlige metrikker i layoutet af CMS's egen skabelon. CMS-0057-visningen under Exchange siger, hvilke af de fire denne forekomst kan besvare og hvad hver af dem stadig mangler, og udfører alle tre konverteringer i browseren.
Lægemidler er uden for scope overalt, da de er i regelens prior autorisations-bestemmelser: ingen apotek-krav, ingen formular, og en metrikrække, der navngiver et lægemiddel, afvises i stedet for at blive talt med.
16.1 De fire API'er
| API | Hvor det tjener | Guider | Aktiveret af |
|---|---|---|---|
| Patientadgang | En medlems krav, kliniske data og forhåndsgodkendelser til en app, de vælger | CARIN Blue Button 2.2.0, PDex 2.2.0, US Core, SMART App Launch | -fhir og en SMART-udsteder (-smart-issuer) |
| Lægeadgang | Det samme for en læges tilknyttede medlemmer i bulk | PDex 2.2.0, Da Vinci ATR 2.1.0, Bulk Data | -fhir-payer-apis og -fhir-bulk-export |
| Betaler-til-betaler | En medlems record til en anden betaler, efter at have matchet dem | HRex 1.2.0 $member-match, PDex 2.2.0 | -fhir-payer-apis |
| Forhåndsgodkendelse | Hvad en ordre har brug for, dokumentationen, så anmodningen og beslutningen | Da Vinci CRD, DTR og PAS 2.2.x (2.2.1, 2.2.0, 2.2.1) og 2.1.0, med X12 278-oversættelse | -fhir, skrivbar, og -crd-rules |
Patient Access API har ikke brug for nogen egen operation: det er FHIR-endpointens almindelige læs- og søgefunktion, beskyttet af SMART, med CARIN- og PDex-resourcer i butikken. Søgning efter ExplanationOfBenefit understøtter parametrene CARIN-navne — patient, identifier, type, service-date, billable-period-start, provider, insurer, coverage — og Coverage understøtter subscriber-id, identifier og payor.
16.1.1 To udgaver af guiderne: 2.1.0 og 2.2.x
CMS-0057-F anbefaler CRD, DTR og PAS 2.0.1 og 2.1.0. 2.0.1-udgaverne hviler på US Core 3.1.1, som udløb den 1. januar 2026, så 2.1.0 er den udgave, en EHR bygget for reglen sandsynligvis taler; de nyeste er CRD 2.2.1, DTR 2.2.0 og PAS 2.2.1. Perfuse besvarer begge. Den finder ud af, hvilken en kalder taler, mest specifik først:
- fra anmodningen: CRD's CDS Hooks-udvidelse
davinci-crd.requestedVersion("2.1"), eller versionen på et Da Vinci-profil for en DTR- eller PAS-inputkrav (profile-pas-request-bundle|2.1.0);
2. fra kalderens registrering: davinci_version: "2.1" på en SMART-klient (-smart-clients) eller en CDS-klient (-cds-clients); 3. fra serveren: serve -davinci-version 2.1; standarden er 2.2.
clients:
- issuer: https://ehr.example.org
jwks_url: https://ehr.example.org/.well-known/jwks.json
davinci_version: "2.1"
Hver beslutning er besluttet og gemt i 2.2.x-form og omskrevet til en 2.1.0-kald, som det sendes, så reglerne, gennemgangskøen, X12 278-linket og metric er de samme for begge. Omskrivningen dækker, hvad udgivelserne staver forskelligt: CRD 2.1.0 har ingen indeterminate (Perfuse siger betinget, med årsagen) og ingen kategori på en dækningdetalje; DTR 2.1.0 navngiver pakken PackageBundle og lader QuestionnaireResponse være appens ansvar; PAS 2.1.0's $inquire besvarer med én Bundle, og den mangler reviewer- og transmissions-udvidelser. Den fulde liste og kontrollen mod hver 2.1.0-vejlednings eget eksempler er i conformance/davinci21. En PAS-besked følger -davinci-version, da en abonnement ikke angiver, hvilken udgave ejeren læser.
16.2 Dækning krav og dokumentation: CRD og DTR
Prior Authorization API'er er i praksis tre Da Vinci-vejledninger sammen. CRD fortæller klinikerne, mens ordren stadig er en kladde, om den er dækket, om den kræver forhåndsgodkendelse og hvilken dokumentation, der ønskes. DTR giver EHR'en spørgeskemaet, der indsamler den ønskede dokumentation. PAS indsender anmodningen og returnerer beslutningen. Perfuse betjener alle tre som betaler.
-crd-rules rules.yaml betjener CRD over CDS Hooks på /cds-services: alle seks af CRD's hooks, order-sign, order-select, order-dispatch, appointment-book, encounter-start og encounter-discharge, hver med en prefetch for patientens aktive dækning. De to encounter-hooks prefetcher også encounter og besvarer om encounter selv, matcheret af dets type og servicetype, som appointment-book besvarer om en aftale. Reglerne er betalingspolitikken, der holdes i en fil, fordi de ændrer sig uden software-udgivelser:
payer: Springfield Health Plan
rules:
- description: Home oxygen equipment
codes: [E0424, E0431]
covered: covered # covered, not-covered, conditional
pa: auth-needed # no-auth, auth-needed, satisfied, performpa, conditional
documentation: [clinical]
questionnaire: https://www.springfield-health-plan.example/fhir/Questionnaire/home-oxygen
Hver ordre får en systemActions-opdatering med CRD's dækningsoplysningsextension - som EHR lagrer på ordren og senere sender med i forhåndsgodkendelsen - og et kort, som klinikerne kan læse. En ordre, hvis kode ikke har nogen regel, besvares conditional og antages aldrig at være dækket; en anmodning uden nogen dækning overhovedet får et kort, der siger det. examples/crd/ indeholder en regelfil og et tilsvarende spørgeskema.
En regel kan også medføre resten af, hvad CRD lader en betaler sige:
billing_codes: de koder, der skal faktureres under.details: begrænsninger og omkostninger, såsomallowed-periodellerin-network-copay.contact: hvem man skal ringe til.expiry_days: hvor lang tid svaret er gyldigt.depends_on: koder for andre ordrer, som svaret afhænger af, så EHR spørger igen, hvis de ændres.doc_purpose: formålet med dokumentationen (withclaim,withorder,retain-doc).withpaafvises, fordi CRD 2.2.1's
egen invariant crd-ci-q4 afviser det.
Hvad EHR ikke har forhåndshentet, læser Perfuse fra EHR's fhirServer med den token, der er sendt. Hvis det fejler, er svaret indeterminate med CRD's technical årsag, aldrig en gæt. En dækning, der er udløbet eller ikke er aktiv, besvares not-covered, no-active-coverage.
members: fhir i regelsfilen løser dækningen mod betalerens egne optegnelser i denne servers FHIR-lager (start det med -fhir), de samme optegnelser, som $member-match læser:
- en patient, der ikke er medlem, besvares
no-member-found; - et medlem, hvis dækning ikke matcher, besvares
coverage-not-found; - en forhåndsgodkendelse, der allerede er godkendt der for ydelsen (en ClaimResponse med en
preAuthRef), gør svaretsatisfied,
med det nummer.
Discovery deklarerer davinci-crd.version og en coverage-info konfigurationsindstilling. Når en klient slår indstillingen fra, er svaret .tomt. EHR JWT'er kontrolleres som CDS Hooks definerer dem, med iss, aud, exp, iat og jti og ingen sub, og en gentaget jti afvises.
Opkald autentificerer med den JWT, som EHR signerer for hvert opkald, fra en udsteder, der er navngivet i -cds-clients med dets JWKS URL - som CDS Hooks beskriver det - eller med en Perfuse API-token. Opdagelse er åben, som CDS Hooks kræver.
DTR: indlæs spørgeskemaer i FHIR-endpointet, og POST /fhir/Questionnaire/$questionnaire-package returnerer dem som DTR pakke-bundter, med de CQL-biblioteker, de navngiver. Anmodningen kan navngive spørgeskemaet eller sende ordren og lade dets coverage-information sige, hvilket.
Prøv det: Payers → Claims & auth → Coverage requirements (CRD) sender en ordre til denne servers regler eller til en payers CDS service URL, og viser kortene og dækningsoplysningerne.
16.3 Krav som CARIN Blue Button
perfuse cms0057 carinbb parrer hver krav i en 837 med dens betaling i en 835, efter patientkonto-nummeret, som 835 kræver at echo tilbage, og skriver en FHIR-transaktion for hver: ExplanationOfBenefit med Patient, Coverage, Organisationer og Praktikere, det henviser til.
perfuse cms0057 carinbb -system https://fhir.your-plan.org/identifier -network innetwork \
claims.837 remittance.835
Profilen følger kravet: professionelle krav (837P) bliver C4BB-ExplanationOfBenefit-Professional-NonClinician, og institutionelle krav (837I) indlæggelse eller udskrivning efter regningstypen. Hver post er en PUT med et id, der tages fra kilde-identifikatorerne, så indlæsning af det samme krav to gange opdaterer det i stedet for at lave en anden kopi.
Tre ting er ikke i nogen af X12-filerne, og hver håndteres ved at sige det i stedet for at gætte:
- Identifikationssystemet. CARIN kræver, at medlemmets identifikator navngiver payers namespace.
-systemer påkrævet; der er ingen standard, fordi en standard ville give alle payere, der bruger Perfuse, det samme namespace. - Netværksstatus. Ingen af transaktionerne angiver, om faktureringsudbyderen er i netværket, og det afgør, hvad medlemmet betaler. Uden
-networker fordelingsbetalingens statusotherog konverteringsnoterne hvorfor. - En krav, der ikke nævnes i 835. En CARIN ExplanationOfBenefit er en vurderet krav. Uden 835 er der ingen payers kravnummer, ingen betaling og ingen medlemsskade, så kravet rapporteres som oversprunget og ikke konverteret.
Diagnoser skrives med deres decimalpunkt (J02.9, ikke J029), fordi det er sådan, kode-systemet offentliggør dem, og en terminologiserver, der bedes om den anden staving, siger, at den ikke findes. En afhængigs medlem-identifikator er abonnentens, som 837 medfører, og noterne siger det. En NPI, hvis kontrolléciffer er forkert, rapporteres, før US Core afviser det.
16.4 Forhåndsgodkendelser som PDex
perfuse cms0057 priorauth konverterer en Da Vinci PAS ClaimResponse - eller PAS-svarspakken, der transporterer en - til en PDex prior autorisation ExplanationOfBenefit, som er hvad de tre data-API'er serverer.
perfuse cms0057 priorauth pas-response.json pas-claim.json
PAS-kravet er valgfrit og næsten altid nødvendigt. En ExplanationOfBenefit skal angive, hvilket dækning beslutningen blev truffet under, og kun anmodningen indeholder det; uden det stopper konverteringen og siger det. Gennemgangsaktionen - godkendt, afvist, udsat, med dens autorisationsnummer og årsag - flytter fra PAS-udvidelsen til PDex's, og X12-service-typen beholder sin kode under URI'en, som PDex binder den til.
16.5 Provider Access og Payer-to-Payer API'er
Med -fhir-payer-apis besvarer FHIR-endpointen tre flere operationer:
POST /fhir/Patient/$member-match— HRex-medlemssammenligning. Dækningens identifikatorer indsnævres til få kandidater, og efternavn og fødselsdato skal derefter være enige; et fornavn sammenlignes med initial, og køn kun når begge sider angiver det. Mere end en overlevende kandidat er ikke en match, og svaret er 422 i stedet for et gæt, fordi et gæt afslører en fremmeds krav. En aktiv samtykke, der tillader afsløring, er påkrævet, da Payer-to-Payer-API'en er opt-in for medlemmet;-fhir-member-match-without-consentslår det fra for testformål.GETellerPOST /fhir/Group/{id}/$davinci-data-export— Da Vincis bulk-eksport af en Groups nuværende medlemmer.exportTypevælger publikum:hl7.fhir.us.davinci-pdex#provider-downloadeller#provider-deltatil Provider Access,#payertopayertil Payer-to-Payer.GET /fhir/Group/{id}/$export— standard Bulk Data-gruppe-eksport, behandlet som Provider Access.
Eksporterne anvender regelens eksklusioner på vej ud. Krav taber betaling og hver kostdelings- og refusionsbeløb, og beholder tjenester, koder, datoer og leverandører; CARIN-profilen fjernes fra meta.profile, fordi ressourcen ikke længere opfylder den. Payer-to-Payer udelader også afviste prior-autoriseringer. Medlemmer, der holder en aktiv PDex Provider Access-opt-out-samtykke, udelades fra en provider-eksport, og loggen optegner, hvor mange. patient-parametren kan kun indsnævres til medlemmer af Gruppen; navngivning af andre personer afvisses.
Adgang til en Groups eksport afgøres af endpointets autentificering. SMART-omfang siger, hvilke typer ressourcer en token må læse, ikke hvilken Gruppe, så hver provider har brug for en token, der kan nå kun sin egen tilskrivelsesliste. En API-token kan begrænses til Grupper, når den oprettes — perfuse token create -label riverside-provider-access -fhir-groups riverside-attributed, eller feltet Begræns til FHIR-Grupper under Brugere → Maskinlegitimationer — og på FHIR-endpointet kan den derefter læse disse Grupper, køre $davinci-data-export eller $export på dem og hente, hvad eksporten producerede, og intet andet. En anden providers Gruppe returnerer ikke-found i stedet for forbudt, så en token lærer ikke, hvilke andre tilskrivelseslister findes; hver anden anmodning, medlemssammenligning og almindelig søgning inklusive, afvises. Begrænsningen gælder for API-token; en token fra en SMART-udsteder bærer ingen Gruppebegrænsning. Når SMART er konfigureret også, afvises API-token, medmindre Indstillinger → FHIR → Acceptér Perfuse API-token ved siden af SMART-token er slået til (se Sikkerhed, *Hvem kan ringe til FHIR-endpointet*); en providers Gruppebegrænsede token har brug for det.
16.6 En provider-katalog: Plan-Net
CMS-0057 beder også payere om en provider-katalog, og FHIR-endpointet serverer en til Da Vinci Plan-Net 1.1.0 uden mulighed for at slå den til: indlæs Practitioners, PractitionerRoles, Organizations, OrganizationAffiliations, Locations, HealthcareServices, InsurancePlans og Endpoints, og medlemmers apps kan søge i dem. Hver Plan-Net-søgeparameter er indekseret - en rolles netværk og service, en plans dækningområde, en tilknytnings deltagende organisation, en organisations partof - sammen med de inklusioner og omvendte kæder (_has), vejledningens forespørgsler bruger, og CapabilityStatement listen over Plan-Net-profilerne.
Infernos Plan-Net-suite passerer 199 tests. De 10, den fejler, er fremadrettet kæder, hvor kit'taget sin søgeværdi fra den første Organisation, det har set, i stedet for en, de søgte ressourcer refererer til; det rapporteres til kit'tet (dets problem 34), og tjeneren returnerer disse forespørgsler korrekt, når den får en værdi, dataene indeholder.
16.7 Prior-autorisering-målinger
perfuse cms0057 metrics læser en CSV over beslutninger, der er eksporteret fra udnyttelsesstyringssystemet, og producerer den offentlige side, CMS kræver, i layoutet af dets *Prior Authorization Metrics Reporting — Overview and Template*.
perfuse cms0057 metrics -year 2025 -org "Springfield Health Plan" -services services.csv \
decisions.csv > prior-authorization-metrics-2025.html
Kolonner findes ved overskrift: priority, received, decided og decision er påkrævet, og request_id, line_of_business, extended, appealed, appeal_decision, service_code og service_description læses, når de er til stede. En anmodning tilhører året, den blev besluttet i; en, der stadig er pendende, er opført som ekskluderet, aldrig talt. Hver række, der ikke kan læses, rapporteres med dens linjenummer.
Arithmetikken følger skabelonen: for standard- og hurtige anmodninger adskilt, andelen godkendt og afvist, godkendt og afvist inden for beslutningstidsrammen, godkendt efter, at gennemgangstiden blev forlænget, og godkendt efter appel — ud af appeller, ikke ud af anmodninger — med gennemsnit og median tid fra modtagelse til beslutning. En median under en dag skrives i timer i stedet for afrundet til "0 dage", som skabelonen udtrykkeligt beder om. Delvist godkendte anmodninger tælles som godkendt, da skabelonen ikke har en kategori for dem, og siden siger, hvor mange der var. Målinger rapporteres pr. forretningsområde, som er niveauet, CMS kræver.
Siden er selvstændig — ingen script, ingen ekstern stylesheet eller font — fordi den publiceres på en offentlig website af den, der vedligeholder den, og alt, der indlæses fra andre steder, er noget, der kan fejle eller spore en besøgende. -format csv og -format json giver de samme tal for andre formål. Uden -services bærer siden en meddelelse om, at listen over elementer og tjenester, der kræver forhåndsgodkendelse, mangler, fordi CMS kræver det på samme side.
16.8 Lægemidler: formulariet, Real-Time Prescription Benefit og elektronisk forhåndsgodkendelse
CMS-0062-P (forslag 14. april 2026) ville bringe lægemidler ind i forhåndsgodkendelse: berørte payere ville støtte NCPDP SCRIPT elektronisk forhåndsgodkendelse, NCPDP Formulary & Benefit-standard og NCPDP Real-Time Prescription Benefit fra 1. oktober 2027, beslutte lægemiddel-anmodninger inden for 24 timer (hastet) og 72 timer (standard), give en specifik årsag for hver afvisning, og rapportere lægemiddel-målinger fra 2028. Medicare Part D kræver allerede SCRIPT ePA. En fil, formulariet, besvarer alt dette:
perfuse serve -fhir -pas -crd-rules payer-rules.yaml -formulary formulary.yaml
examples/formulary/formulary.yaml er et eksempel, hvis lægemidler er virkelige RxNorm-begreber med NDC'er RxNorm lister for dem (kontrolleret mod RxNav). En fil navngiver payeren, dets planer (hver med det formularium, det bruger, dets gruppe-id'er og dets omkostningsandele efter apotek fordele og niveau) og dets formularier. Hvert lægemiddel er et RxNorm SCD eller SBD med dets RxNorm-gruppe (den SCDG eller SBDG, Drug Formulary API kræver), dets NDC'er, et niveau og dets begrænsninger: prior_authorization, step_therapy, quantity_limit (en mængde i en rullende antal dage, og en daglig maksimum), not_covered, alternatives (RxNorm-koder, mest foretrukne først), notes, og questionnaire, den kanoniske URL for FHIR-spørgeskemaet en forhåndsgodkendelse beder om. cost_30_day er plans omkostning for en 30-dages forsyning, som en coinsurance er en procentdel af; uden det er en coinsurance citeret som en procent, aldrig som en opfundet mængde. Hele filen kontrolleres, når den indlæses, hver problem liste på én gang. En medlem findes af filens members-liste, via gruppe, eller gennem FHIR-lageret: en Coverage, hvis subscriberId er medlem-id'et og hvis class af type plan er plans id. Payers › Lægemidler viser formulariet, priser et lægemiddel og kører en forhåndsgodkendelse fra ende til anden.
16.8.1 Da Vinci US Drug Formulary API
Publiceret på /formulary/fhir som Da Vinci US Drug Formulary 2.1.0: hver plan er en PayerInsurancePlan, hver formular er en Formulary (begge InsurancePlan), hver medicin er en FormularyDrug (MedicationKnowledge) og hver post er en FormularyItem (Basic). Guidens søgninger betjenes (Basic?code=formulary-item&formulary=...&drug-tier=...&pharmacy-benefit-type=...&period=..., subject:MedicationKnowledge.code, InsurancePlan?formulary-coverage=..., coverage-type, MedicationKnowledge?code=...&doseform=...) med _include=Basic:subject, Basic:formulary og InsurancePlan:formulary-coverage. Det er offentligt, uden legitimationsnål, som CMS kræver af en payers formular: det betjenes fra en butik af sin egen, i hukommelsen, der indeholder formulariet og intet andet, så åbent kan ikke nå en patients journal. Det er kun læsbaar. En ekskluderet medicin offentliggøres ikke, da API'en listar, hvad et formular dækker; RTPB og ePA svarer stadig, at det ikke er dækket. Verificeret med HL7 FHIR-valideringsværktøjet mod guidens 2.1.0-pakke med terminologi kontrolleret: hver ressource genereret fra eksemplet har ingen fejl.
16.8.2 Real-Time Prescription Benefit
POST /ncpdp/rtpb tager en RTPBRequest (NCPDP RTPB v13) med en API-nøgle for operatørens rolle og svarer med en RTPBResponse fra formulariet: dækningens status, formulariets status, medlemmets estimerede andel og planens, og dækningens begrænsninger, med op til fem dækkede alternativer prissat på samme måde. Begrænsningskoder og den status, hver af dem er knyttet til, følger NCPDP's offentlige RTPB-implementeringsanbefalinger: 75 kræver forudgående autorisation, 608 trinvis terapi, 76 planlægningsgrænser overskredet, 7X dages forsyning over planlægningsgrænsen (en medicin, der ikke er tilgængelig via post, fx), 70 ikke dækket, alle *dækket med begrænsninger* (CR) undtagen 70 (NC). En medlem med en godkendt forudgående autorisation på fil får CC og AB8, som Surescripts-guiden beder om, så prescriberen ikke bliver bedt om at spørge igen. En anmodning, der ikke kan prissættes, er NotProcessed med en NCPDP-afvisningskode: 52 for en medlem, der ikke er fundet, E7 og 19 for en manglende mængde eller dages forsyning. Apoteksgodtægten læses fra anmodningen: en fyldning over 34 dage er en tre-måneders forsyning, og apotekstype M er postordre.
16.8.3 Elektronisk forhåndsgodkendelse (NCPDP SCRIPT)
POST /ncpdp/script tager PAInitiationRequest, PARequest, PAAppealRequest og PACancelRequest med en API-nøgle for operatørens rolle og svarer på hver af dem med dens svar:
| Anmodning | Svar |
|---|---|
PAInitiationRequest | Closed, når ingen er nødvendig: CC ingen forhåndsgodkendelse påkrævet, FN inden for mængdebegrænsningen, FM ikke dækket eller ikke på formulariet, FQ en godkendelse på fil, CD ingen sådan medlem, CG en allerede i gang. Ellers Open, med en sag-id og spørgeskemaet. |
PARequest | Afgjort som en PAS-anmodning: Approved med godkendelsesnummer og periode, Denied med grund, eller Open under gennemgang. |
PAAppealRequest | En afvist sag afgjort igen, på grund af PANote (en appel uden en er bedt om den). |
PACancelRequest | Approved, mens sagen er åben eller under gennemgang, og PAS-anmodningen annulleres; Denied en gang den er afgjort. |
Spørgsmålsættet er medicinens FHIR-spørgeskema fra FHIR-butikken, det samme, som DTR udfylder: en boolesk værdi bliver et ja/nej-valg, et valg et valg, et tal et numerisk tal, en dato en dato, og alt andet frit tekst; grupper er fladet i rækkefølge, og enableWhen medtages ikke, da SCRIPT afgrener efter valg og ikke efter betingelse. En medicin uden spørgeskema bliver bedt om tre frit-tekst-spørgsmål: diagnosen, hvad der er prøvet, og hvorfor denne medicin. En PARequest bliver en Da Vinci PAS-anmodning: en Claim for medicinen (RxNorm og NDC), den MedicationRequest, der bedes om, patienten, prescriberen, payeren og dækningen, og svarene som en QuestionnaireResponse, med eventuelle vedhæftninger som DocumentReferences. Derefter besluttes det, som hver forudgående autorisation på denne server er: regelfilen, en beslutningstjeneste (-pas-decider-url), eller reviewer-køen, hvor det markeres Medicin og holdes til medicin-tidsrammerne. En beslutningstjeneste ser en medicinanmodning præcis, som den ser en anmodning fra en EHR's PAS-klient. Vi anbefaler Vaglio, BioDreams kilde-tilgængelige (PolyForm Shield) beslutningsmotor, der har medicinpolitikker med trinvis terapi; en payers egen motor kan indsættes gennem samme -pas-decider-url, og ingen er nødvendig for regelfilen og reviewerne til at beslutte.
En beslutning, der er truffet efter anmodningen er besvaret (en reviewers, en appel), sendes til prescriberen som et uanmodet PAResponse eller PAAppealResponse, routeret til kanalen navngivet af -epa-reply-channel, der leverer det til netværket. Uden en, eller når leveringen mislykkes, siger sagen, at prescriberen ikke er blevet underrettet, og skærmen sender det igen.
Payers › Medicin › Forudgående autorisation sender beskederne, en prescribers system ville sende til denne servers egen endpoint (start, besvar spørgsmålene, se beslutningen), listar hver sag med, hvad prescriberen er blevet sagt, og viser medicintallene, CMS-0062-P foreslår: anmodninger godkendt, afvist og ventende, appelleret og godkendt eller afvist efter appel, gennemsnitlig og median timer fra anmodning til beslutning, og hvor mange blev besluttet for sent. Medicin til medicinfordele, der er anmodet gennem PAS (en HCPCS J-kode med en MedicationRequest, eller en vare kodet i RxNorm eller NDC), medtages i PAS-tallene.
Hvad dette hviler på, udtrykt på en enkel måde. NCPDP's skemaer og implementeringsvejledninger er licenseret. Elementnavnene og rækkefølgen her følger de offentlige Surescripts ePA- og RTPB-vejledninger og deres eksempler, og NCPDP's offentlige RTPB-anbefalinger. To elementer, det offentlige materiale aldrig viser, er skrevet til SCRIPT-mønsteret, der bruges andre steder, og skal kontrolleres mod en licenseret kopi, før certificering: Closed/ReasonCode og Denied/DenialReason. Ingen besked er blevet kontrolleret mod NCPDP's XSD eller et netværks certificering. NCPDP Formulary & Benefit-filen produceres ikke: dens fulde layout er i NCPDP's licenserede vejledning, og en delvis fil vil blive afvist af netværket, der indlæser den.
16.9 Hvad der er kontrolleret, og mod hvad
CARIN- og PDex-udgangspunkterne er valideret med den officielle HL7 FHIR-validerer, indlæst med de offentliggjorte pakker (hl7.fhir.us.carin-bb#2.2.0, hl7.fhir.us.davinci-pdex#2.2.0): professionel, indlagt og ambulant patient, og to PAS-beslutninger, uden fejl. PDex-indgangspunkterne var PAS-vejledningens egne eksempler og ikke former, der er skrevet her for at være enige med konverteren. Validereren fandt fem fejl ved den første kørsel - herunder, at CARIN kræver profilversionen i meta.profile og claim-type kodsystemversion på institutionelle krav - og hver af dem er rettet og dækket af en test.
Opbygningen af dette fandt en fejl, der er ældre end dette: FHIR-lageret droppede hver enkelt element, som dets interne model ikke erklærede, så en ExplanationOfBenefit mistede sine elementer, diagnoser, vurdering og betaling undervejs. Lageret gemmer nu, hvad som helst en ressource medfører, og en test indlæser en CARIN-krav gennem serveren og læser den tilbage hele.
CRD's output - den opdaterede ordre, og CDS Hooks-svaret mod CRD's egen logiske model - og DTR's pakkeoutput validerer i den officielle HL7-valideringsværktøj mod CRD 2.2.1 og DTR 2.2.0 med ingen fejl.
DTR her er betalingspartens side af 2.2.0. $questionnaire-package tager de navngivne spørgeskemaer, de CRD-navne på en ordre eller dækningens påstand om CRD, der returneres (context, mens samme proces betjener CRD), og returnerer hver som en pakke-bundle med et QuestionnaireResponse til at udfylde, Bibliotekerne det CQL behov og deres afhængigheder. Værdi-sæt, deres svar bruger, rejser i pakken, når de indlæses (PUT /fhir/ValueSet/{id}), og $expand lister deres koder. $log-questionnaire-errors skriver, hvad en DTR-app rapporterer til serverloggen.
Adaptive spørgeskemaer: skriv hele spørgeskemaet én gang, med SDC's questionnaireAdaptive-udvidelse og enableWhen på de spørgsmål, der kun gælder nogle gange. Pakken giver appen en tom skal, og hver $next-question-opkald tilføjer det næste spørgsmål, som er relevant for svarene indtil videre, indtil der ikke er flere spørgsmål at stille, og svaret er markeret som fuldført. Rækkefølgen og afgreningen er betalerens egne regler; spørgsmål, der ikke gælder, vises aldrig.
Logge ind som klient: DTR- og PAS-klienter når betaleren med SMART Backend Services - en signeret JWT udvekslet for en token på betalerens autorisationsserver. Peger Perfuse på den server med -smart-issuer (og -smart-jwks, hvis dens adresse ikke kan løses fra Perfuse), og passer -smart-backend-services, så opdagelsesdokumentet siger det. Inferno DTR-suiten passerer denne vej med Keycloak som autorisationsserver.
Perfuse kan selv være en autorisationsserver: serve -fhir -smart-clients clients.yaml udsteder Backend Services-token til /auth/token til de klienter, der er opført, hver med de offentlige nøgler, den signerer sine påstande med, og de systemomfang, der kan blive tildelt, og FHIR-endpointen accepterer dem. Der er ikke brug for en separat identitetsserver til en betalers maskine-til-maskine-klienter.
Med -smart-users users.yaml også, logger medlemmer og kliniske medarbejdere ind for at godkende apps, som Patient Access API behøver: appen sender personen til /auth/authorize, de logger ind, en kliniker vælger patienten, og begge ser, hvad appen beder om, og kan fjerne noget af det. Et medlem får kun sin egen post, uanset hvad appen beder om. Hver person i filen navngiver den FHIR-resurs, han eller hun er, Patient/… eller Practitioner/…, og en adgangskodehash fra perfuse smart hash; adgangskoden selv bliver aldrig skrevet ned.
Personer kan logge ind på organisationens egen identitetsudbyder i stedet: -smart-oidc oidc.yaml navngiver den (udsteder, klient-id og hvor hemmeligheden er), og log-in-siden tilbyder "Log ind med" den ved siden af adgangskoden. Hver person er knyttet til udbyderens emne, oidc_subject i brugerfilen, så filen stadig beslutter, hvem der må godkende apps og hvilke FHIR-resurse de er; en konto knyttet til ingen er afvist. Koder, opfriskningstokens og annulleringer gemmes i databasen, så en genstart logger ingen ud.
Brugere → SMART-apps i konsollen viser de registrerede apps og personer og tilføjer, redigerer og fjerner dem. Hver gemt ændring kontrolleres, som filerne er ved start, skrives til dem og bruges med det samme. En fortrolig app gemt uden hemmelighed får en, vises én gang; en adgangskode indstilles der og vises aldrig igen. Fjernelse af en app eller en person standsner de adgangstoken, der allerede er udstedt til den eller tildelt af dem, med det samme, ikke når de udløber, og deres opfriskningstoken med dem.
Omfang kan være detaljerede, som SMART App Launch 2 og US Core definerer dem: patient/Observation.rs?category=laboratory læser kun de Observationer, som søgningen ville finde. En tilladelse, der er filtreret for en type, anvender dens filter til hver søgning og hver læsning af den type; en ufiltroet tilladelse for typen eller for * ophæver det. Et filter, der ikke kan læses, giver intet i stedet for alt.
16.10 Afgørelse af forhåndsautorisationer: PAS
serve -fhir -pas -crd-rules rules.yaml besvarer Da Vinci PAS 2.2.1 på POST /fhir/Claim/$submit og POST /fhir/Claim/$inquire. Afgørelserne kommer fra den samme regelfil som CRD's svar, så rækkefølgen, en kliniker bliver bedt om at godkende, bestemmes af reglen, der sagde det:
- description: Physical therapy
codes: ["PT"] # matched on the item's productOrService, then the code of the order it requests
system: https://codesystem.x12.org/005010/1365
covered: covered
pa: auth-needed
pa_decision: approve # approve, deny or pend; empty: not-covered is denied, no-auth approved, the rest pended
details:
- {code: allowed-quantity, value: "6"} # asked for more, it is certified for six (A6, with the authorised detail)
- description: MRI
codes: ["62"]
pa_decision: approve
pa_alternative: {system: "https://codesystem.x12.org/005010/1365", code: "4"} # approved as an X-ray instead (an added item)
- description: Surgery
codes: ["2"]
pa: auth-needed # pended for a reviewer, asking for:
questionnaire: https://payer.example.org/Questionnaire/surgery # a DTR questionnaire
pa_attachments: ["18776-5"] # and documents, by LOINC attachment code
Hver vare får en X12-gennemgangsaktion: A1 certificeret, A3 ikke certificeret, A4 udsat, A6 ændret, C annulleret (certificeringstype 3). En linje, der ikke navngiver en service, bliver ikke afgjort, men besvaret med en fejl (X12 901 AG, korrekt og genindsend). Svaret gentager, hvad et 278-svar gentager — varenumre, de anmodede services datoer, mødets datoer, overførselsidentifikatorerne med afsender og modtager ombyttet — og giver hver linje betalers egen administrationsreferencenummer. En service, ingen regel navngiver, bliver udsat, aldrig godkendt: en afgørelse, ingen skrev ned, er en afgørelse for en person.
Udsatte anmodninger venter på en gennemgående, der besvarer med POST /fhir/Claim/$decide:
{"resourceType": "Parameters", "parameter": [
{"name": "claimResponse", "valueString": "<the ClaimResponse id>"},
{"name": "decision", "valueCode": "approve"},
{"name": "reason", "valueString": "Reviewed with the plan of care."},
{"name": "reviewer", "valueString": "<the reviewer's NPI>"}]}
decision kan også være modify: certificeret, men ikke som bedt om, med quantity (valueDecimal, de certificerede enheder) og/eller alternative (valueCoding, den godkendte service i stedet). Responsen siger så A6 Modified, med den certificerede detalje eller den alternative som et tilføjet element, og en autorisationsnummer. item (valueInteger, gentagelig) begrænser beslutningen til nogle linjer. Beslutningen bliver en ny version af responsen, markeret som gennemgået af en person, og med -fhir-subscriptions leveres den på PAS-emnet (PASSubscriptionTopic, filteret af org-identifier, den anmodende organisations identifier) som den fulde PAS Response Bundle, i samme transaktion som optager den. $inquire returnerer den aktuelle respons til hver anmodning, som udbyderen har foretaget om den medlem; en anden udbyders anmodning finder intet. $decide kræver en skriveomfang; $inquire er en læs.
Anmodninger og hver version af deres svar gemmes i pas_requests og pas_responses i serverens database.
16.10.1 Gennemgangskøen
I webkonsollen viser Betalere → CMS-0057 → Gennemgangskø de udsatte anmodninger, der snartest skal behandles først: en accelereret anmodning (Krav.priority stat) skal behandles 72 timer efter ankomst, en standard 7 dage. Valg af en viser medlemmet, udbyderen, hver service med de enheder, der er anmodet, og hvor den står, hvad svaret anmoder om, og hver dokument, der er modtaget for den, med plain-text-dokumenter vist inline. En redaktør optegner afgørelsen der: godkend, afvis, eller ændre (enheder certificeret, eller en anden service godkendt i stedet), med en grund og gennemgåendes NPI. En ændring må certificere færre enheder, end der blev anmodet om; lige så mange eller flere er en godkendelse og afvises som en ændring. En service, der er godkendt i stedet, starter i kodesystemet for den, der blev anmodet om. Det er den samme afgørelse, $decide træffer, så udbyderens abonnement leverer den. Læsning af en anmodning og afgørelse af den skrives begge til revisionsloggen.
Overvågning → Team-dashboard → Prior autorisation viser, for de sidste 30 dage, hvor mange standard- og hurtige anmodninger blev besluttet inden for CMS-0057's tidsrammer, besluttet for sent, stadig venter på beslutning og er forsinket nu, med median-tiden til at beslutte, og hvordan de services, der blev bedt om, blev besvaret: godkendt, ændret, afvist eller stadig uafgjort. Disse to fliser læses fra anmodningerne selv, så de er ikke i dashboardets Grafana-eksport, som siger det i dets beskrivelse.
16.10.2 Modtagelse af dokumenter, som en afventende anmodning anmoder om
En pendent svar beder om dokumenter med en opgave og en CommunicationRequest per dokument. En spørgeskema bedes om, som PAS beskriver det: en CommunicationRequest med den enkelte LOINC-kode 102089-0, under sporingsnummeret for linjen, det er for (itemTraceNumber, som ClaimResponse echoer; en linje sendt uden et sporingsnummer får et). Det sporingsnummer er DTR-konteksten: $questionnaire-package med kun context sat til det returnerer spørgeskemaet. Leverandøren sender, hvad der blev bedt om, med Da Vinci CDex $submit-attachment (POST /fhir/$submit-attachment): TrackingId er anmodningens eget sporingsnummer (ClaimResponses første identifier, som også er opgavens), eller en CommunicationRequests identifier, AttachTo er preauthorization, og MemberId skal være anmodningens medlem. Hver vedhæftnings DocumentReference eller QuestionnaireResponse holdes med anmodningen og vises til dets gennemganger; et dokument, der ankommer, afgør intet.
16.10.3 Afgørelse i et X12-udnyttelsesstyringssystem
De fleste betalere beslutter prioriteringer i et UM-system, der taler X12 278. Med -pas-278-url er Perfuse FHIR-fronten af dette system: hver $submit sendes som én 278-anmodning (005010X217), hver item en patientbegivenhed. Hver bærer, hvad PAS navngiver for det: anmeldelses typen (extension-serviceItemRequestType, UM01: sundhedsydelser, indlæggelse eller specialbehandling), certificeringstypen (extension-certificationType, UM02), servicetypen, servicestedsstedet (UM04), serviceniveaueret (extension-levelOfServiceCode, UM06: valgfri, akut eller nødsituation; en stat-prioritet står i stedet for akut), dato, en indlæggelsesanmeldelse indlæggelse og udskrivningsdato, diagnoserne, plejeteams leverandøren, der skal udføre servicen, og proceduren og mængden som en professionel (SV1) eller, på en institutionskrav, et hospital (SV2) servicelinje. 278-svarets handlingkode og autorisationsnummer bliver items anmeldelseshandling: godkendt, delvist eller ændret, afvist, udsat, annulleret eller ikke overvejet (udsat for en anmelder, med afvisningsårsager). Lokale regler konsulteres ikke.
perfuse serve -fhir -pas -pas-278-url https://um.example/x12/278 -pas-278-receiver ACMEUM \
-pas-278-token-env UM_TOKEN
Et UM-system, der først pender og senere beslutter, posterer sin senere 278-respons til POST /fhir/Claim/$decide-278; hver begivenhed matcher sin anmodning med sporingstallet Perfuse sendte, og beslutter som $decide ville beslutte det. Hvis UM-systemet ikke kan nås, eller svarer med noget, der ikke er en 278-respons, pender hver vare for en reviewer, og udbyderen fortælles kun, at; årsagen er i serverloggen.
Spørgsmål, som UM-systemet besvarer
En udbyders $inquire skal finde en autorisation, uanset hvordan den blev anmodet om: via fax, gennem betalers portal, via telefon eller i en 278, en anden indsender sendte. Perfuse holder kun anmodningerne, der kom gennem det; UM-systemet holder dem alle. Så med et UM-system, der besvarer i realtid (hver transport undtagen sftp), sendes hver $inquire også til det som en 278-anmodning (005010X215: BHT02 28, medlemmet, udbyderen, autorisationsnummeret fra Kravets insurance.preAuthRef, når det har et, og begivenhedsdatoerne fra billablePeriod eller service-datoerne for punkterne, ellers et år på hver side af i dag). Hver autorisation, svaret indeholder, som Perfuse ikke gør (matchet af sporingstal, det sendte, og autorisationsnumre, det allerede gav), kommer tilbage som endnu en Claim Inquiry Response Bundle: UM-systemets beslutning for hver servicelinje, autorisationsnummer og periode og en note, der siger, hvor den blev fundet. Ingen Krav oprettes for en autorisation, ingen indsendte i FHIR: dets ClaimResponse.request bærer en data-fravær-årsag, som PAS's profil tillader. En anmodning læser kun; intet i Perfuses egne optegnelser ændres. Hvis UM-systemet er nede eller besvarer med en TA1 eller 999, får udbyderen, hvad Perfuse holder, og linkets status siger, hvorfor. Formen følger 278-anmodningens companion guides, som UnitedHealthcare, Cigna og Blue Cross Blue Shield of Massachusetts publicerer; den er ikke blevet testet mod et rigtigt UM-system.
Hvordan 278'er når UM-systemet
UM-systemets vejledning om, hvordan det modtager 278'er, og -pas-278-transport (Indstillinger, Payers, Anvendelse af ledelse af sundhedsydelser link) følger det:
| Transport | Hvad der sendes | Godkendelse |
|---|---|---|
x12 (standard) | 278 POSTet som application/edi-x12; svaret er responsens brødtekst | En bærertoken, OAuth, HTTP Basic, et clientcertifikat |
core-soap | CAQH CORE real-time SOAP 1.2-envelopen (COREEnvelopeRealTimeRequest, payloadtype X12_278_Request_005010X217E1_2, eller X12_278_Request_005010X215 til en forespørgsel): Connectivity Rule vC2.2.0 med payloaden i envelopen, som de fleste betalere og CMS esMD kører, eller -pas-278-core-version C4.0.0 med payloaden som en MTOM-vedhæftning | vC2.2.0: et brugernavn og adgangskode (WS-Security UsernameToken) eller et clientcertifikat. vC4.0.0: et clientcertifikat og en OAuth-token |
core-mime | CAQH CORE vC2.2.0 HTTP MIME multipart-envelopen, payloaden som en fildel | Envelopens brugernavn og adgangskode, eller et clientcertifikat |
sftp | Hver 278 placeret i en mappe på UM-systemets SFTP-server (-pas-278-sftp, -pas-278-sftp-outbound); dens svar indsamlet fra en anden (-pas-278-sftp-inbound, hver -pas-278-sftp-every) | En SSH-nøgle eller adgangskode; serverens nøgle skal være i -pas-278-sftp-known-hosts |
En klientcertifikat er -pas-278-cert og -pas-278-key; -pas-278-ca tillader en betalers egen certifikatmyndighed. OAuth er -pas-278-oauth-token-url, -pas-278-oauth-client-id og hemmeligheden, hentet med client-credentials-tilskud og holdt, indtil en minut før udløb. Adgangskoder, tokens og hemmeligheder er aldrig flags: hver er navngivet af en miljøvariabel (-pas-278-password-env, -pas-278-token-env, -pas-278-oauth-secret-env, -pas-278-sftp-password-env), eller skrevet ind i indstillings-skærmen, hvor den gemmes i indstillingsfilen (læselig af serverkontoen alene) og aldrig vises igen.
UM_PASSWORD=... perfuse serve -fhir -pas -pas-278-transport core-soap \
-pas-278-url https://um.example/CORE/RealTime -pas-278-receiver ACMEUM \
-pas-278-user perfuse -pas-278-password-env UM_PASSWORD
Over SFTP ventes hver anmodning, indtil svaret ankommer: 278-svaret afgør posterne, og Perfuse placerer en 999, der accepterer det, i udgående-mappen. En fil, der ikke kan læses, bliver i indgående-mappen til en person og tilbydes igen ved næste læsning.
Når UM-systemet ikke kan læse en anmodning
Et UM-system, der ikke kan læse en 278, besvarer med en TA1 (konvolutten) eller en 999 (transaktionen) i stedet for en beslutning. Perfuse læser, hvilken og hvad den siger, udsætter hver enkelt post ("utilization management kunne ikke læse anmodningen") og optager den. Payer, CMS-0057, Reviewer-køen viser linket: hvad der er sendt i de sidste syv dage, hver interchange efter dets kontrolleringsnummer, og hvad der blev af det (besvaret; anerkendt, svar kommer; afvist med 999's segment, element og kode; ikke nået). Hver interchange har sit eget kontrolleringsnummer, ét mere end det sidste, som er hvad en TA1 eller 999 navngiver, når den besvarer.
16.10.4 Afgørelse på basis af kliniske beviser med en afgørelseservice
En regelfil beslutter efter servicetype: en kode behøver ingen autorisation, er ikke dækket eller går til en reviewer. Om denne patient opfylder kriterierne for den er en anden spørgsmål, besvaret fra betingelserne, spørgeskema-svar og dokumenter, udbyderen sendte med anmodningen. Med -pas-decider-url lægges hver vare, som reglerne lader en reviewer, først til en beslutningstjeneste, såsom Vaglio, som læser den samme PAS-anmodning Bundle gennem Perfuses offentliggjorte pas-pakke. En offentlig Vaglio, på opfundne anmodninger, køre ved siden af Perfuses testinstance på https://vaglio.perfuse.health:8443 (log ind som demo, adgangskode try-vaglio-demo; den kan se på alt og ændre intet): hver beslutning der har sin bevis, et klarsprog-brev og en kvittering, som alle kan kontrollere.
perfuse serve -fhir -pas -crd-rules payer-rules.yaml -pas-decider-url https://vaglio.example/api/pas/decide \
-pas-decider-token-env VAGLIO_TOKEN
URL'en skal være https eller plain http til denne maskine (localhost, 127.0.0.1), da den indeholder en patients journal og token. Vaglio selv besvarer kun på https; når den bruger et certifikat fra sin egen myndighed, skal myndigheden medfølge med -pas-decider-ca DATA/tls/ca.crt (eller enhver betalers interne myndighed, som tjenestens certifikat kommer fra). Tjenesten modtager anmodnings-bundlen, som udbyderen sendte den, POST <url>?item=<sequence> (application/fhir+json), og besvarer {"decision": "approve" | "deny" | "pend", "why": "...", "requested": ["..."]}, eller 404, når den ikke træffer nogen beslutning for det pågældende element, hvilket efterlader reglernes svar stående. why er processnoten i svaret og er påkrævet for en afvisning, som ellers bliver udsat; requested siges til udbyderen som den information, en udsat anmodning har brug for. En udsættelse kan også medføre "questionnaire": "<canonical>" og "attachments": ["<LOINC>", ...], som bedes om i svarets CDex Task og CommunicationRequests ud over hvad reglens spørgeskema eller vedhæftninger beder om (reglens spørgeskema sejrer, da en opgave beder om én; en kode, der ikke har LOINC's form, bliver droppet og logget). En regel, der godkender eller afviser, er betalers dækningsspolitik og sendes ikke til tjenesten. Et fejl, en timeout eller et svar, der ikke er en af de tre beslutninger, udsætter elementet for en gennemganger, med årsagen i serverloggen: intet her omdanner et fejl til en godkendelse. Det kan ikke kombineres med -pas-278-url, hvor UM-systemet besvarer hvert element.
Råd før indsendelse. Med -crd-advisor-url ved siden af -crd-rules beder CRD også en beslutningstjeneste, hvad en forhåndsautorisationanmodning for hver ordre, der har brug for det, ville blive sagt, som journalen står, og viser svaret som endnu en kort: "Før du indsender: en anmodning om dette ville have brug for: ...", eller "ville blive godkendt", med hvad der stadig er nødvendigt, spørgeskemaet, der beder om det, og hvad der ville godkende det. Vaglio svarer på /api/pas/advise, med samme token og myndighed som ovenfor:
perfuse serve -fhir -pas -crd-rules payer-rules.yaml \
-crd-advisor-url https://vaglio.example/api/pas/advise -crd-advisor-token-env VAGLIO_TOKEN
CRD sender POST <url> med {"service": {"system": "...", "code": "..."}, "resources": [ ... ]}, hvor ressourcerne er hook'ets forhåndshentning (patienten først, dækning udeladt), og læser {"decides": true, "answer": "approve" | "pend" | "deny", "summary": "...", "missing": [...], "questionnaire": "...", "toApprove": [[...]], "policyTitle": "..."}. Det er råd og ændrer intet: dækningsoplysningerne, de andre kort og PAS-beslutningen er, hvad reglerne siger. Det venter højest tre sekunder, og intet svar, et fejl eller "decides": false efterlader svaret helt, som det er, uden det. Perfuse har aldrig brug for en beslutningstjeneste.
Anmodningen bærer X-PAS-Request-Id, id'et, som svaret kendes ved. En tjeneste med egne gennemgangsfolk, der udsætter et element, kan sende deres beslutning senere, som en hvilken som helst gennemgangs beslutning sendes: Claim/$decide med det id som claimResponse, elementets sekvens og beslutningen og årsagen. Udbyderens abonnement leverer det, som det ville en, der er lavet i gennemgangskøen.
Et abonnement med id-only indhold fortæller udbyderen, hvilket svar der er ændret, uden at sige, hvad det er: meddelelsens fokus er Bundle/<id>. GET /fhir/Bundle/<id> returnerer den seneste PAS-svar-bundle, GET /fhir/Bundle/<id>/_history/<n> versionen, en meddelelse sendte, og GET /fhir/ClaimResponse/<id> ClaimResponse alene. En token, der er bundet til én patient, fortælles, at de ikke eksisterer, som for en hvilken som helst journal uden for dens patient.
Verificeret med den officielle Inferno PAS Server v2.2.1-suite (se verificering). Ikke sendt, selvom PAS markerer dem som must-support: ClaimResponse.adjudication med en gennemgangsaktion, ClaimResponse.extension:authorizedProvider og ClaimResponse.item.extension:communicatedDiagnosis, fordi udvidelserne de behøver ikke er tilladt der af deres egen kontekst i PAS 2.2.1 og validatoren afviser en respons, der bærer dem; og request.extension:DataAbsentReason, fordi Perfuse altid kender anmodningen. De 278'er, der sendes til et utilization management-system (ovenfor), er kontrolleret mod PAS 2.2.1's egne anmodningseksempler, CMS's offentliggjorte esMD 278-prøver og en 278-afprøvning skrevet fra offentlige companion guides, og hver transport mod en stand-in UM-system skrevet fra CAQH's Connectivity Rules (se verificering); ikke endnu mod et rigtigt UM-system eller clearinghouse, og ikke CORE-certificeret. Ikke implementeret: vedhæftninger sendt tilbage med CDex.
En regelfil bliver kontrolleret mod CRD's egne invarianter, når den indlæses: et spørgeskema har brug for dokumentation, en tjeneste, der ikke er dækket, kan ikke have brug for autorisation, satisfied hører til én sag og ikke en regel, og alt, der er betinget, skal give en årsag.
Ikke verificeret: eksporterne og medlemssammenligning mod en anden betalers implementering, metric mod en betalers offentliggjorte tal, og CRD mod en rigtig EHR's CDS Hooks-klient.
16.11 Sendning af forudgående autorisationsanmodninger til en betaler (for udbydere)
Alt ovenfor besvarer anmodninger, som en betaler. En udbyders side er den modsatte vej: en EHR eller en DTR-app bygger en Da Vinci PAS-anmodningsbundle, og noget skal sende den til betaleren, holde svaret og videregive det. En pas-destination gør det.
name: prior-auth-out
dataType: raw
source:
type: http
http:
listen: 127.0.0.1:8095
path: /pas
destinations:
- name: acme-health
type: pas
pas:
payer: https://pas.acme-health.example/fhir
bearer_token: ${ACME_PAS_TOKEN} # or auth: { type: client_credentials, token_url, client_id, client_secret }
results_to: pas-answers # optional: a channel that takes each answer back to the EHR
Hvert meddelelse skal være en hel PAS-anmodning Bundle på en rå kanal. Perfuse poster den uændret til {payer}/Claim/$submit : betaleren afgør kravet sammen med patienten, dækning og understøttende ressourcer i bundlen, og et krav genopbygget fra en sammenfatning ville miste dem. Af denne maskine skal betalerens adresse være https.
En beslutning er en leveret anmodning, uanset hvad den siger. En godkendelse, en afvisning og en udsættelse bliver alle registreret, og ingen af dem bliver genprøvet, fordi genprøving af en afvisning indsender samme anmodning to gange. Det, der fejler leveringen, og som bliver genprøvet, er en betaler, der ikke har truffet en beslutning: en fejlstatus, en OperationOutcome (dets tekst er fejlen) eller en ClaimResponse, hvis resultat er error. Beslutningen læses punkt for punkt fra PAS-gennemgangsaktionens kode (X12 306: A1 godkendt, A2 delvist, A3 afvist, A4 udsat, A6 ændret); en respons uden kode er opført som "ingen beslutningskode" snarere end taget som en godkendelse. En afvisning uden nogen grund er afvist, da den ikke opfylder CMS-0057.
Betalernes svar er destinationens svar, så Inspect the reply kan bedømme det, og results_to overdrager det til en anden kanal. Hver anmodning bliver listet på CMS-0057, Anmodninger sendt til betalere: når den blev sendt, patienten, servicen, afgørelsen og betalerens reference (preAuthRef), som en senere forespørgsel nævner. Listen bliver opbevaret i prior-auth.json ved siden af databasen (højst 10.000 anmodninger; de ældste afgjorte anmodninger fjernes først, en afventende anmodning gør det aldrig), og hver lejer ser kun sin egen.
Verificeret mod HL7 Da Vinci PAS-betalers referenceimplementering (docker-billede hlseven/davinci-prior-auth): en anmodning sendt gennem en kørende kanal bliver afventet af den med dens reference, og svaret vises på skærmen (se verificering). Endnu ikke prøvet mod en produktionsbetalere. Ikke bygget: at følge op på en afventet anmodning med $inquire, eller at modtage betalerens senere svar via abonnement; en kanal kan gøre det ene eller det andet i dag med en http- eller fhir-destination.
16.12 CMS Aligned Netværk
CMS Interoperability Framework (CMS Health Technology Ecosystem) beder sundhedsdata-netværk om at selv-attestere til 26 kriterier og blive listet som CMS Aligned Networks; EHR'er, udbydere, betalere og apps tilslutter sig dem. Kriterier 13 til 16 har været i kraft siden 4. juli 2026: FHIR-API'er på US Core med en fuld CapabilityStatement og Bulk Data, dokumenter som menneskelæsbare FHIR-vedhæftninger, aftale- og mødeanmodninger via FHIR-abonnement og en journallokator.
Administrer › CMS Aligned Network listar hver kriterium med, hvad Perfuse tilbyder til det, og hvor denne server står, læst fra, hvad der er slået til her:
| Status | Mening |
|---|---|
| Klar her | Perfuse tilbyder det, og det er slået til. |
| Klar, med et gap | Det er slået til, og en del af kriteriet ligger uden for det (navngivet på skærmen). |
| Bygget, ikke slået til | Perfuse tilbyder det; skærmen navngiver indstillingen eller flaget, der slår det til. |
| Dit at gøre | Organisationens del: en aftale, en certificering, offentliggørelse til National Provider Directory. |
| Ikke bygget | Software ville gøre det, og Perfuse gør det ikke. |
Hvad de fire, der er i kraft, har brug for fra denne server:
| Kriterium | I Perfuse | Slå til |
|---|---|---|
| 13 FHIR-API'er, US Core, Bulk Data | FHIR-endpointet med dets CapabilityStatement og $export | -fhir, -fhir-bulk-export |
| 14 Dokumenter som FHIR-bilag | DocumentReference med Binary og IHE MHD over XDS-registrering | -fhir (MHD også -xds) |
| 15 Møde- og appointmentsnotifikationer | Emnebaserede abonnementer (R5 Backport for R4) fra ADT- og SIU-feeds | -fhir-subscriptions |
| 16 Record locator | XDS.b-registrering, XCA for andre fællesskaber, PIXm | -xds, -xds-home-community |
Skærmen er et regneark til attestationen, ikke en certificering: CMS gennemgår netværk, det mistænker ikke opfylder kriterierne, og rammeværkets egen tekst er myndigheden. Ikke bygget i dag: åbne kvalitetsgap-anmodninger (kriterium 8), en betalers anmodning om en kravs møde-data (9), rapportering af anmodnings-målinger til National Provider Directory (19), kontrol af udbydere mod den directory (6), læsning af mobile chaufførløsninger eller digitale forsikringskort (3, 23) og gennemtvingelse af en generel samtykkepolitik på hver læsning (5). IAL2-identitetsverificering er identitetstjenestens; Perfuse accepterer token fra den, du vælger.
17 Sikkerhed
Perfuse håndterer kliniske data. Dette kapitel er, hvad det gør ved det, og hvad det overlader til dig.
17.1 Transport-sikkerhed
TLS på web-grænsefladen konfigureres med -tls-cert og -tls-key. Uden dem er grænsefladen plain HTTP, som er acceptabelt på en loopback-adresse til en første kig og ingen andre steder — den indeholder legitimationsoplysninger og meddelelsesindhold, begge læselige på wiren.
TLS på kanaltransporter er per kilde og per destination, under en tls-blok. De tilgængelige indstillinger er i kilde og destination referencer.
insecure_skip_verify accepterer ethvert certifikat. Det eksisterer, fordi hospitalsystemer rutinemæssigt præsenterer certifikater, der ikke kan verificeres, og afvisning af forbindelse ville betyde afvisning af integration. Det er navngivet for at være iøjnefaldende, og brug af det betyder, at forbindelsen er krypteret, men ikke autentificeret — du har beskyttelse mod passiv aflytning og ingen mod en indsat server.
17.2 Autentificering og roller
Brugere gemmes i databasen. Hver har en af fem roller, og hver rolle inkluderer alt i de overliggende roller:
| Rolle | Kan |
|---|---|
| Overvåger | Se, om alt fungerer: kanalstatus, antal, flowkort, alarms, dashboards, metrics og køens dybde. Ingen meddelelsesindhold, kanalfiler eller køede meddelelser. |
| Læser | Læse meddelelser, kanalfiler, spor og aktivitetlog også. |
| Operatør | Læse og gensende: genbehandle en meddelelse, afspille en kanal og gensende køede leveringer. |
| Redaktør | Læse, oprette og ændre kanaler, og køre sammenligninger. |
| Administrator | Læse, oprette, ændre, starte og stoppe kanaler, rydde køer, og administrere personer, tokens og serverindstillinger. |
En sjette rolle, Platform, tilhører den, der kører en delt server: den opretter lejere og sætter deres begrænsninger og har ingen kanaler af sig selv.
Overvågning er til en hjælpedesk eller til en operations-skærm på en væg: alt, der er nødvendigt for at se, om en feed er stoppet, og intet, der nævner en patient. Viser kan læse meddelelsesindhold, som er kliniske data; det er en lav-privilegeret rolle til *konfiguration*, ikke til privatliv. Operatør adskiller reparation af en fejlet levering om natten fra ændring af, hvad en feed gør: personen, der gen sender, behøver ikke at kunne omskrive kanalen.
17.2.1 Gentagne forkerte adgangskoder
Forkerte adgangskoder og mislykkede passkey-login er talt af den adresse, forbindelsen kommer fra, og efter et par i træk venter den adresse, før den må prøve igen (svaret er 429, med Retry-After). Konti er ikke låst af navn, fordi det ville lade hvem som helst låse en administrator ud med vilje.
Adressen er forbindelsens egen, aldrig en adresse, en anmodning kræver i X-Forwarded-For, som afsenderen skriver. Bag en omvendt proxy på samme maskine bruger Perfuse den sidste X-Forwarded-For-post i stedet, den proxy tilføjede, så hver klient tælles stadig separat. En proxy på en anden maskine når Perfuse fra en adresse, og alle dets klienter deler en tælling: rate-limiter-login på den proxy også.
17.2.2 Kanalgrupper
En person (eller en API-nøgle) kan begrænses til visse kanalgrupper: de ser og handler herefter kun på kanaler, hvis group er en af deres. Dette er arrangementet af et hospital på én server, hvor hver institutions analytikere passer deres egne feeds, og et centralt hold uden begrænsning passer alle. Rhapsody kalder det en låge.
Begrænsningen gælder overalt på én gang, fordi den påføres anmodningen i stedet for at huskes af hver skærm: kanallisten, dashboard og flow-kort, meddelelser og deres søgning, tællinger og diagrammer, køen, alarmer, metrikker, certifikater, kontrakter og kode-sætbrug. En kanal uden for personens grupper eksisterer ikke for dem; at spørge efter den ved navn giver *ikke fundet*, så dens navn bekræftes heller ikke. En kanal med ingen gruppe ses kun af personer med ingen begrænsning.
Gemning af en kanal holder den inden for personens grupper: de kan ikke oprette en kanal i en anden gruppe eller flytte en ud af deres egen. Det, som hver facilitet deler - kode-tabeller, script-biblioteker, forhånds-godkendelsesbeslutninger - kan de læse, men ikke ændre. Server-omfattende tal (forhånds-godkendelse, token-brug, tunneller) vises kun til personer med ingen begrænsning, og det samme gælder metrikker og alarmer om hele serveren i stedet for en kanal.
En administrator begrænset til grupper er en facilitets egen administrator. De administrerer personer og tokens i deres grupper, starter og stopper deres kanaler og rydder deres køer. En kollega, de tilføjer, får deres grupper, medmindre de navngiver nogle af dem; de kan ikke give en gruppe, de ikke har, og de ser aldrig eller ændrer nogen med ingen begrænsning. Alt andet, en administrator kan gøre, ændrer hele serveren - indstillinger, logon, genstart, alarmer, branding, flåde, SMART-serveren - og nægtes dem.
Grupper indstilles i Brugere (og for tokens i Tokens), som en kommasepareret liste. Hver ændring registreres i aktivitetens log og træder i kraft ved personens næste anmodning.
En anden rolle i hver gruppe
En person kan have en anden rolle i hver af deres grupper: lab=editor, adt i Brugere redigerer lab'ets kanaler og har rollen valgt ved siden af - fx viser - i admissions-kanalerne. De ser begges grupper kanaler på hver skærm. Gemning, start eller genafsendelse af en kanal i en gruppe, hvor deres rolle er for lav, afvises med rollen, de har der; det prætender ikke, at kanalen mangler, da de kan se den. Deres rolle øverst på skærmen er den stærkeste, de har, som åbner skærme, der bruger den rolle, og hver handling på disse skærme er stadig begrænset til grupperne, hvor de har den.
Kun personer begrænset til kanalgrupper kan have en. Nogen, der ser hver kanal, har en rolle, fordi "redaktør af labets kanaler" for en person med ingen begrænsning ville være redaktør af alt, der tilhører ingen gruppe, og af server-omfattende sider. En facilitets administrator kan give en rolle pr. gruppe kun i grupperne, de administrerer, og aldrig over deres egen rolle der.
17.3 Hvem må ringe til FHIR-endpointet
FHIR-endpointet (serve -fhir) kontrollerer en af to typer tokens:
- Perfuse API-token, oprettet under Brugere → Maskinlogin eller med
perfuse token create. Hver bærer en rolle og kan
begrænses til FHIR-grupper. Dette er standard, når ingen SMART-autentiseringsserver er konfigureret.
- SMART-adgangstoken, fra Perfuses egen autentiseringsserver (
-smart-clients) eller en ekstern en (-smart-issuer). Hver
bærer omfang, og endpointet holder hver anmodning til dem.
Med SMART konfigureret accepteres kun SMART-tokens, så hver afkaldsholder holdes til deres omfang. En API-nøgle har en rolle og ingen omfang: en viser-token kan læse hver patients journal. En betaler, der aktiverede SMART for at begrænse hver app til, hvad den var tildelt, bør ikke have en adgang, der ikke er begrænset.
Nogle steder har brug for begge dele - en intern krav-feed, der holder en API-nøgle og har ingen SMART-klient, ved siden af medlemmer-applikationer, der logger ind gennem SMART. Til dem låser Indstillinger → FHIR → Acceptér Perfuse API-tokens ved siden af SMART-tokens (-fhir-api-tokens ved start) API-tokens ind. Det er slået fra som standard, det træder i kraft ved den næste anmodning i begge retninger, og ændring af det skrives til revisionsloggen. En token skelnes fra sin form: en SMART-token er en signeret JWT, og en API-nøgle er aldrig det, så den ene tjekkes aldrig som den anden. Hvor du kan, giv sådant et system en SMART Backend Services-klient i stedet, med kun de systemomfang, det har brug for.
17.3.1 En FHIR-endpoint åben for fremmede
En offentlig testserver udsteder legitimationsoplysninger, der kan skrive, fordi test af forudgående autorisation eller abonnementer kræver skriverettigheder. To begrænsninger forhindrer, at en enkelt klient ødelægger det for alle, begge under Indstillinger → FHIR og begge slået fra som standard:
- Skriver en minut fra en klient (
-fhir-writes-per-minute): opretter, opdaterer og sletter fra en klientadresse. Over det, besvares en skrivning med 429 ogRetry-After: 60. Læsninger og søgninger, herunder søgninger via POST, tælles aldrig. - De fleste ressourcer holdt (
-fhir-max-resources): over det, afvises nye ressourcer med 507, mens opdateringer og sletninger stadig virker.
Et hospitals eget endpoint har brug for ingen af delene.
17.4 AI-agenter: MCP-serveren
Med Indstillinger › Sikkerhed › AI-agenter (MCP) slået til (eller serve -mcp), serverer Perfuse Model Context Protocol på /mcp, så en AI-agent som Claude, ChatGPT eller en IDE-assistent kan spørge, hvad der sker. Det er slået fra som standard, og slåning af det stopper hver agent på dens næste opkald.
En agent forbindes med en API-nøgle fra Administer › Brugere › Maskinadfærdskoder som en bærertoken, aldrig med en persons browser-session (det afvises, så en agent handler aldrig med en persons fulde adgang). En klientkonfiguration ligner:
{ "mcpServers": { "perfuse": { "type": "http", "url": "https://perfuse.example/mcp",
"headers": { "Authorization": "Bearer <token>" } } } }
| Værktøj | Rolle | Hvad det gør |
|---|---|---|
server_status, list_channels, queue, alerts | monitor | Om ting fungerer, uden beskedindhold |
get_channel, search_messages, get_message, find_patient, fhir_search | viser | Kanaler, beskeder (med indhold), en patients beskeder på tværs af formater, en FHIR-søgning |
retry_delivery, reprocess_message | operatør og mcp:write | Gentag en køet levering, send en besked gennem dens kanal igen |
start_channel, stop_channel | admin og mcp:write | Start eller stop en kanal |
Hvert værktøj besvares af samme rute eller FHIR-søgning, som en persons skærm bruger, kaldt med agentens egen token, så tokenets rolle, kanalgrupper og lejer afgør, hvad det ser, præcis som de gør i konsollen; og fhir_search får tokenets egen adgang til FHIR-endpointet (som kan afvise API-nøgler helt; se FHIR-afsnittet ovenfor). En agent tilbydes kun de værktøjer, dens token kan bruge. Læsning er standard: et værktøj, der ændrer noget, har også brug for tokenets mcp:write-omfang ("Lad en AI-agent handle med det", når tokenet udstedes), så et token udstedt til en rapporteringsagent ikke kan overtales til at handle ved en prompt. Et overvågnings-token svar har fjernet meddelelsesindhold, uanset hvad en rute returnerer.
Hver opkald er i Activity som mcp.tool med tokenets navn, værktøjet, dets argumenter og udfaldet (ok, refused, invalid, rate-limited eller HTTP-status); mcp.connect optager, hvilken klient der er connected. Hvert token kan foretage 60 værktøjopkald pr. minut (Værktøjopkald pr. minut fra ét token); over dette, besvares et opkald med en fejl, som agenten kan læse, og intet bliver gjort. En anmodning fra en browser-side på en anden oprindelse afvises, hvilket MCP beder om af en server for at stoppe DNS-ombinding. Transporten er MCP's Streamable HTTP, besvaret som JSON uden begivenhedsstrøm; protokollversioner 2025-06-18, 2025-03-26 og 2024-11-05 accepteres. Beskeder og FHIR-resourcer indeholder patientdata: en agents svar går til den model, det kører på, så give et token til en agent kun, hvor den model er tilladt at se dem, og give det den laveste rolle, der gør arbejdet.
17.5 En demonstrationskonto
serve -demo-account demo:PASSWORD opretter en fælles konto til en offentlig demonstrationsserver, og login-siden viser brugernavnet og adgangskoden med en knap, der logger ind med dem. Kontot er en viser, så det kan se på alt og ændre intet. I modsætning til enhver anden viser kan den også åbne administratorens skærme (brugere, maskintoken, indstillinger, dataværnsbeskyttelse, flådens peers), skrivebeskyttet: en demonstration bedømmes af dens skærme. Den læser dem som en viser læser kanaler, med hver legitimationsoplysning vist som indstillet eller ej, aldrig dens værdi, og hver ændring afvist. Den kan også trykke på kontrollerne, der ikke ændrer noget og ikke når noget uden for serveren: et scripts Kontrol, og kanalredigeringsværktøjets valider og parse. Den kan ikke ændre sin adgangskode eller tilføje en adgangsnøgle, fordi den første besøgende, der gør det, vil låse alle andre ude efter dem. Hver start sætter den tilbage som en viser med den offentliggjorte adgangskode. Adgangskoden skal være mindst 12 tegn, ligesom enhver anden. Brug den kun på en server, der indeholder testdata: enhver, der læser login-siden, kan læse hver besked på serveren.
17.6 Revisionshistorik
Konfigurationsændringer, login og adgang til beskedindhold registreres med hvem, hvad og hvornår.
Revisionshistorikken er i samme database som beskederne. Det er praktisk, og det er en begrænsning: nogen, der kan ændre i databasen, kan ændre revisionshistorikken. Hvis dine krav inkluderer en revisionshistorik, der er modstandsdygtig over for manipulation, skal loggen sendes til et sted, hvor den kan tilføjes, og Perfuses egen logudskrift er måden at gøre det på.
17.7 Hemmeligheder i konfiguration
Adgangskoder, adgangskoder og nøgler vises i kanal-konfiguration, hvilket betyder, at de er i YAML-filerne.
To konsekvenser. Filerne kræver filsystemrettigheder, der afspejler deres indhold, og hvis de er i versionskontrol — hvilket ellers anbefales — indeholder repositoryen legitimationsoplysninger og skal behandles derefter.
Hvor en værdi er en hemmelighed, viser grænsefladen den som en hemmelighed, og API'et returnerer den ikke, når den er gemt. Dette beskytter den mod at blive læst over skulderen eller lækket i et screenshot. Det beskytter ikke filen.
17.8 Hvad der er i databasen
Beskeden gemmer beskeder, som de modtages, hvilket for en klinisk feed betyder patientidentificerbare data. Den skal være på krypteret lager, sikkerhedskopieret som klinisk data med den tilhørende retention og adgangskontrolleret på både filsystemniveau og gennem Perfuse's egne roller.
cleanup.periodDays begrænser, hvor længe den gemmes. Se beskedlagret for spændingen mellem dette og at have tilstrækkelig historik til rytmebevidst alarmering.
17.9 Databeskyttelse (GDPR og UK GDPR)
Skærmen Databeskyttelse (Administer, kun administratorer) besvarer en persons anmodninger under GDPR og UK GDPR. Den afgør intet på controllerens vegne: om en anmodning skal godkendes, og om en undtagelse gælder, er controllerens afgørelse, optaget med anmodningen.
At finde, hvad der er til rådighed. En person identificeres ved hjælp af identifikatorer: system|value (et NHS-nummer, et MRN med dets tildelende myndighed) eller et nummer alene. Med en patientindeks udvides disse til hvert nummer på hver post, der er knyttet til samme person, så en anmodning, der citerer et hospitalnummer, finder posterne, der er arkiveret under de andre. Se, hvad der er til rådighed, søger derefter i hver butik, der gemmer patientdata:
| Lager | Fundet af |
|---|---|
| Beskeder | identitetsindekset (Indstillinger → Data → Indeks patientidentifikatorer); uden det kan beskeder ikke findes ved hjælp af identifikator |
| Leveringskøen | læsning af hver køet beskeds identifikatorer |
| FHIR-lagret | Patientressourcer, der bærer en identifikator, og hver ressource, hvis indekserede referencer peger på en |
| Forudgående autorisationsanmodninger | identifikatorerne for anmodningens patient |
| Patientindekset | identifikatoreren eller EUID |
Hvad den ikke kan nå, siger den: spor sendt til en samler (-trace-endpoint), overvågningsloggen (bevaret: den er optegnelsen over, hvem gjorde hvad, herunder denne anmodning), og sikkerhedskopier.
Anmodninger. En anmodning optages med dens type (adgang, artikel 15; overførlighed, artikel 20; sletning, artikel 17; begrænsning, artikel 18), hvem den er fra, som controllerens optegnelser henviser til dem, identifikatorerne og en note (hvordan identiteten blev bekræftet, en forlængelse og dens grund). Den skal besvares en måned efter modtagelse (artikel 12(3)); en forsinket anmodning vises i rødt.
- Adgang og overførbarhed: Hent kopi giver en zip: hver besked som modtaget med dens post, hver FHIR-resurs med hver gemt version, tidligere autorisationsanmodninger og deres svar, og patientregisterets poster, JSON gennem hele, med en README der forklarer hvad hver del er. Marker som besvaret lukker det.
- Sletning: en anden administrator godkender det (den der optog det kan ikke).
Slet nu sletter alt fundet: beskeder hele (post, brødtekst, leveringer, identifikatorer, vedhæftninger som ingen andre beskeder bruger), køede leveringer (de sendes ikke), FHIR-resurserne med deres historik, tidligere autorisationsanmodninger med deres svar, vedhæftninger og sporingnumre, og personen i patientregisteret med hver tilknyttet post og dens historik (én begivenhed optegner at en sletning fandt sted, og af hvem).
- Begrænsning: optaget som en juridisk varetægt, så intet slettes eller udløber mens det varer.
- Afvis lukker en anmodning med dens grund, som personen skal underrettes om.
En lukket anmodning gemmer kun de sidste tegn af personens numre: den bliver som optegnelsen over et svar uden at være en anden kopi af dem. Hver skridt er i overvågningsloggen med numrene maskeret.
Juridiske retentioner. En retention navngiver en person ved identifikatorer, med dens grund og en valgfri slutdato. Mens den er i kraft, afvises en sletning helt, og meddelelsesbutikkens retentionsvindue sparér personens meddelelser (poster og brødtekster), indtil retentionen ophæves.
Sikkerhedskopier og sletningsoptegnelser. En sikkerhedskopi, der er lavet før en sletning, indeholder stadig det, der blev slettet, indtil den udløber. Hver sletning bliver skrevet til en optegnelse: hvornår, af hvem, godkendt af hvem, hvor meget der blev fjernet fra hver lagre, og personens identifikatorer som saltede SHA-256-hashes i stedet for i klartekst. Efter gensendelse af en sikkerhedskopi, hasher Gentilføj sletninger identifikatorerne, som de gensendte lagre indeholder, med hver entries salt og sletter hver person, som optegnelsen nævner. Korte numre kan findes fra deres hashes ved at prøve alle værdier, så optegnelsen er selv persondata og opbevares med databasens egen beskyttelse.
Opbevaring. Skærmen viser, hvor lang tid hver type optegnelse opbevares her og hvad der ændrer det: meddelelsesoptegnelser og -kroppe efter deres opbevaringsvinduer, køen indtil den er leveret eller fjernet, FHIR-lagret, forhåndsautoriseringsanmodninger og patientindekset indtil det slettes (kliniske optegnelser slettes ikke efter en tidsplan), revisionsloggen opbevares.
Behandlingsregister (Artikel 30). Behandlingsregister henter, som Markdown eller CSV, hvad denne server ved om det: controlleren, datatilsynsmanden og hvor dataene gemmes (Indstillinger → Data → Datatilsyn), hver posttypes retentionsvarighed, og én behandlingsaktivitet per kanal med, hvad den modtager, fra hvilken kilde, til hvilke destinationer, og værterne den sender til. Formålene, lovlige grunde og kategorier af datasubjekt er efterladt til controlleren at udfylde og sige det. En CSV-celle, der begynder med =, +, - eller @, skrives med en førende apostrof, så et regneark ikke kører det.
Hvor dataene opbevares. Hvor dataene opbevares (Indstillinger → Data → Datatilsyn) angiver, i ord en regulator kan kontrollere, hvor serveren, dens database og dens sikkerhedskopier køres; Datatilsynsskærmen og optegnelsen viser det. En udkast til en databehandlingsaftale for organisationer BioDream værter er i docs/legal/dpa-template.md; det er et udkast til en advokat, ikke juridisk rådgivning.
API'er er /api/privacy (samlet), /api/privacy/find, /api/privacy/requests (og /{id}/approve, /{id}/export, /{id}/erase, /{id}/close), /api/privacy/holds, /api/privacy/reapply og /api/privacy/register.
17.10 Lejere
En lejer er en isolationsgrænse: kanaler, meddelelser, brugere og indstillinger tilhører en, og intet krydser.
Dette eksisterer for en tjenesteudbyder, der kører feeds for flere praksisser. Brug det ikke til at adskille afdelinger inden for en organisation, der har brug for at se hinandens trafik: isolationen er reel, og der er ingen tværgående visning. Brug i stedet kanalgrupper (ovenfor), der opdeler personerne i en organisation, mens en central team kan se alt.
17.10.1 Begrænsninger
En platformoperator indstiller hver lejer's grænser i Tenants, så en kunde ikke kan overskygge resten af en delt server. Lad en grænse stå tom for ingen.
- Kanaler: hvor mange kanaler lejeren må have. Oprettelse af endnu en kanal bliver afvist, med angivelse af antallet og grænsen.
- Beskeder per minut: hvor mange beskeder samlet, som kanalene må modtage i et minut.
- Lager: hvor meget lagret beskedindhold, der må gemmes, i megabyte.
Ingen af dem mister en meddelelse. Over hastigheds- eller opbevaringsgrænsen, afvises en modtaget meddelelse på samme måde, som en beskæftiget modtager afviser en, før noget bliver gemt eller leveret: MLLP får ingen bekræftelse (ikke en afvisning, som nogle sendere tager som "genSend ikke"), HTTP får 429 med Retry-After, SOAP får 503, DICOM får en genforeningsstatus, og en kø, bucket eller fil bliver ladt, hvor den var. Afsenderen gensender, som hver interface-motor og EHR gør. Ingen allerede gemte data slettes for at gøre plads. En højere grænse træder i kraft inden for et minut, og hver ændring af grænserne bliver optegnet i aktivitetsloggen.
17.11 Testdata
De genererede meddelelser, der er beskrevet i testing, findes delvist som en privatkontrol. Reproduktion af et problem et andet sted, sende et eksempel til en leverandør eller befolke en testmiljø er alle ting, der ellers gøres med rigtige meddelelser.
Generatorens output indeholder ingen patientdata ved konstruktion snarere end ved redigering. Foretræk det til håndstrippede rigtige meddelelser, som er en proces, der kan gøres ufuldstændigt og som regel er.
17.12 Enkeltlogon
Tre mekanismer og lokale konti sammen med alle af dem.
OpenID Connect (-oidc), en mappe over LDAP (-ldap) og SAML 2.0 (-saml). Hver er konfigureret fra Administrer → Logon og skrevet til filen, der hedder flagene, så skærmen og filen er to visninger af ét snarere end to steder at holde i trit.
Lokale konti er altid tilgængelige og kan ikke slås fra. Det er bevidst: en lokal integrationsserver, hvis eneste adgangsvej er en identitetsudbyder, bliver utilgængelig netop, når identitetsudbyderen er utilgængelig, og en klinisk grænseflade er ikke et godt sted at lære det. Logonskærmen fortæller dig, hvor mange lokale administratorer findes, før den opmuntrer dig til at afhænge af noget andet.
17.12.1 Hvad en gruppeafstemning beslutter
Alle tre mapper grupper fra mappen til Perfuse-roller, og nogen i grupper, der matcher mere end en, får den mest privilegerede. Det er den eneste sikre retning at løse det — alternativet er en person, der mister adgang, de har ret til, fordi de også er i en mindre gruppe.
En af de seks roller kan tildeles: overvåge, viser, operatør, redaktør, admin og platform.
En gruppe kan også begrænses til visse kanalgrupper i anden boks i dens række (channel_groups i filen). Når en gruppe først nævner en, sætter hver logon brugerens kanalgrupper fra de grupper, der tildelte deres rolle: en person i en gruppe, der redigerer laboratoriets kanaler, og i en anden gruppe, der viser hver kanal, er redaktør af laboratoriets kanaler og intet andet. Den stærkeste rol bliver aldrig forbundet med den bredeste rækkevidde, fordi ingen gruppe giver det. En gruppe med en tom boks giver hver kanal. Mens ingen gruppe nævner nogen, efterlader logon kanalgrupper, som en administrator har sat dem i Brugere.
Når hver gruppe, en person matcher, nævner kanalgrupper, får hver kanalgruppe den stærkeste rol blandt de grupper, der nævner den: med Lab-Interfaces (redaktør, laboratorium) og Clinical-IT (viser, laboratorium og adt), redigerer personen laboratoriets kanaler og viser adgangs kanaler, som om det var sat af hånd. Når en af deres grupper giver hver kanal, er der ingen liste til at holde en rol per gruppe, og reglen ovenfor gælder.
roles:
editor: [Lab-Interfaces]
operator: [Night-Desk]
viewer: [Clinical-IT]
channel_groups:
Lab-Interfaces: [lab, pathology]
Night-Desk: [adt]
Det er OpenID Connect- og SAML-filen. Katalogets fil mapper hver gruppe til en rol (roles: {Lab-Interfaces: editor}), og channel_groups sidder ved siden af roles der.
En mapping, der ikke giver nogen noget, afvises i stedet for at gemmes. En konfiguration, der autentificerer personer og afviser alle, ligner en fejl i produktet set udefra: den cirkulære rejse afsluttes, og alle afvises uden nogen forklaring på hvorfor.
Oprettelse af en konto ved første login er slået fra som standard. Med den slået fra, skal en person eksistere i Perfuse, før de kan logge ind, så kataloget afgør, hvem de er, og Perfuse afgør, hvem der er tilladt.
17.12.2 SAML, specifikt
De dele, der er værd at vide, før du konfigurerer det:
- Kun det certifikat, du konfigurerer, er tillidt. Et certifikat, der er indeholdt i en respons, bruges aldrig. En angriber, der kan sende en dokument, kan også indsætte deres eget certifikat i den, og en verificator, der læser det, er en, som alle kan autentificere til som alle.
- En respons skal svare på en login, denne server startede. Perfuse husker anmodningen, den sendte, og afviser en respons, der nævner noget andet, eller nævner en anmodning, den allerede har svaret på. Uden denne kontrol er en gyldig respons en bærertoken for hvem som helst, der holder den: nogen logger ind som sig selv, gemmer responsen og poster den i din browser, og du er derefter inde i deres konto med audit-loggen, der optager deres navn.
- Logins, der starter ved identitetsudbyderen, er derfor slået fra som standard. Slå *Acceptér logins, der starter ved identitetsudbyderen* kun på, hvis du har brug for en portal-tile, og ved, at det er, hvad der gør det ovenfor muligt.
- Gruppeattributten har ingen standardværdi og er påkrævet. Entra sender
groups, Okta sender, hvad applikationen er konfigureret med, ADFS sender en krav-URI. Et gæt ville producere en login, der fungerer og giver ingen noget. Hvis en login afvises for ikke at have nogen rolle, navngiver serverloggen de attributter, der ankom — hvilket normalt er hele svaret. - Svar-URL'en skal matche nøjagtigt, hvad der er registreret hos udbyderen. En respons siger, hvor den var bestemt, og en, der er adresseret et andet sted, afvises, fordi accept af den ville betyde accept af en respons, der var bestemt for en anden service.
17.12.3 Hvad hver udbyder sender
Gruppeattributten er, hvor logins går galt, og de tre almindelige udbydere hver navngiver den forskelligt.
| Udbyder | Sender normalt | Noter |
|---|---|---|
| Keycloak | groups | Kræver en gruppe-medlemskabs-mapper tilføjet til klienten. |
| Entra ID | en krav-URI, der slutter /claims/groups | Sender gruppe-objekt-id'er, medmindre applikationen er konfigureret til at sende navne. Map id'erne eller ændr udbyderen. |
| Okta | hvad applikationen er konfigureret med | Almindeligvis groups, med en filter, der afgør, hvilke der sendes. |
| ADFS | en krav-URI | Signerer responsen i stedet for påstand, som Perfuse accepterer. |
En krav-URI kan indtastes ved dens sidste segment: at skrive groups finder http://schemas.microsoft.com/ws/2008/06/identity/claims/groups. Et navn, der blot slutter med ordet, matcher ikke — excluded_groups er ikke groups.
Gruppe-medlemskab, der ankommer som en enkelt kommasepareret værdi, behandles som et enkelt gruppenavn og matcher intet. Det er den korrekte læsning af standarden, og at splitte på kommamaer ville betyde, at en gruppe, der berettiget indeholder en, stille blev to. Hvis det er, hvad din udbyder sender, ændr det der.
Test på login-skærmen kontrollerer alt, der kan kontrolleres uden en person: indstillingerne, certifikatet og om en login-anmodning kan opbygges. Det siger åbent, at det ikke kan bevise, at nogen kan logge ind, fordi det kræver en reel påstand om en reel person, og den eneste måde at få en på, er ved at de prøver.
17.13 Konti, der er klargjort af identitetsudbyderen: SCIM
Med -scim (Indstillinger → Logon → Automatiske konti), opretter en identitetsudbyder, såsom Okta, Microsoft Entra ID eller Google Workspace, Perfuse-konti selv på /scim/v2/Users, så en person, der forlader organisationen, mister adgang, når deres katalogkonto deaktiveres, ikke når nogen husker. Udbederen autentificerer med en API-nøgle, der indeholder admin-rollen, oprettet under Brugere → Maskinlegitimationer, sendt som en bærertoken.
- Deaktivering af en konto afslutter dens sessioner med det samme, og serveren kontrollerer, at ingen overlevede, før den besvarer. En provider bliver
aldrig underrettet om, at en konto er deaktiveret, når det ikke er tilfældet, fordi en provider ikke gentager, hvad den har fået at vide, er lykkedes.
- En sletning deaktiverer først, derefter sletter, så en fejl halvvejs efterlader en konto, som ingen kan logge ind med. Audit-historikken for
en fjernet konto gemmes.
- Rollen kommer fra personens grupper eller roller, der matchas ved navn: en gruppe, hvis navn indeholder *admin*, *editor*, *operator*,
*viewer* (eller *read-only*) eller *monitor*, giver denne rolle, så APP-Perfuse-Editor og Perfuse Operators fungerer, som de er navngivet. Alt andet får -scim-default-role, viewer medmindre andet er angivet. Platform kan aldrig tildeles på denne måde.
- Ingen adgangskoder. En konto oprettet via SCIM logger ind via identitetsudbyderen; en anden adgangskode, som ingen længere oppe
kender, ville overleve en deaktivering der.
/scim/v2/ServiceProviderConfigangiver, hvad der understøttes: oprettelse, læsning, erstatning, retning og sletning af brugere samt filtre op til 200
resultater. Bulkoperationer, sortering og ETags understøttes ikke.
17.14 Hvad Perfuse ikke gør
Det krypterer ikke databasen i hvile. Brug filsystem- eller volumekryptering.
Det administrerer ikke sine egne certifikater eller forlænger dem. Peger på filer og administrer disse filer med det, du allerede bruger.
SAML er verificeret mod to uafhængige udbydere, hver med en rigtig browser-login, en rigtig påstand og en rigtig session: Keycloak 26 og Microsoft Entra. To sager betyder mere end dobbelt så meget som en, fordi de to er uenige på en måde, der viste sig at være bærende - Keycloak skriver sin påstand med navnerumsprefix og Entra skriver de samme elementer uden dem, og den ene fejl, dette område har haft, var i prefixhåndtering.
Start med at læse din udbyders metadata. Indstillinger, derefter Log på, derefter SAML-fanen: give metadata-URL'en eller indsæt dokumentet, og log på-adressen og signaturcertifikatet udfyldes automatisk. Hver SAML-udbyder offentliggør en af disse - Okta, Entra, AWS IAM Identity Center, Keycloak, ADFS - og det er forskellen på at konfigurere en udbyder og at transskribere en. At gøre det manuelt betyder at finde certifikatet inde i XML, fjerne linjeskiftene fra base64 og indpakke det i PEM-overskrifter, hvor et enkelt forkert mellemrum producerer en signaturfejl, der ikke siger noget om formatering.
Hvad der kommer tilbage, beskrives snarere end dumpes: hver certifikats emne, udløb og SHA-256-fingerprint, så du kan kontrollere det mod, hvad din udbyders egen console viser. Et udløbet certifikat kaldes udløbet snarere end efterladt som en dato at sammenligne med øjet. Intet gemmes ved at læse - at anvende det på formularen er et separat klik, fordi et dokument, som nogen har indsætter, endnu ikke er en beslutning om, hvad der skal tillides.
En metadata-URL hentes over https kun, og adressen kontrolleres mod den samme politik, der regulerer kanaldestinationer, så dette kan ikke bruges til at få serveren til at læse skyinstans-credentials. Omdirigeringer følges ikke, fordi en tilladt adresse, der omdirigerer til en blokeret, ville gå lige forbi denne kontrol.
Hvis du konfigurerer Entra, vil fem ting ikke matche, hvad eksemplerne viser dig. Det sender ingen email-påstand overhovedet. Dets NameID er en uigennemsigtig identifikator snarere end en adresse. Det sender ingen gruppepåstand, medmindre programmet er eksplizit konfigureret til at udsende en, så en rolletilknytning skrevet mod grupper afviser hver logon. Når grupper udsendes, er de objekt-GUID'er snarere end navne, medmindre din lejer synkroniserer fra lokale Active Directory. Og dets påstandsnave bor under schemas.microsoft.com/identity, hvor de fleste dokumentationer viser schemas.xmlsoap.org. Perfuse håndterer alle fem; de er opført, fordi de fire første ellers vil se ud som fejl i Perfuse, når de er Entra, der er Entra.
Denne forskel er ikke teoretisk her. Den første ægte Keycloak-påstand fejlede helt, fordi den kanoniske form, som signaturen dækker, blev beregnet med navnerumsprefix droppet. Ingen rigtig identitetsudbyder kunne have logget nogen ind, og pakkenes egne fem kanoniseringsforsøg passede hele tiden - hver af dem signeret og verificeret med den samme kode, så de kun beviste, at det var enige med sig selv. Hvis du er den første til at pege en anden udbyder på dette, forvent at finde noget, og serverloggen vil navngive det stadium, der fejlede.
18 Operationer
18.1 Installation
En binær fil og to stier: en mappe med kanalfiler og en databasefil. Der er ingen programserver, ingen separat webtier og ingen message broker påkrævet.
perfuse serve -channels ./channels -db ./perfuse.db -addr 0.0.0.0:8443 \
-tls-cert ./cert.pem -tls-key ./key.pem
Kør det under hvad som helst, der overvåger tjenester på værten - systemd, launchd, en container runtime. Det forventer at blive genstartet, hvis det afsluttes.
18.2 Hvor data kan gå (dataresidens)
serve -residency (Indstillinger → Data → Hvor data kan gå) angiver de cloudregioner, som denne servers data kan sendes til eller læses fra: områder (eea, uk, ch) og regionskoder (eu-central-1, uksouth, europe-west2), komma-separeret. eea er AWS-, Azure- og Google Cloud-regionerne i Det Europæiske Økonomiske Samarbejdsområde (Frankfurt, Irland, Paris, Stockholm, Milano, Spanien; Nederlandene, Tyskland, Frankrig, Sverige, Norge, Italien, Polen, Spanien; Belgien, Nederlandene, Tyskland, Italien, Frankrig, Finland, Spanien, Polen), uk er dem i Storbritannien, ch er dem i Schweiz.
Med det sat, afvises en kanal, når den gemmes og når den indlæses, hvis en connector nævner en region uden for listen: en S3-, SQS- eller SNS-kilde eller -destinationens region (eller dens endpoint, når det er en AWS-vært), eller enhver destination, hvis adresse er en AWS-vært, der bærer en region (sqs.us-east-1.amazonaws.com, en API-Gateway-URL). Serveren afviser at starte med en sporingssamler eller en alert-webhook i en anden region. En connector, der peger på en vært, der ikke nævner nogen region (et hospitals eget system, MinIO på stedets netværk), bliver ikke bedømt: behandlingsoptegnelsen på Datatilsynsskærmen viser hver vært, som hver kanal sender til, til controlleren at kontrollere. Dashboardet og Datatilsynsskærmen siger, hvor data kan gå.
Vært i EU og Storbritannien. deploy/hosted indeholder OpenTofu (eller Terraform) til en værtsserver per organisation i Frankfurt, Irland eller London: serveren, dens PostgreSQL-database og sikkerhedskopier, en sikkerhedskopibucket, logfiler og supportsessionsoptagelser, alt krypteret med en nøgle i regionen, intet replikeret til en anden region, support gennem Session Manager kun, og Perfuse kørt med -residency. Dets README siger, hvad det bygger, hvad det ikke dækker, hvad der er verificeret (valideret og planlagt mod en rigtig konto; endnu ikke anvendt) og hvad det koster til listepris i hver region.
18.3 Konfiguration som filer
Kanaler er filer, hvilket betyder, at de kan være i versionsstyring, gennemgået før installation, og sammenlignet efter en incident.
Filer genlæses uden genstart. En fil, der ikke kan parses, rapporteres, og den tidligere indlæste version fortsætter med at køre, så en syntaksfejl kan ikke tage en fungerende feed af luften.
18.4 Sikkerhedskopi
To ting at sikkerhedskopiere, og de har forskellige egenskaber.
Kanalmappen er lille, ændrer sjældent, og er det, du behøver for at genopbygge tjenesten. Sikkerhedskopier den som konfiguration; versionsstyring er normalt tilstrækkeligt.
Databasen indeholder meddelelser, brugere og revisionshistorik. Den er stor, ændrer konstant, og indeholder kliniske data — så den kræver sikkerhedskopi som kliniske data, med den bevarelse og kryptering, det indebærer. At miste den stopper ikke tjenesten, men den mister evnen til at undersøge noget, der allerede er sket, og den historik, der afhænger af rytme-læren.
18.5 Genstartadfærd
Ved genstart indlæses kanaler, og kilder begynder at lytte. Køede leveringer genoptages.
Det, man skal forstå, er, hvad der sker med arbejde under flyvning. Under den standardmæssige on_delivery-bekræftelse, bliver en meddelelse, der endnu ikke er bekræftet, ikke bekræftet, så afsenderen vil gensende den — hvilket er det korrekte udfald. Under on_receipt, er en meddelelse, der blev bekræftet, men endnu ikke leveret, i køen, og genoptages; hvis køen er deaktiveret, går den tabt. Se meddelelsesflow.
18.6 Opgradering
Erstat binærfilen og genstart. Databasenskemaet migreres automatisk fremad ved start.
Migrationer er kun fremadgående. Der er ingen nedgradering, så en tilbagerulning til en tidligere binærfil efter skemaet er flyttet, kræver den tidligere database. Tag en kopi før opgradering — dette er den eneste operationelle forsigtighed, der er værd at være disciplineret om.
18.7 Overvågning
Advarsel fra inden for Perfuse er dækket i advarsel og er, hvad der vil fortælle dig, at en feed er stoppet.
Udefra overvåges processen, disken, databasen er på, og om webgrænsefladen responderer. Databasen vokser, og en fuld disk stopper meddelelsesoptagelse, hvilket er en fejltilstand med ingen anden advarsel.
18.7.1 SNMP
Til overvågningsværktøjer, der taler SNMP (Nagios, Zabbix, PRTG, SolarWinds, LibreNMS), kører Perfuse en læse-only SNMPv2c-agent og sender en fælde, når en alarm udløses eller løses. Indstil det under Indstillinger → Overvågning → SNMP, eller med flags:
perfuse serve -snmp-listen :161 -snmp-community 'long-random-community' -snmp-allow 10.0.5.0/24 \
-snmp-traps nms.example.org,10.0.5.9:1162
- Agenten besvarer GET, GETNEXT og GETBULK, og kun fra netværkene i
-snmp-allow: v2c's fællesskab er en adgangskode sendt i klartekst, så det er aldrig åbent for alle. Et fællesskab under 6 tegn ellerpublic/privatestopper serveren ved startup. - Den betjener systemgruppen (sysDescr, sysUpTime, sysName fra fleet-mærket, sysContact, sysLocation), totals under
BASE.1 (kanaler, kører, fejl, modtaget, leveret, fejlet, køet) og en kanal-tabel under BASE.2.1 (navn, kører eller stoppet, modtaget, leveret, fejlet, køet, alderen af den ældste køede besked). Tallene er de samme, som dashboard og /metrics viser.
- Fælder går til hver manager i
-snmp-traps:BASE.0.1en alarm udløst,BASE.0.2den løst, medførende alarmens
type, alvorlighed, kanal, destination og sammenfatning. Aldrig beskedindhold. En anerkendt alarm sender ingen fælde.
BASEer1.3.6.1.4.1.8072.9999.9999.16(Net-SNMP's eksperimentelle område) medmindre-snmp-base-oidplacerer det under
jeres eget virksomhedsnummer. Hent MIB på Indstillingspanelet (eller GET /api/snmp/mib) giver en MIB for den basis, der er i brug; det samme panel siger, om agenten besvarer og hvor mange fælder der er sendt.
18.7.2 En oversigt over hver grænseflade
-inventory interfaces.md (Indstillinger → Overvågning → Inventar) skriver en Markdown-dokument, der listar hver kanal - dens format, om den kører, hvad den modtager fra og hvad den sender til - efterfulgt af hver kanals egen beskrivelse, og omskriver den hver -inventory-every (en dag som standard). Den er ment til at committes ved siden af kanal-filerne eller overdraget til en revisor og læst uden for applikationen.
18.8 Kapacitet
Perfuses gennemløbsloft er ikke målt på rigtigt hardware under rigtigt trafik, og denne vejledning vil ikke udskrive et tal, det ikke kan støtte.
Hvad der kan siges: arkitekturen er en goroutine per forbindelse med køer per destination, så gennemløb skalerer med destinationer snarere end at være serieliseret gennem en arbejder; meddelelsesoptagelse er en SQLite-skrivning per meddelelse, hvilket gør disken til den mest sandsynlige første begrænsning; og meddelelseslagringen vokser lineært med trafikken, så bevarelse er indstillingen, der styrer langsigtede diskanvendelse.
Hvis du størrelsesbestemmer dette til en stor feed, mål det med din egen trafik ved hjælp af det genererede testkorpus beskrevet i testing. Det er det ærlige svar, og det er også et bedre svar end et tal fra en anden persons hardware.
18.9 Hvor denne installation blev fast
Aktiviteten medfører en panel, synlig for administratorer, der viser, hvad Perfuse har nægtet at gøre — grupperet efter besked, mest hyppigt først — og hvor langt installationen er kommet i retning af en fungerende kanal.
Det eksisterer, fordi hver anden påstand om, hvorvidt denne software er let at bruge, kommer fra de personer, der skrev den. En afvisning gør ikke: nogen ønskede noget, serveren sagde nej, og ingen af parterne gættede. Det er det eneste bevis i produktet, der ikke kommer fra BioDream LLC.
Kanalen navngiver det skridt, der endnu ikke er sket, i stedet for at lade tidsstempel sammenlignes. Tilstanden, der er værd at overvåge, er beskeder ankommer, og ingen er blevet leveret til en destination — en kanal kan tage trafik i uger og levere ingen af det, og fra hver anden skærm ser det ud, som om det fungerer.
Intet, nogen har tastet, bliver optaget. Tabellen indeholder anmodningsruten med identifikatorer erstattet af {id}, status og serverens egen sætning. En valideringsbesked navngiver et felt og en regel, som er den nyttige del; værdien, der brød reglen, er meget ofte patientdata, og en tabel over disse ville være en værre ansvarliggørelse end den friktion, den målte.
To bevidste udeladelser. En 5xx er en fejl i denne software og er allerede logget som en — at blande de to ville begrave tilfældene, hvor nogen ikke kunne finde ud af, hvad de skulle taste, under tilfældene, hvor intet, de tastede, ville have hjulpet. Og en udløbet session producerer en række 401'er, der ikke siger noget om brugervenlighed og ville oversvømme hver opdagelse, der gør.
Læsning af rapporten trimmer også tabellen til de seneste fem tusinde rækker. Afvisninger er 4xx-svar, så det vokser langsomt, og læsning er et naturligt øjeblik at rydde op: ingen timer og intet, der kører, når ingen ser på.
GET /api/friction returnerer det samme for enhver, der hellere læser det som JSON.
18.10 Logfiler
Perfuse logger til standardoutput, som er, hvor en supervisor eller container-runtime vil samle det.
Beskedniveauets detaljer går til beskedlagret i stedet for logfilen, bevidst. En loglinje per besked på en travl feed er støj, der skjuler de linjer, der betyder noget, og lagret er søgbart på måder, en logfil ikke er.
Logfilen medfører, hvad lagret ikke kan: start og stop, konfigurationslastresultater, kanaltilstandsændringer og fejl, der ikke kan tilskrives en bestemt besked.
18.11 Kørsel af to forekomster
To eller flere servere kan køre som én cluster: når den, der kører en feed, stopper, overtager en anden den inden for få sekunder, og afsenderens næste forsøg når den. De deler én PostgreSQL-database i stedet for hver især at holde en SQLite-fil, og enes mellem sig gennem den, om hvilken af dem, der kører hvad.
perfuse serve -db 'postgres://perfuse:SECRET@db.hospital.internal/perfuse?sslmode=verify-full' \
-cluster active-passive -node-name perfuse-01 -node-address https://perfuse-01.hospital.internal:8443 \
-data /var/lib/perfuse
Start hver server på samme måde med dens eget navn og adresse. Databasekontoen skal oprette tabeller og, en gang, citext-udvidelsen (eller en administrator køre CREATE EXTENSION citext først). Hver server holder sine egne filer i -data: dens log, dens node-id og dens kopier af konfigurationen.
To måder at dele arbejdet på.
active-passive: lederen kører hver kanal og hver opgave, der skal køres én gang (FHIR-abonnementsmeddelelser). De andre venter. Det er det nemmest at forstå, og det er, hvad et websted med én busy server og en reserve vil have.active-active: kanalerne er fordelt over de aktive servere, omtrent ligeligt. En server, der stopper, overdrager sine kanaler til de resterende; en server, der tilslutter sig, tager sin andel, når kanaler bliver ledige, én ad gangen. Kanaler, der ruterer til hinanden (en kanaldestination), kører på én server og flytter sig sammen, fordi routing sker inden for en server. En administrator kan manuelt flytte en kanal fra Overvågning → Flåde; den bliver, hvor den blev sat, så længe serveren er i live.
Hvem kører hvad, og intet øjeblik med to. Hver arbejdsenhed er en leje i databasen, der fornyes hver femte del af -cluster-lease (15 s som standard). En server, der ikke kan fornye den (den crashede, dens netværk fejlede, databasen er utilgængelig), stopper selv arbejdet, når dens egen ur siger, at lejen er næsten udløbet, med en tredjedel af lejen til overs. En anden server tager lejen kun efter, at dens egen ur har set lejens tæller stå stille i en hel leje. Ingen ur sammenlignes med et andet, så servernes ur og databasens ur behøver ikke være enige; de behøver kun at køre i omtrent samme takt, hvilket ehver ur gør. Mellem den gamle indehaver, der stopper, og den nye, der starter, er der et kort hul med ingen, der lytter, hvilket en afsender ser som en afvist forbindelse og prøver igen; der er aldrig et øjeblik med to, der lytter på én feed eller to arbejdere, der tømmer én kø.
En server, der lukker ned ordentligt, eller en administrator, der vælger Træd tilbage på lederen, overdrager straks i stedet for efter leaset.
Hvad hver server deler. Beskeder, leveringskøen, konti og sessioner, overvågningsloggen, FHIR-lageret, terminologitabellerne og patientindekset er i databasen, så uanset hvilken server der kører en kanal, finder den køen, som den sidste har ladet. Kanalens filer, indstillingsfilen, alarmregler, single sign-on-filer, logo, Direct-certifikater og gemte visninger opbevares på samme måde på hver server via databasen: hver server har sin egen kopi på sin egen disk, og en ændring på en server (i konsollen, manuelt, via en git pull) når de andre inden for to sekunder, og en kanal, der er ændret på en anden server, genstartes med sin nye fil. Den samme fil, der er ændret på to servere på samme tid, beholder den version, der nåede databasen først, og den anden ved siden af som NAME.conflict-SERVER. Indstillinger, der kun gælder ved genstart (beskededatabasen, de porte, som konsollen lytter på), anvendes af hver server ved dens næste genstart, og loggen angiver det. Navne på noget på en maskine, der bliver på den servers kommandolinje og uden for den delte fil: certifikatet og nøglen (-tls-cert, -tls-key), SNMP-lytadressen og serverens navn i spor. Indstillinger viser dem som sat på hver server.
Start og stop. At starte eller stoppe en kanal på en server gælder for clusteret: den server, der kører den, starter eller stopper den inden for et sekund, og svaret angiver, hvilken server det er.
Loadbalanceren foran. En feeds adresse skal nå frem til den server, der kører den. Peger afsenderen på en virtuel adresse (en loadbalancer, en flydende IP, et DNS-navn med en kort TTL) og lad loadbalanceren kontrollere /readyz?channel=NAME, som kun svarer 200 på serveren, der kører den kanal, og 503 på de andre. Til konsollen er /readyz 200 på hver live-server; /readyz?role=leader kun på lederen.
På en AWS Network Load Balancer, brug en target gruppe per feed med en HTTPS-sundhedstjek på /readyz?channel=NAME, et interval på 5 sekunder og en grænse på 2, og slå cross-zone load balancing til. Med den slukket, ser loadbalancerens node i en zone, hvor ingen server kører feeden, kun usunde mål, sender til alle alligevel, og en afsender, der blev resolveret til den node, venter, til feeden kommer tilbage til sin zone (95 sekunder i en test). Sæt deregistreringsforsinkelsen til 0, da en server, der stopper med at køre en feed, ikke har noget at dræne.
Hvad der blev testet. To servere på PostgreSQL 16, en afsender, der streamer 300 meddelelser, gensender, indtil de blev besvaret, og serveren, der kørte feeden, blev dræbt med SIGKILL to gange (først den ene, så den anden efter den første kom tilbage). Hver bekræftet meddelelse nåede modtageren, i begge former, der blev prøvet: leveret før bekræftelsen, og køet i den delte butik, mens modtageren nægtede (185 bekræftede meddelelser ventede i køen ved dræbet; overlevenden leverede dem alle). Failover tog 3 til 4 sekunder på en 3-sekunders leje. En duplikat er mulig og blev set én gang ud af 600: en meddelelse, som den døende server leverede og ikke kunne bekræfte, som afsenderen gensendte. Koordinatorens egne tests dækker et crash, en server, der blev skåret af fra databasen, mens den kører, step-down, spredning, flytninger og delt konfiguration med konflikter. De køres i CI mod PostgreSQL med racedetektoren, med hele suiten.
Det samme blev så gjort på AWS: to Linux-servere (ARM) og en Windows Server 2022 i tre tilgængelighedszoner, Amazon RDS PostgreSQL 16 over TLS med certifikatet kontrolleret (sslmode=verify-full), en intern Network Load Balancer foran, og afsendere, der gensender, indtil de blev besvaret:
| Test | Beskeder | Bekræftet, men tabt | Duplikater | Længst en afsender ventede |
|---|---|---|---|---|
| Aktiv-passiv, serveren, der kører feeden, dræbt to gange (Linux, så Windows), modtager, der nægter imellem | 2.000 | 0 | 0 | 15 s |
| En Linux-leader afbrudt fra databasen (brandmur), dens proces efterladt kørende | 3.000 | 0 | 1 | 16 s |
| En Windows-leader afbrudt fra databasen | 3.000 | 0 | 0 | 20 s |
| Lederen dræbt, mens en servers ur løb 2 minutter foran og en andens 90 sekunder bagud | 2.000 | 0 | 0 | 18 s |
| Aktiv-aktiv, fire feeds over tre servere, en dræbt og genstartet | 6.000 | 0 | 2 | 24 s |
Med den standardmæssige 15-sekunders leje, stoppede en server, der blev skåret af fra databasen, sin feed 10 sekunder efter sin sidste fornyelse, og den næste server startede den 6 til 8 sekunder efter det: aldrig begge på én gang. De skæve ure ændrede intet, da intet ur sammenlignes med et andet.
Ikke endnu. En cluster betjener én organisation: -cluster med -multi-tenant er afvist. Lyttere flytter med deres kanal, så loadbalanceren er stedets at levere.
En server på egen hånd fungerer, som den altid har, på SQLite, uden noget cluster.
18.12 Mere end en server
Et sted med to instanser har et spørgsmål, som ingen enkelt konsol kan besvare: kører alt? Mirth opkræver for svaret. Dette er flådebilledet.
Én instans er udpeget som det sted, man ser. Den afhører de andre og viser hver kanal på hver server i én tabel, med en opsummering på tværs af alle.
18.12.1 Tilføje en peer
Indstillinger → Flåde, eller PUT /api/fleet/peers. En peer har brug for et navn, en URL og en token, der er udstedt af peer'en selv.
Navnet er påkrævet og er ikke URL'en, fordi en URL ikke er noget, nogen genkender klokken tre om morgenen.
Tokenet skal oprettes på peer, under Brugere, og skal være viewer-scoped. At tilføje en peer uden et token er afvist, med disse instruktioner, i stedet for at blive accepteret og så fejl på hver afhøring. At læse en anden instans' sundhed er den mindste privilegie, der er, og det er den eneste, flådebilledet har brug for.
18.12.2 Kontrol af en peer, der er af
allow_control tillader start og stop af den peers kanaler herfra. Det er slukket som standard, og hver brug er auditeret efter navn.
De to privilegier er bevidst adskilt. At læse en anden servers sundhed er mindre; at stoppe dens kanaler under en transfusion er ikke, og den sidste skal aldrig ankomme stilleheden hæftet på den første.
18.12.3 Hvad rapporten siger
Hver server rapporterer det totale antal kanaler, hvor mange der kører, stoppet eller fejlet, koeniveauet og alderen af den ældste ventende besked, hvor mange alerts der udløses, og hvorvidt den afvikles ved lukning.
Opsummeringen tæller servere på tre måder: nåbar, unåbar og ubestemt. Den tredje dækker peers, hvis sundhed ingen kender — endnu ikke afhørt, nægter tokenet eller kører en version, denne ikke kan læse. Den holdes adskilt fra unåbar, fordi 'vi kan ikke sige' ikke er 'det er nede', og at folde de to sammen er, hvordan et flådebillede starter med at lyve.
Af samme grund bærer opsummeringen knownFrom: hvor mange instanser kanal- og køfigurerne faktisk blev læst fra. Tolv kanaler, der kører på tværs af en flåde, betyder noget andet, når to af fem servere ikke svarede, og totalen alene kan ikke sige det.
En unåbar peer siger hvorfor på en måde, en operatør kan handle på. En nægtet forbindelse rapporteres som værende op med intet, der lytter på den port, hvilket er et andet problem end en vært, der ikke svarer overhovedet.
18.12.4 Urskæv
Opsummeringen rapporterer den største forskel mellem servernes ure i den: Værd at have et tal for: at korrelerer en incident på tværs af to instanser, hvis ure er uenige med fire minutter, producerer en sekvens af begivenheder, der ikke skete.
18.12.5 Hvad en peer lærer om dig
Tællinger og hastigheder. Rapporten, én instans giver en anden, indeholder ingen meddelelses-id'er, ingen kanal-niveau-detajler og ingen patientdata af nogen art.
Det er dét, der forhindrer, at et fleet-overblik er en centralisering af kliniske data: den samlerenhed lærer, hvor mange kanaler der kører, og intet som helst om, hvad der flød gennem dem. Hvis du ønsker beskederne, åbner du serverens egen console, hvor audit-loggen optegner, at du gjorde det.
18.12.6 En peer, der peger på sig selv
Afvist. En instance, der afhenter sin egen adresse gennem sin egen HTTP-stak, vises to gange i sit eget fleet-overblik og tæller dobbelt for hver kanal, den har.
18.12.7 TLS på interne netværk
insecure_skip_verify accepterer en peers certifikat uden at verificere det. Det findes, fordi hospitalers infrastruktur kører på private certifikatudstedere, og at nægte at fungere overhovedet ville få folk til at gå over til plain HTTP, hvilket er værre. Det er navngivet sådan, så det ikke kan forveksles med en god idé.
19 Kommandolinjen
Alt, hvad Perfuse gør til et kørende system, er tilgængeligt fra webgrænsefladen, og det er bevidst: en funktion, der kræver en terminal, behandles som en fejl i stedet for en designvalg. Kommandoerne her er for arbejdet, der sker *omkring* et kørende system — før det eksisterer, mens du beslutter, om du skal stole på det, og når du har brug for at give noget til en anden.
Flere af dem rører slet ikke en server. perfuse explain, perfuse profile, perfuse deident og perfuse translate læser filer og skriver filer, så de er nyttige på en bærbar computer mod en ejendom, der stadig kører helt på noget andet.
Kør en kommando med -h for dens flags. Dette kapitel siger, hvad hver enkelt er *til*.
-h genereres fra koden og kan ikke falde ud af dato; en liste, der er kopieret ind i prosa, kan.19.1 Kører kanaler
19.1.1 perfuse serve
Kører webgrænsefladen og API'et, og kører som standard også kanalerne. Dette er kommandoen, en installation bruger.
Hver mulighed, den tager, er opført i Serverindstillinger, genereret fra programmet. Den nægter at betjene plain HTTP til andet end loopback, medmindre du passerer -insecure. Det er ikke konfigurerbar høflighed: klinisk trafik og en sessionscookie over en ukrypteret LAN-forbindelse er en rapporterbar begivenhed, og flaget findes, så at sige ja er en beslutning, nogen har truffet, snarere end en standard, de har arvet. Se sikkerhed.
19.1.2 perfuse run
Kører kanaler fra YAML uden webgrænseflade og uden database. Nyttigt i en container, der skal gøre nøjagtig én ting, og nyttigt, når du vil se en kanals adfærd uden noget andet kører.
19.1.3 perfuse check
Validerer kanaldefinitioner og udskriver, hvad de gør, uden at køre dem. Den anden halvdel er pointen: en kanal, der indlæses, er ikke nødvendigvis den kanal, du mente, og at læse en plain-English-resume af, hvad en fil vil gøre, fanger en fejl, som validering ikke kan se.
Afslutter med en ikke-nul-værdi ved en fejl, så den hører til i hvilke som helst checks, der kontrollerer din konfiguration, før den når en server. -quiet udskriver intet ved succes, til den brug.
-allow-metadata-egress tillader destinationer, der peger på cloud-instans-metadata-adresser. Disse adresser indeholder maskinens egne legitimationsoplysninger, så en kanal, der kan overtales til at sende derhen, er en lækkage af legitimationsoplysninger; kontrollen nægter dem, medmindre du siger andet.
19.1.4 perfuse test
Kører tests, der er skrevet mod kanaldefinitioner. En test sender en besked gennem kanaltets rigtige filter, rigtige transformationer og rigtige scripts, i den rigtige rækkefølge, med kun netværket erstattet — så det, der passerer her, er, hvad kanalen gør.
Tests befinder sig i *_test.yaml eller *.test.yaml ved siden af kanalerne. Se test.
19.2 Migration fra en anden motor
Disse tre er dem, der skal køres først, før noget andet beslutes. Se migration.
19.2.1 perfuse explain
Læser Mirth, Open Integration Engine og BridgeLink-eksport — en kanal, en kanalgruppe eller en hel server-sikkerhedskopi — og beskriver, hvad hver kanal gør, og hvad der ville blokere en migration. Den ændrer intet og har ikke brug for en Perfuse-installation, hvilket gør det til det billigste mulige første skridt: peg på en eksport af din ejendom og læs, hvad der kommer tilbage.
-strict afslutter med en ikke-nul-værdi, hvis noget er blokeret, så den kan styre en pipeline. -json udsender de samme resultater for en maskine.
19.2.2 perfuse translate
Konverterer Mirth, Open Integration Engine og BridgeLink-eksport til Perfuse-kanalfiler: en kanal, en kanalgruppe, en kode-skabelon-eksport eller en hel server-sikkerhedskopi.
perfuse translate -o ./kanaler server-sikkerhedskopi.xml
Kode-skabelon-biblioteker skrives til lib/ ved siden af kanalerne, og hver kanal, Mirth havde en bibliotek aktiveret for, inkluderer det. Se migration.
Intet bliver tavs drop. Hver del af en kanal er enten oversat, overført som et script, der kører uændret, eller rapporteret som krævende en menneskelig. Den tredje kategori er den ærlige — en oversætter, der producerede en ren og pæn fil for hver indgang, ville være skjult for de beslutninger, du mest har brug for at træffe.
19.2.3 perfuse compare
Kører den samme trafik gennem to motorer og rapporterer, hvor de er uenige, grupperet efter felt.
Dette er kommandoen, der besvarer spørgsmålet "hvorfor skal jeg stole på dette med patientdata", og den besvarer det med bevis, du har indsamlet, snarere end en påstand, der gøres her. Det er det anbefalede sidste trin, før du skifter over, og det anbefalede første trin i enhver diskussion om, hvorvidt Perfuse er klar.
19.3 Forståelse af en feed
19.3.1 perfuse profil
Læser meddelelser og rapporterer, hvad der faktisk er i dem: hvilke felter altid er udfyldt, hvilke aldrig er, de faktiske værdisæt for kodede felter, gentagelsesantal og hvilke Z-segmenter, der vises.
Værdier rapporteres kun for felter, hvis værdier danner et lille kodeudsnit, så en profil af rigtig trafik ikke bliver en fil fuld af patientdata.
Gemning af en profil og sammenligning med den senere er, hvordan du opdager, at en afsender har ændret noget:
perfuse profil -save sidste-måned.json korpus/ perfuse profil -imod sidste-måned.json ny/
19.3.2 perfuse kontrakt
Omdanner outputtet af denne tankegang til noget, der kan gøres gældende. En kontrakt siger, hvordan en feed skal se ud, så den dag det ændrer sig, bliver du underrettet, snarere end at opdage det uger senere fra en modtager, der fik fejl — meddelelserne er stadig gyldige HL7, når et felt forsvinder, så intet andet lægger mærke til det.
perfuse kontrakt fremme -o adt.kontrakt.yaml korpus/ perfuse kontrakt kontroller adt.kontrakt.yaml i-dag/
promote genererer et startpunkt, ikke et svar. Læs det og slet det meste: hver linje optager, om den blev målt eller besluttet, hvilket er, hvad fortæller dig, hvilke linjer du skal beholde.
19.4 Produktion af meddelelser
19.4.1 perfuse generer
Producerer syntetiske HL7 v2-meddelelser. Alt er opfundet — åbenlyst fiktive navne, sekventielle identifikatorer, opfundne adresser — så outputtet er sikkert at committe, sende og vedhæfte til en billet.
Det kan sende direkte til en kanal snarere end skrive en fil, hvilket er den hurtigste måde at bevise, at en lytter virker:
perfuse generer -n 100 -send 127.0.0.1:6661
19.4.2 perfuse deidentificer
Læser rigtige meddelelser og skriver en korpus, der beholder deres struktur, deres koder og deres interval, og intet af, hvad der identificerer en patient. Dette er forskellen på at kunne sende nogen en rekonstruktion og ikke.
Det er ikke det samme værktøj som perfuse generate, og forskellen er væsentlig. Genererede meddelelser er opfundne og derfor sikre, men urealistiske; en de-identificeret samling er *afledt fra rigtig trafik*, så den genskaber de særheder, der faktisk bryder grænserne.
To egenskaber, der er værd at forstå, før du bruger det:
- Samme salt producerer altid samme korpus, så en fælles korpus kan genoprettes snarere end arkiveres.
- Behold saltet hemmeligt. Pseudonymer er afledt af rigtige værdier, så enhver, der har saltet, kan bekræfte en gætning om, hvem en post henviser til.
-keep-local-segments passerer Z-segmenter uændret og er usikkert. Z-segmenter er præcis, hvor stederne putter navne, noter og frit tekst, så at beholde dem modsiger formålet med værktøjet. Det eksisterer, fordi et strukturelt problem nogle gange er *i* et Z-segment, og så har du brug for en korpus, du ikke må dele.19.5 Flytning af meddelelser for hånd
19.5.1 perfuse lyt
Accepterer HL7 v2 over MLLP og bekræfter det. En modtager, der eksisterer, så længe du har brug for det, for at bevise, at en afsender kan nå denne maskine overhovedet.
19.5.2 Perfuse send
Sender HL7 v2-besked over MLLP fra filer.
19.6 FHIR
19.6.1 Perfuse fhir
Konverterer HL7 v2 til FHIR, validerer FHIR eller serverer det, afhængigt af underkommandoen.
Valideringsunderkommandoen er nyttig i sig selv: den fortæller dig, om en ressource, som nogen har sendt dig, opfylder US Core, som er profilen, som den amerikanske lovgivning er skrevet imod. At kunne svare på det uden at adoptere en motor er pointen.
19.6.2 perfuse x12
Converts X12 (or other delimited EDI) to the XML Mirth Connect and Open Integration Engine write for it, and back: perfuse x12 xml FILE and perfuse x12 from-xml FILE, standard input when no file is given. The output is what OIE 4.6 writes, byte for byte, so it can be compared with what a Mirth server produced or fed to a system built against it. A channel does the same with x12.arrives_as: xml and a destination's x12_as: xml; see X12.
19.6.3 Perfuse sof
Runs a SQL on FHIR ViewDefinition over FHIR files (the NDJSON of a bulk export, Bundles or JSON arrays; - for stdin) and writes the table: -view FILE (required), -format csv|ndjson|json|parquet (csv by default), -header=false, and -o FILE (required for Parquet). See SQL on FHIR views.
19.6.4 Perfuse measure
Evaluere en kvalitetsmåling med FHIRPath-kriterier over FHIR-filer (NDJSON fra en bulk-eksport, Bundles eller JSON-arrays; - for stdin) og skriver MeasureReport. Flag:
-measure FILE, or-measure example:IDfor a shipped example: required.-exampleslists the examples.-period-startand-period-end: required.-type summary|subject|subject-list.-subject Patient/ID.-reporter NAME.-o FILE.
Se digitale kvalitetsmålinger.
19.6.5 FHIR-flag på perfuse serve
| Flag | Effekt |
|---|---|
-fhir | Servér FHIR-endpoint på /fhir. Slået til som standard. |
-fhir-version | Udgaven, der servérer. R4 som standard. |
-fhir-read-only | Afvis skrivning. |
-fhir-api-tokens | Med SMART konfigureret, acceptér Perfuse API-tokens samt SMART-tokens (slået fra som standard; også under Indstillinger → FHIR). |
-fhir-bulk-export | Aktivér $export. Slået fra som standard. |
-fhir-subscriptions | Aktivér emneabonnementer: møde- og appointmentsnotifikationer til endepunkter, som FHIR-klienter vælger. Slået fra som standard; kræver R4 og et skrivbart endepunkt. |
-fhir-subscriptions-allow-http | Tillad abonnementer at levere til almindelig http. Kun til en testmodtager, aldrig til patientdata på et netværk. |
-fhir-patient-directory-search | Tillad en token, der er begrænset til en patient, at søge i kataloget (praktiserende, organisationer, lokaliteter) inden for dens omfang. Slået fra som standard. |
-fhir-declares | Guider, som denne server erklærer i sin kapacitetserklæring, adskilt af komma: en guides CapabilityStatement-adresse eller Type=profile-adresse. En erklæring til klienter og testkits; den ændrer intet, som lagret accepterer. |
Lagringsstedet gemmer dokumenter samt ressourcer: et dokument, en samling eller en meddelelse-Bundle, der er lagt til /fhir/Bundle/{id}, gemmes helt, læses tilbage med hver post i den version, der serveres, og findes ved type, identifier, timestamp og composition. En transaktion, der er lagt til der, gemmes som en post og ikke anvendes; en POST til /fhir anvender en.
Svar er JSON, medmindre klienten anmoder om XML (Accept: application/fhir+xml, eller _format=xml). Perfuse læser kun JSON: en brødtekst sendt som XML får 415. En dokument-Bundle, der er POSTet til /fhir, gemmes, når denne server har, efter identifikator, patienten og mødet, som dets Composition-navne, og afvist med 422 ellers. En Binary-læsning med Accept sat til sin egen indholdstype svarer med indholdet selv.
19.7 Opsætning og drift
19.7.1 Perfuse init
Opretter directory-layoutet, et eksempelkanal og en service-definition for det operativsystem, det køres på. Intet eksisterende erstattes, medmindre du passerer -force.
Perfuse init -dir /opt/perfuse -service systemd
19.7.2 Perfuse service
Registrerer Perfuse som en Windows-service, fjerner den eller rapporterer, om den er installeret og kørende. Kun Windows; på Linux er det tilsvarende enheden fil perfuse init kan skrive til dig. Se drift.
19.7.3 Perfuse token
Udsteder legitimationsoplysninger til maskiner i stedet for mennesker. En token udløber ikke og påvirkes ikke af, at nogen logger af, hvilket er, hvad en server, der afhører sin nabo, har brug for, og hvad en browsersession bevidst ikke er.
perfuse token opret -db perfuse.db -label fleet-from-site-a -rolle viewer perfuse token liste -db perfuse.db perfuse token annuller -db perfuse.db -label fleet-from-site-a
Kun hashen gemmes, så en token vises kun én gang, når den oprettes, og kan ikke genskabes herefter. En stjålet database giver derfor ingen brugbar token. Giv en token den laveste rolle, der gør jobbet: en flådebetraktning har brug for viewer, og intet, der kun læser, skal have noget mere.
-fhir-groups riverside-attributed,riverside-north begrænser en token til disse FHIR-Grupper, til en udbyders CMS-0057 Provider Access-eksport: på FHIR-endpointen kan den læse disse Grupper og eksportere dem, og intet andet. Se CMS-0057 for betalere.
19.7.4 Perfuse Athena
Udskriver Amazon Athenas CREATE EXTERNAL TABLE for en S3-arkiv skrevet med format: ndjson, ved hjælp af partitionsprojektion på dt=YYYY-MM-DD-delen af nøglen, så ingen crawler behøver at køre, når dage tilføjes.
Perfuse Athena -bucket hospital-arkiv -destination arkiv
Udskrevet i stedet for kørt, fordi oprettelse af en tabel kræver Athena- og Glue-behørigheder, som dette program ikke bør have.
19.7.5 Perfuse SBOM
Lister alt, der er linket til binærfilen, læst fra bygningen selv og ikke fra go.mod — så den beskriver binærfilen foran dig og ikke, hvad nogen engang har bedt om.
-json udsender CycloneDX og -spdx udsender SPDX tag-værdi, som normalt er, hvad en indkøbs- eller sikkerhedsrevision faktisk beder om. Den browserkode, der er indlejret i binærfilen, er inkluderet, fordi en reviewer, der matcher en binærfil mod råd, har brug for at vide, at den indeholder en React-applikation.
19.7.6 Perfuse version
Udskriver versionen og den commit, den blev bygget fra. Det er værd at indsætte i en billet: "den nuværende" er ikke en version, og to maskiner, der blev installeret en uge apart, kører ofte ikke den samme build.
20 Serverindstillinger
Hver indstilling, perfuse serve tager, genereret fra programmet selv, så listen kan ikke navngive en indstilling, der ikke findes, eller udelade en. De fleste er også en indstilling i webgrænsefladen, navngivet i den sidste kolonne: en værdi, der er gemt der, sejrer over flaget ved næste start, og flaget forbliver måden at indstille det fra en servicedefinition. Lytadressen, databasen og kanal-kataloget bliver kun flag, fordi de siger, hvor serveren finder, hvad den ellers ville redigere.
Hemmeligheder er aldrig flag. En indstilling, der kræver en adgangskode eller en token, navngiver en miljøvariabel, der holder den.
20.1 Alle indstillinger
| Option | Takes | Default | What it does | In the console |
|---|---|---|---|---|
-addr | string | 127.0.0.1:8080, or 127.0.0.1:8443 with -tls-cert | address to serve the interface on | — |
-alert-severity | string | warning | minimum severity to send to the webhook: warning or critical | Settings › Alerts › Delivery: Only send alerts at least this serious |
-alert-webhook | string | — | POST alerts to this URL as JSON. Works with Slack, Teams, Mattermost, Alertmanager or anything that accepts a webhook. The payload carries channel names, counts and thresholds; never message content | Settings › Alerts › Delivery: Send alerts to this address |
-alerts | string | — | YAML file of alert rules. Default: alerts.yaml beside the database, written when the rules are first saved in the console; until then a conservative default set is used | — |
-allow-metadata-egress | on/off | — | permit destinations pointed at cloud instance metadata addresses, which hold this machine's credentials | Settings › Security › What may leave: Allow destinations at cloud instance metadata addresses |
-cds-clients | string | — | the EHRs trusted to call the CDS services with signed JWTs (issuer and jwks_url) | Settings › Payers › Prior authorization: EHRs trusted to call the CDS services |
-channels | string | ./channels | directory holding channel files | — |
-cluster | string | — | share the work with other servers on the same PostgreSQL -db: active-passive (one runs everything, another takes over when it stops) or active-active (channels spread over all) | — |
-cluster-lease | duration | 15s | how long a crashed server holds its work before another takes it over; renewed five times as often | — |
-crd-advisor-ca | string | — | a PEM file of certificate authorities to trust for -crd-advisor-url beside the system's (Vaglio's is its DATA/tls/ca.crt) | Settings › Payers › Decision service: Certificate authorities to trust for the advice service |
-crd-advisor-token-env | string | — | name of an environment variable holding a bearer token for -crd-advisor-url (the token itself is never a flag) | Settings › Payers › Decision service: Environment variable holding the advice service's token |
-crd-advisor-url | string | — | with -crd-rules, ask the decision service at this URL (such as Vaglio's /api/pas/advise) what a prior authorization request for each order needing one would be told as the record stands, shown as one more CRD card; the prefetched record is POSTed to it. No answer, or any failure, leaves the cards as they are without it | Settings › Payers › Decision service: Advice before submitting (CRD) |
-crd-rules | string | — | a Da Vinci CRD rules file: serve coverage requirements over CDS Hooks at /cds-services | Settings › Payers › Prior authorization: Coverage rules file (Da Vinci CRD) |
-dashboards | string | — | a file mapping directory groups and roles to the dashboard each opens on | Settings › Monitoring › Dashboards: Which dashboard each group opens on (file) |
-data | string | — | directory for this server's own files (settings, alerts, sign-in configuration, the log): default beside -db when it is a file, the current directory when it is a PostgreSQL URL | — |
-davinci-version | string | 2.2 | the Da Vinci CRD, DTR and PAS release answered when neither a request nor its client's registration says: 2.2 (CRD 2.2.1, DTR 2.2.0, PAS 2.2.1) or 2.1 (2.1.0) | — |
-db | string | ./perfuse.db | database for users, messages and stored resources: a file, or a postgres:// URL for servers that share one store (a cluster) | — |
-demo-account | string | — | for a public demonstration server: username:password of a shared viewer account shown on the sign-in page | — |
-dicomweb-archive | string | — | keep imaging objects in this directory and serve them over DICOMweb (QIDO-RS, WADO-RS, WADO-URI, STOW-RS) at /dicomweb | Settings › Data › Imaging archive: Keep images in this folder and serve them over DICOMweb |
-dicomweb-cors | string | — | comma-separated browser origins, such as an OHIF viewer's, allowed to call /dicomweb | Settings › Data › Imaging archive: Browser origins allowed to call it |
-drain-for | duration | — | after SIGTERM, report not-ready for this long before shutting down (for rolling deploys) | Settings › Engine › Shutdown: Wait for in-flight messages on shutdown |
-ecr-agency | string | — | play a public health agency for testing eCR: answer case reports at $process-message with a Reportability Response, using the agency YAML file given (name, phone, address, endpoint; optional rctc, reply) | Settings › Public health › Case reporting: Act as a test public health agency |
-ecr-responses | on/off | — | accept eCR Reportability Responses at the FHIR endpoint's $process-message, storing each as DocumentReference/<id> derived from the eICR it answers | Settings › Public health › Case reporting: Receive Reportability Responses |
-engine | on/off | true | run the channel engine in this process, so the interface can start, stop and monitor channels | — |
-epa-payer-id | string | — | this payer's identifier on the prescribing network, the From of every RTPB and ePA response (default: the formulary's payer id) | Settings › Payers › Drug formulary: Payer ID on the prescribing network |
-epa-reply-channel | string | — | route ePA decisions made after the request was answered (a reviewer's, an appeal's) to this channel, which delivers them to the prescriber's network | Settings › Payers › Drug formulary: Channel that sends later ePA decisions |
-fhir | on/off | true | serve a FHIR endpoint at /fhir | Settings › FHIR › The FHIR server: Serve a FHIR endpoint at /fhir |
-fhir-api-tokens | on/off | — | with SMART configured, accept Perfuse API tokens on the FHIR endpoint as well (unscoped; the console's FHIR settings can switch it) | Settings › FHIR › Access: Accept Perfuse API tokens beside SMART tokens |
-fhir-bulk-export | on/off | — | enable $export, which produces a file holding every record the FHIR endpoint serves | Settings › FHIR › Bulk data: Bulk Data export ($export) |
-fhir-declares | string | — | guides this FHIR server declares in its capability statement, comma-separated: a CapabilityStatement address, or Type=profile address | Settings › FHIR › Capability statement: Guides this server declares |
-fhir-max-resources | int | — | for a public server: refuse new FHIR resources once this many are held (0: no limit) | Settings › FHIR › Access: Most resources held |
-fhir-member-match-without-consent | on/off | — | let $member-match answer without an active Consent; the Payer-to-Payer API is opt-in, so only for testing | Settings › Payers › CMS-0057-F: Answer $member-match without the member's consent |
-fhir-open | on/off | — | serve the FHIR endpoint with no authentication at all, exposing every stored record | Settings › FHIR › Access: Let anyone read the FHIR endpoint without signing in |
-fhir-patient-directory-search | on/off | — | let a token limited to one patient search the directory (practitioners, organisations, locations) within its scopes | Settings › FHIR › Access: Let a patient's app search the directory |
-fhir-payer-apis | on/off | — | enable the CMS-0057 payer operations: $member-match (Payer-to-Payer) and Group $davinci-data-export (Provider Access); the Group exports also need -fhir-bulk-export | Settings › Payers › CMS-0057-F: The CMS-0057-F payer APIs |
-fhir-read-only | on/off | — | refuse writes to the FHIR endpoint | Settings › FHIR › Access: Refuse writes to the FHIR endpoint |
-fhir-subscriptions | on/off | — | enable topic-based subscriptions, which send encounter and appointment notifications to URLs FHIR clients choose | Settings › FHIR › Notifications: FHIR subscriptions (encounter and appointment notifications) |
-fhir-subscriptions-allow-http | on/off | — | let subscriptions deliver to plain-http endpoints; for a test receiver, never for patient data on a network | Settings › FHIR › Notifications: Allow subscriptions to notify plain-HTTP addresses |
-fhir-version | string | 4.0.1 | FHIR release to serve: R4, R4B or R5 | Settings › FHIR › The FHIR server: FHIR version clients see |
-fhir-writes-per-minute | int | — | for a public server: writes one client address may make to the FHIR endpoint a minute (0: no limit) | Settings › FHIR › Access: Writes a minute from one client |
-fleet-label | string | — | how this instance names itself in a fleet view (default: hostname) | Settings › Fleet › This server: Name for this server |
-formulary | string | — | publish this drug formulary over the Da Vinci US Drug Formulary API at /formulary/fhir and answer NCPDP Real-Time Prescription Benefit and SCRIPT electronic prior authorization from it | Settings › Payers › Drug formulary: Drug formulary file |
-icd11-client-id | string | — | a WHO ICD API client: ICD-11 codes not imported are looked up there | Settings › Data › Code systems: WHO ICD API client ID |
-icd11-client-secret | string | — | the WHO ICD API client's secret | Settings › Data › Code systems: WHO ICD API client secret |
-icd11-release | string | 2025-01 | the ICD-11 MMS release the WHO ICD API is asked about | Settings › Data › Code systems: ICD-11 release to ask for |
-icd11-url | string | — | the ICD API's address when it is not the WHO's: the WHO's ICD-API container on your network needs no client | Settings › Data › Code systems: ICD API address |
-index-identity | on/off | true | index patient identifiers from message contents so a message can be found by MRN, name or accession in any format; has no effect when -store-payloads is off | Settings › Data › What is kept: Index patient identifiers |
-insecure | on/off | — | serve over plain HTTP on a non-loopback address (not recommended) | — |
-inventory | string | — | write a Markdown inventory of every interface to this file, and keep it current | Settings › Monitoring › Inventory: Write an interface inventory to |
-inventory-every | duration | 24h0m0s | how often to rewrite the interface inventory | Settings › Monitoring › Inventory: Rewrite the inventory every |
-json-logs | on/off | — | emit structured JSON logs | Settings › Monitoring › Logging: Write logs as JSON |
-ldap | string | — | YAML file configuring directory (LDAP) sign-in (default: ldap.yaml beside the database, once saved in the console) | — |
-log-file | string | — | append the log, and the first administrator's one-time password, to this file (mode 0600) instead of the console. A Windows service has no console, so there it defaults to perfuse.log beside the database | — |
-mcp | on/off | — | serve the Model Context Protocol at /mcp, so AI agents with an API token can read status, messages, the queue, alerts and the FHIR store with that token's own access | Settings › Security › AI agents (MCP): Let AI agents connect over MCP |
-measure-reporter | string | Perfuse | the reporting organisation's name on MeasureReports from $evaluate-measure when the request names no reporter | — |
-metrics-open | on/off | — | serve /metrics to anybody who can reach the port. Only safe where that port is genuinely private: metric labels name your channels, and on a multi-tenant server they name every tenant's | Settings › Security › Metrics: Serve /metrics without a token |
-metrics-token | string | — | credential the Prometheus scrape endpoint requires. Give the scraper the same value in bearer_token_file. Without this, only a signed-in operator can read /metrics | Settings › Security › Metrics: Token a metrics scraper presents |
-mpi | on/off | — | keep a patient index (master patient index) in mpi.db beside the database: patient records from every system linked into one enterprise identifier per person, fed by mpi destinations and the PIX v3 identity feed, answering Patient/$match, PIXm, PIX v3 (/pixv3) and PDQ v3 (/pdqv3) | Settings › Data › Patient index: Keep a patient index |
-multi-tenant | on/off | — | keep each tenant's channels in their own subdirectory of -channels, so one server can run integration for several organisations without them being able to see each other | — |
-node-address | string | — | this server's console URL as the other servers and a load balancer reach it | — |
-node-name | string | — | this server's name in the cluster (default: an id kept in -data) | — |
-oidc | string | — | YAML file configuring OpenID Connect sign-in (default: oidc.yaml beside the database, once saved in the console) | — |
-pas | on/off | — | serve Da Vinci PAS 2.2.1 and 2.1.0 (Claim/$submit, $inquire, $decide) on the FHIR endpoint; decisions come from -crd-rules, and what no rule decides is pended for a reviewer. With -fhir-subscriptions, the PAS topic delivers each pended request's result | Settings › Payers › Prior authorization: Da Vinci PAS prior authorization server |
-pas-278-ca | string | — | a PEM file of certificate authorities to trust for the UM system beside the system's | Settings › Payers › Utilization management link: Certificate authorities to trust for the UM system |
-pas-278-cert | string | — | a PEM client certificate for X.509 mutual TLS with the UM system (CORE's authentication) | Settings › Payers › Utilization management link: Client certificate file |
-pas-278-core-receiver | string | — | the CORE envelope's ReceiverID, as the UM system's connectivity guide gives it (default: -pas-278-receiver) | Settings › Payers › Utilization management link: CORE envelope ReceiverID |
-pas-278-core-rule-version | string | — | what to write in the CORE envelope's CORERuleVersion when the UM system's guide asks for something other than the version itself (CMS esMD's sample says v2.2.0) | Settings › Payers › Utilization management link: CORERuleVersion written in the envelope |
-pas-278-core-sender | string | — | the CORE envelope's SenderID, as the UM system's connectivity guide gives it (default: -pas-278-sender) | Settings › Payers › Utilization management link: CORE envelope SenderID |
-pas-278-core-version | string | 2.2.0 | the CAQH CORE Connectivity Rule the UM system runs, for core-soap and core-mime: 2.2.0 (payload in the envelope) or C4.0.0 (payload as an MTOM attachment; SOAP only) | Settings › Payers › Utilization management link: CAQH CORE Connectivity Rule |
-pas-278-key | string | — | the private key (PEM) for -pas-278-cert | Settings › Payers › Utilization management link: Client certificate key file |
-pas-278-oauth-client-id | string | — | the OAuth client ID for -pas-278-oauth-token-url | Settings › Payers › Utilization management link: OAuth client ID |
-pas-278-oauth-scope | string | — | the scope asked for with the OAuth token, when the UM system wants one | Settings › Payers › Utilization management link: OAuth scope |
-pas-278-oauth-secret-env | string | — | name of an environment variable holding the OAuth client secret (the secret itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the OAuth client secret |
-pas-278-oauth-token-url | string | — | an OAuth 2.0 token endpoint: a token got with the client-credentials grant is sent as a bearer token (CORE vC4.0.0's authorization) | Settings › Payers › Utilization management link: OAuth token endpoint |
-pas-278-password-env | string | — | name of an environment variable holding the password for -pas-278-user (the password itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the password |
-pas-278-payer-id | string | — | the UMO's payer ID (NM1*X3) when the request's insurer carries no identifier | Settings › Payers › Utilization management link: Payer ID for the 278s |
-pas-278-production | on/off | — | mark the 278s sent as production (ISA15 P) rather than test | Settings › Payers › Utilization management link: Mark the 278s as production |
-pas-278-receiver | string | — | ISA08/GS03 receiver ID on the 278s sent to the UM system | Settings › Payers › Utilization management link: Receiver ID on the 278s |
-pas-278-sender | string | PERFUSE | ISA06/GS02 sender ID on the 278s sent to the UM system | Settings › Payers › Utilization management link: Sender ID on the 278s |
-pas-278-sftp | string | — | host:port of the UM system's SFTP server, for -pas-278-transport sftp | Settings › Payers › Utilization management link: SFTP server |
-pas-278-sftp-every | duration | 1m0s | how often the SFTP inbound folder is read | Settings › Payers › Utilization management link: Read the SFTP inbound folder every |
-pas-278-sftp-inbound | string | — | the SFTP folder the UM system's 278 responses, 999s and TA1s are collected from | Settings › Payers › Utilization management link: SFTP inbound folder |
-pas-278-sftp-key | string | — | an OpenSSH private key file for the SFTP user, instead of a password | Settings › Payers › Utilization management link: SFTP key file |
-pas-278-sftp-known-hosts | string | — | an OpenSSH known_hosts file holding the SFTP server's key; required, so requests never go to whoever answers | Settings › Payers › Utilization management link: SFTP known_hosts file |
-pas-278-sftp-outbound | string | — | the SFTP folder the 278 requests (and the 999s for the answers) are put in | Settings › Payers › Utilization management link: SFTP outbound folder |
-pas-278-sftp-password-env | string | — | name of an environment variable holding the SFTP password (the password itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the SFTP password |
-pas-278-sftp-user | string | — | the SFTP user name | Settings › Payers › Utilization management link: SFTP user |
-pas-278-token-env | string | — | name of an environment variable holding a bearer token for the UM system (the token itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the token |
-pas-278-transport | string | x12 | how the 278s reach the UM system: x12 (POSTed as application/edi-x12), core-soap (a CAQH CORE SOAP envelope), core-mime (CAQH CORE HTTP MIME multipart), or sftp (batch files over -pas-278-sftp, answers collected from its inbound folder) | Settings › Payers › Utilization management link: How the 278s travel |
-pas-278-url | string | — | forward every PAS request to the payer's utilization management system as an X12 278 request sent to this URL (by -pas-278-transport), and answer with its 278 response; later 278 responses go to Claim/$decide-278 | Settings › Payers › Utilization management link: Send PAS requests on to the UM system at |
-pas-278-user | string | — | user name for the UM system: CORE's UserName (WS-Security UsernameToken in SOAP), or HTTP Basic for x12 | Settings › Payers › Utilization management link: User name |
-pas-decider-ca | string | — | a PEM file of certificate authorities to trust for -pas-decider-url beside the system's, such as the payer's own authority or the decision service's (Vaglio's is its DATA/tls/ca.crt) | Settings › Payers › Decision service: Certificate authorities to trust for the decision service |
-pas-decider-token-env | string | — | name of an environment variable holding a bearer token for -pas-decider-url (the token itself is never a flag) | Settings › Payers › Decision service: Environment variable holding the decision service's token |
-pas-decider-url | string | — | ask the decision service at this URL (such as Vaglio) to decide each PAS item on the request's clinical evidence, when -crd-rules leave it to a reviewer; the PAS request Bundle is POSTed to it. Cannot be combined with -pas-278-url | Settings › Payers › Decision service: Decision service URL |
-passkey-allowed-models | string | — | comma-separated authenticator AAGUIDs that may enrol; requires -passkey-attestation-roots | — |
-passkey-attestation-roots | string | — | a PEM file of authenticator vendor certificates; passkey attestation is verified against these | — |
-passkey-domain | string | — | the bare domain passkeys are registered for, such as perfuse.example.org. No scheme, no port, no path. Setting it turns passkeys on; leaving it empty leaves them off | Settings › Sign-in › Passkeys: Domain passkeys are bound to |
-passkey-name | string | Perfuse | the name an authenticator shows a person when they register a passkey | Settings › Sign-in › Passkeys: Name shown on the device |
-passkey-origins | string | — | comma-separated origins the console is reached at, with scheme and port: https://perfuse.example.org. Defaults to https:// plus the domain | Settings › Sign-in › Passkeys: Other origins passkeys are accepted from |
-peers | string | — | YAML file listing other Perfuse instances to show in a fleet view | Settings › Fleet › Fleet: Other Perfuse servers to show (file) |
-public-url | string | — | the https address patients' phones and other organisations reach this server at, for the SMART Health Links it hosts (default: the listen address) | Settings › FHIR › The FHIR server: Address others reach this server at |
-rctc | string | — | eCR trigger codes for the case report preview: a FHIR ValueSet or Bundle of them, such as the eRSD | Settings › Public health › Case reporting: Trigger codes file (RCTC or eRSD) |
-residency | string | — | cloud regions this server's data may go to or come from: areas (eea, uk, ch) and region codes (eu-central-1), comma-separated; channels with connectors elsewhere are refused | Settings › Data › Data protection: Where data may go (cloud regions) |
-retention-days | int | 30 | how long to keep recorded messages; 0 keeps them for ever, which will eventually fill the disk | Settings › Data › How long it is kept: Delete records after |
-saml | string | — | YAML file configuring SAML 2.0 sign-in (default: saml.yaml beside the database, once saved in the console) | — |
-scim | on/off | — | accept SCIM 2.0 provisioning from an identity provider at /scim/v2. Okta, Entra ID and Google Workspace use it to create accounts and, more importantly, to disable them when somebody leaves | Settings › Sign-in › Automatic accounts: Let the identity provider manage accounts |
-scim-default-role | string | viewer | role for an account the identity provider does not describe. Defaults downward on purpose: an account whose role could not be determined should be able to read and nothing else | — |
-settings | string | — | settings file the web interface may edit (default: perfuse-settings.yaml beside the database) | — |
-shl-allow-http | on/off | — | let a received SMART Health Link point at plain HTTP; for testing only | Settings › Public health › Health links: Allow SMART Health Links over plain HTTP |
-signing-cert | string | — | certificate for signing documents (defaults to -tls-cert) | Settings › Security › Document signing: Certificate for signing documents |
-signing-key | string | — | key for signing documents (defaults to -tls-key) | Settings › Security › Document signing: Key for signing documents |
-smart-audience | string | — | the audience a SMART token must be issued for, normally the FHIR base URL | Settings › SMART › Authorization: Audience tokens must name |
-smart-authorize | string | — | the authorization endpoint to advertise to SMART apps | Settings › SMART › Authorization: Authorization endpoint |
-smart-backend-services | on/off | — | advertise that the SMART authorization server issues backend-services (client_credentials, signed JWT) tokens | Settings › SMART › Built-in server: Backend Services (system-to-system tokens) |
-smart-clients | string | — | run Perfuse's own SMART authorization server at /auth for the apps registered in this YAML file | Settings › SMART › Built-in server: Registered apps file (turns on the built-in server) |
-smart-issuer | string | — | accept SMART on FHIR access tokens from this authorization server | Settings › SMART › Authorization: Accept SMART access tokens from this authorization server |
-smart-jwks | string | — | where to fetch the SMART issuer's signing keys, when not from its published metadata (split DNS, a private address) | Settings › SMART › Authorization: Key set file |
-smart-jwks-uri | string | — | the authorization server's public key set URL, advertised to SMART apps (needed to claim OpenID Connect sign-in) | Settings › SMART › Authorization: Key set address |
-smart-key | string | smart-signing.key | the built-in authorization server's RSA signing key (PEM, mode 0600), created if missing | Settings › SMART › Built-in server: Signing key file |
-smart-oidc | string | — | with -smart-users, let people sign in at this OpenID Connect provider (YAML: issuer, client_id, client_secret_file or client_secret_env, label); each is linked by oidc_subject | Settings › SMART › Built-in server: Sign people in through the OpenID Connect provider |
-smart-token | string | — | the token endpoint to advertise to SMART apps | Settings › SMART › Authorization: Token endpoint |
-smart-users | string | — | with -smart-clients, the people who may sign in to authorize apps (YAML: username, password_hash, fhir_user) | Settings › SMART › Built-in server: People who sign in to authorize apps (file) |
-snmp-allow | string | — | comma-separated networks or addresses the SNMP agent answers, such as 10.0.5.0/24; required with -snmp-listen | Settings › Monitoring › SNMP: Networks that may ask |
-snmp-base-oid | string | 1.3.6.1.4.1.8072.9999.9999.16, Net-SNMP's experimental space | where Perfuse's values sit, under your enterprise number | Settings › Monitoring › SNMP: Base OID |
-snmp-community | string | — | the SNMPv2c community (a password sent in clear: at least 6 characters, not public or private) | Settings › Monitoring › SNMP: SNMP community |
-snmp-contact | string | — | sysContact the SNMP agent reports | Settings › Monitoring › SNMP: Contact (sysContact) |
-snmp-listen | string | — | answer SNMPv2c GET/GETNEXT/GETBULK on this UDP address, such as :161 (off when empty). Read-only: channel states, counts and queue depths | Settings › Monitoring › SNMP: Answer SNMP on this address |
-snmp-location | string | — | sysLocation the SNMP agent reports | Settings › Monitoring › SNMP: Location (sysLocation) |
-snmp-traps | string | — | comma-separated managers (host or host:port, default port 162) that receive an SNMPv2 trap when an alert fires or resolves | Settings › Monitoring › SNMP: Send traps to |
-store-messages | on/off | true | record every message handled, which is what makes the message browser work | Settings › Data › What is kept: Keep a record of each message |
-store-payloads | on/off | true | store message contents as well as their outcomes; turn this off where PHI must not be held at rest | Settings › Data › What is kept: Keep message contents |
-tls-cert | string | — | TLS certificate file | Settings › Security › Encryption: TLS certificate file |
-tls-key | string | — | TLS private key file | Settings › Security › Encryption: TLS private key file |
-trace-endpoint | string | — | OTLP/HTTP base URL to export message traces to, for example http://localhost:4318 | Settings › Monitoring › Tracing: Send traces to |
-trace-instance | string | — | name for this instance in traces; defaults to the hostname, which is what distinguishes replicas | Settings › Monitoring › Tracing: This instance's name in traces |
-trace-sample | float | 1 | fraction of traces to record, 0 to 1 | — |
-tsa-url | string | — | RFC 3161 time-stamping authority for DSDR signatures on claims attachments | Settings › Security › Document signing: Time-stamping authority |
-vpn | string | — | partner VPN tunnels to report on the Connections dashboard (YAML: AWS Site-to-Site VPN, Azure VPN Gateway or strongSwan, and both sides' settings); see examples/vpn.yaml | Settings › Monitoring › Connections: VPN tunnels to watch (file) |
-watch-access | on/off | true | watch traffic and reads of patient data for what a breach looks like (bursts, night traffic, new destinations, bulk reads) and raise alerts | — |
-xds | string | — | keep clinical documents here as an IHE XDS.b registry and repository with this repository uniqueId (an OID), answering ITI-41, ITI-42, ITI-18 and ITI-43 at /xds/repository and /xds/registry | Settings › Data › Document sharing (IHE XDS): Keep documents here as an XDS registry and repository |
-xds-home-community | string | — | this community's home community id (urn:oid:...), so /xca/gateway answers XCA ITI-38 and ITI-39 for it | Settings › Data › Document sharing (IHE XDS): Home community id, for XCA |
21 Kanaloreference
Hver nøgle, der kan forekomme på toppen af en kanalfil. Disse er udtrukket fra kilden, så dette kapitel kan ikke beskrive en mulighed, der ikke findes, eller udelade en, der gør.
21.1 Kanal
Kanal er en konfigureret meddelelsesstrøm: et sted, hvor meddelelser ankommer, et valgfrit filter og ét eller flere steder, de går til.
Defineret som Channel i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
name | tekst | ja | — |
description | tekst | nej | — |
group | tekst | nej | — |
attachments | Vedhæftninger (en blok, udelad for at undlade) | nej | — |
delimited | Afgrænset (en blok, udelad for at undlade) | nej | — |
tables | liste af tekst | nej | — |
contract | KontraktRef (en blok, udelad for at undlade) | nej | — |
enabled | sandt eller falsk (en blok, udelad for at undlade) | nej | — |
dataType | DataType | nej | hl7 |
hl7v3 | HL7v3Options (en blok, udelad for at undlade) | nej | — |
x12 | X12Options (en blok, udelad for at undlade) | nej | — |
ncpdp | NCPDPOptions (en blok, udelad for at undlade) | nej | — |
edifact | EDIFACTOptions (en blok, udelad for at undlade) | nej | — |
script | ScriptOptions (en blok, udelad for at undlade) | nej | — |
dicom | DICOMOptions (en blok, udelad for at undlade) | nej | — |
source | Kilde | ja | — |
filter | tekst | nej | — |
transformations | liste af transform.Step | nej | — |
scripts | Scripts (en blok, udelad for at undlade) | nej | — |
shadow | Skygge (en blok, udelad for at undlade) | nej | — |
destinations | liste af Destination | ja | — |
21.1.1 navn
Navn identificerer kanalen i logfiler og målinger.
Kræves og unikt.
21.1.2 gruppe
Gruppe er, hvad denne kanal er en del af, til organisering af en liste, der er vokset for lang til at læse.
Kosmetisk ved fem kanaler og strukturel ved to hundrede: en sites kanaler divideres af systemet, de taler til, eller af holdet, der ejer dem, og en flad liste af to hundrede navne er ubrugelig, uanset hvor god resten af grænsefladen er.
En almindelig streng i stedet for en gruppeobjekt med sin egen fil, fordi en gruppe ikke har nogen adfærd. Øjeblikket, det har en fil, tilegner det indstillinger, og indstillinger på en gruppe betyder, at en kanals adfærd afhænger af noget, der ikke er skrevet i kanalen - hvilket er den egenskab, der gør Mirth-konfiguration svær at forstå. Grupper her er en mærkning og intet mere.
21.1.3 vedhæftninger
Vedhæftninger flytter store payloads ud af meddelelsen og sætter dem tilbage, før de leveres.
Valgfrit per kanal: en feed af plain ADT-meddelelser har intet at trække ud og bør ikke betale for maskineriet.
21.1.4 afgrænset
Afgrænset konfigurerer en afgrænset kanal.
Kun meningsfuldt, når datatypen er afgrænset.
21.1.5 tabeller
Tabeller navngiver filer af fælles kortlægningsstabeller, en transformation kan henvisne til ved navn.
Fælles, fordi domænetaksen er større end genoprettelse af en kortlægning, som nogen allerede har udledt: en sites kønskoder og patientklasser bliver oversat identisk i hver kanal, der berører dem, og en tabel inde i en kanal er en tabel, kun den kanalen kan bruge.
21.1.6 aktiveret
Aktiveret standarder til sandt.
En deaktiveret kanal er indlæst og valideret, men ikke startet, så en fil, der midlertidigt er af, er stadig kontrolleret af CI.
21.1.7 datatyp
Datatyp er formatet for de meddelelser, denne kanal modtager.
Standardværdien er hl7, så alle kanaler skrevet før denne eksisterede, fortsætter med at fungere.
21.1.8 x12
X12 indeholder indstillinger, der kun har betydning på en X12-kanal.
At angive det på en anden type kanal afvises i stedet for at blive ignoreret.
21.1.9 script
Script konfigurerer en NCPDP SCRIPT-kanal.
Dets trin lever her i stedet for i de øverste transformations for den samme grund, som enhver anden non-v2-format gør: trinstyperne varierer pr. format, så en nøgle ville betyde forskellige ting afhængigt af datatyp.
21.1.10 dicom
Billedekonfiguration konfigurerer en DICOM-kanals navngivne transformations-trin.
Navngivet Billede i stedet for DICOM, fordi kilde og destination allerede har et DICOM-felt, og tre felter med samme navn på forskellige niveauer er, hvordan nogen sætter det forkerte. YAML-nøglen er dicom, som er, hvad en person, der skriver filen, forventer, og Go-navnet er det, der forhindrer en fejl på kaldepladsen.
21.1.11 filter
Filter er en udtryk, der skal være sandt for en meddelelse at blive videresendt.
En meddelelse, der ikke matcher, bliver stadig bekræftet: afsenderen har ikke gjort noget forkert, vi er bare ikke interesseret.
21.1.12 transformations
Transformationer er deklarative ændringer, der anvendes på accepterede meddelelser i rækkefølge, før nogen script køres.
Dette er laget, der er ment til at bære den almindelige arbejde: hvert trin valideres, når filen indlæses, vises i en diff, og kan gennemgås af nogen, der ikke læser JavaScript.
21.1.13 scripts
Scripts indeholder JavaScript for de tilfælde, hvor de deklarative trin ikke kan udtrykkes, og er, hvad en Mirth-kanals egne scripts indsættes i uændret.
En kanal med et script markeres som sådan i grænsefladen, fordi dens opførsel ikke kan fastslås ved at læse konfigurationen.
21.1.14 skygge
Skygge kører en kandidatversion af denne kanal ved siden af og rapporterer, hvor de afviger.
Intet, det gør, kan nå en modtager.
22 Kilde Reference
Enhver måde, en kanal kan modtage meddelelser, og hver nøgle, hver af dem accepterer. En kanal har præcis én kilde.
22.1 AMQP Kilde
AMQP Kilde modtager fra en kø eller abonnement.
En meddelelse accepteres kun efter, at kanalen har behandlet den. En, der ikke kunne behandles, frigøres som en mislykket levering, så brokeren leverer den igen og - på Service Bus, efter køens maksimale leveringsantal - dead-letter den.
Defineret som AMQPSource i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
prefetch | helt tal | nej | 10 |
reconnect | varighed, såsom 30s eller 5m | nej | 5s |
22.1.1 prefetch
Prefetch er, hvor mange meddelelser brokeren må sende i forvejen.
Standard er 10. De behandles stadig én ad gangen, i rækkefølge.
22.1.2 reconnect
Reconnect er ventetiden efter en tabt forbindelse.
Defaults to 5s.
22.2 AS2 Kilde
AS2 Kilde modtager AS2 (RFC 4130): EDI posteret over HTTP, signeret og krypteret med S/MIME, besvaret med en kvittering (en MDN) med en digest af, hvad der ankom.
Payloaden er, hvad kanalen behandler; X12 og EDIFACT er de sædvanlige.
Defineret som AS2Source i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
listen | tekst | ja | — |
path | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
id | tekst | ja | — |
cert_file | tekst | ja | — |
key_file | tekst | ja | — |
partners | liste af AS2Partner | ja | — |
max_message_size | helt tal | nej | — |
duplicate_window | varighed, såsom 30s eller 5m | nej | — |
22.2.1 path
Sti er URL-stien, partnere poster til.
Default /as2.
22.2.2 tls
TLS betjener HTTPS.
De fleste partnere kræver det i deres aftale, oven i S/MIME.
22.2.3 id
ID er vores AS2-identifikator, som partnere sender i AS2-To.
En meddelelse til nogen anden afvises.
22.2.4 partnere
Partnere er de, der må sende her.
En besked fra nogen andre afvises.
22.2.5 duplicate_window
DuplicateWindow er, hvor længe en partners Message-ID huskes, så en besked, der sendes igen (partneren fik aldrig vores kvittering og prøvede igen), besvares med en kvittering og ikke videreformidles to gange (RFC 4130 afsnit 7.5).
Default 30 days.
22.3 Azure Blob Kilde
AzureBlobSource henter blobs op fra en container-præfiks.
Defineret som AzureBlobSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
prefix | tekst | ja | — |
suffix | tekst | nej | — |
after_read | tekst | nej | — |
move_to | tekst | nej | processed/ |
error_prefix | tekst | nej | error/ |
poll_interval | varighed, f.eks. 30s eller 5m | nej | 30s |
max_object_size | helt tal | nej | 16 MiB |
framed | sandt eller falsk | nej | — |
22.3.1 flyt_til
FlytTil er, hvor en behandlet blob flyttes.
Standard er processed/.
22.3.2 fejl_præfiks
FejlPræfiks er, hvor en blob, der ikke kan behandles, flyttes, så den ikke blokerer resten.
Standard er error/.
22.3.3 afhentningsinterval
Afhentningsinterval mellem listinger.
Defaults to 30s.
22.3.4 maks_objektstørrelse
MaksObjektStørrelse afviser en større blob, der bliver, hvor den er.
Standard er 16 MiB.
22.4 Mægler Kilde
BrokerSource læser beskeder fra en beskedmægler.
Mirth's JMS Reader, nået over STOMP, fordi JMS er en Java-API og ikke et protokol. Se internal/stomp for, hvorfor STOMP og ikke OpenWire.
Defineret som BrokerSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
addr | tekst | ja | — |
destination | tekst | ja | — |
login | tekst | nej | — |
passcode | tekst | nej | — |
host | tekst | nej | adressens vært |
selector | tekst | nej | — |
subscription_id | tekst | nej | kanalnavnet |
heartbeat | varighed, f.eks. 30s eller 5m | nej | tredive sekunder |
reconnect | varighed, f.eks. 30s eller 5m | nej | fem sekunder |
timeout | varighed, f.eks. 30s eller 5m | nej | tredive sekunder |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
22.4.1 adresse
Addr er brokerens vært og port.
Påkrævet. 61613 er den sædvanlige STOMP-port.
22.4.2 destination
Destination er køen eller emnet, der læses fra.
Required.
Brokere staver disse forskelligt - /queue/navn på ActiveMQ, et nøgent navn på RabbitMQ - så det sendes ubeskåret igennem i stedet for at blive samlet her. At gætte ville betyde at arbejde imod en broker og stille læse ingenting på en anden.
22.4.3 login
Login og adgangskode autentificerer.
De fleste brokere afviser en anonym forbindelse.
22.4.4 adgangskode
Login og adgangskode autentificerer.
De fleste brokere afviser en anonym forbindelse.
22.4.5 vært
Vært er den virtuelle vært.
Standardværdi er adressens vært.
22.4.6 selector
Selector filtrerer meddelelser på brokeren.
En JMS-selector, der sendes igennem i stedet for fortolkedes. Filtrering på brokeren i stedet for her betyder, at meddelelserne, som denne kanal ikke ønsker, aldrig krydser netværket - hvilket på en delt kø er forskellen på at læse hundredvis af meddelelser om dagen og hundredtusindvis.
22.4.7 subscription_id
SubscriptionID navngiver abonnementet.
Standardværdi er kanalnavnet.
Navngivet i stedet for genereret, fordi et varigt abonnement identificeres ved det: et genereret ville oprette et nyt abonnement ved hver genstart og lade de gamle abonnementer samle meddelelser, som ingen læser.
22.4.8 heartbeat
Heartbeat holder forbindelsen i live.
Standardværdi er tredive sekunder.
Aktiveret som standard her, til forskel fra klientens egen standardværdi, fordi en kilde holder en forbindelse åben i uger. Uden heartbeats ser en forbindelse gennem en brandmur, der stille har droppet ruten, ud til at være helt sund fra denne side, og meddelelserne stopper simpelthen med at ankomme, uden noget bliver logget.
22.4.9 reconnect
Genforbindelse er, hvor lang tid der skal vente, før genforbindelse sker efter en fejl.
Standardværdi er fem sekunder.
22.4.10 timeout
Tidsgrænseforbindelse.
Standardværdi er tredive sekunder.
22.5 DICOM-forespørgselssource
DICOMQuerySource afhører et arkiv med C-FIND og udsender en besked per nyt studie.
Mirth har ingen tilsvarende connector. Dets DICOM-understøttelse er en lytter og en afsender - det kan modtage billeder, der er pushet til det, og pushe dem videre, og det er alt. At spørge et arkiv, hvad det indeholder, er blevet anmodet på deres fora siden 2015.
Det, der gør det værd at have, er ikke forespørgslen, men automationen: en prefetch, der kører klokken tre om morgenen, en afstemning, der bemærker, at arkivet mangler et studie, som RIS siger findes, en arbejdsliste opbygget af, hvad der faktisk er scannet, snarere end hvad der er bestilt. Disse er jobs, som websteder i øjeblikket udfører med et planlagt script uden for motoren, hvilket betyder, at de er usynlige for den - ingen genprøvninger, ingen alarmer, ingen beskedshistorik.
Defineret som DICOMQuerySource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
address | tekst | ja | — |
called_ae | tekst | ja | — |
calling_ae | tekst | nej | — |
level | tekst | nej | STUDY |
patient_root | sandt eller falsk | nej | — |
match | mapping af tekst til tekst | nej | — |
return | liste af tekst | nej | — |
interval | varighed, f.eks. 30s eller 5m | ja | — |
window | varighed, f.eks. 30s eller 5m | nej | — |
overlap | varighed, f.eks. 30s eller 5m | nej | en time |
limit | helt tal | nej | 500 |
timeout | varighed, f.eks. 30s eller 5m | nej | to minutter |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
emit_on_first_poll | sandt eller falsk | nej | falsk |
22.5.1 adresse
Adresse er arkivets vært og port.
Required.
Navngivet for at matche DICOM-destinationen snarere end forkortet. De to var "adresse" og "addr" for en eftermiddag, hvilket er den slags inkonsistens, som nogen, der skriver en kanal-fil i hånden, får galt en gang og så mistænker hele formatet over.
22.5.2 kaldt_ae
KaldtAE er arkivets AE-titel.
Kræves i praksis: de fleste arkiver afviser en association, der er adresseret til noget andet, og denne afvisning læses som et afbrud snarere end som en konfigurationsfejl.
22.5.3 kalde_ae
KaldeAE er AE-titlen, som Perfuse præsenterer.
Arkiver bruger det ofte til adgangskontrol.
22.5.4 niveau
Niveau er forespørgselsniveauet: PATIENT, STUDIE, SERIE eller BILLEDE.
Standardværdi er STUDIE.
STUDIE er standardværdi, fordi det er, hvad næsten alle nyttige forespørgsler ønsker, og fordi alternativerne overrasker folk: BILLEDE-niveau mod en stor CT returnerer en respons per skive, hvilket er hundredvis per studie.
22.5.5 match
Match er forespørgselsnøglerne.
En værdi filtrerer; en tom værdi beder om, at feltet skal returneres.
Nøgler er navngivet snarere end nummereret - "PatientID" snarere end "0010,0020" - fordi en kanal-fil læses af mennesker, og en tag-nummer i en konfigurationsfil er en opslag, som hver læser må udføre.
22.5.6 returnerer
Return-felter er felter, der skal returneres uden filtrering på dem.
Adskilt fra Match med en tom værdi, selvom de kodificeres identisk, fordi intentionen er forskellig, og en læser kan se, hvilke nøgler der indsnævrer søgningen og hvilke der indsamles.
22.5.7 interval
Interval er, hvor ofte der skal afhentes.
Required.
22.5.8 vindue
Vindue er, hvor langt tilbage hver afhentning ser, som en studie-dato-række.
Nul deaktiverer datofiltrering helt.
Et vindue er, hvad der holder dette begrænset. Uden et, spørger hver afhentning arkivet om alt, det nogensinde har holdt, og derefter kasserer, hvad det har set før - hvilket virker på et testarkiv og er asocialt over for et rigtigt arkiv, der holder millioner af studier.
22.5.9 overlappende
Overlappende gen-spørger så langt ind i allerede-afhentede perioden.
Standardværdi er en time.
Nødvendigt snarere end forsigtigt. En studie kan være registreret med gårsdagens dato, vores ur og arkivets behøver ikke at være enige, og en afhentningsgrænse, der linjer op nøjagtigt med en ankomst, mister den. Overlappende gen-spørgning og allerede-settjek stopper duplikaten - så omkostningen ved overlappende er en lidt større forespørgsel, og omkostningen ved ikke at overlappe er en stille overset studie.
22.5.10 begrænsning
Begrænsning afgrænser antallet af match, der accepteres fra én afhentning.
Defaults to 500.
En begrænsning snarere end ingen begrænsning, fordi en forkert match-nøgle omdanner dette til "giv mig alt", og det første symptom på det over for et rigtigt arkiv er arkivets administrator, der spørger, hvem der banker på det.
22.5.11 timeout
Timeout afgrænser én afhentning.
Standardværdi er to minutter.
22.5.12 emit_on_first_poll
EmitOnFirstPoll sender meddelelser for alt, den første afhentning finder.
Standardværdi er falsk.
Falsk er vigtigt. At pege på et arkiv, der allerede holder en million studier, og få det til at sende en meddelelse for hver, er ikke en nyttig første kørsel, og det er den type fejl, der opdages nedstrøms snarere end her. Den første afhentning optager, hvad der eksisterer, og udsender intet; den anden afhentning og derefter rapporterer, hvad der er nyt.
22.6 DICOM Kilde
DICOMKilde modtager billedobjekter som en C-STORE serviceklasse-udbyder.
Hvad et hospital peger en modalitet eller et PACS mod. Mirth kalder dette DICOM-lytteren, og det gør kun C-STORE, så dette er lighed snarere end en undermængde.
Defineret som DICOMSource i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
listen | tekst | ja | — |
ae_title | tekst | nej | — |
allowed_calling_ae | liste af tekst | nej | — |
sop_classes | liste af tekst | nej | — |
transfer_syntaxes | liste af tekst | nej | — |
max_object_bytes | helt tal | nej | — |
idle_timeout | varighed, f.eks. 30s eller 5m | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
22.6.1 lyt
Lyt er adressen til at betjene på.
Kræves. 104 er den registrerede DICOM-port; 11112 er den almindelige alternativ, hvor binding af en privilegeret port ikke er mulig.
22.6.2 ae_title
AETitle er, hvad denne endpoint kalder sig selv.
Stærkt anbefalet snarere end krævet, og advaret om, når fraværende. En sides eneste adgangskontrol på en DICOM-endpoint er ofte AE-titlen, så en endpoint, der accepterer enhver titel, accepterer alt, der kan nå det.
22.6.3 allowed_calling_ae
AllowedCallingAE listar AE-titler, der er tilladt at oprette forbindelse.
Tom accepterer enhver opkaldende.
Dette er den adgangskontrol, DICOM faktisk har. En PACS er rutinemæssigt konfigureret til at acceptere en navngivet opkaldende titel og afvise alt andet, og denne side havde ingen tilsvarende: den opkaldte titel blev kontrolleret - hvilket er navnet, opkaldende ringer, så enhver kan sende det korrekt - mens hvem der ringede, blev optaget i loggen og ellers ignoreret.
Tom accepterer stadig alt, fordi en modalitet, som ingen har nævnt, er den normale tilstand for en første installation, og afvisning som standard ville ødelægge hver enkelt installation på dag én. Den advarer i stedet, og advarslen nævner titlerne, der har oprettet forbindelse, så nogen kan udfylde dette fra, hvad der faktisk ankom.
22.6.4 sop_classes
SOPClasses begrænser, hvilke typer af objekter der accepteres.
Tom accepterer enhver.
Tom er en rimelig standard her, fordi denne motor videreformidler objekter snarere end fortolker dem, så afvisning af en ukendt klasse ville afvise gyldige billeder uden nogen fordel.
22.6.5 transfer_syntaxes
TransferSyntaxes begrænser kodningerne, der accepteres, i foretrukkens rækkefølge.
Tom accepterer de ukomprimerede tre.
22.6.6 max_object_bytes
MaxObjectBytes afgrænser et modtaget objekt.
Nul anvender en standard.
22.6.7 idle_timeout
IdleTimeout lukker en association, der er gået stille.
Nul betyder aldrig, hvilket som regel er korrekt - en modalitet holder en association åben mellem studier.
22.6.8 tls
TLS krypterer indgående associationer og kan kræve en klientcertifikat.
Værd at nævne åbent: Mirth har brug for sin betalte SSL Manager-udvidelse til dette, og de fællesskabsfork kan ikke leveres overhovedet. DICOM indeholder patientnavne i dens metadata, så dette er et af stederne, hvor at være en omskrivning i stedet for en fork er en reel fordel i stedet for en stilistisk.
22.7 DICO Mweb Kilde
DICOMwebSource accepterer STOW-RS-anmodninger.
Defineret som DICOMwebSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
listen | tekst | ja | — |
path | tekst | nej | /dicom-web |
token | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
max_object_bytes | helt tal | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
22.7.1 lyt
Lyt er adressen til at betjene på.
Required.
22.7.2 path
Sti er servicens rod.
Objekter accepteres på Sti/studier og Sti/studier/{uid}. Standard er /dicom-web, som Orthanc og dcm4chee bruger, så en afsender konfigureret til enten af dem behøver kun at ændre værten.
22.7.3 token
Token, når det er angivet, kræves som en bærertoken.
Brugernavn og adgangskode kræver HTTP-basisk godkendelse.
22.7.4 brugernavn
Token, når det er angivet, kræves som en bærertoken.
Brugernavn og adgangskode kræver HTTP-basisk godkendelse.
22.7.5 adgangskode
Token, når det er angivet, kræves som en bærertoken.
Brugernavn og adgangskode kræver HTTP-basisk godkendelse.
22.8 Database Kilde
DatabaseSource læser rækker fra en database og omdanner hver enkelt til en besked.
Dette er, hvordan en stor del af hospitalgrænseflader faktisk starter. Et afdelingsystem har ingen HL7-funktion, så nogen skriver rækker ind i en midlertidig tabel, og grænsefladen poller den. Det er ikke glamourøst, og det er overalt.
Det er også den mest almindelige måde, en Mirth-kanal blokerer, og årsagen er næsten altid den samme form: en række, der ikke kan behandles, læses, mislykkes og læses igen, for evigt, fordi intet markerer den. Kanalen ser levende ud. Køen ser tom ud. Ingen bevæger sig, og hver besked bag den dårlige række venter på en række, der aldrig vil lykkes.
Det meste af designet her handler om det.
Defineret som DatabaseSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
driver | tekst | ja | — |
dsn | tekst | ja | — |
query | tekst | ja | — |
after_query | tekst | nej | — |
key_column | tekst | nej | — |
template | tekst | nej | — |
column | tekst | nej | — |
poll_interval | varighed, f.eks. 30s eller 5m | nej | — |
batch_size | helt tal | nej | 100 |
max_attempts | helt tal | nej | 3 |
query_timeout | varighed, f.eks. 30s eller 5m | nej | 30s |
22.8.1 driver
Driver navngiver databasen.
See SupportedDrivers.
22.8.2 dsn
DSN er forbindelsesstrengen.
Foretræk en reference til en miljøvariabel over en literal, fordi denne normalt indeholder en adgangskode og kanaler er ment til at være i git.
22.8.3 forespørgsel
Forespørgslen vælger rækkerne, der venter på at blive sendt.
Required.
Det skal være en SELECT. En afstemning, der stille og roligt udfører skriver, ville køre på en tidsplan med ingen optegnelse over, hvad den ændrede.
22.8.4 efter_forespørgsel
EfterForespørgsel markerer en række som behandlet og køres med rækens nøgle bundet til den.
Strongly recommended.
Uden det læser hver afstemning hver række, som forespørgslen stadig matcher, så forespørgslen selv må udelade behandlede rækker på en anden måde. Hvis ingen af delene er sande, sender kanalen de samme rækker for evigt, hvilket er en duplikatstorm i stedet for en blokering og er måske endnu værre.
22.8.5 nøglekolonne
NøgleKolonne identificerer en række til EfterForespørgsel, karantæne og deduplikation.
Kræves, når EfterForespørgsel er angivet.
22.8.6 skabelon
Skabelon opbygger en meddelelse fra en række.
Enten dette eller Kolonne er krævet.
Kolonner referencer bruger ${kolonne_navn}. Manglende kolonner er en fejl ved indlæsning i stedet for en tom streng i en klinisk meddelelse.
22.8.7 batch_størrelse
BatchStørrelse begrænser rækkerne, der tages per afstemning.
Defaults to 100.
Begrænset, fordi en ubegrænset første afstemning mod en tabel, som nogen har fyldt i et år, ville læse hele den ind i hukommelsen og derefter sende hele den, hvilket er, hvordan en migration oversvømmer en live modtager.
22.8.8 max_forsøg
MaxForsøg er, hvor mange gange en enkelt række må fejle, før den karantæneres og afstemningen fortsætter.
Defaults to 3.
Dette er indstillingen, der forhindrer blokeringen. At gentage for evigt er ikke robusthed; det er en dårlig række, der stopper et hospital feed.
22.8.9 forespørgsel_tidsgrænse
ForespørgselTidsgrænse begrænser en enkelt afstemning.
Defaults to 30s.
22.9 Direkte kilde
DirekteKilde modtager Direct mail, som HISP leverer: en SMTP-lytter til denne addresses mail.
Hver meddelelse dekrypteres, dens signatur kontrolleres mod anchor og dens underskriver mod Fra, og dens indhold videregives: et XDM-pakkes dokumenter, ellers hver vedhæftning, ellers teksten.
Defineret som DirectSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
listen | tekst | nej | — |
tls_cert | tekst | nej | — |
tls_key | tekst | nej | — |
max_bytes | helt tal | nej | — |
smtp_host | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
imap | DirectIMAP (en blok, udelad for at efterlade) | nej | — |
xdr | DirectXDR (en blok, udelad for at efterlade) | nej | — |
22.9.1 smtp_host
SMTPHost, Brugernavn og Adgangskode er HISP's indsendelsesserver, der bruges til at sende en "behandlet" leveringsmeddelelse (MDN) til afsenderen, når en besked er taget imod.
Uden det sendes der ingen meddelelse.
22.9.2 brugernavn
SMTPHost, Brugernavn og Adgangskode er HISP's indsendelsesserver, der bruges til at sende en "behandlet" leveringsmeddelelse (MDN) til afsenderen, når en besked er taget imod.
Uden det sendes der ingen meddelelse.
22.9.3 adgangskode
SMTPHost, Brugernavn og Adgangskode er HISP's indsendelsesserver, der bruges til at sende en "behandlet" leveringsmeddelelse (MDN) til afsenderen, når en besked er taget imod.
Uden det sendes der ingen meddelelse.
22.10 E-mail Kilde
EmailSource læser mail fra en postkasse og omdanner vedhæftninger, beskeder eller hele meddelelser til beskeder.
Defineret som EmailSource i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
protocol | tekst | nej | — |
host | tekst | ja | — |
port | helt tal | nej | — |
security | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
username | tekst | ja | — |
password | tekst | nej | — |
oauth | EmailOAuth (en blok, udelad for at undlade) | nej | — |
mailbox | tekst | nej | — |
take | tekst | nej | — |
attachment_names | liste af tekst | nej | — |
allowed_senders | liste af tekst | nej | — |
after_read | tekst | nej | — |
move_to | tekst | nej | — |
error_folder | tekst | nej | — |
poll_interval | varighed, såsom 30s eller 5m | nej | — |
max_message_size | helt tal | nej | — |
22.10.1 adgangskode
Adgangskode kan være ${ENV}; til Gmail en app-adgangskode.
Ignoreret med oauth.
22.10.2 attachment_names
AttachmentNames begrænser, hvilke vedhæftninger der tages, efter filnavnmønster (*.hl7).
Tomt tager alle vedhæftninger.
22.10.3 allowed_senders
AllowedSenders begrænser, hvis mail der læses: adresser og domæner.
Fra-hovedningen kan forfalskes, så dette holder uheld og tilfældig mail ude, ikke en angriber.
22.10.4 flyt_til
MoveTo er den mappe, der håndteres mail flyttes til; Behandlet som standard.
Oprettet, når den mangler.
22.11 FTP Kilde
FTPSource indsamler filer fra en FTP eller FTPS-server.
Hvorfor FTP stadig er her
Det er tredive år efter anbefalet erstatning, og mange hospitalsystemer exporterer stadig til det: apparater, hvis firmware aldrig vil blive opdateret, regnskabssystemer, hvis leverandør opkræver for en ændring. At afvise at tale det får ikke disse systemer til at forsvinde, det betyder, at integrationsmotoren ikke kan bruges.
FTPS er standard. Det er det samme protokol med TLS, de fleste overlevende servere understøtter det, og det er en meget lettere samtale med et sikkerhedsteam end plain FTP.
Defineret som FTPSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
host | tekst | ja | — |
user | tekst | nej | — |
password | tekst | nej | — |
security | ftpconn.Security | nej | explicit |
insecure_skip_verify | sandt eller falsk | nej | — |
root | tekst | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | tredive sekunder |
22.11.1 vært
Værten er serveren med en valgfri port.
Port 21 antages.
22.11.2 bruger
Bruger og adgangskode autentificerer.
Begge kan udelades for en anonym server.
Anonym FTP er stadig, hvordan nogle offentlige referencefodring er publiceret, så en tom bruger er en gyldig konfiguration snarere end en oversigt og afvises ikke. På en server, der forventer legitimationsoplysninger, vil udeladelse af dem medføre en fejl ved login på tilslutningstidspunktet, som rapporteres mod kanalen snarere end genoptages stille.
22.11.3 adgangskode
Bruger og adgangskode autentificerer.
Begge kan udelades for en anonym server.
Anonym FTP er stadig, hvordan nogle offentlige referencefodring er publiceret, så en tom bruger er en gyldig konfiguration snarere end en oversigt og afvises ikke. På en server, der forventer legitimationsoplysninger, vil udeladelse af dem medføre en fejl ved login på tilslutningstidspunktet, som rapporteres mod kanalen snarere end genoptages stille.
22.11.4 sikkerhed
Sikkerheden er explicit, implicit eller ingen.
Standard er explicit, som er FTPS forhandlet med AUTH TLS på den almindelige port. "ingen" er plain FTP og skal anmodes om ved navn.
22.11.5 rod
Rod er den mappe, som hver sti er relativ til, og hvad indehold er gennemført imod.
Serveren har ingen forestilling om det: en FTP-server vil gerne acceptere ../.. som en sti. Så dette er, hvad stopper en move_to fra at skrive hvor som helst kontoen kan nå.
22.11.6 timeout
Timeout afgrænser én operation, ikke hele afhentningen.
Standardværdi er tredive sekunder.
Per operation, fordi en afhentning, der lister en mappe og henter tyve filer, udfører enogtyve operationer, og en enkelt budget for alle af dem ville afbryde en fuldstændig sund overførsel af en stor fil.
22.12 Fil kilde
FileSource læser filer fra en mappe, som denne server kan se.
Den forbindelse, et websted forsøger først
En analyser skriver resultater til en mappe. En faktureringsystem dropper en batch om natten. Radiologi eksporterer rapporter til en mappe, som nogen monterede for år siden. Ingen af det involverer en protokol, og en integrationsmotor, der ikke kan læse en mappe, mislykkes i sin vurdering på den første eftermiddag.
Defineret som FileSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
root | tekst | ja | — |
follow_symlinks | sandt eller falsk | nej | — |
22.12.1 rod
Rod afgrænser hver sti, denne kilde rører.
Required.
Separat fra Dir, så move_to og error_dir kan være relative og stadig være indeholdt. Givet kun Dir, ville en error_dir på "../fejlet" være uden for noget, kilden havde fået tilladelse til, og afvisning af det ville være arbitrær, fordi der ikke ville være noget at afvise det imod.
22.13 GCS kilde
GCSSource samler objekter op fra en bucket-præfiks, som s3 og azure_blob-kilderne gør.
Defineret som GCSSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
prefix | tekst | ja | — |
suffix | tekst | nej | — |
after_read | tekst | nej | — |
move_to | tekst | nej | processed/ |
error_prefix | tekst | nej | error/ |
poll_interval | varighed, f.eks. 30s eller 5m | nej | 30s |
max_object_size | helt tal | nej | 16 MiB |
framed | sandt eller falsk | nej | — |
22.13.1 flyt_til
MoveTo er, hvor et behandlet objekt går hen, når after_read er flyt.
Standard er processed/.
22.13.2 fejl_præfiks
ErrorPrefix er, hvor et objekt, der ikke kunne behandles, går hen.
Standard er error/.
22.13.3 afhentningsinterval
PollInterval er, hvor ofte præfikset listenes.
Defaults to 30s.
22.13.4 maks_objektstørrelse
MaxObjectSize lader større objekter være, hvor de er.
Standard er 16 MiB.
22.14 HTTP-kilde
HTTP-kilden accepterer meddelelser over HTTP.
En lytter i stedet for en afhenter: noget posterer en meddelelse og får en bekræftelse tilbage, hvilket er, hvordan den moderne halvdel af hospitalet integrerer, når MLLP ikke er tilgængelig for det.
Defineret som HTTPSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
listen | tekst | ja | — |
path | tekst | nej | "/" |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
token | tekst | nej | — |
max_message_size | helt tal | nej | — |
read_timeout | varighed, f.eks. 30s eller 5m | nej | — |
ack | Ack | nej | — |
22.14.1 lyt
Lyt er adressen til at betjene på.
Required.
22.14.2 path
Sti er URL-stien til at acceptere meddelelser på.
Defaults to "/".
22.14.3 token
Token, når det er angivet, kræves i en Authorization: Bearer-header.
Der er ingen standard og ingen anonym tilstandsknap: en HTTP-endpoint på et hospitalsnetværk med ingen godkendelse overhovedet er en beslutning, der skal være synlig i filen, så lad dette felt være tomt, rapporteres som en advarsel under indlæsning.
22.14.4 max_meddelelse_størrelse
MaxMessageSize begrænser en indgående brødtekst.
Nul anvender en standard.
22.15 IBMMQ-kilde
IBMMQ-kilden læser en kø.
Defineret som IBMMQSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
poll_interval | varighed, f.eks. 30s eller 5m | nej | 2s |
22.15.1 afhentningsinterval
Afhentningsinterval er ventetiden, når køen er tom, eller efter en meddelelse, der ikke kunne behandles.
Defaults to 2s.
22.16 Java Script-kilde
JavaScript-kilden konfigurerer en kilde, der kører et script på en timer og føder de returnerede meddelelser ind i kanalen.
Dette er Mirths "JavaScript-læser"-ækvivalent.
Scriptet kører i en goja-VM med samme sandkasse som transformerings-script: msg er ikke tilgængelig (der er ingen indgående meddelelse endnu), men globalMap, configurationMap, logger og DateUtil er til stede. Scriptet skal returnere en streng (en meddelelse) eller en matrix af strenge (mange). At returnere ingenting eller en tom matrix betyder, at afhentningen producerede ingen meddelelser, hvilket er normalt.
Defineret som JavaScriptSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
script | tekst | ja | — |
poll_interval | varighed, såsom 30s eller 5m | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | — |
22.16.1 afhentningsinterval
PollInterval er, hvor ofte scriptet køres.
Nul betyder 5 sekunder.
22.16.2 timeout
Timeout begrænser en enkelt scriptkørsel.
Nul betyder 30 sekunder.
22.17 Kafka Kilde
KafkaSource læser meddelelser fra et Kafka-emne.
Defineret som KafkaSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
brokers | liste af tekst | ja | — |
topics | liste af tekst | ja | — |
group | tekst | ja | — |
from_beginning | sandt eller falsk | nej | — |
commit_after_delivery | sandt eller falsk (en blok, udelad for at udelade) | nej | — |
max_message_size | helt tal | nej | kanallens begrænsning |
session_timeout | varighed, f.eks. 30s eller 5m | nej | femogfyrre sekunder |
timeout | varighed, f.eks. 30s eller 5m | nej | tredive sekunder |
sasl | KafkaSASL (en blok, udelad for at udelade) | nej | — |
tls | tlsconf.Settings (en blok, udelad for at udelade) | nej | — |
22.17.1 brokers
Brokers er den bootstrap-serverliste.
Required.
En liste i stedet for en enkelt adresse, fordi en enkelt bootstrap-broker er et enkelt fejlpunkt for opstart: clusteren overlever tabet af den, og denne kanal ville ikke.
22.17.2 emner
Emnerne er de emner, der læses.
Mindst én er påkrævet.
22.17.3 gruppe
Gruppe er forbrugergruppen.
Required.
Navngivet i stedet for genereret, og påkrævet i stedet for standard, fordi det er det, der husker, hvor langt denne kanal har læst. En genereret gruppe ville starte fra begyndelsen - eller fra enden, tabe alt - ved hver genstart, og den ville efterlade den gamle gruppe bagved med committed offsets, som ingen læser. At kræve det gør personen navngive det, der skal være det samme på tværs af genstart.
22.17.4 fra_begyndelsen
FraBegyndelsen læser emnet fra starten, når gruppen ikke har nogen committed offset.
Slået fra som standard, så en ny kanal, der peger på et emne med to års historik, ikke afspiller to års patienthændelser i et live-system på den dag, det tændes. Den første person, der rammer det, ville gøre det i produktion, fordi det er der, emnet med historikken er.
22.17.5 commit_etter_levering
CommitEfterLevering committer offset kun, når meddelelsen er blevet behandlet.
Slået til som standard, og årsagen er hele forskellen på at tabe en meddelelse og se den to gange. At committere ved læsning betyder, at et crash mellem commit og levering taber meddelelsen stille, og intet sted optager, at den eksisterede. At committere efter betyder, at et crash i samme vindue leverer den igen, hvilket er synligt, og som HL7-modtagere er bygget til at tolerere - en duplikat A08 er en generthed, og en manglende laboratorie-resultat er en patient-sikkerhedshændelse.
22.17.6 max_meddelelse_størrelse
MaxMeddelelseStørrelse begrænser en enkelt post.
Standardværdi er kanallens begrænsning.
22.17.7 session_udløb
SessionTimeout angiver, hvor lang tid gruppekoordinatoren venter, før den antager, at denne forbruger er væk, og genplacerer dets partitioner.
Standardværdi er førtifem sekunder.
22.17.8 timeout
Tidsbegrænsninger for forbindelse og metadataanmodninger.
Standardværdi er tredive sekunder.
22.18 MQTT Kilde
MQTTSource abonnerer på en emnefilter.
Defineret som MQTTSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
topic | tekst | ja | — |
reconnect | varighed, f.eks. 30s eller 5m | nej | 5s |
22.18.1 reconnect
Genopret er ventetiden efter en tabt forbindelse eller efter en besked, der ikke kunne håndteres.
Defaults to 5s.
22.19 Pub Sub Kilde
PubSubSource henter fra en Pub/Sub-abonnement.
Defineret som PubSubSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
subscription | tekst | ja | — |
max_messages | helt tal | nej | 10 |
reconnect | varighed, f.eks. 30s eller 5m | nej | 5s |
22.19.1 max_besked
MaxBeskeder er, hvor mange der hentes ad gangen.
De håndteres stadig én ad gangen, i rækkefølge. Standardværdi er 10.
22.19.2 reconnect
Genopret er ventetiden efter en fejl.
Defaults to 5s.
22.20 S3 Kilde
S3Source henter objekter fra en bucket.
Defineret som S3Source i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
bucket | tekst | ja | — |
path_style | sandt eller falsk | nej | — |
prefix | tekst | nej | — |
suffix | tekst | nej | — |
after_read | tekst | nej | — |
move_to | tekst | nej | processed/ |
error_prefix | tekst | nej | error/ |
poll_interval | varighed, f.eks. 30s eller 5m | nej | 30s |
max_object_size | helt tal | nej | 16 MiB |
framed | sandt eller falsk | nej | — |
22.20.1 præfiks
Præfiks begrænser, hvilke objekter der læses, f.eks. inbound/.
Tomme læsninger af hele bucketen nægtes med efter_læs: flyt, medmindre flyt_til er uden for den - ellers ville flyttede objekter blive læst igen.
22.20.2 efter_læs
AfterRead flytter (standard) eller sletter.
Der er ingen mulighed for at lade vær: En bucket har ingen fil, som en poller kan huske at have set på tværs af en genstart, så lægge objekter betyder at læse dem alle igen hver gang Perfuse starter.
22.20.3 flyt_til
MoveTo er præfikset for et behandlet objekt, der flyttes til.
Standard er processed/.
22.20.4 fejl_præfiks
ErrorPrefix er, hvor et objekt, der ikke kan behandles, flyttes til, så en dårlig fil ikke blokerer resten.
Standard er error/.
22.20.5 afhentningsinterval
Afhentningsinterval mellem listinger.
Defaults to 30s.
22.20.6 maks_objektstørrelse
MaxObjectSize afviser alt, der er større.
Standard er 16 MiB.
22.20.7 rammet
Framed læser flere MLLP-rammede meddelelser fra ét objekt.
Ellers er et objekt én meddelelse.
22.21 SFTP Kilde
SFTPSource indsamler meddelelser fra en mappe på en SFTP-server.
Ekstremt almindelig og sjældent diskuteret. Et laboratorium eller et radiologisystem skriver en fil hver få minutter, en SFTP-server holder den, og noget skal komme og hente den. Halvdelen af feeds, der beskrives som "vi sender dig HL7", er dette.
Den del, der kræver omsorg, er ikke overførslen. Det er, at en fil, der skrives til, og en fil, der er færdig med at blive skrevet til, ser ens ud over SFTP, så en poll, der er så meget som lidt for ivrig, indsamler en halv meddelelse. Dette resulterer i en afkortet, men ofte parsebar HL7-meddelelse, som er det værste resultat, der er tilgængeligt: Den accepteres, bekræftes, gemmes og leveres, og den manglende halvdel nævnes aldrig igen.
Defineret som SFTPSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
host | tekst | ja | 22 |
user | tekst | ja | — |
password | tekst | nej | — |
key_file | tekst | nej | — |
key_passphrase | tekst | nej | — |
known_hosts_file | tekst | nej | — |
insecure_skip_host_key_check | sandt eller falsk | nej | — |
dir | tekst | ja | — |
pattern | tekst | nej | alt |
poll_interval | varighed, f.eks. 30s eller 5m | nej | — |
after_read | tekst | nej | — |
move_to | tekst | nej | — |
error_dir | tekst | nej | — |
stable_for | varighed, f.eks. 30s eller 5m | nej | 5s |
framed | sandt eller falsk | nej | — |
max_file_size | helt tal | nej | 64MB |
timeout | varighed, f.eks. 30s eller 5m | nej | 60s |
22.21.1 vært
Værten er serveren med en valgfri port.
Defaults to 22.
22.21.2 adgangskode
Adgangskode godkender med en adgangskode.
Prefer KeyFile.
22.21.3 nøglefil
Nøglefil er en privat nøgle.
Det bedre valg, og det, som hospitalernes sikkerhedshold beder om.
22.21.4 kendte_værter_fil
KendteVærterFil verificerer serverens identitet.
Kræves, medmindre InsecureSkipHostKeyCheck er angivet. Uden det er der intet, der kan skelne den rigtige server fra noget, der besvarer på den adresse, og legitimationsoplysningerne overdrages, før nogen lægger mærke til det.
22.21.5 insecure_skip_host_key_check
InsecureSkipHostKeyCheck accepterer enhver værtsnøgle.
Findes, fordi en direkte afvisning sender folk til et shell-script med StrictHostKeyChecking=no, som er værre på alle måder, herunder overholdelse af regler. Den advarer højlydt, og den er aldrig standard.
22.21.6 mønster
Mønster vælger filer efter glob.
Standardværdi er alt.
22.21.7 flyt_til
MoveTo er den fjerndirectory, som filer flyttes til efter læsning.
Kræves, når AfterRead er "flyt".
22.21.8 stable_for
StableFor er, hvor lang tid en fils størrelse og ændringsdato skal være uændret, før den læses.
Defaults to 5s.
Dette er indstillingen, der forhindrer, at halvdelen af en meddelelse indsamles. Nul betyder, at der læses, hvad der er der, hvilket virker, indtil en fil er stor nok eller et netværk langsomt nok til, at skrivning tager længere tid end en afstemning.
22.21.9 rammet
Framed angiver, at filen indeholder MLLP-rammede meddelelser.
Når dette er falsk, deles filen op efter MSH-grænser.
22.21.10 max_file_size
MaxFileSize afviser en fil, der er større end dette antal byte.
Standardværdi er 64 MB.
22.21.11 timeout
Timeout begrænser en enkelt forbindelse.
Defaults to 60s.
22.22 SMB Kilde
SMBKilde indsamler filer fra en Windows-fildeling.
Defineret som SMBSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
host | tekst | ja | — |
share | tekst | ja | — |
user | tekst | nej | — |
password | tekst | nej | — |
domain | tekst | nej | — |
root | tekst | nej | — |
timeout | varighed, f.eks. 30s eller 5m | nej | tredive sekunder |
22.22.1 vært
Værten er serveren med en valgfri port.
Port 445 antages.
22.22.2 fildeling
Fildeling er kun fildelingsnavnet: "data" i \\\server\data.
En sti her afvises i stedet for at blive klippet.
22.22.3 bruger
Bruger og adgangskode er det Windows-konto.
Kræves i praksis.
En fildeling, der kan nås uden nogen legitimationsoplysninger overhovedet, er sjælden nok på et domæne, så en tom bruger her er langt mere sandsynlig at være en fejl end en gæstefildeling - men den accepteres, fordi afvisning af den ville blokere den ene ordning, hvor det er korrekt. Hvor kontoen tilhører et domæne, skal domænet også angives: godkendelse af en domænekonto uden det mislykkes på en måde, der ligner en forkert adgangskode.
22.22.4 adgangskode
Bruger og adgangskode er det Windows-konto.
Kræves i praksis.
En fildeling, der kan nås uden nogen legitimationsoplysninger overhovedet, er sjælden nok på et domæne, så en tom bruger her er langt mere sandsynlig at være en fejl end en gæstefildeling - men den accepteres, fordi afvisning af den ville blokere den ene ordning, hvor det er korrekt. Hvor kontoen tilhører et domæne, skal domænet også angives: godkendelse af en domænekonto uden det mislykkes på en måde, der ligner en forkert adgangskode.
22.22.5 domæne
Domæne er den Windows-domæne eller arbejdsgruppe.
Tomt er normalt korrekt for en lokal konto.
22.22.6 timeout
Timeout begrænser én operation.
Standardværdi er tredive sekunder.
Værd at øge, hvis en fil ressource nås via en site-forbindelse. En SMB-operation mod en fjernserver er langsommere end samme operation lokalt, og en standard, der er tilpasset et LAN, kan resultere i timeouts, der ligner en utilgængelig fil ressource.
22.23 SOAP Kilde
SOAP Kilde accepterer meddelelser indpakket i en SOAP-enveloppe.
Modstykket til SOAP destination og den mindre almindelige retning: de fleste hospital-integrationer har Perfuse, der kalder en tjeneste i stedet for at være en. Den findes, fordi Mirths Web Service Listener findes, og et websted, hvis afsendende system kun taler SOAP, ikke kan migrere uden den.
Bevidst ikke en generel webtjenesteframework. Den accepterer en enveloppe, tager meddelelsen ud af den og besvarer med en enveloppe. Der er ingen WS-Security, ingen MTOM, ingen WS-Addressing og ingen genererede bindings - samme udeladelser som destinationen, af samme grund: en halvimplementering af WS-Security er værre end ingen.
Defineret som SOAPSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
listen | tekst | ja | — |
profile | tekst | nej | — |
path | tekst | nej | "/" |
version | tekst | nej | 1 |
element | tekst | nej | — |
base64 | sandt eller falsk | nej | — |
response_element | tekst | nej | "AckResponse" |
response_namespace | tekst | nej | — |
wsdl | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
token | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
max_message_size | helt tal | nej | — |
read_timeout | varighed, f.eks. 30s eller 5m | nej | — |
ack | Ack | nej | — |
fault_on_nak | sandt eller falsk | nej | — |
22.23.1 lyt
Lyt er adressen til at betjene på.
Required.
22.23.2 profil
Profilnavn angiver en standardtjeneste, som denne slutpunkt implementerer.
Tomt accepterer enhver enveloppe, som er konfigureret nedenfor.
"cdc-iis" besvarer, som en vaccinationsregister gør, på CDC-grænsefladen (urn:cdc:iisb:2011): connectivityTest bliver gentaget, submitSingleMessages hl7Message er meddelelsen, og kanalen acknowledgement bliver returneret, WSDL bliver serveret på ?wsdl, og brugernavn og adgangskode, når de er angivet, bliver kontrolleret mod dem i brødteksten (hvor WSDL placerer dem) i stedet for mod HTTP-autentificering. Til en test-dobbeltgænger for et register eller til et websted, der modtager indsendelser, som registre gør.
22.23.3 path
Sti er URL-stien for at acceptere envelopper på.
Defaults to "/".
22.23.4 version
Version er den SOAP-version, der skal besvares i, "1.1" eller "1.2".
Defaults to 1.1.
Anmodninger accepteres i begge versioner uanset, fordi en afsender, der får dette forkert, er almindelig, og afvisning af det lærer ingen noget. Indstillingen kontrollerer svaret, hvor forkert betyder, at afsenderen ikke kan læse svaret.
22.23.5 element
Elementnavn angiver det element inde i SOAP-Brødteksten, der indeholder meddelelsen.
Tomt betyder hele brødteksten.
Navngivet i stedet for gættet, fordi en brødtekst kan medføre flere elementer - en meddelelse sammen med en afsender-identifikator og en tidsstempel - og at tage hele brødteksten ville give motoren en XML-fragment, hvor den forventede HL7.
22.23.6 base64
Base64 afkoder elementindholdet, før det behandles som en meddelelse.
Almindeligt i rigtige tjenester, fordi HL7 medfører vende linjer, og opkaldere, der ikke tænkte på det, ender med XML, der ødelægger dem. Hvis indholdet afkodes som base64, men ikke var ment til at være det, er resultatet ikke en meddelelse, og motoren siger det - hvilket er, hvorfor dette er eksplitt i stedet for snuset.
22.23.7 svar_element
ResponseElement navner det element, der indeholder bekræftelsen i svaret.
Standardværdi er "AckResponse".
22.23.8 wsdl
WSDL er en fil, der serveres på lytningssøgeadressen med ?wsdl.
Tom betyder, at ingen fil serveres.
En fil i stedet for noget, der genereres. En genereret WSDL ville beskrive, hvad denne endpoint accepterer, hvilket næsten aldrig er det, som sendesystemet er bygget til - og en WSDL, der er næsten rigtig, koster mere tid end ingen WSDL overhovedet, fordi den ser autoritativ ud.
22.23.9 brugernavn
Brugernavn og adgangskode kræver, når de er angivet, HTTP-basisk godkendelse.
Tilbudt sammen med en token, fordi SOAP-kaldere overvældende forventer basisk godkendelse, og et websted, hvis sendesystem ikke kan ændres, har brug for den mulighed, det allerede har.
22.23.10 adgangskode
Brugernavn og adgangskode kræver, når de er angivet, HTTP-basisk godkendelse.
Tilbudt sammen med en token, fordi SOAP-kaldere overvældende forventer basisk godkendelse, og et websted, hvis sendesystem ikke kan ændres, har brug for den mulighed, det allerede har.
22.23.11 max_meddelelse_størrelse
MaxMessageSize begrænser en indgående brødtekst.
Nul anvender en standard.
22.23.12 fejl_på_nak
FaultOnNak returnerer en SOAP-fejl i stedet for et normalt svar, der indeholder NAK, som svar på en negativ bekræftelse.
Slået fra som standard, hvilket er den rigtige standard og værd at forklare. HL7 har allerede en måde at sige "Jeg modtog dette og afviste det" på, og det er en NAK - en succesfuld udveksling, der rapporterer om en afvist besked. At omdanne det samme til en transportfejl fortæller afsenderen, at dens anmodning var forkert, hvilket den ikke var, og mange klienter responderer ved at prøve igen i al evighed.
Den findes, fordi nogle kaldere kun ser på HTTP-status og ellers ville behandle en afvisning som succes.
22.24 SQS kilde
SQSSource læser fra en SQS-kø.
En besked slettes kun efter, at kanalen har behandlet den - leveret, eller filtreret, eller fejlet på en måde, som kanalen optegner. Indtil da forbliver den i køen, usynlig for visibility_timeout, og kommer tilbage, hvis Perfuse stopper. Så en besked går aldrig tabt; prisen er, at en kan ankomme to gange, hvilket SQS selv allerede tillader.
Defineret som SQSSource i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
queue_url | tekst | ja | — |
wait_seconds | hele tal | nej | 20: en tom kø koster en anmodning hver tyvende sekund |
max_messages | hele tal | nej | 10 |
visibility_timeout | varighed, såsom 30s eller 5m | nej | køens egen indstilling |
22.24.1 visibility_timeout
VisibilityTimeout er, hvor lang tid en modtaget besked forbliver skjult, mens den behandles.
Standardværdi er køens egen indstilling.
22.25 Seriel kilde
SerialSource læser beskeder fra en seriel port.
Hvorfor en seriel connector i 2026
Fordi udstyret stadig findes. En blodgasanalyser købt i 2009 med en fungerende sensor og en 25-pins stik, en sengekantmonitor, en vægt i en dialyseenhed, en ældre anæstesimaskine. Ingen af dem får nogensinde en Ethernet-port, flere af dem koster seks cifre, og alternativet til at læse dem er, at nogen skriver resultaterne ind i en formular.
Mirth har en serieconnector. Perfuse havde intet, og et websted med en af disse havde overhovedet ingen rute ind.
Ramningen deles med TCP-connector
Ramningerne er de samme, uanset hvor byte kommer fra: en analyser, der taler STX/ETX over en socket, taler STX/ETX over en kabel. Derfor genbruges TCP-ramningsblokken i stedet for at definere sin egen, hvilket også betyder, at en enhed, der flyttes fra en seriekabel til en serie-til-Ethernet-adapter, beholder sin ramningskonfiguration.
Hvad er forskellen på en seriekabel
Der er ingen forbindelse. En socket fortæller dig, når modparten er gået væk; en kabel gør ikke. En afbrudt kabel, en enhed slukket og en enhed med intet at sige er ikke til at skelne - alle tre er tavshed. Det er derfor, quiet_after findes: uden noget at sige "denne linje har været stille i længere tid, end den burde være", ser en død feed ud præcis som en stille nat.
Defineret som SerialSource i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
port | tekst | ja | — |
baud | helt tal | ja | — |
data_bits | helt tal | nej | 8 |
parity | tekst | nej | ingen |
stop_bits | tekst | nej | 1 |
flow_control | tekst | nej | ingen |
max_message_size | helt tal | nej | — |
quiet_after | varighed, f.eks. 30s eller 5m | nej | — |
reply | tekst | nej | — |
reply_text | tekst | nej | — |
reopen_after | varighed, f.eks. 30s eller 5m | nej | — |
22.25.1 baud
Baud er hastigheden.
Kræves, fordi gætning producerer bytes i stedet for en fejl.
En forkert baudrate mislykkes ikke. Den leverer troværdigt udseende skrammel: ramningsbytes vises tilfældigt, lejlighedsvis kører decode som printable tegn, og en tolerant parser accepterer noget af det. Der er bevidst ingen standard.
22.25.2 parity
Parity er ingen, ulig, lige, mærke eller rum.
Standard er ingen.
22.25.3 stop_bits
StopBits er 1, 1,5 eller 2, skrevet som "1", "1,5" eller "2".
Defaults to 1.
22.25.4 flow_control
FlowControl er ingen, hardware eller software.
Standard er ingen.
Værd at indstille korrekt i stedet for at lade det stå. Med hardware-flowcontrol forventet og ikke konfigureret, stopper en enhed med at sende midt i en lang besked, og resultatet er en afkortet besked i stedet for en fejl.
22.25.5 quiet_after
QuietAfter logger en advarsel, når intet er modtaget i denne længde.
Den eneste måde at bemærke en død seriefeed på. En afbrudt kabel og en stille nat er den samme tavshed, så nogen må sige, hvor lang tid der er for længe for denne enhed.
22.25.6 reopen_after
ReopenAfter er, hvor lang tid man skal vente, før man genåbner en port, der fejlede.
En USB-serieadapter, der er afbrudt og genopluset, kommer tilbage som den samme enhedssti, men en anden kernelhåndtering, så den gamle returnerer fejl for evigt. Genåbning er den eneste genoprettelse, og at gøre det i en tæt løkke fylder loggen.
22.26 Kilde
Kilde er, hvor en kanal modtager beskeder.
Defineret som Source i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
type | SourceType | ja | — |
listen | tekst | ja | — |
max_message_size | helt tal | nej | — |
idle_timeout | varighed, f.eks. 30s eller 5m | nej | — |
max_connections | helt tal | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
http | HTTPSource (en blok, udelad for at undlade) | nej | — |
soap | SOAPSource (en blok, udelad for at undlade) | nej | — |
dicomweb | DICOMwebSource (en blok, udelad for at undlade) | nej | — |
direct | DirectSource (en blok, udelad for at undlade) | nej | — |
dicom | DICOMSource (en blok, udelad for at undlade) | nej | — |
file | FileSource (en blok, udelad for at undlade) | nej | — |
tcp | TCPSource (en blok, udelad for at undlade) | nej | — |
ftp | FTPSource (en blok, udelad for at undlade) | nej | — |
smb | SMBSource (en blok, udelad for at undlade) | nej | — |
webdav | WebDAVSource (en blok, udelad for at undlade) | nej | — |
serial | SerialSource (en blok, udelad for at undlade) | nej | — |
dicom_query | DICOMQuerySource (en blok, udelad for at undlade) | nej | — |
broker | BrokerSource (en blok, udelad for at undlade) | nej | — |
kafka | KafkaSource (en blok, udelad for at undlade) | nej | — |
sqs | SQSSource (en blok, udelad for at undlade) | nej | — |
s3 | S3Source (en blok, udelad for at undlade) | nej | — |
amqp | AMQPSource (en blok, udelad for at undlade) | nej | — |
azure_blob | AzureBlobSource (en blok, udelad for at undlade) | nej | — |
email | EmailSource (en blok, udelad for at undlade) | nej | — |
as2 | AS2Source (en blok, udelad for at undlade) | nej | — |
pgp | PGPReceive (en blok, udelad for at undlade) | nej | — |
mqtt | MQTTSource (en blok, udelad for at undlade) | nej | — |
ibm_mq | IBMMQSource (en blok, udelad for at undlade) | nej | — |
pubsub | PubSubSource (en blok, udelad for at undlade) | nej | — |
gcs | GCSSource (en blok, udelad for at undlade) | nej | — |
database | DatabaseSource (en blok, udelad for at undlade) | nej | — |
sftp | SFTPSource (en blok, udelad for at undlade) | nej | — |
javascript | JavaScriptSource (en blok, udelad for at undlade) | nej | — |
ack | Ack | nej | — |
22.26.1 type
Type er transporten.
Kun mllp er implementeret.
22.26.2 max_meddelelse_størrelse
MaxMessageSize begrænser en indgående besked.
Nul bruger transportens standardværdi.
22.26.3 idle_timeout
IdleTimeout lukker en forbindelse, der har været stille i denne tid.
Nul betyder aldrig, hvilket normalt er rigtigt: et hospitalfeed holder en forbindelse åben i måneder og går stille om natten.
22.26.4 max_connections
MaxConnections begrænser samtidige forbindelser.
Nul betyder ubegrænset.
22.27 TCP-kilde
TCPSource lytter på en socket efter beskeder, der ikke nødvendigvis er HL7.
Hvorfor dette er adskilt fra en mllp-kilde
MLLP er en ramme og Perfuse har altid talt det. Meget udstyr gør ikke: et laboratorieanalyseapparat, en vægt, en monitor ved sengen, et ældre regnskabssystem. Hver har sin egen konvention, og Mirths TCP-connector dækker alle disse, så et sted med en socketfeed, der ikke var HL7, kunne ikke bruge Perfuse overhovedet.
Defineret som TCPSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
listen | tekst | ja | — |
max_message_size | helt tal | nej | — |
idle_timeout | varighed, f.eks. 30s eller 5m | nej | — |
max_connections | helt tal | nej | — |
reply | tekst | nej | — |
reply_text | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
22.27.1 idle_timeout
IdleTimeout lukker en forbindelse, der har været stille i denne tid.
Nul betyder aldrig, hvilket normalt er rigtigt: en enhedsfeed holder en forbindelse åben i måneder og går stille om natten.
22.27.2 max_connections
MaxConnections begrænser samtidige forbindelser.
Nul betyder ubegrænset.
22.27.3 reply
Svar er, hvad der skal sendes tilbage efter hver besked: intet, ack eller en fast streng.
De fleste rå feeds forventer intet. Nogle forventer en enkelt ACK-bajt. En enhed, der forventer et svar og ikke får det, gentager normalt den samme besked for evigt, så dette er værd at være eksplicit om.
22.28 Web DAV-kilde
WebDAVSource indsamler filer fra en WebDAV-samling.
Hvor dette dukker op: dokumenthåndteringssystemer, SharePoint, Nextcloud og leverandørportaler, der eksponerer en drop-mappe over HTTPS, fordi det er den eneste udgående port, der tillades af deres kunders brandvægge.
Defineret som WebDAVSource i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
url | tekst | ja | — |
user | tekst | nej | — |
password | tekst | nej | — |
insecure_skip_verify | sandt eller falsk | nej | — |
timeout | varighed, f.eks. 30s eller 5m | nej | sekssindstyve sekunder |
22.28.1 bruger
Bruger og adgangskode autentificerer med HTTP-basisautentificering.
Basisautentificering sender adgangskoden i en header, der kun er beskyttet af TLS, så disse hører sammen med en https-URL. Over http er de læselige for alt på vej, og der kommer ingen advarsel fra serveren, der fortæller dig det.
22.28.2 adgangskode
Bruger og adgangskode autentificerer med HTTP-basisautentificering.
Basisautentificering sender adgangskoden i en header, der kun er beskyttet af TLS, så disse hører sammen med en https-URL. Over http er de læselige for alt på vej, og der kommer ingen advarsel fra serveren, der fortæller dig det.
22.28.3 timeout
Timeout begrænser en anmodning.
Standard er sekunder.
Længere end FTP- og SMB-standarder med vilje. En WebDAV-samlingsoversigt er en enkelt PROPFIND, som serveren kan bruge lang tid på at samle for en stor mappe, og der er ingen delvis resultat at falde tilbage på.
23 Destination Reference
Enhver måde, en kanal kan sende meddelelser på, og hver nøgle, hver af dem accepterer. En kanal kan have et vilkårligt antal destinationer, og de er uafhængige: en fejl stopper ikke de andre.
23.1 AMQP Destination
AMQPDestination sender til en kø eller emne, og rapporterer kun succes, når brokeren har accepteret meddelelsen.
Defineret som AMQPDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
content_type | tekst | nej | kanalens datatype |
23.1.1 content_type
ContentType sendes med hver meddelelse.
Standard er kanalens datatype.
23.2 AS2 Destination
AS2Destination sender hver meddelelse som AS2: signeret med vores nøgle, krypteret til partnerens certifikat, offentliggjort på partnerens URL og, som standard, leveret kun, når partnerens signeret kvittering navngiver den samme digest.
Defineret som AS2Destination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
url | tekst | ja | — |
from | tekst | ja | — |
to | tekst | ja | — |
cert_file | tekst | nej | — |
key_file | tekst | nej | — |
partner_cert_file | tekst | nej | — |
unsigned | sandt eller falsk | nej | — |
unencrypted | sandt eller falsk | nej | — |
compress | sandt eller falsk | nej | — |
receipt | tekst | nej | — |
unsigned_receipt | sandt eller falsk | nej | — |
receipt_url | tekst | nej | — |
content_type | tekst | nej | — |
file_name | tekst | nej | — |
subject | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
23.2.1 compress
Compress komprimerer payloaden (zlib, RFC 5402) før signering og kryptering.
Hver AS2-modtager, der annoncerer version 1.1 eller senere, læser det; spørg partneren, før du aktiverer det.
23.2.2 unsigned_receipt
UnsignedReceipt anmoder om en kvittering, der ikke er signeret.
Fra: en signeret anmodes om, og en unsigned afvist.
23.2.3 content_type
ContentType er payloadens MIME-type.
Standard efter kanalens data type: application/edi-x12, application/edifact, application/hl7-v2, ellers application/octet-stream.
23.3 Azure Blob Destination
AzureBlobDestination skriver hver besked som en block blob.
Defineret som AzureBlobDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
blob | tekst | nej | ${date}/${channel}/${control_id} |
tier | tekst | nej | — |
content_type | tekst | nej | — |
23.3.1 blob
Blob navngiver hver blob, med S3-destinationspladsholdere.
Standard er ${date}/${channel}/${control_id}.hl7.
23.3.2 tier
Tier er Hot, Cool, Cold eller Arkiv.
Arkiv er offline: læsning af en blob igen betyder genopfyldning, hvilket tager timer.
23.4 Broker Destination
BrokerDestination offentliggør beskeder til en message broker.
Mirth's JMS Writer.
Defineret som BrokerDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
addr | tekst | ja | — |
destination | tekst | ja | — |
login | tekst | nej | — |
passcode | tekst | nej | — |
host | tekst | nej | adressens host |
content_type | tekst | nej | text/plain for HL7 |
headers | mapping af tekst til tekst | nej | — |
persistent | sandt eller falsk (en blok, udelad for at lade være) | nej | sandt |
timeout | varighed, såsom 30s eller 5m | nej | — |
tls | tlsconf.Settings (en blok, udelad for at lade være) | nej | — |
23.4.1 adresse
Addr er brokerens vært og port.
Required.
23.4.2 destination
Destination er køen eller emnet, der offentliggøres til.
Required.
23.4.3 login
Login og adgangskode autentificerer.
De fleste brokere afviser en anonym forbindelse.
23.4.4 adgangskode
Login og adgangskode autentificerer.
De fleste brokere afviser en anonym forbindelse.
23.4.5 vært
Vært er den virtuelle vært.
Standardværdi er adressens vært.
Værd at angive eksplicit på en broker, der værter flere virtuelle værter, hvor standarden lander offentliggørelsen på hvilken som helst, der svarer til serverens eget navn - en kø, der findes, accepterer beskeden og læses af ingen.
23.4.6 content_type
ContentType sendes med hver meddelelse.
Standard er text/plain for HL7.
23.4.7 headers
Headers sendes med hver besked.
Konfiguration kun, aldrig meddelelseindhold. En header, der tages fra et felt, ville placere en patientidentifikator i brokerens metadata, der logges, indekseres og er synlig for alle andre programmer på køen.
23.4.8 varig
Varig beder brokeren om at overleve en genstart.
Standardværdi er sand.
Sand, fordi en ikke-varig meddelelse går tabt, når brokeren genstartes, og det er ikke en rimelig standard for kliniske data. Falsk findes til en virkelig midlertidig feed - et overvågningsheartbeat - og skal vælges.
23.5 CDA-destination
CDADestination konfigurerer en CDA-destination: den tager det kliniske dokument, der er indeholdt i en HL7 v2-meddelelse, konverterer det og skriver eller posterer resultatet.
Dette eksisterer, fordi et dokument næsten aldrig ankommer på egen hånd. Det ankommer base64-kodet inde i en MDM^T02, og hver engine, der behandler meddelelsen som en uigennemsigtig blob, lader dokumentet være ulæst. At eje begge ender af det er pointen.
Defineret som CDADestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
url | tekst | nej | — |
dir | tekst | nej | — |
write | tekst | nej | — |
version | tekst | nej | R5 |
identifier_systems | mapping af tekst til tekst | nej | — |
require_agreement | sand eller falsk | nej | — |
on_no_document | tekst | nej | — |
headers | mapping af tekst til tekst | nej | — |
bearer_token | tekst | nej | — |
23.5.1 url
URL er en FHIR-server, der posterer den konverterede samling.
Lad den være tom for at skrive til Dir i stedet. En af de to er påkrævet.
23.5.2 dir
Dir skriver output til filer i stedet for at poste det.
Nyttigt til en landingssone, som en anden proces samler op, og til at se, hvad konverteringen producerer, før den pege på en live-server.
23.5.3 write
Write vælger, hvad der skrives eller posterer:
fhir den konverterede transaktionsbundle (standard) dokumenter det originale dokument i ubændret form, både begge, med dokumentet sammen med bundt overfører en PACIO Transitions of Care overførselsresumé: en FHIR R4-dokumentbundle for det sted, patienten går til herefter (et plejehjem, en rehabiliteringsenhed, hjemmesygepleje), offentliggjort på url/Bundle eller skrevet til dir
"dokument" er værd at have på egen hånd: et websted, der ønsker sine CDAs på disk til en records-team, har ikke brug for FHIR-konverteringen overhovedet.
23.5.4 identifier_systems
IdentifierSystems mapper et OID-rod fra dokumentet til en URI, så et MRN bliver navngivet.
En CDA identificerer personer ved OID og FHIR ved URI, og intet kan udlede den ene fra den anden.
23.5.5 require_agreement
RequireAgreement afviser et dokument, hvis narrative og kodet indtastninger modsiger hinanden.
Er fra standard deaktiveret, og det er med vilje. Kontrollen er værdifuld, men det er en vurdering af et dokument, som en anden person har skrevet, og en kanal, der stille droppe virkelige kliniske dokumenter, fordi en senders C-CDA-genererator er sløv, er værre end en, der sender dem videre med en advarsel. Et websted, der har set på sine egne fund og besluttet, at det ønsker porten, kan aktivere den.
23.5.6 på_intet_dokument
OnNoDocument afgør, hvad der sker, når meddelelsen ikke indeholder nogen klinisk dokument:
spring over leverer intet og rapporterer succes (standard) fejl behandle det som en leveringsfejl
Standarden er spring over, fordi en kanal, der transporterer en blandet ADT- og MDM-feed, ellers ville fejle ved hver indlæggelse. En kanal, der er dedikeret til dokumenter, skal sætte fejl, da et dokumentmeddelelse uden dokument i det er et rigtigt problem hos afsenderen.
23.5.7 bærertoken
BearerToken sendes som en Authorization-header.
Foretræk en miljøvariabelreference over en litteral i en fil, der går ind i git.
23.6 Kanaldestination
Kanaldestination router til en anden kanal på samme server.
Defineret som ChannelDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
name | tekst | ja | — |
23.7 DICOM-destination
DICOMDestination sender billedobjekter som en C-STORE-serviceklassebruger.
Mirth kalder dette DICOM-afsenderen.
Defineret som DICOMDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
address | tekst | ja | — |
called_ae | tekst | nej | — |
calling_ae | tekst | nej | — |
transfer_syntaxes | liste af tekst | nej | — |
timeout | varighed, f.eks. 30s eller 5m | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
23.7.1 adresse
Adresse er den fjerne vært og port.
Required.
23.7.2 kaldt_ae
CalledAE er, hvad den fjerne kalder sig selv, og CallingAE er, hvad denne ende kalder sig selv.
Begge er vigtige. Websteder konfigurerer en PACS til at acceptere en bestemt ringende titel og afvise alt andet, så en mislighed er den hyppigste årsag til, at en første forbindelse fejler - og fejlen ligner et netværksproblem.
23.7.3 kalde_ae
CalledAE er, hvad den fjerne kalder sig selv, og CallingAE er, hvad denne ende kalder sig selv.
Begge er vigtige. Websteder konfigurerer en PACS til at acceptere en bestemt ringende titel og afvise alt andet, så en mislighed er den hyppigste årsag til, at en første forbindelse fejler - og fejlen ligner et netværksproblem.
23.7.4 transfer_syntaxes
OverførselsSyntax begrænser, hvad der skal tilbydes, i foretrukkens rækkefølge.
Tomt tilbyder objektets egen kodning og derefter implicit VR little endian som en reserve.
23.7.5 timeout
Timeout begrænser en enkelt lagringsoperation.
Nul anvender en standard.
23.8 DICO Mweb-destination
DICOMwebDestination gemmer hver objekt med STOW-RS.
Defineret som DICOMwebDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
url | tekst | ja | — |
token | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
headers | mapping af tekst til tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
timeout | varighed, f.eks. 30s eller 5m | nej | — |
23.9 Database Destination
DatabaseDestination skriver hver besked til en database.
Defineret som DatabaseDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
driver | tekst | ja | — |
dsn | tekst | ja | — |
statement | tekst | ja | — |
params | liste af tekst | nej | — |
timeout | varighed, f.eks. 30s eller 5m | nej | 30s |
max_open_conns | helt tal | nej | 4 |
23.9.1 driver
Driver navngiver databasen.
See SupportedDrivers.
23.9.2 erklæring
Erklæringen udføres en gang per besked, med Parametre bundet til den i rækkefølge.
Pladsholdere er driverens egne: $1 for postgres, ? for mysql og sqlite, @p1 for sqlserver. Perfuse omskriver dem ikke, fordi et oversættelseslag, der fik en pladsholder forkert, ville binde en patients navn til den forkerte kolonne, og resultatet ville se ud som gyldig data.
23.9.3 parametre
Parametrene er HL7-stier eller ${...}-udtryk, bundet til erklæringen i rækkefølge.
Værdier er altid bundet som parametre og aldrig interpoleret i SQL. Det handler ikke kun om injection: O'Brien er et almindeligt navn, og en sammenkædet forespørgsel bryder på apostrofen.
23.9.4 timeout
Timeout begrænser en enkelt erklæring.
Defaults to 30s.
23.9.5 max_open_conns
MaxOpenConns begrænser puljen.
Defaults to 4.
23.10 Destination
Destination er ét sted, hvor en kanal sender beskeder.
Defineret som Destination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
name | tekst | ja | — |
type | DestinationType | ja | — |
enabled | sandt eller falsk (en blok, udelad for at lade være) | nej | — |
filter | tekst | nej | — |
address | tekst | nej | — |
dir | tekst | nej | — |
file_name | tekst | nej | — |
temp_suffix | tekst | nej | " |
append | sandt eller falsk | nej | — |
retain_hours | helt tal | nej | — |
tls | tlsconf.Settings (en blok, udelad for at lade være) | nej | — |
fhir | FHIRDestination (en blok, udelad for at lade være) | nej | — |
cda | CDADestination (en blok, udelad for at lade være) | nej | — |
http | HTTPDestination (en blok, udelad for at lade være) | nej | — |
database | DatabaseDestination (en blok, udelad for at lade være) | nej | — |
sftp | SFTPDestination (en blok, udelad for at lade være) | nej | — |
tcp | TCPDest (en blok, udelad for at lade være) | nej | — |
smtp | SMTPDestination (en blok, udelad for at lade være) | nej | — |
channel | ChannelDestination (en blok, udelad for at lade være) | nej | — |
s3 | S3Destination (en blok, udelad for at lade være) | nej | — |
ftp | FTPDestination (en blok, udelad for at lade være) | nej | — |
document | DocumentDestination (en blok, udelad for at lade være) | nej | — |
soap | SOAPDestination (en blok, udelad for at lade være) | nej | — |
dicomweb | DICOMwebDestination (en blok, udelad for at lade være) | nej | — |
xds | XDSDestination (en blok, udelad for at lade være) | nej | — |
direct | DirectDestination (en blok, udelad for at lade være) | nej | — |
as2 | AS2Destination (en blok, udelad for at lade være) | nej | — |
mpi | MPIDestination (en blok, udelad for at lade være) | nej | — |
tefca | TEFCADestination (en blok, udelad for at lade være) | nej | — |
pas | PASDestination (en blok, udelad for at lade være) | nej | — |
x12_as | tekst | nej | — |
dicom | DICOMDestination (en blok, udelad for at lade være) | nej | — |
javascript | JavaScriptDestination (en blok, udelad for at lade være) | nej | — |
broker | BrokerDestination (en blok, udelad for at lade være) | nej | — |
kafka | KafkaDestination (en blok, udelad for at lade være) | nej | — |
sqs | SQSDestination (en blok, udelad for at lade være) | nej | — |
sns | SNSDestination (en blok, udelad for at lade være) | nej | — |
amqp | AMQPDestination (en blok, udelad for at lade være) | nej | — |
azure_blob | AzureBlobDestination (en blok, udelad for at lade være) | nej | — |
mqtt | MQTTDestination (en blok, udelad for at lade være) | nej | — |
ibm_mq | IBMMQDestination (en blok, udelad for at lade være) | nej | — |
pubsub | PubSubDestination (en blok, udelad for at lade være) | nej | — |
gcs | GCSDestination (en blok, udelad for at lade være) | nej | — |
elr | ELRDestination (en blok, udelad for at lade være) | nej | — |
pgp | PGPSend (en blok, udelad for at lade være) | nej | — |
response_transformer | tekst | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | — |
retry | Retry | nej | — |
queue | QueueConfig (en blok, udelad for at lade være) | nej | — |
23.10.1 navn
Navn identificerer destinationen i logfiler og metrics.
Påkrævet inden for en kanal.
23.10.2 file_name
Filnavn, for en fildestination, skabeloner én fil per besked (${timestamp}, ${date}, ${control_id}, ${message_type}, ${destination}).
Tom holder standarden: én fil per dag og meddelelsstype, tilføjet til.
23.10.3 temp_suffix
TempSuffix er navnet på en fil per besked, mens den skrives, fjernet ved omnavning, når den er færdig, så det, der samler filerne, aldrig læser halvdelen af en.
Standard er ".part".
23.10.4 retain_hours
RetainHours sletter filer i Dir, der er ældre end dette.
Nul holder dem for evigt.
23.10.5 x12_as
X12As er xml for en destination på en X12-kanal, der modtager interchange som XML Mirth Connect og Open Integration Engine skriver for X12, til en modtager bygget mod hvad Mirth sender det.
Tom eller x12 sender X12.
23.10.6 elr
ELR gør denne destination til en offentlig sundhedsrapportering: hver laboratorieresultat (ORU^R01) omformes til en ELR 2.5.1-meddelelse, der kun indeholder de ordrer med en rapporterbar resultat, og det er, hvad der leveres; en meddelelse med intet rapporterbart sendes ikke overhovedet.
Gælder for destinationer, der leverer en HL7 v2-meddelelse, som den er (mllp, http, fil, sftp og resten), på en hl7-kanal.
23.10.7 response_transformer
ResponseTransformer inspicerer, hvad modtageren svarede tilbage, og kan markere leveringen som mislykket.
Den findes, fordi "er denne ankommet" ofte ikke er et spørgsmål, transporten kan besvare: en MLLP-modtager returnerer en applikationsbekræftelse, hvis betydning er i dens tekst, og en HTTP-modtager returnerer 200 med en fejldokument. I begge tilfælde lykkedes transporten, og meddelelsen ankom ikke.
Kun meningsfuldt på en destination, der modtager en svar. På en, der ikke kan, afvisses den ved indlæsning i stedet for at lade være med at køre.
23.10.8 kø
Køen gør leveringen holdbar: en besked, der ikke kan leveres nu, gemmes på disk og genprøves, indtil den kan leveres.
Deaktiveret som standard.
23.11 Direkte Destination
DirectDestination sender hver besked som Direct: signeret med denne adresse, krypteret til hver modtagers certifikat og indsendt til HISP via SMTP.
Defineret som DirectDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
to | liste af tekst | ja | — |
subject | tekst | nej | — |
text | tekst | nej | — |
attach_name | tekst | nej | — |
xdm | sandt eller falsk | nej | — |
xdm_source_id | tekst | nej | — |
recipient_certs_dir | tekst | nej | — |
dns | tekst | nej | — |
ldap | tekst | nej | — |
smtp_host | tekst | ja | — |
username | tekst | nej | — |
password | tekst | nej | — |
request_mdn | sandt eller falsk | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | — |
23.11.1 til
Til er modtagernes Direct-adresser.
Feltreferencer er erstattet, så en modtager kan komme fra beskeden.
23.11.2 modtager_certifikat_mappe
ModtagerCertifikatMappe indeholder modtagercertifikater (PEM, en fil per adresse eller domæne, adresse.pem eller domæne.pem) fundet på forhånd; tom læser serverens Direct-adresseliste (Direct-skærmen).
Modtagere, der ikke er der, søges i DNS (CERT-poster). Direct sender ikke til en modtager, hvis certifikat ikke kan findes.
23.11.3 ldap
LDAP er den mappe, hvor en modtagers certifikat findes, når DNS ikke har nogen (vært:port, port 389): den anden måde, Direct certifikatopdagelsesvejledningen tillader.
Tom finder modtagerdomænets mappe ved dens DNS SRV-post (_ldap._tcp), som vejledningen siger; "fra" aldrig spørger en mappe.
23.12 Dokument Destination
DocumentDestination renderer hver besked til et dokument.
Defineret som DocumentDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
dir | tekst | ja | — |
format | DocumentFormat | nej | |
template | tekst | ja | — |
title | tekst | nej | — |
file_name | tekst | nej | — |
font_size | tal | nej | 10 |
landscape | sandt eller falsk | nej | — |
temp_suffix | tekst | nej | " |
timeout | varighed, såsom 30s eller 5m | nej | 30s |
23.12.1 format
Format er pdf eller tekst.
Standardværdi er pdf.
23.12.2 skabelon
Skabelon er dokumentets brødtekst med ${PID-5.1} stil-referencer til beskedstier.
Kræves. Der er ingen fornuftig standardværdi: et dokument uden skabelon ville enten være den rå besked, som ingen ønsker udskrevet, eller tomt.
23.12.3 fontstørrelse
Fontstørrelse i punkter.
Standardværdi er 10, som passer 80 tegn på tværs af A4.
23.12.4 temp_suffix
TempSuffix føjes til, mens der skrives, og fjernes ved en omdøbning.
Standard er ".part".
Samme hensyn som ethvert andet fildestination, og det betyder mere her: en print-watcher, der samler en halv-skrevet PDF, producerer en side med ingenting, og ingen undersøger en tom side.
23.12.5 timeout
Timeout begrænser én skrivning.
Defaults to 30s.
23.13 ECR Destination
ECRDestination konfigurerer elektronisk sagssrapportering.
Defineret som ECRDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
rctc | tekst | nej | — |
source | tekst | ja | — |
facility | ECRFacility | ja | — |
23.13.1 rctc
RCTC er en FHIR ValueSet eller en samling af dem, såsom eRSD, der indeholder triggerkoderne.
Uden det bruger Perfuse en kort indbygget eksempel til testformål, som myndighederne forventer RCTC.
23.14 ELR Destination
ELRDestination konfigurerer elektronisk laboratorierapportering.
Defineret som ELRDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
config | tekst | ja | — |
rctc | tekst | nej | — |
23.14.1 config
Konfiguration er ELR-filen, som perfuse elr -config læser: den sender og modtager programmer og faciliteter efter OID, behandlingsmodus og hvad der udfylder hullerne i en laboratorieforsyning (bestillingsfacilitet, udførende laboratorium, tildelingsmyndigheder).
En relativ sti læses fra kanalens filmappe.
23.14.2 rctc
RCTC er en FHIR ValueSet eller en samling af dem, såsom eRSD, der indeholder triggerkoderne.
Uden det bruger Perfuse en kort indbygget eksempel til testformål, som myndighederne forventer RCTC. Relativ til kanalens fil, som konfiguration.
23.15 FHIR Destination
FHIRDestination konfigurerer omkonvertering til FHIR og levering til en FHIR-server.
Defineret som FHIRDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
url | tekst | ja | — |
version | tekst | nej | R5 |
timezone | tekst | nej | — |
default_identifier_system | tekst | nej | — |
identifier_systems | afbildning af tekst til tekst | nej | — |
claim_us_core | sandt eller falsk | nej | — |
validate_before_send | sandt eller falsk (en blok, udelad for at lade være) | nej | sandt: sending af en ressource, som en server vil afvise, spilder en genforeningsbudget og skjuler det virkelige problem bag en transportfejl |
reject_on_warning | sandt eller falsk | nej | — |
headers | afbildning af tekst til tekst | nej | — |
bearer_token | tekst | nej | — |
auth | FHIRAuth (en blok, udelad for at lade være) | nej | — |
ecr | ECRDestination (en blok, udelad for at lade være) | nej | — |
bundle_script | tekst | nej | — |
23.15.1 url
URL er den grundlæggende URL for FHIR-serveren, f.eks. "https://fhir.example.org/fhir".
Samlingen sendes direkte til den.
23.15.2 version
Version er den FHIR-udgave, der skal produceres: R4, R4B eller R5. Standard er R5, den seneste offentliggjorte udgave.
En installation, der kommunikerer med en EHR, ønsker næsten altid R4 og bør sige det, fordi stille nedgradering ville skjule en reel interoperabilitetsbeslutning.
23.15.3 tidszone
Tidszonen anvendes til HL7 v2-tidsstempel, der ikke har nogen offset. v2 tillader en lokal tid uden offset, og FHIR gør ikke, så noget må supplere med en.
Når den ikke er angivet, bruges afsenderens offset på MSH-7, da v2 antager, at en lokal tid uden offset er afsenderens lokale tid; en besked, hvis MSH-7 ikke har nogen offset, falder tilbage til UTC.
23.15.4 standard_identifier_system
StandardIdentifierSystem-navneområder identificererer, hvis tildelingsmyndigheden ikke har nogen konfigureret URI.
Uden et system er en MRN tvetydig mellem faciliteter.
23.15.5 claim_us_core
ClaimUSCore tilføjer US Core 9.0.0-profilen til hver ressource, der er produceret og har været kontrolleret imod den og overholder den.
En ressource, der ikke opfylder kravene, sendes uden kravet, med en note om, hvorfor.
23.15.6 valider_før_send
ValiderFørSend afviser at sende en samling, der ikke består valideringen.
Standardværdi er sand: At sende en ressource, som en server vil afvise, spilder en genforeningsbudget og skjuler det virkelige problem bag en transportfejl.
23.15.7 afvis_på_advarsel
AfvisPåAdvarsel afviser også på advarsler, såsom en manglende US Core-identifikator.
Fra standard, fordi en advarsel er en vurdering af profiloverensstemmelse snarere end om gyldighed.
23.15.8 bærertoken
BearerToken sendes som en Authorization-header.
Foretræk en miljøvariabelreference, ${NAME}, over en bogstavelig værdi i en fil, der kommer ind i git.
23.15.9 ecr
ECR gør dette til en offentlig sundhedsrapporteringdestination.
Hver besked kontrolleres for udløsende koder; en, der har nogen, sendes som en eCR 2.1 eICR, indpakket i en eCR-besked, til url's $process-message, og en uden nogen sendes slet ikke.
23.15.10 bundle_script
BundleScript er JavaScript, der køres på hver konverteret Bundle, før det valideres og sendes: bundle er Bundle som et objekt, redigeret på stedet.
Det er, hvordan et websted tilføjer, hvad dets egne systemer ved, og v2-meddelelsen ikke siger - dets organisations IKNR eller ODS-kode, et nationalt profils kontakt niveau - uden, at konverteren gætter det. Et script, der kaster, mislykkes meddelelsen, som enhver anden transformerer gør. Ikke kørt for sagrapporter (ecr).
23.16 FTP-destination
FTPDestination uploader en fil per besked.
Defineret som FTPDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
host | tekst | ja | 21 |
user | tekst | nej | — |
password | tekst | nej | — |
security | FTPSecurity | nej | explicit i stedet for ingen |
insecure_skip_verify | sandt eller falsk | nej | — |
allow_clear_password | sandt eller falsk | nej | — |
dir | tekst | ja | — |
file_name | tekst | nej | — |
temp_suffix | tekst | nej | " |
framed | sandt eller falsk | nej | — |
timeout | varighed, f.eks. 30s eller 5m | nej | 60s |
23.16.1 vært
Værten er serveren med en valgfri port.
Standardværdi er 21 eller 990 for implicit TLS.
23.16.2 bruger
Bruger og adgangskode autentificerer.
En tom bruger betyder anonym.
23.16.3 adgangskode
Bruger og adgangskode autentificerer.
En tom bruger betyder anonym.
23.16.4 sikkerhed
Sikkerhed vælger TLS: eksplitt, implicit eller ingen.
Standardværdi er eksplitt i stedet for ingen, fordi standardværdi til plain FTP ville gøre det usikre valg til det stille valg, og et websted, der virkelig ikke har nogen TLS, skal have det skrevet ned.
23.16.5 insecure_skip_verify
InsecureSkipVerify accepterer ethvert certifikat.
Behøves oftere, end nogen ville ønske: disse servere har ofte et selvsigneret certifikat, der er genereret for år tilbage, som ingen kan genudstede. Navngivet separat, så valget er bevidst og synligt i filen i stedet for skjult inde i en "sikkerhed: afslappet"-tilstand.
23.16.6 allow_clear_password
AllowClearPassword tillader en adgangskode over plain FTP.
Afvises som standard, fordi det sender en legitimationsoplysning over netværket i klartekst på hver enkelt levering. Nogle analysatorer har virkelig ingen TLS, så det må være muligt - men det må være skrevet ned, så det er en beslutning, nogen har truffet, i stedet for en standard, de har arvet. Navnet er bevidst ubehageligt at taste.
23.16.7 temp_suffix
TempSuffix føjes til, mens filen skrives, og fjernes ved en omdøbning, når den er færdig.
Standard er ".part".
Den, der indsamler disse filer, er normalt et planlagt job, der tager, hvad det finder, og uden omdøbningen tager det til sidst halvdelen af en meddelelse.
23.16.8 timeout
Timeout begrænser én overførsel.
Defaults to 60s.
23.17 GCS-destination
GCSDestination skriver hver meddelelse som et objekt.
Defineret som GCSDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
object | tekst | nej | ${date}/${channel}/${control_id} |
storage_class | tekst | nej | — |
content_type | tekst | nej | — |
23.17.1 objekt
Objektet er objektnavnet med samme placeringer som en S3-nøgle.
Standard er ${date}/${channel}/${control_id}.hl7.
23.18 HTTP-destination
HTTPDestination posterer meddelelser til en HTTP-slutpunkt.
Det almindeligste, en Mirth-kanal gør, som Perfuse ikke kan, og det almindeligste blokerer, oversætteren rapporterer. De fleste brug er jordnære: post meddelelsen til en intern API, post den til en webtjeneste, der indkapsler et legacy-system, post den til noget, nogen skrev på en eftermiddag.
Defineret som HTTPDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
url | tekst | ja | — |
method | tekst | nej | — |
content_type | tekst | nej | — |
headers | mapping af tekst til tekst | nej | — |
bearer_token | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at efterlade) | nej | — |
success_status | liste af hele tal | nej | enhver 2xx |
fail_on_body | liste af tekst | nej | — |
follow_redirects | sandt eller falsk | nej | — |
23.18.1 url
URL er, hvor du poster.
Required.
23.18.2 metode
Metoden standarder til POST.
PUT er tilladt for en endpoint, der ønsker det.
GET og DELETE afvises: dette sender en meddelelseskrop, og en transport, der stille og roligt droppede meddelelsen på grund af en metodevalg, ville være en meget stille måde at miste data på.
23.18.3 content_type
ContentType standarder til application/hl7-v2+er7, som er den registrerede type for en pipe-adskilt HL7 v2-meddelelse.
Mange endpoints ønsker text/plain i stedet.
23.18.4 bærertoken
BearerToken sendes som en Authorization-header.
Foretræk en miljøvariabelreference over en litteral i en fil, der går ind i git.
23.18.5 success_status
SuccessStatus listar statuskoderne, der tælles som leveret.
Standarder til enhver 2xx.
Konfigurerbart, fordi endpoints er uenige om, hvordan succes ser ud: nogle besvarer 200 med en fejl i kroppen, og nogle besvarer 202 for en kø, de har accepteret meddelelsen til.
23.18.6 fail_on_body
FailOnBody behandler en respons, der indeholder nogen af disse streng, som en fejl, uanset statuskoden.
Dette eksisterer, fordi en endpoint, der besvarer 200 med "ERROR: patient ikke fundet" i kroppen, er almindelig, og hvis det behandles som leveret, betyder det, at meddelelsen er væk, og ingen ved det.
23.18.7 follow_redirects
FollowRedirects tillader, at anmodningen kan omdirigeres.
Slået fra som standard: en omdirigering på en skrivning ville gensende kliniske data et sted, som konfigurationen aldrig har nævnt.
23.19 IBMMQ Destination
IBMMQDestination placerer hver meddelelse på en kø.
Defineret som IBMMQDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
non_persistent | sandt eller falsk | nej | — |
23.19.1 non_persistent
NonPersistent sender meddelelser, der ikke overlever en køleder-genstart.
Deaktiveret som standard.
23.20 Java Script Destination
JavaScriptDestination kører et script i stedet for at sende et sted hen.
Mirths JavaScript Writer, og det bruges langt mere end dets position i en funktionliste antyder. Det er undslipningshullet: når et websted skal tale med noget, som ingen connector dækker, eller anvende logik, som ingen transformation udtrykker, skriver de en JavaScript Writer. En migration, der ikke kan køre disse, kan ikke flytte kanalerne, der har dem, hvilket i en moden Mirth-installation er en stor brøkdel.
Bevidst ikke en generel scripting-vært. Scriptet får meddelelsen og de samme hjælpere, en transformer får; hvad det ikke får, er en måde at nå filsystemet eller netværket på, fordi det er, hvad de andre destinations er til, og et script, der åbner sin egen socket, er usynligt for enhver gentagelse, kø og måling i motoren.
Defineret som JavaScriptDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
script | tekst | ja | — |
timeout | varighed, såsom 30s eller 5m | nej | — |
success_on_undefined | sandt eller falsk (en blok, udelad for at lade være) | nej | sandt |
23.20.1 script
Script er den kode, der skal køres.
Required.
23.20.2 timeout
Timeout afgrænser en enkelt eksekvering.
Nul anvender en standard.
Afgrænset, fordi et destinations-script er på leveringsstien: en uendelig løkke i ét script holder ikke kun meddelelsen tilbage, men også køen bagved.
23.20.3 success_on_undefined
SuccessOnUndefined behandler et script, der ikke returnerer noget, som en succes.
Standardværdi er sand.
Sandt er den rigtige standard og værd at forklare. Mirths JavaScript-forfattere udfører overvejende deres arbejde og returnerer intet, så krav om en ekspllicit returnering ville ødelægge alle på import. At sætte det til falsk er til en lokalitet, der ønsker, at et script skal være eksplikt om, hvorvidt det fungerede.
23.21 Kafka Destination
KafkaDestination offentliggør meddelelser til et Kafka-emne.
Defineret som KafkaDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
brokers | liste af tekst | ja | — |
topic | tekst | ja | — |
key | tekst | nej | — |
acks | tekst | nej | all |
compression | tekst | nej | snappy |
headers | mapping af tekst til tekst | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | tredive sekunder |
sasl | KafkaSASL (en blok, udelad for at efterlade) | nej | — |
tls | tlsconf.Settings (en blok, udelad for at efterlade) | nej | — |
23.21.1 brokers
Brokers er den bootstrap-serverliste.
Required.
23.21.2 emne
Emne er, hvor meddelelsen skal offentliggøres.
Required.
23.21.3 nøgle
Nøgle er en skabelon for postnøglen, der afgør partitionen.
Dette er feltet, der gør Kafka sikker for en klinisk feed, og det er værd at være præcis om, hvorfor. Kafka garanterer ordenen inden for en partition og ingen andre steder. Poster med samme nøgle lander altid i samme partition, så nøgle på patientidentifikatoren holder patientens begivenheder i orden, mens forskellige patienter kan gå i parallel.
Uden en nøgle er der ingen sådan garanti. Målt mod en reel broker, gik tredive unøglede poster til en partition i stedet for at sprede sig: klienten holder en batch sammen og vælger en ny partition mellem batcher. Så ordenen holder ved en tilfældighed og bryder ved en grænse, som ingen kan se, hvilket er værre end at bryde konsekvent - en A03-udskrivning læst før dens A01-optagelse, intermittent, under belastning.
En HL7-sti, der evalueres mod den afgående meddelelse: PID-3.1 nøgle på patient.
23.21.4 acks
Acks er, hvor mange brokers skal bekræfte en skrivning: "alle", "leder" eller "ingen".
Standard er alle, hvilket er den eneste indstilling, der overlever en brokerfejl mellem skrivning og replikering. "Ingen" er ild-og-glem og vil miste meddelelser; det eksisterer, fordi nogen, der flytter ikke-klinisk telemetri, legitimt kan ønske det, og at afvise det helt ville betyde, at de skrev deres egen producer i stedet.
23.21.5 kompression
Kompression er "ingen", "gzip", "snappy", "lz4" eller "zstd".
Standard er snappy.
Aktiveret som standard, fordi HL7 er højkomprimerbar tekst, og wiren er normalt begrænsningen. Snappy i stedet for zstd som standard: det er det billigste i CPU, og en connector på leveringsstien bør ikke være det, der mætter en kerne.
23.21.6 headers
Overskrifter er postoverskrifter, der skal angives.
Værdier er skabeloner, der vurderes pr. meddelelse.
23.21.7 timeout
Timeout begrænser en publicering.
Standardværdi er tredive sekunder.
23.22 MPI Destination
MPIDestination registrerer hver meddelelses patient i denne servers patientindeks: en HL7 v2 PID (en A40 fusion fusionerer), eller en FHIR Patient på en rå kanal.
Indekset afgør, hvilke poster der er den samme person; se Patientindeksskærmen.
Defineret som MPIDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
authorities | afbildning af tekst til tekst | nej | — |
id_type | tekst | nej | — |
ssn_system | tekst | nej | — |
no_merge | sandt eller falsk | nej | — |
23.22.1 authorities
Authorities afbilder en tildelende myndigheds navnerum (PID-3.4.1) til dets identifikationssystem, for afsendere, der ikke giver nogen universel identifikator.
Ukortlagte bliver urn:perfuse:aa:<namespace>.
23.22.2 id_type
IDType er identifikationstypen (PID-3.5) for postens eget nummer.
Default MR.
23.22.3 ssn_system
SSNSystem navngiver PID-19 som en identifikator.
Default http://hl7.org/fhir/sid/us-ssn.
23.23 MQTT Destination
MQTTDestination offentliggør til et emne.
Defineret som MQTTDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
topic | tekst | ja | — |
retain | sandt eller falsk | nej | — |
23.23.1 emne
Emne offentliggøres til.
Det må ikke indeholde wildcard-tegn.
23.24 PAS-destination
PASDestination sender hver besked, en Da Vinci PAS-anmodningsbundle, til en payers Claim/$submit, til en udbyder hvis systemer bygger anmodningen (en EHR, DTR) og har brug for den sendt, beslutningen registreret og svaret videregivet.
Defineret som PASDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
payer | tekst | ja | — |
bearer_token | tekst | nej | — |
auth | FHIRAuth (en blok, udelad for at lade være) | nej | — |
results_to | tekst | nej | — |
23.24.1 bærertoken
BearerToken er en statisk token, ${ENV} tilladt.
Auth er OAuth client credentials i stedet, eller Azure, som en FHIR-destinations.
23.24.2 auth
BearerToken er en statisk token, ${ENV} tilladt.
Auth er OAuth client credentials i stedet, eller Azure, som en FHIR-destinations.
23.25 Pub Sub Destination
PubSubDestination offentliggør til et Pub/Sub-emne.
Defineret som PubSubDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
topic | tekst | ja | — |
order_by | tekst | nej | — |
23.26 S3 Destination
S3Destination skriver hver besked som et objekt.
Defineret som S3Destination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
bucket | tekst | ja | — |
region | tekst | ja | — |
key | tekst | nej | en dato-partitioneret sti plus kontrol-id |
access_key_id | tekst | nej | — |
secret_access_key | tekst | nej | — |
session_token | tekst | nej | — |
endpoint | tekst | nej | — |
path_style | sandt eller falsk | nej | — |
server_side_encryption | tekst | nej | — |
content_type | tekst | nej | application/hl7-v2 for HL7 og text/plain ellers |
framed | sandt eller falsk | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | 60s |
storage_class | tekst | nej | — |
format | tekst | nej | — |
23.26.1 nøgle
Nøgle-skalering skabeloner objekt-nøglen, ved hjælp af samme ${date}, ${timestamp}, ${control_id}, ${message_type} og ${channel} placeringer som fil- og SFTP-destinationer.
Standard er en dato-partitioneret sti plus kontrol-id.
Dato-partitionering som standard, fordi alternativet - hver objekt i én flad præfiks - gør en bucket, der er langsom at liste og umulig at livscyklus efter alder, og ingen opdager det, før der er fire millioner objekter i den.
23.26.2 access_key_id
AccessKeyID og SecretAccessKey autentificerer.
Enten kan navne en miljøvariabel i stedet for at holde værdien, ved hjælp af formen ${NAME}.
23.26.3 secret_access_key
AccessKeyID og SecretAccessKey autentificerer.
Enten kan navne en miljøvariabel i stedet for at holde værdien, ved hjælp af formen ${NAME}.
23.26.4 path_style
PathStyle adresserer bucket'en som en sti i stedet for et underdomæne.
De fleste S3-kompatible lagre har brug for dette.
23.26.5 content_type
ContentType mærker objektet.
Standard er application/hl7-v2 for HL7 og text/plain ellers.
23.26.6 timeout
Timeout begrænser én upload.
Defaults to 60s.
23.26.7 storage_class
StorageClass er den S3-lagringklasse, som hver objekt skrives med: STANDARD_IA, INTELLIGENT_TIERING, GLACIER_IR, GLACIER, DEEP_ARCHIVE og så videre.
Dette er, hvordan et arkiv går direkte til Glacier - S3 har ingen separat Glacier-API at ringe til.
23.26.8 format
Format er hl7 (standard: hver objekt er beskeden) eller ndjson: hver objekt er en JSON-linje med beskeden og felterne, der er værd at forespørge, under dato-partitioneret nøgler, så Amazon Athena kan forespørge arkivet.
Se Perfuse Athena.
23.27 SFTP Destination
SFTPDestination skriver hver besked til en fil på en SFTP-server.
Defineret som SFTPDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
host | tekst | ja | 22 |
user | tekst | ja | — |
password | tekst | nej | — |
key_file | tekst | nej | — |
key_passphrase | tekst | nej | — |
known_hosts_file | tekst | nej | — |
insecure_skip_host_key_check | sandt eller falsk | nej | — |
dir | tekst | ja | — |
file_name | tekst | nej | et tidsstempel plus kontrol-ID |
temp_suffix | tekst | nej | " |
framed | sandt eller falsk | nej | — |
append | sandt eller falsk | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | 60s |
23.27.1 vært
Værten er serveren med en valgfri port.
Defaults to 22.
23.27.2 adgangskode
Adgangskode godkender med en adgangskode.
Prefer KeyFile.
23.27.3 file_name
Filnavntemplate navngiver filen.
Standard er et tidsstempel plus kontrol-ID.
23.27.4 temp_suffix
TempSuffix føjes til, mens filen skrives, og fjernes ved omnavning, når den er færdig.
Standard er ".part".
Den samme hensyntagen kræves også på vej ind. Den, der indsamler disse filer, har det samme problem, og en omnavning i en mappe er atomar på enhver server, der er værd at bruge.
23.27.5 timeout
Timeout begrænser en enkelt forbindelse.
Defaults to 60s.
23.28 SMTP Destination
SMTPDestination konfigurerer levering via e-mail.
Defineret som SMTPDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
host | tekst | ja | — |
from | tekst | ja | — |
to | liste af tekst | ja | — |
cc | liste af tekst | nej | — |
bcc | liste af tekst | nej | — |
subject | tekst | nej | — |
body | tekst | nej | — |
attach | sandt eller falsk | nej | — |
attach_name | tekst | nej | kontrol-ID med en |
username | tekst | nej | — |
password | tekst | nej | — |
starttls | sandt eller falsk (en blok, udelad for at undlade) | nej | — |
insecure_skip_verify | sandt eller falsk | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | — |
23.28.1 vært
Host er mailserveren med en valgfri port.
Port 587 antages, hvilket er submission med STARTTLS - den port, en moderne server forventer en klient på. Port 25 er server-til-server og er normalt enten blokeret eller ikke-autentificeret.
23.28.2 fra
Fra er afsenderen af konvolutten.
Påkrævet, fordi en besked uden afsender diskret bliver ignoreret af en stor del af mail-infrastrukturen, hvilket gør det til den sværeste mulige fejl at diagnosticere.
23.28.3 til
Til, CC og BCC er modtagere.
Mindst én Til er påkrævet.
23.28.4 cc
Til, CC og BCC er modtagere.
Mindst én Til er påkrævet.
23.28.5 bcc
Til, CC og BCC er modtagere.
Mindst én Til er påkrævet.
23.28.6 body
Body er beskedens tekst.
Feltreferencer er erstattet, som i Emne. Når den er tom, er beskeden selv body.
23.28.7 attach_name
AttachName navngiver vedhæftningen.
Standard er kontrol-ID med en .hl7-suffix.
23.28.8 brugernavn
Brugernavn og adgangskode autentificerer til serveren.
Enten begge eller ingen.
23.28.9 adgangskode
Brugernavn og adgangskode autentificerer til serveren.
Enten begge eller ingen.
23.28.10 starttls
StartTLS opgraderer forbindelsen, før den autentificerer.
Den er som standard tændt, og at slå den fra med et brugernavn sat er afvist i stedet for at være tilladt: at sende en adgangskode over en ukrypteret forbindelse er ikke en kompromis, der er værd at tilbyde.
23.28.11 insecure_skip_verify
InsecureSkipVerify accepterer ethvert certifikat.
Navngivet entydigt, fordi det er det, den gør.
23.29 SNS-destination
SNSDestination offentliggør hver besked i et SNS-emne.
Defineret som SNSDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
topic_arn | tekst | ja | — |
subject | tekst | nej | — |
group_by | tekst | nej | — |
23.29.1 emne
Emne sendes med e-mail-abonnementer.
Valgfrit; ${besked_type} og ${kontrol_id} udfyldes.
23.30 SOAP-destination
SOAPDestination poster en SOAP-anmodning per besked.
Defineret som SOAPDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
url | tekst | ja | — |
profile | tekst | nej | — |
facility_id | tekst | nej | — |
warnings_are_errors | sandt eller falsk | nej | — |
action | tekst | nej | — |
version | tekst | nej | 1 |
body | tekst | ja | — |
header | tekst | nej | — |
headers | mapping af tekst til tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at efterlade) | nej | — |
fault_is_success | liste af tekst | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | 30s |
23.30.1 profil
Profilnavn giver navn til en standardtjeneste, hvis kuvert Perfuse selv bygger.
Tom er et almindeligt SOAP-opkald med brødteksten skrevet i denne fil.
"cdc-iis" er CDC's vaccinationsregistergrænseflade (urn:cdc:iisb:2011), som hver amerikansk delstatsregister bruger: beskeden kommer i submitSingleMessage, brugernavn og adgangskode kommer i brødteksten, som WSDL siger (ikke som HTTP-autentificering), SOAP 1.2 som standard, og registerets HL7-bekræftelse afgør, om beskeden blev leveret. Et register svarer med en afvist vaccination med HTTP 200 og en AR deri, så uden dette læser en afvisning som en succes.
23.30.2 facilitets_id
FacilitetsID er cdc-iis facilitetsID, registerets identifikator for den indsendende organisation.
Valgfrit i WSDL; nogle registre kræver det.
23.30.3 advarsler_er_fejl
AdvarslerErFejl, for cdc-iis, behandler en AE-bekræftelse, der kun indeholder advarsler, som en fejl.
Slået fra som standard: registre sender AE for "accepteret med advarsler", og ERR-alvorlighedsgraden siger, om noget gik tabt.
23.30.4 handling
Handling er SOAPAction.
Kræves af de fleste 1.1-tjenester.
23.30.5 body
Brødteksten er XML, der kommer indenfor konvolutten, med ${PID-5.1}-lignende referencer til beskedstier.
Kræves, medmindre en profil opbygger den. Der er ingen nyttig standardværdi: elementnavnene kommer fra tjenestens eget schema, og ingen motor kan gætte dem.
23.30.6 header
Header er XML til konvoluttens Header-element.
Udelades helt, når den er tom, fordi nogle tjenester afviser en tom.
23.30.7 fejl_er_success
FejlErSuccess listar fejlkoder, der tælles som leveret.
Behøves oftere, end det burde. En tjeneste, der besvarer en genafsendelse med "allerede indsendt", fortæller dig, at beskeden ankom, og uden dette må et websted skrive en respons-transformation til at sige det - eller værre, ser en kø afprøve mod en modtager, der allerede har beskeden.
23.30.8 timeout
Tidsgrænse begrænser én opkald.
Defaults to 30s.
23.31 SQS Destination
SQSDestination sender hver besked til en SQS-kø.
Defineret som SQSDestination i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
queue_url | tekst | ja | — |
group_by | tekst | nej | — |
23.31.1 queue_url
QueueURL navngiver køen.
En, der slutter med .fifo, er en FIFO-kø og grupperes og dedupliceres.
23.32 TCP Dest
TCPDest sender beskeder til en socket med konfigurerbar ramme.
Defineret som TCPDest i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
address | tekst | ja | — |
max_message_size | helt tal | nej | — |
timeout | varighed, f.eks. 30s eller 5m | nej | — |
expect_reply | sandt eller falsk | nej | — |
keep_alive | sandt eller falsk | nej | — |
tls | tlsconf.Settings (en blok, udelad for at lade være) | nej | — |
23.32.1 expect_reply
ExpectReply venter på bytes tilbage, før det rapporterer succes.
Er fra start deaktiveret og værd at at overveje. Når den er deaktiveret, betyder "leveret", at bytes nåede operativsystemets sendbuffer, som en peer, der crashede et øjeblik senere, aldrig læste. Når den er aktiveret, får en peer, der aldrig besvarer, hver besked til at udløbe.
23.32.2 keep_alive
KeepAlive holder en forbindelse åben på tværs af beskeder i stedet for at ringe op per besked.
De fleste enhedsendepunkter forventer dette; nogle afviser en anden besked på samme forbindelse. Fra start deaktiveret, fordi en forbindelse per besked er det beteende, der virker overalt, på bekostning af en håndtryk hver gang.
23.33 TEFCA-destination
TEFCADestination beder TEFCA Facilitated FHIR-partneren om patientens optegnelser for hver beskeds patient.
Hvem denne server er på nettet, dens certifikat og partneren er serverindstillinger (Indstillinger, TEFCA), fordi de tilhører organisationen og dens aftale med en QHIN. Hvad en kanal beslutter er, hvornår og hvorfor: formålet med brugen er en del af kanalen, ikke af den, der er logget ind, så hver forespørgsel en feed foretager angiver samme grund og audit-sporingen kan læses imod den.
Defineret som TEFCADestination i internal/config.
| Key | Type | Required | Default |
|---|---|---|---|
purpose | text | yes | — |
results_to | text | no | — |
23.33.1 formål
Formålet er formålet med brugen: behandling, betaling, drift, folkesundhed eller adgang til enkeltperson.
Det skal være en af de deltagere, der erklærer det.
23.33.2 resultater_til
ResultaterTil navngiver en kanal i denne server, der modtager hver Bundle, partneren returnerer, som en besked i sig selv.
Tom holder Bundle som denne destinations svar alene, så en respons-transformation kan læse det.
23.34 XDS Destination
XDSDestination offentliggør hver klinisk dokument til et IHE XDS.b Document Repository med ITI-41 Provide and Register.
Metadata læses fra CDA-dokumentet (patient, titel, type, tid, forfatter, fortrolighed, sprog) og fuldføres fra disse indstillinger, som angiver, hvad dokumentet ikke kan: hvem sender det, hvilken type facilitet og praksis det kommer fra, og hvilken af patientens identifikatorer er affinitetsdomænets.
Defineret som XDSDestination i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
url | tekst | ja | — |
source_id | tekst | ja | — |
patient_domain | tekst | nej | — |
facility_type | XDSCode | ja | — |
practice_setting | XDSCode | ja | — |
class | XDSCode (en blok, udelad for at udelade) | nej | — |
content_type | XDSCode (en blok, udelad for at udelade) | nej | — |
token | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
headers | mapping af tekst til tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at udelade) | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | — |
direct_from | tekst | nej | — |
direct_to | liste af tekst | nej | — |
23.34.1 patient_domain
PatientDomain er affinitetsdomænets tildelende myndigheds OID: patientidentifikatoren med denne rod er den, der er registreret.
Uden det sender en dokument, hvis patient har en identifikator, denne ene, og en med flere identifikatorer afvises.
23.34.2 token
Token eller Brugernavn/Adgangskode autentificerer; Headers føjes til hver anmodning.
De fleste affinitetsdomæner bruger mutual TLS (tls) i stedet.
23.34.3 brugernavn
Token eller Brugernavn/Adgangskode autentificerer; Headers føjes til hver anmodning.
De fleste affinitetsdomæner bruger mutual TLS (tls) i stedet.
23.34.4 adgangskode
Token eller Brugernavn/Adgangskode autentificerer; Headers føjes til hver anmodning.
De fleste affinitetsdomæner bruger mutual TLS (tls) i stedet.
23.34.5 headers
Token eller Brugernavn/Adgangskode autentificerer; Headers føjes til hver anmodning.
De fleste affinitetsdomæner bruger mutual TLS (tls) i stedet.
23.34.6 tls
Token eller Brugernavn/Adgangskode autentificerer; Headers føjes til hver anmodning.
De fleste affinitetsdomæner bruger mutual TLS (tls) i stedet.
23.34.7 direct_fra
DirectFrom og DirectTo gør indsendelsen XDR som Directs transport: en Direct-adresseblok, der navngiver denne afsenders Direct-adresse og modtagerens, og modtagerne i indsendelsens intendedRecipient.
En HISP, der tager XDR, leverer den som Direct-mail eller til modtagerens eget XDR-endpoint.
23.34.8 direct_til
DirectFrom og DirectTo gør indsendelsen XDR som Directs transport: en Direct-adresseblok, der navngiver denne afsenders Direct-adresse og modtagerens, og modtagerne i indsendelsens intendedRecipient.
En HISP, der tager XDR, leverer den som Direct-mail eller til modtagerens eget XDR-endpoint.
24 Format Reference
Indstillinger, der styrer, hvordan beskeder parses og skrives, for de formater, der kræver mere end et navn.
24.1 Vedhæftninger
Vedhæftninger konfigurerer flytning af store payload ud af en besked.
En besked, der bærer en scannet rapport eller en PDF, er almindelig i dokumentworkflows, og payloaden er rutinemæssigt hundredvis af gange større end beskeden omkring den. Lad den være inline, betyder det, at lagret vokser i takt med dokumenterne i stedet for trafikken, en besked, der er køet til fem destinationer, kopieres fem gange, og grænsefladen strømmer megabytes for at vise en patientnavn.
Mirth kalder disse vedhæftningshåndterere. Dette er det samme, og det er valgfrit per kanal, fordi en feed af almindelige ADT-beskeder ikke har noget at trække ud og bør ikke betale for maskineriet.
Defineret som Attachments i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
extract | liste af attach.Regel | ja | — |
reassemble | sandt eller falsk (en blok, udelad for at lade være) | nej | sandt |
24.1.1 reassemble
Reassemble sætter payload tilbage, før levering.
Standardværdi er sand.
Standardindstillingen er aktiveret, fordi en modtager, der forventer et dokument, skal få et dokument; en besked, der indeholder en bogstavelig token, ville blive arkiveret som en rapport, og ingen ville opdage det, før nogen åbnede optegnelsen.
At slå det fra er for det tilfælde, hvor formålet med kanalen er at fjerne dokumenter - videregive metadata til et system, der ikke har brug for billedet, hvor afsendelse af det ville være et spørgsmål om privatliv snarere end båndbredde.
24.2 Afgrænset
Afgrænset konfigurerer en afgrænset kanal.
Mirths afgrænsede datatypen: CSV, tab-separeret og den lange hale af formater, som en laboratorieanalyse eller en bureau-service udsender.
Defineret som Delimited i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
delimiter | tekst | nej | — |
quote | tekst | nej | et dobbelt citationstegn |
comment | tekst | nej | — |
has_header | sandt eller falsk | nej | — |
columns | liste af tekst | nej | — |
trim_space | sandt eller falsk | nej | — |
relaxed | sandt eller falsk | nej | — |
split | sandt eller falsk (en blok, udelad for at efterlade) | nej | sandt |
keep_blank_lines | sandt eller falsk | nej | — |
filter | tekst | nej | — |
transformations | liste af steps.Step | nej | — |
24.2.1 afgrænser
Afgøres afgrænser kolonner som et tegn eller et navn.
Et navn accepteres, fordi en tabel ikke kan skrives ind i en YAML-fil uden forveksling, og en konfigurationsfil, der indeholder et usynligt tegn, er ulæselig for den, der åbner den næste.
24.2.2 citat
Citat omgiver værdier, der indeholder afgøres afgrænser.
Standardværdien er et dobbelt citationstegn; "ingen" deaktiverer det.
24.2.3 split
Split gør hver række til sin egen besked.
Standardværdi er sand.
Dette er beslutningen, der former en afgrænset kanal, og det fortjener at blive sagt højt. En fil med fem tusinde resultater er enten en besked eller fem tusinde. En besked betyder en bekræftelse, en post i browseren og en fejl, der tager hele filen med sig. Fem tusinde betyder, at hver række filtreres, transformerer, leveres og genprøves på egen hånd, og en enkelt dårlig række stopper ikke resten.
Splitning er standard, fordi behandling pr. række er, hvad næsten alle steder ønsker, og fordi alternativet opdages sent: en kanal, der så fint ud under testen med en tre-rækkers fil, mislykkes en hel nats overførsel på grund af en forkert linje.
24.2.4 behold_blanke_linjer
BeholdBlankeLinjer stands blank linjer fra at blive sprunget over.
Springning er standard, fordi hver fil ender med en ny linje, og en post med tomme felter er ikke en post. Dette findes for den sjældne format, hvor en blank linje er meningsfuld.
24.2.5 filter
Filter afgør, hvilke beskeder fortsætter, skrevet mod kolonne navne.
Her snarere end på kanalen, fordi kanal-niveau filter kompilere HL7-stier. To indstillinger med navnet filter ville være forvirrende, men en indstilling, der betyder forskellige ting afhængigt af dataType, er værre: en afgrænset kanal, der stille kompilerede sin filter som HL7, ville matche intet og droppe alt, hvilket er fejlen, som top-niveau afvisning eksisterer for at forhindre.
24.2.6 transformations
Transformationer er de deklarative trin, der henvender sig til kolonner snarere end HL7-felter.
Separat fra kanalens transformationer af samme grund som filter, og det er arrangementet X12 og NCPDP allerede bruger.
24.3 HL7v3-indstillinger
HL7v3-indstillingerne er indstillingerne, der kun gælder for en HL7 v3-kanal.
Defineret som HL7v3Options i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
filter | tekst | nej | — |
acknowledge | sandt eller falsk (en blok, udelad for at efterlade) | nej | — |
sender_device | tekst | nej | — |
sender_oid | tekst | nej | — |
transformations | liste af hl7v3.Step | nej | — |
24.3.1 filter
Filter udelukker meddelelser ved hjælp af v3-stier.
Dets eget felt i stedet for kanalens almindelige filter, fordi de to er forskellige sprog mod forskellige meddelelsesmodeller. At dele feltet ville betyde, at et v2-filter tavst aldrig matcher på en v3-kanal, eller at et v3-filter ikke kan parses som v2 - og det sidste er kun bedre, fordi det fejler højlydt.
En kanal, der angiver begge, afvises under indlæsning, da en af dem ville være nødt til at blive ignoreret, og der er ingen ærlig måde at vælge på.
24.3.2 bekræft
Bekræft sender en MCCI_IN000002UV01-bekræftelse tilbage.
Aktiveret som standard, til forskel fra X12. En v3-interaktion over en synkron transport forventer en bekræftelse - den sendende aplikation venter generelt på en - og en afsender, der ikke modtager noget, vil normalt gentage, hvilket er, hvordan en patient bliver registreret tre gange.
En peger, så
24.3.3 sender_enhed
SenderEnhed er enhedsidentifikatoren, vi placerer i en bekræftelse.
Kræves, når der gives en bekræftelse. En v3-bekræftelse navngiver enheden, den kommer fra, og en modtager, der ikke genkender vores, kan forkaste den - hvilket ser ud, som om den ikke sender en.
24.3.4 transformations
Transformationer ændrer indholdet af et v3-dokument.
Dets eget felt i stedet for kanalens almindelige transformationer, af samme grund som filteret: de er forskellige ordforråd mod forskellige meddelelsesmodeller. De v2-trin adresserer segmenter og felter, som et v3-dokument ikke har, så deling af feltet ville betyde, at et trin tavst ikke gjorde noget.
Trinnavne matcher v2-navnene, hvor betydningen matcher, så nogen, der har skrevet en kanal, kan skrive den anden. Hvad der er forskelligt, er, hvad v3 har brug for, og v2 ikke kan udtrykke - først og fremmest, at fjernelse af en værdi har tre forskellige betydninger, så clear, nullflavor og remove er tre trin i stedet for ét.
24.4 TCP-indramning
TCPIndramning er, hvordan meddelelsesgrænser findes på en rå sok.
Deles af TCP-kilden og TCP-destinationen og af den serielle kilde, fordi indramningerne er de samme, uanset hvor byte kommer fra. Et laboratorieanalyseapparat, der taler STX/ETX over en sok, taler STX/ETX over en seriekabel også.
Defineret som TCPFraming i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
framing | tekst | ja | — |
delimiter | tekst | nej | — |
start_block | tekst | nej | — |
keep_delimiter | sandt eller falsk | nej | — |
record_length | helt tal | nej | — |
trim_padding | sandt eller falsk (en blok, udelad for at efterlade) | nej | — |
length_bytes | helt tal | nej | — |
big_endian | sandt eller falsk | nej | — |
length_includes_header | sandt eller falsk | nej | — |
24.4.1 indramning
Indramning er mllp, adskilt, fast, længde eller hel.
Kræves, med ingen standard. At læse en strøm med forkert indramning producerer meddelelser, der ser plausibelt ud i stedet for en fejl, så gætning er værre end at spørge.
24.4.2 start_blok
StartBlok kan begynde en meddelelse.
Byte før det kasseres som støj fra en delvis forbindelse.
24.4.3 behold_adskiller
KeepDelimiter inkluderer separatorerne i meddelelsen.
Fra valgt: det er rammer, ikke indhold.
24.4.4 trim_padding
TrimPadding fjerner trailinge mellemrum og NUL'er fra en fast post.
Slået til som standard.
24.5 X12-indstillinger
X12-indstillingerne er indstillinger, der kun gælder for en X12-kanal.
Defineret som X12Options i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
envelope | EnvelopePolicy | nej | kræves |
split | sandt eller falsk | nej | — |
acknowledge | tekst | nej | — |
ack_sender_id | tekst | nej | — |
ack_sender_qualifier | tekst | nej | — |
arrives_as | tekst | nej | — |
transformations | liste over x12.Step | nej | — |
24.5.1 envelope
Envelope angiver, hvad der skal ske, når de selvdeklarede tællinger ikke stemmer overens med, hvad der er til stede.
Standardværdi er kræves.
24.5.2 split
Split sender en meddelelse per transaktionssæt i stedet for en per fil.
Fra valgt. En enkelt 837 kan indeholde hundredvis af krav, så at slå dette til multiplicerer alt downstream - meddelelsesantal, bekræftelser, rækker, alarmgrænser - og det skal være en beslutning, nogen har truffet, snarere end en standard, de har arvet.
24.5.3 bekræft
Acknowledge angiver, hvilken bekræftelse der skal sendes tilbage: 999, 997, ta1 eller ingen.
Hvilken en er en egenskab ved handelspartnerforholdet snarere end ved meddelelsen, så den skal konfigureres. En 999 erstatter en 997 for HIPAA-transaktioner, men mange partnere - især ældre betalingsforbindelser - er konfigureret til at forvente en 997 og vil behandle en 999 som en ukendt fil. At sende den forkerte er værre end at sende ingen, fordi det besvarer et spørgsmål, ingen har stillet, og efterlader det rigtige åbent.
Tomt betyder ingen, hvilket er den sikre standard: en partner, der ikke forventer en bekræftelse og modtager en, kan behandle den som en uanmodet udveksling.
24.5.4 ack_sender_id
AckSenderID og AckSenderQualifier er vores egen interchange-identifikator, der bliver ISA06 og ISA05 i enhver bekræftelse.
Kræves, når Acknowledge er angivet, og afvist under indlæsning ellers. Disse skal være de værdier, handelspartneren har konfigureret for os, og der er ingen måde at gætte dem på: en udveksling, hvis ISA06-partneren ikke genkender, bliver kasseret, før nogen læser den, så en forkert værdi producerer tavshed, der ligner nøjagtig det samme som ikke at sende noget - og nogen bruger en uge på at lede i det forkerte sted.
24.5.5 ack_sender_qualifier
AckSenderID og AckSenderQualifier er vores egen interchange-identifikator, der bliver ISA06 og ISA05 i enhver bekræftelse.
Kræves, når Acknowledge er angivet, og afvist under indlæsning ellers. Disse skal være de værdier, handelspartneren har konfigureret for os, og der er ingen måde at gætte dem på: en udveksling, hvis ISA06-partneren ikke genkender, bliver kasseret, før nogen læser den, så en forkert værdi producerer tavshed, der ligner nøjagtig det samme som ikke at sende noget - og nogen bruger en uge på at lede i det forkerte sted.
24.5.6 ankommer_som
AnkommerSom er xml, når kilden leverer interchange som den XML, Mirth Connect og Open Integration Engine skriver for X12 (en X12Transaction-rod, elementer med navn CLM.05.1), som en motor, der migreres fra, eller et system bygget mod en, sender det.
Det konverteres tilbage til X12, før noget andet sker. Tom eller x12 er X12.
24.5.7 transformations
Transformationer er deklarative ændringer, der anvendes på accepterede udvekslinger.
Separat fra kanalniveauets transformationer af samme årsag, som v3-ændringerne er: disse adresserer HL7-felter gennem en parser, der læser segment-felt-komponent-underkomponent, og X12 har ingen underkomponent, behandler gentagne segmenter som almindelige snarere end exceptionelle og skrives CLM01 af dem, der konfigurerer det. En fælles parser skulle acceptere begge notationer og ville så være tvetydig i begge.
Navnene på trinnene er de samme, som HL7- og v3-trinnene bruger, så det, en forfatter allerede har lært, kan overføres.
25 Opførselsreference
Bekræftelse, køning, gentagningsforsøg, afhøring og skyggeindstillinger. Disse gælder uanset hvilken transport en kanal bruger.
25.1 AMQP-forbindelse
AMQP-forbindelse er hvor og som hvem man skal oprette forbindelse.
Defineret som AMQPConnection i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
addr | tekst | ja | — |
address | tekst | ja | — |
username | tekst | nej | — |
password | tekst | nej | — |
hostname | tekst | nej | værten for addr |
tls | tlsconf.Settings (en blok, udelad for at efterlade) | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | 30s |
25.1.1 brugernavn
Brugernavn og adgangskode autentificerer med SASL PLAIN; begge tomme betyder ANONYMOUS.
Til Service Bus, politiknavn og nøgle.
25.1.2 adgangskode
Brugernavn og adgangskode autentificerer med SASL PLAIN; begge tomme betyder ANONYMOUS.
Til Service Bus, politiknavn og nøgle.
25.1.3 værtsnavn
Værtsnavn sendes til brokeren, som Service Bus ruter på.
Standardværdi er værten for addr.
25.1.4 tls
TLS krypterer forbindelsen.
Kræves til Service Bus og Event Hubs.
25.1.5 timeout
Timeout begrænser forbindelse og hver venten på brokeren.
Defaults to 30s.
25.2 AS2-partner
AS2-partner er en handelspartner, som en AS2-kilde accepterer meddelelser fra.
Defineret som AS2Partner i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
id | tekst | ja | — |
cert_file | tekst | ja | — |
allow_unsigned | sandt eller falsk | nej | — |
allow_unencrypted | sandt eller falsk | nej | — |
25.2.1 cert_fil
CertFil er partnerens certifikat (PEM) til dets signaturer.
Ofte selvsigneret: AS2-partnere udveksler certifikater direkte i stedet for gennem en myndighed.
25.2.2 tillad_usigneret
TilladUsigneret og TilladUikrypteret accepterer en meddelelse fra denne partner, som ikke er signeret eller ikke krypteret.
Slukket: en sådan meddelelse afvises med en kvittering, der forklarer hvorfor.
25.2.3 tillad_uikrypteret
TilladUsigneret og TilladUikrypteret accepterer en meddelelse fra denne partner, som ikke er signeret eller ikke krypteret.
Slukket: en sådan meddelelse afvises med en kvittering, der forklarer hvorfor.
25.3 AWS-adgang
AWS-adgang er, hvordan en connector når AWS: den region, det signerer for, nøglerne og et valgfrit endpoint-override.
Legitimationsoplysninger kan være litterale eller ${ENV_VAR}-referencer, som er, hvordan de skal leveres. Der er ingen instans-metadata-legitimationskæde, bevidst: se internal/awsv4.
Defineret som AWSAccess i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
region | tekst | ja | — |
access_key_id | tekst | nej | — |
secret_access_key | tekst | nej | — |
session_token | tekst | nej | — |
endpoint | tekst | nej | — |
25.3.1 secret_access_key
SecretAccessKey er den hemmelige, litterale eller ${AWS_SECRET_ACCESS_KEY}.
Foretræk referencen: denne fil går ind i versionskontrol.
25.3.2 session_token
SessionToken er kun til midlertidige legitimationsoplysninger.
De udløber, og connector stopper med at fungere, når de gør.
25.4 Ack
Ack konfigurerer acknowledgements-generering.
Defineret som Ack i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
when | AckWhen | nej | — |
application | tekst | nej | — |
facility | tekst | nej | — |
include_trigger_event | sandt eller falsk | nej | — |
25.4.1 include_trigger_event
IncludeTriggerEvent sender ACK^A01 i stedet for ACK.
Nogle modtagere kræver det, og andre afviser det, så det er eksplicit.
25.5 Azure Blob-adgang
AzureBlobAccess er konto, beholder og legitimationsoplysninger.
Defineret som AzureBlobAccess i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
account | tekst | ja | — |
container | tekst | ja | — |
key | tekst | nej | — |
sas | tekst | nej | — |
endpoint | tekst | nej | — |
25.5.1 nøgle
Nøgle er konto-nøglen eller ${AZURE_STORAGE_KEY}.
Angiv den eller sas.
25.5.2 sas
SAS er en delt adgangssignatur-forespørgselsstreng eller en ${...}-reference.
Foretrukket: den kan begrænses til denne beholder.
25.6 Kontrakt Reference
ContractRef peger en kanal mod dens kontrakt.
Defineret som ContractRef i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
file | tekst | ja | — |
check_every | tekst | nej | 15 minutter |
over | helt tal | nej | 500 |
25.6.1 check_every
CheckEvery er, hvor ofte der skal genkontrolleres, som en varighed.
Standardværdi er 15 minutter.
Effektivt bundet ved alarmevalueringsintervallet, som er 30 sekunder som standard, fordi kontrollen køres fra denne løkke og ikke fra en selvstændig timer - så en kontrakt, der beder om 3 sekunder, får 30 sekunder. Det er bevidst: en timer er nemmere at forstå end to, og det holder et kontraktresultat i trit med den læsning, det er knyttet til. Værd at vide, før nogen sætter en kort interval og konkluderer, det er defekt.
Ikke per besked. At opbygge et profil betyder at læse recent trafik, og at gøre det på hver besked ville gøre en kanals gennemstrømning afhængig af, hvor meget historik det har - hvilket er den type performanceskarakteristika, der kun viser sig i produktion, seks måneder inde.
25.6.2 over
Over er, hvor mange nyeste beskeder der skal profilere.
Defaults to 500.
Et tal i stedet for et tidsvindue, fordi en stille feed og en travl feed har brug for samme mængde bevis for at retfærdiggøre en rate, og et tidsvindue giver dem vildt forskellige mængder.
25.7 DICOM Indstillinger
DICOMOptions konfigurerer en billedkanal.
Hvorfor trinnene er navngivet i stedet for stier
Hver anden format får en sti-forfatter. DICOM får bevidst ikke det, og årsagen er pixeldataen: et objekt er binært, en generel tag-forfatter kan sætte enhver tag til enhver bytes, og en fejl der ikke producerer en afvist besked - det producerer et billede, der åbner og er forkert. En radiolog, der læser en undersøgelse, har ingen måde at vide på.
Så de fire ting, stederne faktisk har brug for, er navngivne handlinger med begrænsede effekter: de-identificere, omskrive en AE-titel, fjerne private tags, sætte institutionen. Hver ved, hvilke tags den berører, og ingen kan nå pixeldataen.
Hvorfor denne blok findes nu
internal/dicom har båret steps.go og transform.go i en periode - de fire handlinger, dicom.Apply, og tests. Ingen henvisninger til dem. Fem hundrede linjer med ingen kald, som køens egen afsnit 7 navner: en implementering med ingen kald er ikke til at skelne fra en funktion, der ikke findes. Denne blok og motoropkaldet er wiringen, ikke funktionen.
Defineret som DICOMOptions i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
transformations | liste af dicom.Step | nej | — |
25.8 Direkte Adresse
DirectAddress er en Direct-adresse, denne server har: dens certifikat og nøgle, og de anchors, det stoler på.
Samme blok bruges til at sende (signere som denne adresse) og til at modtage (dekryptere for den).
Defineret som DirectAddress i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
address | tekst | ja | — |
cert_file | tekst | ja | — |
key_file | tekst | ja | — |
anchors_file | tekst | ja | — |
25.8.1 cert_fil
Certifikatfil og Nøglefil er adressens certifikat (PEM, med dets kæde efter det) og privat nøgle (PEM).
HISP eller dets registreringsmyndighed udsteder dem; de er adressens identitet.
25.8.2 nøglefil
Certifikatfil og Nøglefil er adressens certifikat (PEM, med dets kæde efter det) og privat nøgle (PEM).
HISP eller dets registreringsmyndighed udsteder dem; de er adressens identitet.
25.8.3 ankre_filer
AnkreFiler er tillidsankre (PEM): de certifikatudstedere, som denne adresse tillader sendere og modtagere at stole på, såsom DirectTrust-bundlen.
En besked, der er signeret med noget andet, afvises.
25.9 Direct IMAP
DirectIMAP er HISP-postboksen, som en Direct-kilde læser.
Defineret som DirectIMAP i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
host | tekst | ja | — |
port | helt tal | nej | — |
security | tekst | nej | — |
username | tekst | ja | — |
password | tekst | nej | — |
mailbox | tekst | nej | — |
after_read | tekst | nej | — |
move_to | tekst | nej | — |
error_folder | tekst | nej | — |
poll_interval | varighed, såsom 30s eller 5m | nej | — |
tls | tlsconf.Settings (en blok, udelad for at efterlade) | nej | — |
25.9.1 flyt_til
FlytTil er mappen, som meddelelserne flyttes til; som standard er det Behandlet.
Oprettet, når den mangler.
25.9.2 tls
TLS tillader en CA-fil (eller HISP's eget certifikat) og navngiver serveren forventet i den, til en HISP hvis IMAP-certifikat ikke er fra en offentlig myndighed.
Certifikatet verificeres altid.
25.10 Direkte XDR
DirekteXDR er endpointet, som en direkte kilde modtager XDR fra.
Defineret som DirectXDR i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
listen | tekst | ja | — |
tls_cert | tekst | nej | — |
tls_key | tekst | nej | — |
client_ca_file | tekst | nej | — |
25.11 ECR-facilitet
ECRFacilitet er organisationen, der sender sagrapporter.
Defineret som ECRFacility i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
name | tekst | ja | — |
npi | tekst | nej | — |
phone | tekst | ja | — |
line | tekst | nej | — |
city | tekst | ja | — |
state | tekst | ja | — |
postal_code | tekst | nej | — |
25.12 EDIFACT-indstillinger
EDIFACTOptions er indstillinger, der kun gælder for en EDIFACT-kanal.
Defineret som EDIFACTOptions i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
envelope | tekst | nej | — |
split | sandt eller falsk | nej | — |
acknowledge | tekst | nej | — |
25.12.1 bekræft
Anerkendelse svarer en afsender, der poster over HTTP med en CONTRL i svaret: accepteret (handling 7), når interchange blev læst og leveret, afvist (4) ellers.
Default none.
25.13 E-mail-O-Auth
EmailOAuth logger ind med OAuth 2.0 (SASL XOAUTH2), som Microsoft 365 og Gmail kræver i stedet for en adgangskode.
Defineret som EmailOAuth i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
provider | tekst | ja | — |
tenant | tekst | nej | — |
token_url | tekst | nej | — |
client_id | tekst | ja | — |
client_secret | tekst | nej | — |
refresh_token | tekst | nej | — |
scope | tekst | nej | — |
25.13.1 klient_hemmelighed
KlientHemmelighed kan være ${ENV}.
Uden opfrisk_token vælger den Microsofts app-kun klient-credentials-bevilgning.
25.13.2 opfrisk_token
OpfriskToken kan være ${ENV}: en postkasse, som en person har givet samtykke til.
Kræves for Gmail.
25.14 FHIR Auth
FHIRAuth er, hvordan en FHIR-destination godkender sig til en vært FHIR-tjeneste.
Tre forudindstillinger, fordi de værtstjenester er, hvor en bærertoken, der er indssat i en fil, ophører med at virke inden for timen:
- aws: AWS HealthLake, som tager anmodninger signeret med Signaturversion 4 til tjenesten "healthlake" - ingen token overhovedet. - azure: Azure Health Data Services, som tager en Microsoft Entra ID-token til FHIR-tjenestens egen publikum, som er opnået med client-credentials-bevillingen af en app-registrering, der indeholder rollen FHIR Data Contributor. - client_credentials: enhver OAuth 2.0-token-endpoint - Keycloak, Okta, en SMART-backend-tjeneste med en client-hemmelighed.
Tokens hentes, når de er nødvendige, og genbruges, indtil de udløber en minut før de udløber.
Defineret som FHIRAuth i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
type | tekst | ja | — |
region | tekst | nej | — |
access_key_id | tekst | nej | — |
secret_access_key | tekst | nej | — |
session_token | tekst | nej | — |
tenant_id | tekst | nej | — |
token_url | tekst | nej | — |
client_id | tekst | nej | — |
client_secret | tekst | nej | — |
scope | tekst | nej | — |
25.14.1 region
Region er den AWS-region.
Læses fra en HealthLake-URL, når den ikke er givet.
25.14.2 token_url
TokenURL er OAuth-token-endpointet til client_credentials.
For azure er det afledt fra lejeren.
25.14.3 client_id
ClientID og ClientSecret identificerer programmet.
Hemmeligheden kan være en ${ENV}-reference, som er, hvordan den skal gives.
25.14.4 klient_hemmelighed
ClientID og ClientSecret identificerer programmet.
Hemmeligheden kan være en ${ENV}-reference, som er, hvordan den skal gives.
25.14.5 scope
Omfang anmodes med token.
For azure standardiserer det til FHIR-tjenestens URL efterfulgt af /.default, som er dets publikum.
25.15 Filafstemning
FilePoll er den del af en fil-samler-kilde, der ikke har noget at gøre med transporten.
Deles af lokale, FTP, SMB og WebDAV-kilder og af SFTP. Hver af disse indstillinger findes, fordi filer kan gå galt på en måde, der ikke har noget at gøre med, hvordan transporten adskiller sig, hvilket er, hvorfor de hører sammen: et websted, der har arbejdet ud, hvilken den rigtige stable_for er til dets analyser, skal ikke behøve at arbejde det ud igen, når analysen flyttes til en andel.
Defineret som FilePoll i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
dir | tekst | ja | — |
pattern | tekst | nej | — |
poll_interval | varighed, såsom 30s eller 5m | nej | — |
after_read | tekst | nej | — |
move_to | tekst | nej | — |
error_dir | tekst | nej | — |
stable_for | varighed, såsom 30s eller 5m | nej | — |
max_file_size | helt tal | nej | — |
framed | sandt eller falsk | nej | — |
raw | sandt eller falsk | nej | — |
batch_size | helt tal | nej | — |
sort_by | tekst | nej | navn |
25.15.1 mønster
Mønster vælger filer efter glob.
Tomt betyder hver fil.
25.15.2 fejlmappe
ErrorDir er, hvor en fil der ikke kunne behandles, kommer til at ligge.
Separat fra MoveTo med vilje. En mappe, der kun indeholder fejl, er noget, som nogen kan overvåge, og at blande fejl ind i arkivet betyder, at den eneste måde at finde dem på er at læse hver enkelt fil.
25.15.3 rå
Raw behandler hele filen som én besked uanset indhold.
Indstillingen, der gør denne connector nyttig til andet end HL7. Uden den vil en CSV-batch, en X12-kravfil eller en PDF blive splittet på linjer, der starter med MSH, og producere ingenting, og fejlen siger, at filen ikke er HL7 - sandt, men ikke pointen, da filen aldrig var ment til at være.
25.15.4 batch_størrelse
BatchSize begrænser, hvor mange filer én afhentning kan læse.
Nul betyder ingen begrænsning.
Findes for den første afhentning efter et udfald. En mappe, der indeholder fyrre tusinde filer, der er samlet op om natten, vil ellers blive læst i ét løb, hvilket holder afhentningsløkken beskæftiget, så længe det tager, og gør kanalen ustabil og køen synligt tømmende.
25.15.5 sortér_efter
SortBy bestemmer rækkefølgen af filerne inden for en afhentning: navn, ændret eller ingen.
Standard er navn. Rækkefølgen betyder mere, end det ser ud til: en ADT-strøm, hvor A08-opdateringer ankommer før A01-indlæggelsen, producerer patienter, der ikke eksisterer endnu. Mappenavnens rækkefølge er arbitrær på de fleste filsystemer, så at lade den forblive usorteret betyder, at rækkefølgen ændrer sig mellem afhentninger uden synlig grund.
25.16 GCP-adgang
GCPAccess er, hvordan man godkender til Google Cloud.
Defineret som GCPAccess i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
project | tekst | nej | — |
credentials_file | tekst | nej | — |
endpoint | tekst | nej | — |
25.16.1 credentials_fil
CredentialsFile er en servicekonto's JSON-nøgle.
Tom bruger servicekontoen, der er knyttet til den virtuelle maskine, GKE-pod eller Cloud Run-tjenesten, som Perfuse kører på (metadata-serveren), medmindre Endpoint navngiver en emulator.
25.17 GCS-adgang
GCSAccess er en Cloud Storage-bucket.
Defineret som GCSAccess i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
bucket | tekst | ja | — |
25.18 IBMMQ-forbindelse
IBMMQConnection er en kø, der nås gennem kølederens messaging REST-API.
Defineret som IBMMQConnection i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
url | tekst | ja | — |
queue_manager | tekst | ja | — |
queue | tekst | ja | — |
username | tekst | nej | — |
password | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
api_version | tekst | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | 30s |
25.18.1 brugernavn
Brugernavn og adgangskode er en mqweb-bruger med rollen MQWebUser; adgangskoden kan være ${ENV}.
Lad begge være tomme, når en klientcertifikat (tls.cert_file) godkender.
25.18.2 adgangskode
Brugernavn og adgangskode er en mqweb-bruger med rollen MQWebUser; adgangskoden kan være ${ENV}.
Lad begge være tomme, når en klientcertifikat (tls.cert_file) godkender.
25.18.3 timeout
Timeout begrænser hver anmodning.
Defaults to 30s.
25.19 Kafka SASL
KafkaSASL godkender til en Kafka-kluster.
Defineret som KafkaSASL i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
mechanism | tekst | ja | — |
username | tekst | ja | — |
password | tekst | ja | — |
25.19.1 mekanisme
Mekanismen er "plain", "scram-sha-256" eller "scram-sha-512".
PLAIN sender adgangskoden læselig på ledningen, så den hører til med TLS. SCRAM gør ikke det, hvilket er hvorfor det er værd at nævne forskellen her i stedet for at behandle de tre som udskiftelige.
25.19.2 adgangskode
Adgangskoden er den SASL-adgangskode.
Understøtter ${ENV}-referencer som alle andre hemmeligheder her, så en kluster-legitimation ikke behøver at være skrevet ind i kanal-filen.
25.20 MQTT-forbindelse
MQTT-forbindelse er, hvordan man når en MQTT 3.1.1-mægler: Mosquitto, EMQX, HiveMQ, AWS IoT Core, Azure Event Grid.
Defineret som MQTTConnection i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
addr | tekst | ja | — |
client_id | tekst | nej | — |
username | tekst | nej | — |
password | tekst | nej | — |
tls | tlsconf.Settings (en blok, udelad for at undlade) | nej | — |
qos | hele tal (en blok, udelad for at undlade) | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | 30s |
25.20.1 client_id
ClientID navngiver sessionen.
En kilde beholder sine meddelelser på tværs af genforbindelser kun under et fast client-id; det standardiserer til perfuse-<channel>.
25.20.2 brugernavn
Brugernavn og adgangskode godkender; enten kan være tom.
Adgangskoden kan være ${ENV}.
25.20.3 adgangskode
Brugernavn og adgangskode godkender; enten kan være tom.
Adgangskoden kan være ${ENV}.
25.20.4 timeout
Timeout begrænser forbindelse og hver venten på brokeren.
Defaults to 30s.
25.21 NCPDP-indstillinger
NCPDP-indstillingerne er indstillingerne, der kun gælder for en apotek-krav-kanal.
Defineret som NCPDPOptions i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
transformations | liste af ncpdp.Step | nej | — |
25.21.1 transformations
Transformationer er deklarative ændringer, der anvendes på hver transmission før levering.
Samme vokabular som ethvert andet format - angiv, kopier, slet, kort, erstat, trim, tilfælde, hver med en valgfri betingelse - fordi step-motoren i internal/steps er generisk. Det, der adskiller, er notationen: en sti skrives D1 eller 07-D7, ved hjælp af standardens egne to-bogstavs feltidentifikatorer.
25.22 PGP Modtag
PGPModtag åbner, hvad en kilde modtager med OpenPGP: dekrypteret med vores hemmelige nøgle og dens signatur kontrolleret mod afsenderens offentlige nøgler.
Defineret som PGPReceive i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
decrypt_with | tekst | nej | — |
passphrase | tekst | nej | — |
verify_with | liste af tekst | nej | — |
require_signature | sandt eller falsk | nej | — |
allow_unencrypted | sandt eller falsk | nej | — |
pass_plain | sandt eller falsk | nej | — |
25.22.1 decrypt_with
DecryptWith er vores hemmelige nøglefil.
Påkrævet, medmindre allow_unencrypted er aktiveret og beskeder kun er signeret.
25.22.2 passphrase
Passphrase låser op for DecryptWith, når den er beskyttet.
Foretræk en reference til en miljøvariabel, ${NAME}.
25.22.3 verify_with
VerifyWith er afsenderens offentlige nøglefiler.
En signatur fra nogen af dem kontrolleres og registreres.
25.22.4 pass_plain
PassPlain giver en besked, der slet ikke er PGP, lov til at passere uændret, til en mappe, der modtager begge.
Deaktiveret: en sådan besked afvisses, så en afsender, der glemte at kryptere, bliver underrettet.
25.23 PGP Send
PGPSend beskytter, hvad en destination leverer med OpenPGP: krypteret til modtagerens offentlige nøgle, signeret med vores, eller begge.
Betalere, clearinghouses og statlige myndigheder modtager ofte filer over SFTP kun på denne måde.
Defineret som PGPSend i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
encrypt_to | liste af tekst | nej | — |
sign_with | tekst | nej | — |
passphrase | tekst | nej | — |
armor | sandt eller falsk | nej | — |
no_compress | sandt eller falsk | nej | — |
file_name | tekst | nej | — |
25.23.1 encrypt_to
EncryptTo er modtagernes offentlige nøglefiler (armored eller binær).
Meddelelsen kan læses af enhver af dem. Tom: meddelelsen er kun signeret.
25.23.2 signer_med
SignWith er vores hemmelige nøglefil, der bruges til at signere hver meddelelse.
Tom: kun krypteret.
25.23.3 passphrase
Adgangskode låser SignWith, når det er beskyttet.
Foretræk en reference til en miljøvariabel, ${NAME}.
25.24 Køkonfiguration
KøKonfiguration aktiverer varig køning for en destination.
Uden det vil en destination, der er nede i to minutter, miste alt, der sendes under de to minutter: gentagne forsøg sker i hukommelsen, og når de løber ud, bliver meddelelsen optaget som fejlet og væk. Med det bliver meddelelsen på disken og beholder sin plads, indtil modtageren kommer tilbage.
Det er slået fra som standard, hvilket er et bevidst valg snarere end forsigtighed. En kø ændrer, hvad en bekræftelse betyder, og det ændrer ordningsadfærd under en fejl, og begge dele er ting, en operatør skal vælge bevidst snarere end opdage.
Defineret som QueueConfig i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
enabled | sandt eller falsk | nej | — |
max_attempts | hele tal | nej | — |
backoff | varighed, såsom 30s eller 5m | nej | — |
max_backoff | varighed, såsom 30s eller 5m | nej | — |
max_depth | hele tal | nej | — |
retain_hours | hele tal | nej | — |
25.24.1 max_forsøg
MaxForsøg er, hvor mange gange køen forsøger, før den markerer en meddelelse som fejlet og går videre til den næste.
Nul betyder, at den skal fortsætte uendeligt, hvilket er legitimitet for en feed, der ikke må tabe noget, men skal vælges snarere end arves.
25.24.2 max_tilbagehold
MaxTilbagehold begrænser den voksende forsinkelse.
Standarden er en minut snarere end noget større, fordi en modtager, der kommer tilbage efter en kort fejl, skal findes hurtigt: en time-lang loft kan omdanne en to-minutters fejl til en time med bagudstrøgning.
25.24.3 max_dybde
MaxDybde afviser nye meddelelser, når så mange venter, så en modtager, der har været nede i en uge, ikke kan fyldte disken.
Nul betyder ingen begrænsning.
Når grænsen nås, markeres meddelelsen som fejlet snarere end køet, og afsenderen underrettes herom — hvilket er det ærlige svar, fordi vi ikke længere lover at levere det.
25.24.4 retain_hours
BeholdTimer er, hvor lang tid leverede og forladte elementer beholdes, før de slettes.
De beholdes overhovedet, så nogen, der overvåger en bagudstrøgningsdræn, kan se, at det sker, og så en forladt meddelelse kan findes herefter.
25.25 Gentag
Gentag kontrollerer levering igen efter en fejl.
Defineret som Retry i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
attempts | hele tal | nej | — |
backoff | varighed, såsom 30s eller 5m | nej | — |
max_backoff | varighed, såsom 30s eller 5m | nej | — |
25.25.1 forsøg
Forsøg er det totale antal forsøg, herunder det første.
Nul betyder standard.
25.25.2 tilbagehold
Tilbagehold er ventetiden før det andet forsøg.
Det fordobles hver gang, op til MaxTilbagehold.
25.26 Scriptindstillinger
ScriptOptions konfigurerer en NCPDP SCRIPT-kanal.
Hvorfor SCRIPT får en blok, når dens filter er på øverste niveau
Kanalens filter for hver datatype er filternøglen på øverste niveau, fordi internal/expr er generisk over beskedtypen: en nøgle, kompuleret mod den træ eller krav, som kanalen transporterer. Trin kan ikke arrangeres på den måde. Et v2-trin adresserer et segment og et felt, et X12-trin adresserer et fast breddeelement, og typerne er forskellige, så en yaml-nøgle ville være nødt til at holde hvilken som helst af datatypen implicerede - hvilket er et felt, der betyder forskellige ting afhængigt af et andet felt, og fejltillstanden er et trin, der stille gør ingenting.
Så dette følger hl7v3, x12, ncpdp og adskilt: trinnene bor i formatets egen blok, og nøglen transformations på øverste niveau afvises på en SCRIPT-kanal i stedet for at accepteres og ignoreres.
Defineret som ScriptOptions i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
transformations | liste af hl7v3.Step | nej | — |
25.26.1 transformations
Transformationer er de deklarative trin, der adresserer recepten som et XML-træ.
hl7v3.Step i stedet for en type af sin egen, og det er ikke dovnhed. En recept og et v3-dokument er begge XML, sti-grammatikken er den samme, og internal/eprescribe låner allerede hl7v3.Path til dets filter med en kommentar, der siger det - v3 og CDA bruger allerede det, og en tredje kopi ville være en tredje sæt svar på, hvad //a/b[2]@c betyder.
Trinnene, der transporterer v3-kun-betydning, afvises under indlæsning i stedet for at være stille tilgængelige. nullflavor er den ene: den skriver v3-attributten, der angiver, hvorfor en værdi er fraværende, hvilket en recept ikke har nogen pendant til, og et trin, der skrev det, ville producere et dokument, modtageren ikke forstår.
25.27 Scripts
Manuskripter indeholder det JavaScript, der er knyttet til en kanal.
Defineret som Scripts i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
filter | tekst | nej | — |
transformer | tekst | nej | — |
preprocessor | tekst | nej | — |
deploy | tekst | nej | — |
undeploy | tekst | nej | — |
postprocessor | tekst | nej | — |
language | tekst | nej | — |
timeout | varighed, såsom 30s eller 5m | nej | — |
include | liste af tekst | nej | — |
file_roots | liste af tekst | nej | — |
allow | liste af tekst | nej | — |
25.27.1 filter
Filter kører efter udtryksfilteret, hvis der er et, og skal returnere en boolesk værdi.
Et Mirth-filtermanuskript indsættes her uændret.
25.27.2 transformator
Transformator kører efter de deklarative trin og kan ændre beskeden.
Et Mirth-transformator-manuskript indsættes her uændret.
25.27.3 præprocessor
Præprocessoren kører før meddelelsen parses, læser teksten som "meddelelse" og returnerer teksten til parsing.
En Mirth-præprocessor kan indsættes her uændret.
Dette er det eneste sted, hvor en meddelelse, der ikke kan parses, kan repareres. Sites bruger det til en vild karakter fra en seriegateway, en segmentafslutter, der ankommer som en linjeskift, eller en leverandør, der fylder et felt med noget ulovligt for dets position. Uden det afviser Perfuse trafik, som Mirth accepterer i dag.
25.27.4 udrulning
Udrulning kører en gang, når kanalen starter, før den accepterer noget.
Dette er, hvor sites varmer en opslags-cache eller kontrollerer, om noget, de afhænger af, er tilgængeligt. Den kører før kildebindningen, så et udrulnings-script, der fejler, stopper kanalen fra at starte i stedet for at lade den acceptere meddelelser, den ikke kan håndtere.
25.27.5 afvikling
Afvikling kører en gang, når kanalen stopper.
Efter at kilde har stoppet med at acceptere og efter at meddelelserne i gang er færdige, så den ser en kanal, der virkelig er inaktiv. Dens fejl kan ikke stoppe en stop: en kanal, der ikke kunne lukkes, fordi et rengøringsscript kastede, ville være værre end en, der loggede og lukkede.
25.27.6 postprocessor
Postprocessoren kører efter, at meddelelsen er blevet behandlet, og kan ikke ændre den.
Meddelelsen og hvad der skete med den er synlige, så den kan give besked, tælle eller optage. Den kan ikke ændre, hvad der blev sendt: på det tidspunkt, hvor den kører, er sendingen sket, og et script, der syntes at ændre en leveret meddelelse, ville lyve om det.
25.27.7 sprog
Sprog er hvilket scripting-sprog disse script er skrevet i: javascript eller lua.
Hvorfor en indstilling for hele blokket i stedet for en per script
En kanals script deler kanalkortet og connector-kortet, og de læses sammen af den, der vedligeholder dem. Et filter i Lua ved siden af en transformer i JavaScript ville betyde to sprog i én gennemgang, delende tilstand gennem et kort, hvis værdier skulle betyde det samme i begge. Sites, der ønsker det, kan splitte kanalen.
Hvorfor standarden er javascript
Hvert script, der er skrevet før denne indstilling eksisterede, er JavaScript og siger intet om sit sprog. At gøre lua standarden ville stille reinterpret alle dem; kræve feltet ville afvise dem. Ingen af delene er acceptabelt for en indstilling, der er tilføjet senere.
25.27.8 timeout
Timeout afgrænser hvert script.
Nul betyder fem sekunder.
Der er bevidst ingen måde at deaktivere det på. Mirth tillader en transformer at løbe for evigt, hvilket stopper kanalen, og et interface, der stopper med at acceptere optagelser på grund af et trykfejl, er ikke noget, der bør tilbydes som en mulighed.
25.27.9 inkluder
Inkluder navngiver filer af delt scriptkilde, der er tilgængelig for hvert script på denne kanal, i hvilket som helst sprog script.sprog navngiver.
Dette er Mirths kode-skabeloner. En side med fyrre kanaler har normalt en bibliotek, som hver kanal kalder, og uden det betyder en migration, at biblioteket skal kopieres ind i fyrre filer - fyrre steder at rette næste gang, det ændres.
Stier er relative til kanal-filen, så en bibliotek ved siden af kanalerne rejser med dem. Det er en liste, fordi alternativet er en enorm fil, og biblioteker har tendens til at dele sig efter emne.
Filerne skal være på kanalens sprog. Dette var JavaScript-kun i en periode, og ikke af afvisning: en Lua-kanal læste filerne, afviste en manglende, og derefter installerer runtime ingen af dem, så hver opkald til biblioteket fejlede på den første besked med en nil-global - præcis den fejl, som afvisningen ovenfor findes for at undgå.
25.27.10 file_roots
FileRoots er de directoryer, som FileUtil må læse og skrive.
Kræves altid, når "file" er tilladt. At give filadgang uden at navngive directoryer betød tidligere, at hele filsystemet kunne læses: et script kunne læse Perfuses egen database, som indeholder adgangskode-hashes, LDAP-servicekonto-adgangskoden og OIDC-klient-hemmeligheden. Oprettelse af en kanal kræver kun redigeringsrollen, så eskaleringen blev fuldført, øjeblikkeligt efter at en administrator startede den.
25.27.11 allow
Allow giver scriptet kapaciteter, som ellers ville blive afvist: "file", "database", "route".
Mirth giver alle disse til hvert script; krav om at navngive dem betyder, at en transformer ikke stille kan begynde at læse filsystemet efter en kopier-og-indsæt-operation.
25.28 Skygge
Shadow kører en kandidatversion af en kanal ved siden af den live kanal og rapporterer, hvor de forskellige er.
Dette er svaret på spørgsmålet, der gør grænsefladearbejde skræmmende: hvordan ved du, om en ændring er sikker? Ikke ved at læse den. En transformation er et program, der opererer på beskeder, hvis variation ingen har katalogiseret, og det tilfælde, der bryder, er altid det, som ingen tænkte på - patienten med to identifikatorer, resultatet med et tomt enhedsfelt, A08, der ankommer før A01.
En kanaltest beviser tilfældene, som nogen tænkte på. Shadow-tilstand beviser tilfældene, der faktisk ankommer, mod rigtig trafik, før ændringen transporterer nogen af dem.
To egenskaber gør det sikkert, og begge er strukturelle snarere end konfigurerbare:
- Shadow leverer aldrig. Dets destinationer er ikke opbygget, så der er ingen kodevej fra en shadow-kanal til en modtager, og ingen indstilling kan oprette en ved fejl. - Shadow påvirker aldrig den live kanal. Den kører efter den live besked er blevet leveret og bekræftet, og en shadow, der panikerer, kaster eller hænger, bliver optegnet som en shadow-fejl og intet andet.
Defineret som Shadow i internal/config.
| Nøgle | Type | Kræves | Standard |
|---|---|---|---|
channel | tekst | ja | — |
sample | nummer | nej | 1 |
compare | liste af tekst | nej | — |
ignore | liste af tekst | nej | — |
max_differences | helt tal | nej | 100 |
timeout | varighed, såsom 30s eller 5m | nej | 5s |
25.28.1 channel
Kanal er stien til den kandidat-kanalfil.
En separat fil snarere end en inline-blok, med vilje: kandidaten er ment til at blive den live kanal, så den skal være den genstand, der gennemgås, committes og fremmes, ikke en fragment, der skal udtrækkes.
25.28.2 sample
Sample er den brøkdel af beskeder, der skal skygges, fra 0 til 1. Standardværdi er 1.
Værdi at sænke kun på en travl feed, og værdi at forstå, før man gør det: sampling reducerer omkostninger og reducerer tillid i nøjagtig samme proportion, og den besked, der ville have vist forskellen, er den usædvanlige.
25.28.3 compare
Compare begrænser sammenligningen til disse feltstier.
Tom sammenligner alt.
25.28.4 ignore
Ignorerer eksklusionsfeltveje fra sammenligningen.
Nødvendigt i praksis, fordi en kanal, der stæmpeler en tidsstempel eller en sekvensnummer, afviger på hver enkelt besked og ville rapportere en forskelsrate på 100%, mens den ikke fortæller noget.
25.28.5 max_forskelle
MaxForskelle begrænser, hvor mange afvigende beskeder der gemmes til inspektion.
Defaults to 100.
25.28.6 timeout
Timeout begrænser en skyggekørsel.
Defaults to 5s.
Separat fra kanallens egen timeout, og kortere. En kandidat med en løbsk script må ikke akkumulere goroutines bag live-trafikken.
25.29 XDS-kode
XDS-kode er en kodet værdi i destinationsindstillinger: kode, kodningsordning (en OID) og visning.
Defineret som XDSCode i internal/config.
| Nøgle | Type | Påkrævet | Standard |
|---|---|---|---|
code | tekst | ja | — |
scheme | tekst | ja | — |
display | tekst | nej | — |
26 Hvordan hver komponent fungerer
Perfuse er bygget af små pakker, hver med ét job. Dette kapitel er hver enkelt pakkes egen beskrivelse af, hvad den gør, og hvorfor den er bygget på den måde, taget fra kilden. Hvor en beslutning har en grund, der ikke er åbenlys, er grunden her og ikke i en commit-besked, som ingen vil finde.
26.1 fhir
Pakken fhir implementerer FHIR-resourcer, serialisering og validering.
Versionshåndtering er den første designbeslutning, fordi "FHIR" alene ikke identificerer en wire-format. R5 er den seneste offentliggjorte udgave og er standard her. R4 er, hvad den installeret base og den amerikanske regulering faktisk forbruger, så det er fuldt understøttet i stedet for at blive behandlet som en arv.
Resourcemodellen er R5-formet. Hvor R4 adskiller sig, anvendes forskellen ved serialisering i stedet for at fastholde to parallelle sæt af structs, hvilket er, hvordan en kodebase ender med at have to subtilt divergerende definitioner af Patient.
Source: github.com/biodream-llc/perfuse/fhir
26.2 hoved
Kommandoen xmlordergen skriver elementrækkefølgen, som FHIR XML har brug for, fra en kernepakkes StructureDefinitions.
go run ./fhir/xmlordergen hl7.fhir.r4.core-4.0.1.tgz | gzip -9 -n > fhir/xmlorder_r4.txt.gz
JSON-objekter kan holde deres medlemmer i enhver rækkefølge; XML må ikke: hvert element skal komme i den rækkefølge, som dets definition listar. Hver udgangslinje er en sti og dens børn i den rækkefølge, hver barn med hvordan at finde sine egne børn: "@Path" (et element defineret inline, en rygrad), "#Path" (det samme som et andet element), eller dets typer.
Source: github.com/biodream-llc/perfuse/fhir/xmlordergen
26.3 hl7
Pakken hl7 læser HL7-version 2-besked.
Den har ingen afhængigheder uden for standardbiblioteket, og en test påtvinger dette. Den udfører ingen netværks-I/O, skriver ingen filer og starter ingen goroutines, så den er sikker at bruge fra hvor som helst.
Reading a message
msg, err := hl7.Parse(raw) hvis err != nil { return err } mrn := msg.MustGet("PID-3.1") navn := msg.MustGet("PID-5.1") msgType, event, _ := msg.Type() // "ADT", "A01"
Stier er notationen, som folk allerede bruger, når de taler om HL7: segment, felt, derefter valgfrit komponent og underkomponent, som i PID-5.1 eller OBX-5.2.3. Gentagelser adresseres med kvadratparenteser, som i PID-3[2].1.
Get returnerer en fejl for en sti, den ikke kan parse; MustGet returnerer den tomme streng i stedet. Begge er sikre på fraværende segmenter og felter, fordi en rigtig feed er fuld af begge, og en parser, der panikker over manglende data, er værdiløs til jobbet. Fravær er ikke en fejl — en besked, der blot ikke medfører PID-8, giver "" i stedet for en fejl.
Fraværende og tom
HL7 skelner mellem et felt, der ikke blev sendt, og et felt, der blev sendt med vilje tom, og klinisk kan disse betyde forskellige ting - "ingen allergier registreret" er ikke "ingen kendte allergier". Value.Exists rapporterer forskellen, hvor opkaldere har brug for den, mens String flader begge til "" til det almindelige tilfælde.
Kopiering og den ene måde at få dette galt
Parse kopierer sin input, så det returnerede Message forbliver gyldigt, uanset hvordan kalderen genbruger sin buffer. Det koster omkring 3% og en allocation per besked.
WithZeroCopy springer kopieringen over og holder en reference til kalderens slice i stedet. Det er hurtigere, og det gør Message usikkert at bruge efter, at slice er skrevet igen. At læse ind i en genbrugt buffer er den normale, effektive måde at læse fra et netværk i Go, så fælden fanger omhyggeligt kode, og symptomet er stillede forkerte feltværdier i stedet for en fejl - en patients data under en anden patients navn. Brug det til input, der er uændelige eller overlever Message, og ikke andet.
Acknowledgements
AckFor opbygger en ACK eller NAK for en besked, herunder for en, der ikke kunne parses, hvilket er det tilfælde, der betyder mest: en afsender har brug for en besked, selv når det, der blev sendt, ikke var en besked. Se AckOptions.
Hvad dette pakke ikke gør
Det skriver eller ændrer ikke beskeder. Det har ingen forestilling om beskedstruktur ud over segmenter, så det vil ikke fortælle dig, at en PV1 tilhører en bestemt besøgsgruppe. Det validerer ikke mod en versions tabeller. Disse udeladelser er bevidste og ikke oversigtsomhed: dette er en indexer for rigtig trafik, der ofte ikke er standard-overensstemmende og alligevel skal rutes.
Source: github.com/biodream-llc/perfuse/hl7
26.4 admit
Pakken admit begrænser, hvor meget arbejde der er i gang på én gang.
Motoren opretter en goroutine per destination per besked. Goroutines er billige; det, de holder, er ikke. Hver udgående levering holder en socket i den fjerne ende og en filbeskrivelse her, og det holder dem for hele retry-budgetten - med standardindstillingerne, fem forsøg med en tidsgrænse på 30 sekunder plus 15 sekunders tilbagehold, så næsten tre minutter. Et par hundrede afsendere mod en modtager, der er gået stille, er derfor et par hundrede beskrivelser, der holdes i minutter, og processen kører tør.
At køre tør er fejlen, der er værd at forhindre, fordi den ikke viser, hvor den skete. Den viser sig som "for mange åbne filer" et sted, der ikke er relateret: databasen kan ikke åbne sin journal, grænsefladen stopper med at acceptere, en log kan ikke skrives. Motoren ser brudt ud på tre steder på én gang, og årsagen er et partnersystem, der stoppede med at svare.
To begrænsninger, og den anden betyder mere end den første:
En total, så processen forbliver inden for sin beskrivelsesbudget.
En begrænsning per destination, så en modtager ikke kan forbruge totalen. Uden det kan en enkelt hængt partner tage ned alle andre kanaler, hvilket er værre end at have ingen begrænsning overhovedet: fejlområdet vokser fra en grænseflade til alle af dem.
Source: github.com/biodream-llc/perfuse/internal/admit
26.5 alerts
Pakken alerts overvåger målinger og siger, når noget er galt.
Pointen er, at ingen skal behøve at kigge på dashboardet. "Fejlede transaktioner forbliver i kø uden rettidig undersøgelse" er en dokumenteret operativ fejl i denne klasse af software, og årsagen er altid den samme: informationen var på en skærm, som ingen var foran klokken fire om morgenen.
Tre beslutninger former det.
En advarsel skal rydde sig selv. En notifikation, der affyres og aldrig opløses, træner folk til at ignorere notifikationer. Hver regel her vurderes mod den aktuelle tilstand, så en modtager, der kommer tilbage, lukker advarslen, den åbnede.
Advarsler er afkortede af varighed, ikke af antal. "Fejlrate over 5% lige nu" affyres på en enkelt uheldig besked under en stille time. "Over 5% i to minutter" gør det ikke. Hver regel bærer en varighed, og intet affyres, før betingelsen har holdt så længe.
Hvad der sendes, indeholder ingen patientdata. En advarsel bærer en kanalnavn, en destinationnavn, et nummer og en grænseværdi. Disse kommer fra konfiguration og fra tælling. En webhook går til en chatrum, en chatrum har en scrollback, og en scrollback er ikke et sted, hvor en patientidentifikator skal ende.
Source: github.com/biodream-llc/perfuse/internal/alerts
26.6 amqp
Pakken amqp er en AMQP 1.0-klient: en forbindelse, en session, sende- og modtagelseslinks, afgjort efter modtageren siger det.
AMQP 1.0 er, hvad Azure Service Bus og Event Hubs taler, hvad RabbitMQ 4 taler naturligt, og hvad ActiveMQ og Artemis taler ved siden af STOMP. Skrevet her af den grund, STOMP-klienten og AWS-underskriveren er: en fuld klientbibliotek ville være det meste af binærfilens afhængighedsliste for fire performativer, der betyder noget.
Hvad det gør: SASL PLAIN eller ANONYMOUS (Service Bus tager et delt adgangsnavn og nøgle som PLAIN), TLS, åbn/begynd/attach, kredittering-baseret flow, en overførsel delt i rammer, når den overstiger modpartens maksimale ramme-størrelse, og dispositioner - accepteret, frigivet, afvist. Afsenderen venter på brokerens disposition, før det rapporterer succes, så "sendt" betyder, at brokeren tog vare på det. Tomme rammer holder forbindelsen i live inden for modpartens inaktive tidsgrænse, som Service Bus gennemtvinger.
Hvad det ikke gør: transaktioner, multiple sessioner, link-genoprettelse og beskedannoteringer ud over at læse dem.
Source: github.com/biodream-llc/perfuse/internal/amqp
26.7 analyser
Pakken analyze omdanner en parsed Mirth-kanal til noget, som en menneskelig kan handle på: en simpel beskrivelse af, hvad kanalen gør, og en ærlig liste over, hvad der ikke vil overleve en migration.
Designreglen her er, at en fund må være specifik nok til at handle på. "Denne kanal bruger JavaScript" er ikke et fund. "Destination 1 kalder java.util.Date, som ikke har nogen tilsvarende uden for JVM" er.
Source: github.com/biodream-llc/perfuse/internal/analyze
26.8 api
Pakken api betjener HTTP-grænsefladen, der bruges af webfrontenden.
Den vigtige designbegrænsning: Kanaler læses fra og skrives til filer på disken. API'et er en editor for disse filer, ikke et andet lagringsystem, der tilfældigvis eksporterer YAML. En kanal oprettet i browseren og en skrevet med hånden er det samme artifact, hvilket er det, der gør "eksportér til deling" trivialt og holder git som historien over record.
Source: github.com/biodream-llc/perfuse/internal/api
26.9 as2
Pakken as2 er Applicability Statement 2 (RFC 4130): EDI over HTTP, signeret og krypteret med S/MIME, med en signeret kvittering (en MDN), der nævner en digest af, hvad der ankom.
Betalere og handelspartnere bruger det til X12 og EDIFACT.
S/MIME er internal/cms, det samme kode, der bruges af Direct messaging. Det, der er her, er AS2's eget: dets headers, message integrity check (MIC) og kvitteringen.
Source: github.com/biodream-llc/perfuse/internal/as2
26.10 attach
Pakken attach flytter store payload ud af en besked og sætter dem tilbage.
En HL7-besked, der bærer en scannet rapport eller en PDF, er almindelig i dokument-workflows, og payloaden er rutinemæssigt hundredvis af gange større end beskeden omkring den. At lagre det inline betyder, at besked-lageret vokser i takt med dokumenterne snarere end trafikken, en besked, der er køet for fem destinationer, kopieres fem gange, og grænsefladen må streame megabytes for at vise nogen et patientnavn.
Så payloaden udtrækkes, lagres én gang efter indhold og erstattes i beskeden med en token. Mirth kalder disse attachment-håndterere, og det er en dokumenteret migrationsfunktion, hvilket er grunden til, at token-formatet her er designet til at være genkendeligt snarere end clever.
Hvad denne pakke ikke beslutter
Den udfører ingen lagring og ingen I/O. Uddrag producerer den omskrevne besked og payload; et lager et andet sted beslutter, hvor de skal hen. Den adskillelse er det, der gør, at uddragstesten kan køre uden en database, og det er også det, der låser den samme logik til at køre i WASM-legepladsen, hvor der ikke er nogen database overhovedet.
Source: github.com/biodream-llc/perfuse/internal/attach
26.11 authlimit
Pakken authlimit begrænser mislykkede autentificeringsforsøg efter kildeadresse.
Den findes, fordi to lyttere havde brug for det samme, og en af dem havde intet. FHIR-serveren fik en begrænsning, da den fik autentificering; console-login havde ingen overhovedet, og en måling viste tyve adgangsforsøg i sekundet mod administrator-kontot uden nogen forsinkelse og uden låsning. I den takt er en svag adgangskode væk om natten, og det eneste, der samles, er forkert.
Bevidst ikke en almindelig begrænsning af hastighed. Den begrænser mislykkede forsøg, ikke anmodninger: en travlt legitimitets-klient påvirkes aldrig, og det eneste, der akkumuleres, er forkert.
Source: github.com/biodream-llc/perfuse/internal/authlimit
26.12 awsmsg
Pakken awsmsg kommunikerer med Amazon SQS og SNS med standardbiblioteket og den fælles Signature Version 4-underskriver.
Det samme argument som s3put: AWS SDK ville fordoble størrelsen af regnskabsmaterialet for fire API-opkald. SQS bruger sin JSON-protokol (AWS JSON 1.0, X-Amz-Target AmazonSQS.<Action>), som AWS dokumenterer som den aktuelle; SNS bruger sin forespørgselsprotokol, som er den eneste, den har. Begge virker mod LocalStack og VPC-endpoints via en endpoint-overskridelse.
Source: github.com/biodream-llc/perfuse/internal/awsmsg
26.13 awsv4
Pakken awsv4 signerer anmodninger til AWS med Signature Version 4, ved hjælp af kun standardbiblioteket.
Den startede inde i s3put. SQS, SNS og læsning fra S3 har brug for samme signatur med et andet servicenavn og med en forespørgelsesstreng, og en anden kopi af signaturkoden ville være en anden placering for den ene fejl, der betyder noget - en signatur-mismatch læser præcis som forkert legitimationsoplysninger. Så den bor her, kontrolleret mod AWS's offentliggjorte testvektorer, og hver AWS-connector bruger den.
Legitimationsoplysninger er statiske nøgler eller standardmiljøvariabler. Der er bevidst ingen instans-metadata-legitimationskæde: det indebærer IMDS-opkald, cachelagring og opdatering, hvilket er, hvor en lille implementering ophører med at være lille, og Perfuse afviser metadata-adresser som destinationsstandard.
Source: github.com/biodream-llc/perfuse/internal/awsv4
26.14 azblob
Pakken azblob læser og skriver Azure Blob Storage med standardbiblioteket: Shared Key eller SAS-godkendelse over almindelige HTTP-opkald.
Samme begrundelse som s3put: Azure SDK er stort, og operationerne, som en integrationsmotor har brug for, er fem - indsætte, hente, liste, slette og indstille adgangsniveauet. Shared Key-signering er specificeret præcist ("Autoriser med Shared Key", Azure Storage REST), og Azurite, Microsofts emulator, kontrollerer det på samme måde som tjenesten.
Source: github.com/biodream-llc/perfuse/internal/azblob
26.15 branding
Pakken branding gemmer en kundes logo og produktnavn, så en installation kan præsentere sig selv som deres eget produkt i stedet for som Perfuse.
Hvorfor logoet ikke er en indstilling
Alt andet, som en operatør kan ændre, er en skalar i indstillingsfilen. Et logo er nogle få hundred kilobyte binærdata, og at placere det der ville betyde base64 i en YAML-fil, som en person er ment at kunne læse og redigere manuelt. Det bor ved siden af den fil i stedet, og kun dets tilstedeværelse er synlig gennem indstillingsoverfladen.
Den del, der betyder noget: et uploadet billede er upålidelig input
Et logo uploades af en administrator og derefter serveres til hver browser, der loader konsollen, herunder på login-siden, før nogen har godkendt. Det gør det til det mest udbredte stykke angrebsleveret indhold i produktet, så det behandles derefter:
- Den erklærede indholdstype ignoreres. Byte-værdierne snuses, og resultatet skal være i en tilladt liste. En fil kaldt logo.png, der indeholder HTML, er HTML. - SVG accepteres, fordi det er, hvad virksomheder faktisk har, men det er et eksekverbart dokumentformat: det kan medføre scriptelementer, begivenhedshåndteringsegenskaber, eksterne referencer og indlejrede fremmedobjekter. Det omskrives for at fjerne alle disse, før det gemmes, og omskrivningen verificeres ved at plante hvert angreb i en test. - Det serveres med en indholdssikkerhedsstrategi, der tillader intet, med snusning deaktiveret og som et attachment-frit inline-billede kun. Selv en sanitærfejl bør ikke blive scripteksekvering på konsollens egen oprindelse. - Det uploadede filnavn bruges aldrig til at bygge en sti. Det gemte navn er afledt af den snusede type, så et navn som ../../etc/perfuse ikke kan undslippe noget sted.
Source: github.com/biodream-llc/perfuse/internal/branding
26.16 cda
Pakken cda læser kliniske dokumenter.
Designet starter fra, hvordan disse dokumenter faktisk rejser, hvilket ikke er som filer. En udskrivelsessummarum forlader en EHR inde i en HL7 v2 MDM^T02-meddelelse, med hele dokumentet base64-kodet i OBX-5 og beskrevet af en TXA-segment. Det er tusinder af meddelelser om dagen på et midtsized hospital, og det er derfor, denne pakke sidder ved siden af en HL7 v2-parser i stedet for i et dokumentværktøj: v2-halvdel er allerede her, så pipeline fra "en meddelelse ankom" til "en FHIR DocumentReference findes" er kort.
Tre ting er bevidst inden for omfanget, og en er bevidst udenfor.
Inden for omfanget: læsning af et dokument og sigende, hvad det indeholder i almindelige vendinger; kontrollering af, at den menneskeligt-læsbare narrative og de kodificerede poster er enige; og omvandling til FHIR. Narrative-kontrollen er den usædvanlige. Hver C-CDA-sektion bærer den samme information to gange, en gang som tekst for en kliniker og en gang som koder for en maskine, og de skal matche. I praksis gør de det ofte ikke, og intet kontrollerer det - hverken certificeringstjenesterne, hverken motorerne. Når teksten siger, at en patient er allergisk over for penicillin, og den kodificerede post siger noget andet, handler en af de to læsere på den forkerte information. Det er en patient-sikkerhedsfejl, der er mekanisk opdækkelig, så den opdages her.
Uden for omfanget: generering af konform C-CDA. At skrive en betyder at tilfredsstille flere hundrede skabelonregler og en Schematron, og at producere dokumenter, der er 95% rigtige, ville fejle i certificering på måder, der er elendige at fejlfinde. Læsning, kontrollering og omvandling er størstedelen af værdien for en brøkdel af risikoen.
Source: github.com/biodream-llc/perfuse/internal/cda
26.17 channeltest
Pakken channeltest kører tests mod en kanaldefinition.
En kanal er et program. Det filtrerer, omskriver og routerer kliniske meddelelser, og det redigeres under pres af personer, der ikke kan prøve det mod produktion. Fraværet af en måde at teste en kanal på er den eneste største grund til, at grænsefladearbejde er skræmmende, og "Jeg ændrede transformeringsprogrammet, og intet så ud til at være anderledes i meddelelsesbrowseren" er ikke en test.
Den centrale beslutning er, at en test kører meddelelsen gennem den virkelige transformationsvej — samme filter, samme deklarative trin, samme scriptmotor, i samme rækkefølge — med kun transporten erstattet. En test, der trænede en genimplementering, ville passe, mens kanalen fejlede, hvilket er værre end at have ingen test overhovedet, fordi det aktivt misleder.
Source: github.com/biodream-llc/perfuse/internal/channeltest
26.18 chanscope
Pakken chanscope indsnævrer læsninger og skrivninger på en kontekst til nogle kanaler.
Det afhænger af konteksten snarere end af at være en parameter for hver forespørgsel, fordi der er dusinvis af forespørgsler på tværs af meddelelseslagret og leveringskøen, og grænsen er en egenskab ved den, der spørger, og ikke ved spørgsmålet. API'et indstiller det én gang pr. anmodning for en person, der er begrænset til visse kanalgrupper; hver telling, liste, diagram, søgning og køhandling er herefter enig med de andre, så ingen bliver fortalt, at der er i alt fyrre fejl og vist fire.
Source: github.com/biodream-llc/perfuse/internal/chanscope
26.19 kluster
Pakken kluster giver flere Perfuse-servere mulighed for at dele én PostgreSQL-lager og beslutte, hvilken af dem der kører hvad.
Problemet det løser
Én server er ét fejlpoint: Når den stopper, stopper alle grænseflader. To servere på én database løser kun dette, hvis de aldrig begge kører den samme kanal, fordi to MLLP-lyttere på én feed skifter til senderen, to køarbejdere leverer samme meddelelse to gange, og to DICOM-pollere rapporterer hver den samme undersøgelse.
How
En leasing er en række, der navngiver, hvem der ejer noget, med en tæller, som ejeren flytter på ved hver fornyelse, hver få sekunder. Ingen ur sammenlignes med et andet: En ejer, der ikke kan forny (er styrtet sammen, er afbrudt fra database), stopper, hvad leasingen dækker, så snart dens eget ur siger, at leasingen er næsten færdig, og en anden server tager det kun efter, at dens eget ur har set tælleren stå stille i hele leasingen. Hver måler et interval på sin egen ur, så servernes ur og databaseens ur behøver ikke være enige; de behøver kun at køre med omtrent samme hastighed. Et ur, der springer (en virtuel maskine synkroniserer, en administrator indstiller tiden), ændrer intet: Den første version brugte databaseens ur til udløb, og en test fandt en database, hvis ur sprang tretten sekunder over og gav hver leasing til en ny server, mens de gamle stadig kørte dem.
- aktiv-passiv: én leasing, "leder". Dens ejer kører hver kanal og hver opgave, der skal køres én gang (abonnementsmeddelelser, beskeder). De andre venter, og den første, der ser den udløbe, overtager. - aktiv-aktiv: Lederen kører stadig opgaverne, og hver kanal har sin egen leasing, fordelt jævnt over de aktive servere. En server, der forlader, giver sine kanaler til de andre; en, der tilslutter, tager sin andel, når de bliver ledige.
Two modes:
- aktiv-passiv: én leasing, "leder". Dens ejer kører hver kanal og hver opgave, der skal køres én gang (abonnementsmeddelelser, beskeder). De andre venter, og den første, der ser den udløbe, overtager. - aktiv-aktiv: Lederen kører stadig opgaverne, og hver kanal har sin egen leasing, fordelt jævnt over de aktive servere. En server, der forlader, giver sine kanaler til de andre; en, der tilslutter, tager sin andel, når de bliver ledige.
Hver leasing har en epoke, der tælles op, hver gang ejeren ændres, som navngiver et ejerskab i historien.
Source: github.com/biodream-llc/perfuse/internal/cluster
26.20 cms
Pakken cms er Cryptographic Message Syntax (RFC 5652), som S/MIME og Direct secure messaging bruger: SignedData (signer en meddelelse, verificér en og sig, hvem der har signeret den) og EnvelopedData (kryptér en meddelelse til modtagerens certifikater, dekryptér en med vores nøgle).
Kun det, som Direct Applicability Statement og dens Implementeringsvejledning kræver: RSA med SHA-256 (SHA-1 accepteres kun til læsning, da ældre HISPs stadig sender det), RSA-nøgletransport med PKCS#1 v1.5 eller OAEP, og AES-128 eller AES-256 i CBC-tilstand. Krypteringen er standardbibliotekets; denne pakke er ASN.1 omkring det.
Source: github.com/biodream-llc/perfuse/internal/cms
26.21 cms0057
Pakken cms0057 indeholder betalingspartsdelene af CMS Interoperability og Prior Authorization slutreglen (CMS-0057-F), som handler om data snarere end transport: afregnet krav som CARIN Blue Button ExplanationOfBenefit-resourcer, forhåndsautorisationer som Da Vinci PDex ExplanationOfBenefit-resourcer, HRex-medlemssammenligning til Payer-to-Payer-API, medlemslisten bag Provider Access-API og forhåndsautorisationsmetrikker, som en betaler skal offentliggøre hvert år.
FHIR-endpointene, der betjener disse, findes i fhirserver; denne pakke afgør, hvad der kommer i dem.
Lægemidler er uden for området i hele reglen om forhåndsautorisation: ingen apoteks-ExplanationOfBenefit, ingen formular, ingen NCPDP.
Source: github.com/biodream-llc/perfuse/internal/cms0057
26.22 kodesæt
Pakken kodesæt indeholder mappingstabeller, der overlever kanalen, der først havde brug for en.
Domænetaksen består for det meste i at genskabe en mapping, som nogen allerede har afledt. En lokalitets kønskoder, patientklasser, ordrestatus og facilitetsidentifikatorer oversættes på samme måde i hver kanal, der berører dem, og i dag er hver af disse oversættelser en separat tabel inde i en separat kanal. Fyrre kanaler betyder fyrre kopier og fyrre steder at rette næste gang modtagersystemet ændrer sig.
Så en tabel bliver et navngivet objekt, der refereres til ved navn. Det er åbenbart og det er den mindre halvdel af værdien.
Den halvdel, som ingen bygger
Den større halvdel er proveniens. Det meste af, hvad der gør en grænseflade svær at vedligeholde, er ikke mappingen - det er, at ingen ved *hvorfor*. "Vi fjerner førende nuller, fordi laboratoriets MRN-kolonne er numerisk" er viden, der findes i én persons hoved og forlader bygningen, når de går på pension, og den mapping, der bliver tilbage, bliver noget, som ingen tør ændre og ingen tør slette.
Så hver tabel optegner, hvem der besluttede og hvornår, hver post kan optegne sin egen grund, og begge overlever til filen, der kommer i versionskontrol. En mapping med en grund kan diskuteres. En mapping uden en grund bliver overtro.
Hvorfor filen er separat fra kanalen
Fordi det er delt. En tabel inde i en kanal er en tabel, som kun denne kanal kan bruge, hvilket er problemet. Og en delt tabel har brug for sin egen historik: "hvem ændrede kønskortlægningen og hvornår" er et spørgsmål om tabellen, ikke om hvilken kanal der skete at blive redigeret den dag.
Source: github.com/biodream-llc/perfuse/internal/codeset
26.23 overholdelse
Pakken overholdelse implementerer CMS ADT-begivenhedsmeddelelsesarbejdsgangen, som kræves af 42 CFR 482.24(d) siden maj 2021.
Hospitaler skal elektronisk underrette en patients etablerede behandlere - primær sundhedspleje, specialister, efterfølgende plejefaciliteter - når patienten indlægges, udskrives eller overføres. Reguleringen findes, fordi patienter falder igennem sprækker under overgangen: en PCP, der ikke ved noget om en udskrivning, kan ikke planlægge den opfølgning, der forhindrer en genindlæggelse.
Denne pakke giver maskineriet til: - At spore, hvilke behandlere der er etableret for hver patient. - At lede ADT-begivenheder til de rette behandlere med den rette prioritet. - At optage hver meddelelse, der er sendt, med leveringsstatus, til CMS-undersøgelsesauditorer. - At generere overholdelsesrapporter, der viser meddelelseshastigheder og fejl.
Trådsikkerhed kræves overalt, fordi ADT-meddelelser ankommer samtidigt fra multiple kanaler, og meddelelsesrøret køres i parallel.
Source: github.com/biodream-llc/perfuse/internal/compliance
26.24 config
Pakken config indlæser kanalddefinitioner fra filer.
Konfigurationen lever i filer snarere end i en database, hvilket er det vigtigste, Perfuse gør anderledes end Mirth. Mirth holder kanaler i sin egen database, hvilket er hvorfor versionskontrol er et separat produkt, hvorfor det er svært at fremme en kanal fra test til produktion, og hvorfor ingen kan svare på "hvad ændrede sig sidste tirsdag" uden en supportopkald. Filer giver git, diffs, gennemgang, CI og miljøfremme med ingen ekstra maskineri.
Validering er bevidst streng og sker ved indlæsning: ukendte felter er en fejl, filterudtryk kompiles, adresser tjekkes. En kanal, der ikke kan forstås, må nægte at starte snarere end køre på en måde, ingen havde til hensigt.
Source: github.com/biodream-llc/perfuse/internal/config
26.25 kontrakt
Pakken kontrakt omdanner, hvordan en feed ser ud, til, hvordan en feed skal se ud.
En profil besvarer "hvad modtager jeg". Det er nyttigt en gang. Det dyre problem er dagen, det ændrer sig: en vendoropgradering dropper et felt, en ny kode dukker op, en sektion begynder at gentage. Ingen af dem er en fejl - meddelelserne er stadig gyldige HL7, og hver motor i verden accepterer dem - så intet bemærker det, før en modtager falder om, som regel uger senere, og undersøgelsen starter fra den forkerte ende.
En kontrakt er profilen skrevet ned som en forventning og derefter kontrolleret. Det er kontrakttestning, som er en løst idé i software generelt og næsten helt fraværende fra sundhedsintegration.
Hvorfor enheden er en hastighed og ikke en meddelelse
Den åbenlyse design er at kontrollere hver meddelelse og klage, når en fejler. Det producerer et system, ingen kan bruge. Reelle feeds indeholder en proportion af virkelig underlige meddelelser - en testmeddelelse fra vendor, en patient med ingen registreret køn, en manuel indtastning - og alarm på hver enkelt træner folk til at ignorere alarmene, på det tidspunkt funktionen er værre end ingenting, fordi den har forbrugt opmærksomheden, den havde brug for.
Så en forventning handler om en proportion over et vindue: "PID-3 er befolket i mindst 99% af meddelelserne". En underlig meddelelse får aldrig ild. Fem procent af meddelelserne, der mister deres medicinske journalnummer, gør.
En kontrakt beskriver, hvad ankommer, ikke hvad forlader
Dette er forskellen, folk får forkert først, herunder mig selv, mens integrationstestning. Perfuse gemmer meddelelsen, som den ankom - det er bevidst, fordi den gemte meddelelse er bevis for, hvad en afsender sendte - så en kontrakt kontrolleres mod den indgående feed og ikke mod outputtet af kanaltrensformationerne.
Det er den rette standard med en stor margin: det, der ændrer sig uden varsel, er sendesystemet, og formålet med en kontrakt er at bemærke. Men det betyder, en forventning skrevet om en kortlagt værdi ("efter kortlægning, skal kun laboratoriets koder forblive") vil fejle med det samme og forvirrende, fordi koderne, den nævner, aldrig dukker op i trafikken, der profileres. Alt om, hvad der forlader, hører til i en kanaltest, som kører de virkelige transformationer.
Hvorfor en overtrædelse navngiver tolerancen, den brød
"PID-3 fejlede" fortæller nogen intet. "PID-3 var befolket i 94,2% af de sidste 500 meddelelser; kontrakten kræver 99%" fortæller dem, hvor dårligt det er, hvor sikker de skal være, og om det er værd at vække nogen. Tallene er meddelelsen.
Source: github.com/biodream-llc/perfuse/internal/contract
26.26 crd
Pakken crd er en Da Vinci Coverage Requirements Discovery-tjeneste (CRD 2.2.1): betalingspartens side af CDS Hooks-samtalen, der fortæller en kliniker, mens ordren stadig er en kladde, om det er dækket, om det kræver forhåndsgodkendelse, og hvilken dokumentation betaleren vil ønske.
CMS-0057's Prior Authorization API er i praksis tre Da Vinci-retningslinjer sammen: CRD for at sige, hvad der kræves, DTR for at samle det, PAS for at indsende det. Perfuse havde PAS. Dette er den første af de to andre; DTR's $questionnaire-package er på FHIR-endpointet.
Dækningbeslutningerne kommer fra en regel-fil, fordi de er betalerens politik og ændrer sig uden software-udgivelser: en kode (eller en liste over koder) og hvad der gælder for den - dækket eller ej, forhåndsgodkendelse nødvendig eller ej, dokumentation og DTR-spørgeskemaet, der indsamler den. En ordre, der ikke matcher nogen regel, besvares "betinget" og "uafgjort", hvilket er, hvad CRD siger, skal returneres, når tjenesten ikke kan træffe en beslutning - aldrig en gæt på, om det er dækket.
Svar følger vejledningen: en systemhandling, der opdaterer hver ordre med dækning-informations-udvidelsen, som EHR lagrer på ordren og senere sender med forhåndsgodkendelsen; og et kort per ordre, så en kliniker kan se det.
Source: github.com/biodream-llc/perfuse/internal/crd
26.27 dashboard
Pakken dashboard definerer dashboards, som Perfuse leverer til hver type person, der overvåger det, og hvordan en person tildeles et: ved deres rolle, ved en directory-gruppe, som dashboards-filen mapper, eller ved den visning, de har gemt.
Dashboards består af fliser, og fliser viser kun aggregater - antal, hastigheder, tider, tilstande. Ingen viser en meddelelse, en patient eller en identifikator, så et dashboard kan gives til en afdelingsleder eller placeres på en vægskærm uden at udvide, hvem der ser patientdata. En flise, der har brug for data, som Perfuse endnu ikke optager, bliver ikke fabrikeret: dashboardet listar den under Planlagt.
Fuld fleksibilitet er Grafanas job, ikke denne pakkes. Hver flise, der har en metrik bag sig, eksporterer som en Grafana-panel over Perfuses /metrics, så et websted, der ønsker mere end let konfiguration, tager dashboardet derhen.
Source: github.com/biodream-llc/perfuse/internal/dashboards
26.28 davinci
Pakken davinci angiver, hvilken version af Da Vinci prior-authorization guider (CRD, DTR, PAS), som en klient understøtter.
Perfuse besvarer i to versioner: 2.2 (CRD 2.2.1, DTR 2.2.0, PAS 2.2.1), den nyeste, og 2.1 (CRD, DTR og PAS 2.1.0), den version, som CMS-0057-F's anbefalede liste henviser til, når basisversionen 2.0.1 for US Core 3.1.1 udløber. De to versioner adskiller sig i de former, som en klient læser ved navn - DTR's $questionnaire-package parametre (PackageBundle i 2.1, packagebundle i 2.2), PAS's $inquire svar (en Bundle i 2.1, en Parameters af dem i 2.2), udvidelser, som kun findes i en af dem - så ét svar ikke kan betjene begge, og serveren må vide, hvilken version den kommunikerer med.
Det oplyses, mest specifik først: ved selve anmodningen (CRD's davinci-crd.requestedVersion; versionen på en profil, som input påstår, profil|2.1.0), derefter ved klientens registrering (davinci_version på en SMART eller CDS-klient), derefter ved serverens egen indstilling (serve -davinci-version), som standard er sat til den nyeste.
Source: github.com/biodream-llc/perfuse/internal/davinci
26.29 dbtime
Pakken dbtime formaterer tidsstempel, sådan at sorteringsfunktionen som tekst sorterer dem som tid.
Hver butik i Perfuse gemmer tidsstempel som TEXT i SQLite og afhænger af strengsammenligning til sortering og til områdeforespørgsler: ORDER BY received_at DESC, WHERE expires_at < ?, WHERE at >= ?. Det er en rimelig design - det holder en database, som nogen kan læse med sqlite3-shell - men det fungerer kun, hvis tekstformen er fast bredde.
time.RFC3339Nano er det ikke. Dets dokumentation siger, at det fjerner trailing nulle fra sekundfeltet, så den samme ur producerer strenger af forskellig længde:
20:56:33.12345Z <- 123450 mikrosekunder, trailing nul fjernet 20:56:33.123456Z <- 123456 mikrosekunder
Sammenlignet som tekst, er den første *større*, fordi efter det fælles præfiks "12345" har den 'Z', hvor den anden har '6', og 'Z' sorterer over hver cifre. Så den tidligere instant sorterer senere. Omtrent en tilstødende par på ti er berørt, hvilket er, hvorfor det præsenterede som en intermitterende testfejl snarere end som en åbenbart fejlende funktion.
Hvad det faktisk brød: revisionsloggen og meddelelse-browseren begge sorterer efter et tidsstempel og kan derfor liste indgange fra samme sekund i forkert rækkefølge. En revisionsstik er et overholdelsesartefakt og en meddelelse-browser er, hvordan nogen rekonstruerer, hvad der skete, så i begge tilfælde er rækkefølgen punktet.
Layout nedenfor bruger .000000000 i stedet for .999999999. Begge trykker nanosekunder; forskellen er, at nulle er betydningsfulde i den første og fjernet i den anden.
Source: github.com/biodream-llc/perfuse/internal/dbtime
26.30 afgrænset
Pakken delimited parserer poster, adskilt og delt af konfigurerede tegn.
Dette er Mirths Delimited data type: CSV, tab-adskilt, pipe-adskilt, fast-kolonne-filer og den lange hale af formater, som et laboratorie-analyse- eller et bureau-service udsender, fordi nogen skrev det i 1994 og det virker.
Bevidst ikke en generel CSV-bibliotek. Hvad der betyder her er, hvad en sundhedsfeed gør, som en velformet CSV ikke gør: en header-række, der kan være til stede eller ej, en efterfølgende tom linje, der ikke må blive en tom post, kolonner, der henvises til navn, så en transformation ikke bryder, når en leverandør indsætter en, og evnen til at behandle en hel fil som en meddelelse eller hver række som sin egen.
Den sidste af disse er beslutningen, der former alt andet. En fil med fem tusinde resultater er enten en meddelelse eller fem tusinde, og de to er ikke udskiftelige: en meddelelse betyder en bekræftelse og en fejl for hele filen, og fem tusinde betyder, at hver række kan filtreres, transformeres og genprøves på sin egen.
Source: github.com/biodream-llc/perfuse/internal/delimited
26.31 dicom
Pakken dicom læser DICOM-data-sæt.
DICOM er, hvor radiologien bor, og et hospital-integrationsmotor, der ikke kan tale det, er lukket ude af billederne helt. Mirth har en DICOM-lytter og afsender, så dette er en migrationsblokerer for ethvert websted, der udfører modalitetsarbejde.
Omfang, udtrykt på en enkel måde
Denne pakke parser data-sæt: fil-metaoplysninger, elementer, overførselssyntaks og værdier, der er vigtige for routing og identifikation. Den dekoder ikke pixeldata og vil aldrig gøre det, så vidt denne pakke er bekymret - en integrationsmotor flytter billeder, den viser dem ikke, og en decoder er en stor mængde format-specifik arbejde, hvis eneste formål her ville være at gøre den binære større.
Læsning af metadata uden at røre pixels er også, hvad der gør det hurtigt på den trafik, der betyder noget: en bryst-CT er hundredvis af megabyte af pixels bag to kilobyte af den information, nogen router på.
Hvorfor værdirepræsentationerne behandles eksplicit
Et DICOM-element indeholder en to-bogstavs værdirepræsentation, der beskriver, hvordan værdien skal læses, og reglerne afviger pr. VR på måder, der ikke kan gættes: nogle har en to-byte længde og nogle fire, nogle er fyldt op med et mellemrum og nogle med en null, og numeriske strenge kan indeholde flere værdier adskilt af bindestreger. At få en forkert producerer ikke en fejl, men en plausibel forkert værdi - et patientnavn læst fra midten af en dato eller et studie-id, der er én byte forkert.
Source: github.com/biodream-llc/perfuse/internal/dicom
26.32 dicomweb
Pakken dicomweb taler DICOMweb (DICOM PS3.18): QIDO-RS til søgning, WADO-RS og WADO-URI til hentning, STOW-RS til lagring, over HTTP.
Det er, hvordan visningsværktøjer, AI-tjenester og cloud-arkiver når billedmaterialer nu: OHIF, Google Cloud Healthcare, Azure Health Data Services, AWS HealthImaging, Orthanc's og dcm4chee's DICOMweb-grænseflader. En integrationsmotor, der kun taler netværksprotokollen fra 1993 (DIMSE: C-STORE, C-FIND), kan føde en PACS, men ikke en browser.
Pakken har fire dele: en datasæt-læser, der gennemgår hele objektet, inklusive sekvenser, og ved, hvor pixeldataen er, uden at indlæse den; DICOM JSON-modellen (PS3.18 F.2); multipart/related, som er, hvordan DICOMweb flytter flere objekter i en anmodning; og et arkiv med en indeks, som er, hvad QIDO og WADO besvarer fra.
Source: github.com/biodream-llc/perfuse/internal/dicomweb
26.33 direct
Pakken direct er Direct-sikker beskeder som et kantsystem: en besked til en Direct-adresse er signeret med denne adressens certifikat og krypteret til modtagerens, som S/MIME, og sendt til en HISP via SMTP; en besked modtaget fra HISP (via SMTP eller indsamlet over IMAP) er dekrypteret, og dens signatur kontrolleres mod tillidsankre, før noget læser den.
Den følger Direct Project Applicability Statement for Secure Health Transport 1.2 og XDM-specifikationen (IHE ITI TF-1 Annex 15) for dokumenter med metadata. Den er ikke en HISP: HISP's akkreditering, dens certifikatpolitik og dens directory forbliver hos HISP.
Source: github.com/biodream-llc/perfuse/internal/direct
26.34 drug
Pakken drug håndterer koderne og mængderne, der identificerer et lægemiddel.
Splittet ud fra apotekstandarderne, der bærer dem, fordi den samme lægemiddelkode optræder i en NCPDP-krav, en SCRIPT-recept, en HL7 RXE-segment og en FHIR MedicationRequest, og en konvertering, der bor i en af disse steder, er en konvertering, de andre tre ikke har brug for.
Source: github.com/biodream-llc/perfuse/internal/drug
26.35 dsdr
Pakken dsdr signerer og verificerer CDA-dokumenter, som beskrevet i HL7 Implementation Guide for CDA Release 2: Digital Signatures and Delegation of Rights, Release 1 (oktober 2014) - den elektroniske signaturstandard, der er vedtaget af HIPAA for kravvedhæftninger i CMS-0053-F, 45 CFR 162.2002(e), med overholdelse fra 26. maj 2028.
Hvad vejledningen beder om, og hvor det udføres her:
- Sammenfattelsen er over hele dokumentet, med undtagelse af alle legalAuthenticator- og authenticator-elementer (sektion 3.1.2), så senere signaturer ikke ødelægger tidligere signaturer. Udtrykt i signatur som en XPath Filter 2.0 subtract-transformation, som enhver XML-DSig-implementering kan evaluere. - Signatur er XAdES-X-L (3.1.1, ESMD-1 til ESMD-6): signaturcertifikatet, UTC-signeringstid, en rolle fra NUCC-leverandør-taxonomien, en signaturformål fra ASTM E1762, certifikatstien i CertificateValues og en OCSP- eller CRL-respons i RevocationValues, med tidsstempel X-L er bygget på. - Det er medtaget base64 i sdtc:signatureText på den, der har signeret, med en plain-text miniature (3.3, ESMD-7 til ESMD-16), inde i digitalSignature/authorizedSigner.
Hvor vejledningen er tavs, er valgene lavet og navngivet: den giver ikke et navneområde for sine egne elementer (digitalSignature, authorizedSigner, SignaturePurpose), så de er placeret i urn:hl7-org:sdtc; og formålet er også udtalt som en XAdES CommitmentTypeIndication med ASTM OID, som XAdES-værktøjer læser, og vejledningens eget element, de ikke gør.
Delegering af rettigheder (en deputeret signer med en SAML-påstand) er ikke produceret; en signatur, der bærer en, rapporteres som sådan.
Source: github.com/biodream-llc/perfuse/internal/dsdr
26.36 e4x
Pakken e4x får Mirth Connect's JavaScript til at køre uændret.
Mirth-skripter er skrevet til Rhino, der implementerer E4X: XML er en naturlig type med sin egen syntaks. Motoren her er goja, der ikke gør det, og gapet er ikke kun et runtime-problem. Tre dele af E4X er *syntaks*, så goja's parser afviser filen pure, før noget objektmodel kunne hjælpe:
for each (var seg in msg..OBX) { } // for-each, og descendant-operatoren var z = <ZZZ><ZZZ.1>value</ZZZ.1></ZZZ>; // en XML-literal var id = node.@root; // en attribut-henvisning
Denne fil omskriver dem til almindelig ECMAScript, som goja parser, og overlader semantikken til runtime-objektet i xml.go. Alt andet om E4X - egenskabsadgang via elementnavn, indeksering af gentagelser, tildeling, toString - er allerede gyldig JavaScript-syntaks og har ikke brug for omskrivning.
Omskrivningen udføres med en reel lexer i stedet for regulære udtryk, fordi alternativet korrumperer fungerende skripter. Et mønster for descendant-operatoren finder en inde i "http://example.org", et mønster for XML-literaler finder en i "a < b && c > d", og et skript, der stille ændrer mening, er værre end et, der nægter at indlæse.
Source: github.com/biodream-llc/perfuse/internal/e4x
26.37 edifact
Pakken edifact læser og skriver UN/EDIFACT-interchanges (ISO 9735): UNA-service-streng-råd, UNB/UNZ-interchange-envelopen, valgfrie UNG/UNE-funktionelle grupper og UNH/UNT-besked, med udgivelses-tegnet og, for syntaks-version 4, gentagelses-separatoren.
Det kontrollerer kuvertets tællinger og referencer, adresserer dataelementer til filtre, splitter en udveksling i én per besked og opbygger en CONTRL-bekræftelse.
Det læser enhver beskedtype (ORDERS, INVOIC, IFTSTA, MEDRPT ...); det har ikke de kataloger, der angiver, hvilke segmenter en beskedtype kan indeholde, så det kontrollerer struktur, ikke indhold.
Source: github.com/biodream-llc/perfuse/internal/edifact
26.38 afgang
Pakken afgang afgør, om denne motor kan oprette en forbindelse udad til en adresse.
Den findes, fordi en destination kan pege overalt hen, og en kombination gør det til en måde at læse det interne netværk på: en SOAP-destination med en respons-transformation returnerer modtagerens svar til et script, så en redaktør kan oprette en kanal, der henter en intern URL og skriver brødteksten ind i en log eller en besked.
Demontreret snarere end teoriseret: en SOAP-destination rettet mod en lokal HTTP-server satte serverens responsbrødtekst ind i en kanalloglinje.
Det proportionale svar er ikke at forbyde udgående forbindelser - levering af beskeder til konfigurerede endepunkter er det samlede formål med softwaren, og en redaktør er ment til at konfigurere dem. Det er at afvise de specifikke adresser, der aldrig er en beskeddestination og altid er en legitimationslager.
Source: github.com/biodream-llc/perfuse/internal/egress
26.39 motor
Pakken motor kører konfigurerede kanaler.
En kanal er en kilde, et filter og en samling destinationer. Runtime-miljøets job er at være ærlig om, hvad der skete med hver besked: en bekræftelse skal betyde, hvad konfigurationen siger, det skal, en besked, der er filtreret fra, skal kunne skelnes fra en, der blev leveret, og en besked, der ikke kunne leveres til noget sted, må ikke rapporteres som accepteret.
Source: github.com/biodream-llc/perfuse/internal/engine
26.40 epa
Pakken epa er NCPDP SCRIPT elektronisk forudgodkendelse, betalerens side: PAInitiationRequest, PARequest, PAAppealRequest og PACancelRequest ind, og deres svar ud.
CMS-0062-P foreslår, at berørte betalere skal understøtte det fra 1. oktober 2027, og Medicare Part D kræver allerede det. En anmodning afgøres på samme måde, som enhver forudgodkendelse på denne server: den bliver en Da Vinci PAS-anmodning (en krav, MedicationRequest og prescriberens svar som et QuestionnaireResponse) og går til samme regel-fil, beslutningstjeneste og gennemgangskø.
NCPDP's skemaer er licenseret. Elementnavne og rækkefølge her følger den offentlige Surescripts ePA-kompletærvejledning og dens eksempler; to elementer, det offentlige materiale aldrig viser (årsagen inde i Closed og inde i Denied), følger SCRIPT-mønsteret, der bruges andre steder, og er navngivet i manualen, så en betaler kan kontrollere dem mod sin egen kopi af skemaet.
Source: github.com/biodream-llc/perfuse/internal/epa
26.41 eprescribe
Pakken eprescribe læser og skriver NCPDP SCRIPT, den standard, recepter rejser i.
Navngivet efter, hvad den gør, snarere end efter standarden, fordi intern/script allerede er JavaScript-motoren, og to pakker kaldt script i ét træ er en fejl, der venter på at blive lavet på en importlinje.
SCRIPT er XML, til forskel fra Telekommunikationsstandarden, der bærer den resulterende krav. En prescriber sender en NEWRX til en apotek; apoteket sender tilbage RXFILL for at sige, hvad der skete, REFREQ for at bede om en genopfyldning, eller RXCHG for at bede om en ændring. Hver af disse er en besked her.
Hvor farerne er
To felter i en recept er farlige, når de mislæses snarere end når de mangler.
Erstatninger er det første. En null betyder, at erstatning er tilladt, og en et betyder, at det skal udstedes, som skrevet. Det læser baglæns for enhver, der forventer en flag, hvor en betyder ja, og får det galt, udsteder en generisk, hvor prescriberen krævede mærkevaren - eller nægter en erstatning, der var tilladt, hvilket er den samme fejl, der koster patienten penge i stedet. Så denne pakke nægter at gætte: et fraværende Substitutions-element er en fejl snarere end en standard, fordi begge standarder er forkerte.
Genopfyldningsantal er det andet. En schedule II-recept må ikke genopfyldes overhovedet, og et system, der bærer et genopfyldningsantal over fra en ikke-kontrolleret skabelon, producerer en gyldig udseende recept, som et apotek må nægte.
Hvad ikke er verificeret
Beskedstrukturen følger de offentliggjorte SCRIPT-elementnavne. Ingen besked fra denne pakke er blevet sendt gennem et rigtigt routingsnetværk, såsom Surescripts, og certificering af en er en kommerciel proces snarere end en teknisk. Dette parser og opbygger formatet; det kræver ikke certificering.
Source: github.com/biodream-llc/perfuse/internal/eprescribe
26.42 ækvivalent
Pakken equiv beviser, at to motorer er enige, eller siger præcis, hvor de ikke er.
Dette er svaret på det eneste spørgsmål, der faktisk blokerer en migration. Et interface-team afviser ikke en ny motor, fordi den mangler funktioner; de afviser, fordi de ikke kan være sikre på, at den vil gøre det samme med den trafik, de allerede har, og at være forkert betyder, at laboratorie-resultater ikke når lægerne. Ingen funktionssammenligning kan besvare det. Bevis kan.
Den tiltænkte brug er en parallel kørsel. Begge motorer modtager de samme produktionsmeddelelser; den siddende motor leverer stadig, og Perfuse leverer til ingen, hvilket er, hvad skyggekanaler allerede er. Efter to uger sammenlignes output her, og samtalen ændrer sig fra "betror dette" til "her er de tre meddelelser ud af fire hundred tusind, hvor vi var uenige, og hvorfor".
Gruppering er hele funktionen
En naiv diff af 400.000 meddelelser producerer 400.000 fund og bliver lukket uden at blive læst. Næsten hver reel forskel har én årsag: et datoformat, en facilitetskode, ét transformations-trin, som ingen har overført. Så forskelle grupperes efter årsag - stien i meddelelsen og typen af forskel - og rapporteres én gang med en tæller. Tre tusind forskelle fra én årsag er én fund, ikke tre tusind. Den enkelte beslutning er, hvad der gør rapporten læselig, og en læselig rapport er forskellen på en migration, der fortsætter, og en, der stopper.
Værdier meddeles ikke som standard
Rigtig trafik er patientdata, så en sammenligningsrapport er et sted, hvor PHI kunne lække ind i en billet, en e-mail eller en diasslide. Som standard rapporterer denne stier, typer og tællere - aldrig værdier. Det er nok til at finde årsagen: "MSH-7 adskiller sig i 3.000 af 3.000 meddelelser" fortæller en analyst, at det er datoformatet uden at vise én dato.
Værdier kan aktiveres bevidst, fordi nogen til sidst skal se én, og at prøve at lade som om, ville blot skyde dem over til et værre værktøj. Det er en eksplicit opt-in, og rapporten siger på sin egen face, at den indeholder meddelelsesindhold.
Source: github.com/biodream-llc/perfuse/internal/equiv
26.43 expr
Den HL7 v2-binding.
Dette er logikken, der tidligere boede inline i eval.go. Den er uændret i opførsel - bevidst, fordi v2-filtret er, hvad hver HL7-kanal kører, og pointen med den generiske grammatik var at tilføje formater, ikke at ændre dette.
Source: github.com/biodream-llc/perfuse/internal/expr
26.44 fdlimit
Pakken fdlimit finder ud af, hvor mange filbeskrivere denne proces kan åbne, og hæver grænsen, hvis det kan.
Dette eksisterer på grund af formen på fejlen, det forhindrer. Hver indgående forbindelse er en beskrivelse, og det samme gælder hver udgående levering i flyvning. En modtager, der har stoppet med at svare, holder en beskrivelse for hele genstartsbudgettet - med standardindstillingerne, fem forsøg med en tidsgrænse på tredive sekunder plus femten sekunders tilbagehold, så næsten tre minutter. Et par hundred forbindelser mod én hængt modtager er derfor et par hundred beskrivelser, der holdes i minutter.
At løbe tør ikke producerer en pæn fejl på det sted, der løb tør. Det producerer "for mange åbne filer" et helt andet sted: databasen kan ikke åbne sin journal, webgrænsefladen stopper med at acceptere, en logfil kan ikke skrives. Motoren ser ud til at være brudt på tre ikke-relaterede steder på én gang, og den virkelige årsag er et partnersystem, der er blevet stille. Det er den supportopkald, denne pakke eksisterer for at undgå.
To ting sker ved start. Den bløde grænse hæves til den hårde grænse, hvilket normalt fjerner problemet helt - den bløde standard er ofte et par hundred, mens den hårde grænse er titusinder. Så rapporteres, hvad der er tilgængeligt, så motoren kan begrænse sin egen samtidighed inde i den selv, i stedet for at opdage det ved at ramme det.
Source: github.com/biodream-llc/perfuse/internal/fdlimit
26.45 fhirpath
Pakken fhirpath evaluerer FHIRPath (HL7 FHIRPath N1, 2.0.0) over FHIR-resourcer, der holdes som afkodede JSON.
Den har ingen FHIR-model: et elements type er kendt, når FHIR JSON siger det (et valg-elements suffiks, såsom valueQuantity, en ressources resourceType) eller er afledt fra JSON-værdien ellers. Det dækker, hvad SQL på FHIR-visninger og CQL-frie kvalitetsmål behøver; navigation, der afhænger af modellen (en primitivs egen type, når den ikke er et valg), besvares fra værdiens form.
Source: github.com/biodream-llc/perfuse/internal/fhirpath
26.46 fhirserver
Pakken fhirserver implementerer en FHIR REST-server.
Dette eksisterer, fordi den nyttige ende af en v2-til-FHIR-mapper er et sted at placere resultatet. At kunne konvertere en meddelelse er en demo; at kunne konvertere den, gemme den og derefter finde patienten igen efter identifikator er et produkt.
Det er en rigtig FHIR-server i de dele, der betyder noget for det: en kapacitetserklæring, opret, læs, opdater, slet, søg på parametrene, som folk faktisk bruger, og transaktionsbundter, der anvendes atomisk. Det er ikke en komplet FHIR-server - ingen historik, ingen kædede søgning, ingen _include - og det siger så i sin egen kapacitetserklæring, i stedet for at lade en klient opdage hullerne.
Source: github.com/biodream-llc/perfuse/internal/fhirserver
26.47 formulary
Pakken formulary er en betalers lægemiddel-formular: hvilke lægemidler hver plan dækker, på hvilken niveau, og med hvilke begrænsninger (første autorisation, trin-terapi, mængde-begrænsninger), og hvad medlemmet betaler.
En fil er den enkelte kilde til alt, der besvarer et spørgsmål om et lægemiddel: Da Vinci US Drug Formulary API (publiceret fra det som FHIR), NCPDP Real-Time Prescription Benefit-svar og NCPDP SCRIPT elektronisk forudgodkendelse (om et lægemiddel har brug for det, og hvilke spørgsmål der skal stilles). En formular, der lever i tre steder, vil besvare det samme spørgsmål på tre måder.
Source: github.com/biodream-llc/perfuse/internal/formulary
26.48 indramning
Pakke rammer læser og skriver meddelelser på en byte-strøm, der ikke er MLLP.
Hvorfor dette eksisterer separat fra mllp
MLLP er en ramme: 0x0B før, 0x1C 0x0D efter. Det er, hvad HL7 v2 bruger over TCP, og Perfuse har altid talt det.
Meget udstyr gør ikke. En laboratorieanalyser, en vægt, en sengekantmonitor, et ældre regnskabssystem - hver har tendens til at have sin egen konvention, og konventionerne er alle simple variationer over de samme tre ideer: en afgrænser et sted, en fast rekordlængde eller en længde skrevet foran payloaden.
Mirths TCP-connector dækker dette, og Perfuse havde intet, så et websted med en socket-feed, der ikke var HL7, kunne ikke bruge det overhovedet.
Fejlen, som denne pakke er skrevet for at undgå
At læse fra en strøm og gætte, hvor en meddelelse slutter, er hele problemet. Gæt for kort, og en meddelelse bliver klippet midt over; gæt for langt, og to meddelelser ankommer som en. Begge producerer output, der ofte ser plausibel ud, hvilket er værre end en fejl, så hver tilstand her er eksplicit om, hvad der afslutter en meddelelse, og ingen af dem falder tilbage til en anden.
En meddelelse med ingen ramme overhovedet er en gyldig konfiguration - nogle enheder åbner en forbindelse, sender en meddelelse og lukker - men den kan ikke kombineres med noget andet og kan ikke bruges på en forbindelse, der forbliver åben, så den er navngivet og valideret i stedet for at blive behandlet som en standard.
Source: github.com/biodream-llc/perfuse/internal/framing
26.49 ftpconn
Pakken ftpconn uploader filer over FTP og FTPS ved hjælp af kun standardbiblioteket.
FTP er gammel, snakkesalig og ikke en god protokol. Det er også stadig, hvordan et stort antal hospitalsystemer accepterer filer, normalt fordi den fjerne ende er en laboratorieanalyser eller en byra service, hvis software ikke er blevet berørt, siden det fungerede. At nægte at understøtte det gør ikke systemerne moderne; det gør Perfuse ubrugelig på disse websteder.
Implementeret her i stedet for at blive taget som en afhængighed af samme grund som S3: de otte afhængigheders regnskab er et virkeligt argument med hvem som helst, der gennemgår software, før et hospital installerer det. FTP's kontrolkanal er tekst, der er orienteret mod linjer over TCP, så dette er et par hundred linjer net og crypto/tls.
Hvad der understøttes og hvad der nægtes
Kun passiv tilstand. Aktiv tilstand kræver, at serveren åbner en forbindelse tilbage til klienten, hvilket hver hospital-brandmur bygget i dette århundrede blokerer, og at tilbyde det ville betyde, at folk konfigurerer det og derefter fejlfinder en brandmur.
Eksplicit FTPS (AUTH TLS) understøttes og er standard, når TLS anmodes om. Implicit FTPS på port 990 understøttes også, fordi nogle analysatorer kun taler det.
Almindelig FTP understøttes og advarer. Den sender adgangskoden i klartekst, og et websted, der skal bruge det, skal fortælles det en gang i stedet for at lade dem opdage det fra en pakkeaftryk.
Source: github.com/biodream-llc/perfuse/internal/ftpconn
26.50 gcp
Pakken gcp taler med Google Cloud Pub/Sub og Cloud Storage over deres REST-API'er med Google's OAuth 2.0 gjort her: en servicekonto-nøgle signerer en JWT (RS256, crypto/rsa), der handleres for en adgangstoken, eller, på Google Cloud selv, metadata-serveren uddeler en.
Ingen Google SDK.
Emulatorer (Pub/Sub-emulator, fake-gcs-server) tager ingen legitimationsoplysninger: Angiv Endpoint og lad legitimationsoplysningerne være tomme.
Source: github.com/biodream-llc/perfuse/internal/gcp
26.51 generate
Pakken generate laver syntetiske HL7 v2-meddelelser.
To formål. Nogen, der prøver Perfuse, har brug for trafik at se på, og en kanaltest har brug for en fastsætning, der er realistisk nok til at træne det, der testes. En generator er en betalt udvidelse i Mirth, hvilket fortæller os, at folk ønsker en.
Alt her er opfundet. Navnene kommer fra en fast liste over åbenbart fiktive navne, identifikatorerne er sekventielle inden for en kørsel, og adresserne er opfundne. Det er ikke en disclaimer, det er designet: en generator, der producerer plausibelt udseende rigtige navne, ville til sidst sætte ét i en test-fastsætning, en fejlrapport og derefter et repository.
Realisme anvendes, hvor det er nødvendigt til testformål og ingen andre steder. Tidsstempel indeholder offset, gentagne felter gentager faktisk, et navn har undertiden et melleminitial og undertiden ikke, og omtrent en besked ud af tolv er bevidst besværlig: et manglende valgfrit felt, en usædvanlig men lovlig separator, en tom komponent. At føde en kanal med kun perfekt formede beskeder fortæller dig meget lidt.
Source: github.com/biodream-llc/perfuse/internal/generate
26.52 hl7dict
Pakken hl7dict navngiver felterne i HL7 v2-segmenter.
Dette eksisterer for én skærm: en beskedviser, der kan fortælle dig, at PID-5.1 er patientens efternavn i stedet for at lade dig tælle caret-tegn. Enhver, der har fejlrettet en grænseflade, har gjort den tælling manuelt, og det er den mest almindelige kilde til fejl af typen off-by-one, der placerer en værdi i det forkerte felt.
Det er ikke hele standarden. HL7 v2 har hundredvis af segmenter og tusindvis af felter, og de, der er her, er dem, der optræder i ADT-, ORU-, ORM- og SIU-trafik. Et ukendt felt rapporteres som ukendt i stedet for at gættes.
Source: github.com/biodream-llc/perfuse/internal/hl7dict
26.53 hl7v3
Pakken hl7v3 læser HL7-version 3-beskeder.
Version 3 er en anden ting end version 2 med samme navn. Version 2 er en pipe-adskilt strøm af segmenter, hvis betydning er positionel; version 3 er XML genereret fra en referenceinformationmodel, hvor betydningen medføres af elementnavne og af et lille sæt datatyper, der gentager sig overalt. Kun meget lidt overføres mellem de to ud over den kliniske vokabular.
I praksis ankommer v3 i en af to former. Enten er det et CDA-dokument, der er v3-afledt og håndteres af cda-pakken, eller også er det en IHE-transaktion - PIX og PDQ v3 i særdeleshed, hvilket er, hvordan en stor del af hospitalerne løser patientidentifikatorer på tværs af systemer. Denne pakke sigter mod den sidste.
Hvorfor datatyperne kommer først
Det eneste mest konsekvensfulde ved v3 er, at et element kan være til stede og eksplisit nul, med en angivet årsag. En fødselsdato, der bærer nullFlavor="ASKU", betyder, at patienten blev spurgt og nægtede at svare. En, der bærer nullFlavor="NAV", betyder, at værdien findes, men er ikke tilgængelig lige nu, så at spørge igen senere kan fungere. En, der blot er fraværende, betyder, at ingen optog noget som helst.
At sammenflette dem i en tom streng er fejlen, som denne pakke er arrangeret for at forhindre. Det er ikke en kosmetisk tab: et downstream-system, der modtager en tom fødselsdato, hvor kildeangivelsen sagde "patient nægtede", vil som regel behandle det som manglende data, der skal forfølges, og en demografisk match, der burde være blevet efterladt uløst, bliver løst af en menneskelig gætning. Så hver datatyper her skelner mellem fraværende, nul-med-årsag og til stede.
Source: github.com/biodream-llc/perfuse/internal/hl7v3
26.54 hl7xml
Pakken hl7xml konverterer HL7 v2-beskeder til og fra den XML-form, Mirth Connect bruger, og tilbage til ER7-kodning.
Formen er ikke et designvalg. Mirths scripts er skrevet mod outputtet af dets eget ER7-til-XML-serieliserer, så de indeholder udtryk som
msg['PID']['PID.5']['PID.5.1'].toString()
og løftet om, at en eksisterende script køres uændret, opretholdes kun, hvis træet, det vandrer, har præcis de samme elementnavne, indlejring og gentagningsadfærd. Hver beslutning nedenfor er derfor "hvad gør Mirth", ikke "hvad ville være pænere".
De to, der betyder mest:
Hvert felt er indhyllet i nummererede komponentelementer, selv når feltet kun har én komponent, så PID-5 med værdien "Doe" producerer stadig <PID.5><PID.5.1>Doe</PID.5.1></PID.5>. Scripts indexerer direkte til .1 konstant, og et træ, der placerer teksten på felt-elementet, ville bryde næsten alle af dem.
MSH beholder standard HL7-felt numre, hvor MSH-1 er feltseparator og MSH-9 er beskedtypen. Parseren i internal/hl7 indexerer MSH med en offset, fordi separator besætter en position, ingen delimiter splitter, og denne offset stopper her: et script, der siger MSH.9, betyder beskedtypen.
Source: github.com/biodream-llc/perfuse/internal/hl7xml
26.55 ibmmq
Pakken ibmmq sender til og læser fra IBM MQ-køer via kømanagerens messaging REST-API (mqweb), som IBM MQ 9.1.5 og senere leverer på hver platform, z/OS inklusive.
Den kræver ingen MQ-klientbibliotek: den native MQI-protokol er IBMs og udocumenteret, og REST-API'en er den understøttede måde at nå MQ uden en. (IBM MQ taler også AMQP 1.0 på en AMQP-kanal; Perfuses amqp-connector dækker den rute.)
Læsning sker i hvert fald én gang: den første besked bliver gennemlæst, overdraget til opkaldsprocessen og fjernet efter dens besked-id kun én gang, opkaldsprocessen har behandlet den. En besked, der ikke kunne behandles, bliver på køen, først i rækkefølge.
Source: github.com/biodream-llc/perfuse/internal/ibmmq
26.56 identitet
At finde en besked efter, hvad du ved om den, uanset hvilken format den ankom i.
Den eksisterende indholdssøgning matcher metadata, tilbyder en understrengsmatch mod payload og kan evaluere et filterudtryk - men udtrykket evalueres kun mod HL7 v2, og hvert udtryk kræver kendskab til stien. Således betød fundet af en enkelt patients trafik, at man kendte, at identiteten bor på PID-3 i en HL7 v2-admission, på Patient.identifier i en FHIR-resurs, på (0010,0020) i en DICOM-forekomst og på NM109 af en NM1*IL-løkke i en 837-krav. Fire formater, fire fagtermer, og under en incident kan den søgte besked være i nogen af dem.
Denne pakke mapper et lille sæt begreber - hvem beskeden er om, hvilket besøg, hvilket studie, hvilket krav - til det sted, hvor hver format gemmer dem, så en søgning kan være for "MRN 12345" i stedet for for en sti. Begreberne er bevidst få: disse er de ting, folk faktisk har i hånden, når de skal finde en besked, som er et nummer fra en telefonsamtale eller et navn fra en klage.
Hvorfor ekstraktion sker én gang, på optegningstidspunkt
Alternativet er at parse payload på forespørgselstidspunkt, hvilket er, hvad udtrykssøgningen gør. Det virker, og det er ærligt om at være en begrænset scan, men det kan ikke besvare "hver besked om denne patient på tværs af fire feeds og to måneder" uden at læse hver række. Ekstraktion én gang til en indekseret tabel omdanner det til en indeks-søgning.
Dette er en privatlivs-escalering, og det er valgfrit
Patientnavne og -identifikatorer sidder for øjeblikket inde i en uigennemsigtig payload-kolonne. Indeksering af dem gør dem forespørgelige, hvilket er pointen, og gør dem også opremmelige, hvilket er en reel ændring i eksponering: en database, der kun kunne være greppet, kan nu bedes om "liste alle patienter". Det er en beslutning for webstedet, ikke for denne pakke, så ekstraktion er omstødelig, og hver søgning gennem den bliver optaget i PHI-revisionsloggen.
Source: github.com/biodream-llc/perfuse/internal/identity
26.57 iis
Pakken iis taler transporten, som hver US-immunisationsregister deler: CDC's IIS SOAP-webtjeneste.
I 2011 valgte en ekspertpane, der var indkaldt af CDC og American Immunization Registry Association, én SOAP-grænseflade til at sende HL7 v2-beskeder til Immunization Information Systems, og registrene antog den. WSDL'en er lille - to operationer, connectivityTest og submitSingleMessage - og HL7-besked (en VXU for at rapportere et skud, en QBP^Q11 for at bede om en patients historik) rejser som escaped tekst inde i SOAP-kroppen. Svaret kommer tilbage på samme måde: en ACK eller en RSP^K11, der bærer historikken og prognosen.
Den generiske SOAP-destination kunne være konfigureret til at gøre dette, men hvert websted skulle taste den samme konvolut, få navneområdet ret, sætte legitimationsoplysningerne i kroppen i stedet for i HTTP-godkendelse og derefter læse HL7-bekræftelsen ud af svaret for at lære, om registret beholdt optegnelsen. En registry svarer på et afvist skud med HTTP 200 og en AR; at behandle 200 som succes er, hvordan immuniseringer stille og roligt ikke bliver rapporteret. Så denne pakke gør CDC-konvolutten og dømmer bekræftelsen én gang.
Hvad den ikke gør: WSDL's brugernavn og adgangskode er registrets program-credentials og sendes, som WSDL siger, i kroppen. Gensidig TLS, hvor en registry kræver det, er destinationens TLS-indstilling, som for enhver HTTPS-opkald. Intet her er specifikt for én stat; hvor staterne adskiller sig (facilitets-ID kræves eller ej, SOAP 1.1 accepteres eller ej, advarsler sendes som AE), siger destinationens indstillinger, at det er sådan.
Source: github.com/biodream-llc/perfuse/internal/iis
26.58 kafka
Kafka, som en klient i stedet for noget, der skal erstatte.
Et sundhedssystem, der har en begivenhedsryg, har en Kafka-ryg, og systemerne, der er bygget i det sidste årti, offentliggør på den i stedet for på en JMS-mægler. Så denne connector findes for at gøre Perfuse til den sundhedsbevidste kant af nogen andens begivenhedsplatform: den læser kliniske beskeder af emner og offentliggør dem på emner, og den gør bevidst ikke forsøg på at være en streaming-platform. Vinduer, joins, stream-processing og skema-registre er Kafkas økosystem og bliver der.
Hvorfor en afhængighed, når STOMP og MLLP blev skrevet med hånd
Den fastsatte regel i dette repository er, at en afhængighed skal købe kapacitet i stedet for bekvemmelighed, og skal være ren Go, så én statisk binær-fil stadig kan kompilere til hver mål. franz-go er ren Go og bærer ingen cgo, hvilket blev kontrolleret mod alle seks mål.
Kafkas protokol er ikke STOMP's. STOMP er en tekstprotokol, der passer i nogle få hundrede linjer. Kafka er en versioneret binærprotokol på omtrent syv ti anmodningstyper, og den del, der betyder mest her - forbrugergrupper - er en distribueret koordinationsprotokol med join, sync, heartbeat og offset-commit-faser og en rebalancedans mellem dem. At få det subtilt forkert producerer ikke en åbenlys fejl: det producerer en partition, som ingen læser, eller to forbrugere, der læser den samme. I en klinisk feed er det en manglende laboratorie-resultat og en duplikeret ordre. Det er kapacitet, og det er ikke værd at hånd-rulle for at spare en afhængighed.
Source: github.com/biodream-llc/perfuse/internal/kafka
26.59 ldap
Pakken ldap taler nok LDAP til at godkende en person og læse deres grupper.
Hospitaler kører næsten universelt Active Directory, og AD taler LDAP. OpenID Connect er det bedre svar, hvor det er tilgængeligt - se internal/oidc, og noten der om, at Mirth ikke har single sign-on til nogen pris - men en integrationsmotor sidder ofte på en isoleret VLAN, hvor en browser ikke kan nå en identitetsudbyder overhovedet. Det er derfor, denne funktion findes.
Selvlaget BER i stedet for en afhængighed, af samme grund som DICOM og STOMP: kodningen er lille, og hvad der ankommer på denne socket afgør, om nogen kommer ind i et system, der flytter patientdata.
encoding/asn1 i standardbiblioteket er ikke brugbar her. Det sigter mod DER og afviser kontekstspecifikke tags og implicit tagging, som LDAP bruger overalt, så de dele, der betyder noget, ville alligevel kræve selvlagning.
Source: github.com/biodream-llc/perfuse/internal/ldap
26.60 postkasse
Pakken postkasse læser e-mail fra IMAP4rev1 (RFC 3501) og POP3 (RFC 1939) servere, logger ind med en adgangskode eller med OAuth 2.0 (SASL XOAUTH2, som Microsoft 365 og Gmail kræver), og tager beskeder fra hinanden (RFC 5322 og MIME), så en vedhæftning eller tekstkorpus kan blive en besked på en kanal.
Kun det, en indgående feed har brug for: Vælg en postkasse, find ulæste breve, hent dem hele, og flyt, markér eller slet dem. Standardbibliotek kun; TLS er crypto/tls.
Source: github.com/biodream-llc/perfuse/internal/mailbox
26.61 kortlægger
Pakken kortlægger foreslår felttilknytninger mellem systemer med tillidsværdighedsscore.
Dette er en regelbaseret intelligent tilknytningsmotor. Ingen LLM, ingen netværksopkald, ingen eksterne afhængigheder. Den kører offline i samme binær fil og sender aldrig patientdata et sted hen.
Motoren kombinerer flere signaler - fuzzy strengmatchning på feltnavne, sundhedsidentifikator-mønstergenkendelse, kode-systemsøgninger og historisk acceptancedata - til en enkelt tillidsværdighedsscore per forslag. Når tillidsværdigheden er under en konfigurerbar grænse, afstår kortlæggeren fra at gætte forkert, fordi en forkert tilknytning i sundhedssektoren kan sende data til det forkerte felt, og det er en patient-sikkerhedsfejl.
Afståelse er den centrale designbeslutning. Et system, der altid producerer et svar, træner brugere til at stoppe med at kontrollere, og den ene gang det er forkert, lægger ingen mærke til det, før en laboratorie-resultat lander i en noteringsfelt. Et system, der siger "Jeg ved ikke", tvinger en menneskelig beslutning præcis, når mennesket er nødvendigt.
Source: github.com/biodream-llc/perfuse/internal/mapper
26.62 måling
Pakken måling vurderer FHIR Målinger (digitale kvalitetsmålinger), hvis populationskriterier er FHIRPath, og skriver resultatet som en FHIR Målingsrapport: sammenfatning, enkelt eller subjektliste, med stratifikatorer og en proportionscore.
Hver kriterie vurderes én gang per patient, med fokus på en samling af patientens journal (deres afdeling) og disse variabler: %subjekt (patienten), %periodeStart og %periodeSlut (målingsperioden, som DateTimes) og %"Målingsperiode" (samme som en periode). Kriterier i CQL afvises med årsagen: Perfuse har ingen CQL-motor.
Source: github.com/biodream-llc/perfuse/internal/measure
26.63 metrik
Pakken metrik indsamler, hvad motoren laver, og gemmer nok historik til at tegne det.
En integrationsmotor overvåges, ikke kun køres. Når en afdeling siger, at resultaterne stoppede med at ankomme for tyve minutter siden, er spørgsmålet, hvad der ændrede sig for tyve minutter siden, og det kan ikke besvares af nuværende tellere alene. Så denne gemmer serier i stedet for totaler, i hukommelse, med en fast opløsning.
Tre beslutninger former det.
Ventetid gemmes som et histogram i stedet for en gennemsnit. En gennemsnitlig leveringstid er næsten værdiløs i denne domæne: det tal, der betyder noget, er, om de langsommeste få procent af beskederne er langsomme nok til at krænke en omsvøbningstidsforpligtelse, og en gennemsnit skjuler præcis det. Buketter er eksponentielle og faste ved byggetid, så optagelse af en varighed er en sammenligning og en forøgelse uden allokering.
Serier er begrænsede ringbuffere, størrelse ved oprettelse af samleren. Intet her vokser uden begrænsning, fordi en integrationsmotor kører i måneder ad gangen, og et metriksystem, der kræver genstart, er værre end intet.
Kardinalitet er kapslet. En mærkeværdi taget fra beskeddata - en afsendende ansøger, for eksempel - kan tage tusinder af værdier, hvis nogen miskonfigurerer en feed, og ubegrænsede mærker er den standardmåde, overvågning tager ned det, der overvåges. Forbi kapslen kollapser værdierne til en "anden"-bucket, og kapslen rapporteres selv.
Source: github.com/biodream-llc/perfuse/internal/metrics
26.64 mirth
Java-analyse for importeret Mirth-kanaler.
Hvorfor denne findes
Mirth kører Rhino på JVM, så en Mirth-script kan kalde enhver Java på classpath, herunder Mirths egne serverklasser. Perfuse kører goja og har ingen Java-runtime. Den afviser disse kald med en fejl, der navngiver klassen - men den afvisning sker, når scriptet kører, hvilket for en kilde-connector betyder, når den første rigtige besked ankommer.
Så en migration plejede at gå: importen lykkes stille, kanalen deployes, og den første besked fra ledningen fejler. En migration, der ser ren ud, men fejler ved første trafik, er værre end en, der afviser ved døren, fordi personen, der gjorde det, allerede har fortalt sine kolleger, at det virkede.
Dette finder disse opkald ved importtidspunktet og siger, hvad der skal gøres med hvert af dem.
Hvorfor fire udtalelser og ikke to
"Bruger Java" er en bid information og den forkerte, fordi Java'en, en rigtig Mirth-kanal bruger, falder i grupper med helt forskellige mængder arbejde knyttet. Omtrent halvdelen af, hvad stederne faktisk skriver, er SimpleDateFormat og HashMap, som JavaScript gør naturligt. Noget af det er Mirth's dokumenterede script-API, som Perfuse allerede implementerer under de samme navne. En lille del af det vil starte og stoppe kanaler, som Perfuse kan gøre over sin REST-API, men ikke eksponerer til scripts. Og noget af det er en vendor-jar, der aldrig vil køre her.
At rapportere disse som ét tal fortæller en migrator intet om, hvorvidt deres eftermiddag eller deres kvartal er på spil.
Source: github.com/biodream-llc/perfuse/internal/mirth
26.65 mirthlive
Pakken mirthlive finder de kørende Mirth-familie-motorer, som interoperabilitets-testerne taler til.
Mirth Connect ophørte med at være open source ved 4.6 (marts 2025). Stederne, der forlader det, går til en af tre steder: Mirth 4.5.2, den sidste open release, som de holder kørende; Open Integration Engine, den Eclipse-værtsfork; eller BridgeLink, Innovars fork, som nummererer sine udgaver efter år (26.9.0). En kanal Perfuse eksporterer skal kunne indlæses i alle disse, og en kanal, som nogen af dem eksporterer, skal importeres her, så hver live-test køres én gang per motor, der svarer.
Motorerne findes ved at spørge, ikke konfigureres: ./scripts/interop-up.sh starter dem på faste porte, og en motor, der ikke kører, rapporteres som oversprunget i stedet for at gå stille med.
Kun tests importerer dette. Det lever uden for en _test.go-fil, fordi to pakker deler det.
Source: github.com/biodream-llc/perfuse/internal/mirth/mirthlive
26.66 mpi
Pakken mpi er en master patient indeks: den tager patientoptegnelser fra hvert kilde-system (hvert identificeret ved sin tildelende myndighed og nummer), beslutter, hvilke tilhører den samme person, og giver hver person en virksomheds-identifikator (EUID).
Visse matches linker på egen hånd; usikre venter i en gennemgangskø for en person til at beslutte; hver linking, unlinking, sammenlægning og beslutning registreres med, hvem der gjorde det.
Matching er deterministisk først (en identifikator fra et system, stedet stoler på at være unikt per person, såsom en national identifikator eller en virksomhedsnummer) og probabilistisk ellers: Fellegi-Sunter-vægte over navn, fødselsdato, køn, postnummer, telefon og adresse, med Jaro-Winkler til navne. Det beslutter intet klinisk: det siger, hvilke optegnelser er den samme person, med dets grunde, til en person til at bekræfte, når det ikke er sikker.
Source: github.com/biodream-llc/perfuse/internal/mpi
26.67 mqtt
Pakken mqtt er en MQTT 3.1.1-klient: connect (med TLS, en brugernavn og adgangskode eller en klientcertifikat), publicer på QoS 0 eller 1, abonner, og anerkend hver modtaget QoS 1-meddelelse kun én gang, kalderen siger, det var behandlet.
Skrevet mod OASIS MQTT 3.1.1-standarden i stedet for importeret, som Perfuse's andre wire-protokoller er. 3.1.1 er versionen, hver broker taler: Mosquitto, EMQX, HiveMQ, VerneMQ, RabbitMQ's MQTT-plugin, IBM MQ's telemetrikanal, AWS IoT Core og Azure Event Grid.
Levering: en meddelelse, der modtages på QoS 1, anerkendes (PUBACK) kun, når Ack kalder. En kalder, der ikke kan håndtere en meddelelse, lukker forbindelsen i stedet; med en varig session (CleanSession false) sender brokeren den igen, markeret som en duplikat, når klienten genopretter forbindelsen. MQTT 3.1.1 har ingen negativ anerkendelse, så dette er den eneste måde at bede om en meddelelse igen.
Source: github.com/biodream-llc/perfuse/internal/mqtt
26.68 msgstore
At finde en gemt meddelelse efter, hvad nogen ved om den.
Søgningen, en person faktisk har brug for, er "her er et nummer fra en telefonsamtale, vis mig hver meddelelse om det". Før dette betød det enten en understrengsmatch over payload, som er grep og langsom, eller et filterudtryk, som kræver at vide, at identitet lever på PID-3 i HL7 v2 og et andet sted helt i de andre fire formater på samme server.
Identitet udtrækkes én gang, når meddelelsen optages, og indekseres, så dette er en opslag i stedet for en scan. Omkostningerne betales på optagelsesstien, én gang per meddelelse, i stedet for på hver søgning.
Source: github.com/biodream-llc/perfuse/internal/msgstore
26.69 natid
Pakken natid kender de nationale patient- og person-identifikatorer i Storbritannien og Europa: deres formater, deres kontrolléciffer, identifikatorsystemet, hver lands FHIR-retningslinjer navngiver dem efter, og hvor meget af én, der må vises.
Det eksisterer til patientindekset. En national nummer er den stærkeste bevis for, at to optegnelser er én person, og også det letteste at gøre forkert: en ciffer, der taster to gange, giver et nummer, der tilhører en anden person, og en kilde sender NHS-nummeret under et OID, mens en anden sender det under dets FHIR-URL. Så hver identifikator, indekset gemmer, går gennem her: dets kontrolléciffer testes (en forkert én bruges aldrig til at linke), dets mellemrum fjernes, og dets system skrives på én måde.
Hvad der verificeres og hvad der ikke er, siges per skema. Algoritmerne er offentlige; identifikatorsystem-URI'er er landets egne, hvor en national FHIR-retningslinje navngiver én (SystemVerified), og en dokumenteret standard ellers, som et sted kan ændre til dets nationale værdi under Indstillinger → Patientindeks. Intet her beslutter noget klinisk.
Source: github.com/biodream-llc/perfuse/internal/natid
26.70 ncpdp
Skriver et felt i en NCPDP-overførsel.
Hvorfor et skrive afviser en tvetydig sti
Læs returnerer hver værdi en sti adresserer, fordi et filter, der spørger, om der er nogen DUR-konflikt, der er en terapeutisk duplikation, skal se alle dem. Et skrive kan ikke fungere på den måde. Hvis D7 adresserer produktkoderne for to krav i én overførsel, har indstilling af D7 ingen enkelt betydning: skrivning af begge ville ændre et lægemiddel, som ingen har bedt om, og skrivning af den første ville stille og roligt lade den anden være.
Så et skrive afviser en sti, der adresserer mere end ét felt, og fejlen navngiver den kvalificerede form, der ville være entydig. Dette er den samme begrundelse, der giver transformationstrinnene ingen fjernaktion: hvor det ærlige svar er, at konfigurationen er tvetydig, siger det samme slås fast, at det er bedre end at vælge ét.
Source: github.com/biodream-llc/perfuse/internal/ncpdp
26.71 oidc
Pakken oidc verificerer OpenID Connect-identiteter.
Skrevet mod standardbiblioteket i stedet for en JWT-afhængighed. Autentificering er det eneste sted, hvor en unauditeret afhængighed er mindst acceptabel, og signaturverificering for de algoritmer, der er vigtige, er omkring hundred linjer af crypto/rsa og crypto/ecdsa, og Perfuse bærer allerede nok, så tilføjelse af mere kræver en grund og ikke en vane.
Omfanget er bevidst snævert: verificere, at en identitetsudbyder har garanteret for en person, og rapportere, hvad den sagde om dem. Alt andet - hvad de må gøre, hvor lang tid sessionen varer - bliver hos Perfuse, fordi en identitetsudbyder ved, hvem nogen er, og ikke, hvad de har lov til at gøre i en grænseflade-motor.
Source: github.com/biodream-llc/perfuse/internal/oidc
26.72 parity
Pakken parity sammenligner, hvad Perfuse producerer, med hvad motoren, der erstattes, producerede.
Hvorfor denne findes
Perfuse kan importere en Mirth-kanal og kan spore, hvad den ville gøre med en besked. Ingen af delene besvarer spørgsmålet, nogen faktisk har, før de flytter en live-feed, som er: vil dette producere samme output som det, der har kørt i seks år?
Ingen mængde designkvalitet besvarer det. Det eneste ærlige svar er beviser, og beviserne må komme fra den gamle motors egen output på webstedets egen trafik.
Hvorfor parrene skal leveres
Dette kan ikke nå ind i Mirth, og at prætende, at det kan, ville være den værste form for funktion. Det, det kræver, er par: en besked, som den ankom, og beskeden den gamle motor producerede fra den. Begge er i Mirths egen beskedlager og kan eksporteres fra dens beskedbrowser, som er en ting, en administrator allerede ved, hvordan man gør.
Denne begrænsning er angivet i stedet for skjult. Et værktøj, der påstår at verificere en migration uden nogensinde at se den gamle motors output, ville verificere ingenting.
Hvorfor forskelle er grupperet i stedet for listet
En kørsel over 50.000 beskeder, der rapporterer 4.000 forskelle, har fortalt nogen intet, de kan handle på. Den samme kørsel, der rapporterer, at PID-8 forskellige i hver besked, fordi den gamle motor kortlagde M til Mand, har fortalt dem præcis én ting at beslutte om.
Så resultaterne er grupperet efter felt, med en tæller, et eksempel og de distinkte værdipar, der ses. Én beslutning per resultat er den enhed, nogen kan arbejde igennem.
Source: github.com/biodream-llc/perfuse/internal/parity
26.73 pas278
Pakken pas278 kortlægger mellem Da Vinci prior- autorisation og X12 278-transaktionen.
Hvorfor denne findes
CMS-0057-F kræver, at betalere eksponerer en FHIR prior-autorisations-API fra 1. januar 2027. Det erstatter ikke X12 278, og det var aldrig meningen: en betalers udnyttelsesstyringssystem beslutter autorisationer og taler 278. Så en betaler, der opfylder reglen, oversætter FHIR til 278 og tilbage, og en udbyder, der sender 278 i dag, vil sende FHIR i morgen til de samme betalere, der stadig accepterer begge.
Den oversættelse er det, der er værd at eje. En motor, der holder begge modeller og ikke kan konvertere mellem dem, efterlader den hårdaste del af arbejdet - og den del, hvor fejlene er dyre - til den, der integrerer den.
Reglerne, denne pakke følger, angivet i stedet for antydet
Skrevet ned af samme grund, v2fhir skriver sin egen ned: kortlægning er, hvor interoperabilitetsprojekter fejler, og fejlene er stille.
- En beslutning opgraderes aldrig. Delvis certificering bliver ikke til godkendelse, og en anmodning, som betaleren afslog at overveje, bliver ikke til en afvisning. Begge af disse sammenfald er tilgængelige i den åbenlyse kortlægning, og begge er forkerte i den retning, der koster nogen uger: en appel indgivet mod en beslutning, som ingen har truffet, eller seks sessioner booket mod tre godkendte. - Intet opfindes for at udfylde et påkrævet felt. Hvor målformatet kræver noget, kildeformatet ikke bærer, rapporterer kortlægningen det som en note i stedet for at levere en plausibel standard. En fabrikeret autorisationsnummer er værre end et fraværende. - Hver dom bliver rapporteret. Noter kommer tilbage med resultatet, så en person kan læse den håndfuld, der krævede en beslutning, i stedet for hele output. - Rundture testes, ikke antages. En kortlægning, der mister et felt i én retning, findes ved at konvertere tilbage og sammenligne, som er den eneste måde at se et felt, som ingen tænkte på at påstå på.
Source: github.com/biodream-llc/perfuse/internal/pas278
26.74 pdf
Pakken pdf skriver simple tekstdokumenter, ved hjælp af kun standardbiblioteket.
Mirths Document Writer rendererer HTML til PDF, hvilket kræver en layout-motor. Det er ikke det, dette er. Dette producerer et enkelt, pagineret tekstdokument med et fastspacet font og eksisterer, fordi det faktiske krav på næsten alle steder, der bruger denne connector, er "sæt dette rapport på en deling, så nogen kan udskrive det" - en udskrivningssummarisk, en resultatråport, en daglig afrapportering. Disse er tekst.
At afvise funktionen helt ville efterlade en Tier 2-migrationsblokeringsplads. At trække en HTML-renderingsmotor ind ville koste mere end resten af binærfilen og bringe en CVE-strøm med sig, hvilket ville omgøre argumentet for billedmaterialet. Så: tekst, ærligt beskrevet som tekst, og et sted, der virkelig har brug for typesat udgang, er bedst tjent med en fildestination og et værktøj bygget til det.
Hvorfor skrive en PDF overhovedet i stedet for en tekstfil
Fordi modtagende ende normalt er en person med en printer og en Windows-deling, og en .txt-fil, der udskrives fra en deling, mister sin paginering, margener og ofte sin linjeafslutning. En PDF udskrives det samme overalt, hvilket er den eneste grund til, at nogen nogensinde har bedt om en.
Source: github.com/biodream-llc/perfuse/internal/pdf
26.75 pgp
Pakken pgp krypterer, signerer, dekrypterer og verificerer OpenPGP-besked (RFC 9580 og RFC 4880 til ældre peers), til betalere, clearinghouses og statlige myndigheder, der udveksler filer over SFTP eller e-mail under PGP.
Kryptografien er github.com/ProtonMail/go-crypto, den vedligeholdte fork af golang.org/x/crypto/openpgp; intet her implementerer en primitiv. Denne pakke loader kun nøgler og beslutter, hvad en besked skal medføre.
Source: github.com/biodream-llc/perfuse/internal/pgp
26.76 pixv3
Pakken pixv3 er HL7-version 3-ansigtet af patientindekset: IHE Patient Identifier Cross-referencing og Patient Demographics Query-profilerne, som de fleste hospitaler uden for FHIR-verdenen stadig kommunikerer med.
- ITI-44, Patient Identity Feed HL7 V3: En kilde tilføjer en patient (PRPA_IN201301UV02), reviderer en (PRPA_IN201302UV02) eller siger, at to poster er den samme person (PRPA_IN201304UV02). Besvaret med MCCI_IN000002UV01. - ITI-45, PIXV3 Query: De andre identifikatorer for personen, der ejer en (PRPA_IN201309UV02 -> PRPA_IN201310UV02). - ITI-47, PDQV3 Query: Personerne, der matcher nogle demografiske data (PRPA_IN201305UV02 -> PRPA_IN201306UV02), med fortsættelse (QUQI_IN000003UV01) og annullering (QUQI_IN000003UV01_Cancel).
Svarene kommer fra det samme patientindeks som PIXm, PDQm, Patient/$match og indeksskærmen, så en post, der er fødet ind i v3, kan findes over FHIR og omvendt. Beskederne er skrevet hånd i hand, i skemaorden, på grund af, at hl7v3.Ack giver.
Source: github.com/biodream-llc/perfuse/internal/pixv3
26.77 priorauth
Pakken priorauth implementerer provider-side prior autorisationsarbejdsgangen, som kræves af CMS-0057. Den sender prior autorisationsanmodninger til betalers FHIR-API'er, sporer svar og konverterer mellem interne typer og FHIR-resourcer.
Source: github.com/biodream-llc/perfuse/internal/priorauth
26.78 privacy
Pakken privacy besvarer en datasubjekts anmodninger under GDPR og UK GDPR: find alt, hvad denne server har om en person, giv det til dem (Artikler 15 og 20), slet det (Artikel 17), og behold, hvad en juridisk hold dækker.
Den når hver sted, hvor Perfuse gemmer patientdata: beskedlagret (gennem dens identitetsindeks), leveringskøen, FHIR-lagret (personens Patient-resourcer og alt, der henviser til dem, med deres historik), gemte prior autorisationsanmodninger og patientindekset, hvis links udvider en identifikator til alle personens numre. Hvad den ikke kan nå, navngiver den: spor, der sendes til en samler, auditloggen (som opbevares, som optegnelsen over, hvem gjorde hvad), og sikkerhedskopier, der opbevarer, hvad der er slettet, indtil de udløber - så hver sletning skrives til en regnskabsbog, som saltede hashes af identifikatorerne i stedet for identifikatorerne, og kan anvendes igen på en genskabt kopi.
Den beslutter intet på nogen persons vegne. Om en anmodning skal godkendes, og om en undtagelse gælder, er kontrollørens beslutning; sletning kræver en anden administrators godkendelse, og en juridisk hold afviser det direkte.
Source: github.com/biodream-llc/perfuse/internal/privacy
26.79 publichealth
Pakken publichealth implementerer tovejs offentlig sundhedsrapportering: elektronisk sagrapportering (eCR), elektronisk laboratorierapportering (ELR) og immunisationsregisterforespørgsler.
Hvert hospital er lovpligtigt til at rapportere visse tilstande - tuberkulose, mæslinger, hepatitis, COVID-19, kønssygdomme, fødevarebåren sygdom - til statlige og lokale sundhedsmyndigheder. Rapporteringen sker gennem tre forskellige grænseflader:
- ELR: HL7 2.5.1 ORU^R01-besked med laboratorieresultater til offentlige sundhedsmyndigheder (elr.go). - eCR: FHIR-baseret elektronisk initial sagrapport (eICR), når en rapporterbar tilstand er diagnosticeret. - Immunisationsregister: VXU^V04 til at rapportere vacciner, der er administreret, og VXQ^V01 til at forespørge en patients vaccinationshistorik.
Pakken er tovejs: den rapporterer udad (ELR, eCR, VXU) og forespørger tilbage (VXQ/VXR). Alle operationer er i realtid i stedet for natlige batch.
Trådsikkerhed: SubmissionLog er sikker for samtidig brug. Byggefunktionerne er rene og sikre at kalde fra en hvilken som helst goroutine.
Source: github.com/biodream-llc/perfuse/internal/publichealth
26.80 published
Pakken published indeholder vagterne for Perfuses importable pakker, på ét sted.
hl7 var den første pakke, der blev publiceret, og medfører sin egen kopi af disse kontroller. fhir og pas blev publiceret, så en beslutningstjeneste som Vaglio læser FHIR- og PAS-anmodninger med nøjagtig den kode, Perfuse bruger, i stedet for en kopi, der glider: fire læsere af X12-handlingskoderne i dette repository var enige, og en læste en afvisning som en godkendelse. Vagterne opbevares her i stedet for at kopieres ind i hver pakke, af samme grund.
Source: github.com/biodream-llc/perfuse/internal/published
26.81 kø
Pakken queue er en holdbar, per-destination leveringskø
Uden det, mister en destination, der er nede i to minutter, alt, der sendes under de to minutter: gentagne forsøg sker i hukommelsen, og når de løber ud, bliver meddelelsen optaget som fejlet og væk. Med det er meddelelsen på disk og beholder sin plads, indtil destinationen kommer tilbage.
To designbeslutninger former alt andet.
Rækkefølgen bevares per destination, og det betyder, at en køet destination stopper med at tage den hurtige vej. HL7 er en strøm af begivenheder om de samme patienter: en A01 indlægger, en A03 udskriver. Hvis en fejlet A01 går til køen, mens den næste A03 leveres direkte, ser det modtagende system en udskrivning for en patient, som det aldrig har indlagt. Så når noget er køet for en destination, køer alt for den destination bag det, indtil køen tømmes. Det koster gennemstrømning under et udfald, og det er ikke valgfrit, fordi alternativet er stille klinisk nonsens. Det er også det specifikke, der går galt i andre motorer, når nogen aktiverer samtidige køtråde for at få en tilbagestående kø til at dræne hurtigere.
En køet meddelelse er en accepteret meddelelse. Afsenderen bliver fortalt AA, fordi byte er på disk og fsyncet, før bekræftelsen sendes ud. At sige AE ville gøre en korrekt fungerende kø til en fejl og invitere afsenderen til at gensende, hvad vi allerede har.
Source: github.com/biodream-llc/perfuse/internal/queue
26.82 residens
Pakke-residens siger, hvor denne servers data må gå: skyregionerne, som en side tillader (EEA, UK, Schweiz eller regioner navngivet én for én), og om en connectors region er en af dem.
Perfuse checker, hvad den kan vide. En AWS-connector navngiver sin region (S3, SQS, SNS), og en AWS-vært navngiver en (sqs.eu-west-2.amazonaws.com); disse checker, når en kanal gemmes og indlæses, så en kanal ikke kan sende patientdata til en bucket i Virginia fra en server, hvis data skal blive i Frankfurt. En almindelig vært (et hospitals eget system, en partners MLLP-lytter) siger intet om, hvor den er, og bliver ikke bedømt her: behandlingsposten lister hver vært, som en kanal sender til, til kontrollen til at checke.
Source: github.com/biodream-llc/perfuse/internal/residency
26.83 rtpb
Pakke rtpb besvarer NCPDP Real-Time Prescription Benefit-anmodninger fra en formular: hvad et lægemiddel vil koste denne medlem på denne apotek, om det kræver en forhåndsgodkendelse eller et trin først, og hvilke alternativer koster mindre.
CMS-0062-P foreslår RTPB for berørte betalere fra 1. oktober 2027. XML'en er NCPDP RTPB v13 (PBv13). NCPDP's skema er licenseret, så elementnavne og rækkefølge følger de offentlige Surescripts RTPB-eksempler og NCPDP's offentlige RTPB-Implementeringsanbefalinger (dækning begrænsningskoder og den dækning status, hver af dem kortlægger til); en respons bliver ikke checket mod XSD her, og en netværkscertificering er, hvor det sker.
Source: github.com/biodream-llc/perfuse/internal/rtpb
26.84 s3put
Pakke s3put skriver objekter til S3 ved hjælp af kun standardbiblioteket.
Den åbenlyse måde at tale til S3 er AWS SDK, og SDK'et er enormt. Dette projekt sælger en statisk binær fil med otte direkte afhængigheder og en vareliste, der kan være på én skærm - det er et rigtigt argument med den person, der gennemgår software, før et hospital installerer det, og at handle det væk for en enkelt connector ville være en dårlig handel.
Hvad S3 faktisk behøver, er en HTTP-PUT og en signatur. Signaturversion 4 er fuldt specificeret, det er deterministisk, og AWS offentliggør testvektorer for det. Så det er implementeret her: omkring to hundrede linjer mod crypto/hmac og net/http, med ingen nye afhængigheder og intet at rette, når SDK'et har en vejledning.
Hvad dette bevidst ikke gør
Ingen multipart-upload, ingen gentagne forsøg af sig selv, ingen kredenskæde ud over statiske nøgler og standardmiljøvariable. En HL7-meddelelse er kilobytes, så multipart løser et problem, som dette ikke har; motoren gentager allerede; og en instans-rolle-kredenskæde ville betyde IMDS-opkald, caching og opfriskningslogik, som er, hvor en lille implementering stopper med at være lille. Hvis nogen har brug for det, er den ærlige besked en fildestination og et synkroniseringsværktøj, ikke en halvfærdig SDK.
Det fungerer med alt, der taler S3-API'en - MinIO, Ceph, Wasabi, Backblaze - fordi det er bare signeret HTTP. Det er en sideeffekt, der er værd at have, da et hospitalsobjektgemme ofte ikke er AWS.
Source: github.com/biodream-llc/perfuse/internal/s3put
26.85 saml
Exklusiv XML-Kanalisering (exc-c14n) per https://www.w3.org/TR/xml-exc-c14n/
Dette er den byte-exakte kanoniske form, som en XML-signatur signerer. At få det forkert betyder, at gyldige signaturer ser ugyldige ud, og - værre - en implementering, der får det mest ret, vil gå igennem i test mod sine egne signaturer, mens den afviser rigtige IdP-svar.
Reglerne, der betyder noget for SAML: - Navnerumserklæringer renderes kun, hvis de er synligt anvendt af elementet eller dets attributter. - Arvede navnerum, som et element bruger, men ikke erklærer, renderes, som om de var erklæret på det element. - Attributter sorteres: navnerumserklæringer først (sorteret efter præfiks), derefter andre attributter (sorteret efter udvidet navn: navnerum-URI derefter lokale navn). - Tomme elementer bruger start-tag/slut-tag, aldrig selv-lukkende. - Tekstnoder udskrives uændret; CDATA erstattes af dens indhold med enhed-escapning. - Behandlingsinstruktioner og kommentarer uden for dokumentelementet udelades.
Source: github.com/biodream-llc/perfuse/internal/saml
26.86 scim
Pakke scim implementerer SCIM 2.0, det protocol, som identitetsudbydere bruger til at klargøre konti.
Okta, Entra ID, Google Workspace og OneLogin taler alle dette sprog. En administrator tilføjer en person til en gruppe i identitetsudbyderen, og inden for et minut dukker en konto op her med den rigtige rolle. De fjerner dem, og kontoen forsvinder.
Deprovisioning er det afgørende punkt
Provisioning er en bekvemmelighed. Deprovisioning er årsagen til, at dette er værd at bygge, og det er den halvdel, der går galt.
Når en person forlader en organisation, er identitetsudbyderen det system, der først får besked - som regel fordi HR afslutter dem, og udbyderen drives fra HR-registreringen. Derefter meddeler det alle tilknyttede applikationer at deaktivere kontoen. Hvis dette opkald fejler eller lykkes uden at fjerne adgangen, beholder en tidligere ansat adgang til en klinisk integrationsmotor, og ingen opdager det, fordi der ikke er noget, der overvåger en begivenhed, der ikke sker.
Så de dele af denne pakke, der betyder mest, er dem, der gør deprovisioning til virkelighed:
- At sætte active til false afslutter alle sessioner med det samme, ikke ved næste udløb. En browserfane, der er åben på en bærbar computer, der er taget hjem af en afsluttet ansat, må ophøre med at fungere, og en session, der overlever, indtil den udløber, er en session, der overlever fyringen. - Et fejl er et fejl. SCIM har ingen gentagningssemantik, som en applikation kan stole på, så returnering af 200 for noget, der ikke sker, betyder, at identitetsudbyderen optegner deprovisioning som fuldført og aldrig prøver igen. - Sletning af en bruger behandles på samme måde som deaktivering: adgangen ophører. Audit-historikken bibeholdes uanset, fordi en post, der navngiver en person, der ikke længere eksisterer, er værre end en, der er markeret som trukket tilbage.
Hvorfor det er en separat pakke
SCIM's former er ikke Perfuse's. Den har sin egen fejlformat, sin egen listeomslag, sit eget patchsprog og sine egne holdninger til attributskapitalisering. At holde oversættelsen på ét sted betyder, at håndtererne kan omhandle, hvad der sker med en konto, snarere end om JSON.
Source: github.com/biodream-llc/perfuse/internal/scim
26.87 script
Pakke-script kører Mirth Connect JavaScript.
Målet er, at en kanals script flyttes over uden berøring. Det er en kompatibilitetsøvelse, ikke en designøvelse, så formen på alt her er dikteret af, hvad Mirth eksponerer: msg og tmp som E4X-træer, seks kort med Java's Map-metoder, $-familien af opslagfunktioner, logger og en håndfuld hjælpeobjekter, hvis metodenavne og datoformateringsstreng er Java's.
Tre beslutninger er vores snarere end Mirth's, og hver er en bevidst afvigelse:
Et script kører med en deadline og afbrydes, når det passerer. Mirth vil lade et script løbe i uendelighed, hvilket tager kanalen med; et interface, der stopper med at acceptere optagelser på grund af en fejl i en transformer, er ikke acceptabelt, så der er altid en timeout.
Java-sammenhæng refuses med en fejl, der navngiver klassen, snarere end at returnere undefined. Et script, der rækker ind i Packages.java.sql, kan ikke gøres at arbejde her, og det nyttige resultat er en besked, der siger præcis det på den linje, hvor det sker, ikke en NullPointerException tre linjer senere.
Filen og databaseadgang er af, medmindre en kanal aktiverer dem. Mirth giver begge til hvert script som standard. En transformer, der kan læse enhver fil, processen kan læse, er en rimelig ting at ønske og en urimelig standard.
Source: github.com/biodream-llc/perfuse/internal/script
26.88 indstillinger
Pakke-indstillinger er den enkelte beskrivelse af alt om en Perfuse-server, som en operatør kan ændre.
Hvorfor denne findes
Før denne pakke var der omtrent tredive ting, der var kommandolinjeflag og intet andet. At ændre, hvor længe beskeder blev gemt, betød at redigere en service-definition og genstarte, hvilket på et hospital betyder en ændringsbillett - så i praksis ændrede ingen noget, og en standard, der var valgt på den første eftermiddag, blev indstillingen for evigt.
Hvorfor en registry snarere end en form
Den åbenlyse måde at bygge en indstillings-side er at skrive formen. Det producerer to beskrivelser af hver indstilling - en i serveren, der validerer den, og en i grænsefladen, der render den - og de driver. Driften er stille: et felt, serveren stoppede med at acceptere, har stadig en kontrol, så nogen indstiller det, ser det gemt og gør intet.
Så en indstilling erklæres én gang, her, med alt, der er nødvendigt for at både kontrollere og tegne den: hvilken type værdi det er, hvilken kontrol det passer, hvilken gruppe det tilhører, hvad det betyder, og om ændring af det får virkning nu. Grænsefladen beder om den beskrivelse og render, hvad den bliver sagt. At tilføje en indstilling er én post i denne pakke og ingen grænseflade-arbejde overhovedet.
TestEverySettingIsFullyDescribed gennemtvinger de dele, en menneskelig har tilført, fordi en indstilling uden hjælpetekst er en indstilling, nogen gætter på.
Hvorfor en fil snarere end en database
Indstillinger bor i en YAML-fil, som grænsefladen redigerer på stedet, svarende til, hvordan kanaler og alarmregler allerede fungerer. Tre årsager, i rækkefølge af vægt: et hospitals ændringskontrol ønsker konfiguration, der kan diffes og lægges i versionskontrol; en operatør med maskinen, men ikke applikationen, kan læse en fil og ikke læse en database; og genskabelse af i går indstillinger skal ikke kræve, at applikationen fungerer.
Hvorfor flags kun seede det
Filen vinder, så snart den eksisterer, og flags leverer de oprindelige indhold. Alternativet - flags vinder altid - ville gøre grænsefladen til en løgner, da hvad som helst, der nogensinde er overført på en kommandolinje, kan redigeres og gemmes og stille ignoreres.
En flag, der er uenig med filen, rapporteres ved opstart, med navngivning af begge værdier, for ellers bliver flaget i tjenestedefinitionen i år og den næste person, der læser det, tror på det.
Source: github.com/biodream-llc/perfuse/internal/settings
26.89 sftpconn
Pakken sftpconn åbner SFTP-forbindelser.
Split ud fra connectors, fordi den interessante del er godkendelse og værtsgodkendelse, og begge er identiske, uanset om en kanal indsamler filer eller skriver dem. To kopier ville glide fra hinanden, og den halvdel, der gled fra, ville være den halvdel, der ophørte med at verificere.
Source: github.com/biodream-llc/perfuse/internal/sftpconn
26.90 skygge
Pakken shadow sammenligner en kandidatkanal med den aktive.
Selv sammenligningen er den lette del. Hele værdien ligger i to garantier, og begge er gennemført ved konstruktion snarere end ved konfiguration:
- En shadow kan ikke levere. Den indeholder en transformationsrørledning og ingen afsendere, så der er ingen kodevej herfra til en modtager. En indstilling kan ikke oprette en, og en fejl kan ikke aktivere en. - En shadow kan ikke påvirke den aktive kanal. Den kaldes efter, at den aktive besked er blevet leveret og bekræftet, dens panik er gensendt, og dens tidsgrænser er dens egne.
Noget mindre end det, og shadow-tilstand bliver en måde at bryde produktion på, mens man forsøger at undgå at bryde produktion.
Source: github.com/biodream-llc/perfuse/internal/shadow
26.91 shl
Pakken shl implementerer SMART Health Links og SMART Health Cards: QR-koderne CMS's "Kill the Clipboard" beder leverandører om at acceptere ved indtjekning og at give tilbage med besøgsrekorden.
En SMART Health Link (SMART Health Links STU 1) er shlink:/ efterfulgt af base64url JSON: en manifest-URL, en 256-bit-nøgle og valgfrit et udløbsdato, en label og flags (P adgangskode, L langvarig, U en enkelt fil via GET). Modtageren sender til manifest-URL'en og får filer tilbage, hver en JWE-krypteret med den nøgle - alg dir, enc A256GCM, valgfrit DEFLATE-komprimeret - indeholdende FHIR JSON, SMART Health Cards eller en SMART-adgangstoken. Serveren, der hoster filerne, ser aldrig nøglen: den rejser kun i linket, som er patientens.
En SMART Health Card (SMART Health Cards Framework 1.4) er en signeret FHIR-bundle: en kompakt JWS, ES256, med en DEFLATE-komprimeret payload, der navngiver udgiveren, hvis offentlige nøgle er på <iss>/.well-known/jwks.json. Den rejser som en numerisk shc:/ QR-kode eller en .smart-health-card-fil.
Kun standardbiblioteket: crypto/aes, crypto/cipher, crypto/ecdsa og compress/flate dækker alt, og et JOSE-bibliotek ville bringe en langt større overflade for to algoritmer.
Source: github.com/biodream-llc/perfuse/internal/shl
26.92 smartauth
Pakken smartauth er en SMART App Launch-autentificeringsserver: den udsteder adgangstoken, som Perfuse's FHIR-endpoint accepterer.
Skrevet mod standardbiblioteket, ligesom internal/oidc, som verificerer, hvad denne signerer. Tokenene er JWT'er signeret RS256, den ene algoritme, som hver SMART-klient og specifikationens ID-token-regler kan regne med.
Source: github.com/biodream-llc/perfuse/internal/smartauth
26.93 snmp
Pakken snmp er en lille læse-only SNMPv2c-agent: GET, GETNEXT og GETBULK over UDP mod en tabel med værdier, som opkaldsstedet udfylder, og SNMPv2-fælder.
Beskeder er BER (X.690) kodet her; intet i det er kryptografi (v2c's fællesskabsstreng er en ren tekst-adgangskode, som er hvorfor agenten kun besvarer de netværk, den er blevet fortalt at).
Source: github.com/biodream-llc/perfuse/internal/snmp
26.94 soap
Pakken soap sender SOAP-anmodninger og læser SOAP-fejl, ved kun at bruge standardbiblioteket.
SOAP er en del ceremoni omkring en HTTP-POST, og det er stadig, hvordan en stor del af hospital-mellemvare accepterer data - patientadministrationssystemer, dokumentrepositorier, regionale rekordservices, alt specificeret i årtiet, da dette var svaret. Mirth har en Web Service-connector, så dette er en Tier 2-migrationsblokerer snarere end en nice-to-have.
Hvorfor ikke en genereret klient
Den sædvanlige tilgang er at tage en WSDL og generere Go-typer fra den. Det er det rigtige svar for en applikation, der taler til en kendt tjeneste, og det forkerte svar her: en integrationsmotors destination er konfigureret af nogen, der redigerer en kanal, ikke genkompilerer, så kuverten skal samles ved kørselstidspunktet fra en skabelon, de kan se og ændre. Det betyder også, at der ikke er nogen kodegenereringstrin og intet at regenerere, når den fjerne ende publicerer en ny WSDL.
Hvad dette bevidst ikke gør
Ingen WSDL-parsing, ingen WS-Sikkerhed, ingen MTOM, ingen WS-Adresse. Disse er hver især en specifikation i deres eget ret, og at prætende at understøtte en af dem, mens man får en detalje forkert, er værre end ikke at tilbyde det - en signatur, der næsten verificerer, er ikke til at skelne fra et angreb i den fjerneste ende. WS-Sikkerhed er især det sted, hvor en halvimplmentation ville kunne forårsage reel skade.
Hvad der er her: SOAP 1.1 og 1.2-konvolutter, en skabelon-besked, SOAPAction-overskriften og fejlregistrering, der læser fejlstrengen i stedet for at rapportere "500".
Source: github.com/biodream-llc/perfuse/internal/soap
26.95 sof
Pakken sof kører SQL på FHIR v2 ViewDefinitions: en visning omdanner hver FHIR-resurs af en type til rækker af navngivne kolonner via FHIRPath, så FHIR-data kan læses som tabeller af SQL-motorer, regneark og kvalitetsmål.
Den følger ViewDefinition's procesalgoritme (kolonne, vælg, forEach, forEachOrNull, gentag, unionAll, hvor, konstanter, %rowIndex, getResourceKey og getReferenceKey) og kontrolleres mod de officielle sql-on-fhir testfikseringer.
Source: github.com/biodream-llc/perfuse/internal/sof
26.96 sqldb
Pakken sqldb åbner databaseforbindelser for databasekilden og -destinationen.
Driverne er registreret her og ingen andre steder, så der er kun ét sted, der bestemmer, hvad Perfuse kan tilslutte sig.
Source: github.com/biodream-llc/perfuse/internal/sqldb
26.97 sqlitedb
Pakken sqlitedb åbner SQLite på den måde, en server har brug for: en forbindelse til skrivning og flere til læsning.
Grunden er en fejltilstand, der kun opstår, når en installation har været i drift i en periode. SQLite i WAL-tilstand lader læsere køre sideløbende med en skriver, men Go's forbindelsespul sidder oven på SQLite, så en pulje på én serialiserer alt, uanset hvad databasen ville tillade. En beskedbrowsersøgning, der scanner payload-kolonnen, holder herefter den eneste forbindelse, og hver ankomne besked venter bagved den.
Målt på denne maskine, tager en skrivning 104µs, når lagret er inaktivt, og 2,6 ms, mens en søgning scanner fire tusinde beskeder: 25 gange langsommere. Det skalerer med tabellen, så ved et par hundredtusinde gemte beskeder bliver en rapport til sekunder af leveringsforsinkelse, og en skrivning er på bekendtgørelsesstien. Afsenderen ser en timeout, sender igen, og nogen bruger en formiddag på at lede efter et problem i netværket.
At splitte puljerne koster ingenting og fjerner interaktionen: rapporter får deres egne forbindelser, og skriveren beholder én for sig selv, fordi SQLite tillader nøjagtig én skriver i forvejen.
Source: github.com/biodream-llc/perfuse/internal/sqlitedb
26.98 trin
Declarative transformations-trin til enhver beskedformat.
Hvorfor dette er delt
Trin-vokabularet - indstil, kopier, ryd, kort, erstat, trim, tilfælde, hver med en beskrivelse og en valgfri betingelse - har intet at gøre med nogen bestemt format. Kun tre ting adskiller sig mellem formater: hvordan en sti skrives, hvordan en værdi læses, og hvordan den skrives tilbage.
Dette er samme konklusion, filter-grammatikken nåede i internal/expr, og af samme grund. X12 havde en trin-motor, og NCPDP havde brug for en; at kopiere den ville have resulteret i en anden firehundredlinje-motor, der skal holdes i trit med hånden, og derefter en tredje til adskilt. Det værdifulde adfærd er subtilt nok, så en kopi ville ikke have holdt det - grunden til, at resultatet genlæses efter hver skrivning, for eksempel, tog en reel fejl at opdage.
Hvad et format leverer
En Accessor: en sti-kompiler, en betingelses-kompiler og en valgfri veto på trin, det ikke kan honore. Intet andet.
Source: github.com/biodream-llc/perfuse/internal/steps
26.99 stomp
Pakken stomp taler STOMP 1.2 til en beskedformidler.
Dette er, hvad "JMS-understøttelse" skal betyde i et program, der ikke er Java. JMS er en API snarere end en protokol, så der er intet at implementere: hvad et websted faktisk har brug for, er, at Perfuse taler med formidleren, der sidder bag deres JMS-applikationer.
STOMP snarere end OpenWire, og begrundelsen er værd at optegne, fordi det åbenlyse svar er forkert. OpenWire er ActiveMQ's native protokol og en binær serialisering af JMS-kommandoer - uger af arbejde, specifik for én formidlerfamilie, og udokumenteret undtagen ved dens implementering. ActiveMQ auto-detekterer STOMP, AMQP og MQTT på samme port, som den serverer OpenWire på, så en tekstprotokol når samme formidlere. STOMP dækker ActiveMQ Classic, Artemis og RabbitMQ; AMQP 1.0 ville tilføje Azure Service Bus og IBM MQ, og er den fornuftige næste i stedet for OpenWire.
Skrevet mod standardbiblioteket. En formidlerklient er ikke stedet for en afhængighed, hvis fejltilstande er nogen andens at forklare, og rammen her er lille nok, så at eje den koster mindre end at læse deres issuetracker.
Source: github.com/biodream-llc/perfuse/internal/stomp
26.100 lager
Pakke lager indeholder de data, der faktisk er tilstandsbaseret: brugere, sessioner og en revisionshistorik.
Kanaler er bevidst ikke her. De lever i filer, fordi det er det, der giver git, diffs, kodegennemgang og miljøfremme for gratis. At placere kanaler i en database er beslutningen, der tvinger hver af disse til at købes separat, og det er årsagen til, at et tredjepartsprodukt findes udelukkende til at transportere Mirth-kanaler mellem sin database og et git-repository.
Så splitningen er: konfiguration i filer, identitet og historik i SQLite.
Source: github.com/biodream-llc/perfuse/internal/store
26.101 tefca
Pakke tefca implementerer de dele af TEFCA-deltagelse, der ikke kræver en QHIN-forbindelse.
Hvad er virkeligt
Formål-med-brug-validering, konfigurationsvalidering og revisionshistorikken - herunder dens persistence, dens forespørgselsschnitt og dens forpligtelse til at optage mislykkede forsøg samt succesfulde. Sidstnævnte er ikke en teknikalitet: en række mislykkede leverancer til en modtager er, hvordan en fejlkonfigureret partner viser sig, og en række mislykkede forespørgsler for forskellige patienter er, hvordan afprøvning viser sig.
Hvad ikke er
Netværket. Der er ingen QHIN-transport i denne build, så der sker ingen udveksling, og hver udvekslingsfunktion afviser med ErrExchangeNotImplemented i stedet for at returnere succes.
Denne forskel blev ikke altid trukket, og måden det gik galt på er værd at holde fast. Alle fire udvekslingsfunktioner validerede tidligere deres input, foretog ingen netværksopkald og returnerede succes; Deliver returnerede en accepteret respons med et sporing-id bygget fra uret. Revisionslaget optog herefter hver som en fuldført udveksling - i den log, der findes for at bevise, hvad der blev udvekslet, når nogen spørger måneder senere. Fire tests hævdede, at adfærd og bestod.
Hvad fuldførelse kræver
Onboarding med et kvalificeret sundhedsinformationssystem, gensidigt autentificeret TLS med certifikater udstedt gennem denne proces, og enten IHE-profilerne fra den fælles aftale eller Facilitated FHIR som defineret af Sequoia Projects standardprocedur, effektiv fra den 8. marts 2026. Ingen af disse kan skrives spekulativt: det testes mod et virkeligt QHIN eller det testes ikke, og en ubevist udvekslingsimplementering er den samme fejl som ingen implementering i en bedre forklædning.
Source: github.com/biodream-llc/perfuse/internal/tefca
26.102 lejer
Pakke lejer giver identitets- og isolationsregler for multi-lejer-drift.
En sundhedsinformationssystem, en clearinghouse eller en managed service provider kører en motor på vegne af mange organisationer. Mirth kan ikke gøre dette - en enkelt instance betjener en organisation, og en MSP ender med at køre femti JVM'er og femti databases.
Hvad en lejer ejer
Dens kanaler, som en filmappe. Dens brugere. Dens meddelelser, kø, revisionshistorik og FHIR-resourcer. Dens metikkekilder. Intet deles undtagen processen, de lytterporte det blev tildelt, og platformadministratorerne.
Isolation er strukturel, ikke husket
Den farlige fejl her er ikke et crash. Det er lejer A ser lejer B's meddelelser, hvilket er en rapporterbar overtrædelse snarere end en fejl. En design, hvor hver forespørgsel tager en lejer_id-parameter, fejler første gang, nogen skriver en forespørgsel og glemmer en, og den forespørgsel ser perfekt ud i gennemgang.
Så lejeren er ikke en parameter. Adgang til data sker gennem en håndtering, der allerede bærer den, og der er ingen måde at nå tabellerne uden en. At glemme er ikke tilgængeligt.
Source: github.com/biodream-llc/perfuse/internal/tenant
26.103 terminologi
Pakke terminologi holder offentliggjorte kode-systemer (LOINC, SNOMED CT, RxNorm, ICD-10-CM, CPT og lokale) for at se koder op, og værdi-mappingstabellerne havde ikke, for nogen at kortlægge.
Kode-systemerne importeres fra filerne deres udgivere distribuerer. Flere er licenseret (LOINC kræver en gratis konto, SNOMED CT en affiliate-licens, RxNorm en UMLS-licens, CPT en AMA-licens), så ingen følger med Perfuse: en administrator, der har licensen, uploader filen, og Perfuse optager, hvem der importerer det og hvornår.
Source: github.com/biodream-llc/perfuse/internal/terminology
26.104 tlsconf
Pakken tlsconf opbygger TLS-konfiguration fra filer og beskriver certifikater.
Dette er den gratis ekvivalent af en udvidelse, som Mirth nu opkræver betaling for. Det meste af værdien ligger ikke i krypteringen, som kun er nogle få linjer, men i den del, der forhindrer, at nogen installerer noget, de tror er sikret, men ikke er: afvisning af at springe verificeringen over uden at give besked, insisteren på, at en klientcertifikat faktisk bliver kontrolleret, når en sådan anmodes, og klart at sige, når et certifikat er på vej til at udløbe.
Et udløbet certifikat på en interface-feed er en ægte hospitalsnedlukning, og det sker, fordi ingen blev underrettet. Den beskreibende del af denne pakke findes af den grund.
Source: github.com/biodream-llc/perfuse/internal/tlsconf
26.105 tomirth
Pakken tomirth skriver en Perfuse-kanal ud som Mirth-kanal-XML.
Hvorfor denne pakke findes. Indvendingen mod at antage en ny integrationsmotor er sjældent "er den nogen god". Det er "hvad hvis vi tager fejl og bliver fast", og det billigste svar på det er at kunne gå tilbage ud. Perfuse har læst Mirths kanaler fra starten; indtil nu kunne den ikke skrive en kanal, hvilket gjorde forsikringen ensrettet og derfor ikke meget værd.
Hvordan den undgår fælden, der gjorde det første forsøg værdiløst. Mirths XML er XStreams output, og XStream læser klassen og versionsattributterne som instruktioner: et element, der ikke genkendes, droppes uden et ord, og en kanal, der ikke kan samles, gemmes med sin beskrivelse erstattet af "Denne kanal er ugyldig. Verificér, at alle nødvendige udvidelser er indlæst korrekt" og dens destinationer droppes. Intet i svaret nævner det fejlende element. En eksportør, der komponerer egenskabsblokke fra en læsning af formatet, fejler derfor på den måde, der er dyrt at diagnosticere, hvilket er, hvad der skete: dette repository indeholdt en eksportør med ni gennemførte tests, hvis output Mirth smed væk, fordi hver test sammenlignede det med vores egen parser i stedet for en server.
Så ingen af egenskabsblokkene komponeres her. scripts/mirth-dump-connector-templates.sh har Mirths egen ObjectXMLSerializer serialisere standardværdierne for hver connector-egensklasse, og disse dokumenter er gemt under templates/. Denne pakke erstatter værdier i dem, og mirth.SetRawProperty afviser enhver sti, skabelonen ikke allerede indeholder - så en fejl er en fejl i navngivningen af stien, på tidspunktet for eksport, i stedet for en kanal, der forsvinder ved import.
Hvad den ikke vil gøre. En transport med ingen Mirth-ekvivalent afvises navngivet i stedet for at blive approksimeret. En eksport, der stille og roligt omdannede en S3-destination til en filskriver, ville være værre end ingen eksport overhovedet, fordi kanalen ville importere renligt og levere til det forkerte sted.
Source: github.com/biodream-llc/perfuse/internal/tomirth
26.106 trace
Pakken trace producerer distribuerede spor for meddelelser, der flytter gennem en kanal, og eksporterer dem over OTLP/HTTP med JSON-kodningen.
Hvorfor denne pakke findes i stedet for OpenTelemetry SDK: SDK plus en OTLP-eksportør trækker omtrent tres moduler ind og tilføjer lige så meget til binærfilen som hele resten af dette program. Det, der faktisk er nødvendigt her, er smalt - W3C-spor-kontekstpropagation, en spænmodel, hovedprøvning og en batchet HTTP-POST - og OTLP/JSON er en dokumenteret stabil kodning, der kan produceres med standardbiblioteket alene. Samme handel som at vælge lib/pq over pgx: tage det små ting, når kun en del af det store ting er ønsket.
Konsekvensen, der er værd at nævne: der er ingen auto-instrumentering og ingen vendor-specifik eksportør. Spæn er de, dette program skaber bevidst, og de går til enhver OTLP-endpoint - en samler, Jaeger, Grafana Tempo, Honeycomb, Datadogs OTLP-indtagelse.
Egenskaben, der betyder mere end spæn
En meddelelse ankommer ofte med en traceparent-header fra systemet, der sendte den, og forlader mod et system, der vil optage en af sin egen. At fortsætte dette spor i stedet for at starte et nyt er, hvad der gør en enkelt visning af "den elektroniske patientjournal sendte dette, motoren omdannede det, registret afviste det" mulig overhovedet. Interface-problemer er næsten altid rapporteret som "vi sendte det, og intet skete", og det spørgsmål er ubesvaret uden en identifikator, der overlever springet.
Sporing må aldrig påvirke levering
Hver operation her er bedst-effort. Spæn droppes, når bufferen er fuld, eksportfejl tælles og gensendes aldrig ind i meddelelsesstien, og ingen opkald blokerer på netværket. Et droppet spæn er en ulempe. En meddelelse, der er forsinket eller tabt, fordi sporingens backend var langsom, er en klinisk incident, så handlen er aldrig i spørgsmål.
Source: github.com/biodream-llc/perfuse/internal/trace
26.107 transform
Pakken transform anvender deklarative ændringer på en meddelelse.
Dette er laget, der er ment til at bære den almindelige arbejde, med scripting holdt som en markeret undvigelsesmulighed. Forskellen er ikke stilistisk. Et trin, der er deklareret i YAML, kan valideres, før det køres, vises i en diff, gennemgås af nogen, der ikke læser JavaScript, og rapporteres om; et script kan kun køres og håbes om. Det meste af, hvad Mirth-omdannere faktisk gør, er kedsommeligt - kopiere et felt, udfylde en identifikator, kortlægge en kode gennem en tabel, rydde noget, der ikke skal forlade bygningen - og alt det hører her til.
Hvert trin navngiver sit mål eksplitt og hvert trin er omvendeligt i den forstand, at det siger, hvad det gjorde, fordi den dyreste fejl i en interface er en omdannelse, der ikke var kendt.
Source: github.com/biodream-llc/perfuse/internal/transform
26.108 translate
Pakken translate konverterer en Mirth-kanal til en Perfuse-kanaldefinition.
perfuse explain rapporterer, hvad blokerer en migration. Dette gør det meste af migrationen, som er et helt andet og langt større krav, så det er bevidst konservativt om, hvad det vil påstå.
Tre regler former hele sagen.
Intet bliver tavs droppet. Hver del af kildekanalen er enten oversat, overført uændret som et script eller rapporteret som krævende en menneskelig hånd. En oversætter, der stillede et trin, ville producere en kanal, der starter, kører og taber data — det værste mulige udfald og årsagen til, at folk mistænker migrationsværktøjer.
Declarativt, hvor det er sikkert, script, hvor det ikke er. Et Mapper-trin, der kopierer et felt, bliver et declarativt trin, fordi det er læseligt og kontrollerbart. Et JavaScript-trin bliver et script, fordi Perfuse kører Mirths JavaScript uændret, og om skrivning af det til noget, der ligner noget ækvivalent, er præcis, hvor en oversætter ville introducere en forskel, som ingen lægger mærke til.
Udgangen er meant til at blive læst. Den indeholder kommentarer, der forklarer, hvad der kom fra hvor, og hvad der blev efterladt for en person. En migration gennemgås af nogen, der skal godkende den, og en uannoteret væg af YAML kan ikke gennemgås.
Source: github.com/biodream-llc/perfuse/internal/translate
26.109 udap
Pakken udap implementerer client-delen af HL7-sikkerhed til Skalérbar Registrering, Autentificering og Autorisation — specifikationen TEFCA's Facilitated FHIR-udveksling hviler på.
UDAP er en offentlig nøgleinfrastruktur boltet på OAuth 2.0. En tillidskommunitet udsteder X.509-certifikater til dets medlemmer; et medlem beviser, hvem det er, ved at signere JWT'er med den private nøgle og vedhæfte certifikat-kæden i JWT-headeren. Det erstatter den fælles klienthemmelighed i almindelig OAuth, som ikke kan skaleres til tusinder af organisationer, der aldrig har mødt hinanden.
Hvorfor denne pakke findes overhovedet. TEFCA-udveksling kan ikke fuldt verificeres uden en rigtig QHIN: at melde sig til en kræver onboarding og udstedte certifikater og kan ikke fabrikeres. Men sikkerhedsprofilen under det er en offentlig HL7-implementeringsvejledning med offentlige reference-servere, og en af dem besvarer på det åbne internet. Så den del, der kan verificeres, verificeres her, og den del, der ikke kan, afvises ved grænsen i stedet for at gætte.
Forskellen betyder noget på grund af, hvad der skete med SAML i dette repository: tusind linjer tests passede, fem af dem specifikt om signatur-kanonisering, mens ingen rigtig identitetsudbyder kunne autentificere nogen. Begge halvdele var blevet skrevet her og var enige med hinanden. Lektien, der er taget fra det, er, at en sikkerhedsimplementering ikke er værd noget, før noget, en anden har skrevet, har accepteret eller afvist det.
Specifikationsreferencer: - HL7 UDAP Security STU 1: http://hl7.org/fhir/us/udap-security/STU1/ - TEFCA SOP Facilitated FHIR Implementation v2.0, effektiv 8. marts 2026
Source: github.com/biodream-llc/perfuse/internal/udap
26.110 umlink
Pakken umlink transporterer X12 278'er til et betalers brug af system til udnyttelsesstyring, og svarene tilbage, de måder, hvorpå disse systemer nås i praksis: X12 i brødteksten af en HTTPS POST; CAQH CORE's SOAP-enveloppe (Connectivity Rule vC2.2.0, den, som de fleste betalere og CMS'er kører esMD, og vC4.0.0); CAQH CORE's HTTP MIME multipart-enveloppe (vC2.2.0); og batch-filer over SFTP.
Skrevet fra CAQH's offentliggjorte Connectivity Rules (vC2.2.0 og vC4.0.0), deres XML-skema og WSDL, og CMS's esMD X12N 278 Companion Guide. Det er ikke CORE-certificeret: certificering udføres af CAQH's autoriserede testleverandører.
De realtidsforbindelser returnerer svaret, som UM-systemet gav, som kan være en 278-svar eller, når det ikke kunne læse anmodningen, en 999 eller TA1: opkaldsprocessen læser, hvilken af dem. Batch-forbindelsen returnerer ErrAnswerLater, så snart filen er leveret, og Poll indsamler, hvad der kommer tilbage.
Source: github.com/biodream-llc/perfuse/internal/umlink
26.111 v2fhir
Pakken v2fhir mapper HL7 v2-besked til FHIR-resourcer.
Mapping er, hvor interoperabilitetsprojekter faktisk fejler, så reglerne, denne pakke følger, er angivet i stedet for antydet:
- En værdi, der ikke kan mappes, bevares som tekst, aldrig gættet. En lokal kode omdannet til en plausibel standardkode er værre end en ukodet værdi, fordi modtageren tror på den. - Hver mappningsbeslutning, der involverede dømmekraft, rapporteres som en note, så et menneske kan kontrollere dem, der betyder noget, i stedet for at læse hele output. - Tidsstempel konverteres, ikke kopieres. HL7 v2-tidsstempel er ikke ISO 8601, og en dateTime, der bærer en lokal tid med ingen offset, er den mest almindelige årsag til, at en konverteret ressource afvises. - Enheder beholder deres oprindelige tekst og får kun en UCUM-kode, når mappningen er sikker. En forkert enhedskode er en patient-sikkerhedsfejl, ikke et formateringsproblem.
Source: github.com/biodream-llc/perfuse/internal/v2fhir
26.112 vcs
Pakken vcs læser kanal-filernes historie fra git.
Kanalhistorik er en betalt udvidelse andre steder, og det er en betalt udvidelse, fordi disse motorer holder kanaler i en database, så sporing af ændringer betyder opbygning af en ændringssporingssystem. Perfuse holder kanaler i filer, så historikken allerede findes og har gjort det siden den første commit. Denne pakke skal kun læse den.
Den giver kommando til git i stedet for at indlejre en git-bibliotek. Biblioteket ville tilføje en stor afhængighed til en binær, hvis salgsargument er at have fire, og det ville købe intet: en installation, der holder sine kanaler under versionskontrol, har git installeret, og en, der ikke gør, får en klar "ikke en git-repository" i stedet for en subtilt forskellig implementering af det samme.
Source: github.com/biodream-llc/perfuse/internal/vcs
26.113 vfs
Pakken vfs er den lille samling filoperationer, en polling-connector har brug for.
Hvorfor en interface i stedet for fire connectorer
Perfuse indsamler filer fra en lokal disk, en SFTP-server, en FTP-server, en Windows-del og en WebDAV-server. Overførslen adskiller sig i hver sag. Alt, der faktisk afgør, om beskeder overlever, gør ikke:
- En fil, der skrives, og en fil, der er færdig med at blive skrevet, er ikke til at skelne. Der er ingen lås, ingen flag og ingen meddelelse på nogen af disse transportmidler - der er en størrelse og en ændringsdato, og begge er sande for en halvt skrevet fil. At læse for tidligt indsamler en halv besked, og HL7 har ingen terminator, så en halv besked er ofte stadig parsebar. MSH er intakt, de segmenter, der ankom, er velformulerede, de, der ikke gjorde, er simpelthen fraværende. Det accepteres, bekræftes, gemmes, leveres, og intet vil nogensinde nævne det. - En fil må ikke kasseres, før hver besked i den er blevet accepteret, fordi filen er den eneste kopi. - En fil, der fejlede, må ikke samles op igen på næste afhentning for evigt, og må ikke stille og roligt droppes.
Skrives én gang pr. transport, ville disse regler være subtilt forskellige fem gange, og forskellene ville kun optræde som beskeder, der forsvandt på ét sted. Så de skrives én gang, her, over det mindste grænseflade, der understøtter dem.
Hvad der ikke er her med vilje
Ingen skrivning, ud over hvad bortskaffelse har brug for. At sende filer er et andet problem med andre fejlmodi - en delvis skrevet fil i den fjerne ende, som de eksisterende afsendere håndterer ved at skrive til et midlertidigt navn og omdøbe. At folde begge retninger ind i ét grænseflade ville gøre hver af dem sværere at forstå.
Ingen rekursion. En afhenter, der går ned i underkataloger, indsamler arkivkataloget, den lige har flyttet en fil til.
Source: github.com/biodream-llc/perfuse/internal/vfs
26.114 vpn
Pakken vpn rapporterer tilstanden for site-til-site VPN-tunneller, som partnertrafikken kører over - AWS Site-to-Site VPN, Azure VPN Gateway-forbindelser og strongSwan - og holder hver partners forbindelsesskema: beggesiders tunnelindstillinger og om de er enige.
En tunnel, der er nede, ligner fra en grænseflademotor præcis en partner, hvis motor er stoppet: forbindelserne times out. At sige, at "tunnelen er nede" i stedet for er forskellen på at ringe til netværksteamet og ringe til partneren.
Kun læsning. Intet her ændrer en tunnel, og ingen foruddelte nøgle læses, gemmes eller vises nogensinde.
Source: github.com/biodream-llc/perfuse/internal/vpn
26.115 web
Pakken web betjener den byggede frontend fra inden for binærfilen.
Aktiverne er indlejret i stedet for at blive sendt sammen med, så installationen bliver én fil. Det er samme årsag, som motoren undgår cgo: en operatør skal kunne kopiere en binær fil til en server og køre den, uden JVM, uden installer og uden aktiverkatalog, der kommer ud af trit med det eksekverbare.
Byggeoutput er committet, så go build virker på et checkout uden Node installeret. Genbyg det med make web.
Source: github.com/biodream-llc/perfuse/internal/web
26.116 webauthn
Pakken webauthn verificerer passkeys.
En passkey er et nøglepar, som autentificeren holder - Touch ID, Windows Hello, en YubiKey, en telefon - hvor den private halvdel aldrig forlader enheden. At logge ind betyder, at serveren sender en tilfældig udfordring, autentificeren signerer den efter at have kontrolleret, om brugeren er til stede, og serveren verificerer signaturerne mod den offentlige nøgle, den gemte under registreringen.
Egenskaben, der betyder noget, er ikke, at det er bekvemt. Det er, at der intet er at phish. En adgangskode kan tastes ind på en overbevisende kopi af en login-side; en passkey-signatur er bundet til oprindelsen, den blev oprettet for, så kopien får en signatur, dens server ikke kan bruge. Til en integrationsmotor, der holder en hospitals grænseflader, er det forskellen, der er værd at have.
Hvad denne implementering nægter at gøre
Specifikationen er tilladende på steder, hvor at være tilladende er, hvordan implementeringer bliver brudt. Denne er det ikke:
- Signeralgoritmen er fastsat ved registrering og gemt med nøglen. Intet under login læser en algoritme fra klienten, fordi det er algoritme-forvirring, og der er ingen funktion her, der kunne gøre det. - Oprindelsen sammenlignes præcis, aldrig ved præfiks eller suffiks. En check, der accepterer alt, der slutter med det rigtige domæne, accepterer en angribers underdomæne. - En udfordring er enkeltbrug og udløber. Den slettes, når den forbruges, så en fanget påstand ikke kan afspilles igen. - Attestation betrodes ikke til noget. Attestationserklæringen parses for at trække legitimationsoplysningerne ud og derefter ignorerer dens signatur, fordi at verificere den ordentligt kræver en vedligeholdt rod-lager og at prætende at verificere den er værre end at ikke gøre krav på det. - Signaturtælleren kontrolleres, når autentificeren leverer en, og dens fravær behandles ikke som mistænkeligt. Mange autentificere har legitimeret fravær af det på null.
Source: github.com/biodream-llc/perfuse/internal/webauthn
26.117 winservice
Pakken winservice kører Perfuse som en Windows-tjeneste.
Denne fil er den anden halvdel overalt. Den findes, så cmd/perfuse kan ringe ind i denne pakke uden at omringe hver kaldested i en byggetag: underkommandoen er altid kompuleret, og på Linux eller macOS forklarer den, at tjenester er en Windows-idé snarere end at fejle at eksistere.
At nægte med en klar sætning er bedre end at skjule underkommandoen. Nogen, der følger Windows-instruktioner på den forkerte maskine, får at vide, hvad der faktisk sker, og det samme for deres platform.
Source: github.com/biodream-llc/perfuse/internal/winservice
26.118 x12
Læsning og skrivning af værdier på en sti.
Hvorfor dette er adskilt fra Path
path.go bestemmer, hvad en sti-udtryk betyder. Denne fil løser en sti mod en faktisk udveksling. Holdes adskilt, fordi parsing-reglerne er værd at læse uden byte-håndtering, og fordi parseren bruges af konfigurationsvalidereren, som ikke har nogen besked at løse imod.
Hvorfor en skrivning gen-parser i stedet for at redigere bytes på stedet
Segment.elements er under-slices af Segment.raw, og Message.segs indekserer i Message.raw. Redigering af en værdi på stedet ændrer længden af alt efter det, så alle disse slices skulle justeres, og enhver, der blev overset, ville læse korrekt, indtil den ene besked, hvor det ikke gjorde.
Så en skrivning gen-opbygger segmentet, gen-opbygger udvekslingen og parser den igen. Det koster en parsing per ændret besked og køber garantien for, at en Message returneret herfra er præcis, hvad parsing af dens egne bytes producerer. Der er ingen tilstand, hvor indekserne og bytes ikke er enige, fordi den tilstand er urepræsentabel.
Source: github.com/biodream-llc/perfuse/internal/x12
26.119 x12xml
Pakken x12xml konverterer X12 (og andre afgrænsede EDI) til og fra den XML, som Mirth Connect og Open Integration Engine skriver for det, og tilbage.
Hvorfor den XML og ikke en af vores egne
Formålet med en XML-form for X12 er de systemer, der allerede bruger en. En side, der flytter fra Mirth, har modtagere bygget mod, hvad Mirths EDI/X12-data-type emitterer, scripts, der går msg['CLM']['CLM.05']['CLM.05.1'], og upstream-motorer, der sender X12 som den XML. En mere ordnet form af vores egen ville ikke tjene nogen af dem. Så denne skriver nøjagtig, hvad Open Integration Engine 4.6 skriver, og læser nøjagtig, hvad den læser, og testene sammenligner de to byte for byte mod OIEs egen serializer.
En tidligere version af denne pakke opfandt sin egen form (en X12Interchange-rod, elementer med navn CLM05) og sagde, at den matchede Mirths. Det gjorde den ikke; den var aldrig blevet sammenlignet med Mirth, og intet i Perfuse brugte den.
The format
Roden er X12Transaction, når meddelelsen starter med et ISA-segment, og EDIMessage ellers, med de tre afgrænsere som attributter (segmentDelimiter, elementDelimiter, subelementDelimiter). Hvert segment er et element med navn efter dets identifikator. Hvert data-element er SEG.NN, nummereret fra 01 (ISA.01, CLM.05), og holder sine komponenter som SEG.NN.1, SEG.NN.2 og så videre: altid mindst SEG.NN.1 for et element med en værdi, ingen for et tomt.
Afgrenserne læses fra ISA, når der er et: element-separatoren fra position 3, komponent-separatoren fra position 104 og segment-terminatoren fra position 105, med en linje-feed efter den tælles som en del af den. Ellers er de ~ * og:. Repetitions-separatoren (ISA11) fortolkes ikke, hvilket også er OIEs adfærd: et gentaget element beholder sin ^ inde i en værdi.
Dette er en genimplementering af adfærden, skrevet fra at observere OIEs output og fra dets dokumenterede format; intet kode fra Mirth er i det.
Source: github.com/biodream-llc/perfuse/internal/x12xml
26.120 xds
Pakken xds er IHE cross-enterprise dokument-deling: en XDS.b Dokument-registry og -repository (ITI-41 Provide and Register, ITI-18 Registry Stored Query, ITI-43 Retrieve Document Set), en XCA Responding Gateway over samme butik (ITI-38, ITI-39), og klient-siden af hver, så en kanal kan publicere et dokument til en anden organisations repository, og konsollen kan forespørge en registry eller en fællesskab.
Metadata er ebXML Registry 3.0 (ebRIM), som XDS.b definerer det i IHE ITI TF-3 kapitel 4. Det er modelleret her som Go-structs, hvis XML-tags bærer navneområderne, så en besked læses på samme måde, uanset hvilke præfikser afsenderen valgte, og skrives navneområd-korrekt.
Source: github.com/biodream-llc/perfuse/internal/xds
26.121 xmldsig
Pakken xmldsig implementerer XML Digital Signatures og XAdES-profilen af dem.
Hvorfor dette er skrevet i stedet for lånt
Et signerede klinisk dokument er en juridisk genstand. Det hævder, at en navngivet person, på en navngivet tid, tog ansvar for en bestemt sæt bytes. At få det forkert i begge retninger er alvorligt: en signatur, der ikke kan verificeres, gør et gyldigt dokument se forfalsket ud, og en verificator, der er for generøs, accepterer et dokument, nogen ændrede.
Kanonisering er hele problemet
XML har mange byte-sekvenser, der betyder det samme. Attribut-rækkefølge er ikke betydningsfuld, navneområd-præfikser kan omdøbes, tomme elementer kan skrives på to måder, og whitespace inden for en tag er frit. En signatur er over bytes, så før noget hashes, skal begge parter være enige om præcis én byte-sekvens for et givet dokument. Den aftale er kanonisering, og det er, hvor implementeringer går galt, fordi hver fejl producerer en signatur, der verificeres mod egen output og fejler mod alle andres.
Så denne fil er kanoniseringen, på egen hånd, med sine egne tests. Der er intet om signing her.
Eksklusiv i stedet for inklusiv, som standard
Inklusiv kanonisering trækker ind hver navneområd-erklæring, der er i omfang, herunder dem, der aldrig bruges af det signerede element. Det gør en signatur knækket, når dokumentet senere indlejres i noget, der erklærer en urelateret navneområde på en forfader, hvilket er præcis, hvad der sker, når en CDA indsættes i en SOAP-enveloppe eller en IHE-metadata-omslag. Eksklusiv kanonisering inkluderer kun de erklæringer, elementet faktisk bruger, og det er, hvad dokument-udvekslingsprofiler specificerer af denne grund.
Source: github.com/biodream-llc/perfuse/internal/xmldsig
26.122 xtree
Pakken xtree er et mutable XML-træ.
Tre meget forskellige funktioner skal modificere XML: HL7-transformationer, som Mirth modellerer som XML, fordi det er det, deres scripts opererer på; kliniske dokumenter, som er XML i deres natur; og de deklarative transformationstrin. De deler dette ene træ i stedet for at hver især udvikler deres eget, fordi alternativet er tre modeller, der er uenige om, hvad et tomt element betyder.
Designmålet er troskab over for E4X-semantik, da Mirth-scripts er E4X, og hele pointen med at køre dem uændret er, at de opfører sig på samme måde. Det driver to beslutninger, der ellers ville se underlige ud: en node gemmer en peker til sin forælder, fordi E4X eksponerer parent(), og børn er ordnet med tilladelse til duplikater, fordi en HL7-feltgentagelse bogstaveligt talt er et gentaget element, og scripts indekserer i dem efter position.
Source: github.com/biodream-llc/perfuse/internal/xtree
26.123 pakke pas
Pakken pas læser Da Vinci Prior Authorization Support (PAS) anmodningsbundter.
Det er læseren, som Perfuse's egen PAS-server bruger, offentliggjort, så hvad som helst, der afgør en forhåndsgodkendelse - en betalers regler, et system til udnyttelsesstyring, en beslutningstjeneste som Vaglio - læser en anmodning med samme kode, og så samme svar om, hvad en anmodning indeholder. To læsere af én meddelelsesformat er to meninger om det.
Den har ingen afhængigheder uden for standardbiblioteket. En anmodning gemmes som afkodet JSON (map[string]any) i stedet for som typede ressourcer, fordi en PAS-bundle transporterer hvilke som helst understøttende ressourcer, som udbyderen har valgt at sende, og en læser, der dropper, hvad den ikke modellerer, ville skjule beviser fra beslutningen.
req, problems := pas.Læs(bundle, false) hvis len(problems) > 0 { // afvis: anmodningen kan ikke besvares korrekt } for _, svc := range req.Tjenester() { // svc.Koder, svc.Punkt, og req.Løs for alt, som punktet refererer til }
Source: github.com/biodream-llc/perfuse/pas
27 Indeks over konfigurationsnøgler
Hver nøgle i alfabetisk rækkefølge, med de blokke, den kan optræde i. En nøgle, der optræder i flere blokke, betyder det samme i hver enkelt; hvor den ikke gør, er blokkene dokumenteret separat, og forskellen er angivet der.
27.1 Alle nøgler
| Nøgle | Fremtræder i |
|---|---|
access_key_id | AWS Adgang, FHIR Auth, S3 Destination |
account | Azure Blob Adgang |
ack | HTTP Source, SOAP Source, Source |
ack_sender_id | X12 Options |
ack_sender_qualifier | X12 Options |
acknowledge | EDIFACT Options, HL7v3 Options, X12 Options |
acks | Kafka Destination |
action | SOAP Destination |
addr | AMQP Connection, Broker Destination, Broker Source, MQTT Connection |
address | AMQP Connection, DICOM Destination, DICOM Query Source, Destination, Direct Address, TCP Dest |
ae_title | DICOM Source |
after_query | Database Source |
after_read | Azure Blob Source, Direct IMAP, Email Source, File Poll, GCS Source, S3 Source, SFTP Source |
allow | Scripts |
allow_clear_password | FTP Destination |
allow_unencrypted | AS2 Partner, PGP Receive |
allow_unsigned | AS2 Partner |
allowed_calling_ae | DICOM Source |
allowed_senders | Email Source |
amqp | Destination, Source |
anchors_file | Direct Address |
api_version | IBMMQ Connection |
append | Destination, SFTP Destination |
application | Ack |
armor | PGP Send |
arrives_as | X12 Options |
as2 | Destination, Source |
attach | SMTP Destination |
attach_name | Direct Destination, SMTP Destination |
attachment_names | Email Source |
attachments | Channel |
attempts | Retry |
auth | FHIR Destination, PAS Destination |
authorities | MPI Destination |
azure_blob | Destination, Source |
backoff | Queue Config, Retry |
base64 | SOAP Source |
batch_size | Database Source, File Poll |
baud | Serial Source |
bcc | SMTP Destination |
bearer_token | CDA Destination, FHIR Destination, HTTP Destination, PAS Destination |
big_endian | TCP Framing |
blob | Azure Blob Destination |
body | SMTP Destination, SOAP Destination |
broker | Destination, Source |
brokers | Kafka Destination, Kafka Source |
bucket | GCS Access, S3 Destination, S3 Source |
bundle_script | FHIR Destination |
called_ae | DICOM Destination, DICOM Query Source |
calling_ae | DICOM Destination, DICOM Query Source |
cc | SMTP Destination |
cda | Destination |
cert_file | AS2 Destination, AS2 Partner, AS2 Source, Direct Address |
channel | Destination, Shadow |
check_every | Contract Ref |
city | ECR Facility |
claim_us_core | FHIR Destination |
class | XDS Destination |
client_ca_file | Direct XDR |
client_id | Email O Auth, FHIR Auth, MQTT Connection |
client_secret | Email O Auth, FHIR Auth |
code | XDS Code |
column | Database Source |
columns | Delimited |
comment | Delimited |
commit_after_delivery | Kafka Source |
compare | Shadow |
compress | AS2 Destination |
compression | Kafka Destination |
config | ELR Destination |
container | Azure Blob Access |
content_type | AMQP Destination, AS2 Destination, Azure Blob Destination, Broker Destination, GCS Destination, HTTP Destination, S3 Destination, XDS Destination |
contract | Channel |
credentials_file | GCP Access |
dataType | Channel |
data_bits | Serial Source |
database | Destination, Source |
decrypt_with | PGP Receive |
default_identifier_system | FHIR Destination |
delimited | Channel |
delimiter | Delimited, TCP Framing |
deploy | Scripts |
description | Channel |
destination | Broker Destination, Broker Source |
destinations | Channel |
dicom | Channel, Destination, Source |
dicom_query | Source |
dicomweb | Destination, Source |
dir | CDA Destination, Destination, Document Destination, FTP Destination, File Poll, SFTP Destination, SFTP Source |
direct | Destination, Source |
direct_from | XDS Destination |
direct_to | XDS Destination |
display | XDS Code |
dns | Direct Destination |
document | Destination |
domain | SMB Source |
driver | Database Destination, Database Source |
dsn | Database Destination, Database Source |
duplicate_window | AS2 Source |
ecr | FHIR Destination |
edifact | Channel |
element | SOAP Source |
elr | Destination |
email | Source |
emit_on_first_poll | DICOM Query Source |
enabled | Channel, Destination, Queue Config |
encrypt_to | PGP Send |
endpoint | AWS Access, Azure Blob Access, GCP Access, S3 Destination |
envelope | EDIFACT Options, X12 Options |
error_dir | File Poll, SFTP Source |
error_folder | Direct IMAP, Email Source |
error_prefix | Azure Blob Source, GCS Source, S3 Source |
expect_reply | TCP Dest |
extract | Attachments |
facility | Ack, ECR Destination |
facility_id | SOAP Destination |
facility_type | XDS Destination |
fail_on_body | HTTP Destination |
fault_is_success | SOAP Destination |
fault_on_nak | SOAP Source |
fhir | Destination |
file | Contract Ref, Source |
file_name | AS2 Destination, Destination, Document Destination, FTP Destination, PGP Send, SFTP Destination |
file_roots | Scripts |
filter | Channel, Delimited, Destination, HL7v3 Options, Scripts |
flow_control | Serial Source |
follow_redirects | HTTP Destination |
follow_symlinks | File Source |
font_size | Document Destination |
format | Document Destination, S3 Destination |
framed | Azure Blob Source, FTP Destination, File Poll, GCS Source, S3 Destination, S3 Source, SFTP Destination, SFTP Source |
framing | TCP Framing |
from | AS2 Destination, SMTP Destination |
from_beginning | Kafka Source |
ftp | Destination, Source |
gcs | Destination, Source |
group | Channel, Kafka Source |
group_by | SNS Destination, SQS Destination |
has_header | Delimited |
header | SOAP Destination |
headers | Broker Destination, CDA Destination, DICO Mweb Destination, FHIR Destination, HTTP Destination, Kafka Destination, SOAP Destination, XDS Destination |
heartbeat | Broker Source |
hl7v3 | Channel |
host | Broker Destination, Broker Source, Direct IMAP, Email Source, FTP Destination, FTP Source, SFTP Destination, SFTP Source, SMB Source, SMTP Destination |
hostname | AMQP Connection |
http | Destination, Source |
ibm_mq | Destination, Source |
id | AS2 Partner, AS2 Source |
id_type | MPI Destination |
identifier_systems | CDA Destination, FHIR Destination |
idle_timeout | DICOM Source, Source, TCP Source |
ignore | Shadow |
imap | Direct Source |
include | Scripts |
include_trigger_event | Ack |
insecure_skip_host_key_check | SFTP Destination, SFTP Source |
insecure_skip_verify | FTP Destination, FTP Source, SMTP Destination, Web DAV Source |
interval | DICOM Query Source |
javascript | Destination, Source |
kafka | Destination, Source |
keep_alive | TCP Dest |
keep_blank_lines | Delimited |
keep_delimiter | TCP Framing |
key | Azure Blob Access, Kafka Destination, S3 Destination |
key_column | Database Source |
key_file | AS2 Destination, AS2 Source, Direct Address, SFTP Destination, SFTP Source |
key_passphrase | SFTP Destination, SFTP Source |
known_hosts_file | SFTP Destination, SFTP Source |
landscape | Document Destination |
language | Scripts |
ldap | Direct Destination |
length_bytes | TCP Framing |
length_includes_header | TCP Framing |
level | DICOM Query Source |
limit | DICOM Query Source |
line | ECR Facility |
listen | AS2 Source, DICO Mweb Source, DICOM Source, Direct Source, Direct XDR, HTTP Source, SOAP Source, Source, TCP Source |
login | Broker Destination, Broker Source |
mailbox | Direct IMAP, Email Source |
match | DICOM Query Source |
max_attempts | Database Source, Queue Config |
max_backoff | Queue Config, Retry |
max_bytes | Direct Source |
max_connections | Source, TCP Source |
max_depth | Queue Config |
max_differences | Shadow |
max_file_size | File Poll, SFTP Source |
max_message_size | AS2 Source, Email Source, HTTP Source, Kafka Source, SOAP Source, Serial Source, Source, TCP Dest, TCP Source |
max_messages | Pub Sub Source, SQS Source |
max_object_bytes | DICO Mweb Source, DICOM Source |
max_object_size | Azure Blob Source, GCS Source, S3 Source |
max_open_conns | Database Destination |
mechanism | Kafka SASL |
method | HTTP Destination |
move_to | Azure Blob Source, Direct IMAP, Email Source, File Poll, GCS Source, S3 Source, SFTP Source |
mpi | Destination |
mqtt | Destination, Source |
name | Channel, Channel Destination, Destination, ECR Facility |
ncpdp | Channel |
no_compress | PGP Send |
no_merge | MPI Destination |
non_persistent | IBMMQ Destination |
npi | ECR Facility |
oauth | Email Source |
object | GCS Destination |
on_no_document | CDA Destination |
order_by | Pub Sub Destination |
over | Contract Ref |
overlap | DICOM Query Source |
params | Database Destination |
parity | Serial Source |
partner_cert_file | AS2 Destination |
partners | AS2 Source |
pas | Destination |
pass_plain | PGP Receive |
passcode | Broker Destination, Broker Source |
passphrase | PGP Receive, PGP Send |
password | AMQP Connection, AS2 Destination, DICO Mweb Destination, DICO Mweb Source, Direct Destination, Direct IMAP, Direct Source, Email Source, HTTP Destination, IBMMQ Connection, Kafka SASL, MQTT Connection, SFTP Destination, SFTP Source, SMB Source, SMTP Destination, SOAP Destination, SOAP Source, Web DAV Source, XDS Destination |
path | AS2 Source, DICO Mweb Source, HTTP Source, SOAP Source |
path_style | S3 Destination, S3 Source |
patient_domain | XDS Destination |
patient_root | DICOM Query Source |
pattern | File Poll, SFTP Source |
payer | PAS Destination |
persistent | Broker Destination |
pgp | Destination, Source |
phone | ECR Facility |
poll_interval | Azure Blob Source, Database Source, Direct IMAP, Email Source, File Poll, GCS Source, IBMMQ Source, Java Script Source, S3 Source, SFTP Source |
port | Direct IMAP, Email Source, Serial Source |
postal_code | ECR Facility |
postprocessor | Scripts |
practice_setting | XDS Destination |
prefetch | AMQP Source |
prefix | Azure Blob Source, GCS Source, S3 Source |
preprocessor | Scripts |
profile | SOAP Destination, SOAP Source |
project | GCP Access |
protocol | Email Source |
provider | Email O Auth |
pubsub | Destination, Source |
purpose | TEFCA Destination |
qos | MQTT Connection |
query | Database Source |
query_timeout | Database Source |
queue | Destination, IBMMQ Connection |
queue_manager | IBMMQ Connection |
queue_url | SQS Destination, SQS Source |
quiet_after | Serial Source |
quote | Delimited |
raw | File Poll |
rctc | ECR Destination, ELR Destination |
read_timeout | HTTP Source, SOAP Source |
reassemble | Attachments |
receipt | AS2 Destination |
receipt_url | AS2 Destination |
recipient_certs_dir | Direct Destination |
reconnect | AMQP Source, Broker Source, MQTT Source, Pub Sub Source |
record_length | TCP Framing |
refresh_token | Email O Auth |
region | AWS Access, FHIR Auth, S3 Destination |
reject_on_warning | FHIR Destination |
relaxed | Delimited |
reopen_after | Serial Source |
reply | Serial Source, TCP Source |
reply_text | Serial Source, TCP Source |
request_mdn | Direct Destination |
require_agreement | CDA Destination |
require_signature | PGP Receive |
response_element | SOAP Source |
response_namespace | SOAP Source |
response_transformer | Destination |
results_to | PAS Destination, TEFCA Destination |
retain | MQTT Destination |
retain_hours | Destination, Queue Config |
retry | Destination |
return | DICOM Query Source |
root | FTP Source, File Source, SMB Source |
s3 | Destination, Source |
sample | Shadow |
sas | Azure Blob Access |
sasl | Kafka Destination, Kafka Source |
scheme | XDS Code |
scope | Email O Auth, FHIR Auth |
script | Channel, Java Script Destination, Java Script Source |
scripts | Channel |
secret_access_key | AWS Access, FHIR Auth, S3 Destination |
security | Direct IMAP, Email Source, FTP Destination, FTP Source |
selector | Broker Source |
sender_device | HL7v3 Options |
sender_oid | HL7v3 Options |
serial | Source |
server_side_encryption | S3 Destination |
session_timeout | Kafka Source |
session_token | AWS Access, FHIR Auth, S3 Destination |
sftp | Destination, Source |
shadow | Channel |
share | SMB Source |
sign_with | PGP Send |
smb | Source |
smtp | Destination |
smtp_host | Direct Destination, Direct Source |
sns | Destination |
soap | Destination, Source |
sop_classes | DICOM Source |
sort_by | File Poll |
source | Channel, ECR Destination |
source_id | XDS Destination |
split | Delimited, EDIFACT Options, X12 Options |
sqs | Destination, Source |
ssn_system | MPI Destination |
stable_for | File Poll, SFTP Source |
start_block | TCP Framing |
starttls | SMTP Destination |
state | ECR Facility |
statement | Database Destination |
stop_bits | Serial Source |
storage_class | GCS Destination, S3 Destination |
subject | AS2 Destination, Direct Destination, SMTP Destination, SNS Destination |
subscription | Pub Sub Source |
subscription_id | Broker Source |
success_on_undefined | Java Script Destination |
success_status | HTTP Destination |
suffix | Azure Blob Source, GCS Source, S3 Source |
tables | Channel |
take | Email Source |
tcp | Destination, Source |
tefca | Destination |
temp_suffix | Destination, Document Destination, FTP Destination, SFTP Destination |
template | Database Source, Document Destination |
tenant | Email O Auth |
tenant_id | FHIR Auth |
text | Direct Destination |
tier | Azure Blob Destination |
timeout | AMQP Connection, Broker Destination, Broker Source, DICO Mweb Destination, DICOM Destination, DICOM Query Source, Database Destination, Destination, Direct Destination, Document Destination, FTP Destination, FTP Source, IBMMQ Connection, Java Script Destination, Java Script Source, Kafka Destination, Kafka Source, MQTT Connection, S3 Destination, SFTP Destination, SFTP Source, SMB Source, SMTP Destination, SOAP Destination, Scripts, Shadow, TCP Dest, Web DAV Source, XDS Destination |
timezone | FHIR Destination |
title | Document Destination |
tls | AMQP Connection, AS2 Destination, AS2 Source, Broker Destination, Broker Source, DICO Mweb Destination, DICO Mweb Source, DICOM Destination, DICOM Query Source, DICOM Source, Destination, Direct IMAP, Email Source, HTTP Destination, HTTP Source, IBMMQ Connection, Kafka Destination, Kafka Source, MQTT Connection, SOAP Destination, SOAP Source, Source, TCP Dest, TCP Source, XDS Destination |
tls_cert | Direct Source, Direct XDR |
tls_key | Direct Source, Direct XDR |
to | AS2 Destination, Direct Destination, SMTP Destination |
token | DICO Mweb Destination, DICO Mweb Source, HTTP Source, SOAP Source, XDS Destination |
token_url | Email O Auth, FHIR Auth |
topic | Kafka Destination, MQTT Destination, MQTT Source, Pub Sub Destination |
topic_arn | SNS Destination |
topics | Kafka Source |
transfer_syntaxes | DICOM Destination, DICOM Source |
transformations | Channel, DICOM Options, Delimited, HL7v3 Options, NCPDP Options, Script Options, X12 Options |
transformer | Scripts |
trim_padding | TCP Framing |
trim_space | Delimited |
type | Destination, FHIR Auth, Source |
undeploy | Scripts |
unencrypted | AS2 Destination |
unsigned | AS2 Destination |
unsigned_receipt | AS2 Destination |
url | AS2 Destination, CDA Destination, DICO Mweb Destination, FHIR Destination, HTTP Destination, IBMMQ Connection, SOAP Destination, Web DAV Source, XDS Destination |
user | FTP Destination, FTP Source, SFTP Destination, SFTP Source, SMB Source, Web DAV Source |
username | AMQP Connection, AS2 Destination, DICO Mweb Destination, DICO Mweb Source, Direct Destination, Direct IMAP, Direct Source, Email Source, HTTP Destination, IBMMQ Connection, Kafka SASL, MQTT Connection, SMTP Destination, SOAP Destination, SOAP Source, XDS Destination |
validate_before_send | FHIR Destination |
verify_with | PGP Receive |
version | CDA Destination, FHIR Destination, SOAP Destination, SOAP Source |
visibility_timeout | SQS Source |
wait_seconds | SQS Source |
warnings_are_errors | SOAP Destination |
webdav | Source |
when | Ack |
window | DICOM Query Source |
write | CDA Destination |
wsdl | SOAP Source |
x12 | Channel |
x12_as | Destination |
xdm | Direct Destination |
xdm_source_id | Direct Destination |
xdr | Direct Source |
xds | Destination |