1 Einführung

Perfuse überträgt klinische Nachrichten zwischen Systemen, die nie dafür konzipiert wurden, miteinander zu sprechen. Ein Labor sendet Ergebnisse in HL7 v2; das Praxismanagementsystem erwartet sie mit unterschiedlichen Feldpositionen, einem anderen Patientenidentifikator und einer Bestätigung innerhalb von fünf Sekunden. Etwas muss in der Mitte sitzen, und das ist ein Integrationsmotor.

Dieses Handbuch beschreibt, was Perfuse tut, jede Option, die es akzeptiert, und – wo eine Entscheidung nicht offensichtlich ist – warum es so funktioniert.

1.1 Wofür Perfuse ist

Eine einzelne Schnittstelle zwischen zwei klinischen Systemen wird in der Regel mit Zehntausenden von Dollar berechnet, mit 15 bis 20 Prozent davon pro Jahr für Wartung. Ein großer Teil dieser Kosten ist nicht die Arbeit; es ist, dass die Arbeit jemanden erfordert, der bereits Erfahrung mit HL7 hat, und die meisten Praxen beschäftigen niemanden damit.

Perfuse basiert auf der Annahme, dass die Person, die es konfiguriert, ein Problem zu lösen hat und keine vorherige HL7-Erfahrung hat. Diese Annahme zeigt sich an bestimmten Stellen:

Das Kapitel über Testen und das über Migration existieren, weil die Antwort auf „Warum sollte ich diesem vertrauen“ Beweise sein müssen, die Sie selbst sammeln, und nicht ein hier gemachter Anspruch.

1.2 Was drin ist

Alles unten ist in einer einzigen Binärdatei enthalten. Jede Zeile nennt das Kapitel, das es abdeckt.

1.3 Standards und Versionen

Welche Version jedes Standards Perfuse implementiert und wie diese überprüft wurde. „Überprüft“ nennt das externe Tool oder die Referenz, die das Ergebnis beurteilt hat; wenn nichts Externes beurteilt wurde, wird dies angegeben. Die Ergebnisse stammen aus Testdaten, nicht aus einer Produktionsstätte.

1.3.1 Nachrichten und Dokumente

StandardVersionÜberprüft
HL7 v2jede Version: Nachrichten werden durch ihre eigenen Trennzeichen gelesen, nicht durch ein Versions-Schema; Bestätigungen standardmäßig 2.5.1NIST HL7 v2-Validator; echter Mirth- und OIE-Verkehr
HL7 v2 zu FHIRHL7s V2-zu-FHIR-Mapping (ADT, ORU, SIU, MDM, VXU und die Segmente in ihnen)der HL7 FHIR-Validator gegen US Core, UK Core, FR Core, ISiK, nl-core und HL7 Europe
FHIRR4 (4.0.1), mit R4B und R5 lesbar und schreibbarder HL7 FHIR-Validator; Inferno
C-CDA und CDAC-CDA 2.1ONC-SITE (C-CDA-Beispiele gesendet und empfangen über XDR); nicht durch ein CDA-Schematron
HL7 v3PIX und PDQ (IHE ITI-44, 45, 47)IHEs NE2008-Schemata und Beispielnachrichten
DICOM und DICOMwebDIMSE C-STORE, C-FIND, C-MOVE, C-GET, C-ECHO; QIDO-RS, WADO-RS, WADO-URI, STOW-RSOrthanc
X12 (HIPAA)005010: 837, 835, 270/271 (X279A1), 276/277 (X212), 834, 278-Anfrage (X217) und Anfrage (X215); 275 in 006020 (X314)Zahler-Veröffentlichungen; CMS esMD-Beispiele
CAQH CORE-KonnektivitätvC2.2.0 SOAP und MIME, vC4.0.0 mit MTOMein Ersatz-UM-System, das aus CAQHs Regeln erstellt wurde
NCPDPTelekommunikation D.0; SCRIPT 2023011 (und 2017071) mit ePA; Echtzeit-Rezeptvorteil v13aus den öffentlichen Surescripts-Beispielen und deren Begleitdokumentation; nicht gegen NCPDPs lizenzierte Schemata
UN/EDIFACTSyntax 3 und 4, CONTRLpydifact 0.1.8
IHE-DokumentfreigabeXDS.b, XCA, XDR, MHD 4.2.2, PIXm, PDQm, XDMdas NIST XDS-Toolkit; ONC-SITE
Direktes sicheres MessagingAnwendungsstatement 1.2, XDR und XDM für Direkt, DNS- und LDAP-ZertifikatserkennungONC-SITE; ONCs Zertifikatserkennungstool (18 von 18)
AS2RFC 4130, Komprimierung RFC 5402pyas2lib
Signierte AnlagenHL7 DSDR, XAdES-X-Lxmlsec1, OpenSSL

1.3.2 FHIR-Implementierungsleitfäden

LeitfadenReleaseÜberprüft
US CoreUmstellungen auf 9.0.0 (USCDI v6); FHIR-Server gegen 6.1.0 und 7.0.0der HL7-Validator; Inferno US Core
SMART App Launch2.2Inferno: 80 von 80 (öffentliche App)
Bulk Data Access2.0.0Inferno: 48 von 48
Abonnements R5 Backportfür R4ein echter HTTP-Empfänger; die Benachrichtigungstests des PAS-Kits
Da Vinci CRD2.2.1 und 2.1.0Inferno 2.2.1: 92 bestanden, keine fehlgeschlagen; 2.1.0 durch die eigenen Beispiele des Leitfadens
Da Vinci DTR2.2.0 und 2.1.0Inferno 2.2.0: 43 bestanden, 2 fehlgeschlagen (ein Kit-Defekt); 2.1.0 durch die eigenen Beispiele des Leitfadens
Da Vinci PAS2.2.1 und 2.1.0Inferno 2.2.1: 82 von 84; 2.1.0 durch die eigenen Beispiele des Leitfadens
Da Vinci PAS, senden (Anbieterseite)2.2.1die HL7-Da-Vinci-PAS-Payer-Referenzimplementierung; kein Produktionspayer
Da Vinci PDex2.2.0Inferno PDex 2.0: Payer-to-Payer 19 von 19
Da Vinci HRex $member-match1.2.0Inferno PDex Payer-to-Payer
Da Vinci ATR2.1.0nicht durch ein externes Tool überprüft
Da Vinci CDex $submit-attachment2.1nicht durch ein externes Tool überprüft
Da Vinci Plan-Net1.1.0Inferno: 199 bestanden, 10 fehlgeschlagen (ein Kit-Defekt)
Da Vinci US Drug Formulary2.1.0der HL7-Validator
ISiK (deutsche Krankenhäuser), FHIR-ServerStufe 5, Basis-Modulgematik's ISiK-Test-Suite 3.0.9: 421 von 421
PACIO Transitions of Care, Medication Profile, Advance Directives, Functioning1.0.0, 1.0.0, 2.0.0-Ballot, 2.0.0PACIO's Inferno-Kits mit PACIO-eigenen Daten: jeder Fehler in den Daten oder dem Kit. C-CDA zu TOC-Dokument: der HL7-Validator auf HL7-Beispielen, ein Fehler übrig, die eigenen des Leitfadens
CARIN Blue Button2.2.0der HL7-Validator
eCR2.1.2der HL7-Validator
ELRHL7 2.5.1 ELR Release 1 mit seinen ErrataONC's ELR-Tool: 28 von 28
International Patient Summary2.0.0der HL7-Validator
DEQM5.0.0der HL7-Validator
SQL on FHIRv2die offizielle Test-Suite: 144 von 144
SMART Health Cards und LinksCards 1.4, Links STU 1die eigenen Beispiele der Spezifikationen; eine veröffentlichte SMART Health Links-Bibliothek
UDAP SecuritySTU 1ein echter Autorisierungsserver und Vertrauensgemeinschaft
TEFCA Facilitated FHIRSOP v2.0nicht gegen einen echten QHIN überprüft

1.3.3 Nationale und europäische Profile

Überprüft durch Umwandlung veröffentlichter oder erfundener HL7-v2-Nachrichten und Validierung jeder Ressource; die vollständigen Ergebnisse und die Gründe für jedes Versagen befinden sich im Repository-Ordner conformance/national.

ProfilReleaseRessourcen gültig
UK CoreSTU2 2.0.2185 von 187
FR Core2.2.0138 von 156
ISiK Basismodul4.0.3 (Stufe 4)18 von 47; 42 von 47 mit dem eigenen Bundle-Skript des Krankenhauses
Nictiz nl-core0.12.1-beta.1 (zib 2020)12 von 24; 18 von 24 mit dem eigenen Bundle-Skript des Krankenhauses
HL7 Europe Laboratory Report2.1.0106 von 426 (die Anleitung erwartet ein Dokument, ein v2-Ergebnis ist nicht)
HL7 Europe Hospital Discharge Report1.0.068 von 69

Keines davon ist eine Zertifizierung. Perfuse wurde nicht von ONC, CMS, gematik, Nictiz, NHS England oder einer anderen Stelle zertifiziert.

1.4 Was es ersetzt

Perfuse deckt den Boden ab, den Mirth Connect hält, und kann Mirth-Kanal-Exporte direkt importieren. Das Kapitel über Migration beschreibt, was sauber übersetzt wird, was eine Entscheidung erfordert und wie man den Nachweis erbringen kann, dass das Ergebnis vor dem Umstieg übereinstimmt.

Die Unterschiede, die in der täglichen Verwendung zählen, sind Fehlerbehebung und Stille. In Mirth bedeutet das Anzeigen, was ein Transformer mit einer Nachricht gemacht hat, in der Regel, den Kanal mit hinzugefügtem Logging neu zu bereitstellen. In Perfuse kann jede aufgezeichnete Nachricht durch die aktuelle Konfiguration abgespielt und Schritt für Schritt untersucht werden, ohne den laufenden Kanal zu berühren. Und wo in Mirth eine Warnung auf „keinen Verkehr“ ein fester Schwellenwert ist, der auf jedem Feed, der nachts ruhig ist, nutzlos ist, lernt Perfuse, wie jede Feed normalerweise aussieht, und warnt dagegen.

1.5 Wie man dieses Handbuch liest

Die ersten Kapitel sind konzeptionell und sollten in der Reihenfolge gelesen werden: Kanäle, Nachrichtenfluss, dann Transformation. Alles danach kann wie benötigt gelesen werden.

Die Referenzkapitel am Ende listen jeden Konfigurationsschlüssel, seinen Typ, ob er erforderlich ist und seinen Standardwert auf. Diese Kapitel werden aus der Quelle generiert, daher können sie keine Option beschreiben, die nicht existiert, oder eine auslassen, die existiert. Wenn ein Schlüssel in einer Konfigurationsdatei erscheint und nicht im Index aufgeführt ist, ist er kein Perfuse-Schlüssel.

1.6 Konventionen

Die Konfiguration erfolgt in YAML. Die meisten Schlüssel sind snake_case auf dem Draht — max_message_size, idle_timeout — und dieses Handbuch gibt immer die Drahtform an, da dies der Teil ist, den Sie eingeben. Es gibt eine langjährige Ausnahme, dataType auf einem Kanal, der camelCase ist; er wird auf diese Weise im Kanalexemplar dokumentiert und nur in dieser Schreibweise akzeptiert.

Feldreferenzen in HL7 verwenden die übliche Notation: PID-5 ist das fünfte Feld des PID-Segments, PID-5.1 sein erster Bestandteil und PID-3(2) die zweite Wiederholung des dritten Feldes. Ein Pfad, der ohne Wiederholung geschrieben wird, adressiert jede Wiederholung (siehe Pfade).

Dauern werden als Zahl und Einheit geschrieben — 30s, 5m, 2h. Eine nackte Zahl ist keine Dauer und wird abgelehnt, anstatt geraten zu werden.

2 Erste Schritte

Perfuse ist ein einzelnes Binärprogramm mit einer eingebetteten Web-Oberfläche. Es muss kein Anwendungsserver installiert, keine Datenbank bereitgestellt und keine separate Administrationskonsole eingerichtet werden.

2.1 Ausführen

perfuse serve -channels ./channels -db ./perfuse.db -addr 0.0.0.0:8443 \
  -tls-cert ./cert.pem -tls-key ./key.pem

-channels ist ein Verzeichnis von YAML-Dateien, eine pro Kanal. -db ist eine SQLite-Datei, die aufgezeichnete Nachrichten, Benutzer und Audit-Verlauf enthält; sie wird erstellt, wenn sie nicht existiert.

Beim ersten Start ohne konfigurierte Benutzer wird ein Administratorkonto erstellt und sein Passwort einmal im Logbuch geschrieben. Dieses Passwort kann später nicht wiederhergestellt werden.

Ohne -tls-cert und -tls-key wird plain HTTP verwendet. Das ist auf einer Loopback-Adresse für einen ersten Blick akzeptabel und anderswo nicht akzeptabel: die Web-Oberfläche enthält Anmeldeinformationen und Nachrichteninhalte, die beide ohne TLS im Klartext lesbar sind. Siehe Sicherheit.

2.2 Der erste Kanal

Ein Kanal benötigt einen Namen, eine Quelle und mindestens ein Ziel. Der kleinste nützliche Kanal empfängt HL7 über MLLP und schreibt jede Nachricht in eine Datei:

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

Speichern Sie dies als channels/first-feed.yaml und es wird ohne Neustart aufgenommen.

Drei Dinge in dieser Datei sind bemerkenswert, weil sie die Form jedes Kanals darstellen:

2.3 Erstellen eines Kanals aus der Oberfläche

Alles oben kann auch über die Web-Oberfläche durchgeführt werden, und für den ersten Kanal ist dies der bessere Weg, da das Formular nicht zulässt, dass eine Datei erstellt wird, die nicht geladen werden kann.

Der Ersteller bietet drei Möglichkeiten:

  1. Aus einer Nachricht, die Ihnen jemand geschickt hat. Fügen Sie die Probe ein, die das Labor oder der Hersteller per E-Mail geschickt hat. Perfuse liest sie und schlägt einen Kanal vor, zusammen mit drei separaten Listen: was die Probe zeigt, was erraten wurde und was keine Probe sagen kann. Dies wird im Testen beschrieben.
  2. Aus etwas, das bereits funktioniert. Eine Reihe von vollständigen Kanälen, die nur ihre Adressen benötigen.
  3. Aus nichts. Ein leeres Formular. Verfügbar, aber dies ist der langsamste der drei und der einfachste, um Fehler zu machen.

2.4 Überprüfen, ob es funktioniert, bevor etwas verbunden wird

Zwei Dinge können vor dem Vorhandensein des sendenden Systems durchgeführt werden.

Senden Sie eine Nachricht manuell von der Oberfläche — der Nachrichtensender akzeptiert eingefügten Text und berichtet, was mit ihr passiert ist, einschließlich der Ziele, die sie akzeptiert haben, und was jede Transformation getan hat.

Oder erzeugen Sie Testverkehr. Wenn der Kanal überhaupt Nachrichten bearbeitet hat, kann Perfuse ihre Form erlernen und ähnliche Nachrichten in den gleichen Proportionen erzeugen, ohne den ursprünglichen Inhalt. Siehe Testen.

2.5 Was als Nächstes zu tun ist

3 Die Web-Oberfläche

Perfuse basiert auf der Annahme, dass alles über den Browser erledigt werden kann, und eine Funktion, die nur durch Bearbeiten einer Datei erreicht werden kann, als Fehler behandelt wird. Dieses Kapitel ist eine Tour durch das, was hinter jedem Teil der Navigation steckt, organisiert nach der Art, wie die Oberfläche ist: nach der Frage, die Sie stellen.

Die Leiste enthält Dashboard und Kanäle direkt, da dies die Punkte sind, an denen die meisten Sitzungen beginnen und enden. Alles andere ist gruppiert, und die Gruppen sind nach Fragen benannt, anstatt nach Subsystemen - Sie gehen nicht zum "Audit-Subsystem", sondern suchen heraus, wer etwas geändert hat.

3.1 Lesen des Headers

Fünf Dinge im Header sind leicht zu übersehen.

Jede Ansicht hat eine Adresse. Die Adresszeile folgt der Ansicht — #/channels, #/messages, #/settings —, sodass ein Neuladen zur gleichen Ansicht zurückkehrt, ein Lesezeichen diese öffnet, ein an einen Kollegen gesendeter Link ihn direkt auf dieser Ansicht landen lässt und die Zurück-Schaltfläche zwischen Ansichten wechselt, anstatt die Konsole zu verlassen. Eine Adresse, die eine Ansicht über Ihrer Rolle benennt, öffnet stattdessen das Dashboard.

Suche, oder ⌘K. Sie sucht über Kanäle, Einstellungen, Nachrichten und das Handbuch, was bedeutet, dass sie in der Regel schneller ist als die Navigation - insbesondere für eine Einstellung, deren Namen Sie halb erinnern.

Design. Drei davon: Midnight, Dark und Light. Midnight ist nahezu schwarz und ist das, was eine Wandanzeige in einem Serverraum normalerweise möchte; Dark ist ein weicheres neutrales Grau; Light ist für ein Laptop neben einem Fenster. Die Wahl wird im Browser und nicht gegen das Konto gespeichert, da ein Design eine Eigenschaft des Ortes ist, an dem sich jemand befindet, und nicht der Person - der gleiche Bediener möchte Midnight an der Wand und Light im Zug. Die eigene Präferenz einer Maschine wird einmal abgefragt, um eine sinnvolle Voreinstellung beim ersten Mal zu wählen.

Sprache. Die Konsole ist in Englisch (UK- oder US-Datumsformat), Deutsch, Französisch, Niederländisch, Spanisch, Italienisch, Portugiesisch, Polnisch, Schwedisch, Dänisch, Norwegisch oder Finnisch verfügbar, mit Datums- und Zahlenformaten, die der jeweiligen Region entsprechen. Die Auswahl wird im Browser gespeichert, und die Sprache des Browsers wird verwendet, bis eine Auswahl getroffen wird. Die Übersetzungen wurden maschinell erstellt und noch nicht von Muttersprachlern überprüft; Englisch ist die Referenzsprache, und der Sprachauswahlschalter weist darauf hin. Code, Nachrichten, Payloads, Kanalnamen und alles, was eingegeben wird, werden nie übersetzt. Das Handbuch wird in den gleichen Sprachen unter https://perfuse.health/manual/<language>/ veröffentlicht (das eigene Handbuch dieses Servers ist das englische).

Handbuch. Das Dokument, das Sie lesen, wird vom laufenden Server bereitgestellt. Es ist die gleiche Datei, die die Binärdatei auf die Festplatte schreiben kann, so dass es immer die Version beschreibt, die vor Ihnen liegt, und nicht die neueste Version.

3.2 Überwachung - ob es funktioniert und was passiert ist

3.2.1 Dashboard

Der Zustand jedes Kanals, die Durchsatzrate und alles, was derzeit falsch ist. Dies ist der Bildschirm, der geöffnet bleiben sollte.

3.2.2 Nachrichten

Jede Nachricht, die angekommen ist, was sie in jede Zieldestination umgewandelt wurde, und was mit ihr passiert ist. Durchsuchbar, einschließlich mit einem Filterausdruck, so dass "zeigen Sie mir die, die von diesem Absender stammen und abgelehnt wurden" eine Abfrage und kein Nachmittag ist.

Eine Nachricht kann von hier aus erneut abgespielt und mit der *aktuellen* Konfiguration neu verarbeitet werden, anstatt mit der Konfiguration, die zum Zeitpunkt des ursprünglichen Versands aktiv war — was Ihnen ermöglicht, zu bestätigen, ob eine Korrektur gegen den Datenverkehr funktioniert, der ursprünglich zum Fehler geführt hat. Weitere Informationen zu den gespeicherten Daten und der Speicherdauer finden Sie im Nachrichtenspeicher.

3.2.3 Warteschlange

Was zur Auslieferung ansteht und warum. Eine Queue, die nicht abfließt, ist die nützlichste frühzeitige Warnung, die ein Integrationsmotor produziert, und es lohnt sich, sie mit einer Warnregel zu kombinieren, damit niemand ständig überwachen muss. Siehe delivery.

3.2.4 Alarme

Was ausgelöst wurde und was die Regeln sind. Regeln werden hier bearbeitet und nicht in einer Datei. Siehe alerting.

3.2.5 Metriken

Durchsatzrate, Latenz und Fehlerquoten im Laufe der Zeit. Nützlich für Kapazitätsfragen und, häufiger, für Board-Packs - daher erscheint das Logo der Website auf ihm, wenn eines hochgeladen wurde.

3.2.6 SQL auf FHIR

SQL auf FHIR-Ansichten: Wählen Sie ein Beispiel oder eine gespeicherte Ansicht, schreiben Sie eine eigene, führen Sie sie über den FHIR-Speicher dieses Servers (alle Patienten oder einen) oder über pastete Ressourcen aus, sehen Sie die Zeilen mit ihren Typen und laden Sie sie als CSV, NDJSON oder Parquet herunter. Speichern bewahrt sie für den FHIR-Endpunkt $sql-run. Siehe Nachrichtenformate.

3.2.7 Qualitätsmaße

Digitale Qualitätsmaßnahmen: Wählen Sie ein Beispiel oder ein Maß im FHIR-Speicher aus, oder schreiben Sie eines mit FHIRPath-Kriterien. Wählen Sie einen Messzeitraum und einen Bericht (Zusammenfassung, Zusammenfassung mit Patientenlisten oder einen Patienten) und bewerten Sie ihn über den FHIR-Speicher oder eingefügte Ressourcen. Der Bildschirm zeigt die Anzahl und Patienten jeder Population, den Score und die Schichten an. Maßnahmenbericht herunterladen speichert das FHIR-Ergebnis, und In den FHIR-Speicher speichern behält das Maß für Measure/$evaluate-measure bei. Maßnahmen in CQL werden abgelehnt: Perfuse verfügt über keine CQL-Engine. Siehe digitale Qualitätsmaßnahmen.

3.2.8 Flussdiagramm

Ein Bild davon, wie Nachrichten tatsächlich fließen: welche Quellen welche Kanäle speisen und welche Ziele sie erreichen.

Sein Wert ist nicht nur Dekoration. Jedes Anwesen sammelt einen Kanal, den niemand mehr in Erinnerung hat, und ein Ziel, das niemand mehr realisiert hat, und beides ist hier auf eine Weise sichtbar, die es in einer Liste von Kanaldateien nicht ist.

3.2.9 Team-Dashboards

Ein Dashboard für jede Art von Person, die die Schnittstellen überwacht: Betrieb, Verbindungen, Schnittstellenanalyst, Vorabgenehmigung, Bildgebung, Rechnungskreislauf, Labor, Datenschutz und Sicherheit sowie eine einfache Zusammenfassung der Abteilung. Kacheln zeigen Zahlen, Zustände und Zeiten, niemals eine Nachricht oder einen Patienten, sodass ein Dashboard an einen Manager oder einen Bildschirm weitergegeben werden kann, ohne dass die Anzahl der Personen, die Patientendaten sehen, erhöht wird.

Jede Person öffnet das Dashboard, das ihrer Verzeichnisgruppe oder Rolle zugewiesen ist. -dashboards dashboards.yaml ordnet sie zu:

groups: {PACS-Admins: imaging, Network-Team: connections}
roles: {viewer: manager}

Eine Gruppe gewinnt über eine Rolle, und jeder, der nicht übereinstimmt, öffnet den Betrieb. Kacheln anordnen versteckt und ordnet Kacheln neu, der Kanal-Auswahlfeld filtert sie, und Als meine Ansicht speichern bewahrt diese als Ihre eigene Dashboard-Vorlage, bis Zurücksetzen.

Exportieren nach Grafana lädt das Dashboard als Grafana-JSON über /metrics herunter, mit einer Datenquellenvariable und einem Kanalfilter, für jeden, der mehr als eine leichte Konfiguration benötigt. Kacheln ohne Metrik werden weggelassen, und die Exportbeschreibung benennt sie.

Die Verbindungen-Kachel überprüft jeden vernetzten Zielort in Schichten. Sie sucht den Namen auf, öffnet eine TCP-Verbindung, vervollständigt TLS, wo es verwendet wird, und liest die letzte Lieferung und den letzten Fehler des Zielorts aus dem echten Datenverkehr. Jeder Fehler sagt, was er bedeutet, z. B. „abgelehnt: Der Partner-Engine ist wahrscheinlich gestoppt“, „Zeitüberschreitung: Ein Firewall oder ein VPN-Tunnel, der down ist“ oder „Ein Zertifikat von einer Autorität, der dieser Server nicht vertraut“. Nichts wird an den Partner gesendet, mit einer Ausnahme: Ein Impfregister, das in den letzten sieben Tagen keinen Datenverkehr hatte, wird nach seinem CDC connectivityTest gefragt, der nichts sendet. Mit -vpn tunnels.yaml liest die VPN-Tunnel-Kachel neben ihr den Zustand jedes Partner-Tunnels von AWS Site-to-Site VPN, einer Azure VPN-Gateway-Verbindung oder strongSwan auf diesem Host, sodass eine Zeitüberschreitung von einem Tunnel, der down ist, unterschieden werden kann. Sie vergleicht auch die IKE- und IPsec-Einstellungen beider Seiten, da die Cloud unsere und die Datei ihre auflistet, und sagt, wo sie nicht übereinstimmen. Verbindungsbogen lädt die Einstellungen eines Partners side by side als Markdown herunter, um sie zu senden; sie enthält niemals einen gemeinsam genutzten Schlüssel. Zahlen, die ein Dashboard benötigt, die noch nicht aufgezeichnet sind, werden unter Noch nicht gemessen aufgeführt, anstatt als leere Kacheln gezeichnet zu werden.

Die Fachbereichs-Dashboards berechnen ihre eigenen Zahlen auf dem Server, und jede sagt, welches Fenster und welche Quelle sie abdeckt:

3.2.10 Teilen, was ein Feed tatsächlich enthält

Diesen Feed profilieren berichtet, was wirklich ankommt: welche Trigger-Ereignisse, welche Felder sind bevölkert und wie oft, welche Formen die Werte annehmen, und welche Codes ein Absender tatsächlich verwendet. Letzteres ist normalerweise die nützlichste einzelne Tatsache darin.

Ein Profil kann heruntergeladen und an jemand anderen gesendet werden. Es benötigt einen Namen und — erforderlich — welches System den Feed produziert hat, weil die Frage, die ein Fremder einem geteilten Profil stellt, ist, ob es sein System beschreibt, und ein optionales Feld würde "Unbekannt" zur häufigsten Antwort in jeder geteilten Sammlung machen.

Es enthält keine Patientendaten, und das wird überprüft, anstatt angenommen. Ein Profil ist statistisch: Zahlen, Raten, Längen, Formen. Werte werden nur für Felder aufbewahrt, die der Standard als Code-Tabellen definiert, weil ein Code-Tabellen-Wert nicht identifizierend ist. Identifier-Werte werden nie aufgelistet.

Zwei Dinge ergeben sich daraus, dass es sich um ein Versprechen und nicht um eine Hoffnung handelt. Der Server baut das Profil aus den gespeicherten Nachrichten auf, wenn Sie es exportieren, anstatt das auf Ihrem Bildschirm angezeigte Profil zu senden - was also das Gebäude verlässt, wird vom Profiler erstellt, der einen Test hat, der diese Eigenschaft beweist, und nicht von einem Browser. Und der Export wird rundweg abgelehnt, wenn ein Profil jemals Werte für ein Feld auflistet, das kein Code-Tabelle ist, wobei das Feld, aber nicht die Werte, genannt werden.

Ein Profil, das von woanders kommt, wird auf dem Weg hierher auf die gleiche Weise überprüft, aus einem anderen Grund: Es wurde von jemandem erstellt, dessen Sorgfalt unbekannt ist, und die Anzeige der Patienten-Identifikatoren wäre eine Veröffentlichung durch diesen Server. Das Importieren ändert nichts - ein Profil beschreibt eine Datenquelle, und was damit zu tun ist, ist eine separate Entscheidung.

3.3 Erstellen - ändern Sie, was ein Kanal tut, und testen Sie es, bevor es live geht

3.3.1 Kanäle

Der Kanal-Ersteller. Quellen, Ziele, Filter, Transformationen, Skripte und Tests, wobei die generierte YAML-Datei neben dem Formular angezeigt wird, während Sie arbeiten - damit die Datei niemals ein Mysterium ist und jeder, der die Datei bevorzugt, mitlesen kann.

Siehe Kanäle für die Bestandteile und Transformation für die Schritte.

3.3.2 Skripte

Eine Arbeitsplatz für Skripte, getrennt vom Ersteller, weil das Schreiben eines Skripts und das Verbinden eines Skripts unterschiedliche Aktivitäten sind.

Alle sieben Slots werden angeboten - Filter, Transformer, Preprocessor, Postprocessor, Writer, Lifecycle und Reader - und die Auswahl des richtigen Slots ist wichtig, da der Slot entscheidet, was das Skript erhält und was es zurückgeben soll. Das Überprüfen eines Skripts als falsche Art ist kein Workaround; es kompiliert ein anderes Objekt.

JavaScript, Lua und WebAssembly sind verfügbar. Siehe Transformation.

3.3.3 Verträge

Erwartungen darüber, wie eine Feed aussehen muss, werden hier sowie von perfuse contract erstellt und überprüft. Siehe die Kommandozeile.

3.3.4 Tabellen

Lookup-Tabellen und Code-Sets: die Zuordnungen, die die Codes eines Systems in die eines anderen umwandeln. Hier bearbeitbar, damit das Hinzufügen eines Codes keine Bereitstellung ist.

3.3.5 AI-Mapper

Schlägt Feldzuordnungen mit einem Vertrauenswert für jede vor und enthält sich eher, als zu raten. Trotz des Namens verwendet es kein Sprachmodell und macht keinen Netzwerkauf ruf: Die Vorschläge kommen von Regeln, Feldnamen und dem Inhalt der Probe, auf diesem Server. Es schlägt auch einen Kanal aus einer einzelnen Beispielnachricht vor und gibt explizit an, was die Probe nicht sagen kann. Dieser zweite Teil ist der Teil, der es vertrauenswürdig macht - ein Vorschlag, der vollständig aussähe, würde Sie dazu einladen, Dinge zu glauben, die die Nachricht nie gesagt hat.

3.3.6 Spielplatz

Eine Scratchpad für Nachrichten und Transformationen. Fügen Sie eine Nachricht hinzu, wenden Sie Schritte an, sehen Sie das Ergebnis.

Nichts wird irgendwohin gesendet, sobald die Seite geladen wurde, was der Grund ist, warum es in dieser Form existiert: es ist sicher, etwas Reales hineinzufügen, unter der Annahme, dass es im Browser bleibt.

3.3.7 Schatten

Leitet den Datenverkehr durch eine Kandidatenkonfiguration neben der Live-Konfiguration und berichtet über die Unterschiede, sodass eine Änderung belegt werden kann, bevor sie als vertrauenswürdig gilt. Das gleiche Konzept wie perfuse compare, angewendet auf eine Änderung anstelle einer Migration. Siehe testing.

3.4 Austausch - die Standards, die dieser Server mit anderen Organisationen spricht

3.4.1 FHIR-Lab

Wandeln Sie HL7 v2 in FHIR um, überprüfen Sie eine Ressource und untersuchen Sie das Ergebnis. Die Proben umfassen Aufnahmen, Laborergebnisse, Termine, klinische Notizen, Impfungen und einen meldepflichtigen Besuch. Die Überprüfung umfasst US Core, das die amerikanische Regulierung gegen schreibt, sodass dies die Frage beantwortet, ob das, was sie uns geschickt haben, tatsächlich konform ist, ohne etwas zu übernehmen.

Öffentlicher Gesundheitsfallbericht erstellt den eCR eICR, den ein Fallberichtsziel für die Nachricht senden würde. Es zeigt an, welcher Trigger-Code den Besuchsbericht meldepflichtig gemacht hat, was der Bericht als fehlend markieren musste und das Dokument selbst. Eine Nachricht mit nichts Meldepflichtigem erhält stattdessen den Grund. Von hier aus wird nichts gesendet.

3.4.2 Abonnements

FHIR-Abonnements und ob deren Benachrichtigungen ankommen: Ereignisse, akzeptiert, wartend und der letzte Grund, warum eines abgelehnt wurde. Abonnements werden von FHIR-Clients über die FHIR-API erstellt, nicht von dieser Seite, und die Anmeldeinformationen, die sie dem Server gegeben haben, werden nie angezeigt. Siehe Nachrichtenformate.

3.4.3 Dokumente

Klinische Dokumente — CDA und die druckbare Form eines Dokuments. Nützlich, wenn das ausgetauschte Objekt eine Entlassungssummarie und nicht eine Nachricht ist.

3.4.4 Dokumentenfreigabe

Das IHE XDS.b-Register und -Repository, das mit -xds gestartet wurde: wie viele Dokumente, Patienten und Übermittlungssätze es enthält und wie viele ersetzt wurden; die Adressen des Repository, des Registers, des XCA-Gateways und von MHD; eine Suche nach den Dokumenten eines Patienten in diesem Register oder einem anderen (ein ITI-18-Register oder ein ITI-38-Gateway, mit einem Token dafür); und die manuelle Veröffentlichung eines CDA-Dokuments, mit dem Typ der Einrichtung und der Praxis, die ein Dokument nicht angibt. Siehe Nachrichtenformate.

3.4.5 Direkt

Direkte sichere Nachrichtenübermittlung. Diese Server-Adressen listet jede Adresse auf, die ein Kanal sendet oder empfängt, mit seinem Zertifikat, wenn es abläuft, den vertrauenswürdigen Anker und alles, was falsch ist (eine fehlende Datei, ein abgelaufenes Zertifikat). Das Adressbuch speichert Korrespondenten und die Zertifikate, mit denen ihre Nachrichten verschlüsselt sind: fügen Sie eines von ihrem HISP hinzu oder Speichern Sie es mit dem Zertifikat aus DNS; ein Zertifikat, das nicht für die Adresse oder deren Domäne ist, wird abgelehnt. Zertifikat in DNS finden fragt ohne Speichern. Siehe Nachrichtenformate.

SMART Health Links and Cards, for CMS's *Kill the Clipboard*. Receive a SMART Health Link reads the link or QR code a patient shows at check-in, verifies the health cards inside and sends it on to a channel. Share a visit record makes a link this server hosts, optionally with a passcode, and a QR code for the patient; Use their patient summary fills it with the patient's International Patient Summary from this server's FHIR store. Links this server hosts lists them with how often each was fetched, when it expires and the passcode tries left, and revokes one. Verify a SMART Health Card checks a card's signature and issuer on its own. See CMS-0057 for the server options it needs.

3.4.7 Bildgebung

Das Archiv, das dieser Server bei Ausführung mit -dicomweb-archive speichert: Zählungen von Studien, Serien, Instanzen und verwendeter Speicherplatz, die DICOMweb-Adresse und der Datenquellenblock für einen OHIF-Viewer, und eine Studiensuche nach Patientennamen, -ID, Zugangsdatum und Erstellungsdatum, die mit demselben QIDO-RS-Anfrage wie ein Viewer erstellt wird. Eine Studie öffnet sich zu ihren Serien und Instanzen, und eine Instanz kann als DICOM-Datei heruntergeladen werden. Nichts wird gerendert: Perfuse verschiebt Bilder und ein Viewer zeigt sie an. Ohne Archiv zeigt der Bildschirm an, wie es aktiviert werden kann. Siehe DICOMweb.

3.4.8 TEFCA

Die Audit-Trail für den Austausch durch ein qualifiziertes Gesundheitsinformationssystem und die Zweckbestimmungsregeln, die es regieren.

Zwei Transporte, die sich wirklich in unterschiedlichen Stadien befinden, und der Bildschirm sagt, welcher welcher ist. Eine Flagge, die beide abdeckt, wäre in beiden Richtungen falsch.

Facilitated FHIR ist implementiert und hat noch nie mit einem echten QHIN gesprochen. Es folgt dem Sequoia-Projekt-Standardverfahren vom 8. März 2026: Entdecken des Partner-UDAP-Metadatensatzes, Überprüfen dessen, dynamische Registrierung, Erhalt eines Zugriffstokens mit der Zweckbestimmung und Abfrage. UDAP ist eine öffentliche Schlüsselinfrastruktur über OAuth 2.0 — eine Vertrauensgemeinschaft stellt X.509-Zertifikate für ihre Mitglieder aus, und ein Mitglied authentifiziert sich, indem es JWTs mit dem privaten Schlüssel signiert und die Zertifikatkette anhängt.

Die Sicherheitsebene wird gegen die Implementierung eines anderen überprüft, was die einzige Überprüfung ist, die hier etwas wert ist. Eine Registrierung, die von diesem Build signiert wurde, wurde an einen Live-Referenzserver gesendet und mit unapproved_software_statement — Untrusted: Certificate is not a member of community abgelehnt. Um diese Antwort zu produzieren, hat der Server die Anfrage decodiert, den Software-Statement als JWT analysiert, die Signatur überprüft, die Zertifikatkette durchlaufen und eine Entscheidung über die Mitgliedschaft getroffen. Es ist der Unterschied zwischen dem Ablehnen an der Tür und dem Zurückgeben eines unlesbaren Briefes.

Was noch übrig bleibt, kann nicht von hier aus durchgeführt werden. Das Zertifikat, das die Gemeinschaftsmitgliedschaft beweist, kommt aus der QHIN-Onboarding und ist nicht etwas, das Software produziert. Bis eines existiert, wird kein Austausch mit einem echten Partner abgeschlossen.

Wie ein Kanal fragt. Ein Ziel vom Typ tefca fragt den Facilitated FHIR-Partner-Satz in Einstellungen, TEFCA (tefca.partnerFHIRBase) für jedes Nachrichten-Patienten an: durch Identifikator, wenn die Nachricht einen hat (PID-3 oder ein FHIR-Patienten-Identifikator), ansonsten durch Familiennamen mit Geburtsdatum und niemals durch einen Namen allein, da eine falsche Übereinstimmung auf einem Namen ohne Fehler die Akte einer anderen Person zurückgibt. Das Ziel legt den Verwendungszweck (Behandlung, Zahlung, Betrieb, öffentliche Gesundheit, individueller Zugriff) fest; ein Verwendungszweck, den der Teilnehmer nicht erklärt, wird vor dem Senden abgelehnt. Verwendungszwecke werden als TEFCA-Austauschzwecke (T-TRTMNT, T-PYMNT, T-HCO, T-PH, T-IAS, System urn:oid:2.16.840.1.113883.3.7204.1.5.2.1) oder mit tefca.purposeCodes: hl7 als HL7-Verwendungszwecke für Gemeinschaften, die diese verwenden, übermittelt. Das gefundene Bundle ist die Antwort des Ziels und kann an einen anderen Kanal mit results_to weitergeleitet werden. Jede Anfrage, einschließlich abgelehnter Anfragen, ist in der auf diesem Bildschirm angezeigten Spur enthalten, die den Partner benennt.

Der gesamte Pfad, von der Entdeckung bis zu einem Token, das der Partner-FHIR-Server akzeptiert, wird gegen den udap-dotnet-Referenzserver getestet (siehe Überprüfung).

Der ältere QHIN-zu-QHIN-Austausch, der auf den IHE-Profilen basiert, ist nicht implementiert. Ein Versuch wird mit einem Fehler abgelehnt, der besagt, dass dies nicht implementiert ist, und die Ablehnung wird als Fehlschlag auditiert. Das ist absichtlich und nicht nur eine vorübergehende Lösung: ein Austausch, der Erfolg meldet, obwohl er nie stattgefunden hat, würde Einträge in die Audit-Trail für Austausche erstellen, die nie stattgefunden haben, und eine Trail, die nicht mit dem übereinstimmt, was passiert ist, ist schlimmer als gar keine, weil die Trail das ist, was geglaubt wird.

Auf der ganzen Linie werden die Endpunkte, die für den Austausch verwendet werden, aus dem signierten Teil der Metadaten eines Partners stammen, nie aus dem Dokumentenkörper. Die Überprüfung einer Signatur und dann das Lesen der Endpunkte aus der unsignierten Kopie wäre eine aufwändige Art, dem Netzwerk zu vertrauen: ein Angreifer, der die Antwort umschreiben kann, lässt das signierte Element unberührt, zeigt den Token-Endpunkt auf seinen eigenen Server und sammelt Client-Assertionen von allen, die die Signatur überprüft und dann ignoriert, was sie abdeckt.

Ein Trust-Anker-Bundle ist erforderlich und dessen Abwesenheit wird beim Start verweigert. Die Überprüfung der signierten Metadaten eines Partners gegen das Zertifikat, das innerhalb davon angekommen ist, beweist nur, dass eine Partei beide erstellt hat - ein Fehler, den dieser Codebase bereits bei SAML gemacht hat, wo der Verifizierer das eingebettete Zertifikat bevorzugte und einen Angreifer als Administrator authentifizierte, während alle Tests bestanden. Fügen Sie die Zwischenzertifikate zum Bundle hinzu: Ein UDAP-Server muss nur sein Blattzertifikat senden, und der öffentliche Referenzserver tut genau das.

3.5 Zahler - Ansprüche, vorherige Genehmigung, Medikamente und die CMS-Zahlerregeln

3.5.1 Ansprüche und Authentifizierung

Erstellen Sie eine X12-275-Anspruchsanlage im 006020-Format, das CMS-0053-F annimmt, aus einer eingefügten C-CDA oder einer hochgeladenen PDF, TIFF oder JPEG, und sehen Sie es zurückgelesen. Lesen Sie eine 275 und laden Sie das Dokument darin herunter. Konvertieren Sie eine X12-278-Entscheidung in eine Da Vinci PAS-ClaimResponse. Nichts auf dieser Seite wird gespeichert oder gesendet. Siehe Nachrichtenformate für das, was die 275 erstellt und was sie nicht tut.

3.5.2 Medikamente

Die mit -formulary geladene Arzneimittel-Formulierung und die beiden NCPDP-Standards, die von ihr beantwortet werden. Formulierung listet die Pläne und die Arzneimittel mit ihren Stufen und Anforderungen auf, sowie den öffentlichen Da Vinci US Drug Formulary API und die NCPDP-Endpunkte. Preisprüfung (RTPB) prüft den Preis eines Arzneimittels für ein Mitglied als Echtzeit-Anfrage eines Verschreibers: den Abdeckungsstatus, die Einschränkungen in Worten mit ihren Codes, den Anteil des Mitglieds und den des Plans, sowie die günstigeren Alternativen. Vorabgenehmigung (ePA) sendet eine SCRIPT-Initiierung an den eigenen Endpunkt dieses Servers, zeigt die Fragestellung als Formular an, sendet die Antworten und zeigt die Entscheidung an; darunter jede Vorabgenehmigung mit ihrem Status und ob der Verschreiber informiert wurde, die Antworten der Vorabgenehmigung, ein Button, um eine ungesendete Entscheidung erneut zu senden, und die Arzneimittelzahlen, die CMS-0062-P vorschlägt. Siehe CMS-0057.

3.5.3 CMS-0057

Die Zahlerseite der CMS-Interoperabilitäts- und Vorabgenehmigungsregel als fünf Tools:

Die Konvertierungen speichern nichts und senden nichts.

3.5.4 CMS-Netzwerk

Bereitschaft für das CMS-Interoperabilitätsframework: jedes der 26 Kriterien, gruppiert wie CMS sie gruppiert, mit dem, was Perfuse bereitstellt, ob es hier aktiviert ist, die Einstellung, die es aktiviert, und was die Organisation zu tun hat. Die Zählungen oben filtern die Liste. Siehe CMS-0057.

3.6 Verwalten - wer was tun kann und wie dieser Server eingerichtet ist

3.6.1 Benutzer

Konten, Rollen (Überwacher, Betrachter, Operator, Editor, Admin) und Kanalgruppen. Die Kanalgruppen jedes Personen können direkt in der Liste bearbeitet werden; leer bedeutet jeden Kanal, und lab=editor, adt gibt eine andere Rolle in einer Gruppe. Ein Administrator, der auf einige Gruppen beschränkt ist, sieht nur die Personen dieser Gruppen. Der Header zeigt Ihre eigenen Gruppen neben Ihrer Rolle, wenn Sie welche haben. Siehe Sicherheit.

Maschinenanmeldeinformationen sind auch hier. Ein Token ist für eine Maschine und nicht für eine Person: Es läuft nicht ab und wird nicht von jemandem beeinflusst, der sich abmeldet, was ein Server benötigt, der seinen Nachbarn abfragt. Nur ein Hash wird gespeichert, sodass ein Token nur einmal angezeigt wird, wenn es erstellt wird, und nicht wiederhergestellt werden kann - eine gestohlene Datenbank ergibt keinen verwendbaren Token. Geben Sie ihm die niedrigste Rolle, die den Auftrag erledigt.

Mit MCP aktiviert, zeigt der Abschnitt auch die Adresse an, die ein KI-Agent verbindet, eine Client-Konfiguration zum Kopieren und jedes Tool mit der Rolle, die es benötigt; die Ausgabe eines Tokens mit Lassen Sie einen KI-Agenten damit handeln gibt ihm den mcp:write-Umfang. Siehe Sicherheit.

3.6.2 Mieter

Auf einem gemeinsam genutzten Server, die Liste der Organisationen des Plattformoperators: jede Organisation mit ihrer Kanalanzahl und ihrem gespeicherten Umfang neben ihren Grenzwerten (Kanäle, Nachrichten pro Minute, Speicher), die in der Liste festgelegt werden. Nur für die Plattformrolle sichtbar. Siehe Sicherheit für die Funktion jeder Grenze.

3.6.3 Zertifikate

Die verwendeten TLS-Zertifikate und wann sie ablaufen. Die Ablaufdaten sind der Punkt: Ein Zertifikat, das an einem Sonntag abgelaufen ist, ist eine Klasse von Ausfällen, die völlig vermeidbar und routinemäßig nicht vermeidbar sind.

3.6.4 Aktivität

Wer was geändert hat und wann. Jede Konfigurationsänderung wird aufgezeichnet, was es ermöglicht, "Es hat am Dienstag angefangen, zu versagen" zu beantworten.

3.6.5 DatenSchutz

Eine Person kann Anfragen nach der DSGVO und der UK-DSGVO stellen, rechtliche Sperrungen, das Löschregister, die Aufbewahrungsfrist und das Verarbeitungsprotokoll; nur Administratoren. Siehe Datenschutz.

3.6.6 Flotte

Jede Perfuse-Instanz auf einer Seite.

Mirth verkauft dies als separates Produkt; hier ist es eine Konfigurationsdatei und ein schreibgeschütztes Token. Der Grund, warum es sich lohnt, es zu haben, ist eng und wichtig: ein toter Server sieht nicht wie ein stiller aus. Das Dashboard einer einzelnen Instanz kann nicht erkennen, ob ein zweiter Standort aufgehört hat, Berichte zu liefern, und eine Flottenansicht kann dies auch nicht.

3.6.7 Migrieren

Fügen Sie einen Mirth- oder OIE-Kanalexport hinzu und sehen Sie, wie viele Ihrer Kanäle hier unverändert ausgeführt werden. Die gleiche Analyse wie perfuse explain und perfuse translate, ohne dass ein Terminal benötigt wird. Siehe Migration.

3.6.8 Einstellungen

Jede Einstellung, die der Server hat, mit einer Steuerung für jede - einschließlich derjenigen, die traditionell nur in einer Datei leben. Jede gibt an, ob sie sofort wirkt oder einen Neustart benötigt und ob sie explizit festgelegt wurde oder auf ihrem Standardwert bleibt.

Die Einstellungen umfassen jede perfuse serve-Option, die ein Feature aktiviert: den FHIR-Endpunkt und seine Version, die Payer-APIs, PAS und die CRD-Regeln, die X12-278-Brücke, eCR, den SMART-Autorisierungsserver, TLS und Signierung, Metriken, Flotte und VPN. Sie sind gruppiert als FHIR, Payer, öffentliche Gesundheit, SMART, Sicherheit und so weiter. Jede ist auch mit der Flagge angezeigt, die sie entspricht.

Neustart vom Console. Eine Einstellung, die mit *Benötigt Neustart* markiert ist, wird sofort gespeichert, aber erst beim nächsten Start des Servers gelesen. Solange eine Einstellung auf Neustart wartet, wird sie in einem Banner am oberen Rand der Einstellungen aufgelistet, zusammen mit einem Server neu starten-Button (der auch im Editor für Anmeldedaten und in den Einstellungsdateien nach dem Speichern verfügbar ist). Bevor der Neustart erfolgt, wird eine Bestätigung abgefragt, da jeder Kanal für einige Sekunden anhält: Jeder Kanal beendet die Nachricht, die er gerade bearbeitet, wie es auch beim Beenden des Dienstes der Fall ist, und sendet erneut, was in der Zwischenzeit angekommen ist. Die Konsole wartet dann, bis der Server wieder antwortet, und liest die Einstellungen erneut. Nur ein Administrator kann den Server neu starten, und jeder Neustart wird im Aktivitätsprotokoll als server.restart aufgezeichnet.

Unter Linux und macOS ersetzt der Prozess sich selbst durch eine frische Kopie desselben Programms und der gleichen Argumente, wodurch die Prozess-ID beibehalten wird, sodass systemd, launchd oder eine Laufzeitumgebung für Container nichts bemerkt. Unter Windows startet der Server erneut innerhalb desselben Prozesses, der einen Windows-Dienst unter dem Dienst-Manager beibehält. Wenn der Server nach zwei Minuten nicht geantwortet hat, teilt die Konsole dies mit; der Grund dafür befindet sich im Protokoll des Servers.

Flags und Einstellungsdatei. Beim ersten Start des Servers werden die Flags, die er erhalten hat, in die Einstellungsdatei geschrieben. Danach hat die Datei Vorrang vor den Flags, sodass die Änderung einer Einstellung in der Konsole (oder der Datei) vorgenommen wird und nicht durch Bearbeiten der Befehlszeile des Dienstes. Ein Flag, das die Datei noch nicht erwähnt, wird aufgezeichnet, wenn der Server mit diesem Flag startet. Das Entfernen eines Flags aus der Befehlszeile später schaltet dessen Funktion nicht aus: Schalten Sie es in den Einstellungen aus.

SNMP hat ein Panel unter den Einstellungen: Ob der Agent antwortet und auf welcher Adresse, die Netzwerke, auf die er antwortet, wie viele Warnungen gesendet oder fehlgeschlagen sind, und MIB herunterladen für den Basis-OID, der verwendet wird. Die Werte werden unter Überwachung, SNMP, festgelegt.

Markenidentität ist auch hier: Ein Standort kann den Produktnamen, einen Untertitel, eine Akzentfarbe festlegen und ein Logo hochladen. Das Logo erscheint dann im Header, auf der Anmeldeseite, auf dem Dashboard und auf den Berichtsbildschirmen. Wenn keines hochgeladen wird, wird nichts ersetzt - eine unmarkierte Installation bleibt unmarkiert, anstatt Dekorationen zu erhalten.

3.7 Was die Farben bedeuten

Vier Register, und jedes sagt etwas anderes. Der Unterschied ist erwähnenswert, weil es der Unterschied zwischen einem Bildschirm ist, den Sie auf einen Blick lesen können, und einem, bei dem alles um Aufmerksamkeit wetteifert.

Klartext ist ein Fakt über die Funktionsweise von Perfuse. Der größte Teil der Oberfläche. Nichts ist farblich gekennzeichnet, um anzugeben, dass es wichtig ist.

Grün bedeutet, dass etwas gerade erfolgreich war, weil Sie etwas getan haben. Es erscheint nach einer Aktion und bleibt nicht bestehen.

Gelb ist eine Warnung: Es lohnt sich, vor dem Handeln zu lesen, und es ist kein Fehler. Ein Feature, das nicht aktiviert ist, eine Einstellung, deren Änderungen überwacht werden, eine Umwandlung, die approximiert, anstatt exakt zu reproduzieren, ein Transport, den Perfuse handhabt, aber nicht vollständig überprüfen kann. Gelb ist die Farbe von "lesen Sie dies, bevor Sie fortfahren".

Rot bedeutet, dass etwas im Moment falsch ist. Ein Wert, der abgelehnt wurde, eine Anfrage, die fehlgeschlagen ist, ein Zertifikat, das abgelaufen ist, eine kritische Warnung, die ausgelöst wird. Nichts anderes verwendet es.

Diese letzte Regel ist der Grund, warum ein Bildschirm nicht rot geöffnet wird. Rot ist die einzige Farbe, die eine Anweisung übermittelt - stoppen, und es kann etwas sein, das Sie getan haben - und ein Bildschirm, der es für Dekorationen ausgibt, hat nichts mehr zu sagen, wenn die Eingabe tatsächlich falsch ist. Dies war nicht immer der Fall: Der Benutzerbildschirm öffnete sich früher mit "der Server hat eine Antwort gesendet, die nicht gelesen werden konnte" auf jeder Installation, die keine Passwörter konfiguriert hatte, und der Einstellungsbildschirm markierte überwachte Werte in der gleichen Farbe wie einen abgelehnten. Ein Test in web/src/RedMeansWrong.test.ts schlägt jetzt fehl, wenn ein Ausdruck, der etwas Abwesendes oder Approximatives beschreibt, einen roten Stil erhält.

Innerhalb einer Code-Box ist das Vokabular anders. Dort ist Rot ein Token-Typ - ein HL7-Segmentname, ein XML-Element - und übermittelt keine Bewertung.

4 Kanäle

Ein Kanal ist ein Nachrichtenfluss: irgendwoher kommen sie, optional mit Änderungen und an einem oder mehreren Orten ankommen. Er ist die Konfigurationseinheit, die Überwachungseinheit und die Bereitstellungseinheit. Alles andere in Perfuse dient den Kanälen.

4.1 Anatomie

Eine Kanaldatei besteht aus diesen Teilen, in der Reihenfolge, in der sie wirksam werden:

TeilSchlüsselErforderlichWas es tut
IdentitätnamejaBenennt den Kanal. Muss eindeutig sein.
DatentypdataTypeneinWie Nachrichten zu parsen sind. Standardmäßig HL7 v2.
QuellesourcejaWo Nachrichten ankommen. Genau einer.
FilterfilterneinEntscheidet, welche Nachrichten akzeptiert werden.
TransformationentransformationsneinGeordnete Änderungen an der Nachricht.
ZieledestinationsjaWo Nachrichten hingehen. Eines oder mehrere.

Plus mehrere, die auf den gesamten Kanal anwendbar sind: scripts, shadow, contract, tables, attachments, group und enabled. Jedes ist im Kanalreferenz beschrieben.

4.2 Eine Quelle, viele Ziele

Diese Asymmetrie ist beabsichtigt und es lohnt sich, sie frühzeitig zu verstehen, da sie die häufigste Quelle der Verwirrung ist, wenn man von einem anderen Motor kommt.

Ein Kanal hat genau eine Quelle. Wenn Nachrichten von zwei Orten kommen, sind das zwei Kanäle. Wenn man es als einen Kanal ausdrücken möchte, entsteht eine Konfiguration, bei der ein Fehler in einem der Transporte von außen gleich aussieht und bei der der Datenverkehr der beiden Feeds in den Statistiken gemischt wird - so dass ein Abfall in einem durch den anderen verdeckt wird.

Ein Kanal hat beliebig viele Ziele und sie sind unabhängig. Ein Fehler in einem stoppt die anderen nicht und jeder hat seine eigene Warteschlange, seine eigene Wiederholungsrichtlinie und seinen eigenen Lieferverlauf. Eine Nachricht, die drei von vier Zielen erreicht hat, wird genau so aufgezeichnet, nicht als Erfolg oder Misserfolg.

4.3 Ziele sind keine Kette

Jedes Ziel erhält die Nachricht so, wie sie nach den Transformationen des Kanals steht. Ein Ziel erhält nicht die Ausgabe des vorherigen Ziels.

Das ist wichtig, wenn ein Ziel seine eigenen Transformationen hat, was es auch haben kann. Diese gelten nur für die Kopie dieses Ziels. Ein häufiger Fehler ist, eine Änderung auf dem ersten Ziel zu setzen und zu erwarten, dass das zweite sie sieht.

Wenn Sie tatsächlich eine Kette benötigen - die Ausgabe eines Flusses, der in einen anderen fließt -, verwenden Sie ein Kanalziel, das an einen anderen Kanal per Name sendet. Das ist explizit, erscheint in der Nachrichtenhistorie als zwei Kanäle und kann als zwei Dinge überwacht werden, was eine versteckte Kette nicht kann.

4.4 Benennung

Der Name ist die Identität des Kanals überall: in der Datei, im Nachrichtenspeicher, in Warnungen, im Prüfungsjournal und in der URL. Eine Änderung ist kein Umbenennen; es ist ein neuer Kanal und die Historie des alten bleibt unter dem alten Namen.

group ist separat und dient der Organisation der Oberfläche. Eine Gruppe hat keine Auswirkung auf das Verhalten und das Gruppieren von Kanälen bedeutet nicht, dass sie etwas teilen.

Bei einer mehrstufigen Bereitstellung sollten Sie die Einrichtung im Namen anstelle von nur in der Gruppe angeben. Mirth-Bereitstellungen über mehrere Standorte hinweg driften zuverlässig in inkonsistente Benennungen ab und der Zeitpunkt, an dem dies schmerzhaft wird, ist ein Vorfall um zwei Uhr morgens, bei dem die Kanalliste vier Dinge mit dem Namen adt-inbound enthält.

4.5 Aktivieren und Deaktivieren

enabled: false stoppt einen Kanal, ohne ihn zu löschen. Seine Konfiguration, Historie und Statistiken bleiben bestehen.

Ein deaktivierter Kanal ist nicht ein pausierter. Seine Quelle hört nicht zu, sodass ein Absender, der versucht, eine Verbindung herzustellen, eine abgelehnte Verbindung erhält, anstatt eine hängende. Für MLLP ist das das richtige Verhalten - der Absender wird warten und wiederholen - aber es bedeutet, dass das Fehlerprotokoll des Absenders sich füllt, sodass ein deaktivierter Kanal kein Ersatz für die Vereinbarung eines Ausfalls mit dem Absender ist.

4.6 Wo Kanäle leben

Eine YAML-Datei pro Kanal im durch -channels angegebenen Verzeichnis. Der Dateiname ist nicht der Kanalname; der name-Schlüssel ist es. Es wird dringend empfohlen, sie gleich zu halten, und nichts erzwingt es.

Dateien werden ohne Neustart neu gelesen. Eine Datei, die nicht geparst werden kann, wird gemeldet und die zuvor geladene Version bleibt aktiv, sodass ein Syntaxfehler einen aktiven Feed nicht außer Gefecht setzen kann.

Ein Kanal, der in der Web-Oberfläche bearbeitet wird, wird in seine Datei zurückgeschrieben. Wenn diese Dateien in einer Versionskontrolle sind - was empfohlen wird - erwarten Sie Commits von Konfigurationsänderungen, die über die Oberfläche vorgenommen wurden, und bearbeiten Sie keine Datei gleichzeitig, während jemand sie im Builder geöffnet hat.

4.7 Verschlüsseln eines Kanallisteners

Ein Kanal, der auf einem Port hört, ist sein eigener Server, und sein TLS ist getrennt von dem TLS der Perfuse-Weboberfläche. Das Festlegen eines schaltet das andere nicht ein. Für eine HTTP-Quelle sind die Einstellungen unter TLS und Grenzen auf der Quelle zu finden.

Das Aktivieren von TLS fordert ein Zertifikat und einen privaten Schlüssel an. Das Erfordern eines Client-Zertifikats wandelt es in ein gegenseitiges TLS um: Der Absender muss eines vorlegen, das von einer von Ihnen genannten Behörde signiert wurde, was eine Authentifizierung darstellt, sodass ein Listener mit aktiviertem TLS nicht auch ein gemeinsames Token benötigt — obwohl das Vorhandensein beider nicht falsch ist.

Die Behörde wird nur einmal abgefragt, wenn ein Client-Zertifikat gefordert wird, und bleibt aus der Datei heraus, bis dies geschieht. Ein Kanal, der eine Behörde nennt, die nie konsultiert wird, liest sich so, als ob Absender verifiziert würden, wenn sie es nicht sind.

Ein MLLP-Listener hat die gleichen Einstellungen unter Diesen Listener verschlüsseln, mit einer Ausnahme, die erwähnenswert ist: Bei MLLP ist ein Client-Zertifikat die einzige verfügbare Authentifizierung. Es gibt kein Token und keine Kopfzeile, sodass ein Listener ohne eines Nachrichten von jedem Host annimmt, der den Port erreichen kann.

Zwei Grenzen stehen neben ihm. Nach einer Dauer aufgeben, weil ein Absender, der eine Verbindung öffnet und aufhört zu schreiben, diese sonst offen hält. Und größte akzeptierte Nachricht in Bytes, weil Null bedeutet, dass es keine Grenze gibt und die Grenze dann im Speicher liegt — ein Absender, der eine Gigabyte-Datei postet, wird abgelehnt, anstatt absorbiert zu werden.

4.8 Validierung

Ein Kanal wird überprüft, wenn er geladen wird, und die Überprüfungen sind Ablehnungen und keine Warnungen, wo die Alternative ein Kanal wäre, der läuft und das Falsche tut.

Beispiele für Dinge, die sofort abgelehnt werden: ein Ziel ohne Typ, eine Transformation, die einen Pfad anspricht, der im deklarierten Datentyp nicht existieren kann, ein Bestätigungsmodus, den der Quelltransport nicht liefern kann, und ein Rezept der Klasse II mit Wiederholungen.

Die Unterscheidung, die Perfuse versucht zu treffen, ist, dass alles, was ein plausibel aussehendes falsches Ergebnis produzieren würde, abgelehnt wird, und alles, was nur ungewöhnlich ist, zugelassen und gemeldet wird. Ein Kanal, der nicht falsch sein kann, ist wertvoller als ein Kanal, der startet.

5 Nachrichtenfluss

Dieses Kapitel verfolgt eine Nachricht vom Moment ihrer Ankunft bis zum Moment ihrer Zustellung oder bis sie aufgegeben wird. Die Kenntnis dieser Reihenfolge ist der schnellste Weg, um herauszufinden, wo eine Änderung hingehört und warum etwas nicht passiert.

5.1 Die Reihenfolge der Ereignisse

Arrival de-frame Parse Record as received Filter Transform Destination A Destination B Destination C unparseable filtered Filtered is a normal outcome, not an error. Unparseable is recorded and stops. The acknowledgement is sent after delivery by default, so a sender is not told "received" before it is true.
  1. Ankunft. Die Quelle akzeptiert die Bytes. Für einen Stream-Transport umfasst dies auch das De-Framing - das Finden, wo eine Nachricht endet und die nächste beginnt.
  2. Parse. Die Bytes werden gemäß dem dataType des Kanals in einen Baum umgewandelt. Eine Nachricht, die nicht geparst werden kann, stoppt hier und wird als Parse-Fehler aufgezeichnet.
  3. Aufzeichnen. Die Nachricht wird im Nachrichtenspeicher aufgezeichnet, wie sie empfangen wurde, bevor sie modifiziert wird. Dies ermöglicht die Wiedergabe und erneute Verarbeitung.
  4. Filter. Wenn der Kanal einen filter hat, entscheidet er, ob die Nachricht akzeptiert wird. Eine abgelehnte Nachricht wird als gefiltert aufgezeichnet, was ein normales Ergebnis und kein Fehler ist.
  5. Transform. Die transformations des Kanals werden in der Reihenfolge ausgeführt, jede gegen das Ergebnis der letzten.
  6. Fan out. Jedes Ziel erhält eine Kopie der transformierten Nachricht, wendet seine eigenen Transformationen an, wenn es welche hat, und liefert.
  7. Aufzeichnen des Ergebnisses. Pro Ziel: geliefert, gewartet, fehlgeschlagen oder gefiltert.
  8. Bestätigen. Wenn die Quelle eine Bestätigung erwartet, wird sie generiert und gesendet. Standardmäßig geschieht dies hier, nach der Lieferung - siehe unten.

5.2 Wenn die Bestätigung gesendet wird

Dies ist die folgenreichste Einstellung in einem Kanal, da sie entscheidet, was dem Absender versprochen wird. Es ist ack.when, und es hat zwei Werte.

on_delivery ist der Standard. Die Bestätigung wird nur gesendet, nachdem jedes aktiviertes Ziel die Nachricht akzeptiert hat. Eine positive Bestätigung bedeutet daher, dass die Daten tatsächlich irgendwo angekommen sind, was der stärkste Anspruch ist, den ein Motor in der Mitte ehrlich machen kann.

on_receipt bestätigt, sobald die Nachricht geparst und in die Warteschlange gestellt wurde, bevor ein Ziel geschrieben wurde.

Perfuse verwendet standardmäßig on_delivery, da das Versprechen der Zustellung und dann das Verlieren der Nachricht schlimmer ist als Langsamkeit. Unter on_receipt kann eine Nachricht, die bestätigt wurde, immer noch verloren gehen, wenn der Prozess mit Arbeit in der Warteschlange abstürzt – der Absender glaubt, sie sei zugestellt, nichts Upstream wird sie erneut senden, und die einzige Aufzeichnung, dass sie existiert hat, ist in Perfuse's eigenem Speicher.

5.3 Wann man on_receipt wählen sollte

Der Fall dafür ist real, und es sind Timeouts. Ein MLLP-Absender, der innerhalb von einigen Sekunden keine Bestätigung erhält, sendet die Nachricht normalerweise erneut, sodass ein langsames Ziel unter on_delivery Duplikate anstelle von Verzögerungen erzeugt. Wenn ein Ziel ein langsames Archiv oder ein System ist, das regelmäßig nicht verfügbar ist, bindet on_delivery das Timeout des Absenders an den schlechtesten Fall dieses Ziels.

Der Handel ist explizit: on_receipt verlagert das Risiko von Duplikaten auf Verlust. Die Wahl bedeutet, dass eine bestätigte Nachricht bei einem Absturz verloren gehen kann, und es lohnt sich, dies mit einer Queue-Tiefe-Warnung zu paaren, damit eine Queue, die aufgehört hat zu drainen, bemerkt wird. Siehe Warnung.

Unter beiden Einstellungen ist eine positive Bestätigung kein Versprechen, dass die empfangende Anwendung die Nachricht *verarbeitet* hat – nur, dass sie die Bytes akzeptiert hat. Wenn Sie wissen müssen, dass ein Ergebnis abgelegt wurde, muss dies von der empfangenden System kommen, und kein Integrationsmotor kann es liefern.

5.4 Wo die Nachricht aufgezeichnet wird

Bevor dem Filter und daher bevor jede Transformation. Drei Konsequenzen:

Die transformierte Form wird auch aufgezeichnet, pro Ziel, neben dem Ergebnis. Der Speicher enthält also, was angekommen ist, was gesendet wurde und was passiert ist – was für eine Untersuchung benötigt wird.

5.5 Fehler bei jedem Schritt

PhaseWie ein Fehler aussiehtWas passiert
AnkunftFraming-Fehler, Verbindung wird während der Nachrichtenübertragung getrenntAufgezeichnet, Verbindung geschlossen, Absender wiederholt den Vorgang
ParsenNicht gültig für den deklarierten TypAufgezeichnet als Parsen-Fehler, negative Bestätigung, wenn die Quelle eine erwartet
FilterDer Filter selbst enthält einen FehlerBehandelt als Ablehnung, aufgezeichnet mit dem Fehler
TransformierenEin Schritt schlägt fehlHängt vom on_error-Schritt ab; siehe transformation
LiefernZiel ist nicht erreichbar oder lehnt abIn der Warteschlange und erneut versucht, gemäß der Richtlinie des Ziels; siehe delivery

Die wichtige Asymmetrie: Ein Parse-Fehler ist permanent, und ein Zustellfehler ist normalerweise nicht permanent. Das erneute Versenden einer nicht parsbaren Nachricht wird nie helfen, also wird sie nicht erneut versucht. Das erneute Versenden eines unerreichbaren Ziels wird normalerweise helfen, also wird es erneut versucht.

5.6 Reihenfolge

Innerhalb eines Ziels werden Nachrichten in der Reihenfolge geliefert, in der sie angekommen sind, und eine Nachricht, die fehlschlägt und in die Warteschlange eintritt, behält ihren Platz — spätere Nachrichten warten hinter ihr, anstatt sie zu überholen.

Dies ist die richtige Standardvorgabe für klinische Daten, bei denen eine Aufnahme, die einer Entlassung folgt und in der falschen Reihenfolge geliefert wird, schlimmer ist als wenn beide zu spät sind. Es bedeutet auch, dass eine fehlerhafte Nachricht eine Warteschlange blockieren kann, was der Grund ist, warum die Warteschlangentiefe einen Alarm wert ist.

Über Ziele hinweg gibt es keine Reihenfolgegarantie, da sie unabhängig sind. Zwei Ziele erhalten nicht unbedingt dieselbe Nachricht zur gleichen Zeit, und ein schnelles Ziel kann mehrere Nachrichten vor einem langsamen Ziel liegen.

Die Reihenfolge über Kanäle hinweg ist überhaupt nicht garantiert. Wenn zwei Datenströme in einer bestimmten Reihenfolge zueinander angewendet werden müssen, muss diese Reihenfolge durch das empfangende System durchgesetzt werden, da nichts dazwischen wissen kann, welche von zwei unabhängig ankommenden Nachrichten zuerst ankam.

5.7 Parallelität

Eine Quelle kann mehrere Verbindungen gleichzeitig bearbeiten, begrenzt durch max_connections. Nachrichten von verschiedenen Verbindungen werden gleichzeitig verarbeitet.

Das bedeutet, dass die Ankunftsreihenfolge von zwei Nachrichten, die gleichzeitig über zwei Verbindungen gesendet werden, nicht definiert ist und nicht definiert werden kann — sie sind tatsächlich zur gleichen Zeit angekommen. Ein Absender, der eine Reihenfolge benötigt, muss eine Verbindung verwenden, was die meisten von ihnen tun.

6 Transformation

Transformationen ändern eine Nachricht. Sie sind eine Liste, sie werden in der Reihenfolge ausgeführt, und jede sieht das Ergebnis der vorherigen.

Perfuses Transformationen sind deklarativ: Jeder Schritt benennt eine Operation und das Feld, auf das sie angewendet wird. Es gibt keine Skriptsprache im normalen Pfad. Dies ist eine bewusste Einschränkung und die Begründung finden Sie in why not a script unten.

6.1 Die Schritte

SchrittWas es tut
setSchreibt einen Literalwert in einen Pfad, falls abwesend.
copyKopiert einen Pfad in einen anderen, mit einem optionalen Standardwert, wenn die Quelle abwesend ist.
clearLeert ein Feld, lässt es aber vorhanden.
removeEntfernt ein Feld vollständig.
mapSucht den aktuellen Wert in einer Tabelle und ersetzt ihn.
replaceReguläre Ausdrucksersetzung innerhalb eines Feldes.
padFüllt einen Wert auf eine feste Breite.
dateKonvertiert ein Datum oder einen Zeitstempel zwischen Formaten.
trimEntfernt umgebendes Leerzeichen.
caseKonvertiert in Groß- oder Kleinschreibung.

Jeder Schritt akzeptiert auch description, das im Trace und in der Schnittstelle erscheint, und when, das den Schritt bedingt macht.

Ein Schritt wird als Operationname mit seinem eigenen Block geschrieben:

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 und value sind keine Geschwister. set nimmt einen Block auf, der path und value enthält. Das Schreiben von set: PID-3.4 mit value: daneben ist der häufigste Fehler in einem handgeschriebenen Kanal und produziert einen Ladeerror anstelle einer stillen Fehlkonfiguration.

6.2 Klärung, Entfernen und der Unterschied

clear lässt das Feld vorhanden und leer. remove entfernt es vollständig.

Für HL7 ist dieser Unterschied real und er erreicht den Empfänger. Ein leeres Feld sagt „Ich habe dieses Feld und es hat keinen Wert“. Ein abwesendes Feld sagt überhaupt nichts. Einige empfangende Systeme behandeln das erste als Anweisung, den gespeicherten Wert zu löschen, und das zweite als Anweisung, ihn unverändert zu lassen — was der Unterschied zwischen dem Löschen einer aufgezeichneten Patientenallergie und dem Nichterwähnen ist.

Wenn Sie nicht wissen, was der Empfänger will, fragen Sie. Raten hat eine 50-prozentige Chance, Daten auf der anderen Seite stillschweigend zu zerstören.

6.3 Bedingungen

when nimmt einen Ausdruck und der Schritt wird nur ausgeführt, wenn er wahr ist:

  - when: MSH-9.2 == "A08"
    set:
      path: EVN-1
      value: A08

Ein Schritt, dessen Bedingung falsch ist, wird als übersprungen aufgezeichnet, und dies wird separat von einem Schritt gemeldet, der ausgeführt und nichts geändert hat. Dieser Unterschied ist der Punkt des Schrittdurchlaufs-Debuggers und wird in Debugging behandelt: Eine falsche Bedingung und ein abwesendes Feld sehen von außen identisch aus und bedeuten gegenteilige Dinge.

6.4 Pfade

Ein Pfad adressiert ein Feld: PID-5 ist das fünfte Feld von PID, PID-5.1 sein erster Bestandteil, PID-3(2) die zweite Wiederholung von PID-3 und OBX(3)-5 das fünfte Feld des dritten OBX-Segments.

Zwei Verhaltensweisen, die es wert sind, zu wissen:

6.5 Fehler

Die meisten Schritte haben nichts, was fehlschlagen könnte. Das Festlegen eines Werts, das Löschen eines Felds oder das Kopieren von einem nicht vorhandenen Pfad mit einem Standardwert sind alle für jede Eingabe definiert.

date ist die Ausnahme, da ein Wert, der kein Datum ist, das es erkennt, keine korrekte Konvertierung hat. Es nimmt on_error:

Der Standard ist fail, da ein Zeitstempel, der stillschweigend nicht konvertiert wurde, schlimmer ist als eine Nachricht, die nicht angekommen ist. Ein Datum im falschen Format sieht normalerweise immer noch wie ein Datum aus, sodass es die Validierung des Empfängers besteht und im Datensatz als falscher Tag landet.

keep ist gerechtfertigt, wenn der Empfänger beide Formate toleriert und wenn es verwendet wird, markiert die Spur die Änderung als beabsichtigt, sodass sie nicht wie ein stillschweigend fehlgeschlagener Schritt gelesen wird.

6.6 Die Reihenfolge ist wichtig und die Spur zeigt sie

Jeder Schritt sieht die Ausgabe des vorherigen Schritts. Zwei Konsequenzen, die die Leute erwischen:

Beides ist im Schritt-für-Schritt-Modus sichtbar, der die gesamte Nachricht nach jedem Schritt anzeigt, anstatt nur die Änderung. Siehe Fehlerbehebung.

6.7 Vorschlagen von Zuordnungen und was mit einem Vorschlag zu tun ist

Der AI Mapper schlägt Zuordnungen zwischen einer Menge von Quellfeldern und einer Menge von Zielen vor. Sein definierendes Verhalten ist, dass er ablehnt: unter seinem Konfidenzschwellenwert enthält er sich, anstatt zu raten, da eine zuverlässige falsche Zuordnung in einem klinischen System schlimmer ist als gar keine Zuordnung.

6.7.1 Geben Sie ihm etwas, worüber er sich sicher sein kann

Ein Name allein ist ein schwaches Beweisstück, auch wenn er genau übereinstimmt. PatientMRN gegen PatientMRN erzielt 68, was unter dem Standard-Schwellenwert von 70 ablehnt.

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.

Das erhält eine Zuordnung fast vollständig. Um sie abzuschließen, liefern Sie beide Hälften:

Mit diesen kann der Motor sehen, dass die Werte mit der Art des Ziels übereinstimmen und ein Vorschlag auf mehr als nur einem Namen basiert.

6.7.2 Die Genehmigung erfolgt für eine Zuordnung nach der anderen

Jeder Vorschlag hat seine eigene Genehmigungsbox. Es gibt kein „Alles akzeptieren über 80 %“, absichtlich: Der Engine hat bereits das Vertrauen genutzt, um zu entscheiden, ob die Zuordnung angeboten wird, und was bleibt, ist eine Entscheidung über dieses Feld in diesem Feed. Eine Zahl ist nicht diese Entscheidung.

Eine Enthaltung kann nicht genehmigt werden. Sie hat keine Box, nicht einmal eine deaktivierte, und der Bildschirm sagt, dass der Engine die Antwort nicht kennt. Wenn Sie die Antwort kennen, ordnen Sie sie manuell zu — das ist eine andere Handlung als die Zustimmung zu einem Vorschlag.

Ein Vorschlag unter Ihrem Schwellenwert wird ohne Box angezeigt, als unter ihm markiert. Es lohnt sich, ihn zu lesen — ein nahe liegender Treffer ist oft die gewünschte Zuordnung, und das Verstecken würde dazu führen, dass Sie sich fragen, ob der Engine sie berücksichtigt hat — aber nicht genehmigungsfähig, weil Ihr Schwellenwert die Linie ist, die Sie gezogen haben.

6.7.3 Zwei Dinge, die Sie mit dem Genehmigten tun können

Hinzufügen zu einem Kanal wandelt jede Zuordnung in einen Kopierschritt um. Dies funktioniert nur, wenn die Quelle ein Pfad in der Nachricht ist, wie z. B. ZPI-1, da ein Schritt von einem Ort in einer Nachricht an einen anderen kopiert. Die Schritte werden in die Kanaldatei eingefügt und treten in Kraft, wenn sie das nächste Mal geladen wird — bis dahin ändert sich nichts im Datenverkehr.

Herunterladen als Rezept ist die richtige Antwort für den häufigeren Fall: Eine Zuordnung von einem Spaltennamen, einem JSON-Schlüssel oder einem Feldnamen eines Herstellers. Diese sind echte Zuordnungen, und ein Kanal kann ein solches Feld nicht direkt lesen, sodass ein Schritt es nicht ausdrücken kann. Das Rezept zeichnet sie als genehmigt auf und kann geteilt werden.

6.8 Warum kein Skript

Mirth platziert einen JavaScript-Transformer im Zentrum jedes Kanals, und es ist das flexibelste Design, das verfügbar ist. Perfuse bietet Skripting — siehe den scripts-Schlüssel in der Kanalreferenz — aber macht es nicht zum gewöhnlichen Pfad, aus drei Gründen, die aus dem praktischen Fehler resultieren.

Ein deklaratives Schritt kann inspiziert werden. Perfuse kann Ihnen sagen, dass ein Schritt PID-5 liest und PID-8 schreibt, bevor er ausgeführt wird, und kann daher eine Spur auf Feldebene anzeigen, warnen, dass ein Schritt einen Pfad anspricht, den der deklarierte Datentyp nicht enthalten kann, und eine pro-Schritt-Wiedergabe generieren. Keines davon ist für beliebigen Code möglich.

Ein deklaratives Schritt kann von der Schnittstelle begründet werden. Der Builder kann die Felder anbieten, die in diesem Kanalverkehr existieren, und eine Änderung eines Schritts kann vor dem Speichern gegen reale historische Nachrichten überprüft werden.

Und ein deklaratives Schritt kann nichts tun, was nicht mit der Nachricht zusammenhängt. Ein Skript kann auf das Netzwerk zugreifen, die Dateisystemhierarchie lesen oder von der Tageszeit abhängen. Wenn ein Kanal, der zwei Jahre lang funktioniert hat, plötzlich falsche Ausgaben produziert, ist die Ursache, die außerhalb der Nachricht liegt, der schwerste Fall, den man diagnostizieren kann, und die Beseitigung dieser Möglichkeit ist es wert, mehr als die Flexibilität, die es kostet.

Wo eine echte Transformation nicht deklarativ ausgedrückt werden kann, verwenden Sie ein Skript und akzeptieren Sie, dass die Spur es als einen undurchsichtigen Schritt anzeigen wird.

6.9 Was ein Skript tun darf

Ein Skript wird alles außerhalb der Nachricht verweigert, es sei denn, es wird gewährt, und die Gewährungen sind im Skriptabschnitt des Builders. Dies ist absichtlich unähnlich zu Mirth, der jedem Skript alle gibt — dort kann ein Transformer stillschweigend nach einem Kopieren und Einfügen mit der Dateisystemhierarchie beginnen.

Es gibt drei.

Dateien lesen und schreiben erfordert, dass Sie die Verzeichnisse nennen, die es verwenden darf, und ein Kanal, der Dateizugriff ohne diese Verzeichnisse gewährt, wird bei der Initialisierung abgelehnt. Diese Anforderung ist der gesamte Unterschied zwischen Dateizugriff und unbeschränktem Dateizugriff: Die Gewährung ohne Verzeichnisse einmal erreichte das gesamte Dateisystem, einschließlich der Perfuse-Datenbank, die Passwort-Hashes, das LDAP-Servicekonto-Passwort und das OIDC-Client-Geheimnis enthält. Die Erstellung eines Kanals erfordert nur die Editor-Rolle, sodass die Eskalation abgeschlossen war, sobald ein Administrator den Kanal startete.

Abfrage einer Datenbank verwendet die im Kanal konfigurierten Verbindungen. Ein Skript mit diesem kann alles lesen, auf das diese Anmeldedaten zugreifen können.

Nachrichten an andere Kanäle weiterleiten ermöglicht es einem Skript, eine Nachricht in einen anderen Kanal zu senden, was die Möglichkeit bietet, eine Schleife zwischen zwei Kanälen zu erstellen.

Die Gewährung einer Fähigkeit für einen Kanal ohne Skripte hat keine Auswirkungen, und die generierte Datei omittiert den gesamten Block in diesem Fall.

6.10 Umgang mit einem Datum, das seinem Format nicht entspricht

Ein Datumschritt konvertiert von einem Format in ein anderes, und die interessante Frage ist, was passiert, wenn ein Wert seinem Format nicht entspricht.

Der Standard ist es, die Nachricht zu stoppen, und es ist der richtige Standard: Ein Zeitstempel, der stillschweigend nicht konvertiert wurde, wird downstream akzeptiert und dann falsch gelesen, was schlimmer ist als eine Nachricht, die laut fehlgeschlagen ist und an einem Ort liegt, an dem jemand sie sehen kann.

Den Wert so lassen, wie er ist gibt ihn im ursprünglichen Format weiter. Downstream sieht dann zwei Formate in einem Feld, was der Fehler ist, den der Schritt verhindern sollte — aber es ist die richtige Wahl, wenn das Feld optional ist und ein Partner es inkonsistent sendet.

Das Feld leeren ist ehrlich und besser als ein falsches Format, aber ein Empfänger, der das Feld erfordert, lehnt die Nachricht dann ab.

6.11 Die Skriptsprachen

Drei werden akzeptiert und welche davon zu wählen ist, hängt hauptsächlich davon ab, ob Sie migrieren. Der Wert wird in einem Skript-Schlüssel language gespeichert:

WertWas es ist
javascriptDer Standard. Ein unmarkiertes Skript wird als JavaScript behandelt.
luaDie bessere Wahl, wenn niemand migriert.
wasmDie Bytes eines kompilierten WebAssembly-Moduls, nicht der Quellcode.

JavaScript ist der Standard und ein unmarkiertes Skript wird als JavaScript behandelt. Es ist hier als Kompatibilitätsverpflichtung und nicht als Vorliebe: Mirths Skripte sind JavaScript und ein Standort, der umzieht, hat Tausende von Zeilen davon. Dazu gehört auch die Unterstützung für E4X, eine lange tote Erweiterung der Sprache, die Mirth-Skripte für XML verwenden und die vor anything übersetzt werden muss.

Lua (lua) ist die bessere Wahl für jeden, der nicht migriert. Ein kleinerer Laufzeitumfang, keine Prototypkette, die missbraucht werden kann, und integer-indexierte Tabellen, die Segment- und Feldadressierung natürlicher als JavaScripts entsprechen. Seine Standardbibliothek ist klein genug, um aufzuzählen, was es einfacher macht, sich über seine Sandbox sicher zu sein.

WebAssembly (wasm) ist keine Sprache, sondern ein kompiliertes Modul und das Feld möchte die Bytes einer .wasm-Datei und nicht den Quellcode. Verwenden Sie es, wenn die Transformation bereits in einer kompilierten Sprache existiert oder wenn sie so umfangreich ist, dass die Laufzeitkosten wichtig sind.

Sein Vertrag ist absichtlich der einfachste verfügbar: ein Modul liest die Nachricht auf der Standard-Eingabe und schreibt sein Ergebnis auf die Standard-Ausgabe. Bytes rein, Bytes raus — was jeder Werkzeugkette bereits tut und was jemand, der ein Modul auf seiner eigenen Kommandozeile testet, bereits hat. Die Alternative war eine exportierte Funktion über linearen Speicher, die schneller ist und erfordert, dass jeder Modulautor über die Speicherzuweisung, die Zeichenkodierung und wer was freigibt, einverstanden ist; für etwas, das pro Nachricht nur einmal ausgeführt wird, ist dieser Handel nicht lohnenswert.

Alles, was ein Modul auf der Standard-Fehlerausgabe schreibt, werden Log-Zeilen, sodass es sich selbst erklären kann, wie ein Skript, das logger aufruft.

Ein nicht-nuller Exit-Code bedeutet, dass das Modul *fehlgeschlagen* ist, was nicht dasselbe ist wie ein Filter, der eine Nachricht ablehnt. Ein Filter-Modul gibt true oder false auf der Standard-Ausgabe aus. Die Vermischung der beiden würde ein abgestürztes Modul von einem, das absichtlich den Datenverkehr ablehnt, nicht unterscheidbar machen.

6.11.1 Was die Ausgabe bedeutet

Die Regeln sind für alle drei Sprachen dieselben und nicht neue pro Laufzeit, sodass das beobachtbare Verhalten eines Skripts — was es sehen kann, was es tun darf, wie lange es dauern darf, was ein Filter-Urteil bedeutet — einmal definiert ist.

Für einen Transformer, Preprocessor oder Writer bedeutet leere Ausgabe, dass die Nachricht unverändert bleibt. Wenn ein Skript am Ende ist, bleibt die Nachricht unverändert; wenn keine Ausgabe als „die Nachricht ist jetzt leer“ behandelt wird, würde dies den Datenverkehr aus technischen Gründen verwerfen.

WebAssembly-Module werden beim Laden des Kanals kompiliert, nicht bei der ersten Nachricht. Die Kompilierung ist nicht kostenlos — ein Modul, das aus einer Sprache erstellt wird, die ihre eigene Laufzeit mitbringt, kann Hunderte von Millisekunden dauern — und diese Kosten bei der Ladezeit zu zahlen bedeutet, dass die erste Nachricht in einem Kanal nicht mysteriös langsamer ist als der Rest.

6.12 Gemeinsame Zuordnungstabellen

Die andere Hälfte desselben Problems: Die Geschlechtscodes und Patientenklassen eines Standorts werden in jedem Kanal, der sie berührt, identisch übersetzt, und eine Tabelle innerhalb eines Kanals ist nur eine Tabelle, die dieser Kanal verwenden kann.

# 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

Die Herkunft ist der Punkt. Das meiste, was eine Schnittstelle schwer zu warten macht, ist, dass niemand weiß, *warum* eine Zuordnung so ist, wie sie ist, und die Person, die es wusste, gegangen ist. Eine Zuordnung mit einem Grund kann diskutiert werden; eine ohne wird zu etwas, das niemand zu ändern oder zu löschen wagt.

Tabellen werden auf Build → Tabellen sowie in der Datei erstellt und geändert. Das Speichern einer Tabelle, die in Kraft ist, startet die laufenden Kanäle neu, die ihre Datei laden, sodass die nächste Nachricht sie verwendet; ein Entwurf startet nichts neu.

6.12.1 Versionen und Gültigkeitsdaten

Eine Tabelle kann mehrere Ausgaben unter einem Namen speichern, jede mit ihrer eigenen version. Die Ausgabe, die eine Nachricht verwendet, wird ausgewählt, wenn die Nachricht ankommt: von den genehmigten Ausgaben, deren Datum diesen Tag (UTC) abdeckt, diejenige, die zuletzt begonnen hat. Wenn also eine Änderung eines Codes für den ersten Tag des nächsten Monats vereinbart wird, kann sie jetzt eingetragen und übernimmt automatisch am geplanten Tag.

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: [...]

(beim Laden der Datei abgelehnt).

die am gleichen Tag beginnen, werden abgelehnt, wenn die Datei geladen wird.

auf heute, sodass es die aktuell gültige ersetzt. Eine, die selbst nur heute begonnen hat, wird in den Ruhestand versetzt, da zwei Ausgaben, die am gleichen Tag beginnen, keine Regel lassen.

andernfalls werden die Einstellungen der Tabelle verwendet.

wer sie gespeichert und wer sie genehmigt hat, und Vergleichen mit der aktuellen Version zeigt, was eine Ausgabe hinzufügt, entfernt und ändert.

6.12.2 Abzeichnung

Mit Einstellungen → Daten → Zuordnungstabellen "Änderungen an einer Zuordnungstabelle benötigen die Genehmigung einer zweiten Person" (data.tableApproval) aktiviert, ist jeder Speichervorgang ein Entwurf, und die Person, die ihn gespeichert hat, kann ihn nicht genehmigen: Jemand anderes muss dies tun, optional mit dem Tag, an dem er in Kraft tritt. Eine genehmigte Ausgabe kann nicht direkt bearbeitet werden; Neue Version aus dieser kopiert sie in die nächste Version. Die Genehmigung, Pensionierung und Löschung eines Entwurfs werden im Prüfungprotokoll aufgezeichnet, und die Genehmigung startet die laufenden Kanäle neu, die die Datei laden.

6.12.3 Werte, die keine Tabelle zuordnet

Jeder Wert, den ein Mapping-Schritt suchte und nicht fand, wird pro Tabelle gezählt, zusammen mit den Kanälen, durch die er kam, und dem Zeitpunkt, an dem er zum ersten und letzten Mal gesehen wurde. Der Bildschirm „Tabellen“ listet sie auf, beginnend mit den häufigsten. Map it öffnet die Tabelle mit diesem Wert bereits als Zeile hinzugefügt; Dismiss entfernt es, bis es erneut gesehen wird. Werte, die länger als 64 Zeichen sind, werden nicht aufgezeichnet (sie sind keine Codes), und die Liste behält, was innerhalb der Nachrichten-Aufbewahrungsfrist gesehen wurde. Die Liste wird in terminology.db neben der Hauptdatenbank aufbewahrt.

6.12.4 Codesysteme

Veröffentlichte Codesysteme können aus den eigenen Dateien der Herausgeber importiert werden, unter Code-Systemen auf dem Bildschirm „Tabellen“ (Administratoren) oder mit POST /api/terminology/import?format=… und der Datei als Textkörper:

FormatDateiSystem
loincLoinc.csv aus der LOINC-Tabelle-Veröffentlichunghttp://loinc.org
icd10cmdie CMS-Bestelldatei (icd10cm_order_*.txt) oder Codierungsdateihttp://hl7.org/fhir/sid/icd-10-cm
rxnormRXNCONSO.RRF aus der RxNorm-Vollveröffentlichunghttp://www.nlm.nih.gov/research/umls/rxnorm
snomedder RF2-Beschreibungs-Snapshot (sct2_Description_Snapshot-en_*.txt)http://snomed.info/sct
snomed-rf2ein vollständiges SNOMED CT RF2-Veröffentlichungspaket (die ZIP-Datei, die ein nationales Veröffentlichungszentrum veröffentlicht)http://snomed.info/sct, Version http://snomed.info/sct/{module}/version/{date}
clamleine ClaML-Datei: WHO ICD-10, ICD-10-GM und OPS (BfArM), CIM-10 FR (ATIH)aus dem Dateinamen oder dem angegebenen system
icd11die WHO ICD-11 MMS-einfache Tabulation (tabulatorgetrennt, mit Code- und Title-Spalten)http://id.who.int/icd/release/11/mms
csvjede durch Trennzeichen getrennte Datei, mit system, codeColumn und displayColumn (CPT, HCPCS, lokale Codes, nationale Tabellen)das angegebene system

Keines davon wird mit Perfuse ausgeliefert: LOINC, SNOMED CT, RxNorm und CPT haben jeweils ihre eigene Lizenz, und der Bildschirm fordert den Importeur auf, zu bestätigen, dass die Organisation diese Lizenz besitzt (aufgezeichnet mit dem Import). Importierte Codes werden auf drei Arten verwendet:

Nationale Ausgaben und Klassifikationen. Eine SNOMED CT-Ausgabe wird aus ihrem gesamten RF2-Paket importiert: Konzepte mit ihrem tatsächlichen Status, jede aktive Beschreibung und die Sprachreferenzsets. Die Ausgabe wird aus dem Paket ermittelt (das nationale Modul mit den meisten Konzepten; edition benennt es anstelle dessen) und wird zur Version-URI. language wählt, dessen bevorzugter Begriff jeder Konzepts Anzeige ist (sv, da, nl, de, fr, en-GB, en-US ...; Englisch ansonsten), und jeder Sprache bevorzugter Begriff und vollständig spezifizierter Name werden als Bezeichnungen aufbewahrt: $lookup gibt sie zurück, und dessen displayLanguage wählt eine (de-CH fällt auf de zurück). Die Ausgaben, die Perfuse benennt (International, UK, Deutschland, Niederlande, Schweden, Dänemark, Belgien, Irland, Norwegen, Schweiz, Estland, Spanien), werden durch GET /api/terminology/editions aufgelistet, die Modul-IDs werden nicht gegen eine veröffentlichte Quelle überprüft; jede andere Ausgabe importiert auch, benannt durch ihr Modul.

ClaML-Dateien werden in UTF-8, ISO-8859-1, ISO-8859-15 oder Windows-1252 gelesen, wie ihre XML-Erklärung angibt. Jeder Kategorietitel ist ihre bevorzugte Rubrik (verschachtelte Begriffe eingeschlossen); ein Modifikator (ein fünfter Buchstabe für den Ort einer Fraktur, sagen wir) macht die Codes, die er hinzufügt, mit dem Modifikator-Titel nach dem Kategorietitel, es sei denn, die Kategorie schließt ihn aus; blocks=true importiert Kapitel und Blöcke ebenfalls. Die ICD-11-Tabulationsspalten werden durch ihren Namen gefunden, da ihre Reihenfolge zwischen den Versionen geändert wurde, und die Bindestriche, die die Tiefe anzeigen, werden aus den Titeln entfernt. Eine durch Trennzeichen getrennte Datei benötigt delimiter (, ; | oder tab), encoding (utf-8, iso-8859-1, iso-8859-15, windows-1252) und noHeader=true, wobei die Spalten dann von 1 nummeriert werden. Die Konsole bietet Einstellungen für die UK-ICD-10-5.-Ausgabe und OPCS-4-Dateien (TRUD), Frankreichs CIM-10-FR-Tabelle der Etiketten (ATIH) und eine ICD-10-BE-Ausgabe; ihre Herausgeber dokumentieren nicht alle ihre Spalten, daher sollten Sie sie gegen die Kopfzeile der Datei überprüfen.

Wirksame Daten. effective=YYYY-MM-DD importiert eine Version jetzt und verwendet sie ab diesem Tag (ICD-10-GM, sagen wir, jedes Jahr am 1. Januar): Bis dahin wird eine Abfrage, die keine Version angibt, durch die Version beantwortet, die bereits in Kraft ist, und der Bildschirm zeigt das Datum an.

ICD-11 von der WHO. Mit einem Client, der bei icd.who.int registriert ist (Einstellungen → Daten → Codesysteme, serve -icd11-client-id und -icd11-client-secret; -icd11-release, standardmäßig 2025-01), werden ICD-11-Codes, die nicht importiert wurden, in der WHO-ICD-API (codeinfo, dann der Titel der Entität) abgefragt und für einen Tag gespeichert. Ein postkoordinierter Code (NC72.2&XK9K) wird als Ganzes überprüft, sodass eine Kombination, die ICD-11 nicht zulässt, abgelehnt wird, und seine Anzeigennamen für jeden Teil ("Fraktur des Halses des Oberschenkels (Rechts)").

ICD-11 ohne Codes übermitteln. Die WHO veröffentlicht dieselbe API als Container (whoicd/icd-api, kostenlos, Intel und Arm). Führen Sie es in Ihrem eigenen Netzwerk aus und geben Sie dessen Adresse an (serve -icd11-url http://icd-api.local, oder ICD-API-Adresse in den gleichen Einstellungen); kein Client ist erforderlich und kein Code verlässt Ihr Netzwerk. Getestet gegen diesen Container (Version 2.6.0, Release 2025-01 in Englisch und Französisch).

7 Filterung

Ein Filter entscheidet, welche Nachrichten ein Kanal akzeptiert. Es ist ein Ausdruck auf dem Kanal, der nach dem Parsen und Aufzeichnen der Nachricht, aber vor jeder Transformation, ausgewertet wird.

filter: MSH-9.1 == "ADT" && MSH-9.2 in ("A01", "A03", "A08")

Eine Nachricht, die der Filter ablehnt, wird mit dem Ergebnis gefiltert aufgezeichnet. Das ist ein normales Ergebnis, kein Fehler, und es löst keine Warnung aus oder produziert eine negative Bestätigung.

7.1 Geiltert ist nicht fehlgeschlagen

Diese Unterscheidung ist es wert, festzuhalten, weil die Vermischung beider ein reales Problem versteckt.

Eine gefilterte Nachricht wurde richtig abgelehnt: sie war nicht für diesen Kanal bestimmt. Eine fehlgeschlagene Nachricht war eine, die dieser Kanal hätte bearbeiten sollen und nicht konnte. Wenn beide auf die gleiche Weise aufgezeichnet würden, würde ein Kanal, der jeden Nachrichten ablehnt, genau wie ein Kanal aussehen, der den größten Teil seines Datenverkehrs filtert, was der normale Zustand vieler Kanäle ist.

Die Statistiken zählen sie daher getrennt, die Warnregeln behandeln sie unterschiedlich, und die Oberfläche zeigt sie in verschiedenen Farben an. Ein Anstieg der gefilterten Nachrichten könnte bedeuten, dass der Absender etwas Neues zu senden begonnen hat; ein Anstieg der Fehlschläge bedeutet, dass etwas kaputt ist.

7.2 Was ein Filter lesen kann

Jedes Feld in der geparsten Nachricht, mit den gleichen Pfaden, die Transformationen verwenden. Der Filter läuft vor den Transformationen, daher sieht er die Nachricht, wie sie angekommen ist — nicht, wie sie gesendet wird.

Diese Reihenfolge ist absichtlich. Ein Filter, der post-Transformationswerte liest, würde entscheiden, ob er eine Nachricht akzeptiert, basierend auf Änderungen, die unter der Annahme vorgenommen wurden, dass sie akzeptiert wurde, was zirkulär ist und Kanäle erzeugt, deren Verhalten von der Reihenfolge von zwei Dingen abhängt, die unabhängig erscheinen.

7.3 Ausdrücke

Vergleiche: ==, != und für Zahlen <, <=, >, >=.

Mitgliedschaft: in ("A01", "A03"), was klarer ist als eine Kette von || und die Form ist, die der Builder produziert.

Kombination: &&, || und Klammern. Negation mit !.

Abwesenheit: Ein Pfad, der nicht vorhanden ist, vergleicht sich ungleich mit jedem Wert, einschließlich der leeren Zeichenkette. Um Abwesenheit explizit zu testen, vergleichen Sie gegen absent. Dies ist wichtig, weil ein abwesendes Feld und ein leeres Feld unterschiedlich sind, wie in Transformation beschrieben, und ein Filter, der sie gleich behandelt, Nachrichten akzeptiert, die er ausschließen sollte.

7.4 Ein Fehler im Filter ist eine Ablehnung

Wenn der Filter selbst nicht ausgewertet werden kann - ein fehlerhafter Ausdruck, der die Validierung passiert hat, oder ein Vergleich, der nicht durchgeführt werden kann - wird die Nachricht abgelehnt und der Fehler wird gegen sie aufgezeichnet.

Ablehnen anstelle von Akzeptieren ist die sicherere der beiden Optionen, aber keine davon ist gut, und das Ergebnis wird unterschiedlich von einer gewöhnlichen Filterablehnung aufgezeichnet, damit es alarmiert werden kann. Ein Filter, der bei jeder Nachricht fehlt, lässt die gesamte Nachrichtenquelle stillschweigend fallen, und er darf nicht wie ein funktionierender Filter aussehen.

7.5 Filtern Sie an der Quelle, wo Sie können

Ein Filter läuft nachdem die Nachricht das Netzwerk überquert und geparst wurde. Einige Quellen können früher und billiger filtern:

Filtern an der Quelle ist eine Leistungsentscheidung, nicht eine Korrektheitsentscheidung, und es hat einen Kostenfaktor: Eine Nachricht, die am Broker gefiltert wird, wird nie von Perfuse aufgezeichnet, daher erscheint sie nicht im Nachrichtenspeicher und kann später nicht mehr überprüft werden. Wenn Sie nachweisen müssen, was der Absender gesendet hat, filtern Sie hier anstelle von dort.

7.6 Testen eines Filters

Ein Filter kann vor dem Speichern gegen echten historischen Verkehr überprüft werden. Die Schnittstelle berichtet, wie viele der letzten N aufgezeichneten Nachrichten der Filter akzeptieren, ablehnen und fehlerhaft verarbeiten würde - was der schnellste Weg ist, herauszufinden, dass ein Ausdruck, der richtig aussieht, nichts akzeptiert.

Die Spur zeigt auch pro Nachricht, welche Felder der Filter gelesen hat und welche Werte er gefunden hat. Ein Filter, der unerwartet alles ablehnt, liest normalerweise einen Pfad, der in diesem Feed nicht existiert, und die Spur benennt ihn.

8 Nachrichtenformate

Die dataType eines Kanals entscheidet, wie Bytes zu einer Nachricht werden. Sie beeinflusst die Analyse, was Pfade bedeuten, wie die Nachricht wieder ausgegeben wird und welche Transformationen gültig sind.

WertFormat
hl7HL7 v2, der pipe-getrennte Standard. Der Standardwert.
hl7v3HL7 v3 und CDA-Dokumente, die XML sind.
x12ASC X12, verwendet für die Eignung und Ansprüche.
ncpdpNCPDP Telekommunikationsstandard D.0 Apothekenansprüche.
scriptNCPDP SCRIPT, elektronische Rezepte. XML.
dicomDICOM-Bildobjekte.
delimitedCSV und andere durch Trennzeichen getrennte Texte.
rawKeine Analyse. Bytes rein, Bytes raus.

8.1 HL7 v2

Der Standardwert und das, was die meisten Beispiele in diesem Handbuch verwenden. Segmente werden durch Wagenrücklauf beendet, Felder durch |, Komponenten durch ^, Wiederholungen durch ~.

Zwei Dinge über die Kodierung sind wichtig zu wissen, weil sie stille Fehler verursachen.

Die Trennzeichen sind nicht fest. Sie werden in MSH-1 und MSH-2 jeder Nachricht deklariert, und Perfuse liest sie von dort anstelle von Annahmen über Rohre. Ein Absender, der ein anderes Feldtrennzeichen verwendet, wird korrekt geparst.

Die Konsequenz ist, dass eine Nachricht, deren Trennzeichen ersetzt wurden — meistens durch einen Textverarbeitungsprogramm oder einen E-Mail-Client, der typografische Ersatzzeichen einsetzt —, perfekt in Felder parsen lässt, die alle falsch sind. Es tritt kein Fehler auf. Dies ist der Grund, warum der Beispiel-Reader, der im testing beschrieben wird, den Trennzeichencharakter anzeigt, den er gefunden hat, und sich weigert, Zuversicht auszudrücken, wenn dieser ungewöhnlich ist.

Wenn jemand Ihnen ein Beispiel sendet und der Kanal, der aus ihm erstellt wird, Unsinn produziert, überprüfen Sie die Trennzeichen, bevor Sie irgendetwas anderes tun. Fordern Sie eine einfache Textanlage anstelle einer Nachricht, die in den E-Mail-Text eingefügt ist.

8.2 HL7 v3 und CDA

XML anstelle von durch Trennzeichen getrennt. Pfade sind Element- und Attributpfade anstelle von Feldpositionen.

In v3 ist ein Wert fast immer ein Attribut und kein Elementtext. Ein Vergleich, der nur Elementtext liest, würde zwei Dokumente als identisch melden, wenn das Geburtsdatum, das Geschlecht und jeder Identifier unterschiedlich sind. Der Vergleich von Perfuse liest beides, und das ist der Grund: Die Alternative funktioniert stillschweigend.

hl7v3-Optionen finden Sie im Format-Referenz.

8.3 X12

Segmente, die durch die ~-Konvention beendet werden, wobei die Trennzeichen im ISA-Segment deklariert sind. Wie HL7 werden sie aus der Nachricht gelesen und nicht angenommen.

Die Struktur von X12 besteht aus Umschlägen in Umschlägen - Austausch, funktionale Gruppe, Transaktionssatz - und ein einzelner Austausch kann viele Transaktionen enthalten.

Standardmäßig ist ein Austausch eine Nachricht. Die gesamte Datei erhält einen Datensatz, ein Ergebnis und eine Zeile in der Schnittstelle, unabhängig von der Anzahl der Transaktionen, die sie enthält.

8.3.1 Mirths X12-XML

Mirth Connect und Open Integration Engine zeigen X12 als XML: eine Wurzel X12Transaction (oder EDIMessage, wenn die Eingabe nicht mit ISA beginnt) mit den Trennzeichen als Attribute und ein Element pro Segment und Element namens ISA.01, NM1.03.1 usw. Kanäle und Empfänger, die für Mirth erstellt wurden, lesen und schreiben diese Form. Perfuse liest und schreibt dieselbe Form:

Das Format wurde aus dem beobachteten Ausgabe- und veröffentlichten Format von Open Integration Engine 4.6 erstellt und wird gegen dieses überprüft: 25 generierte Interchanges und 4 beibehaltene Beispiele werden Byte für Byte wie von OIE geschrieben und zurückgegeben (siehe Überprüfung). Ein DOCTYPE wird abgelehnt, wie in jeder XML, die Perfuse liest.

8.3.2 Aufteilen eines Austauschs

Das Festlegen von split macht jeden Transaktionssatz zu einer eigenen Nachricht mit seinem eigenen Datensatz, seinen eigenen Metriken und seiner eigenen Zeile. Ein Operator, der nach einem einzelnen Anspruch sucht, findet dann einen einzelnen Anspruch und nicht eine Datei mit vierhundert.

Es ist standardmäßig deaktiviert, da die Aktivierung alles Downstream multipliziert - Nachrichtenzahlen, Zeilen, Warnschwellen - und ein Schwellenwert, der für Dateien, die plötzlich Ansprüche zählt, abgestimmt wurde, nicht mehr dasselbe bedeutet, was er zuvor bedeutete. Das sollte eine Entscheidung sein, die jemand getroffen hat, und nicht ein Standard, den man geerbt hat.

split und acknowledge können nicht beide festgelegt werden, und ein Kanal mit beiden wird bei der Ladung abgelehnt. Eine Bestätigung ist eine Aussage über den gesamten Austausch, sodass das Aufteilen eine pro Transaktionssatz senden würde, und ein Partner, der mehrere 999-Nachrichten mit demselben Funktionsgruppennamen erhält, hat keine Möglichkeit, sie zu vereinbaren.

8.3.3 Wenn die Zahlen nicht addieren

X12 deklariert seine eigenen Zahlen - wie viele Segmente, wie viele Transaktionen - und der envelope-Schlüssel sagt, was zu tun ist, wenn sie nicht mit dem tatsächlich Vorhandenen übereinstimmen. Diese Zahlen sind der einzige Mechanismus, den X12 für die Erkennung hat, dass die Hälfte einer Anspruchdatei angekommen ist.

WertVerhalten
requireDer Austausch wird abgelehnt. Der Standard.
warnEr wird verarbeitet und der Fehler wird gegen die Nachricht aufgezeichnet.
ignoreEs wird nicht überprüft.

warn existiert für eine reale Situation: Die Software einiger Partner hat seit Jahren falsche Zahlen in ansonsten vollständigen Dateien generiert, und ein Standort, der diese verarbeiten muss, benötigt eine Möglichkeit, dies in der Konfiguration auszudrücken, anstatt die Überprüfung ganz abzuschalten.

ignore ist so benannt, um unangenehm zu sein. Das Festlegen davon wirft den einzigen Mechanismus weg, den X12 Ihnen bietet, um ein abgekürztes Datei zu erkennen, und eine abgekürzte Anspruchdatei ist nicht von einer kleinen zu unterscheiden.

8.3.4 Transaktionen, die Perfuse als strukturierte Daten liest

Jeder X12-Austausch kann geroutet, gefiltert und adressiert werden. Diese Transaktionen werden zusätzlich in benannte Felder analysiert, sodass ein Kanal fragen kann, was ein Zahlungspflichtiger entschieden hat, anstatt zu fragen, welches Element an Position vier sitzt.

TransaktionWas es enthält
835Abrechnungsberatung: was bezahlt wurde, was abgelehnt wurde und die Anpassungsgründe.
275Anspruchsanlagen: klinische Dokumentation, die einen Anspruch unterstützt.
277Anspruchstatus, einschließlich eines Zahlungspflichtigen, der um zusätzliche Dokumentation bittet.
278Vorabgenehmigung: die Anfrage zur Überprüfung und die Entscheidung des Zahlungspflichtigen.
999Funktionale Bestätigung, die Perfuse auch generiert.
271Eignung: ob ein Patient abgedeckt ist, und seine Mitversicherung, Selbstbeteiligung, Zuzahlung und außergewöhnliche Ausgaben, im und außerhalb des Netzwerks.
834Anmeldung: Mitglieder, die hinzugefügt, geändert und beendet wurden, mit jedem Abdeckungsstrang und seinen Daten.
837Ansprüche, professionell und institutionell (für die CARIN-Konvertierung von CMS-0057).

Perfuse erstellt auch die 270-Abfrage zur Eignung und die 276-Anfrage zum Status des Anspruchs unter Zahler → Ansprüche & Authentifizierung oder durch POST /api/x12/eligibility/build und /api/x12/claimstatus/build. Beide sind die HIPAA-5010-Versionen (005010X279A1, 005010X212), werden zurückgelesen und umhüllt überprüft, bevor sie angezeigt werden, und keines von beiden wird von dieser Seite aus gesendet: Die Lieferung einer davon ist die Aufgabe eines Kanals, in dem der Handelspartner und seine Anmeldeinformationen sind.

8.3.5 Eignung und die CAQH-CORE-Dateninhaltsregel

Eine 271 ist eine Liste von EB-Segmenten, von denen jedes eine einzelne Tatsache ist: aktive Abdeckung oder 25 $-Kopfzahl für Dienstleistungsart 30 im Netzwerk oder 800 $ des verbleibenden individuellen Selbstbehalts im Netzwerk. Der Leser setzt sie zu der Antwort zusammen, die eine Empfangstheke möchte - „Abdeckung aktiv unter Gold PPO 2000; Kopfzahl im Netzwerk 25 $; verbleibender individueller Selbstbehalt im Netzwerk 800 $“ - und benennt eine Ablehnung (ein AAA-Segment) in Worten, zusammen mit dem, was der Zahler als nächstes tun soll.

Es überprüft auch die Antwort gegen die CAQH-CORE-Regel für den Inhalt von Eignungs- und Leistungsdaten: Für eine Anfrage zur Abdeckung des Gesundheitsleistungsplans (Dienstleistungsart 30) sollte eine aktive Antwort Abdeckungsdaten, den Plan-Namen, Kopfzahl, Selbstbehalt, verbleibenden Selbstbehalt sowohl im als auch außerhalb des Netzwerks und die Basisdienstleistungsarten (1, 33, 35, 47, 48, 50, 86, 88, 98, AL, MH, UC) enthalten. Jeder wird als erfüllt oder fehlend aufgelistet. Dies ist Perfuses Lesart der Regel, nützlich für „Warum sagt uns dieser Zahler nie den Selbstbehalt?“ - Es handelt sich nicht um eine CORE-Zertifizierung, die CAQHs autorisierte Testanbieter durchführen.

8.3.6 Vorabgenehmigung

Perfuse implementiert die Vorabgenehmigung zweimal, mit Absicht.

Die FHIR-Seite ist das, was CMS-0057-F von den Zahlern verlangt, bis zum 1. Januar 2027 zu veröffentlichen. Die 278 ist das, was die Zahler heute akzeptieren, und die Regel ersetzt es nicht - Da Vinci PAS ist in der Praxis eine Abbildung auf diese Transaktion, da eine 278 das ist, was ein Nutzungsmanagement-System spricht. Ein Motor, der nur die FHIR-Hälfte liest, kann mit den Systemen sprechen, die existieren werden und nicht mit denen, die es nicht tun.

Eine 278-Antwort enthält die Autorisierungsnummer, und das ist das Feld, für das die gesamte Transaktion existiert. Ohne sie ist ein zertifizierter Dienst nicht abrechnungsfähig: der Anspruch wird ohne Autorisierungsnummer eingereicht und wegen Fehlens einer solchen abgelehnt, was downstream als klinische Ablehnung gelesen wird.

Eine Ablehnung und eine Ablehnung zur Berücksichtigung sind nicht dasselbe

Dies ist die teuerste Verwirrung in der Transaktion, und Perfuse berichtet die beiden getrennt.

Was angekommen istWas es bedeutetWas zu tun ist
HCR mit Aktion A3Der Zahler hat den Antrag berücksichtigt und wird ihn nicht zertifizieren.Berufung einlegen oder den Behandlungsplan ändern.
Ein AAA-SegmentDer Zahler wird es nicht berücksichtigen - Patient nicht gefunden, Antragsteller nicht anerkannt, Überprüfung nicht abgedeckt. Nichts wurde entschieden.Den Antrag korrigieren und erneut senden.

Beide werden als „nicht genehmigt“ für jeden gelesen, der scanniert, und die richtigen Aktionen sind entgegengesetzt. Die Berufung auf etwas, über das niemand entschieden hat, führt zu nichts; die erneute Einreichung einer Ablehnung produziert dieselbe Ablehnung. Der Name des geparsten Ergebnisses sagt, was passiert ist — denied gegenüber not-considered — und AAA04 enthält den Rat des Zahlungspflichtigen, ob die Anfrage überhaupt wiederholbar ist.

Eine teilweise Zertifizierung wird als partially-certified gemeldet, anstatt in die Genehmigung einbezogen zu werden. Es gibt eine Autorisationsnummer, gegen die abgerechnet werden kann, also zählt es als genehmigt, aber die zertifizierte Menge ist nicht die angeforderte Menge — und eine Praxis, die sechs Sitzungen gegen drei Genehmigungen bucht, entdeckt es bei der vierten Abrechnung.

Ein Aktioncode, den Perfuse nicht erkennt, wird als unknown gemeldet, nicht als ausstehend. Ausstehend liest sich als „warten“, und warten ist die falsche Aktion für die meisten Dinge, die ein nicht erkannter Code sein könnte.

Ein Kanal kann direkt auf die Entscheidung umleiten:

filter: HCR-1 == "A3"

Umwandlung zwischen den beiden

Perfuse wandelt eine analysierte 278 in eine Da Vinci PAS ClaimResponse um und meldet jede Entscheidung, die die Umwandlung benötigt, anstatt nur das Ergebnis. Die Umwandlung folgt drei Regeln:

Die Einschränkung auf ein dreistufiges Vokabular - genehmigt, abgelehnt, ausstehend - ist verfügbar und explizit darüber, was es verwirft. Die Einschränkung einer Ablehnung zur Berücksichtigung ergibt "abgelehnt" und sagt in Worten, dass die richtige Aktion eine korrigierte erneute Einreichung und nicht eine Berufung ist.

Überprüft gegen PAS 2.2.1, nicht nur gegen sich selbst

Die ClaimResponse ist an das Da Vinci PAS 2.2.1-Profil angepasst und wurde mit dem offiziellen HL7-Validator überprüft, der mit dem veröffentlichten PAS-Paket geladen wurde. Die erste Version war nur von den eigenen Tests von Perfuse überprüft worden, und der Validator lehnte sie mit sechs bis acht Fehlern pro Ressource ab. Jeder von ihnen ist etwas, das auch ein PAS-Endpunkt eines Zahlers abgelehnt hätte:

Was falsch warWo PAS es platziert
Die Entscheidung war in adjudication.category und reason.Die reviewAction-Erweiterung, auf einer Adjudikation, deren Kategorie submitted ist.
Der Grundcode wurde nach X12-Element 1034 benannt.X12-externes Code-Liste 886.
Ein ausstehender Antrag antwortete outcome: queued.outcome ist über die Verarbeitung und PAS erlaubt nur complete, error und partial. Ein ausstehender Antrag ist complete, mit Überprüfungsaktion A4.
processNote.type war ein CodeableConcept.R4 hat einen Code: print.
patient, created, insurer und request fehlten.Alle vier sind erforderlich. Sie werden als Identifier-Verweise angegeben, da die Antwort allein steht und nicht in einem Bundle.

Die korrigierte Ausgabe validiert ohne Fehler für eine Zertifizierung, eine Ablehnung und eine ausstehende Anfrage. Die Warnungen, die bleiben, sind der Validator, der sagt, dass er die X12-Code-Systeme nicht laden kann, die X12 lizenziert. Die Autorisierungsnummer wird in reviewAction.number übertragen, wo das Beispiel des Leitfadens es platziert, und in preAuthRef, wenn die Antwort nur eine hat.

Der Validator ist nicht Teil von make check, da er Java und einen Download des Leitfadens und seiner Abhängigkeiten benötigt. Was er gefunden hat, wird von einem Test gehalten: Jede Regel, die er durchgesetzt hat, wird behauptet, sodass eine Änderung, die einen dieser Fehler wieder einführt, fehlschlägt.

Die Claims & auth-Ansicht wandelt eine eingefügte 278 um und zeigt die Entscheidungen, die Notizen und die Ressourcen an.

8.3.7 Anhänge und warum sie eine spezielle Behandlung benötigen

CMS-0053-F macht die 275 zu einem HIPAA-Standard für Claims-Anhänge, wobei die Einhaltung bis zum 26. Mai 2028 erforderlich ist. Sie enthält ein Dokument - eine Operationsnotiz, einen Bildbericht, ein gescanntes Formular - das an den Anspruch geknüpft ist, den es unterstützt.

Die 277 ist die andere Hälfte desselben Gesprächs. Ein Zahlungspflichtiger erhält einen Anspruch, entscheidet, dass er Dokumentation benötigt, und sendet eine 277 mit der Anfrage; der Anbieter antwortet mit einer 275.

Ein Kanal kann direkt auf den Statuscode umleiten, da STC01 ein Composite ist und dessen zweiter Bestandteil der Status ist. In kanonischer Form geschrieben, da ein Bestandteil mit einem Punkt angesprochen wird und die beiden Notationen nicht gemischt werden können - STC-1.2 ist Element 1, Bestandteil 2:

filter: STC-1.2 in ("227", "233", "252", "287")

Das sind die Codes, die unmissverständlich bedeuten, dass ein Dokument gewünscht wird. Die Status-Kategorie in STC-1.1 wird absichtlich nicht allein verwendet: R4 bedeutet in einigen Implementierungsleitfäden eine Dokumentenanfrage und in anderen "weitergeleitet an anderer Stelle", sodass ein Filter auf die Kategorie allein finalisierte Ansprüche in die Warteschlange für jemanden einfügen würde, der sie verfolgen soll.

Zwei Identifikatoren entscheiden, ob ein Anhang jemals mit seinem Anspruch verknüpft wird, und beide werden gemeldet: die Anhangskontrollnummer, die der Anbieter auf den ursprünglichen Anspruch gesetzt hat, um anzugeben, dass Dokumentation folgen wird, und die Spurnummer, die der Anfrage des Zahlungspflichtigen entspricht. Ein Anhang, der ohne eine dieser Nummern ankommt, wird abgelegt und nie mit etwas verknüpft, während der Anspruch altert.

Ein Dokument innerhalb einer 275 wird nicht interpretiert. Perfuse meldet seine Bytes und das, was der Absender darüber sagt. Ein Anhang kann ein PDF, ein TIFF, ein CDA-Dokument oder eine HL7-Nachricht sein, und ein Kanal, der den Inhalt benötigt, kann diese Bytes an das Format weitergeben, das sie liest.

Das Formular 006020, das die Regel übernimmt

CMS-0053-F übernimmt die Version 006020, und dessen 275 unterscheidet sich von der 005010-Form in zwei Punkten, die wichtig sind.

Perfuse entpackt die Entität und meldet das Dokument innerhalb davon, mit seinem Inhaltstyp und Dateinamen. Die Bytes, die es meldet, sind genau die, die der Absender verpackt hat. Eine Entität, die nicht entpackt werden kann, lässt die rohe Nutzlast an ihrem Platz, mit einer Notiz, die angibt, warum.

Erstellung einer 275. Perfuse erstellt auch 006020X314-Anhänge: einen unverlangten, der einen Anspruch begleitet, oder eine Antwort auf eine Anfrage des Zahlungspflichtigen mit einer 277. Der Unterschied liegt in BGN01 02 gegen 11 und darin, ob TRN02 den PWK06 des Anspruchs oder den TRN02 der 277 enthält. Jeder erstellte Austausch wird vor seiner Rückgabe erneut analysiert, und die Antwort sagt, ob das Dokument innerhalb dessen das ist, das hereingekommen ist.

Die Struktur stammt aus den zwei veröffentlichten Begleitleitfäden für 006020X314: dem CMS-esMD-Leitfaden und dem von UnitedHealthcare. Sie stammt nicht aus dem X12-Technikbericht, den X12 lizenziert und den dieses Projekt nicht besitzt.

Es gibt keine Validierung gegen den Technikbericht. Der Begleitleitfaden des Partners regelt.

8.3.8 Elektronische Signaturen auf Anhängen

CMS-0053-F übernimmt auch einen Signaturenstandard, in 45 CFR 162.2002(e): den HL7-Implementierungsleitfaden für CDA Release 2, Digitale Signaturen und Delegation von Rechten, Release 1. Er gilt für Signaturen, die auf Anhangsinformationen gesetzt werden, wenn sie in einer HIPAA-Anhangstransaktion gesendet werden, ab dem 26. Mai 2028. Ein Zahlungspflichtiger darf nicht mehr verlangen, als der Leitfaden vorsieht.

Perfuse signiert ein C-CDA auf diese Weise auf dem Weg in eine 275 und überprüft die Signaturen auf jedem C-CDA in einer 275, die es liest.

Wenn eines davon nicht verfügbar ist, wird die Signatur dennoch erstellt und ist gültig. Das Ergebnis nennt die XAdES-Form, die erreicht wurde, und gibt an, was sie daran gehindert hat, X-L zu erreichen: beispielsweise ein selbstsigniertes Zertifikat (keine CA, die gefragt werden kann) oder keine Zeitstempelbehörde.

Der Schlüssel ist -signing-cert und -signing-key. Legen Sie die CA-Zertifikate nach dem Signierzertifikat in der gleichen Datei ab, damit der Pfad mit der Signatur mitgegeben wird. Für eine Signatur, die das bedeutet, was DSDR bedeutet, sollte das Zertifikat den Cliniker nennen, mit seiner NPI, anstelle des Servers. Die Signierung ist eine Admin-Aktion, da die Signierung jedes Dokuments eine solche ist.

Der Leitfaden nennt keinen Namespace für seine eigenen Elemente. Perfuse legt digitalSignature, authorizedSigner und SignaturePurpose in urn:hl7-org:sdtc ab. Es gibt auch den Zweck als XAdES-Commitment-Typ mit dem ASTM-OID an, den XAdES-Tools verstehen. Die Delegation von Rechten, bei der ein Delegierter mit einer SAML-Behauptung vom autorisierten Signierer signiert, wird nicht produziert, und ein empfangener wird als nicht verifiziert gemeldet.

Die Anbieter-NPI wird gegen ihre Prüfziffer überprüft. Ein Zahlungspflichtiger ordnet eine Anlage seinem Anspruch teilweise anhand dieser Nummer zu, und eine falsch eingegebene Nummer lässt die Anlage unzugeordnet, während der Anspruch wegen fehlender Dokumentation abgelehnt wird.

Die Ansprüche & Auth-Ansicht erstellt ein 275 aus einer eingefügten C-CDA oder einer hochgeladenen Datei, optional signiert die C-CDA, und liest eine zurück mit den Ergebnissen jeder Signatur. Nichts auf dieser Seite sendet etwas: der Austausch wird an einen Kanal weitergegeben, der den Partner, die Anmeldeinformationen und die Audit-Trail enthält.

8.3.9 Binärsegmente

Ein BIN-Segment enthält rohe Bytes, und rohe Bytes enthalten Trennzeichen. Jedes andere X12-Segment endet am Segment-Terminator, sodass ein normaler Parser Segmente findet, indem er nach einem Byte sucht; eine Anlage kann nicht auf diese Weise gefunden werden. Ein PDF, das ein ~ enthält, würde in Stücke geschnitten, und jedes Stück wäre ein strukturell gültiges Segment - somit würde das Dokument abgeschnitten, jedes Segment danach wäre fehljustiert, und nichts würde einen Fehler melden.

Perfuse liest die Byte-Zahl, die das Segment deklariert, und nimmt genau diese vielen Bytes. Zwei Konsequenzen, die es wert sind, zu wissen:

Der esMD-Leitfaden gibt selbst ein Beispiel für einen Austausch an, der 16 Bytes für die gleiche 53-Byte-Nutzlast deklariert, die seine Tabelle korrekt als 53 zählt. Perfuse lehnt dieses Beispiel ab, wie es sollte. Ein Test enthält sowohl das Beispiel der Tabelle als auch den Tippfehler des Beispiels, sodass eine Änderung in beide Richtungen bemerkt wird.

8.4 FHIR

8.4.1 Woraus eine HL7-v2-Nachricht wird

Der Nachrichtentyp entscheidet, was produziert wird, und jede Konvertierung berichtet die Urteile, die sie benötigte, als Notizen neben dem Bundle.

v2FHIR
ADTPatient, ein Encounter, wenn ein Besuch vorliegt, ein Condition pro DG1-Diagnose (auch in der Encounter-diagnosis aufgeführt, eine zugelassene als AD), ein Procedure pro PR1 und ein AllergyIntolerance pro AL1. A28, A31, A29 und A24 beziehen sich auf die Person, so dass sie keinen Encounter oder Diagnosen erzeugen, aber Allergien enthalten.
ORUDiagnosticReport pro OBR, mit seinen Observations und Specimen, und der Bestellung, die es beantwortet, als ServiceRequest (sein Anforderer OBR-16 oder ORC-12, sein Status ORC-5); OBR-32 ist der Ergebnis-Interpreter, OBR-34 und OBR-35 sind die Ausführenden. Ergebnisse werden unter dem vorherigen OBR nach Position gruppiert, da OBX-4 nicht zuverlässig ist.
ORM, OML, OMGServiceRequest.
SIUAppointment, mit dem Patienten, den Praktikern aus AIP und den Standorten aus AIL.
MDMDocumentReference, der das Dokument enthält.
VXUImmunization, eine pro RXA.

Alles andere produziert den Patienten und eine Warnung, die den Typ nennt, der nicht zugeordnet wurde.

Scheduling. Eine Buchung, eine Umbuchung, eine Stornierung und ein No-Show landen alle auf dem gleichen Appointment. Seine Identität kommt von den eigenen Zahlen des Appointments in SCH-1 und SCH-2, niemals von der Nachricht, sodass eine Stornierung die Buchung aktualisiert. Die Alternative wäre ein zweites, storniertes Appointment neben einem aktiven, was zeigt, dass der Patient in einem Slot gebucht ist, der nicht mehr existiert.

Dokumente. Textnotizen (TX, FT, ST) behalten ihre Zeilenumbrüche bei, einschließlich leerer Zeilen, da ein leerer Wiederholung in einer Notiz ein Absatzumbruch ist.

Dies ist, wonach das CMS-Interoperabilitätsframework-Kriterium 14 fragt: Krankenblatt-Notizen und klinische Dokumente als FHIR-Anhänge zurückgegeben.

Impfungen. Eine Dosis wird nie als verabreicht gemeldet, wenn die Nachricht das Gegenteil besagt.

Ungünstige Eingaben. Jede dieser wird in den Notizen gemeldet, anstatt stillschweigend entschieden zu werden:

8.4.2 Was ein Standort hinzufügt: das Bundle-Skript

Ein nationales Profil möchte oft, was eine HL7-v2-Nachricht nicht enthält: eine Krankenhaus-IK-Nummer oder ODS-Code, welches Kontaktlevel ein Besuch ist (ISiK), ob ein Vorname ein erster Name oder eine Initiale ist (das niederländische nl-core). Perfuse errät diese nicht. Ein fhir-Ziel hat ein bundle_script, in dem ein Standort sie schreibt: JavaScript, das auf jedes konvertierte Bundle ausgeführt wird, als bundle, bevor es validiert und gesendet wird. Was das Skript übrig lässt, ist, was ausgeht, wie jede Konvertierung überprüft wird, und ein Skript, das einen Fehler wirft, versagt die Nachricht wie jeder Transformer. Die Konsole hat es unter dem Ziels *Hinzufügen, was Ihre Systeme wissen*.

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.

Das Bundle geht durch Perfuses Modell auf seinem Rückweg, sodass die Änderungen eines Skripts überprüft und im Ziels FHIR-Version geschrieben werden. Mitglieder, für die das Modell kein Feld hat, werden so beibehalten, wie das Skript sie geschrieben hat, auch innerhalb von Datentypen.

8.4.3 US Core 9.0.0 und USCDI v6

-us-core (und claim_us_core auf einem fhir-Ziel) setzt ein US-Core-Profil in meta.profile, aber nur auf einer Ressource, die gegen dieses Profil überprüft und als konform befunden wurde. Eine, die nicht den Anforderungen entspricht, wird dennoch umgewandelt und ohne den Anspruch gesendet, und eine Notiz gibt den Grund an, wie z.B. "US Core erfordert einen Kontakttyp und dieser Kontakt hat keinen". Die Überprüfungen werden aus US Core 9.0.0 transkribiert, der Version, die ONCs 2026 Standards Version Advancement Process für USCDI v6 genehmigt. Sie umfassen Patient, Kontakt, die Labor-Observation und DiagnosticReport, Specimen, Practitioner, Organization, Location, Immunization, DocumentReference, die Kontakt-Diagnose Condition und AllergyIntolerance.

Was der Konverter überträgt, nach USCDI v6-Datenclass:

USCDI v6VonAls
Patientendemografische DatenPIDName, Geburtsdatum, Geschlecht, Adresse, Telefon und E-Mail, Identifikatoren. Rasse und ethnische Zugehörigkeit (PID-10, PID-22) in US Core-Erweiterungen, wenn sie in CDC-Rasse und ethnische Zugehörigkeit kodiert sind. Bevorzugte Sprache (PID-15) als BCP 47
Informationen zum AufenthaltPV1Aufenthalt mit Typ, Klasse, Zeitraum, Standort und Teilnehmern
EinrichtungsinformationenPV1-3Standort, mit der Einrichtung als seiner verantwortlichen Organisation
Probleme, BeginnDG1Condition (Aufenthaltsdiagnose). DG1-5 ist der Beginn, wie ihn die HL7-v2-zu-FHIR-Karte hat
Allergien und Unverträglichkeiten, ReaktionAL1AllergyIntolerance mit Kategorie, Kritikalität und Reaktion
LaborORUDiagnosticReport, Observations, Specimen (aus SPM), ServiceRequest
BestellungenORM, OMLServiceRequest
ImpfungenVXUImmunization
Klinische NotizenMDMDocumentReference
Mitglieder des PflegeteamsPV1, TXA, DG1Practitioner

Nicht übernommen, da v2-Nachrichten dieser Typen sie nicht enthalten oder Perfuse sie nicht zuordnet: Medikamente, Verfahren, Ziele und Präferenzen, Gesundheitsstatusbewertungen, Pflegeplan, Familien-Gesundheitsgeschichte, Medizinische Geräte (UDI), Gesundheitsversicherungsinformationen, Vitalzeichen als eigenes Profil und Herkunft.

8.4.4 R4 in beide Richtungen

Ein FHIR-Server, der R4 deklariert, akzeptiert R4. Das war bis zu dieser Version nicht der Fall bei Encounters. Der Server konvertierte, was er bereitstellte, in R4, aber las, was er erhielt, als ob es bereits in seiner internen Form vorlag, so dass ein R4-Encounter mit einem 400 abgelehnt wurde. Ebenso wurde jedes Bundle abgelehnt, das Perfuse eigene ADT-Konvertierung produzierte, da jedes Encounter.class enthält, das R4 als einzelnes Coding schreibt.

Es wurde das erste Mal festgestellt, als etwas ein konvertiertes ADT an Perfuse eigenen R4-Server gesendet wurde. Ein Test tut dies jetzt für jeden kartierten Nachrichtentyp, und ein weiterer überprüft, dass alles, was als R4 geschrieben wird, unverändert gelesen wird.

8.4.5 Internationale Patientenzusammenfassung

GET /fhir/Patient/{id}/$summary, oder GET /fhir/Patient/$summary?identifier=system|value, gibt eine internationale Patientenzusammenfassung (HL7 IPS 2.0.0) zurück: ein FHIR-document-Bundle, dessen Composition die aktiven Probleme, Allergien, Medikamente, Impfungen, Ergebnisse, Vitalwerte, Eingriffe, Geräte, vergangene Erkrankungen, Sozialgeschichte und Behandlungspläne des Patienten auflistet, jeweils mit einer lesbaren Erzählung. Es ist die kurze Aufzeichnung, die ein Kliniker, der den Patienten noch nie getroffen hat, zuerst liest, und die Zusammenfassung, die der Europäische Gesundheitsdatenraum ab 2029 zwischen den Ländern austauscht.

Es wird aus dem aufgebaut, was der FHIR-Speicher enthält, und nichts wird erfunden:

Access follows $everything: a token limited to one patient gets a 403 for another, and an identifier that matches two patients is refused rather than guessed. Only the IPS profile is built; asking for another profile is refused. The document Perfuse produces from its test records validates against the IPS 2.0.0 Bundle profile with the HL7 validator, with no errors. A record built from real feeds can still fail where the feed's own codes do (a display name the code system does not use, for example), because the summary passes the data on as it was received.

Austausch → Gesundheitslinks → Teilen füllt den Inhalt mit einer Patientenzusammenfassung: geben Sie die FHIR-ID des Patienten ein und wählen Sie Verwenden Sie ihre Patientenzusammenfassung, dann lesen und erstellen Sie den Link. Die Erstellung wird als fhir.summary auditiert.

8.4.6 Übertragungszusammenfassungen für post-akute Pflege (PACIO)

Wenn ein Patient aus dem Krankenhaus in ein Pflegeheim, eine Rehabilitationseinheit oder eine häusliche Gesundheitsversorgung entlassen wird, sendet das Krankenhaus-EHR ein C-CDA: eine Übertragungszusammenfassung, eine Entlassungszusammenfassung oder ein CCD. Perfuse wandelt dieses Dokument in die Übertragungszusammenfassung um, die PACIOs Transitions of Care-Leitfaden beschreibt (hl7.fhir.us.pacio-toc 1.0.0): ein FHIR R4 document-Bundle, US Core 8.0.1 darin, das das Empfangssystem der Einrichtung ohne dass jemand XML lesen muss, ablegen kann.

Drei Möglichkeiten, eines zu erstellen:

Überprüft mit dem offiziellen FHIR-Validator gegen das TOC 1.0.0 Bundle-Profil, auf HL7-eigenen C-CDA-Beispielen (eine Übertragungszusammenfassung, eine Entlassungszusammenfassung und ein CCD). Der eine Fehler, den es meldet, befindet sich in der Anleitung: Jedes Vitalzeichen entspricht sowohl seinem simple-observation- als auch seinem vital-signs-Bundle-Eintrag, sodass es von keinem Absender vermieden werden kann. Noch nicht erledigt: Die Umwandlung der textbasierten Abschnitte (Funktionsstatus, psychischer Status, Pflegeplan, Geräte) in codierte Ressourcen und die TOC-Dokumentreferenz der Anleitung, die einen gespeicherten Übertragungszusammenfassung indexiert.

8.4.7 Abonnements

Mit -fhir-subscriptions sendet der FHIR-Endpunkt Benachrichtigungen, wenn ein Encounter oder eine Terminvereinbarung erstellt oder geändert wird. Es folgt dem FHIR-Subscriptions-R5-Backport-IG für R4, das von CMS Interoperability Framework-Kriterium 15 und TEFCA's FHIR-Roadmap für Termin- und Encounter-Benachrichtigungen verwendet wird.

Ein Client erstellt ein Subscription, das ein Thema angibt, und optional einen Filter wie Encounter?patient=Patient/123. Die Themen sind in der Fähigkeitsanzeige aufgeführt:

ThemaAuslöst aufFilter
https://perfuse.health/fhir/SubscriptionTopic/encounterEncounter erstellt oder aktualisiertpatient, status, class
https://perfuse.health/fhir/SubscriptionTopic/appointmentTerminvereinbarung erstellt oder aktualisiertpatient, status

Ein Filter, der etwas anderes angibt, wird abgelehnt, nicht ignoriert. Ein ignorerter Filter ist ein Abonnement, das Benachrichtigungen über jeden Patienten sendet, wenn der Client nach einem bestimmten Patienten gefragt hat.

Die Eigenschaften, um die die Implementierung aufgebaut ist:

Was ein Client den Server tun lassen kann, ist absichtlich begrenzt:

Es ist standardmäßig deaktiviert, da ein FHIR-Client diesen Server auffordern kann, Patientendaten an eine URL des Clients zu senden, sobald es aktiviert ist. Es benötigt einen R4-Endpunkt, der Schreibvorgänge akzeptiert, und weigert sich, andernfalls zu starten.

Nicht implementiert, sodass niemand durch Ausprobieren herausfinden muss:

Die Abonnements-Ansicht zeigt für jedes Abonnement das Thema, den Filter und den Endpunkt an, wie viele Ereignisse es hatte, wie viele akzeptiert wurden und wie viele warten, sowie den letzten Grund, warum eines abgelehnt wurde. Headerwerte und die Abfragezeichenfolge des Endpunkts werden zurückgehalten, da dies der Ort ist, an dem die Anmeldeinformationen des Abonnenten gespeichert sind.

8.5 NCPDP Telekommunikationsstandard

Apothekenansprüche. Fester Breitenkopf, gefolgt von variablen Segmenten.

Zwei Details, die wichtig sind, beide leicht falsch zu machen und plausiblen Ergebnissen zu produzieren:

Der Kopf ist genau 56 Bytes lang und hat eine feste Breite. Ein kurzer Kopf kann nicht allein durch die Länge erkannt werden, da ein abgekürzter Kopf plus die folgenden Segmente immer noch 56 Bytes überschreitet. Die Erkennung erfolgt durch die Suche nach einem Trennerbyte, sodass ein Nachricht, die eines enthält, abgelehnt wird, wobei die Anzahl der fehlenden Bytes angegeben wird.

0x1E und 0x1C sind Gruppen- und Feld-Start-Marker, keine Trenner. Wenn sie als Trenner behandelt werden, werden alle Felder um eine Position nach links verschoben, und die meisten der resultierenden Werte bleiben plausibel — eine Menge landet, wo ein Tagessatz erwartet wurde, und beide sind Zahlen.

NCPDP- und SCRIPT-Kanäle sind von der MLLP-Einrahmung ausgeschlossen, und dies wird durchgesetzt, anstatt nur empfohlen. Ein Anspruch enthält legitimerweise 0x1C, was MLLP eigenes End-of-Block-Byte ist, sodass die Einrahmung eines Anspruchs bei dem ersten Feldmarker abgeschnitten würde.

8.6 NCPDP SCRIPT

Elektronische Rezepte, in XML. Das interne Paket heißt eprescribe, weil script vom JavaScript-Engine bereits verwendet wurde.

Die zentrale Sicherheitsbedenken ist die Ersetzungsflagge, und sie liest sich entgegen der Intuition: im Datenverkehr bedeutet 0, dass die Ersetzung erlaubt ist, und 1 bedeutet, dass sie als geschrieben abgegeben werden soll.

Eine fehlende Ersetzungsflagge wird abgelehnt, anstatt standardmäßig gesetzt. Beide möglichen Standardwerte erreichen den Patienten — einer kann ein Generikum abgeben, wo der verschreibende Arzt die Marke erforderte, der andere verhindert eine Ersetzung, die der verschreibende Arzt erlaubt hat —, sodass es keine sichere Annahme gibt und die Nachricht stoppt.

Ein Rezept der Klasse II mit Wiederholungen wird abgelehnt, und der Ersteller wird keinen produzieren.

Ablehnungen und Warnungen werden als separate Listen aufbewahrt, anstatt als eine Liste mit Schweregrad-Tag, da ein Leser, der einen Schweregrad-Tag überprüfen muss, um zu wissen, ob die Nachricht gesendet wurde, schließlich nicht überprüfen wird.

Elektronische Vorabgenehmigung (PAInitiationRequest, PARequest, PAAppealRequest, PACancelRequest) und Echtzeit-Rezeptvorteil werden von der Zahlungsseite unter /ncpdp/script und /ncpdp/rtpb beantwortet, aus der Arzneimittel-Formulierung; siehe CMS-0057.

8.7 DICOM

Bildgebung. Perfuse kann DICOM-Objekte empfangen, eine Remote-Archiv abfragen und in einem speichern, über die klassischen DICOM-Netzwerkdienste oder über DICOMweb, und es kann ein eigenes Archiv für Viewer aufbewahren.

DICOM ist kein Nachrichtenformat im gleichen Sinne wie die anderen — Objekte sind groß, und die Assoziations-Handshake ist wichtiger als die Payload-Parsing. Die called_ae- und calling_ae-Titel sind der häufigste Grund, warum eine erste Verbindung fehlschlägt, und der Fehler sieht wie ein Netzwerkproblem aus, anstatt ein Konfigurationsproblem.

8.7.1 Was ein C-STORE-Listener akzeptiert

Wenn ein DICOM-Listener geöffnet wird, akzeptiert er alles von jedem, der den Port erreichen kann. Vier Einstellungen unter Was dieser Listener akzeptiert verengen dies, und die erste ist die, die verstanden werden sollte.

Nur diese aufrufenden AE-Titel akzeptieren ist die Einschränkung. Der *aufgerufene* AE-Titel — der neben der Adresse steht — ist der Name, den ein Absender wählt, um diesen Listener zu identifizieren, und er ist keine Einschränkung. Jeder, der den Port erreichen kann, kann den korrekten aufgerufenen AE-Titel verwenden, da er veröffentlicht wird. Ohne eine Liste der zulässigen Anrufer kann jeder Host im Netzwerk Bilder in einen klinischen Kanal pushen.

Nur diese SOP-Klassen akzeptieren und nur diese Übertragungssyntaxen akzeptieren nehmen durch Komma getrennte UIDs. Leer akzeptiert jeden Objekttyp und verhandelt jede Komprimierung, die der Absender anbietet, was auch Arten umfasst, die dieser Kanal nicht verarbeiten kann. Die Ablehnung bei der Assoziation ist für den Absender klarer als die Annahme des Objekts und das spätere Scheitern.

Größtes akzeptiertes Objekt ist in Bytes angegeben, und Null bedeutet keine Begrenzung. Ganzglasbilder und lange Serien können Gigabytes erreichen, daher ist die Begrenzung ansonsten durch den Speicher bestimmt.

8.7.2 DICOMweb

DICOMweb ist DICOM über HTTP: QIDO-RS-Suchen, WADO-RS- und WADO-URI-Retrieval, STOW-RS-Speicherung. Browser-Viewer wie OHIF sprechen nur DICOMweb, und auch die Cloud-Bildgebungsdienste (Google Cloud Healthcare, Azure Health Data Services, AWS HealthImaging). Perfuse verwendet es an drei Stellen.

Das Bilddatenarchiv. Starten Sie den Server mit -dicomweb-archive DIR (Einstellungen › Daten › Bilddatenarchiv) und es speichert Objekte in diesem Ordner, indiziert in SQLite und stellt sie unter /dicomweb auf der eigenen Adresse der Konsole bereit: QIDO-RS auf Study-, Series- und Instance-Ebene, WADO-RS für Objekte, Metadaten, Frames und Massendaten, WADO-URI unter /dicomweb/wado und STOW-RS. Das Lesen übernimmt die Viewer-Rolle und das Speichern die Operator-Rolle, mit einer Sitzung oder einem API-Token; jeder Lese- und Speichervorgang wird in Aktivität als dicomweb.read oder dicomweb.store protokolliert. Ein Konto, das auf einen Mandanten oder auf Kanalgruppen beschränkt ist, wird abgelehnt, da das Archiv dem gesamten Server gehört. Objekte werden genau so gespeichert, wie sie empfangen werden, sodass das, was ein Viewer abruft, bytegenau das ist, was gespeichert wurde. Frames werden in der Übertragungssyntax zurückgegeben, in der sie gespeichert wurden; eine Anfrage, die eine Transkodierung erfordern würde, antwortet mit 406 anstelle eines konvertierten Bildes.

Eine Suche nach einem Attribut, das das Archiv nicht indiziert, antwortet mit 400 anstelle der Ignorierung der Bedingung und der Rückgabe mehrer Studien als angefordert. Indiziert: Patientenname (Wildcards und fuzzy matching mit fuzzymatching=true), Patienten-ID, Geburtsdatum, Geschlecht, Studiendatum und -uhrzeit (Bereiche), Zugangsnummer, Studien-ID, Beschreibung, überweisender Arzt, Studie, Serie und SOP-Instance-UIDs (Listen), Modalität, Körperteil, Seriennummer und -beschreibung, SOP-Klasse, Instanznummer, Zeilen, Spalten und Anzahl der Frames.

Die Quelle. type: dicomweb hört auf STOW-RS, standardmäßig unter /dicom-web/studies (den Pfad, den Orthanc und dcm4chee verwenden), und sendet jedes Objekt durch den Kanal als DICOM-Nachricht. Der Kanal benötigt dataType: dicom. Legen Sie einen Bearer-Token oder einen Benutzernamen und ein Passwort fest: ohne eines kann jeder, der den Port erreichen kann, Bilder in den Kanal senden. Die Antwort listet jedes Objekt als gespeichert oder fehlgeschlagen auf, mit dem DICOM-Fehlergrund, sodass ein Sender weiß, welche er erneut senden muss.

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}

Das Ziel befindet sich unter Lieferung, unter DICOMweb-Archiven.

OHIF auf das Archiv verweisen

Verwenden Sie eine DICOMweb-Datenquelle mit qidoRoot und wadoRoot, die auf die Adresse des Archivs gesetzt sind (der Bildschirm zeigt sie an, mit dem gesamten Datenquellenblock zum Kopieren), wadoUriRoot auf diese Adresse gefolgt von /wado, imageRendering und thumbnailRendering auf wadors und supportsFuzzyMatching auf true. Ein Viewer auf einem anderen Ursprung benötigt diesen Ursprung in -dicomweb-cors (Zulässige Browser-Ursprünge), und seine Anfragen benötigen ein API-Token im Authorization-Header, da ein Browser auf einem anderen Ursprung das Sitzungscookie der Konsole nicht sendet. Das Bereitstellen von OHIF vom gleichen Ursprung über einen Reverse-Proxy vermeidet beides.

Getestet gegen Orthanc mit seinem DICOMweb-Plugin, in beide Richtungen: das Ziel speichert in Orthanc, und Orthancs DICOMweb-Client durchsucht das Archiv von Perfuse und ruft eine Studie ab, die byte-identisch mit der gespeicherten ist. OHIF 3 listet die Studien des Archivs auf und zeigt ihre Frames mit den oben genannten Einstellungen an. OHIF und mehrere andere Clients senden type= unquoted in den Accept- und Content-Type-Headern, was RFC 2045 nicht erlaubt; Perfuse akzeptiert es.

8.8 IHE-Dokumentfreigabe: XDS.b, XCA, XDR, MHD, PIXm und PDQm

Klinische Dokumente, die zwischen Organisationen auf die Weise von Gesundheitsinformationenaustauschen, Carequality und eHealth Exchange geteilt werden: ein Repository enthält sie, ein Register indiziert ihre Metadaten und eine Gemeinschaft beantwortet die Anfragen anderer Gemeinschaften durch ein Gateway. Starten Sie den Server mit -xds REPOSITORY-OID (Einstellungen › Daten › Dokumentfreigabe) und es ist all dies, in der Datenbank dieses Servers, unter diesen Adressen, die jeweils ein API-Token als Bearer-Token akzeptieren (die Viewer-Rolle zum Abfragen und Abrufen, die Operator-Rolle zum Übermitteln; die meisten Affinitätsdomänen fügen mutual TLS davor hinzu):

AdresseAkteurTransaktionen
/xds/repositoryDokumenten-RepositoryITI-41 Dokumentensatz bereitstellen und registrieren-b, ITI-43 Dokumentensatz abrufen
/xds/registryDokumenten-RegisterITI-18 Registry-gespeicherte Abfrage (alle dreizehn gespeicherten Abfragen), ITI-42 Dokumentensatz registrieren-b
/xca/gatewayXCA-Antwort-GatewayITI-38 Cross-Gateway-Abfrage, ITI-39 Cross-Gateway-Abfrage, mit -xds-home-community urn:oid:...
/mhdMHD-Dokumenten-Empfänger und -AntwortenderITI-65 Dokumenten-Bundle bereitstellen, ITI-66 Listen finden, ITI-67 Dokumenten-Referenzen finden, ITI-68 Dokument abrufen
/mhd/PatientPDQm-Lieferant und PIXm-ManagerITI-78 Patienten-Demografien-Abfrage, ITI-83 Patient/$ihe-pix, aus dem FHIR-Speicher der Patienten
/pixv3PIX-Manager (HL7 v3)ITI-44 Patienten-Identitäts-Feed HL7 V3, ITI-45 PIXV3-Abfrage, aus dem Patienten-Index (-mpi)
/pdqv3PDQ-Lieferant (HL7 v3)ITI-47 PDQV3-Abfrage, mit Fortsetzung und Abbruch, aus dem Patienten-Index

Die SOAP-Transaktionen sind SOAP 1.2 mit WS-Addressing und MTOM/XOP, wo Dokumente reisen (ein Dokument inline als base64 wird auch akzeptiert). Eine fehlgeschlagene Transaktion wird mit einer RegistryResponse beantwortet, die IHE-Fehlercodes enthält, nicht mit einem SOAP-Fehler: XDSDuplicateUniqueIdInRegistry, XDSNonIdenticalHash, XDSPatientIdDoesNotMatch, XDSMissingDocument, XDSRegistryMetadataError (mit dem fehlenden Feld), XDSStoredQueryMissingParam, XDSUnknownStoredQuery, XDSUnknownRepositoryId, XDSUnknownCommunity und UnresolvedReferenceException. Ein Ersatz (RPLC, XFRM_RPLC) veraltet das Dokument, das es ersetzt, das dann nur noch Anfragen beantwortet, die nach veralteten Dokumenten fragen; APND, XFRM und signs werden als Assoziationen beibehalten. Hash und Größe werden vom Repository berechnet und mit dem überprüft, was die Übermittlung angibt. On-Demand-Dokumente und Metadatenaktualisierungen (ITI-57) werden nicht unterstützt und eine Übermittlung, die sie anfordert, wird mit dem Grund abgelehnt.

MHD ist das gleiche Register in FHIR: ein über MHD bereitgestelltes Dokument wird von ITI-18 und über XCA gefunden, und eines, das über XDS.b bereitgestellt wird, wird von ITI-67 gefunden. Die ID einer DocumentReference ist die UUID des Eintrags, die masterIdentifier die uniqueId und die URL des Attachments die ITI-68-Adresse des Dokuments. Patienten werden in die Affinitätsdomäne-Identifikator aus dem FHIR-Speicher aufgelöst: die erste Identifikator, deren System urn:oid: ist, oder der Patient, der im Bundle enthalten ist. PIXm beantwortet jede andere Identifikator des Patienten mit der gegebenen (sourceIdentifier=system|value, eingeschränkt durch targetSystem) und 404 für eine, die es nicht kennt; PDQm sucht nach Identifikator, Name, Geburtsdatum, Geschlecht, Adresse und Telecom.

Veröffentlichung. Ein Kanals xds-Ziel veröffentlicht jedes klinische Dokument, das es erhält, ein CDA-Dokument oder eines, das in einer HL7-v2-Nachricht enthalten ist, in jedem XDS.b-Repository mit ITI-41. Die Metadaten werden aus dem Dokument gelesen: der Patient (die Identifikator in patient_domain, die Affinitätsdomäne-Zuweisungsbehörde), Titel, Typ (als typeCode und, sofern nicht festgelegt, classCode), Erstellungs- und Servicedatum, Autor, Vertraulichkeit, Sprache und Format (C-CDA 2.1 oder 1.1 strukturierter Körper, XDS-SD oder mimeTypeSufficient, aus seinen Vorlagen); und vervollständigt aus dem, was ein Dokument nicht sagt: die source_id des Senders, die facility_type und practice_setting, die jedes Register erfordert. Die RegistryResponse des Repositorys entscheidet über die Lieferung: ein Fehler oder ein Fehler in einem PartialSuccess ist eine fehlgeschlagene Lieferung mit den Fehlercodes des Registers.

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. Fügen Sie direct_from (Ihre Direct-Adresse) und direct_to (die Empfänger) hinzu und der gleiche Zielort sendet XDR als Direct-Transport, wie es in *XDR und XDM für Direct Messaging* des Direct-Projekts beschrieben ist: Ein Direct-Adressblock (urn:direct:addressing) im SOAP-Header benennt den Absender und die Empfänger, und die intendedRecipient-Übermittlung benennt jeden Empfänger (||^^Internet^address). Richten Sie url auf den XDR-Endpunkt des Empfängers oder einen HISP aus, der XDR akzeptiert. XDR wird über TLS übertragen, normalerweise mit einem Clientzertifikat (tls), und ist kein S/MIME. Eine direct-Quelle akzeptiert auch XDR (siehe Direct unten).

    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 und PDQ in HL7-Version 3. Mit dem Patienten-Index aktiviert (-mpi), ist /pixv3 ein PIX-Manager und /pdqv3 ein PDQ-Lieferant über SOAP 1.2, für Krankenhäuser und Austauschdienste, die noch IHEs v3-Profile sprechen. Eine Quelle speist Patienten mit ITI-44 (Datensatz hinzugefügt PRPA_IN201301UV02, geändert PRPA_IN201302UV02, Duplikate aufgelöst PRPA_IN201304UV02): die erste Identifikator des Patienten ist sein Datensatz, die anderen und die in asOtherIDs sind Identifikatoren, die er trägt, und eine Zusammenführung falzt den vorherigen Identifikator des Datensatzes in den überlebenden ein, wie ein HL7-v2-A40. ITI-45 (PRPA_IN201309UV02) antwortet mit den anderen Identifikatoren der Person, die einen bestimmten Identifikator trägt, eingeschränkt durch dataSource, in Patient.id; der abgefragte Identifikator kommt nur in der wiederholten Abfrage zurück. ITI-47 (PRPA_IN201305UV02) entspricht Demografien (Name, Geschlecht, Geburtszeit, Identifikator, Adresse, Kommunikation) mit dem Matcher des Index, minimumDegreeMatch als Punktzahl aus 100, otherIDsScopingOrganization begrenzt die Domänen, und initialQuantity paginiert die Antwort: der Rest kommt mit QUQI_IN000003UV01 für zehn Minuten, oder wird durch seinen Abbruch fallen gelassen. Die Antworten folgen den Transaktionsfällen: ein unbekannter Patient oder eine unbekannte Domäne ist AE mit Fehler 204 und der Position des Parameters, ein bekannter Patient mit nichts in den abgefragten Domänen ist NF. v3 benennt eine Autorität nur durch OID, also wird ein Identifikator, dessen System eine URL ohne OID dahinter ist (einige nationale Nummern), aus v3-Antworten ausgelassen und über FHIR bereitgestellt; setzen Sie das System der Unternehmens-Identifikator auf eine OID (urn:oid:..., in den Indexeinstellungen), um die EUID und den Verwahrer anzuzeigen. Die Viewer-Rolle fragt ab und die Operator-Rolle speist; jede Transaktion wird mit einem Identifikator, nie mit einem Namen, auditiert. Eine nackte v3-Nachricht, die als application/xml gepostet wird, wird auf die gleiche Weise beantwortet, was für manuelle Tests nützlich ist.

Austausch › Dokumentenfreigabe zeigt, was das Register enthält und wo es erreicht wird, findet die Dokumente eines Patienten in diesem Register oder einem anderen (ein Register-ITI-18 oder ein Gateway-ITI-38), lädt eines herunter und veröffentlicht ein CDA-Dokument manuell mit den Metadaten, die ein Ziel dafür bereitstellen würde.

Überprüft gegen das NIST XDS Toolkit 7.13.0, die IHE-Referenzimplementierung: Perfuses ITI-41, ITI-18 und ITI-43 gegen sein Registry/Repository-Simulator (akzeptiert ohne Validierungsfehler, das abgerufene Dokument byte-identisch), und sein Initiating-Gateway-Simulator, der von Perfuses Responding Gateway über XCA abfragt und abruft, ohne Fehler in seinem Protokoll. Jede SOAP-Nachricht, die Perfuse schreibt, wird gegen die ebXML-Registry-3.0- und XDS.b-Schemata validiert, und die MHD DocumentReference und SubmissionSet gegen IHE MHD 4.2.2 mit dem HL7 FHIR-Validator. XDR von einem xds-Ziel mit einem Direct-Adressblock wurde vom Toolkits Document Recipient-Simulator akzeptiert, dessen Metadatenvalidierung den einen Defekt fand, der in docs/verification.md beschrieben ist, und von ONC SITEs XDR-Validator, der Direct XDR-Checkliste, die der (h)(2)-Zertifizierungstest anwendet. Die PIX- und PDQ-v3-Antworten werden gegen IHEs HL7-V3-Schemata (NE2008 multicacheschemas) validiert, und IHEs eigene Beispielnachrichten (die ITI-44-Feed-, Merge-, ITI-45-Abfrage-, ITI-47-Abfrage-, Fortsetzungs- und Abbruchantworten) werden wie ihre veröffentlichten Antworten geantwortet. Noch nicht gegen eine unabhängige PIX- oder PDQ-v3-Implementierung, Gazelle oder einen Connectathon überprüft.

8.9 Direkte sichere Nachrichtenübermittlung

Direct ist die Methode, mit der US-Anbieter einander Überweisungen, Zusammenfassungen und Ergebnisse per sicheren E-Mail versenden: jede Nachricht ist mit dem Zertifikat des Absenders signiert und für das Zertifikat des Empfängers verschlüsselt (S/MIME), und reist zwischen HISPs (Health-Information-Service-Providern), die die Adressen ausstellen und für sie bürgen. Perfuse ist das Rand-system neben Ihrem HISP, kein HISP: Der HISP stellt Ihre Adresse, sein Zertifikat und seinen Schlüssel aus, und Sie behalten sein Vertrauensbündel (wie DirectTrusts). Es folgt dem Direct-Applicability-Statement für Secure Health Transport 1.2, dem Implementation Guide für Delivery Notification, IHE XDM (ITI TF-1 Annex 15) für Dokumente mit Metadaten, dem Certificate-Discovery- für Direct-Project-Implementation-Guide (DNS und LDAP) und XDR und XDM für 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

Empfangen. Eine direct-Quelle ist der SMTP-Server, an den der HISP die E-Mails für Ihre Adresse liefert. Sie akzeptiert nur E-Mails für diese Adresse (alles andere wird bei RCPT abgelehnt), erfordert STARTTLS, wenn ein Zertifikat angegeben ist, und öffnet jede Nachricht, bevor sie gelesen wird: entschlüsselt sie mit Ihrem Schlüssel, überprüft die Signatur gegen Ihre Anker und prüft, ob das signierende Zertifikat für die Absenderadresse oder ihre Domäne ist. Eine Nachricht, die nicht verschlüsselt ist, von einem Absender stammt, dem Sie nicht vertrauen, oder von einem Zertifikat für jemand anderen signiert ist, wird bei DATA mit dem Grund abgelehnt, so dass der HISP sie behält und dem Absender meldet; Perfuse akzeptiert nie etwas, das es dann ablehnt. Ein XDM-Paket wird in separate Dokumente umgewandelt (gegen die Hashes in seinen Metadaten überprüft); andernfalls wird jeder Anhang in eine separate Nachricht umgewandelt oder der Text, wenn es keinen Anhang gibt. Mit smtp_host wird jede empfangene Nachricht mit einer signierten, verschlüsselten "verarbeitet"-Benachrichtigung (MDN) beantwortet, und Benachrichtigungen, die für das Gesendete ankommen, werden protokolliert.

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

Vom HISP-Postfach. Ein HISP, der E-Mails speichert, anstatt sie zuzustellen, gibt der Adresse ein IMAP-Postfach: imap liest es (TLS oder STARTTLS, jede Abfrage eine neue Sitzung), öffnet jede Nachricht wie oben, verschiebt, was genommen wurde, zu move_to (oder löscht es) und was nicht geöffnet werden konnte, zu error_folder, so dass nichts zweimal gelesen wird. listen kann dann weggelassen werden. Ein HISP, dessen Mailserver ein privates Zertifikat hat, wird mit tls.ca_file (sein Zertifikat oder das seiner Autorität) und tls.server_name vertraut; die Überprüfung kann nicht deaktiviert werden.

    imap:
      host: imap.hisp.example
      username: intake@direct.clinic.example
      password: ${DIRECT_MAILBOX_PASSWORD}
      move_to: Processed

XDR. xdr akzeptiert XDR unter /xdr auf seiner eigenen HTTPS-Adresse, wie ein HISP Direct konvertiert zu SOAP oder ein Partner punkt-zu-punkt sendet: eine ITI-41-Providing- und -Register-Anfrage, deren Dokumente jeweils eine Nachricht werden. Eine Übermittlung, deren Direct-Adressblock eine andere Adresse benennt, wird abgelehnt, und eine, die der Kanal nicht akzeptiert, wird mit einer RegistryResponse-Fehlermeldung beantwortet, die den Grund angibt. client_ca_file erfordert ein Clientzertifikat von diesen Behörden. XDR wird durch TLS geschützt, nicht durch S/MIME, sodass eine Quelle, die nur XDR akzeptiert, die Adresse benötigt, aber nicht ihr Zertifikat, Schlüssel oder Anker. Jedes Dokument wird zu einer Nachricht des Kanals dataType: CDA-Dokumente benötigen raw (weitergeleitet, wie sie sind) oder hl7v3, da der Standard, hl7, HL7 v2 erwartet und sie ablehnt.

    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

Austausch › Direct listet die Direct-Adressen auf, die Ihre Kanäle senden und empfangen, mit ihren Zertifikaten, Ablaufdatum und Anker; verwaltet das Adressbuch der Korrespondenten (Name, Organisation, Notizen und Zertifikat, aus ihrem HISP kopiert oder in DNS oder LDAP gefunden und abgelehnt, wenn es nicht für diese Adresse oder Domäne ist); und sucht die Zertifikate einer Adresse in DNS oder LDAP ohne sie zu speichern. Das Buch ist das Verzeichnis direct-certs neben der Datenbank, eine PEM-Datei pro Adresse oder Domäne, die ein Ziel liest, es sei denn, es benennt sein eigenes recipient_certs_dir.

Überprüft gegen OpenSSL 4.0's cms und smime in beide Richtungen: Was Perfuse signiert und verschlüsselt, wird von OpenSSL verifiziert und entschlüsselt (PKCS#1 v1.5 und OAEP-Schlüsseltransport), und Perfuse öffnet, was OpenSSL signiert und verschlüsselt (AES-128 und AES-256). Eine Nachricht, die mit openssl smime erstellt und über SMTP zugestellt wird, wird von einem Kanal empfangen, geöffnet und gespeichert, und eine, die Perfuse sendet, erhält eine MDN, die der Absender öffnet. Zertifikate werden in OpenLDAP 2.4 gefunden (adressegebunden und domänengebunden, geschrieben von OpenLDAP's eigenem ldapadd); eine Direct-Nachricht wird aus einem GreenMail-IMAP-Postfach gelesen und geöffnet, und eine, die nicht Direct ist, wird in den Fehlerordner verschoben; XDR von einem xds-Ziel wird von einem direct-Quell akzeptiert und abgelehnt, wenn sie an jemand anderen adressiert ist, und von dem NIST XDS Toolkit's Document Recipient und ONC SITE's XDR-Validator akzeptiert; SITE's Direct XDR Edge Test Tool sendete sowohl seine minimalen als auch vollständigen Metadaten-Nachrichten an einen direct-Quell, der sie akzeptierte. Gegen ONC's Direct Certificate Discovery Tool wählt ein Direct-Ziel das richtige Zertifikat oder keines in allen 18 seiner Entdeckungsarten (D1 bis D18: abgelaufene, widerrufene und AIA-ausgestellte Zertifikate, SRV-Priorität und Gewichtung, ein unerreichbares Verzeichnis). Ein Direct-Quell liest eine Nachricht aus SITE's eigenem HISP (Apache James) über IMAP mit STARTTLS. Noch nicht getestet: SMTP-Austausch mit SITE's HISP (AWS hält ausgehende E-Mails auf Port 25 für neue Konten) oder mit einem akkreditierten HISP.

8.10 SQL auf FHIR-Ansichten

Eine ViewDefinition (HL7 SQL auf FHIR v2) wandelt jedes FHIR-Ressourcen eines Typs in Zeilen benannter Spalten um, jede Spalte ein FHIRPath-Ausdruck, so dass FHIR-Daten als Tabellen von DuckDB, Athena, Spark, einem Data-Warehouse oder einer Tabelle gelesen werden können. Perfuse führt sie mit seinem eigenen FHIRPath-Motor aus: column, verschachteltes select, forEach, forEachOrNull, repeat und unionAll, where, constant (jeder value[x]-Typ), collection-Spalten, %rowIndex und die getResourceKey()- und getReferenceKey(type)-Verknüpfungsschlüssel.

{
  "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" }
  ]}]
}

Überwachung › SQL auf FHIR führt eine Ansicht über den FHIR-Speicher dieses Servers (einen Patienten oder alle) oder über pastete Ressourcen (NDJSON aus einer Massenexportierung, ein Bundle, ein JSON-Array) aus, zeigt die Zeilen an und lädt sie als CSV, NDJSON oder Parquet herunter. Es startet mit fünf Beispielansichten (Patientendemografie, Beobachtungen mit einem Wert, Blutdruck, Zustände, Begegnungen) und speichert Ansichten im views-Verzeichnis neben der Datenbank, jeweils eine JSON-Datei.

Der FHIR-Endpunkt antwortet auf die Spezifikation $sql-run auf Systemebene, per GET oder POST, für eine ViewDefinition, die inline gegeben ist (subjectResource), per subjectReference (ViewDefinition/<name>, eine gespeicherte Ansicht) oder per subjectCanonical (die url einer gespeicherten Ansicht), mit _format (csv, ndjson (Standard), json oder parquet), header, patient, _since, _limit und resource, um über Ressourcen zu laufen, die mit der Anfrage gesendet werden, anstatt über den Speicher. Es handelt sich um einen Lesevorgang: ein SMART-Token benötigt Leseberechtigung für den Ressourcentyp der Ansicht, ein Token, das an einen Patienten gebunden ist, erhält nur die Zeilen dieses Patienten, und granulare Berechtigungen verengen die gelesenen Ressourcen, wie sie eine Suche tun. Mehr als eine Million Zeilen benötigt _limit, patient oder _since.

perfuse sof -view v.json [-format csv|ndjson|json|parquet] [-o out] files... führt eine Ansicht über FHIR-Dateien ohne Server aus: die NDJSON-Dateien eines Massenexports, Bundles oder 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-Dateien haben eine Zeilengruppe und unkomprimierte PLAIN-Seiten; Boolesche Werte sind BOOLEAN, ganzzahlige Typen INT64, Dezimalzahlen DOUBLE und alles andere UTF-8-Zeichenfolgen (eine Sammlungsspalte als ihr JSON).

Verifiziert mit dem offiziellen SQL-on-FHIR-Testsuite (die 144 Tests des sql-on-fhir.js-Repositorys tests/, die bei jedem Build ausgeführt werden: alle bestehen), und die Parquet-Ausgabe wird von DuckDB 1.5.6 mit den richtigen Typen und Werten gelesen. Nicht unterstützt: SQLQuery und SQLView-Bibliotheken (SQL über die Tabellen der Ansichten), $sql-export, _format=fhir und die source- und group-Parameter; jeder wird mit dem Grund abgelehnt.

8.11 Digitale Qualitätsmaße

Ein digitales Qualitätsmaß zählt die Patienten in jeder Population einer FHIR-Measure über einen Messzeitraum (anfängliche Population, Nenner, Nenner-Ausschlüsse und Ausnahmen, Zähler, Zähler-Ausschlüsse) und bewertet das Ergebnis. Die Antwort ist ein FHIR-MeasureReport, der wie vom Da Vinci Data Exchange for Quality Measures (DEQM)-Leitfaden gefordert, geformt ist. Hierhin sind die CMS-eCQM-Programme und die digitalen HEDIS von NCQA unterwegs.

In Perfuse the population criteria are FHIRPath ("language": "text/fhirpath"), run by the same engine as SQL on FHIR. Each criterion is evaluated once per patient. Its focus is a Bundle of that patient's record (the Patient compartment), and it has these variables: %subject (the Patient), %periodStart and %periodEnd (the period, as dateTimes) and %"Measurement Period". A criterion gives true or false; a single value that exists counts as true.

{
  "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()"
  }
}

Die Populationen schachteln sich wie in der Measure-Spezifikation angegeben. Ein Patient ist nur dann im Nenner, wenn er in der anfänglichen Population ist. Ein Nenner-Ausschluss entfernt den Patienten, bevor der Zähler beurteilt wird. Eine Nenner-Ausnahme zählt nur für einen Patienten, der nicht im Zähler ist. Die Bewertung eines Verhältnisses ist (Zähler − Zähler-Ausschlüsse) / (Nenner − Ausschlüsse − Ausnahmen); die eines Verhältnisses ist Zähler / Nenner; ein Kollektiv hat Zählungen und keine Bewertung. Einkriterien-Stratifikatoren teilen jede Population nach ihrem Wert (Geschlecht, sagen wir).

Perfuse hat keinen CQL-Motor. Die veröffentlichten CMS-eCQMs und HEDIS-Digitalmaße sind in CQL geschrieben, daher können sie nicht in ihrer ursprünglichen Form ausgeführt werden. Ein Maß, dessen Kriterien in CQL sind, wird mit diesem Grund abgelehnt. Schreiben Sie die Logik als FHIRPath stattdessen. Kontinuierliche Variablenbewertung, mehrkomponentige Stratifikatoren und Gruppen- oder Praktiker-Subjekte werden auf die gleiche Weise abgelehnt.

Überwachung › Qualitätsmaße bewertet ein Maß über den FHIR-Speicher dieses Servers oder über pastete Ressourcen für einen Zeitraum. Es bietet drei Berichte: eine Zusammenfassung, eine Zusammenfassung mit den Patienten in jeder Population oder einen Patienten. Der Bildschirm zeigt die Populationen, die Bewertung und die Schichten an und lädt den MeasureReport herunter. Es startet mit drei Beispielen: Blutdruck unter Kontrolle, Diabetes mit einem HbA1c-Test und Patienten, die im Zeitraum gesehen wurden. Sie sind illustrativ, für dieses Handbuch geschrieben und keine CMS-eCQMs oder HEDIS-Maße. Speichern im FHIR-Speicher überprüft das Maß und speichert es als Measure-Ressource.

Der FHIR-Endpunkt beantwortet Measure/[id]/$evaluate-measure und Measure/$evaluate-measure?measure=<url>, sowohl durch GET als auch durch POST einer Parameters-Ressource. Parameter:

Der Bericht wird zurückgegeben, nicht gespeichert. Der Vorgang ist ein Lesevorgang, daher benötigt ein SMART-Token Lesezugriff auf Measure und Patient. Ein Token, das an einen Patienten gebunden ist, erhält einen individuellen Bericht über diesen Patienten und keinen anderen.

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... bewertet ein Maß über FHIR-Dateien (eine Bulk-Export-NDJSON, Bundles, Arrays) ohne einen Server. -measure example:example-bp-control führt ein mitgeliefertes Beispiel aus, und -examples listet sie auf.

Verifiziert. Der HL7 FHIR-Validator überprüft die mitgelieferten Maße gegen FHIR R4, ohne Fehler. Er überprüft eine Zusammenfassung, einen Einzel- und einen Subjektslisten-MeasureReport gegen die DEQM 5.0.0-Zusammenfassungs-, Einzel- und Subjektslistenprofile, ebenfalls ohne Fehler. Nicht verifiziert: Äquivalenz mit veröffentlichten eCQMs, da keine ohne CQL hier ausgeführt werden kann.

8.12 Der Patientenindex (MPI)

Ein Master-Patienten-Index verknüpft die Aufzeichnungen, die jedes System für eine Person (die Krankenhaus-MRN, die Klinik, das Labor) führt, in einen einzigen Unternehmens-Identifikator, den EUID. Es ist ausgeschaltet, bis jemand beschließt, einen zu führen, da es eine Tabelle mit Patientennamen, Geburtsdaten und Identifikatoren ist: aktivieren Sie Einstellungen → Daten → Patientenindex (oder serve -mpi) und starten Sie neu. Es befindet sich in mpi.db neben der Hauptdatenbank.

Daten einfügen. Fügen Sie einem Kanal, der Registrierungen transportiert, ein Ziel vom Typ mpi (Patientenindex im Builder) hinzu. Es liest die PID jedes HL7-v2-Nachrichten oder eines FHIR-Patienten auf einem Rohkanal. Die eigene Identifikator des Datensatzes ist die PID-3-Wiederholung vom Typ MR (id_type ändert dies); die anderen und PID-19 werden zu seinen anderen Identifikatoren. Eine zuweisende Behörde mit einer universellen Identifikator (PID-3.4.2 mit Typ ISO) wird zu urn:oid:...; eine mit nur einem Namensraum wird durch authorities abgebildet oder wird zu urn:perfuse:aa:<namespace>. Ein A40, A34, A18 oder A39 kombiniert die Person, die den Identifikator von MRG-1 hält, mit der Person, die den Identifikator von PID-3 hält (no_merge ignoriert sie).

destinations:
  - name: index
    type: mpi
    mpi:
      authorities: { HOSP: "urn:oid:1.2.840.114350.1.13.1" }

Abgleich. Ein neuer Datensatz wird in dieser Reihenfolge verknüpft:

  1. Vertrauenswürdige Identifikatoren. Ein Datensatz, der eine Identifikator aus einem System teilt, das als vertrauenswürdig gelistet ist (eine nationale Identifikator, eine Unternehmensnummer), ist dieselbe Person, ohne Bewertung. Listen Sie nie ein System auf, das eine Familie teilt, wie z.B. eine Abonnentennummer eines Zahlungspflichtigen.
  2. Bewertung. Andernfalls werden die Personen, deren Datensätze möglicherweise übereinstimmen, durch Blockierung (derselbe klingende Familienname und Geburtsjahr, derselbe Geburtsdatum oder dieselbe Telefonnummer) und mit Fellegi-Sunter-Gewichten über Familien- und Vornamen (Jaro-Winkler und Soundex, Akzente und Interpunktion ignoriert, vertauschte Namen beachtet), Geburtsdatum (ein vertauschter Tag und Monat ist eine teilweise Übereinstimmung), Geschlecht, Postleitzahl, Telefon und Adresse gefunden. Nur Felder, die beide Datensätze haben, werden berücksichtigt. Die Bewertung ist der Anteil der gefundenen Beweise an den möglichen Beweisen. Die Blockierung verwendet fünf Schlüssel, sodass ein Fehler nicht eine Person versteckt: Familienname-Klang und Geburtsjahr, Geburtsdatum, Telefon, Klang beider Namen (in beliebiger Reihenfolge) und Postleitzahl mit dem Klang des Vornamens.
  3. Entscheidung. Standardmäßig wird nichts allein aufgrund einer Bewertung verknüpft. Ein Datensatz, der eine Bewertung von mindestens der Überprüfungsschwelle (60%) erreicht, wird zu einer neuen Person und die mögliche Übereinstimmung wartet in der Überprüfungswarteschlange; diejenigen, die die automatische Schwelle (90%) mit übereinstimmendem Familienname und Geburtsdatum erreichen, werden als *sicher* markiert. Das Verknüpfen zweier Personen in eine (eine Überlagerung) legt die Ergebnisse einer Patientin in die Akte einer anderen, sodass die automatische Verknüpfung ein Schalter ist, den ein Administrator einschaltet (Sichere Übereinstimmungen ohne Nachfrage verknüpfen), sobald die Warteschlange gezeigt hat, dass die sicheren Übereinstimmungen richtig sind. Mit eingeschaltetem Schalter wird eine sichere Übereinstimmung verknüpft, wenn keine zweite Person eine so hohe Bewertung erreicht. Unter der Überprüfungsschwelle wird der Datensatz zu einer neuen Person.

Nationale Nummern. Die NHS-Nummer (und Schottlands CHI und Nordirlands Health and Care-Nummer), Irlands PPSN und IHI, Deutschlands KVNR, Österreichs SVNR, der Schweiz AHV-Nummer, der Niederlande BSN, Belgiens nationale Registrierungsnummer, Luxemburgs Matricule, Frankreichs INS (NIR und NIA), Italiens Steueridentifikationsnummer, Spaniens DNI/NIE und CIP-SNS, Portugals SNS-Nummer, die nordischen Personenkennzahlen (Schweden, Dänemark, Norwegen mit seiner D-Nummer, Finnland, Island), die baltischen Codes, Polens PESEL, die tschechische und slowakische Geburtsnummer und die ungarische, rumänische, bulgarische, kroatische, slowenische und griechische Nummern sind dem Index bekannt. Jede wird auf eine Weise gespeichert: unter ihrem Schemasystem, Leerzeichen und Punkte entfernt, sodass die NHS-Nummer, die von einem System als urn:oid:2.16.840.1.113883.2.1.4.1|999 000 0018 und von einem anderen System als https://fhir.nhs.uk/Id/nhs-number|9990000018 gesendet wird, eine Identifikator ist. Eine HL7-v2-PID-3-Wiederholung, deren Identifikatortyp NN ist und einen dreibuchstabigen Ländercode (NNDEU, NNNLD) enthält, wird als die Hauptnummer dieses Landes gelesen, und der Typ NH von der NHS-Behörde als die NHS-Nummer. Jede Nummer wird auf ihre Prüfziffer überprüft: eine fehlerhafte Nummer wird in ihrem Datensatz aufbewahrt, in der Antwort (maskiert) gemeldet und nie zur Verknüpfung oder zum Auffinden einer Person verwendet, da ein falsch eingegebener Ziffer normalerweise die Nummer einer anderen Person ergibt. Dänemarks CPR wird nur auf sein Datum überprüft, da Nummern, die seit 2007 ausgestellt wurden, den alten Modulus-11-Test nicht bestehen müssen.

Die Einstellungen listen jedes Schema mit seinem Format, seinem Prüfwert und dem System, unter dem es gespeichert wird, auf. Systeme, die aus dem eigenen FHIR-Leitfaden des Landes (UK Core, fhir.de, Nictiz, CH Core, ANS, HL7 Italia, MedCom, die schwedischen, norwegischen und finnischen OID-Register) übernommen werden, sind als solche gekennzeichnet; die anderen sind Standardwerte, die pro Schema geändert werden können (der alte Wert wird immer noch erkannt). Ein Schema zu vertrauen, ist ein Tick. Nationale Nummern werden standardmäßig in vollem Umfang an Editoren und höhere Ebenen angezeigt und maskiert (die letzten paar Zeichen) für alle anderen; Wer sieht Nummern in vollem Umfang ändert dies, bis hinunter zu Betrachtern oder bis hinauf zu Administratoren. Wo das Gesetz eines Landes die Verwendung einer Nummer einschränkt (Frankreichs Référentiel INS, Irlands PPSN, Belgiens nationale Registrierungsnummer, Deutschlands §290 SGB V), sagen die Einstellungen dies. GET /api/mpi/schemes listet die Schemata auf und POST /api/mpi/check überprüft eine Nummer ohne sie zu speichern. FHIR $match und PIXm antworten autorisierten Clients mit Nummern in vollem Umfang.

Ein Datum, das Tag- oder Monatsanfangsweise (08/15/1972) geschrieben wird, bleibt so geschrieben und entspricht nicht einem jahresanfangsweise geschriebenen Datum: Die US- und europäischen Reihenfolgen stimmen nicht überein, und eine Vermutung würde die falschen Personen verbinden.

Der Patienten-Index-Bildschirm (Build) zeigt die Zählungen an, findet Personen nach Namen, Nummer, EUID oder Geburtsdatum und öffnet jede Person: ihre Aufzeichnungen, jeden Identifier und die Historie dessen, was mit ihnen passiert ist und wer es getan hat. Editoren entscheiden über Überprüfungen (Die gleiche Person verlinkt sie; Unterschiedliche Personen hält sie für immer getrennt), verschieben eine Aufzeichnung zu einer anderen Person, nehmen eine Aufzeichnung heraus (Nicht diese Person), und fusionieren zwei Personen. Administratoren legen die Schwellenwerte, die vertrauenswürdigen Identifikationssysteme, die nationalen Nummern und das EUID-System fest. Jede Suche und jeder Personenzugriff werden im Audit-Log aufgezeichnet.

Antworten auf andere. POST /fhir/Patient/$match (FHIRs Operation, wie sie von IHE PDQm ITI-119 verwendet wird) nimmt einen Patienten und gibt die Personen zurück, die es sein könnten, zuerst diejenigen, die am besten passen, jeden Patienten, dessen ID die EUID ist, mit jedem Identifier, search.score und der match-grade-Erweiterung (certain, probable, possible); onlyCertainMatches und count werden berücksichtigt. PIXm (/mhd/Patient/$ihe-pix, ITI-83) antwortet aus dem Index: jeden Identifier jedes mit der Person verknüpften Datensatzes und die EUID. Das gleiche tun PIX und PDQ in HL7 v3 (/pixv3, /pdqv3; siehe IHE-Dokumentfreigabe), die auch davon gespeist werden.

Die API ist /api/mpi (Zusammenfassung und Suche), /api/mpi/persons/{euid}, /api/mpi/find, /api/mpi/reviews, /api/mpi/records (Register, Verknüpfung, Entfernung der Verknüpfung), /api/mpi/merge und /api/mpi/settings.

Gewichte. Die Standard-Fellegi-Sunter-Gewichte stammen aus der Literatur zur Aufzeichnung von Krankenhausregistrierungen. Schätzen aus unseren Aufzeichnungen (in den Einstellungen, Administratoren; POST /api/mpi/estimate) passt sie an den eigenen Index des Standorts mit Erwartung-Maximierung an, ohne dass überprüfte Paare benötigt werden: m (Übereinstimmung unter wahren Übereinstimmungen) aus den Paaren, die das Blockieren zusammenbringt, u (Übereinstimmung durch Zufall) aus 20.000 zufällig ausgewählten Paaren, da blockierte Paare per Konstruktion auf Namen und Daten übereinstimmen. Die Schätzung wird neben den verwendeten Gewichten angezeigt und ändert nichts, bis sie verwendet und gespeichert wird. Ein Feld, das in zu wenigen Paaren verglichen wird, behält sein Standardgewicht bei. Die Anpassung geht davon aus, dass die Felder voneinander unabhängig sind, was sie nicht ganz sind, daher sollte eine große Änderung mit Misstrauen behandelt werden.

Gemessen. Im FEBRL-Datensatz 3 (5.000 synthetische Aufzeichnungen von 2.000 Personen, die Duplikate mit Tippfehlern, vertauschten Feldern, fehlenden Werten und Spitznamen enthalten; PERFUSE_TEST_FEBRL), die in der Dateireihenfolge registriert wurden, wobei ein Überprüfer jedes gepufferte Paar korrekt beantwortete:

Auf eigene Faust verknüpftVor einem Überprüfer mit der richtigen Person platziertVerpasstFalsche Verknüpfungen
Automatische Verknüpfung aus (Standard)02.649 von 3.0003510
Ein, Standardgewichte1.6371.0123510
Ein, Gewichte aus den Aufzeichnungen geschätzt1.6221.0703080

Keine Aufzeichnung wurde jemals mit der falschen Person verknüpft, und keine der 2.000 neuen Personen wurde unnötigerweise in die Warteschlange gestellt. Die verpassten Aufzeichnungen unterscheiden sich in fast jedem Feld (ein Geburtsdatum und eine Adresse, die beide fehlerhaft sind, zum Beispiel) und haben einen Wert unter dem Überprüfungsschwellenwert. FEBRL ist synthetisch und hat wenige Namensvetter; ein echter Index hat mehr, daher wird seine Überprüfungswarteschlange länger sein, und diese Zahlen sind ein Mindestwert für die Sorgfalt, nicht ein Versprechen.

8.13 Abgegrenzt

CSV und seine Verwandten. Die Optionen sind im Quellcode im Builder und die Formatreferenz listet die Dateischlüssel auf.

Pfade adressieren Spalten. Eine benannte Spalte ist verfügbar, wenn eine Headerzeile deklariert wird oder die Namen angegeben werden; ansonsten werden Spalten positionell adressiert.

8.13.1 Benennen der Spalten

Es gibt zwei Möglichkeiten, und sie sind exklusiv. Entweder benennt die erste Zeile der Datei sie — die erste Zeile benennt die Spalten — oder Sie listen sie selbst auf, in der Reihenfolge. Die Deklaration eines Headers bedeutet, dass die Zeile nicht als Daten behandelt wird.

Wenn keines von beiden festgelegt ist, können Spalten nur positionell adressiert werden, also hat ein Filter, der gegen einen Namen geschrieben wird, nichts, was er abgleichen kann. Das Aktivieren des Headers entfernt die Liste der Namen, anstatt beides beizubehalten: Mit einem Header stammen die Namen aus der Datei, also würde eine zurückgelassene Liste ignoriert werden, und ein Kanal, der so liest, als ob er die Namen gewählt hat, wenn die Datei sie gewählt hat, ist schwieriger zu debuggen als einer, der ablehnt.

8.13.2 Was ein Filter oder ein Skript sieht

Ein abgegrenztes Dokument wird zu vielen Nachrichten, also muss dies angegeben werden, bevor Sie entweder schreiben.

Mit aktiviertem Splitting wird alles pro Zeile ausgeführt. Deklarative Schritte, der Filter und das Transformer-Skript sehen jeweils eine Zeile, und ein Pfad bedeutet *diese* Zeile's Spalte. Ein Filter, der eine Zeile ablehnt, lehnt nur diese Zeile ab und keine andere, und die empfangene Anzahl ist Zeilen und nicht Dokumente.

Mit deaktiviertem Splitting ist die Nachricht das gesamte Dokument und ein Schreibvorgang, der Zeilen überschreitet, wird verweigert, anstatt auf die erste Zeile angewendet zu werden. Diese Verweigerung ist absichtlich: Ein stilles Schreiben in die erste Zeile ist das Verhalten, das eine Datei erzeugt, die wie transformiert aussieht, aber nicht ist.

8.13.3 Die drei, die bestimmen, was als Fehler gilt

Zeilen mit der falschen Anzahl von Spalten akzeptieren ist standardmäßig deaktiviert. Eine Zeile mit zu vielen oder zu wenigen Spalten ist dann ein Fehler, was ein Datei-Shape-Wechsel ohne Warnung auffängt. Wenn es aktiviert ist, wird die Zeile akzeptiert und fehlende Spalten bleiben leer.

Leerzeichen um jeden Wert entfernen behebt den häufigen Fall eines Wertes, der auf eine Spaltenbreite gepaddet ist. Lassen Sie es deaktiviert, wenn nachfolgende Leerzeichen bedeutungsvoll sind, was gelegentlich bei einem Identifikator der Fall ist.

Leere Zeilen als Zeilen behalten ist standardmäßig deaktiviert und sollte es in der Regel auch sein. Wenn es aktiviert ist, wird eine leere Zeile zu einer Zeile mit leeren Spalten, was nur dann wichtig ist, wenn eine Anzahl genau der Datei entsprechen muss.

8.14 Roh

Keine Analyse überhaupt. Die Nachricht ist Bytes.

Verwenden Sie dies, wenn der Inhalt nicht etwas ist, das Perfuse versteht und nicht benötigt: Ein PDF, das zwischen Systemen verschoben wird, ein proprietäres Format, ein bereits gebildetes Dokument, das unverändert weitergeleitet wird.

Der Preis dafür ist, dass nichts, was von der Struktur abhängt, funktioniert - keine Feldtransformation, kein Filter auf einem Feld, kein Feldvergleich im Paritätsprüfer. Ein roher Kanal ist eine Rohrleitung, und er ist ehrlich darüber, eine zu sein.

8.15 Wählen

Wenn die Nachricht HL7 v2 ist, verwenden Sie hl7, auch wenn Sie sie nur unverändert weiterleiten möchten. Die Analyse gibt Ihnen die Spur, die Feldstatistiken, die Möglichkeit, später zu filtern und die Möglichkeit, zu vergleichen. raw auf analysierbarem Inhalt bringt nichts und verliert all das.

Verwenden Sie raw, wenn die Analyse fehlschlagen oder eine Lüge über den Inhalt wäre.

CMS's *Kill the Clipboard* bittet die Anbieter, die Aufzeichnungen eines Patienten von einem QR-Code bei der Anmeldung zu akzeptieren und die Besuchsaufzeichnung auf die gleiche Weise zurückzugeben. Der QR-Code enthält einen SMART Health Link (shlink:/...): eine Adresse, einen 256-Bit-Schlüssel und optional eine Bezeichnung, ein Ablaufdatum und eine Passcode-Flag. Exchange → Health links liest einen aus.

Empfangen. Fügen Sie den Link ein oder scannen Sie ihn mit der Kamera, wo der Browser dies kann (Chrome und Edge). Perfuse ruft das Manifest ab, entschlüsselt jede Datei mit dem Schlüssel aus dem Link, fasst jedes FHIR-Bündel zusammen - wer der Patient ist, wie viele Ressourcen jeder Art - und überprüft jede SMART Health Card innerhalb gegen den veröffentlichten Schlüssel des Ausstellers. *Liefern an den Kanal* übergibt den FHIR-Inhalt an einen Kanal als Nachricht, auf die Weise erreicht er die EHR. Der Abruf wird auf die Egress-Richtlinie bei der Verbindung beschränkt, plain HTTP wird abgelehnt und die Antwort eines Servers, der kein Manifest-Server ist, wird nie angezeigt, da die Adresse von einem fremden QR-Code stammt.

Teilen. *Teilen* verschlüsselt ein FHIR-Bündel, hostet es und zeigt den Link und seinen QR-Code einmal an. Der Server speichert den verschlüsselten Text und nicht den Schlüssel - er kann nicht öffnen, was er hostet, und kann den Link nicht erneut anzeigen. Ein Passcode wird gehasht; zehn falsche Passcodes deaktivieren den Link. Links laufen nach 30 Tagen ab, können widerrufen werden und listen aus, wie oft und von wem sie abgerufen wurden. Starten Sie den Server mit -public-url, die auf die https-Adresse gesetzt ist, die die Telefone der Patienten erreichen; die Manifest-URL, die sie erstellt, muss den Spezifikationen von 128 Zeichen entsprechen.

Überprüfen einer Karte. *Überprüfen einer Karte* nimmt einen numerischen shc:/-QR-Code (ein Chunk oder mehrere), eine .smart-health-card-Datei oder ein JWS und sagt, ob die Signatur dem Schlüssel des Ausstellers entspricht.

8.17 UN/EDIFACT

dataType: edifact liest UN/EDIFACT-Interchanges (ISO 9735): ORDERS, INVOIC, DESADV, IFTSTA und den Rest, einschließlich der europäischen Gesundheitsansprüche und LaborNachrichten. Die Dienstzeichen-Empfehlung (UNA) wird beachtet, mit dem Freigabecharakter und, für die Syntaxversion 4, dem Wiederholungstrenner; funktionale Gruppen (UNG/UNE) sind optional. Der Interchange wird genau so geliefert, wie der Absender ihn geschrieben hat.

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"'

Die Hülle. UNT's Segmentzähler und Referenz, UNE's Nachrichtenzähler und Referenz und UNZ's Zähler und Referenz werden mit dem verglichen, was der Interchange enthält. Mit require, dem Standard, verweigert eine Übereinstimmung den Interchange (es ist die Art, wie ein abgebrochener Transfer angezeigt wird); warn akzeptiert ihn und protokolliert eine Warnung; ignore überprüft nicht.

Pfade, für den Kanal und die Zieldatenfilter, zählen Elemente und Komponenten ab 1 in der Reihenfolge, in der das Segment geschrieben wird, wie Implementierungsleitfäden sie nummerieren: BGM-2 (die Dokumentennummer), BGM-1.1, NAD(2)-2.1 (die zweite NAD-Partei), LIN-3(2).1 (eine Wiederholung), UNB-2.1 (der Absender), UNH-2.1 (die Nachrichtentyp). Ein Pfad ohne Vorkommen adressiert jedes.

Aufteilen liefert einen Austausch pro Nachricht, jeweils mit dem ursprünglichen UNB (und Gruppenkopf) und Trailern, die eins zählen, sodass eine Bestellung gefiltert, gesucht und erneut versucht werden kann. Ziel-Filter sehen jedes Stück. Ein Datei-Ziel benennt Dateien nach Nachrichtentyp (ORDERS_INVOIC-20261017.edi) und ${control_id} ist die Austauschreferenz.

CONTRL. Mit acknowledge: contrl wird ein Absender, der über HTTP postet, mit einem CONTRL-Syntax- und Dienstbericht beantwortet: UCI-Aktion 7, wenn der Interchange gelesen und geliefert wurde, 4, wenn er verweigert oder nicht geliefert werden konnte (HTTP 400 oder 502 dann). Es kann nicht mit split kombiniert werden, da ein CONTRL einen gesamten Interchange beantwortet. Über AS2 ist der Empfang des Partners die Bestätigung.

Nicht angeboten: die Nachrichtenverzeichnisse (die Segmente, die ORDERS D.96A zulässt), sodass die Struktur überprüft wird, nicht der Inhalt; Transformationen, die ein Dokument eines Partners neu schreiben würden; und Filter- oder Transformer-Skripte (ein Preprocessor wird ausgeführt, bevor die Analyse durchgeführt wird). Überprüft gegen pydifact 0.1.8, einen unabhängigen Parser, in beide Richtungen.

9 Bestätigungen

Eine Bestätigung teilt dem Absender mit, was passiert ist. Für HL7 v2 über MLLP ist es eine ACK-Nachricht; der Absender sendet die nächste Nachricht nicht, bevor sie eintrifft, und sendet sie normalerweise erneut, wenn sie nicht eintrifft.

Bestätigungen falsch zu machen, ist der häufigste Weg, wie eine Integration still Daten verliert, da ein Absender, der bestätigt wird, keinen Grund zur Beschwerde hat.

9.1 Zeitplan

In Nachrichtenfluss behandelt und die Zusammenfassung ist: ack.when ist standardmäßig on_delivery, was bedeutet, dass die Bestätigung nur gesendet wird, nachdem jedes aktivierte Ziel die Nachricht akzeptiert hat. on_receipt sendet sie, sobald die Nachricht analysiert und in die Warteschlange gestellt wurde.

9.2 Was Perfuse sendet

Ein AA, wenn die Nachricht akzeptiert wurde, ein AE, wenn sie aus einem Grund abgelehnt wurde, auf den der Absender reagieren kann, und ein AR, wenn sie aus einem Grund abgelehnt wurde, auf den der Absender nicht reagieren kann.

Die Unterscheidung zwischen AE und AR besteht darin, wer etwas unternehmen muss. AE bedeutet, dass die Nachricht ein Problem hatte - ein Feld, das nicht als Datum analysiert werden konnte, ein fehlendes erforderliches Segment - und der Absender es korrigieren und erneut senden kann. AR bedeutet, dass Perfuse sie unabhängig vom Inhalt nicht akzeptieren konnte, was normalerweise bedeutet, dass ein Konfigurations- oder Verfügbarkeitsproblem auf dieser Seite vorliegt. Ein Absender, der nach einem AR erneut sendet, erhält die gleiche Antwort.

9.3 Identifizierung dieses Motors

ack.application und ack.facility füllen MSH-3 und MSH-4 der Bestätigung.

Wenn beide leer sind, spiegelt die Bestätigung den ursprünglichen Empfänger wider - sie verwendet das, was die eingehende Nachricht in MSH-5 und MSH-6 hatte. Das ist, was die meisten Absender erwarten, und es ist der Standard aus diesem Grund.

Setzen Sie sie explizit, wenn der Absender sie überprüft, oder wenn mehrere Perfuse-Instanzen den gleichen Feed bearbeiten und Sie wissen müssen, welche geantwortet hat.

9.4 Das Trigger-Ereignis

ack.include_trigger_event sendet ACK^A01 anstelle einer bloßen ACK.

Einige Empfänger erfordern es, und andere lehnen es ab, was der Grund ist, warum es eine explizite Option ohne cleveren Standard ist. Wenn ein Absender Ihre Bestätigungen ablehnt und der Inhalt richtig aussieht, ist dies das Erste, was Sie versuchen sollten.

9.5 Negative Bestätigungen sind keine Fehler, die zu verbergen sind

Eine NACK, die als Erfolg behandelt wird, ist eine der schädlichsten Fehlkonfigurationen, die es gibt, und sie ist häufig genug, um sie zu benennen. Sie tritt auf, wenn ein Ziel eine negative Bestätigung sendet und die sendende Seite die *Übertragung* als erfolgreich aufzeichnet, weil die Bytes ausgegeben und etwas zurückgekommen sind.

Perfuse liest die Bestätigung, die es von einem MLLP-Ziel erhält, und zeichnet das Ergebnis entsprechend auf. Ein AE oder AR von einem nachgelagerten System ist ein Zustellfehler, wird gemäß der Richtlinie des Ziels erneut gesendet und zählt zu der Fehlerquote, die Warnungen auslöst.

Wenn Sie von einem anderen Motor migrieren, lohnt es sich, dies explizit an Ihrem eigenen Datenverkehr zu überprüfen, anstatt es anzunehmen. Der Paritätsprüfer zeigt es an: ein Ziel, das der alte Motor als zugestellt aufgezeichnet hat und Perfuse als fehlgeschlagen aufzeichnet, bedeutet normalerweise, dass der alte Motor eine NACK ignoriert hat.

9.6 Zeitüberschreitungen

Das Warten auf eine Bestätigung ist begrenzt. Wenn sie nicht rechtzeitig eintrifft, ist die Zustellung ein Fehler und wird für eine erneute Sendung in die Warteschlange gestellt.

Eine Zeitüberschreitung ist nicht dasselbe wie eine Ablehnung und wird anders aufgezeichnet. Eine Ablehnung bedeutet, dass die andere Seite die Nachricht berücksichtigt und abgelehnt hat; eine Zeitüberschreitung bedeutet, dass Sie nicht wissen, ob sie verarbeitet wurde. Diese Unterscheidung entscheidet, ob eine erneute Sendung sicher ist: eine erneute Sendung nach einer Ablehnung ist sinnlos, und eine erneute Sendung nach einer Zeitüberschreitung birgt das Risiko einer Duplizierung. Perfuse sendet erneut nach einer Zeitüberschreitung, da eine fehlende klinische Nachricht normalerweise schlimmer ist als eine Duplizierung und das empfangende System normalerweise in der Lage ist, eine wiederholte Nachrichtensteuer-ID zu erkennen.

Ob dieser Tausch für einen bestimmten Feed richtig ist, ist eine Entscheidung, und es lohnt sich, sie absichtlich für alles zu treffen, bei dem eine Duplizierung eine klinische Konsequenz hat - eine Bestellung, eine Medikamentenverabreichung - anstatt den Standard stillschweigend zu akzeptieren.

9.7 Quellen, die keine Bestätigung senden

Nicht jeder Transport verfügt über das Konzept. Eine Dateiquelle hat nowhere, um eine Bestätigung zu senden; eine Broker-Quelle bestätigt dem Broker und nicht dem ursprünglichen Absender; eine HTTP-Quelle antwortet mit einem Statuscode.

Wenn die Quelle die angeforderte Bestätigungsart nicht liefern kann, wird der Kanal bei der Initialisierung abgelehnt, anstatt zu starten und stillschweigend keine Bestätigung zu senden. Ein Kanal, der glaubt, er sendet eine Bestätigung, aber tatsächlich nicht, ist schlimmer als einer, der nicht startet.

9.8 X12-Bestätigungen

Alles oben bezieht sich auf HL7 v2. X12 hat seine eigenen Bestätigungen, und im Gegensatz zu v2 sind sie standardmäßig deaktiviert: eine leere Einstellung bedeutet keine Bestätigung.

Diese Standard-Einstellung ist die sichere, da ein Handelspartner, der keine Bestätigung erwartet und eine erhält, diese als unerwünschte Interchange behandeln kann. Der acknowledge-Schlüssel in einem X12-Kanal kann einen von vier Werten annehmen:

WertWas gesendet wird
noneNichts. Der Standard.
999Implementierungsbestätigung. Ersetzt die 997 für HIPAA-Transaktionen.
997Funktionsbestätigung. Älter und immer noch das, was viele Verbindungspartner erwarten.
ta1Interchange-Bestätigung, bezogen auf die Hülle und nicht den Inhalt.

Welche Bestätigung gesendet werden soll, ist eine Eigenschaft der Handelspartnerbeziehung und nicht der Nachricht, weshalb sie konfiguriert werden muss und nicht abgeleitet werden kann. Eine 999 ersetzt eine 997 für HIPAA-Transaktionen, aber viele Partner – insbesondere ältere Verbindungspartner – sind so konfiguriert, dass sie eine 997 erwarten und eine 999 als unerkannte Datei behandeln.

Die Sendung der falschen Bestätigung ist schlimmer als die Sendung keiner. Sie beantwortet eine Frage, die niemand gestellt hat, während die eigentliche Frage offen bleibt, und der Absender hat keine Möglichkeit, den Unterschied zu erkennen.

9.9 HL7-v3-Bestätigungen

Ein HL7-v3-Kanal sendet standardmäßig eine Bestätigung, was das Gegenteil von X12 ist und beachtet werden sollte.

Der Grund liegt im Transport und nicht im Standard: eine v3-Interaktion trifft normalerweise über eine synchrone Verbindung ein, bei der die sendende Anwendung auf eine Antwort wartet, und ein Absender, der nichts erhält, wird normalerweise erneut versuchen. Das ist, wie ein Patient dreimal registriert wird.

Die Deaktivierung ist möglich und muss explizit durchgeführt werden – „nicht gesetzt“ und „auf false gesetzt“ sind absichtlich unterschiedlich, sodass der Standard gilt, es sei denn, jemand hat etwas anderes angegeben.

10 Lieferung, Queueing und Wiederholung

Ein Ziel, das nicht erreicht werden kann, ist der Normalfall und nicht die Ausnahme. Systeme werden neu gestartet, Netzwerke fallen aus, und ein Krankenhaus-Schnittstellen-Engine ist während seines eigenen Wartungsfensters nicht verfügbar. Die Lieferung ist darauf ausgelegt.

10.1 Queue pro Ziel

Attempt Delivered queue on disk — per destination 1, 2, 3, 4 … Retry growing backoff Dead letter kept, never discarded the same message, at the front Each destination has its own queue, so one slow receiver does not hold up the others. The queue is on disk, so a restart does not lose it. Order is preserved: message 2 is not attempted before message 1 succeeds or is given up on. A message that exhausts its attempts is dead-lettered and kept. Nothing is deleted to make a queue look healthy.

Jedes Ziel hat seine eigene Queue. Ein Ziel, das fehlschlägt, beeinträchtigt die anderen nicht, und jedes hat seinen eigenen Status, Alter und Wiederholungsstatus.

Die Queueing erfolgt pro Ziel und nicht pro Kanal, da der Fehler pro Ziel auftritt. Eine kanalweite Queue würde die Lieferung an drei funktionierende Systeme blockieren, weil ein viertes System down ist, und die beiden Situationen – ein Ziel ist nicht verfügbar, alle vier Ziele sind nicht verfügbar – würden in den Statistiken gleich aussehen.

10.2 Queue-Einstellungen

queue on a destination:

SchlüsselWas es tut
enabledOb fehlgeschlagene Nachrichten überhaupt in die Queue gelegt werden.
max_attemptsWie oft versucht wird, bevor aufgegeben wird.
backoffWartezeit vor dem ersten Wiederholungsversuch.
max_backoffObergrenze für die wachsende Wartezeit.
max_depthMaximale Anzahl von Nachrichten, die gehalten werden. Unset bedeutet keine Begrenzung.
retain_hoursWie lange eine gelieferte Nachricht aufbewahrt wird. Unset bedeutet, dass sie unbegrenzt aufbewahrt wird.

Die letzten beiden fehlten in dieser Tabelle und im Builder, und sie sind das Paar, das verhindert, dass die Festplatte voll wird. Eine Queue ohne diese beiden wächst, bis das Dateisystem voll ist, und dieser Fehler tritt als etwas Unverwandtes auf – ein Schreibfehler irgendwo ganz anders – anstatt als Queue-Problem.

Die Wartezeit zwischen den Versuchen wächst bis zur max_backoff. Wachsend und nicht fest, da ein Ziel, das down ist, normalerweise für Minuten und nicht für Sekunden down ist, und das Wiederholen alle Sekunde für zehn Minuten produziert mehrere hundert Log-Einträge, die den wichtigen Eintrag begraben.

10.3 Die Reihenfolge wird beibehalten

Innerhalb eines Ziels werden Nachrichten in der Reihenfolge ihrer Ankunft geliefert, und eine Nachricht, die fehlschlägt, behält ihren Platz. Spätere Nachrichten warten hinter ihr, anstatt sie zu überholen.

Dies ist die richtige Standard-Einstellung für klinische Daten – eine Aufnahme und eine Entlassung, die in der falschen Reihenfolge angewendet werden, sind schlimmer als wenn beide spät sind – und sie hat eine Konsequenz, die verstanden werden sollte: eine Nachricht, die immer fehlschlägt, hält alles hinter ihr auf.

Das ist der Grund, warum Warteschlangentiefe und Warteschlangenalter separate Warnbedingungen sind. Eine tiefe Warteschlange, die abfließt, ist ein beschäftigtes System. Eine Warteschlange, deren älteste Nachricht immer älter wird, ist blockiert, und die Warnarten queue-depth, queue-age und queue-stuck unterscheiden sie.

Eine Giftnachricht — eine, die nie erfolgreich sein wird, egal wie oft sie wiederholt wird — ist das spezifische Versagen, auf das sich dieses Design auswirkt. max_attempts ist das, was den Schaden begrenzt: nach diesem Zeitpunkt wird die Nachricht als fehlgeschlagen aufgezeichnet und die Warteschlange geht weiter. Wenn max_attempts sehr hoch eingestellt wird, um letztendlich Erfolg zu haben, wird eine einzelne fehlgeschlagene Nachricht in eine gestoppte Zufuhr umgewandelt.

10.4 Wenn die Warteschlangenverarbeitung deaktiviert ist

Mit queue.enabled auf false ist eine fehlgeschlagene Zustellung eine fehlgeschlagene Zustellung. Sie wird aufgezeichnet und nicht erneut versucht.

Das ist die richtige Wahl, wenn verspätete Daten schlimmer sind als keine Daten — eine Echtzeit-Anzeige, ein Paging-System, alles, bei dem eine Nachricht, die 40 Minuten nach dem Ereignis zugestellt wird, irreführend statt nur verzögert wäre.

Es ist die falsche Wahl für alles, was in einen Datensatz aufgenommen wird, wo die Nachricht genauso gültig ist, wenn sie eine Stunde später zugestellt wird.

10.5 Wiederholung versus Warteschlange

Es gibt zwei Mechanismen und sie funktionieren auf unterschiedlichen Ebenen.

retry auf einem Ziel bestimmt die sofortigen Versuche innerhalb einer Zustellung — eine Verbindung, die fehlschlägt, wird nach einer kurzen Pause erneut versucht, ohne den Zustellweg zu verlassen. Dies behandelt vorübergehende Fehler: eine abgebrochene Verbindung, eine vorübergehende Ablehnung.

queue bestimmt, was passiert, wenn diese sofortigen Versuche erschöpft sind. Die Nachricht verlässt den Zustellweg und wird später nach einem längeren Zeitplan erneut versucht.

Beide existieren, weil die beiden Fehler unterschiedlich sind. Ein Verbindungsreset beim ersten Versuch ist normalerweise beim zweiten Versuch behoben, und wenn man durch die Warteschlange geht, würde dies Minuten Latenz zu einem Fehler hinzufügen, der nur Millisekunden gedauert hat. Ein Ziel, das für Wartungsarbeiten deaktiviert wurde, wird nicht innerhalb von drei sofortigen Versuchen wieder verfügbar, und es ist sinnlos, es zu bombardieren.

10.6 Was ein HTTP-Endpunkt als zugestellt betrachtet

Ein HTTP-Ziel hat drei Einstellungen, die bestimmen, ob eine Nachricht als gesendet behandelt wird, und alle drei befinden sich im Ziel im Builder.

Statuscodes, die als zugestellt gelten. Leer bedeutet jeden 2xx-Code. Einige Endpunkte antworten mit 202 Accepted für etwas, das sie noch nicht verarbeitet haben, und einige antworten mit 200 und einem Fehler im Text — letzteres ist der Grund für *Behandeln als fehlgeschlagen, wenn die Antwort den folgenden Text enthält* . Die Festlegung einer expliziten Liste ist sinnvoll, wenn ein Partner Ihnen mitgeteilt hat, welcher Code was bedeutet, da die Alternative darin besteht, den Unterschied aus einer Nachricht zu ermitteln, die nie zugestellt und nie in die Warteschlange gestellt wurde.

Umleitungen verfolgen. Standardmäßig deaktiviert und absichtlich. Eine Umleitung kann auf einen anderen Host verweisen, sodass das Senden einer Nachricht an einen Ort, den niemand konfiguriert hat, und die Meldung eines Erfolgs erfolgt.

Bearer-Token. Als Authorization-Header gesendet. Es wird mit dem Kanal gespeichert und nicht erneut angezeigt, sodass das Leerlassen des Felds beim Bearbeiten eines vorhandenen Kanals das bereits gespeicherte Token beibehält, anstatt es zu löschen.

10.7 Benennen und Beschneiden eines Archivordners

Ein Dateiziel fügt standardmäßig zu einer Datei pro Tag und Nachrichtentyp hinzu (20261012-ADT_A01.hl7), MLLP-gerahmt, sodass die Datei mit perfuse send abgespielt werden kann. Vier Einstellungen auf dem Ziel ändern dies.

Dateiname (file_name) erstellt eine Datei pro Nachricht, die nach ${date}, ${timestamp}, ${control_id}, ${message_type} und ${destination} benannt wird. Ein Name, der bereits vergeben ist (die gleiche Steuer-ID zweimal), erhält ein eindeutiges Suffix anstelle der Überschreibung der Nachricht dort.

Anfügen (append: true) schreibt jede Nachricht in die Datei, die Dateiname benennt, sodass ${date}.hl7 eine Datei pro Tag für jeden Typ ist.

Suffix während der Schreiboperation (temp_suffix, eine Datei pro Nachricht, nur für die erste Nachricht) ist standardmäßig auf .part gesetzt und wird durch eine Umbenennung entfernt, sobald die Datei vollständig ist. Der Sammler dieser Dateien sollte keine halb geschriebene Datei aufnehmen, und eine Umbenennung innerhalb eines Ordners ist atomar. Ändern Sie es nur, wenn der Sammler auf eine andere Erweiterung filtert.

Löschen nach (retain_hours) löscht Dateien im Ordner, die älter sind als die angegebene Anzahl von Stunden, überprüft wird höchstens alle zehn Minuten, während Nachrichten eintreffen. Nur einfache Dateien direkt im Ordner werden gelöscht, niemals ein Unterordner. Leer oder Null bedeutet, dass sie für immer aufbewahrt werden, was der Standard ist und eine Entscheidung und kein Versehen darstellt — aber ein Archiv, das niemand löscht, füllt die Festplatte, und eine volle Festplatte stoppt den Kanal anstelle des Archivierens.

10.8 Senden an einen FHIR-Server

Drei Einstellungen bestimmen, wie viel überprüft wird, bevor ein Bundle verschickt wird.

US Core-Konformität beanspruchen fügt jedem Ressourcenprofil hinzu. Beanspruchen Sie es nur, wenn die Ressource das enthält, was das Profil erfordert, da ein Empfänger es gegen die Beanspruchung validieren und ein Bundle ablehnen kann, das ansonsten akzeptiert worden wäre.

Validieren vor dem Senden überprüft jede Ressource hier anstelle dessen, etwas vom Empfänger zu lernen. Eine Ablehnung am entfernten Ende teilt Ihnen weniger mit, später und oft nur in einem Log, das Sie nicht lesen können.

Warnungen als Ablehnungen behandeln hat nur eine Auswirkung, wenn die Validierung aktiviert ist, und die Steuerung ist nicht verfügbar, bis dies der Fall ist. Es ist streng genug, um einen Bundle zu stoppen, den ein Empfänger akzeptieren würde, sodass es auf einer Feed gehört, die aufgebaut wird, anstelle einer, die bereits in Betrieb ist.

10.8.1 Hosted FHIR-Dienste

Ein fhir-Ziel hat einen auth-Block, der sich bei den gehosteten Diensten anmeldet, wobei ein eingefügter Bearer-Token innerhalb einer Stunde abläuft:

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 signiert jede Anfrage für AWS HealthLake mit Signature Version 4, wobei die Region aus der URL gelesen wird. azure erhält ein Microsoft Entra-ID-Token für Azure Health Data Services von tenant_id, client_id und client_secret - eine App-Registrierung, die die FHIR-Daten-Contributor-Rolle hält - mit der FHIR-Service-URL als Zielgruppe. client_credentials tut das Gleiche gegen jede OAuth 2.0 token_url. Tokens werden wiederverwendet, bis sie eine Minute vor ihrem Ablaufdatum ablaufen. Die gleichen Optionen stehen unter dem Ziel des Hosted Service-Anmeldeinformationen im Kanal-Builder.

10.8.2 Öffentliche Gesundheitsberichterstattung

Aktivieren Sie Meldbare Bedingungen an die öffentliche Gesundheit melden auf einem FHIR-Ziel und es sendet Fallberichte anstelle von Bündeln. Jede Nachricht wird auf einen meldbaren-Bedingungen-Trigger-Code überprüft: eine Diagnose, einen Labortest oder ein kodiertes Ergebnis. Wenn es einen hat, wird die Nachricht zu einem HL7-eCR-2.1.2-eICR, in einer eCR-Nachricht eingeschlossen und an die URL's $process-message gesendet. Wenn es keinen hat, wird nichts gesendet und nichts schlägt fehl; das Ziel zählt es als nicht meldepflichtig.

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 ist der Reportable Conditions Trigger Codes, als FHIR-ValueSet oder das eRSD-Bündel. Es benötigt eine UMLS-Lizenz, daher ist es nicht enthalten; ohne es wird ein kurzes, eingebautes Beispiel verwendet, nur für Testzwecke. source ist, wo die Agentur ihre Reportability-Antwort sendet. Die Einrichtung ist erforderlich, da eCR nach ihrer Telefonnummer und Adresse fragt und eine v2-Nachricht keine davon hat.

Ein Bericht sagt, was die Nachricht fehlte, anstelle es zu erfinden, und jede Lücke wird protokolliert. Versuchen Sie, eine Nachricht im FHIR-Lab-Öffentliche Gesundheitsfallbericht-Panel zu testen, bevor Sie einen Live-Feed an eine Agentur verweisen.

10.8.3 Laborergebnisse an die öffentliche Gesundheit: ELR

perfuse elr -config elr.yaml results.hl7 wandelt die Ergebnisse eines Labors in HL7-2.5.1-ELR-Nachrichten um, die Gesundheitsministerien erhalten, eine für jede Nachricht mit einem meldepflichtigen Ergebnis und nur die Aufträge, die eines tragen: ein vollständiger Blutbild neben einem positiven SARS-CoV-2-Test ist nicht das Geschäft der öffentlichen Gesundheit. Die Trigger-Codes sind dieselben wie bei der Fallberichterstattung, die RCTC, die Sie laden oder das eingebaute Beispiel.

ELR benennt jeden mit OID oder CLIA-Nummer, was kein Labor-Feed für den Absender und den Empfänger enthält, sodass diese aus der Datei stammen:

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}

Die bestellende Einrichtung, die durchführende Laboreinrichtung und die zuweisenden Behörden werden nur verwendet, wo die Labornachricht sie weglässt, und jede Verwendung ist eine Notiz. Was nur das Labor weiß, wird nie ausgefüllt: ein Ergebnis ohne Probenart geht mit SPM-4 leer und einer Notiz, die dies angibt, da eine geratene Probe in einem Bericht an die öffentliche Gesundheit schlimmer ist als eine Lücke, die der Staat fragen kann. Beginnen Sie mit processing: T, während das Onboarding-Team des Staates den Feed testet.

Was das Labor richtig gemacht hat, wird so belassen, wie es gesendet wurde. Eine untergeordnete Bestellung (ein Empfindlichkeitspanel oder ein Reflextest, dessen OBR-29 den Elternnamen nennt und der keine eigene ORC hat) wird so gesendet, wie es empfangen wurde, ohne ORC oder Probe zu erfinden, und eine untergeordnete Bestellung ohne eigenes meldepflichtiges Ergebnis wird mit dem des Eltern, da eine Empfindlichkeit nichts ohne die Kultur bedeutet, zu der sie gehört. Eine Notiz nach dem PID bleibt beim Patienten, und ORC-14, die Rückruf-Telefonnummer, wird von OBR-17 kopiert, wenn das Labor sie nur dort platziert hat. Alle 28 Beispiel-Nachrichten, die ONC für sein ELR-Zertifizierungstool veröffentlicht, sind gültig und enthalten keine Fehler.

MSH-2 wird als ^~\&# geschrieben, die fünf Zeichen, die ELR-Release-1-Erata erfordern und die ONC-Zertifizierungstool überprüft. Wenn die Anleitung Ihres Staates die älteren vier zeigt, fügen Sie encoding_characters: "^~\\&" zur Datei hinzu.

Um sie von einem Kanal anstelle der Kommandozeile zu senden, geben Sie dem Ziel, das den Staat erreicht, einen elr-Block, der die gleiche Datei nennt. Jedes Laborergebnis wird auf dem Weg nach draußen umgestaltet, und eines mit nichts Meldepflichtigem wird nicht gesendet, was als geliefert und nicht als fehlgeschlagen gezählt wird: der Staat hat nur um meldepflichtige Ergebnisse gebeten.

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

Der Block gilt für einen HL7-v2-Kanal, für Ziele, die die Nachricht selbst liefern (mllp, http, tcp, Datei, sftp, ftp, S3, Azure Blob, soap, die Nachrichtenbroker oder einen anderen Kanal); der Kanal weigert sich, ihn zu laden, wenn die Datei fehlt oder es an der sendenden Einrichtung, der empfangenden Anwendung oder der empfangenden Einrichtung mangelt. Die Notizen werden mit der Nachrichten-Kontroll-ID im Protokoll geschrieben.

Die ELR-Datei ist der Begleiter des Kanals, kein Kanal: perfuse check und der Kanal-Bildschirm überspringen sie, anstatt einen Kanal zu melden, der nicht geladen wird. Im Kanal-Builder sind die gleichen beiden Einstellungen unter dem Ziel, in Laborberichterstattung (ELR 2.5.1); das Trigger-Codes-Feld öffnet sich, sobald eine ELR-Datei benannt ist, und das Speichern verweigert eine Datei, die nicht neben dem Kanal liegt.

10.8.4 DICOMweb-Archive

type: dicomweb speichert jedes Objekt mit STOW-RS: Orthanc, dcm4chee, die Cloud-Bildgebungsdienste oder den eigenen Archivserver von Perfuse. Geben Sie die Dienstwurzel (https://pacs.example/dicom-web) an; /studies wird hinzugefügt und eine URL, die bereits mit /studies endet, wird abgelehnt, anstatt auf /studies/studies zu posten. Authentifizieren Sie sich mit token (einem Bearer-Token) oder username und password; headers fügt weitere hinzu, wie z. B. den Projekt-Header eines Cloud-Dienstes. Der Kanal benötigt dataType: dicom.

Die Antwort des Servers entscheidet über das Ergebnis, nicht nur der Statuscode. Ein Objekt, das die Antwort als fehlgeschlagen auflistet, ist eine fehlgeschlagene Lieferung mit dem DICOM-Fehlergrund, und auch ein 202, der nichts als gespeichert auflistet, ist eine fehlgeschlagene Lieferung: Der Server hat die Anfrage angenommen und nichts davon behalten. Die Timeout-Standardzeit beträgt zwei Minuten, da eine große Serie langsam ist.

10.8.5 Dokumenten-Repositorys (IHE XDS.b)

type: xds veröffentlicht jedes klinische Dokument in einem XDS.b-Repository mit ITI-41 Provide and Register: ein CDA-Dokument oder eines, das eine HL7-v2-Nachricht (MDM, ORU) enthält. Die Metadaten stammen aus dem Dokument und den Einstellungen des Ziels (source_id, patient_domain, facility_type, practice_setting) und die Antwort des Registries entscheidet über die Lieferung. Siehe IHE-Dokumentfreigabe.

10.8.6 Impf-Register

Jedes US-amerikanische Immunisierungsregister (IIS) akzeptiert HL7-2.5.1-Nachrichten auf der gleichen SOAP-Schnittstelle, die die CDC 2011 veröffentlicht hat (Namespace urn:cdc:iisb:2011). Es gibt zwei Operationen: connectivityTest, die den Endpunkt nachweist, und submitSingleMessage, die die Nachricht enthält. Eine VXU^V04-Nachricht meldet eine Impfung und kommt als ACK zurück; eine QBP^Q11-Nachricht fragt die Geschichte und Prognose eines Patienten ab und kommt als RSP^K11 zurück.

Wählen Sie Impf-Register (CDC IIS-Webservice) als Dienst eines SOAP-Ziels oder schreiben Sie 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 erstellt die Hülle, sodass es keinen Textkörper zum Schreiben gibt. Der Benutzername und das Passwort werden innerhalb der Anfrage platziert, wo die CDC-WSDL sie platziert, und nicht in die HTTP-Authentifizierung. Die Version ist SOAP 1.2, die Bindung der WSDL, es sei denn, Sie setzen version: "1.1" für ein Register, dessen Anleitung dies erfordert. Wenn ein Register ein Clientzertifikat erfordert, setzen Sie die tls-Einstellung des Ziels wie für jeden HTTPS-Aufruf.

Die Bestätigung des Registers entscheidet darüber, ob die Nachricht geliefert wurde, nicht der HTTP-Status. Ein Register antwortet auf eine abgelehnte Impfung mit HTTP 200 und einem AR, sodass ein Ziel, das dem Status vertraut, eine verlorene Impfung als geliefert melden würde.

Die Antwort des RegistersPerfuse zeichnet auf
AA (oder CA)Geliefert.
AE, dessen ERR-Segmente alle Warnungen sind (ERR-4 W oder I)Geliefert. Die Warnungen sind in der Antwort enthalten.
AE mit jedem ERR-4 E oder einem ERR ohne SchweregradFehlgeschlagen, mit jedem ERR-Ort, -Code und -Text im Fehler.
AR oder CRFehlgeschlagen, auf die gleiche Weise.
Ein SOAP-Fehler (falsches Passwort, Nachricht zu groß)Fehlgeschlagen, mit dem Grund des Registers.
Etwas, das keine HL7-Nachricht istFehlgeschlagen.

warnings_are_errors: true (Warnungen als Fehler behandeln) macht jeden AE warten, bis eine Person ihn bearbeitet. Die Antwort, die Skripte für Antworten und ein HTTP-Aufrufer, der auf dem Kanal wartet, liest, ist die HL7-Nachricht des Registers: die ACK oder die RSP mit der Geschichte und Prognose. examples/iis enthält drei Kanäle, mit denen Sie beginnen können: VXU von einem EHR über MLLP, QBP-Abfragen über HTTP und ein lokales Register als Ersatz.

Das Verbindungen-Dashboard fragt ein Register nach seinem connectivityTest, wenn in den letzten sieben Tagen nichts übermittelt wurde. Diese Operation existiert für diesen Zweck und übermittelt nichts, sodass sie die einzige anwendungsspezifische Überprüfung ist, die Perfuse durchführt. Sie beweist die Adresse, TLS und die SOAP-Bindung, nicht den Benutzernamen und das Passwort; nur eine echte Übermittlung testet diese.

Eine SOAP-Quelle kann auf die gleiche Weise antworten: Antworten wie ein Immunisierungsregister, oder profile: cdc-iis auf der Quelle. Sie wiederholt connectivityTest, nimmt die Nachricht von submitSingleMessage, gibt die Bestätigung des Kanals in return zurück und dient die CDC-WSDL bei ?wsdl. Ein Benutzername und ein Passwort, wenn gesetzt, werden gegen die im Request enthaltenen überprüft, und ein falsches Paar erhält den SecurityFault der WSDL. Eine Nachricht, die der Kanal ablehnt, wird als NAK zurückgegeben, nie als Fehler, wie es die CDC-Anleitung besagt. Verwenden Sie es als Testdouble oder um Übermittlungen auf die gleiche Weise wie ein Register zu empfangen.

Nicht abgedeckt: die staatsspezifischen Teile der Onboarding-Prozesse. Jedes Register hat seinen eigenen Endpunkt, seinen eigenen Kontoprozess und sein eigenes Profil der 2.5.1-Anleitung (erforderliche RXA- und OBX-Felder, VFC-Eignung, Ablehnungsgründe). Diese sind der Inhalt der Nachrichten, den die Transformationen des Kanals formen; kein staatlicher Endpunkt ist integriert. Perfuse wurde gegen sich selbst und gegen aufgezeichnete Registerantworten getestet, nicht gegen ein live staatliches Register.

10.9 Wenn der Transport Ja sagt und die Nachricht nicht angekommen ist

„Ist dies angekommen“ ist oft keine Frage, die der Transport beantworten kann. Ein MLLP-Empfänger gibt eine Anwendungsbestätigung zurück, deren Bedeutung in ihrem Text liegt. Ein HTTP-Empfänger gibt 200 mit einem Fehlerdokument zurück. In beiden Fällen ist der Transport erfolgreich und die Nachricht ist nicht angekommen.

Antwort überprüfen auf einem Ziel nimmt ein Skript, das die Antwort des Empfängers erhält. Wenn es false zurückgibt oder eine Ausnahme auslöst, wird die Lieferung als fehlgeschlagen markiert – was bedeutet, dass sie erneut versucht wird, in die Warteschlange gestellt wird und im Fehlerzähler erscheint, anstatt stillschweigend als geliefert gezählt zu werden.

Es wird nur auf Zielen angeboten, die eine Antwort empfangen. Auf einem, das keine Antwort empfangen kann, wird es bei der Ladung abgelehnt, anstatt nie ausgeführt zu werden.

10.10 Was ein Lieferungsergebnis bedeutet

ErgebnisBedeutung
DeliveredDas Ziel hat die Nachricht akzeptiert. Für MLLP wurde eine positive Bestätigung erhalten.
QueuedDie Lieferung ist fehlgeschlagen und die Nachricht wird erneut versucht.
FailedDie Lieferung ist fehlgeschlagen und wird nicht erneut versucht, entweder weil die Warteschlange ausgeschaltet ist oder die Versuche erschöpft sind.
FilteredDas Ziel hat die Nachricht durch seinen eigenen Filter abgelehnt. Kein Fehler.

Diese werden pro Ziel pro Nachricht aufgezeichnet, sodass eine Nachricht, die drei von vier Zielen erreicht hat, genau so aufgezeichnet wird. Es gibt keine Kanal-"Erfolg", da dies nichts bedeuten würde.

10.11 Langsamer Versand

Ein Ziel, das Nachrichten akzeptiert, aber lange braucht, ist ein separates Problem von einem, das fehlschlägt, und es ist leicht zu übersehen, da jedes Ergebnis ein Erfolg ist.

Der slow-delivery-Warnungstyp existiert für diesen Zweck. Es lohnt sich, ihn auf alles zu setzen, wo die Bestätigung des Absenders auf die Lieferung wartet, da ein Ziel, dessen Antwortzeit stillschweigend verdoppelt wurde, schließlich die Zeitüberschreitung des Absenders überschreiten und Resends produzieren wird — und zu diesem Zeitpunkt erscheint das Symptom stromaufwärts, in einem System, das Sie möglicherweise nicht verwalten.

10.12 Schreiben in eine Datenbank

type: database führt eine Anweisung pro Nachricht mit Werten aus, die an die Nachricht gebunden sind.

Platzhalter sind die eigenen des Treibers — $1 für postgres, ? für mysql und sqlite, @p1 für sqlserver — und Perfuse ändert sie nicht. Das ist absichtlich: eine Übersetzungsschicht, die einen Platzhalter falsch interpretiert, würde einen Patientennamen an die falsche Spalte binden, und das Ergebnis würde wie gültige Daten aussehen, anstatt wie ein Fehler.

Eine Anweisung, die in der falschen Dialekt geschrieben ist, wird abgelehnt, wenn sie gespeichert wird, und der Stil, den der Treiber möchte, wird genannt. Bevor diese Überprüfung existierte, trat der Fehler als syntax error at or near "," vom Server auf, wenn eine Nachricht ankam, was eine Anweisung nennt, die Sie tatsächlich geschrieben haben, und Sie daher nach einem Tippfehler suchen, anstatt nach dem Dialekt.

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

Ein zitierter Parameter ist eine Konstante und kein Pfad, was so ist, wie ein Kanal seinen eigenen Namen oder einen Quellsystemcode in eine Zeile neben den Nachrichtendaten schreibt.

Werte werden immer als Parameter gebunden. Eine ${...}-Referenz innerhalb der Anweisung wird abgelehnt: ein Name, der ein Apostroph enthält, würde die Anweisung brechen, und ein feindlicher Wert würde sie neu schreiben.

10.13 Senden an einen rohen Socket

type: tcp schreibt in einen Socket mit der von Ihnen gewählten Rahmen, was normalerweise von einem Gerät oder einem Laborinstrument gewünscht wird. MLLP ist eine Rahmen unter mehreren; dieses Ziel bietet die anderen.

destinations:
  - name: instrument
    type: tcp
    tcp:
      address: instrument.lab:9100
      framing: delimited
      delimiter: \r
      expect_reply: true
      timeout: 30s

Die Rahmen haben keinen Standard, absichtlich. Schreiben mit der falschen Rahmen führt nicht zum Fehler. Das entfernte Ende liest Nachrichten, die an den falschen Stellen geteilt sind, oder wartet auf einen Terminator, der nie kommt, und das Symptom erscheint im Empfangssystem und nicht hier.

framingWas es schreibt
mllp0x0b vor, 0x1c 0x0d nach. Die gleiche Rahmen, die ein MLLP-Ziel verwendet.
delimitedEin delimiter nach jeder Nachricht und ein optionaler start_block vor ihr.
fixedAufzeichnungen, die auf record_length gepaddet oder gekürzt werden.
lengthEin length_bytes-Präfix. big_endian und length_includes_header haben beide zwei Konventionen in der Praxis und die Differenz ist stillschweigend.
wholeEine Nachricht pro Verbindung, geschlossen, um das Ende zu markieren.

Nur die Einstellungen, die die gewählte Rahmen verwendet, werden akzeptiert. Eine Aufzeichnungslänge in einem begrenzten Datenstrom wird abgelehnt, anstatt ignoriert, da eine Einstellung, die stillschweigend ignoriert wird, eine ist, an die jemand glaubt, sie sei in Kraft.

expect_reply ändert, was geliefert bedeutet. Ohne es bedeutet Erfolg, dass die Bytes den Sendepuffer des Betriebssystems erreicht haben — was ein Peer, der einen Moment später abstürzt, nie gelesen hat.

10.14 Amazon S3, SQS und SNS

Ein Kanal kann aus einer SQS-Warteschlange oder einem S3-Bucket-Präfix lesen und an SQS, SNS oder S3 liefern. Alle fünf sind signierte HTTP-Anfragen ohne AWS-SDK im Binärformat, und alle fünf akzeptieren die gleichen Zugriffseinstellungen: region, access_key_id, secret_access_key (schreiben Sie ${AWS_SECRET_ACCESS_KEY}, um die Umgebungsvariable zu lesen), ein optionales session_token und endpoint für LocalStack, MinIO oder einen VPC-Endpunkt. Unter Kanäle → Neuer Kanal wählen Sie *Wir lesen aus einer Amazon-SQS-Warteschlange*, *Wir sammeln Objekte aus einem Amazon-S3-Bucket* oder die SQS-, SNS- und S3-Zieltypen.

Nichts wird an AWS bestätigt, bis der Kanal es bearbeitet hat. Eine SQS-Nachricht wird danach gelöscht und erscheint ansonsten erneut, wenn ihre Sichtbarkeitszeitüberschreitung endet, sodass die Wiederholungsrichtlinie einer Warteschlange eine Nachricht, die immer wieder fehlschlägt, in eine Warteschlange für tote Briefe verschiebt. Ein S3-Objekt wird danach in processed/ verschoben oder in error/, wenn es nicht bearbeitet werden konnte, sodass eine fehlerhafte Datei die anderen nicht stoppt.

In einer FIFO-Warteschlange oder einem Thema werden Nachrichten standardmäßig nach Patienten gruppiert - SQS behält die Reihenfolge innerhalb einer Gruppe und nirgendwo anders - und dedupliziert nach Inhalt, sodass eine Wiederholung nicht zweimal geliefert wird.

Ein S3-Archiv kann direkt in Glacier mit storage_class geschrieben werden und als JSON-Zeilen für Amazon Athena mit format: ndjson; perfuse athena gibt die Tabelle aus. Die Referenz enthält jede Einstellung.

10.15 AMQP 1.0 und Azure

AMQP 1.0 ist das Protokoll, das Azure Service Bus und Event Hubs sprechen, sowie RabbitMQ 4, ActiveMQ und Artemis neben ihren anderen Protokollen. Ein amqp-Quell empfängt von einer Warteschlange oder einem Abonnement und akzeptiert jede Nachricht nur dann, wenn der Kanal sie bearbeitet hat; eine Nachricht, die nicht bearbeitet werden konnte, wird als fehlgeschlagene Lieferung freigegeben, so dass der Broker sie erneut liefert und, wenn die Warteschlangenbegrenzung überschritten wird, in die Totenbriefe legt. Ein amqp-Ziel meldet Erfolg nur dann, wenn der Broker die Nachricht akzeptiert. Für Service Bus: addr ist <namespace>.servicebus.windows.net:5671 mit tls, username der Name der gemeinsam genutzten Zugriffsrichtlinie, password ihr Schlüssel und address der Name der Warteschlange, oder <topic>/subscriptions/<name>, um zu empfangen.

Azure Blob Storage: Ein azure_blob-Ziel schreibt einen Blob pro Nachricht in der ausgewählten Zugriffsebene - Hot, Cool, Cold oder Archiv - und ein azure_blob-Quell nimmt Blobs von einem Präfix auf und verschiebt sie in processed/ oder error/, wie der S3-Quell es auch tut. Es ist ratsam, ein SAS-Token zu verwenden, das auf den Container beschränkt ist, anstelle des Kontoschlüssels.

10.16 MQTT

Ein mqtt-Quell abonniert einen Themenfilter (+ entspricht einem Level, # jedem Level darunter) auf jedem MQTT 3.1.1-Broker: Mosquitto, EMQX, HiveMQ, AWS IoT Core, Azure Event Grid. Bei QoS 1, dem Standard, wird jede Nachricht nur dann bestätigt, wenn der Kanal sie bearbeitet hat. MQTT hat keine Möglichkeit, eine einzelne Nachricht abzulehnen, daher bleibt eine Nachricht, die nicht bearbeitet werden konnte, unbestätigt und die Verbindung wird erneut hergestellt; der Broker hält die Sitzung unter der Client-ID (perfuse-<channel>, sofern client_id nichts anderes angibt) und sendet sie erneut, zuerst in der Warteschlange. QoS 0 ist höchstens einmal: alles, was während Perfuse heruntergefahren ist, geht verloren. Ein mqtt-Ziel veröffentlicht und meldet bei QoS 1 Erfolg, wenn der Broker die Nachricht hat.

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 benötigt ein Clientzertifikat: geben Sie tls.cert_file und tls.key_file an.

10.17 IBM MQ

ibm_mq liest und schreibt IBM-MQ-Warteschlangen über die Messaging-REST-API (mqweb) des Queue-Managers, die IBM MQ 9.1.5 und später auf jeder Plattform, einschließlich z/OS, ausliefern, so dass kein MQ-Client neben Perfuse installiert werden muss. Der Benutzer benötigt die Rolle MQWebUser und die Berechtigung zum Schreiben, Lesen und Durchsuchen der Warteschlange. Ein Quell durchsucht die erste Nachricht, übergibt sie an den Kanal und entfernt sie nur dann durch ihre Nachrichten-ID, wenn sie bearbeitet wurde; eine Nachricht, die fehlschlägt, bleibt an erster Stelle in der Warteschlange. Führen Sie einen Leser pro Warteschlange aus. Ein Ziel setzt persistente Nachrichten (sofern non_persistent nicht angegeben ist), wobei die HL7-Steuer-ID als Korrelations-ID verwendet wird.

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 ist v3 für MQ 9.3 und später (Standard), v2 für 9.1.5 bis 9.2. Ein Queue-Manager mit einem AMQP-Kanal kann auch mit dem amqp-Connector erreicht werden.

10.18 Google Cloud Pub/Sub und Cloud Storage

Ein pubsub-Quell zieht von einem Abonnement und bestätigt jede Nachricht, sobald sie bearbeitet wurde; eine Nachricht, die fehlschlägt, wird sofort zurückgegeben (ihre Bestätigungsfrist auf Null gesetzt), zusammen mit dem Rest ihrer Charge, so dass Pub/Sub sie erneut liefert und, wenn die Abonnement-Totenbriefrichtlinie überschritten wird, in die Totenbriefe legt. Ein pubsub-Ziel veröffentlicht mit dem HL7-Nachrichtentyp und der Steuer-ID als Attributen; order_by: patient legt den Sortierschlüssel aus PID-3.1 fest, so dass ein Abonnement mit Nachrichtenordnung die Nachrichten jedes Patienten in der Reihenfolge hält.

Ein gcs-Ziel schreibt ein Objekt pro Nachricht, benannt wie ein S3-Schlüssel, in der ausgewählten Speicherklasse (STANDARD, NEARLINE, COLDLINE, ARCHIV). Ein gcs-Quell nimmt Objekte von einem Präfix auf und verschiebt sie in processed/ oder error/, wie der S3-Quell es auch tut.

Beide melden sich als Dienstkonto an: credentials_file ist ihr JSON-Schlüssel. Lassen Sie es auf Google Cloud (einer VM, GKE oder Cloud Run) leer, um das angehängte Dienstkonto zu verwenden. endpoint benennt einen Emulator (den Pub/Sub-Emulator, fake-gcs-server), der keine Anmeldeinformationen benötigt.

source:
  type: pubsub
  pubsub:
    project: hospital-integration
    subscription: adt-to-perfuse
    credentials_file: /etc/perfuse/gcp-key.json

10.19 Lesen einer Mailbox (IMAP und POP3)

Ein email-Quell liest ein Postfach und wandelt das, was er findet, in Nachrichten um: jede Anlage (take: attachments, Standard, eingeschränkt durch attachment_names-Muster), den Text der E-Mail (take: body) oder die gesamte E-Mail (take: raw) für ein Skript, das sie auseinandernehmen soll. Laboratorien, Bildungszentren und kleine Praxen senden Ergebnisse immer noch auf diese Weise.

Jede Überprüfung meldet sich an, liest die ungelesenen Nachrichten von ältesten zuerst und meldet sich ab. Über IMAP wird eine E-Mail abgerufen, ohne als gelesen markiert zu werden, an den Kanal übergeben und nur dann, wenn jede Nachricht daraus akzeptiert wurde, in move_to (Verarbeitet) verschoben, als gelesen markiert (after_read: flag) oder gelöscht. E-Mails, die fehlschlugen oder nicht aufgenommen wurden (ein Absender außerhalb von allowed_senders, keine Anlage, die attachment_names entspricht, größer als max_message_size), werden in error_folder (Fehler) mit dem Grund im Protokoll verschoben. Beide Ordner werden erstellt, wenn sie fehlen. POP3 hat keine Ordner oder Flaggen, daher werden Nachrichten gelöscht: Löschungen werden durch den QUIT am Ende der Überprüfung bestätigt, so dass eine Sitzung, die abbricht, nichts löscht und eine bearbeitete E-Mail möglicherweise erneut gelesen wird (nie verloren geht). POP3-E-Mails, die nicht aufgenommen werden, bleiben auf dem Server und werden einmal gemeldet.

Die Anmeldung erfolgt durch ein Passwort (${MAIL_PASSWORD}; ein App-Passwort für Gmail) oder OAuth 2.0 über SASL XOAUTH2, was Microsoft 365 erfordert (es hat die Anmeldung mit Passwort deaktiviert) und Gmail bevorzugt:

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]

Mit client_secret und ohne refresh_token wird der Microsoft 365-App-Only-Zugriff verwendet (der client-credentials-Zuweisung, Bereich https://outlook.office365.com/.default): Ein Administrator registriert die App, gewährt ihr IMAP.AccessAsApp und beschränkt sie auf das eine Postfach mit einem Exchange-Dienstprinzipal. Mit einem refresh_token (einer Zustimmung einer Person) wird der delegierte Bereich IMAP.AccessAsUser.All oder POP.AccessAsUser.All verwendet, und ein rotierter Refresh-Token wird für die Lebensdauer des Prozesses aufbewahrt. Gmail benötigt einen refresh_token: Google bietet keinen App-Only-Zugriff auf ein Postfach an.

allowed_senders akzeptiert Adressen und Domänen. Die From-Zeile einer E-Mail kann gefälscht werden, daher verhindert dies Unfälle und unerwünschtes Post, aber nicht einen Angreifer; ein Feed, der vertrauenswürdig sein muss, gehört auf Direct (S/MIME signiert), SFTP oder ein VPN. security ist tls (993 oder 995, Standard), starttls (143 oder 110) oder none, das nur zu localhost erlaubt ist. Überprüfungen erfolgen mindestens 10 Sekunden auseinander (60 Sekunden standardmäßig), da Mail-Dienste Konten drosseln, die häufiger überprüfen.

Getestet gegen GreenMail 2.1.3 (IMAPS, IMAP, POP3S und POP3: Anmeldung mit falschem Passwort abgelehnt, Abrufen ohne Markieren als gelesen, VERSCHIEBEN, Markieren, Löschen, eine zu große E-Mail vor dem Lesen abgelehnt) und gegen Gmails IMAP mit einem App-Passwort (Erstellen eines Ordners, Anhängen, Abrufen, VERSCHIEBEN, Löschen). OAuth wurde nur gegen einen Ersatz-Token-Endpunkt getestet: nicht gegen Microsoft oder Google.

10.20 AS2

AS2 (RFC 4130) ist die Methode, mit der viele Zahler, Clearinghäuser und Lieferanten EDI austauschen: ein HTTP-POST, dessen Body mit dem Zertifikat des Absenders signiert und für den Empfänger verschlüsselt ist, der mit einer Quittung (einer MDN) beantwortet wird, die einen Digest des Eingehenden nennt. Das S/MIME ist der gleiche Code, den Direct-Nachrichten verwenden. Beide Enden sind im Kanal-Builder: Handelspartner senden uns EDI über AS2 als Quelle, Ein Handelspartner über AS2 als Ziel.

# 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"

Empfangen. Eine Nachricht an ein anderes AS2-To oder von einem Absender, der nicht in partners ist, wird mit 403 abgelehnt und ohne Quittung. Eine Nachricht eines Partners muss signiert und verschlüsselt sein, es sei denn, dessen Eintrag setzt allow_unsigned oder allow_unencrypted. Die Nutzlast wird entschlüsselt, ihre Signatur wird gegen das Zertifikat des Partners überprüft (Partner tauschen normalerweise selbstsignierte Zertifikate aus, was in Ordnung ist: das Zertifikat ist das Vertrauen), und an den Kanal weitergegeben, wie es das Nachrichtenformat des Kanals vorsieht. Der Partner erhält die Quittung, die er angefordert hat: in der Antwort oder an seiner Receipt-Delivery-Option-URL gepostet; signiert, wenn er eine signierte angefordert hat. Eine Nachricht, die fehlschlägt, erhält eine Quittung, die den Grund nennt (decryption-failed, authentication-failed, insufficient-message-security, unexpected-processing-error).

Senden. Jede Nachricht wird signiert (SHA-256) und verschlüsselt (AES-256-CBC). Mit receipt: sync, dem Standard, gilt sie als zugestellt, wenn die Quittung gegen partner_cert_file überprüft wird, processed sagt und den gleichen Digest (MIC) wie das Gesendete trägt; alles andere ist eine fehlgeschlagene Zustellung und wird erneut versucht. receipt: async fordert die Quittung an receipt_url an, die ein AS2-Quell auf diesem Server sein muss, der den Partner auflistet: die Nachricht gilt als zugestellt, sobald der Partner die Anfrage akzeptiert, und eine Quittung, die später widerspricht, wird als Fehler protokolliert. receipt: none fordert nichts an. unsigned, unencrypted und unsigned_receipt lockern jeden Teil für eine Vereinbarung, die so besagt; username und password fügen HTTP-Basicauthentifizierung für Gateways hinzu, die sie erfordern. Der Inhaltstyp folgt dem Format des Kanals (application/edi-x12 für X12), es sei denn, content_type setzt einen.

Triple DES, AES-128 und AES-192 werden ebenfalls gelesen, sowie AES-256, da Partner sie immer noch senden, und auch der Streaming-BER (unbestimmte Längen), den Java-Gateways schreiben.

Komprimierung (RFC 5402). Eine komprimierte Nachricht wird gelesen, egal wie sie erstellt wurde: komprimiert vor der Signierung oder Verschlüsselung oder eine signierte Nachricht, die als Ganzes komprimiert ist. Der MIC der Quittung folgt dem RFC: über das Signierte, wenn es signiert ist, über den unkomprimierten Inhalt, wenn es nicht signiert ist. Eine Nachricht, die sich über das Zehnfache der max_message_size des Quells erweitern würde, wird mit decompression-failed abgelehnt, damit einige Kilobyte nicht Gigabytes an Speicher beanspruchen können. Ein Ziel komprimiert mit compress: true, vor der Signierung und Verschlüsselung, wie es die meisten Gateways tun; fragen Sie den Partner zuerst.

Eine Nachricht, die zweimal gesendet wird. Ein Partner, der unsere Quittung nie erhalten hat, sendet die Nachricht erneut mit der gleichen Message-ID (RFC 4130 Abschnitt 7.5). Die Quelle erinnert sich an jede Message-ID des Partners für duplicate_window (Standard 720h, 30 Tage; mindestens eine Stunde) und beantwortet eine erneute Sendung mit einer processed-Quittung, ohne sie erneut weiterzuleiten. Der Eintrag wird in der Datenbank gespeichert, damit ein Neustart ihn nicht vergisst. Eine Nachricht, deren Verarbeitung fehlgeschlagen ist, wird nicht erinnert, sodass der erneute Versuch des Partners durchgeht. Kopien, die gleichzeitig eintreffen, warten aufeinander, und nur die erste wird weitergeleitet. Wenn der Eintrag nicht gelesen werden kann, wird die Nachricht mit unexpected-processing-error abgelehnt, und der Partner versucht es später erneut, anstatt ein zweites Exemplar zu riskieren. Eine Nachricht ohne Message-ID kann nicht erkannt werden und wird als solche protokolliert.

Die Interoperabilität wird in beiden Richtungen gegen pyas2lib 1.4.3 getestet, mit Triple DES und AES-256, komprimiert und nicht komprimiert, einschließlich synchroner signierter Quittungen.

10.21 OpenPGP

Zahler, Clearinghäuser und staatliche Behörden übernehmen und senden Dateien oft nur unter OpenPGP. Ein pgp-Block auf einer Quelle öffnet das Eintreffende; ein Block auf einem Ziel schützt das Ausgehende. Beide befinden sich auf dem Kanal-Builder: OpenPGP-verschlüsselte Nachrichten unter der Quelle, Mit OpenPGP verschlüsseln auf jedem Ziel.

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}

Zertifikatsdateien werden relativ zur Kanaldatei gelesen und beim Laden des Kanals gelesen und entsperrt: ein fehlendes Zertifikat oder ein falsches Passwort stoppt den Kanal dort, nicht bei der ersten Datei.

Nachrichten werden mit AES-256 im RFC-4880-Format geschrieben, das ältere Empfänger lesen können, und das neuere RFC-9580-Format kann auch gelesen werden. Die Kryptographie ist ProtonMail/go-crypto; Perfuse implementiert keine primitiven Funktionen. Die Interoperabilität wird gegen GnuPG in beiden Richtungen getestet: gpg entschlüsselt und verifiziert, was Perfuse schreibt, und Perfuse öffnet und verifiziert, was gpg schreibt.

10.22 Lieferung an einen anderen Kanal

Ein Kanalziel übergibt die Nachricht an einen anderen Kanal durch dessen Namen. Der empfangende Kanal behandelt sie wie jede andere Ankunft: Er zeichnet sie auf, filtert sie, transformiert sie und verteilt sie.

Dies ist die unterstützte Methode, um eine Kette zu bauen. Sie ist absichtlich sichtbar – zwei Kanäle, zwei Sätze von Statistiken, zwei Einträge in der Nachrichtenhistorie –, weil eine Kette, die innerhalb eines Kanals verborgen ist, eine Kette ist, die niemand überwachen kann.

Die Nachricht wird im Speicher anstelle eines Netzwerks übergeben, sodass es keine Framing, keine Bestätigung und keine Zeitüberschreitung zwischen den beiden gibt.

10.23 Was passiert, wenn der Prozess beendet wird

Die Frage, die jeder, der einen Integrations-Engine bereits ausgeführt hat, zuerst stellt, und diejenige, die selten beantwortet wird, weil die ehrliche Antwort normalerweise peinlich ist.

Sie wurde beantwortet, indem der Prozess mit SIGKILL teilweise durch einen Batch getötet wurde — was einem Stromausfall, einem Out-of-Memory-Kill und einem Hypervisor-Reset von innen ähnelt — und das, was überlebt hat, gegen das, was versprochen wurde, gezählt wurde.

Die Eigenschaft, die getestet wird, ist nicht „nichts geht verloren“. Das ist nicht erreichbar und zu behaupten, es wäre eine Lüge. Es ist das enger gefasste Versprechen, auf das ein Absender tatsächlich vertraut: eine Nachricht, die positiv bestätigt wurde, ist eine Nachricht, die angekommen ist.

Mit ack.when: on_delivery, was standardmäßig ist, wird jedes Ziel vor der Bestätigung geschrieben, sodass ein AA eine Aussage über das Ziel und nicht über eine Warteschlange ist. Eine Nachricht, die vor ihrer Bestätigung getötet wird, kann sehr wohl verloren gehen, und das ist korrekt: Der Absender wurde nie etwas versprochen und wird sie erneut senden.

10.23.1 Bestätigung bei Lieferung

Fünf Durchläufe, getötet nach 5, 25, 40, 75 und 110 Nachrichten von 120.

BestätigtDanach downstream vorhandenBestätigt, aber fehlend
2552550

Das Versprechen wurde bei jedem Killpunkt gehalten, und nichts wurde dupliziert. Eine Duplikation wäre akzeptabel gewesen und ein Verlust nicht: Eine erneut gesendete A08 ist ein Ärger, den Empfänger absorbieren, und ein Laborergebnis, das stillschweigend nie ankommt, ist ein Patientensicherheitsereignis.

10.23.2 Bestätigung bei Empfang

on_receipt antwortet, sobald die Nachricht in die Warteschlange gestellt wird, bevor ein Ziel geschrieben wurde. Dieses Kapitel hat immer gesagt, dass eine bestätigte Nachricht dennoch auf diese Weise verloren gehen kann. Hier ist die Größe davon.

Getötet nachBestätigtDownstream vorhandenVerloren
5514
2525124
7575273
1101102108

Im Wesentlichen alles, was unterwegs ist. Die Einstellung ist kein Defekt, und es gibt Feeds, bei denen sie die richtige Wahl ist, aber sie sollte unter Kenntnis der Tatsache gewählt werden, dass ein Absturz das, was bestätigt, aber noch nicht geschrieben wurde, verwirft, und dass dies fast alles eines Burst ist.

Nichts wird bei Neustart wiederhergestellt, da perfuse run keinen dauerhaften Speicher hat. Ein Ziel, das keine Nachrichten während eines Ausfalls verlieren darf, benötigt queue.enabled, was die Datenbank benötigt, die perfuse serve bereitstellt — und perfuse run weigert sich jetzt, einen solchen Kanal zu starten, anstatt ihn ohne Warteschlange zu starten.

10.23.3 Ein Absender, der auf halbem Weg durch eine Nachricht stirbt

Der gefährlichste dieser Fehler, da eine verkürzte HL7-Nachricht normalerweise immer noch analysiert werden kann. Die Segmente vor dem Schnitt sind vollständig und wohlgeformt, sodass ein Empfänger keine Möglichkeit hat, zu wissen, dass PID und PV1 angekommen sind und die OBX-Segmente mit den Ergebnissen nicht.

Ein Frame wurde geöffnet, sechs Zehntel einer Nachricht gesendet und die Verbindung zurückgesetzt, anstatt geschlossen zu werden. Die partielle Nachricht wurde nicht geliefert, der Listener überlebte, und eine wohlgeformte Nachricht, die sofort danach gesendet wurde, wurde normal akzeptiert, sodass das Fragment nicht in die nächste Nachricht übernommen wurde.

Der Verbindungsprotokollbericht gibt nun an, wie viele Bytes eines unvollständigen Frames für jeden Fehlermodus und nicht nur für ein sauberes Schließen aufgegeben wurden. Zuvor wurden ein abgestürzter Absender, ein getöteter Prozess und ein gezogener Kabel alle mit messages=0 protokolliert und nichts anderes, was einen leeren Gesundheitscheck nicht von einem Laborergebnis unterscheiden kann, das neun Zehntel des Weges durchgeworfen wird.

10.23.4 Eine volle Festplatte

Platzmangel wird erkannt und protokolliert, anstatt geschluckt zu werden. Zwei Dinge darüber sind erwähnenswert.

Der Absender erhält keine prompte Ablehnung. Die Lieferung wird nach dem üblichen Zeitplan wiederholt — eine Sekunde, zwei, vier, acht — und die negative Bestätigung trifft etwa 15 Sekunden später ein. Ein Absender, dessen eigene Zeitüberschreitung kürzer ist als diese, sieht eine blockierte Verbindung anstelle eines AE und wird daraus schließen, dass das Netzwerk und nicht die Festplatte fehlerhaft ist.

Und ein Volume, das null freie Bytes meldet, kann immer noch kleine Anhänge für eine Weile akzeptieren, denn das Hinzufügen von ein paar hundert Bytes zu einer Datei, deren letztes Block noch Platz hat, benötigt keine neue Zuweisung. Der erste Schreibfehler tritt später ein als der Moment, in dem die Disk voll war.

10.23.5 Was nicht getestet wurde

Ein Zielverzeichnis, das die Schreibberechtigung verliert. Es kann nicht mit chmod injiziert werden: der Motor hält die Ausgabedatei geöffnet und das Ändern des Modus einer Datei hat keine Auswirkung auf einen bereits geöffneten Descriptor. Um es ordnungsgemäß zu testen, muss das Volume neu gemountet werden als schreibgeschützt oder unter dem Prozess entfernt werden, was bisher nicht durchgeführt wurde. Es wird hier benannt, anstatt weggelassen zu werden, weil eine Lücke, über die niemand spricht, wie eine Lücke aussieht, nach der niemand gesucht hat.

11 Benachrichtigung

Nichts außerhalb von Perfuse wird Ihnen mitteilen, dass ein Feed gestoppt wurde. Der Sender wird bestätigt und ist zufrieden; der Empfänger hat keine Möglichkeit, zu wissen, dass eine Nachricht gesendet wurde. Die Benachrichtigung ist das Einzige, das zwischen einer fehlerhaften Schnittstelle und jemandem, der es Wochen später bemerkt, steht.

11.1 Die Benachrichtigungsarten

ArtWann ausgelöst
error-rateFehler überschreiten einen Anteil des Datenverkehrs.
queue-depthEine Warteschlange hat mehr als N Nachrichten im Warten.
queue-ageDie älteste wartende Nachricht ist älter als eine Dauer.
queue-stuckEine Warteschlange wird nicht entleert.
no-trafficNichts ist für eine feste Periode angekommen.
below-rhythmDer Datenverkehr ist deutlich unter dem, was diese Feed normalerweise *zu dieser Tageszeit* tut.
channel-downEin Kanal, der laufen sollte, ist nicht verfügbar.
script-errorsEin Skript schlägt fehl.
rows-quarantinedEine Datenbankquelle setzt Zeilen zurück.
slow-deliveryZustellungen sind erfolgreich, aber dauern zu lange.
contractEine Nachricht verletzt den erklärten Vertrag des Kanals.
phi-volumeEin Kanal transportiert mehrere Male seine übliche Rate pro Stunde.
phi-after-hoursEin Kanal, der nur tagsüber Daten transportiert, transportiert einige nachts.
phi-new-destinationEin Kanal liefert an eine Adresse, an die er noch nie zuvor geliefert hat.
phi-bulk-readsEine Person liest mehr als N verschiedene Patientenakten innerhalb einer Minute.

Die letzten vier überwachen den Zugriff auf Patientendaten und werden unten beschrieben.

11.2 Stille ist das Schwierigste zu erkennen

Ein Kanal, der aufgehört hat, Nachrichten zu empfangen, produziert keine Fehler. Es gibt nichts zu zählen. Deshalb existiert no-traffic, und deshalb reicht es allein nicht aus.

no-traffic ist ein fester Schwellenwert: Benachrichtigen, wenn nichts für, sagen wir, zwei Stunden angekommen ist. Bei einem Feed, der tatsächlich nie stillsteht, funktioniert das. Bei einem Labor-Feed einer Klinik ist es jedoch nutzlos — der Feed ist still jede Nacht und an jedem Wochenende, also wird jemand um 1 Uhr morgens jede Nacht benachrichtigt, und ein Schwellenwert, der lang genug ist, um das Wochenende zu überstehen, wird einen Ausfall am Dienstagmorgen erst am Dienstagnachmittag bemerken.

Es gibt keine einzige Zahl, die beides ist. Das ist kein Anpassungsproblem; es ist, dass die Frage „hat dieser Feed aufgehört“ nicht durch eine Konstante beantwortet werden kann, wenn der normale Datenverkehr um einen Faktor von hundert über die Woche variiert.

11.3 Rhythmus-erkannte Erkennung

below-rhythm vergleicht den aktuellen Datenverkehr mit dem, was dieser Kanal normalerweise in dieser Stunde dieses Tages der Woche tut.

Perfuse lernt die Woche jedes Kanals aus seiner eigenen Aufzeichnungsgeschichte: 168 stündliche Buckets, beginnend mit Montag, so dass eine Arbeitswoche zusammenhängend ist. Für jeden Bucket hält es einen Median, ein Minimum und ein Maximum, einen Boden und wie viele Beobachtungen es basiert auf.

Der Schwellenwert ist ein Anteil des Normalwertes und beträgt standardmäßig 0.8 (80 Prozent in der Konsole) – eine Warnung wird ausgelöst, wenn der Datenverkehr unter vier Fünftel des Normalwertes für diese Stunde fällt.

11.3.1 Median, nicht Mittelwert

Ein einzelner Rückstau von vierzigtausend Nachrichten gegen einen normalen Wert von dreihundert verschiebt den Mittelwert weit genug, dass der Feed völlig stillsteht, ohne jemals unter ihn zu fallen. Der Median bleibt unverändert durch eine außergewöhnliche Stunde, was genau die erforderliche Eigenschaft ist.

11.3.2 Der Boden ist ein Perzentil, nicht das Minimum

Ob der Rhythmus eines Kanals zuverlässig genug ist, um eine Benachrichtigung auszulösen, wird durch sein unteres Ende und nicht durch sein oberes Ende entschieden. Eine Benachrichtigung über einen Engpass wird ausgelöst, wenn der Datenverkehr *niedrig* ist, also kann nur das untere Ende bestimmen, ob es falsche Positives produziert. Eine frühere Version davon verglich das Maximum mit dem Median und hatte es in beiden Richtungen gleichzeitig falsch: es disqualifizierte einen perfekt stabilen Feed für einen Monat nach einem Rückstau und akzeptierte einen tatsächlich unregelmäßigen Feed, der zwischen zwei- und neunhundert Nachrichten in der gleichen Stunde schwankte, weil sein Maximum nur drei Mal so hoch war wie sein Median.

Der Boden ist der zwanzigste Perzentil und nicht das Minimum, da das Minimum durch einen einzelnen Feiertag auf Null gezogen wird. Und das Perzentil wird nicht interpoliert - jede Zahl in einer Warnung um zwei Uhr morgens sollte eine Zählung sein, die die Feed tatsächlich produziert hat, und nicht ein Durchschnitt von zwei Zählungen, die sie nicht produziert hat.

11.3.3 Es wird angezeigt, wenn es nicht sagen kann

Ein Kanal mit keiner Geschichte wird vollständig weggelassen, anstatt als einer behandelt zu werden, der gestoppt wurde. Ein neuer Kanal darf nicht wie ein defekter aussehen.

Wo die Geschichte zu dünn oder zu unregelmäßig ist, um ein Urteil zu unterstützen, lehnt die Regel es ab, zu feuern, anstatt zu raten. „Ich kann ehrlich nicht sagen“ ist eine erste-Klasse-Antwort hier und wird bevorzugt gegenüber einer Warnung, die slightly öfter richtig ist als Zufall.

Fehlende Stunden innerhalb des Lernfensters werden als echte Nullen aufgezeichnet, nicht als fehlende Daten. Die Hälfte des Signals in einem Klinik-Feed ist *wann es legitim still ist*, und die Behandlung dieser Stunden als unbekannt würde es wegwerfen.

11.4 Warnungen einrichten

Über die Schnittstelle, unter Alerts, pro Kanal oder über alle hinweg. Jede Regel hat eine Art, einen Schwellenwert und einen Ort, an den die Warnung gesendet wird. Die Regeln werden in alerts.yaml neben der Datenbank (oder der Datei -alerts genannt) gespeichert und treten sofort in Kraft; bis zum ersten Speichern gelten die integrierten Regeln. Die Datei kann auch manuell bearbeitet werden: Die Änderung wird innerhalb von dreißig Sekunden übernommen, und eine Datei, die nicht mehr geladen werden kann, wird im Log gemeldet und die geltenden Regeln bleiben bestehen.

Es lohnt sich, dies vor einem Live-Gang eines Feeds zu tun, anstatt nach dem ersten Vorfall.

  1. below-rhythm — der Feed ist still geworden, obwohl er nicht still sein sollte.
  2. error-rate — Nachrichten werden empfangen und fehlschlagen.
  3. queue-age — etwas ist stecken geblieben, anstatt nur beschäftigt zu sein.
  4. channel-down — der Kanal läuft überhaupt nicht.

Die erste ist die, die den Ausfall fängt, den niemand anders melden wird.

11.5 Überwachung des Zugriffs auf Patientendaten

Ein Verstoß meldet sich selten selbst. Es sieht aus wie ein Feed, der mehr als üblich transportiert, Datenverkehr um drei Uhr morgens auf einem Kanal, der nur Bürozeiten arbeitet, ein Ziel, das niemand eingerichtet hat, oder eine Person, die Patientenakte nach Patientenakte öffnet. Perfuse überwacht diese vier, standardmäßig aktiviert (serve -watch-access=false deaktiviert es), und meldet, was es sieht, durch die Warnregeln oben, sodass es konfiguriert, bestätigt und wie jede andere Warnung zugestellt wird.

Ein Kanal wird nicht beurteilt, bis er 200 Nachrichten transportiert hat, da "unüblich" nichts bedeutet, ohne ein Muster. Das Muster wird aus den letzten 14 Tagen der Nachrichtenspeicherung gelernt, wenn der Server startet, sodass ein Neustart jeden Kanal nicht erneut zum Neuen macht. Alles, was gesehen wird, wird für 15 Minuten gespeichert, dann löscht sich die Warnung selbst.

Es beobachtet und meldet nur. Es hält niemals eine Nachricht auf oder verweigert ein Lesen: dies sind Heuristiken, und ein Feed, der wegen einer falschen Vermutung angehalten wird, ist ein klinisches Problem. Jede Warnung sagt, was gesehen wurde und was es harmlos sein könnte, da die meisten von ihnen harmlos sein werden.

Administratoren sehen, was der Monitor gelernt hat, auf dem Bildschirm "Warnungen", unter Zugriff auf Patientendaten überwachen: das Muster jedes Kanals (noch im Lernen, nur tagsüber oder Tag und Nacht), wie viele Ziele es kennt und alles, was in den letzten 15 Minuten gesehen wurde, einschließlich dessen, was unter dem Schwellenwert einer Regel liegt.

11.6 Wohin Warnungen gehen

Warnungen können als JSON an einen Webhook (-alert-webhook: Slack, Teams, Mattermost, PagerDuty, Alertmanager oder alles, was einen POST akzeptiert) gesendet, als SNMPv2-Fallen an SNMP-Manager (-snmp-traps, siehe SNMP) gesendet oder im Protokoll für einen Sammler geschrieben werden. Es gibt keine eigene E-Mail-Lieferung: Richten Sie den Webhook auf einen Relay aus, wenn Warnungen als E-Mail ankommen müssen.

Eine Warnung, die nur in ein Log geschrieben wird, das niemand liest, ist keine Warnung. Wenn Perfuse das einzige ist, das einen gestoppten Feed bemerken wird, muss die Warnung eine Person erreichen.

12 Der Nachrichtenspeicher

Jede Nachricht, die Perfuse erhält, wird aufgezeichnet, wie sie empfangen wurde, bevor sie modifiziert wird. Ebenso wird aufgezeichnet, was an jeden Empfänger gesendet wurde und was damit passierte. Der Speicher ist eine SQLite-Datei, die durch -db angegeben wird.

12.1 Was aufbewahrt wird

Pro Nachricht: die rohen Bytes, wie sie ankamen, wann sie ankamen, welcher Kanal, die analysierte Nachrichtentyp und Trigger-Ereignis und das Filterergebnis.

Pro Empfänger pro Nachricht: die Bytes, die gesendet wurden, das Ergebnis, die Zeit, die benötigt wurde, und jeder Fehler oder negative Bestätigung, die empfangen wurde.

Dies ist die Form, die eine Untersuchung benötigt. „Was haben sie uns gesendet“, „was haben wir ihnen gesendet“ und „was haben sie darüber gesagt“ sind drei verschiedene Fragen und jede von ihnen wird gestellt.

12.2 Suchen

Nach Kanal, nach Zeitraum, nach Ergebnis, nach Nachrichtentyp und Trigger-Ereignis und nach Feldwert.

Feldsuche funktioniert auf der analysierten Nachricht, sodass die Suche nach einer Aufzeichnungsnummer sie findet, wo immer in der Nachricht dieses Feld lebt, anstatt die Ziffern irgendwo im Text zu entsprechen. Eine Textsuche nach 12345 in einer Nachricht, die eine Menge von 12345 enthält, findet eine Nachricht, die nichts mit dem Patienten zu tun hat, den Sie suchen.

12.3 Wiedergabe und erneute Verarbeitung

Weil das Original aufbewahrt wird, kann eine Nachricht durch die aktuelle Konfiguration erneut ausgeführt werden.

Trace nimmt eine aufgezeichnete Nachricht und zeigt, was der Kanal damit machen würde, ohne etwas zu senden. Im Abschnitt Debugging behandelt.

Neuverarbeiten führt es tatsächlich erneut aus, einschließlich der Zustellung. Dies behebt eine Charge von Nachrichten, die aufgrund einer falschen Konfiguration des Ziels fehlgeschlagen sind: Korrigieren Sie die Konfiguration, wählen Sie die betroffenen Nachrichten aus und verarbeiten Sie sie erneut.

Neuverarbeiten liefert erneut aus. Wenn die Nachrichten beim ersten Mal teilweise erfolgreich waren, wird die Neuverarbeitung Duplikate an den Zielen erzeugen, die sie bereits erhalten haben. Perfuse protokolliert, welche Ziele erfolgreich waren, sodass die Neuverarbeitung auf diejenigen beschränkt werden kann, die fehlgeschlagen sind - tun Sie dies, anstatt alles neu zu verarbeiten, es sei denn, das empfangende System entfernt Duplikate anhand der Nachrichtensteuerungs-ID.

12.4 Veraltetheit

Eine Spur einer alten Nachricht gegen die aktuelle Konfiguration beantwortet eine hypothetische Frage: was *würde* jetzt passieren. Das ist normalerweise das, was Sie wollen, aber nicht immer - wenn Sie untersuchen, was letzten Dienstag schiefgelaufen ist, kann der Kanal sich seitdem geändert haben.

Perfuse erkennt dies und teilt es mit. Eine Spur einer Nachricht, die vor der letzten Bearbeitung des Kanals eingetroffen ist, wird als solche markiert, damit die Antwort nicht mit einer Rekonstruktion dessen verwechselt wird, was tatsächlich passiert ist.

12.5 Aufbewahrung

Der Speicher wächst. cleanup.periodDays steuert, wie lange Nachrichten aufbewahrt werden.

Zwei Dinge, die abgewogen werden müssen. Klinische Nachrichten können unter Aufbewahrungsanforderungen fallen, die länger sind als alles, was Sie aus betrieblichen Gründen wählen würden, und der Speicher ist nicht das System der Aufzeichnungen - das empfangende System ist es. Die Kopie von Perfuse dient zur Diagnose und zur Neuverarbeitung, und beide Bedürfnisse fallen nach einigen Wochen stark ab.

Die Aufbewahrung entscheidet auch, wie viel Geschichte der Rhythmus-Lerner zur Verfügung hat. Siehe Alerting: Ein Aufbewahrungszeitfenster, das kürzer als einige Wochen ist, lässt es nicht zu, zwischen einem stillen Sonntag und einem gestoppten Feed zu unterscheiden.

12.6 Der Speicher enthält klinische Daten

Dies ist der Teil von Perfuse, der Patienteninformationen enthält, und er sollte entsprechend behandelt werden: auf verschlüsseltem Speicher, als klinische Daten gesichert und zugriffsbeschränkt. Siehe Sicherheit.

Die generierten Testnachrichten, die in Testing beschrieben werden, existieren teilweise, damit diese Daten nicht aus der Umgebung entfernt werden müssen, um ein Problem an anderer Stelle zu reproduzieren.

13 Fehlerbehebung

Die Frage ist fast immer dieselbe: Diese Nachricht kam herein, etwas Falsches ging heraus, wo hat sie sich geändert? Perfuse beantwortet sie, indem sie eine aufgezeichnete Nachricht durch die aktuelle Konfiguration abspielt und jeden Schritt zeigt.

Nichts wird gesendet, während die Nachverfolgung durchgeführt wird. Der Kanal läuft unberührt weiter, und keine Neukonfiguration ist erforderlich.

13.1 Nachverfolgung einer Nachricht

Wählen Sie eine aufgezeichnete Nachricht aus und verfolgen Sie sie nach. Das Ergebnis zeigt in der Reihenfolge:

13.2 Schritt für Schritt

Die Schritt-für-Schritt-Ansicht führt jede Transformation einzeln aus und erstellt ein Snapshot der gesamten Nachricht nach jeder Transformation. Eine nummerierte Leiste mit Schritten, farblich nach dem Ergebnis gekennzeichnet, und die Nachricht, wie sie nach jedem Schritt aussah.

Die gesamte Nachricht anstelle nur der Änderung, weil die Änderung oft nicht der Punkt ist, an dem das Problem liegt - ein Schritt, der das Feld, auf das er abzielte, korrekt geändert hat, auf einer Nachricht, bei der ein früherer Schritt bereits das Falsche dort platziert hat, sieht in Isolation perfekt korrekt aus.

13.3 Vier Ergebnisse und die Unterscheidung, die zählt

ErgebnisBedeutung
changedDer Schritt wurde ausgeführt und hat die Nachricht modifiziert.
no-effectDer Schritt wurde ausgeführt, und die Nachricht ist unverändert.
skippedDie when-Bedingung des Schritts war falsch, daher wurde er nicht ausgeführt.
failedDer Schritt ist fehlgeschlagen.

no-effect und skipped werden separat gemeldet, und dies ist der Sinn der gesamten Funktion.

Von außen sind sie identisch: die Nachricht ist danach auf beide Weise dieselbe. Sie bedeuten jedoch entgegengesetzte Dinge. skipped bedeutet, dass die Bedingung wie geschrieben funktioniert hat und diese Nachricht nicht eine war, auf die sie angewendet wurde — normalerweise korrekt. no-effect bedeutet, dass der Schritt ausgeführt und nichts zu tun gefunden wurde, was normalerweise bedeutet, dass er auf ein Feld abzielt, das nicht vorhanden ist.

Ein Motor, der sowohl als "nichts ist passiert" meldet, lässt Sie nicht erkennen, ob ein funktionierender bedingter Pfad oder ein fehlerhafter Pfad vorliegt, und das ist der häufigste Transformationfehler, der existiert.

Ein Schritt, der bei jeder Nachricht no-effect meldet, ist fast immer ein falscher Weg. Der Schrittzähler im Header zeigt, wie viele Schritte nichts gefunden haben, was der schnellste Weg ist, um dies zu erkennen: Ein Kanal mit drei Schritten und drei no-effect-Ergebnissen transformiert überhaupt nichts.

13.4 Testen einer Änderung vor dem Speichern

Der Builder kann eine Kandidatenkonfiguration gegen aufgezeichneten Datenverkehr ausführen und melden, was sich unterscheiden würde. Dies ist der sicherste Weg, um einen Live-Kanal zu ändern: Führen Sie die Bearbeitung durch, sehen Sie, was sie mit den letzten paar hundert echten Nachrichten macht, und speichern Sie sie dann.

Es ist auch der Weg, um herauszufinden, dass eine Änderung, die offensichtlich korrekt aussieht, Nachrichten beeinflusst, an die Sie nicht gedacht haben - ein Schritt, der auf einem Trigger-Ereignis bedingt ist, in einer Feed, die sich als vier tragend erweist.

13.5 Was die Nachverfolgung nicht sagen kann

Sie führt die aktuelle Konfiguration aus. Wenn der Kanal seit dem Eintreffen der Nachricht bearbeitet wurde, ist die Nachverfolgung hypothetisch und nicht eine Rekonstruktion, und Perfuse markiert sie als solche, anstatt den Unterschied stillschweigend zu übergehen.

Sie übt auch den Transport nicht aus. Eine Nachverfolgung zeigt, was gesendet werden würde, nicht, ob das Ziel sie akzeptieren würde - eine Nachricht, die korrekt ist, und ein Ziel, das Verbindungen ablehnt, erzeugen eine saubere Nachverfolgung und eine fehlgeschlagene Lieferung. Diese sind im Lieferverzeichnis sichtbar.

13.6 Skripte

Ein Skript ist ein undurchsichtiger Schritt in der Nachverfolgung. Perfuse kann zeigen, was hereingekommen ist und was herausgekommen ist, und kann nicht zeigen, was dazwischen passiert ist oder welche Felder gelesen wurden.

Dies ist der konkrete Kosten des Einsatzes eines Skripts anstelle von deklarativem Schritten, und es lohnt sich, dies abzuwägen, wenn Sie eine Wahl treffen. Siehe Transformation.

14 Testen

Die Standard-Empfehlung für das Testen einer Schnittstelle besteht darin, Beispielnachrichten zu erstellen, die Ihre eigene Umgebung widerspiegeln - die Codes Ihres Labors, Ihre Fallmischung, die Gewohnheiten Ihres Absenders - und die Patientendaten von Hand zu entfernen. Das ist langsam, und unvollständig zu tun, ist das normale Ergebnis.

Perfuse bietet stattdessen drei Dinge an: generierten Datenverkehr, der der Form einer Feed entspricht, ohne deren Inhalt, einen vorgeschlagenen Kanal aus einer Beispielnachricht, die jemand Ihnen geschickt hat, und einen Vergleich mit dem Motor, den Sie ersetzen.

14.1 Generierter Testdatenverkehr

Wenn ein Kanal Nachrichten bearbeitet hat, kann Perfuse weitere Nachrichten wie diese erzeugen.

Was treu ist:

Was nicht treu ist und dies ausdrücklich und nicht implizit ist: klinische Kohärenz. Eine generierte Patientin hat eine nicht verwandte Aktennummer, einen namenförmigen String und eine Diagnose, die keine Beziehung zur Beobachtung hat. Diese Nachrichten üben eine Schnittstelle aus. Sie sind kein klinisches Testset und können nicht zur Validierung klinischer Logik verwendet werden.

14.1.1 Warum sie keine echten Daten enthält

Das Argument ist strukturell und nicht ein Anspruch über den Aufwand. Die einzige Eingabe des Generators ist das Verkehrsprofil des Kanals, und ein Profil enthält Füllraten, Formen, Längen, Wiederholungszahlen und Segmenthäufigkeiten. Es enthält keine Werte.

Die einzige Ausnahme sind Code-Tabellenfelder, und ein Code identifiziert niemanden.

Dies ist eine stärkere Garantie als die Anonymisierung echter Nachrichten, was ein Prozess ist, der unvollständig durchgeführt werden kann und normalerweise auch ist. Hier gibt es keinen Weg, auf dem ein Name das Ausgabeformat erreichen könnte, weil der Name nie in der Eingabe war.

Jede generierte Nachricht wird vor ihrer Rückgabe analysiert - ein nicht analysierbarer Korpus würde jemanden dazu bringen, nach einem Fehler in ihrer Schnittstelle zu suchen, der tatsächlich ein Fehler des Generators ist - und jede wird mit T in MSH-11 markiert, mit einem absichtlich synthetischen sendenden Anwendung und Einrichtung.

Eine Testnachricht, die nicht als solche markiert ist, wird schließlich in einem Produktivsystem von jemandem gefunden, der keine Möglichkeit hat, zu wissen, dass sie nicht echt war. Das T und der synthetische Absender sind nicht kosmetisch.

14.2 Erstellen eines Kanals aus einer Beispielnachricht

Fügen Sie die Nachricht ein, die ein Labor, ein Krankenhaus oder ein Lieferant Ihnen per E-Mail geschickt hat, und Perfuse schlägt einen Kanal dafür vor. Es muss nichts im Voraus ausgeführt werden.

Es bearbeitet, was die Menschen tatsächlich einfügen: mehrere Nachrichten in einem Block, beliebige Zeilenenden, MLLP-Rahmung, die die Kopie überstanden hat, und die Decknotiz über der Nachricht. Die Ablehnung einer Probe, weil sie mit Windows-Zeilenenden angekommen ist, wäre ein Hindernis und kein Check.

14.2.1 Drei Listen

Das Angebot kommt mit dem, was die Probe zeigt, was erraten wurde und was die Probe nicht sagen kann — drei separate Listen, die in der Oberfläche gleich gewichtet sind.

Sie sind getrennt, weil ein Leser, der nicht erkennen kann, welches welches ist, alles überprüfen oder alles vertrauen muss, und beides ist schlimmer als zu wissen, wo man suchen muss.

Aus einer einzelnen Nachricht werden die Grenzen spezifisch benannt, anstatt allgemein: welche Felder optional sind, welche Segmente sich wiederholen, welche Codes jenseits der hier vorhandenen existieren, ob der Absender jemals ein anderes Trigger-Ereignis sendet. Eine allgemeine Vorsicht ist etwas, das die Menschen überlesen.

Vertrauen ist ein Wort — niedrig, moderat, vernünftig — nie ein Prozentsatz. Ein Prozentsatz impliziert eine Berechnung, und dies ist eine Beurteilung darüber, wie viele Proben es gibt.

Z-Segmente werden namentlich genannt, weil ein lokales Segment das ist, was keine Spezifikation erwähnt, und der häufigste Grund, warum ein Kanal, der aus einer Standardvorlage erstellt wurde, nicht funktioniert.

14.2.2 Die Trennerwarnung

Wenn der Feldtrenner der Probe nicht der übliche | ist, erscheint dies zuerst, und das Vertrauen sinkt auf niedrig.

Der Grund ist ein echtes stilles Versagen. HL7 nimmt seinen Feldtrenner aus der Nachricht selbst, sodass eine Probe, deren Pipes durch typografische Ähnlichkeiten ersetzt wurden — was ein Textverarbeitungsprogramm tut —, perfekt in Felder parsen kann, die alle falsch sind. Nirgendwo tritt ein Fehler auf.

Die Ablehnung einer solchen Probe wäre falsch, weil ein Absender legitimerweise einen anderen Trenner verwenden kann. Es wird also gekennzeichnet, der Charakter wird benannt, und es wird vorgeschlagen, eine einfache Textanlage zu fordern.

14.3 Vergleichen mit dem alten Motor

Bevor ein Live-Feed verschoben wird, ist die Frage, ob Perfuse die gleiche Ausgabe wie das erzeugt, was jahrelang ausgeführt wurde. Keine Menge an Designqualität beantwortet das. Siehe Migration.

14.4 Überprüfen gegen die reale Sache, in Containern

Drei Checks werden gegen reale Implementierungen und nicht gegen die eigene Vorstellung von Perfuse von einem Protokoll ausgeführt. Sie leben außerhalb von make check, weil sie eine Container-Laufzeit benötigen, und ein Check, der Docker benötigt, ist ein Check, den die Leute aufhören auszuführen.

scripts/interop-up.sh startet alle davon und gibt aus, was jeder entsperrt.

ContainerChecksWas es gefunden hat
Keycloak 26web/e2e-saml/, und internal/saml-FixturesEin Defekt. Die kanonische Form, die eine Signatur abdeckt, wurde mit Namespace-Präfixen berechnet, die weggelassen wurden, sodass kein echter Identitätsanbieter jemals jemanden hätte anmelden können
Microsoft Entrainternal/saml-Live-Tests und -FixturesZwei Defekte, beide in dem, was das Protokoll umgibt. Ein Konto wurde unter Entras undurchsichtigem NameID erstellt, weil die logik für lesbare Namen eine E-Mail-Behauptung wollte und Entra keine sendet. Und ein SAML-Konto wurde als OIDC aufgezeichnet, weil der Store das Protokoll aus einem Aussteller ableitete, der für beide identisch aussieht
HAPI FHIRgo test ./internal/engine/ -run HAPIEin Defekt. Eine nicht zugeordnete Zuweisungsbehörde produzierte ein Identifikationssystem, das eine OID ankündigte und ein Wort trug, das HAPI ohne Beschwerde akzeptierte
ActiveMQgo test ./internal/engine/ -run RealBrokerKorrekt, einschließlich des Nullbyte-Rahmenfalls. Behauptet durch die Verwaltungsschnittstelle des Brokers selbst und nicht durch eine Funktion, die nil zurückgibt
nginx, Clientzertifikatego test ./internal/engine/ -run ClientCertificateKorrekt
Orthanc (ein echter PACS)go test ./internal/engine/ -run RealPACSKorrekt. Ein C-STORE arrives und der Patientenname, -identifikator, Studiendatum, Modalität und SOP-Klasse überleben alle
PostgreSQLgo test ./internal/engine/ -run RealPostgresKorrekt, und es hat zu einem besseren Fehler geführt: eine Anweisung in den Platzhaltern der falschen Dialekte wird jetzt abgelehnt, wenn sie gespeichert wird, anstatt zu einem Syntaxfehler auf dem Server zu werden, wenn eine Nachricht ankommt
OpenSSH sftp-Servergo test ./internal/engine/ -run OpenSSHServerKorrekt. Die bestehenden SFTP-Tests verwenden die gleiche Go-Bibliothek auf beiden Enden; OpenSSH ist eine andere Implementierung und die auf dem anderen Ende fast jedes echten Feeds
Mirth 4.5.2go test ./internal/mirth/ -run RealMirthKorrekt jetzt. Das einzige Fixture wurde früher von Hand geschrieben und Mirth würde es nicht laden; scripts/mirth-author-channel.sh hat Mirth dazu gebracht, einen Kanal zu erstellen, und Perfuse liest ihn

Jeder davon überspringt anstatt auszufallen, wenn sein Container fehlt, sodass make check auf einem Computer mit keinem Docker durchläuft.

Warum dies getrennt von dem Rest des Suites ist. Jeder andere Test dieser Funktionen hatte beide Hälften hier geschrieben: ein Dokument, das dieser Codebasis unterzeichnet wurde, von dem Code gelesen, der es unterzeichnet hat. Das ist eine Übereinstimmung mit sich selbst, und es ist weniger wert, als es erscheint.

Der SAML-Kanonisierer ist der Fall, der den Punkt beweist. Er trug tausend Zeilen an Tests, fünf davon speziell über die Kanonisierung, und alle davon bestanden, während kein echter Identitätsanbieter jemals jemanden hätte anmelden können — die kanonische Form, die eine Signatur abdeckt, wurde mit Namespace-Präfixen berechnet, die weggelassen wurden, und der einzige Weg, dies zu finden, war, ihm ein Dokument zu übergeben, das Perfuse nicht geschrieben hatte.

Zwei der acht Prüfungen haben Mängel direkt gefunden, und eine dritte hat eine echte Verbesserung ausgelöst. Drei haben nichts falsch gefunden. Dieses Verhältnis ist das Argument dafür, alle beizubehalten: Eine Prüfung, die bestanden wird, hat Ihnen etwas mitgeteilt, was Sie sonst nicht hätten wissen können, und es gab keine Möglichkeit, im Voraus zu bestimmen, welche davon es sein würden.

Ein Muster, das erwähnenswert ist, weil es in beiden Mängeln auftrat: Akzeptanz ist nicht Verifizierung. HAPI akzeptierte das fehlerhafte Identifikationssystem und speicherte es; der Mangel erschien erst beim Lesen der Ressource. Ein Empfänger, der etwas toleriert, ist kein Beweis dafür, dass es richtig ist, sondern nur, dass dieser Empfänger nachsichtig war.

Zwei erfasste Behauptungen sind committet, bei internal/saml/testdata/keycloak-assertion.xml und entra-response.xml, mit Tests über beide — damit wird diese spezifische Regression ohne Container erfasst.

Beide sind erforderlich und nicht nur ein Ersatz. Keycloak fügt seiner Behauptung und Signatur ein Präfix hinzu, Entra nicht, und diese sind die beiden entgegengesetzten Fälle bei der Kanonisierung — genau dort, wo der Mangel war. Ein Test behauptet, dass jedes Dokument immer noch seinen eigenen Fall abdeckt, weil ein Ersatz, der zufällig ein Präfix hatte, die Abdeckung stillschweigend halbieren würde, ohne etwas zu fehlschlagen. Die allgemeine Lektion verallgemeinert sich nicht so billig: Für alles andere ist der Container die Prüfung.

14.5 Diagnose eines Tests, der einmal fehlschlägt und nie wieder

Ein Test, der in einem vollständigen Lauf fehlschlägt und allein 16 Mal bestanden wird, ist kein fehlerhafter Test. Es ist ein Test, der etwas mit dem Lauf gemeinsam hat, und die Art, es herauszufinden, besteht darin, die gemeinsame Sache zu messen, anstatt den Test.

Zwei Instrumente existieren dafür, und beide sollen während eines vollständigen Testlaufs ausgeführt werden:

./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

Jedes entdeckt die Ports des Laufs aus der eigenen Zustandsdatei der Einrichtung und sampelt alle 500 Millisekunden, bis der Server beendet wird. Sie protokollieren jedes Sample und nicht nur die Fehler, was sie nützlich macht: Ein kleiner Ausschlag zeigt sich in einem Lauf, in dem nichts fehlgeschlagen ist, so dass ein Fehler, der einmal in drei Läufen auftritt, in jedem messbar wird.

Setzen Sie PERFUSE_E2E_KEEP=1, um das temporäre Verzeichnis zu behalten, das die Datenbank enthält, wie sie zurückgelassen wurde, und die Server-Logdatei für den gesamten Lauf. Die Server-Logdatei ist normalerweise die Antwort. In einem untersuchten Fall hat sie aufgezeichnet, dass ein Kanal gestoppt und sein Listener 421 Millisekunden später neu gebunden wurde, und die Ablehnung der Verbindung des Probes fiel in dieses Zeitfenster.

Lesen Sie die Spur anstelle von error-context.md, die bei mehr als einer Gelegenheit leer war, wo die Spur die eigentliche Meldung enthielt.

Kopieren Sie die Artefakte vor dem erneuten Ausführen von etwas. Ein erfolgreicher Lauf löscht test-results, so dass die Spur des Fehlers, den Sie untersuchen, verschwindet, sobald Sie versuchen, ihn zu reproduzieren. Sobald verloren, kann die Frage, die sie beantworten würde, nicht beantwortet werden.

Stoppen Sie die Interop-Container zuerst. Stoppen Sie sie vor einem vollständigen Browser-Lauf und starten Sie sie mit ./scripts/interop-up.sh danach, wenn Sie sie immer noch benötigen.

Acht Container halten etwa 9,8 GB Speicher, und auf einem Computer mit nicht viel mehr als das gibt es zu wenig für die Prozesse von Chromium, Node und der Go-Toolchain zusammen. Was es produziert, ist kein Out-of-Memory-Fehler, sondern ein Renderer, der aufhört, geplant zu werden: Eine aufgezeichnete Spur zeigt eine 60,2-Sekunden-Lücke mit keinen Frames, während Playwright auf eine Schaltfläche wartete, die "sichtbar, aktiviert und stabil" wurde, und nicht zwei aufeinanderfolgende Animationsframes zum Vergleich erhalten konnte. Der Server war während des gesamten Laufs gesund, die langsamste Anfrage im gesamten Lauf betrug 154 Millisekunden.

Dieser Fehler liest sich wie ein Mangel in dem Test, der zufällig ausgeführt wurde. Es lohnt sich, die Form davon zu kennen: Jede Anfrage schnell, die Seite visuell eingefroren, die Wiederholungsschleife erreicht nie eine zweite Iteration, und das Ganze wird in Isolation bestanden.

Nur ein Lauf gleichzeitig. Der Testlauf teilt einen Server, eine angemeldete Sitzung in web/e2e/.auth/admin.json und eine Zustandsdatei, die den Serverprozess benennt. Keines davon ist pro-Lauffähig, so dass ein zweiter Lauf, der während des ersten startet, die Zustandsdatei überschreibt, und welcher Teardown zuerst beendet wird, den Server des anderen Laufs tötet und dessen Sitzung löscht.

What that looks like is nothing like the cause. It produced a run of 279 failures whose first message was ENOENT: no such file or directory, open './e2e/.auth/admin.json', a run that stopped early reporting 217 passed, and two tests failing with bind: address already in use — none of which suggest two runs fighting. The suite now takes a lock and refuses to start, naming the process that holds it. A lock left by an interrupted run is taken over rather than blocking for ever, because a safety measure that wedges the suite is one somebody deletes along with the safety.

Eine verwandte Falle, die jetzt behoben ist: Zwei Spezifikationen benannten ihre Listener-Ports direkt, so dass ein Server, der von einem unterbrochenen Lauf zurückgelassen wurde, sie zum Scheitern brachte, weil sie nichts mit dem zu tun hatten. Ports werden jetzt vom Betriebssystem angefordert.

Beantworten Sie nichts davon mit Wiederholungen. Ein Test, der beim zweiten Versuch bestanden wird, hat eine echte Rennsituation gefunden und versteckt sie, und playwright.config.ts setzt retries: 0 aus diesem Grund.

Eine Vorsicht: Das Sammeln aller 100 Millisekunden spawnete zwanzig Prozesse pro Sekunde, dehnte einen Lauf um die Hälfte und ließ zwei Tests aufgrund von Timeouts fehlschlagen, die nichts falsch hatten. Ein Instrument, das das misst, was es ändert, produziert Ergebnisse über sich selbst.

14.6 Was immer noch reale Infrastruktur benötigt

Mehrere Teile von Perfuse sind implementiert und wurden noch nie gegen die Realität getestet. Sie werden hier aufgelistet, anstatt sie zufällig zu entdecken:

Die Funktionen in diesem Kapitel und dem nächsten existieren, damit Sie Ihre eigenen Beweise sammeln können, anstatt dem Wort eines anderen zu glauben.

14.7 Gemessen an öffentlichen Konformitätscorpora

Ein Test-Set, dessen Fixtures hier geschrieben wurden, beweist die Übereinstimmung mit sich selbst. Diese sind die Daten anderer Leute.

14.7.1 FHIR R4, die eigenen Beispiele der Spezifikation

Alle 2.912 Beispiel-Dateien, die mit der FHIR-R4-Spezifikation veröffentlicht wurden - jedes Beispiel, das die Autoren des Standards geschrieben haben.

ErgebnisAnzahl
Ressourcen, die mit keinen Ergebnissen validiert wurden13.723
Ressourcen, die als ungültig gemeldet wurden0
Dateien, die als unimplementierter Ressourcentyp abgelehnt wurden753
Bundle-Einträge, die als unimplementierter Typ übersprungen wurden1.348

Keine Ressource wurde falsch validiert. Jeder Fehler ist eine explizite Ablehnung, die den Typ nennt, den sie nicht lesen kann - 672 ValueSet, 80 ConceptMap und ein Parameters. Ein Validator, der stillschweigend akzeptiert, was er nicht versteht, ist schlimmer als einer, der es sagt.

Der Korpus fand einen Defekt, der der Grund für den Lauf ist. Die Validierung eines Bundles druckte "Bundle-Validierung aus einer Datei wird noch nicht unterstützt" und fuhr fort. Das war in beiden Richtungen falsch: Bundles, deren Einträge zufällig Typen waren, die der Parser halten konnte, wurden bereits validiert, und ein Bundle, das tatsächlich ungültig war, produzierte die gleiche Zeile, zählte nichts und beendete sich mit Null - einschließlich unter -strict, das existiert, um dies zu verhindern. Zweiundvierzig der Bundles der Spezifikation selbst wurden übersprungen.

Bundles werden jetzt Eintrag für Eintrag validiert, mit drei Ergebnissen, die auseinander gehalten werden: Ein Eintrag, der falsch ist, schlägt fehl und nennt das Feld, ein Eintrag eines Typs, den dieser Build nicht lesen kann, wird als übersprungen gezählt und gemeldet, und ein Bundle, das keine Ressourcenkörper enthält, wird nicht gezählt. Der gleiche Korpus ging von 2.100 geprüften Ressourcen auf 13.723.

14.7.2 HL7 v2, das HAPI-Test-Corpus

Die Nachrichten-Fixtures von HAPI, der Referenz-Java-HL7-v2-Implementierung - absichtlich schwieriges Material, einschließlich uuencodierter Payloads, escaped Delimiter und wiederholter Gruppen.

59 Nachrichten, 59 geparst, nichts abgelehnt. Sieben Nachrichtentypen in einem Korpus, das jedes einzelne System als eine Sache beschreiben würde, was der Punkt ist, zu dem perfuse profile existiert.

14.7.3 Was noch nicht ausgeführt wurde

DICOM gegen ein öffentliches Konformitätssatz und X12 gegen ein veröffentlichtes Korpus. Keines davon wurde gemacht, und keines davon sollte aus den beiden oben genannten abgeleitet werden.

15 Migration von Mirth

Zwei Dinge sind erforderlich, um einen funktionierenden Motor zu ersetzen: die Kanäle müssen übernommen werden, und jemand muss in der Lage sein, zu zeigen, dass der Ersatz den gleichen Ausgang produziert. Perfuse macht das Erste, indem es Mirths eigene Exporte importiert, und das Zweite, indem es die beiden Motoren auf Ihrem eigenen Verkehr vergleicht.

Alles in diesem Kapitel gilt gleichermaßen für die Open Integration Engine und BridgeLink. Mirth Connect hörte auf, Open-Source zu sein, bei 4.6 im März 2025; OIE (gehostet von der Eclipse Foundation) und BridgeLink (Innovar Healthcare) sind die Forks, die die Open-Source-Linie fortsetzen, und beide schreiben die gleichen Exportformate. Der Importer wird gegen alle drei getestet, unten.

15.1 Importieren von Kanälen

Perfuse liest jeden Export, den diese Motoren schreiben:

ExportAus dem AdministratorWas übernommen wird
Ein KanalExport ChannelDer Kanal
Eine KanalgruppeExport GroupJeder Kanal in ihr, jeder behält die Gruppe
Code-VorlagenExport Code TemplatesJede Bibliothek als eine Skriptdatei
Ein Server-BackupBackup Config, oder GET /api/server/configurationAlle oben genannten auf einmal

Zeigen Sie perfuse translate auf einen davon, oder legen Sie einen auf Administer → Migrate:

perfuse translate -o ./channels server-backup.xml

Eine Code-Bibliothek wird zu lib/<library>.js neben den Kanälen, und jeder Kanal, für den Mirth die Bibliothek aktiviert hatte, erhält scripts.include: [lib/<library>.js] — damit ein Transformer, der eine Site-Funktion wie formatMRN() aufruft, diese immer noch findet. Ein Kanal, für den die Bibliothek nicht aktiviert war, enthält sie nicht, da seine Skripte sie in Mirth nicht sehen konnten. Drag-and-drop-Snippets werden ausgelassen: Mirth fügt diese nur manuell in einen Schritt ein, sodass sie nicht als eigenständiger Code ausgeführt werden. Im Browser werden die Bibliotheken, die ein Kanal enthält, beim Importieren des Kanals zuerst gespeichert.

Ein Channel Writer benennt den Kanal, an den er liefert, durch seine ID. In einer Gruppe oder einem Backup befindet sich das Ziel im gleichen Dokument, sodass es zu einem channel-Ziel wird, das diesen Kanal benennt. Von einem Single-Channel-Export wird es für Sie ausgefüllt. Serverweite globale Skripte haben kein Perfuse-Äquivalent und werden daher gemeldet, anstatt verworfen zu werden.

Der Bericht sagt pro Kanal, ob er sauber übersetzt wurde, mit Warnungen übersetzt wurde oder nicht gelesen werden konnte.

Die Überschrift ist ein Bruch mit seinem Nenner - "37 von 40 bereit" - weil "37 bereit" Ihnen nichts über das sagt, was Sie noch zu tun haben.

Ein Kanal, der nicht gelesen werden kann, ist ein anderes Problem als einer, der nicht übersetzt werden kann. Ersteres bedeutet, dass das XML selbst nicht geparst wurde und normalerweise ein trunkierter oder teilweiser Export ist. Letzteres bedeutet, dass der Inhalt des Kanals etwas enthält, das kein Perfuse-Äquivalent hat. Der Import trennt sie.

15.2 Was übersetzt wird und was eine Entscheidung benötigt

Quellen, Ziele, Filter und die gewöhnlichen Transformer-Schritte werden direkt übersetzt. Die Konnektoren, die übersetzt werden: TCP/MLLP (und roher TCP mit seiner Rahmenbildung), HTTP, Datei, Datenbank, JavaScript, DICOM, Webdienst (SOAP), SMTP und Channel-Reader/Writer. JMS und der Document-Writer werden nicht übersetzt und werden als Blockierer gemeldet.

Ein Mapper-Schritt, der eine Variable setzt, legt sie in die Karte ab, die ihr Bereich benennt - channelMap standardmäßig - genau wie Mirth, sodass spätere Schritte, die sie mit $('name') lesen, sie finden.

JavaScript-Transformer funktionieren im Allgemeinen nicht. Mirth-Kanäle enthalten häufig erheblichen Code in einem Transformer, und es gibt keine automatische Konvertierung von beliebigem JavaScript in deklarative Schritte. Der Importeur meldet diese anstelle eines Versuchs, eine Übersetzung vorzunehmen, die subtil falsch sein könnte: ein fehlübersetzter Transformer ist schlimmer als einer, der für einen Menschen gekennzeichnet ist, da er ausgeführt wird.

Wo ein Skript tatsächlich ein Skript bleiben muss, kann Perfuse es ausführen - siehe den scripts-Schlüssel in der Kanaldokumentation - auf Kosten der schrittweisen Spur, die in Fehlerbehebung beschrieben wird.

15.3 Was der Importeur getestet hat

Fünf Motoren, jeder erstellt seine eigenen Dokumente: Mirth 4.5.2, OIE 4.5.2, 4.6.0 und 4.7.0 und BridgeLink 26.9.0. scripts/mirth-engine-corpus.sh kompiliert ein kleines Programm gegen die eigenen Jars jedes Motors und hat seinen eigenen Serialisierer, der drei normale Kanäle schreibt - einen MLLP-Feed mit einem Mapper, ein Skript, das eine Code-Bibliothek aufruft, und einen Filter; einen HTTP-Feed in eine Datenbank; eine Datei-Abfrage per MLLP - plus die Bibliothek und eine Kanalgruppe. Es lädt sie in den laufenden Motor und lädt die eigene Server-Sicherungskopie herunter. Die Ergebnisse werden unter internal/mirth/testdata/engines/ committet, und die Test-Suite hält den Importer an jedem von ihnen auf jedem Build: Jede Sicherungskopie wird gelesen, übersetzt, geladen, und der ADT-Kanal wird mit zwei Nachrichten ausgeführt, um zu überprüfen, ob die Bibliothek die Aktennummer puffert und der Filter das Ergebnis fallen lässt.

Die eigenen Exporte von Perfuse gehen in die andere Richtung — Perfuse-Kanäle werden in jeden laufenden Motor importiert und es wird überprüft, ob der Motor sie nicht als ungültig speichert. Alle fünf akzeptieren jeden Transport, den Perfuse exportiert. Open Integration Engine 4.7.0 fügte zwei HTTP-Einstellungen ohne Äquivalent hier hinzu: ein HTTP-Sender, der an eine gewählte lokale Adresse gebunden ist, wird als Warnung gemeldet, und ein HTTP-Listener-Anforderungskopflimit nur, wenn es über dem 1-MB-Limit von Perfuse liegt.

Der erste Lauf gegen dieses Korpus fand vier Defekte, alle behoben: Der Übersetzer lehnte HTTP- und Datei-Quellen als "nur MLLP wird unterstützt" ab, lange nachdem Perfuse beide hatte; er las die Adresse eines HTTP-Senders aus einem Feld, das keiner der Motoren schreibt; er übersetzte die Socket-Puffergröße von Mirth als 64-KB-Nachrichtenlimit; und eine Variable eines Mappers wurde zu einer JavaScript-Globalen, die $('mrn') nie sah, sodass die Bibliothek eine leere Zeichenfolge auffüllte.

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.

Das manuelle Schreiben eines solchen war nie funktionell, und der Grund ist es wert, bekannt zu sein, wenn Sie eigene Exporte produzieren. Mirths Serialisierer ignoriert Elemente, die er nicht erkennt, sodass ein falscher Elementname überhaupt keinen Fehler verursacht - der Konnektor ist einfach nicht mehr da.

scripts/mirth-author-channel.sh erstellt eines, indem es Mirths eigene Modellklassen und seinen eigenen Serialisierer verwendet, und postet es dann an einen laufenden Server und schlägt fehl, wenn der Server es ablehnt. Perfuses Importeur liest das Ergebnis: Name, Quelltransport und Ziele überleben alle.

15.4 Beweisen, dass es übereinstimmt

Dies ist der Teil, der entscheidet, ob eine Migration stattfindet, und er benötigt Beweise anstelle von Vertrauen.

Perfuse vergleicht seine eigene Ausgabe mit der des alten Motors, Nachricht für Nachricht, auf Ihrem Datenverkehr. Was es benötigt, sind Paare: Die Nachricht, wie sie ankam, und die Nachricht, die der alte Motor aus ihr produzierte. Beide befinden sich in Mirths eigener Nachrichtenspeicher und können aus seinem Nachrichtenbrowser exportiert werden.

Perfuse kann nicht in Mirth eindringen, und diese Anleitung wird dies auch nicht vorgeben. Ein Tool, das behauptet, eine Migration zu überprüfen, ohne jemals die tatsächliche Ausgabe des alten Motors gesehen zu haben, würde nichts überprüfen. Die Bereitstellung der Paare ist die ehrliche Form der Übung.

15.4.1 Vier Zahlen, kein Bestehensgrad

ErgebnisBedeutung
IdentischByte für Byte identisch.
Nur kosmetische ÄnderungenUnterscheidet sich in Punkten, die keine Informationen tragen — nachfolgende leere Felder, ein abschließender Terminator.
UnterschiedeDer Wert eines Feldes ist unterschiedlich.
Kann nicht ausgeführt werdenPerfuse konnte die Nachricht überhaupt nicht verarbeiten.

Es sind vier Zahlen, weil sie vier verschiedene Dinge bedeuten und das Zusammenfassen von Informationen diejenigen versteckt, die eine Entscheidung erfordern.

Identisch bedeutet Byte für Byte, nicht äquivalent. Ein schwächerer Test würde Unterschiede in der Segmentreihenfolge oder nachfolgenden Trennzeichen zulassen, und genau diese werden von einem pingeligen Downstream-System abgelehnt.

Kosmetische Unterschiede werden separat gezählt und nicht in die gute Spalte eingefügt. Sie tragen tatsächlich keine Informationen, sodass ihre Behandlung als Fehler echte Ergebnisse unter Tausenden von Nichts begraben würde — aber sie sind auch nicht identisch, und ein Empfänger, der seine eigene strenge Analyse durchführt, kann anderer Meinung sein.

"Kann nicht ausgeführt werden" ist getrennt von "unterschiedlich", weil es normalerweise eine Konfigurationslücke ist, die der Importeur nicht füllen kann, und nicht eine Entscheidung über die Zuordnung. Wenn alles in dieser Spalte ist, sagt das Urteil das und fordert Sie auf, die Konfiguration zu überprüfen, bevor Sie irgendetwas anderes lesen.

15.4.2 Unterschiede werden nach Feldern gruppiert

Ein Lauf über fünfzigtausend Nachrichten, der viertausend Unterschiede meldet, hat Ihnen nichts gesagt, auf das Sie reagieren können. Derselbe Lauf, der meldet, dass PID-8 in jeder Nachricht unterschiedlich ist, weil der alte Motor Male schrieb, wo Perfuse M schreibt, hat Ihnen genau eine Entscheidung mitgeteilt.

Jedes Ergebnis ist also ein Feld mit einer Zählung, und es sagt, ob der Unterschied systematisch ist — dasselbe Wertepaar jedes Mal — oder ob der Inhalt des Feldes unterschiedlich ist.

Diese Unterscheidung ist das Nützlichste im Bericht. Ein einzelnes Wertepaar über viertausend Nachrichten hinweg ist eine einzelne Entscheidung über die Zuordnung. Viertausend verschiedene Paare sind ein unterschiedlicher Inhalt, was ein anderes und viel größeres Problem ist, und die beiden dürfen nicht gleich aussehen.

Ergebnisse sind nach der Anzahl der Nachrichten, die sie betreffen, geordnet, sodass die größte einzelne Ursache zuerst kommt.

15.4.3 Das Urteil rundet nicht

Es gibt genaue Zählungen: 49.993 von 50.000, nicht "über 99%". Die sieben sind der ganze Punkt des Laufens.

Es ist so geschrieben, dass es in einer Änderungsanfrage zitierfähig ist, weil das der Ort ist, an dem die Zahl endet.

15.5 Ein vorgeschlagener Ablauf

  1. Importieren Sie die Kanäle und lösen Sie alles, was als nicht lesbar gemeldet wird.
  2. Überprüfen Sie für jeden Kanal die Warnungen. Die meisten werden Skripte sein.
  3. Exportieren Sie einige tausend Nachrichtenpaare aus Mirth für den aktivsten Kanal und führen Sie den Vergleich durch.
  4. Arbeiten Sie die Ergebnisse durch. Systematische sind jeweils eine Entscheidung.
  5. Führen Sie den Vorgang erneut durch, bis die einzigen Unterschiede diejenigen sind, die Sie als korrekt entschieden haben.
  6. Führen Sie Perfuse im Schatten neben Mirth mit Live-Verkehr durch, liefern Sie nirgendwohin und vergleichen Sie erneut über einen Zeitraum, der ein Wochenende und ein Monatsende umfasst.
  7. Schalten Sie einen Kanal um, nicht alle.

15.6 Was nur auf einer Software eines Anbieters läuft

Der Migrationsbildschirm beantwortet eine zweite Frage, und es lohnt sich, sie zu stellen, bevor Sie eine Meinung über Perfuse haben: Wie viel Ihrer Integrationslogik kann nur auf der Software laufen, die Sie haben.

Jeder Kanal erhält ein Portabilitäts-Urteil, aus demselben Scan, der die Migrationsnotizen produziert. Es läuft gegen eine Kanalexportierung, sodass es nichts installieren muss und nichts ändert.

15.6.1 Die Unterscheidung ist der ganze Punkt

Die meisten Java-Elemente in Mirth-Skripten sind keine Bindung. SimpleDateFormat, HashMap, Apache Commons — all das arbeitet um eine JavaScript-Engine von 2009 herum, all das ist normal, all das hat direkte Äquivalente. Ein Kanal mit drei hundert solcher Verweise ist vollständig portabel, und ein Tool, das "300 Java-Verweise, Sie sind gefangen" meldet, würde Ihnen gegenüber lügen.

Bindung ist speziell die Aufrufe, die den Server des Anbieters benötigen: com.mirth.connect.* und Anbieter-Jars. Fünf davon und Sie sind festgelegt. Fünfhundert der anderen Art und Sie sind frei.

Das Urteil beginnt also mit der Zahl, die zählt, und sagt im selben Satz, dass die größere Zahl nicht die richtige ist. Wenn es Anbieteraufrufe gibt, werden sie nach Name aufgelistet — eine Zählung ist eine Behauptung, und eine Liste ist etwas, das Ihr eigener Ingenieur überprüfen kann.

Eine dritte Kategorie wird getrennt gehalten: Fähigkeiten, die existieren, aber nicht aus einem Skript. Das Starten eines Kanals aus JavaScript hat kein Äquivalent hier, und es gibt einen API-Endpunkt, der genau das Gleiche tut. Das als Bindung zu bezeichnen, würde die Feststellung überbewerten.

15.6.2 Java-Aufrufe, die unverändert laufen

Die häufigsten dieser Java-Klassen werden wie geschrieben ausgeführt. Perfuse hat keine Java-Laufzeit, also sind diese JavaScript-Klassen mit den gleichen Namen und Methoden, ausreichend für die Art und Weise, wie Kanal-Skripte sie verwenden; importPackage(java.util) und importClass(...) bringen sie in den Gültigkeitsbereich durch ihre Kurznamen, wie in Rhino (JavaScripts eigene Date, Map, Set, Math, String und Boolean werden nie ersetzt: Die Java-Elemente sind immer noch unter ihrem vollen Namen vorhanden). Der Migrationsbericht zählt jeden dieser Aufrufe als bereits unterstützt.

PaketKlassen
java.utilArrayList, LinkedList, Vector, List, Collection, HashMap, LinkedHashMap, Hashtable, TreeMap, Properties, HashSet, LinkedHashSet, TreeSet, Arrays, Collections, Date, Calendar, GregorianCalendar, UUID, Base64, regex.Pattern (mit Matcher), concurrent.ConcurrentHashMap
java.langString, StringBuilder, StringBuffer, Integer, Long, Short, Byte, Double, Float, Boolean, Math, System (nur Zeit und Zeilen-Trenner)
java.text, java.math, java.net, java.nioSimpleDateFormat und DateFormat (Mirths Musterbuchstaben), BigDecimal (als Doppelwert), URLEncoder, URLDecoder, StandardCharsets
Apache Commonslang3.StringUtils und lang.StringUtils (etwa sechzig Methoden), StringEscapeUtils, codec.binary.Base64

Sie verhalten sich wie Java, wenn Skripte von ihnen abhängen: Integer.parseInt("x") löst eine NumberFormatException aus, String.replaceAll und split nehmen reguläre Ausdrücke, während replace buchstäblich ist, Karten Schlüsselzeichenfolgen nach Wert, TreeMap und TreeSet iterieren in der Reihenfolge, und SimpleDateFormat.parse gibt ein Datum zurück, auf das getTime() funktioniert. Eine Methode, die ein Skript aufruft, die die äquivalente Methode fehlt, schlägt an dieser Zeile fehl, indem sie den Namen nennt; jede andere Java-Klasse schlägt durch Namen fehl, wie zuvor. BigDecimal ist hier ein Double, also hält es nicht die exakte Dezimalarithmetik von Java: Überprüfen Sie Skripte, die es für Geld verwenden.

15.6.3 Externe Skripte werden als unbekannt gemeldet

Ein Schritt, der eine externe Skriptdatei ausführt, verweist auf einen Pfad auf dem alten Server, und die Datei ist nicht im Export enthalten. Nichts kann über ihren Inhalt gesagt werden, daher wird sie als unbekannt gezählt, anstatt sie als richtig oder falsch anzunehmen. Holen Sie sich diese Dateien, bevor Sie irgendetwas schlussfolgern — in beide Richtungen.

15.6.4 Perfuses eigene Lock-in, in einem Atemzug genannt

Dieser Abschnitt wäre ohne ihn unehrlich.

Perfuse ist Apache 2.0, was für bereits veröffentlichten Code unwiderruflich ist. Sie können den aktuellen Code forken und niemand kann ihn zurückziehen. Kanäle sind YAML-Dateien und Skripte sind normales JavaScript, daher gibt es keine proprietäre Oberfläche, die aufgerufen werden kann — Mirths Java-Abhängigkeit ist hier strukturell nicht verfügbar, was der eine Ort ist, an dem eine Einschränkung tatsächlich ein Feature ist.

Was das nicht verspricht: dass eine zukünftige Version offen bleibt, dass ein gehosteter Dienst zu einem Preis, den Sie mögen, existiert, oder dass der Umzug von Perfuse nichts kostet. Der Umzug einer Integrations Ebene bedeutet, jeden Kanal gegen echten Datenverkehr zu testen. Sie wählen, ob die Artefakte, die Sie erstellen, lesbar und portabel sind und ob der Ausstieg von einer Lizenz abhängt, die jemand anderes kontrolliert.

15.6.5 Einrichten von Schritt 6

One message real traffic Live channel unchanged Candidate the version you are testing Receiver delivers nothing Comparison field by field The candidate sees the same real messages as the live channel and delivers none of them. Only the live channel reaches the receiver. What you read afterwards is where the two disagreed, field by field — not a pass or a fail.

Der Shadow-Abschnitt beginnt einen Vergleich. Wählen Sie den laufenden Kanal, wählen Sie den Kandidaten aus der Liste aus und starten Sie ihn.

Drei Dinge sind es wert, vorher zu wissen, bevor Sie sich auf die Zahlen verlassen.

Der Kandidat wird aus einer Liste ausgewählt, nicht eingegeben. Ein Shadow benennt eine Kanaldatei, und ein Name, der nicht aufgelöst wird, macht den *laufenden* Kanal ungültig — Perfuse lehnt einen Kanal insgesamt ab, wenn etwas, auf das er verweist, defekt ist. Ein Tippfehler produziert also keine Warnung, sondern macht den laufenden Kanal verschwinden.

Der Anteil ist ein Prozentsatz. Verringern Sie ihn nur auf einem beschäftigten Feed und wissen Sie, was es kostet: Stichproben reduzieren die Arbeit und das Vertrauen im gleichen Verhältnis, und die Nachricht, die den Unterschied zeigen würde, ist die ungewöhnliche.

Felder, die ignoriert werden sollen, werden normalerweise benötigt. Ein Kanal, der einen Zeitstempel oder eine Sequenznummer stempelt, unterscheidet sich bei jeder einzelnen Nachricht, was einen Unterschiedsgrad von 100% meldet und Ihnen nichts sagt. MSH-7 und MSH-10 sind das übliche Paar.

Ein Vergleich wird in die Kanaldatei geschrieben, sobald Sie ihn starten, und beginnt mit der Beobachtung, wenn der Kanal als Nächstes geladen wird — der Bildschirm sagt es an, anstatt zu behaupten, er sei bereits im Gange. Das Stoppen eines Vergleichs lässt den Kandidatenkanal an seinem Platz, da der Kandidat das ist, was live gehen soll.

Schritt 6 ist der, der nicht verkürzt werden kann. Die Unterschiede, die wichtig sind, treten normalerweise in Datenverkehr auf, der nur gelegentlich erscheint — ein seltener Trigger-Ereignis, ein Monatsend-Batch, ein Absender, der sich um Mitternacht anders verhält — und eine Stichprobe, die über einen Nachmittag genommen wird, enthält sie nicht.

15.7 Zurück auf dem anderen Weg

Ein Kanal kann als Mirth-Kanaldatei exportiert werden, aus dem Browser: Kanäle, dann Zu Mirth auf dem Kanal, den Sie möchten.

Dies existiert, weil der Einwand gegen die Ersetzung eines funktionierenden Motors selten ist, ob die Ersetzung gut ist. Es ist, was passiert, wenn die Entscheidung sich als falsch herausstellt, und ein Export, der zurück in die entgegengesetzte Richtung geht, ist die billigste Antwort darauf.

Lesen Sie, was der Dialog Ihnen sagt, bevor Sie die Datei übernehmen. Mirths Format hat keinen Platz, um einen Perfuse-Filter, eine Transformationskette, einen Vertrag oder einen Shadow-Vergleich zu platzieren, daher tut ein exportierter Kanal weniger als der, von dem er stammt. Die Transporte und ihre Adressen konvertieren; die Logik tut dies nicht. Jeder Verlust wird namentlich aufgeführt, bevor die Datei angeboten wird, und die gleiche Liste wird in die Beschreibung des Kanals aufgenommen, damit derjenige, der ihn importiert, sie auch sieht.

Ein Kanal, den Mirth nicht ausdrücken kann, wird abgelehnt, anstatt approximiert zu werden. Ein S3-Ziel hat keine Mirth-Äquivalenz, und ein Kanal, der sauber importiert wurde, während er an einem anderen Ort als dem Bucket lieferte, wäre schlimmer als gar keine Datei. Die Ablehnung nennt das Ziel, das schuld ist.

Die Connector-Definitionen werden nicht durch das Lesen von Mirths Format erstellt. scripts/mirth-dump-connector-templates.sh verwendet Mirths eigenen Serialisierer, um die Standardwerte für jede Connector-Klasse zu erzeugen, und Perfuse ersetzt Werte in diesen Dokumenten — und lehnt jede Einstellung ab, die das Template nicht bereits enthält. Dies ist wichtig, weil Mirth auf einen Kanal, den es nicht parsen kann, nicht ablehnt. Es speichert einen Kanal, dessen Beschreibung durch „Dieser Kanal ist ungültig. Stellen Sie sicher, dass alle erforderlichen Erweiterungen korrekt geladen sind“ ersetzt wurde und dessen Ziele stillschweigend verworfen wurden. Ein Export, der gegen seine eigene Ausgabe und nicht gegen einen Server überprüft wird, besteht jeden Test, während er Dokumente erzeugt, die weggeworfen werden, was genau hier passiert ist, bevor die Exporte gegen einen laufenden Mirth getestet wurden.

Was heute überschritten wird: MLLP und TCP in beide Richtungen, HTTP in beide Richtungen, Dateilesen und -schreiben, Datenbanklesen und -schreiben, DICOM in beide Richtungen und SMTP-, SOAP- und JavaScript-Ziele. Jedes Paar wird durch Import in einen echten Mirth 4.5.2 verifiziert und überprüft, ob der Server den Kanal nicht stillschweigend ersetzt hat.

16 CMS-0057 für Zahlstellen

Die CMS-Interoperabilitäts- und Vorabgenehmigungs-Endregel (CMS-0057-F) verlangt von betroffenen Zahlstellen — Medicare-Advantage-Organisationen, staatlichen Medicaid- und CHIP-Programmen und ihren Managed-Care-Plänen sowie QHP-Issuern auf den Bundesbörsen —, vier FHIR-APIs ab dem 1. Januar 2027 bereitzustellen und Vorabgenehmigungsmetriken auf ihrer öffentlichen Website jedes Jahr ab 2026 zu veröffentlichen.

Perfuse bietet die vier APIs auf seinem FHIR-Endpunkt und die Konvertierungen, die sie füllen: begutachtete Ansprüche als CARIN Blue Button, Vorabgenehmigungen als Da Vinci PDex und die jährlichen Metriken im Layout von CMS-eigenen Vorlagen. Die CMS-0057-Ansicht unter Exchange sagt, welche der vier diese Instanz beantworten kann und was jede noch benötigt, und führt alle drei Konvertierungen im Browser durch.

Medikamente sind in der gesamten Regelung außerhalb des Vorabgenehmigungsbereichs, da sie in den Vorabgenehmigungsbestimmungen der Regelung nicht enthalten sind: keine Apothekenansprüche, keine Formulare und eine Metrikzeile, die ein Medikament nennt, wird abgelehnt, anstatt gezählt zu werden.

16.1 Die vier APIs

APIWas es dientAnleitungenAktiviert durch
PatientenzugriffEin Mitgliedsansprüche, klinische Daten und vorherige Genehmigungen an eine von ihm ausgewählte AppCARIN Blue Button 2.2.0, PDex 2.2.0, US Core, SMART App Launch-fhir und ein SMART-Issuer (-smart-issuer)
Zugriff für AnbieterDasselbe für die einem Anbieter zugeordneten Mitglieder, in BulkPDex 2.2.0, Da Vinci ATR 2.1.0, Bulk Data-fhir-payer-apis und -fhir-bulk-export
Payer-to-PayerEin Mitgliedsdatensatz an einen anderen Payer, nachdem sie abgeglichen wurdenHRex 1.2.0 $member-match, PDex 2.2.0-fhir-payer-apis
VorabgenehmigungWas eine Bestellung benötigt, die Dokumentation, dann die Anfrage und die EntscheidungDa Vinci CRD, DTR und PAS 2.2.x (2.2.1, 2.2.0, 2.2.1) und 2.1.0, mit X12 278-Übersetzung-fhir, schreibbar, und -crd-rules

Die Patientenzugriff-API benötigt keine eigene Operation: Es handelt sich um den gewöhnlichen Lese- und Suchvorgang des FHIR-Endpunkts, der durch SMART geschützt ist, mit CARIN- und PDex-Ressourcen im Store. Die Suche nach ExplanationOfBenefit unterstützt die von CARIN benannten Parameter — patient, identifier, type, service-date, billable-period-start, provider, insurer, coverage — und Coverage unterstützt subscriber-id, identifier und payor.

16.1.1 Zwei Versionen der Anleitungen: 2.1.0 und 2.2.x

CMS-0057-F empfiehlt CRD, DTR und PAS 2.0.1 und 2.1.0. Die 2.0.1-Veröffentlichungen basieren auf US Core 3.1.1, die am 1. Januar 2026 abgelaufen sind, sodass 2.1.0 die Version ist, die ein EHR, das für die Regel erstellt wurde, wahrscheinlich spricht; die neuesten sind CRD 2.2.1, DTR 2.2.0 und PAS 2.2.1. Perfuse antwortet in beiden. Es ermittelt, welche Version der Anrufer spricht, am spezifischsten zuerst:

  1. aus der Anfrage: CRD's CDS Hooks-Erweiterung davinci-crd.requestedVersion ("2.1"), oder die Version auf einem Da Vinci-Profil, das ein DTR- oder PAS-Eingabeanspruch (profile-pas-request-bundle|2.1.0);
  2. aus der Registrierung des Anrufers: davinci_version: "2.1" auf einem SMART-Client (-smart-clients) oder einem CDS-Client (-cds-clients);
  3. vom Server: serve -davinci-version 2.1; die Standardversion ist 2.2.
clients:
  - issuer: https://ehr.example.org
    jwks_url: https://ehr.example.org/.well-known/jwks.json
    davinci_version: "2.1"

Jede Antwort wird entschieden und in der 2.2.x-Form gespeichert und für einen 2.1.0-Anrufer umgeschrieben, wenn sie gesendet wird, sodass die Regeln, die Überprüfungswarteschlange, der X12-278-Link und die Metriken für beide gleich sind. Die Umschreibung umfasst, was die Veröffentlichungen anders buchstabieren: CRD 2.1.0 hat kein indeterminate (Perfuse sagt bedingt, mit dem Grund) und keine Kategorie auf einem Abdeckungsdetail; DTR 2.1.0 benennt das Paket PackageBundle und überlässt die QuestionnaireResponse der App; PAS 2.1.0s $inquire antwortet mit einem Bundle und fehlt die Überprüfer- und Übertragungserweiterungen. Die vollständige Liste und die Überprüfung gegen jedes 2.1.0-Leitfadenbeispiel befindet sich in conformance/davinci21. Eine PAS-Benachrichtigung folgt -davinci-version, da ein Abonnement nicht angibt, welche Version sein Besitzer liest.

16.2 Abdeckungsanforderungen und Dokumentation: CRD und DTR

Die Priorisierungs-API ist in der Praxis drei Da-Vinci-Leitfäden zusammen. CRD teilt dem Kliniker mit, während die Bestellung noch ein Entwurf ist, ob sie abgedeckt ist, ob sie eine vorherige Autorisierung benötigt und welche Dokumentation gewünscht wird. DTR übergibt der EHR die Fragebogen, die diese Dokumentation sammelt. PAS übermittelt die Anfrage und gibt die Entscheidung zurück. Perfuse dient allen drei als Zahler.

-crd-rules rules.yaml dient CRD über CDS-Hooks unter /cds-services: alle sechs CRD-Hooks, order-sign, order-select, order-dispatch, appointment-book, encounter-start und encounter-discharge, jeweils mit einer Prefetch für die aktive Abdeckung des Patienten. Die beiden Encounter-Hooks prefetchen auch den Encounter und beantworten Fragen über den Encounter selbst, abgestimmt auf seinen Typ und Diensttyp, wie appointment-book über einen Termin antwortet. Die Regeln sind die Richtlinie des Zahlungspflichtigen, die in einer Datei gespeichert wird, da sie ohne Software-Veröffentlichungen geändert werden:

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

Jede Bestellung erhält ein systemActions-Update, das CRD-Abdeckungsinformationen enthält - die die EHR auf der Bestellung speichert und später mit der vorherigen Autorisierung sendet - und eine Karte, die der Kliniker liest. Eine Bestellung, deren Code keine Regel hat, wird mit conditional beantwortet, nie angenommen, abgedeckt; eine Anfrage ohne Abdeckung erhält eine Karte, die dies angibt. examples/crd/ enthält eine Regeldatei und einen entsprechenden Fragebogen.

Eine Regel kann auch den Rest von dem enthalten, was CRD einer Zahlstelle erlaubt:

Was die EHR nicht prefetchte, liest Perfuse vom fhirServer der EHR mit dem Token, das es gesendet hat. Wenn das fehlschlägt, ist die Antwort indeterminate mit CRD's technical Grund, niemals eine Vermutung. Eine Coverage, die beendet wurde oder nicht aktiv ist, wird mit not-covered, no-active-coverage beantwortet.

members: fhir in der Regeldatei löst die Abdeckung gegen die eigenen Aufzeichnungen des Zahlungspflichtigen in diesem Servers FHIR-Speicher (starten Sie es mit -fhir), dieselben Aufzeichnungen, die $member-match liest:

mit dieser Nummer.

Discovery deklariert davinci-crd.version und eine coverage-info-Konfigurationsoption. Wenn ein Client diese Option deaktiviert, ist die Antwort leer. EHR-JWTs werden wie in CDS Hooks definiert überprüft, mit iss, aud, exp, iat und jti und ohne sub, und ein wiederholtes jti wird abgelehnt.

Anrufe authentifizieren sich mit dem JWT, das eine EHR für jeden Anruf signiert, von einem Aussteller, der in -cds-clients mit seiner JWKS-URL genannt ist - so wie CDS Hooks es beschreibt - oder mit einem Perfuse-API-Token. Discovery ist offen, wie CDS Hooks es erfordert.

DTR: Laden Sie die Fragebögen in den FHIR-Endpunkt, und POST /fhir/Questionnaire/$questionnaire-package gibt sie als DTR-Paketbündel mit den CQL-Bibliotheken zurück, die sie nennen. Die Anfrage kann den Fragebogen nennen oder die Bestellung senden und seine Abdeckungsinformationen sagen, welche.

Ausprobieren: Payers → Claims & Auth → Coverage-Anforderungen (CRD) sendet eine Bestellung an die Regeln dieses Servers oder an die CDS-Service-URL eines Payers und zeigt die Karten und die Abdeckungsinformationen an.

16.3 Ansprüche als CARIN Blue Button

perfuse cms0057 carinbb paart jeden Anspruch in einer 837 mit seiner Zahlung in einer 835, basierend auf der Patientenkontonummer, die die 835 zurückgeben muss, und schreibt eine FHIR-Transaktion für jeden: die ExplanationOfBenefit mit dem Patienten, der Abdeckung, den Organisationen und den Fachleuten, auf die sie verweist.

perfuse cms0057 carinbb -system https://fhir.your-plan.org/identifier -network innetwork \
    claims.837 remittance.835

Das Profil folgt dem Anspruch: Professionelle Ansprüche (837P) werden zu C4BB-ExplanationOfBenefit-Professional-NonClinician, und institutionelle Ansprüche (837I) werden basierend auf dem Rechnungstyp inpatient oder outpatient. Jeder Eintrag ist ein PUT mit einer ID, die aus den Quellidentifikatoren übernommen wird, so dass das Laden desselben Anspruchs zweimal aktualisiert, anstatt eine zweite Kopie zu erstellen.

Drei Dinge sind weder in der X12-Datei noch in der anderen enthalten, und jedes wird dadurch gehandhabt, dass es angegeben wird, anstatt zu raten:

Diagnosen werden mit ihrem Dezimalpunkt (J02.9, nicht J029) geschrieben, weil das so ist, wie das Codesystem sie veröffentlicht, und ein Terminologischer Server, der nach der anderen Schreibweise gefragt wird, sagt, dass es nicht existiert. Die Mitgliedsidentifikation eines Abhängigen ist die des Abonnenten, was die 837 enthält, und die Notizen sagen es. Ein NPI, dessen Prüfziffer falsch ist, wird vor dem US-Core-Abweisungsverfahren gemeldet.

16.4 Vorabgenehmigungen als PDex

perfuse cms0057 priorauth konvertiert eine Da Vinci PAS ClaimResponse - oder das PAS-Antwortbündel, das eine enthält - in eine PDex-Vorabgenehmigungs-ExplanationOfBenefit, die alle drei Daten-APIs bereitstellen.

perfuse cms0057 priorauth pas-response.json pas-claim.json

Die PAS-Anspruch ist optional und fast immer erforderlich. Eine ExplanationOfBenefit muss angeben, unter welcher Abdeckung die Entscheidung getroffen wurde, und nur die Anfrage enthält diese; ohne sie stoppt die Konvertierung und sagt es. Die Überprüfungsaktion - genehmigt, abgelehnt, ausgestellt, mit ihrer Genehmigungsnummer und ihrem Grund - wird von der PAS-Erweiterung zu PDex übertragen, und der X12-Service-Typ behält seinen Code unter der URI, die PDex bindet.

16.5 Die Provider Access- und Payer-to-Payer-APIs

Mit -fhir-payer-apis antwortet der FHIR-Endpunkt auf drei weitere Operationen:

Die Exporte wenden die Ausschlussregeln auf dem Weg aus. Ansprüche verlieren die Zahlung und jeden Kostenbeteiligungs- und Abrechnungsbetrag und behalten die Dienstleistungen, Codes, Daten und Anbieter; das CARIN-Profil wird aus meta.profile entfernt, da die Ressource es nicht mehr erfüllt. Payer-to-Payer lässt auch abgelehnte Vorabgenehmigungen aus. Mitglieder, die eine aktive PDex-Provider-Access-Opt-out-Zustimmung haben, werden aus einem Anbieterexport ausgeschlossen, und das Protokoll verzeichnet, wie viele. Der patient-Parameter kann nur auf Mitglieder der Gruppe eingeschränkt werden; die Nennung einer anderen Person wird abgelehnt.

Der Zugriff auf die Exportfunktion einer Gruppe wird durch die Authentifizierung des Endpunkts entschieden. SMART-Berechtigungen legen fest, welche Arten von Ressourcen ein Token lesen darf, nicht jedoch, welche Gruppe, sodass jeder Anbieter ein Token benötigt, das nur auf seine eigene Attributionsliste zugreifen kann. Ein API-Token kann bei seiner Erstellung auf Gruppen beschränkt werden - perfuse token create -label riverside-provider-access -fhir-groups riverside-attributed oder das Feld Beschränken auf FHIR-Gruppen unter Benutzer → Maschinenanmeldeinformationen - und kann dann auf dem FHIR-Endpunkt diese Gruppen lesen, $davinci-data-export oder $export auf ihnen ausführen und das Ergebnis abrufen, aber nichts anderes. Die Beschränkung gilt für API-Tokens; ein Token von einem SMART-Aussteller enthält keine Gruppenbeschränkung. Wenn SMART ebenfalls konfiguriert ist, werden API-Tokens abgelehnt, es sei denn, Einstellungen → FHIR → Perfuse-API-Tokens neben SMART-Tokens akzeptieren ist aktiviert (siehe Sicherheit, *Wer darf den FHIR-Endpunkt aufrufen*); ein Gruppenbeschränktes Token eines Anbieters benötigt es.

16.6 Ein Anbieterverzeichnis: Plan-Net

CMS-0057 fragt Payer auch nach einem Anbieterverzeichnis, und der FHIR-Endpunkt dient einem solchen für Da Vinci Plan-Net 1.1.0 ohne Option, es zu aktivieren: Laden Sie die Practitioners, PractitionerRoles, Organizations, OrganizationAffiliations, Locations, HealthcareServices, InsurancePlans und Endpoints, und Mitglieds-Apps können sie durchsuchen. Jeder Plan-Net-Suchparameter ist indexiert - eine Rolle, ein Netzwerk und ein Dienst, ein Plan, ein Abdeckungsbereich, eine Affiliation, eine teilnehmende Organisation, eine Organisation, partof - sowie die Includes und Reverse-Ketten (_has), die die Anfragen des Leitfadens verwenden, und die CapabilityStatement listet die Plan-Net-Profile auf.

Infernos Plan-Net-Suite besteht 199 Tests. Die 10, die sie nicht besteht, sind Vorwärtsketten, bei denen das Kit seinen Suchwert aus der ersten Organisation nimmt, die es gesehen hat, anstatt aus einer, auf die die durchsuchten Ressourcen verweisen; dies wird dem Kit gemeldet (sein Problem 34), und der Server beantwortet diese Anfragen korrekt, wenn er einen Wert erhält, den die Daten enthalten.

16.7 Metriken für vorherige Genehmigungen

perfuse cms0057 metrics liest eine CSV-Datei mit Entscheidungen, die aus dem Nutzungsmanagement-System exportiert wurden, und erzeugt die öffentliche Seite, die CMS erfordert, im Layout von *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

Spalten werden durch den Header gefunden: priority, received, decided und decision sind erforderlich, und request_id, line_of_business, extended, appealed, appeal_decision, service_code und service_description werden gelesen, wenn sie vorhanden sind. Eine Anfrage gehört zum Jahr, in dem sie entschieden wurde; eine noch ausstehende Anfrage wird als ausgeschlossen aufgeführt und nie gezählt. Jede Zeile, die nicht gelesen werden kann, wird mit ihrer Zeilennummer gemeldet.

Die Arithmetik folgt dem Template: für Standard- und Expressanfragen getrennt, der Anteil der Genehmigungen und Ablehnungen, der Genehmigungen und Ablehnungen innerhalb der Entscheidungsfrist, der Genehmigungen nach Verlängerung der Überprüfungszeit und der Genehmigungen nach Berufung — von Berufungen, nicht von Anfragen — mit dem Mittelwert und dem Median der Zeit von der Einreichung bis zur Entscheidung. Ein Median unter einem Tag wird in Stunden anstelle von auf 0 Tage gerundet geschrieben, was das Template ausdrücklich verlangt. Teilweise genehmigte Anfragen werden als genehmigt gezählt, da das Template keine Kategorie dafür hat, und die Seite gibt an, wie viele es gab. Metriken werden pro Geschäftsbereich gemeldet, was das erforderliche Niveau von CMS ist.

Die Seite ist selbstständig — kein Skript, kein externes Stylesheet oder Schriftart —, da sie auf einer öffentlichen Website von dem, der diese Website verwaltet, veröffentlicht wird, und alles, was sie von anderswo lädt, etwas anderes ist, das brechen oder einen Besucher verfolgen kann. -format csv und -format json liefern die gleichen Zahlen für andere Verwendungen. Ohne -services enthält die Seite einen Hinweis, dass die Liste der Artikel und Dienstleistungen, die eine vorherige Genehmigung erfordern, fehlt, da CMS dies auf der gleichen Seite erfordert.

16.8 Medikamente: das Formular, Real-Time Prescription Benefit und elektronische vorherige Genehmigung

CMS-0062-P (vorgeschlagen am 14. April 2026) würde Medikamente in die vorherige Genehmigung aufnehmen: betroffene Payer würden ab dem 1. Oktober 2027 NCPDP-SCRIPT-elektronische vorherige Genehmigung, den NCPDP-Formular- und Benefit-Standard und NCPDP-Echtzeit-Rezeptvorteil unterstützen, Medikamentenanfragen innerhalb von 24 Stunden (beschleunigt) und 72 Stunden (Standard) entscheiden, einen spezifischen Grund für jede Ablehnung angeben und ab 2028 Medikamentenmetriken melden. Medicare Part D erfordert bereits SCRIPT-ePA. Eine Datei, das Formular, beantwortet all dies:

perfuse serve -fhir -pas -crd-rules payer-rules.yaml -formulary formulary.yaml

examples/formulary/formulary.yaml ist ein Beispiel, dessen Medikamente reale RxNorm-Konzepte mit NDCs sind, die RxNorm für sie auflistet (gegen RxNav überprüft). Eine Datei nennt den Payer, seine Pläne (jeweils mit dem Formular, das sie verwenden, ihren Gruppen-ID und ihren Kostenanteilen nach Apothekenleistung und Stufe) und seine Formulare. Jedes Medikament ist ein RxNorm-SCD oder SBD mit seiner RxNorm-Gruppe (der SCDG oder SBDG, die die Drug-Formulary-API erfordert), seinen NDCs, einer Stufe und seinen Einschränkungen: prior_authorization, step_therapy, quantity_limit (eine Menge in einer rollierenden Anzahl von Tagen und einem täglichen Maximum), not_covered, alternatives (RxNorm-Codes, am meisten bevorzugt zuerst), notes und questionnaire, die kanonische URL des FHIR-Fragebogens, den eine vorherige Genehmigung anfordert. cost_30_day ist die Kosten des Plans für eine 30-Tage-Versorgung, die ein Selbstbehalt als Prozentsatz davon ist; ohne sie wird ein Selbstbehalt als Prozentsatz angegeben, nie als erfundener Betrag. Die gesamte Datei wird überprüft, wenn sie geladen wird, jedes Problem wird auf einmal aufgelistet. Ein Mitglied wird durch die members-Liste der Datei, durch Gruppe oder durch den FHIR-Speicher gefunden: eine Coverage, deren subscriberId die Mitglieds-ID und deren class vom Typ plan die ID des Plans ist. Payer › Medikamente zeigt das Formular an, berechnet den Preis eines Medikaments und führt eine vorherige Genehmigung von Anfang bis Ende durch.

16.8.1 Die Da Vinci US Drug Formulary API

Veröffentlicht unter /formulary/fhir als Da Vinci US Drug Formulary 2.1.0: Jeder Plan ist ein PayerInsurancePlan, jede Formulareintragung ein Formulary (beide InsurancePlan), jedes Medikament ein FormularyDrug (MedicationKnowledge) und jeder Eintrag ein FormularyItem (Basic). Die Suchanfragen des Leitfadens werden bereitgestellt (Basic?code=formulary-item&formulary=...&drug-tier=...&pharmacy-benefit-type=...&period=..., subject:MedicationKnowledge.code, InsurancePlan?formulary-coverage=..., coverage-type, MedicationKnowledge?code=...&doseform=...) mit _include=Basic:subject, Basic:formulary und InsurancePlan:formulary-coverage. Es ist öffentlich, ohne Anmeldeinformationen, wie es die CMS für ein Formular eines Zahlungspflichtigen erfordert: Es wird aus einem eigenen Speicher bereitgestellt, der im Arbeitsspeicher gehalten wird und nur das Formular enthält, so dass es nicht auf die Patientenakte zugreifen kann. Es ist schreibgeschützt. Ein ausgeschlossenes Medikament wird nicht veröffentlicht, da die API auflistet, was ein Formular abdeckt; RTPB und ePA antworten dennoch, dass es nicht abgedeckt ist. Verifiziert mit dem HL7 FHIR-Validator gegen das 2.1.0-Paket des Leitfadens mit überprüfter Terminologie: Jede Ressource, die aus dem Beispiel generiert wird, enthält keine Fehler.

16.8.2 Echtzeit-Verschreibungsvorteil

POST /ncpdp/rtpb nimmt eine RTPBRequest (NCPDP RTPB v13) mit einem API-Token der Operatorrolle an und antwortet mit einer RTPBResponse aus dem Formular: den Abdeckungsstatus, den Formularstatus, den geschätzten Anteil des Mitglieds und den des Plans sowie die Abdeckungsbeschränkungen, mit bis zu fünf abgedeckten Alternativen, die auf die gleiche Weise berechnet werden. Beschränkungs-Codes und der Status, auf den jede Abbildung erfolgt, folgen den öffentlichen NCPDP-RTPB-Implementierungsempfehlungen: 75 vorherige Genehmigung erforderlich, 608 Stufentherapie, 76 Planlimits überschritten, 7X Tageszufuhr über dem Planlimit (z. B. ein Medikament, das nicht per Post erhältlich ist), 70 nicht abgedeckt, alle *abgedeckt mit Beschränkungen* (CR) außer 70 (NC). Ein Mitglied mit einer genehmigten vorherigen Genehmigung in der Datei erhält CC und AB8, wie es der Surescripts-Leitfaden verlangt, damit der Verordner nicht aufgefordert wird, erneut zu fragen. Eine Anfrage, die nicht berechnet werden kann, ist NotProcessed mit einem NCPDP-Ablehnungscode: 52 für ein nicht gefundenes Mitglied, E7 und 19 für eine fehlende Menge oder Tageszufuhr. Der Apotheken-Vorteil wird aus der Anfrage gelesen: Eine Auffüllung über 34 Tage ist eine Dreimonatszufuhr und die Apothekentyp M ist die Bestellung per Post.

16.8.3 Elektronische vorherige Genehmigung (NCPDP SCRIPT)

POST /ncpdp/script nimmt PAInitiationRequest, PARequest, PAAppealRequest und PACancelRequest mit einem API-Token der Operatorrolle an und antwortet auf jede mit ihrer Antwort:

AnfrageAntwort
PAInitiationRequestClosed, wenn keine erforderlich ist: CC keine vorherige Genehmigung erforderlich, FN innerhalb der Mengenbegrenzung, FM nicht abgedeckt oder nicht in der Formulierung, FQ eine Genehmigung in der Datei, CD kein solches Mitglied, CG eine bereits in Bearbeitung. Andernfalls Open, mit einer Fall-ID und dem Fragebogen.
PARequestEntscheidet als PAS-Anfrage: Approved mit der Genehmigungsnummer und dem Zeitraum, Denied mit dem Grund oder Open unter Überprüfung.
PAAppealRequestEin abgelehnter Fall wird erneut entschieden, basierend auf dem Grund in PANote (eine Berufung ohne einen wird aufgefordert, ihn anzugeben).
PACancelRequestApproved, solange der Fall offen oder unter Überprüfung ist, und die PAS-Anfrage wird abgebrochen; Denied, sobald er entschieden ist.

Die Fragestellung ist das FHIR-Fragebogen des Medikaments aus dem FHIR-Speicher, derselbe, den DTR ausfüllt: Ein Boolean wird zu einer Ja/Nein-Auswahl, eine Auswahl zu einer Auswahl, eine Zahl zu einer numerischen Eingabe, ein Datum zu einem Datum und alles andere zu einem freien Text; Gruppen werden flach angeordnet und enableWhen wird nicht übernommen, da SCRIPT nach Auswahl und nicht nach Bedingung verzweigt. Ein Medikament ohne Fragebogen wird drei freie Textfragen gestellt: Diagnose, was ausprobiert wurde und warum dieses Medikament. Eine PARequest wird zu einer Da Vinci PAS-Anfrage: Ein Claim für das Medikament (RxNorm und NDC), die MedicationRequest, um die gebeten wird, der Patient, der Verordner, der Zahlungspflichtige und der Abdeckungsschutz sowie die Antworten als QuestionnaireResponse mit allen Anlagen als DocumentReferences. Es wird dann entschieden, wie jede vorherige Genehmigung auf diesem Server: Die Regeldatei, ein Entscheidungsdienst (-pas-decider-url), oder die Prüferwarteschlange, in der es als Medikament markiert und an die Medikamentzeitrahmen gebunden wird. Ein Entscheidungsdienst sieht eine Medikamentenanfrage genau so, wie er sie von einem PAS-Client eines EHRs sieht. Wir empfehlen Vaglio, BioDreams quelloffene (PolyForm Shield) Entscheidungs-Engine, die Medikamentenrichtlinien mit Stufentherapie hat; eine eigene Engine eines Zahlungspflichtigen kann über dieselbe -pas-decider-url eingebunden werden und keine ist erforderlich, damit die Regeldatei und die Prüfer entscheiden.

Eine Entscheidung, die nach der Beantwortung der Anfrage getroffen wird (eine des Prüfers, eine Berufung), wird dem Verordner als unverlangte PAResponse oder PAAppealResponse gesendet, die an den Kanal gesendet wird, der durch -epa-reply-channel benannt wird, der sie an das Netzwerk liefert. Ohne diesen oder wenn die Lieferung fehlschlägt, sagt der Fall, dass der Verordner nicht informiert wurde und der Bildschirm sendet sie erneut.

Zahlungspflichtige › Medikamente › Vorabgenehmigung sendet die Nachrichten, die das System eines Verordners an diesen Server-Endpunkt senden würde (Start, Beantworten der Fragen, Entscheidung anzeigen), listet jeden Fall mit dem auf, was dem Verordner mitgeteilt wurde, und zeigt die Medikamenten-Zahlen an, die CMS-0062-P vorschlägt: Anfragen genehmigt, abgelehnt und ausstehend, Berufungen und genehmigt oder abgelehnt bei der Berufung, die mittleren und medianen Stunden von der Anfrage bis zur Entscheidung und wie viele zu spät entschieden wurden. Medikamente mit medizinischem Vorteil, die über PAS angefordert werden (ein HCPCS-J-Code mit einer MedicationRequest oder ein in RxNorm oder NDC codiertes Element), werden auch in den PAS-Zahlen als Medikamente gezählt.

Was dies begründet, klar ausgedrückt. NCPDPs Schemata und Implementierungsleitfäden sind lizenziert. Die Elementnamen und die Reihenfolge hier folgen den öffentlichen Surescripts-ePA- und RTPB-Begleitleitfäden und deren Beispielen sowie NCPDPs öffentlichen RTPB-Empfehlungen. Zwei Elemente, die das öffentliche Material nie zeigt, sind dem SCRIPT-Muster geschrieben, das anderswo verwendet wird, und sollten vor der Zertifizierung gegen eine lizenzierte Kopie überprüft werden: Closed/ReasonCode und Denied/DenialReason. Keine Nachricht wurde gegen NCPDPs XSD oder eine Netzwerkzertifizierung überprüft. Die NCPDP-Formulare- und Vorteilsdatei wird nicht erstellt: Die vollständige Layout ist in NCPDPs lizenziertem Leitfaden enthalten und eine teilweise Datei würde vom Netzwerk, das sie lädt, abgelehnt.

16.9 Was überprüft wurde und gegen was

Die CARIN- und PDex-Ausgaben wurden mit dem offiziellen HL7-FHIR-Validator validiert, der mit den veröffentlichten Paketen (hl7.fhir.us.carin-bb#2.2.0, hl7.fhir.us.davinci-pdex#2.2.0) geladen wurde: professionelle, stationäre und ambulante Ansprüche und zwei PAS-Entscheidungen, ohne Fehler. Die PDex-Eingaben waren die eigenen Beispiele des PAS-Leitfadens und nicht die Formen, die hier geschrieben wurden, um mit dem Konverter übereinzustimmen. Der Validator fand fünf Mängel beim ersten Lauf – darunter, dass CARIN das Profilversion in meta.profile und die Version des Claim-Typ-Code-Systems auf institutionellen Ansprüchen erfordert – und jeder ist behoben und von einem Test abgedeckt.

Beim Aufbau wurde ein älterer Mangel gefunden: der FHIR-Speicher ließ jedes Element fallen, das sein internes Modell nicht deklarierte, so dass ein ExplanationOfBenefit seine Elemente, Diagnosen, Abrechnung und Zahlung auf dem Weg verlor. Der Speicher behält jetzt alles, was eine Ressource trägt, und ein Test lädt einen CARIN-Anspruch durch den Server und liest ihn wieder vollständig.

CRDs Ausgabe - die aktualisierte Bestellung und die CDS-Hooks-Antwort gegen CRDs eigenes logisches Modell - und DTRs Paketausgabe sind gültig im offiziellen HL7-Validator gegen CRD 2.2.1 und DTR 2.2.0 mit keinen Fehlern.

DTR ist hier die Seite des Zahlungspflichtigen von 2.2.0. $questionnaire-package nimmt die benannten Fragebögen, die CRD benannt auf einer Bestellung oder die Abdeckungsbekundungs-ID CRD zurückgegeben (context, während der gleiche Prozess CRD bedient), und gibt jeden als Paketbundle mit einer QuestionnaireResponse zur Ausfüllung zurück, die Bibliotheken, die CQL benötigt, und deren Abhängigkeiten. Die Werte, die ihre Antworten verwenden, reisen im Paket, wenn sie geladen werden (PUT /fhir/ValueSet/{id}), und $expand listet ihre Codes auf. $log-questionnaire-errors schreibt, was eine DTR-App an den Server-Log meldet.

Adaptive Fragebögen: schreiben Sie den gesamten Fragebogen einmal, mit SDCs questionnaireAdaptive-Erweiterung und enableWhen auf den Fragen, die nur manchmal anwendbar sind. Das Paket übergibt der App eine leere Hülle, und jeder $next-question-Aufruf fügt die nächste Frage hinzu, die auf die Antworten bisher anwendbar ist, bis nichts mehr zu fragen ist und die Antwort als abgeschlossen markiert ist. Die Reihenfolge und die Verzweigung sind die eigenen Regeln des Zahlungspflichtigen; Fragen, die nicht anwendbar sind, werden nie angezeigt.

Anmelden als Client: DTR- und PAS-Clients erreichen den Zahlungspflichtigen mit SMART-Backend-Services - ein signierter JWT wird gegen ein Token auf dem Autorisierungsserver des Zahlungspflichtigen ausgetauscht. Richten Sie Perfuse auf diesen Server mit -smart-issuer (und -smart-jwks, wenn die Adresse nicht von Perfuse aufgelöst wird) und übergeben Sie -smart-backend-services, damit das Discovery-Dokument dies angibt. Der Inferno-DTR-Suite geht auf diese Weise mit Keycloak als Autorisierungsserver vor.

Perfuse kann selbst dieser Autorisierungsserver sein: serve -fhir -smart-clients clients.yaml gibt Backend-Services-Tokens an /auth/token für die aufgelisteten Clients aus, jeweils mit den öffentlichen Schlüsseln, mit denen es seine Aussagen signiert, und den Systemberechtigungen, die ihm gewährt werden können, und der FHIR-Endpunkt akzeptiert sie. Es ist kein separates Identitätsserver für die maschinellen Clients des Zahlungspflichtigen erforderlich.

Mit -smart-users users.yaml ebenfalls, melden sich Mitglieder und Kliniker dort an, um Apps zu autorisieren, die die Patient Access API benötigt: die App sendet die Person an /auth/authorize, sie melden sich an, ein Kliniker wählt den Patienten aus und beide sehen, worum die App bittet und können jedes davon abwählen. Ein Mitglied erhält immer nur seine eigene Akte, unabhängig davon, worum die App bittet. Jede Person in der Datei benennt die FHIR-Ressource, die sie ist, Patient/… oder Practitioner/…, und einen Passwort-Hash aus perfuse smart hash; das Passwort selbst wird nie aufgeschrieben.

Personen können sich auch bei dem Identitätsanbieter der Organisation anmelden: -smart-oidc oidc.yaml benennt ihn (Aussteller, Client-ID und Ort, an dem das Geheimnis ist), und die Anmeldeseite bietet "Anmelden mit" ihm neben dem Passwort an. Jede Person wird durch das Subjekt des Anbieters, oidc_subject in der Benutzerdatei, verknüpft, sodass die Datei weiterhin entscheidet, wer Apps autorisieren und welche FHIR-Ressourcen sie sind; ein Konto, das niemandem zugeordnet ist, wird abgelehnt. Codes, Aktualisierungstoken und Widerrufe werden in der Datenbank gespeichert, sodass ein Neustart niemanden abmeldet.

Benutzer → SMART-Apps in der Konsole listet die registrierten Apps und Personen auf und fügt, bearbeitet und entfernt sie. Jedes Speichern wird wie die Dateien bei der Startseite überprüft, in sie geschrieben und sofort verwendet. Eine vertrauliche App, die ohne Geheimnis gespeichert wird, erhält eines, das einmal angezeigt wird; ein Passwort wird dort festgelegt und nie wieder angezeigt. Das Entfernen einer App oder einer Person stoppt die bereits ausgestellten Zugriffstoken für sie oder durch sie sofort, nicht wenn sie ablaufen, und ihre Aktualisierungstoken mit ihnen.

Berechtigungen können granular sein, wie SMART App Launch 2 und US Core sie definieren: patient/Observation.rs?category=laboratory liest nur die Observationen, die diese Suche finden würde. Eine Gewährung, die für einen Typ filtert, wendet ihren Filter auf jede Suche und jeden Lesevorgang dieses Typs an; eine unfilterte Gewährung für den Typ oder für * hebt sie auf. Ein Filter, der nicht gelesen werden kann, gewährt nichts anstelle von allem.

16.10 Entscheidung über vorherige Autorisierungsanfragen: PAS

serve -fhir -pas -crd-rules rules.yaml antwortet auf Da Vinci PAS 2.2.1 bei POST /fhir/Claim/$submit und POST /fhir/Claim/$inquire. Die Entscheidungen stammen aus der gleichen Regeldatei wie CRD's Antworten, sodass die Reihenfolge, in der einem Kliniker mitgeteilt wird, dass eine Genehmigung erforderlich ist, durch die Regel entschieden wird, die dies angegeben hat:

  - 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

Jedes Element erhält eine X12-Überprüfungsaktion: A1 zertifiziert, A3 nicht zertifiziert, A4 ausgestellt, A6 geändert, C storniert (Zertifizierungstyp 3). Eine Zeile, die keinen Dienst benennt, wird nicht entschieden, sondern mit einem Fehler beantwortet (X12 901 AG, korrigieren und erneut senden). Die Antwort wiederholt, was eine 278-Antwort wiederholt - Elementspurnummern, die angeforderten Dienstdaten, die Datumsangaben des Kontakts, die Übertragungsidentifikatoren mit vertauschten Absender und Empfänger - und gibt jedem Element die eigene Verwaltungsreferenznummer des Zahlungspflichtigen. Ein Dienst, den keine Regel benennt, wird ausgestellt, nie genehmigt: eine Entscheidung, die niemand aufgeschrieben hat, ist eine Entscheidung für eine Person.

Ausgestellte Anfragen warten auf einen Prüfer, der mit POST /fhir/Claim/$decide antwortet:

{"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 kann auch modify sein: zertifiziert, aber nicht wie angefordert, mit quantity (valueDecimal, die zertifizierten Einheiten) und/oder alternative (valueCoding, der genehmigten Dienst anstelle). Die Antwort sagt dann A6 geändert, mit dem zertifizierten Detail oder der Alternative als hinzugefügtem Element und einer Autorisationsnummer. item (valueInteger, wiederholbar) beschränkt die Entscheidung auf einige Zeilen. Die Entscheidung wird zu einer neuen Version der Antwort, markiert als von einer Person überprüft, und mit -fhir-subscriptions wird sie auf dem PAS-Topic (PASSubscriptionTopic, gefiltert von org-identifier, dem Identifier der anfragenden Organisation) als vollständiges PAS-Antwort-Bundle in der gleichen Transaktion geliefert, die es aufzeichnet. $inquire gibt die aktuelle Antwort auf jede Anfrage zurück, die der Anbieter über dieses Mitglied gestellt hat; eine Anfrage eines anderen Anbieters findet nichts. $decide benötigt einen Schreibbereich; $inquire ist ein Lesen.

Anfragen und jede Version ihrer Antworten werden in pas_requests und pas_responses in der Datenbank des Servers gespeichert.

16.10.1 Die Prüferwarteschlange

Im Web-Console listet Payers → CMS-0057 → Reviewer-Warteschlange die ausstehenden Anfragen in der Reihenfolge ihrer Fälligkeit: Eine beschleunigte Anfrage (Claim.priority stat) ist 72 Stunden nach Eingang fällig, eine Standardanfrage nach 7 Tagen. Die Auswahl einer Anfrage zeigt das Mitglied, den Anbieter, jeden Dienst mit den angeforderten Einheiten und dem aktuellen Status, die angeforderte Antwort und jedes für diese Anfrage empfangene Dokument, wobei Textdokumente inline angezeigt werden. Ein Editor nimmt die Entscheidung dort vor: Genehmigen, Ablehnen oder Ändern (zertifizierte Einheiten oder ein anderer genehmigter Dienst), mit einem Grund und der NPI des Reviewers. Eine Änderung muss weniger Einheiten zertifizieren als angefordert; so viele oder mehr sind eine Genehmigung und werden als Änderung abgelehnt. Ein genehmigter Dienst beginnt im Codesystem des angeforderten Dienstes. Es ist dieselbe Entscheidung, die $decide trifft, sodass die Abonnement des Anbieters diese liefert. Das Lesen einer Anfrage und die Entscheidung darüber werden beide im Audit-Log aufgezeichnet.

Monitor → Team-Dashboards → Priorisierung zeigt für die letzten 30 Tage, wie viele Standard- und beschleunigte Anfragen innerhalb der CMS-0057-Fristen entschieden wurden, verspätet entschieden wurden, noch innerhalb der Frist warten und jetzt überfällig sind, mit der Median-Entscheidungszeit und wie die angeforderten Dienste beantwortet wurden: Genehmigt, geändert, abgelehnt oder noch ausstehend. Diese beiden Kacheln werden direkt aus den Anfragen selbst gelesen, sodass sie nicht in der Grafana-Export der Dashboard enthalten sind, was in der Beschreibung vermerkt ist.

16.10.2 Empfangen der Dokumente, die eine ausgestellte Anfrage anfordert

Eine ausstehende Antwort fordert Dokumente mit einer Aufgabe und einer Kommunikationsanfrage pro Dokument. Ein Fragebogen wird wie von PAS beschrieben angefordert: eine Kommunikationsanfrage mit dem einzigen LOINC-Code 102089-0, unter der Zeichenspur der Zeile, für die sie bestimmt ist (itemTraceNumber, die die ClaimResponse echoiert; eine Zeile, die ohne eine solche gesendet wird, erhält eine solche). Diese Zeichenspur ist der DTR-Kontext: $questionnaire-package mit nur context auf sie gesetzt, gibt den Fragebogen zurück. Der Anbieter sendet, was angefordert wurde, mit Da Vinci CDex $submit-attachment (POST /fhir/$submit-attachment): die TrackingId ist die eigene Zeichenspur der Anfrage (die erste Identifikation der ClaimResponse, die auch die der Aufgabe ist), oder eine Identifikation der Kommunikationsanfrage, AttachTo ist preauthorization, und MemberId muss das Mitglied der Anfrage sein. Jedes Anhangs-Dokument oder jede Fragebogenantwort wird mit der Anfrage gespeichert und ihrem Prüfer gezeigt; ein ankommendes Dokument entscheidet nichts.

16.10.3 Entscheidung in einem X12-Nutzungsmanagement-System

Die meisten Zahlstellen entscheiden über Vorabgenehmigungen in einem UM-System, das X12 278 spricht. Mit -pas-278-url ist Perfuse die FHIR-Schnittstelle dieses Systems: Jedes $submit wird als eine 278-Anfrage (005010X217) gesendet, wobei jedes Element ein Patientenereignis darstellt. Jedes trägt die von PAS dafür benannten Informationen: den Überprüfungstyp (extension-serviceItemRequestType, UM01: Gesundheitsdienste, Aufnahme oder Fachpflege), den Zertifizierungstyp (extension-certificationType, UM02), den Dienstleistungstyp, den Ort der Dienstleistung (UM04), den Dienstleistungsgrad (extension-levelOfServiceCode, UM06: elektiv, dringend oder Notfall; eine stat-Priorität steht für dringend), das Datum, die Aufnahmedaten und Entlassungsdaten einer Aufnahmeverification, die Diagnosen, den Leistungserbringer, der die Dienstleistung durchführen wird, und das Verfahren und die Menge, als professionelle (SV1) oder, bei einer institutionellen Abrechnung, als Krankenhaus (SV2)-Dienstleistungszeile. Die Antwortcode- und Autorisationsnummer der 278-Antwort werden zur Überprüfungsaktion des Elements: zertifiziert, teilweise oder geändert, abgelehnt, ausgesetzt, storniert oder nicht berücksichtigt (ausgesetzt für einen Prüfer, mit Ablehnungsgründen). Lokale Regeln werden nicht konsultiert.

perfuse serve -fhir -pas -pas-278-url https://um.example/x12/278 -pas-278-receiver ACMEUM \
  -pas-278-token-env UM_TOKEN

Ein UM-System, das zunächst aussteht und später entscheidet, sendet seine spätere 278-Antwort an POST /fhir/Claim/$decide-278; jedes Ereignis wird seinem Antrag durch die Spurnummer, die Perfuse gesendet hat, zugeordnet und wie $decide entschieden. Wenn das UM-System nicht erreicht werden kann oder mit etwas antwortet, das keine 278-Antwort ist, wird jedes Element für einen Reviewer ausgestellt und dem Anbieter wird nur mitgeteilt; der Grund ist im Server-Log.

Anfragen, die das UM-System beantwortet

Ein Anbieter muss seine $inquire-Anfrage so finden, wie sie gestellt wurde: per Fax, über das Portal des Zahlungspflichtigen, per Telefon oder in einer 278-Anfrage, die ein anderer Antragsteller gesendet hat. Perfuse speichert nur die Anfragen, die durch es selbst gestellt wurden; das UM-System speichert alle. Mit einem UM-System, das in Echtzeit antwortet (jeder Transport außer sftp), wird jede $inquire-Anfrage auch dorthin als 278-Anfrage (005010X215: BHT02 28, das Mitglied, der Anbieter, die Autorisierungsnummer aus dem insurance.preAuthRef des Claims, wenn vorhanden, und die Ereignisdaten aus billablePeriod oder den Service-Daten der Artikel, andernfalls ein Jahr vor oder nach heute) gesendet. Jede Autorisierung, die die Antwort enthält, die Perfuse nicht hat (abgestimmt durch die von ihm gesendeten Nachverfolgungsnummern und die bereits erteilten Autorisierungsnummern), wird als weitere Claim-Inquiry-Response-Bundle zurückgegeben: die Entscheidung des UM-Systems für jede Service-Zeile, die Autorisierungsnummer und -periode sowie eine Notiz, die angibt, wo sie gefunden wurde. Kein Claim wird für eine Autorisierung erstellt, die niemand in FHIR eingereicht hat: sein ClaimResponse.request enthält einen Grund für das Fehlen von Daten, wie es in PAS-Profilen erlaubt ist. Eine Anfrage liest nur; nichts in den eigenen Aufzeichnungen von Perfuse ändert sich. Wenn das UM-System down ist oder mit einem TA1 oder 999 antwortet, erhält der Anbieter, was Perfuse speichert, und der Status des Links gibt den Grund an. Die Form folgt den 278-Anfrage-Begleitanleitungen, die UnitedHealthcare, Cigna und Blue Cross Blue Shield of Massachusetts veröffentlichen; sie wurde noch nicht gegen ein reales UM-System getestet.

Wie die 278er den UM-System erreichen

Die Konnektivitätsanleitung des UM-Systems sagt, wie es 278s benötigt, und -pas-278-transport (Einstellungen, Payer, Verwaltungslink) folgt ihm:

TransportWas gesendet wirdAuthentifizierung
x12 (Standard)Die 278-Anfrage als application/edi-x12; die Antwort ist der AntworttextEin Bearer-Token, OAuth, HTTP-Basic, ein Clientzertifikat
core-soapDie CAQH-CORE-Echtzeit-SOAP-1.2-Hülle (COREEnvelopeRealTimeRequest, Payload-Typ X12_278_Request_005010X217E1_2 oder X12_278_Request_005010X215 für eine Anfrage): Connectivity-Regel vC2.2.0 mit der Payload in der Hülle, die die meisten Zahlungspflichtigen und CMS esMD verwenden, oder -pas-278-core-version C4.0.0 mit der Payload als MTOM-AnhangvC2.2.0: ein Benutzername und ein Passwort (WS-Sicherheit-UsernameToken) oder ein Clientzertifikat. vC4.0.0: ein Clientzertifikat und ein OAuth-Token
core-mimeDie CAQH-CORE-vC2.2.0-HTTP-MIME-Multipart-Hülle, die Payload als DateiteilDer Benutzername und das Passwort der Hülle oder ein Clientzertifikat
sftpJede 278-Anfrage in einem Ordner auf dem SFTP-Server des UM-Systems (-pas-278-sftp, -pas-278-sftp-outbound); die Antworten werden aus einem anderen Ordner gesammelt (-pas-278-sftp-inbound, jedes -pas-278-sftp-every)Ein SSH-Schlüssel oder ein Passwort; der Schlüssel des Servers muss in -pas-278-sftp-known-hosts sein

Ein Clientzertifikat ist -pas-278-cert und -pas-278-key; -pas-278-ca vertraut einer eigenen Zertifizierungsstelle des Payers. OAuth ist -pas-278-oauth-token-url, -pas-278-oauth-client-id und das Geheimnis, abgerufen mit dem client-credentials-Grant und aufbewahrt, bis es eine Minute vor dem Ablaufdatum abläuft. Passwörter, Token und Geheimnisse werden nie als Flags verwendet: Jedes wird durch eine Umgebungsvariable benannt (-pas-278-password-env, -pas-278-token-env, -pas-278-oauth-secret-env, -pas-278-sftp-password-env), oder in das Einstellungsbildschirm eingegeben, wo es in der Einstellungsdatei (lesbar nur durch das Konto des Servers) aufbewahrt wird und nie wieder angezeigt wird.

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

Über SFTP wird jede Anfrage bis zur Ankunft der Antwort gepuffert: Die 278-Antwort entscheidet über die Elemente, und Perfuse legt eine 999, die sie akzeptiert, in den Ausgangsordner. Eine Datei, die nicht gelesen werden kann, bleibt im Eingangsordner für eine Person und wird beim nächsten Lesen erneut angeboten.

Wenn das UM-System eine Anfrage nicht lesen kann

Ein UM-System, das eine 278 nicht lesen kann, antwortet mit einer TA1 (der Hülle) oder einer 999 (der Transaktion) anstelle einer Entscheidung. Perfuse liest, welche und was sie sagt, puffert jedes Element („die Nutzungsverwaltung konnte die Anfrage nicht lesen“) und zeichnet es auf. Payer, CMS-0057, Reviewer-Warteschlange zeigt den Link: Was in den letzten sieben Tagen gesendet wurde, jede Interchange nach ihrer Kontrollnummer und was daraus wurde (beantwortet; bestätigt, Antwort zu kommen; abgelehnt, mit dem 999-Segment, -Element und -Code; nicht erreicht). Jede Interchange hat ihre eigene Kontrollnummer, eine mehr als die letzte, die von einer TA1 oder 999 bei der Antwort genannt wird.

16.10.4 Entscheidung auf der Grundlage der klinischen Beweise, mit einem Entscheidungsdienst

Eine Regeldatei entscheidet nach Dienstcode: Ein Code benötigt keine Autorisierung, ist nicht abgedeckt oder geht an einen Reviewer. Ob dieser Patient die Kriterien für diesen erfüllt, ist eine andere Frage, die aus den Bedingungen, Fragebogenantworten und Dokumenten beantwortet wird, die der Anbieter mit dem Antrag gesendet hat. Mit -pas-decider-url wird jedes Element, das die Regeln einem Reviewer überlassen, zunächst an einen Entscheidungsdienst übergeben, wie z. B. Vaglio, der das gleiche PAS-Antrags-Bundle durch Perfuse's veröffentlichtes pas-Paket liest. Ein öffentliches Vaglio, das nur auf erfundenen Anträgen läuft, läuft neben Perfuse's Testinstanz unter https://vaglio.perfuse.health:8443 (Anmelden als demo, Passwort try-vaglio-demo; es kann alles anzeigen und nichts ändern): Jede Entscheidung dort hat ihren Nachweis, einen Klartextbrief und eine Quittung, die jeder überprüfen kann.

perfuse serve -fhir -pas -crd-rules payer-rules.yaml -pas-decider-url https://vaglio.example/api/pas/decide \
  -pas-decider-token-env VAGLIO_TOKEN

Die URL muss https sein oder plain http zu diesem Computer (localhost, 127.0.0.1), da sie einen Patientenrecord und den Token enthält. Vaglio selbst antwortet nur auf https; wenn es ein Zertifikat von seiner eigenen Autorität verwendet, muss diese Autorität mit -pas-decider-ca DATA/tls/ca.crt übergeben werden (oder jede interne Autorität des Payers, von der das Zertifikat des Dienstes stammt). Der Dienst erhält das Antrags-Bundle als der Anbieter es gesendet hat, POST <url>?item=<sequence> (application/fhir+json), und antwortet {"decision": "approve" | "deny" | "pend", "why": "...", "requested": ["..."]}, oder 404, wenn es für dieses Element nichts entscheidet, was die Antwort der Regeln stehen lässt. why ist die Prozessnotiz der Antwort und ist für eine Ablehnung erforderlich, die sonst ausgestellt wird; requested wird dem Anbieter als die Information mitgeteilt, die ein ausstehender Antrag benötigt. Eine Ausstellung kann auch "questionnaire": "<canonical>" und "attachments": ["<LOINC>", ...] enthalten, die in der Antwort-CDex-Aufgabe und Kommunikationsanfragen neben jeder DTR-Fragebogen oder Anlagen, die die Regel anfordert (die Regel-Fragebogen gewinnt, da eine Aufgabe eine anfordert; ein Code, der nicht LOINC's Form hat, wird abgelehnt und protokolliert). Eine Regel, die genehmigt oder ablehnt, ist die Abdeckungspolitik des Payers und wird nicht an den Dienst gesendet. Ein Fehler, ein Timeout oder eine Antwort, die keine der drei Entscheidungen ist, stellt das Element für einen Reviewer aus, mit dem Grund im Server-Log: Nichts hier wandelt einen Fehler in eine Genehmigung um. Es kann nicht mit -pas-278-url kombiniert werden, wo das UM-System jedes Element beantwortet.

Rat vor dem Senden. Mit -crd-advisor-url neben -crd-rules fragt CRD auch einen Entscheidungsdienst, was eine Priorisierungsanfrage für jede Bestellung, die eine benötigt, mitgeteilt werden würde, wenn der Record so steht, und zeigt die Antwort als eine weitere Karte an: "Bevor Sie senden: Eine Anfrage für dies würde benötigen: ...", oder "würde genehmigt", mit dem, was noch benötigt wird, dem Fragebogen, der danach fragt, und was genehmigen würde. Vaglio antwortet unter /api/pas/advise, mit dem gleichen Token und der gleichen Autorität wie oben:

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 sendet POST <url> mit {"service": {"system": "...", "code": "..."}, "resources": [ ... ]}, die Ressourcen sind der Haken der Prefetch (der Patient zuerst, die Abdeckung links ausgelassen), und liest {"decides": true, "answer": "approve" | "pend" | "deny", "summary": "...", "missing": [...], "questionnaire": "...", "toApprove": [[...]], "policyTitle": "..."}. Es ist ein Rat und ändert nichts: Die Abdeckungsinformation, die anderen Karten und die PAS-Entscheidung sind, was die Regeln sagen. Es wartet höchstens drei Sekunden, und keine Antwort, ein Fehler oder "decides": false lässt die Antwort genau so, wie sie ist, ohne sie. Perfuse benötigt nie einen Entscheidungsdienst.

Die Anfrage enthält X-PAS-Request-Id, die ID, durch die die Antwort bekannt ist. Ein Dienst mit eigenen Reviewern, der ein Element zurückhält, kann seine Entscheidung später senden, wie es jeder Reviewer sendet: Claim/$decide mit dieser ID als claimResponse, der Sequenz des Elements und der Entscheidung und Begründung. Das Abonnement des Anbieters liefert es, als ob es in der Reviewer-Warteschlange erstellt worden wäre.

Ein Abonnement mit id-only-Inhalt teilt dem Anbieter mit, welche Antwort geändert wurde, ohne zu sagen, was sie ist: der Fokus der Benachrichtigung ist Bundle/<id>. GET /fhir/Bundle/<id> gibt das neueste PAS-Antwort-Bundle zurück, GET /fhir/Bundle/<id>/_history/<n> die Version, die eine Benachrichtigung gesendet hat, und GET /fhir/ClaimResponse/<id> die ClaimResponse allein. Ein Token, das an einen Patienten gebunden ist, wird informiert, dass es nicht existiert, wie bei jedem Datensatz außerhalb seines Patienten.

Verifiziert mit dem offiziellen Inferno PAS Server v2.2.1 Suite (siehe Verifizierung). Nicht gesendet, obwohl PAS sie als must-support markiert: ClaimResponse.adjudication mit einer Überprüfungsaktion, ClaimResponse.extension:authorizedProvider und ClaimResponse.item.extension:communicatedDiagnosis, weil die Erweiterungen, die sie benötigen, nicht in ihrem eigenen Kontext in PAS 2.2.1 und der Validator lehnt eine Antwort ab, die sie enthält; und request.extension:DataAbsentReason, weil Perfuse immer die Anfrage kennt. Die 278er, die an ein Nutzungsverwaltungssystem (oben) gesendet werden, werden gegen PAS 2.2.1 eigene Anfragebeispiele, CMS veröffentlichte esMD 278 Beispiele und ein 278-Prüfer, der aus öffentlichen Begleitlektüren erstellt wurde, überprüft, und jeder Transport gegen ein Ersatz-UM-System, das aus CAQHs Konnektivitätsregeln erstellt wurde (siehe Verifizierung); noch nicht gegen ein reales UM-System oder Clearinghouse und nicht CORE-zertifiziert. Nicht implementiert: Anlagen, die mit CDex zurückgesendet werden.

Eine Regeldatei wird bei der Initialisierung gegen die eigenen Invarianten von CRD überprüft: ein Fragebogen benötigt eine Dokumentation, ein Dienst, der nicht abgedeckt ist, kann keine Autorisierung benötigen, satisfied gehört zu einem Fall und nicht zu einer Regel, und alles Bedingte muss einen Grund angeben.

Nicht verifiziert: die Exporte und die Mitgliedermatching gegen eine Implementierung eines anderen Zahlungsträgers, die Metriken gegen die veröffentlichten Zahlen eines Zahlungsträgers und CRD gegen einen echten CDS-Hooks-Client einer EHR.

16.11 Senden von Genehmigungsanfragen an einen Zahlungspflichtigen (für Anbieter)

Alles oben beantwortet Anfragen als Zahlungspflichtiger. Die Seite eines Anbieters ist umgekehrt: eine EHR oder eine DTR-App erstellt ein Da Vinci-PAS-Anfrage-Bündel, und etwas muss es an den Zahlungspflichtigen senden, die Antwort aufbewahren und weiterleiten. Ein pas-Ziel tut dies.

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

Jede Nachricht muss ein vollständiges PAS-Anfrage-Bundle auf einem rohen Kanal sein. Perfuse sendet es unverändert an {payer}/Claim/$submit: Der Payer entscheidet über den Anspruch zusammen mit dem Patienten, der Abdeckung und den unterstützenden Ressourcen im Bundle, und ein Anspruch, der aus einer Zusammenfassung neu erstellt wird, würde sie verlieren. Außerhalb dieser Maschine muss die Adresse des Payers https sein.

Eine Entscheidung ist eine zugestellte Anfrage, egal was sie besagt. Eine Genehmigung, eine Ablehnung und ein Zurückstellen werden alle aufgezeichnet und keine wird erneut versucht, da das erneute Versuchen einer Ablehnung die gleiche Anfrage zweimal übermittelt. Was die Zustellung verhindert und erneut versucht wird, ist ein Zahlungspflichtiger, der keine Entscheidung getroffen hat: ein Fehlerstatus, ein OperationOutcome (dessen Text der Fehler ist) oder ein ClaimResponse, dessen Ergebnis error ist. Die Entscheidung wird Zeile für Zeile aus den PAS-Überprüfungsaktionscodes (X12 306: A1 genehmigt, A2 teilweise, A3 abgelehnt, A4 zurückgestellt, A6 geändert) gelesen; eine Antwort ohne Code wird als "kein Entscheidungscode" aufgeführt, anstatt als Genehmigung angenommen. Eine Ablehnung ohne Grund wird als nicht den Anforderungen von CMS-0057 entsprechend abgelehnt.

Die Antwort des Zahlungspflichtigen ist die Antwort des Ziels, sodass Antwort überprüfen sie beurteilen kann, und results_to übergibt sie an einen anderen Kanal. Jede Anfrage wird auf CMS-0057, Anfragen an Zahlungspflichtige gesendet aufgeführt: wann sie gesendet wurde, der Patient, der Dienst, die Entscheidung und die Referenz des Zahlungspflichtigen (preAuthRef), die eine spätere Anfrage benennt. Die Liste wird in prior-auth.json neben der Datenbank gespeichert (maximal 10.000 Anfragen; die ältesten entschiedenen Anfragen gehen zuerst, eine ausstehende Anfrage nie), und jeder Mandant sieht nur seine eigene.

Verifiziert gegen die HL7 Da Vinci PAS-Payer-Referenzimplementierung (Docker-Image hlseven/davinci-prior-auth): Eine über einen laufenden Kanal gesendete Anfrage wird von diesem mit seiner Referenz angehalten und die Antwort wird auf dem Bildschirm angezeigt (siehe Verifizierung). Noch nicht gegen einen Produktions-Payer getestet. Noch nicht erstellt: Eine angehaltene Anfrage mit $inquire nachverfolgen oder die spätere Antwort des Payers durch Abonnement empfangen; ein Kanal kann beides heute mit einem http- oder fhir-Ziel tun.

16.12 CMS-Aligned Networks

Das CMS-Interoperabilitätsframework (CMS Health Technology Ecosystem) fordert Gesundheitsdatennetze auf, sich selbst gegen 26 Kriterien zu überprüfen und als CMS-Aligned Networks aufgeführt zu werden; EHRs, Anbieter, Zahlungsträger und Apps verbinden sich mit ihnen. Kriterien 13 bis 16 sind seit dem 4. Juli 2026 in Kraft: FHIR-APIs auf US Core mit einer vollständigen CapabilityStatement und Bulk Data, Dokumente als menschenlesbare FHIR-Anlagen, Termin- und Begegnungsbenachrichtigungen durch FHIR-Abonnement und ein Aufzeichnungslokalisierer.

Verwalten › CMS-Aligned Network listet jedes Kriterium mit dem auf, was Perfuse dafür bereitstellt, und wo dieser Server steht, gelesen von dem, was hier eingeschaltet ist:

StatusBedeutung
Bereit hierPerfuse stellt es bereit und es ist eingeschaltet.
Bereit, mit einer LückeEs ist eingeschaltet, und ein Teil des Kriteriums liegt außerhalb davon (auf dem Bildschirm benannt).
Erstellt, nicht eingeschaltetPerfuse stellt es bereit; der Bildschirm benennt die Einstellung oder den Schalter, der es einschaltet.
Ihre AufgabeDer Teil der Organisation: eine Vereinbarung, eine Zertifizierung, Veröffentlichung im Nationalen Anbieterverzeichnis.
Nicht erstelltSoftware würde es tun, und Perfuse tut es nicht.

Was die vier in Kraft gesetzten Kriterien von diesem Server benötigen:

KriteriumIn PerfuseEinschalten
13 FHIR-APIs, US Core, Bulk DataDer FHIR-Endpunkt mit seinem CapabilityStatement und $export-fhir, -fhir-bulk-export
14 Dokumente als FHIR-AnhängeDocumentReference mit Binary und IHE MHD über das XDS-Register-fhir (MHD auch -xds)
15 Begegnungs- und TerminbenachrichtigungenThemenbasierte Abonnements (R5-Backport für R4) von ADT- und SIU-Feeds-fhir-subscriptions
16 AufzeichnungslokatorDas XDS.b-Register, XCA für andere Gemeinschaften, PIXm-xds, -xds-home-community

Der Bildschirm ist ein Arbeitsblatt für die Überprüfung, nicht eine Zertifizierung: CMS überprüft Netze, von denen es vermutet, dass sie die Kriterien nicht erfüllen, und der Text des Frameworks ist die Autorität. Noch nicht gebaut: offene Qualitätslückenabfragen (Kriterium 8), eine Abfrage eines Zahlungsträgers für Begegnungsdaten eines Anspruchs (9), Berichtsmetriken an das National Provider Directory (19), Überprüfung von Anbietern gegen dieses Verzeichnis (6), Lesen von mobilen Führerscheinen oder digitalen Versicherungskarten (3, 23) und Durchsetzen einer allgemeinen Zustimmungsrichtlinie für jeden Lesevorgang (5). IAL2-Identitätsüberprüfung ist der Identitätsdienst; Perfuse akzeptiert die Token des von Ihnen gewählten Dienstes.

17 Sicherheit

Perfuse behandelt klinische Daten. Dieses Kapitel beschreibt, was es damit macht und was es Ihnen überlässt.

17.1 Transportsicherheit

TLS im Webinterface wird mit -tls-cert und -tls-key konfiguriert. Ohne diese ist das Interface einfaches HTTP, was auf einer Loopback-Adresse für einen ersten Blick akzeptabel ist, aber nirgendwo anders – es enthält Anmeldeinformationen und Nachrichteninhalte, die beide im Klartext lesbar sind.

TLS auf Kanaltransporten ist pro Quelle und pro Ziel, unter einem tls-Block. Die verfügbaren Einstellungen sind in den Quellen und Zielreferenzen aufgeführt.

insecure_skip_verify akzeptiert jedes Zertifikat. Es existiert, weil Krankenhaus-Systeme routinemäßig Zertifikate präsentieren, die nicht verifiziert werden können, und die Verbindung ablehnen würde bedeuten, die Integration ablehnen – Sie haben Schutz vor passiver Abfangung, aber keinen vor einem eingeschobenen Server.

Eine nicht verifizierte TLS-Verbindung ist nicht dasselbe wie eine verifizierte, und der Unterschied ist es wert, ihn irgendwo aufzuzeichnen, wo Ihre Prüfer ihn finden. Die bessere Lösung ist fast immer, das Zertifikat des entfernten Endes zu erhalten und es explizit zu vertrauen, anstatt alles zu vertrauen.

17.2 Authentifizierung und Rollen

Benutzer werden in der Datenbank gespeichert. Jeder hat eine von fünf Rollen, und jede Rolle umfasst alles, was in den Rollen darüber enthalten ist:

RolleKann
MonitorÜberprüfen, ob alles funktioniert: Kanalstatus, Zähler, Flussdiagramm, Warnungen, Dashboards, Metriken und die Tiefe der Warteschlange. Keine Nachrichteninhalte, Kanaldateien oder gewartete Nachrichten.
ViewerAuch Nachrichten lesen, Kanaldateien, Spuren und den Aktivitätsprotokoll.
OperatorAuch erneut senden: eine Nachricht erneut verarbeiten, einen Kanal erneut abspielen und gewartete Lieferungen erneut versuchen.
EditorAuch Kanäle erstellen und ändern sowie Vergleiche durchführen.
AdminAuch Kanäle starten und stoppen, Warteschlangen löschen und Personen, Token und die Servereinstellungen verwalten.

Eine sechste Rolle, Plattform, gehört dem, der einen gemeinsam genutzten Server betreibt: sie erstellt Mandanten und legt ihre Grenzen fest und hält keine Kanäle selbst.

Überwachung ist für eine Hilfsdesk oder für einen Betriebsbildschirm an einer Wand: alles, was benötigt wird, um zu sehen, dass ein Feed gestoppt wurde, und nichts, was einen Patienten nennt. Viewer kann Nachrichteninhalte lesen, was klinische Daten sind; es ist eine Rolle mit geringen Rechten für die *Konfiguration*, nicht für die Privatsphäre. Operator trennt die Reparatur einer fehlgeschlagenen Lieferung in der Nacht von der Änderung dessen, was ein Feed tut: die Person, die erneut sendet, muss nicht in der Lage sein, den Kanal neu zu schreiben.

17.2.1 Wiederholt falsche Passwörter

Falsche Passwörter und fehlgeschlagene Passkey-Anmeldungen werden von der Adresse gezählt, von der die Verbindung stammt, und nach einigen aufeinanderfolgenden muss diese Adresse warten, bevor sie es erneut versuchen darf (die Antwort ist 429, mit Retry-After). Konten werden nicht durch den Namen gesperrt, da dies es jedem ermöglichen würde, einen Administrator absichtlich zu sperren.

Die Adresse ist die eigene der Verbindung, niemals eine, die ein Anfrage in X-Forwarded-For angibt, die der Absender schreibt. Hinter einem Reverse-Proxy auf dem gleichen Gerät verwendet Perfuse den letzten X-Forwarded-For-Eintrag anstelle dessen, den der Proxy hinzugefügt hat, sodass jeder Kunde immer noch separat gezählt wird. Ein Proxy auf einem anderen Gerät erreicht Perfuse von einer Adresse aus, und alle seine Kunden teilen sich eine Zählung: Rate-Limit-Anmeldungen an diesem Proxy.

17.2.2 Kanalgruppen

Eine Person (oder ein API-Token) kann auf bestimmte Kanalgruppen beschränkt werden: sie sehen und handeln dann nur auf die Kanäle, deren group eine der ihren ist. Dies ist die Anordnung einer Krankenhausgruppe auf einem Server, wobei jeder Einrichtung ihre eigenen Analysten hat, die sich um ihre eigenen Feeds kümmern, und ein zentrales Team ohne Beschränkung, das sich um alle von ihnen kümmert. Rhapsody nennt es einen Schließfach.

Die Beschränkung gilt überall auf einmal, da sie auf die Anfrage und nicht auf jedem Bildschirm angewendet wird: die Kanalliste, das Dashboard und der Flussplan, Nachrichten und ihre Suche, Zahlen und Diagramme, die Warteschlange, Warnungen, Metriken, Zertifikate, Verträge und die Verwendung von Codesätzen. Ein Kanal außerhalb der Gruppen der Person existiert für sie nicht; eine Anfrage nach seinem Namen antwortet mit *nicht gefunden*, sodass sein Name auch nicht bestätigt wird. Ein Kanal ohne Gruppe wird nur von Personen mit keiner Beschränkung gesehen.

Das Speichern eines Kanals hält es innerhalb der Gruppen der Person: sie können keinen Kanal in einer anderen Gruppe erstellen oder einen aus ihrer eigenen Gruppe verschieben. Was jede Einrichtung teilt - Code-Tabellen, Skriptbibliotheken, Entscheidungen zur vorherigen Genehmigung - können sie lesen, aber nicht ändern. Serverweite Zahlen (vorherige Genehmigung, Token-Verwendung, Tunnel) werden nur Personen ohne Beschränkung gezeigt, und auch Metriken und Warnungen über den gesamten Server und nicht über einen Kanal.

Ein Administrator, der auf Gruppen beschränkt ist, ist der eigene Administrator einer Einrichtung. Er verwaltet die Personen und Token seiner Gruppen, startet und stoppt ihre Kanäle und löscht ihre Queues. Ein Kollege, den er hinzufügt, erhält seine Gruppen, es sei denn, er nennt einige von ihnen, er kann keine Gruppe zuweisen, die er nicht hat, und er sieht oder ändert niemals jemanden ohne Einschränkung. Alles andere, was ein Administrator tun kann, ändert den gesamten Server - Einstellungen, Anmeldung, Neustart, Warnregeln, Markenbild, Flotte, SMART-Server - und wird ihm verwehrt.

Gruppen werden in Benutzer (und für Token in Token) als kommagetrennte Liste festgelegt. Jede Änderung wird im Aktivitätsprotokoll aufgezeichnet und wirkt sich bei der nächsten Anfrage der Person aus.

Eine andere Rolle in jeder Gruppe

Eine Person kann in jeder ihrer Gruppen eine unterschiedliche Rolle haben: lab=editor, adt in Benutzer bearbeitet die Kanäle des Labors und hat die gewählte Rolle - sagen wir Viewer - in den Aufnahmegruppen. Sie sieht die Kanäle beider Gruppen auf jedem Bildschirm. Das Speichern, Starten oder erneute Senden eines Kanals in einer Gruppe, in der ihre Rolle zu niedrig ist, wird mit der Rolle, die sie dort hat, abgelehnt; es tut nicht so, als ob der Kanal fehlt, da sie ihn sehen kann. Ihre Rolle am oberen Rand des Bildschirms ist die stärkste, die sie hat, die die Bildschirme öffnet, die diese Rolle verwendet, und jede Aktion auf diesen Bildschirmen ist immer noch auf die Gruppen eingeschränkt, in denen sie diese Rolle hat.

Nur Personen, die auf Kanalgruppen beschränkt sind, können eine haben. Jemand, der jeden Kanal sieht, hat eine Rolle, denn „Editor der Kanäle des Labors“ für eine Person ohne Einschränkung wäre Editor von allem, was keiner Gruppe angehört, und der serverweiten Seiten. Ein Administrator einer Einrichtung kann eine Rolle pro Gruppe nur in den Gruppen zuweisen, die er verwaltet, und niemals über seine eigene Rolle hinaus.

17.3 Wer den FHIR-Endpunkt aufrufen darf

Der FHIR-Endpunkt (serve -fhir) überprüft eine von zwei Arten von Token:

Mit konfiguriertem SMART werden nur SMART-Token akzeptiert, sodass jeder Aufrufer an seine Berechtigungen gebunden ist. Ein API-Token hat eine Rolle und keine Berechtigungen: Ein Viewer-Token kann jeden Patientenrecord lesen. Ein Zahlungspflichtiger, der SMART aktiviert hat, um jede App auf das zu beschränken, was ihr gewährt wurde, sollte keine Möglichkeit haben, die nicht beschränkt ist.

Einige Sites benötigen beides - eine interne Abrechnungsfeed, die ein API-Token hält und keinen SMART-Client hat, neben Mitglieds-Apps, die sich über SMART anmelden. Für diese ermöglicht Einstellungen → FHIR → Perfuse-API-Token neben SMART-Tokens akzeptieren (-fhir-api-tokens beim Start) die Verwendung von API-Tokens. Es ist standardmäßig deaktiviert, wirkt sich auf die nächste Anfrage in beide Richtungen aus und die Änderung wird im Prüfungsjournal aufgezeichnet. Ein Token wird anhand seiner Form erkannt: Ein SMART-Token ist ein signierter JWT, und ein API-Token ist es nie, sodass keiner jemals als der andere überprüft wird. Wo immer möglich, sollte einem solchen System ein SMART-Backend-Dienst-Client mit nur den Systemberechtigungen, die es benötigt, zur Verfügung gestellt werden.

17.3.1 Ein FHIR-Endpunkt, der für Fremde geöffnet ist

Ein öffentlicher Testserver gibt Anmeldeinformationen aus, die schreiben können, da das Testen der vorherigen Autorisierung oder Abonnements Schreibvorgänge erfordert. Zwei Beschränkungen verhindern, dass ein Client alle anderen beeinträchtigt, beide unter Einstellungen → FHIR und beide standardmäßig deaktiviert:

Ein Krankenhaus-Endpunkt benötigt keines von beiden.

17.4 Künstliche Intelligenz-Agenten: Der MCP-Server

Mit Einstellungen › Sicherheit › KI-Agents (MCP) aktiviert (oder serve -mcp), dient Perfuse das Model Context Protocol unter /mcp, sodass ein KI-Agent wie Claude, ChatGPT oder ein IDE-Assistent fragen kann, was passiert. Es ist standardmäßig deaktiviert und das Deaktivieren stoppt jeden Agenten bei seinem nächsten Aufruf.

Ein Agent verbindet sich mit einem API-Token von Verwalten › Benutzer › Maschinenanmeldeinformationen als Trägertoken, niemals mit einer Personensitzung im Browser (das wird abgelehnt, sodass ein Agent niemals mit dem vollen Zugriff einer Person handelt). Eine Clientkonfiguration sieht folgendermaßen aus:

{ "mcpServers": { "perfuse": { "type": "http", "url": "https://perfuse.example/mcp",
    "headers": { "Authorization": "Bearer <token>" } } } }
WerkzeugRolleWas es tut
server_status, list_channels, queue, alertsÜberwachungOb alles funktioniert, ohne Nachrichteninhalte
get_channel, search_messages, get_message, find_patient, fhir_searchBetrachterKanäle, Nachrichten (mit Inhalten), eine Patientennachrichten über Formate hinweg, eine FHIR-Suche
retry_delivery, reprocess_messageOperator und mcp:writeEine ausgestellte Lieferung wiederholen, eine Nachricht erneut durch ihren Kanal senden
start_channel, stop_channelAdmin und mcp:writeEinen Kanal starten oder stoppen

Jedes Werkzeug wird von der gleichen Route oder FHIR-Suche beantwortet, die ein Bildschirm einer Person verwendet, aufgerufen mit dem Token des Agents, sodass die Rolle, Kanalgruppen und Mandant des Tokens bestimmen, was es sieht, genau wie sie es in der Konsole tun; und fhir_search erhält den eigenen Zugriff des Tokens auf dem FHIR-Endpunkt (der API-Tokens insgesamt ablehnen kann; siehe den FHIR-Abschnitt oben). Ein Agent wird nur die Werkzeuge angeboten, die sein Token verwenden darf. Lesen ist standardmäßig: Ein Werkzeug, das etwas ändert, benötigt auch den mcp:write-Bereich des Tokens („Ermöglichen Sie es einem KI-Agenten, damit zu handeln“, wenn das Token ausgestellt wird), sodass ein Token, das für einen Berichtsagenten ausgestellt wird, nicht durch einen Prompt zum Handeln gebracht werden kann. Die Antworten eines Überwachungstokens enthalten entfernte Nachrichteninhalte, unabhängig von dem, was eine Route zurückgibt.

Jeder Aufruf ist in Activity als mcp.tool mit dem Namen des Tokens, des Tools, seiner Argumente und des Ergebnisses (ok, refused, invalid, rate-limited oder dem HTTP-Status) enthalten; mcp.connect protokolliert, welcher Client verbunden ist. Jedes Token kann 60 Toolaufrufe pro Minute (Toolaufrufe pro Minute von einem Token) durchführen; darüber hinaus wird ein Aufruf mit einem Fehler beantwortet, den der Agent lesen kann, und nichts wird durchgeführt. Eine Anfrage von einer Browserseite mit einem anderen Ursprung wird abgelehnt, worum MCP einen Server bittet, um DNS-Rebinding zu verhindern. Der Transport ist MCPs Streamable HTTP, der als JSON ohne Ereignisstrom beantwortet wird; Protokollversionen 2025-06-18, 2025-03-26 und 2024-11-05 werden akzeptiert. Nachrichten und FHIR-Ressourcen enthalten Patientendaten: Die Antworten eines Agents gehen an das Modell, auf dem es ausgeführt wird, daher sollte ein Token nur einem Agent erteilt werden, wenn dieses Modell berechtigt ist, darauf zuzugreifen, und es sollte die niedrigste Rolle erhalten, die den Auftrag erfüllt.

17.5 Ein Demokonto

serve -demo-account demo:PASSWORD erstellt ein gemeinsames Konto für einen öffentlichen Demonstrationsserver, und die Anmeldeseite zeigt den Benutzernamen und das Passwort mit einem Button an, der sich damit anmeldet. Das Konto ist ein Betrachter, sodass es alles anzeigen und nichts ändern kann. Im Gegensatz zu jedem anderen Betrachter kann es auch die Administratorenseiten (Benutzer, Maschinentoken, Einstellungen, Datenschutz, die Peers der Flotte) lesen, nur lesen: eine Demonstration wird an ihren Bildschirmen beurteilt. Es liest sie wie ein Betrachter Kanäle liest, wobei jedes Anmeldeinformation als gesetzt oder nicht gesetzt angezeigt wird, nie jedoch sein Wert, und jede Änderung verweigert wird. Es kann auch die Überprüfungen durchführen, die nichts ändern und nichts außerhalb des Servers erreichen: eine Skript-Überprüfung und die Validierung und Analyse des Kanaleditors. Es kann nicht sein Passwort ändern oder einen Passkey hinzufügen, da der erste Besucher, der dies tut, jeden nachfolgenden Besucher aussperren würde. Jeder Start stellt es als Betrachter mit dem veröffentlichten Passwort wieder her. Das Passwort muss mindestens 12 Zeichen lang sein, wie jedes andere. Verwenden Sie es nur auf einem Server, der Testdaten enthält: Jeder, der die Anmeldeseite liest, kann jede Nachricht auf dem Server lesen.

17.6 Audit

Konfigurationsänderungen, Anmeldungen und Zugriffe auf Nachrichteninhalte werden mit Angabe, wer, was und wann, aufgezeichnet.

Die Audit-Protokolle befinden sich in der gleichen Datenbank wie die Nachrichten. Das ist bequem und es ist eine Einschränkung: Jemand, der die Datenbank ändern kann, kann auch die Audit-Protokolle ändern. Wenn Ihre Anforderungen ein manipulationsevidentes Audit erfordern, müssen die Protokolle an einen append-only-Ort gesendet werden, und die eigene Log-Ausgabe von Perfuse ist der Weg, dies zu tun.

17.7 Geheimnisse in der Konfiguration

Passwörter, Passcodes und Schlüssel erscheinen in der Kanalkonfiguration, was bedeutet, dass sie in den YAML-Dateien enthalten sind.

Zwei Konsequenzen. Die Dateien benötigen Dateisystemberechtigungen, die dem Inhalt entsprechen, und wenn sie in einer Versionskontrolle sind — was ansonsten empfohlen wird — enthält das Repository Anmeldeinformationen und muss entsprechend behandelt werden.

Wo ein Wert ein Geheimnis ist, wird es von der Oberfläche als Geheimnis dargestellt und die API gibt es nach dem Speichern nicht zurück. Das schützt es davor, über die Schulter eines anderen gelesen oder in einem Screenshot geleakt zu werden. Es schützt die Datei nicht.

17.8 Was in der Datenbank ist

Der Nachrichtenspeicher enthält Nachrichten im empfangenen Zustand, was für eine klinische Zufuhr patientenidentifizierbare Daten bedeutet. Er sollte auf verschlüsseltem Speicher platziert, als klinische Daten mit der entsprechenden Aufbewahrungsfrist gesichert und auf Dateisystemebene sowie durch Perfuse-Rollen gesteuert werden.

cleanup.periodDays begrenzt, wie lange es aufbewahrt wird. Siehe den Nachrichtenspeicher für die Spannung zwischen diesem und der Notwendigkeit, genügend Historie für rhythmusbewusste Alarmierung zu haben.

17.9 Datenschutz (DSGVO und UK-DSGVO)

Der Datenschutz-Bildschirm (Verwalten, nur Administratoren) beantwortet die Anfragen einer Person gemäß der DSGVO und der UK-DSGVO. Er trifft keine Entscheidungen im Namen des Verantwortlichen: Ob eine Anfrage gewährt werden muss und ob eine Ausnahme gilt, ist die Entscheidung des Verantwortlichen, die mit der Anfrage aufgezeichnet wird.

Feststellen, was vorhanden ist. Eine Person wird durch Identifikatoren benannt: system|value (eine NHS-Nummer, ein MRN mit seiner Zuweisungsbehörde) oder eine Nummer allein. Mit einem Patientenindex erweitern sich diese auf jede Nummer jedes verknüpften Datensatzes, sodass eine Anfrage, die eine Krankenhausnummer angibt, die unter den anderen abgelegten Datensätze findet. Sehen Sie, was vorhanden ist, durchsucht dann jeden Speicher, der Patientendaten enthält:

SpeicherGefunden durch
Nachrichtenden Identitätsindex (Einstellungen → Daten → Patientenidentifikatoren indizieren); ohne diesen können Nachrichten nicht durch Identifikatoren gefunden werden
Die Zustellwarteschlangedurch Lesen der Identifikatoren jeder wartenden Nachricht
Der FHIR-Speicherdie Patientenressourcen, die einen Identifikator tragen, und jede Ressource, deren indizierte Verweise auf einen hinweisen
Anfragen für vorherige Genehmigungendie Identifikatoren des Patienten der Anfrage
Der Patientenindexden Identifikator oder die EUID

Was es nicht erreichen kann, sagt es: Spuren, die an einen Sammler gesendet werden (-trace-endpoint), das Audit-Log (aufbewahrt: Es ist das Protokoll darüber, wer was getan hat, einschließlich dieser Anfrage), und Backups.

Anfragen. Eine Anfrage wird mit ihrer Art (Zugriff, Artikel 15; Übertragbarkeit, Artikel 20; Löschung, Artikel 17; Einschränkung, Artikel 18), wer sie ist, wie der Verantwortliche sie bezeichnet, die Identifikatoren und einer Notiz (wie die Identität bestätigt wurde, eine Verlängerung und ihr Grund) aufgezeichnet. Sie ist innerhalb eines Monats nach Erhalt fällig (Artikel 12(3)); eine überfällige Anfrage wird in Rot angezeigt.

Eine abgeschlossene Anfrage behält nur die letzten Zeichen der Personenzahlen: Sie bleibt als Aufzeichnung einer Antwort, ohne eine weitere Kopie davon zu sein. Jeder Schritt ist im Audit-Log mit den Zahlen maskiert enthalten.

Rechtliche Sperrungen. Eine Sperrung benennt eine Person durch Identifikatoren, mit ihrem Grund und einem optionalen Enddatum. Solange sie in Kraft ist, wird eine Löschung direkt abgelehnt, und das Retentionsfenster des Nachrichtenspeichers schont die Nachrichten der Person (Records und Bodies), bis die Sperrung aufgehoben wird.

Backups und Löschungsverzeichnis. Ein vor einer Löschung erstelltes Backup enthält noch die gelöschten Daten, bis es abläuft. Jede Löschung wird in ein Verzeichnis eingetragen: Wann, von wem, genehmigt von wem, wie viel von jedem Store entfernt wurde, und die Identifikatoren der Person als salzierte SHA-256-Hashes anstelle von Klartext. Nach dem Wiederherstellen eines Backups Löschungen erneut anwenden hashen die Identifikatoren, die die wiederhergestellten Stores enthalten, mit jedem Eintragssalz und löschen jede Person, die das Verzeichnis nennt. Kurze Zahlen können aus ihren Hashes durch Ausprobieren jedes Wertes gefunden werden, daher ist das Verzeichnis selbst personenbezogene Daten und wird mit dem Schutz der Datenbank selbst aufbewahrt.

Aufbewahrung. Der Bildschirm listet auf, wie lange jede Art von Record hier aufbewahrt wird und was sie ändert: Nachrichtenrecords und -bodies durch ihre Retentionsfenster, die Warteschlange, bis sie zugestellt oder entfernt wird, der FHIR-Store, vorherige Autorisierungsanfragen und der Patientenindex, bis sie gelöscht werden (Klinische Records werden nicht nach einem Zeitplan gelöscht), das Audit-Log wird aufbewahrt.

Verarbeitungsverzeichnis (Artikel 30). Verarbeitungsverzeichnis lädt herunter, als Markdown oder CSV, was dieser Server über es weiß: den Verantwortlichen, den Datenschutzbeauftragten und wo die Daten gespeichert werden (Einstellungen → Daten → Datenschutz), die Aufbewahrungsfrist für jede Art von Aufzeichnung und eine Verarbeitungstätigkeit pro Kanal mit dem, was sie erhält, von wo, an welche Ziele und die Hosts, an die sie sendet. Die Zwecke, Rechtsgrundlagen und Kategorien von Betroffenen werden dem Verantwortlichen überlassen, um sie auszufüllen und anzugeben. Eine CSV-Zelle, die mit =, +, - oder @ beginnt, wird mit einem führenden Apostroph geschrieben, damit eine Tabelle sie nicht ausführt.

Wo die Daten gespeichert werden. Wo die Daten gespeichert werden (Einstellungen → Daten → Datenschutz) gibt an, in Worten, die ein Regulator überprüfen kann, wo der Server, seine Datenbank und seine Backups ausgeführt werden; der Datenschutz-Bildschirm und die Aufzeichnung zeigen es. Ein Entwurf für eine Vereinbarung zum Datenschutz für Organisationen, die BioDream hostet, befindet sich in docs/legal/dpa-template.md; es ist ein Entwurf für einen Anwalt, keine Rechtsberatung.

Die API ist /api/privacy (Zusammenfassung), /api/privacy/find, /api/privacy/requests (und /{id}/approve, /{id}/export, /{id}/erase, /{id}/close), /api/privacy/holds, /api/privacy/reapply und /api/privacy/register.

17.10 Mieter

Ein Mandant ist eine Isolierungsgrenze: Kanäle, Nachrichten, Benutzer und Einstellungen gehören einem Mandanten an, und nichts überschreitet diese Grenze.

Dies existiert für einen Dienstleister, der Feeds für mehrere Praxen ausführt. Verwenden Sie es nicht, um Abteilungen innerhalb einer Organisation zu trennen, die einander gegenseitig sehen müssen: die Isolation ist real und es gibt keine Übersicht über Mandanten. Verwenden Sie stattdessen Kanalgruppen (oben), die die Menschen einer Organisation trennen, während ein zentrales Team alles sehen kann.

17.10.1 Einschränkungen

Ein Plattformoperator legt die Grenzwerte für jeden Mandanten in Mandanten fest, damit ein Kunde die restlichen Mandanten auf einem gemeinsam genutzten Server nicht verdrängen kann. Lassen Sie eine Grenze leer, wenn keine festgelegt werden soll.

Keiner von ihnen verliert eine Nachricht. Über die Rate oder die Speicherbegrenzung hinaus wird eine empfangene Nachricht abgelehnt, wie ein beschäftigter Empfänger eine ablehnt, bevor etwas gespeichert oder geliefert wird: MLLP erhält keine Bestätigung (keine Ablehnung, die einige Absender als „nicht erneut senden“ interpretieren), HTTP erhält 429 mit Retry-After, SOAP erhält 503, DICOM erhält einen wiederholbaren Status und eine Warteschlange, ein Bucket oder eine Datei bleibt, wo sie war. Der Absender sendet erneut, wie jeder Schnittstellen-Engine und jedes EHR. Nichts, was bereits gespeichert ist, wird gelöscht, um Platz zu schaffen. Eine erhöhte Begrenzung wird innerhalb einer Minute wirksam, und jede Änderung der Begrenzungen wird im Aktivitätsprotokoll aufgezeichnet.

17.11 Testdaten

Die generierten Nachrichten, die in Testen beschrieben werden, existieren teilweise als Datenschutzkontrolle. Das Wiederholen eines Problems an einem anderen Ort, das Senden eines Beispiels an einen Hersteller oder das Befüllen einer Testumgebung sind alle Dinge, die normalerweise mit echten Nachrichten durchgeführt werden.

Die Ausgabe des Generators enthält keine Patientendaten durch Konstruktion und nicht durch Redaktion. Bevorziehen Sie sie gegenüber von Hand gestrichenen echten Nachrichten, was ein Prozess ist, der unvollständig durchgeführt werden kann und normalerweise auch ist.

17.12 Einmaliges Anmelden

Drei Mechanismen und lokale Konten neben all diesen.

OpenID Connect (-oidc), ein Verzeichnis über LDAP (-ldap) und SAML 2.0 (-saml). Jeder wird von Verwalten → Anmelden konfiguriert und in die Datei geschrieben, die der Flagname angibt, sodass der Bildschirm und die Datei zwei Ansichten desselben sind und nicht zwei Orte, die synchron gehalten werden müssen.

Lokale Konten sind immer verfügbar und können nicht deaktiviert werden. Das ist absichtlich: ein lokales Integrations-Engine, dessen einziger Zugriff ein Identitätsanbieter ist, wird genau dann unerreichbar, wenn der Identitätsanbieter unerreichbar ist, und ein klinischer Schnittstelle ist kein guter Ort, um das zu lernen. Der Anmeldeschirm teilt Ihnen mit, wie viele lokale Administratoren existieren, bevor er Sie ermutigt, sich auf etwas anderes zu verlassen.

17.12.1 Was eine Gruppenzuordnung entscheidet

Alle drei ordnen Gruppen aus dem Verzeichnis zu Perfuse-Rollen zu, und jemand in Gruppen, die mehr als eine Rolle entsprechen, erhält die höchste Rolle. Das ist die einzige sichere Richtung, um es zu lösen — die Alternative ist eine Person, die den Zugriff verliert, auf den sie Anspruch hat, weil sie auch in einer geringeren Gruppe ist.

Jede der sechs Rollen kann gewährt werden: Monitor, Viewer, Operator, Editor, Admin und Plattform.

Eine Gruppe kann auch auf einige Kanalgruppen beschränkt werden, im zweiten Feld ihrer Zeile (channel_groups in der Datei). Sobald eine Gruppe einen Namen angibt, legt jede Anmeldung die Kanalgruppen der Person auf Grundlage der Gruppen fest, die ihre Rolle gewährt haben: Jemand in einer Gruppe, die die Labor-Kanäle bearbeitet, und in einer anderen, die jeden Kanal ansieht, ist ein Bearbeiter der Labor-Kanäle und nichts anderes. Die stärkste Rolle wird nie mit dem umfassendsten Zugriff verbunden, da keine Gruppe beides gewährt. Eine Gruppe mit einem leeren Feld gibt jeden Kanal frei. Solange keine Gruppe einen Namen angibt, lässt die Anmeldung die Kanalgruppen so, wie sie ein Administrator in Benutzer festgelegt hat.

Wenn jede Gruppe, der eine Person angehört, Kanalgruppen angibt, erhält jede Kanalgruppe die stärkste Rolle unter den Gruppen, die sie angibt: Mit Lab-Interfaces (Bearbeiter, Labor) und Clinical-IT (Betrachter, Labor und ADT) bearbeitet die Person die Labor-Kanäle und sieht die Aufnahmen, als ob sie von Hand festgelegt worden wären. Wenn eine ihrer Gruppen jeden Kanal freigibt, gibt es keine Liste, die eine Rolle pro Gruppe aufnehmen kann, und die obige Regel gilt.

roles:
  editor: [Lab-Interfaces]
  operator: [Night-Desk]
  viewer: [Clinical-IT]
  channel_groups:
    Lab-Interfaces: [lab, pathology]
    Night-Desk: [adt]

Das ist die OpenID Connect- und SAML-Datei. Die Datei des Verzeichnisses ordnet jeder Gruppe eine Rolle zu (roles: {Lab-Interfaces: editor}), und channel_groups befindet sich neben roles dort.

Eine Zuordnung, die niemandem etwas gewährt, wird abgelehnt, anstatt gespeichert zu werden. Eine Konfiguration, die Personen authentifiziert und alle abweist, sieht von außen genauso aus wie ein fehlerhaftes Produkt: der Round-Trip wird abgeschlossen und jeder wird abgelehnt, ohne dass irgendetwas erklärt, warum.

Das Erstellen eines Kontos beim ersten Anmelden ist standardmäßig deaktiviert. Wenn es deaktiviert ist, muss jemand in Perfuse existieren, bevor er sich anmelden kann, sodass das Verzeichnis entscheidet, wer er ist, und Perfuse entscheidet, wer hereingelassen wird.

17.12.2 SAML, speziell

Die Teile, die Sie wissen sollten, bevor Sie es konfigurieren:

17.12.3 Was jeder Anbieter sendet

Das Gruppenattribut ist der Punkt, an dem Anmeldungen schiefgehen, und die drei gängigen Anbieter nennen es jeweils anders.

AnbieterSendet in der RegelHinweise
KeycloakgroupsBenötigt einen Gruppenmitgliedschafts-Zuordner, der dem Client hinzugefügt wird.
Entra IDeine Claim-URI, die mit /claims/groups endetSendet Gruppen-Objekt-IDs, es sei denn, die Anwendung ist konfiguriert, um Namen zu senden. Ordnen Sie die IDs zu, oder ändern Sie den Anbieter.
Oktawas die Anwendung konfiguriert wurdeHäufig groups, wobei ein Filter entscheidet, welche gesendet werden.
ADFSeine Claim-URISigniert die Antwort anstelle der Assertion, die Perfuse akzeptiert.

Eine Claim-URI kann durch ihren letzten Abschnitt eingegeben werden: Die Eingabe von groups findet http://schemas.microsoft.com/ws/2008/06/identity/claims/groups. Ein Name, der einfach mit dem Wort endet, stimmt nicht überein — excluded_groups ist nicht groups.

Gruppenmitgliedschaft, die als ein komma-getrennter Wert ankommt, wird als ein einzelner Gruppenname behandelt und stimmt mit nichts überein. Das ist die korrekte Auslegung des Standards, und das Aufteilen anhand von Kommas würde bedeuten, dass eine Gruppe, die rechtmäßig ein Element enthält, stillschweigend zu zwei wird. Wenn Ihr Anbieter das sendet, ändern Sie es dort.

Testen auf dem Anmeldeschirm überprüft alles, was ohne eine Person überprüft werden kann: die Einstellungen, das Zertifikat und ob eine Anmeldungsanfrage erstellt werden kann. Es sagt deutlich, dass es nicht beweisen kann, dass jemand sich anmelden kann, da dafür eine reale Assertion über eine reale Person erforderlich ist und der einzige Weg, sie zu erhalten, darin besteht, dass sie es versucht.

17.13 Konten, die vom Identitätsanbieter bereitgestellt werden: SCIM

Mit -scim (Einstellungen → Anmeldung → Automatische Konten), erstellt ein Identitätsanbieter wie Okta, Microsoft Entra ID oder Google Workspace Perfuse-Konten selbstständig unter /scim/v2/Users, sodass eine Person, die die Organisation verlässt, Zugriff verliert, wenn ihr Verzeichniskonto deaktiviert wird, und nicht wenn jemand daran denkt. Der Anbieter authentifiziert sich mit einem API-Token mit der Admin-Rolle, der unter Benutzer → Maschinenanmeldeinformationen erstellt wird und als Bearer-Token gesendet wird.

17.14 Was Perfuse nicht tut

Es verschlüsselt die Datenbank im Ruhezustand nicht. Verwenden Sie Dateisystem- oder Volume-Verschlüsselung.

Es verwaltet seine eigenen Zertifikate nicht oder erneuert sie. Weisen Sie es auf Dateien hin und verwalten Sie diese Dateien mit dem, was Sie bereits verwenden.

SAML wurde gegen zwei unabhängige Anbieter überprüft, jeweils mit einer realen Browser-Anmeldung, einer realen Assertion und einer realen Sitzung: Keycloak 26 und Microsoft Entra. Zwei Angelegenheiten sind mehr als doppelt so viel wie eine, da die beiden auf eine Weise widersprechen, die sich als tragfähig erwies — Keycloak schreibt seine Assertion mit Namenspräfixen und Entra schreibt dieselben Elemente ohne sie, und der eine Defekt, den dieser Bereich hatte, lag in der Präfixbehandlung.

Fangen Sie an, indem Sie die Metadaten Ihres Anbieters lesen. Einstellungen, dann Anmeldung, dann die SAML-Registerkarte: Geben Sie die Metadaten-URL ein oder fügen Sie das Dokument ein, und die Anmeldeadresse und das Signaturzertifikat werden automatisch ausgefüllt. Jeder SAML-Anbieter veröffentlicht eines davon — Okta, Entra, AWS IAM Identity Center, Keycloak, ADFS — und es ist der Unterschied zwischen der Konfiguration eines Anbieters und der manuellen Eingabe.

Was zurückgegeben wird, wird beschrieben, anstatt dass es einfach ausgegeben wird: Jedes Zertifikat enthält das Thema, das Ablaufdatum und den SHA-256-Fingerabdruck, damit Sie es mit dem überprüfen können, was die Konsole Ihres Anbieters anzeigt. Ein abgelaufenes Zertifikat wird als abgelaufen bezeichnet, anstatt nur als Datum angezeigt, das visuell verglichen werden muss. Durch das Lesen wird nichts gespeichert — das Anwenden auf das Formular ist ein separater Schritt, da ein Dokument, das jemand eingegeben hat, noch nicht als Entscheidung über das Vertrauen gilt.

Eine Metadaten-URL wird nur über https abgerufen, und die Adresse wird gegen dieselbe Richtlinie überprüft, die die Ziele der Kanäle regelt, sodass dies nicht verwendet werden kann, um den Server dazu zu bringen, Cloud-Instanz-Anmeldeinformationen zu lesen. Umleitungen werden nicht verfolgt, da eine zulässige Adresse, die auf eine blockierte Adresse umleitet, diese Überprüfung umgehen würde.

Wenn Sie Entra konfigurieren, stimmen fünf Dinge nicht mit dem überein, was die Beispiele Ihnen zeigen. Es sendet keine E-Mail-Anspruch überhaupt. Seine NameID ist ein undurchsichtiger Identifikator und kein Adressfeld. Es sendet keine Gruppenansprüche, es sei denn, die Anwendung ist explizit so konfiguriert, dass sie einen ausgibt, sodass eine Rollenzuweisung, die gegen Gruppen geschrieben wird, jede Anmeldung ablehnt. Wenn Gruppen ausgegeben werden, sind sie Objekt-GUIDs und keine Namen, es sei denn, Ihr Mandant synchronisiert von einer lokalen Active Directory. Und seine Anspruchsnamen leben unter schemas.microsoft.com/identity, wo die meisten Dokumentationen schemas.xmlsoap.org zeigen. Perfuse behandelt alle fünf; sie werden aufgeführt, weil die ersten vier anderenfalls wie Fehler in Perfuse aussehen würden, wenn sie tatsächlich Entra sind.

Dieser Unterschied ist hier nicht theoretisch. Die erste echte Keycloak-Behauptung schlug vollständig fehl, weil die kanonische Form, die die Signatur abdeckt, mit entfernten Namenspräfixen berechnet wurde. Kein echter Identitätsanbieter hätte jemanden anmelden können, und die fünf Kanonisierungstests des Pakets wurden währenddessen bestanden — jeder von ihnen wurde signiert und überprüft mit dem gleichen Code, sodass sie nur bewiesen, dass er mit sich selbst übereinstimmt. Wenn Sie der Erste sind, der einen anderen Anbieter darauf zeigt, erwarten Sie, etwas zu finden, und der Server-Log wird die Phase nennen, die fehlgeschlagen ist.

18 Betrieb

18.1 Bereitstellung

Ein Binärdatei und zwei Pfade: ein Verzeichnis von Kanaldateien und eine Datenbankdatei. Es gibt keinen Anwendungsserver, keine separate Web-Ebene und keinen Nachrichtenbroker, der erforderlich ist.

perfuse serve -channels ./channels -db ./perfuse.db -addr 0.0.0.0:8443 \
  -tls-cert ./cert.pem -tls-key ./key.pem

Führen Sie es unter dem aus, was die Dienste auf dem Host überwacht — systemd, launchd, eine Container-Laufzeit. Es erwartet, dass es neu gestartet wird, wenn es beendet wird.

18.2 Wo Daten gespeichert werden können (Datenresidenz)

serve -residency (Einstellungen → Daten → Wo Daten gesendet werden dürfen) gibt die Cloud-Regionen an, in die die Daten dieses Servers gesendet oder von denen sie gelesen werden dürfen: Gebiete (eea, uk, ch) und Regionencodes (eu-central-1, uksouth, europe-west2), kommagetrennt. eea sind die AWS-, Azure- und Google-Cloud-Regionen im Europäischen Wirtschaftsraum (Frankfurt, Irland, Paris, Stockholm, Mailand, Spanien; Niederlande, Deutschland, Frankreich, Schweden, Norwegen, Italien, Polen, Spanien; Belgien, Niederlande, Deutschland, Italien, Frankreich, Finnland, Spanien, Polen), uk die Regionen im Vereinigten Königreich, ch die Regionen in der Schweiz.

Wenn es gesetzt ist, wird ein Kanal abgelehnt, wenn er gespeichert und wenn er geladen wird, wenn ein Connector eine Region außerhalb der Liste nennt: eine S3-, SQS- oder SNS-Quelle oder -Ziel, dessen region (oder dessen endpoint, wenn dies ein AWS-Hostname ist), oder jedes Ziel, dessen Adresse ein AWS-Hostname mit einer Region ist (sqs.us-east-1.amazonaws.com, eine API-Gateway-URL). Der Server startet nicht mit einem Trace-Collector oder einem Alert-Webhook in einer anderen Region. Ein Connector, der auf einen Host zeigt, der keine Region nennt (ein eigenes System eines Krankenhauses, MinIO im Netzwerk des Standorts), wird nicht beurteilt: Der Verarbeitungsverlauf auf dem Datenschutz-Bildschirm listet jeden Host auf, an den jeder Kanal sendet, damit der Controller ihn überprüfen kann. Das Dashboard und der Datenschutz-Bildschirm sagen, wohin Daten gehen können.

Hosting in der EU und im UK. deploy/hosted enthält OpenTofu (oder Terraform) für einen gehosteten Server pro Organisation in Frankfurt, Irland oder London: den Server, seine PostgreSQL-Datenbank und Backups, einen Backup-Bucket, Logs und Support-Sitzungsprotokolle, alles verschlüsselt mit einem Schlüssel in der Region, nichts repliziert in eine andere Region, Support nur über Session Manager und Perfuse mit -residency. Die README-Datei sagt, was sie baut, was sie nicht abdeckt, was verifiziert wurde (validiert und gegen ein reales Konto geplant; noch nicht angewendet) und was es in jeder Region kostet zum Listenpreis.

18.3 Konfiguration als Dateien

Kanäle sind Dateien, was bedeutet, dass sie in einer Versionskontrolle sein können, vor der Bereitstellung überprüft werden können und nach einem Vorfall verglichen werden können.

Dateien werden ohne Neustart neu gelesen. Eine Datei, die nicht geparst werden kann, wird gemeldet und die zuvor geladene Version bleibt aktiv, sodass ein Syntaxfehler einen aktiven Feed nicht außer Gefecht setzen kann.

Ein Kanal, der in der Web-Oberfläche bearbeitet wird, wird in seine Datei zurückgeschrieben. Wenn diese Dateien in einer Versionskontrolle sind, erwarten Sie Commits von Konfigurationsänderungen, die über die Oberfläche vorgenommen wurden, und bearbeiten Sie keine Datei manuell, während jemand sie im Builder geöffnet hat.

18.4 Sicherung

Zwei Dinge, die gesichert werden müssen, und sie haben unterschiedliche Eigenschaften.

Das Kanalverzeichnis ist klein, ändert sich selten und ist das, was Sie benötigen, um den Dienst neu aufzubauen. Sichern Sie es als Konfiguration; die Versionskontrolle ist in der Regel ausreichend.

Die Datenbank enthält Nachrichten, Benutzer und Audit-Verlauf. Sie ist groß, ändert sich ständig und enthält klinische Daten — daher muss sie wie klinische Daten gesichert werden, mit der damit verbundenen Aufbewahrungsfrist und Verschlüsselung. Der Verlust der Datenbank stoppt den Dienst nicht, aber es geht die Fähigkeit verloren, bereits Geschehenes zu untersuchen und die Historie, auf die der Rhythmus-Lerner angewiesen ist.

18.5 Neustartverhalten

Beim Neustart werden Kanäle geladen und Quellen beginnen mit dem Zuhören. Ausgestellte Lieferungen werden fortgesetzt.

Das Wichtigste ist, was mit der Arbeit im Flug passiert. Unter der Standard-on_delivery-Bestätigung wird eine Nachricht, die noch nicht bestätigt wurde, nicht bestätigt, sodass der Absender sie erneut senden wird — was das richtige Ergebnis ist. Unter on_receipt ist eine Nachricht, die bestätigt, aber noch nicht zugestellt wurde, in der Warteschlange und wird fortgesetzt; wenn die Warteschlange deaktiviert ist, geht sie verloren. Siehe Nachrichtenfluss.

18.6 Aktualisierung

Ersetzen Sie die Binärdatei und starten Sie neu. Das Datenbankschema wird automatisch beim Start migriert.

Migrations sind nur in eine Richtung möglich. Es gibt keine Abwärtskompatibilität, sodass ein Rollback auf eine vorherige Binärdatei nach dem Schema-Wechsel die vorherige Datenbank erfordert. Erstellen Sie eine Kopie, bevor Sie aktualisieren — dies ist die einzige operationale Vorsichtsmaßnahme, die es wert ist, diszipliniert zu sein.

18.7 Überwachung

Benachrichtigungen aus Perfuse heraus sind in Benachrichtigungen beschrieben und werden Ihnen mitteilen, wenn ein Feed gestoppt wurde.

Von außen können Sie den Prozess, die Festplatte, auf der die Datenbank gespeichert ist, und ob die Web-Oberfläche reagiert, überwachen. Die Datenbank wächst und eine volle Festplatte stoppt die Aufzeichnung von Nachrichten, was ein Ausfallmodus ohne andere Warnung ist.

18.7.1 SNMP

Für Überwachungstools, die SNMP sprechen (Nagios, Zabbix, PRTG, SolarWinds, LibreNMS), führt Perfuse einen schreibgeschützten SNMPv2c-Agenten aus und sendet eine Falle, wenn eine Warnung ausgelöst oder aufgelöst wird. Konfigurieren Sie es unter Einstellungen → Überwachung → SNMP oder mit 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

18.7.2 Ein Inventar aller Schnittstellen

-inventory interfaces.md (Einstellungen → Überwachung → Inventar) schreibt ein Markdown-Dokument, das jeden Kanal auflistet - sein Format, ob er läuft, was er von wo empfängt und wohin er sendet - gefolgt von der eigenen Beschreibung jedes Kanals und schreibt es alle -inventory-every (einen Tag standardmäßig) neu. Es soll neben den Kanaldateien committet oder einem Prüfer übergeben werden und ohne die Anwendung gelesen werden.

18.8 Kapazität

Die Durchsatz-Obergrenze von Perfuse wurde nicht auf echter Hardware unter echtem Datenverkehr gemessen, und dieses Handbuch wird keine Zahl ausdrucken, die es nicht unterstützen kann.

Was gesagt werden kann: Die Architektur ist ein Goroutine pro Verbindung mit pro-Ziel-Warteschlangen, sodass der Durchsatz mit den Zielen skaliert und nicht durch einen einzigen Worker serialisiert wird; die Aufzeichnung von Nachrichten ist ein SQLite-Schreiben pro Nachricht, was die Festplatte zum wahrscheinlichsten ersten Einschränkung macht; und der Nachrichtenspeicher wächst linear mit dem Datenverkehr, sodass die Aufbewahrungsfrist die langfristige Festplattennutzung regiert.

Wenn Sie dies für einen großen Feed dimensionieren, messen Sie es mit Ihrem eigenen Datenverkehr mithilfe des generierten Testkorpus, das in Testen beschrieben ist. Das ist die ehrliche Antwort, und es ist auch eine bessere Antwort als eine Zahl von jemand anderem's Hardware.

18.9 Wo diese Installation stecken blieb

Die Aktivität enthält ein Panel, das für Administratoren sichtbar ist und zeigt, was Perfuse abgelehnt hat — gruppiert nach Nachricht, am häufigsten zuerst — und wie weit die Installation gekommen ist, um einen funktionierenden Kanal zu erstellen.

Es existiert, weil jeder andere Anspruch darüber, ob diese Software einfach zu verwenden ist, von den Leuten kommt, die sie geschrieben haben. Eine Ablehnung tut das nicht: jemand wollte etwas, der Server sagte nein, und keine der Parteien riet. Es ist der einzige Beweis im Produkt, der nicht von BioDream LLC stammt.

Der Trichter benennt den Schritt, der noch nicht passiert ist, anstatt Timestamps zum Vergleichen zu überlassen. Der Zustand, auf den Sie achten sollten, ist Nachrichten treffen ein und keine wurde an ein Ziel geliefert — ein Kanal kann den Datenverkehr für Wochen aufnehmen und nichts davon liefern, und von jedem anderen Bildschirm sieht es so aus, als ob es funktioniert.

Nichts, was jemand eingegeben hat, wird aufgezeichnet. Der Tisch enthält die Anforderungsroute mit Identifiern, die durch {id} ersetzt wurden, den Status und den Satz des Servers. Eine Validierungsnachricht nennt ein Feld und eine Regel, was der nützliche Teil ist; der Wert, der die Regel brach, ist sehr oft Patientendaten, und eine Tabelle davon wäre eine schlimmere Haftung als die Reibung, die sie messen würde.

Zwei bewusste Ausnahmen. Ein 5xx-Fehler ist ein Fehler in dieser Software und wird bereits als solcher protokolliert — die Vermischung der beiden würde die Fälle, in denen jemand nicht herausfinden konnte, was einzugeben war, unter den Fällen vergraben, in denen nichts, was eingegeben wurde, geholfen hätte. Und eine abgelaufene Sitzung produziert eine Reihe von 401-Fehlern, die nichts über die Benutzerfreundlichkeit aussagen und jede Feststellung, die dies tut, überschwemmen würden.

Das Lesen des Berichts beschneidet auch die Tabelle auf ihre letzten fünftausend Zeilen. Ablehnungen sind 4xx-Antworten, sodass sie langsam wächst, und das Lesen ist ein natürlicher Moment, um aufzuräumen: keine Zeitüberschreitung und nichts, was ausgeführt wird, wenn niemand hinsieht.

GET /api/friction gibt das gleiche Ergebnis für jeden, der es lieber als JSON lesen möchte.

18.10 Protokolle

Perfuse protokolliert in die Standardausgabe, wo ein Supervisor oder ein Container-Laufzeitumfeld es sammeln wird.

Details auf Nachrichtenebene gehen in den Nachrichtenspeicher und nicht in das Protokoll, absichtlich. Eine Protokollzeile pro Nachricht in einem aktiven Feed ist Rauschen, das die Zeilen versteckt, die wichtig sind, und der Speicher ist auf Weise durchsuchbar, die eine Protokolldatei nicht ist.

Das Protokoll enthält, was der Speicher nicht kann: Starten und Beenden, Konfigurationsladergebnisse, Änderungen des Kanalzustands und Fehler, die nicht einer bestimmten Nachricht zugeordnet werden können.

18.11 Zwei Instanzen ausführen

Zwei oder mehr Server können als ein Cluster laufen: Wenn der Server, der einen Feed läuft, stoppt, übernimmt ein anderer innerhalb weniger Sekunden und der nächste Versuch des Senders erreicht ihn. Sie teilen eine PostgreSQL-Datenbank anstelle jedes eigenen SQLite-Datei und stimmen untereinander über diese ab, welcher von ihnen was läuft.

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

Starten Sie jeden Server auf die gleiche Weise mit seinem eigenen Namen und seiner Adresse. Das Datenbankkonto benötigt die Berechtigung, Tabellen zu erstellen und einmal die citext-Erweiterung (oder ein Administrator führt CREATE EXTENSION citext aus). Jeder Server hält seine eigenen Dateien in -data: seine Log-Datei, seine Knoten-ID und seine Kopien der Konfiguration.

Zwei Arten der Aufteilung der Arbeit.

Wer läuft was und nie einen Moment mit zwei. Jedes Stück Arbeit ist eine Pacht in der Datenbank, die alle fünf -cluster-lease (15 s standardmäßig) erneuert wird. Ein Server, der sie nicht erneuern kann (er ist abgestürzt, sein Netzwerk ist fehlgeschlagen, die Datenbank ist nicht erreichbar), stoppt diese Arbeit selbst, sobald seine eigene Uhr sagt, dass die Pacht fast abgelaufen ist, mit einem Drittel der Pacht, um zu sparen. Ein anderer Server übernimmt die Pacht nur, nachdem seine eigene Uhr die Pachtzähler stillstehen gesehen hat, für eine ganze Pacht. Keine Uhr wird mit einer anderen verglichen, also müssen die Serveruhren und die Datenbankuhr nicht übereinstimmen; sie müssen nur etwa im gleichen Tempo laufen, was jede Uhr tut. Zwischen dem alten Halter, der stoppt, und dem neuen, der startet, gibt es eine kurze Lücke, in der niemand zuhört, die ein Sender als abgelehnte Verbindung sieht und erneut versucht; es gibt nie einen Moment mit zwei, die auf einem Feed oder zwei Arbeitern, die eine Warteschlange leeren, zuhören.

Ein Server, der sauber herunterfährt, oder ein Administrator, der Step down auf dem Leader auswählt, übergibt sofort anstelle von nach dem Lease.

Was jeder Server teilt. Nachrichten, die Lieferwarteschlange, Konten und Sitzungen, das Audit-Log, der FHIR-Speicher, die Terminologietabellen und der Patientenindex befinden sich in der Datenbank, sodass der Server, der einen Kanal ausführt, die Warteschlange findet, die der letzte hinterlassen hat. Die Kanaldateien, die Einstellungsdatei, die Warnregeln, Single-Sign-On-Dateien, das Logo, Direct-Zertifikate und gespeicherte Ansichten werden auf jedem Server durch die Datenbank gleich gehalten: Jeder Server hält seine eigene Kopie auf seiner eigenen Festplatte, eine Änderung auf einem Server (in der Konsole, von Hand, durch ein git pull) erreicht die anderen innerhalb von zwei Sekunden, und ein Kanal, der auf einem anderen Server geändert wird, startet mit seiner neuen Datei neu. Die gleiche Datei, die auf zwei Servern gleichzeitig geändert wird, behält die Version, die zuerst die Datenbank erreicht hat, und die andere neben ihr als NAME.conflict-SERVER. Einstellungen, die nur bei einem Neustart gelten (die Nachrichtendatenbank, die Ports, auf denen die Konsole hört), werden von jedem Server bei seinem nächsten Neustart angewendet, und das Log sagt dies an. Was einen Namen auf einem Computer behält, bleibt auf der Befehlszeile dieses Servers und aus der gemeinsamen Datei heraus: das Zertifikat und der Schlüssel (-tls-cert, -tls-key), die SNMP-Adresse und der Name des Servers in den Spuren. Einstellungen zeigen sie als auf jedem Server festgelegt an.

Starten und stoppen. Das Starten oder Stoppen eines Kanals auf einem Server gilt für den Cluster: Der Server, der ihn ausführt, startet oder stoppt ihn innerhalb einer Sekunde, und die Antwort sagt, welcher Server dies ist.

Der Lastenausgleich davor. Eine Adresse eines Feeds muss den Server erreichen, der ihn ausführt. Richten Sie den Absender an eine virtuelle Adresse (einen Lastenausgleich, eine schwimmende IP, einen DNS-Namen mit einer kurzen TTL) und lassen Sie den Lastenausgleich /readyz?channel=NAME überprüfen, der nur auf dem Server, der diesen Kanal ausführt, 200 antwortet und auf den anderen 503. Für die Konsole ist /readyz auf jedem aktiven Server 200; /readyz?role=leader nur auf dem Leader.

Auf einem AWS-Netzwerk-Lastenausgleich verwenden Sie eine Zielgruppe pro Feed mit einem HTTPS-Integritätstest auf /readyz?channel=NAME, einem Intervall von 5 Sekunden und einem Schwellenwert von 2 und schalten Sie Lastenausgleich zwischen Zonen ein. Wenn er ausgeschaltet ist, sieht der Knoten des Lastenausgleichs in einer Zone, in der kein Server den Feed ausführt, nur ungesunde Ziele, sendet dennoch an alle und ein Absender, der zu diesem Knoten aufgelöst wurde, wartet, bis der Feed in seine Zone zurückkehrt (95 Sekunden in einem Test). Stellen Sie die Entregistrierungsverzögerung auf 0, da ein Server, der den Feed nicht mehr ausführt, nichts ablassen muss.

Was getestet wurde. Zwei Server auf PostgreSQL 16, ein Absender, der 300 Nachrichten streamt, und der Server, der den Feed ausführt, wurde mit SIGKILL zweimal getötet (das erste Mal, dann das zweite Mal, nachdem das erste wiederhergestellt wurde). Jede bestätigte Nachricht erreichte den Empfänger in beiden Formen, die versucht wurden: geliefert, bevor die Bestätigung erfolgte, und in der gemeinsamen Speicherwarteschlange, während der Empfänger ablehnte (185 bestätigte Nachrichten warteten in der Warteschlange bei der Tötung; der Überlebende lieferte sie alle). Der Failover dauerte 3 bis 4 Sekunden bei einem Lease von 3 Sekunden. Ein Duplikat ist möglich und wurde einmal in 600 gesehen: eine Nachricht, die der sterbende Server geliefert hatte und nicht bestätigen konnte, die der Absender erneut sendete. Die eigenen Tests des Koordinators umfassen einen Absturz, einen Server, der vom Datenbankzugriff abgeschnitten wird, während er ausgeführt wird, Step-down, Verteilung, Bewegungen und gemeinsame Konfiguration mit Konflikten. Sie werden in CI gegen PostgreSQL mit dem Racedetektor und mit dem gesamten Satz durchgeführt.

Das gleiche wurde dann auf AWS durchgeführt: zwei Linux-Server (ARM) und ein Windows-Server 2022 in drei Verfügbarkeitszonen, Amazon RDS PostgreSQL 16 über TLS mit dem Zertifikat, das überprüft wurde (sslmode=verify-full), einem internen Lastenausgleich davor und Absendern, die bis zur Bestätigung erneut senden:

TestNachrichtenBestätigt, aber verlorenDuplikateLängste Wartezeit eines Absenders
Aktiv-Passiv, der Server, der den Feed ausführt, zweimal getötet (Linux, dann Windows), Empfänger ablehnend dazwischen2.0000015 s
Ein Linux-Leader, der vom Datenbankzugriff abgeschnitten wird (Firewall), sein Prozess weiterläuft3.0000116 s
Ein Windows-Leader, der vom Datenbankzugriff abgeschnitten wird3.0000020 s
Der Leader wird getötet, während die Uhr eines Servers 2 Minuten schneller und die eines anderen 90 Sekunden langsamer läuft2.0000018 s
Aktiv-Aktiv, vier Feeds über drei Server, einer getötet und zurückgebracht6.0000224 s

Mit der Standard-Leasezeit von 15 Sekunden hörte ein Server, der vom Datenbankverbindung getrennt wurde, seine Feed 10 Sekunden nach seiner letzten Verlängerung auf, und der nächste Server startete sie 6 bis 8 Sekunden später: nie beide gleichzeitig. Die fehlgenauen Uhren änderten nichts, da keine Uhr mit einer anderen verglichen wird.

Noch nicht. Ein Cluster dient einer Organisation: -cluster mit -multi-tenant wird abgelehnt. Listener bewegen sich mit ihrem Kanal, sodass der Lastenausgleich vom Standort bereitgestellt wird.

Ein Server alleine funktioniert weiterhin wie immer, auf SQLite, ohne Cluster.

18.12 Mehr als ein Server

Ein Standort mit zwei Instanzen hat eine Frage, die keine einzelne Konsole beantworten kann: Läuft alles? Mirth berechnet für die Antwort. Dies ist die Flottenansicht.

Eine Instanz wird als der Ort benannt, an dem man hinschaut. Sie pollt die anderen und zeigt jeden Kanal auf jedem Server in einer Tabelle an, mit einer Zusammenfassung über alle.

18.12.1 Hinzufügen eines Peers

Einstellungen → Flotte oder PUT /api/fleet/peers. Ein Peer benötigt einen Namen, eine URL und ein Token, das vom Peer selbst ausgestellt wird.

Der Name ist erforderlich und ist nicht die URL, da eine URL nichts ist, was jemand um drei Uhr morgens erkennt.

Das Token muss auf dem Peer unter Benutzern erstellt werden und sollte viewer-scoped sein. Das Hinzufügen eines Peers ohne eines wird abgelehnt, mit diesen Anweisungen, anstatt akzeptiert und dann stillschweigend bei jedem Poll zu scheitern. Das Lesen des Zustands einer anderen Instanz ist das geringste Privileg, das es gibt, und es ist das einzige, das die Flottenansicht benötigt.

18.12.2 Steuerung eines Peers, der ausgeschaltet ist

allow_control ermöglicht das Starten und Stoppen der Kanäle dieses Peers von hier. Es ist standardmäßig deaktiviert und jede Verwendung wird von Name aus überwacht.

Die beiden Privilegien sind absichtlich getrennt. Das Lesen des Zustands eines anderen Servers ist eine geringe Sache; das Stoppen seiner Kanäle während einer Transfusion ist es nicht, und die zweite sollte niemals stillschweigend an die erste angehängt werden.

18.12.3 Was der Bericht sagt

Jeder Server meldet die Gesamtzahl der Kanäle, wie viele davon ausgeführt, gestoppt oder fehlerhaft sind, die Warteschlangentiefe und das Alter der ältesten wartenden Nachricht, wie viele Warnungen ausgelöst werden und ob er für einen Herunterfahren entleert wird.

Die Zusammenfassung zählt Server auf drei Arten: erreichbar, nicht erreichbar und unbestimmt. Der dritte umfasst Peers, deren Zustand niemand kennt — noch nicht abgefragt, lehnt das Token ab oder läuft eine Version aus, die diese nicht lesen kann. Es wird von nicht erreichbar getrennt, weil „wir können nicht sagen“ nicht „es ist down“ ist, und das Zusammenfalten der beiden ist, wie eine Flottenseite anfängt, zu lügen.

Aus demselben Grund enthält die Zusammenfassung knownFrom: wie viele Instanzen die Kanal- und Warteschlangenzahlen tatsächlich gelesen wurden. Zwölf Kanäle, die über eine Flotte laufen, bedeuten etwas anderes, wenn zwei von fünf Servern nicht geantwortet haben und die Gesamtsumme allein dies nicht aussagen kann.

Ein nicht erreichbarer Peer sagt, warum in Begriffen, auf die ein Operator reagieren kann. Eine abgelehnte Verbindung wird als Host gemeldet, der hoch ist, aber nichts auf diesem Port hört, was ein anderes Problem darstellt als ein Host, der überhaupt nicht antwortet.

18.12.4 Uhrabweichung

Die Zusammenfassung berichtet über den größten Unterschied zwischen den Uhren der Server in ihr. Es lohnt sich, eine eigene Zahl zu haben: die Korrelation eines Vorfalls über zwei Instanzen, deren Uhren um vier Minuten voneinander abweichen, produziert eine Sequenz von Ereignissen, die nicht stattgefunden hat.

18.12.5 Was ein Peer über Sie lernt

Zählungen und Raten. Der Bericht, den eine Instanz einer anderen liefert, enthält keine Nachrichten-IDs, keine Kanal-Ebene-Details und keine Patientendaten irgendeiner Art.

Das ist es, was verhindert, dass eine Flottenansicht eine Zentralisierung von klinischen Daten ist: die aggregierende Instanz erfährt, wie viele Kanäle laufen, und nichts darüber, was durch sie hindurchgeflossen ist. Wenn Sie die Nachrichten sehen möchten, öffnen Sie die Konsole des jeweiligen Servers, wo das Audit-Log aufzeichnet, dass Sie dies getan haben.

18.12.6 Ein Peer, der auf sich selbst zeigt

Abgelehnt. Eine Instanz, die ihre eigene Adresse über ihren eigenen HTTP-Stack abfragt, erscheint zweimal in ihrer eigenen Flottenansicht und zählt jeden Kanal, den sie hat, doppelt.

18.12.7 TLS in internen Netzwerken

insecure_skip_verify akzeptiert das Zertifikat eines Peers ohne es zu überprüfen. Es existiert, weil Krankenhaus-Infrastrukturen auf privaten Zertifizierungsstellen basieren und das Ablehnen der Arbeit überhaupt die Menschen auf plain HTTP drängen würde, was schlimmer ist. Es ist so benannt, dass es nicht mit einer guten Idee verwechselt werden kann.

19 Die Kommandozeile

Alles, was Perfuse mit einem laufenden System macht, ist über die Web-Oberfläche erreichbar, und das ist absichtlich: eine Funktion, die ein Terminal benötigt, wird als Defekt und nicht als Design-Entscheidung behandelt. Die Befehle hier sind für die Arbeit, die *um* ein laufendes System herum passiert - bevor es existiert, während Sie entscheiden, ob Sie ihm vertrauen, und wenn Sie etwas an jemand anderen übergeben müssen.

Einige von ihnen berühren überhaupt keinen Server. perfuse explain, perfuse profile, perfuse deident und perfuse translate lesen Dateien und schreiben Dateien, sodass sie auf einem Laptop gegen eine Liegenschaft, die noch vollständig auf etwas anderem läuft, nützlich sind.

Führen Sie jeden Befehl mit -h für seine Flags aus. Dieses Kapitel sagt, wofür jeder von ihnen *ist*.

Die hier gezeigten Flags sind illustrativ, nicht erschöpfend. -h wird aus dem Code generiert und kann nicht veralten; eine Liste, die in die Prospekten kopiert wird, kann.

19.1 Laufende Kanäle

19.1.1 perfuse serve

Führt die Web-Oberfläche und die API aus und führt standardmäßig auch die Kanäle aus. Dies ist der Befehl, den eine Installation verwendet.

Jede Option, die es übernimmt, ist in Server-Optionen aufgeführt, die aus dem Programm generiert werden. Es verweigert die Bereitstellung von unverschlüsseltem HTTP für alles außer Loopback, es sei denn, Sie übergeben -insecure. Das ist keine konfigurierbare Höflichkeit: klinischer Datenverkehr und ein Sitzungs-Cookie über eine unverschlüsselte LAN-Verbindung sind ein meldepflichtiges Ereignis, und die Flagge existeiert, damit das Ja ein Entscheidung ist, die jemand getroffen hat, anstatt ein Standard, den sie geerbt haben. Siehe Sicherheit.

19.1.2 perfuse run

Führt Kanäle aus YAML mit keiner Web-Oberfläche und keiner Datenbank aus. Nützlich in einem Container, der genau eine Sache tun soll, und nützlich, wenn Sie das Verhalten eines Kanals sehen möchten, ohne dass etwas anderes läuft.

19.1.3 perfuse check

Überprüft Kanal-Definitionen und gibt aus, was sie tun, ohne sie auszuführen. Der zweite Teil ist der Punkt: ein Kanal, der geladen wird, ist nicht unbedingt der Kanal, den Sie meinten, und das Lesen einer plain-English-Zusammenfassung dessen, was eine Datei tun wird, fängt einen Fehler, den die Überprüfung nicht sehen kann.

Beendet mit einem nicht-nullen Wert bei einem Fehler, sodass es in alle Überprüfungen gehört, die Ihre Konfiguration vor Erreichen eines Servers überprüfen. -quiet gibt nichts bei Erfolg aus, für diesen Zweck.

-allow-metadata-egress erlaubt Ziele, die auf Cloud-Instanz-Metadaten-Adressen verweisen. Diese Adressen enthalten die eigenen Anmeldeinformationen des Computers, sodass ein Kanal, der dazu gebracht werden kann, dort zu senden, einen Anmeldeinformationsleak darstellt; die Überprüfung lehnt sie ab, es sei denn, Sie sagen etwas anderes.

19.1.4 Perfuse-Test

Führt Tests aus, die gegen Kanaldefinitionen geschrieben wurden. Ein Test sendet eine Nachricht durch den tatsächlichen Filter, die tatsächlichen Transformationen und die tatsächlichen Skripte des Kanals, in der tatsächlichen Reihenfolge, wobei nur das Netzwerk ersetzt wird – daher ist das, was hier funktioniert, das, was der Kanal tut.

Tests befinden sich in *_test.yaml oder *.test.yaml neben den Kanälen. Siehe Testen.

19.2 Migration von einem anderen Engine

Diese drei sind die ersten, die Sie ausführen sollten, bevor Sie eine Entscheidung treffen. Siehe Migration.

19.2.1 Perfuse erläutern

Liest Mirth-, Open-Integration-Engine- und BridgeLink-Exporte – einen Kanal, eine Kanalgruppe oder eine gesamte Server-Sicherungskopie – und beschreibt, was jeder Kanal tut und was eine Migration blockieren würde. Es ändert nichts und benötigt keine Perfuse-Installation, was es zum billigsten möglichen ersten Schritt macht: Zeigen Sie es auf eine Exportierung Ihres Besitztums und lesen Sie, was zurückgegeben wird.

-strict beendet mit einem nicht-nullen Wert, wenn etwas blockiert ist, sodass es ein Pipeline-Tor sein kann. -json gibt die gleichen Ergebnisse für eine Maschine aus.

19.2.2 Perfuse übersetzen

Wandelt Mirth-, Open-Integration-Engine- und BridgeLink-Exporte in Perfuse-Kanaldateien um: einen Kanal, eine Kanalgruppe, eine Code-Vorlagen-Exportierung oder eine gesamte Server-Sicherungskopie.

Perfuse übersetzen -o ./kanäle server-sicherungskopie.xml

Code-Vorlagen-Bibliotheken werden in lib/ neben den Kanälen geschrieben, und jeder Kanal, für den Mirth eine Bibliothek aktiviert hatte, enthält sie. Siehe Migration.

Nichts wird stillschweigend fallen gelassen. Jeder Teil eines Kanals wird entweder übersetzt, als Skript übernommen, das unverändert ausgeführt wird, oder als benötigend einer menschlichen Intervention gemeldet. Die letzte Kategorie ist die ehrliche – ein Übersetzer, der für jede Eingabe eine saubere Datei produziert, würde die Entscheidungen verbergen, die Sie am meisten treffen müssen.

19.2.3 Perfuse vergleichen

Führt den gleichen Datenverkehr durch zwei Engines aus und berichtet, wo sie nicht übereinstimmen, gruppiert nach Feld.

Dies ist der Befehl, der die Frage „Warum sollte ich diesem mit Patientendaten vertrauen“ beantwortet, und er beantwortet sie mit Beweisen, die Sie gesammelt haben, anstatt mit einem hier gemachten Anspruch. Es ist der empfohlene letzte Schritt vor dem Umstellen und der empfohlene erste Schritt in jedem Argument darüber, ob Perfuse bereit ist.

19.3 Verständnis einer Datenquelle

19.3.1 Perfuse profilieren

Liest Nachrichten und berichtet, was tatsächlich in ihnen enthalten ist: welche Felder immer bevölkert sind, welche nie, die tatsächlichen Wertemengen von kodierten Feldern, Wiederholungszahlen und welche Z-Segmente erscheinen.

Werte werden nur für Felder gemeldet, deren Werte eine kleine Code-Menge bilden, sodass ein Profil des tatsächlichen Datenverkehrs nicht zu einer Datei voller Patientendaten wird.

Ein Profil speichern und später damit vergleichen, ist die Möglichkeit, herauszufinden, dass ein Absender etwas geändert hat:

Perfuse profilieren -speichern letzter-monat.json korpus/ Perfuse profilieren -gegen letzter-monat.json neu/

19.3.2 Perfuse vertrag

Wandelt die Ausgabe dieses Denkprozesses in etwas Umsetzbares um. Ein Vertrag legt fest, wie eine Nachricht aussehen muss, damit Sie am Tag einer Änderung benachrichtigt werden, anstatt Wochen später von einem Empfänger zu erfahren, der zusammengebrochen ist - die Nachrichten sind immer noch gültige HL7, wenn ein Feld verschwindet, sodass nichts anderes bemerkt.

perfuse contract promote -o adt.contract.yaml corpus/ perfuse contract check adt.contract.yaml today/

promote generiert einen Ausgangspunkt, nicht eine Antwort. Lesen Sie es und löschen Sie den größten Teil davon: jede Zeile protokolliert, ob sie gemessen oder entschieden wurde, was Ihnen sagt, welche Zeilen Sie behalten sollen.

19.4 Erzeugen von Nachrichten

19.4.1 perfuse generate

Erzeugt synthetische HL7-v2-Nachrichten. Alles ist erfunden - offensichtlich fiktive Namen, sequenzielle Identifikatoren, erfundene Adressen - sodass die Ausgabe sicher zum Committen, Mailen und Anfügen an ein Ticket ist.

Es kann direkt an einen Kanal senden, anstatt eine Datei zu schreiben, was der schnellste Weg ist, um zu beweisen, dass ein Listener funktioniert:

perfuse generate -n 100 -send 127.0.0.1:6661

19.4.2 perfuse deident

Liest reale Nachrichten und schreibt einen Korpus, der ihre Struktur, ihre Codes und ihre Intervalle beibehält, und nichts von dem, was einen Patienten identifiziert. Dies ist der Unterschied zwischen dem Senden einer Reproduktion an jemanden und dem Nicht-Senden.

Es ist nicht das gleiche Tool wie perfuse generate und die Unterscheidung ist wichtig. Generierte Nachrichten sind erfunden und daher sicher, aber unrealistisch; ein anonymisierter Korpus ist *abgeleitet von realen Daten*, sodass er die Eigenheiten reproduziert, die tatsächlich Schnittstellen brechen.

Zwei Eigenschaften, die Sie vor der Verwendung verstehen sollten:

-keep-local-segments lässt Z-Segmente unverändert passieren und ist unsicher. Z-Segmente sind genau dort, wo Sites Namen, Notizen und Freitext einfügen, sodass das Beibehalten davon den Zweck des Tools zunichtemacht. Es existiert, weil ein strukturelles Problem manchmal *in* einem Z-Segment liegt, und dann benötigen Sie einen Korpus, den Sie nicht teilen dürfen.

19.5 Manuelles Verschieben von Nachrichten

19.5.1 perfuse listen

Akzeptiert HL7 v2 über MLLP und bestätigt es. Ein Empfänger, der so lange existiert, wie Sie ihn benötigen, um zu beweisen, dass ein Sender diesen Computer überhaupt erreichen kann.

19.5.2 perfuse send

Sendet HL7-v2-Nachrichten über MLLP aus Dateien.

MLLP hat keine Authentifizierung und keine Verschlüsselung, weder in Perfuse noch anderswo. Beide Befehle unterliegen dem, und auch jede MLLP-Quelle und -Ziel: der Zugriff wird auf der Netzwerkebene eingeschränkt oder ist nicht eingeschränkt.

19.6 FHIR

19.6.1 perfuse fhir

Konvertiert HL7 v2 in FHIR, validiert FHIR oder dient es, je nach Unterbefehl.

Der Validierungs-Unterbefehl ist nützlich für sich genommen: er sagt Ihnen, ob eine Ressource, die Ihnen jemand gesendet hat, US Core erfüllt, was das Profil ist, gegen das die amerikanische Regulierung geschrieben ist. Die Fähigkeit, diese Frage zu beantworten, ohne einen Motor zu adoptieren, ist der Punkt.

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-Messung

Bewertet eine Qualitätsmessung mit FHIRPath-Kriterien über FHIR-Dateien (das NDJSON einer Massenexportierung, Bundles oder JSON-Arrays; - für stdin) und schreibt den MeasureReport. Flags:

Siehe digitale Qualitätsmaße.

19.6.5 FHIR-Flags auf Perfuse serve

FlaggeEffekt
-fhirFHIR-Endpunkt unter /fhir bereitstellen. Standardmäßig aktiviert.
-fhir-versionDie bereitgestellte Version. Standardmäßig R4.
-fhir-read-onlySchreiboperationen ablehnen.
-fhir-api-tokensMit SMART konfiguriert, akzeptiert Perfuse-API-Tokens sowie SMART-Tokens (standardmäßig deaktiviert; auch unter Einstellungen → FHIR).
-fhir-bulk-export$export aktivieren. Standardmäßig deaktiviert.
-fhir-subscriptionsThemenabonnements aktivieren: Begegnungs- und Terminbenachrichtigungen an Endpunkte, die FHIR-Clients auswählen. Standardmäßig deaktiviert; benötigt R4 und einen beschreibbaren Endpunkt.
-fhir-subscriptions-allow-httpAbonnements über plain http zulassen. Für einen Testempfänger, niemals für Patientendaten in einem Netzwerk.
-fhir-patient-directory-searchEin Token, das auf einen Patienten beschränkt ist, darf das Verzeichnis (Praktiker, Organisationen, Standorte) innerhalb seiner Berechtigungen durchsuchen. Standardmäßig deaktiviert.
-fhir-declaresLeitfäden, die dieser Server in seiner Fähigkeitsanzeige deklariert, kommagetrennt: eine Fähigkeitsanzeige-Adresse eines Leitfadens oder Type=profile-Adresse. Eine Anzeige für Clients und Testkits; sie ändert nichts, was der Speicher akzeptiert.

Der Speicher hält Dokumente sowie Ressourcen: Ein Dokument, eine Sammlung oder ein Nachrichten-Bundle, das per PUT an /fhir/Bundle/{id} gesendet wird, wird ganz gespeichert, mit jedem Eintrag in der bereitgestellten Version zurückgelesen und durch type, identifier, timestamp und composition gefunden. Eine Transaktion, die per PUT dort gesendet wird, wird als Aufzeichnung gespeichert und nicht angewendet; ein POST an /fhir wendet eine an.

Antworten sind JSON, sofern der Client nicht XML anfordert (Accept: application/fhir+xml, oder _format=xml). Perfuse liest nur JSON: Ein Body, der als XML gesendet wird, erhält 415. Ein Document-Bundle, das an /fhir gesendet wird, wird beibehalten, wenn dieser Server den Patienten und die Begegnung, die seine Composition benennt, besitzt, und andernfalls mit 422 abgelehnt. Ein Binary-Lesevorgang mit Accept, das auf seinen eigenen Inhaltstyp gesetzt ist, antwortet mit dem Inhalt selbst.

19.7 Einrichten und Betreiben

19.7.1 Perfuse init

Erstellt das Verzeichnislayout, einen Beispielkanal und eine Dienstdefinition für das Betriebssystem, auf dem es ausgeführt wird. Nichts Existierendes wird ersetzt, es sei denn, Sie übergeben -force.

Perfuse init -dir /opt/perfuse -service systemd

19.7.2 Perfuse-Dienst

Registriert Perfuse als Windows-Dienst, entfernt es oder berichtet, ob es installiert und ausgeführt wird. Nur unter Windows; unter Linux ist die entsprechende Datei die Einheitsdatei, die perfuse init für Sie schreiben kann. Siehe Betrieb.

19.7.3 Perfuse-Token

Stellt Anmeldeinformationen für Maschinen anstelle von Personen aus. Ein Token läuft nicht ab und wird nicht durch das Abmelden einer Person beeinflusst, was ein Server benötigt, der seinen Nachbarn abfragt, und was eine Browser-Sitzung absichtlich nicht ist.

Perfuse token create -db perfuse.db -label fleet-from-site-a -role viewer perfuse token list -db perfuse.db perfuse token revoke -db perfuse.db -label fleet-from-site-a

Nur der Hash wird gespeichert, sodass ein Token nur einmal angezeigt wird, wenn es erstellt wird, und danach nicht wiederhergestellt werden kann. Ein gestohlener Datenbestand liefert daher kein verwendbares Token. Geben Sie einem Token die niedrigste Rolle, die den Auftrag erledigt: Eine Flotte benötigt viewer, und nichts, das nur liest, sollte mehr als das besitzen.

-fhir-groups riverside-attributed,riverside-north beschränkt ein Token auf diese FHIR-Gruppen, für einen Anbieter-Export CMS-0057 Provider Access: Auf dem FHIR-Endpunkt kann es diese Gruppen lesen und exportieren und nichts anderes. Siehe CMS-0057 für Zahlstellen.

19.7.4 Perfuse athena

Gibt die Amazon Athena CREATE EXTERNAL TABLE für ein S3-Archiv aus, das mit format: ndjson geschrieben wurde, unter Verwendung der Partitionsvorhersage auf dem dt=YYYY-MM-DD-Teil des Schlüssels, sodass kein Crawler ausgeführt werden muss, wenn Tage hinzugefügt werden.

Perfuse athena -bucket hospital-archive -destination archive

Gedruckt anstelle von ausgeführt, da die Erstellung einer Tabelle Athena- und Glue-Berechtigungen erfordert, die dieses Programm nicht besitzen sollte.

19.7.5 Perfuse sbom

Listet alles auf, was in die Binärdatei eingebunden ist, gelesen aus dem Build selbst und nicht aus go.mod — also beschreibt die Binärdatei vor Ihnen und nicht, was jemand einmal angefordert hat.

-json gibt CycloneDX aus und -spdx gibt SPDX-Tag-Wert aus, was normalerweise das ist, wonach eine Beschaffung oder Sicherheitsprüfung tatsächlich fragt. Der im Binärcode eingebettete Browsercode ist enthalten, da ein Prüfer, der eine Binärdatei mit Warnungen abgleicht, wissen muss, dass sie eine React-Anwendung enthält.

19.7.6 Perfuse-Version

Druckt die Version und den Commit, mit dem sie erstellt wurde, aus. Es lohnt sich, in einem Ticket zu erwähnen: „die aktuelle“ ist keine Version und zwei Maschinen, die eine Woche auseinander installiert wurden, laufen häufig nicht mit dem gleichen Build.

20 Server-Optionen

Jede Option, die perfuse serve akzeptiert, wird aus dem Programm selbst generiert, sodass diese Liste keine Option nennen kann, die nicht existiert, oder eine auslassen kann. Die meisten sind auch eine Einstellung in der Web-Oberfläche, die im letzten Spaltenfeld benannt ist: Ein dort gespeicherter Wert hat Vorrang vor der Flagge beim nächsten Start und die Flagge bleibt der Weg, um sie aus einer Service-Definition zu setzen. Die Zuhör-Adresse, die Datenbank und das Channel-Verzeichnis bleiben Flaggen, da sie angeben, wo der Server das findet, was er bearbeiten würde.

Geheime Daten sind niemals Flaggen. Eine Option, die ein Passwort oder einen Token benötigt, benennt eine Umgebungsvariable, die es enthält.

20.1 Alle Optionen

OptionTakesDefaultWhat it doesIn the console
-addrstring127.0.0.1:8080, or 127.0.0.1:8443 with -tls-certaddress to serve the interface on—
-alert-severitystringwarningminimum severity to send to the webhook: warning or criticalSettings › Alerts › Delivery: Only send alerts at least this serious
-alert-webhookstring—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 contentSettings › Alerts › Delivery: Send alerts to this address
-alertsstring—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-egresson/off—permit destinations pointed at cloud instance metadata addresses, which hold this machine's credentialsSettings › Security › What may leave: Allow destinations at cloud instance metadata addresses
-cds-clientsstring—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
-channelsstring./channelsdirectory holding channel files—
-clusterstring—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-leaseduration15show long a crashed server holds its work before another takes it over; renewed five times as often—
-crd-advisor-castring—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-envstring—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-urlstring—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 itSettings › Payers › Decision service: Advice before submitting (CRD)
-crd-rulesstring—a Da Vinci CRD rules file: serve coverage requirements over CDS Hooks at /cds-servicesSettings › Payers › Prior authorization: Coverage rules file (Da Vinci CRD)
-dashboardsstring—a file mapping directory groups and roles to the dashboard each opens onSettings › Monitoring › Dashboards: Which dashboard each group opens on (file)
-datastring—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-versionstring2.2the 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)—
-dbstring./perfuse.dbdatabase for users, messages and stored resources: a file, or a postgres:// URL for servers that share one store (a cluster)—
-demo-accountstring—for a public demonstration server: username:password of a shared viewer account shown on the sign-in page—
-dicomweb-archivestring—keep imaging objects in this directory and serve them over DICOMweb (QIDO-RS, WADO-RS, WADO-URI, STOW-RS) at /dicomwebSettings › Data › Imaging archive: Keep images in this folder and serve them over DICOMweb
-dicomweb-corsstring—comma-separated browser origins, such as an OHIF viewer's, allowed to call /dicomwebSettings › Data › Imaging archive: Browser origins allowed to call it
-drain-forduration—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-agencystring—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-responseson/off—accept eCR Reportability Responses at the FHIR endpoint's $process-message, storing each as DocumentReference/<id> derived from the eICR it answersSettings › Public health › Case reporting: Receive Reportability Responses
-engineon/offtruerun the channel engine in this process, so the interface can start, stop and monitor channels—
-epa-payer-idstring—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-channelstring—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 networkSettings › Payers › Drug formulary: Channel that sends later ePA decisions
-fhiron/offtrueserve a FHIR endpoint at /fhirSettings › FHIR › The FHIR server: Serve a FHIR endpoint at /fhir
-fhir-api-tokenson/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-exporton/off—enable $export, which produces a file holding every record the FHIR endpoint servesSettings › FHIR › Bulk data: Bulk Data export ($export)
-fhir-declaresstring—guides this FHIR server declares in its capability statement, comma-separated: a CapabilityStatement address, or Type=profile addressSettings › FHIR › Capability statement: Guides this server declares
-fhir-max-resourcesint—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-consenton/off—let $member-match answer without an active Consent; the Payer-to-Payer API is opt-in, so only for testingSettings › Payers › CMS-0057-F: Answer $member-match without the member's consent
-fhir-openon/off—serve the FHIR endpoint with no authentication at all, exposing every stored recordSettings › FHIR › Access: Let anyone read the FHIR endpoint without signing in
-fhir-patient-directory-searchon/off—let a token limited to one patient search the directory (practitioners, organisations, locations) within its scopesSettings › FHIR › Access: Let a patient's app search the directory
-fhir-payer-apison/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-exportSettings › Payers › CMS-0057-F: The CMS-0057-F payer APIs
-fhir-read-onlyon/off—refuse writes to the FHIR endpointSettings › FHIR › Access: Refuse writes to the FHIR endpoint
-fhir-subscriptionson/off—enable topic-based subscriptions, which send encounter and appointment notifications to URLs FHIR clients chooseSettings › FHIR › Notifications: FHIR subscriptions (encounter and appointment notifications)
-fhir-subscriptions-allow-httpon/off—let subscriptions deliver to plain-http endpoints; for a test receiver, never for patient data on a networkSettings › FHIR › Notifications: Allow subscriptions to notify plain-HTTP addresses
-fhir-versionstring4.0.1FHIR release to serve: R4, R4B or R5Settings › FHIR › The FHIR server: FHIR version clients see
-fhir-writes-per-minuteint—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-labelstring—how this instance names itself in a fleet view (default: hostname)Settings › Fleet › This server: Name for this server
-formularystring—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 itSettings › Payers › Drug formulary: Drug formulary file
-icd11-client-idstring—a WHO ICD API client: ICD-11 codes not imported are looked up thereSettings › Data › Code systems: WHO ICD API client ID
-icd11-client-secretstring—the WHO ICD API client's secretSettings › Data › Code systems: WHO ICD API client secret
-icd11-releasestring2025-01the ICD-11 MMS release the WHO ICD API is asked aboutSettings › Data › Code systems: ICD-11 release to ask for
-icd11-urlstring—the ICD API's address when it is not the WHO's: the WHO's ICD-API container on your network needs no clientSettings › Data › Code systems: ICD API address
-index-identityon/offtrueindex 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 offSettings › Data › What is kept: Index patient identifiers
-insecureon/off—serve over plain HTTP on a non-loopback address (not recommended)—
-inventorystring—write a Markdown inventory of every interface to this file, and keep it currentSettings › Monitoring › Inventory: Write an interface inventory to
-inventory-everyduration24h0m0show often to rewrite the interface inventorySettings › Monitoring › Inventory: Rewrite the inventory every
-json-logson/off—emit structured JSON logsSettings › Monitoring › Logging: Write logs as JSON
-ldapstring—YAML file configuring directory (LDAP) sign-in (default: ldap.yaml beside the database, once saved in the console)—
-log-filestring—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—
-mcpon/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 accessSettings › Security › AI agents (MCP): Let AI agents connect over MCP
-measure-reporterstringPerfusethe reporting organisation's name on MeasureReports from $evaluate-measure when the request names no reporter—
-metrics-openon/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'sSettings › Security › Metrics: Serve /metrics without a token
-metrics-tokenstring—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 /metricsSettings › Security › Metrics: Token a metrics scraper presents
-mpion/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-tenanton/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-addressstring—this server's console URL as the other servers and a load balancer reach it—
-node-namestring—this server's name in the cluster (default: an id kept in -data)—
-oidcstring—YAML file configuring OpenID Connect sign-in (default: oidc.yaml beside the database, once saved in the console)—
-pason/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 resultSettings › Payers › Prior authorization: Da Vinci PAS prior authorization server
-pas-278-castring—a PEM file of certificate authorities to trust for the UM system beside the system'sSettings › Payers › Utilization management link: Certificate authorities to trust for the UM system
-pas-278-certstring—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-receiverstring—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-versionstring—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-senderstring—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-versionstring2.2.0the 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-keystring—the private key (PEM) for -pas-278-certSettings › Payers › Utilization management link: Client certificate key file
-pas-278-oauth-client-idstring—the OAuth client ID for -pas-278-oauth-token-urlSettings › Payers › Utilization management link: OAuth client ID
-pas-278-oauth-scopestring—the scope asked for with the OAuth token, when the UM system wants oneSettings › Payers › Utilization management link: OAuth scope
-pas-278-oauth-secret-envstring—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-urlstring—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-envstring—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-idstring—the UMO's payer ID (NM1*X3) when the request's insurer carries no identifierSettings › Payers › Utilization management link: Payer ID for the 278s
-pas-278-productionon/off—mark the 278s sent as production (ISA15 P) rather than testSettings › Payers › Utilization management link: Mark the 278s as production
-pas-278-receiverstring—ISA08/GS03 receiver ID on the 278s sent to the UM systemSettings › Payers › Utilization management link: Receiver ID on the 278s
-pas-278-senderstringPERFUSEISA06/GS02 sender ID on the 278s sent to the UM systemSettings › Payers › Utilization management link: Sender ID on the 278s
-pas-278-sftpstring—host:port of the UM system's SFTP server, for -pas-278-transport sftpSettings › Payers › Utilization management link: SFTP server
-pas-278-sftp-everyduration1m0show often the SFTP inbound folder is readSettings › Payers › Utilization management link: Read the SFTP inbound folder every
-pas-278-sftp-inboundstring—the SFTP folder the UM system's 278 responses, 999s and TA1s are collected fromSettings › Payers › Utilization management link: SFTP inbound folder
-pas-278-sftp-keystring—an OpenSSH private key file for the SFTP user, instead of a passwordSettings › Payers › Utilization management link: SFTP key file
-pas-278-sftp-known-hostsstring—an OpenSSH known_hosts file holding the SFTP server's key; required, so requests never go to whoever answersSettings › Payers › Utilization management link: SFTP known_hosts file
-pas-278-sftp-outboundstring—the SFTP folder the 278 requests (and the 999s for the answers) are put inSettings › Payers › Utilization management link: SFTP outbound folder
-pas-278-sftp-password-envstring—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-userstring—the SFTP user nameSettings › Payers › Utilization management link: SFTP user
-pas-278-token-envstring—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-transportstringx12how 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-urlstring—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-278Settings › Payers › Utilization management link: Send PAS requests on to the UM system at
-pas-278-userstring—user name for the UM system: CORE's UserName (WS-Security UsernameToken in SOAP), or HTTP Basic for x12Settings › Payers › Utilization management link: User name
-pas-decider-castring—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-envstring—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-urlstring—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-urlSettings › Payers › Decision service: Decision service URL
-passkey-allowed-modelsstring—comma-separated authenticator AAGUIDs that may enrol; requires -passkey-attestation-roots—
-passkey-attestation-rootsstring—a PEM file of authenticator vendor certificates; passkey attestation is verified against these—
-passkey-domainstring—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 offSettings › Sign-in › Passkeys: Domain passkeys are bound to
-passkey-namestringPerfusethe name an authenticator shows a person when they register a passkeySettings › Sign-in › Passkeys: Name shown on the device
-passkey-originsstring—comma-separated origins the console is reached at, with scheme and port: https://perfuse.example.org. Defaults to https:// plus the domainSettings › Sign-in › Passkeys: Other origins passkeys are accepted from
-peersstring—YAML file listing other Perfuse instances to show in a fleet viewSettings › Fleet › Fleet: Other Perfuse servers to show (file)
-public-urlstring—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
-rctcstring—eCR trigger codes for the case report preview: a FHIR ValueSet or Bundle of them, such as the eRSDSettings › Public health › Case reporting: Trigger codes file (RCTC or eRSD)
-residencystring—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 refusedSettings › Data › Data protection: Where data may go (cloud regions)
-retention-daysint30how long to keep recorded messages; 0 keeps them for ever, which will eventually fill the diskSettings › Data › How long it is kept: Delete records after
-samlstring—YAML file configuring SAML 2.0 sign-in (default: saml.yaml beside the database, once saved in the console)—
-scimon/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 leavesSettings › Sign-in › Automatic accounts: Let the identity provider manage accounts
-scim-default-rolestringviewerrole 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—
-settingsstring—settings file the web interface may edit (default: perfuse-settings.yaml beside the database)—
-shl-allow-httpon/off—let a received SMART Health Link point at plain HTTP; for testing onlySettings › Public health › Health links: Allow SMART Health Links over plain HTTP
-signing-certstring—certificate for signing documents (defaults to -tls-cert)Settings › Security › Document signing: Certificate for signing documents
-signing-keystring—key for signing documents (defaults to -tls-key)Settings › Security › Document signing: Key for signing documents
-smart-audiencestring—the audience a SMART token must be issued for, normally the FHIR base URLSettings › SMART › Authorization: Audience tokens must name
-smart-authorizestring—the authorization endpoint to advertise to SMART appsSettings › SMART › Authorization: Authorization endpoint
-smart-backend-serviceson/off—advertise that the SMART authorization server issues backend-services (client_credentials, signed JWT) tokensSettings › SMART › Built-in server: Backend Services (system-to-system tokens)
-smart-clientsstring—run Perfuse's own SMART authorization server at /auth for the apps registered in this YAML fileSettings › SMART › Built-in server: Registered apps file (turns on the built-in server)
-smart-issuerstring—accept SMART on FHIR access tokens from this authorization serverSettings › SMART › Authorization: Accept SMART access tokens from this authorization server
-smart-jwksstring—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-uristring—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-keystringsmart-signing.keythe built-in authorization server's RSA signing key (PEM, mode 0600), created if missingSettings › SMART › Built-in server: Signing key file
-smart-oidcstring—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_subjectSettings › SMART › Built-in server: Sign people in through the OpenID Connect provider
-smart-tokenstring—the token endpoint to advertise to SMART appsSettings › SMART › Authorization: Token endpoint
-smart-usersstring—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-allowstring—comma-separated networks or addresses the SNMP agent answers, such as 10.0.5.0/24; required with -snmp-listenSettings › Monitoring › SNMP: Networks that may ask
-snmp-base-oidstring1.3.6.1.4.1.8072.9999.9999.16, Net-SNMP's experimental spacewhere Perfuse's values sit, under your enterprise numberSettings › Monitoring › SNMP: Base OID
-snmp-communitystring—the SNMPv2c community (a password sent in clear: at least 6 characters, not public or private)Settings › Monitoring › SNMP: SNMP community
-snmp-contactstring—sysContact the SNMP agent reportsSettings › Monitoring › SNMP: Contact (sysContact)
-snmp-listenstring—answer SNMPv2c GET/GETNEXT/GETBULK on this UDP address, such as :161 (off when empty). Read-only: channel states, counts and queue depthsSettings › Monitoring › SNMP: Answer SNMP on this address
-snmp-locationstring—sysLocation the SNMP agent reportsSettings › Monitoring › SNMP: Location (sysLocation)
-snmp-trapsstring—comma-separated managers (host or host:port, default port 162) that receive an SNMPv2 trap when an alert fires or resolvesSettings › Monitoring › SNMP: Send traps to
-store-messageson/offtruerecord every message handled, which is what makes the message browser workSettings › Data › What is kept: Keep a record of each message
-store-payloadson/offtruestore message contents as well as their outcomes; turn this off where PHI must not be held at restSettings › Data › What is kept: Keep message contents
-tls-certstring—TLS certificate fileSettings › Security › Encryption: TLS certificate file
-tls-keystring—TLS private key fileSettings › Security › Encryption: TLS private key file
-trace-endpointstring—OTLP/HTTP base URL to export message traces to, for example http://localhost:4318Settings › Monitoring › Tracing: Send traces to
-trace-instancestring—name for this instance in traces; defaults to the hostname, which is what distinguishes replicasSettings › Monitoring › Tracing: This instance's name in traces
-trace-samplefloat1fraction of traces to record, 0 to 1—
-tsa-urlstring—RFC 3161 time-stamping authority for DSDR signatures on claims attachmentsSettings › Security › Document signing: Time-stamping authority
-vpnstring—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.yamlSettings › Monitoring › Connections: VPN tunnels to watch (file)
-watch-accesson/offtruewatch traffic and reads of patient data for what a breach looks like (bursts, night traffic, new destinations, bulk reads) and raise alerts—
-xdsstring—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/registrySettings › Data › Document sharing (IHE XDS): Keep documents here as an XDS registry and repository
-xds-home-communitystring—this community's home community id (urn:oid:...), so /xca/gateway answers XCA ITI-38 and ITI-39 for itSettings › Data › Document sharing (IHE XDS): Home community id, for XCA

21 Kanalanleitung

Jeder Schlüssel, der auf der obersten Ebene einer Kanaldatei erscheinen kann. Diese werden aus der Quelle extrahiert, daher kann dieses Kapitel keine Option beschreiben, die nicht existiert, oder eine auslassen, die es tut.

21.1 Kanal

Ein Kanal ist ein konfigurierter Nachrichtenfluss: An einem Ort treffen Nachrichten ein, optional ein Filter und ein oder mehrere Orte, an die sie gesendet werden.

Definiert als Channel in internal/config.

SchlüsselTypErforderlichStandard
nameTextja—
descriptionTextnein—
groupTextnein—
attachmentsAnlagen (ein Block, weglassen, um nicht zu verwenden)nein—
delimitedBegrenzt (ein Block, weglassen, um nicht zu verwenden)nein—
tablesListe von Textnein—
contractContractRef (ein Block, weglassen, um nicht zu verwenden)nein—
enabledwahr oder falsch (ein Block, weglassen, um nicht zu verwenden)nein—
dataTypeDataTypeneinhl7
hl7v3HL7v3-Optionen (ein Block, weglassen, um nicht zu verwenden)nein—
x12X12-Optionen (ein Block, weglassen, um nicht zu verwenden)nein—
ncpdpNCPDP-Optionen (ein Block, weglassen, um nicht zu verwenden)nein—
edifactEDIFACT-Optionen (ein Block, weglassen, um nicht zu verwenden)nein—
scriptSkriptoptionen (ein Block, weglassen, um nicht zu verwenden)nein—
dicomDICOM-Optionen (ein Block, weglassen, um nicht zu verwenden)nein—
sourceQuelleja—
filterTextnein—
transformationsListe von transform.Stepnein—
scriptsSkripte (ein Block, weglassen, um nicht zu verwenden)nein—
shadowSchatten (ein Block, weglassen, um nicht zu verwenden)nein—
destinationsListe von Destinationja—

21.1.1 name

Der Name identifiziert den Kanal in Protokollen und Metriken.

Erforderlich und eindeutig.

21.1.2 gruppe

Die Gruppe ist das, zu dem dieser Kanal gehört, um eine Liste zu organisieren, die zu lang geworden ist, um sie noch lesen zu können.

Kosmetisch bei fünf Kanälen und strukturell bei zweihundert: Die Kanäle eines Standorts teilen sich nach dem System, mit dem sie kommunizieren, oder nach dem Team, das sie besitzt, und eine flache Liste von zweihundert Namen ist unbenutzbar, egal wie gut die restliche Oberfläche ist.

Ein einfacher String anstelle eines Gruppenobjekts mit seiner eigenen Datei, da eine Gruppe kein Verhalten hat. Im Moment, in dem sie eine Datei hat, erwirbt sie Einstellungen, und Einstellungen auf einer Gruppe bedeuten, dass das Verhalten eines Kanals von etwas abhängt, das nicht in dem Kanal geschrieben ist - was die Eigenschaft ist, die Mirth-Konfigurationen schwer verständlich macht. Gruppen hier sind ein Label und nichts mehr.

21.1.3 anlagen

Anlagen verschiebt große Nutzlasten aus der Nachricht und setzt sie vor der Lieferung wieder ein.

Opt-in pro Kanal: Eine Feed von einfachen ADT-Nachrichten hat nichts zu extrahieren und sollte nicht für die Maschinerie zahlen.

21.1.4 begrenzt

Begrenzt konfiguriert einen begrenzten Kanal.

Nur sinnvoll, wenn der Datentyp begrenzt ist.

21.1.5 tabellen

Tabellen benennen Dateien von gemeinsam genutzten Zuordnungstabellen, auf die eine Umwandlung durch den Namen verweisen kann.

Gemeinsam, weil die Domänensteuer größtenteils darin besteht, eine Zuordnung neu abzuleiten, die jemand bereits abgeleitet hat: Die Geschlechtscodes und Patientenklassen eines Standorts werden in jedem Kanal, der sie berührt, identisch übersetzt, und eine Tabelle in einem Kanal ist eine Tabelle, die nur dieser Kanal verwenden kann.

21.1.6 aktiviert

Aktiviert ist standardmäßig wahr.

Ein deaktivierter Kanal wird geladen und validiert, aber nicht gestartet, sodass eine Datei, die vorübergehend ausgeschaltet ist, immer noch von CI überprüft wird.

21.1.7 DatenTyp

Der DatenTyp ist das Format der Nachrichten, die dieser Kanal erhält.

Standardmäßig ist es hl7, sodass jeder Kanal, der vorher existierte, weiterhin funktioniert.

21.1.8 x12

X12 enthält die Einstellungen, die nur auf einem X12-Kanal eine Bedeutung haben.

Die Festlegung auf einem anderen Typ wird abgelehnt, anstatt ignoriert zu werden.

21.1.9 Skript

Das Skript konfiguriert einen NCPDP-SCRIPT-Kanal.

Seine Schritte leben hier, anstatt in den obersten Transformationen für den gleichen Grund, warum jeder andere nicht-v2-Format dies tut: Die Schritttypen unterscheiden sich pro Format, sodass ein Schlüssel unterschiedliche Dinge bedeuten würde, abhängig vom DatenTyp.

21.1.10 dicom

Imaging konfiguriert die benannten Transformationschritte eines DICOM-Kanals.

Benannt als Imaging anstelle von DICOM, da Quelle und Ziel bereits ein DICOM-Feld haben und drei Felder mit dem gleichen Namen auf unterschiedlichen Ebenen dazu führen, dass jemand das falsche Feld setzt. Der YAML-Schlüssel ist dicom, was eine Person, die die Datei schreibt, erwartet, und der Go-Name ist der, der einen Fehler am Aufrufort verhindert.

21.1.11 Filter

Der Filter ist ein Ausdruck, der für eine Nachricht gelten muss, damit sie weitergeleitet wird.

Eine Nachricht, die nicht übereinstimmt, wird dennoch bestätigt: Der Absender hat nichts falsch gemacht, wir sind einfach nicht interessiert.

21.1.12 Transformationen

Transformationen sind deklarative Änderungen, die auf akzeptierte Nachrichten in einer bestimmten Reihenfolge angewendet werden, bevor ein Skript ausgeführt wird.

Dies ist die Ebene, die den normalen Arbeitsablauf tragen soll: Jeder Schritt wird bei der Dateiladung validiert, erscheint in einer Differenz und kann von jemandem überprüft werden, der kein JavaScript liest.

21.1.13 Skripte

Skripte enthält JavaScript für die Fälle, die die deklarativen Schritte nicht ausdrücken können, und ist das, was in ein Mirth-Kanals eigenes Skript unverändert einfließt.

Ein Kanal mit einem Skript wird in der Oberfläche als solcher markiert, da sein Verhalten nicht durch das Lesen der Konfiguration festgestellt werden kann.

21.1.14 Schatten

Schatten führt eine Kandidatenversion dieses Kanals neben ihm aus und berichtet, wo sie sich unterscheiden.

Nichts, was es tut, kann einen Empfänger erreichen.

22 Quellenreferenz

Jeder Weg, auf dem ein Kanal Nachrichten empfangen kann, und jeder Schlüssel, den jeder davon akzeptiert. Ein Kanal hat genau eine Quelle.

22.1 AMQP-Quelle

AMQP-Quelle empfängt von einer Warteschlange oder einem Abonnement.

Eine Nachricht wird nur akzeptiert, nachdem der Kanal sie bearbeitet hat. Eine, die nicht bearbeitet werden konnte, wird als fehlgeschlagene Zustellung freigegeben, sodass der Broker sie erneut zustellt und - im Service Bus, nachdem die maximale Anzahl von Zustellungen für die Warteschlange erreicht wurde - sie im Dead-Letter-Verzeichnis speichert.

Definiert als AMQPSource in internal/config.

SchlüsselTypErforderlichStandard
prefetchganze Zahlnein10
reconnectDauer, z. B. 30s oder 5mnein5s

22.1.1 prefetch

Prefetch ist die Anzahl der Nachrichten, die der Broker im Voraus senden darf.

Standardmäßig 10. Sie werden dennoch einzeln und in der Reihenfolge bearbeitet.

22.1.2 reconnect

Reconnect ist die Wartezeit nach einem Verbindungsverlust.

Defaults to 5s.

22.2 AS2-Quelle

AS2-Quelle empfängt AS2 (RFC 4130): EDI, das über HTTP gepostet, mit S/MIME signiert und verschlüsselt und mit einer Quittung (einer MDN) beantwortet wird, die einen Digest des Eingangs enthält.

Die Nutzlast ist das, was der Kanal bearbeitet; X12 und EDIFACT sind die üblichen.

Definiert als AS2Source in internal/config.

SchlüsselTypErforderlichStandard
listenTextja—
pathTextnein—
tlstlsconf.Settings (ein Block, weglassen, um es nicht zu verwenden)nein—
idTextja—
cert_fileTextja—
key_fileTextja—
partnersListe von AS2-Partnernja—
max_message_sizeganze Zahlnein—
duplicate_windowDauer, z. B. 30s oder 5mnein—

22.2.1 path

Pfad ist der URL-Pfad, an den Partner posten.

Default /as2.

22.2.2 tls

TLS dient dem HTTPS.

Die meisten Partner verlangen es in ihrem Vertrag, zusätzlich zu S/MIME.

22.2.3 id

ID ist unsere AS2-Identität, die Partner in AS2-To senden.

Eine Nachricht an jede andere wird abgelehnt.

22.2.4 partner

Partner sind diejenigen, die hier senden dürfen.

Eine Nachricht von jedem anderen wird abgelehnt.

22.2.5 duplicate_window

DuplicateWindow legt fest, wie lange die Message-ID eines Partners im Gedächtnis behalten wird, damit eine erneut gesendete Nachricht (der Partner hat unsere Quittung nicht erhalten und sie erneut gesendet) mit einer Quittung beantwortet und nicht zweimal weitergeleitet wird (RFC 4130 Abschnitt 7.5).

Default 30 days.

22.3 Azure Blob Quelle

AzureBlobSource nimmt Blobs aus einem Containerpräfix auf.

Definiert als AzureBlobSource in internal/config.

SchlüsselTypErforderlichStandard
prefixTextja—
suffixTextnein—
after_readTextnein—
move_toTextneinprocessed/
error_prefixTextneinerror/
poll_intervalDauer, z. B. 30s oder 5mnein30s
max_object_sizeGanze Zahlnein16 MiB
framedwahr oder falschnein—

22.3.1 move_to

MoveTo ist der Ort, an den ein bearbeiteter Blob verschoben wird.

Standardmäßig processed/.

22.3.2 error_prefix

ErrorPrefix ist der Ort, an den ein Blob, der nicht bearbeitet werden kann, verschoben wird, damit er den Rest nicht blockiert.

Standardmäßig error/.

22.3.3 poll_interval

PollInterval zwischen den Auflistungen.

Defaults to 30s.

22.3.4 max_object_size

MaxObjectSize verweigert einen größeren Blob, der an seinem Ort belassen wird.

Standardmäßig 16 MiB.

22.4 Broker Quelle

BrokerSource liest Nachrichten aus einem Nachrichtenbroker.

Mirths JMS-Reader, der über STOMP erreicht wird, da JMS eine Java-API und kein Protokoll ist. Siehe internal/stomp, um zu erfahren, warum STOMP und nicht OpenWire verwendet wird.

Definiert als BrokerSource in internal/config.

SchlüsselTypErforderlichStandard
addrTextja—
destinationTextja—
loginTextnein—
passcodeTextnein—
hostTextneinder Host der Adresse
selectorTextnein—
subscription_idTextneinder Kanalname
heartbeatDauer, z. B. 30s oder 5mneindreißig Sekunden
reconnectDauer, z. B. 30s oder 5mneinfünf Sekunden
timeoutDauer, z. B. 30s oder 5mneindreißig Sekunden
tlstlsconf.Settings (ein Block, weglassen, um TLS zu deaktivieren)nein—

22.4.1 addr

Addr ist der Host und Port des Brokers.

Erforderlich. 61613 ist der übliche STOMP-Port.

22.4.2 Ziel

Ziel ist die Warteschlange oder das Thema, aus dem gelesen wird.

Required.

Broker schreiben diese unterschiedlich - /queue/name bei ActiveMQ, ein unbekleideter Name bei RabbitMQ - daher wird es unverändert übergeben, anstatt es hier zusammenzustellen. Eine Vermutung würde bedeuten, gegen einen Broker zu arbeiten und stillschweigend nichts auf einem anderen zu lesen.

22.4.3 Anmeldung

Anmeldung und Passcode authentifizieren.

Die meisten Broker lehnen eine anonyme Verbindung ab.

22.4.4 Passwort

Anmeldung und Passcode authentifizieren.

Die meisten Broker lehnen eine anonyme Verbindung ab.

22.4.5 Host

Host ist der virtuelle Host.

Standardmäßig ist es der Host der Adresse.

22.4.6 Selektor

Der Selektor filtert Nachrichten beim Broker.

Ein JMS-Selektor, der weitergeleitet wird, anstatt interpretiert zu werden. Das Filtern beim Broker anstelle von hier bedeutet, dass die Nachrichten, die dieser Kanal nicht möchte, niemals das Netzwerk überqueren - was bei einer gemeinsam genutzten Warteschlange der Unterschied zwischen dem Lesen von hundert Nachrichten pro Tag und hunderttausend ist.

22.4.7 Abonnement-ID

Die Abonnement-ID benennt das Abonnement.

Standardmäßig ist es der Name des Kanals.

Benannt anstelle von generiert, da ein dauerhaftes Abonnement durch es identifiziert wird: Ein generiertes würde bei jedem Neustart ein neues Abonnement erstellen und die alten ansammeln, die niemand liest.

22.4.8 Herzschlag

Der Herzschlag hält die Verbindung aufrecht.

Standardmäßig ist es auf dreißig Sekunden eingestellt.

Standardmäßig ist es hier aktiviert, im Gegensatz zum Standardwert des Clients, da eine Quelle eine Verbindung für Wochen offen hält. Ohne Herzschläge sieht eine Verbindung durch eine Firewall, die stillschweigend die Route abgelehnt hat, von hier aus perfekt aus und Nachrichten hören einfach auf, anzukommen, ohne dass etwas protokolliert wird.

22.4.9 reconnect

Neuverbindung ist die Zeit, die gewartet wird, bevor nach einem Fehler eine Neuverbindung hergestellt wird.

Standardmäßig ist es auf fünf Sekunden eingestellt.

22.4.10 Zeitüberschreitung

Zeitüberschreitungs-Grenzwerte bei der Verbindung.

Standardmäßig ist es auf dreißig Sekunden eingestellt.

22.5 DICOM-Abfragequelle

DICOMQuerySource befragt ein Archiv mit C-FIND und sendet eine Nachricht pro neuem Studium.

Mirth hat keinen äquivalenten Connector. Seine DICOM-Unterstützung ist ein Listener und ein Sender - er kann Bilder empfangen, die an ihn gesendet werden, und sie weiterleiten, und das ist alles. Die Anfrage an ein Archiv, was es enthält, wurde auf ihren Foren seit 2015 angefordert.

Was es wert macht, ist nicht die Abfrage, sondern die Automatisierung: eine Prefetch, die um drei Uhr morgens läuft, eine Rekonkiliation, die feststellt, dass das Archiv ein Studium fehlt, das die RIS sagt, existiert, eine Arbeitsliste, die aus dem tatsächlich gescannten und nicht aus dem bestellten erstellt wird. Diese sind Jobs, die Sites derzeit mit einem geplanten Skript außerhalb des Motors ausführen, was bedeutet, dass sie für ihn unsichtbar sind - keine Wiederholungen, keine Alarmierung, keine Nachrichtenverlauf.

Definiert als DICOMQuerySource in internal/config.

SchlüsselTypErforderlichStandard
addressTextja—
called_aeTextja—
calling_aeTextnein—
levelTextneinSTUDIUM
patient_rootwahr oder falschnein—
matchZuordnung von Text zu Textnein—
returnListe von Textnein—
intervalDauer, z. B. 30s oder 5mja—
windowDauer, z. B. 30s oder 5mnein—
overlapDauer, z. B. 30s oder 5mneineine Stunde
limitGanzzahlnein500
timeoutDauer, z. B. 30s oder 5mneinzwei Minuten
tlstlsconf.Einstellungen (ein Block, weglassen, um nichts zu ändern)nein—
emit_on_first_pollwahr oder falschneinfalsch

22.5.1 Adresse

Die Adresse ist der Host und Port des Archivs.

Required.

Benannt, um mit dem DICOM-Ziel zu übereinstimmen, anstatt abgekürzt. Die beiden waren "Adresse" und "Addr" für einen Nachmittag, was die Art von Inkonsistenz ist, die jemand, der eine Kanaldatei von Hand schreibt, einmal falsch macht und dann das gesamte Format misstraut.

22.5.2 called_ae

CalledAE ist der AE-Titel des Archivs.

In der Praxis erforderlich: Die meisten Archive lehnen eine Assoziation ab, die an etwas anderes adressiert ist, und diese Ablehnung liest sich als Ausfall und nicht als Konfigurationsfehler.

22.5.3 calling_ae

CallingAE ist der AE-Titel, den Perfuse präsentiert.

Archive verwenden es häufig für die Zugriffskontrolle.

22.5.4 Ebene

Die Ebene ist die Abfrageebene: PATIENT, STUDIUM, SERIE oder BILD.

Standardmäßig STUDIUM.

STUDIUM ist der Standard, weil es das ist, was fast jede nützliche Abfrage möchte, und weil die Alternativen die Menschen überraschen: Die Ebene BILD gegen ein großes CT ergibt eine Antwort pro Scheibe, was Hunderte pro Studium sind.

22.5.5 Übereinstimmung

Die Übereinstimmungen sind die Abfrageschlüssel.

Ein Wert filtert; ein leerer Wert fordert, dass das Feld zurückgegeben wird.

Die Schlüssel sind benannt und nicht nummeriert - "Patienten-ID" und nicht "0010,0020" - weil eine Kanaldatei von Menschen gelesen wird und eine Tag-Nummer in einer Konfigurationsdatei eine Nachschlagewerk ist, die jeder Leser durchführen muss.

22.5.6 Rückgabe

Rückgabe sind Felder, die zurückgegeben werden, ohne dass auf sie gefiltert wird.

Getrennt von Match mit einem leeren Wert, obwohl sie identisch codiert sind, da die Absicht unterschiedlich ist und ein Leser sehen kann, welche Schlüssel die Suche einschränken und welche gesammelt werden.

22.5.7 Intervall

Intervall ist, wie oft abgefragt wird.

Required.

22.5.8 Fenster

Fenster ist, wie weit zurück jede Abfrage schaut, als Studien-Datumsbereich.

Null deaktiviert die Datum-Filterung vollständig.

Ein Fenster ist, was dies begrenzt. Ohne eines fragt jede Abfrage das Archiv nach allem, was es jemals gehalten hat, und verwirft dann, was es zuvor gesehen hat - was in einem Testarchiv funktioniert und gegen ein reales Archiv mit Millionen von Studien antisozial ist.

22.5.9 Überlappung

Überlappung fragt erneut in den bereits abgefragten Zeitraum hinein.

Standardmäßig eine Stunde.

Erforderlich und nicht vorsichtig. Eine Studie kann mit dem Datum von gestern registriert werden, unsere Uhr und die des Archivs müssen nicht übereinstimmen, und eine Abfrage-Grenze, die genau mit einer Ankunft übereinstimmt, verliert sie. Die Überlappung fragt erneut und die bereits gesehene Überprüfung stoppt die Duplizität - so dass die Kosten der Überlappung eine leicht größere Abfrage sind und die Kosten der Nicht-Überlappung eine stillschweigend verpasste Studie sind.

22.5.10 Begrenzung

Begrenzung begrenzt die Anzahl der akzeptierten Übereinstimmungen pro Abfrage.

Defaults to 500.

Eine Begrenzung und nicht keine Begrenzung, da ein falsch eingegebener Schlüssel diese in „Gib mir alles“ umwandelt und das erste Symptom davon gegen ein reales Archiv die Frage des Archiv-Administrators ist, wer es bearbeitet.

22.5.11 Zeitüberschreitung

Timeout begrenzt eine Abfrage.

Standardmäßig zwei Minuten.

22.5.12 emit_on_first_poll

EmitOnFirstPoll sendet Nachrichten für alles, was die erste Abfrage findet.

Standardmäßig false.

False ist wichtig. Wenn man dies auf ein Archiv richtet, das bereits eine Million Studien enthält, und es eine Nachricht für jede sendet, ist dies kein nützlicher erster Lauf, und es ist die Art von Fehler, die downstream eher als hier bemerkt wird. Die erste Abfrage zeichnet auf, was existiert, und sendet nichts; die zweite Abfrage und folgende berichten, was neu ist.

22.6 DICOM-Quelle

DICOM-Quelle empfängt Bilddaten als C-STORE-Serviceklasse-Anbieter.

Was ein Krankenhaus einem Modality oder einem PACS zuweist. Mirth bezeichnet dies als DICOM-Listener und es führt nur C-STORE aus, so dass dies Parität und nicht ein Subset ist.

Definiert als DICOMSource in internal/config.

SchlüsselTypErforderlichStandard
listenTextja—
ae_titleTextnein—
allowed_calling_aeListe von Textnein—
sop_classesListe von Textnein—
transfer_syntaxesListe von Textnein—
max_object_bytesGanzzahlnein—
idle_timeoutDauer, z. B. 30s oder 5mnein—
tlstlsconf.Settings (ein Block, weglassen, um es nicht zu verwenden)nein—

22.6.1 Hören

Hören ist die Adresse, auf der der Dienst ausgeführt wird.

Erforderlich. 104 ist der registrierte DICOM-Port; 11112 ist der häufige Alternative, wenn die Bindung an einen privilegierten Port nicht möglich ist.

22.6.2 ae_title

AETitle ist der Name, den dieser Endpunkt selbst verwendet.

Stark empfohlen, aber nicht erforderlich, und bei Abwesenheit gewarnt. Die einzige Zugriffskontrolle auf einem DICOM-Endpunkt ist häufig der AE-Titel, sodass ein Endpunkt, der jeden Titel akzeptiert, alles akzeptiert, was ihn erreichen kann.

22.6.3 allowed_calling_ae

AllowedCallingAE listet die AE-Titel auf, die eine Verbindung herstellen dürfen.

Leer akzeptiert jeden Anrufer.

Dies ist die Zugriffskontrolle, die DICOM tatsächlich hat. Ein PACS ist in der Regel so konfiguriert, dass er einen benannten Anruftitel akzeptiert und alles andere ablehnt, und dieses Ende hatte keine Entsprechung: der angerufene Titel wurde überprüft - also der Name, den der Anrufer wählt, sodass jeder ihn richtig senden kann - während der Anrufer im Logbuch aufgezeichnet und ansonsten ignoriert wurde.

Leer akzeptiert immer noch alles, weil ein Modus, den niemand aufgelistet hat, der normale Zustand einer ersten Installation ist und eine Ablehnung standardmäßig jeden Einsatz am ersten Tag brechen würde. Stattdessen wird gewarnt, und die Warnung nennt die Titel, die eine Verbindung hergestellt haben, sodass jemand diese Informationen aus dem tatsächlich Eingegangenen ausfüllen kann.

22.6.4 sop_classes

SOPClasses beschränkt die Arten von Objekten, die akzeptiert werden.

Leer akzeptiert alles.

Leer ist hier ein vernünftiger Standard, da dieser Motor Objekte weiterleitet, anstatt sie zu interpretieren, sodass die Ablehnung einer unbekannten Klasse gültige Bilder ohne Vorteil ablehnen würde.

22.6.5 transfer_syntaxes

TransferSyntaxes beschränkt die Kodierungen, die akzeptiert werden, in der bevorzugten Reihenfolge.

Leer akzeptiert die drei unkomprimierten.

22.6.6 max_object_bytes

MaxObjectBytes begrenzt ein empfangenes Objekt.

Null verwendet einen Standardwert.

22.6.7 idle_timeout

IdleTimeout schließt eine assoziation, die stillgelegt wurde.

Null bedeutet nie, was normalerweise richtig ist - eine Modalität hält eine Assoziation zwischen Studien offen.

22.6.8 tls

TLS verschlüsselt eingehende Assoziationen und kann ein Clientzertifikat erfordern.

Es ist erwähnenswert: Mirth benötigt für dies sein kostenpflichtiges SSL-Manager-Add-on, und die Community-Forks können es überhaupt nicht ausliefern. DICOM enthält Patientennamen in seinen Metadaten, daher ist dies einer der Orte, an denen es ein echter Vorteil ist, eine Neuschreibung und nicht eine Fork zu sein.

22.7 DICOM-Web-Quelle

DICOMweb-Quelle akzeptiert STOW-RS-Anfragen.

Definiert als DICOMwebSource in internal/config.

SchlüsselTypErforderlichStandard
listenTextja—
pathTextnein/dicom-web
tokenTextnein—
usernameTextnein—
passwordTextnein—
max_object_bytesGanzzahlnein—
tlstlsconf-Einstellungen (ein Block, weglassen, um es nicht zu verwenden)nein—

22.7.1 Hören

Hören ist die Adresse, auf der der Dienst ausgeführt wird.

Required.

22.7.2 path

Pfad ist die Dienstwurzel.

Objekte werden an Pfad/Studien und Pfad/Studien/{uid} akzeptiert. Standardmäßig ist es /dicom-web, was Orthanc und dcm4chee verwenden, sodass ein Sender, der für einen dieser konfiguriert ist, nur den Host ändern muss.

22.7.3 Token

Token, wenn festgelegt, ist als Bearer-Token erforderlich.

Benutzername und Passwort erfordern HTTP-Basicauthentifizierung.

22.7.4 Benutzername

Token, wenn festgelegt, ist als Bearer-Token erforderlich.

Benutzername und Passwort erfordern HTTP-Basicauthentifizierung.

22.7.5 Passwort

Token, wenn festgelegt, ist als Bearer-Token erforderlich.

Benutzername und Passwort erfordern HTTP-Basicauthentifizierung.

22.8 Datenbank-Quelle

Datenbank-Quelle liest Zeilen aus einer Datenbank und wandelt jede in eine Nachricht um.

So beginnen tatsächlich sehr viele Krankenhaus-Schnittstellen. Ein Abteilungssystem hat keine HL7-Fähigkeit, also schreibt jemand Zeilen in eine Zwischentabelle und die Schnittstellen-Engine pollt sie. Es ist unglamourös und es ist überall.

Es ist auch die häufigste Ursache, warum ein Mirth-Kanal blockiert, und der Grund ist fast immer dieselbe Form: Eine Zeile, die nicht verarbeitet werden kann, wird gelesen, schlägt fehl und wird erneut gelesen, für immer, weil nichts sie markiert. Der Kanal sieht lebendig aus. Die Warteschlange sieht leer aus. Nichts bewegt sich, und jede Nachricht hinter der fehlerhaften Zeile wartet auf eine Zeile, die nie erfolgreich sein wird.

Der größte Teil des Designs hier dreht sich darum.

Definiert als DatabaseSource in internal/config.

SchlüsselTypErforderlichStandard
driverTextja—
dsnTextja—
queryTextja—
after_queryTextnein—
key_columnTextnein—
templateTextnein—
columnTextnein—
poll_intervalDauer, z. B. 30s oder 5mnein—
batch_sizeGanzzahlnein100
max_attemptsGanzzahlnein3
query_timeoutDauer, z. B. 30s oder 5mnein30s

22.8.1 Treiber

Treiber benennt die Datenbank.

See SupportedDrivers.

22.8.2 dsn

DSN ist die Verbindung Zeichenfolge.

Bevorziehen Sie eine Umgebungsvariablenreferenz gegenüber einem Literal, da dies normalerweise ein Passwort enthält und Kanäle so konzipiert sind, dass sie in Git gespeichert werden.

22.8.3 Abfrage

Die Abfrage wählt die Zeilen aus, die noch gesendet werden müssen.

Required.

Es muss eine SELECT-Abfrage sein. Eine Abfrage, die schweigend Schreibvorgänge ausführt, würde nach einem Zeitplan mit keiner Aufzeichnung dessen ausgeführt, was geändert wurde.

22.8.4 nach_abfrage

NachAbfrage markiert eine Zeile als verarbeitet und wird mit dem Schlüssel der Zeile ausgeführt.

Strongly recommended.

Ohne diese würde jede Abfrage alle Zeilen noch einmal lesen, die die Abfrage noch entspricht, sodass die Abfrage selbst auf andere Weise verarbeitete Zeilen ausschließen muss. Wenn keines von beiden zutrifft, sendet der Kanal dieselben Zeilen immer wieder, was ein Duplikatsturm und nicht ein Stillstand ist und sogar schlimmer ist.

22.8.5 schluessel_spalte

SchluesselSpalte identifiziert eine Zeile für NachAbfrage, Quarantäne und Entfernung von Duplikaten.

Erforderlich, wenn NachAbfrage festgelegt ist.

22.8.6 vorlage

Vorlage erstellt eine Nachricht aus einer Zeile.

Entweder diese oder Spalte ist erforderlich.

Spaltenverweise verwenden ${spalten_name}. Fehlende Spalten sind ein Fehler beim Laden und nicht eine leere Zeichenfolge in einer klinischen Nachricht.

22.8.7 batch_groesse

BatchGroesse begrenzt die Zeilen, die pro Abfrage übernommen werden.

Defaults to 100.

Begrenzt, da eine unbegrenzte erste Abfrage gegen eine Tabelle, die jemand seit einem Jahr gefüllt hat, alle Daten in den Speicher lesen und dann senden würde, was dazu führt, dass eine Migration einen Live-Empfänger überflutet.

22.8.8 max_versuche

MaxVersuche ist die Anzahl der Male, die eine einzelne Zeile fehlschlagen darf, bevor sie in Quarantäne genommen und die Abfrage fortgesetzt wird.

Defaults to 3.

Dies ist die Einstellung, die den Stillstand verhindert. Ein endloses Wiederholen ist keine Widerstandsfähigkeit, sondern ein schlechter Datensatz, der einen Krankenhaus-Feed stoppt.

22.8.9 abfrage_zeitlimit

AbfrageZeitlimit begrenzt eine einzelne Abfrage.

Defaults to 30s.

22.9 Direkte Quelle

DirekteQuelle empfängt Direct-Mail, das der HISP liefert: einen SMTP-Listener für diese Adresse.

Jede Nachricht wird entschlüsselt, ihre Signatur wird gegen die Anker und ihr Absender gegen Von überprüft und ihr Inhalt wird weitergeleitet: ein XDM-Paket mit Dokumenten, andernfalls jedes Anhang, andernfalls der Text.

Definiert als DirectSource in internal/config.

SchlüsselTypErforderlichStandard
listenTextnein—
tls_certTextnein—
tls_keyTextnein—
max_bytesGanzzahlnein—
smtp_hostTextnein—
usernameTextnein—
passwordTextnein—
imapDirectIMAP (ein Block, weglassen, um es nicht zu verwenden)nein—
xdrDirectXDR (ein Block, weglassen, um es nicht zu verwenden)nein—

22.9.1 smtp_host

SMTPHost, Username und Password sind der HISP-Submission-Server, der verwendet wird, um eine "verarbeitete" Lieferbenachrichtigung (MDN) an den Absender zu senden, sobald eine Nachricht entgegengenommen wurde.

Ohne ihn wird keine Benachrichtigung gesendet.

22.9.2 Benutzername

SMTPHost, Username und Password sind der HISP-Submission-Server, der verwendet wird, um eine "verarbeitete" Lieferbenachrichtigung (MDN) an den Absender zu senden, sobald eine Nachricht entgegengenommen wurde.

Ohne ihn wird keine Benachrichtigung gesendet.

22.9.3 Passwort

SMTPHost, Username und Password sind der HISP-Submission-Server, der verwendet wird, um eine "verarbeitete" Lieferbenachrichtigung (MDN) an den Absender zu senden, sobald eine Nachricht entgegengenommen wurde.

Ohne ihn wird keine Benachrichtigung gesendet.

22.10 E-Mail-Quelle

EmailSource liest E-Mails aus einem Postfach und wandelt Anhänge, Nachrichtentexte oder ganze Nachrichten in Nachrichten um.

Definiert als EmailSource in internal/config.

SchlüsselTypErforderlichStandard
protocolTextnein—
hostTextja—
portGanzzahlnein—
securityTextnein—
tlstlsconf-Einstellungen (ein Block, weglassen, um nicht zu verwenden)nein—
usernameTextja—
passwordTextnein—
oauthEmailOAuth (ein Block, weglassen, um nicht zu verwenden)nein—
mailboxTextnein—
takeTextnein—
attachment_namesListe von Textnein—
allowed_sendersListe von Textnein—
after_readTextnein—
move_toTextnein—
error_folderTextnein—
poll_intervalDauer, z. B. 30s oder 5mnein—
max_message_sizeGanzzahlnein—

22.10.1 Passwort

Das Passwort kann ${ENV} sein; für Gmail ein App-Passwort.

Wird mit oauth ignoriert.

22.10.2 attachment_names

AttachmentNames begrenzt, welche Anhänge entnommen werden, nach Dateinamensmuster (*.hl7).

Leer nimmt jeden Anhang.

22.10.3 allowed_senders

AllowedSenders begrenzt, deren E-Mails gelesen werden: Adressen und Domänen.

Die From-Headers können gefälscht werden, daher hält dies Unfälle und ungezielte E-Mails fern, nicht jedoch einen Angreifer.

22.10.4 move_to

MoveTo ist das Postfach, in das die verarbeitete E-Mail verschoben wird; standardmäßig „Verarbeitet“.

Wird erstellt, wenn es fehlt.

22.11 FTP-Quelle

FTPSource sammelt Dateien von einem FTP- oder FTPS-Server.

Warum FTP noch hier ist

Es ist dreißig Jahre her, dass es durch etwas anderes ersetzt werden sollte, und viele Krankenhaus-Systeme exportieren immer noch dorthin: Geräte, deren Firmware nie aktualisiert wird, Abrechnungssysteme, deren Hersteller für eine Änderung Geld verlangen. Die Weigerung, FTP zu verwenden, bedeutet nicht, dass diese Systeme verschwinden, sondern dass der Integrationsserver nicht verwendet werden kann.

FTPS ist standardmäßig. Es ist das gleiche Protokoll mit TLS, die meisten verbleibenden Server unterstützen es, und es ist ein viel einfacheres Gespräch mit einem Sicherheitsteam als einfaches FTP.

Definiert als FTPSource in internal/config.

SchlüsselTypErforderlichStandard
hostTextja—
userTextnein—
passwordTextnein—
securityftpconn.Securityneinexplizit
insecure_skip_verifywahr oder falschnein—
rootTextnein—
timeoutDauer, wie 30s oder 5mneindreißig Sekunden

22.11.1 Host

Host ist der Server mit einem optionalen Port.

Port 21 wird angenommen.

22.11.2 Benutzer

Benutzer und Passwort authentifizieren.

Beide können für einen anonymen Server weggelassen werden.

Anonymes FTP wird immer noch verwendet, um einige öffentliche Referenz-Feeds zu veröffentlichen, sodass ein leerer Benutzer eine legitime Konfiguration und kein Übersehen ist und nicht abgelehnt wird. Auf einem Server, der Credentials erwartet, führt das Weglassen von Credentials zu einem Anmeldefehler bei der Verbindung, der gegen den Kanal gemeldet wird und nicht stillschweigend erneut versucht wird.

22.11.3 Passwort

Benutzer und Passwort authentifizieren.

Beide können für einen anonymen Server weggelassen werden.

Anonymes FTP wird immer noch verwendet, um einige öffentliche Referenz-Feeds zu veröffentlichen, sodass ein leerer Benutzer eine legitime Konfiguration und kein Übersehen ist und nicht abgelehnt wird. Auf einem Server, der Credentials erwartet, führt das Weglassen von Credentials zu einem Anmeldefehler bei der Verbindung, der gegen den Kanal gemeldet wird und nicht stillschweigend erneut versucht wird.

22.11.4 Sicherheit

Sicherheit ist explizit, implizit oder keine.

Standardmäßig ist explizit, was FTPS mit AUTH TLS auf dem normalen Port verhandelt. "Keine" ist einfaches FTP und muss namentlich angefordert werden.

22.11.5 Root

Root ist das Verzeichnis, relativ zu dem jeder Pfad ist, und gegen das die Einschränkung durchgesetzt wird.

Der Server hat keine Vorstellung davon: Ein FTP-Server akzeptiert gerne ../.. als Pfad. Also ist dies das, was einen move_to-Vorgang daran hindert, überall zu schreiben, wohin das Konto reichen kann.

22.11.6 Zeitüberschreitung

Timeout begrenzt einen Vorgang, nicht die gesamte Abfrage.

Standardmäßig ist es auf dreißig Sekunden eingestellt.

Pro Vorgang, da eine Abfrage, die ein Verzeichnis auflistet und zwanzig Dateien abruft, einundzwanzig Vorgänge durchführt und ein einziger Budgetrahmen für alle diese Vorgänge den Transfer einer großen Datei abbrechen würde.

22.12 Dateiquelle

FileSource liest Dateien aus einem Verzeichnis, das dieser Server sehen kann.

Der Connector, den ein Standort zuerst versucht

Ein Analyse-Tool schreibt Ergebnisse in einen Ordner. Ein Abrechnungssystem legt eine Charge über Nacht ab. Radiologie exportiert Berichte in ein Verzeichnis, das jemand vor Jahren gemountet hat. Keiner davon beinhaltet ein Protokoll, und eine Integrations-Engine, die keinen Ordner lesen kann, scheitert an ihrer Bewertung am ersten Nachmittag.

Definiert als FileSource in internal/config.

SchlüsselTypErforderlichStandard
rootTextja—
follow_symlinkswahr oder falschnein—

22.12.1 Root

Root begrenzt jeden Pfad, den diese Quelle berührt.

Required.

Getrennt von Dir, damit move_to und error_dir relativ und dennoch eingeschränkt sein können. Wenn nur Dir angegeben wird, wäre ein error_dir von "../failed" außerhalb von allem, was die Quelle genehmigt wurde, und die Ablehnung wäre willkürlich, da es nichts gäbe, gegen das sie ablehnen könnte.

22.13 GCS-Quelle

GCSSource nimmt Objekte von einem Bucket-Präfix auf, wie die s3- und azure_blob-Quellen.

Definiert als GCSSource in internal/config.

SchlüsselTypErforderlichStandard
prefixTextja—
suffixTextnein—
after_readTextnein—
move_toTextneinprocessed/
error_prefixTextneinerror/
poll_intervalDauer, z. B. 30s oder 5mnein30s
max_object_sizeGanze Zahlnein16 MiB
framedwahr oder falschnein—

22.13.1 move_to

MoveTo ist der Ort, an den ein bearbeitetes Objekt geht, wenn after_read auf move gesetzt ist.

Standardmäßig processed/.

22.13.2 error_prefix

ErrorPrefix ist der Ort, an den ein Objekt geht, das nicht bearbeitet werden konnte.

Standardmäßig error/.

22.13.3 poll_interval

PollInterval ist die Häufigkeit, mit der das Prefix aufgelistet wird.

Defaults to 30s.

22.13.4 max_object_size

MaxObjectSize lässt größere Objekte an ihrem Ort.

Standardmäßig 16 MiB.

22.14 HTTP-Quelle

HTTPSource akzeptiert Nachrichten über HTTP.

Ein Listener anstelle eines Pollers: Etwas postet eine Nachricht und erhält eine Bestätigung zurück, was die moderne Hälfte des Krankenhauses integriert, wenn MLLP nicht verfügbar ist.

Definiert als HTTPSource in internal/config.

SchlüsselTypErforderlichStandard
listenTextja—
pathTextnein"/"
tlstlsconf.Settings (ein Block, weglassen, um nichts zu setzen)nein—
tokenTextnein—
max_message_sizeGanzzahlnein—
read_timeoutDauer, z. B. 30s oder 5mnein—
ackAcknein—

22.14.1 Hören

Hören ist die Adresse, auf der der Dienst ausgeführt wird.

Required.

22.14.2 path

Pfad ist der URL-Pfad, auf dem Nachrichten akzeptiert werden.

Defaults to "/".

22.14.3 Token

Token, wenn gesetzt, ist in einem Authorization: Bearer-Header erforderlich.

Es gibt keinen Standard und keinen anonymen Modus-Schalter: Ein HTTP-Endpunkt in einem Krankenhausnetzwerk ohne Authentifizierung ist eine Entscheidung, die im Datei sichtbar sein muss, sodass das Leerlassen dieses Feldes bei der Ladezeit als Warnung gemeldet wird.

22.14.4 max_message_size

MaxMessageSize begrenzt den eingehenden Nachrichtentext.

Null verwendet einen Standardwert.

22.15 IBMMQ-Quelle

IBMMQSource liest eine Warteschlange.

Definiert als IBMMQSource in internal/config.

SchlüsselTypErforderlichStandard
poll_intervalDauer, z. B. 30s oder 5mnein2s

22.15.1 poll_interval

PollInterval ist die Wartezeit, wenn die Warteschlange leer ist oder nach einer Nachricht, die nicht bearbeitet werden konnte.

Defaults to 2s.

22.16 JavaScript-Quelle

JavaScriptSource konfiguriert eine Quelle, die ein Skript auf einem Timer ausführt und die zurückgegebenen Nachrichten in den Kanal einfügt.

Dies ist das Äquivalent zum Mirth-"JavaScript-Reader".

Das Skript wird in einer goja-VM mit dem gleichen Sandbox wie Transformer-Skripte ausgeführt: msg ist nicht verfügbar (es gibt noch keine eingehende Nachricht), aber globalMap, configurationMap, logger und DateUtil sind vorhanden. Das Skript muss einen String (eine Nachricht) oder ein Array von Strings (viele) zurückgeben. Das Zurückgeben von nichts oder einem leeren Array bedeutet, dass der Poll keine Nachrichten produziert hat, was normal ist.

Definiert als JavaScriptSource in internal/config.

SchlüsselTypErforderlichStandard
scriptTextja—
poll_intervalDauer, z. B. 30s oder 5mnein—
timeoutDauer, z. B. 30s oder 5mnein—

22.16.1 poll_interval

PollInterval legt fest, wie oft das Skript ausgeführt wird.

Null bedeutet 5 Sekunden.

22.16.2 Zeitüberschreitung

Timeout begrenzt die Ausführung eines einzelnen Skripts.

Null bedeutet 30 Sekunden.

22.17 Kafka-Quelle

KafkaSource liest Nachrichten aus einem Kafka-Topic.

Definiert als KafkaSource in internal/config.

SchlüsselTypErforderlichStandard
brokersListe von Textja—
topicsListe von Textja—
groupTextja—
from_beginningwahr oder falschnein—
commit_after_deliverywahr oder falsch (ein Block, weglassen, um es auszulassen)nein—
max_message_sizeganze Zahlneinder Kanallimit
session_timeoutDauer, z. B. 30s oder 5mneinfünfundvierzig Sekunden
timeoutDauer, z. B. 30s oder 5mneindreißig Sekunden
saslKafkaSASL (ein Block, weglassen, um es auszulassen)nein—
tlstlsconf.Settings (ein Block, weglassen, um es auszulassen)nein—

22.17.1 Brokerverzeichnis

Brokerverzeichnis ist die Liste der Bootstrap-Server.

Required.

Eine Liste anstelle einer einzelnen Adresse, da ein einzelner Bootstrap-Broker ein einzelner Fehlerpunkt für das Hochfahren ist: Der Cluster überlebt den Verlust und dieser Kanal würde es nicht.

22.17.2 Themen

Themen sind die Themen, die gelesen werden.

Mindestens eines ist erforderlich.

22.17.3 gruppe

Gruppe ist die Consumer-Gruppe.

Required.

Benannt anstelle von generiert und erforderlich anstelle von standardmäßig, da es sich um das handelt, was sich daran erinnert, wie weit dieser Kanal gelesen hat. Eine generierte Gruppe würde von Anfang an beginnen - oder vom Ende, wodurch alles verloren ginge - bei jedem Neustart und sie würde die alte Gruppe zurücklassen, die die committeten Offsets hält, die niemand liest. Die Anforderung macht die Person, die die Sache benennen muss, die über Neustarts hinweg gleich bleiben muss.

22.17.4 from_beginning

FromBeginning liest das Thema von seinem Anfang, wenn die Gruppe keinen committeten Offset hat.

Standardmäßig ausgeschaltet, damit ein neuer Kanal, der auf ein Thema mit zwei Jahren Geschichte zeigt, nicht zwei Jahre Patientenereignisse in ein Live-System auf dem Tag abspielt, an dem es eingeschaltet wird. Die erste Person, die das tut, würde es in der Produktion tun, da das Thema mit der Geschichte dort ist.

22.17.5 commit_after_delivery

CommitAfterDelivery committet den Offset nur dann, wenn die Nachricht verarbeitet wurde.

Standardmäßig eingeschaltet und der Grund dafür ist der ganze Unterschied zwischen dem Verlust einer Nachricht und dem zweimaligen Anzeigen. Das Committen beim Lesen bedeutet, dass ein Absturz zwischen dem Committen und der Lieferung die Nachricht stillschweigend verliert und nichts irgendwo aufzeichnet, dass es existiert. Das Committen nach der Lieferung bedeutet, dass ein Absturz im gleichen Fenster es erneut liefert, was sichtbar ist und das HL7-Empfänger darauf ausgelegt sind, es zu tolerieren - eine doppelte A08 ist ein Ärgernis und ein fehlendes Laborergebnis ist ein Patientensicherheitsereignis.

22.17.6 max_message_size

MaxMessageSize begrenzt einen Datensatz.

Standardmäßig auf die Kanallimit gesetzt.

22.17.7 Sitzungszeitüberschreitung

SessionTimeout legt fest, wie lange der Gruppenkoordinator wartet, bevor er annimmt, dass dieser Consumer nicht mehr vorhanden ist und seine Partitionen neu zuweist.

Standardmäßig sind es fünfundvierzig Sekunden.

22.17.8 Zeitüberschreitung

Zeitlimits für Verbindungen und Metadatenanfragen.

Standardmäßig ist es auf dreißig Sekunden eingestellt.

22.18 MQTT-Quelle

MQTTSource abonniert einen Themenfilter.

Definiert als MQTTSource in internal/config.

SchlüsselTypErforderlichStandard
topicTextja—
reconnectDauer, z. B. 30s oder 5mnein5s

22.18.1 reconnect

Neuverbinden ist die Wartezeit nach einer unterbrochenen Verbindung oder nach einer Nachricht, die nicht bearbeitet werden konnte.

Defaults to 5s.

22.19 Pub-Sub-Quelle

PubSubSource liest von einem Pub/Sub-Abonnement.

Definiert als PubSubSource in internal/config.

SchlüsselTypErforderlichStandard
subscriptionTextja—
max_messagesGanzzahlnein10
reconnectDauer, z. B. 30s oder 5mnein5s

22.19.1 Max_Nachrichten

MaxMessages legt fest, wie viele Nachrichten auf einmal abgerufen werden.

Sie werden dennoch einzeln und in der Reihenfolge bearbeitet. Standardmäßig sind es 10.

22.19.2 reconnect

Neuverbinden ist die Wartezeit nach einem Fehler.

Defaults to 5s.

22.20 S3-Quelle

S3Source liest Objekte aus einem Bucket.

Definiert als S3Source in internal/config.

SchlüsselTypErforderlichStandard
bucketTextja—
path_stylewahr oder falschnein—
prefixTextnein—
suffixTextnein—
after_readTextnein—
move_toTextneinverarbeitet/
error_prefixTextneinfehler/
poll_intervalDauer, z. B. 30s oder 5mnein30s
max_object_sizeGanzzahlnein16 MiB
framedwahr oder falschnein—

22.20.1 Präfix

Präfix begrenzt, welche Objekte gelesen werden, z. B. eingehend/.

Leere liest den gesamten Bucket, was mit nach_Lesen: verschieben abgelehnt wird, es sei denn, verschieben_nach ist außerhalb davon - ansonsten würden verschobene Objekte erneut gelesen.

22.20.2 nach_Lesen

AfterRead ist verschieben (Standard) oder löschen.

Es gibt kein Verlassen: Ein Bucket hat keine Datei, an die sich ein Poller erinnern kann, über einen Neustart hinweg, also bedeutet das Verlassen von Objekten, dass sie jedes Mal, wenn Perfuse startet, erneut gelesen werden.

22.20.3 move_to

MoveTo ist das Präfix, zu dem ein bearbeitetes Objekt verschoben wird.

Standardmäßig processed/.

22.20.4 error_prefix

ErrorPrefix ist der Ort, an den ein Objekt verschoben wird, das nicht bearbeitet werden konnte, damit eine fehlerhafte Datei den Rest nicht blockiert.

Standardmäßig error/.

22.20.5 poll_interval

PollInterval zwischen den Auflistungen.

Defaults to 30s.

22.20.6 max_object_size

MaxObjectSize lehnt alles Größere ab.

Standardmäßig 16 MiB.

22.20.7 gerahmt

Framed liest mehrere MLLP-gerahmte Nachrichten aus einem Objekt.

Ansonsten ist ein Objekt eine Nachricht.

22.21 SFTP-Quelle

SFTPSource sammelt Nachrichten aus einem Verzeichnis auf einem SFTP-Server.

Extrem häufig und selten besprochen. Ein Labor oder ein Radiologiesystem schreibt alle paar Minuten eine Datei, ein SFTP-Server hält sie, und etwas muss kommen und sie abholen. Die Hälfte der als "wir senden Ihnen HL7" bezeichneten Feeds ist dies.

Der Teil, der Pflege verdient, ist nicht der Transfer. Es ist, dass eine Datei, die geschrieben wird, und eine Datei, die fertig geschrieben wurde, über SFTP identisch aussehen, sodass eine Poll, die auch nur slightly zu eifrig ist, eine halbe Nachricht sammelt. Das produziert eine verkürzte, aber oft parsebare HL7-Nachricht, was das schlechteste verfügbare Ergebnis ist: Sie wird akzeptiert, bestätigt, gespeichert und geliefert, und die fehlende Hälfte wird nie wieder erwähnt.

Definiert als SFTPSource in internal/config.

SchlüsselTypErforderlichStandard
hostTextja22
userTextja—
passwordTextnein—
key_fileTextnein—
key_passphraseTextnein—
known_hosts_fileTextnein—
insecure_skip_host_key_checkwahr oder falschnein—
dirTextja—
patternTextneinalles
poll_intervalDauer, wie 30s oder 5mnein—
after_readTextnein—
move_toTextnein—
error_dirTextnein—
stable_forDauer, wie 30s oder 5mnein5s
framedwahr oder falschnein—
max_file_sizeganze Zahlnein64MB
timeoutDauer, wie 30s oder 5mnein60s

22.21.1 Host

Host ist der Server mit einem optionalen Port.

Defaults to 22.

22.21.2 Passwort

Passwort authentifiziert mit einem Passwort.

Prefer KeyFile.

22.21.3 key_file

KeyFile ist ein privater Schlüssel.

Die bessere Wahl, und die, die Krankenhaus-Sicherheitsteams anfordern.

22.21.4 known_hosts_file

KnownHostsFile verifiziert die Identität des Servers.

Erforderlich, es sei denn, InsecureSkipHostKeyCheck ist gesetzt. Ohne es gibt es nichts, um den echten Server von allem zu unterscheiden, was auf diese Adresse antwortet, und die Anmeldeinformationen werden übergeben, bevor jemand es bemerkt.

22.21.5 insecure_skip_host_key_check

InsecureSkipHostKeyCheck akzeptiert jeden Host-Schlüssel.

Existiert, weil eine direkte Ablehnung die Leute zu einem Shell-Skript mit StrictHostKeyChecking=no führt, was in jeder Hinsicht, einschließlich der Überprüfbarkeit, schlimmer ist. Es warnt laut und ist niemals der Standard.

22.21.6 pattern

Das Muster wählt Dateien nach Glob aus.

Standardmäßig werden alle Dateien ausgewählt.

22.21.7 move_to

MoveTo ist das Remote-Verzeichnis, in das Dateien nach dem Lesen verschoben werden.

Erforderlich, wenn AfterRead auf "move" gesetzt ist.

22.21.8 stabil für

StableFor legt fest, wie lange die Größe und die Änderungszeit einer Datei unverändert bleiben müssen, bevor sie gelesen wird.

Defaults to 5s.

Diese Einstellung verhindert, dass nur die Hälfte einer Nachricht gesammelt wird. Null bedeutet, dass alles gelesen wird, was funktioniert, bis eine Datei groß genug ist oder ein Netzwerk langsam genug ist, dass das Schreiben länger dauert als eine Abfrage.

22.21.9 gerahmt

Framed gibt an, dass die Datei MLLP-gerahmte Nachrichten enthält.

Wenn falsch, wird die Datei an MSH-Grenzen geteilt.

22.21.10 maximale Dateigröße

MaxFileSize verweigert eine Datei, die größer ist als diese Anzahl von Bytes.

Standardmäßig 64 MB.

22.21.11 Zeitüberschreitung

Timeout begrenzt eine einzelne Verbindung.

Defaults to 60s.

22.22 SMB-Quelle

SMB-Quelle sammelt Dateien von einem Windows-Dateifreigabe.

Definiert als SMBSource in internal/config.

SchlüsselTypErforderlichStandard
hostTextja—
shareTextja—
userTextnein—
passwordTextnein—
domainTextnein—
rootTextnein—
timeoutDauer, z. B. 30s oder 5mneindreißig Sekunden

22.22.1 Host

Host ist der Server mit einem optionalen Port.

Port 445 wird angenommen.

22.22.2 Freigabe

Freigabe ist der Freigabename: das "data" in \\\server\data.

Ein Pfad hier wird abgelehnt, anstatt ihn zu kürzen.

22.22.3 Benutzer

Benutzer und Passwort sind das Windows-Konto.

In der Praxis erforderlich.

Eine Freigabe, die ohne Anmeldeinformationen erreicht werden kann, ist selten genug in einem Netzwerk, dass ein leerer Benutzer hier eher ein Fehler als ein Gastkonto ist - aber es wird akzeptiert, da die Ablehnung es blockieren würde, wo die Anordnung korrekt ist. Wenn das Konto einer Domäne angehört, setzen Sie auch die Domäne: Die Authentifizierung eines Domänenkontos ohne diese schlägt fehl, was wie ein falsches Passwort aussieht.

22.22.4 Passwort

Benutzer und Passwort sind das Windows-Konto.

In der Praxis erforderlich.

Eine Freigabe, die ohne Anmeldeinformationen erreicht werden kann, ist selten genug in einem Netzwerk, dass ein leerer Benutzer hier eher ein Fehler als ein Gastkonto ist - aber es wird akzeptiert, da die Ablehnung es blockieren würde, wo die Anordnung korrekt ist. Wenn das Konto einer Domäne angehört, setzen Sie auch die Domäne: Die Authentifizierung eines Domänenkontos ohne diese schlägt fehl, was wie ein falsches Passwort aussieht.

22.22.5 Domäne

Das Domäne ist die Windows-Domäne oder Arbeitsgruppe.

Leer ist normalerweise richtig für ein lokales Konto.

22.22.6 Zeitüberschreitung

Timeout begrenzt eine Operation.

Standardmäßig ist es auf dreißig Sekunden eingestellt.

Es lohnt sich, dies auf einem Freigabe-Link über einen Standort hinweg zu erhöhen. Eine SMB-Operation gegen einen entfernten Server ist langsamer als dieselbe Operation lokal, sodass ein für ein LAN abgestimmter Standard Timeouts verursacht, die so aussehen, als ob die Freigabe nicht verfügbar wäre.

22.23 SOAP-Quelle

SOAP-Quelle akzeptiert Nachrichten, die in einem SOAP-Umschlag eingeschlossen sind.

Das Gegenstück zur SOAP-Zieladresse und die seltenere Richtung: Die meisten Krankenhausintegrationen haben Perfuse, das einen Dienst aufruft, anstatt selbst einer zu sein. Es existiert, weil Mirths Web Service Listener existiert und ein Standort, dessen sendendes System nur SOAP spricht, nicht migrieren kann, ohne es.

Dies ist absichtlich kein allgemeines Webdienst-Framework. Es akzeptiert einen Umschlag, nimmt die Nachricht daraus heraus und antwortet mit einem Umschlag. Es gibt kein WS-Sicherheit, kein MTOM, kein WS-Adressierung und keine generierten Bindungen - dieselben Auslassungen wie bei der Zieladresse, aus demselben Grund: Eine halbe Implementierung von WS-Sicherheit ist schlimmer als gar keine.

Definiert als SOAPSource in internal/config.

SchlüsselTypErforderlichStandard
listenTextja—
profileTextnein—
pathTextnein"/"
versionTextnein1
elementTextnein—
base64wahr oder falschnein—
response_elementTextnein"AckResponse"
response_namespaceTextnein—
wsdlTextnein—
tlstlsconf-Einstellungen (ein Block, weglassen, um nicht zu verwenden)nein—
tokenTextnein—
usernameTextnein—
passwordTextnein—
max_message_sizeGanzzahlnein—
read_timeoutDauer, z. B. 30s oder 5mnein—
ackAcknein—
fault_on_nakwahr oder falschnein—

22.23.1 Hören

Hören ist die Adresse, auf der der Dienst ausgeführt wird.

Required.

22.23.2 Profil

Der Profilname gibt einen Standarddienst an, den dieser Endpunkt implementiert.

Leer akzeptiert jeden Umschlag, wie unten konfiguriert.

"cdc-iis" antwortet wie ein Impfregister auf der CDC-Schnittstelle (urn:cdc:iisb:2011): connectivityTest wird widergegeben, submitSingleMessage's hl7Message ist die Nachricht und die Kanalbestätigung wird zurückgegeben, die WSDL wird unter ?wsdl bereitgestellt und Benutzername und Passwort, wenn festgelegt, werden gegen die im Textkörper (wo die WSDL sie platziert) und nicht gegen die HTTP-Authentifizierung überprüft. Für ein Testdouble eines Registers oder für einen Standort, der Submissions auf die Weise von Registern erhält.

22.23.3 path

Pfad ist der URL-Pfad, auf dem Umschläge akzeptiert werden.

Defaults to "/".

22.23.4 Version

Die Version ist die SOAP-Version, die als Antwort verwendet wird, „1.1“ oder „1.2“.

Defaults to 1.1.

Anfragen werden unabhängig von der Version akzeptiert, da ein Absender, der dies falsch macht, häufig ist und die Ablehnung nichts bewirkt. Die Einstellung steuert die Antwort, bei der ein Fehler bedeutet, dass der Absender die Antwort nicht lesen kann.

22.23.5 Element

Element gibt den Namen des Elements an, das den Nachrichtentext im SOAP-Body enthält.

Leer bedeutet den gesamten Body-Text.

Benannt anstelle von erraten, da ein Body mehrere Elemente enthalten kann - eine Nachricht neben einem Absenderkennzeichen und einem Zeitstempel - und die gesamte Body-Entnahme dem Motor einen XML-Fragment übergeben würde, wo er HL7 erwartet.

22.23.6 Base64

Base64 decodiert den Inhalt des Elements, bevor es als Nachricht behandelt wird.

Häufig in realen Diensten, da HL7 Wagenrücklaufzeichen enthält und Anrufer, die nicht darüber nachgedacht haben, XML-Code erzeugen, der diese Zeichen verdirbt. Wenn der Inhalt als Base64 decodiert wird, aber nicht dazu bestimmt war, ist das Ergebnis keine Nachricht und der Motor sagt es - was der Grund ist, warum dies explizit und nicht erraten wird.

22.23.7 Antwort-Element

ResponseElement benennt das Element, das die Bestätigung in der Antwort umschließt.

Standardmäßig ist es auf "AckResponse" gesetzt.

22.23.8 wsdl

WSDL ist eine Datei, die am Hörpfad mit ?wsdl bereitgestellt wird.

Leer bedeutet, dass keine bereitgestellt wird.

Eine Datei anstelle von etwas Generiertem. Ein generiertes WSDL würde beschreiben, was dieser Endpunkt akzeptiert, was fast nie das ist, wogegen das sendende System entwickelt wurde - und ein WSDL, das fast richtig ist, kostet mehr Zeit als gar keines, weil es autoritativ erscheint.

22.23.9 Benutzername

Benutzername und Passwort erfordern, wenn gesetzt, HTTP-Basicauthentifizierung.

Es wird zusammen mit einem Token angeboten, weil SOAP-Anrufer überwiegend Basicauthentifizierung erwarten und eine Website, deren sendendes System nicht geändert werden kann, die Option benötigt, die es bereits hat.

22.23.10 Passwort

Benutzername und Passwort erfordern, wenn gesetzt, HTTP-Basicauthentifizierung.

Es wird zusammen mit einem Token angeboten, weil SOAP-Anrufer überwiegend Basicauthentifizierung erwarten und eine Website, deren sendendes System nicht geändert werden kann, die Option benötigt, die es bereits hat.

22.23.11 max_message_size

MaxMessageSize begrenzt den eingehenden Nachrichtentext.

Null verwendet einen Standardwert.

22.23.12 fault_on_nak

FaultOnNak beantwortet eine negative Bestätigung mit einem SOAP-Fehler anstelle einer normalen Antwort, die die NAK enthält.

Standardmäßig ist es deaktiviert, was die richtige Standardeinstellung ist und erklärt werden sollte. HL7 hat bereits eine Möglichkeit, zu sagen: "Ich habe dies erhalten und abgelehnt", und das ist eine NAK - ein erfolgreicher Austausch, der eine abgelehnte Nachricht meldet. Das Gleiche in einen Transportfehler umzuwandeln, teilt dem Absender mit, dass seine Anfrage fehlerhaft war, was nicht der Fall war, und viele Clients reagieren damit, dass sie sie ewig wiederholen.

Es existiert, weil einige Anrufer nur auf den HTTP-Status achten und eine Ablehnung sonst als Erfolg behandeln würden.

22.24 SQS-Quelle

SQSSource liest von einer SQS-Warteschlange.

Eine Nachricht wird nur gelöscht, nachdem der Kanal sie bearbeitet hat - zugestellt, gefiltert oder auf eine Weise fehlgeschlagen, die der Kanal aufzeichnet. Bis dahin bleibt sie in der Warteschlange, unsichtbar für visibility_timeout, und kommt zurück, wenn Perfuse stoppt. Eine Nachricht geht also nie verloren; der Preis dafür ist, dass eine doppelt ankommen kann, was SQS selbst bereits zulässt.

Definiert als SQSSource in internal/config.

SchlüsselTypErforderlichStandard
queue_urlTextja—
wait_secondsGanzzahlnein20: eine leere Warteschlange kostet eine Anfrage alle zwanzig Sekunden
max_messagesGanzzahlnein10
visibility_timeoutDauer, wie z. B. 30s oder 5mneindie eigene Einstellung der Warteschlange

22.24.1 visibility_timeout

VisibilityTimeout ist die Zeit, die eine empfangene Nachricht verborgen bleibt, während sie bearbeitet wird.

Standardmäßig ist es auf die eigene Einstellung der Warteschlange gesetzt.

22.25 Serien-Quelle

SerialSource liest Nachrichten von einem Seriellen Anschluss.

Warum ein Serien-Stecker im Jahr 2026

Weil die Geräte noch vorhanden sind. Ein Blutgasanalysator, der 2009 gekauft wurde, mit einem funktionierenden Sensor und einer 25-poligen Steckverbindung, ein Bettmonitor, eine Waage in einer Dialyseeinheit, eine ältere Narkosemaschine. Keines von ihnen wird jemals einen Ethernet-Anschluss erhalten, mehrere davon kosten sechsstellige Beträge, und die Alternative zum Lesen davon ist, dass jemand Ergebnisse in ein Formular eingibt.

Mirth hat einen seriellen Connector. Perfuse hatte nichts und ein Standort mit einem dieser Geräte hatte überhaupt keine Route.

Framing wird mit dem TCP-Connector gemeinsam genutzt

Die Framings sind überall gleich, egal woher die Bytes kommen: Ein Analyser, der STX/ETX über einen Socket spricht, spricht auch STX/ETX über ein Kabel. Deshalb wird der TCP-Framing-Block wiederverwendet, anstatt einen eigenen zu definieren, was auch bedeutet, dass ein Gerät, das von einem seriellen Kabel zu einem seriellen-Ethernet-Adapter umgezogen wird, seine Framing-Konfiguration beibehält.

Was unterscheidet eine serielle Leitung

Es gibt keine Verbindung. Ein Socket teilt Ihnen mit, wenn der Peer weg ist; ein Kabel tut dies nicht. Ein abgestecker Kabel, ein ausgeschaltetes Gerät und ein Gerät, das nichts zu sagen hat, sind nicht zu unterscheiden - alle drei sind Stille. Deshalb gibt es quiet_after: Ohne etwas, das sagt, „diese Leitung ist länger still, als sie sollte“, sieht eine tote Leitung genauso aus wie eine ruhige Nacht.

Definiert als SerialSource in internal/config.

SchlüsselTypErforderlichStandard
portTextja—
baudGanzzahlja—
data_bitsGanzzahlnein8
parityTextneinnone
stop_bitsTextnein1
flow_controlTextneinnone
max_message_sizeGanzzahlnein—
quiet_afterDauer, z. B. 30s oder 5mnein—
replyTextnein—
reply_textTextnein—
reopen_afterDauer, z. B. 30s oder 5mnein—

22.25.1 Baud

Baud ist die Geschwindigkeit.

Erforderlich, da das Raten Bytes anstelle eines Fehlers produziert.

Ein falscher Baud-Rate schlägt nicht fehl. Er liefert plausibel aussehenden Unsinn: Framing-Bytes erscheinen zufällig, gelegentliche Läufe decodieren als druckbare Zeichen, und ein nachsichtiger Parser akzeptiert einige davon. Es gibt absichtlich keinen Standard.

22.25.2 Parität

Parität ist none, odd, even, mark oder space.

Standardmäßig none.

22.25.3 Stoppbits

Stoppbits sind 1, 1,5 oder 2, geschrieben als „1“, „1,5“ oder „2“.

Defaults to 1.

22.25.4 Flusskontrolle

Flusskontrolle ist none, hardware oder software.

Standardmäßig none.

Wert, korrekt einzustellen, anstatt es unkonfiguriert zu lassen. Mit erwarteter Hardware-Flusskontrolle und nicht konfiguriert, hält ein Gerät mitten in einer langen Nachricht auf und das Ergebnis ist eine verkürzte Nachricht anstelle eines Fehlers.

22.25.5 quiet_after

QuietAfter protokolliert eine Warnung, wenn nichts für diese Dauer empfangen wurde.

Der einzige Weg, um eine tote serielle Leitung zu bemerken. Ein abgestecker Kabel und eine ruhige Nacht sind die gleiche Stille, also muss jemand sagen, wie lange zu lange für dieses bestimmte Gerät ist.

22.25.6 reopen_after

ReopenAfter ist die Dauer, die gewartet werden soll, bevor ein Port, der fehlgeschlagen ist, wieder geöffnet wird.

Ein USB-Serienadapter, der abgesteckt und wieder eingesteckt wird, kommt als gleicher Gerätepfad zurück, aber mit einem anderen Kernel-Handle, sodass der alte Fehlermeldungen für immer zurückgibt. Das Wiederöffnen ist die einzige Wiederherstellung, und das Ausführen in einer engen Schleife füllt das Protokoll.

22.26 Quelle

Die Quelle ist der Ort, an dem ein Kanal Nachrichten empfängt.

Definiert als Source in internal/config.

SchlüsselTypErforderlichStandard
typeSourceTypeja—
listenTextja—
max_message_sizeGanzzahlnein—
idle_timeoutDauer, z. B. 30s oder 5mnein—
max_connectionsGanzzahlnein—
tlstlsconf.Settings (ein Block, weglassen, um nichts zu übertragen)nein—
httpHTTPSource (ein Block, weglassen, um nichts zu übertragen)nein—
soapSOAPSource (ein Block, weglassen, um nichts zu übertragen)nein—
dicomwebDICOMwebSource (ein Block, weglassen, um nichts zu übertragen)nein—
directDirectSource (ein Block, weglassen, um nichts zu übertragen)nein—
dicomDICOMSource (ein Block, weglassen, um nichts zu übertragen)nein—
fileFileSource (ein Block, weglassen, um nichts zu übertragen)nein—
tcpTCPSource (ein Block, weglassen, um nichts zu übertragen)nein—
ftpFTPSource (ein Block, weglassen, um nichts zu übertragen)nein—
smbSMBSource (ein Block, weglassen, um nichts zu übertragen)nein—
webdavWebDAVSource (ein Block, weglassen, um nichts zu übertragen)nein—
serialSerialSource (ein Block, weglassen, um nichts zu übertragen)nein—
dicom_queryDICOMQuerySource (ein Block, weglassen, um nichts zu übertragen)nein—
brokerBrokerSource (ein Block, weglassen, um nichts zu übertragen)nein—
kafkaKafkaSource (ein Block, weglassen, um nichts zu übertragen)nein—
sqsSQSSource (ein Block, weglassen, um nichts zu übertragen)nein—
s3S3Source (ein Block, weglassen, um nichts zu übertragen)nein—
amqpAMQPSource (ein Block, weglassen, um nichts zu übertragen)nein—
azure_blobAzureBlobSource (ein Block, weglassen, um nichts zu übertragen)nein—
emailEmailSource (ein Block, weglassen, um nichts zu übertragen)nein—
as2AS2Source (ein Block, weglassen, um nichts zu übertragen)nein—
pgpPGPReceive (ein Block, weglassen, um nichts zu übertragen)nein—
mqttMQTTSource (ein Block, weglassen, um nichts zu übertragen)nein—
ibm_mqIBMMQSource (ein Block, weglassen, um nichts zu übertragen)nein—
pubsubPubSubSource (ein Block, weglassen, um nichts zu übertragen)nein—
gcsGCSSource (ein Block, weglassen, um nichts zu übertragen)nein—
databaseDatabaseSource (ein Block, weglassen, um nichts zu übertragen)nein—
sftpSFTPSource (ein Block, weglassen, um nichts zu übertragen)nein—
javascriptJavaScriptSource (ein Block, weglassen, um nichts zu übertragen)nein—
ackAcknein—

22.26.1 Typ

Der Typ ist der Transport.

Nur MLLP ist implementiert.

22.26.2 max_message_size

MaxMessageSize begrenzt eine eingehende Nachricht.

Null verwendet den Standardwert des Transports.

22.26.3 idle_timeout

IdleTimeout schließt eine Verbindung, die stillgelegt wurde.

Null bedeutet nie, was normalerweise richtig ist: Eine Krankenhausanbindung hält eine Verbindung für Monate offen und wird über Nacht still.

22.26.4 max_connections

MaxConnections begrenzt gleichzeitige Verbindungen.

Null bedeutet unbegrenzt.

22.27 TCP-Quelle

TCPSource hört auf einem Socket auf Nachrichten, die nicht unbedingt HL7 sind.

Warum dies von einer MLLP-Quelle getrennt ist

MLLP ist ein Rahmen und Perfuse hat es immer gesprochen. Viele Geräte sprechen es jedoch nicht: ein Laboranalyser, eine Waage, ein Bettmonitor, ein älteres Abrechnungssystem. Jedes hat normalerweise seine eigene Konvention und Mirths TCP-Connector deckt alle ab, sodass ein Standort mit einer Socket-Anbindung, die nicht HL7 war, Perfuse überhaupt nicht verwenden konnte.

Definiert als TCPSource in internal/config.

SchlüsselTypErforderlichStandard
listenTextja—
max_message_sizeGanzzahlnein—
idle_timeoutDauer, z. B. 30s oder 5mnein—
max_connectionsGanzzahlnein—
replyTextnein—
reply_textTextnein—
tlstlsconf.Settings (ein Block, weglassen, um nichts zu übertragen)nein—

22.27.1 idle_timeout

IdleTimeout schließt eine Verbindung, die stillgelegt wurde.

Null bedeutet nie, was normalerweise richtig ist: Eine Geräteanbindung hält eine Verbindung für Monate offen und wird still über Nacht.

22.27.2 max_connections

MaxConnections begrenzt gleichzeitige Verbindungen.

Null bedeutet unbegrenzt.

22.27.3 Antwort

Antwort ist, was nach jeder Nachricht zurückgesendet wird: nichts, Ack oder ein fester String.

Die meisten Rohanbindungen erwarten nichts. Einige erwarten ein einzelnes ACK-Byte. Ein Gerät, das eine Antwort erwartet und keine erhält, versucht normalerweise, dieselbe Nachricht endlos zu wiederholen, sodass es sich lohnt, dies explizit anzugeben.

22.28 WebDAV-Quelle

WebDAV-Quelle sammelt Dateien aus einer WebDAV-Sammlung.

Wo dies auftaucht: Dokumentenmanagementsysteme, SharePoint, Nextcloud und Anbieterportale, die einen Drop-Ordner über HTTPS verfügbar machen, da dies der einzige ausgehende Port ist, den die Firewalls ihrer Kunden zulassen.

Definiert als WebDAVSource in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
userTextnein—
passwordTextnein—
insecure_skip_verifywahr oder falschnein—
timeoutDauer, z. B. 30s oder 5mneinsechzig Sekunden

22.28.1 Benutzer

Benutzer und Passwort authentifizieren mit HTTP-Basicauthentifizierung.

Die Basicauthentifizierung sendet das Passwort in einem Header, der nur durch TLS geschützt ist, sodass diese mit einer https-URL zusammengehören. Über http sind sie für alles auf dem Pfad lesbar und der Server gibt keine Warnung aus.

22.28.2 Passwort

Benutzer und Passwort authentifizieren mit HTTP-Basicauthentifizierung.

Die Basicauthentifizierung sendet das Passwort in einem Header, der nur durch TLS geschützt ist, sodass diese mit einer https-URL zusammengehören. Über http sind sie für alles auf dem Pfad lesbar und der Server gibt keine Warnung aus.

22.28.3 Zeitüberschreitung

Timeout begrenzt eine Anfrage.

Standardmäßig sechzig Sekunden.

Länger als die Standardwerte für FTP und SMB, absichtlich. Eine WebDAV-Sammlungsliste ist ein einzelnes PROPFIND, das der Server für ein großes Verzeichnis möglicherweise lange Zeit benötigt, und es gibt keine teilweise Ergebnisse, auf die zurückgegriffen werden kann.

23 Zielreferenz

Jede Möglichkeit, wie ein Kanal Nachrichten senden kann, und jeder Schlüssel, den jeder davon akzeptiert. Ein Kanal kann beliebig viele Ziele haben und diese sind unabhängig: Wenn eines fehlschlägt, stoppt dies die anderen nicht.

23.1 AMQP-Ziel

AMQPDestination sendet an eine Warteschlange oder ein Thema und meldet Erfolg erst, wenn der Broker die Nachricht akzeptiert hat.

Definiert als AMQPDestination in internal/config.

SchlüsselTypErforderlichStandard
content_typeTextneinder DatenTyp des Kanals

23.1.1 content_type

ContentType wird mit jeder Nachricht gesendet.

Standardmäßig der DatenTyp des Kanals.

23.2 AS2-Ziel

AS2Destination sendet jede Nachricht als AS2: signiert mit unserem Schlüssel, verschlüsselt mit dem Zertifikat des Partners, an die URL des Partners gesendet und standardmäßig nur dann geliefert, wenn die signierte Quittung des Partners den gleichen Digest nennt.

Definiert als AS2Destination in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
fromTextja—
toTextja—
cert_fileTextnein—
key_fileTextnein—
partner_cert_fileTextnein—
unsignedwahr oder falschnein—
unencryptedwahr oder falschnein—
compresswahr oder falschnein—
receiptTextnein—
unsigned_receiptwahr oder falschnein—
receipt_urlTextnein—
content_typeTextnein—
file_nameTextnein—
subjectTextnein—
usernameTextnein—
passwordTextnein—
tlstlsconf.Einstellungen (ein Block, weglassen, um nicht zu verwenden)nein—

23.2.1 Komprimieren

Komprimieren komprimiert die Nutzlast (zlib, RFC 5402) vor der Signierung und Verschlüsselung.

Jeder AS2-Empfänger, der Version 1.1 oder höher ankündigt, liest dies; fragen Sie den Partner, bevor Sie es aktivieren.

23.2.2 unsigned_receipt

UnsignedReceipt fordert eine Quittung, die nicht signiert ist.

Aus: Eine signierte Quittung wird angefordert und eine nicht signierte abgelehnt.

23.2.3 content_type

ContentType ist der MIME-Typ der Nutzlast.

Standardmäßig durch den Datentyp des Kanals bestimmt: application/edi-x12, application/edifact, application/hl7-v2, ansonsten application/octet-stream.

23.3 Azure Blob Ziel

AzureBlobDestination schreibt jede Nachricht als Block-Blob.

Definiert als AzureBlobDestination in internal/config.

SchlüsselTypErforderlichStandard
blobTextnein${date}/${channel}/${control_id}
tierTextnein—
content_typeTextnein—

23.3.1 blob

Blob benennt jeden Blob mit den Platzhaltern des S3-Ziels.

Standardmäßig ${date}/${channel}/${control_id}.hl7.

23.3.2 tier

Tier ist Hot, Cool, Cold oder Archive.

Archive ist offline: Das Lesen eines Blobs bedeutet, dass es rehydriert werden muss, was Stunden dauert.

23.4 Broker Ziel

BrokerDestination veröffentlicht Nachrichten an einem Nachrichtenbroker.

Mirths JMS-Writer.

Definiert als BrokerDestination in internal/config.

SchlüsselTypErforderlichStandard
addrTextja—
destinationTextja—
loginTextnein—
passcodeTextnein—
hostTextneinder Host der Adresse
content_typeTextneintext/plain für HL7
headersZuordnung von Text zu Textnein—
persistentwahr oder falsch (ein Block, weglassen, um es wegzulassen)neinwahr
timeoutDauer, wie z. B. 30s oder 5mnein—
tlstlsconf.Settings (ein Block, weglassen, um es wegzulassen)nein—

23.4.1 addr

Addr ist der Host und Port des Brokers.

Required.

23.4.2 Ziel

Ziel ist die Warteschlange oder das Thema, das veröffentlicht werden soll.

Required.

23.4.3 Anmeldung

Anmeldung und Passcode authentifizieren.

Die meisten Broker lehnen eine anonyme Verbindung ab.

23.4.4 Passwort

Anmeldung und Passcode authentifizieren.

Die meisten Broker lehnen eine anonyme Verbindung ab.

23.4.5 Host

Host ist der virtuelle Host.

Standardmäßig ist es der Host der Adresse.

Es lohnt sich, es explizit auf einem Broker zu setzen, der mehrere virtuelle Hosts hostet, wo der Standard die Veröffentlichung auf denjenigen landen lässt, der auf den Namen des Servers antwortet - eine Warteschlange, die existiert, die Nachricht akzeptiert und von niemandem gelesen wird.

23.4.6 content_type

ContentType wird mit jeder Nachricht gesendet.

Standardmäßig text/plain für HL7.

23.4.7 headers

Header werden mit jeder Nachricht gesendet.

Konfiguration nur, nie Nachrichteninhalt. Ein Header, der aus einem Feld entnommen wird, würde einen Patientenidentifikator in Broker-Metadaten einfügen, die protokolliert, indiziert und für jede andere Anwendung in der Warteschlange sichtbar sind.

23.4.8 beständig

Beständig bittet den Broker, einen Neustart zu überstehen.

Standardmäßig true.

True, da eine nicht-beständige Nachricht bei einem Neustart des Brokers verloren geht und dies kein vernünftiger Standard für klinische Daten ist. False existiert für eine wirklich flüchtige Zufuhr - ein Überwachungs-Heartbeat - und muss ausgewählt werden.

23.5 CDA-Ziel

CDADestination konfiguriert ein CDA-Ziel: es nimmt das klinische Dokument, das innerhalb einer HL7-v2-Nachricht enthalten ist, wandelt es um und schreibt oder postet das Ergebnis.

Dies existiert, weil ein Dokument fast nie allein ankommt. Es kommt base64-codiert innerhalb eines MDM^T02 an, und jeder Motor, der diese Nachricht als undurchsichtigen Blob behandelt, lässt das Dokument ungelesen. Die Kontrolle beider Enden davon ist der Punkt.

Definiert als CDADestination in internal/config.

SchlüsselTypErforderlichStandard
urlTextnein—
dirTextnein—
writeTextnein—
versionTextneinR5
identifier_systemsZuordnung von Text zu Textnein—
require_agreementwahr oder falschnein—
on_no_documentTextnein—
headersZuordnung von Text zu Textnein—
bearer_tokenTextnein—

23.5.1 URL

URL ist ein FHIR-Server, an den das umgewandelte Bundle gepostet wird.

Lassen Sie es leer, um stattdessen in Dir zu schreiben. Eines von beiden ist erforderlich.

23.5.2 Verzeichnis

Verzeichnis schreibt die Ausgabe in Dateien anstelle von Posten.

Nützlich für eine Landezone, die ein anderer Prozess aufnimmt, und für die Überprüfung, was die Umwandlung produziert, bevor es auf einen Live-Server zeigt.

23.5.3 Schreiben

Schreiben wählt aus, was geschrieben oder gepostet wird:

FHIR das konvertierte Transaktionsbundle (Standard) Dokumentieren Sie das ursprüngliche Dokument in Bytes, unverändert beides, mit dem Dokument neben dem Bundle übertragen Ein PACIO-Übergangsbericht zur Weitergabe: Ein FHIR-R4-Dokumentbundle für den Ort, an den der Patient als Nächstes geht (ein Pflegeheim, eine Rehabilitationseinheit, eine häusliche Gesundheitsversorgung), der an die URL/Bundle gepostet oder in das Verzeichnis dir geschrieben wird

"Dokument" ist allein wertvoll: ein Standort, der seine CDAs auf Disk für ein Aufzeichnungsteam haben möchte, benötigt die FHIR-Umwandlung überhaupt nicht.

23.5.4 Identifikationssysteme

Identifikationssysteme ordnen eine OID-Wurzel aus dem Dokument einer URI zu, sodass ein MRN benannt wird.

Ein CDA identifiziert Personen durch OID und FHIR durch URI, und nichts kann eine davon ableiten.

23.5.5 Vereinbarung erforderlich

Vereinbarung erforderlich lehnt ein Dokument ab, dessen Erzählung und codierte Einträge sich gegenseitig widersprechen.

Standardmäßig deaktiviert und mit Bedacht so. Die Überprüfung ist wertvoll, aber es handelt sich um eine Beurteilung eines Dokuments, das jemand anderes erstellt hat, und ein Kanal, der reale klinische Dokumente stillschweigend ablehnt, weil der C-CDA-Generator des Absenders schlampig ist, ist schlimmer als einer, der sie mit einer Warnung durchlässt. Ein Standort, der seine eigenen Ergebnisse überprüft und beschlossen hat, dass er das Tor haben möchte, kann es aktivieren.

23.5.6 on_no_document

OnNoDocument entscheidet, was passiert, wenn die Nachricht kein klinisches Dokument enthält:

überspringen: nichts liefern und Erfolg melden (Standard) fehlschlagen: als Lieferfehler behandeln

Der Standard ist überspringen, da ein Kanal, der eine gemischte ADT- und MDM-Feeds überträgt, ansonsten bei jeder Aufnahme fehlschlagen würde. Ein Kanal, der ausschließlich für Dokumente bestimmt ist, sollte fehlschlagen, da eine Dokumentnachricht ohne Dokument darin ein echtes Problem beim Absender ist.

23.5.7 bearer_token

BearerToken wird als Authorization-Header gesendet.

Bevorzugen Sie eine Umgebungsvariablenreferenz gegenüber einem Literal in einer Datei, die in git landet.

23.6 Kanaldestination

Kanaldestination leitet an einen anderen Kanal auf dem gleichen Server weiter.

Definiert als ChannelDestination in internal/config.

SchlüsselTypErforderlichStandard
nameTextja—

23.7 DICOM-Destination

DICOMDestination sendet Bilddaten als C-STORE-Serviceklasse-Benutzer.

Mirth bezeichnet dies als DICOM-Sender.

Definiert als DICOMDestination in internal/config.

SchlüsselTypErforderlichStandard
addressTextja—
called_aeTextnein—
calling_aeTextnein—
transfer_syntaxesListe von Textnein—
timeoutDauer, z. B. 30s oder 5mnein—
tlstlsconf.Settings (ein Block, weglassen, um es nicht zu verwenden)nein—

23.7.1 Adresse

Adresse ist der Remote-Host und -Port.

Required.

23.7.2 called_ae

CalledAE ist, wie der Remote sich selbst bezeichnet, und CallingAE, wie sich dieses Ende bezeichnet.

Beides ist wichtig. Standorte konfigurieren ein PACS, um einen bestimmten Aufruf-Titel anzunehmen und alles andere abzulehnen, sodass eine Fehlpassung der häufigste Grund für ein erstes Verbindungsfehler ist - und der Fehler sieht wie ein Netzwerkproblem aus.

23.7.3 calling_ae

CalledAE ist, wie der Remote sich selbst bezeichnet, und CallingAE, wie sich dieses Ende bezeichnet.

Beides ist wichtig. Standorte konfigurieren ein PACS, um einen bestimmten Aufruf-Titel anzunehmen und alles andere abzulehnen, sodass eine Fehlpassung der häufigste Grund für ein erstes Verbindungsfehler ist - und der Fehler sieht wie ein Netzwerkproblem aus.

23.7.4 transfer_syntaxes

TransferSyntaxes beschränkt, was angeboten wird, in der bevorzugten Reihenfolge.

Leer bietet die eigene Kodierung des Objekts und dann implizite VR little endian als Fallback.

23.7.5 Zeitüberschreitung

Timeout begrenzt eine Store-Operation.

Null verwendet einen Standardwert.

23.8 DICO Mweb-Destination

DICOMwebDestination speichert jedes Objekt mit STOW-RS.

Definiert als DICOMwebDestination in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
tokenTextnein—
usernameTextnein—
passwordTextnein—
headersZuordnung von Text zu Textnein—
tlstlsconf-Einstellungen (ein Block, weglassen, um es nicht zu verwenden)nein—
timeoutDauer, z. B. 30s oder 5mnein—

23.9 Datenbankziel

DatabaseDestination schreibt jede Nachricht in eine Datenbank.

Definiert als DatabaseDestination in internal/config.

SchlüsselTypErforderlichStandard
driverTextja—
dsnTextja—
statementTextja—
paramsListe von Textnein—
timeoutDauer, z. B. 30s oder 5mnein30s
max_open_connsGanzzahlnein4

23.9.1 Treiber

Treiber benennt die Datenbank.

See SupportedDrivers.

23.9.2 Anweisung

Die Anweisung wird einmal pro Nachricht ausgeführt, wobei die Parameter in der Reihenfolge an sie gebunden sind.

Platzhalter sind die eigenen des Treibers: $1 für Postgres, ? für MySQL und SQLite, @p1 für SQL-Server. Perfuse überschreibt sie nicht, da eine Übersetzungsebene, die einen Platzhalter falsch übersetzt, den Namen eines Patienten an die falsche Spalte binden und das Ergebnis wie gültige Daten aussehen würde.

23.9.3 Parameter

Parameter sind HL7-Pfade oder ${...}-Ausdrücke, die in der Reihenfolge an die Anweisung gebunden sind.

Werte werden immer als Parameter gebunden und nie in den SQL-Code eingefügt. Das ist nicht nur wegen der Einschleusung: O'Brien ist ein häufiger Name, und eine verkettete Abfrage bricht bei dem Apostroph ab.

23.9.4 Zeitüberschreitung

Die Zeitbegrenzung begrenzt eine einzelne Anweisung.

Defaults to 30s.

23.9.5 max_open_conns

MaxOpenConns begrenzt den Pool.

Defaults to 4.

23.10 Ziel

Ziel ist ein Ort, an den ein Kanal Nachrichten sendet.

Definiert als Destination in internal/config.

SchlüsselTypErforderlichStandard
nameTextja—
typeDestinationTypeja—
enabledtrue oder false (ein Block, weglassen, um es auszulassen)nein—
filterTextnein—
addressTextnein—
dirTextnein—
file_nameTextnein—
temp_suffixTextnein"
appendtrue oder falsenein—
retain_hoursganze Zahlnein—
tlstlsconf.Settings (ein Block, weglassen, um es auszulassen)nein—
fhirFHIRDestination (ein Block, weglassen, um es auszulassen)nein—
cdaCDADestination (ein Block, weglassen, um es auszulassen)nein—
httpHTTPDestination (ein Block, weglassen, um es auszulassen)nein—
databaseDatabaseDestination (ein Block, weglassen, um es auszulassen)nein—
sftpSFTPDestination (ein Block, weglassen, um es auszulassen)nein—
tcpTCPDest (ein Block, weglassen, um es auszulassen)nein—
smtpSMTPDestination (ein Block, weglassen, um es auszulassen)nein—
channelChannelDestination (ein Block, weglassen, um es auszulassen)nein—
s3S3Destination (ein Block, weglassen, um es auszulassen)nein—
ftpFTPDestination (ein Block, weglassen, um es auszulassen)nein—
documentDocumentDestination (ein Block, weglassen, um es auszulassen)nein—
soapSOAPDestination (ein Block, weglassen, um es auszulassen)nein—
dicomwebDICOMwebDestination (ein Block, weglassen, um es auszulassen)nein—
xdsXDSDestination (ein Block, weglassen, um es auszulassen)nein—
directDirectDestination (ein Block, weglassen, um es auszulassen)nein—
as2AS2Destination (ein Block, weglassen, um es auszulassen)nein—
mpiMPIDestination (ein Block, weglassen, um es auszulassen)nein—
tefcaTEFCADestination (ein Block, weglassen, um es auszulassen)nein—
pasPASDestination (ein Block, weglassen, um es auszulassen)nein—
x12_asTextnein—
dicomDICOMDestination (ein Block, weglassen, um es auszulassen)nein—
javascriptJavaScriptDestination (ein Block, weglassen, um es auszulassen)nein—
brokerBrokerDestination (ein Block, weglassen, um es auszulassen)nein—
kafkaKafkaDestination (ein Block, weglassen, um es auszulassen)nein—
sqsSQSDestination (ein Block, weglassen, um es auszulassen)nein—
snsSNSDestination (ein Block, weglassen, um es auszulassen)nein—
amqpAMQPDestination (ein Block, weglassen, um es auszulassen)nein—
azure_blobAzureBlobDestination (ein Block, weglassen, um es auszulassen)nein—
mqttMQTTDestination (ein Block, weglassen, um es auszulassen)nein—
ibm_mqIBMMQDestination (ein Block, weglassen, um es auszulassen)nein—
pubsubPubSubDestination (ein Block, weglassen, um es auszulassen)nein—
gcsGCSDestination (ein Block, weglassen, um es auszulassen)nein—
elrELRDestination (ein Block, weglassen, um es auszulassen)nein—
pgpPGPSend (ein Block, weglassen, um es auszulassen)nein—
response_transformerTextnein—
timeoutDauer, wie z. B. 30s oder 5mnein—
retryRetrynein—
queueQueueConfig (ein Block, weglassen, um es auszulassen)nein—

23.10.1 name

Name identifiziert das Ziel in Protokollen und Metriken.

Erforderlich innerhalb eines Kanals.

23.10.2 file_name

Dateiname, für ein Dateiziel, erstellt eine Datei pro Nachricht (${timestamp}, ${date}, ${control_id}, ${message_type}, ${destination}).

Leer behält den Standard: eine Datei pro Tag und Nachrichtentyp, angehängt an.

23.10.3 temp_suffix

TempSuffix ist der Name, den eine pro-Nachricht-Datei während des Schreibens trägt, entfernt durch eine Umbenennung, sobald sie abgeschlossen ist, sodass der Dateisammler nie eine halbe Datei liest.

Standardmäßig ".part".

23.10.4 retain_hours

RetainHours löscht Dateien im Verzeichnis, die älter sind als diese.

Null behält sie für immer.

23.10.5 x12_as

X12As ist XML für ein Ziel auf einem X12-Kanal, das den Austausch als XML empfängt, wie es Mirth Connect und Open Integration Engine für X12 schreiben, für einen Empfänger, der gegen das geschriebene Mirth-X12-XML erstellt wurde.

Leer oder x12 sendet X12.

23.10.6 elr

ELR macht dieses Ziel zu einem öffentlichen Gesundheitslaborberichtszweck: Jedes Laborergebnis (ORU^R01) wird in eine ELR 2.5.1-Nachricht umgestaltet, die nur die Bestellungen mit einem meldepflichtigen Ergebnis enthält, und diese wird geliefert; eine Nachricht mit nichts Meldepflichtigem wird überhaupt nicht gesendet.

Gilt für Ziele, die eine HL7-v2-Nachricht so wie sie ist (mllp, http, Datei, sftp und der Rest) auf einem HL7-Kanal liefern.

23.10.7 response_transformer

ResponseTransformer untersucht, was der Empfänger zurückgesagt hat, und kann die Lieferung als fehlgeschlagen markieren.

Es existiert, weil „ist dies angekommen“ oft keine Frage ist, die der Transport beantworten kann: Ein MLLP-Empfänger gibt eine Anwendungsbestätigung zurück, deren Bedeutung in seinem Text liegt, und ein HTTP-Empfänger gibt 200 mit einem Fehlerdokument zurück. In beiden Fällen ist der Transport erfolgreich und die Nachricht ist nicht angekommen.

Nur sinnvoll auf einem Ziel, das eine Antwort erhält. Auf einem, das keine Antwort erhält, wird es bei der Ladung abgelehnt, anstatt nie ausgeführt zu werden.

23.10.8 queue

Die Warteschlange macht die Zustellung dauerhaft: Eine Nachricht, die derzeit nicht zugestellt werden kann, wird auf der Festplatte gespeichert und so lange wiederholt, bis sie zugestellt werden kann.

Standardmäßig deaktiviert.

23.11 Direktes Ziel

DirectDestination sendet jede Nachricht als Direct: signiert mit dieser Adresse, verschlüsselt mit dem Zertifikat jedes Empfängers und über SMTP an den HISP übermittelt.

Definiert als DirectDestination in internal/config.

SchlüsselTypErforderlichStandard
toListe von Textja—
subjectTextnein—
textTextnein—
attach_nameTextnein—
xdmwahr oder falschnein—
xdm_source_idTextnein—
recipient_certs_dirTextnein—
dnsTextnein—
ldapTextnein—
smtp_hostTextja—
usernameTextnein—
passwordTextnein—
request_mdnwahr oder falschnein—
timeoutDauer, z. B. 30s oder 5mnein—

23.11.1 an

An sind die Direct-Adressen der Empfänger.

Feldreferenzen werden ersetzt, sodass ein Empfänger aus der Nachricht stammen kann.

23.11.2 recipient_certs_dir

RecipientCertsDir enthält die Zertifikate der Empfänger (PEM, eine Datei pro Adresse oder Domäne, address.pem oder domain.pem), die im Voraus gefunden werden; leer liest das Server-Adressbuch von Direct (der Direct-Bildschirm).

Empfänger, die nicht vorhanden sind, werden in DNS (CERT-Records) nachgeschlagen. Direct sendet nicht an einen Empfänger, dessen Zertifikat nicht gefunden werden kann.

23.11.3 ldap

LDAP ist das Verzeichnis, in dem das Zertifikat eines Empfängers nachgeschlagen wird, wenn DNS keines hat (Host:Port, Port 389): die zweite Methode, die der Direct-Zertifikat-Entdeckungsleitfaden zulässt.

Leer findet das Verzeichnis der Empfängerdomäne durch seinen DNS-SRV-Eintrag (_ldap._tcp), wie es der Leitfaden sagt; „aus“ fragt nie ein Verzeichnis.

23.12 Dokumentziel

DocumentDestination rendert jede Nachricht in ein Dokument.

Definiert als DocumentDestination in internal/config.

SchlüsselTypErforderlichStandard
dirTextja—
formatDocumentFormatneinpdf
templateTextja—
titleTextnein—
file_nameTextnein—
font_sizeZahlnein10
landscapewahr oder falschnein—
temp_suffixTextnein"
timeoutDauer, z. B. 30s oder 5mnein30s

23.12.1 format

Das Format ist pdf oder Text.

Standardmäßig ist es pdf.

23.12.2 vorlage

Die Vorlage ist der Dokumenttextkörper mit ${PID-5.1}-Stil-Referenzen zu Nachrichtenpfaden.

Erforderlich. Es gibt keinen sinnvollen Standardwert: Ein Dokument ohne Vorlage wäre entweder die rohe Nachricht, die niemand gedruckt haben möchte, oder leer.

23.12.3 font_size

Schriftgröße in Punkten.

Standardmäßig ist es 10, was 80 Zeichen über A4 passt.

23.12.4 temp_suffix

TempSuffix wird während des Schreibens angehängt und durch eine Umbenennung entfernt.

Standardmäßig ".part".

Die gleiche Höflichkeit wie bei jeder anderen Dateizieladresse gilt auch hier: Ein Druckbeobachter, der ein halb geschriebenes PDF aufnimmt, produziert eine Seite mit nichts, und niemand untersucht eine leere Seite.

23.12.5 Zeitüberschreitung

Timeout-Begrenzung einer Schreibvorgang.

Defaults to 30s.

23.13 ECR-Ziel

ECR-Ziel konfiguriert die elektronische Fallberichterstattung.

Definiert als ECRDestination in internal/config.

SchlüsselTypErforderlichStandard
rctcTextnein—
sourceTextja—
facilityECR-Facilityja—

23.13.1 rctc

RCTC ist ein FHIR-ValueSet oder ein Bundle davon, wie z. B. das eRSD, das die Triggercodes enthält.

Ohne es wird Perfuses kurzes, eingebautes Beispiel verwendet, das für Tests gedacht ist: Agenturen erwarten den RCTC.

23.14 ELR-Ziel

ELR-Ziel konfiguriert die elektronische Laborberichterstattung.

Definiert als ELRDestination in internal/config.

SchlüsselTypErforderlichStandard
configTextja—
rctcTextnein—

23.14.1 Konfiguration

Die Konfiguration ist die ELR-Datei, die perfuse elr -config liest: die sendenden und empfangenden Anwendungen und Einrichtungen nach OID, der Verarbeitungsmodus und was die Lücken füllt, die ein Labor-Feed hinterlässt (Bestell-Einrichtung, ausführendes Labor, Zuweisungsbehörden).

Ein relativer Pfad wird aus dem Verzeichnis der Kanaldatei gelesen.

23.14.2 rctc

RCTC ist ein FHIR-ValueSet oder ein Bundle davon, wie z. B. das eRSD, das die Triggercodes enthält.

Ohne es wird Perfuses kurzes, eingebautes Beispiel verwendet, das für Tests gedacht ist: Agenturen erwarten den RCTC. Relativ zur Kanaldatei, wie Konfiguration.

23.15 FHIR-Ziel

FHIR-Ziel konfiguriert die Konvertierung in FHIR und die Lieferung an einen FHIR-Server.

Definiert als FHIRDestination in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
versionTextneinR5
timezoneTextnein—
default_identifier_systemTextnein—
identifier_systemsZuordnung von Text zu Textnein—
claim_us_corewahr oder falschnein—
validate_before_sendwahr oder falsch (ein Block, weglassen, um es nicht zu verwenden)neintrue: Das Senden einer Ressource, die ein Server ablehnt, verschwendet ein Wiederholungsbudget und versteckt das eigentliche Problem hinter einem Transportfehler
reject_on_warningwahr oder falschnein—
headersZuordnung von Text zu Textnein—
bearer_tokenTextnein—
authFHIRAuth (ein Block, weglassen, um es nicht zu verwenden)nein—
ecrECRDestination (ein Block, weglassen, um es nicht zu verwenden)nein—
bundle_scriptTextnein—

23.15.1 URL

Die URL ist die Basis-URL des FHIR-Servers, z. B. "https://fhir.example.org/fhir".

Das Bundle wird direkt an diese Adresse gesendet.

23.15.2 Version

Die Version ist die FHIR-Veröffentlichung, die produziert werden soll: R4, R4B oder R5. Standardmäßig wird R5 verwendet, die neueste veröffentlichte Version.

Eine Bereitstellung, die mit einem EHR kommuniziert, möchte fast immer R4 verwenden und sollte dies angeben, da eine stille Herabstufung eine reale Interoperabilitätsentscheidung verbergen würde.

23.15.3 Zeitzone

Die Zeitzone wird auf HL7-v2-Timestamps angewendet, die keinen Offset enthalten. v2 erlaubt eine nackte lokale Zeit und FHIR nicht, also muss etwas einen Offset bereitstellen.

Wenn nicht gesetzt, wird der Offset verwendet, den der Absender auf MSH-7 gesetzt hat, da v2 annimmt, dass eine nackte Zeit die lokale Zeit des Absenders ist; eine Nachricht, deren MSH-7 keinen Offset enthält, fällt auf UTC zurück.

23.15.4 Standard-Identifikationssystem

DefaultIdentifierSystem bereit Namen für Identifikatoren, deren ausgebende Behörde keine konfigurierte URI hat.

Ohne ein System ist eine MRN mehrdeutig zwischen Einrichtungen.

23.15.5 claim_us_core

ClaimUSCore fügt dem US Core 9.0.0-Profil zu jedem produzierten Ressourcen hinzu, der überprüft und konform ist.

Eine Ressource, die nicht den Anforderungen entspricht, wird ohne den Anspruch gesendet, mit einer Notiz, die den Grund angibt.

23.15.6 validieren_bevor_senden

ValidateBeforeSend verweigert die Übertragung eines Bündels, das die Validierung nicht besteht.

Standardmäßig auf true gesetzt: Das Senden einer Ressource, die ein Server ablehnt, verschwendet ein Wiederholungsbudget und versteckt das eigentliche Problem hinter einem Transportfehler.

23.15.7 ablehnen_beim_warnen

RejectOnWarning verweigert auch bei Warnungen, wie einem fehlenden US Core-Identifikator.

Standardmäßig ausgeschaltet, da eine Warnung ein Urteil über die Profilkonformität und nicht über die Gültigkeit ist.

23.15.8 bearer_token

BearerToken wird als Authorization-Header gesendet.

Bevorziehen Sie eine Umgebungsvariablen-Referenz, ${NAME}, gegenüber einem Literal in einer Datei, die in git landet.

23.15.9 ecr

ECR macht dies zu einem öffentlichen Gesundheitsfall-Meldeziel.

Jede Nachricht wird auf Trigger-Codes überprüft; eine, die einen solchen Code enthält, wird als eCR 2.1 eICR gesendet, in einer eCR-Nachricht eingeschlossen, an die URL $process-message, und eine ohne Trigger-Code wird überhaupt nicht gesendet.

23.15.10 bundle_script

BundleScript ist JavaScript, das auf jedes konvertierte Bundle ausgeführt wird, bevor es validiert und gesendet wird: bundle ist das Bundle als Objekt, das bearbeitet wird.

Es ist die Möglichkeit, wie eine Website hinzufügt, was ihre eigenen Systeme wissen und die v2-Nachricht nicht sagt - den IKNR- oder ODS-Code ihrer Organisation, ein Kontaktlevel eines nationalen Profils - ohne dass der Konverter raten muss. Ein Skript, das einen Fehler wirft, führt zum Scheitern der Nachricht, wie jeder andere Transformer auch. Wird nicht für Fallberichte (ecr) ausgeführt.

23.16 FTP-Ziel

FTPDestination lädt eine Datei pro Nachricht hoch.

Definiert als FTPDestination in internal/config.

SchlüsselTypErforderlichStandard
hostTextja21
userTextnein—
passwordTextnein—
securityFTP-Sicherheitneinexplizit anstelle von keiner
insecure_skip_verifywahr oder falschnein—
allow_clear_passwordwahr oder falschnein—
dirTextja—
file_nameTextnein—
temp_suffixTextnein"
framedwahr oder falschnein—
timeoutDauer, z. B. 30s oder 5mnein60s

23.16.1 Host

Host ist der Server mit einem optionalen Port.

Standardmäßig 21, oder 990 für implizites TLS.

23.16.2 Benutzer

Benutzer und Passwort authentifizieren.

Ein leerer Benutzer bedeutet anonym.

23.16.3 Passwort

Benutzer und Passwort authentifizieren.

Ein leerer Benutzer bedeutet anonym.

23.16.4 Sicherheit

Sicherheit wählt TLS: explizit, implizit oder keines.

Standardmäßig wird explizit anstelle von keines verwendet, da das Standardmäßige auf plain FTP die unsichere Wahl wäre und ein Standort, der tatsächlich kein TLS hat, dies aufschreiben sollte.

23.16.5 insecure_skip_verify

InsecureSkipVerify akzeptiert jedes Zertifikat.

Häufiger benötigt, als jemandem lieb sein könnte: Diese Server haben häufig ein selbstsigniertes Zertifikat, das vor Jahren generiert wurde und das niemand neu ausstellen kann. Es wird separat benannt, damit die Auswahl absichtlich und im Datei sichtbar ist und nicht innerhalb eines "Sicherheit: entspannt"-Modus versteckt ist.

23.16.6 allow_clear_password

AllowClearPassword erlaubt ein Passwort über plain FTP.

Standardmäßig abgelehnt, da dies ein Credential über das Netzwerk in Klartext bei jeder einzelnen Lieferung sendet. Einige Analysatoren haben tatsächlich kein TLS, also muss es möglich sein - aber es muss aufgeschrieben werden, damit es eine Entscheidung ist, die jemand getroffen hat, und nicht ein Standard, den sie geerbt haben. Der Name ist absichtlich unangenehm zum Tippen.

23.16.7 temp_suffix

TempSuffix wird während der Schreibvorgang des Datei angehängt und durch eine Umbenennung entfernt, sobald es abgeschlossen ist.

Standardmäßig ".part".

Wer auch immer diese Dateien sammelt, ist normalerweise ein geplanter Job, der alles nimmt, was er findet, und ohne die Umbenennung nimmt er schließlich die Hälfte einer Nachricht.

23.16.8 Zeitüberschreitung

Timeout begrenzt eine Übertragung.

Defaults to 60s.

23.17 GCS-Ziel

GCSDestination schreibt jede Nachricht als Objekt.

Definiert als GCSDestination in internal/config.

SchlüsselTypErforderlichStandard
objectTextnein${date}/${channel}/${control_id}
storage_classTextnein—
content_typeTextnein—

23.17.1 object

Objekt ist der Objektname mit denselben Platzhaltern wie ein S3-Schlüssel.

Standardmäßig ${date}/${channel}/${control_id}.hl7.

23.18 HTTP-Ziel

HTTPDestination sendet Nachrichten an einen HTTP-Endpunkt.

Die häufigste Sache, die ein Mirth-Kanal tut, die Perfuse nicht konnte, und der häufigste Blockierer, den der Übersetzer meldet. Die meisten Verwendungen sind unglamourös: die Nachricht an eine interne API senden, an einen Webservice senden, der ein Legacy-System umhüllt, oder an etwas senden, das jemand in einem Nachmittag geschrieben hat.

Definiert als HTTPDestination in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
methodTextnein—
content_typeTextnein—
headersZuordnung von Text zu Textnein—
bearer_tokenTextnein—
usernameTextnein—
passwordTextnein—
tlstlsconf.Settings (ein Block, weglassen, um es wegzulassen)nein—
success_statusListe von ganzen Zahlenneinjede 2xx
fail_on_bodyListe von Textnein—
follow_redirectswahr oder falschnein—

23.18.1 URL

URL ist der Ort, an den gesendet wird.

Required.

23.18.2 method

Methode standardmäßig POST.

PUT ist für einen Endpunkt erlaubt, der es wünscht.

GET und DELETE werden abgelehnt: dies sendet einen Nachrichtentext, und ein Transport, der die Nachricht stillschweigend aufgrund einer Methodenwahl fallen lässt, wäre eine sehr stille Art, Daten zu verlieren.

23.18.3 content_type

ContentType standardmäßig auf application/hl7-v2+er7, was der registrierte Typ für eine durch Pipe-getrennte HL7-v2-Nachricht ist.

Viele Endpunkte bevorzugen text/plain.

23.18.4 bearer_token

BearerToken wird als Authorization-Header gesendet.

Bevorzugen Sie eine Umgebungsvariablenreferenz gegenüber einem Literal in einer Datei, die in git landet.

23.18.5 Erfolgsstatus

Erfolgsstatus listet die Statuscodes auf, die als zugestellt gelten.

Standardmäßig jeder 2xx-Code.

Konfigurierbar, da Endpunkte unterschiedlicher Meinung darüber sind, wie Erfolg aussieht: einige antworten mit 200 und einem Fehler im Text, und einige antworten mit 202 für eine Warteschlange, die die Nachricht angenommen hat.

23.18.6 Fehler bei Nachrichtentext

FehlerBeiNachrichtentext behandelt eine Antwort, die einen dieser Texte enthält, als Fehler, unabhängig vom Statuscode.

Dies existiert, weil ein Endpunkt, der mit 200 und "ERROR: Patient nicht gefunden" im Text antwortet, häufig ist und die Behandlung als zugestellt bedeutet, dass die Nachricht verschwunden ist und niemand etwas weiß.

23.18.7 Weiterleitungen verfolgen

WeiterleitungenVerfolgen ermöglicht es der Anfrage, umgeleitet zu werden.

Standardmäßig deaktiviert: eine Umleitung bei einem Schreibvorgang würde klinische Daten an einen Ort reposten, den die Konfiguration nie benannt hat.

23.19 IBMMQ-Ziel

IBMMQZiel legt jede Nachricht in eine Warteschlange.

Definiert als IBMMQDestination in internal/config.

SchlüsselTypErforderlichStandard
non_persistenttrue oder falsenein—

23.19.1 nicht_persistierend

NichtPersistierend sendet Nachrichten, die einen Neustart des Warteschlangenmanagers nicht überleben.

Standardmäßig deaktiviert.

23.20 JavaScript-Ziel

JavaScriptZiel führt ein Skript anstelle des Sendens an einen bestimmten Ort aus.

Mirths JavaScript-Schreiber und es wird viel häufiger verwendet, als seine Position in einer Funktionsliste vermuten lässt. Es ist der Notausgang: wenn ein Standort mit etwas sprechen muss, das kein Connector abdeckt, oder Logik anwenden muss, die keine Transformation ausdrückt, schreiben sie einen JavaScript-Schreiber. Eine Migration, die diese nicht ausführen kann, kann die Kanäle, die sie haben, nicht verschieben, was in einer ausgereiften Mirth-Installation ein großer Bruchteil ist.

Bewusst kein allgemeiner Skript-Host. Das Skript erhält die Nachricht und die gleichen Helfer wie ein Transformer; was es nicht erhält, ist eine Möglichkeit, auf das Dateisystem oder das Netzwerk zuzugreifen, weil das der Zweck der anderen Ziele ist und ein Skript, das seine eigene Socket öffnet, für jede Wiederholung, Warteschlange und Metrik im Motor unsichtbar ist.

Definiert als JavaScriptDestination in internal/config.

SchlüsselTypErforderlichStandard
scriptTextja—
timeoutDauer, z. B. 30s oder 5mnein—
success_on_undefinedtrue oder false (ein Block, weglassen, um es nicht zu setzen)neintrue

23.20.1 Skript

Script ist der Code, der ausgeführt wird.

Required.

23.20.2 Zeitüberschreitung

Timeout begrenzt eine Ausführung.

Null verwendet einen Standardwert.

Begrenzt, weil ein Ziel-Script auf dem Lieferweg ist: Eine Endlosschleife in einem hält nicht nur eine Nachricht auf, sondern blockiert auch die Warteschlange dahinter.

23.20.3 success_on_undefined

SuccessOnUndefined behandelt ein Script, das nichts zurückgibt, als Erfolg.

Standardmäßig true.

True ist der richtige Standard und es lohnt sich, ihn zu erklären. Mirths JavaScript-Writer führen ihre Arbeit überwiegend aus und geben nichts zurück, sodass eine explizite Rückgabe erforderlich wäre, um jeden von ihnen bei der Importierung zu brechen. Das Festlegen auf false ist für einen Standort, der möchte, dass ein Script explizit angibt, ob es funktioniert hat.

23.21 Kafka-Ziel

Kafka-Ziel veröffentlicht Nachrichten in einem Kafka-Topic.

Definiert als KafkaDestination in internal/config.

SchlüsselTypErforderlichStandard
brokersListe von Textja—
topicTextja—
keyTextnein—
acksTextneinall
compressionTextneinsnappy
headersZuordnung von Text zu Textnein—
timeoutDauer, z. B. 30s oder 5mneindreißig Sekunden
saslKafkaSASL (ein Block, weglassen, um es nicht zu setzen)nein—
tlstlsconf-Einstellungen (ein Block, weglassen, um es nicht zu setzen)nein—

23.21.1 Brokerverzeichnis

Brokerverzeichnis ist die Liste der Bootstrap-Server.

Required.

23.21.2 topic

Topic ist der Ort, an dem veröffentlicht wird.

Required.

23.21.3 key

Key ist eine Vorlage für den Datensatzschlüssel, der die Partition bestimmt.

Dies ist das Feld, das Kafka für einen klinischen Feed sicher macht, und es lohnt sich, genau zu erklären, warum. Kafka garantiert die Reihenfolge innerhalb einer Partition und nirgendwo anders. Datensätze mit dem gleichen Schlüssel landen immer in der gleichen Partition, sodass die Verwendung des Patientenidentifikators die Ereignisse eines Patienten in der Reihenfolge hält, während unterschiedliche Patienten parallel verarbeitet werden können.

Ohne einen Schlüssel gibt es keine solche Garantie. Im Vergleich zu einem realen Broker gingen dreißig nicht geschlüsselte Datensätze in eine Partition, anstatt sich zu verteilen: Der Client hält eine Charge zusammen und wählt eine neue Partition zwischen den Chargen. Die Reihenfolge bleibt also zufällig und bricht an einer unsichtbaren Grenze, was schlimmer ist als ein konsequenter Bruch - ein A03-Entlassungsschreiben wird vor seinem A01-Aufnahmeschreiben gelesen, intermittierend, unter Last.

Ein HL7-Pfad, der gegen die ausgehende Nachricht ausgewertet wird: PID-3.1 wird durch den Patienten geschlüsselt.

23.21.4 acks

Acks ist die Anzahl der Broker, die einen Schreibvorgang bestätigen müssen: "all", "leader" oder "none".

Standardmäßig ist es auf "all" gesetzt, was die einzige Einstellung ist, die einen Brokerfehler zwischen dem Schreiben und der Replikation übersteht. "none" ist feuer-und-vergessen und wird Nachrichten verlieren; es existiert, weil jemand, der nicht-klinische Telemetrie bewegt, es möglicherweise berechtigterweise möchte, und es abzulehnen würde bedeuten, dass er seinen eigenen Producer schreibt.

23.21.5 compression

Komprimierung ist "none", "gzip", "snappy", "lz4" oder "zstd".

Standardmäßig ist es auf snappy gesetzt.

Standardmäßig aktiviert, da HL7 hoch komprimierbarer Text ist und das Kabel normalerweise die Einschränkung darstellt. Snappy anstelle von zstd als Standard: Es ist der günstigste in Bezug auf CPU, und ein Connector auf dem Lieferweg sollte nicht das sein, was einen Kern sättigt.

23.21.6 headers

Header sind Rekordheader, die festgelegt werden.

Werte sind Vorlagen, die pro Nachricht ausgewertet werden.

23.21.7 Zeitüberschreitung

Timeout begrenzt eine Veröffentlichung.

Standardmäßig ist es auf dreißig Sekunden eingestellt.

23.22 MPI-Ziel

MPIDestination registriert jeden Patienten einer Nachricht in diesem Servers Patientenindex: ein HL7 v2 PID (ein A40-Merge merge), oder ein FHIR-Patient auf einem rohen Kanal.

Der Index entscheidet, welche Datensätze dieselbe Person sind; siehe den Patientenindex-Bildschirm.

Definiert als MPIDestination in internal/config.

SchlüsselTypErforderlichStandard
authoritiesZuordnung von Text zu Textnein—
id_typeTextnein—
ssn_systemTextnein—
no_mergewahr oder falschnein—

23.22.1 Behörden

Behörden ordnen einem Zuweisungsautoritäts-Namespace (PID-3.4.1) sein Identifikationssystem zu, für Sender, die keine universelle Identifikator angeben.

Nicht zugeordnete werden zu urn:perfuse:aa:<namespace>.

23.22.2 id_type

ID-Typ ist der Identifikationstyp (PID-3.5) der eigenen Nummer des Datensatzes.

Default MR.

23.22.3 ssn_system

SSN-System benennt PID-19 als Identifikator.

Default http://hl7.org/fhir/sid/us-ssn.

23.23 MQTT-Ziel

MQTTDestination veröffentlicht in einem Thema.

Definiert als MQTTDestination in internal/config.

SchlüsselTypErforderlichStandard
topicTextja—
retainwahr oder falschnein—

23.23.1 topic

Thema, das veröffentlicht wird.

Es darf keine Wildcards enthalten.

23.24 PAS-Ziel

PASDestination sendet jedes Nachrichtenpaket, ein Da Vinci PAS-Anforderungspaket, an den Claim/$submit-Endpunkt eines Zahlungsempfängers, für einen Anbieter, dessen Systeme die Anforderung (ein EHR, DTR) erstellen und sie senden müssen, die Entscheidung aufzeichnen und die Antwort weiterleiten.

Definiert als PASDestination in internal/config.

SchlüsselTypErforderlichStandard
payerTextja—
bearer_tokenTextnein—
authFHIRAuth (ein Block, weglassen, um es auszulassen)nein—
results_toTextnein—

23.24.1 bearer_token

BearerToken ist ein statischer Token, ${ENV} ist erlaubt.

Auth ist OAuth-Zugangsdaten oder Azure, wie ein FHIR-Ziel.

23.24.2 auth

BearerToken ist ein statischer Token, ${ENV} ist erlaubt.

Auth ist OAuth-Zugangsdaten oder Azure, wie ein FHIR-Ziel.

23.25 Pub Sub-Ziel

PubSubDestination veröffentlicht in einem Pub/Sub-Thema.

Definiert als PubSubDestination in internal/config.

SchlüsselTypErforderlichStandard
topicTextja—
order_byTextnein—

23.26 S3-Ziel

S3Destination schreibt jede Nachricht als Objekt.

Definiert als S3Destination in internal/config.

SchlüsselTypErforderlichStandard
bucketTextja—
regionTextja—
keyTextneinein datumspartitionierter Pfad plus die Kontroll-ID
access_key_idTextnein—
secret_access_keyTextnein—
session_tokenTextnein—
endpointTextnein—
path_stylewahr oder falschnein—
server_side_encryptionTextnein—
content_typeTextneinapplication/hl7-v2 für HL7 und text/plain ansonsten
framedwahr oder falschnein—
timeoutDauer, wie 30s oder 5mnein60s
storage_classTextnein—
formatTextnein—

23.26.1 key

Schlüssel-Vorlagen für den Objektschlüssel, unter Verwendung der gleichen ${date}, ${timestamp}, ${control_id}, ${message_type} und ${channel}-Platzhalter wie die Datei- und SFTP-Ziele.

Standardmäßig ein datumspartitionierter Pfad plus die Kontroll-ID.

Datumspartitionierung standardmäßig, da die Alternative - jedes Objekt in einem flachen Präfix - einen Bucket erstellt, der langsam zu listen und unmöglich zu verwalten ist, und niemand entdeckt das, bis es vier Millionen Objekte darin gibt.

23.26.2 access_key_id

AccessKeyID und SecretAccessKey authentifizieren.

Jeder kann auch eine Umgebungsvariable anstelle des Wertes angeben, unter Verwendung der Form ${NAME}.

23.26.3 secret_access_key

AccessKeyID und SecretAccessKey authentifizieren.

Jeder kann auch eine Umgebungsvariable anstelle des Wertes angeben, unter Verwendung der Form ${NAME}.

23.26.4 path_style

PathStyle adressiert den Bucket als Pfad anstelle eines Subdomains.

Die meisten S3-kompatiblen Speicher benötigen dies.

23.26.5 content_type

ContentType kennzeichnet das Objekt.

Standardmäßig application/hl7-v2 für HL7 und text/plain ansonsten.

23.26.6 Zeitüberschreitung

Timeout begrenzt eine Upload.

Defaults to 60s.

23.26.7 storage_class

StorageClass ist die S3-Speicherklasse, mit der jedes Objekt geschrieben wird: STANDARD_IA, INTELLIGENT_TIERING, GLACIER_IR, GLACIER, DEEP_ARCHIVE und so weiter.

So wird ein Archiv direkt an Glacier gesendet - S3 hat keine separate Glacier-API, die aufgerufen werden kann.

23.26.8 format

Format ist hl7 (Standard: jedes Objekt ist die Nachricht) oder ndjson: jedes Objekt ist eine JSON-Zeile mit der Nachricht und den Feldern, die abgefragt werden können, unter datumspartitionierten Schlüsseln, so dass Amazon Athena die Archivabfrage durchführen kann.

Siehe Perfuse Athena.

23.27 SFTP-Ziel

SFTPDestination schreibt jede Nachricht in eine Datei auf einem SFTP-Server.

Definiert als SFTPDestination in internal/config.

SchlüsselTypErforderlichStandard
hostTextja22
userTextja—
passwordTextnein—
key_fileTextnein—
key_passphraseTextnein—
known_hosts_fileTextnein—
insecure_skip_host_key_checkwahr oder falschnein—
dirTextja—
file_nameTextneinein Zeitstempel plus die Kontroll-ID
temp_suffixTextnein"
framedwahr oder falschnein—
appendwahr oder falschnein—
timeoutDauer, wie 30s oder 5mnein60s

23.27.1 Host

Host ist der Server mit einem optionalen Port.

Defaults to 22.

23.27.2 Passwort

Passwort authentifiziert mit einem Passwort.

Prefer KeyFile.

23.27.3 file_name

Dateinamenvorlagen benennen den Namen.

Standardmäßig wird ein Zeitstempel plus die Kontroll-ID verwendet.

23.27.4 temp_suffix

TempSuffix wird während der Erstellung einer Datei angehängt und durch eine Umbenennung entfernt, sobald diese abgeschlossen ist.

Standardmäßig ".part".

Der gleiche Service, den dieser Connector auf dem Weg herein benötigt. Wer auch immer diese Dateien sammelt, hat das gleiche Problem, und eine Umbenennung innerhalb eines Verzeichnisses ist auf jedem Server, der es wert ist, verwendet zu werden, atomar.

23.27.5 Zeitüberschreitung

Timeout begrenzt eine einzelne Verbindung.

Defaults to 60s.

23.28 SMTP-Ziel

SMTP-Ziel konfiguriert die Zustellung per E-Mail.

Definiert als SMTPDestination in internal/config.

SchlüsselTypErforderlichStandard
hostTextja—
fromTextja—
toListe von Textja—
ccListe von Textnein—
bccListe von Textnein—
subjectTextnein—
bodyTextnein—
attachwahr oder falschnein—
attach_nameTextneindie Kontroll-ID mit einer
usernameTextnein—
passwordTextnein—
starttlswahr oder falsch (ein Block, weglassen, um es wegzulassen)nein—
insecure_skip_verifywahr oder falschnein—
timeoutDauer, wie 30s oder 5mnein—

23.28.1 Host

Host ist der Mail-Server mit einem optionalen Port.

Port 587 wird angenommen, was die Übermittlung mit STARTTLS ist - der Port, den ein moderner Server von einem Client erwartet. Port 25 ist Server-zu-Server und wird normalerweise entweder blockiert oder nicht authentifiziert.

23.28.2 von

Von ist der Absender des Umschlags.

Erforderlich, da eine Nachricht ohne Absender von einer großen Menge an Mail-Infrastruktur stillschweigend verworfen wird, was es zur schwersten möglichen Fehldiagnose macht.

23.28.3 an

An, CC und BCC sind Empfänger.

Mindestens ein An muss vorhanden sein.

23.28.4 cc

An, CC und BCC sind Empfänger.

Mindestens ein An muss vorhanden sein.

23.28.5 bcc

An, CC und BCC sind Empfänger.

Mindestens ein An muss vorhanden sein.

23.28.6 Körper

Körper ist der Nachrichtentext.

Feldreferenzen werden wie in Betreff ersetzt. Wenn es leer ist, ist die Nachricht selbst der Körper.

23.28.7 Anhangsname

Anhangsname benennt die Anlage.

Standardmäßig wird die Kontroll-ID mit einer .hl7-Erweiterung verwendet.

23.28.8 Benutzername

Benutzername und Passwort authentifizieren den Server.

Entweder beide oder keines von beiden.

23.28.9 Passwort

Benutzername und Passwort authentifizieren den Server.

Entweder beide oder keines von beiden.

23.28.10 starttls

StartTLS aktualisiert die Verbindung vor der Authentifizierung.

Es ist standardmäßig aktiviert und die Deaktivierung mit einem festgelegten Benutzernamen wird verweigert, anstatt zugelassen zu werden: das Senden eines Passworts über eine unverschlüsselte Verbindung ist kein Kompromiss, der angeboten werden sollte.

23.28.11 insecure_skip_verify

InsecureSkipVerify akzeptiert jedes Zertifikat.

Eindeutig benannt, weil es genau das tut.

23.29 SNS-Ziel

SNS-Ziel veröffentlicht jede Nachricht in einem SNS-Thema.

Definiert als SNSDestination in internal/config.

SchlüsselTypErforderlichStandard
topic_arnTextja—
subjectTextnein—
group_byTextnein—

23.29.1 Betreff

Betreff wird mit E-Mail-Abonnements gesendet.

Optional; ${message_type} und ${control_id} werden ausgefüllt.

23.30 SOAP-Ziel

SOAP-Ziel sendet eine SOAP-Anfrage pro Nachricht.

Definiert als SOAPDestination in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
profileTextnein—
facility_idTextnein—
warnings_are_errorswahr oder falschnein—
actionTextnein—
versionTextnein1
bodyTextja—
headerTextnein—
headersZuordnung von Text zu Textnein—
usernameTextnein—
passwordTextnein—
tlstlsconf.Einstellungen (ein Block, weglassen, um nicht zu verwenden)nein—
fault_is_successListe von Textnein—
timeoutDauer, wie z. B. 30s oder 5mnein30s

23.30.1 Profil

Der Profilname bezeichnet einen Standarddienst, dessen Umschlag Perfuse selbst erstellt.

Leer ist ein einfacher SOAP-Aufruf mit dem Text, der in dieser Datei geschrieben wird.

"cdc-iis" ist die Schnittstelle des CDC-Immunregister (urn:cdc:iisb:2011), die jedes US-Bundesstaatsregister verwendet: die Nachricht wird in submitSingleMessage geschrieben, Benutzername und Passwort werden im Text wie im WSDL angegeben (nicht als HTTP-Authentifizierung), standardmäßig SOAP 1.2 und die Bestätigung des Registers entscheidet, ob die Nachricht zugestellt wurde. Ein Register antwortet auf eine abgelehnte Impfung mit HTTP 200 und einem AR, sodass ohne diese Einstellung eine Ablehnung als Erfolg gelesen wird.

23.30.2 Einrichtungs-ID

Die Einrichtungs-ID ist die cdc-iis-Einrichtungs-ID, die Kennung des Registers für die übermittelnde Organisation.

Optional im WSDL; einige Register erfordern sie.

23.30.3 Warnungen_sind_Fehler

Warnungen_sind_Fehler behandelt für cdc-iis eine AE-Bestätigung, die nur Warnungen enthält, als Fehler.

Standardmäßig deaktiviert: Register senden AE für "akzeptiert mit Warnungen" und die Schwere ERR sagt aus, ob etwas verloren gegangen ist.

23.30.4 Aktion

Aktion ist die SOAPAction.

Erforderlich von den meisten 1.1-Diensten.

23.30.5 Körper

Body ist das XML, das innerhalb des Umschlags platziert wird, mit ${PID-5.1}-Stil-Verweisen auf Nachrichtenpfade.

Erforderlich, es sei denn, ein Profil erstellt es. Es gibt keinen nützlichen Standard: Die Elementnamen stammen aus dem eigenen Schema des Dienstes und kein Motor kann sie erraten.

23.30.6 Kopf

Kopf ist XML für das Header-Element des Umschlags.

Wird vollständig weggelassen, wenn leer, da einige Dienste einen leeren ablehnen.

23.30.7 Fehler_ist_Erfolg

FehlerIsErfolg listet Fehlercodes auf, die als zugestellt gelten.

Wird öfter benötigt, als es sein sollte. Ein Dienst, der auf eine erneute Sendung mit "bereits übermittelt" antwortet, teilt Ihnen mit, dass die Nachricht angekommen ist, und ohne diese muss eine Website einen Antwort-Transformer schreiben, um dies zu bestätigen - oder schlimmer noch, beobachtet eine Warteschlange, die sich ewig gegen einen Empfänger wiederholt, der die Nachricht bereits hat.

23.30.8 Zeitüberschreitung

Timeout begrenzt einen Aufruf.

Defaults to 30s.

23.31 SQS-Ziel

SQSZiel sendet jede Nachricht an eine SQS-Warteschlange.

Definiert als SQSDestination in internal/config.

SchlüsselTypErforderlichStandard
queue_urlTextja—
group_byTextnein—

23.31.1 queue_url

QueueURL benennt die Warteschlange.

Eine mit .fifo endende Warteschlange ist eine FIFO-Warteschlange und wird gruppiert und dedupliziert.

23.32 TCP-Ziel

TCPZiel sendet Nachrichten an einen Socket mit konfigurierbarer Rahmen.

Definiert als TCPDest in internal/config.

SchlüsselTypErforderlichStandard
addressTextja—
max_message_sizeganze Zahlnein—
timeoutDauer, wie 30s oder 5mnein—
expect_replywahr oder falschnein—
keep_alivewahr oder falschnein—
tlstlsconf.Einstellungen (ein Block, weglassen, um es wegzulassen)nein—

23.32.1 expect_reply

ExpectReply wartet auf Bytes zurück, bevor Erfolg gemeldet wird.

Standardmäßig deaktiviert und erwähnenswert. Wenn es deaktiviert ist, bedeutet "zugestellt" , dass die Bytes den Sendepuffer des Betriebssystems erreicht haben, den ein Peer, der einen Moment später abstürzt, nie gelesen hat. Wenn es aktiviert ist, verursacht ein Peer, der nie antwortet, dass jede Nachricht zeitlich begrenzt ist.

23.32.2 keep_alive

KeepAlive hält eine Verbindung über Nachrichten hinweg geöffnet, anstatt pro Nachricht zu wählen.

Die meisten Geräteendpunkte erwarten dies; einige weisen eine zweite Nachricht auf der gleichen Verbindung ab. Standardmäßig deaktiviert, da eine Verbindung pro Nachricht das Verhalten ist, das überall funktioniert, auf Kosten eines Handschlags jedes Mal.

23.33 TEFCA-Ziel

TEFCADestination fragt den TEFCA-Facilitated FHIR-Partner nach den Aufzeichnungen jedes Patienten in jeder Nachricht.

Wer dieser Server im Netzwerk ist, sein Zertifikat und der Partner sind Servereinstellungen (Einstellungen, TEFCA), da sie der Organisation und ihrer Vereinbarung mit einem QHIN angehören. Was ein Kanal entscheidet, ist, wann und warum er fragt: der Zweck der Verwendung ist Teil des Kanals, nicht des angemeldeten Benutzers, sodass jede Abfrage, die ein Feed ausführt, denselben Grund angibt und die Audit-Trail gegen ihn gelesen werden kann.

Definiert als TEFCADestination in internal/config.

SchlüsselTypErforderlichStandard
purposeTextja—
results_toTextnein—

23.33.1 zweck

Zweck ist der Zweck der Verwendung: Behandlung, Zahlung, Betrieb, öffentliche Gesundheit oder Zugriff durch eine einzelne Person.

Es muss einer der Zwecke sein, den der Teilnehmer angibt.

23.33.2 ergebnisse_an

ErgebnisseAn benennt einen Kanal in diesem Server, der jedes Bundle erhält, das der Partner zurückgibt, als eine eigene Nachricht.

Leer lässt das Bundle als Antwort dieses Ziels, damit ein Antwort-Transformer es lesen kann.

23.34 XDS-Ziel

XDSDestination veröffentlicht jedes klinische Dokument in einem IHE XDS.b-Dokumentenrepository mit ITI-41 Provide and Register.

Die Metadaten werden aus dem CDA-Dokument (Patient, Titel, Typ, Zeit, Autor, Vertraulichkeit, Sprache) gelesen und durch diese Einstellungen vervollständigt, die angeben, was das Dokument nicht kann: wer es sendet, welche Art von Einrichtung und Praxis es stammt und welcher der Patientenidentifikatoren der Affinitätsdomäne ist.

Definiert als XDSDestination in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
source_idTextja—
patient_domainTextnein—
facility_typeXDSCodeja—
practice_settingXDSCodeja—
classXDSCode (ein Block, weglassen, um es nicht zu verwenden)nein—
content_typeXDSCode (ein Block, weglassen, um es nicht zu verwenden)nein—
tokenTextnein—
usernameTextnein—
passwordTextnein—
headersZuordnung von Text zu Textnein—
tlstlsconf.Settings (ein Block, weglassen, um es nicht zu verwenden)nein—
timeoutDauer, z. B. 30s oder 5mnein—
direct_fromTextnein—
direct_toListe von Textnein—

23.34.1 patient_domain

PatientDomain ist die Affinitätsdomäne, die die OID der Zuweisungsbehörde zuweist: der Patientenidentifikator mit dieser Wurzel ist der registrierte.

Ohne ihn sendet ein Dokument, dessen Patient einen Identifikator hat, diesen einen, und eines mit mehreren wird abgelehnt.

23.34.2 Token

Token oder Benutzername/Kennwort authentifizieren; Header werden jeder Anfrage hinzugefügt.

Die meisten Affinitätsdomänen verwenden gegenseitiges TLS (tls) anstelle dessen.

23.34.3 Benutzername

Token oder Benutzername/Kennwort authentifizieren; Header werden jeder Anfrage hinzugefügt.

Die meisten Affinitätsdomänen verwenden gegenseitiges TLS (tls) anstelle dessen.

23.34.4 Passwort

Token oder Benutzername/Kennwort authentifizieren; Header werden jeder Anfrage hinzugefügt.

Die meisten Affinitätsdomänen verwenden gegenseitiges TLS (tls) anstelle dessen.

23.34.5 headers

Token oder Benutzername/Kennwort authentifizieren; Header werden jeder Anfrage hinzugefügt.

Die meisten Affinitätsdomänen verwenden gegenseitiges TLS (tls) anstelle dessen.

23.34.6 tls

Token oder Benutzername/Kennwort authentifizieren; Header werden jeder Anfrage hinzugefügt.

Die meisten Affinitätsdomänen verwenden gegenseitiges TLS (tls) anstelle dessen.

23.34.7 direct_from

DirectFrom und DirectTo machen die Übermittlung XDR als Direct-Transport: ein Direct-Adressblock, der die Direct-Adresse dieses Absenders und die der Empfänger nennt, und die Empfänger in der beabsichtigten Empfängerliste.

Ein HISP, der XDR übernimmt, liefert es als Direct-E-Mail oder an den eigenen XDR-Endpunkt des Empfängers.

23.34.8 direct_to

DirectFrom und DirectTo machen die Übermittlung XDR als Direct-Transport: ein Direct-Adressblock, der die Direct-Adresse dieses Absenders und die der Empfänger nennt, und die Empfänger in der beabsichtigten Empfängerliste.

Ein HISP, der XDR übernimmt, liefert es als Direct-E-Mail oder an den eigenen XDR-Endpunkt des Empfängers.

24 Formatreferenz

Optionen, die steuern, wie Nachrichten analysiert und geschrieben werden, für Formate, die mehr als einen Namen benötigen.

24.1 Anhänge

Anhänge konfigurieren das Verschieben großer Payloads aus einer Nachricht.

Eine Nachricht, die einen gescannten Bericht oder ein PDF enthält, ist in Dokumentenworkflows normal, und die Payload ist routinemäßig hundertmal größer als die Nachricht selbst. Wenn sie inline belassen wird, bedeutet dies, dass der Speicher mit der Rate der Dokumente und nicht mit dem Datenverkehr wächst, eine in fünf Ziele wartende Nachricht wird fünfmal kopiert und die Schnittstelle streamt Megabyte, um jemandem einen Patientennamen zu zeigen.

Mirth bezeichnet diese Anhänge als Attachment-Handler. Dies ist das Äquivalent, und es ist pro Kanal optional, da ein Feed mit einfachen ADT-Nachrichten nichts zu extrahieren hat und nicht für die Maschinerie zahlen sollte.

Definiert als Attachments in internal/config.

SchlüsselTypErforderlichStandard
extractListe von attach.Ruleja—
reassembletrue oder false (ein Block, weglassen, um es wegzulassen)neintrue

24.1.1 reassemble

Reassemble setzt Payloads vor der Zustellung wieder zusammen.

Standardmäßig true.

Der Standard ist aktiviert, da ein Empfänger, der ein Dokument erwartet, ein Dokument erhalten muss; eine Nachricht, die einen literalen Token enthält, würde als Bericht abgelegt und niemand würde es herausfinden, bis jemand den Datensatz öffnet.

Es wird ausgeschaltet, wenn der Zweck des Kanals darin besteht, Dokumente zu entfernen - Metadaten an ein System weiterzuleiten, das keine Verwendung für das Bild hat, wo das Senden eher eine Datenschutzfrage als eine Bandbreitenfrage wäre.

24.2 Abgegrenzt

Begrenzt konfiguriert einen begrenzten Kanal.

Mirths Delimited-Datentyp: CSV, tabulatorgetrennt und die Vielzahl von Formaten, die ein Laboranalyser oder ein Bürodienst ausgibt.

Definiert als Delimited in internal/config.

SchlüsselTypErforderlichStandard
delimiterTextnein—
quoteTextneinein doppeltes Anführungszeichen
commentTextnein—
has_headerwahr oder falschnein—
columnsListe von Textnein—
trim_spacewahr oder falschnein—
relaxedwahr oder falschnein—
splitwahr oder falsch (ein Block, weglassen, um es auszulassen)neinwahr
keep_blank_lineswahr oder falschnein—
filterTextnein—
transformationsListe von Schritten.Stepnein—

24.2.1 Trenner

Der Trenner trennt Spalten als Zeichen oder Namen.

Ein Name wird akzeptiert, weil ein Tabulator nicht eindeutig in eine YAML-Datei geschrieben werden kann und eine Konfigurationsdatei, die ein unsichtbares Zeichen enthält, für den nächsten Benutzer, der sie öffnet, nicht lesbar ist.

24.2.2 Anführungszeichen

Das Anführungszeichen umschließt Werte, die den Trenner enthalten.

Standardmäßig ist es ein doppeltes Anführungszeichen; „keines“ deaktiviert es.

24.2.3 Teilen

Teilen macht jede Zeile zu einer eigenen Nachricht.

Standardmäßig true.

Dies ist die Entscheidung, die einen begrenzten Kanal formt und es verdient, ausdrücklich erwähnt zu werden. Eine Datei mit fünftausend Ergebnissen ist entweder eine Nachricht oder fünftausend. Eine Nachricht bedeutet eine Bestätigung, einen Eintrag im Browser und einen Fehler, der die gesamte Datei mit sich reißt. Fünftausend bedeutet, dass jede Zeile gefiltert, transformiert, geliefert und erneut versucht wird und eine einzelne fehlerhafte Zeile die anderen nicht stoppt.

Teilen ist standardmäßig, weil die Verarbeitung pro Zeile das ist, was fast jeder Standort möchte, und weil die Alternative erst spät entdeckt wird: Ein Kanal, der bei einem Test mit einer dreizeiligen Datei fehlerfrei aussieht, versagt eine gesamte Nachtübertragung aufgrund einer fehlerhaften Zeile.

24.2.4 Leere_Zeilen_behalten

LeereZeilenBehalten verhindert, dass leere Zeilen übersprungen werden.

Überspringen ist standardmäßig, weil jede Datei mit einem Zeilenvorschub endet und ein Datensatz mit leeren Feldern kein Datensatz ist. Dies existiert für das seltene Format, bei dem eine leere Zeile bedeutungsvoll ist.

24.2.5 Filter

Filter entscheidet, welche Nachrichten fortgesetzt werden, basierend auf Spaltennamen.

Hier anstelle des Kanals, weil der Kanalfilter HL7-Pfade kompiliert. Zwei Einstellungen namens Filter wären verwirrend, aber eine Einstellung, die je nach Datentyp unterschiedliche Bedeutungen hat, ist schlimmer: Ein begrenzter Kanal, der stillschweigend seinen Filter als HL7 kompiliert, würde nichts finden und alles fallen lassen, was der Fehler ist, den die oberste Ablehnung verhindern soll.

24.2.6 Transformationen

Transformationen sind die deklarativen Schritte, die Spalten anstelle von HL7-Feldern ansprechen.

Getrennt von den Transformationen des Kanals aus demselben Grund wie Filter und es ist die Anordnung, die X12 und NCPDP bereits verwenden.

24.3 HL7v3-Optionen

HL7v3-Optionen sind die Einstellungen, die nur für einen HL7-v3-Kanal gelten.

Definiert als HL7v3Options in internal/config.

SchlüsselTypErforderlichStandard
filterTextnein—
acknowledgewahr oder falsch (ein Block, weglassen, um es auszulassen)nein—
sender_deviceTextnein—
sender_oidTextnein—
transformationsListe von hl7v3.Schrittennein—

24.3.1 Filter

Filter schließt Nachrichten aus, unter Verwendung von v3-Pfaden.

Es handelt sich um ein eigenes Feld und nicht um den gewöhnlichen Filter des Kanals, da es sich um zwei verschiedene Sprachen gegenüber unterschiedlichen Nachrichtenmodellen handelt. Die gemeinsame Verwendung des Feldes würde bedeuten, dass ein v2-Filter stillschweigend nie auf einem v3-Kanal übereinstimmt oder ein v3-Filter nicht als v2 parsen kann - und letzteres ist nur besser, weil es laut fehlschlägt.

Ein Kanal, der beide setzt, wird bei der Ladung abgelehnt, da eines von ihnen ignoriert werden müsste und es keine ehrliche Möglichkeit gibt, eine Wahl zu treffen.

24.3.2 Bestätigung

Bestätigung sendet eine MCCI_IN000002UV01-Bestätigung zurück.

Standardmäßig aktiviert, im Gegensatz zu X12. Eine v3-Interaktion über ein synchrones Transportmittel erwartet eine Bestätigung - die sendende Anwendung wartet in der Regel darauf - und ein Sender, der nichts erhält, wird normalerweise erneut versuchen, was dazu führt, dass ein Patient dreimal registriert wird.

Ein Zeiger, damit "nicht gesetzt" und "auf false gesetzt" unterschieden werden können: Der Standard ist aktiviert, und jemand, der es deaktiviert, sollte dies ausdrücklich tun.

24.3.3 sender_gerät

SenderGerät ist die Gerätekennung, die wir in einer Bestätigung verwenden.

Erforderlich bei der Bestätigung. Eine v3-Bestätigung nennt das Gerät, von dem sie stammt, und ein Empfänger, der unser Gerät nicht erkennt, kann sie verwerfen - was genau so aussieht, als ob keine gesendet wurde.

24.3.4 Transformationen

Transformationen ändern den Inhalt eines v3-Dokuments.

Es handelt sich um ein eigenes Feld und nicht um die gewöhnlichen Transformationen des Kanals, aus demselben Grund wie der Filter: Es handelt sich um unterschiedliche Vokabulare gegenüber unterschiedlichen Nachrichtenmodellen. Die v2-Schritte adressieren Segmente und Felder, die ein v3-Dokument nicht hat, so dass die gemeinsame Verwendung des Feldes bedeuten würde, dass ein Schritt stillschweigend nichts tut.

Die Schrittnamen entsprechen den v2-Namen, wo die Bedeutung übereinstimmt, so dass jemand, der einen Kanal geschrieben hat, den anderen schreiben kann. Was unterschiedlich ist, ist, was v3 benötigt und v2 nicht ausdrücken kann - vor allem, dass das Entfernen eines Wertes drei unterschiedliche Bedeutungen hat, so dass clear, nullflavor und remove drei Schritte sind und nicht einer.

24.4 TCP-Rahmung

TCP-Rahmung ist die Methode, mit der Nachrichtengrenzen auf einem rohen Socket gefunden werden.

Geteilt von der TCP-Quelle und der TCP-Zieladresse und von der seriellen Quelle, da die Rahmungen überall gleich sind, woher die Bytes stammen. Ein Laboranalyser, der STX/ETX über einen Socket spricht, spricht auch STX/ETX über ein Seriellkabel.

Definiert als TCPFraming in internal/config.

SchlüsselTypErforderlichStandard
framingTextja—
delimiterTextnein—
start_blockTextnein—
keep_delimiterwahr oder falschnein—
record_lengthganze Zahlnein—
trim_paddingwahr oder falsch (ein Block, weglassen, um es auszulassen)nein—
length_bytesganze Zahlnein—
big_endianwahr oder falschnein—
length_includes_headerwahr oder falschnein—

24.4.1 rahmung

Rahmung ist mllp, begrenzt, fest, Länge oder ganz.

Erforderlich, ohne Standard. Das Lesen eines Streams mit der falschen Rahmung produziert Nachrichten, die plausibel aussehen, anstatt einen Fehler zu erzeugen, so dass das Raten schlimmer ist als das Fragen.

24.4.2 start_block

StartBlock beginnt optional eine Nachricht.

Bytes davor werden als Rauschen von einer unvollständigen Verbindung verworfen.

24.4.3 trenner_behalten

KeepDelimiter enthält das Trennzeichen in der Nachricht.

Standardmäßig ausgeschaltet: Es handelt sich um eine Rahmen- und keine Inhaltsfestlegung.

24.4.4 trim_padding

TrimPadding entfernt nachfolgende Leerzeichen und NULs aus einem festen Datensatz.

Standardmäßig eingeschaltet.

24.5 X12-Optionen

X12-Optionen sind Einstellungen, die nur für einen X12-Kanal gelten.

Definiert als X12Options in internal/config.

SchlüsselTypErforderlichStandard
envelopeEnvelopePolicyneinerforderlich
splittrue oder falsenein—
acknowledgeTextnein—
ack_sender_idTextnein—
ack_sender_qualifierTextnein—
arrives_asTextnein—
transformationsListe von x12.Stepnein—

24.5.1 envelope

Envelope legt fest, was zu tun ist, wenn die selbstdeklarierten Zählungen nicht mit dem Vorhandenen übereinstimmen.

Standardmäßig auf „erforderlich“ gesetzt.

24.5.2 Teilen

Split sendet eine Nachricht pro Transaktionssatz anstelle von einer pro Datei.

Standardmäßig ausgeschaltet. Eine einzelne 837 kann Hunderte von Ansprüchen enthalten, daher multipliziert sich durch die Aktivierung alles Downstream – Nachrichtenzählungen, Bestätigungen, Zeilen, Warnschwellen – und das sollte eine Entscheidung sein, die jemand trifft, anstatt ein Standardwert, der vererbt wird.

24.5.3 Bestätigung

Acknowledge legt fest, welche Bestätigung zurückgesendet werden soll: 999, 997, ta1 oder keine.

Welche davon eine Eigenschaft der Handelspartnerbeziehung und nicht der Nachricht ist, sodass sie konfiguriert werden muss. Eine 999 ersetzt eine 997 für HIPAA-Transaktionen, aber viele Partner – insbesondere ältere Verbindungen zu Zahlern – sind so konfiguriert, dass sie eine 997 erwarten und eine 999 als unerkannte Datei behandeln. Das Senden der falschen Bestätigung ist schlimmer als das Senden keiner, da es eine Frage beantwortet, die niemand gestellt hat, und die eigentliche Frage offen lässt.

Leer bedeutet keine, was der sichere Standardwert ist: Ein Partner, der keine Bestätigung erwartet und eine erhält, kann diese als unerwünschte Interchange behandeln.

24.5.4 ack_sender_id

AckSenderID und AckSenderQualifier sind unsere eigene Interchange-Kennung, die zu ISA06 und ISA05 jeder Bestätigung wird.

Erforderlich, wenn Acknowledge festgelegt ist, und ansonsten bei der Ladung abgelehnt. Diese müssen die Werte sein, die der Handelspartner für uns konfiguriert hat, und es gibt keine Möglichkeit, sie zu erraten: Ein Interchange, dessen ISA06 der Partner nicht erkennt, wird vor dem Lesen durch jemanden verworfen, sodass ein falscher Wert zu Schweigen führt, das genau wie das Nichtsenden aussieht – und jemand verbringt eine Woche damit, an der falschen Stelle zu suchen.

24.5.5 ack_sender_qualifier

AckSenderID und AckSenderQualifier sind unsere eigene Interchange-Kennung, die zu ISA06 und ISA05 jeder Bestätigung wird.

Erforderlich, wenn Acknowledge festgelegt ist, und ansonsten bei der Ladung abgelehnt. Diese müssen die Werte sein, die der Handelspartner für uns konfiguriert hat, und es gibt keine Möglichkeit, sie zu erraten: Ein Interchange, dessen ISA06 der Partner nicht erkennt, wird vor dem Lesen durch jemanden verworfen, sodass ein falscher Wert zu Schweigen führt, das genau wie das Nichtsenden aussieht – und jemand verbringt eine Woche damit, an der falschen Stelle zu suchen.

24.5.6 ankommt_wie

AnkommtWie ist XML, wenn die Quelle den Austausch als das XML liefert, das Mirth Connect und Open Integration Engine für X12 (eine X12-Transaktion-Wurzel, Elemente mit dem Namen CLM.05.1) schreiben, oder wenn ein System, das von einem dieser Systeme migriert wird oder darauf basiert, es sendet.

Es wird vor jeder weiteren Verarbeitung wieder in X12 umgewandelt. Leer oder x12 ist X12.

24.5.7 Transformationen

Transformationen sind deklarative Änderungen, die auf akzeptierte Interchanges angewendet werden.

Getrennt von den kanalübergreifenden Transformationen aus dem gleichen Grund, aus dem die v3-Transformationen getrennt sind: Diese adressieren HL7-Felder durch einen Parser, der Segment-Feld-Komponente-Subkomponente liest, und X12 hat keine Subkomponente, behandelt wiederholte Segmente als normal und nicht als außergewöhnlich und wird von den Menschen, die es konfigurieren, als CLM01 geschrieben. Ein gemeinsamer Parser müsste beide Notationen akzeptieren und wäre dann in beiden Notationen mehrdeutig.

Die Schrittnamen sind dieselben, die die HL7- und v3-Schritte verwenden, sodass das, was ein Autor bereits gelernt hat, übernommen wird.

25 Verhaltensreferenz

Bestätigung, Queueing, Wiederholung, Polling, Skripting und Schatten-Einstellungen. Diese gelten unabhängig vom Transport, den ein Kanal verwendet.

25.1 AMQP-Verbindung

AMQP-Verbindung ist, wo und als wer eine Verbindung hergestellt wird.

Definiert als AMQPConnection in internal/config.

SchlüsselTypErforderlichStandard
addrTextja—
addressTextja—
usernameTextnein—
passwordTextnein—
hostnameTextneinder Host von addr
tlstlsconf.Settings (ein Block, weglassen, um nichts zu verwenden)nein—
timeoutDauer, wie 30s oder 5mnein30s

25.1.1 Benutzername

Benutzername und Passwort authentifizieren mit SASL PLAIN; beide leer bedeutet ANONYMOUS.

Für Service Bus, der Name und der Schlüssel der Richtlinie.

25.1.2 Passwort

Benutzername und Passwort authentifizieren mit SASL PLAIN; beide leer bedeutet ANONYMOUS.

Für Service Bus, der Name und der Schlüssel der Richtlinie.

25.1.3 Hostname

Hostname wird an den Broker gesendet, auf den Service Bus routet.

Standardmäßig der Host von addr.

25.1.4 tls

TLS verschlüsselt die Verbindung.

Erforderlich für Service Bus und Event Hubs.

25.1.5 Zeitüberschreitung

Timeout begrenzt die Verbindung und jedes Warten auf den Broker.

Defaults to 30s.

25.2 AS2-Partner

AS2-Partner ist ein Handelspartner, von dem eine AS2-Quelle Nachrichten akzeptiert.

Definiert als AS2Partner in internal/config.

SchlüsselTypErforderlichStandard
idTextja—
cert_fileTextja—
allow_unsignedwahr oder falschnein—
allow_unencryptedwahr oder falschnein—

25.2.1 cert_file

CertFile ist das Zertifikat des Partners (PEM), für seine Signaturen.

Oft selbstsigniert: AS2-Partner tauschen Zertifikate direkt aus, anstatt über eine Behörde.

25.2.2 allow_unsigned

AllowUnsigned und AllowUnencrypted akzeptieren eine Nachricht von diesem Partner, die nicht signiert oder nicht verschlüsselt ist.

Aus: Eine solche Nachricht wird mit einem Empfangsbeleg abgelehnt, der den Grund angibt.

25.2.3 allow_unencrypted

AllowUnsigned und AllowUnencrypted akzeptieren eine Nachricht von diesem Partner, die nicht signiert oder nicht verschlüsselt ist.

Aus: Eine solche Nachricht wird mit einem Empfangsbeleg abgelehnt, der den Grund angibt.

25.3 AWS-Zugriff

AWS-Zugriff legt fest, wie ein Connector auf AWS zugreift: die Region, für die er unterschreibt, die Schlüssel und eine optionale Endpunktüberschreibung.

Anmeldedaten können wörtlich oder als ${ENV_VAR}-Referenzen angegeben werden, was die empfohlene Methode ist. Es gibt keine Instanz-Metadaten-Anmeldedatenkette, und das ist absichtlich: siehe internal/awsv4.

Definiert als AWSAccess in internal/config.

SchlüsselTypErforderlichStandard
regionTextja—
access_key_idTextnein—
secret_access_keyTextnein—
session_tokenTextnein—
endpointTextnein—

25.3.1 secret_access_key

SecretAccessKey ist der geheime Schlüssel, wörtlich oder ${AWS_SECRET_ACCESS_KEY}.

Bevorzugen Sie die Referenz: diese Datei wird in die Versionskontrolle aufgenommen.

25.3.2 session_token

SessionToken ist nur für temporäre Anmeldedaten.

Sie laufen ab, und der Connector hört auf zu funktionieren, wenn sie ablaufen.

25.4 Bestätigung

Bestätigung konfiguriert die Erstellung von Bestätigungen.

Definiert als Ack in internal/config.

SchlüsselTypErforderlichStandard
whenAckWhennein—
applicationTextnein—
facilityTextnein—
include_trigger_eventwahr oder falschnein—

25.4.1 include_trigger_event

IncludeTriggerEvent sendet ACK^A01 anstelle von ACK.

Einige Empfänger erfordern es, und andere lehnen es ab, daher ist es explizit.

25.5 Azure Blob-Zugriff

AzureBlobAccess ist das Konto, der Container und die Anmeldedaten.

Definiert als AzureBlobAccess in internal/config.

SchlüsselTypErforderlichStandard
accountTextja—
containerTextja—
keyTextnein—
sasTextnein—
endpointTextnein—

25.5.1 key

Der Schlüssel ist der Kontoschlüssel oder ${AZURE_STORAGE_KEY}.

Setzen Sie ihn oder sas.

25.5.2 sas

SAS ist eine gemeinsam genutzte Zugriffs-Signatur-Abfragezeichenfolge oder eine ${...}-Referenz.

Bevorzugt: es kann auf diesen Container beschränkt werden.

25.6 Vertragsreferenz

ContractRef zeigt auf einen Kanal und seinen Vertrag.

Definiert als ContractRef in internal/config.

SchlüsselTypErforderlichStandard
fileTextja—
check_everyTextnein15 Minuten
overganze Zahlnein500

25.6.1 Überprüfen alle

CheckEvery legt fest, wie oft die Überprüfung wiederholt wird, als Dauer.

Standardmäßig 15 Minuten.

Effektiv auf den Alert-Bewertungsintervall von 30 Sekunden begrenzt, da die Überprüfung von dieser Schleife und nicht von einem eigenen Timer ausgeführt wird. Das bedeutet, dass ein Vertrag, der eine Überprüfung alle 3 Sekunden anfordert, stattdessen alle 30 Sekunden überprüft wird. Dies ist beabsichtigt: Ein Timer ist einfacher zu verstehen als zwei, und er hält das Ergebnis eines Vertrags mit der zugehörigen Lesung synchron. Es ist wichtig, dies zu wissen, bevor jemand ein kurzes Intervall festlegt und zu dem Schluss kommt, dass es defekt ist.

Nicht pro Nachricht. Das Erstellen eines Profils bedeutet, den aktuellen Datenverkehr zu lesen, und dies bei jeder Nachricht zu tun, würde die Durchsatzleistung eines Kanals von der Menge an Historie abhängig machen - was die Art von Leistungsmerkmal ist, die nur in der Produktion, sechs Monate im Voraus, sichtbar wird.

25.6.2 Über

Über legt fest, wie viele aktuelle Nachrichten für das Profil verwendet werden sollen.

Defaults to 500.

Eine Zählung anstelle eines Zeitfensters, da ein ruhrender Feed und ein beschäftigter Feed die gleiche Menge an Beweisen benötigen, um eine Rate zu rechtfertigen, und ein Zeitfenster ihnen sehr unterschiedliche Mengen gibt.

25.7 DICOM-Optionen

DICOMOptions konfiguriert einen Imaging-Kanal.

Warum die Schritte benannt sind und nicht Pfade

Jedes andere Format erhält einen Pfad-Writer. DICOM erhält absichtlich keinen, und der Grund dafür sind die Pixel-Daten: Ein Objekt ist binär, ein allgemeiner Tag-Writer kann jeden Tag auf beliebige Bytes setzen, und ein Fehler dort produziert keine abgelehnte Nachricht - es produziert ein Bild, das geöffnet und falsch ist. Ein Radiologe, der eine Studie liest, hat keine Möglichkeit, dies zu erkennen.

Die vier Dinge, die Sites tatsächlich benötigen, sind benannte Aktionen mit begrenzten Auswirkungen: Entidentifizierung, Ändern eines AE-Titels, Entfernen privater Tags, Festlegen der Institution. Jede weiß, welche Tags sie berührt, und keine kann die Pixel-Daten erreichen.

Warum dieser Block jetzt existiert

internal/dicom hat seit einer Weile steps.go und transform.go - die vier Aktionen, dicom.Apply und Tests. Nichts hat sie referenziert. Fünfhundert Zeilen ohne Aufrufer, was die eigene Sektion 7 des Queues nennt: Eine Implementierung ohne Aufrufer ist nicht von einem Feature zu unterscheiden, das nicht existiert. Dieser Block und der Motoraufruf sind die Verdrahtung, nicht das Feature.

Definiert als DICOMOptions in internal/config.

SchlüsselTypErforderlichStandard
transformationsListe von dicom.Schrittennein—

25.8 Direkte Adresse

DirectAddress ist eine Direkt-Adresse, die dieser Server hält: sein Zertifikat und Schlüssel und die Vertrauensanker, die er vertraut.

Der gleiche Block wird verwendet, um zu senden (als diese Adresse zu signieren) und zu empfangen (für sie zu entschlüsseln).

Definiert als DirectAddress in internal/config.

SchlüsselTypErforderlichStandard
addressTextja—
cert_fileTextja—
key_fileTextja—
anchors_fileTextja—

25.8.1 cert_file

CertFile und KeyFile sind das Zertifikat der Adresse (PEM, mit seiner Kette dahinter) und der private Schlüssel (PEM).

Die HISP oder ihre Registrierungsbehörde stellt sie aus; sie sind die Identität der Adresse.

25.8.2 key_file

CertFile und KeyFile sind das Zertifikat der Adresse (PEM, mit seiner Kette dahinter) und der private Schlüssel (PEM).

Die HISP oder ihre Registrierungsbehörde stellt sie aus; sie sind die Identität der Adresse.

25.8.3 anchors_file

AnchorsFile sind die Vertrauensanker (PEM): die Zertifizierungsstellen, deren Absender und Empfänger diese Adresse vertraut, wie z. B. das DirectTrust-Bundle.

Eine Nachricht, die von etwas anderem signiert ist, wird abgelehnt.

25.9 Direct IMAP

DirectIMAP ist das HISP-Postfach, das eine Direct-Quelle liest.

Definiert als DirectIMAP in internal/config.

SchlüsselTypErforderlichStandard
hostTextja—
portGanzzahlnein—
securityTextnein—
usernameTextja—
passwordTextnein—
mailboxTextnein—
after_readTextnein—
move_toTextnein—
error_folderTextnein—
poll_intervalDauer, wie z. B. 30s oder 5mnein—
tlstlsconf.Settings (ein Block, weglassen, um es nicht zu verwenden)nein—

25.9.1 move_to

MoveTo ist der Ordner, in den die verarbeiteten Nachrichten verschoben werden; standardmäßig ist es "Processed".

Wird erstellt, wenn es fehlt.

25.9.2 tls

TLS vertraut einer Zertifikatsdatei (oder dem eigenen Zertifikat des HISP) und benennt den erwarteten Server darin, für einen HISP, dessen IMAP-Zertifikat nicht von einer öffentlichen Behörde stammt.

Das Zertifikat wird immer überprüft.

25.10 Direct XDR

DirectXDR ist der Endpunkt, an dem eine Direct-Quelle XDR übernimmt.

Definiert als DirectXDR in internal/config.

SchlüsselTypErforderlichStandard
listenTextja—
tls_certTextnein—
tls_keyTextnein—
client_ca_fileTextnein—

25.11 ECR-Einrichtung

ECRFacility ist die Organisation, die Fallberichte sendet.

Definiert als ECRFacility in internal/config.

SchlüsselTypErforderlichStandard
nameTextja—
npiTextnein—
phoneTextja—
lineTextnein—
cityTextja—
stateTextja—
postal_codeTextnein—

25.12 EDIFACT-Optionen

EDIFACTOptions sind die Einstellungen, die nur für einen EDIFACT-Kanal gelten.

Definiert als EDIFACTOptions in internal/config.

SchlüsselTypErforderlichStandard
envelopeTextnein—
splitwahr oder falschnein—
acknowledgeTextnein—

25.12.1 Bestätigung

Acknowledge antwortet einem Absender, der über HTTP postet, mit einem CONTRL in der Antwort: akzeptiert (Aktion 7), wenn der Austausch gelesen und zugestellt wurde, abgelehnt (4) sonst.

Default none.

25.13 E-Mail-OAuth

EmailOAuth meldet sich mit OAuth 2.0 (SASL XOAUTH2) an, was Microsoft 365 und Gmail anstelle eines Passworts erfordern.

Definiert als EmailOAuth in internal/config.

SchlüsselTypErforderlichStandard
providerTextja—
tenantTextnein—
token_urlTextnein—
client_idTextja—
client_secretTextnein—
refresh_tokenTextnein—
scopeTextnein—

25.13.1 client_secret

ClientSecret kann ${ENV} sein.

Ohne refresh_token wird Microsofts App-only-Client-Credentials-Zuweisung ausgewählt.

25.13.2 refresh_token

RefreshToken kann ${ENV} sein: ein Postfach, dem eine Person zugestimmt hat.

Erforderlich für Gmail.

25.14 FHIR-Authentifizierung

FHIRAuth ist die Methode, mit der ein FHIR-Ziel eine Authentifizierung bei einem gehosteten FHIR-Dienst durchführt.

Es gibt drei vorkonfigurierte Einstellungen, da die gehosteten Dienste den Punkt erreicht haben, an dem ein in eine Datei eingefügter Bearer-Token innerhalb einer Stunde nicht mehr funktioniert:

Tokens werden abgerufen, wenn sie benötigt werden, und wiederholt verwendet, bis sie eine Minute vor ihrem Ablaufdatum ablaufen.

Definiert als FHIRAuth in internal/config.

SchlüsselTypErforderlichStandard
typeTextja—
regionTextnein—
access_key_idTextnein—
secret_access_keyTextnein—
session_tokenTextnein—
tenant_idTextnein—
token_urlTextnein—
client_idTextnein—
client_secretTextnein—
scopeTextnein—

25.14.1 Region

Region ist die AWS-Region.

Wird aus einer HealthLake-URL gelesen, wenn sie nicht angegeben ist.

25.14.2 token_url

TokenURL ist der OAuth-Token-Endpunkt für client_credentials.

Für Azure wird er aus dem Mandanten abgeleitet.

25.14.3 client_id

ClientID und ClientSecret identifizieren die Anwendung.

Das Geheimnis kann eine ${ENV}-Referenz sein, was die empfohlene Methode zur Angabe ist.

25.14.4 client_secret

ClientID und ClientSecret identifizieren die Anwendung.

Das Geheimnis kann eine ${ENV}-Referenz sein, was die empfohlene Methode zur Angabe ist.

25.14.5 scope

Der Umfang wird mit dem Token angefordert.

Für Azure wird er standardmäßig auf die FHIR-Service-URL gefolgt von /.default gesetzt, was seine Zielgruppe ist.

25.15 Dateiabfrage

FilePoll ist der Teil einer dateisammelnden Quelle, der nichts mit dem Transport zu tun hat.

Wird von den lokalen, FTP-, SMB- und WebDAV-Quellen sowie von SFTP gemeinsam genutzt. Jede dieser Einstellungen existiert, weil Dateien auf eine bestimmte Weise fehlerhaft sind und nicht, weil sich die Transporte unterscheiden, was der Grund ist, warum sie zusammengehören: Ein Standort, der die richtige stable_for-Einstellung für seinen Analyser ermittelt hat, sollte sie nicht noch einmal ermitteln müssen, wenn der Analyser in einen Shared-Ordner verschoben wird.

Definiert als FilePoll in internal/config.

SchlüsselTypErforderlichStandard
dirTextja—
patternTextnein—
poll_intervalDauer, z. B. 30s oder 5mnein—
after_readTextnein—
move_toTextnein—
error_dirTextnein—
stable_forDauer, z. B. 30s oder 5mnein—
max_file_sizeGanzzahlnein—
framedwahr oder falschnein—
rawwahr oder falschnein—
batch_sizeGanzzahlnein—
sort_byTextneinname

25.15.1 pattern

Das Muster wählt Dateien nach Glob aus.

Leer bedeutet jede Datei.

25.15.2 Fehlerverzeichnis

ErrorDir ist das Verzeichnis, in das eine Datei verschoben wird, die nicht verarbeitet werden konnte.

Getrennt von MoveTo, da ein Verzeichnis, das nur Fehler enthält, überwacht werden kann und das Mischen von Fehlern in das Archiv bedeutet, dass die einzige Möglichkeit, sie zu finden, darin besteht, jede Datei zu lesen.

25.15.3 roh

Raw behandelt die gesamte Datei als eine Nachricht, unabhängig vom Inhalt.

Die Einstellung, die diesen Connector nützlich für alles andere als HL7 macht. Ohne sie wird eine CSV-Batch-Datei, eine X12-Claim-Datei oder eine PDF-Datei bei Zeilen, die mit MSH beginnen, aufgeteilt und produziert nichts, und der Fehler sagt, dass die Datei kein HL7 ist - was stimmt, aber nicht der Punkt ist, da die Datei nie als HL7 gedacht war.

25.15.4 batch_groesse

BatchSize begrenzt die Anzahl der Dateien, die bei einem Poll gelesen werden.

Null bedeutet keine Begrenzung.

Wird für den ersten Poll nach einem Ausfall erstellt. Ein Verzeichnis, das vierzigtausend Dateien enthält, die über Nacht angefallen sind, wird ansonsten in einem Durchgang gelesen, was die Poll-Schleife so lange blockiert, bis sie abgeschlossen ist, und den Kanal unresponsive macht. Das Lesen einer begrenzten Anzahl von Dateien pro Poll hält den Kanal responsive und den Queue sichtbar leer.

25.15.5 sort_by

SortBy ordnet die Dateien innerhalb eines Polls: Name, geändert oder keine.

Standardmäßig ist der Name. Die Reihenfolge ist wichtiger, als es aussieht: Ein ADT-Stream, bei dem A08-Aktualisierungen vor dem A01-Einweisungstermin eintreffen, produziert Patienten, die noch nicht existieren. Die Reihenfolge der Verzeichnisanzeige ist auf den meisten Dateisystemen willkürlich, sodass das Nichtsortieren bedeutet, dass die Reihenfolge zwischen den Polls ohne sichtbaren Grund geändert wird.

25.16 GCP-Zugriff

GCPAccess ist die Methode, um sich bei Google Cloud zu authentifizieren.

Definiert als GCPAccess in internal/config.

SchlüsselTypErforderlichStandard
projectTextnein—
credentials_fileTextnein—
endpointTextnein—

25.16.1 credentials_file

CredentialsFile ist der JSON-Schlüssel eines Dienstkonto.

Leer verwendet das Dienstkonto, das an die VM, GKE-Pod oder Cloud-Run-Dienst angehängt ist, auf dem Perfuse ausgeführt wird (der Metadata-Server), es sei denn, der Endpunkt benennt einen Emulator.

25.17 GCS-Zugriff

GCSAccess ist ein Cloud-Storage-Bucket.

Definiert als GCSAccess in internal/config.

SchlüsselTypErforderlichStandard
bucketTextja—

25.18 IBMMQ-Verbindung

IBMMQConnection ist eine Warteschlange, die über die Messaging-REST-API des Warteschlangen-Managers erreicht wird.

Definiert als IBMMQConnection in internal/config.

SchlüsselTypErforderlichStandard
urlTextja—
queue_managerTextja—
queueTextja—
usernameTextnein—
passwordTextnein—
tlstlsconf.Settings (ein Block, weglassen, um nicht zu verwenden)nein—
api_versionTextnein—
timeoutDauer, wie z. B. 30s oder 5mnein30s

25.18.1 Benutzername

Benutzername und Passwort sind ein mqweb-Benutzer mit der Rolle MQWebUser; das Passwort kann ${ENV} sein.

Beide Felder leer lassen, wenn ein Clientzertifikat (tls.cert_file) authentifiziert.

25.18.2 Passwort

Benutzername und Passwort sind ein mqweb-Benutzer mit der Rolle MQWebUser; das Passwort kann ${ENV} sein.

Beide Felder leer lassen, wenn ein Clientzertifikat (tls.cert_file) authentifiziert.

25.18.3 Zeitüberschreitung

Timeout begrenzt jede Anfrage.

Defaults to 30s.

25.19 Kafka SASL

KafkaSASL authentifiziert sich bei einem Kafka-Cluster.

Definiert als KafkaSASL in internal/config.

SchlüsselTypErforderlichStandard
mechanismTextja—
usernameTextja—
passwordTextja—

25.19.1 Mechanismus

Mechanismus ist "plain", "scram-sha-256" oder "scram-sha-512".

PLAIN sendet das Passwort im Klartext, daher gehört es mit TLS. SCRAM tut dies nicht, was der Grund ist, warum der Unterschied hier genannt wird, anstatt die drei als austauschbar zu behandeln.

25.19.2 Passwort

Passwort ist das SASL-Passwort.

Unterstützt ${ENV}-Verweise wie jedes andere Geheimnis hier, sodass ein Cluster-Credential nicht in die Kanaldatei geschrieben werden muss.

25.20 MQTT-Verbindung

MQTTConnection ist die Möglichkeit, einen MQTT 3.1.1-Broker zu erreichen: Mosquitto, EMQX, HiveMQ, AWS IoT Core, Azure Event Grid.

Definiert als MQTTConnection in internal/config.

SchlüsselTypErforderlichStandard
addrTextja—
client_idTextnein—
usernameTextnein—
passwordTextnein—
tlstlsconf.Settings (ein Block, weglassen, um nicht zu verwenden)nein—
qosganze Zahl (ein Block, weglassen, um nicht zu verwenden)nein—
timeoutDauer, wie z. B. 30s oder 5mnein30s

25.20.1 client_id

ClientID benennt die Sitzung.

Eine Quelle behält ihre Nachrichten über Neukonnektionen hinweg nur unter einer festen Client-ID; es ist standardmäßig perfuse-<channel>.

25.20.2 Benutzername

Benutzername und Passwort authentifizieren; einer von beiden kann leer sein.

Das Passwort kann ${ENV} sein.

25.20.3 Passwort

Benutzername und Passwort authentifizieren; einer von beiden kann leer sein.

Das Passwort kann ${ENV} sein.

25.20.4 Zeitüberschreitung

Timeout begrenzt die Verbindung und jedes Warten auf den Broker.

Defaults to 30s.

25.21 NCPDP-Optionen

NCPDPOptionen sind die Einstellungen, die nur für einen Apothekenanspruchskanal gelten.

Definiert als NCPDPOptions in internal/config.

SchlüsselTypErforderlichStandard
transformationsListe von ncpdp.Stepnein—

25.21.1 Transformationen

Transformationen sind deklarative Änderungen, die auf jede Übertragung vor der Zustellung angewendet werden.

Das gleiche Vokabular wie jedes andere Format - Set, Kopie, Löschen, Zuordnen, Ersetzen, Trimmen, Groß-/Kleinschreibung, jeweils mit einer optionalen Bedingung - da die Schritt-Engine in internal/steps generisch ist. Was sich unterscheidet, ist die Notation: ein Pfad wird als D1 oder 07-D7 geschrieben, unter Verwendung der eigenen zwei Zeichen langen Feldkennungen des Standards.

25.22 PGP Empfang

PGPReceive öffnet, was eine Quelle mit OpenPGP erhält: entschlüsselt mit unserem geheimen Schlüssel und dessen Signatur überprüft gegen die öffentlichen Schlüssel der Absender.

Definiert als PGPReceive in internal/config.

SchlüsselTypErforderlichStandard
decrypt_withTextnein—
passphraseTextnein—
verify_withListe von Textnein—
require_signaturewahr oder falschnein—
allow_unencryptedwahr oder falschnein—
pass_plainwahr oder falschnein—

25.22.1 decrypt_with

DecryptWith ist unsere geheime Schlüsseldatei.

Erforderlich, es sei denn, allow_unencrypted ist aktiviert und Nachrichten sind nur signiert.

25.22.2 passphrase

Passphrase entsperrt DecryptWith, wenn es geschützt ist.

Bevorzugt eine Umgebungsvariablen-Referenz, ${NAME}.

25.22.3 verify_with

VerifyWith sind die öffentlichen Schlüsseldateien der Absender.

Eine Signatur von einem von ihnen wird überprüft und aufgezeichnet.

25.22.4 pass_plain

PassPlain lässt eine Nachricht, die überhaupt kein PGP ist, unverändert durch, für einen Ordner, der sowohl verschlüsselte als auch unverschlüsselte Nachrichten erhält.

Aus: eine solche Nachricht wird abgelehnt, sodass ein Absender, der vergessen hat zu verschlüsseln, informiert wird.

25.23 PGP Senden

PGPSend schützt, was ein Ziel mit OpenPGP liefert: verschlüsselt mit dem öffentlichen Schlüssel des Empfängers, signiert mit unserem, oder beides.

Zahler, Clearinghäuser und staatliche Behörden nehmen Dateien oft nur auf diese Weise über SFTP entgegen.

Definiert als PGPSend in internal/config.

SchlüsselTypErforderlichStandard
encrypt_toListe von Textnein—
sign_withTextnein—
passphraseTextnein—
armorwahr oder falschnein—
no_compresswahr oder falschnein—
file_nameTextnein—

25.23.1 encrypt_to

EncryptTo sind die öffentlichen Schlüsseldateien der Empfänger (armored oder binary).

Die Nachricht kann von jedem von ihnen gelesen werden. Leer: Die Nachricht ist nur signiert.

25.23.2 sign_with

SignWith ist unsere geheime Schlüsseldatei, um jede Nachricht zu signieren.

Leer: Nur verschlüsselt.

25.23.3 passphrase

Das Passwort entsperrt SignWith, wenn es geschützt ist.

Bevorzugt eine Umgebungsvariablen-Referenz, ${NAME}.

25.24 Warteschlangenkonfiguration

QueueConfig aktiviert die zuverlässige Warteschlangenverarbeitung für ein Ziel.

Ohne sie verliert ein Ziel, das für zwei Minuten nicht erreichbar ist, alles, was während dieser zwei Minuten gesendet wurde: Wiederholungsversuche erfolgen im Speicher und wenn sie erschöpft sind, wird die Nachricht als fehlgeschlagen aufgezeichnet und ist weg. Mit ihr bleibt die Nachricht auf der Festplatte und behält ihren Platz, bis der Empfänger wieder verfügbar ist.

Sie ist standardmäßig deaktiviert, was eine bewusste Entscheidung und nicht Vorsicht ist. Eine Warteschlange ändert die Bedeutung einer Bestätigung und ändert das Verhalten bei der Sortierung während eines Ausfalls, und beides sind Dinge, die ein Betreiber bewusst akzeptieren sollte, anstatt sie zu entdecken.

Definiert als QueueConfig in internal/config.

SchlüsselTypErforderlichStandard
enabledtrue oder falsenein—
max_attemptsganze Zahlnein—
backoffDauer, wie 30s oder 5mnein—
max_backoffDauer, wie 30s oder 5mnein—
max_depthganze Zahlnein—
retain_hoursganze Zahlnein—

25.24.1 max_versuche

MaxAttempts ist die Anzahl der Versuche, die die Warteschlange unternimmt, bevor eine Nachricht als fehlgeschlagen markiert und zur nächsten übergegangen wird.

Null bedeutet, unendlich oft zu versuchen, was für eine Datenquelle, die nichts verlieren darf, legitim ist, aber bewusst gewählt werden sollte, anstatt geerbt zu werden.

25.24.2 max_backoff

MaxBackoff begrenzt die zunehmende Verzögerung.

Der Standardwert ist eine Minute und nicht etwas Größeres, weil ein Empfänger, der nach einem kurzen Ausfall zurückkehrt, schnell gefunden werden sollte: eine einstündige Obergrenze verwandelt einen zweiminütigen Ausfall in eine einstündige Verzögerung.

25.24.3 max_depth

MaxDepth lehnt neue Nachrichten ab, wenn so viele bereits wartend sind, sodass ein Empfänger, der eine Woche lang nicht erreichbar war, die Festplatte nicht überfluten kann.

Null bedeutet keine Begrenzung.

Wenn die Grenze erreicht ist, wird die Nachricht als fehlgeschlagen aufgezeichnet, anstatt in die Warteschlange gestellt zu werden, und der Absender wird entsprechend informiert — was die ehrliche Antwort ist, weil wir nicht mehr die Lieferung versprechen.

25.24.4 retain_hours

RetainHours ist die Dauer, wie lange bereits gelieferte und aufgegebene Elemente vor dem Löschen aufbewahrt werden.

Sie werden aufbewahrt, damit jemand, der eine Warteschlange beobachtet, die Entleerung sehen kann, und damit eine aufgegebene Nachricht später gefunden werden kann.

25.25 Wiederholung

Wiederholung kontrolliert die erneute Zustellung nach einem Fehler.

Definiert als Retry in internal/config.

SchlüsselTypErforderlichStandard
attemptsganze Zahlnein—
backoffDauer, z. B. 30s oder 5mnein—
max_backoffDauer, z. B. 30s oder 5mnein—

25.25.1 Wiederholungen

Wiederholungen ist die Gesamtzahl der Versuche, einschließlich des ersten.

Null bedeutet den Standardwert.

25.25.2 Backoff

Backoff ist die Wartezeit vor dem zweiten Versuch.

Es verdoppelt sich jedes Mal, bis MaxBackoff erreicht ist.

25.26 Skriptoptionen

ScriptOptions konfiguriert einen NCPDP-SCRIPT-Kanal.

Warum SCRIPT einen Block erhält, wenn sein Filter auf oberster Ebene ist

Der Kanalfilter für jeden Datentyp ist der Filter-Schlüssel auf oberster Ebene, da internal/expr generisch über den Nachrichtentyp ist: ein Schlüssel, der gegen jeden Baum oder Anspruch, den der Kanal trägt, kompiliert wird. Schritte können nicht auf diese Weise angeordnet werden. Ein v2-Schritt adressiert ein Segment und ein Feld, ein X12-Schritt adressiert ein festes Element, und die Typen sind unterschiedlich, so dass ein yaml-Schlüssel entweder das Feld halten müsste, das der Datentyp impliziert - was ein Feld ist, das je nach einem anderen Feld unterschiedliche Bedeutungen hat, und der Fehlermodus ist ein Schritt, der stillschweigend nichts tut.

Dies folgt also hl7v3, x12, ncpdp und delimited: die Schritte leben in dem Block des Formats, und der top-level-Transformations-Schlüssel wird auf einem SCRIPT-Kanal verweigert, anstatt akzeptiert und ignoriert zu werden.

Definiert als ScriptOptions in internal/config.

SchlüsselTypErforderlichStandard
transformationsListe von hl7v3.Schrittennein—

25.26.1 Transformationen

Transformationen sind die deklarativen Schritte, die die Verschreibung als XML-Baum adressieren.

hl7v3.Schritt anstelle eines eigenen Typs, und das ist keine Faulheit. Eine Verschreibung und ein v3-Dokument sind beide XML, die Pfad-Grammatik ist dieselbe, und internal/eprescribe hat bereits hl7v3.Pfad für seinen Filter mit einem Kommentar, der so viel sagt - v3 und CDA verwenden es bereits, und eine dritte Kopie wäre ein dritter Satz von Antworten auf die Frage, was //a/b[2]@c bedeutet.

Die Schritte, die nur v3-Bedeutung tragen, werden bei der Ladezeit verweigert, anstatt stillschweigend verfügbar zu sein. nullflavor ist der eine: es schreibt das v3-Attribut, das angibt, warum ein Wert fehlt, was eine Verschreibung nicht hat, und ein Schritt, der es schreibt, würde ein Dokument erzeugen, das der Empfänger nicht versteht.

25.27 Skripte

Skripte enthält das an einen Kanal angehängte JavaScript.

Definiert als Scripts in internal/config.

SchlüsselTypErforderlichStandard
filterTextnein—
transformerTextnein—
preprocessorTextnein—
deployTextnein—
undeployTextnein—
postprocessorTextnein—
languageTextnein—
timeoutDauer, z. B. 30s oder 5mnein—
includeListe von Textnein—
file_rootsListe von Textnein—
allowListe von Textnein—

25.27.1 Filter

Filter wird nach dem Ausdrucksfilter, falls vorhanden, ausgeführt und muss einen booleschen Wert zurückgeben.

Ein Mirth-Filter-Skript wird hier unverändert eingefügt.

25.27.2 Transformer

Transformer wird nach den deklarativen Schritten ausgeführt und kann die Nachricht modifizieren.

Ein Mirth-Transformer-Skript wird hier unverändert eingefügt.

25.27.3 Präprozessor

Der Präprozessor wird vor der Parsierung der Nachricht ausgeführt, liest den Text als „Nachricht“ und gibt den Text zurück, der zu parsen ist.

Ein Mirth-Präprozessor wird hier unverändert eingefügt.

Dies ist der einzige Ort, an dem eine Nachricht, die nicht geparsed werden kann, repariert werden kann. Sites verwenden es für ein verirrtes Zeichen von einem Seriengateway, ein Segment-Terminator, der als Zeilenabsatz ankam, oder ein Hersteller, der ein Feld mit etwas unzulässigem für seine Position paddet. Ohne es würde Perfuse den Datenverkehr ablehnen, den Mirth heute akzeptiert.

25.27.4 bereitstellen

Bereitstellen wird einmal ausgeführt, wenn der Kanal startet, bevor er etwas akzeptiert.

Dies ist der Ort, an dem Sites einen Lookup-Cache wärmen oder überprüfen, ob etwas, von dem sie abhängig sind, erreichbar ist. Es wird vor dem Binden der Quelle ausgeführt, sodass ein Bereitstellungsskript, das fehlschlägt, den Kanal daran hindert, zu starten, anstatt zuzulassen, dass er Nachrichten akzeptiert, die er nicht bearbeiten kann.

25.27.5 abbrechen

Abbrechen wird einmal ausgeführt, wenn der Kanal stoppt.

Nachdem die Quelle aufgehört hat, Nachrichten anzunehmen, und nachdem die in der Luft befindlichen Nachrichten fertiggestellt wurden, sodass es einen Kanal sieht, der wirklich inaktiv ist. Sein Versagen kann einen Stopp nicht verhindern: Ein Kanal, der nicht heruntergefahren werden könnte, weil ein Bereinigungsskript eine Ausnahme ausgelöst hat, wäre schlimmer als einer, der protokolliert und geschlossen wird.

25.27.6 Postprozessor

Der Postprozessor wird nach der Bearbeitung der Nachricht ausgeführt und kann sie nicht ändern.

Die Nachricht und das, was mit ihr passiert ist, sind sichtbar, sodass es benachrichtigen, zählen oder aufzeichnen kann. Es kann nicht ändern, was gesendet wurde: Zu dem Zeitpunkt, an dem es ausgeführt wird, ist das Senden bereits geschehen, und ein Skript, das so tut, als ob es eine gesendete Nachricht ändert, würde darüber lügen.

25.27.7 Sprache

Die Sprache ist die Skriptsprache, in der diese Skripte geschrieben sind: javascript oder lua.

Warum eine Einstellung für den gesamten Block anstelle von einer pro Skript

Die Skripte eines Kanals teilen sich die Kanalkarte und die Connector-Karte, und sie werden von demjenigen, der sie wartet, gemeinsam gelesen. Ein Filter in Lua neben einem Transformer in JavaScript würde bedeuten, zwei Sprachen in einer Überprüfung, die den Zustand durch eine Karte teilen, deren Werte in beiden gleichbedeutend sein müssten. Sites, die das wollen, können den Kanal aufteilen.

Warum die Standard-Einstellung javascript ist

Jedes Skript, das vor dieser Einstellung geschrieben wurde, ist JavaScript und sagt nichts über seine Sprache aus. Wenn lua die Standard-Einstellung wäre, würde es alle stillschweigend neu interpretieren; wenn das Feld erforderlich wäre, würde es sie ablehnen. Beides ist für eine Einstellung, die später hinzugefügt wurde, nicht akzeptabel.

25.27.8 Zeitüberschreitung

Die Zeitüberschreitung begrenzt jedes Skript.

Null bedeutet fünf Sekunden.

Es gibt absichtlich keine Möglichkeit, es zu deaktivieren. Mirth ermöglicht es einem Transformer, endlos zu schleifen, was den Kanal stoppt, und eine Schnittstelle, die aufgrund eines Tippfehlers keine Aufnahmen mehr akzeptiert, ist keine Option, die angeboten werden sollte.

25.27.9 einbeziehen

Einbeziehen benennt Dateien mit gemeinsamer Skriptquelle, die für jedes Skript auf diesem Kanal in der Sprache verfügbar gemacht werden, die Skripte.Sprache angibt.

Dies ist Mirths Code-Vorlagen. Ein Site mit vierzig Kanälen hat normalerweise eine Bibliothek, die jeder Kanal aufruft, und ohne sie würde eine Migration bedeuten, diese Bibliothek in vierzig Dateien zu kopieren - vierzig Orte, an denen der nächste Änderung zu korrigieren ist.

Pfade sind relativ zur Kanaldatei, sodass eine Bibliothek neben den Kanälen mit ihnen reist. Es handelt sich um eine Liste, da die Alternative eine enorme Datei wäre und Bibliotheken tendenziell nach Thema getrennt werden.

Die Dateien müssen in der Sprache des Kanals sein. Dies war zunächst nur JavaScript und nicht aus Verweigerung: Ein Lua-Kanal las die Dateien, verweigerte eine fehlende Datei und dann installierte die Laufzeit keine davon, sodass jeder Aufruf in der Bibliothek mit einem nil-Global fehlgeschlagen ist - genau der Fehler, den die obige Verweigerung vermeiden soll. Beide Sprachen installieren sie jetzt, und eine Bibliothek, die nicht geparst werden kann, wird bei der Ladung unter Nennung der Datei verweigert.

25.27.10 Dateiwurzeln

Dateiwurzeln sind die Verzeichnisse, die FileUtil lesen und schreiben darf.

Erforderlich, wenn "Datei" erlaubt ist. Die Gewährung des Dateizugriffs ohne Nennung der verwendeten Verzeichnisse bedeutete früher, dass das gesamte Dateisystem zugänglich war: Ein Skript konnte die eigene Datenbank von Perfuse lesen, die Passwort-Hashes, das LDAP-Dienstkonto-Passwort und das OIDC-Client-Geheimnis enthält. Die Erstellung eines Kanals benötigt nur die Editor-Rolle, sodass die Eskalation abgeschlossen war, sobald ein Administrator sie gestartet hat.

25.27.11 Erlauben

Erlauben gewährt Fähigkeiten, die einem Skript sonst verweigert würden: "Datei", "Datenbank", "Route".

Mirth gewährt all diese Fähigkeiten jedem Skript; die Anforderung, dass sie benannt werden müssen, bedeutet, dass ein Transformer nicht leise mit dem Lesen des Dateisystems beginnen kann, nachdem er kopiert wurde.

25.28 Schatten

Shadow führt eine Kandidatenversion eines Kanals neben der Live-Version aus und meldet, wo sie sich unterscheiden.

Dies ist die Antwort auf die Frage, die Interface-Arbeit beängstigend macht: Wie wissen Sie, dass eine Änderung sicher ist? Nicht durch das Lesen. Eine Transformation ist ein Programm, das auf Nachrichten operiert, deren Vielfalt niemand katalogisiert hat, und der Fall, der bricht, ist immer der, an den niemand gedacht hat - der Patient mit zwei Identifikatoren, das Ergebnis mit einem leeren Einheitenfeld, das A08, das vor seinem A01 ankommt.

Ein Kanaltest beweist die Fälle, an die jemand gedacht hat. Der Shadow-Modus beweist die Fälle, die tatsächlich ankommen, gegen echten Datenverkehr, bevor die Änderung irgendetwas davon überträgt.

Zwei Eigenschaften machen es sicher, und beide sind strukturell und nicht konfigurierbar:

Definiert als Shadow in internal/config.

SchlüsselTypErforderlichStandard
channelTextja—
sampleZahlnein1
compareListe von Textnein—
ignoreListe von Textnein—
max_differencesganze Zahlnein100
timeoutDauer, wie z. B. 30s oder 5mnein5s

25.28.1 Kanal

Kanal ist der Pfad zur Kandidaten-Kanaldatei.

Eine separate Datei anstelle eines Inline-Blocks, mit Absicht: Der Kandidat soll die Live-Kanaldatei werden, sodass er die zu überprüfende, committete und promotete Artefakt sein sollte, nicht ein Fragment, das extrahiert werden muss.

25.28.2 Stichprobe

Stichprobe ist der Anteil der Nachrichten, die shadowed werden sollen, von 0 bis 1. Standardmäßig 1.

Nur auf einem beschäftigten Feed lohnt es sich, dies zu senken, und es lohnt sich, dies zu verstehen, bevor man es tut: Stichproben reduzieren die Kosten und reduzieren das Vertrauen in genau dem gleichen Verhältnis, und die Nachricht, die den Unterschied gezeigt hätte, ist die ungewöhnliche.

25.28.3 Vergleichen

Vergleichen beschränkt den Vergleich auf diese Feldpfade.

Leere Vergleiche alles.

25.28.4 Ignorieren

Ignoriert Ausschlussfeldpfade beim Vergleich.

In der Praxis notwendig, da ein Kanal, der einen Zeitstempel oder eine Sequenznummer stampft, bei jeder einzelnen Nachricht unterschiedlich ist und einen Differenzierungsgrad von 100 % melden würde, ohne jedoch etwas zu sagen.

25.28.5 max_differences

MaxDifferences begrenzt die Anzahl der unterschiedlichen Nachrichten, die für die Inspektion aufbewahrt werden.

Defaults to 100.

25.28.6 Zeitüberschreitung

Timeout begrenzt einen Schattenlauf.

Defaults to 5s.

Getrennt vom Timeout des Kanals selbst und kürzer. Ein Kandidat mit einem durchgelaufenen Skript darf keine Goroutinen hinter dem Live-Verkehr ansammeln.

25.29 XDS-Code

XDSCode ist ein codierter Wert in den Zieldaten: Code, Codierungsschema (eine OID) und Anzeige.

Definiert als XDSCode in internal/config.

SchlüsselTypErforderlichStandard
codeTextja—
schemeTextja—
displayTextnein—

26 Wie jedes Komponentenwerk funktioniert

Perfuse ist aus kleinen Paketen aufgebaut, von denen jedes eine Aufgabe hat. Dieses Kapitel ist die eigene Beschreibung jeder Komponente, in der sie erläutert, was sie tut und warum sie so aufgebaut ist, direkt aus der Quelle. Wenn eine Entscheidung einen Grund hat, der nicht offensichtlich ist, ist dieser Grund hier und nicht in einer Commit-Nachricht, die niemand finden wird.

26.1 fhir

Paket fhir implementiert FHIR-Ressourcen, Serialisierung und Validierung.

Die Versionsverwaltung ist die erste Designentscheidung, da "FHIR" allein keinen Drahtformat-Standard identifiziert. R5 ist die neueste veröffentlichte Version und der Standard hier. R4 ist das, was die installierte Basis und die US-Regulierung tatsächlich verbrauchen, daher wird es vollständig unterstützt und nicht als veraltet behandelt. R6 ist zum Zeitpunkt des Schreibens im Ballot und wird absichtlich nicht implementiert: Die Auslieferung einer Vermutung über eine unveröffentlichte Spezifikation wäre schlimmer, als sie nicht zu unterstützen.

Das Ressourcenmodell ist R5-geformt. Wo R4 sich unterscheidet, wird der Unterschied bei der Serialisierung angewendet und nicht durch die Aufrechterhaltung von zwei parallelen Satz von Strukturen, was dazu führt, dass ein Codebasis zwei subtil divergierende Definitionen von Patienten hat.

Source: github.com/biodream-llc/perfuse/fhir

26.2 Haupt

Der Befehl xmlordergen schreibt die Elementreihenfolge, die FHIR-XML benötigt, aus einem Core-Paket heraus, aus dessen StructureDefinitions.

go run ./fhir/xmlordergen hl7.fhir.r4.core-4.0.1.tgz | gzip -9 -n > fhir/xmlorder_r4.txt.gz

JSON-Objekte können ihre Mitglieder in beliebiger Reihenfolge enthalten; XML nicht: Jedes Element muss in der Reihenfolge erscheinen, die seine Definition auflistet. Jede Ausgabezeile ist ein Pfad und seine Kinder in dieser Reihenfolge, jedes Kind mit der Information, wie seine eigenen Kinder gefunden werden können: "@Pfad" (ein Element, das inline definiert ist, ein Rückgrat), "#Pfad" (derselbe wie ein anderes Element) oder seine Typen.

Source: github.com/biodream-llc/perfuse/fhir/xmlordergen

26.3 hl7

Paket hl7 liest HL7-Version-2-Nachrichten.

Es hat keine Abhängigkeiten außerhalb der Standardbibliothek und ein Test erzwingt dies. Es führt keine Netzwerk-E/A aus, schreibt keine Dateien und startet keine Goroutinen, daher ist es sicher, es von überall aus zu verwenden.

Reading a message

msg, err := hl7.Parse(raw) if err != nil { return err } mrn := msg.MustGet("PID-3.1") name := msg.MustGet("PID-5.1") msgType, event, _ := msg.Type() // "ADT", "A01"

Pfade sind die Notation, die die Leute bereits verwenden, wenn sie über HL7 sprechen: Segment, Feld, dann optionaler Komponente und Subkomponente, wie in PID-5.1 oder OBX-5.2.3. Wiederholungen werden mit eckigen Klammern angesprochen, wie in PID-3[2].1.

Get gibt einen Fehler zurück für einen Pfad, den es nicht parsen kann; MustGet gibt stattdessen den leeren String zurück. Beide sind sicher bei fehlenden Segmenten und Feldern, da ein echter Feed voll davon ist und ein Parser, der bei fehlenden Daten panikt, für die Aufgabe nutzlos ist. Abwesenheit ist kein Fehler — eine Nachricht, die einfach kein PID-8 enthält, ergibt "" anstelle eines Fehlers.

Abwesend und leer

HL7 unterscheidet ein Feld, das nicht gesendet wurde, von einem, das absichtlich leer gesendet wurde, und klinisch können diese unterschiedliche Bedeutungen haben - "keine Allergien aufgezeichnet" ist nicht "keine bekannten Allergien". Value.Exists berichtet den Unterschied, wo Anrufer ihn benötigen, während String beide auf "" für den häufigen Fall flacht.

Kopieren und der eine Weg, dies falsch zu machen

Parse kopiert seine Eingabe, sodass die zurückgegebene Nachricht gültig bleibt, egal wie der Aufrufer seinen Puffer wiederverwendet. Das kostet etwa 3% und eine Zuweisung pro Nachricht.

WithZeroCopy überspringt die Kopie und behält einen Verweis auf den Slice des Aufrufers. Es ist schneller und macht die Nachricht unsicher zum Verwenden, nachdem der Slice erneut geschrieben wurde. Das Lesen in einen wiederverwendeten Puffer ist die normale, effiziente Methode, um von einem Netzwerk in Go zu lesen, sodass die Falle sorgfältigen Code fängt und das Symptom stillschweigend falsche Feldwerte anstelle eines Fehlers ist - die Daten eines Patienten unter dem Namen eines anderen Patienten. Verwenden Sie es für Eingaben, die unveränderlich sind oder die Nachricht überleben, und nicht anders.

Acknowledgements

AckFor erstellt ein ACK oder NAK für eine Nachricht, einschließlich für eine, die nicht parse werden konnte, was der Fall ist, der am meisten zählt: ein Absender benötigt eine Antwort, auch wenn das, was er gesendet hat, keine Nachricht war. Siehe AckOptions.

Was dieses Paket nicht tut

Es schreibt oder modifiziert keine Nachrichten. Es hat keine Vorstellung von Nachrichtenstruktur jenseits von Segmenten, sodass es Ihnen nicht sagen kann, dass ein PV1 zu einer bestimmten Besuchsgruppe gehört. Es validiert nicht gegen die Tabellen einer Version. Diese sind bewusste Auslassungen und keine Übersehen: dies ist ein Indexer für echten Datenverkehr, der häufig nicht standardkonform ist und dennoch geroutet werden muss.

Source: github.com/biodream-llc/perfuse/hl7

26.4 aufnehmen

Paket aufnehmen begrenzt, wie viel Arbeit auf einmal im Flug ist.

Der Motor spawnert einen Goroutine pro Ziel pro Nachricht. Goroutines sind billig; was sie halten, ist es nicht. Jede ausgehende Lieferung hält einen Socket am entfernten Ende und einen Dateideskriptor hier und hält sie für den gesamten Wiederholungsbudget - mit den Standardwerten, fünf Versuche mit einer Zeitüberschreitung von 30 Sekunden plus 15 Sekunden Verzögerung, also fast drei Minuten. Einige hundert Absender gegen einen Empfänger, der stillgelegt wurde, sind daher einige hundert Deskriptoren, die für Minuten gehalten werden, und der Prozess läuft aus.

Auslaufen ist der Fehler, den es zu verhindern gilt, weil er nicht dort auftritt, wo er passiert. Er tritt als "zu viele offene Dateien" an einem völlig anderen Ort auf: die Datenbank kann ihr Journal nicht öffnen, die Schnittstelle hört auf, Annahmen zu akzeptieren, ein Protokoll kann nicht geschrieben werden. Der Motor sieht an drei Stellen gleichzeitig kaputt aus und die Ursache ist ein Partnersystem, das aufgehört hat zu antworten.

Zwei Grenzen und die zweite ist wichtiger als die erste:

Eine Gesamtsumme, damit der Prozess innerhalb seines Deskriptor-Budgets bleibt.

Eine Grenze pro Ziel, damit ein Empfänger die Gesamtsumme nicht verbrauchen kann. Ohne sie kann ein einzelnes hängendes Partner-System alle anderen Kanäle lahmlegen, was schlimmer ist als gar keine Grenze zu haben: der Radius der Zerstörung wächst von einem Interface zu allen.

Source: github.com/biodream-llc/perfuse/internal/admit

26.5 Warnungen

Paket Warnungen überwacht die Metriken und sagt, wenn etwas falsch ist.

Der Punkt ist, dass niemand auf das Dashboard schauen sollte. "Transaktionen bleiben in der Warteschlange, ohne dass jemand sie rechtzeitig untersucht" ist ein dokumentierter betrieblicher Fehler in dieser Klasse von Software, und der Grund ist immer derselbe: die Information war auf einem Bildschirm, den niemand um vier Uhr morgens ansah.

Drei Entscheidungen prägen es.

Eine Warnung muss sich selbst löschen. Eine Benachrichtigung, die ausgelöst wird und nie aufgelöst wird, trainiert die Leute, Benachrichtigungen zu ignorieren. Jede Regel hier wird gegen den aktuellen Zustand ausgewertet, sodass ein Empfänger, der zurückkehrt, die Warnung schließt, die er geöffnet hat.

Warnungen werden durch Dauer und nicht durch Zählung abgefedert. "Fehlerquote über 5% gerade jetzt" wird bei einer einzigen unglücklichen Nachricht während einer stillen Stunde ausgelöst. "Über 5% für zwei Minuten" wird nicht. Jede Regel trägt eine Dauer und nichts wird ausgelöst, bis die Bedingung so lange bestanden hat.

Was gesendet wird, enthält keine Patientendaten. Eine Warnung enthält einen Kanalnamen, einen Zielnamen, eine Zahl und einen Schwellenwert. Diese stammen aus der Konfiguration und der Zählung. Ein Webhook geht in einen Chat-Raum, ein Chat-Raum hat einen Scrollback und ein Scrollback ist nicht der Ort, an dem ein Patientenidentifikator landen sollte.

Source: github.com/biodream-llc/perfuse/internal/alerts

26.6 amqp

Paket amqp ist ein AMQP 1.0-Client: eine Verbindung, eine Sitzung, sendende und empfangende Links, abgeschlossen, nachdem der Empfänger es sagt.

AMQP 1.0 ist das, was Azure Service Bus und Event Hubs sprechen, was RabbitMQ 4 nativ spricht und was ActiveMQ und Artemis neben STOMP sprechen. Hier geschrieben aus demselben Grund wie der STOMP-Client und der AWS-Signer: eine vollständige Client-Bibliothek wäre der größte Teil der Abhängigkeitsliste für vier Performatives, die wichtig sind.

Was es tut: SASL PLAIN oder ANONYMOUS (Service Bus nimmt einen gemeinsamen Zugriffsschlüsselnamen und -schlüssel als PLAIN), TLS, öffnen/anfangen/anhängen, kreditbasierte Flusssteuerung, eine Übertragung, die in Frames aufgeteilt wird, wenn sie die maximale Framesize des Peers überschreitet, und Dispositionen - akzeptiert, freigegeben, abgelehnt. Der Absender wartet auf die Disposition des Brokers, bevor er den Erfolg meldet, sodass "gesendet" bedeutet, dass der Broker die Verwahrung übernommen hat. Leere Frames halten die Verbindung innerhalb der Leerlaufzeit des Peers am Leben, die Service Bus durchsetzt.

Was es nicht tut: Transaktionen, mehrere Sitzungen, Link-Wiederherstellung und Nachrichtenannotationen jenseits des Lesens.

Source: github.com/biodream-llc/perfuse/internal/amqp

26.7 analysieren

Das Paket analyze wandelt einen analysierten Mirth-Kanal in etwas um, das ein Mensch bearbeiten kann: eine einfache Beschreibung dessen, was der Kanal tut, und eine ehrliche Liste dessen, was nicht überleben wird, wenn es migriert wird.

Die Designregel hier ist, dass ein Ergebnis spezifisch genug sein muss, um darauf zu reagieren. "Dieser Kanal verwendet JavaScript" ist kein Ergebnis. "Destination 1 ruft java.util.Date auf, das außerhalb der JVM keine Entsprechung hat" ist es schon.

Source: github.com/biodream-llc/perfuse/internal/analyze

26.8 api

Das Paket api dient der HTTP-Schnittstelle, die von der Web-Oberfläche verwendet wird.

Die wichtige Designbeschränkung: Kanäle werden aus Dateien auf der Festplatte gelesen und geschrieben. Die API ist ein Editor für diese Dateien, nicht ein anderes Speichersystem, das zufällig YAML exportiert. Ein Kanal, der im Browser erstellt wurde, und einer, der von Hand geschrieben wurde, sind dasselbe Artefakt, was es ermöglicht, dass "Exportieren zum Teilen" trivial ist und git als Historie der Aufzeichnungen beibehält.

Source: github.com/biodream-llc/perfuse/internal/api

26.9 as2

Das Paket as2 ist Applicability Statement 2 (RFC 4130): EDI über HTTP, signiert und verschlüsselt mit S/MIME, mit einer signierten Quittung (einer MDN), die einen Digest des Eingangs nennt.

Payers und Handelspartner verwenden es für X12 und EDIFACT.

Das S/MIME ist internal/cms, derselbe Code, den Direct Messaging verwendet. Was hier ist, ist AS2-eigen: seine Header, die Nachrichtenintegritätsprüfung (MIC) und die Quittung.

Source: github.com/biodream-llc/perfuse/internal/as2

26.10 attach

Das Paket attach verschiebt große Payloads aus einer Nachricht und setzt sie wieder ein.

Eine HL7-Nachricht, die einen gescannten Bericht oder ein PDF enthält, ist in Dokumentenworkflows gewöhnlich, und der Payload ist routinemäßig hundertmal größer als die Nachricht selbst. Das Speichern davon inline bedeutet, dass der Nachrichtenspeicher mit der Rate der Dokumente und nicht mit dem Traffics wächst, eine Nachricht, die für fünf Ziele wartet, wird fünfmal kopiert, und die Schnittstelle muss Megabytes streamen, um jemandem einen Patientennamen zu zeigen.

Der Payload wird also extrahiert, einmal nach Inhalt gespeichert und durch ein Token in der Nachricht ersetzt. Mirth nennt diese Anhang-Handler, und es ist ein dokumentiertes Migrationsfeature, was der Grund ist, warum das Tokenformat hier so gestaltet ist, dass es erkennbar ist, anstatt clever zu sein.

Was dieses Paket nicht entscheidet

Es führt kein Speichern und keine E/A durch. Die Extraktion produziert die umgeschriebene Nachricht und die Payloads; ein Speicher irgendwo anders entscheidet, wohin diese gehen. Diese Trennung ist es, was die Extraktion testbar macht, ohne eine Datenbank, und es ist auch das, was es ermöglicht, dass dieselbe Logik im WASM-Playground läuft, wo es keine Datenbank gibt.

Source: github.com/biodream-llc/perfuse/internal/attach

26.11 authlimit

Das Paket authlimit drosselt fehlgeschlagene Authentifizierungsversuche nach Quelladresse.

Es existiert, weil zwei Listener dasselbe benötigten und einer von ihnen nichts hatte. Der FHIR-Server bekam einen Limiter, als er Authentifizierung bekam; der Console-Login hatte keinen überhaupt, und eine Messung zeigte zwanzig Passworterrate pro Sekunde an, die gegen das Administrator-Konto gerichtet waren, ohne Verzögerung und ohne Sperre. Bei dieser Rate ist ein schwaches Passwort über Nacht verschwunden, und die einzige Spur ist ein Log voller identischer Warnungen.

Absichtlich kein allgemeiner Rate-Limiter. Es drosselt Fehlschläge, nicht Anfragen: ein beschäftigter legitimer Client ist nie betroffen, und das Einzige, was sich ansammelt, ist Falschheit.

Source: github.com/biodream-llc/perfuse/internal/authlimit

26.12 awsmsg

Das Paket awsmsg spricht mit Amazon SQS und SNS mit der Standardbibliothek und dem gemeinsam genutzten Signature Version 4-Unterschreiber.

Das gleiche Argument wie s3put: Die AWS-SDK würde die Größe der Stückliste um das Vierfache vergrößern, für vier API-Aufrufe. SQS verwendet sein JSON-Protokoll (AWS JSON 1.0, X-Amz-Target AmazonSQS.<Action>), das AWS als aktuelles dokumentiert; SNS verwendet sein Abfrageprotokoll, das das einzige ist, das es hat. Beide funktionieren gegen LocalStack- und VPC-Endpunkte über einen Endpunkt-Überschreibungsmechanismus.

Source: github.com/biodream-llc/perfuse/internal/awsmsg

26.13 awsv4

Das Paket awsv4 signiert Anfragen an AWS mit Signature Version 4, unter Verwendung nur der Standardbibliothek.

Es begann innerhalb von s3put. SQS, SNS und das Lesen aus S3 benötigen die gleiche Signatur mit einem anderen Dienstnamen und mit einer Abfragezeichenfolge, und eine zweite Kopie des Signiercodes wäre ein zweiter Ort für den einen Fehler, der zählt - eine Signaturübereinstimmung liest genau wie falsche Anmeldeinformationen. Es lebt also hier, überprüft gegen AWS-veröffentlichte Testvektoren, und jeder AWS-Connector verwendet es.

Zugangsdaten sind statische Schlüssel oder Standard-Umweltvariablen. Es gibt absichtlich keine Instanz-Metadaten-Zugangsdaten-Kette: das bedeutet IMDS-Aufrufe, Zwischenspeicherung und Aktualisierung, was der Punkt ist, an dem eine kleine Implementierung aufhört, klein zu sein, und Perfuse verweigert Metadaten-Adressen als Ziele standardmäßig.

Source: github.com/biodream-llc/perfuse/internal/awsv4

26.14 azblob

Paket azblob liest und schreibt Azure Blob Storage mit der Standardbibliothek: Shared Key- oder SAS-Autorisierung über einfache HTTP-Aufrufe.

Die gleiche Argumentation wie bei s3put: das Azure-SDK ist groß und die Operationen, die ein Integrations-Engine benötigt, sind fünf - put, get, list, delete und Festlegung der Zugriffsebene. Shared Key-Signierung ist genau spezifiziert ("Authorize with Shared Key", Azure Storage REST), und Azurite, Microsofts Emulator, überprüft es auf die gleiche Weise wie der Dienst.

Source: github.com/biodream-llc/perfuse/internal/azblob

26.15 Markenidentität

Paket Markenidentität speichert das Logo und den Produktnamen eines Kunden, damit eine Installation sich als eigenes Produkt präsentieren kann, anstatt als Perfuse.

Warum das Logo kein Einstellung ist

Alles andere, was ein Betreiber ändern kann, ist ein Skalar in der Einstellungsdatei. Ein Logo ist einige hundert Kilobyte Binärdaten, und es dort abzulegen, würde bedeuten, Base64 in einer YAML-Datei zu verwenden, die ein Mensch lesen und von Hand bearbeiten soll. Es lebt neben dieser Datei und nur seine Anwesenheit ist über die Einstellungsfläche sichtbar.

Der Teil, der zählt: ein hochgeladenes Bild ist nicht vertrauenswürdiges Eingabe

Ein Logo wird von einem Administrator hochgeladen und dann an jeden Browser gesendet, der die Konsole lädt, einschließlich der Anmeldeseite, bevor sich jemand authentifiziert hat. Das macht es zum am weitesten verbreiteten Stück Angreifer-lieferter Inhalte im Produkt, also wird es entsprechend behandelt:

Source: github.com/biodream-llc/perfuse/internal/branding

26.16 cda

Paket cda liest klinische Dokumente.

Das Design beginnt damit, wie diese Dokumente tatsächlich transportiert werden, was nicht als Dateien ist. Ein Entlassungsbericht verlässt ein EHR innerhalb einer HL7 v2 MDM^T02-Nachricht, mit dem gesamten Dokument base64-codiert in OBX-5 und beschrieben durch ein TXA-Segment. Das sind Tausende von Nachrichten pro Tag in einem mittelgroßen Krankenhaus, und es ist der Grund, warum dieses Paket neben einem HL7 v2-Parser und nicht in einem Dokumenten-Toolkit sitzt: die v2-Hälfte ist bereits hier, also ist die Pipeline von "eine Nachricht ist angekommen" zu "ein FHIR DocumentReference existiert" kurz.

Drei Dinge sind absichtlich im Umfang und eines ist absichtlich nicht.

Im Umfang: Lesen eines Dokuments und Aussage, was es enthält, in einfachen Begriffen; Überprüfen, dass die menschenlesbare Erzählung und die codierten Einträge übereinstimmen; und Umwandlung in FHIR. Die Erzählungsprüfung ist die ungewöhnliche. Jeder C-CDA-Abschnitt enthält die gleiche Information zweimal, einmal als Text für einen Kliniker und einmal als Codes für eine Maschine, und sie sollen übereinstimmen. In der Praxis stimmen sie oft nicht überein, und nichts überprüft es - weder die Zertifizierungstooling, noch die Motoren. Wenn der Text sagt, ein Patient sei allergisch gegen Penicillin und der codierte Eintrag sagt etwas anderes, handelt einer der beiden Leser aufgrund der falschen Information. Es ist ein Patientensicherheitsfehler, der mechanisch erkennbar ist, also wird er hier erkannt.

Nicht im Umfang: Erzeugen konformen C-CDA. Das Schreiben eines bedeutet, mehrere hundert Template-Regeln und ein Schematron zu erfüllen, und Dokumente zu produzieren, die zu 95% richtig sind, würden die Zertifizierung auf miserable Weise fehlschlagen. Lesen, Überprüfen und Umwandeln ist der größte Teil des Wertes für einen Bruchteil des Risikos.

Source: github.com/biodream-llc/perfuse/internal/cda

26.17 channeltest

Paket channeltest führt Tests gegen eine Kanaldefinition durch.

Ein Kanal ist ein Programm. Es filtert, schreibt um und leitet klinische Nachrichten um, und es wird unter Druck von Menschen bearbeitet, die es nicht gegen die Produktion testen können. Die Abwesenheit einer Möglichkeit, einen zu testen, ist der größte Grund, warum Schnittstellenarbeit beängstigend ist, und "Ich habe den Transformer geändert und nichts sah anders in der Nachrichten-Browser" ist kein Test.

Die zentrale Entscheidung ist, dass ein Test die Nachricht durch den realen Transformationspfad läuft - den gleichen Filter, die gleichen deklarativen Schritte, den gleichen Skript-Engine, in der gleichen Reihenfolge - mit nur dem Transport ersetzt. Ein Test, der eine Neumimplementierung ausübt, würde bestehen, während der Kanal fehlschlägt, was schlimmer ist, als gar keinen Test zu haben, weil es aktiv täuscht.

Source: github.com/biodream-llc/perfuse/internal/channeltest

26.18 chanscope

Paket chanscope verengt Lese- und Schreiboperationen auf einem Kontext auf einige Kanäle.

Es basiert auf dem Kontext, anstatt ein Parameter jeder Abfrage zu sein, da es Dutzende von Abfragen über den Nachrichtenspeicher und die Lieferwarteschlange gibt und die Begrenzung eine Eigenschaft dessen ist, der fragt, und nicht der Frage. Die API legt sie einmal pro Anfrage für eine Person fest, die auf einige Kanalgruppen beschränkt ist; jede Zählung, Liste, Grafik, Suche und Warteschlangenaktion stimmt dann mit den anderen überein, so dass niemand eine Gesamtzahl von vierzig Fehlern mitgeteilt wird und vier angezeigt werden.

Source: github.com/biodream-llc/perfuse/internal/chanscope

26.19 Cluster

Das Paket Cluster ermöglicht es mehreren Perfuse-Servern, einen gemeinsamen PostgreSQL-Speicher zu verwenden und zu entscheiden, welcher was ausführt.

Das Problem, das es löst

Ein Server ist ein einzelner Fehlerpunkt: wenn er stoppt, stoppt jede Schnittstelle. Zwei Server auf einer Datenbank lösen dies nur, wenn sie nie den gleichen Kanal ausführen, da zwei MLLP-Listener auf einem Feed abwechselnd mit dem Absender kommunizieren, zwei Warteschlangenarbeiter die gleiche Nachricht zweimal liefern und zwei DICOM-Poller jeweils die gleiche Studie melden.

How

Eine Lizenz ist eine Zeile, die angibt, wer etwas hält, mit einem Zähler, den der Halter bei jeder Verlängerung bewegt, alle paar Sekunden. Keine Uhr wird mit einer anderen verglichen: ein Halter, der die Lizenz nicht verlängern kann (abgestürzt, vom Datenbankzugriff abgeschnitten), stoppt, was die Lizenz abdeckt, sobald seine eigene Uhr anzeigt, dass die Lizenz fast abgelaufen ist, und ein anderer Server übernimmt sie nur, nachdem seine eigene Uhr den Zähler stillstehen gesehen hat, für die gesamte Lizenz. Jeder misst ein Intervall auf seiner eigenen Uhr, so dass die Uhren der Server und der Datenbank nicht übereinstimmen müssen; sie müssen nur etwa mit der gleichen Rate laufen. Eine Uhr, die springt (eine virtuelle Maschine, die synchronisiert, ein Administrator, der die Zeit einstellt), ändert nichts: die erste Version verwendete die Datenbankuhr für das Ablaufdatum, und ein Test fand eine Datenbank, deren Uhr dreizehn Sekunden sprang und jede Lizenz an einen neuen Server übergab, während die alten noch liefen.

Zwischen dem Stoppen des Halters und dem Starten des nächsten gibt es eine kurze Lücke, in der niemand läuft, was einem Absender ein paar Sekunden verweigerter Verbindungen kostet und nie einen Moment mit zwei.

Two modes:

Jede Lizenz enthält eine Epoche, die gezählt wird, wenn der Halter wechselt, die eine Halterung in der Geschichte benennt.

Source: github.com/biodream-llc/perfuse/internal/cluster

26.20 cms

Das Paket cms ist die Cryptographic Message Syntax (RFC 5652) wie S/MIME und Direct Secure Messaging es verwenden: SignedData (eine Nachricht signieren, eine überprüfen und sagen, wer sie signiert hat) und EnvelopedData (eine Nachricht für die Zertifikate der Empfänger verschlüsseln, eine mit unserem Schlüssel entschlüsseln).

Nur das, was die Direct Applicability Statement und ihr Implementation Guide erfordern: RSA mit SHA-256 (SHA-1 wird für das Lesen akzeptiert, da ältere HISPs es noch senden), RSA-Schlüsseltransport mit PKCS#1 v1.5 oder OAEP und AES-128 oder AES-256 im CBC-Modus. Die Kryptographie ist die Standardbibliothek; dieses Paket ist die ASN.1 um sie herum.

Source: github.com/biodream-llc/perfuse/internal/cms

26.21 cms0057

Das Paket cms0057 enthält die zahlungspflichtigen Teile der CMS-Interoperabilitäts- und Vorabgenehmigungsendregel (CMS-0057-F), die sich auf Daten und nicht auf den Transport beziehen: abgerechnete Ansprüche als CARIN Blue Button ExplanationOfBenefit-Ressourcen, Vorabgenehmigungen als Da Vinci PDex ExplanationOfBenefit-Ressourcen, HRex-Mitgliedermatching für die Payer-to-Payer-API, die Mitgliederliste hinter der Provider Access API und die Vorabgenehmigungsmetriken, die ein Zahlungspflichtiger jedes Jahr veröffentlichen muss.

Die FHIR-Endpunkte, die diese bereitstellen, befinden sich in fhirserver; dieses Paket entscheidet, was in ihnen enthalten ist.

Medikamente sind außerhalb des Rahmens, da sie in den Vorabgenehmigungsbestimmungen der Regel nicht enthalten sind: keine Apotheken-ExplanationOfBenefit, keine Formulare, keine NCPDP.

Source: github.com/biodream-llc/perfuse/internal/cms0057

26.22 codeset

Das Paket codeset enthält Zuordnungstabellen, die den Kanal, der sie zuerst benötigte, überleben.

Die Domänensteuer ist größtenteils die erneute Ableitung einer Zuordnung, die jemand bereits abgeleitet hat. Die Geschlechtscodes, Patientenklassen, Bestellstatus und Einrichtungsidentifikatoren einer Website werden auf die gleiche Weise in jedem Kanal übersetzt, der sie berührt, und heute ist jede dieser Übersetzungen eine separate Tabelle innerhalb eines separaten Kanals. Vierzig Kanäle bedeuten vierzig Kopien und vierzig Orte, an denen die nächste Änderung des Empfangssystems korrigiert werden muss.

Also wird eine Tabelle zu einem benannten Objekt, auf das durch den Namen verwiesen wird. So viel ist offensichtlich und es ist die kleinere Hälfte des Wertes.

Die Hälfte, die niemand baut

Die größere Hälfte ist die Herkunft. Das meiste, was eine Schnittstelle schwer zu warten macht, ist nicht die Zuordnung - es ist, dass niemand weiß *warum*. "Wir entfernen führende Nullen, weil die Labor-MRN-Spalte numerisch ist" ist Wissen, das in einem Menschenkopf existiert und das Gebäude verlässt, wenn er in den Ruhestand geht, und die verbleibende Zuordnung wird zu etwas, das niemand zu ändern oder zu löschen wagt.

Also wird jede Tabelle aufzeichnen, wer entschieden hat und wann, und jeder Eintrag kann seinen eigenen Grund aufzeichnen, und beides überlebt in die Datei, die in die Versionskontrolle einfließt. Eine Zuordnung mit einem Grund kann argumentiert werden. Eine Zuordnung ohne einen wird zu Aberglauben.

Warum die Datei getrennt von dem Kanal ist

Weil es gemeinsam genutzt wird. Eine Tabelle innerhalb eines Kanals ist nur für diesen Kanal zugänglich, was das Problem darstellt. Eine gemeinsam genutzte Tabelle benötigt ihre eigene Historie: "Wer hat die Geschlechtszuordnung geändert und wann" ist eine Frage zur Tabelle und nicht zum Kanal, der an diesem Tag bearbeitet wurde.

Source: github.com/biodream-llc/perfuse/internal/codeset

26.23 Konformität

Das Paket Konformität implementiert den CMS-ADT-Ereignisbenachrichtigungs-Workflow, der seit Mai 2021 gemäß 42 CFR 482.24(d) erforderlich ist.

Krankenhäuser müssen elektronisch die etablierten Anbieter eines Patienten - Hausärzte, Fachärzte, post-akute Pflegeeinrichtungen - benachrichtigen, wenn der Patient aufgenommen, entlassen oder überwiesen wird. Die Regelung existiert, weil Patienten während des Übergangs durch die Lücken fallen: Ein Hausarzt, der nicht über eine Entlassung informiert ist, kann den Folgetermin nicht planen, der eine erneute Aufnahme verhindert.

Dieses Paket bietet die notwendigen Mittel, um: - zu verfolgen, welche Anbieter für jeden Patienten etabliert sind. - ADT-Ereignisse an die richtigen Anbieter mit der richtigen Priorität zu leiten. - jede gesendete Benachrichtigung mit Zustellstatus für CMS-Prüfer aufzuzeichnen. - Konformitätsberichte zu generieren, die die Benachrichtigungsrate und -fehler anzeigen.

Thread-Sicherheit ist überall erforderlich, da ADT-Nachrichten gleichzeitig aus mehreren Kanälen eintreffen und die Benachrichtigungspipeline parallel läuft.

Source: github.com/biodream-llc/perfuse/internal/compliance

26.24 Konfiguration

Das Paket Konfiguration lädt Kanaldefinitionen aus Dateien.

Die Konfiguration befindet sich in Dateien und nicht in einer Datenbank, was der Hauptunterschied zwischen Perfuse und Mirth ist. Mirth speichert Kanäle in seiner eigenen Datenbank, was der Grund dafür ist, dass Versionierung ein separates Produkt ist, warum die Beförderung eines Kanals von Test auf Produktiv schwierig ist und warum niemand beantworten kann, "was sich letzten Dienstag geändert hat", ohne einen Supportanruf zu tätigen. Dateien bieten Git, Diffs, Überprüfung, CI und Umgebungswechsel ohne zusätzliche Maschinerie.

Die Validierung ist absichtlich streng und erfolgt beim Laden: Unbekannte Felder sind ein Fehler, Filterausdrücke werden kompiliert, Adressen werden überprüft. Ein Kanal, der nicht verstanden werden kann, muss sich weigern zu starten, anstatt auf eine Weise zu laufen, die niemand beabsichtigt hat.

Source: github.com/biodream-llc/perfuse/internal/config

26.25 Vertrag

Das Paket Vertrag wandelt das Aussehen eines Feeds in das, was ein Feed aussehen muss.

Ein Profil beantwortet "was ich empfange". Das ist nützlich, einmal. Das teure Problem ist der Tag, an dem es sich ändert: Ein Hersteller-Upgrade entfernt ein Feld, ein neuer Code erscheint, ein Segment beginnt zu wiederholen. Keines davon ist ein Fehler - die Nachrichten sind immer noch gültig HL7 und jeder Motor der Welt akzeptiert sie - also bemerkt niemand etwas, bis ein Empfänger zusammenbricht, normalerweise Wochen später, und die Untersuchung von der falschen Seite beginnt.

Ein Vertrag ist das Profil, das als Erwartung niedergeschrieben und dann überprüft wird. Es handelt sich um Vertragstests, die eine gelöste Idee in der Software allgemein sind und fast völlig in der Gesundheitsintegration fehlen.

Warum die Einheit eine Rate und keine Nachricht ist

Der offensichtliche Entwurf besteht darin, jede Nachricht zu überprüfen und zu beschweren, wenn eine fehlschlägt. Das ergibt ein System, das niemand verwenden kann. Echte Feeds enthalten einen Anteil an wirklich seltsamen Nachrichten - eine Testnachricht vom Hersteller, ein Patient ohne aufgezeichnetes Geschlecht, eine manuelle Eingabe - und das Auslösen von Warnungen für jede davon trainiert die Menschen, die Warnungen zu ignorieren, sodass die Funktion schlimmer als nichts ist, weil sie die Aufmerksamkeit verbraucht hat, die sie benötigt.

Eine Erwartung bezieht sich also auf einen Anteil über einem Fenster: "PID-3 ist in mindestens 99% der Nachrichten aufgefüllt". Eine seltsame Nachricht löst nie aus. Fünf Prozent der Nachrichten, die ihre medizinische Aufzeichnungsnummer verlieren, tun das.

Ein Vertrag beschreibt, was ankommt, nicht was abgeht

Dies ist der Unterschied, den die Leute zuerst falsch verstehen, einschließlich mir, während ich es integrationstestierte. Perfuse speichert die Nachricht, wie sie angekommen ist - das ist absichtlich, weil die gespeicherte Nachricht ein Beweis dafür ist, was ein Absender gesendet hat - also wird ein Vertrag gegen den ankommenden Feed und nicht gegen die Ausgabe der Kanaltransformationen überprüft.

Das ist die richtige Voreinstellung bei weitem: Das, was sich ohne Vorwarnung ändert, ist das sendende System, und der Zweck eines Vertrags ist es, es zu bemerken. Aber es bedeutet, dass eine Erwartung, die über einen zugeordneten Wert geschrieben wird ("nach der Zuordnung sollten nur die Laborcodes übrig bleiben"), sofort und verwirrend fehlschlagen wird, weil die Codes, die sie nennt, nie im zu profilierenden Datenverkehr erscheinen. Alles, was die Ausgabe betrifft, gehört in einen Kanaltest, der die tatsächlichen Transformationen ausführt.

Warum ein Verstoß die Toleranz nennt, die er brach

"PID-3 fehlgeschlagen" sagt jemandem nichts. "PID-3 war in 94,2% der letzten 500 Nachrichten aufgefüllt; der Vertrag erfordert 99%" sagt ihnen, wie schlecht es ist, wie sicher sie sein können und ob es sich lohnt, jemanden zu wecken. Die Zahlen sind die Nachricht.

Source: github.com/biodream-llc/perfuse/internal/contract

26.26 crd

Das Paket crd ist ein Da Vinci Coverage Requirements Discovery-Service (CRD 2.2.1): die Seite des Zahlungspflichtigen der CDS Hooks-Konversation, die einem Kliniker sagt, während die Bestellung noch ein Entwurf ist, ob sie abgedeckt ist, ob sie eine vorherige Genehmigung benötigt und welche Dokumentation der Zahlungspflichtige wünscht.

Die Priorisierungs-API von CMS-0057 ist in der Praxis drei Da Vinci-Leitfäden zusammen: CRD, um zu sagen, was erforderlich ist, DTR, um es zu sammeln, PAS, um es einzureichen. Perfuse hatte PAS. Dies ist der erste der beiden anderen; DTRs $questionnaire-package ist auf dem FHIR-Endpunkt.

Die Abdeckungsentscheidungen stammen aus einer Regeldatei, da sie die Richtlinie des Zahlungspflichtigen sind und sich ohne Software-Veröffentlichungen ändern: Ein Code (oder eine Liste von Codes) und was darauf anwendbar ist - abgedeckt oder nicht, vorherige Genehmigung erforderlich oder nicht, Dokumentation und das DTR-Fragebogen, das es sammelt. Eine Bestellung, die keiner Regel entspricht, wird mit "bedingt" und "nicht bestimmbar" beantwortet, was CRD sagt, zurückzugeben, wenn der Dienst nicht entscheiden kann - nie eine Vermutung, dass es abgedeckt ist.

Antworten folgen der Anleitung: Eine Systemaktion, die jede Bestellung mit der Abdeckungsinformationserweiterung aktualisiert, die die EHR auf der Bestellung speichert und später mit der vorherigen Genehmigung sendet; und eine Karte pro Bestellung, damit ein Kliniker sie sieht.

Source: github.com/biodream-llc/perfuse/internal/crd

26.27 Dashboards

Das Paket Dashboards definiert die Dashboards, die Perfuse für jede Art von Person ausliefert, die es beobachtet, und wie einer Person eines zugewiesen wird: durch ihre Rolle, durch eine Verzeichnisgruppe, die die Dashboards-Datei zuordnet, oder durch die Ansicht, die sie gespeichert hat.

Dashboards bestehen aus Kacheln, und Kacheln zeigen nur Aggregate an - Zahlen, Raten, Zeiten, Zustände. Keine zeigt eine Nachricht, einen Patienten oder einen Identifikator an, sodass ein Dashboard einem Abteilungsleiter zugewiesen oder auf einem Wandbildschirm angezeigt werden kann, ohne die Anzahl der Personen zu erhöhen, die Patientendaten sehen. Eine Kachel, die Daten benötigt, die Perfuse noch nicht aufzeichnet, wird nicht gefälscht: Das Dashboard listet sie unter Geplant auf.

Volle Flexibilität ist Grafanas Aufgabe, nicht die dieses Pakets. Jede Kachel, die einen Metrik hinter sich hat, wird als Grafana-Panel über Perfuses /metrics exportiert, sodass ein Standort, der mehr als leichte Konfiguration möchte, das Dashboard dort übernimmt.

Source: github.com/biodream-llc/perfuse/internal/dashboards

26.28 davinci

Das Paket davinci gibt an, welche Version der Da-Vinci-Vorabgenehmigungsleitfäden (CRD, DTR, PAS) ein Client spricht.

Perfuse antwortet in zwei Versionen: 2.2 (CRD 2.2.1, DTR 2.2.0, PAS 2.2.1), die neueste, und 2.1 (CRD, DTR und PAS 2.1.0), die Version, auf die die empfohlene Liste von CMS-0057-F hinweist, sobald die Basis von US Core 3.1.1 der 2.0.1-Veröffentlichungen abgelaufen ist. Die beiden Versionen unterscheiden sich in den Formen, die ein Client nach Namen liest - DTR-Parameter des $questionnaire-Pakets (PackageBundle in 2.1, packagebundle in 2.2), PAS-Antwort auf $inquire (ein Bundle in 2.1, ein Parametersatz in 2.2), Erweiterungen, die nur in einer von ihnen vorhanden sind - so kann eine Antwort nicht für beide Versionen dienen, und der Server muss wissen, mit welcher Version er spricht.

Es wird angegeben, am spezifischsten zuerst: durch die Anfrage selbst (CRD-davinci-crd.requestedVersion; die Version eines Profils, das die Eingabe beansprucht, Profil|2.1.0), dann durch die Registrierung des Clients (davinci_version in einem SMART- oder CDS-Client), dann durch die eigene Einstellung des Servers (serve -davinci-version), die standardmäßig auf die neueste Version festgelegt ist.

Source: github.com/biodream-llc/perfuse/internal/davinci

26.29 dbtime

Das Paket dbtime formatiert Zeitstempel so, dass das Sortieren von Texten auch das Sortieren von Zeitstempeln bedeutet.

Jeder Speicher in Perfuse speichert Zeitstempel als TEXT in SQLite und verlässt sich auf die Zeichenvergleich für die Sortierung und für Bereichsabfragen: ORDER BY received_at DESC, WHERE expires_at < ?, WHERE at >= ?. Das ist ein vernünftiges Design - es hält eine Datenbank, die jemand mit dem sqlite3-Shell lesen kann - aber es funktioniert nur, wenn die Textform fester Breite ist.

time.RFC3339Nano ist es nicht. Seine Dokumentation sagt, dass es die nachfolgenden Nullen aus dem Sekundenfeld entfernt, sodass dieselbe Uhr Zeichenfolgen unterschiedlicher Länge produziert:

20:56:33.12345Z <- 123450 Mikrosekunden, nachfolgende Null entfernt 20:56:33.123456Z <- 123456 Mikrosekunden

Verglichen als Text, ist die erste *größer*, weil nach dem gemeinsamen Präfix "12345" sie 'Z' hat, wo die zweite '6' hat, und 'Z' über jedem Ziffern sortiert. So sortiert das frühere Ereignis später. Etwa ein benachbartes Paar von zehn ist betroffen, was der Grund ist, warum es als intermittierendes Testversagen präsentiert wurde, anstatt als offensichtlich fehlerhaftes Feature.

Was es tatsächlich brach: Der Audit-Log und der Nachrichtenbrowser ordnen beide nach einem Zeitstempel und können daher Einträge aus der gleichen Sekunde in der falschen Reihenfolge auflisten. Ein Audit-Trail ist ein Compliance-Artefakt und ein Nachrichtenbrowser ist die Möglichkeit, wie jemand rekonstruiert, was passiert ist, sodass in beiden Fällen die Reihenfolge der Punkt ist.

Das Layout unten verwendet .000000000 anstelle von .999999999. Beide drucken Nanosekunden; der Unterschied besteht darin, dass Nullen in der ersten signifikant sind und in der zweiten entfernt werden.

Source: github.com/biodream-llc/perfuse/internal/dbtime

26.30 begrenzt

Das Paket delimited parseert Datensätze, die durch konfigurierte Zeichen getrennt und gespalten sind.

Dies ist Mirths Delimited-Datentyp: CSV, tab-getrennt, pipe-getrennt, feste Spalten-Dateien und der lange Schwanz von Formaten, die ein Laboranalyser oder ein Bürodienst emittiert, weil jemand es 1994 geschrieben hat und es funktioniert.

Bewusst keine allgemeine CSV-Bibliothek. Was hier wichtig ist, ist, was ein Healthcare-Feed tut, was ein wohlgeformtes CSV nicht tut: Eine Header-Zeile, die vorhanden sein kann oder nicht, eine abschließende leere Zeile, die nicht zu einem leeren Datensatz werden darf, Spalten, die nach Namen referenziert werden, sodass eine Transformation nicht bricht, wenn ein Lieferant eine einfügt, und die Fähigkeit, eine ganze Datei als eine Nachricht oder jede Zeile als eigene zu behandeln.

Die letzte davon ist die Entscheidung, die alles andere formt. Eine Datei mit fünftausend Ergebnissen ist entweder eine Nachricht oder fünftausend, und die beiden sind nicht austauschbar: Eine Nachricht bedeutet eine Bestätigung und einen Fehler für die gesamte Datei, und fünftausend bedeutet, dass jede Zeile gefiltert, transformiert und erneut versucht werden kann.

Source: github.com/biodream-llc/perfuse/internal/delimited

26.31 dicom

Das Paket dicom liest DICOM-Datensätze.

DICOM ist, wo Radiologie lebt, und ein Krankenhaus-Integrationstreibwerk, das es nicht sprechen kann, ist von der Bildgebung ausgeschlossen. Mirth hat einen DICOM-Listener und -Sender, sodass dies ein Migrationsblockierer für jeden Standort ist, der Modality-Arbeit durchführt.

Umfang, einfach ausgedrückt

Dieses Paket parseert Datensätze: Die Datei-Metainformationen, die Elemente, die Übertragungssyntax und die Werte, die für die Weiterleitung und Identifizierung wichtig sind. Es decodiert keine Pixel-Daten und wird es auch nie tun, soweit dieses Paket betrifft - ein Integrationstreibwerk bewegt Bilder, es zeigt sie nicht an, und ein Decoder ist ein großer, formatspezifischer Arbeitsbereich, dessen einziger Zweck hier wäre, den Binärcode größer zu machen.

Das Lesen von Metadaten ohne Berührung von Pixeln ist auch das, was es auf dem Verkehr schnell macht, der wichtig ist: Ein Brust-CT ist Hunderte von Megabyte Pixeln hinter zwei Kilobyte der Informationen, auf denen jeder routet.

Warum die Wertdarstellungen explizit behandelt werden

Ein DICOM-Element enthält einen zweibuchstabigen Wert, der angibt, wie sein Wert gelesen werden soll, und die Regeln unterscheiden sich pro VR auf Weise, die nicht erraten werden können: Einige haben eine zweibyte-Länge und einige vier, einige sind mit einem Leerzeichen und einige mit einem Nullwert gepaddet, und numerische Zeichenfolgen können mehrere Werte enthalten, die durch Backslashes getrennt sind. Wenn man einen falsch liest, wird kein Fehler erzeugt, sondern ein plausibel aussehender falscher Wert - ein Patientenname, der aus der Mitte eines Datums gelesen wird, oder ein Studienkennzeichen, das um ein Byte falsch ist.

Source: github.com/biodream-llc/perfuse/internal/dicom

26.32 dicomweb

Das Paket dicomweb spricht DICOMweb (DICOM PS3.18): QIDO-RS zum Suchen, WADO-RS und WADO-URI zum Abrufen, STOW-RS zum Speichern, über HTTP.

Es ist die Art und Weise, wie Viewer, KI-Dienste und Cloud-Archive jetzt Bilder erreichen: OHIF, Google Cloud Healthcare, Azure Health Data Services, AWS HealthImaging, Orthancs und dcm4chees DICOMweb-Schnittstellen. Ein Integrations-Engine, der nur das Netzwerkprotokoll von 1993 spricht (DIMSE: C-STORE, C-FIND), kann ein PACS speisen, aber keinen Browser.

Das Paket besteht aus vier Teilen: Ein Datensatz-Reader, der das gesamte Objekt durchläuft, einschließlich Sequenzen, und weiß, wo die Pixel-Daten sind, ohne sie zu laden; das DICOM-JSON-Modell (PS3.18 F.2); multipart/related, das ist, wie DICOMweb mehrere Objekte in einer Anfrage bewegt; und ein Archiv mit einem Index, das ist, was QIDO und WADO beantworten.

Source: github.com/biodream-llc/perfuse/internal/dicomweb

26.33 direkt

Paket direkt ist Direct-sichere Messaging als Edge-System: Eine Nachricht an eine Direct-Adresse wird mit diesem Adressen-Zertifikat signiert und verschlüsselt für den Empfänger, als S/MIME, und an einen HISP per SMTP gesendet; eine Nachricht, die vom HISP (per SMTP oder über IMAP abgerufen) empfangen wird, wird entschlüsselt und ihre Signatur wird gegen die Trust-Anker überprüft, bevor sie gelesen wird.

Es folgt dem Direct Project Applicability Statement für Secure Health Transport 1.2 und der XDM-Spezifikation (IHE ITI TF-1 Annex 15) für Dokumente mit Metadaten. Es ist kein HISP: Die Akkreditierung des HISP, seine Zertifikatspolitik und sein Verzeichnis bleiben beim HISP.

Source: github.com/biodream-llc/perfuse/internal/direct

26.34 Medikament

Paket Medikament behandelt die Codes und Mengen, die ein Medikament identifizieren.

Aus den Apotheken-Standards, die sie tragen, herausgelöst, weil der gleiche Medikament-Code in einem NCPDP-Anspruch, einem SCRIPT-Rezept, einem HL7-RXE-Segment und einem FHIR-MedicationRequest erscheint, und eine Umwandlung, die in einem dieser Orte lebt, ist eine Umwandlung, die die anderen drei nicht benötigen.

Source: github.com/biodream-llc/perfuse/internal/drug

26.35 dsdr

Paket dsdr signiert und überprüft CDA-Dokumente wie im HL7-Implementierungsleitfaden für CDA Release 2: Digitale Signaturen und Delegation von Rechten, Release 1 (Oktober 2014) beschrieben - den elektronischen Signaturstandard, den HIPAA für Ansprüche-Anhänge in CMS-0053-F, 45 CFR 162.2002(e) annimmt, mit Einhaltung ab dem 26. Mai 2028.

Was der Leitfaden verlangt, und wo es hier gemacht wird:

Wo der Leitfaden schweigt, sind die getroffenen Entscheidungen benannt: Er gibt keinen Namespace für seine eigenen Elemente (digitalSignature, authorizedSigner, SignaturePurpose) an, also werden sie in urn:hl7-org:sdtc platziert; und der Zweck wird auch als XAdES CommitmentTypeIndication mit dem ASTM-OID angegeben, den XAdES-Tools lesen und das eigene Element des Leitfadens nicht.

Delegation von Rechten (ein delegierter Signierer mit einer SAML-Behauptung) wird nicht produziert; eine Signatur, die eine enthält, wird als solche gemeldet.

Source: github.com/biodream-llc/perfuse/internal/dsdr

26.36 e4x

Paket e4x ermöglicht es Mirth Connects JavaScript, unverändert zu laufen.

Mirth-Skripte sind für Rhino geschrieben, das E4X implementiert: XML ist ein natives Typ mit eigener Syntax. Der Engine hier ist goja, der dies nicht tut, und die Lücke ist nicht nur eine Laufzeit-Lücke.

Für jedes (var seg in msg..OBX) { } // für-jedes, und der Nachfahre-Operator var z = <ZZZ><ZZZ.1>Wert</ZZZ.1></ZZZ>; // ein XML-Literal var id = node.@root; // ein Attribut-Verweis

Diese Datei überschreibt diese in gewöhnliches ECMAScript, das goja parsen kann, und überlässt die Semantik dem Laufzeit-Objekt in xml.go. Alles andere über E4X - Eigenschaftszugriff durch Element-Namen, Indexierung von Wiederholungen, Zuweisung, toString - ist bereits gültige JavaScript-Syntax und benötigt keine Überschreibung.

Die Überschreibung wird mit einem echten Lexer und nicht mit regulären Ausdrücken durchgeführt, da die Alternative funktionierende Skripte korrupt.

Source: github.com/biodream-llc/perfuse/internal/e4x

26.37 edifact

Paket edifact liest und schreibt UN/EDIFACT-Interchanges (ISO 9735): Die UNA-Service-String-Empfehlung, die UNB/UNZ-Interchange-Hülle, optional UNG/UNE-Funktionsgruppen und UNH/UNT-Nachrichten, mit dem Freigabezeichen und, für die Syntax-Version 4, dem Wiederholungs-Trenner.

Es überprüft die Zähler und Referenzen des Umschlags, adressiert Daten-elemente für Filter, teilt einen Austausch in eine Nachricht pro Nachricht auf und erstellt eine CONTRL-Bestätigung.

Es liest jeden Nachrichtentyp (ORDERS, INVOIC, IFTSTA, MEDRPT ...); es enthält nicht die Verzeichnisse, die angeben, welche Segmente ein Nachrichtentyp enthalten kann, also überprüft es die Struktur, nicht den Inhalt.

Source: github.com/biodream-llc/perfuse/internal/edifact

26.38 Ausgang

Das Ausgangspaket entscheidet, ob dieser Motor nach außen zu einer Adresse verbinden darf.

Es existiert, weil ein Ziel überall hin zeigen kann und eine Kombination daraus eine Möglichkeit macht, das interne Netzwerk zu lesen: Ein SOAP-Ziel mit einem Antwort-Transformer gibt die Antwort des Empfängers an ein Skript zurück, sodass ein Editor einen Kanal autorisieren kann, der eine interne URL abruft und den Text in ein Protokoll oder eine Nachricht schreibt.

Es wurde demonstriert, anstatt theoretisiert: Ein SOAP-Ziel, das auf einen lokalen HTTP-Server abzielt, hat den Antwort-Text des Servers in eine Kanal-Protokollzeile geschrieben.

Die proportionale Antwort besteht nicht darin, ausgehende Verbindungen zu verbieten - das Zustellen von Nachrichten an konfigurierte Endpunkte ist der gesamte Zweck der Software, und ein Editor soll sie konfigurieren. Es besteht darin, die spezifischen Adressen abzulehnen, die niemals ein Nachrichtenziel sind und immer ein Credential-Speicher sind.

Source: github.com/biodream-llc/perfuse/internal/egress

26.39 Motor

Das Paket Motor führt konfigurierte Kanäle aus.

Ein Kanal ist eine Quelle, ein Filter und eine Menge von Zielen. Die Aufgabe der Laufzeit ist es, ehrlich zu sein, was mit jeder Nachricht passiert ist: Eine Bestätigung sollte bedeuten, was die Konfiguration sagt, eine gefilterte Nachricht sollte von einer, die zugestellt wurde, unterscheidbar sein, und eine Nachricht, die nicht zugestellt werden konnte, darf nicht als akzeptiert gemeldet werden.

Source: github.com/biodream-llc/perfuse/internal/engine

26.40 epa

Das Paket epa ist NCPDP SCRIPT elektronische Vorab-Autorisierung, die Seite des Zahlungspflichtigen: PAInitiationRequest, PARequest, PAAppealRequest und PACancelRequest herein und ihre Antworten heraus.

CMS-0062-P schlägt vor, dass betroffene Zahlungspflichtige es ab dem 1. Oktober 2027 unterstützen, und Medicare Part D erfordert es bereits. Eine Anfrage wird entschieden, wie jede Vorab-Autorisierung auf diesem Server: Sie wird zu einer Da Vinci PAS-Anfrage (ein Claim, die Medikamentenanfrage und die Antworten des Verordners als QuestionnaireResponse) und geht zum gleichen Regeln-Datei, Entscheidungsdienst und Überprüfungs-Queue. Die Formulare sagen, welche Medikamente eine benötigen und welche Fragen zu stellen sind, aus dem gleichen FHIR-Fragebogen, den Da Vinci DTR ausfüllt.

Die Schemas von NCPDP sind lizenziert. Elementnamen und -reihenfolge hier folgen dem öffentlichen Surescripts ePA-Begleitleitfaden und seinen Beispielen; zwei Elemente, die das öffentliche Material nie zeigt (der Grund innerhalb von Closed und innerhalb von Denied), folgen dem SCRIPT-Muster, das anderswo verwendet wird, und sind im Handbuch benannt, sodass ein Zahlungspflichtiger sie gegen seine eigene Kopie des Schemas überprüfen kann.

Source: github.com/biodream-llc/perfuse/internal/epa

26.41 eprescribe

Das Paket eprescribe liest und schreibt NCPDP SCRIPT, den Standard, in dem Rezepte reisen.

Benannt nach dem, was es tut, anstatt nach dem Standard, weil intern/script bereits der JavaScript-Motor ist und zwei Pakete namens script in einem Baum ein Fehler ist, der darauf wartet, in einer Importzeile gemacht zu werden.

SCRIPT ist XML, im Gegensatz zum Telekommunikationsstandard, der den resultierenden Claim trägt. Ein Verordner sendet ein NEWRX an eine Apotheke; die Apotheke sendet zurück RXFILL, um zu sagen, was passiert ist, REFREQ, um eine Wiederholung zu bitten, oder RXCHG, um eine Änderung zu bitten. Jedes davon ist eine Nachricht hier.

Wo die Gefahr ist

Zwei Felder in einer Rezeptur sind gefährlich, wenn sie falsch gelesen werden, anstatt wenn sie fehlen.

Substitutionen sind das erste. Eine Null bedeutet, dass eine Substitution erlaubt ist, und eine Eins bedeutet, dass sie so wie vorgeschrieben abgegeben werden soll. Sie liest rückwärts für jeden, der eine Flagge erwartet, bei der eins ja bedeutet, und es falsch zu machen, dispensen ein Generikum, wo der Verordner die Marke erfordert hat - oder weigert sich, eine Substitution zu akzeptieren, die erlaubt war, was der gleiche Fehler ist, der dem Patienten Geld kostet, anstatt. Also weigert sich dieses Paket, zu raten: Ein fehlendes Substitutions-Element ist ein Fehler und kein Standardwert, weil beide Standardwerte falsch sind.

Die Anzahl der Wiederholungen ist die zweite. Eine Rezeptur der Klasse II darf nicht nachgefüllt werden, und ein System, das eine Wiederholungsanzahl von einem nicht kontrollierten Template übernimmt, produziert eine gültig aussehende Rezeptur, die eine Apotheke ablehnen muss.

Was nicht überprüft wurde

Die Nachrichtenstruktur folgt den veröffentlichten SCRIPT-Elementnamen. Keine Nachricht von diesem Paket wurde durch ein reales Routing-Netzwerk wie Surescripts gesendet, und eine Zertifizierung durch einen ist ein kommerzieller Prozess und kein technischer. Dies analysiert und erstellt das Format; es beansprucht keine Zertifizierung.

Source: github.com/biodream-llc/perfuse/internal/eprescribe

26.42 Äquivalent

Das Paket equiv beweist, dass zwei Motoren übereinstimmen, oder sagt genau aus, wo sie nicht übereinstimmen.

Dies ist die Antwort auf die einzige Frage, die tatsächlich eine Migration blockiert. Ein Interface-Team lehnt einen neuen Motor nicht ab, weil er Funktionen fehlt; sie lehnen ab, weil sie nicht sicher sein können, dass er das gleiche tut, was sie bereits haben, und falsch zu sein bedeutet, dass Laborergebnisse nicht mehr bei den Ärzten ankommen. Kein Vergleich von Funktionen beantwortet das. Beweise tun es.

Der beabsichtigte Einsatz ist ein paralleler Lauf. Beide Motoren erhalten die gleichen Produktionsnachrichten; der etablierte Motor liefert weiter und Perfuse liefert an niemanden, was bereits Schattenkanäle sind. Nach zwei Wochen werden die Ausgaben hier verglichen und das Gespräch ändert sich von „vertraue dem“ zu „hier sind die drei Nachrichten von vierhunderttausend, bei denen wir uns unterschieden haben, und warum“.

Gruppierung ist die gesamte Funktion

Ein naiver Diff von 400.000 Nachrichten produziert 400.000 Ergebnisse und wird ungelesen geschlossen. Fast jeder reale Unterschied hat eine Ursache: ein Datumsformat, einen Einrichtungscode, einen Transformationschritt, den niemand übertragen hat. Daher werden Unterschiede nach Ursache gruppiert - dem Pfad in der Nachricht und der Art des Unterschieds - und einmal mit einer Zählung gemeldet. Drei tausend Unterschiede aus einer Ursache sind ein Ergebnis, nicht drei tausend. Diese einzige Entscheidung ist es, die den Bericht lesbar macht, und ein lesbarer Bericht ist der Unterschied zwischen einer Migration, die fortgesetzt wird, und einer, die ins Stocken gerät.

Werte werden standardmäßig zurückgehalten

Echter Datenverkehr ist Patientendaten, sodass ein Vergleichsbericht ein Ort ist, an dem PHI in ein Ticket, eine E-Mail oder eine Folie einfließen könnte. Standardmäßig berichtet dies über Pfade, Arten und Zählungen - nie Werte. Das reicht aus, um die Ursache zu finden: „MSH-7 unterscheidet sich in 3.000 von 3.000 Nachrichten“ sagt einem Analysten, dass es das Datumsformat ist, ohne ein Datum anzuzeigen.

Werte können absichtlich aktiviert werden, weil letztendlich jemand sie sehen muss, und so zu tun, als ob dies nicht der Fall wäre, würde sie nur zu einem schlechteren Werkzeug drängen. Es ist eine explizite Opt-in und der Bericht sagt auf seiner Oberfläche, dass er Nachrichteninhalte enthält.

Source: github.com/biodream-llc/perfuse/internal/equiv

26.43 expr

Die HL7 v2-Bindung.

Dies ist die Logik, die früher inline in eval.go gelebt hat. Sie ist unverändert in ihrem Verhalten - absichtlich, weil der v2-Filter der ist, den jeder HL7-Kanal ausführt, und der Punkt der generischen Grammatik war, Formate hinzuzufügen, nicht diesen zu ändern.

Source: github.com/biodream-llc/perfuse/internal/expr

26.44 fdlimit

Das Paket fdlimit ermittelt, wie viele Dateideskriptoren dieser Prozess öffnen darf, und erhöht die Grenze, wenn es kann.

Dies existiert wegen der Form des Ausfalls, den es verhindert. Jede eingehende Verbindung ist ein Deskriptor, und auch jede ausgehende Lieferung, die im Flug ist. Ein Empfänger, der aufgehört hat zu antworten, hält einen Deskriptor für den gesamten Wiederholungsbetrag - mit den Standardwerten, fünf Versuche mit einer Zeitüberschreitung von dreißig Sekunden plus fünfzehn Sekunden Verzögerung, also fast drei Minuten. Einige hundert Verbindungen gegen einen hängenden Empfänger sind daher einige hundert Deskriptoren, die für Minuten gehalten werden.

Das Auslaufen produziert keinen ordentlichen Fehler am Ort, an dem es ausgelaufen ist. Es produziert „zu viele offene Dateien“ an einem völlig anderen Ort: die Datenbank kann ihr Journal nicht öffnen, die Web-Oberfläche hört auf, anzunehmen, eine Protokolldatei kann nicht geschrieben werden. Der Motor scheint an drei völlig unabhängigen Stellen gleichzeitig kaputt zu sein, und die tatsächliche Ursache ist ein Partnersystem, das still geworden ist. Dies ist der Support-Anruf, den dieses Paket vermeiden soll.

Zwei Dinge geschehen beim Start. Die weiche Grenze wird auf die harte Grenze erhöht, was normalerweise das Problem direkt beseitigt - die weiche Standardgrenze ist oft einige hundert, während die harte Grenze Zehntausende ist. Dann wird alles, was verfügbar ist, gemeldet, sodass der Motor seine eigene Konkurrenz innerhalb von ihm selbst begrenzen kann, anstatt sie zu entdecken, indem er sie trifft.

Source: github.com/biodream-llc/perfuse/internal/fdlimit

26.45 fhirpath

Das Paket fhirpath bewertet FHIRPath (HL7 FHIRPath N1, 2.0.0) über FHIR-Ressourcen, die als decodierte JSON gehalten werden.

Es hat kein FHIR-Modell: Der Typ eines Elements ist bekannt, wenn FHIR-JSON es sagt (ein Suffix eines Wahl-Elements, wie z. B. valueQuantity, der resourceType einer Ressource) oder aus dem JSON-Wert abgeleitet wird. Das deckt ab, was SQL auf FHIR-Ansichten und CQL-freie Qualitätsmaßnahmen benötigt; Navigation, die vom Modell abhängt (der eigene Typ eines Primitivs, wenn es kein Wahl-Element ist), wird aus der Form des Werts beantwortet.

Source: github.com/biodream-llc/perfuse/internal/fhirpath

26.46 fhirserver

Das Paket fhirserver implementiert einen FHIR-REST-Server.

Dies existiert, weil das nützliche Ende eines v2-zu-FHIR-Mappers ein Ort ist, an den das Ergebnis gelegt werden kann. In der Lage zu sein, eine Nachricht zu konvertieren, ist ein Demo; in der Lage zu sein, sie zu konvertieren, zu speichern und dann den Patienten wieder anhand der Identifikation zu finden, ist ein Produkt.

Es ist ein echter FHIR-Server in den Teilen, die für das wichtig sind: eine Fähigkeitsanzeige, Erstellen, Lesen, Aktualisieren, Löschen, Suchen nach den Parametern, die die Leute tatsächlich verwenden, und transaktionale Bündel, die atomar angewendet werden. Es ist kein vollständiger FHIR-Server - keine Historie, keine verkettete Suche, kein _include - und es sagt das in seiner eigenen Fähigkeitsanzeige, anstatt einem Client die Lücken zu entdecken.

Source: github.com/biodream-llc/perfuse/internal/fhirserver

26.47 formulary

Das Paket formulary ist ein Arzneimittel-Formular eines Zahlenden: welche Medikamente jeder Plan abdeckt, auf welcher Ebene und mit welchen Einschränkungen (vorherige Genehmigung, Stufentherapie, Mengenbegrenzungen) und was der Mitglied zahlt.

Eine Datei ist die einzige Quelle für alles, was eine Frage über ein Medikament beantwortet: die Da Vinci US Drug Formulary API (veröffentlicht als FHIR), NCPDP Real-Time Prescription Benefit-Antworten und NCPDP SCRIPT-Elektronische Vorabgenehmigung (ob ein Medikament eine Genehmigung benötigt und welche Fragen gestellt werden). Ein Formular, das an drei Orten gespeichert ist, würde die gleiche Frage auf drei Arten beantworten.

Source: github.com/biodream-llc/perfuse/internal/formulary

26.48 rahmung

Paketrahmen liest und schreibt Nachrichten in einem Byte-Stream, der nicht MLLP ist.

Warum dies separat von mllp existiert

MLLP ist ein Rahmenvorgabe: 0x0B vorher, 0x1C 0x0D danach. Es ist das, was HL7 v2 über TCP verwendet und Perfuse hat es immer gesprochen.

Eine große Menge an Geräten tut dies nicht. Ein Laboranalyser, eine Waage, ein Bettmonitor, ein älteres Abrechnungssystem - jedes neigt dazu, seine eigene Konvention zu haben, und die Konventionen sind alle einfache Variationen der gleichen drei Ideen: ein Trennzeichen irgendwo, eine feste Rekordlänge oder eine Länge, die vor der Nutzlast geschrieben wird.

Mirths TCP-Connector deckt dies ab und Perfuse hatte nichts, also konnte ein Standort mit einer Socket-Feed, die nicht HL7 war, es überhaupt nicht verwenden.

Der Fehler, den dieses Paket vermeiden soll

Das Lesen aus einem Stream und das Raten, wo eine Nachricht endet, ist das ganze Problem. Wenn man zu kurz ratet, wird eine Nachricht halbiert; wenn man zu lang ratet, kommen zwei Nachrichten als eine. Beides produziert Ausgaben, die oft plausibel aussehen, was schlimmer ist als ein Fehler, also ist jeder Modus hier explizit darüber, was eine Nachricht beendet, und keiner fällt auf einen anderen zurück.

Eine Nachricht ohne Rahmenvorgabe ist eine legitime Konfiguration - einige Geräte öffnen eine Verbindung, senden eine Nachricht und schließen - aber sie kann nicht mit etwas anderem kombiniert werden und kann nicht auf einer Verbindung verwendet werden, die offen bleibt, also wird sie benannt und validiert, anstatt als Standard behandelt zu werden.

Source: github.com/biodream-llc/perfuse/internal/framing

26.49 ftpconn

Paket ftpconn lädt Dateien über FTP und FTPS mit nur der Standardbibliothek hoch.

FTP ist alt, gesprächig und kein gutes Protokoll. Es ist jedoch immer noch die Methode, mit der eine große Anzahl von Krankenhaus-Systemen Dateien akzeptiert, in der Regel weil das andere Ende ein Laboranalyser oder ein Bürodienst ist, dessen Software seitdem nicht mehr geändert wurde, als es funktionierte. Die Ablehnung der Unterstützung macht diese Systeme nicht moderner; es macht Perfuse unbrauchbar an diesen Standorten.

Hier implementiert, anstatt als Abhängigkeit übernommen, aus dem gleichen Grund wie S3: Die Abhängigkeitsliste mit acht Positionen ist ein echtes Argument mit demjenigen, der Software vor der Installation in einem Krankenhaus überprüft. FTPs Steuerkanal ist textorientiert und läuft über TCP, also sind das nur ein paar hundert Zeilen von net und crypto/tls.

Was unterstützt wird und was abgelehnt wird

Nur passiver Modus. Aktiver Modus erfordert, dass der Server eine Verbindung zum Client öffnet, was jeder Krankenhaus-Feuerwall, der in diesem Jahrhundert gebaut wurde, blockiert, und es anzubieten würde bedeuten, dass die Leute es konfigurieren und dann einen Feuerwall debuggen.

Explizites FTPS (AUTH TLS) wird unterstützt und ist der Standard, wenn TLS angefordert wird. Implizites FTPS auf Port 990 wird auch unterstützt, weil einige Analyser nur das sprechen.

Plaines FTP wird unterstützt und warnt. Es sendet das Passwort im Klartext, und ein Standort, der es verwenden muss, sollte einmal informiert werden, anstatt es aus einer Paketerfassung herauszufinden.

Source: github.com/biodream-llc/perfuse/internal/ftpconn

26.50 gcp

Paket gcp spricht mit Google Cloud Pub/Sub und Cloud Storage über ihre REST-APIs, mit Googles OAuth 2.0, das hier durchgeführt wird: Ein Dienstkonto-Schlüssel signiert ein JWT (RS256, crypto/rsa), das gegen ein Zugriffstoken eingetauscht wird, oder, auf Google Cloud selbst, verteilt der Metadatenserver eines aus.

Kein Google-SDK.

Emulatoren (der Pub/Sub-Emulator, fake-gcs-Server) benötigen keine Anmeldeinformationen: Setzen Sie den Endpunkt und lassen Sie die Anmeldeinformationen leer.

Source: github.com/biodream-llc/perfuse/internal/gcp

26.51 generate

Paket generate erstellt synthetische HL7 v2-Nachrichten.

Zwei Verwendungen. Jemand, der Perfuse ausprobiert, benötigt Daten, um sie anzusehen, und ein Kanaltest benötigt ein Fixture, das realistisch genug ist, um das zu testen, was getestet wird. Ein Generator ist eine kostenpflichtige Erweiterung in Mirth, was zeigt, dass die Leute einen wollen.

Alles hier ist erfunden. Die Namen kommen von einer festen Liste offensichtlich fiktiver Namen, die Identifikatoren sind sequenziell innerhalb eines Durchgangs, und die Adressen sind erfunden. Das ist keine Entschuldigung, es ist das Design: Ein Generator, der plausible, echte Namen produziert, würde schließlich einen in ein Test-Fixture, einen Fehlerbericht und dann in ein Repository einfügen.

Realismus wird dort eingesetzt, wo es für Tests wichtig ist, und nirgendwo anders. Zeitstempel enthalten Offsets, wiederholte Felder wiederholen tatsächlich, ein Name enthält manchmal eine mittlere Initialen und manchmal nicht, und ungefähr eine Nachricht von zwölf ist absichtlich unangenehm: ein fehlendes optionales Feld, ein ungewöhnlicher, aber gesetzlicher Trenner, ein leeres Komponenten. Wenn Sie einem Kanal nichts als perfekt geformte Nachrichten übergeben, erfahren Sie sehr wenig.

Source: github.com/biodream-llc/perfuse/internal/generate

26.52 hl7dict

Das Paket hl7dict benennt die Felder von HL7-v2-Segmenten.

Dies existiert für einen Bildschirm: ein Nachrichten-Viewer, der Ihnen sagen kann, dass PID-5.1 der Familienname des Patienten ist, anstatt Sie dazu zu zwingen, die Carets zu zählen. Jeder, der eine Schnittstelle debuggt hat, hat diese Zählung von Hand durchgeführt, und es ist die häufigste Quelle der off-by-one-Fehler, die einen Wert in das falsche Feld setzen.

Es ist nicht der gesamte Standard. HL7 v2 hat Hunderte von Segmenten und Tausende von Feldern, und die hier aufgeführten sind die, die in ADT-, ORU-, ORM- und SIU-Verkehr auftauchen. Ein unbekanntes Feld wird als unbekannt gemeldet, anstatt es zu erraten.

Source: github.com/biodream-llc/perfuse/internal/hl7dict

26.53 hl7v3

Das Paket hl7v3 liest HL7-Version-3-Nachrichten.

Version 3 ist ein anderes Ding als Version 2 mit dem gleichen Namen. Version 2 ist ein durch Trennzeichen getrennter Stream von Segmenten, deren Bedeutung positionell ist; Version 3 ist XML, das aus einem Referenzinformationmodell generiert wird, wobei die Bedeutung durch Elementnamen und durch eine kleine Menge von Datentypen übertragen wird, die überall wiederkehren. Fast nichts wird zwischen den beiden übertragen, außer der klinischen Vokabular.

In der Praxis kommt v3 in einer von zwei Formen an. Entweder ist es ein CDA-Dokument, das von v3 abgeleitet ist und vom cda-Paket behandelt wird, oder es ist eine IHE-Transaktion - insbesondere PIX und PDQ v3, mit denen eine große Anzahl von Krankenhäusern Patienten-Identifikatoren über Systeme hinweg auflöst. Dieses Paket zielt auf die zweite ab.

Warum die Datentypen zuerst kommen

Die wichtigste Sache über v3 ist, dass ein Element vorhanden und explizit null sein kann, mit einem angegebenen Grund. Ein Geburtsdatum, das nullFlavor="ASKU" enthält, bedeutet, dass der Patient gefragt wurde und ablehnte, zu antworten. Ein Geburtsdatum, das nullFlavor="NAV" enthält, bedeutet, dass der Wert existiert, aber derzeit nicht verfügbar ist, so dass das erneute Fragen später funktionieren kann. Ein Geburtsdatum, das einfach fehlt, bedeutet, dass niemand etwas aufgezeichnet hat.

Das Zusammenfallen dieser in eine leere Zeichenfolge ist der Fehler, den dieses Paket verhindern soll. Es ist kein kosmetischer Verlust: ein nachgelagertes System, das eine leere Geburtsdatum-Nachricht erhält, wo die Quelle sagte, dass der Patient ablehnte, wird dies normalerweise als fehlende Daten behandeln, die verfolgt werden müssen, und eine demografische Übereinstimmung, die ungelöst bleiben sollte, wird durch eine menschliche Vermutung gelöst. Daher unterscheidet jeder Datentyp hier zwischen abwesend, null-mit-Grund und vorhanden.

Source: github.com/biodream-llc/perfuse/internal/hl7v3

26.54 hl7xml

Das Paket hl7xml konvertiert HL7-v2-Nachrichten in die XML-Form, die Mirth Connect verwendet, und zurück in die ER7-Codierung.

Die Form ist keine Designentscheidung. Mirths Skripte sind gegen die Ausgabe seines eigenen ER7-zu-XML-Serialisierungsprogramms geschrieben, so dass sie Ausdrücke wie

msg['PID']['PID.5']['PID.5.1'].toString()

und die Zusage enthalten, dass ein bestehendes Skript unverändert ausgeführt wird, nur wenn der Baum, den es durchläuft, genau die gleichen Elementnamen, die gleiche Einbettung und das gleiche Wiederholungsverhalten hat. Jede Entscheidung unten ist daher "was macht Mirth", nicht "was wäre ordentlicher".

Die beiden, die am meisten zählen:

Jedes Feld ist in nummerierte Komponentenelemente eingeschlossen, auch wenn das Feld nur eine Komponente hat, so dass PID-5 mit dem Wert "Doe" immer noch <PID.5><PID.5.1>Doe</PID.5.1></PID.5> produziert. Skripte indexieren direkt auf .1 und ein Baum, der den Text auf dem Feldelement platziert, würde fast alle von ihnen brechen.

MSH behält die Standard-HL7-Feldnummern bei, wobei MSH-1 der Feldtrenner und MSH-9 der Nachrichtentyp ist. Der Parser in internal/hl7 indexiert MSH mit einem Offset, weil der Trenner eine Position einnimmt, die kein Trennzeichen teilt, und dieses Offset stoppt hier: ein Skript, das MSH.9 sagt, bedeutet den Nachrichtentyp.

Source: github.com/biodream-llc/perfuse/internal/hl7xml

26.55 ibmmq

Das Paket ibmmq sendet an und liest von IBM-MQ-Warteschlangen durch die Messaging-REST-API (mqweb) des Warteschlangen-Managers, die IBM MQ 9.1.5 und später auf jeder Plattform, einschließlich z/OS, ausliefern.

Es benötigt keine MQ-Client-Bibliothek: das native MQI-Protokoll ist IBM-eigen und undokumentiert, und die REST-API ist der unterstützte Weg, um MQ ohne eine zu erreichen. (IBM MQ spricht auch AMQP 1.0 auf einem AMQP-Kanal; der amqp-Connector von Perfuse deckt diese Route ab.)

Das Lesen ist mindestens einmal: die erste Nachricht wird durchgesehen, an den Aufrufer übergeben und nur dann entfernt, wenn der Aufrufer sie bearbeitet hat. Eine Nachricht, die nicht bearbeitet werden konnte, bleibt in der Warteschlange, als erste in der Reihe.

Source: github.com/biodream-llc/perfuse/internal/ibmmq

26.56 identity

Eine Nachricht finden, indem Sie nach dem suchen, was Sie über sie wissen, egal in welchem Format sie angekommen ist.

Die bestehende Inhaltsuche entspricht Metadaten, bietet eine Teilstringübereinstimmung gegen die Nutzlast und kann einen Filterausdruck auswerten - aber der Ausdruck wird nur gegen HL7 v2 ausgewertet und jeder Ausdruck erfordert die Kenntnis des Pfads. So bedeutete das Finden eines Patientenverkehrs, dass die Identität bei PID-3 in einer HL7-v2-Zulassung, bei Patient.identifier in einer FHIR-Ressource, bei (0010,0020) in einer DICOM-Instanz und bei NM109 eines NM1 * IL-Schleifens in einem 837-Anspruch lebt. Vier Formate, vier Vokabulare und während eines Vorfalls kann die gesuchte Nachricht in einem davon sein.

Dieses Paket ordnet eine kleine Menge von Konzepten - wer die Nachricht ist, welcher Besuch, welche Studie, welcher Anspruch - den Orten zu, an denen jedes Format sie aufbewahrt, sodass eine Suche nach "MRN 12345" durchgeführt werden kann, anstatt nach einem Pfad. Die Konzepte sind absichtlich wenige: Dies sind die Dinge, die Menschen tatsächlich in der Hand haben, wenn sie eine Nachricht finden müssen, was eine Nummer von einem Telefonanruf oder ein Name von einer Beschwerde ist.

Warum die Extraktion einmal, zur Aufzeichnungszeit, erfolgt

Die Alternative besteht darin, die Nutzlasten zur Abfragezeit zu parsen, was die Ausdruckssuche tut. Das funktioniert und es ist ehrlich darüber, eine begrenzte Überprüfung durchzuführen, aber es kann nicht beantworten, „jede Nachricht über diesen Patienten über vier Feeds und zwei Monate“, ohne jede Zeile zu lesen. Die Extraktion in eine indizierte Tabelle verwandelt dies in eine Indexabfrage.

Dies ist eine Privatsphärenerhöhung und ist optional

Patientennamen und -identifikatoren sitzen derzeit in einer undurchsichtigen Nutzlastspalte. Die Indizierung macht sie abfragbar, was der Zweck ist, und macht sie auch auflistbar, was eine echte Änderung der Exposition darstellt: Eine Datenbank, die nur durch grep durchsucht werden kann, kann jetzt gefragt werden, „listen Sie jeden Patienten auf“. Das ist eine Entscheidung für die Website, nicht für dieses Paket, also ist die Extraktion umschaltbar und jede Suche durch sie wird im PHI-Prüfprotokoll aufgezeichnet.

Source: github.com/biodream-llc/perfuse/internal/identity

26.57 iis

Paket iis spricht den Transport, den jeder US-Immunisierungsregister teilt: den IIS-SOAP-Webservice des CDC.

Im Jahr 2011 wählte ein von der CDC und der American Immunization Registry Association einberufener Expertenrat eine SOAP-Schnittstelle für die Übermittlung von HL7-v2-Nachrichten an Immunisierungsinformationssysteme aus, und die Register übernahmen sie. Die WSDL ist klein - zwei Operationen, connectivityTest und submitSingleMessage - und die HL7-Nachricht (ein VXU, um einen Schuss zu melden, ein QBP^Q11, um die Geschichte eines Patienten zu erfragen) wird als entkommener Text innerhalb des SOAP-Textkörpers übertragen. Die Antwort kommt auf die gleiche Weise zurück: ein ACK oder ein RSP^K11, das die Geschichte und die Prognose enthält.

Das generische SOAP-Ziel könnte so konfiguriert werden, dass es dies tut, aber jede Website müsste das gleiche Kuvert tippen, die Namespace richtig setzen, die Anmeldeinformationen im Textkörper anstelle der HTTP-Authentifizierung platzieren und dann die HL7-Bestätigung aus der Antwort lesen, um zu erfahren, ob das Register den Datensatz behalten hat. Ein Register antwortet auf einen abgelehnten Schuss mit HTTP 200 und einem AR; die Behandlung von 200 als Erfolg ist die Art und Weise, wie Impfungen unhörbar fehlschlagen, gemeldet zu werden. Dieses Paket führt also das CDC-Kuvert durch und bewertet die Bestätigung einmal.

Was es nicht tut: Die Benutzername und das Passwort der WSDL sind die Anwendungsanmeldeinformationen des Registers und werden wie in der WSDL angegeben im Textkörper gesendet. Der gegenseitige TLS, den ein Register erfordert, ist die TLS-Einstellung des Ziels wie bei jedem HTTPS-Aufruf. Nichts davon ist spezifisch für einen Staat; wo Staaten unterschiedlich sind (Einrichtungs-ID erforderlich oder nicht, SOAP 1.1 akzeptiert oder nicht, Warnungen als AE gesendet), sagen die Einstellungen des Ziels so.

Source: github.com/biodream-llc/perfuse/internal/iis

26.58 kafka

Kafka als Client und nicht als Ersatz.

Ein Gesundheitssystem, das ein Ereignis-Rückgrat hat, hat ein Kafka-Rückgrat, und die Systeme, die im letzten Jahrzehnt gebaut wurden, veröffentlichen auf ihm anstelle eines JMS-Brokers. Dieser Connector existiert also, um Perfuse zum gesundheitsbewussten Rand von jemand anderem zu machen Ereignisplattform: Es liest klinische Nachrichten von Themen und veröffentlicht sie auf Themen, und es versucht absichtlich nicht, eine Streaming-Plattform zu sein. Fensterung, Joins, Stream-Verarbeitung und Schemaregister sind Kafkas Ökosystem und bleiben dort.

Warum eine Abhängigkeit, wenn STOMP und MLLP von Hand geschrieben wurden

Die angegebene Regel in diesem Repository ist, dass eine Abhängigkeit Fähigkeiten kaufen muss, anstatt Bequemlichkeit, und reines Go sein muss, damit eine statische Binärdatei immer noch auf jedes Ziel kompiliert wird. franz-go ist reines Go und enthält kein cgo, was gegen alle sechs Ziele überprüft wurde.

Kafkas Protokoll ist nicht STOMP. STOMP ist ein Textprotokoll, das in ein paar hundert Zeilen passt. Kafka ist ein versioniertes Binärprotokoll über ungefähr siebzig Anfragearten, und der Teil, der hier am meisten zählt - Consumer-Gruppen - ist ein verteiltes Koordinationsprotokoll mit Join-, Sync-, Heartbeat- und Offset-Commit-Phasen und einem Wiederherstellungs-Tanz zwischen ihnen. Das Subtil-Falsch-Bekommen produziert keinen offensichtlichen Fehler: Es produziert eine Partition, die niemand liest, oder zwei Consumer, die dieselbe lesen. In einem klinischen Feed sind das ein fehlendes Laborergebnis und eine duplizierte Bestellung. Das ist Fähigkeit, und es lohnt sich nicht, es von Hand zu erstellen, um eine Abhängigkeit zu sparen.

Source: github.com/biodream-llc/perfuse/internal/kafka

26.59 ldap

Paket ldap spricht genug LDAP, um eine Person zu authentifizieren und ihre Gruppen zu lesen.

Krankenhäuser verwenden fast ausnahmslos Active Directory, und AD spricht LDAP. OpenID Connect ist die bessere Antwort, wenn es erreichbar ist - siehe internal/oidc, und die dortige Anmerkung, dass Mirth keine Single-Sign-On-Funktion zu irgendeinem Preis hat - aber ein Integrations-Engine sitzt oft auf einem isolierten VLAN, wo ein Browser nicht auf einen Identitätsanbieter zugreifen kann. Genau dafür ist dies gedacht.

Eigenentwickelte BER anstelle einer Abhängigkeit, aus dem gleichen Grund wie DICOM und STOMP: die Kodierung ist klein, und was auf diesem Socket ankommt, entscheidet, ob jemand in ein System gelangt, das Patientendaten bewegt.

encoding/asn1 in der Standardbibliothek ist hier nicht verwendbar. Es zielt auf DER ab und lehnt die kontextspezifischen Tags und implizite Markierung, die LDAP überall verwendet, ab, so dass die wichtigen Teile ohnehin handgefertigt werden müssten.

Source: github.com/biodream-llc/perfuse/internal/ldap

26.60 Postfach

Package Postfach liest E-Mails von IMAP4rev1- (RFC 3501) und POP3- (RFC 1939) Servern, indem es sich mit einem Passwort oder OAuth 2.0 (SASL XOAUTH2, wie es Microsoft 365 und Gmail erfordern) anmeldet und Nachrichten auseinander nimmt (RFC 5322 und MIME), so dass eine Anlage oder der Textkörper zu einer Nachricht auf einem Kanal werden kann.

Nur das, was ein eingehender Feed benötigt: ein Postfach auswählen, ungelesene E-Mails finden, sie ganz abrufen und dann verschieben, markieren oder löschen. Nur Standardbibliothek; TLS ist crypto/tls.

Source: github.com/biodream-llc/perfuse/internal/mailbox

26.61 Mapper

Package Mapper schlägt Feldzuordnungen zwischen Systemen mit Konfidenzpunktzahlen vor.

Dies ist ein regelbasierter intelligenter Mapping-Engine. Kein LLM, keine Netzwerkanrufe, keine externen Abhängigkeiten. Es läuft offline im gleichen Binärformat und sendet niemals Patientendaten an einen anderen Ort.

Der Engine kombiniert mehrere Signale - unscharfe Zeichenfolgenabgleich auf Feldnamen, Erkennung von Muster für Gesundheitskennungen, Codesystemabfragen und historische Akzeptanzdaten - in einen einzelnen Konfidenzpunktzahl pro Vorschlag. Wenn die Konfidenz unter einem konfigurierbaren Schwellenwert liegt, enthält sich der Mapper, anstatt falsch zu raten, da eine falsche Zuordnung im Gesundheitswesen Daten an das falsche Feld routen und somit ein Patientensicherheitsfehler darstellen kann.

Enthaltung ist die Kernentscheidung. Ein System, das immer eine Antwort liefert, trainiert Benutzer, aufzuhören, zu überprüfen, und das eine Mal, wenn es falsch ist, bemerkt niemand es, bis ein Laborergebnis in einem Notizfeld landet. Ein System, das sagt: "Ich weiß es nicht", zwingt eine menschliche Entscheidung genau dann, wenn der Mensch benötigt wird.

Source: github.com/biodream-llc/perfuse/internal/mapper

26.62 Messung

Package Messung bewertet FHIR-Messungen (digitale Qualitätsmessungen), deren Populationskriterien FHIRPath sind, und schreibt das Ergebnis als FHIR-Messungsbericht: Zusammenfassung, Einzel- oder Subjektnachweis, mit Stratifikatoren und einem Proportionswert.

Jedes Kriterium wird einmal pro Patient bewertet, mit dem Fokus auf einem Bundle des Patientenakts (ihrem Fach) und diesen Variablen: %subject (der Patient), %periodStart und %periodEnd (der Messungszeitraum, als DateTimes) und %"Messungszeitraum" (derselbe wie ein Zeitraum). Kriterien in CQL werden abgelehnt, mit dem Grund: Perfuse hat keinen CQL-Engine.

Source: github.com/biodream-llc/perfuse/internal/measure

26.63 Metriken

Package Metriken sammelt, was der Engine tut, und behält genug Geschichte, um sie zu zeichnen.

Ein Interface-Engine wird beobachtet, nicht nur ausgeführt. Wenn eine Station sagt, dass Ergebnisse vor zwanzig Minuten aufgehört haben anzukommen, ist die Frage, was sich vor zwanzig Minuten geändert hat, und das kann nicht durch aktuelle Zähler allein beantwortet werden. Deshalb werden hier Serien anstelle von Summen aufbewahrt, im Speicher, mit einer festen Auflösung.

Drei Entscheidungen prägen es.

Latenz wird als Histogramm anstelle eines Mittelwerts aufbewahrt. Eine durchschnittliche Lieferzeit ist in diesem Bereich fast nutzlos: die Zahl, die zählt, ist, ob die langsamsten paar Prozent der Nachrichten langsam genug sind, um eine Umkehrzusicherung zu verletzen, und ein Mittelwert versteckt genau das. Eimer sind exponentiell und bei der Build-Zeit festgelegt, so dass die Aufzeichnung einer Dauer ein Vergleich und ein Inkrement ohne Zuweisung ist.

Serien sind begrenzte Puffer. Nichts hier wächst ohne Begrenzung, da ein Interface-Engine monate lang läuft und ein Metrik-System, das neu gestartet werden muss, schlimmer ist als keines.

Kardinalität ist gedeckelt. Ein Labelwert, der aus Nachrichtendaten stammt - eine sendende Anwendung, sagen wir - kann Tausende von Werten annehmen, wenn jemand einen Feed falsch konfiguriert, und unbegrenzte Labels sind der Standardweg, wie Überwachung das Überwachte beeinträchtigt. Über dem Deckel kollabieren Werte in einen "Sonstige"-Eimer, und der Deckel wird selbst gemeldet.

Source: github.com/biodream-llc/perfuse/internal/metrics

26.64 Mirth

Java-Analyse für importierte Mirth-Kanäle.

Warum es existiert

Mirth läuft Rhino auf der JVM, so dass ein Mirth-Skript jeden Java-Code auf dem Klassenpfad aufrufen kann, einschließlich Mirths eigener Serverklassen. Perfuse läuft goja und hat keine Java-Laufzeit. Es lehnt diese Aufrufe mit einem Fehler ab, der die Klasse nennt - aber diese Ablehnung erfolgt, wenn das Skript läuft, was für einen Quell-Connector bedeutet, wenn die erste echte Nachricht ankommt.

Ein Migration lief also: der Import gelingt stillschweigend, der Kanal wird bereitgestellt, und die erste Nachricht vom Draht aus schlägt fehl. Eine Migration, die sauber aussieht und bei der ersten Datenübertragung fehlschlägt, ist schlimmer als eine, die an der Tür ablehnt, da die Person, die es getan hat, bereits ihren Kollegen gesagt hat, es habe funktioniert.

Dies findet diese Aufrufe zur Importzeit und sagt, was mit jedem einzelnen zu tun ist.

Warum vier Urteile und nicht zwei

"Verwendet Java" ist ein Stück Information und das falsche, weil das Java, das ein echter Mirth-Kanal verwendet, in Gruppen mit völlig unterschiedlichen Arbeitsmengen fällt. Etwa die Hälfte dessen, was Sites tatsächlich schreiben, ist SimpleDateFormat und HashMap, was JavaScript nativ unterstützt. Ein Teil davon ist die dokumentierte Skript-API von Mirth, die Perfuse bereits unter den gleichen Namen implementiert. Ein wenig davon möchte Kanäle starten und stoppen, was Perfuse über seine REST-API tun kann, aber Skripten nicht zugänglich macht. Und ein Teil davon ist ein Vendor-JAR, das hier nie ausgeführt wird.

Das Melden dieser als eine Zahl sagt einem Migrator nichts darüber, ob sein Nachmittag oder sein Quartal auf dem Spiel steht.

Source: github.com/biodream-llc/perfuse/internal/mirth

26.65 mirthlive

Das Paket mirthlive findet die laufenden Mirth-Engines, mit denen die Interoperabilitätstests kommunizieren.

Mirth Connect war ab Version 4.6 (März 2025) nicht mehr Open Source. Die Sites, die es verlassen, gehen zu einem von drei Orten: Mirth 4.5.2, der letzten Open-Source-Veröffentlichung, die sie weiterhin ausführen; der Open Integration Engine, der Eclipse-gehosteten Fork; oder BridgeLink, Innovars Fork, der seine Veröffentlichungen nach Jahr nummeriert (26.9.0). Ein Kanal, den Perfuse exportiert, muss in allen davon geladen werden, und ein Kanal, den einer davon exportiert, muss hier importiert werden, sodass jeder Live-Test einmal pro Engine ausgeführt wird, die antwortet.

Die Engines werden durch Anfragen gefunden, nicht konfiguriert: ./scripts/interop-up.sh startet sie auf festen Ports, und eine Engine, die nicht läuft, wird als übersprungen gemeldet, anstatt stillschweigend zu bestehen. PERFUSE_MIRTH_ENGINES überschreibt die Liste, als Name-URL-Paare, die durch Kommas getrennt sind.

Nur Tests importieren dies. Es lebt außerhalb einer _test.go-Datei, weil zwei Pakete es teilen.

Source: github.com/biodream-llc/perfuse/internal/mirth/mirthlive

26.66 mpi

Das Paket mpi ist ein Master-Patienten-Index: es nimmt Patientenakten von jedem Quellsystem (jedes identifiziert durch seine Zuweisungsbehörde und Nummer), entscheidet, welche zu derselben Person gehören, und gibt jeder Person eine Unternehmenskennung (EUID).

Bestimmte Übereinstimmungen verknüpfen sich selbst; unsichere warten in einer Überprüfungswarteschlange auf eine Entscheidung einer Person; jede Verknüpfung, Entverknüpfung, Zusammenführung und Entscheidung wird mit Angabe der Person, die sie getroffen hat, aufgezeichnet.

Die Übereinstimmung ist zunächst deterministisch (eine Kennung aus einem System, dem das Site vertraut, dass es pro Person eindeutig ist, wie z. B. eine nationale Kennung oder eine Unternehmensnummer) und ansonsten probabilistisch: Fellegi-Sunter-Gewichte über Namen, Geburtsdatum, Geschlecht, Postleitzahl, Telefon und Adresse, mit Jaro-Winkler für Namen. Es entscheidet nichts Klinisches: es sagt, welche Akten dieselbe Person sind, mit seinen Gründen, für eine Person, die bestätigen muss, wenn es nicht sicher ist.

Source: github.com/biodream-llc/perfuse/internal/mpi

26.67 mqtt

Das Paket mqtt ist ein MQTT 3.1.1-Client: Verbinden (mit TLS, Benutzername und Passwort oder Clientzertifikat), Veröffentlichen bei QoS 0 oder 1, Abonnieren und Bestätigen jedes empfangenen QoS-1-Nachrichten nur einmal, wenn der Aufrufer sagt, dass es bearbeitet wurde.

Geschrieben gegen den OASIS-MQTT-3.1.1-Standard und nicht importiert, wie die anderen Drahtprotokolle von Perfuse. 3.1.1 ist die Version, die jeder Broker spricht: Mosquitto, EMQX, HiveMQ, VerneMQ, RabbitMQs MQTT-Plugin, IBMs MQ-Telemetrie-Kanal, AWS IoT Core und Azure Event Grid.

Lieferung: eine bei QoS 1 empfangene Nachricht wird nur bestätigt (PUBACK), wenn Ack aufgerufen wird. Ein Aufrufer, der eine Nachricht nicht bearbeiten kann, schließt die Verbindung stattdessen; mit einer persistenten Sitzung (CleanSession false) sendet der Broker sie erneut, als Duplikat markiert, wenn der Client sich erneut verbindet. MQTT 3.1.1 hat keine negative Bestätigung, also ist dies die einzige Möglichkeit, eine Nachricht erneut anzufordern.

Source: github.com/biodream-llc/perfuse/internal/mqtt

26.68 msgstore

Ein gespeichertes Nachrichten finden, indem man nach etwas sucht, das jemand darüber weiß.

Die Suche, die eine Person tatsächlich benötigt, ist „hier ist eine Nummer von einem Telefonanruf, zeigen Sie mir jede Nachricht darüber“. Bevor dies bedeutete, entweder eine Teilstring-Übereinstimmung über Payloads, was grep und langsam ist, oder einen Filterausdruck, der das Wissen erfordert, dass die Identität bei PID-3 in HL7 v2 und irgendwo anders in den anderen drei Formaten auf dem gleichen Server lebt.

Die Identität wird einmal extrahiert, wenn die Nachricht aufgezeichnet und indiziert wird, sodass dies eine Abfrage und kein Scan ist. Die Kosten werden auf dem Aufzeichnungspfad bezahlt, einmal pro Nachricht, anstatt bei jeder Suche.

Source: github.com/biodream-llc/perfuse/internal/msgstore

26.69 natid

Das Paket natid kennt die nationalen Patienten- und Personenkennungen des Vereinigten Königreichs und Europas: ihre Formate, ihre Prüfziffern, das Kennungssystem, das jeder Landes-FHIR-Leitfaden sie nennt, und wie viel von einem gezeigt werden darf.

Es existiert für den Patientenindex. Eine nationale Nummer ist der stärkste Beweis, dass zwei Akten eine Person sind, und auch die leichteste, die falsch zu machen ist: eine zweimal eingegebene Ziffer ergibt eine Nummer, die jemand anderem gehört, und eine Quelle sendet die NHS-Nummer unter einem OID, während eine andere sie unter ihrer FHIR-URL sendet. Jede Kennung, die der Index speichert, geht also durch hier: ihre Prüfziffer wird getestet (eine falsche wird nie verwendet, um zu verknüpfen), ihre Leerzeichen entfernt und ihr System auf eine Weise geschrieben.

Was verifiziert wird und was nicht, wird pro Schema angegeben. Die Algorithmen sind öffentlich; die Kennungssystem-URIs sind die des Landes, wenn ein nationaler FHIR-Leitfaden einen nennt (SystemVerified), und ein dokumentierter Standard ansonsten, den ein Site unter Einstellungen → Patientenindex auf seinen nationalen Wert ändern kann. Nichts hier entscheidet etwas Klinisches.

Source: github.com/biodream-llc/perfuse/internal/natid

26.70 ncpdp

Schreiben eines Feldes in einer NCPDP-Übertragung.

Warum ein Schreiben einen mehrdeutigen Pfad ablehnt

Ein Lesen gibt jeden Wert zurück, den ein Pfad anspricht, da ein Filter, der fragt, ob ein DUR-Konflikt eine therapeutische Duplizierung ist, alle davon sehen sollte. Ein Schreiben kann nicht so funktionieren. Wenn D7 die Produktcodes von zwei Ansprüchen in einer Übertragung anspricht, hat das Setzen von D7 keine einzige Bedeutung: Das Schreiben beider würde ein Medikament ändern, das niemand gefragt hat, und das Schreiben des ersten würde das zweite stillschweigend lassen.

Ein Schreiben lehnt also einen Pfad ab, der mehr als ein Feld anspricht, und der Fehler nennt die qualifizierte Form, die eindeutig wäre. Dies ist dieselbe Argumentation, die den TransformationsSchritten keine Entfernen-Aktion gibt: Wo die ehrliche Antwort ist, dass die Konfiguration mehrdeutig ist, ist es besser, dies zu sagen, als eine auszuwählen.

Source: github.com/biodream-llc/perfuse/internal/ncpdp

26.71 oidc

Das Paket oidc überprüft OpenID Connect-Identitäten.

Geschrieben gegen die Standardbibliothek und nicht gegen eine JWT-Abhängigkeit. Die Authentifizierung ist der Ort, an dem eine unauditierte Abhängigkeit am wenigsten akzeptabel ist, die Signaturüberprüfung für die Algorithmen, die wichtig sind, ist etwa hundert Zeilen von crypto/rsa und crypto/ecdsa, und Perfuse trägt bereits genug, um weitere hinzuzufügen, was einen Grund benötigt, anstatt eine Gewohnheit.

Der Umfang ist absichtlich eng gefasst: Überprüfen, ob ein Identitätsanbieter für eine Person bürgte, und Berichten, was er über sie sagte. Alles andere - was sie tun dürfen, wie lange die Sitzung dauert - bleibt bei Perfuse, da ein Identitätsanbieter weiß, wer jemand ist und nicht, was sie in einem Interface-Engine dürfen.

Source: github.com/biodream-llc/perfuse/internal/oidc

26.72 Parität

Das Paket parity vergleicht, was Perfuse produziert, mit dem, was die Engine produziert, die ersetzt wird.

Warum es existiert

Perfuse kann einen Mirth-Kanal importieren und kann nachvollziehen, was er mit einer Nachricht tun würde. Keines von beiden beantwortet die Frage, die jemand vor dem Umzug eines Live-Feeds hat, nämlich: Wird dies dieselbe Ausgabe produzieren wie das, was sechs Jahre lang gelaufen ist?

Keine Menge an Designqualität beantwortet das. Die einzige ehrliche Antwort ist Beweis, und der Beweis muss aus der Ausgabe der alten Engine auf dem eigenen Traffik der Site kommen.

Warum die Paare geliefert werden müssen

Dies kann nicht in Mirth eindringen und es wäre das schlimmste Feature, dies vorzutäuschen. Was es braucht, sind Paare: Eine Nachricht, wie sie ankam, und die Nachricht, die die alte Engine aus ihr produzierte. Beide sind in Mirths eigener Nachrichtenspeicher und können aus seinem Nachrichtenbrowser exportiert werden, was eine Sache ist, die ein Administrator bereits weiß, wie man sie tut.

Diese Einschränkung wird angegeben, anstatt sie zu verstecken. Ein Tool, das behauptet, eine Migration zu überprüfen, ohne jemals die Ausgabe der alten Engine gesehen zu haben, würde nichts überprüfen.

Warum Unterschiede gruppiert und nicht aufgelistet werden

Ein Lauf über fünfzigtausend Nachrichten, der viertausend Unterschiede meldet, hat niemandem etwas gesagt, das er tun kann. Derselbe Lauf, der meldet, dass PID-8 in jeder Nachricht unterschiedlich ist, weil die alte Engine M auf Male abgebildet hat, hat ihm genau eine Sache gesagt, über die er entscheiden kann.

Die Ergebnisse werden also nach Feldern gruppiert, mit einer Zählung, einem Beispiel und den unterschiedlichen Wertepaaren, die gesehen wurden. Eine Entscheidung pro Ergebnis ist die Einheit, die jemand durcharbeiten kann.

Source: github.com/biodream-llc/perfuse/internal/parity

26.73 pas278

Das Paket pas278 mappt zwischen Da Vinci-Vorabgenehmigung und der X12-278-Transaktion.

Warum es existiert

CMS-0057-F erfordert, dass Payer bis zum 1. Januar 2027 eine FHIR-Vorabgenehmigungs-API exponieren. Es ersetzt nicht die X12-278 und es war nie geplant, dies zu tun: Ein Payers Utilisationsmanagementsystem entscheidet über Genehmigungen und spricht 278. Ein Payer, der die Regel erfüllt, übersetzt also FHIR in 278 und zurück, und ein Anbieter, der heute 278 sendet, wird morgen FHIR an dieselben Payer senden, die beide noch akzeptieren.

Diese Übersetzung ist das, was es wert ist, zu besitzen. Eine Engine, die beide Modelle hält und nicht zwischen ihnen konvertieren kann, überlässt die härteste Arbeit - und den Teil, an dem die Fehler teuer sind - dem, der sie integriert.

Die Regeln, die dieses Paket befolgt, ausgesprochen anstatt angedeutet

Aufgeschrieben aus demselben Grund, aus dem v2fhir seine eigenen aufschreibt: Mapping ist, wo Interoperabilitätsprojekte scheitern, und die Fehler sind still.

Source: github.com/biodream-llc/perfuse/internal/pas278

26.74 pdf

Paket pdf erstellt einfache Textdokumente, die nur die Standardbibliothek verwenden.

Mirths Document Writer rendert HTML in PDF um, was einen Layout-Engine benötigt. Das ist nicht das, was dies ist. Dies erzeugt ein einfaches, paginiertes Textdokument mit einer Monospaced-Schriftart, und es existiert, weil die tatsächliche Anforderung an fast jedem Standort, der diesen Connector verwendet, „lege diesen Bericht auf einen Share, damit jemand ihn drucken kann“ ist - eine Entlassungssumme, ein Ergebnisbericht, eine tägliche Abstimmung. Diese sind Text.

Die Ablehnung dieser Funktion würde einen Tier-2-Migrationsblocker an Ort und Stelle lassen. Das Einbinden eines HTML-Rendering-Engines würde mehr kosten als der gesamte Rest des Binaries und würde einen CVE-Stream mit sich bringen, was das Argument der Stückliste wieder aufheben würde. Also: Text, ehrlich beschrieben als Text, und ein Standort, der tatsächlich gesetzte Ausgabe benötigt, wird besser durch ein Dateiziel und ein dafür entwickeltes Tool bedient.

Warum ein PDF schreiben anstelle eines Textdatei

Weil das empfangende Ende normalerweise eine Person mit einem Drucker und einem Windows-Share ist und eine .txt-Datei, die von einem Share aus gedruckt wird, ihre Paginierung, ihre Ränder und oft ihre Zeilenenden verliert. Ein PDF wird überall gleich gedruckt, was der gesamte Grund ist, warum jemand danach gefragt hat.

Source: github.com/biodream-llc/perfuse/internal/pdf

26.75 pgp

Paket pgp verschlüsselt, signiert, entschlüsselt und überprüft OpenPGP-Nachrichten (RFC 9580 und RFC 4880 für ältere Peers), für Zahler, Clearinghäuser und staatliche Behörden, die Dateien über SFTP oder E-Mail unter PGP austauschen.

Die Kryptographie ist github.com/ProtonMail/go-crypto, der gewartete Fork von golang.org/x/crypto/openpgp; nichts hier implementiert ein primitives Verfahren. Dieses Paket lädt nur Schlüssel und entscheidet, was eine Nachricht übertragen muss.

Source: github.com/biodream-llc/perfuse/internal/pgp

26.76 pixv3

Das Paket pixv3 ist die HL7-Version-3-Oberfläche des Patientenindex: die IHE-Patienten-Identitäts-Überprüfungs- und Patienten-Demografische-Abfrage-Profile, wie sie die meisten Krankenhäuser außerhalb der FHIR-Welt noch sprechen.

Die Antworten kommen aus dem gleichen Patientenindex wie PIXm, PDQm, Patienten/$match und dem Index-Bildschirm, sodass ein in v3 eingespeister Datensatz über FHIR gefunden wird und umgekehrt. Die Nachrichten werden von Hand geschrieben, in der Reihenfolge des Schemas, aus dem Grund, dass hl7v3.Ack gibt.

Source: github.com/biodream-llc/perfuse/internal/pixv3

26.77 priorauth

Paket priorauth implementiert den Anbieter-seitigen Workflow für vorherige Autorisierung, der durch CMS-0057 erforderlich ist. Es sendet vorherige Autorisierungsanfragen an FHIR-APIs von Zahlern, verfolgt Antworten und wandelt zwischen internen Typen und FHIR-Ressourcen um.

Source: github.com/biodream-llc/perfuse/internal/priorauth

26.78 privacy

Paket privacy beantwortet die Anfragen eines Datenunterwerfers unter der DSGVO und der UK-DSGVO: finde alles, was dieser Server über eine Person besitzt, gib es ihnen (Artikel 15 und 20), lösche es (Artikel 17) und behalte, was eine rechtliche Sperrung abdeckt.

Es erreicht jeden Ort, an dem Perfuse Patientendaten speichert: den Nachrichtenspeicher (über seinen Identitätsindex), die Lieferwarteschlange, den FHIR-Speicher (die Patienten-Ressourcen und alles, was auf sie verweist, mit ihrer Geschichte), gespeicherte vorherige Autorisierungsanfragen und den Patientenindex, dessen Links eine Identifikator in alle Identifikatoren einer Person erweitern. Was es nicht erreichen kann, benennt es: Spuren, die an einen Sammler gesendet werden, das Audit-Log (das als Aufzeichnung davon, wer was getan hat, aufbewahrt wird) und Backups, die das Gelöschte bis zum Ablauf aufbewahren - also wird jede Löschung in ein Ledger geschrieben, als gesalzene Hashes der Identifikatoren anstelle der Identifikatoren, und kann erneut auf eine wiederhergestellte Kopie angewendet werden.

Es entscheidet nichts in jemandes Namen. Ob eine Anfrage gewährt werden muss und ob eine Ausnahme anwendbar ist, ist die Entscheidung des Controllers; die Löschung benötigt die Zustimmung eines zweiten Administrators, und eine rechtliche Sperrung verweigert sie rundweg.

Source: github.com/biodream-llc/perfuse/internal/privacy

26.79 publichealth

Paket publichealth implementiert bidirektionale öffentliche Gesundheitsberichterstattung: elektronische Fallberichterstattung (eCR), elektronische Laborberichterstattung (ELR) und Impfstoffregisterabfragen.

Jedes Krankenhaus ist gesetzlich verpflichtet, bestimmte Bedingungen - Tuberkulose, Masern, Hepatitis, COVID-19, sexuell übertragbare Infektionen, durch Lebensmittel übertragene Krankheiten - an staatliche und lokale Gesundheitsbehörden zu melden. Die Meldung erfolgt über drei verschiedene Schnittstellen:

Das Paket ist bidirektional: es meldet nach außen (ELR, eCR, VXU) und fragt zurück (VXQ/VXR). Alle Operationen sind Echtzeit und nicht nachtliche Batch-Operationen.

Thread-Sicherheit: SubmissionLog ist für den konkurrierenden Gebrauch sicher. Die Builder-Funktionen sind rein und sicher, um von jedem Goroutine aufgerufen zu werden.

Source: github.com/biodream-llc/perfuse/internal/publichealth

26.80 published

Paket published enthält die Wächter für die importierbaren Pakete von Perfuse, an einem Ort.

hl7 war das erste Paket, das veröffentlicht wurde und seine eigenen Kopien dieser Prüfungen enthält. fhir und pas wurden veröffentlicht, damit ein Entscheidungsdienst wie Vaglio FHIR- und PAS-Anfragen mit genau dem Code liest, den Perfuse verwendet, anstatt einer Kopie, die abdriftet: vier Leser der X12-Aktionscodes in diesem Repository stimmten einmal nicht überein, und einer las eine Ablehnung als Genehmigung. Die Wächter werden hier aufbewahrt, anstatt in jedes Paket kopiert zu werden, aus demselben Grund.

Source: github.com/biodream-llc/perfuse/internal/published

26.81 queue

Paket queue ist eine dauerhafte, pro-Ziel-Lieferwarteschlange.

Ohne es verliert ein Ziel, das für zwei Minuten nicht erreichbar ist, alles, was während dieser zwei Minuten gesendet wird: Wiederholungsversuche erfolgen im Speicher, und wenn sie ausgeschöpft sind, wird die Nachricht als fehlgeschlagen aufgezeichnet und ist weg. Mit ihm bleibt die Nachricht auf der Festplatte und behält ihren Platz, bis das Ziel wieder verfügbar ist.

Zwei Designentscheidungen prägen alles andere.

Die Reihenfolge wird pro Ziel erhalten, und das bedeutet, dass ein gewähltes Ziel den schnellen Pfad nicht mehr nimmt. HL7 ist ein Strom von Ereignissen über dieselben Patienten: ein A01 gibt eine Aufnahme an, ein A03 eine Entlassung. Wenn ein fehlgeschlagener A01 in die Warteschlange geht, während die nächste A03 direkt geliefert wird, sieht das empfangende System eine Entlassung für einen Patienten, der nie aufgenommen wurde. Sobald also etwas für ein Ziel in die Warteschlange gestellt wird, wartet alles für dieses Ziel in der Warteschlange, bis die Warteschlange geleert ist. Das kostet Durchsatz während eines Ausfalls und ist nicht optional, weil die Alternative stilles klinisches Unsinn ist. Es ist auch das spezifische, was in anderen Motoren schiefgeht, wenn jemand gleichzeitige Warteschlangenthreads aktiviert, um einen Rückstand schneller abzubauen.

Eine gewählte Nachricht ist eine akzeptierte Nachricht. Der Absender wird AA mitgeteilt, weil die Bytes auf der Festplatte sind und vor der Bestätigung fsynced werden. AE zu sagen würde einen korrekt funktionierenden Store-and-Forward-Queue wie einen Fehler aussehen lassen und den Absender einladen, erneut zu senden, was wir bereits halten.

Source: github.com/biodream-llc/perfuse/internal/queue

26.82 Aufenthaltsstatus

Der Aufenthaltsstatus des Pakets legt fest, wohin die Daten dieses Servers gehen dürfen: die Cloud-Regionen, die ein Standort zulässt (EEA, UK, Schweiz oder Regionen, die einzeln benannt werden), und ob die Region eines Connectors eine davon ist.

Perfuse überprüft, was es wissen kann. Ein AWS-Connector nennt seine Region (S3, SQS, SNS), und ein AWS-Hostname trägt eine (sqs.eu-west-2.amazonaws.com); diese werden überprüft, wenn ein Kanal gespeichert und geladen wird, sodass ein Kanal keine Patientendaten an einen Bucket in Virginia senden kann, wenn der Server, dessen Daten in Frankfurt bleiben müssen. Ein einfacher Hostname (ein eigenes System eines Krankenhauses, ein MLLP-Listener eines Partners) sagt nichts über seinen Standort aus und wird hier nicht beurteilt: der Verarbeitungsverlauf listet jeden Host auf, an den ein Kanal sendet, damit der Controller ihn überprüfen kann.

Source: github.com/biodream-llc/perfuse/internal/residency

26.83 rtpb

Das Paket rtpb beantwortet NCPDP-Echtzeit-Anfragen für Rezeptvorteile von einem Formular: was ein Medikament diesem Mitglied in dieser Apotheke kosten wird, ob es eine vorherige Genehmigung oder einen Schritt benötigt und welche Alternativen weniger kosten.

CMS-0062-P schlägt RTPB für betroffene Zahlungspflichtige ab dem 1. Oktober 2027 vor. Das XML ist NCPDP RTPB v13 (PBv13). Das NCPDP-Schema ist lizenziert, daher folgen die Elementnamen und die Reihenfolge den öffentlichen Surescripts-RTPB-Beispielen und den öffentlichen NCPDP-RTPB-Implementierungsempfehlungen (Abdeckungsbeschränkungs-Codes und der Abdeckungsstatus, den jeder zugeordnet); eine Antwort wird hier nicht gegen das XSD überprüft, und eine Netzwerkkertifizierung ist der Ort, an dem dies passiert.

Source: github.com/biodream-llc/perfuse/internal/rtpb

26.84 s3put

Das Paket s3put schreibt Objekte in S3 mithilfe nur der Standardbibliothek.

Der offensichtliche Weg, um mit S3 zu sprechen, ist das AWS-SDK, und das SDK ist enorm. Dieses Projekt verkauft eine statische Binärdatei mit acht direkten Abhängigkeiten und einer Stoffliste, die auf einem Bildschirm passt - das ist ein echtes Argument mit der Person, die Software vor der Installation in einem Krankenhaus überprüft, und es wäre ein schlechtes Geschäft, es für einen Connector aufzugeben.

Was S3 tatsächlich benötigt, ist ein HTTP-PUT und eine Signatur. Signaturversion 4 ist vollständig spezifiziert, sie ist deterministisch, und AWS veröffentlicht Testvektoren dafür. Es wird also hier implementiert: etwa zweihundert Zeilen gegen crypto/hmac und net/http, ohne neue Abhängigkeit und ohne Patches, wenn das SDK ein Advisory hat.

Was dies absichtlich nicht tut

Kein Mehrteil-Upload, keine Wiederholungen eigener Art, keine Berechtigungskette jenseits statischer Schlüssel und der Standard-Umgebungsvariablen. Eine HL7-Nachricht ist Kilobyte, also löst Mehrteil ein Problem, das hier nicht besteht; der Motor wiederholt bereits; und eine Instanz-Rolle-Berechtigungskette würde IMDS-Aufrufe, Caching- und Aktualisierungslogik bedeuten, was der Punkt ist, an dem eine kleine Implementierung aufhört, klein zu sein. Wenn jemand diese benötigt, ist die ehrliche Antwort ein Dateiziel und ein Synchronisierungstool und kein halbgebautes SDK.

Es funktioniert mit allem, was die S3-API spricht - MinIO, Ceph, Wasabi, Backblaze - weil es nur signierter HTTP ist. Das ist eine Nebenwirkung, die es wert ist, zu haben, da ein Krankenhaus-Objektspeicher oft nicht AWS ist.

Source: github.com/biodream-llc/perfuse/internal/s3put

26.85 saml

Exklusive XML-Kanonisierung (exc-c14n) per https://www.w3.org/TR/xml-exc-c14n/

Dies ist die byte-exakte kanonische Form, die eine XML-Signatur signiert. Wenn man es falsch macht, erscheinen gültige Signaturen ungültig und - schlimmer - eine Implementierung, die es größtenteils richtig macht, wird bei der eigenen Signatur im Test bestehen, während sie reale IdP-Antworten ablehnt.

Die Regeln, die für SAML zählen: - Namensraumdeklarationen werden nur dann gerendert, wenn sie vom Element oder seinen Attributen sichtbar verwendet werden. - Vererbte Namensräume, die ein Element verwendet, aber nicht deklariert, werden so gerendert, als ob sie auf diesem Element deklariert wären. - Attribute werden sortiert: Namensraumdeklarationen zuerst (nach Präfix sortiert), dann andere Attribute (nach erweitertem Namen: Namensraum-URI dann lokaler Name). - Leere Elemente verwenden Start-Tag/End-Tag, nie selbstschließend. - Textknoten werden wörtlich ausgegeben; CDATA wird durch seinen Inhalt mit Entity-Escaping ersetzt. - Verarbeitungsanweisungen und Kommentare außerhalb des Dokumentenelements werden ausgeschlossen.

Source: github.com/biodream-llc/perfuse/internal/saml

26.86 scim

Das Paket scim implementiert SCIM 2.0, das Protokoll, das Identitätsanbieter verwenden, um Konten bereitzustellen.

Okta, Entra ID, Google Workspace und OneLogin sprechen alle dieselbe Sprache. Ein Administrator fügt jemanden zu einer Gruppe im Identitätsanbieter hinzu und innerhalb einer Minute erscheint hier ein Konto mit der richtigen Rolle. Wenn er es entfernt, verschwindet das Konto.

Entzug der Berechtigung ist der entscheidende Punkt

Bereitstellung ist ein Komfort. Entzug der Berechtigung ist der Grund, warum dies wertvoll ist, und es ist die Hälfte, die schiefgeht.

Wenn jemand eine Organisation verlässt, ist der Identitätsanbieter das System, das es zuerst erfährt - in der Regel, weil HR den Mitarbeiter beendet und der Anbieter aus dem HR-Datensatz gesteuert wird. Es teilt dann allen verbundenen Anwendungen mit, das Konto zu deaktivieren. Wenn dieser Aufruf fehlschlägt oder erfolgreich ist, ohne den Zugriff tatsächlich zu entfernen, behält ein ehemaliger Mitarbeiter den Zugriff auf einen klinischen Integrations-Engine und niemand findet es heraus, weil nichts auf ein Ereignis wartet, das nicht eingetreten ist.

Die Teile dieses Pakets, die am meisten zählen, sind die, die den Entzug der Berechtigung realisieren:

Warum es ein separates Paket ist

SCIMs Formen sind nicht die von Perfuse. Es hat sein eigenes Fehlerformat, seine eigene Listenhülle, seine eigene Patch-Sprache und seine eigenen Meinungen über Attribut-Groß-/Kleinschreibung. Die Aufrechterhaltung der Übersetzung an einem Ort bedeutet, dass die Handler sich auf das konzentrieren können, was mit einem Konto passiert, anstatt sich auf JSON zu konzentrieren.

Source: github.com/biodream-llc/perfuse/internal/scim

26.87 Skript

Paket-Skript führt Mirth Connect JavaScript aus.

Das Ziel ist, dass die Skripte eines Kanals unverändert übertragen werden. Dies ist ein Kompatibilitäts- und kein Design-Übung, sodass die Form aller Dinge hier durch das diktiert wird, was Mirth bereitstellt: msg und tmp als E4X-Bäume, sechs Karten mit Java-Map-Methoden, die $-Familie von Lookup-Funktionen, logger und eine Handvoll von Hilfsobjekten, deren Methodennamen und Datum-Formatzeichenfolgen Java-sind.

Drei Entscheidungen sind unsere und nicht die von Mirth, und jede ist ein bewusster Abweg:

Ein Skript läuft mit einer Frist und wird unterbrochen, wenn es diese überschreitet. Mirth lässt ein Skript ewig laufen, was den Kanal mit sich reißt; eine Schnittstelle, die aufhört, Aufnahmen anzunehmen, weil ein Tippfehler in einem Transformer vorliegt, ist nicht akzeptabel, daher gibt es immer eine Zeitüberschreitung.

Java-Interoperabilität wird mit einem Fehler abgelehnt, der die Klasse nennt, anstatt undefined zurückzugeben. Ein Skript, das in Packages.java.sql greift, kann nicht zum Laufen gebracht werden, und das nützliche Ergebnis ist eine Meldung, die genau das an der Zeile angibt, an der es passiert, und nicht ein NullPointerException drei Zeilen später.

Datei- und Datenbankzugriff sind ausgeschaltet, es sei denn, ein Kanal schaltet sie ein. Mirth gewährt beiden Skripten standardmäßig Zugriff. Ein Transformer, der jede Datei lesen kann, auf die der Prozess zugreifen kann, ist ein vernünftiges Ding, das man sich wünschen kann, und ein unvernünftiger Standard.

Source: github.com/biodream-llc/perfuse/internal/script

26.88 Einstellungen

Paket-Einstellungen ist die einzige Beschreibung all dessen, was an einem Perfuse-Server geändert werden kann, was ein Operator ändern kann.

Warum es existiert

Bevor dieses Paket erstellt wurde, gab es ungefähr dreißig Dinge, die nur Befehlszeilen-Flags waren. Die Änderung der Aufbewahrungszeit von Nachrichten bedeutete, eine Dienstdefinition zu bearbeiten und neu zu starten, was in einem Krankenhaus einen Änderungsschein bedeutet - daher änderte in der Praxis niemand etwas, und ein Standard, der am ersten Nachmittag gewählt wurde, wurde zur Einstellung für immer.

Warum ein Register und keine Form

Die offensichtliche Art, eine Einstellungsseite zu erstellen, besteht darin, das Formular zu schreiben. Dies ergibt zwei Beschreibungen jeder Einstellung - eine im Server, der sie validiert, und eine in der Schnittstelle, die sie darstellt - und sie driftet auseinander. Die Drift ist leise: ein Feld, das der Server nicht mehr akzeptiert, hat immer noch eine Steuerung, sodass jemand es einstellt, es als gespeichert sieht und es nichts tut.

Einmal wird also eine Einstellung deklariert, hier, mit allem, was benötigt wird, um sie zu überprüfen und zu zeichnen: was für ein Wert es ist, welche Steuerung es passt, welche Gruppe es gehört, was es bedeutet und ob die Änderung sofort wirkt. Die Schnittstelle fragt nach dieser Beschreibung und zeichnet alles, was sie erhält. Das Hinzufügen einer Einstellung ist ein Eintrag in diesem Paket und keine Schnittstellenarbeit.

TestEverySettingIsFullyDescribed erzwingt die Teile, die ein Mensch liefern muss, da eine Einstellung ohne Hilfetext eine Einstellung ist, bei der jemand raten muss.

Warum eine Datei und keine Datenbank

Einstellungen leben in einer YAML-Datei, die die Schnittstelle direkt bearbeitet, was der Art und Weise entspricht, wie Kanäle und Warnregeln bereits funktionieren. Drei Gründe, in der Reihenfolge ihrer Bedeutung: die Änderungskontrolle eines Krankenhauses will eine Konfiguration, die diffed und in eine Versionskontrolle eingebracht werden kann; ein Operator mit der Maschine, aber nicht der Anwendung, kann eine Datei lesen und nicht eine Datenbank; und die Wiederherstellung der Einstellungen von gestern sollte nicht erfordern, dass die Anwendung funktioniert.

Warum nur Flags sie initialisieren

Die Datei gewinnt, sobald sie existiert, und Flags liefern den anfänglichen Inhalt. Die Alternative - Flags gewinnen immer - würde die Schnittstelle zu einem Lügner machen, da alles, was jemals auf einer Befehlszeile übergeben wird, bearbeitet und gespeichert und stillschweigend ignoriert werden kann.

Ein Flag, das mit der Datei nicht übereinstimmt, wird beim Start gemeldet, wobei beide Werte genannt werden, da das Flag sonst für Jahre im Dienstdefinitionssatz bleibt und die nächste Person, die es liest, es für richtig hält.

Source: github.com/biodream-llc/perfuse/internal/settings

26.89 sftpconn

Das Paket sftpconn öffnet SFTP-Verbindungen.

Aus den Konnektoren herausgelöst, da der interessante Teil die Authentifizierung und die Host-Schlüssel-Verifizierung ist und beides unabhängig davon ist, ob ein Kanal Dateien sammelt oder schreibt. Zwei Kopien würden auseinanderdriften, und die Hälfte, die auseinanderdriftet, wäre die Hälfte, die die Verifizierung einstellt.

Source: github.com/biodream-llc/perfuse/internal/sftpconn

26.90 Schatten

Das Paket shadow vergleicht einen Kandidatenkanal mit dem Live-Kanal.

Der Vergleich selbst ist der einfache Teil. Der ganze Wert liegt in zwei Garantien, und beide werden durch die Konstruktion und nicht durch die Konfiguration durchgesetzt:

Alles weniger als das und der Shadow-Modus wird zu einer Möglichkeit, die Produktion zu brechen, während man versucht, die Produktion nicht zu brechen.

Source: github.com/biodream-llc/perfuse/internal/shadow

26.91 shl

Das Paket shl implementiert SMART Health Links und SMART Health Cards: die QR-Codes, die CMS's "Kill the Clipboard" den Anbietern zum Akzeptieren bei der Anmeldung und zur Rückgabe mit dem Besuchsprotokoll anbietet.

Ein SMART Health Link (SMART Health Links STU 1) ist shlink:/ gefolgt von base64url JSON: eine Manifest-URL, ein 256-Bit-Schlüssel und optional ein Ablaufdatum, ein Label und Flags (P Passcode, L Langzeit, U eine einzelne Datei per GET). Der Empfänger postet an die Manifest-URL und erhält Dateien zurück, von denen jede mit diesem Schlüssel verschlüsselt ist - alg dir, enc A256GCM, optional DEFLATE-komprimiert - und FHIR-JSON, SMART Health Cards oder ein SMART-Zugriffstoken enthält. Der Server, der die Dateien hostet, sieht den Schlüssel nie: er reist nur im Link, der dem Patienten gehört.

Ein SMART Health Card (SMART Health Cards Framework 1.4) ist ein signierter FHIR-Bundle: ein kompaktes JWS, ES256, mit einem DEFLATE-komprimierten Payload, der den Aussteller benennt, dessen öffentlicher Schlüssel unter <iss>/.well-known/jwks.json zu finden ist. Es reist als numerischer shc:/ QR-Code oder als .smart-health-card-Datei.

Nur die Standardbibliothek: crypto/aes, crypto/cipher, crypto/ecdsa und compress/flate decken alles ab, und eine JOSE-Bibliothek würde eine viel größere Oberfläche für zwei Algorithmen mitbringen.

Source: github.com/biodream-llc/perfuse/internal/shl

26.92 smartauth

Das Paket smartauth ist ein SMART App Launch-Autorisierungsserver: es stellt die Zugriffstoken aus, die der FHIR-Endpunkt von Perfuse akzeptiert.

Geschrieben gegen die Standardbibliothek, wie internal/oidc, das überprüft, was dies signiert. Die Token sind JWTs, die mit RS256 signiert sind, dem einzigen Algorithmus, auf den jeder SMART-Client und die ID-Token-Regeln der Spezifikation zählen können.

Source: github.com/biodream-llc/perfuse/internal/smartauth

26.93 snmp

Das Paket snmp ist ein kleiner, schreibgeschützter SNMPv2c-Agent: GET, GETNEXT und GETBULK über UDP gegen eine Tabelle von Werten, die der Aufrufer füllt, und SNMPv2-Fallen.

Nachrichten sind hier BER (X.690) kodiert; nichts darin ist Kryptographie (die Community-Zeichenfolge von v2c ist ein Klartext-Passwort, was der Grund ist, warum der Agent nur den Netzwerken antwortet, die er angewiesen wird).

Source: github.com/biodream-llc/perfuse/internal/snmp

26.94 soap

Das Paket soap sendet SOAP-Anfragen und liest SOAP-Fehler, wobei nur die Standardbibliothek verwendet wird.

SOAP ist eine faire Menge Zeremoniell um einen HTTP-POST, und es ist immer noch die Art und Weise, wie eine große Menge Krankenhaus-Middleware Daten akzeptiert - Patientenverwaltungssysteme, Dokumenten-Repositorys, regionale Aufzeichnungsdienste, alles, was in dem Jahrzehnt spezifiziert wurde, als dies die Antwort war. Mirth hat einen Web-Service-Konnektor, also ist dies ein Tier-2-Migrationsblocker und kein Schönheitsfehler.

Warum kein generierter Client

Der übliche Ansatz ist, eine WSDL zu nehmen und Go-Typen daraus zu generieren. Das ist die richtige Antwort für eine Anwendung, die mit einem bekannten Dienst spricht, und die falsche Antwort hier: das Ziel eines Integrationsmotors wird von jemandem konfiguriert, der einen Kanal bearbeitet, und nicht neu kompiliert, sodass der Umschlag zur Laufzeit aus einer Vorlage zusammengestellt werden muss, die er sehen und ändern kann. Es bedeutet auch, dass es keinen Code-Generierungsschritt und nichts zu regenerieren gibt, wenn das entfernte Ende eine neue WSDL veröffentlicht.

Was dies absichtlich nicht tut

Keine WSDL-Parsing, kein WS-Sicherheit, kein MTOM, kein WS-Adressierung. Jedes davon ist eine Spezifikation für sich, und so zu tun, als würde man eine davon unterstützen, während man ein Detail falsch macht, ist schlimmer, als sie gar nicht anzubieten - eine Signatur, die fast verifiziert, ist nicht von einem Angriff am anderen Ende zu unterscheiden. WS-Sicherheit ist insbesondere der Bereich, in dem eine halbe Implementierung echten Schaden anrichten würde.

Was hier vorhanden ist: SOAP 1.1- und 1.2-Umschläge, ein templatisierter Textkörper, der SOAPAction-Header und eine Fehlererkennung, die die Fehlerzeichenfolge liest, anstatt "500" zu melden.

Source: github.com/biodream-llc/perfuse/internal/soap

26.95 sof

Das Paket sof führt SQL auf FHIR v2 ViewDefinitions aus: Eine Ansicht wandelt jedes FHIR-Ressourcen eines bestimmten Typs in Zeilen mit benannten Spalten um, indem FHIRPath verwendet wird, sodass FHIR-Daten von SQL-Engines, Tabellenkalkulationen und Qualitätsmessungen als Tabellen gelesen werden können.

Es folgt dem Verarbeitungsalgorithmus der ViewDefinition (Spalte, Auswählen, forEach, forEachOrNull, wiederholen, unionAll, wo, Konstanten, %rowIndex, getResourceKey und getReferenceKey) und wird gegen die offiziellen sql-on-fhir-Testfixtures überprüft.

Source: github.com/biodream-llc/perfuse/internal/sof

26.96 sqldb

Das Paket sqldb öffnet Datenbankverbindungen für die Datenquelle und -ziel.

Die Treiber werden hier und nirgendwo anders registriert, sodass es genau einen Ort gibt, der entscheidet, zu welchen Datenbanken Perfuse eine Verbindung herstellen kann.

Source: github.com/biodream-llc/perfuse/internal/sqldb

26.97 sqlitedb

Das Paket sqlitedb öffnet SQLite auf die Weise, wie ein Server es benötigt: eine Verbindung für Schreibvorgänge und mehrere für Lesevorgänge.

Der Grund dafür ist ein Fehlermodus, der nur dann auftritt, wenn eine Bereitstellung bereits eine Weile gelaufen ist. SQLite im WAL-Modus ermöglicht es Lesern, neben einem Schreiber zu laufen, aber Go's Verbindungspool sitzt über SQLite, sodass ein Pool von einem alles serialisiert, unabhängig davon, was die Datenbank zulässt. Ein Nachrichtenbrowser-Suchscan, der die Payload-Spalte scanniert, hält dann die einzige Verbindung, und jede ankommende Nachricht wartet dahinter.

Gemessen auf diesem Computer, dauert ein Schreibvorgang 104 µs, wenn der Speicher inaktiv ist, und 2,6 ms, während ein Suchscan vier Thousand Nachrichten scanniert: 25-mal langsamer. Das skaliert mit der Tabelle, sodass bei einigen hunderttausend gespeicherten Nachrichten ein Bericht in Sekunden Lieferverzögerung umgewandelt wird und ein Schreibvorgang auf dem Bestätigungspfad liegt. Der Absender sieht ein Timeout, sendet erneut, und jemand verbringt einen Morgen damit, nach einem Problem im Netzwerk zu suchen.

Die Aufteilung der Pools kostet nichts und entfernt die Interaktion: Berichte erhalten eigene Verbindungen, und der Schreiber behält eine für sich, weil SQLite genau einen Schreiber zulässt.

Source: github.com/biodream-llc/perfuse/internal/sqlitedb

26.98 Schritte

Deklarative Transformierungsschritte für jedes Nachrichtenformat.

Warum dies gemeinsam genutzt wird

Das Vokabular der Schritte - Setzen, Kopieren, Löschen, Zuordnen, Ersetzen, Trimmen, Groß-/Kleinschreibung, jedes mit einer Beschreibung und einer optionalen Bedingung - hat nichts mit einem bestimmten Format zu tun. Nur drei Dinge unterscheiden sich zwischen Formaten: Wie ein Pfad geschrieben wird, wie ein Wert gelesen wird und wie er zurückgeschrieben wird.

Dies ist dieselbe Schlussfolgerung, die die Filtergrammatik in internal/expr erreicht hat, und aus demselben Grund. X12 hatte einen Schrittmotor und NCPDP benötigte einen; das Kopieren hätte einen zweiten vierhundertzeiligen Motor zur Handhabung erzeugt, und dann einen dritten für durch Trennzeichen getrennte Formate. Das Verhalten, das es wert ist, zu haben, ist subtil genug, dass eine Kopie es nicht beibehalten würde - der Grund, warum das Ergebnis nach jedem Schreibvorgang erneut gelesen wird, zum Beispiel, wurde durch einen echten Defekt entdeckt.

Was ein Format liefert

Ein Accessor: ein Pfadcompiler, ein Bedingungscompiler und ein optionaler Veto auf Schritte, die er nicht erfüllen kann. Nichts anderes.

Source: github.com/biodream-llc/perfuse/internal/steps

26.99 stomp

Das Paket stomp spricht STOMP 1.2 mit einem Nachrichtenbroker.

Dies ist, was "JMS-Unterstützung" in einem Programm bedeuten muss, das nicht Java ist. JMS ist eine API und kein Protokoll, sodass es nichts zu implementieren gibt: Was ein Standort tatsächlich benötigt, ist, dass Perfuse mit dem Broker spricht, der hinter ihren JMS-Anwendungen sitzt.

STOMP anstelle von OpenWire, und die Begründung ist es wert, aufgezeichnet zu werden, weil die offensichtliche Antwort falsch ist. OpenWire ist ActiveMQs natives Protokoll und eine binäre Serialisierung von JMS-Befehlen - Wochen der Arbeit, spezifisch für eine Brokerfamilie, und undokumentiert, außer durch seine Implementierung. ActiveMQ erkennt automatisch STOMP, AMQP und MQTT auf demselben Port, auf dem es OpenWire ausführt, sodass ein Textprotokoll dieselben Broker erreicht. STOMP deckt ActiveMQ Classic, Artemis und RabbitMQ ab; AMQP 1.0 würde Azure Service Bus und IBM MQ hinzufügen und ist der sinnvollste nächste Schritt, anstatt OpenWire.

Geschrieben gegen die Standardbibliothek. Ein Broker-Client ist nicht der Ort für eine Abhängigkeit, deren Ausfallmodi jemand anderem zu erklären sind, und das Framing hier ist klein genug, dass es weniger kostet, es selbst zu besitzen, als den Issue-Tracker von jemand anderem zu lesen.

Source: github.com/biodream-llc/perfuse/internal/stomp

26.100 Speicher

Der Paket-Speicher enthält die Daten, die tatsächlich statusbehaftet sind: Benutzer, Sitzungen und eine Audit-Trail.

Kanäle sind absichtlich nicht hier enthalten. Sie leben in Dateien, weil das genau das bietet, was git, Diffs, Code-Review und Umgebungsweitergabe kostenlos bietet. Die Platzierung von Kanälen in einer Datenbank ist die Entscheidung, die jeden dieser Aspekte separat kaufen lässt, und sie ist der Grund, warum ein Drittanbieter-Produkt ausschließlich dazu dient, Mirth-Kanäle zwischen seiner Datenbank und einem git-Repository zu transportieren.

Die Aufteilung ist also: Konfiguration in Dateien, Identität und Historie in SQLite.

Source: github.com/biodream-llc/perfuse/internal/store

26.101 tefca

Das Paket tefca implementiert die Teile der TEFCA-Teilnahme, die keine QHIN-Verbindung erfordern.

Was real ist

Zweck-Validierung, Konfigurationsvalidierung und die Audit-Trail - einschließlich ihrer Persistenz, ihrer Abfrageschnittstelle und ihrer Verpflichtung, fehlgeschlagene Versuche sowie erfolgreiche aufzuzeichnen. Letzteres ist keine Formalität: Eine Reihe fehlgeschlagener Zustellungen an einen Empfänger ist der Weg, auf dem ein falsch konfigurierter Partner erkannt wird, und eine Reihe fehlgeschlagener Abfragen für verschiedene Patienten ist der Weg, auf dem ein Scanning erkannt wird.

Was nicht

Das Netzwerk. Es gibt in diesem Build keine QHIN-Transport, daher findet kein Austausch statt, und jede Austauschfunktion verweigert sich mit ErrExchangeNotImplemented, anstatt Erfolg zurückzugeben.

Diese Unterscheidung wurde nicht immer gezogen, und der Weg, auf dem es schiefging, ist es wert, beizubehalten. Alle vier Austauschfunktionen überprüften früher ihre Eingaben, machten keinen Netzwerkauf, und gaben Erfolg zurück; Deliver gab eine Akzeptiert-Antwort mit einem aus der Uhr erstellten Nachverfolgungs-Identifikator zurück. Die Audit-Schicht zeichnete dann jeden als abgeschlossenen Austausch auf - im Log, das existiert, um zu beweisen, was ausgetauscht wurde, wenn jemand Monate später fragt. Vier Tests behaupteten, dass dieses Verhalten aufwiesen und bestanden.

Was die Vervollständigung erfordert

Onboarding mit einem qualifizierten Gesundheitsinformationen-Netzwerk, gegenseitig authentifizierte TLS mit Zertifikaten, die durch diesen Prozess ausgestellt wurden, und entweder die IHE-Profile, mit denen die Common Agreement begann, oder Facilitated FHIR, wie es durch das Standardbetriebsverfahren des Sequoia-Projekts definiert ist, gültig ab 8. März 2026. Keiner davon kann spekulativ geschrieben werden: Es wird gegen ein reales QHIN getestet oder es wird nicht getestet, und eine ungetestete Austausch-Implementierung ist derselbe Defekt wie keine Implementierung mit einem besseren Verkleidung.

Source: github.com/biodream-llc/perfuse/internal/tefca

26.102 Mieter

Das Paket Mieter bietet die Identitäts- und Isolationsregeln für den Betrieb mit mehreren Mietern.

Ein HIE, ein Clearinghouse oder ein Managed-Service-Provider betreibt einen Motor im Auftrag vieler Organisationen. Mirth kann dies nicht - eine Instanz dient einer Organisation, und ein MSP endet damit, fünfzig JVMs und fünfzig Datenbanken zu betreiben.

Was ein Mieter besitzt

Seine Kanäle, als Verzeichnis von Dateien. Seine Benutzer. Seine Nachrichten, Warteschlange, Audit-Trail und FHIR-Ressourcen. Seine Metrik-Kennzeichnungen. Nichts wird geteilt, außer dem Prozess, den zugeteilten Lauschkontakten und den Plattform-Administratoren.

Isolation ist strukturell, nicht erinnert

Der gefährliche Fehler hier ist nicht ein Absturz. Es ist Mieter A, der die Nachrichten von Mieter B sieht, was ein meldepflichtiger Verstoß und kein Fehler ist. Ein Design, bei dem jede Abfrage einen Mieter-Id-Parameter benötigt, scheitert beim ersten Mal, wenn jemand eine Abfrage schreibt und einen vergisst, und diese Abfrage sieht in der Überprüfung perfekt aus.

Der Mieter ist also kein Parameter. Der Datenzugriff erfolgt über einen Handle, der ihn bereits enthält, und es gibt keine Möglichkeit, die Tabellen ohne einen zu erreichen. Vergessen ist nicht verfügbar.

Source: github.com/biodream-llc/perfuse/internal/tenant

26.103 Terminologie

Das Paket Terminologie hält veröffentlichte Code-Systeme (LOINC, SNOMED CT, RxNorm, ICD-10-CM, CPT und lokale) für das Nachschlagen von Codes und die Werte-Zuordnungstabellen, die nicht hatten, für jemanden, der zuordnen möchte.

Die Code-Systeme werden aus den Dateien importiert, die ihre Herausgeber verteilen. Einige sind lizenziert (LOINC benötigt ein kostenloses Konto, SNOMED CT eine Affiliate-Lizenz, RxNorm eine UMLS-Lizenz, CPT eine AMA-Lizenz), daher wird keiner mit Perfuse ausgeliefert: Ein Administrator, der die Lizenz hält, lädt die Datei hoch, und Perfuse zeichnet auf, wer sie importiert hat und wann.

Source: github.com/biodream-llc/perfuse/internal/terminology

26.104 tlsconf

Das Paket tlsconf erstellt eine TLS-Konfiguration aus Dateien und beschreibt Zertifikate.

Dies ist das kostenlose Äquivalent einer Erweiterung, für die Mirth nun Gebühren verlangt. Der größte Teil des Wertes liegt nicht in der Verschlüsselung, die nur wenige Zeilen umfasst, sondern im Teil, der verhindert, dass jemand etwas bereitstellt, das er für sicher hält, aber nicht ist: das Schweigen der Überprüfung zu verweigern, darauf zu bestehen, dass ein Clientzertifikat tatsächlich überprüft wird, wenn eines angefordert wird, und klar anzugeben, wenn ein Zertifikat bald abläuft.

Ein abgelaufenes Zertifikat auf einer Schnittstellen-Feed ist ein echter Krankenhaus-Ausfall, und das passiert, weil niemand informiert wurde. Der beschreibende Teil dieses Pakets existiert aus diesem Grund.

Source: github.com/biodream-llc/perfuse/internal/tlsconf

26.105 tomirth

Das Paket tomirth schreibt einen Perfuse-Kanal wieder als Mirth-Kanal-XML aus.

Warum es existiert. Der Einwand gegen die Annahme eines neuen Integrationsmotors ist selten "ist es gut". Es ist "was, wenn wir falsch liegen und feststecken", und die billigste Antwort darauf ist, wieder zurückgehen zu können. Perfuse hat seit Anbeginn Mirths Kanäle gelesen; bis jetzt konnte es keinen schreiben, was die Beruhigung einseitig und daher nicht sehr beruhigend machte.

Wie es der Falle ausweicht, die den ersten Versuch nutzlos machte. Mirths XML ist XStreams Ausgabe, und XStream liest die Klassen- und Versionsattribute als Anweisungen: ein Element, das es nicht erkennt, wird ohne ein Wort fallen gelassen, und ein Kanal, den es nicht zusammenbauen kann, wird mit seiner Beschreibung ersetzt durch "Dieser Kanal ist ungültig. Überprüfen Sie alle erforderlichen Erweiterungen, ob sie korrekt geladen sind" und seine Ziele verworfen. Nichts in dieser Antwort benennt das fehlerhafte Element. Ein Exporteur, der Eigenschaftsblöcke aus einer Lektüre des Formats komponiert, versagt auf die eine Weise, die teuer zu diagnostizieren ist, nämlich was passiert ist: dieses Repository trug einen Exporteur mit neun erfolgreichen Tests, dessen Ausgabe Mirth wegwarf, weil jeder Test es gegen unseren eigenen Parser verglich anstelle eines Servers.

Also werden hier keine Eigenschaftsblöcke komponiert. scripts/mirth-dump-connector-templates.sh hat Mirths eigenen ObjectXMLSerializer serialisieren die Standardwerte jeder Connector-Eigenschaftsklasse, und diese Dokumente werden unter templates/ committet. Dieses Paket ersetzt Werte in ihnen, und mirth.SetRawProperty weigert sich, jeden Pfad, den die Vorlage nicht bereits enthält - also ist ein Fehler ein Fehler beim Benennen des Pfads, im Moment des Exports, anstelle eines Kanals, der auf der Importierung verschwindet.

Was es nicht tun wird. Ein Transport, der keine Mirth-Äquivalenz hat, wird mit Namen abgelehnt, anstatt approximiert zu werden. Ein Export, der stillschweigend ein S3-Ziel in einen Dateischreiber umwandelt, wäre schlimmer als gar kein Export, weil der Kanal sauber importiert würde und an den falschen Ort liefern würde.

Source: github.com/biodream-llc/perfuse/internal/tomirth

26.106 trace

Das Paket trace erzeugt verteilte Spuren für Nachrichten, die durch einen Kanal bewegt werden, und exportiert sie über OTLP/HTTP mit der JSON-Codierung.

Warum es existiert, anstatt des OpenTelemetry-SDKs: das SDK plus ein OTLP-Exporteur zieht etwa sechzig Module heran und fügt etwa so viel zur Binärdatei hinzu wie das gesamte übrige Programm. Was hier tatsächlich benötigt wird, ist eng - W3C-Spur-Kontext-Propagierung, ein Span-Modell, Head-Sampling und ein batchter HTTP-POST - und OTLP/JSON ist eine dokumentierte stabile Codierung, die mit der Standardbibliothek allein produziert werden kann. Gleich wie bei der Wahl von lib/pq anstelle von pgx: das kleine Ding nehmen, wenn nur ein Teil des großen Dings gewollt ist.

Die Konsequenz, die erwähnt werden muss: es gibt keine Auto-Instrumentierung und keinen herstellerspezifischen Exporteur. Spans sind die, die dieses Programm absichtlich erstellt, und sie gehen zu jedem OTLP-Endpunkt - einem Collector, Jaeger, Grafana Tempo, Honeycomb, Datadogs OTLP-Import.

Die Eigenschaft, die wichtiger ist als die Spans

Eine Nachricht kommt häufig an, die einen traceparent-Header von dem System trägt, das sie gesendet hat, und verlässt in Richtung eines Systems, das einen eigenen aufzeichnen wird. Die Fortsetzung dieser Spur anstelle eines frischen Starts ist es, was eine einzelne Ansicht von "die EHR hat dies gesendet, der Motor hat es transformiert, das Register hat es abgelehnt" überhaupt möglich macht. Schnittstellenprobleme werden fast immer als "wir haben es gesendet und nichts ist passiert" gemeldet, und diese Frage ist ohne einen Identifikator, der den Hop überlebt, unbeantwortbar.

Spuren dürfen die Lieferung nie beeinflussen

Jeder Vorgang hier ist best-effort. Spans werden fallen gelassen, wenn der Puffer voll ist, Exportfehler werden gezählt und nie in den Nachrichtenpfad wiederholt, und kein Aufruf blockiert das Netzwerk. Ein fallengelassener Span ist eine Unannehmlichkeit. Eine Nachricht, die verzögert oder verloren wird, weil die Spur-Backend langsam war, ist ein klinischer Vorfall, also ist der Handel nie in Frage gestellt.

Source: github.com/biodream-llc/perfuse/internal/trace

26.107 transform

Das Paket transform wendet deklarative Änderungen an einer Nachricht an.

Dies ist die Schicht, die den normalen Arbeitsablauf tragen soll, wobei Skripting als markierter Notausgang gehalten wird. Die Unterscheidung ist nicht stilistisch. Ein Schritt, der in YAML deklariert ist, kann validiert werden, bevor er ausgeführt wird, in einer Differenz angezeigt werden, von jemandem überprüft werden, der kein JavaScript liest, und berichtet werden; ein Skript kann nur ausgeführt und gehofft werden. Die meisten Mirth-Transformer tun eigentlich Langweiliges - ein Feld kopieren, einen Identifikator auffüllen, einen Code durch eine Tabelle abbilden, etwas löschen, das das Gebäude nicht verlassen sollte - und all das gehört hierhin.

Jeder Schritt benennt sein Ziel explizit und jeder Schritt ist reversibel in dem Sinne, dass er sagt, was er getan hat, weil der teuerste Fehler in einer Schnittstelle eine Transformation ist, die niemand wusste, dass sie passiert.

Source: github.com/biodream-llc/perfuse/internal/transform

26.108 translate

Das Paket translate konvertiert einen Mirth-Kanal in eine Perfuse-Kanal-Definition.

perfuse explain berichtet, was eine Migration blockiert. Dies führt den größten Teil der Migration durch, was ein anderer und viel größerer Anspruch ist, daher ist es bewusst konservativ, was es behaupten wird.

Drei Regeln prägen das gesamte Konzept.

Nichts wird stillschweigend fallen gelassen. Jeder Teil des Quellkanals wird entweder übersetzt, wörtlich als Skript übernommen oder als benötigend einer menschlichen Intervention gemeldet. Ein Übersetzer, der stillschweigend einen Schritt auslässt, würde einen Kanal erzeugen, der startet, läuft und Daten verliert - das schlechteste mögliche Ergebnis und der Grund, warum Menschen Migrationstools misstrauen.

Deklarativ, wo es sicher ist, Skript, wo es nicht ist. Ein Mapper-Schritt, der ein Feld kopiert, wird zu einem deklarativen Schritt, weil dies lesbar und überprüfbar ist. Ein JavaScript-Schritt wird zu einem Skript, weil Perfuse Mirths JavaScript unverändert ausführt und es in etwas umzuschreiben, das gleichwertig aussieht, genau der Punkt ist, an dem ein Übersetzer eine Differenz einführen würde, die niemand bemerkt.

Die Ausgabe ist dazu gedacht, gelesen zu werden. Sie enthält Kommentare, die erklären, woher etwas stammt und was für eine Person übrig bleibt. Eine Migration wird von jemandem überprüft, der sie abzeichnen muss, und eine unkommentierte Wand aus YAML kann nicht überprüft werden.

Source: github.com/biodream-llc/perfuse/internal/translate

26.109 udap

Paket udap implementiert die Client-Hälfte von HL7-Sicherheit für skalierbare Registrierung, Authentifizierung und Autorisierung - die Spezifikation, auf der TEFCA-Facilitated FHIR-Austausch basiert.

UDAP ist eine Public-Key-Infrastruktur, die auf OAuth 2.0 aufgesetzt ist. Eine Vertrauensgemeinschaft stellt ihren Mitgliedern X.509-Zertifikate aus; ein Mitglied beweist, wer es ist, indem es JWTs mit dem privaten Schlüssel signiert und die Zertifikatkette im JWT-Header anhängt. Das ersetzt das gemeinsame Client-Geheimnis des normalen OAuth, das nicht für Tausende von Organisationen skaliert, die sich nie getroffen haben.

Warum dieses Paket überhaupt existiert. TEFCA-Austausch kann nicht vollständig verifiziert werden, ohne einen echten QHIN zu haben: dem Beitreten benötigt man Onboarding und ausgestellte Zertifikate, und es kann nicht gefälscht werden. Aber das Sicherheitsprofil darunter ist ein veröffentlichter HL7-Implementierungsleitfaden mit öffentlichen Referenzservern, und einer von ihnen antwortet im offenen Internet. Also wird der Teil, der verifiziert werden kann, hier verifiziert, und der Teil, der nicht verifiziert werden kann, wird an der Grenze abgelehnt, anstatt geraten zu werden.

Die Unterscheidung ist wichtig, weil von dem, was mit SAML in diesem Repository passiert ist: tausend Zeilen Tests sind bestanden, fünf davon speziell über Signatur-Kanonisierung, während kein echter Identitätsanbieter jemanden authentifizieren konnte. Beide Hälften waren hier geschrieben und stimmten miteinander überein. Die Lehre, die daraus gezogen wurde, ist, dass eine Sicherheitsimplementierung nichts wert ist, bis etwas, das jemand anderes geschrieben hat, es akzeptiert oder abgelehnt hat.

Spezifikationsverweise: - HL7 UDAP Sicherheit STU 1: http://hl7.org/fhir/us/udap-security/STU1/ - TEFCA SOP Facilitated FHIR Implementation v2.0, gültig ab 8. März 2026

Source: github.com/biodream-llc/perfuse/internal/udap

Das Paket umlink überträgt X12-278s an ein Nutzungsmangement-System eines Zahlers und dessen Antworten, die Wege, auf denen diese Systeme in der Praxis erreicht werden: X12 im Body eines HTTPS-POST; CAQH-CORE-SOAP-Envelope (Connectivity-Regel vC2.2.0, die meisten Zahlern und CMS-Systeme verwenden esMD, und vC4.0.0); CAQH-CORE-HTTP-MIME-Multipart-Envelope (vC2.2.0); und Batch-Dateien über SFTP.

Es wurde aus den veröffentlichten Konnektivitätsregeln von CAQH (vC2.2.0 und vC4.0.0), deren XML-Schema und WSDL sowie dem esMD-X12N-278-Begleitleitfaden von CMS erstellt. Es ist nicht CORE-zertifiziert: Die Zertifizierung wird von den autorisierten Testanbietern von CAQH durchgeführt.

Die Echtzeit-Verbindungen geben die Antwort des UM-Systems zurück, die möglicherweise eine 278-Antwort oder, wenn es die Anfrage nicht lesen konnte, eine 999- oder TA1-Antwort ist: Der Aufrufer liest sie aus. Die Batch-Verbindung gibt ErrAnswerLater zurück, sobald die Datei geliefert wurde, und Poll sammelt, was zurückkommt.

Source: github.com/biodream-llc/perfuse/internal/umlink

26.111 v2fhir

Paket v2fhir ordnet HL7-v2-Nachrichten FHIR-Ressourcen zu.

Die Zuordnung ist der Punkt, an dem Interoperabilitätsprojekte tatsächlich fehlschlagen, daher werden die Regeln, die dieses Paket befolgt, ausdrücklich genannt und nicht impliziert:

Source: github.com/biodream-llc/perfuse/internal/v2fhir

26.112 vcs

Paket vcs liest die Historie von Kanaldateien aus git.

Kanalhistorie ist eine kostenpflichtige Erweiterung anderswo, und sie ist eine kostenpflichtige Erweiterung, weil diese Motoren Kanäle in einer Datenbank speichern, sodass die Nachverfolgung von Änderungen bedeutet, ein Änderungsverfolgungssystem zu bauen. Perfuse speichert Kanäle in Dateien, daher existiert die Historie bereits und seit dem ersten Commit. Dieses Paket muss sie nur lesen.

Es ruft git auf, anstatt eine git-Bibliothek einzubetten. Die Bibliothek würde eine große Abhängigkeit zu einem Binär hinzufügen, dessen Verkaufspunkt darin besteht, vier zu haben, und es würde nichts kaufen: eine Bereitstellung, die ihre Kanäle unter Versionskontrolle hält, hat git installiert, und eine, die es nicht tut, erhält eine klare "kein git-Repository"-Meldung, anstatt eine subtil unterschiedliche Implementierung desselben.

Source: github.com/biodream-llc/perfuse/internal/vcs

26.113 vfs

Paket vfs ist die kleine Menge an Dateioperationen, die ein Polling-Connector benötigt.

Warum eine Schnittstelle anstelle von vier Connectors

Perfuse sammelt Dateien von einem lokalen Datenträger, einem SFTP-Server, einem FTP-Server, einem Windows-Freigabe und einem WebDAV-Server. Der Transfer unterscheidet sich in jedem Fall. Alles, was tatsächlich entscheidet, ob Nachrichten überleben, nicht:

Geschrieben einmal pro Transport, wären diese Regeln subtil unterschiedlich fünfmal, und die Unterschiede würden nur als fehlende Nachrichten an einem Standort erscheinen. Sie werden also einmal hier geschrieben, über die kleinste Schnittstelle, die sie unterstützt.

Was hier absichtlich nicht ist

Keine Schreiboperationen, außer was für die Entsorgung benötigt wird. Das Senden von Dateien ist ein anderes Problem mit anderen Fehlermodi - eine teilweise geschriebene Datei am entfernten Ende, die die vorhandenen Sender durch das Schreiben in einen temporären Namen und das Umbenennen behandeln. Das Kombinieren beider Richtungen in einer Schnittstelle würde jede davon schwerer verständlich machen.

Keine Rekursion. Ein Poller, der in Unterordner absteigt, sammelt das Archivverzeichnis, in das er gerade eine Datei verschoben hat.

Source: github.com/biodream-llc/perfuse/internal/vfs

26.114 vpn

Das Paket vpn meldet den Zustand der Site-to-Site-VPN-Tunnel, über die der Partnerverkehr läuft - AWS Site-to-Site-VPN, Azure-VPN-Gateway-Verbindungen und strongSwan - und hält für jeden Partner ein Verbindungsbogen: die Tunnel-Einstellungen beider Seiten und ob sie übereinstimmen.

Ein Tunnel, der down ist, sieht aus der Sicht eines Integrationsservers genau wie ein Partner aus, dessen Server gestoppt wurde: Verbindungen time out. Wenn man stattdessen sagt, „der Tunnel ist down“, liegt der Unterschied darin, ob man das Netzwerkteam oder den Partner anruft.

Nur Lesen. Nichts hier ändert einen Tunnel, und kein Pre-Shared-Schlüssel wird jemals gelesen, gespeichert oder angezeigt.

Source: github.com/biodream-llc/perfuse/internal/vpn

26.115 web

Das Paket web dient die gebaute Frontend-Oberfläche aus der Binärdatei.

Die Assets sind eingebettet, anstatt nebenbei geliefert zu werden, so dass die Bereitstellung bei einer Datei bleibt. Das ist der gleiche Grund, warum der Server cgo vermeidet: ein Operator sollte in der Lage sein, eine Binärdatei auf einen Server zu kopieren und sie auszuführen, ohne JVM, ohne Installer und ohne Asset-Verzeichnis, das mit dem Ausführbaren aus dem Takt geraten könnte.

Die gebaute Ausgabe wird committet, damit go build auf einem Checkout ohne Node-Installation funktioniert. Rebuilden Sie es mit make web.

Source: github.com/biodream-llc/perfuse/internal/web

26.116 webauthn

Das Paket webauthn überprüft Passwörter.

Ein Passwort ist ein Schlüsselpaar, das der Authentifizierer hält - Touch ID, Windows Hello, ein YubiKey, ein Telefon - wobei die private Hälfte nie das Gerät verlässt. Das Anmelden bedeutet, dass der Server eine zufällige Herausforderung sendet, der Authentifizierer sie nach Überprüfung, ob der Benutzer anwesend ist, signiert und der Server die Signatur gegen den öffentlichen Schlüssel überprüft, den er bei der Registrierung gespeichert hat.

Die Eigenschaft, die zählt, ist nicht, dass es bequem ist. Es ist, dass es nichts zu phishen gibt. Ein Passwort kann in eine überzeugende Kopie einer Anmeldeseite eingegeben werden; eine Passwort-Signatur ist an den Ursprung gebunden, für den sie erstellt wurde, so dass die Kopie eine Signatur erhält, die ihr Server nicht verwenden kann. Für einen Integrationsserver, der die Schnittstellen eines Krankenhauses hält, ist das der Unterschied, der es wert ist, ihn zu haben.

Was diese Implementierung verweigert zu tun

Die Spezifikation ist an einigen Stellen permissiv, an denen Permissivität dazu führt, dass Implementierungen gebrochen werden. Diese ist es nicht:

Source: github.com/biodream-llc/perfuse/internal/webauthn

26.117 winservice

Das Paket winservice führt Perfuse als Windows-Dienst aus.

Diese Datei ist die andere Hälfte. Sie existiert, damit cmd/perfuse in dieses Paket aufrufen kann, ohne jeden Aufrufort in einen Build-Tag einwickeln zu müssen: der Subbefehl wird immer kompiliert, und auf Linux oder macOS erklärt er, dass Dienste ein Windows-Konzept sind und nicht fehlschlagen, anstatt nicht zu existieren.

Ein Ablehnen mit einem klaren Satz ist besser als das Verstecken des Subbefehls. Jemand, der Windows-Anweisungen auf dem falschen Computer befolgt, wird darüber informiert, was tatsächlich vor sich geht, und das Äquivalent für seine Plattform.

Source: github.com/biodream-llc/perfuse/internal/winservice

26.118 x12

Lesen und Schreiben von Werten an einem Pfad.

Warum dies separat von Pfad ist

path.go entscheidet, was ein Pfadausdruck bedeutet. Diese Datei löst einen gegen einen tatsächlichen Austausch auf. Getrennt gehalten, weil die Analyse-Regeln lesbar sind, ohne die Byte-Verarbeitung, und weil der Parser vom Konfigurations-Validator verwendet wird, der keine Nachricht hat, gegen die er aufgelöst werden kann.

Warum ein Schreiben neu analysiert, anstatt Bytes an Ort und Stelle zu bearbeiten

Segment-Elemente sind Teil-Slices von Segment.raw und Message.segs indexiert in Message.raw. Das Bearbeiten eines Wertes an Ort und Stelle ändert die Länge von allem, was danach kommt, so dass alle diese Slices angepasst werden müssten, und jeder, der übersehen wird, liest korrekt, bis zu der einen Nachricht, bei der es nicht funktioniert.

Ein Schreiben baut also das Segment neu auf, baut den Austausch neu auf und analysiert es erneut. Das kostet eine Analyse pro geänderter Nachricht und kauft die Garantie, dass eine von hier zurückgegebene Nachricht genau das ist, was die Analyse ihrer eigenen Bytes produziert. Es gibt keinen Zustand, in dem die Indizes und die Bytes nicht übereinstimmen, weil dieser Zustand nicht darstellbar ist.

Source: github.com/biodream-llc/perfuse/internal/x12

26.119 x12xml

Das Paket x12xml wandelt X12 (und andere durch Trennzeichen getrennte EDI) in das XML um, das Mirth Connect und Open Integration Engine dafür schreiben, und zurück.

Warum dieses XML und nicht eines von uns

Der Zweck einer XML-Form von X12 sind die Systeme, die bereits eine solche verwenden. Ein Standort, der von Mirth wechselt, hat Empfänger, die gegen das von Mirths EDI/X12-Datentyp ausgegebene Format gebaut sind, Skripte, die msg['CLM']['CLM.05']['CLM.05.1'] durchlaufen, und upstream-Engines, die X12 in diesem XML-Format senden. Eine sauberere Form von unserem eigenen Format würde ihnen nicht dienen. Dieses Paket schreibt also genau das, was Open Integration Engine 4.6 schreibt, und liest genau das, was es liest, und die Tests vergleichen die beiden byte für byte mit OIEs eigenem Serializer.

Eine frühere Version dieses Pakets hat sein eigenes Format erfunden (eine X12-Interchange-Wurzel, Elemente mit dem Namen CLM05) und behauptet, es entspreche Mirths Format. Es entsprach jedoch nicht; es wurde nie mit Mirth verglichen und nichts in Perfuse verwendet es.

The format

Die Wurzel ist X12Transaction, wenn die Nachricht mit einem ISA-Segment beginnt, und EDIMessage sonst, wobei die drei Trennzeichen als Attribute (segmentDelimiter, elementDelimiter, subelementDelimiter) übertragen werden. Jedes Segment ist ein Element, das nach seinem Identifier benannt ist. Jedes Daten-Element ist SEG.NN, nummeriert ab 01 (ISA.01, CLM.05), und enthält seine Komponenten als SEG.NN.1, SEG.NN.2 usw.: immer mindestens SEG.NN.1 für ein Element mit einem Wert, keines für ein leeres Element.

Die Trennzeichen werden aus dem ISA gelesen, wenn vorhanden: der Elementtrenner aus Position 3, der Komponententrenner aus Position 104 und der Segmentbeender aus Position 105, wobei ein nachfolgender Zeilenvorschub als Teil davon gezählt wird. Andernfalls sind sie ~ * und :. Der Wiederholungstrenner (ISA11) wird nicht interpretiert, was auch OIEs Verhalten ist: ein wiederholtes Element behält sein ^ innerhalb eines Wertes bei.

Dies ist eine Neuumsetzung des Verhaltens, geschrieben durch die Beobachtung von OIEs Ausgabe und aus seinem dokumentierten Format; kein Code von Mirth ist darin enthalten.

Source: github.com/biodream-llc/perfuse/internal/x12xml

26.120 xds

Paket xds ist IHE cross-enterprise document sharing: ein XDS.b-Dokument-Register und -Repository (ITI-41 Provide and Register, ITI-18 Registry Stored Query, ITI-43 Retrieve Document Set), ein XCA-Responding-Gateway über den gleichen Store (ITI-38, ITI-39) und die Client-Seite von jedem, so dass ein Channel ein Dokument an das Repository einer anderen Organisation veröffentlichen und die Konsole ein Register oder eine Community abfragen kann.

Die Metadaten sind ebXML-Registry 3.0 (ebRIM), wie XDS.b es in IHE ITI TF-3 Kapitel 4 definiert. Es wird hier als Go-Structs modelliert, deren XML-Tags die Namespaces tragen, so dass eine Nachricht gleich gelesen wird, unabhängig von den Präfixen, die der Absender gewählt hat, und namespace-korrekter geschrieben wird.

Source: github.com/biodream-llc/perfuse/internal/xds

26.121 xmldsig

Paket xmldsig implementiert XML-Digitale Signaturen und das XAdES-Profil davon.

Warum dies geschrieben wird, anstatt entlehnt zu werden

Ein signiertes klinisches Dokument ist ein rechtliches Artefakt. Es behauptet, dass eine benannte Person, zu einem benannten Zeitpunkt, die Verantwortung für einen bestimmten Satz von Bytes übernommen hat. Es falsch zu machen, in beide Richtungen, ist ernst: eine Signatur, die nicht verifiziert werden kann, macht ein gültiges Dokument wie gefälscht aus, und ein Verifizierer, der zu großzügig ist, akzeptiert ein Dokument, das jemand geändert hat.

Kanonisierung ist das ganze Problem

XML hat viele Byte-Folgen, die das gleiche bedeuten. Attribut-Reihenfolge ist nicht signifikant, Namespace-Präfixe können umbenannt werden, leere Elemente können auf zwei Arten geschrieben werden und Whitespace innerhalb eines Tags ist frei. Eine Signatur ist über Bytes, so dass beide Enden vor dem Hashen einer Nachricht genau eine Byte-Folge für ein bestimmtes Dokument vereinbaren müssen. Diese Vereinbarung ist die Kanonisierung, und sie ist der Punkt, an dem Implementierungen falsch liegen, weil jeder Fehler eine Signatur produziert, die gegen die eigene Ausgabe verifiziert und gegen die Ausgabe aller anderen fehlschlägt.

Dieses File ist also die Kanonisierung, für sich allein, mit eigenen Tests. Nichts über das Signieren erscheint hier.

Exklusiv anstelle von inklusiv, standardmäßig

Inklusive Kanonisierung zieht jede Namespace-Deklaration ein, die im Umfang ist, einschließlich derer, die das signierte Element nie verwendet. Das macht eine Signatur kaputt, wenn das Dokument später in etwas eingebettet wird, das eine nicht verwandte Namespace-Deklaration auf einem Vorfahren deklariert, was genau das ist, was passiert, wenn ein CDA in eine SOAP-Hülle oder einen IHE-Metadaten-Wrapper eingebettet wird. Exklusive Kanonisierung umfasst nur die Deklarationen, die das Element tatsächlich verwendet, und ist das, was Dokument-Austausch-Profile aus diesem Grund spezifizieren.

Source: github.com/biodream-llc/perfuse/internal/xmldsig

26.122 xtree

Paket xtree ist ein mutabler XML-Tree.

Drei sehr unterschiedliche Funktionen müssen XML modifizieren: HL7-Transformationen, die Mirth als XML modelliert, weil ihre Skripte darauf operieren; klinische Dokumente, die nativ XML sind; und die deklarativen Transformationschritte. Sie teilen sich diesen einen Baum, anstatt dass jeder seinen eigenen wachsen lässt, weil die Alternative drei Modelle wären, die sich über die Bedeutung eines leeren Elements nicht einig sind.

Das Designziel ist die Treue zur E4X-Semantik, da Mirth-Skripte E4X sind und der ganze Zweck des unveränderten Ausführens darin besteht, dass sie sich gleich verhalten. Das bestimmt zwei Entscheidungen, die sonst seltsam aussehen würden: ein Knoten behält einen Zeiger auf seinen Elternteil, weil E4X parent() exposeiert, und Kinder sind geordnet mit erlaubten Duplikaten, weil eine HL7-Feldwiederholung buchstäblich ein wiederholtes Element ist und Skripte darauf über die Position zugreifen.

Source: github.com/biodream-llc/perfuse/internal/xtree

26.123 Paket pas liest Da Vinci Priorisierungsunterstützungsanfragen (PAS).

Das Paket pas liest Da Vinci Priorisierungsunterstützungsanfragen (PAS)-Anfragebündel.

Es ist der Leser, den der eigene PAS-Server von Perfuse verwendet, der veröffentlicht wird, damit das, was eine vorherige Autorisierung entscheidet - die Regeln eines Zahlungspflichtigen, ein System für die Nutzungsbewirtschaftung, ein Entscheidungsdienst wie Vaglio - eine Anfrage mit dem gleichen Code liest und somit die gleichen Antworten darüber gibt, was eine Anfrage enthält. Zwei Leser eines Nachrichtenformats sind zwei Meinungen darüber.

Es hat keine Abhängigkeiten außerhalb der Standardbibliothek. Eine Anfrage wird als decodiertes JSON (map[string]any) und nicht als typisierte Ressourcen gespeichert, weil ein PAS-Bündel alle unterstützenden Ressourcen enthält, die der Anbieter zum Senden ausgewählt hat, und ein Leser, der das wegwirft, was er nicht modelliert, Beweise vor der Entscheidung verbergen würde.

req, problems := pas.Lese(bündel, false) wenn len(problems) > 0 { // verweigern: die Anfrage kann nicht korrekt beantwortet werden } für _, svc := range req.Dienste() { // svc.Codes, svc.Artikel und req.Lösen für alles, auf das der Artikel verweist }

Source: github.com/biodream-llc/perfuse/pas

27 Index der Konfigurationsschlüssel

Jeder Schlüssel in alphabetischer Reihenfolge, mit den Blöcken, in denen er erscheinen kann. Ein Schlüssel, der in mehreren Blöcken erscheint, bedeutet in jedem von ihnen das gleiche; wo er nicht erscheint, werden die Blöcke separat dokumentiert und der Unterschied wird dort angegeben.

27.1 Alle Schlüssel

SchlüsselVorkommen in
access_key_idAWS-Zugriff, FHIR-Authentifizierung, S3-Ziel
accountAzure-Blob-Zugriff
ackHTTP-Quelle, SOAP-Quelle, Quelle
ack_sender_idX12-Optionen
ack_sender_qualifierX12-Optionen
acknowledgeEDIFACT-Optionen, HL7v3-Optionen, X12-Optionen
acksKafka-Ziel
actionSOAP-Ziel
addrAMQP-Verbindung, Broker-Ziel, Broker-Quelle, MQTT-Verbindung
addressAMQP-Verbindung, DICOM-Ziel, DICOM-Abfrage-Quelle, Ziel, Direkte Adresse, TCP-Ziel
ae_titleDICOM-Quelle
after_queryDatenbank-Quelle
after_readAzure-Blob-Quelle, Direkte IMAP, E-Mail-Quelle, Datei-Abfrage, GCS-Quelle, S3-Quelle, SFTP-Quelle
allowSkripte
allow_clear_passwordFTP-Ziel
allow_unencryptedAS2-Partner, PGP-Empfang
allow_unsignedAS2-Partner
allowed_calling_aeDICOM-Quelle
allowed_sendersE-Mail-Quelle
amqpZiel, Quelle
anchors_fileDirekte Adresse
api_versionIBMMQ-Verbindung
appendZiel, SFTP-Ziel
applicationBestätigung
armorPGP-Versand
arrives_asX12-Optionen
as2Ziel, Quelle
attachSMTP-Ziel
attach_nameDirektes Ziel, SMTP-Ziel
attachment_namesE-Mail-Quelle
attachmentsKanal
attemptsWiederholung
authFHIR-Ziel, PAS-Ziel
authoritiesMPI-Ziel
azure_blobZiel, Quelle
backoffWarteschlangen-Konfiguration, Wiederholung
base64SOAP-Quelle
batch_sizeDatenbank-Quelle, Datei-Abfrage
baudSerielle Quelle
bccSMTP-Ziel
bearer_tokenCDA-Ziel, FHIR-Ziel, HTTP-Ziel, PAS-Ziel
big_endianTCP-Rahmen
blobAzure-Blob-Ziel
bodySMTP-Ziel, SOAP-Ziel
brokerZiel, Quelle
brokersKafka-Ziel, Kafka-Quelle
bucketGCS-Zugriff, S3-Ziel, S3-Quelle
bundle_scriptFHIR-Ziel
called_aeDICOM-Ziel, DICOM-Abfrage-Quelle
calling_aeDICOM-Ziel, DICOM-Abfrage-Quelle
ccSMTP-Ziel
cdaZiel
cert_fileAS2-Ziel, AS2-Partner, AS2-Quelle, Direkte Adresse
channelZiel, Schatten
check_everyVertrags-Verweis
cityECR-Einrichtung
claim_us_coreFHIR-Ziel
classXDS-Ziel
client_ca_fileDirekte XDR
client_idE-Mail-O-Auth, FHIR-Authentifizierung, MQTT-Verbindung
client_secretE-Mail-O-Auth, FHIR-Authentifizierung
codeXDS-Code
columnDatenbank-Quelle
columnsBegrenzt
commentBegrenzt
commit_after_deliveryKafka-Quelle
compareSchatten
compressAS2-Ziel
compressionKafka-Ziel
configELR-Ziel
containerAzure-Blob-Zugriff
content_typeAMQP-Ziel, AS2-Ziel, Azure-Blob-Ziel, Broker-Ziel, GCS-Ziel, HTTP-Ziel, S3-Ziel, XDS-Ziel
contractKanal
credentials_fileGCP-Zugriff
dataTypeKanal
data_bitsSerielle Quelle
databaseZiel, Quelle
decrypt_withPGP-Empfang
default_identifier_systemFHIR-Ziel
delimitedKanal
delimiterBegrenzt, TCP-Rahmen
deploySkripte
descriptionKanal
destinationBroker-Ziel, Broker-Quelle
destinationsKanal
dicomKanal, Ziel, Quelle
dicom_queryQuelle
dicomwebZiel, Quelle
dirCDA-Ziel, Ziel, Dokument-Ziel, FTP-Ziel, Datei-Abfrage, SFTP-Ziel, SFTP-Quelle
directZiel, Quelle
direct_fromXDS-Ziel
direct_toXDS-Ziel
displayXDS-Code
dnsDirektes Ziel
documentZiel
domainSMB-Quelle
driverDatenbank-Ziel, Datenbank-Quelle
dsnDatenbank-Ziel, Datenbank-Quelle
duplicate_windowAS2-Quelle
ecrFHIR-Ziel
edifactKanal
elementSOAP-Quelle
elrZiel
emailQuelle
emit_on_first_pollDICOM-Abfrage-Quelle
enabledKanal, Ziel, Warteschlangen-Konfiguration
encrypt_toPGP-Versand
endpointAWS-Zugriff, Azure-Blob-Zugriff, GCP-Zugriff, S3-Ziel
envelopeEDIFACT-Optionen, X12-Optionen
error_dirDatei-Abfrage, SFTP-Quelle
error_folderDirekte IMAP, E-Mail-Quelle
error_prefixAzure-Blob-Quelle, GCS-Quelle, S3-Quelle
expect_replyTCP-Ziel
extractAnhänge
facilityBestätigung, ECR-Einrichtung
facility_idSOAP-Ziel
facility_typeXDS-Ziel
fail_on_bodyHTTP-Ziel
fault_is_successSOAP-Ziel
fault_on_nakSOAP-Quelle
fhirZiel
fileVertrags-Verweis, Quelle
file_nameAS2-Ziel, Ziel, Dokument-Ziel, FTP-Ziel, PGP-Versand, SFTP-Ziel
file_rootsSkripte
filterKanal, Begrenzt, Ziel, HL7v3-Optionen, Skripte
flow_controlSerielle Quelle
follow_redirectsHTTP-Ziel
follow_symlinksDatei-Quelle
font_sizeDokument-Ziel
formatDokument-Ziel, S3-Ziel
framedAzure-Blob-Quelle, FTP-Ziel, Datei-Abfrage, GCS-Quelle, S3-Ziel, S3-Quelle, SFTP-Ziel, SFTP-Quelle
framingTCP-Rahmen
fromAS2-Ziel, SMTP-Ziel
from_beginningKafka-Quelle
ftpZiel, Quelle
gcsZiel, Quelle
groupKanal, Kafka-Quelle
group_bySNS-Ziel, SQS-Ziel
has_headerBegrenzt
headerSOAP-Ziel
headersBroker-Ziel, CDA-Ziel, DICO Mweb-Ziel, FHIR-Ziel, HTTP-Ziel, Kafka-Ziel, SOAP-Ziel, XDS-Ziel
heartbeatBroker-Quelle
hl7v3Kanal
hostBroker-Ziel, Broker-Quelle, Direkte IMAP, E-Mail-Quelle, FTP-Ziel, FTP-Quelle, SFTP-Ziel, SFTP-Quelle, SMB-Quelle, SMTP-Ziel
hostnameAMQP-Verbindung
httpZiel, Quelle
ibm_mqZiel, Quelle
idAS2-Partner, AS2-Quelle
id_typeMPI-Ziel
identifier_systemsCDA-Ziel, FHIR-Ziel
idle_timeoutDICOM-Quelle, Quelle, TCP-Quelle
ignoreSchatten
imapDirekte Quelle
includeSkripte
include_trigger_eventBestätigung
insecure_skip_host_key_checkSFTP-Ziel, SFTP-Quelle
insecure_skip_verifyFTP-Ziel, FTP-Quelle, SMTP-Ziel, Web DAV-Quelle
intervalDICOM-Abfrage-Quelle
javascriptZiel, Quelle
kafkaZiel, Quelle
keep_aliveTCP-Ziel
keep_blank_linesBegrenzt
keep_delimiterTCP-Rahmen
keyAzure-Blob-Zugriff, Kafka-Ziel, S3-Ziel
key_columnDatenbank-Quelle
key_fileAS2-Ziel, AS2-Quelle, Direkte Adresse, SFTP-Ziel, SFTP-Quelle
key_passphraseSFTP-Ziel, SFTP-Quelle
known_hosts_fileSFTP-Ziel, SFTP-Quelle
landscapeDokument-Ziel
languageSkripte
ldapDirektes Ziel
length_bytesTCP-Rahmen
length_includes_headerTCP-Rahmen
levelDICOM-Abfrage-Quelle
limitDICOM-Abfrage-Quelle
lineECR-Einrichtung
listenAS2-Quelle, DICO Mweb-Quelle, DICOM-Quelle, Direkte Quelle, Direkte XDR, HTTP-Quelle, SOAP-Quelle, Quelle, TCP-Quelle
loginBroker-Ziel, Broker-Quelle
mailboxDirekte IMAP, E-Mail-Quelle
matchDICOM-Abfrage-Quelle
max_attemptsDatenbank-Quelle, Warteschlangen-Konfiguration
max_backoffWarteschlangen-Konfiguration, Wiederholung
max_bytesDirekte Quelle
max_connectionsQuelle, TCP-Quelle
max_depthWarteschlangen-Konfiguration
max_differencesSchatten
max_file_sizeDatei-Abfrage, SFTP-Quelle
max_message_sizeAS2-Quelle, E-Mail-Quelle, HTTP-Quelle, Kafka-Quelle, SOAP-Quelle, Serielle Quelle, Quelle, TCP-Ziel, TCP-Quelle
max_messagesPub Sub-Quelle, SQS-Quelle
max_object_bytesDICO Mweb-Quelle, DICOM-Quelle
max_object_sizeAzure-Blob-Quelle, GCS-Quelle, S3-Quelle
max_open_connsDatenbank-Ziel
mechanismKafka-SASL
methodHTTP-Ziel
move_toAzure-Blob-Quelle, Direkte IMAP, E-Mail-Quelle, Datei-Abfrage, GCS-Quelle, S3-Quelle, SFTP-Quelle
mpiZiel
mqttZiel, Quelle
nameKanal, Kanal-Ziel, Ziel, ECR-Einrichtung
ncpdpKanal
no_compressPGP-Versand
no_mergeMPI-Ziel
non_persistentIBMMQ-Ziel
npiECR-Einrichtung
oauthE-Mail-O-Auth
objectGCS-Ziel
on_no_documentCDA-Ziel
order_byPub Sub-Ziel
overVertrags-Verweis
overlapDICOM-Abfrage-Quelle
paramsDatenbank-Ziel
paritySerielle Quelle
partner_cert_fileAS2-Ziel
partnersAS2-Quelle
pasZiel
pass_plainPGP-Empfang
passcodeBroker-Ziel, Broker-Quelle
passphrasePGP-Empfang, PGP-Versand
passwordAMQP-Verbindung, AS2-Ziel, DICO Mweb-Ziel, DICO Mweb-Quelle, Direktes Ziel, Direkte IMAP, Direkte Quelle, E-Mail-Quelle, FTP-Ziel, FTP-Quelle, HTTP-Ziel, IBMMQ-Verbindung, Kafka-SASL, MQTT-Verbindung, SFTP-Ziel, SFTP-Quelle, SMB-Quelle, SMTP-Ziel, SOAP-Ziel, SOAP-Quelle, Web DAV-Quelle, XDS-Ziel
pathAS2-Quelle, DICO Mweb-Quelle, HTTP-Quelle, SOAP-Quelle
path_styleS3-Ziel, S3-Quelle
patient_domainXDS-Ziel
patient_rootDICOM-Abfrage-Quelle
patternDatei-Abfrage, SFTP-Quelle
payerPAS-Ziel
persistentBroker-Ziel
pgpZiel, Quelle
phoneECR-Einrichtung
poll_intervalAzure-Blob-Quelle, Datenbank-Quelle, Direkte IMAP, E-Mail-Quelle, Datei-Abfrage, GCS-Quelle, IBMMQ-Quelle, Java-Script-Quelle, S3-Quelle, SFTP-Quelle
portDirekte IMAP, E-Mail-Quelle, Serielle Quelle
postal_codeECR-Einrichtung
postprocessorSkripte
practice_settingXDS-Ziel
prefetchAMQP-Quelle
prefixAzure-Blob-Quelle, GCS-Quelle, S3-Quelle
preprocessorSkripte
profileSOAP-Ziel, SOAP-Quelle
projectGCP-Zugriff
protocolE-Mail-Quelle
providerE-Mail-O-Auth
pubsubZiel, Quelle
purposeTEFCA-Ziel
qosMQTT-Verbindung
queryDatenbank-Quelle
query_timeoutDatenbank-Quelle
queueZiel, IBMMQ-Verbindung
queue_managerIBMMQ-Verbindung
queue_urlSQS-Ziel, SQS-Quelle
quiet_afterSerielle Quelle
quoteBegrenzt
rawDatei-Abfrage
rctcECR-Ziel, ELR-Ziel
read_timeoutHTTP-Quelle, SOAP-Quelle
reassembleAnhänge
receiptAS2-Ziel
receipt_urlAS2-Ziel
recipient_certs_dirDirektes Ziel
reconnectAMQP-Quelle, Broker-Quelle, MQTT-Quelle, Pub Sub-Quelle
record_lengthTCP-Rahmen
refresh_tokenE-Mail-O-Auth
regionAWS-Zugriff, FHIR-Authentifizierung, S3-Ziel
reject_on_warningFHIR-Ziel
relaxedBegrenzt
reopen_afterSerielle Quelle
replySerielle Quelle, TCP-Quelle
reply_textSerielle Quelle, TCP-Quelle
request_mdnDirektes Ziel
require_agreementCDA-Ziel
require_signaturePGP-Empfang
response_elementSOAP-Quelle
response_namespaceSOAP-Quelle
response_transformerZiel
results_toPAS-Ziel, TEFCA-Ziel
retainMQTT-Ziel
retain_hoursZiel, Warteschlangen-Konfiguration
retryZiel
returnDICOM-Abfrage-Quelle
rootFTP-Quelle, Datei-Quelle, SMB-Quelle
s3Ziel, Quelle
sampleSchatten
sasAzure-Blob-Zugriff
saslKafka-Ziel, Kafka-Quelle
schemeXDS-Code
scopeE-Mail-O-Auth, FHIR-Authentifizierung
scriptKanal, Java-Script-Ziel, Java-Script-Quelle
scriptsKanal
secret_access_keyAWS-Zugriff, FHIR-Authentifizierung, S3-Ziel
securityDirekte IMAP, E-Mail-Quelle, FTP-Ziel, FTP-Quelle
selectorBroker-Quelle
sender_deviceHL7v3-Optionen
sender_oidHL7v3-Optionen
serialQuelle
server_side_encryptionS3-Ziel
session_timeoutKafka-Quelle
session_tokenAWS-Zugriff, FHIR-Authentifizierung, S3-Ziel
sftpZiel, Quelle
shadowKanal
shareSMB-Quelle
sign_withPGP-Versand
smbQuelle
smtpZiel
smtp_hostDirektes Ziel, Direkte Quelle
snsZiel
soapZiel, Quelle
sop_classesDICOM-Quelle
sort_byDatei-Abfrage
sourceKanal, ECR-Ziel
source_idXDS-Ziel
splitBegrenzt, EDIFACT-Optionen, X12-Optionen
sqsZiel, Quelle
ssn_systemMPI-Ziel
stable_forDatei-Abfrage, SFTP-Quelle
start_blockTCP-Rahmen
starttlsSMTP-Ziel
stateECR-Einrichtung
statementDatenbank-Ziel
stop_bitsSerielle Quelle
storage_classGCS-Ziel, S3-Ziel
subjectAS2-Ziel, Direktes Ziel, SMTP-Ziel, SNS-Ziel
subscriptionPub Sub-Quelle
subscription_idBroker-Quelle
success_on_undefinedJava-Script-Ziel
success_statusHTTP-Ziel
suffixAzure-Blob-Quelle, GCS-Quelle, S3-Quelle
tablesKanal
takeE-Mail-Quelle
tcpZiel, Quelle
tefcaZiel
temp_suffixZiel, Dokument-Ziel, FTP-Ziel, SFTP-Ziel
templateDatenbank-Quelle, Dokument-Ziel
tenantE-Mail-O-Auth
tenant_idFHIR-Authentifizierung
textDirektes Ziel
tierAzure-Blob-Ziel
timeoutAMQP-Verbindung, Broker-Ziel, Broker-Quelle, DICO Mweb-Ziel, DICOM-Ziel, DICOM-Abfrage-Quelle, Datenbank-Ziel, Ziel, Direktes Ziel, Dokument-Ziel, FTP-Ziel, FTP-Quelle, IBMMQ-Verbindung, Java-Script-Ziel, Java-Script-Quelle, Kafka-Ziel, Kafka-Quelle, MQTT-Verbindung, S3-Ziel, SFTP-Ziel, SFTP-Quelle, SMB-Quelle, SMTP-Ziel, SOAP-Ziel, Skripte, Schatten, TCP-Ziel, Web DAV-Quelle, XDS-Ziel
timezoneFHIR-Ziel
titleDokument-Ziel
tlsAMQP-Verbindung, AS2-Ziel, AS2-Quelle, Broker-Ziel, Broker-Quelle, DICO Mweb-Ziel, DICO Mweb-Quelle, DICOM-Ziel, DICOM-Abfrage-Quelle, DICOM-Quelle, Ziel, Direkte IMAP, E-Mail-Quelle, HTTP-Ziel, HTTP-Quelle, IBMMQ-Verbindung, Kafka-Ziel, Kafka-Quelle, MQTT-Verbindung, SOAP-Ziel, SOAP-Quelle, Quelle, TCP-Ziel, TCP-Quelle, XDS-Ziel
tls_certDirekte Quelle, Direkte XDR
tls_keyDirekte Quelle, Direkte XDR
toAS2-Ziel, Direktes Ziel, SMTP-Ziel
tokenDICO Mweb-Ziel, DICO Mweb-Quelle, HTTP-Quelle, SOAP-Quelle, XDS-Ziel
token_urlE-Mail-O-Auth, FHIR-Authentifizierung
topicKafka-Ziel, MQTT-Ziel, MQTT-Quelle, Pub Sub-Ziel
topic_arnSNS-Ziel
topicsKafka-Quelle
transfer_syntaxesDICOM-Ziel, DICOM-Quelle
transformationsKanal, DICOM-Optionen, Begrenzt, HL7v3-Optionen, NCPDP-Optionen, Skript-Optionen, X12-Optionen
transformerSkripte
trim_paddingTCP-Rahmen
trim_spaceBegrenzt
typeZiel, FHIR-Authentifizierung, Quelle
undeploySkripte
unencryptedAS2-Ziel
unsignedAS2-Ziel
unsigned_receiptAS2-Ziel
urlAS2-Ziel, CDA-Ziel, DICO Mweb-Ziel, FHIR-Ziel, HTTP-Ziel, IBMMQ-Verbindung, SOAP-Ziel, Web DAV-Quelle, XDS-Ziel
userFTP-Ziel, FTP-Quelle, SFTP-Ziel, SFTP-Quelle, SMB-Quelle, Web DAV-Quelle
usernameAMQP-Verbindung, AS2-Ziel, DICO Mweb-Ziel, DICO Mweb-Quelle, Direktes Ziel, Direkte IMAP, Direkte Quelle, E-Mail-Quelle, HTTP-Ziel, IBMMQ-Verbindung, Kafka-SASL, MQTT-Verbindung, SMTP-Ziel, SOAP-Ziel, SOAP-Quelle, XDS-Ziel
validate_before_sendFHIR-Ziel
verify_withPGP-Empfang
versionCDA-Ziel, FHIR-Ziel, SOAP-Ziel, SOAP-Quelle
visibility_timeoutSQS-Quelle
wait_secondsSQS-Quelle
warnings_are_errorsSOAP-Ziel
webdavQuelle
whenBestätigung
windowDICOM-Abfrage-Quelle
writeCDA-Ziel
wsdlSOAP-Quelle
x12Kanal
x12_asZiel
xdmDirektes Ziel
xdm_source_idDirektes Ziel
xdrDirekte Quelle
xdsZiel