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:
- Alles kann über die Web-Oberfläche konfiguriert werden. Eine Funktion, die nur über ein Terminal oder eine handbearbeitete Datei erreichbar ist, wird als Fehler und nicht als Designentscheidung behandelt.
- Nachrichten können Schritt für Schritt verfolgt werden, wobei gezeigt wird, was jeder Schritt gelesen, was er geändert und was er übersprungen hat und warum.
- Testverkehr kann generiert werden, der der Form eines echten Feeds entspricht, ohne dessen Daten zu enthalten.
- Ein Kanal kann aus einer einzelnen Beispiel-Nachricht vorgeschlagen werden, mit einer expliziten Aussage darüber, was die Beispiel-Nachricht nicht sagen kann.
- Bevor ein bestehender Motor ersetzt wird, kann dessen Ausgabe und die von Perfuse verglichen werden, Nachricht für Nachricht, wobei die Unterschiede nach Feld gruppiert werden.
1.2 Was drin ist
Alles unten ist in einer einzigen Binärdatei enthalten. Jede Zeile nennt das Kapitel, das es abdeckt.
- Formate. HL7 v2, FHIR R4, R4B und R5, DICOM, X12 (837, 835, 270/271, 276/277, 834, 278, 275), C-CDA und CDA, HL7 v3, NCPDP Telekommunikation und SCRIPT, SMART Health Links und Karten, begrenzt und roh. Siehe Nachrichtenformate.
- Konnectoren. 28 Quelltypen und 32 Zieltypen, darunter MLLP, Dateien, SFTP, Datenbanken, DICOM, Kafka, AMQP 1.0, MQTT, IBM MQ und AWS, Azure und Google Cloud-Speicher und -Nachrichten. Siehe die Quellenreferenz und die Zielreferenz.
- Ändern von Nachrichten. Filter, elf deklarative Transformationschritte, JavaScript (Mirths Dialekt inklusive) und Lua, gemeinsame Zuordnungstabellen und Codesätze sowie Zuordnungsvorschläge. Siehe Filtern und Transformation.
- Liefern Sie sie. Eine dauerhafte, geordnete Warteschlange pro Ziel, Wiederholungen, tote Briefe, die die Nachricht behalten, und Bestätigungen, die nach der Lieferung gesendet werden. Siehe Lieferung und Bestätigungen.
- Beobachten Sie es. Dashboards, Team-Dashboards, ein Flussdiagramm, elf Arten von Warnungen, Metriken, Nachverfolgung und ein Nachrichtenspeicher, der die Nachrichten eines Patienten in verschiedenen Formaten findet. Siehe Warnungen, den Nachrichtenspeicher und Fehlerbehebung.
- Ändern eines Live-Interfaces sicher. Schattenmodus, Feed-Verträge, Kanaltests und Motorenvergleich. Siehe Testen.
- Verlassen von Mirth. Mirth-, Open-Integration-Engine- und BridgeLink-Kanäle erklärt, übersetzt und zurück exportiert. Siehe Migration.
- Zahler und öffentliche Gesundheit. Die vier CMS-0057-APIs, Da Vinci CRD, DTR, PAS, PDex und Plan-Net, CARIN Blue Button, ein optionaler Entscheidungsdienst, eCR und ELR. Da Vinci CRD, DTR und PAS beantworten sowohl ihre 2.2.x- als auch ihre 2.1.0-Veröffentlichungen. Siehe CMS-0057.
- Wer darf was tun. SAML, OpenID Connect, LDAP, Passwörter, SCIM, gegenseitiges TLS, sechs Rollen, Kanalgruppen mit einer Rolle in jeder, Mandanten, ein SMART-Autorisierungsserver, TEFCA und UDAP sowie ein Überwachungsprotokoll. Siehe Sicherheit.
- Ausführen. Ein statischer Binärcode für Linux, macOS und Windows, als Dienst, mit einer Flottenansicht mehrerer Server. Siehe Betrieb, die Web-Schnittstelle, die Befehlszeile und Serveroptionen.
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
| Standard | Version | Überprüft |
|---|---|---|
| HL7 v2 | jede Version: Nachrichten werden durch ihre eigenen Trennzeichen gelesen, nicht durch ein Versions-Schema; Bestätigungen standardmäßig 2.5.1 | NIST HL7 v2-Validator; echter Mirth- und OIE-Verkehr |
| HL7 v2 zu FHIR | HL7s 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 |
| FHIR | R4 (4.0.1), mit R4B und R5 lesbar und schreibbar | der HL7 FHIR-Validator; Inferno |
| C-CDA und CDA | C-CDA 2.1 | ONC-SITE (C-CDA-Beispiele gesendet und empfangen über XDR); nicht durch ein CDA-Schematron |
| HL7 v3 | PIX und PDQ (IHE ITI-44, 45, 47) | IHEs NE2008-Schemata und Beispielnachrichten |
| DICOM und DICOMweb | DIMSE C-STORE, C-FIND, C-MOVE, C-GET, C-ECHO; QIDO-RS, WADO-RS, WADO-URI, STOW-RS | Orthanc |
| X12 (HIPAA) | 005010: 837, 835, 270/271 (X279A1), 276/277 (X212), 834, 278-Anfrage (X217) und Anfrage (X215); 275 in 006020 (X314) | Zahler-Veröffentlichungen; CMS esMD-Beispiele |
| CAQH CORE-Konnektivität | vC2.2.0 SOAP und MIME, vC4.0.0 mit MTOM | ein Ersatz-UM-System, das aus CAQHs Regeln erstellt wurde |
| NCPDP | Telekommunikation D.0; SCRIPT 2023011 (und 2017071) mit ePA; Echtzeit-Rezeptvorteil v13 | aus den öffentlichen Surescripts-Beispielen und deren Begleitdokumentation; nicht gegen NCPDPs lizenzierte Schemata |
| UN/EDIFACT | Syntax 3 und 4, CONTRL | pydifact 0.1.8 |
| IHE-Dokumentfreigabe | XDS.b, XCA, XDR, MHD 4.2.2, PIXm, PDQm, XDM | das NIST XDS-Toolkit; ONC-SITE |
| Direktes sicheres Messaging | Anwendungsstatement 1.2, XDR und XDM für Direkt, DNS- und LDAP-Zertifikatserkennung | ONC-SITE; ONCs Zertifikatserkennungstool (18 von 18) |
| AS2 | RFC 4130, Komprimierung RFC 5402 | pyas2lib |
| Signierte Anlagen | HL7 DSDR, XAdES-X-L | xmlsec1, OpenSSL |
1.3.2 FHIR-Implementierungsleitfäden
| Leitfaden | Release | Überprüft |
|---|---|---|
| US Core | Umstellungen auf 9.0.0 (USCDI v6); FHIR-Server gegen 6.1.0 und 7.0.0 | der HL7-Validator; Inferno US Core |
| SMART App Launch | 2.2 | Inferno: 80 von 80 (öffentliche App) |
| Bulk Data Access | 2.0.0 | Inferno: 48 von 48 |
| Abonnements R5 Backport | für R4 | ein echter HTTP-Empfänger; die Benachrichtigungstests des PAS-Kits |
| Da Vinci CRD | 2.2.1 und 2.1.0 | Inferno 2.2.1: 92 bestanden, keine fehlgeschlagen; 2.1.0 durch die eigenen Beispiele des Leitfadens |
| Da Vinci DTR | 2.2.0 und 2.1.0 | Inferno 2.2.0: 43 bestanden, 2 fehlgeschlagen (ein Kit-Defekt); 2.1.0 durch die eigenen Beispiele des Leitfadens |
| Da Vinci PAS | 2.2.1 und 2.1.0 | Inferno 2.2.1: 82 von 84; 2.1.0 durch die eigenen Beispiele des Leitfadens |
| Da Vinci PAS, senden (Anbieterseite) | 2.2.1 | die HL7-Da-Vinci-PAS-Payer-Referenzimplementierung; kein Produktionspayer |
| Da Vinci PDex | 2.2.0 | Inferno PDex 2.0: Payer-to-Payer 19 von 19 |
Da Vinci HRex $member-match | 1.2.0 | Inferno PDex Payer-to-Payer |
| Da Vinci ATR | 2.1.0 | nicht durch ein externes Tool überprüft |
Da Vinci CDex $submit-attachment | 2.1 | nicht durch ein externes Tool überprüft |
| Da Vinci Plan-Net | 1.1.0 | Inferno: 199 bestanden, 10 fehlgeschlagen (ein Kit-Defekt) |
| Da Vinci US Drug Formulary | 2.1.0 | der HL7-Validator |
| ISiK (deutsche Krankenhäuser), FHIR-Server | Stufe 5, Basis-Modul | gematik's ISiK-Test-Suite 3.0.9: 421 von 421 |
| PACIO Transitions of Care, Medication Profile, Advance Directives, Functioning | 1.0.0, 1.0.0, 2.0.0-Ballot, 2.0.0 | PACIO's Inferno-Kits 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 Button | 2.2.0 | der HL7-Validator |
| eCR | 2.1.2 | der HL7-Validator |
| ELR | HL7 2.5.1 ELR Release 1 mit seinen Errata | ONC's ELR-Tool: 28 von 28 |
| International Patient Summary | 2.0.0 | der HL7-Validator |
| DEQM | 5.0.0 | der HL7-Validator |
| SQL on FHIR | v2 | die offizielle Test-Suite: 144 von 144 |
| SMART Health Cards und Links | Cards 1.4, Links STU 1 | die eigenen Beispiele der Spezifikationen; eine veröffentlichte SMART Health Links-Bibliothek |
| UDAP Security | STU 1 | ein echter Autorisierungsserver und Vertrauensgemeinschaft |
| TEFCA Facilitated FHIR | SOP v2.0 | nicht 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.
| Profil | Release | Ressourcen gültig |
|---|---|---|
| UK Core | STU2 2.0.2 | 185 von 187 |
| FR Core | 2.2.0 | 138 von 156 |
| ISiK Basismodul | 4.0.3 (Stufe 4) | 18 von 47; 42 von 47 mit dem eigenen Bundle-Skript des Krankenhauses |
| Nictiz nl-core | 0.12.1-beta.1 (zib 2020) | 12 von 24; 18 von 24 mit dem eigenen Bundle-Skript des Krankenhauses |
| HL7 Europe Laboratory Report | 2.1.0 | 106 von 426 (die Anleitung erwartet ein Dokument, ein v2-Ergebnis ist nicht) |
| HL7 Europe Hospital Discharge Report | 1.0.0 | 68 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.
-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:
- Der Quellblock ist für MLLP flach.
listensitzt direkt aufsource, nicht innerhalb einessource.mllp-Blocks. Transporte, die mehr als eine Adresse benötigen — HTTP, SOAP, DICOM — haben ihren eigenen Unterblock, und diese sind im Quellenreferenz aufgeführt. - Ein Dateiziel benötigt sowohl
rootals auchdir.rootist die Grenze, gegen die Pfade aufgelöst werden und die nicht verlassen werden kann;dirist der Ort, an dem Nachrichten innerhalb davon landen. - Es gibt keine Transformation und keinen Filter. Beide sind optional, und ein Kanal ohne beides leitet Nachrichten einfach weiter.
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:
- 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.
- Aus etwas, das bereits funktioniert. Eine Reihe von vollständigen Kanälen, die nur ihre Adressen benötigen.
- 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
- Kanäle erklärt, was ein Kanal ist und wie seine Teile zusammenpassen.
- Nachrichtenfluss verfolgt eine Nachricht von der Ankunft bis zur Zustellung, was der schnellste Weg ist, um zu verstehen, wo eine Änderung vorgenommen werden muss.
- Alarmierung ist es wert, vor der Freigabe eines Datenfeeds einzurichten, anstatt nach dem ersten Vorfall.
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:
- Vorabgenehmigung: PAS-Anfragen, die innerhalb von 72 Stunden (beschleunigt) oder 7 Tagen (Standard) entschieden wurden, entschieden wurden, verspätet, warten und überfällig sind, mit der Medianzeit zur Entscheidung. Auch, wie die angeforderten Dienste beantwortet wurden (genehmigt, geändert, abgelehnt, angehalten), wie jeder derzeit steht, über 30 Tage.
- Bildgebung: Objekte, die pro Modalität durch C-STORE empfangen wurden, und die nicht geliefert wurden. Auch die Routing-Verzögerung pro Kanal (Median und 95. Perzentil), C-FIND-Abfragen und -fehler pro Abfragekanal und Bildberichte (ein ORU, dessen OBR-24 ein Bildabschnitt ist, oder ein MDM), die nicht jeden Zielort erreichten.
- Umsatzzyklus: 999 Transaktionsgruppen, die akzeptiert, akzeptiert mit Fehlern und abgelehnt wurden, und 277CA-Ansprüche, die akzeptiert und abgelehnt wurden (A3, A4, A6, A7, A8). Auch 835-Ansprüche, die durch die Patientenkontonummer mit 837s abgeglichen wurden, die durch diesen Server gesendet wurden, und die häufigsten Ablehnungsgründe.
- Labor: Zeit zur Ergebnislieferung, von der Aufnahme bis zur Bestätigung des letzten Zielorts, und kritische Ergebnisse (OBX-8 HH, LL, AA, > oder <), die nicht jeden Zielort erreichten.
- Datenschutz und Sicherheit: Wer Nachrichten geöffnet, nach Patienten gesucht oder Vorabgenehmigungen im Konsole über 7 Tage gelesen hat, aus dem Überwachungsprotokoll (das Öffnen einer Nachricht wird als
message.readprotokolliert). Auch jedes aktive API-Token und wann es zuletzt verwendet wurde; ein Token, das 90 Tage nicht verwendet wurde, wird gekennzeichnet.
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.
3.4.6 Gesundheitslinks
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 vier APIs: ob Patientenzugriff, Anbieterzugriff, Payer-to-Payer und Vorabgenehmigung auf dieser Instanz bereit sind und was jede noch benötigt.
- Prüferwarteschlange: die PAS-Anfragen, die auf eine Person warten, sortiert nach dem nächstliegenden Termin, mit den für jede Anfrage gesendeten Dokumenten; genehmigen, ablehnen oder zertifizieren Sie weniger Einheiten. Siehe die Prüferwarteschlange.
- Ansprüche an CARIN BB: ein 837 und sein 835 in CARIN Blue Button-Bundles umgewandelt.
- Vorabgenehmigung an PDex: eine PAS-Antwort in eine PDex-Vorabgenehmigung umgewandelt.
- Vorabgenehmigungsmetriken: die jährliche öffentliche Vorabgenehmigungsmetriken-Seite, die aus einer CSV-Datei mit Entscheidungen erstellt wird.
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:
| Teil | Schlüssel | Erforderlich | Was es tut |
|---|---|---|---|
| Identität | name | ja | Benennt den Kanal. Muss eindeutig sein. |
| Datentyp | dataType | nein | Wie Nachrichten zu parsen sind. Standardmäßig HL7 v2. |
| Quelle | source | ja | Wo Nachrichten ankommen. Genau einer. |
| Filter | filter | nein | Entscheidet, welche Nachrichten akzeptiert werden. |
| Transformationen | transformations | nein | Geordnete Änderungen an der Nachricht. |
| Ziele | destinations | ja | Wo 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.
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.
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
- 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.
- Parse. Die Bytes werden gemäß dem
dataTypedes Kanals in einen Baum umgewandelt. Eine Nachricht, die nicht geparst werden kann, stoppt hier und wird als Parse-Fehler aufgezeichnet. - Aufzeichnen. Die Nachricht wird im Nachrichtenspeicher aufgezeichnet, wie sie empfangen wurde, bevor sie modifiziert wird. Dies ermöglicht die Wiedergabe und erneute Verarbeitung.
- Filter. Wenn der Kanal einen
filterhat, entscheidet er, ob die Nachricht akzeptiert wird. Eine abgelehnte Nachricht wird als gefiltert aufgezeichnet, was ein normales Ergebnis und kein Fehler ist. - Transform. Die
transformationsdes Kanals werden in der Reihenfolge ausgeführt, jede gegen das Ergebnis der letzten. - Fan out. Jedes Ziel erhält eine Kopie der transformierten Nachricht, wendet seine eigenen Transformationen an, wenn es welche hat, und liefert.
- Aufzeichnen des Ergebnisses. Pro Ziel: geliefert, gewartet, fehlgeschlagen oder gefiltert.
- 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.
5.4 Wo die Nachricht aufgezeichnet wird
Bevor dem Filter und daher bevor jede Transformation. Drei Konsequenzen:
- Eine Nachricht, die der Filter abgelehnt hat, ist immer noch im Speicher. Sie können sehen, was angekommen ist und bestätigen, dass der Filter richtig war.
- Replay und erneute Verarbeitung beginnen immer mit dem, was tatsächlich angekommen ist, und nicht mit einer teilweise transformierten Version.
- Eine Änderung an den Transformationen kann an realen historischen Daten getestet werden, da die ursprüngliche Version immer noch vorhanden ist. Siehe testing.
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
| Phase | Wie ein Fehler aussieht | Was passiert |
|---|---|---|
| Ankunft | Framing-Fehler, Verbindung wird während der Nachrichtenübertragung getrennt | Aufgezeichnet, Verbindung geschlossen, Absender wiederholt den Vorgang |
| Parsen | Nicht gültig für den deklarierten Typ | Aufgezeichnet als Parsen-Fehler, negative Bestätigung, wenn die Quelle eine erwartet |
| Filter | Der Filter selbst enthält einen Fehler | Behandelt als Ablehnung, aufgezeichnet mit dem Fehler |
| Transformieren | Ein Schritt schlägt fehl | Hängt vom on_error-Schritt ab; siehe transformation |
| Liefern | Ziel ist nicht erreichbar oder lehnt ab | In 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
| Schritt | Was es tut |
|---|---|
set | Schreibt einen Literalwert in einen Pfad, falls abwesend. |
copy | Kopiert einen Pfad in einen anderen, mit einem optionalen Standardwert, wenn die Quelle abwesend ist. |
clear | Leert ein Feld, lässt es aber vorhanden. |
remove | Entfernt ein Feld vollständig. |
map | Sucht den aktuellen Wert in einer Tabelle und ersetzt ihn. |
replace | Reguläre Ausdrucksersetzung innerhalb eines Feldes. |
pad | Füllt einen Wert auf eine feste Breite. |
date | Konvertiert ein Datum oder einen Zeitstempel zwischen Formaten. |
trim | Entfernt umgebendes Leerzeichen. |
case | Konvertiert 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:
seterstellt den Pfad, den es adressiert, einschließlich der Zwischenstruktur. Dies ist bequem, und es bedeutet, dasssetniemals demonstrieren kann, dass ein Feld fehlt — nach dem Schritt existiert es. Um zu testen, was passiert, wenn ein Feld fehlt, verwenden Siecopyvon einem Pfad, der nicht existiert.- Ein Pfad ohne Index adressiert jede Wiederholung und jeden Vorkommen, wie es in einem Filter der Fall ist (wo
PID-3.5 == "SS"wahr ist, wenn eine Wiederholung ist). In einer Nachricht mit fünf OBX-Segmenten ändertsetaufOBX-5alle fünf, undsetaufPID-3.4umbenennnt jeden Identifier in PID-3, einschließlich der nationalen Nummer. Um eines zu ändern, geben Sie seinen Index an:PID-3(1).4,OBX(2)-5.
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:
fail- der Standard. Die Nachricht stoppt und wird als Konvertierungsfehler aufgezeichnet.keep- den ursprünglichen Wert unverändert lassen.clear- das Feld leeren.
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:
- Ein
mapnach einemcasesieht den case-konvertierten Wert, sodass seine Tabelle-Schlüssel dem konvertierten Format entsprechen müssen. Eine Tabelle vonM/Fnach einem kleinschreibungsschritt stimmt nichts überein, stillschweigend, da ein Wert, der nicht in der Tabelle ist, unverändert bleibt. - Ein
copyvon einem Feld, das ein späterer Schritt entfernt, funktioniert immer noch, da es zuerst ausgeführt wurde. Das Umgekehrte gilt nicht.
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:
- Beispielwerte für ein Quellfeld, nach einem Gleichheitszeichen:
ZPI-1 = MRN00412, MRN00998 - Die Art des Werts, den ein Ziel hält, auf die gleiche Weise:
PID-3.1 = mrn. Die Arten sindmrn,npi,ssn,phone,dateundemail.
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:
| Wert | Was es ist |
|---|---|
javascript | Der Standard. Ein unmarkiertes Skript wird als JavaScript behandelt. |
lua | Die bessere Wahl, wenn niemand migriert. |
wasm | Die 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.
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: [...]
statusistapproved(Standard),draft(wird nicht verwendet) oderretired(wird für die Aufzeichnung aufbewahrt, wird nicht verwendet).
(beim Laden der Datei abgelehnt).
- Zwei Ausgaben eines Namens mit der gleichen Version oder zwei genehmigte Ausgaben,
die am gleichen Tag beginnen, werden abgelehnt, wenn die Datei geladen wird.
- Das Speichern einer neuen Version ohne Startdatum, während eine andere genehmigt ist, datiert es
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.
- Die eigenen
default- undstrict-Einstellungen eines Kartenschritts werden verwendet, wenn der Schritt diese setzt;
andernfalls werden die Einstellungen der Tabelle verwendet.
- Auf dem Tabellenbildschirm listet Versionen anzeigen jede Ausgabe mit ihrem Status,
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:
| Format | Datei | System |
|---|---|---|
loinc | Loinc.csv aus der LOINC-Tabelle-Veröffentlichung | http://loinc.org |
icd10cm | die CMS-Bestelldatei (icd10cm_order_*.txt) oder Codierungsdatei | http://hl7.org/fhir/sid/icd-10-cm |
rxnorm | RXNCONSO.RRF aus der RxNorm-Vollveröffentlichung | http://www.nlm.nih.gov/research/umls/rxnorm |
snomed | der RF2-Beschreibungs-Snapshot (sct2_Description_Snapshot-en_*.txt) | http://snomed.info/sct |
snomed-rf2 | ein 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} |
claml | eine ClaML-Datei: WHO ICD-10, ICD-10-GM und OPS (BfArM), CIM-10 FR (ATIH) | aus dem Dateinamen oder dem angegebenen system |
icd11 | die WHO ICD-11 MMS-einfache Tabulation (tabulatorgetrennt, mit Code- und Title-Spalten) | http://id.who.int/icd/release/11/mms |
csv | jede 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:
- Eine Tabelle, die
source_systemodertarget_systembenennt, überprüft ihre Einträge beim Speichern und listet Codes auf, die nicht im System sind, in der Ausgabe; - Code finden sucht nach Code oder nach Wörtern im Namen;
- Der FHIR-Server antwortet auf
CodeSystem/$lookupundCodeSystem/$validate-codefür diese (siehe FHIR-Server-Optionen). ICD-10-CM-Codes werden mit oder ohne Punkt akzeptiert.
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:
- Eine Broker-Quelle nimmt einen
selector, der am Broker filtert. Nachrichten, die dieser Kanal nicht möchte, überqueren das Netzwerk überhaupt nicht. In einer gemeinsamen Warteschlange ist das der Unterschied zwischen dem Lesen von hundert Nachrichten pro Tag und hunderttausend. - Eine Datenbank-Quelle entscheidet mit ihrer Abfrage, was sie zurückgibt.
- Eine Datei-Quelle entscheidet mit ihrem Muster, welche Dateien sie aufnimmt.
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.
| Wert | Format |
|---|---|
hl7 | HL7 v2, der pipe-getrennte Standard. Der Standardwert. |
hl7v3 | HL7 v3 und CDA-Dokumente, die XML sind. |
x12 | ASC X12, verwendet für die Eignung und Ansprüche. |
ncpdp | NCPDP Telekommunikationsstandard D.0 Apothekenansprüche. |
script | NCPDP SCRIPT, elektronische Rezepte. XML. |
dicom | DICOM-Bildobjekte. |
delimited | CSV und andere durch Trennzeichen getrennte Texte. |
raw | Keine 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.
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:
x12: { arrives_as: xml }on an X12 channel takes that XML in and handles it as the X12 it stands for (the builder's It arrives as choice);x12_as: xmlon a destination sends the X12 on as that XML (the builder's Send it as Mirth's X12 XML);perfuse x12 xml [file]andperfuse x12 from-xml [file]convert at the command line.
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.
| Wert | Verhalten |
|---|---|
require | Der Austausch wird abgelehnt. Der Standard. |
warn | Er wird verarbeitet und der Fehler wird gegen die Nachricht aufgezeichnet. |
ignore | Es 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.
| Transaktion | Was es enthält |
|---|---|
835 | Abrechnungsberatung: was bezahlt wurde, was abgelehnt wurde und die Anpassungsgründe. |
275 | Anspruchsanlagen: klinische Dokumentation, die einen Anspruch unterstützt. |
277 | Anspruchstatus, einschließlich eines Zahlungspflichtigen, der um zusätzliche Dokumentation bittet. |
278 | Vorabgenehmigung: die Anfrage zur Überprüfung und die Entscheidung des Zahlungspflichtigen. |
999 | Funktionale Bestätigung, die Perfuse auch generiert. |
271 | Eignung: ob ein Patient abgedeckt ist, und seine Mitversicherung, Selbstbeteiligung, Zuzahlung und außergewöhnliche Ausgaben, im und außerhalb des Netzwerks. |
|---|---|
834 | Anmeldung: Mitglieder, die hinzugefügt, geändert und beendet wurden, mit jedem Abdeckungsstrang und seinen Daten. |
837 | Ansprü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 ist | Was es bedeutet | Was zu tun ist |
|---|---|---|
HCR mit Aktion A3 | Der Zahler hat den Antrag berücksichtigt und wird ihn nicht zertifizieren. | Berufung einlegen oder den Behandlungsplan ändern. |
Ein AAA-Segment | Der 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:
- Keine Entscheidung wird hochgestuft. Teilweise Zertifizierung bleibt teilweise, und ein Antrag, den der Zahler ablehnt, wird nicht zu einer Ablehnung. Beide Kollabse sind in der offensichtlichen Abbildung verfügbar und beide sind im teuren Bereich falsch.
- Nichts wird erfunden, um ein erforderliches Feld zu füllen. Ein zertifiziertes Ereignis ohne Autorisierungsnummer wird als solches gemeldet und nicht mit einer plausiblen Nummer versehen - eine erfundene Nummer produziert einen Anspruch, der später aus einem Grund abgelehnt wird, den niemand zurückverfolgen kann.
- Eine Entscheidung, die nur auf Zeilenebene übertragen wird, wird verwendet. Ein Zahler, der pro Dienst antwortet, kann das Ereignis ohne eigene Entscheidung lassen; das Lesen nur des Ereignisses würde es als ausstehend melden, und eine Praxis wartet auf eine Antwort, die sie bereits hat, während die Genehmigung abläuft. Wenn die Zeilen widersprechen, gewinnt die ungünstigste, da ein Ereignis mit einer abgelehnten Zeile keine Genehmigung ist.
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 war | Wo 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.
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.
- Die Nutzlast ist in
BDS, nichtBIN.BDS01benennt einen Filter,ASCoderB64.BDS02ist die Länge undBDS03die Daten. - Die Nutzlast ist eine MIME-Entität, mit Headern, die angeben, was das Dokument ist, und einem base64-Body. Mit
B64ist die Entität selbst auch base64.
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.
- Wo die beiden Leitfäden übereinstimmen, folgt Perfuse ihnen.
- Wo sie sich unterscheiden, versucht es, beiden gerecht zu werden, wenn es kann.
CAT02istHLfür ein HL7-Dokument, das esMD verwendet, undIAfür ein Bild, das UnitedHealthcare verwendet. - Andernfalls sendet es den optionalen Abschnitt nur, wenn ihm der Wert gegeben wird: die
REF*X1-Anspruchskennung von esMD und dasDTP*472-Dienstdatum von UnitedHealthcare.
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.
- Was signiert wird. Das gesamte Dokument außer seinem
legalAuthenticatorundauthenticator-Teilnehmer, sodass jeder spätere Signierer die früheren Signaturen intakt lässt. Die Signatur sagt dies mit einem XPath-Filter 2.0-Transformationsprozess an, den jede XML-Signaturbibliothek auswerten kann. - Wo es hingeht. Base64 in
sdtc:signatureTextauf dem signierenden Teilnehmer, mit einer einzeiligen plain-text-Beschreibung. Der Signierer ist der Rechtsauthentifizierer des Dokuments, wenn es einen unsignierten gibt, ansonsten ein neuerauthenticator. - Was es besagt. Das Zertifikat des Signierers, die Zeit in UTC, eine Rolle aus der NUCC-Providertaxonomie und einen Zweck aus ASTM E1762. Der Zweck standardisiert auf *Autoren-Signatur* für einen Rechtsauthentifizierer und *Koautoren-Signatur* andernfalls, wie im Beispiel des Leitfadens selbst.
- Wie lange es dauert. Der Leitfaden verlangt XAdES-X-L, das alles enthält, was ein Zahlungspflichtiger benötigt, um die Signatur Jahre später ohne Netzwerkzugriff zu überprüfen. Das ist der Zertifizierungspfad, eine OCSP-Antwort oder CRL von der CA und zwei Zeitstempel von einer Zeitstempelbehörde. Perfuse holt die Revokationsdaten von den Adressen im Zertifikat und die Zeitstempel von
-tsa-url.
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:
- Eine deklarierte Länge, die nicht mit den Daten übereinstimmt, wird abgelehnt, wobei beide Zahlen genannt werden. Die nützliche Frage ist, ob die Zählung des Senders falsch war oder die Datei während des Transports abgeschnitten wurde, und nur die beiden Zahlen beantworten sie.
BDS, das006020-Binärsegment, enthält seine Zählung inBDS02und seine Daten inBDS03. Es wurde abgelehnt, bis dies aus einer veröffentlichten Quelle bestätigt werden konnte, anstatt es sich zu merken, und zwei Quellen bestätigen es nun: derBDS-Tabelle des CMS esMD-Begleitleitfadens und des UnitedHealthcare-Leitfadens.
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.
| v2 | FHIR |
|---|---|
ADT | Patient, 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. |
ORU | DiagnosticReport 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, OMG | ServiceRequest. |
SIU | Appointment, mit dem Patienten, den Praktikern aus AIP und den Standorten aus AIL. |
MDM | DocumentReference, der das Dokument enthält. |
VXU | Immunization, 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.
- Status. Der Füller-Status in
SCH-25entscheidet darüber, und das Trigger-Ereignis wird nur verwendet, wenn dieser leer ist. - Blockierte Slots. Ein blockierter Slot ist kein Appointment mit einem Patienten und produziert keines.
- Startzeit. Sie wird aus
AIS,AIG,AILoderAIPzuerst gelesen, dannSCH-11, da Version 2.5 sie verschoben hat und die Feeds nicht alle mitgezogen haben. - Dauern. Eine Dauer in einer Einheit, die Perfuse nicht erkennt, wird weggelassen, nicht geraten.
Dokumente. Textnotizen (TX, FT, ST) behalten ihre Zeilenumbrüche bei, einschließlich leerer Zeilen, da ein leerer Wiederholung in einer Notiz ein Absatzumbruch ist.
- Einbettete Dokumente. Ein eingebettetes PDF, TIFF oder JPEG (
ED) wird byte für byte übertragen. Base64, das kein gültiges Base64 ist, wird abgelehnt, anstatt weitergeleitet zu werden. - Typen. Der Dokumenttyp in
TXA-2wird so beibehalten, wie er gesendet wurde, und wo es eine klare Äquivalenz gibt, wird der LOINC-Code verwendet, den US Core verwendet. - Signierung. Eine Notiz, die niemand unterschrieben hat, ist
preliminary, undT11macht das Dokumententered-in-error. - Kein Inhalt. Eine Benachrichtigung ohne Inhalt (
T01,T03und die anderen ungeraden Ereignisse) produziert keine DocumentReference. FHIR erfordert Inhalt, und eine leere Anlage würde wie die Notiz aussehen, während sie nichts sagt.
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.
- Abgelehnte Dosen. Eine abgelehnte oder nicht verabreichte Dosis (
RXA-20REoderNA) istnot-done, mit dem Grund ausRXA-18. - Löschungen. Eine gelöschte Dosis (
RXA-21D) istentered-in-error. - Historische Aufzeichnungen. Eine Aufzeichnung, die von woanders transkribiert wurde (
RXA-9anders als00), ist keine primäre Quelle. - Unbekannte Mengen. Eine Menge von
999bedeutet unbekannt, nicht 999. - Wege und Orte. Jede Dosis übernimmt den Weg und den Ort aus dem
RXRdanach, sodass eine Nachricht mit zwei Dosen der zweiten Dosis nicht den Weg der ersten Dosis gibt.
Ungünstige Eingaben. Jede dieser wird in den Notizen gemeldet, anstatt stillschweigend entschieden zu werden:
- Identifikatoren.
PID-2undPID-4, die nach v2.7 zurückgezogen, aber immer noch gesendet werden, werden wiePID-3behandelt.CX.7undCX.8werden zuIdentifier.period. Eine zuweisende Behörde, die eine ISO-OID (AUSHIC&2.16.840.1.113883.3.879&ISO) trägt, wird zuurn:oid:. Ein Typcode außerhalb der HL7-Tabelle 0203 wird als Text und nicht als einer beschriftet. - Zusammenführungen.
MRGbei einem Zusammenführungsereignis (A40und ähnliche) sendet den pensionierten Datensatz ebenfalls, inaktiv, mitPatient.linkin beide Richtungen. Bei jedem anderen Ereignis, wie einemA08, wird nichts zusammengeführt und eine Warnung besagt, dass der vorherige Identifikator noch aktiv ist. - Zeiten. Eine Geburtszeit in
PID-7geht zurpatient-birthTime-Erweiterung. Ein Zeitstempel ohne Offset nimmt die konfigurierte Zeitzone, andernfalls den Offset aufMSH-7(v2 geht davon aus, dass der Absender die lokale Zeit verwendet), andernfalls UTC. Eine Geburtszeit ist die Ausnahme: ohne Offset von einem der drei wird sie weggelassen, anstatt als UTC beschriftet zu werden, da ein falscher Offset die Geburt auf einen anderen Tag verschieben kann.birthDatewird beibehalten und eine Warnung besagt, dass die Zeit fallen gelassen wurde und dass das Festlegen einer Zeitzone für die Datenquelle sie beibehält. - Ergebnisse. Wiederholungen eines Textergebnisses werden mit Zeilenumbrüchen verbunden. Ein
ED-Ergebnis oder ein codiertes Ergebnis, dessen Wert offensichtlich Base64 ist, wird zu einer DocumentReference, auf die die Observation inderivedFromverweist, da eine R4-Observation keinen Anhangswert hat. EinSN-Vergleich von=wird als redundant fallen gelassen;<>behält den Text bei, da keine Menge "nicht gleich" sagen kann. - Besuche. Ein
A08mit einem Entlassungsdatum (PV1-45) ist ein abgeschlossener Kontakt. Ein fehlender oder unbekannter Patientenklassifikation ist der Null-GeschmackUNK, da R4 eine Klassifikation erfordert. - Z-Segmente werden in einer Warnung benannt, da es keine Standardzuordnung für sie gibt.
- Namen. Wenn der Absender einen Familiennamen (
XPN.1,XCN.2) in seine Teile aufteilt - ein Nachname-Präfix und einen Nachnamen, den eigenen und den eines Partners, wie niederländische und flämische Namen gesendet werden - istfamilyder gesamte Name und die Teile gehen in HL7's family-name-Erweiterungen (humanname-own-prefix,-own-name,-partner-prefix,-partner-name). - Verfahren.
PR1wird zu einem Verfahren mit dem Statusunknown, da ein ADT nicht angibt, ob es durchgeführt oder geplant wurde; der Anästhesist (PR1-8) und der Chirurg (PR1-11) sind Ausführende mit SNOMED CT-Rollen. Ein OPS-Code erhält auch seine SNOMED CT-Kategorie aus seinem Kapitel, gemäß HL7 DeutschlandsOPS-SNOMED-Category-Karte, die ISiK erfordert.
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 v6 | Von | Als |
|---|---|---|
| Patientendemografische Daten | PID | Name, 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 Aufenthalt | PV1 | Aufenthalt mit Typ, Klasse, Zeitraum, Standort und Teilnehmern |
| Einrichtungsinformationen | PV1-3 | Standort, mit der Einrichtung als seiner verantwortlichen Organisation |
| Probleme, Beginn | DG1 | Condition (Aufenthaltsdiagnose). DG1-5 ist der Beginn, wie ihn die HL7-v2-zu-FHIR-Karte hat |
| Allergien und Unverträglichkeiten, Reaktion | AL1 | AllergyIntolerance mit Kategorie, Kritikalität und Reaktion |
| Labor | ORU | DiagnosticReport, Observations, Specimen (aus SPM), ServiceRequest |
| Bestellungen | ORM, OML | ServiceRequest |
| Impfungen | VXU | Immunization |
| Klinische Notizen | MDM | DocumentReference |
| Mitglieder des Pflegeteams | PV1, TXA, DG1 | Practitioner |
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:
- Datensätze, die als
entered-in-errorgekennzeichnet sind, werden weggelassen. - Ein gelöster Zustand wird unter vergangener Erkrankung und nicht unter Problemen aufgeführt.
- Eine Medikamentenbestellung, die gestoppt oder abgeschlossen wurde, ist Geschichte und kein aktuelles Medikament.
- Die drei Abschnitte, die die IPS erfordert (Probleme, Allergien, Medikamente), sind immer vorhanden. Wenn ein Abschnitt nichts enthält, enthält der Abschnitt den kodierten leeren Grund
unavailableund gibt an, dass der Server keine Informationen enthält, "was nicht bedeutet, dass es keine gibt". Eine leere Allergieliste darf nie als "keine bekannten Allergien" gelesen werden. - Die Praktiker, Organisationen, Medikamente und Orte, auf die die Einträge verweisen, sind enthalten, so dass das Dokument selbst gelesen werden kann.
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.
- Jedes der fünfzehn Abschnitte der Leitlinie ist vorhanden, jeder mit seinem eigenen Text, in der Reihenfolge der Leitlinie: Vorausverfügungen, Allergien, Verhaltensgesundheit, Funktionsstatus, Impfungen, Entlassungsanweisungen, Medizinprodukte, Medikamente, Pflegeplan, Probleme, Eingriffe, Grund für die Überweisung, Ergebnisse, Sozialgeschichte und Vitalzeichen.
- Ein Abschnitt, den das Dokument nicht hatte, wird als fehlend bezeichnet, nie ausgefüllt. Er wird leer ausgegeben, mit dem codierten Grund
unavailableund dem Satz "Das sendende Dokument hatte keinen ... Abschnitt". Ein leerer Allergieabschnitt darf nicht "keine bekannten Allergien" lauten. - Ein Abschnitt, der nur als Text übertragen wird, behält seinen Text und erhält keine Einträge. Prosa wird nicht in codierte Daten umgewandelt. Funktionsstatus, Verhaltensgesundheit (der C-CDAs mentale Statusabschnitt), Vorausverfügungen, Medizinprodukte, Pflegeplan, Entlassungsanweisungen, Grund für die Überweisung und Sozialgeschichte werden heute auf diese Weise gesendet; die Anmerkungen sagen es für jeden.
- Codierte Einträge werden zu Ressourcen, nach den gleichen Regeln wie die gewöhnliche Umwandlung: Allergien (US Core AllergyIntolerance), Probleme und Entlassungsdiagnosen (US Core Condition, Problem- oder Encounterdiaignose), Eingriffe, Impfungen, Ergebnisse, Vitalzeichen und Medikamente als PACIO-Medikamentenliste von MedicationStatements (
104204-3, entlassene Medikamentenliste, aus einem Entlassungsmedikamentenabschnitt;104202-7, aktive Medikamentenliste, ansonsten). - Vitalzeichen in FHIR-Form. Ein systolischer und ein diastolischer Druck, die zusammen aufgenommen werden, werden zu einem Blutdruck-Panel (
85354-9) mit zwei Komponenten, und ein spezifischerer Code (Körpergewicht gemessen,3141-9) trägt auch den Code, den FHIRs Vitalzeichenprofile festlegen (29463-7), neben dem ursprünglichen. - Wer und von wo. Der Autor des Dokuments wird zum Autor der Zusammensetzung (ein Practitioner, mit dem NPI, wenn seine Prüfziffer gültig ist), sein Verwahrer zum Verwahrer-Organisation, sein umfassender Kontakt zum Aufenthalt, den die Zusammenfassung schließt. Ein Dokument ohne Person als Autor oder ohne Verwahrer wird abgelehnt: die Leitlinie erfordert beides, und Perfuse wird keinen Namen auf eine klinische Aufzeichnung setzen, die niemand gegeben hat.
- Negation behält ihre Bedeutung. "Keine bekannten Allergien" (eine verneinte Allergie auf jede Substanz) wird als SNOMED CT
716186003gesendet; eine verneinte Allergie auf ein Medikament wird abgelehnt, da FHIR es nicht sagen kann und die Ressource das Gegenteil sagen würde; eine verneinte Problematik istrefuted.
Drei Möglichkeiten, eines zu erstellen:
- Ein Kanal: Ein
cda-Ziel mitwrite: transferpostet die Übertragungszusammenfassung jedes Dokuments an den FHIR-ServersBundle-Endpunkt (url) oder schreibt<document>.transfer.jsonindir. Im Kanal-Builder: Emit › Eine PACIO-Übertragungszusammenfassung. - Die Kommandozeile:
perfuse fhir transfer [-authority OID=URI] [-out dir] <document.xml>.... - Die Konsole: Dokumente, aktivieren Sie Auch eine PACIO-Übertragungszusammenfassung erstellen und lesen Sie das Dokument.
Ü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:
| Thema | Auslöst auf | Filter |
|---|---|---|
https://perfuse.health/fhir/SubscriptionTopic/encounter | Encounter erstellt oder aktualisiert | patient, status, class |
https://perfuse.health/fhir/SubscriptionTopic/appointment | Terminvereinbarung erstellt oder aktualisiert | patient, 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:
- Eine bestätigte Änderung ist niemals eine verlorene Benachrichtigung. Die Benachrichtigung wird in derselben Datenbanktransaktion wie die Änderung, die sie beschreibt, aufgezeichnet und von dort ausgeliefert, sodass sie einen Neustart übersteht. Ein Test schreibt ein Encounter, startet einen neuen Server auf derselben Datenbank und überprüft, ob die Benachrichtigung ankommt.
- Benachrichtigungen arrive in der Reihenfolge und Lücken sind sichtbar. Ereignis 2 wird nicht vor Ereignis 1 akzeptiert, und jede Benachrichtigung enthält die laufende Zählung, sodass ein Empfänger erkennen kann, wenn er eine verpasst hat.
- Der Server entscheidet, wann ein Abonnement aktiv ist. Ein neues Abonnement wird
requestedund wird nur dannactive, wenn der Endpunkt einen Handschlag akzeptiert. Ein Client, deractiveanfordert, erhältrequested. Ein abgelehnter Handschlag wird viermal über etwa 15 Sekunden hinweg erneut versucht, bevor das Abonnement einenerror-Status erhält: es wird sofort ausgegeben, wenn das Abonnement gespeichert wird, oft bevor der Client, der es erstellt hat, zuhört. - Eine Vollressourcen-Benachrichtigung enthält die Version, die geändert wurde. Eine Entlassungsbenachrichtigung enthält die Entlassung, nicht das, was das Encounter zum Zeitpunkt der erfolgreichen Zustellung geworden war.
- Das Versagen ist begrenzt. Eine abgelehnte Zustellung wird mit einer zunehmenden Verzögerung erneut versucht. Nach zehn aufeinanderfolgenden Fehlern geht das Abonnement in den
error-Status: spätere Änderungen werden gezählt, aber nicht in die Warteschlange gestellt, und die Aktualisierung des Abonnements setzt die Zustellung von der ältesten gehaltenen Benachrichtigung fort. Die Zählung zeigt dann an, wie viele verpasst wurden.
Was ein Client den Server tun lassen kann, ist absichtlich begrenzt:
- Endpunkte müssen
httpssein, es sei denn, der Operator übergeben-fhir-subscriptions-allow-http, was für einen Testempfänger ist. - Die Egress-Richtlinie wird angewendet, wenn ein Abonnement erstellt wird, erneut bei jeder Lieferung und auf die Adresse, die jede Verbindung tatsächlich erreicht (also ein Name, der zwischen der Überprüfung und der Verbindung geändert wird, was zu einer Ablehnung führt); Umleitungen werden nicht verfolgt.
- Die Nutzlast ist standardmäßig auf
id-onlygesetzt, was angibt, was geändert wurde und es dem Empfänger ermöglicht, es mit seinen eigenen Anmeldeinformationen abzurufen. - Nichts, was ein Empfänger zurücksendet, wird jemandem gezeigt, nur sein Statuscode.
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:
- Kanäle andere als
rest-hook - Herzschläge
- Benachrichtigungen bei Löschung
- die
$status- und$events-Operationen
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.
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):
| Adresse | Akteur | Transaktionen |
|---|---|---|
/xds/repository | Dokumenten-Repository | ITI-41 Dokumentensatz bereitstellen und registrieren-b, ITI-43 Dokumentensatz abrufen |
/xds/registry | Dokumenten-Register | ITI-18 Registry-gespeicherte Abfrage (alle dreizehn gespeicherten Abfragen), ITI-42 Dokumentensatz registrieren-b |
/xca/gateway | XCA-Antwort-Gateway | ITI-38 Cross-Gateway-Abfrage, ITI-39 Cross-Gateway-Abfrage, mit -xds-home-community urn:oid:... |
/mhd | MHD-Dokumenten-Empfänger und -Antwortender | ITI-65 Dokumenten-Bundle bereitstellen, ITI-66 Listen finden, ITI-67 Dokumenten-Referenzen finden, ITI-68 Dokument abrufen |
/mhd/Patient | PDQm-Lieferant und PIXm-Manager | ITI-78 Patienten-Demografien-Abfrage, ITI-83 Patient/$ihe-pix, aus dem FHIR-Speicher der Patienten |
/pixv3 | PIX-Manager (HL7 v3) | ITI-44 Patienten-Identitäts-Feed HL7 V3, ITI-45 PIXV3-Abfrage, aus dem Patienten-Index (-mpi) |
/pdqv3 | PDQ-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:
periodStartundperiodEnd: erforderlich. Ein Datum bedeutet den gesamten Tag.reportType:summary,subjectodersubject-list.subject:Patient/<id>.reporter:Organization/<id>. Wenn es fehlt, enthält der Bericht eine Organisation mit dem Namen vonserve -measure-reporter.measure: Ein Measure, das inline als POST-Parameter gesendet wird.
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:
- 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.
- 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.
- 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üpft | Vor einem Überprüfer mit der richtigen Person platziert | Verpasst | Falsche Verknüpfungen | |
|---|---|---|---|---|
| Automatische Verknüpfung aus (Standard) | 0 | 2.649 von 3.000 | 351 | 0 |
| Ein, Standardgewichte | 1.637 | 1.012 | 351 | 0 |
| Ein, Gewichte aus den Aufzeichnungen geschätzt | 1.622 | 1.070 | 308 | 0 |
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.
8.16 SMART-Gesundheitslinks und -Karten
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.
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:
| Wert | Was gesendet wird |
|---|---|
none | Nichts. Der Standard. |
999 | Implementierungsbestätigung. Ersetzt die 997 für HIPAA-Transaktionen. |
997 | Funktionsbestätigung. Älter und immer noch das, was viele Verbindungspartner erwarten. |
ta1 | Interchange-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
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üssel | Was es tut |
|---|---|
enabled | Ob fehlgeschlagene Nachrichten überhaupt in die Queue gelegt werden. |
max_attempts | Wie oft versucht wird, bevor aufgegeben wird. |
backoff | Wartezeit vor dem ersten Wiederholungsversuch. |
max_backoff | Obergrenze für die wachsende Wartezeit. |
max_depth | Maximale Anzahl von Nachrichten, die gehalten werden. Unset bedeutet keine Begrenzung. |
retain_hours | Wie 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.
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 Registers | Perfuse 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 Schweregrad | Fehlgeschlagen, mit jedem ERR-Ort, -Code und -Text im Fehler. |
| AR oder CR | Fehlgeschlagen, auf die gleiche Weise. |
| Ein SOAP-Fehler (falsches Passwort, Nachricht zu groß) | Fehlgeschlagen, mit dem Grund des Registers. |
| Etwas, das keine HL7-Nachricht ist | Fehlgeschlagen. |
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
| Ergebnis | Bedeutung |
|---|---|
Delivered | Das Ziel hat die Nachricht akzeptiert. Für MLLP wurde eine positive Bestätigung erhalten. |
Queued | Die Lieferung ist fehlgeschlagen und die Nachricht wird erneut versucht. |
Failed | Die Lieferung ist fehlgeschlagen und wird nicht erneut versucht, entweder weil die Warteschlange ausgeschaltet ist oder die Versuche erschöpft sind. |
Filtered | Das 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.
framing | Was es schreibt |
|---|---|
mllp | 0x0b vor, 0x1c 0x0d nach. Die gleiche Rahmen, die ein MLLP-Ziel verwendet. |
delimited | Ein delimiter nach jeder Nachricht und ein optionaler start_block vor ihr. |
fixed | Aufzeichnungen, die auf record_length gepaddet oder gekürzt werden. |
length | Ein length_bytes-Präfix. big_endian und length_includes_header haben beide zwei Konventionen in der Praxis und die Differenz ist stillschweigend. |
whole | Eine 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.
- Bei einer Quelle wird die gesamte Datei, das Objekt, die E-Mail-Anlage oder der Anforderungstext zunächst geöffnet und dann in Nachrichten aufgeteilt, sodass eine als eine Datei verschlüsselte Batch funktioniert. Eine Datei, die nicht geöffnet werden kann, wird abgelehnt: Eine Dateiquelle verschiebt sie in ihren Fehlerordner, ein HTTP-Absender antwortet mit 400 und dem Grund.
require_signaturelehnt eine Nachricht ab, die nicht von einem derverify_withsigniert wurde;allow_unencryptedakzeptiert eine, die nur signiert ist;pass_plainlä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. - Bei einem Ziel wird das, was geliefert werden soll, verschlüsselt (mit einem der
encrypt_to) und signiert (mitsign_with), nach jedem anderen Schritt. Eine Datei-, SFTP-, FTP-, S3-, Azure-Blob- oder GCS-Ziel benennt die Datei noch immer nach der unverschlüsselten Nachricht, sodass${control_id}funktioniert, und jedes Framing ist innerhalb der Verschlüsselung.armor: trueschreibt.asc-Text anstelle von Binärdaten;no_compressdeaktiviert die Komprimierung;file_nameist der Name, der innerhalb der Nachricht transportiert wird.
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ätigt | Danach downstream vorhanden | Bestätigt, aber fehlend |
|---|---|---|
| 255 | 255 | 0 |
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 nach | Bestätigt | Downstream vorhanden | Verloren |
|---|---|---|---|
| 5 | 5 | 1 | 4 |
| 25 | 25 | 1 | 24 |
| 75 | 75 | 2 | 73 |
| 110 | 110 | 2 | 108 |
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
| Art | Wann ausgelöst |
|---|---|
error-rate | Fehler überschreiten einen Anteil des Datenverkehrs. |
queue-depth | Eine Warteschlange hat mehr als N Nachrichten im Warten. |
queue-age | Die älteste wartende Nachricht ist älter als eine Dauer. |
queue-stuck | Eine Warteschlange wird nicht entleert. |
no-traffic | Nichts ist für eine feste Periode angekommen. |
below-rhythm | Der Datenverkehr ist deutlich unter dem, was diese Feed normalerweise *zu dieser Tageszeit* tut. |
channel-down | Ein Kanal, der laufen sollte, ist nicht verfügbar. |
script-errors | Ein Skript schlägt fehl. |
rows-quarantined | Eine Datenbankquelle setzt Zeilen zurück. |
slow-delivery | Zustellungen sind erfolgreich, aber dauern zu lange. |
contract | Eine Nachricht verletzt den erklärten Vertrag des Kanals. |
phi-volume | Ein Kanal transportiert mehrere Male seine übliche Rate pro Stunde. |
phi-after-hours | Ein Kanal, der nur tagsüber Daten transportiert, transportiert einige nachts. |
phi-new-destination | Ein Kanal liefert an eine Adresse, an die er noch nie zuvor geliefert hat. |
phi-bulk-reads | Eine 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.
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.
below-rhythm— der Feed ist still geworden, obwohl er nicht still sein sollte.error-rate— Nachrichten werden empfangen und fehlschlagen.queue-age— etwas ist stecken geblieben, anstatt nur beschäftigt zu sein.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.
- Bursts (
phi-volume). Jeder Kanal wird mit seiner eigenen Historie zum gleichen Tageszeitpunkt verglichen, sodass ein beschäftigter Morgen keine Neuigkeit ist. Der Schwellenwert ist ein Vielfaches des üblichen Rates, standardmäßig drei. Ein Burst ist normalerweise ein Rückstau, der nach einem Ausfall freigegeben wird, und es sieht auch so aus, als würden Aufzeichnungen durch einen Feed extrahiert. - Nachverkehr auf einem Tageskanal (
phi-after-hours). Ein Kanal gilt als tagsüber nur, wenn weniger als 2 Prozent dessen, was er transportiert hat, außerhalb von 07:00 bis 19:00 Uhr in der Zeitzone des Servers liegen. - Ein neues Ziel (
phi-new-destination). Die Adresse ist das, was das Ziel benennt: ein Host und Port, eine URL, ein Ordner. Das Umbenennen eines Ziels ist keine Neuigkeit; das Umstellen auf einen neuen Host ist es jedoch. Die Adressen, an die jeder Kanal gesendet hat, werden inaccess-watch.jsonneben der Datenbank gespeichert, sodass ein geändertes Ziel auch dann gemeldet wird, wenn der Server heruntergefahren war. - Bulk-Lesevorgänge (
phi-bulk-reads). Aus der Audit-Trail gezählt: Nachrichten geöffnet, Patienten gesucht oder nachgeschlagen (PDQm, PIXm, Identitätssuche), Dokumente und Bilder gelesen (XDS, MHD, DICOMweb), vorherige Genehmigungen gelesen, Zusammenfassungen und Ansichten ausgeführt. Das erneute Lesen desselben Datensatzes wird nicht zweimal gezählt. Der Schwellenwert ist die Anzahl der verschiedenen Datensätze pro Minute, standardmäßig zehn, pro Konto von einer Adresse.
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.
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:
- Was der Filter gelesen hat. Welche Felder er betrachtet hat und welche Werte er gefunden hat. Ein Filter, der alles ablehnt, liest normalerweise einen Pfad, der in diesem Feed nicht existiert, und benennt ihn.
- Jede Transformation. Was sie geändert hat, von was zu was.
- Was jedes Ziel entschieden hat. Ob es die Nachricht akzeptieren würde und warum nicht, wenn es sie nicht akzeptieren würde.
- Die Ausgabe. Die Nachricht, wie sie jedes Ziel senden würde.
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
| Ergebnis | Bedeutung |
|---|---|
changed | Der Schritt wurde ausgeführt und hat die Nachricht modifiziert. |
no-effect | Der Schritt wurde ausgeführt, und die Nachricht ist unverändert. |
skipped | Die when-Bedingung des Schritts war falsch, daher wurde er nicht ausgeführt. |
failed | Der 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.
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:
- Trigger-Ereignisse in den tatsächlich beobachteten Proportionen, mit mindestens einem von jedem, damit ein seltenes Ereignis immer noch erscheint.
- Felder, die mit den tatsächlichen Raten belegt sind - also der Fall, in dem ein Feld *fehlt*, wird getestet, was der Fall ist, der Dinge bricht.
- Wiederholungen, wo Wiederholungen vorkommen, komposite Struktur, wo sie vorkommt.
- Codes, die aus den tatsächlich gesehenen Code-Tabellen gezogen werden.
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.
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.
| Container | Checks | Was es gefunden hat |
|---|---|---|
| Keycloak 26 | web/e2e-saml/, und internal/saml-Fixtures | Ein 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 Entra | internal/saml-Live-Tests und -Fixtures | Zwei 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 FHIR | go test ./internal/engine/ -run HAPI | Ein Defekt. Eine nicht zugeordnete Zuweisungsbehörde produzierte ein Identifikationssystem, das eine OID ankündigte und ein Wort trug, das HAPI ohne Beschwerde akzeptierte |
| ActiveMQ | go test ./internal/engine/ -run RealBroker | Korrekt, einschließlich des Nullbyte-Rahmenfalls. Behauptet durch die Verwaltungsschnittstelle des Brokers selbst und nicht durch eine Funktion, die nil zurückgibt |
| nginx, Clientzertifikate | go test ./internal/engine/ -run ClientCertificate | Korrekt |
| Orthanc (ein echter PACS) | go test ./internal/engine/ -run RealPACS | Korrekt. Ein C-STORE arrives und der Patientenname, -identifikator, Studiendatum, Modalität und SOP-Klasse überleben alle |
| PostgreSQL | go test ./internal/engine/ -run RealPostgres | Korrekt, 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-Server | go test ./internal/engine/ -run OpenSSHServer | Korrekt. 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.2 | go test ./internal/mirth/ -run RealMirth | Korrekt 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:
- SMB gegen einen echten Windows-Freigabe — der Protokollcode ist vollständig und für Pfadsicherheit und Argumentbehandlung getestet, aber kein Test öffnet einen Socket zu einem domain-verbundenen Server.
- Ein echter Serieller Anschluss.
- Der Mirth-Importer gegen XML, das von einem echten Mirth produziert wurde. Getestet gegen Mirth 4.5.2 in einem Container, und das Ergebnis war über dieses Repository: das einzige Migration-Fixture hier wurde von Hand geschrieben und Mirth lädt es nicht — es speichert den Kanal als ungültig und verwerft jeden Connector. Was geklärt wurde, ist, dass die
version-Attribute, die ein echtes Mirth auf jedem Element schreibt, zum gleichen Kanal parse, also sind sie keine Gefahr; was nicht geklärt ist, ist alles andere, was ein echter Export enthält. - SAML gegen einen gehosteten kommerziellen Identitätsanbieter. Keycloak ist verifiziert; ein Anbieter beweist, dass eine Implementierung einem Anbieter entspricht.
- Ein NCPDP-Anspruch durch einen echten Apotheken-Switch.
- Eine SCRIPT-Nachricht durch Surescripts, wo die Zertifizierung ein kommerzieller Prozess und kein technischer ist.
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.
| Ergebnis | Anzahl |
|---|---|
| Ressourcen, die mit keinen Ergebnissen validiert wurden | 13.723 |
| Ressourcen, die als ungültig gemeldet wurden | 0 |
| Dateien, die als unimplementierter Ressourcentyp abgelehnt wurden | 753 |
| Bundle-Einträge, die als unimplementierter Typ übersprungen wurden | 1.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:
| Export | Aus dem Administrator | Was übernommen wird |
|---|---|---|
| Ein Kanal | Export Channel | Der Kanal |
| Eine Kanalgruppe | Export Group | Jeder Kanal in ihr, jeder behält die Gruppe |
| Code-Vorlagen | Export Code Templates | Jede Bibliothek als eine Skriptdatei |
| Ein Server-Backup | Backup Config, oder GET /api/server/configuration | Alle 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.
15.4.1 Vier Zahlen, kein Bestehensgrad
| Ergebnis | Bedeutung |
|---|---|
| Identisch | Byte für Byte identisch. |
| Nur kosmetische Änderungen | Unterscheidet sich in Punkten, die keine Informationen tragen — nachfolgende leere Felder, ein abschließender Terminator. |
| Unterschiede | Der Wert eines Feldes ist unterschiedlich. |
| Kann nicht ausgeführt werden | Perfuse 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
- Importieren Sie die Kanäle und lösen Sie alles, was als nicht lesbar gemeldet wird.
- Überprüfen Sie für jeden Kanal die Warnungen. Die meisten werden Skripte sein.
- Exportieren Sie einige tausend Nachrichtenpaare aus Mirth für den aktivsten Kanal und führen Sie den Vergleich durch.
- Arbeiten Sie die Ergebnisse durch. Systematische sind jeweils eine Entscheidung.
- Führen Sie den Vorgang erneut durch, bis die einzigen Unterschiede diejenigen sind, die Sie als korrekt entschieden haben.
- 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.
- 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.
| Paket | Klassen |
|---|---|
java.util | ArrayList, 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.lang | String, StringBuilder, StringBuffer, Integer, Long, Short, Byte, Double, Float, Boolean, Math, System (nur Zeit und Zeilen-Trenner) |
java.text, java.math, java.net, java.nio | SimpleDateFormat und DateFormat (Mirths Musterbuchstaben), BigDecimal (als Doppelwert), URLEncoder, URLDecoder, StandardCharsets |
| Apache Commons | lang3.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
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
| API | Was es dient | Anleitungen | Aktiviert durch |
|---|---|---|---|
| Patientenzugriff | Ein Mitgliedsansprüche, klinische Daten und vorherige Genehmigungen an eine von ihm ausgewählte App | CARIN Blue Button 2.2.0, PDex 2.2.0, US Core, SMART App Launch | -fhir und ein SMART-Issuer (-smart-issuer) |
| Zugriff für Anbieter | Dasselbe für die einem Anbieter zugeordneten Mitglieder, in Bulk | PDex 2.2.0, Da Vinci ATR 2.1.0, Bulk Data | -fhir-payer-apis und -fhir-bulk-export |
| Payer-to-Payer | Ein Mitgliedsdatensatz an einen anderen Payer, nachdem sie abgeglichen wurden | HRex 1.2.0 $member-match, PDex 2.2.0 | -fhir-payer-apis |
| Vorabgenehmigung | Was eine Bestellung benötigt, die Dokumentation, dann die Anfrage und die Entscheidung | Da 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:
- 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); - aus der Registrierung des Anrufers:
davinci_version: "2.1"auf einem SMART-Client (-smart-clients) oder einem CDS-Client (-cds-clients); - 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:
billing_codes: die Codes, unter denen abgerechnet wird.details: Grenzen und Kosten, wie z.B.allowed-periododerin-network-copay.contact: wer angerufen werden kann.expiry_days: wie lange die Antwort gültig ist.depends_on: Codes anderer Bestellungen, von denen die Antwort abhängt, sodass die EHR erneut fragt, wenn sie sich ändern.doc_purpose: wofür die Dokumentation ist (withclaim,withorder,retain-doc).withpawird abgelehnt, weil CRD 2.2.1 eigene Invariante crd-ci-q4 ablehnt.
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:
- ein Patient, der kein Mitglied ist, wird mit
no-member-foundbeantwortet; - ein Mitglied, dessen Versicherungsschutz nicht übereinstimmt, wird mit
coverage-not-foundbeantwortet; - eine bereits vorab genehmigte Autorisierung für den Dienst (eine ClaimResponse mit einem
preAuthRef) macht die Antwortsatisfied,
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:
- Das Identifikationssystem. CARIN erfordert, dass die Mitglieds-Identifikation den Namensraum des Zahlungspflichtigen angibt.
-systemist erforderlich; es gibt keine Standardvorgabe, da eine Standardvorgabe jedem Zahlungspflichtigen, der Perfuse verwendet, denselben Namensraum geben würde. - Der Netzwerkstatus. Weder Transaktion gibt an, ob der Abrechnungsanbieter im Netzwerk ist, und es entscheidet, was der Mitglied zahlt. Ohne
-networkist der Vorteilszahlungsstatusotherund die Umwandlungsnote erklärt, warum. - Ein Anspruch, den die 835 nicht erwähnt. Ein CARIN ExplanationOfBenefit ist ein festgestellter Anspruch. Ohne die 835 gibt es keine Zahlungspflichtigen-Anspruchszahl, keine Zahlung und keine Mitgliedshaftung, sodass der Anspruch als übersprungen und nicht umgewandelt gemeldet wird.
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:
POST /fhir/Patient/$member-match— HRex-Mitgliedermatching. Die Abdeckungs-IDs werden auf einige Kandidaten eingeschränkt und der Familienname und das Geburtsdatum müssen dann übereinstimmen; ein Vorname wird durch den Anfangsbuchstaben verglichen und das Geschlecht nur dann, wenn beide Seiten es angeben. Mehr als ein überlebender Kandidat ist kein Match und die Antwort ist 422 anstelle eines Ratschlags, da ein Ratschlag die Ansprüche eines Fremden offenlegt. Eine aktive Zustimmung, die die Offenlegung erlaubt, ist erforderlich, da die Payer-to-Payer-API optional für das Mitglied ist;-fhir-member-match-without-consentschaltet dies für Tests aus.GEToderPOST /fhir/Group/{id}/$davinci-data-export— der Da-Vinci-Bulk-Export der aktuellen Mitglieder einer Gruppe.exportTypewählt das Publikum:hl7.fhir.us.davinci-pdex#provider-downloadoder#provider-deltafür Provider-Zugriff,#payertopayerfür Payer-to-Payer.GET /fhir/Group/{id}/$export— der Standard-Bulk-Data-Gruppen-Export, der als Provider-Zugriff behandelt wird.
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:
| Anfrage | Antwort |
|---|---|
PAInitiationRequest | Closed, 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. |
PARequest | Entscheidet als PAS-Anfrage: Approved mit der Genehmigungsnummer und dem Zeitraum, Denied mit dem Grund oder Open unter Überprüfung. |
PAAppealRequest | Ein abgelehnter Fall wird erneut entschieden, basierend auf dem Grund in PANote (eine Berufung ohne einen wird aufgefordert, ihn anzugeben). |
PACancelRequest | Approved, 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:
| Transport | Was gesendet wird | Authentifizierung |
|---|---|---|
x12 (Standard) | Die 278-Anfrage als application/edi-x12; die Antwort ist der Antworttext | Ein Bearer-Token, OAuth, HTTP-Basic, ein Clientzertifikat |
core-soap | Die 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-Anhang | vC2.2.0: ein Benutzername und ein Passwort (WS-Sicherheit-UsernameToken) oder ein Clientzertifikat. vC4.0.0: ein Clientzertifikat und ein OAuth-Token |
core-mime | Die CAQH-CORE-vC2.2.0-HTTP-MIME-Multipart-Hülle, die Payload als Dateiteil | Der Benutzername und das Passwort der Hülle oder ein Clientzertifikat |
sftp | Jede 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:
| Status | Bedeutung |
|---|---|
| Bereit hier | Perfuse stellt es bereit und es ist eingeschaltet. |
| Bereit, mit einer Lücke | Es ist eingeschaltet, und ein Teil des Kriteriums liegt außerhalb davon (auf dem Bildschirm benannt). |
| Erstellt, nicht eingeschaltet | Perfuse stellt es bereit; der Bildschirm benennt die Einstellung oder den Schalter, der es einschaltet. |
| Ihre Aufgabe | Der Teil der Organisation: eine Vereinbarung, eine Zertifizierung, Veröffentlichung im Nationalen Anbieterverzeichnis. |
| Nicht erstellt | Software würde es tun, und Perfuse tut es nicht. |
Was die vier in Kraft gesetzten Kriterien von diesem Server benötigen:
| Kriterium | In Perfuse | Einschalten |
|---|---|---|
| 13 FHIR-APIs, US Core, Bulk Data | Der FHIR-Endpunkt mit seinem CapabilityStatement und $export | -fhir, -fhir-bulk-export |
| 14 Dokumente als FHIR-Anhänge | DocumentReference mit Binary und IHE MHD über das XDS-Register | -fhir (MHD auch -xds) |
| 15 Begegnungs- und Terminbenachrichtigungen | Themenbasierte Abonnements (R5-Backport für R4) von ADT- und SIU-Feeds | -fhir-subscriptions |
| 16 Aufzeichnungslokator | Das 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.
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:
| Rolle | Kann |
|---|---|
| Monitor | Überprüfen, ob alles funktioniert: Kanalstatus, Zähler, Flussdiagramm, Warnungen, Dashboards, Metriken und die Tiefe der Warteschlange. Keine Nachrichteninhalte, Kanaldateien oder gewartete Nachrichten. |
| Viewer | Auch Nachrichten lesen, Kanaldateien, Spuren und den Aktivitätsprotokoll. |
| Operator | Auch erneut senden: eine Nachricht erneut verarbeiten, einen Kanal erneut abspielen und gewartete Lieferungen erneut versuchen. |
| Editor | Auch Kanäle erstellen und ändern sowie Vergleiche durchführen. |
| Admin | Auch 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:
- Perfuse-API-Token, die unter Benutzer → Maschinenanmeldeinformationen erstellt oder mit
perfuse token createerstellt werden. Jedes trägt eine Rolle und kann auf FHIR-Gruppen beschränkt werden. Dies ist der Standard, wenn kein SMART-Autorisierungsserver konfiguriert ist. - SMART-Zugriffstoken, von Perfuses eigenem Autorisierungsserver (
-smart-clients) oder einem externen Server (-smart-issuer). Jedes trägt Berechtigungen und der Endpunkt hält jeden Zugriff auf sie.
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:
- Schreibt eine Minute von einem Client (
-fhir-writes-per-minute): Erstellt, aktualisiert und löscht von einer Client-Adresse. Darüber hinaus wird ein Schreibvorgang mit 429 undRetry-After: 60beantwortet. Lese- und Suchvorgänge, einschließlich Suchvorgängen per POST, werden nie gezählt. - Meiste Ressourcen gehalten (
-fhir-max-resources): Darüber hinaus werden neue Ressourcen mit 507 abgelehnt, während Aktualisierungen und Löschungen weiterhin funktionieren.
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>" } } } }
| Werkzeug | Rolle | Was es tut |
|---|---|---|
server_status, list_channels, queue, alerts | Überwachung | Ob alles funktioniert, ohne Nachrichteninhalte |
get_channel, search_messages, get_message, find_patient, fhir_search | Betrachter | Kanäle, Nachrichten (mit Inhalten), eine Patientennachrichten über Formate hinweg, eine FHIR-Suche |
retry_delivery, reprocess_message | Operator und mcp:write | Eine ausgestellte Lieferung wiederholen, eine Nachricht erneut durch ihren Kanal senden |
start_channel, stop_channel | Admin und mcp:write | Einen 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:
| Speicher | Gefunden durch |
|---|---|
| Nachrichten | den Identitätsindex (Einstellungen → Daten → Patientenidentifikatoren indizieren); ohne diesen können Nachrichten nicht durch Identifikatoren gefunden werden |
| Die Zustellwarteschlange | durch Lesen der Identifikatoren jeder wartenden Nachricht |
| Der FHIR-Speicher | die Patientenressourcen, die einen Identifikator tragen, und jede Ressource, deren indizierte Verweise auf einen hinweisen |
| Anfragen für vorherige Genehmigungen | die Identifikatoren des Patienten der Anfrage |
| Der Patientenindex | den 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.
- Zugriff und Übertragbarkeit: Kopie herunterladen gibt eine Zip-Datei aus: jede Nachricht wie empfangen mit ihrem Datensatz, jede FHIR-Ressource mit jeder gespeicherten Version, vorherige Autorisierungsanfragen und deren Antworten sowie die Datensätze des Patientenregisters, durchgängig im JSON-Format, mit einer README-Datei, die erklärt, was jeder Teil ist. Als beantwortet markieren schließt es ab.
- Löschung: Ein zweiter Administrator genehmigt dies (derjenige, der es aufgezeichnet hat, kann es nicht tun). Jetzt löschen löscht alles, was gefunden wird: Nachrichten im Ganzen (Datensatz, Inhalt, Zustellungen, Identifikatoren, Anlagen, die keine andere Nachricht verwendet), wartende Zustellungen (sie werden nicht gesendet), die FHIR-Ressourcen mit ihrer Historie, vorherige Autorisierungsanfragen mit ihren Antworten, Anlagen und Tracking-Nummern sowie die Person im Patientenregister mit jedem verknüpften Datensatz und ihrer Historie (ein Ereignis protokolliert, dass eine Löschung stattgefunden hat und von wem).
- Einschränkung: Als rechtliche Sperrung aufgezeichnet, sodass nichts gelöscht oder abläuft, solange sie besteht.
- Ablehnen schließt eine Anfrage mit ihrem Grund ab, den die Person erfahren muss.
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.
- Kanäle: wie viele Kanäle der Mandant haben darf. Die Erstellung eines weiteren Kanals wird abgelehnt, mit der Anzahl und dem Grenzwert.
- Nachrichten pro Minute: wie viele Nachrichten seine Kanäle zusammen pro Minute empfangen dürfen.
- Speicher: wie viel gespeicherten Nachrichteninhalte er behalten darf, in Megabyte.
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:
- Nur das von Ihnen konfigurierte Zertifikat wird vertraut. Ein in einer Antwort enthaltenes Zertifikat wird nie verwendet. Ein Angreifer, der ein Dokument senden kann, kann auch sein eigenes Zertifikat hinzufügen, und ein Verifizierer, der es liest, kann von jedem als jeder authentifiziert werden.
- Eine Antwort muss auf eine Anmeldung antworten, die dieser Server gestartet hat. Perfuse erinnert sich an die Anfrage, die es gesendet hat, und lehnt eine Antwort ab, die etwas anderes nennt oder eine Anfrage, die es bereits beantwortet hat. Ohne diese Überprüfung ist eine gültige Antwort ein Bearer-Token für den, der es hält: Jemand meldet sich als sich selbst an, behält die Antwort und postet sie in Ihren Browser, und Sie sind dann in seinem Konto, wobei der Audit-Log seinen Namen aufzeichnet.
- Anmeldungen, die am Identitätsanbieter gestartet werden, sind daher standardmäßig deaktiviert. Aktivieren Sie *Anmeldungen, die am Identitätsanbieter gestartet werden* nur, wenn Sie ein Portal-Tile benötigen und wissen, dass es das oben Genannte ermöglicht.
- Das Gruppenattribut hat keinen Standardwert und ist erforderlich. Entra sendet
groups, Okta sendet, was die Anwendung konfiguriert wurde, ADFS sendet eine Claim-URI. Eine Vermutung würde zu einer Anmeldung führen, die funktioniert und niemandem etwas gewährt. Wenn eine Anmeldung wegen fehlender Rolle abgelehnt wird, nennt der Server-Log die Attribute, die tatsächlich angekommen sind — was in der Regel die ganze Antwort ist. - Die Antwort-URL muss genau übereinstimmen mit der bei dem Anbieter registrierten URL. Eine Antwort sagt, wo sie bestimmt war, und eine an anderer Stelle adressierte Antwort wird abgelehnt, da ihre Annahme bedeuten würde, eine Antwort anzunehmen, die für einen anderen Dienst bestimmt war.
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.
| Anbieter | Sendet in der Regel | Hinweise |
|---|---|---|
| Keycloak | groups | Benötigt einen Gruppenmitgliedschafts-Zuordner, der dem Client hinzugefügt wird. |
| Entra ID | eine Claim-URI, die mit /claims/groups endet | Sendet Gruppen-Objekt-IDs, es sei denn, die Anwendung ist konfiguriert, um Namen zu senden. Ordnen Sie die IDs zu, oder ändern Sie den Anbieter. |
| Okta | was die Anwendung konfiguriert wurde | Häufig groups, wobei ein Filter entscheidet, welche gesendet werden. |
| ADFS | eine Claim-URI | Signiert 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.
- Das Deaktivieren eines Kontos beendet dessen Sitzungen sofort, und der Server überprüft, dass keine überlebt hat, bevor er antwortet. Ein Anbieter wird nie darüber informiert, dass ein Konto deaktiviert wurde, wenn es nicht deaktiviert wurde, da ein Anbieter nichts wiederholt, was ihm als erfolgreich gemeldet wurde.
- Ein Löschen deaktiviert zunächst und löscht dann, so dass ein Fehler auf halbem Weg ein Konto zurücklässt, auf das niemand zugreifen kann. Die Prüfhistorie eines entfernten Kontos wird beibehalten.
- Die Rolle stammt von den Gruppen oder Rollen der Person, abgeglichen nach Namen: Eine Gruppe, deren Name *admin*, *editor*, *operator*, *viewer* (oder *read-only*) oder *monitor* enthält, gewährt diese Rolle, sodass
APP-Perfuse-EditorundPerfuse Operatorswie benannt funktionieren. Alles andere erhält-scim-default-role, Betrachter, sofern nicht anders festgelegt. Plattform kann auf diese Weise nie gewährt werden. - Keine Passwörter. Ein Konto, das durch SCIM erstellt wird, meldet sich über den Identitätsanbieter an; ein zweites Passwort, das niemand in der Hierarchie kennt, würde ein Deaktivieren dort überleben.
/scim/v2/ServiceProviderConfigsagt, was unterstützt wird: Erstellen, Lesen, Ersetzen, Patchen und Löschen von Benutzern sowie Filter bis zu 200 Ergebnissen. Bulk-Operationen, Sortieren und ETags werden nicht unterstützt.
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.
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
- Der Agent beantwortet GET-, GETNEXT- und GETBULK-Anfragen und nur von den Netzwerken in
-snmp-allow: Die Community von v2c ist ein in Klartext gesendtes Passwort, daher ist es niemals für jeden zugänglich. Eine Community mit weniger als 6 Zeichen oderpublic/privatestoppt den Server beim Start. - Er dient der Systemgruppe (sysDescr, sysUpTime, sysName aus dem Fleet-Label, sysContact, sysLocation), Gesamtwerten unter
BASE.1(Kanäle, laufend, defekt, empfangen, zugestellt, fehlgeschlagen, wartend) und einer Kanaltabelle unterBASE.2.1(Name, laufend oder gestoppt, empfangen, zugestellt, fehlgeschlagen, wartend, Alter der ältesten wartenden Nachricht). Die Zahlen sind diejenigen, die das Dashboard und/metricsanzeigen. - Traps gehen an jeden Manager in
-snmp-traps:BASE.0.1eine ausgelöste Warnung,BASE.0.2eine gelöste Warnung, mit der Art der Warnung, Schweregrad, Kanal, Ziel und Zusammenfassung. Nie Nachrichteninhalte. Eine bestätigte Warnung sendet keinen Trap. BASEist1.3.6.1.4.1.8072.9999.9999.16(Net-SNMP-Experimentierbereich), es sei denn,-snmp-base-oidlegt es unter Ihrer eigenen Unternehmensnummer fest. MIB herunterladen auf der Einstellungsseite (oderGET /api/snmp/mib) gibt eine MIB für die verwendete Basis aus; das gleiche Panel sagt, ob der Agent antwortet und wie viele Traps gesendet wurden.
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.
active-passive: Der Leader führt jeden Kanal und jeden Job aus, der einmal laufen muss (FHIR-Abonnementbenachrichtigungen). Die anderen warten. Das ist die einfachste Variante, die man verstehen kann, und das, was ein Standort mit einem beschäftigten Server und einem Reserve-Server möchte.active-active: Die Kanäle werden auf die aktiven Server verteilt, etwa gleichmäßig. Ein Server, der stoppt, übergibt seine Kanäle an die anderen; ein Server, der beitritt, übernimmt seinen Anteil, wenn Kanäle frei werden, einer nach dem anderen. Kanäle, die aneinander weiterleiten (ein Kanalziel), laufen auf einem Server und bewegen sich zusammen, da die Weiterleitung innerhalb eines Servers stattfindet. Ein Administrator kann einen Kanal von Hand von Überwachung → Fleet verschieben; er bleibt dort, wo er platziert wurde, solange dieser Server existiert.
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:
| Test | Nachrichten | Bestätigt, aber verloren | Duplikate | Längste Wartezeit eines Absenders |
|---|---|---|---|---|
| Aktiv-Passiv, der Server, der den Feed ausführt, zweimal getötet (Linux, dann Windows), Empfänger ablehnend dazwischen | 2.000 | 0 | 0 | 15 s |
| Ein Linux-Leader, der vom Datenbankzugriff abgeschnitten wird (Firewall), sein Prozess weiterläuft | 3.000 | 0 | 1 | 16 s |
| Ein Windows-Leader, der vom Datenbankzugriff abgeschnitten wird | 3.000 | 0 | 0 | 20 s |
| Der Leader wird getötet, während die Uhr eines Servers 2 Minuten schneller und die eines anderen 90 Sekunden langsamer läuft | 2.000 | 0 | 0 | 18 s |
| Aktiv-Aktiv, vier Feeds über drei Server, einer getötet und zurückgebracht | 6.000 | 0 | 2 | 24 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*.
-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:
- Der gleiche Salz erzeugt immer den gleichen Korpus, sodass ein gemeinsamer Korpus neu generiert werden kann, anstatt archiviert zu werden.
- Bewahren Sie den Salz geheim. Pseudonyme werden von realen Werten abgeleitet, sodass jeder, der den Salz besitzt, eine Vermutung über die Identität eines Datensatzes bestätigen kann.
-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.
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:
-measure FILE, or-measure example:IDfor a shipped example: required.-exampleslists the examples.-period-startand-period-end: required.-type summary|subject|subject-list.-subject Patient/ID.-reporter NAME.-o FILE.
Siehe digitale Qualitätsmaße.
19.6.5 FHIR-Flags auf Perfuse serve
| Flagge | Effekt |
|---|---|
-fhir | FHIR-Endpunkt unter /fhir bereitstellen. Standardmäßig aktiviert. |
-fhir-version | Die bereitgestellte Version. Standardmäßig R4. |
-fhir-read-only | Schreiboperationen ablehnen. |
-fhir-api-tokens | Mit 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-subscriptions | Themenabonnements aktivieren: Begegnungs- und Terminbenachrichtigungen an Endpunkte, die FHIR-Clients auswählen. Standardmäßig deaktiviert; benötigt R4 und einen beschreibbaren Endpunkt. |
-fhir-subscriptions-allow-http | Abonnements über plain http zulassen. Für einen Testempfänger, niemals für Patientendaten in einem Netzwerk. |
-fhir-patient-directory-search | Ein Token, das auf einen Patienten beschränkt ist, darf das Verzeichnis (Praktiker, Organisationen, Standorte) innerhalb seiner Berechtigungen durchsuchen. Standardmäßig deaktiviert. |
-fhir-declares | Leitfä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
| Option | Takes | Default | What it does | In the console |
|---|---|---|---|---|
-addr | string | 127.0.0.1:8080, or 127.0.0.1:8443 with -tls-cert | address to serve the interface on | — |
-alert-severity | string | warning | minimum severity to send to the webhook: warning or critical | Settings › Alerts › Delivery: Only send alerts at least this serious |
-alert-webhook | string | — | POST alerts to this URL as JSON. Works with Slack, Teams, Mattermost, Alertmanager or anything that accepts a webhook. The payload carries channel names, counts and thresholds; never message content | Settings › Alerts › Delivery: Send alerts to this address |
-alerts | string | — | YAML file of alert rules. Default: alerts.yaml beside the database, written when the rules are first saved in the console; until then a conservative default set is used | — |
-allow-metadata-egress | on/off | — | permit destinations pointed at cloud instance metadata addresses, which hold this machine's credentials | Settings › Security › What may leave: Allow destinations at cloud instance metadata addresses |
-cds-clients | string | — | the EHRs trusted to call the CDS services with signed JWTs (issuer and jwks_url) | Settings › Payers › Prior authorization: EHRs trusted to call the CDS services |
-channels | string | ./channels | directory holding channel files | — |
-cluster | string | — | share the work with other servers on the same PostgreSQL -db: active-passive (one runs everything, another takes over when it stops) or active-active (channels spread over all) | — |
-cluster-lease | duration | 15s | how long a crashed server holds its work before another takes it over; renewed five times as often | — |
-crd-advisor-ca | string | — | a PEM file of certificate authorities to trust for -crd-advisor-url beside the system's (Vaglio's is its DATA/tls/ca.crt) | Settings › Payers › Decision service: Certificate authorities to trust for the advice service |
-crd-advisor-token-env | string | — | name of an environment variable holding a bearer token for -crd-advisor-url (the token itself is never a flag) | Settings › Payers › Decision service: Environment variable holding the advice service's token |
-crd-advisor-url | string | — | with -crd-rules, ask the decision service at this URL (such as Vaglio's /api/pas/advise) what a prior authorization request for each order needing one would be told as the record stands, shown as one more CRD card; the prefetched record is POSTed to it. No answer, or any failure, leaves the cards as they are without it | Settings › Payers › Decision service: Advice before submitting (CRD) |
-crd-rules | string | — | a Da Vinci CRD rules file: serve coverage requirements over CDS Hooks at /cds-services | Settings › Payers › Prior authorization: Coverage rules file (Da Vinci CRD) |
-dashboards | string | — | a file mapping directory groups and roles to the dashboard each opens on | Settings › Monitoring › Dashboards: Which dashboard each group opens on (file) |
-data | string | — | directory for this server's own files (settings, alerts, sign-in configuration, the log): default beside -db when it is a file, the current directory when it is a PostgreSQL URL | — |
-davinci-version | string | 2.2 | the Da Vinci CRD, DTR and PAS release answered when neither a request nor its client's registration says: 2.2 (CRD 2.2.1, DTR 2.2.0, PAS 2.2.1) or 2.1 (2.1.0) | — |
-db | string | ./perfuse.db | database for users, messages and stored resources: a file, or a postgres:// URL for servers that share one store (a cluster) | — |
-demo-account | string | — | for a public demonstration server: username:password of a shared viewer account shown on the sign-in page | — |
-dicomweb-archive | string | — | keep imaging objects in this directory and serve them over DICOMweb (QIDO-RS, WADO-RS, WADO-URI, STOW-RS) at /dicomweb | Settings › Data › Imaging archive: Keep images in this folder and serve them over DICOMweb |
-dicomweb-cors | string | — | comma-separated browser origins, such as an OHIF viewer's, allowed to call /dicomweb | Settings › Data › Imaging archive: Browser origins allowed to call it |
-drain-for | duration | — | after SIGTERM, report not-ready for this long before shutting down (for rolling deploys) | Settings › Engine › Shutdown: Wait for in-flight messages on shutdown |
-ecr-agency | string | — | play a public health agency for testing eCR: answer case reports at $process-message with a Reportability Response, using the agency YAML file given (name, phone, address, endpoint; optional rctc, reply) | Settings › Public health › Case reporting: Act as a test public health agency |
-ecr-responses | on/off | — | accept eCR Reportability Responses at the FHIR endpoint's $process-message, storing each as DocumentReference/<id> derived from the eICR it answers | Settings › Public health › Case reporting: Receive Reportability Responses |
-engine | on/off | true | run the channel engine in this process, so the interface can start, stop and monitor channels | — |
-epa-payer-id | string | — | this payer's identifier on the prescribing network, the From of every RTPB and ePA response (default: the formulary's payer id) | Settings › Payers › Drug formulary: Payer ID on the prescribing network |
-epa-reply-channel | string | — | route ePA decisions made after the request was answered (a reviewer's, an appeal's) to this channel, which delivers them to the prescriber's network | Settings › Payers › Drug formulary: Channel that sends later ePA decisions |
-fhir | on/off | true | serve a FHIR endpoint at /fhir | Settings › FHIR › The FHIR server: Serve a FHIR endpoint at /fhir |
-fhir-api-tokens | on/off | — | with SMART configured, accept Perfuse API tokens on the FHIR endpoint as well (unscoped; the console's FHIR settings can switch it) | Settings › FHIR › Access: Accept Perfuse API tokens beside SMART tokens |
-fhir-bulk-export | on/off | — | enable $export, which produces a file holding every record the FHIR endpoint serves | Settings › FHIR › Bulk data: Bulk Data export ($export) |
-fhir-declares | string | — | guides this FHIR server declares in its capability statement, comma-separated: a CapabilityStatement address, or Type=profile address | Settings › FHIR › Capability statement: Guides this server declares |
-fhir-max-resources | int | — | for a public server: refuse new FHIR resources once this many are held (0: no limit) | Settings › FHIR › Access: Most resources held |
-fhir-member-match-without-consent | on/off | — | let $member-match answer without an active Consent; the Payer-to-Payer API is opt-in, so only for testing | Settings › Payers › CMS-0057-F: Answer $member-match without the member's consent |
-fhir-open | on/off | — | serve the FHIR endpoint with no authentication at all, exposing every stored record | Settings › FHIR › Access: Let anyone read the FHIR endpoint without signing in |
-fhir-patient-directory-search | on/off | — | let a token limited to one patient search the directory (practitioners, organisations, locations) within its scopes | Settings › FHIR › Access: Let a patient's app search the directory |
-fhir-payer-apis | on/off | — | enable the CMS-0057 payer operations: $member-match (Payer-to-Payer) and Group $davinci-data-export (Provider Access); the Group exports also need -fhir-bulk-export | Settings › Payers › CMS-0057-F: The CMS-0057-F payer APIs |
-fhir-read-only | on/off | — | refuse writes to the FHIR endpoint | Settings › FHIR › Access: Refuse writes to the FHIR endpoint |
-fhir-subscriptions | on/off | — | enable topic-based subscriptions, which send encounter and appointment notifications to URLs FHIR clients choose | Settings › FHIR › Notifications: FHIR subscriptions (encounter and appointment notifications) |
-fhir-subscriptions-allow-http | on/off | — | let subscriptions deliver to plain-http endpoints; for a test receiver, never for patient data on a network | Settings › FHIR › Notifications: Allow subscriptions to notify plain-HTTP addresses |
-fhir-version | string | 4.0.1 | FHIR release to serve: R4, R4B or R5 | Settings › FHIR › The FHIR server: FHIR version clients see |
-fhir-writes-per-minute | int | — | for a public server: writes one client address may make to the FHIR endpoint a minute (0: no limit) | Settings › FHIR › Access: Writes a minute from one client |
-fleet-label | string | — | how this instance names itself in a fleet view (default: hostname) | Settings › Fleet › This server: Name for this server |
-formulary | string | — | publish this drug formulary over the Da Vinci US Drug Formulary API at /formulary/fhir and answer NCPDP Real-Time Prescription Benefit and SCRIPT electronic prior authorization from it | Settings › Payers › Drug formulary: Drug formulary file |
-icd11-client-id | string | — | a WHO ICD API client: ICD-11 codes not imported are looked up there | Settings › Data › Code systems: WHO ICD API client ID |
-icd11-client-secret | string | — | the WHO ICD API client's secret | Settings › Data › Code systems: WHO ICD API client secret |
-icd11-release | string | 2025-01 | the ICD-11 MMS release the WHO ICD API is asked about | Settings › Data › Code systems: ICD-11 release to ask for |
-icd11-url | string | — | the ICD API's address when it is not the WHO's: the WHO's ICD-API container on your network needs no client | Settings › Data › Code systems: ICD API address |
-index-identity | on/off | true | index patient identifiers from message contents so a message can be found by MRN, name or accession in any format; has no effect when -store-payloads is off | Settings › Data › What is kept: Index patient identifiers |
-insecure | on/off | — | serve over plain HTTP on a non-loopback address (not recommended) | — |
-inventory | string | — | write a Markdown inventory of every interface to this file, and keep it current | Settings › Monitoring › Inventory: Write an interface inventory to |
-inventory-every | duration | 24h0m0s | how often to rewrite the interface inventory | Settings › Monitoring › Inventory: Rewrite the inventory every |
-json-logs | on/off | — | emit structured JSON logs | Settings › Monitoring › Logging: Write logs as JSON |
-ldap | string | — | YAML file configuring directory (LDAP) sign-in (default: ldap.yaml beside the database, once saved in the console) | — |
-log-file | string | — | append the log, and the first administrator's one-time password, to this file (mode 0600) instead of the console. A Windows service has no console, so there it defaults to perfuse.log beside the database | — |
-mcp | on/off | — | serve the Model Context Protocol at /mcp, so AI agents with an API token can read status, messages, the queue, alerts and the FHIR store with that token's own access | Settings › Security › AI agents (MCP): Let AI agents connect over MCP |
-measure-reporter | string | Perfuse | the reporting organisation's name on MeasureReports from $evaluate-measure when the request names no reporter | — |
-metrics-open | on/off | — | serve /metrics to anybody who can reach the port. Only safe where that port is genuinely private: metric labels name your channels, and on a multi-tenant server they name every tenant's | Settings › Security › Metrics: Serve /metrics without a token |
-metrics-token | string | — | credential the Prometheus scrape endpoint requires. Give the scraper the same value in bearer_token_file. Without this, only a signed-in operator can read /metrics | Settings › Security › Metrics: Token a metrics scraper presents |
-mpi | on/off | — | keep a patient index (master patient index) in mpi.db beside the database: patient records from every system linked into one enterprise identifier per person, fed by mpi destinations and the PIX v3 identity feed, answering Patient/$match, PIXm, PIX v3 (/pixv3) and PDQ v3 (/pdqv3) | Settings › Data › Patient index: Keep a patient index |
-multi-tenant | on/off | — | keep each tenant's channels in their own subdirectory of -channels, so one server can run integration for several organisations without them being able to see each other | — |
-node-address | string | — | this server's console URL as the other servers and a load balancer reach it | — |
-node-name | string | — | this server's name in the cluster (default: an id kept in -data) | — |
-oidc | string | — | YAML file configuring OpenID Connect sign-in (default: oidc.yaml beside the database, once saved in the console) | — |
-pas | on/off | — | serve Da Vinci PAS 2.2.1 and 2.1.0 (Claim/$submit, $inquire, $decide) on the FHIR endpoint; decisions come from -crd-rules, and what no rule decides is pended for a reviewer. With -fhir-subscriptions, the PAS topic delivers each pended request's result | Settings › Payers › Prior authorization: Da Vinci PAS prior authorization server |
-pas-278-ca | string | — | a PEM file of certificate authorities to trust for the UM system beside the system's | Settings › Payers › Utilization management link: Certificate authorities to trust for the UM system |
-pas-278-cert | string | — | a PEM client certificate for X.509 mutual TLS with the UM system (CORE's authentication) | Settings › Payers › Utilization management link: Client certificate file |
-pas-278-core-receiver | string | — | the CORE envelope's ReceiverID, as the UM system's connectivity guide gives it (default: -pas-278-receiver) | Settings › Payers › Utilization management link: CORE envelope ReceiverID |
-pas-278-core-rule-version | string | — | what to write in the CORE envelope's CORERuleVersion when the UM system's guide asks for something other than the version itself (CMS esMD's sample says v2.2.0) | Settings › Payers › Utilization management link: CORERuleVersion written in the envelope |
-pas-278-core-sender | string | — | the CORE envelope's SenderID, as the UM system's connectivity guide gives it (default: -pas-278-sender) | Settings › Payers › Utilization management link: CORE envelope SenderID |
-pas-278-core-version | string | 2.2.0 | the CAQH CORE Connectivity Rule the UM system runs, for core-soap and core-mime: 2.2.0 (payload in the envelope) or C4.0.0 (payload as an MTOM attachment; SOAP only) | Settings › Payers › Utilization management link: CAQH CORE Connectivity Rule |
-pas-278-key | string | — | the private key (PEM) for -pas-278-cert | Settings › Payers › Utilization management link: Client certificate key file |
-pas-278-oauth-client-id | string | — | the OAuth client ID for -pas-278-oauth-token-url | Settings › Payers › Utilization management link: OAuth client ID |
-pas-278-oauth-scope | string | — | the scope asked for with the OAuth token, when the UM system wants one | Settings › Payers › Utilization management link: OAuth scope |
-pas-278-oauth-secret-env | string | — | name of an environment variable holding the OAuth client secret (the secret itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the OAuth client secret |
-pas-278-oauth-token-url | string | — | an OAuth 2.0 token endpoint: a token got with the client-credentials grant is sent as a bearer token (CORE vC4.0.0's authorization) | Settings › Payers › Utilization management link: OAuth token endpoint |
-pas-278-password-env | string | — | name of an environment variable holding the password for -pas-278-user (the password itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the password |
-pas-278-payer-id | string | — | the UMO's payer ID (NM1*X3) when the request's insurer carries no identifier | Settings › Payers › Utilization management link: Payer ID for the 278s |
-pas-278-production | on/off | — | mark the 278s sent as production (ISA15 P) rather than test | Settings › Payers › Utilization management link: Mark the 278s as production |
-pas-278-receiver | string | — | ISA08/GS03 receiver ID on the 278s sent to the UM system | Settings › Payers › Utilization management link: Receiver ID on the 278s |
-pas-278-sender | string | PERFUSE | ISA06/GS02 sender ID on the 278s sent to the UM system | Settings › Payers › Utilization management link: Sender ID on the 278s |
-pas-278-sftp | string | — | host:port of the UM system's SFTP server, for -pas-278-transport sftp | Settings › Payers › Utilization management link: SFTP server |
-pas-278-sftp-every | duration | 1m0s | how often the SFTP inbound folder is read | Settings › Payers › Utilization management link: Read the SFTP inbound folder every |
-pas-278-sftp-inbound | string | — | the SFTP folder the UM system's 278 responses, 999s and TA1s are collected from | Settings › Payers › Utilization management link: SFTP inbound folder |
-pas-278-sftp-key | string | — | an OpenSSH private key file for the SFTP user, instead of a password | Settings › Payers › Utilization management link: SFTP key file |
-pas-278-sftp-known-hosts | string | — | an OpenSSH known_hosts file holding the SFTP server's key; required, so requests never go to whoever answers | Settings › Payers › Utilization management link: SFTP known_hosts file |
-pas-278-sftp-outbound | string | — | the SFTP folder the 278 requests (and the 999s for the answers) are put in | Settings › Payers › Utilization management link: SFTP outbound folder |
-pas-278-sftp-password-env | string | — | name of an environment variable holding the SFTP password (the password itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the SFTP password |
-pas-278-sftp-user | string | — | the SFTP user name | Settings › Payers › Utilization management link: SFTP user |
-pas-278-token-env | string | — | name of an environment variable holding a bearer token for the UM system (the token itself is never a flag) | Settings › Payers › Utilization management link: Environment variable holding the token |
-pas-278-transport | string | x12 | how the 278s reach the UM system: x12 (POSTed as application/edi-x12), core-soap (a CAQH CORE SOAP envelope), core-mime (CAQH CORE HTTP MIME multipart), or sftp (batch files over -pas-278-sftp, answers collected from its inbound folder) | Settings › Payers › Utilization management link: How the 278s travel |
-pas-278-url | string | — | forward every PAS request to the payer's utilization management system as an X12 278 request sent to this URL (by -pas-278-transport), and answer with its 278 response; later 278 responses go to Claim/$decide-278 | Settings › Payers › Utilization management link: Send PAS requests on to the UM system at |
-pas-278-user | string | — | user name for the UM system: CORE's UserName (WS-Security UsernameToken in SOAP), or HTTP Basic for x12 | Settings › Payers › Utilization management link: User name |
-pas-decider-ca | string | — | a PEM file of certificate authorities to trust for -pas-decider-url beside the system's, such as the payer's own authority or the decision service's (Vaglio's is its DATA/tls/ca.crt) | Settings › Payers › Decision service: Certificate authorities to trust for the decision service |
-pas-decider-token-env | string | — | name of an environment variable holding a bearer token for -pas-decider-url (the token itself is never a flag) | Settings › Payers › Decision service: Environment variable holding the decision service's token |
-pas-decider-url | string | — | ask the decision service at this URL (such as Vaglio) to decide each PAS item on the request's clinical evidence, when -crd-rules leave it to a reviewer; the PAS request Bundle is POSTed to it. Cannot be combined with -pas-278-url | Settings › Payers › Decision service: Decision service URL |
-passkey-allowed-models | string | — | comma-separated authenticator AAGUIDs that may enrol; requires -passkey-attestation-roots | — |
-passkey-attestation-roots | string | — | a PEM file of authenticator vendor certificates; passkey attestation is verified against these | — |
-passkey-domain | string | — | the bare domain passkeys are registered for, such as perfuse.example.org. No scheme, no port, no path. Setting it turns passkeys on; leaving it empty leaves them off | Settings › Sign-in › Passkeys: Domain passkeys are bound to |
-passkey-name | string | Perfuse | the name an authenticator shows a person when they register a passkey | Settings › Sign-in › Passkeys: Name shown on the device |
-passkey-origins | string | — | comma-separated origins the console is reached at, with scheme and port: https://perfuse.example.org. Defaults to https:// plus the domain | Settings › Sign-in › Passkeys: Other origins passkeys are accepted from |
-peers | string | — | YAML file listing other Perfuse instances to show in a fleet view | Settings › Fleet › Fleet: Other Perfuse servers to show (file) |
-public-url | string | — | the https address patients' phones and other organisations reach this server at, for the SMART Health Links it hosts (default: the listen address) | Settings › FHIR › The FHIR server: Address others reach this server at |
-rctc | string | — | eCR trigger codes for the case report preview: a FHIR ValueSet or Bundle of them, such as the eRSD | Settings › Public health › Case reporting: Trigger codes file (RCTC or eRSD) |
-residency | string | — | cloud regions this server's data may go to or come from: areas (eea, uk, ch) and region codes (eu-central-1), comma-separated; channels with connectors elsewhere are refused | Settings › Data › Data protection: Where data may go (cloud regions) |
-retention-days | int | 30 | how long to keep recorded messages; 0 keeps them for ever, which will eventually fill the disk | Settings › Data › How long it is kept: Delete records after |
-saml | string | — | YAML file configuring SAML 2.0 sign-in (default: saml.yaml beside the database, once saved in the console) | — |
-scim | on/off | — | accept SCIM 2.0 provisioning from an identity provider at /scim/v2. Okta, Entra ID and Google Workspace use it to create accounts and, more importantly, to disable them when somebody leaves | Settings › Sign-in › Automatic accounts: Let the identity provider manage accounts |
-scim-default-role | string | viewer | role for an account the identity provider does not describe. Defaults downward on purpose: an account whose role could not be determined should be able to read and nothing else | — |
-settings | string | — | settings file the web interface may edit (default: perfuse-settings.yaml beside the database) | — |
-shl-allow-http | on/off | — | let a received SMART Health Link point at plain HTTP; for testing only | Settings › Public health › Health links: Allow SMART Health Links over plain HTTP |
-signing-cert | string | — | certificate for signing documents (defaults to -tls-cert) | Settings › Security › Document signing: Certificate for signing documents |
-signing-key | string | — | key for signing documents (defaults to -tls-key) | Settings › Security › Document signing: Key for signing documents |
-smart-audience | string | — | the audience a SMART token must be issued for, normally the FHIR base URL | Settings › SMART › Authorization: Audience tokens must name |
-smart-authorize | string | — | the authorization endpoint to advertise to SMART apps | Settings › SMART › Authorization: Authorization endpoint |
-smart-backend-services | on/off | — | advertise that the SMART authorization server issues backend-services (client_credentials, signed JWT) tokens | Settings › SMART › Built-in server: Backend Services (system-to-system tokens) |
-smart-clients | string | — | run Perfuse's own SMART authorization server at /auth for the apps registered in this YAML file | Settings › SMART › Built-in server: Registered apps file (turns on the built-in server) |
-smart-issuer | string | — | accept SMART on FHIR access tokens from this authorization server | Settings › SMART › Authorization: Accept SMART access tokens from this authorization server |
-smart-jwks | string | — | where to fetch the SMART issuer's signing keys, when not from its published metadata (split DNS, a private address) | Settings › SMART › Authorization: Key set file |
-smart-jwks-uri | string | — | the authorization server's public key set URL, advertised to SMART apps (needed to claim OpenID Connect sign-in) | Settings › SMART › Authorization: Key set address |
-smart-key | string | smart-signing.key | the built-in authorization server's RSA signing key (PEM, mode 0600), created if missing | Settings › SMART › Built-in server: Signing key file |
-smart-oidc | string | — | with -smart-users, let people sign in at this OpenID Connect provider (YAML: issuer, client_id, client_secret_file or client_secret_env, label); each is linked by oidc_subject | Settings › SMART › Built-in server: Sign people in through the OpenID Connect provider |
-smart-token | string | — | the token endpoint to advertise to SMART apps | Settings › SMART › Authorization: Token endpoint |
-smart-users | string | — | with -smart-clients, the people who may sign in to authorize apps (YAML: username, password_hash, fhir_user) | Settings › SMART › Built-in server: People who sign in to authorize apps (file) |
-snmp-allow | string | — | comma-separated networks or addresses the SNMP agent answers, such as 10.0.5.0/24; required with -snmp-listen | Settings › Monitoring › SNMP: Networks that may ask |
-snmp-base-oid | string | 1.3.6.1.4.1.8072.9999.9999.16, Net-SNMP's experimental space | where Perfuse's values sit, under your enterprise number | Settings › Monitoring › SNMP: Base OID |
-snmp-community | string | — | the SNMPv2c community (a password sent in clear: at least 6 characters, not public or private) | Settings › Monitoring › SNMP: SNMP community |
-snmp-contact | string | — | sysContact the SNMP agent reports | Settings › Monitoring › SNMP: Contact (sysContact) |
-snmp-listen | string | — | answer SNMPv2c GET/GETNEXT/GETBULK on this UDP address, such as :161 (off when empty). Read-only: channel states, counts and queue depths | Settings › Monitoring › SNMP: Answer SNMP on this address |
-snmp-location | string | — | sysLocation the SNMP agent reports | Settings › Monitoring › SNMP: Location (sysLocation) |
-snmp-traps | string | — | comma-separated managers (host or host:port, default port 162) that receive an SNMPv2 trap when an alert fires or resolves | Settings › Monitoring › SNMP: Send traps to |
-store-messages | on/off | true | record every message handled, which is what makes the message browser work | Settings › Data › What is kept: Keep a record of each message |
-store-payloads | on/off | true | store message contents as well as their outcomes; turn this off where PHI must not be held at rest | Settings › Data › What is kept: Keep message contents |
-tls-cert | string | — | TLS certificate file | Settings › Security › Encryption: TLS certificate file |
-tls-key | string | — | TLS private key file | Settings › Security › Encryption: TLS private key file |
-trace-endpoint | string | — | OTLP/HTTP base URL to export message traces to, for example http://localhost:4318 | Settings › Monitoring › Tracing: Send traces to |
-trace-instance | string | — | name for this instance in traces; defaults to the hostname, which is what distinguishes replicas | Settings › Monitoring › Tracing: This instance's name in traces |
-trace-sample | float | 1 | fraction of traces to record, 0 to 1 | — |
-tsa-url | string | — | RFC 3161 time-stamping authority for DSDR signatures on claims attachments | Settings › Security › Document signing: Time-stamping authority |
-vpn | string | — | partner VPN tunnels to report on the Connections dashboard (YAML: AWS Site-to-Site VPN, Azure VPN Gateway or strongSwan, and both sides' settings); see examples/vpn.yaml | Settings › Monitoring › Connections: VPN tunnels to watch (file) |
-watch-access | on/off | true | watch traffic and reads of patient data for what a breach looks like (bursts, night traffic, new destinations, bulk reads) and raise alerts | — |
-xds | string | — | keep clinical documents here as an IHE XDS.b registry and repository with this repository uniqueId (an OID), answering ITI-41, ITI-42, ITI-18 and ITI-43 at /xds/repository and /xds/registry | Settings › Data › Document sharing (IHE XDS): Keep documents here as an XDS registry and repository |
-xds-home-community | string | — | this community's home community id (urn:oid:...), so /xca/gateway answers XCA ITI-38 and ITI-39 for it | Settings › Data › Document sharing (IHE XDS): Home community id, for XCA |
21 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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
name | Text | ja | — |
description | Text | nein | — |
group | Text | nein | — |
attachments | Anlagen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
delimited | Begrenzt (ein Block, weglassen, um nicht zu verwenden) | nein | — |
tables | Liste von Text | nein | — |
contract | ContractRef (ein Block, weglassen, um nicht zu verwenden) | nein | — |
enabled | wahr oder falsch (ein Block, weglassen, um nicht zu verwenden) | nein | — |
dataType | DataType | nein | hl7 |
hl7v3 | HL7v3-Optionen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
x12 | X12-Optionen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
ncpdp | NCPDP-Optionen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
edifact | EDIFACT-Optionen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
script | Skriptoptionen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
dicom | DICOM-Optionen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
source | Quelle | ja | — |
filter | Text | nein | — |
transformations | Liste von transform.Step | nein | — |
scripts | Skripte (ein Block, weglassen, um nicht zu verwenden) | nein | — |
shadow | Schatten (ein Block, weglassen, um nicht zu verwenden) | nein | — |
destinations | Liste von Destination | ja | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
prefetch | ganze Zahl | nein | 10 |
reconnect | Dauer, z. B. 30s oder 5m | nein | 5s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | ja | — |
path | Text | nein | — |
tls | tlsconf.Settings (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
id | Text | ja | — |
cert_file | Text | ja | — |
key_file | Text | ja | — |
partners | Liste von AS2-Partnern | ja | — |
max_message_size | ganze Zahl | nein | — |
duplicate_window | Dauer, z. B. 30s oder 5m | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
prefix | Text | ja | — |
suffix | Text | nein | — |
after_read | Text | nein | — |
move_to | Text | nein | processed/ |
error_prefix | Text | nein | error/ |
poll_interval | Dauer, z. B. 30s oder 5m | nein | 30s |
max_object_size | Ganze Zahl | nein | 16 MiB |
framed | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
addr | Text | ja | — |
destination | Text | ja | — |
login | Text | nein | — |
passcode | Text | nein | — |
host | Text | nein | der Host der Adresse |
selector | Text | nein | — |
subscription_id | Text | nein | der Kanalname |
heartbeat | Dauer, z. B. 30s oder 5m | nein | dreißig Sekunden |
reconnect | Dauer, z. B. 30s oder 5m | nein | fünf Sekunden |
timeout | Dauer, z. B. 30s oder 5m | nein | dreißig Sekunden |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
address | Text | ja | — |
called_ae | Text | ja | — |
calling_ae | Text | nein | — |
level | Text | nein | STUDIUM |
patient_root | wahr oder falsch | nein | — |
match | Zuordnung von Text zu Text | nein | — |
return | Liste von Text | nein | — |
interval | Dauer, z. B. 30s oder 5m | ja | — |
window | Dauer, z. B. 30s oder 5m | nein | — |
overlap | Dauer, z. B. 30s oder 5m | nein | eine Stunde |
limit | Ganzzahl | nein | 500 |
timeout | Dauer, z. B. 30s oder 5m | nein | zwei Minuten |
tls | tlsconf.Einstellungen (ein Block, weglassen, um nichts zu ändern) | nein | — |
emit_on_first_poll | wahr oder falsch | nein | falsch |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | ja | — |
ae_title | Text | nein | — |
allowed_calling_ae | Liste von Text | nein | — |
sop_classes | Liste von Text | nein | — |
transfer_syntaxes | Liste von Text | nein | — |
max_object_bytes | Ganzzahl | nein | — |
idle_timeout | Dauer, z. B. 30s oder 5m | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | ja | — |
path | Text | nein | /dicom-web |
token | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
max_object_bytes | Ganzzahl | nein | — |
tls | tlsconf-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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
driver | Text | ja | — |
dsn | Text | ja | — |
query | Text | ja | — |
after_query | Text | nein | — |
key_column | Text | nein | — |
template | Text | nein | — |
column | Text | nein | — |
poll_interval | Dauer, z. B. 30s oder 5m | nein | — |
batch_size | Ganzzahl | nein | 100 |
max_attempts | Ganzzahl | nein | 3 |
query_timeout | Dauer, z. B. 30s oder 5m | nein | 30s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | nein | — |
tls_cert | Text | nein | — |
tls_key | Text | nein | — |
max_bytes | Ganzzahl | nein | — |
smtp_host | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
imap | DirectIMAP (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
xdr | DirectXDR (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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
protocol | Text | nein | — |
host | Text | ja | — |
port | Ganzzahl | nein | — |
security | Text | nein | — |
tls | tlsconf-Einstellungen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
username | Text | ja | — |
password | Text | nein | — |
oauth | EmailOAuth (ein Block, weglassen, um nicht zu verwenden) | nein | — |
mailbox | Text | nein | — |
take | Text | nein | — |
attachment_names | Liste von Text | nein | — |
allowed_senders | Liste von Text | nein | — |
after_read | Text | nein | — |
move_to | Text | nein | — |
error_folder | Text | nein | — |
poll_interval | Dauer, z. B. 30s oder 5m | nein | — |
max_message_size | Ganzzahl | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
host | Text | ja | — |
user | Text | nein | — |
password | Text | nein | — |
security | ftpconn.Security | nein | explizit |
insecure_skip_verify | wahr oder falsch | nein | — |
root | Text | nein | — |
timeout | Dauer, wie 30s oder 5m | nein | dreiß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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
root | Text | ja | — |
follow_symlinks | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
prefix | Text | ja | — |
suffix | Text | nein | — |
after_read | Text | nein | — |
move_to | Text | nein | processed/ |
error_prefix | Text | nein | error/ |
poll_interval | Dauer, z. B. 30s oder 5m | nein | 30s |
max_object_size | Ganze Zahl | nein | 16 MiB |
framed | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | ja | — |
path | Text | nein | "/" |
tls | tlsconf.Settings (ein Block, weglassen, um nichts zu setzen) | nein | — |
token | Text | nein | — |
max_message_size | Ganzzahl | nein | — |
read_timeout | Dauer, z. B. 30s oder 5m | nein | — |
ack | Ack | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
poll_interval | Dauer, z. B. 30s oder 5m | nein | 2s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
script | Text | ja | — |
poll_interval | Dauer, z. B. 30s oder 5m | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
brokers | Liste von Text | ja | — |
topics | Liste von Text | ja | — |
group | Text | ja | — |
from_beginning | wahr oder falsch | nein | — |
commit_after_delivery | wahr oder falsch (ein Block, weglassen, um es auszulassen) | nein | — |
max_message_size | ganze Zahl | nein | der Kanallimit |
session_timeout | Dauer, z. B. 30s oder 5m | nein | fünfundvierzig Sekunden |
timeout | Dauer, z. B. 30s oder 5m | nein | dreißig Sekunden |
sasl | KafkaSASL (ein Block, weglassen, um es auszulassen) | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
topic | Text | ja | — |
reconnect | Dauer, z. B. 30s oder 5m | nein | 5s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
subscription | Text | ja | — |
max_messages | Ganzzahl | nein | 10 |
reconnect | Dauer, z. B. 30s oder 5m | nein | 5s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
bucket | Text | ja | — |
path_style | wahr oder falsch | nein | — |
prefix | Text | nein | — |
suffix | Text | nein | — |
after_read | Text | nein | — |
move_to | Text | nein | verarbeitet/ |
error_prefix | Text | nein | fehler/ |
poll_interval | Dauer, z. B. 30s oder 5m | nein | 30s |
max_object_size | Ganzzahl | nein | 16 MiB |
framed | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
host | Text | ja | 22 |
user | Text | ja | — |
password | Text | nein | — |
key_file | Text | nein | — |
key_passphrase | Text | nein | — |
known_hosts_file | Text | nein | — |
insecure_skip_host_key_check | wahr oder falsch | nein | — |
dir | Text | ja | — |
pattern | Text | nein | alles |
poll_interval | Dauer, wie 30s oder 5m | nein | — |
after_read | Text | nein | — |
move_to | Text | nein | — |
error_dir | Text | nein | — |
stable_for | Dauer, wie 30s oder 5m | nein | 5s |
framed | wahr oder falsch | nein | — |
max_file_size | ganze Zahl | nein | 64MB |
timeout | Dauer, wie 30s oder 5m | nein | 60s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
host | Text | ja | — |
share | Text | ja | — |
user | Text | nein | — |
password | Text | nein | — |
domain | Text | nein | — |
root | Text | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | dreiß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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | ja | — |
profile | Text | nein | — |
path | Text | nein | "/" |
version | Text | nein | 1 |
element | Text | nein | — |
base64 | wahr oder falsch | nein | — |
response_element | Text | nein | "AckResponse" |
response_namespace | Text | nein | — |
wsdl | Text | nein | — |
tls | tlsconf-Einstellungen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
token | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
max_message_size | Ganzzahl | nein | — |
read_timeout | Dauer, z. B. 30s oder 5m | nein | — |
ack | Ack | nein | — |
fault_on_nak | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
queue_url | Text | ja | — |
wait_seconds | Ganzzahl | nein | 20: eine leere Warteschlange kostet eine Anfrage alle zwanzig Sekunden |
max_messages | Ganzzahl | nein | 10 |
visibility_timeout | Dauer, wie z. B. 30s oder 5m | nein | die 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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
port | Text | ja | — |
baud | Ganzzahl | ja | — |
data_bits | Ganzzahl | nein | 8 |
parity | Text | nein | none |
stop_bits | Text | nein | 1 |
flow_control | Text | nein | none |
max_message_size | Ganzzahl | nein | — |
quiet_after | Dauer, z. B. 30s oder 5m | nein | — |
reply | Text | nein | — |
reply_text | Text | nein | — |
reopen_after | Dauer, z. B. 30s oder 5m | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
type | SourceType | ja | — |
listen | Text | ja | — |
max_message_size | Ganzzahl | nein | — |
idle_timeout | Dauer, z. B. 30s oder 5m | nein | — |
max_connections | Ganzzahl | nein | — |
tls | tlsconf.Settings (ein Block, weglassen, um nichts zu übertragen) | nein | — |
http | HTTPSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
soap | SOAPSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
dicomweb | DICOMwebSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
direct | DirectSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
dicom | DICOMSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
file | FileSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
tcp | TCPSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
ftp | FTPSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
smb | SMBSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
webdav | WebDAVSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
serial | SerialSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
dicom_query | DICOMQuerySource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
broker | BrokerSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
kafka | KafkaSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
sqs | SQSSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
s3 | S3Source (ein Block, weglassen, um nichts zu übertragen) | nein | — |
amqp | AMQPSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
azure_blob | AzureBlobSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
email | EmailSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
as2 | AS2Source (ein Block, weglassen, um nichts zu übertragen) | nein | — |
pgp | PGPReceive (ein Block, weglassen, um nichts zu übertragen) | nein | — |
mqtt | MQTTSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
ibm_mq | IBMMQSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
pubsub | PubSubSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
gcs | GCSSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
database | DatabaseSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
sftp | SFTPSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
javascript | JavaScriptSource (ein Block, weglassen, um nichts zu übertragen) | nein | — |
ack | Ack | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | ja | — |
max_message_size | Ganzzahl | nein | — |
idle_timeout | Dauer, z. B. 30s oder 5m | nein | — |
max_connections | Ganzzahl | nein | — |
reply | Text | nein | — |
reply_text | Text | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
user | Text | nein | — |
password | Text | nein | — |
insecure_skip_verify | wahr oder falsch | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | sechzig 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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
content_type | Text | nein | der 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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
from | Text | ja | — |
to | Text | ja | — |
cert_file | Text | nein | — |
key_file | Text | nein | — |
partner_cert_file | Text | nein | — |
unsigned | wahr oder falsch | nein | — |
unencrypted | wahr oder falsch | nein | — |
compress | wahr oder falsch | nein | — |
receipt | Text | nein | — |
unsigned_receipt | wahr oder falsch | nein | — |
receipt_url | Text | nein | — |
content_type | Text | nein | — |
file_name | Text | nein | — |
subject | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
blob | Text | nein | ${date}/${channel}/${control_id} |
tier | Text | nein | — |
content_type | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
addr | Text | ja | — |
destination | Text | ja | — |
login | Text | nein | — |
passcode | Text | nein | — |
host | Text | nein | der Host der Adresse |
content_type | Text | nein | text/plain für HL7 |
headers | Zuordnung von Text zu Text | nein | — |
persistent | wahr oder falsch (ein Block, weglassen, um es wegzulassen) | nein | wahr |
timeout | Dauer, wie z. B. 30s oder 5m | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | nein | — |
dir | Text | nein | — |
write | Text | nein | — |
version | Text | nein | R5 |
identifier_systems | Zuordnung von Text zu Text | nein | — |
require_agreement | wahr oder falsch | nein | — |
on_no_document | Text | nein | — |
headers | Zuordnung von Text zu Text | nein | — |
bearer_token | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
name | Text | ja | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
address | Text | ja | — |
called_ae | Text | nein | — |
calling_ae | Text | nein | — |
transfer_syntaxes | Liste von Text | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
token | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
headers | Zuordnung von Text zu Text | nein | — |
tls | tlsconf-Einstellungen (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | — |
23.9 Datenbankziel
DatabaseDestination schreibt jede Nachricht in eine Datenbank.
Definiert als DatabaseDestination in internal/config.
| Schlüssel | Typ | Erforderlich | Standard |
|---|---|---|---|
driver | Text | ja | — |
dsn | Text | ja | — |
statement | Text | ja | — |
params | Liste von Text | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | 30s |
max_open_conns | Ganzzahl | nein | 4 |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
name | Text | ja | — |
type | DestinationType | ja | — |
enabled | true oder false (ein Block, weglassen, um es auszulassen) | nein | — |
filter | Text | nein | — |
address | Text | nein | — |
dir | Text | nein | — |
file_name | Text | nein | — |
temp_suffix | Text | nein | " |
append | true oder false | nein | — |
retain_hours | ganze Zahl | nein | — |
tls | tlsconf.Settings (ein Block, weglassen, um es auszulassen) | nein | — |
fhir | FHIRDestination (ein Block, weglassen, um es auszulassen) | nein | — |
cda | CDADestination (ein Block, weglassen, um es auszulassen) | nein | — |
http | HTTPDestination (ein Block, weglassen, um es auszulassen) | nein | — |
database | DatabaseDestination (ein Block, weglassen, um es auszulassen) | nein | — |
sftp | SFTPDestination (ein Block, weglassen, um es auszulassen) | nein | — |
tcp | TCPDest (ein Block, weglassen, um es auszulassen) | nein | — |
smtp | SMTPDestination (ein Block, weglassen, um es auszulassen) | nein | — |
channel | ChannelDestination (ein Block, weglassen, um es auszulassen) | nein | — |
s3 | S3Destination (ein Block, weglassen, um es auszulassen) | nein | — |
ftp | FTPDestination (ein Block, weglassen, um es auszulassen) | nein | — |
document | DocumentDestination (ein Block, weglassen, um es auszulassen) | nein | — |
soap | SOAPDestination (ein Block, weglassen, um es auszulassen) | nein | — |
dicomweb | DICOMwebDestination (ein Block, weglassen, um es auszulassen) | nein | — |
xds | XDSDestination (ein Block, weglassen, um es auszulassen) | nein | — |
direct | DirectDestination (ein Block, weglassen, um es auszulassen) | nein | — |
as2 | AS2Destination (ein Block, weglassen, um es auszulassen) | nein | — |
mpi | MPIDestination (ein Block, weglassen, um es auszulassen) | nein | — |
tefca | TEFCADestination (ein Block, weglassen, um es auszulassen) | nein | — |
pas | PASDestination (ein Block, weglassen, um es auszulassen) | nein | — |
x12_as | Text | nein | — |
dicom | DICOMDestination (ein Block, weglassen, um es auszulassen) | nein | — |
javascript | JavaScriptDestination (ein Block, weglassen, um es auszulassen) | nein | — |
broker | BrokerDestination (ein Block, weglassen, um es auszulassen) | nein | — |
kafka | KafkaDestination (ein Block, weglassen, um es auszulassen) | nein | — |
sqs | SQSDestination (ein Block, weglassen, um es auszulassen) | nein | — |
sns | SNSDestination (ein Block, weglassen, um es auszulassen) | nein | — |
amqp | AMQPDestination (ein Block, weglassen, um es auszulassen) | nein | — |
azure_blob | AzureBlobDestination (ein Block, weglassen, um es auszulassen) | nein | — |
mqtt | MQTTDestination (ein Block, weglassen, um es auszulassen) | nein | — |
ibm_mq | IBMMQDestination (ein Block, weglassen, um es auszulassen) | nein | — |
pubsub | PubSubDestination (ein Block, weglassen, um es auszulassen) | nein | — |
gcs | GCSDestination (ein Block, weglassen, um es auszulassen) | nein | — |
elr | ELRDestination (ein Block, weglassen, um es auszulassen) | nein | — |
pgp | PGPSend (ein Block, weglassen, um es auszulassen) | nein | — |
response_transformer | Text | nein | — |
timeout | Dauer, wie z. B. 30s oder 5m | nein | — |
retry | Retry | nein | — |
queue | QueueConfig (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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
to | Liste von Text | ja | — |
subject | Text | nein | — |
text | Text | nein | — |
attach_name | Text | nein | — |
xdm | wahr oder falsch | nein | — |
xdm_source_id | Text | nein | — |
recipient_certs_dir | Text | nein | — |
dns | Text | nein | — |
ldap | Text | nein | — |
smtp_host | Text | ja | — |
username | Text | nein | — |
password | Text | nein | — |
request_mdn | wahr oder falsch | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
dir | Text | ja | — |
format | DocumentFormat | nein | |
template | Text | ja | — |
title | Text | nein | — |
file_name | Text | nein | — |
font_size | Zahl | nein | 10 |
landscape | wahr oder falsch | nein | — |
temp_suffix | Text | nein | " |
timeout | Dauer, z. B. 30s oder 5m | nein | 30s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
rctc | Text | nein | — |
source | Text | ja | — |
facility | ECR-Facility | ja | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
config | Text | ja | — |
rctc | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
version | Text | nein | R5 |
timezone | Text | nein | — |
default_identifier_system | Text | nein | — |
identifier_systems | Zuordnung von Text zu Text | nein | — |
claim_us_core | wahr oder falsch | nein | — |
validate_before_send | wahr oder falsch (ein Block, weglassen, um es nicht zu verwenden) | nein | true: Das Senden einer Ressource, die ein Server ablehnt, verschwendet ein Wiederholungsbudget und versteckt das eigentliche Problem hinter einem Transportfehler |
reject_on_warning | wahr oder falsch | nein | — |
headers | Zuordnung von Text zu Text | nein | — |
bearer_token | Text | nein | — |
auth | FHIRAuth (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
ecr | ECRDestination (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
bundle_script | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
host | Text | ja | 21 |
user | Text | nein | — |
password | Text | nein | — |
security | FTP-Sicherheit | nein | explizit anstelle von keiner |
insecure_skip_verify | wahr oder falsch | nein | — |
allow_clear_password | wahr oder falsch | nein | — |
dir | Text | ja | — |
file_name | Text | nein | — |
temp_suffix | Text | nein | " |
framed | wahr oder falsch | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | 60s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
object | Text | nein | ${date}/${channel}/${control_id} |
storage_class | Text | nein | — |
content_type | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
method | Text | nein | — |
content_type | Text | nein | — |
headers | Zuordnung von Text zu Text | nein | — |
bearer_token | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
tls | tlsconf.Settings (ein Block, weglassen, um es wegzulassen) | nein | — |
success_status | Liste von ganzen Zahlen | nein | jede 2xx |
fail_on_body | Liste von Text | nein | — |
follow_redirects | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
non_persistent | true oder false | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
script | Text | ja | — |
timeout | Dauer, z. B. 30s oder 5m | nein | — |
success_on_undefined | true oder false (ein Block, weglassen, um es nicht zu setzen) | nein | true |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
brokers | Liste von Text | ja | — |
topic | Text | ja | — |
key | Text | nein | — |
acks | Text | nein | all |
compression | Text | nein | snappy |
headers | Zuordnung von Text zu Text | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | dreißig Sekunden |
sasl | KafkaSASL (ein Block, weglassen, um es nicht zu setzen) | nein | — |
tls | tlsconf-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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
authorities | Zuordnung von Text zu Text | nein | — |
id_type | Text | nein | — |
ssn_system | Text | nein | — |
no_merge | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
topic | Text | ja | — |
retain | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
payer | Text | ja | — |
bearer_token | Text | nein | — |
auth | FHIRAuth (ein Block, weglassen, um es auszulassen) | nein | — |
results_to | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
topic | Text | ja | — |
order_by | Text | nein | — |
23.26 S3-Ziel
S3Destination schreibt jede Nachricht als Objekt.
Definiert als S3Destination in internal/config.
| Schlüssel | Typ | Erforderlich | Standard |
|---|---|---|---|
bucket | Text | ja | — |
region | Text | ja | — |
key | Text | nein | ein datumspartitionierter Pfad plus die Kontroll-ID |
access_key_id | Text | nein | — |
secret_access_key | Text | nein | — |
session_token | Text | nein | — |
endpoint | Text | nein | — |
path_style | wahr oder falsch | nein | — |
server_side_encryption | Text | nein | — |
content_type | Text | nein | application/hl7-v2 für HL7 und text/plain ansonsten |
framed | wahr oder falsch | nein | — |
timeout | Dauer, wie 30s oder 5m | nein | 60s |
storage_class | Text | nein | — |
format | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
host | Text | ja | 22 |
user | Text | ja | — |
password | Text | nein | — |
key_file | Text | nein | — |
key_passphrase | Text | nein | — |
known_hosts_file | Text | nein | — |
insecure_skip_host_key_check | wahr oder falsch | nein | — |
dir | Text | ja | — |
file_name | Text | nein | ein Zeitstempel plus die Kontroll-ID |
temp_suffix | Text | nein | " |
framed | wahr oder falsch | nein | — |
append | wahr oder falsch | nein | — |
timeout | Dauer, wie 30s oder 5m | nein | 60s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
host | Text | ja | — |
from | Text | ja | — |
to | Liste von Text | ja | — |
cc | Liste von Text | nein | — |
bcc | Liste von Text | nein | — |
subject | Text | nein | — |
body | Text | nein | — |
attach | wahr oder falsch | nein | — |
attach_name | Text | nein | die Kontroll-ID mit einer |
username | Text | nein | — |
password | Text | nein | — |
starttls | wahr oder falsch (ein Block, weglassen, um es wegzulassen) | nein | — |
insecure_skip_verify | wahr oder falsch | nein | — |
timeout | Dauer, wie 30s oder 5m | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
topic_arn | Text | ja | — |
subject | Text | nein | — |
group_by | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
profile | Text | nein | — |
facility_id | Text | nein | — |
warnings_are_errors | wahr oder falsch | nein | — |
action | Text | nein | — |
version | Text | nein | 1 |
body | Text | ja | — |
header | Text | nein | — |
headers | Zuordnung von Text zu Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
tls | tlsconf.Einstellungen (ein Block, weglassen, um nicht zu verwenden) | nein | — |
fault_is_success | Liste von Text | nein | — |
timeout | Dauer, wie z. B. 30s oder 5m | nein | 30s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
queue_url | Text | ja | — |
group_by | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
address | Text | ja | — |
max_message_size | ganze Zahl | nein | — |
timeout | Dauer, wie 30s oder 5m | nein | — |
expect_reply | wahr oder falsch | nein | — |
keep_alive | wahr oder falsch | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
purpose | Text | ja | — |
results_to | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
source_id | Text | ja | — |
patient_domain | Text | nein | — |
facility_type | XDSCode | ja | — |
practice_setting | XDSCode | ja | — |
class | XDSCode (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
content_type | XDSCode (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
token | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
headers | Zuordnung von Text zu Text | nein | — |
tls | tlsconf.Settings (ein Block, weglassen, um es nicht zu verwenden) | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | — |
direct_from | Text | nein | — |
direct_to | Liste von Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
extract | Liste von attach.Rule | ja | — |
reassemble | true oder false (ein Block, weglassen, um es wegzulassen) | nein | true |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
delimiter | Text | nein | — |
quote | Text | nein | ein doppeltes Anführungszeichen |
comment | Text | nein | — |
has_header | wahr oder falsch | nein | — |
columns | Liste von Text | nein | — |
trim_space | wahr oder falsch | nein | — |
relaxed | wahr oder falsch | nein | — |
split | wahr oder falsch (ein Block, weglassen, um es auszulassen) | nein | wahr |
keep_blank_lines | wahr oder falsch | nein | — |
filter | Text | nein | — |
transformations | Liste von Schritten.Step | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
filter | Text | nein | — |
acknowledge | wahr oder falsch (ein Block, weglassen, um es auszulassen) | nein | — |
sender_device | Text | nein | — |
sender_oid | Text | nein | — |
transformations | Liste von hl7v3.Schritten | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
framing | Text | ja | — |
delimiter | Text | nein | — |
start_block | Text | nein | — |
keep_delimiter | wahr oder falsch | nein | — |
record_length | ganze Zahl | nein | — |
trim_padding | wahr oder falsch (ein Block, weglassen, um es auszulassen) | nein | — |
length_bytes | ganze Zahl | nein | — |
big_endian | wahr oder falsch | nein | — |
length_includes_header | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
envelope | EnvelopePolicy | nein | erforderlich |
split | true oder false | nein | — |
acknowledge | Text | nein | — |
ack_sender_id | Text | nein | — |
ack_sender_qualifier | Text | nein | — |
arrives_as | Text | nein | — |
transformations | Liste von x12.Step | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
addr | Text | ja | — |
address | Text | ja | — |
username | Text | nein | — |
password | Text | nein | — |
hostname | Text | nein | der Host von addr |
tls | tlsconf.Settings (ein Block, weglassen, um nichts zu verwenden) | nein | — |
timeout | Dauer, wie 30s oder 5m | nein | 30s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
id | Text | ja | — |
cert_file | Text | ja | — |
allow_unsigned | wahr oder falsch | nein | — |
allow_unencrypted | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
region | Text | ja | — |
access_key_id | Text | nein | — |
secret_access_key | Text | nein | — |
session_token | Text | nein | — |
endpoint | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
when | AckWhen | nein | — |
application | Text | nein | — |
facility | Text | nein | — |
include_trigger_event | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
account | Text | ja | — |
container | Text | ja | — |
key | Text | nein | — |
sas | Text | nein | — |
endpoint | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
file | Text | ja | — |
check_every | Text | nein | 15 Minuten |
over | ganze Zahl | nein | 500 |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
transformations | Liste von dicom.Schritten | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
address | Text | ja | — |
cert_file | Text | ja | — |
key_file | Text | ja | — |
anchors_file | Text | ja | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
host | Text | ja | — |
port | Ganzzahl | nein | — |
security | Text | nein | — |
username | Text | ja | — |
password | Text | nein | — |
mailbox | Text | nein | — |
after_read | Text | nein | — |
move_to | Text | nein | — |
error_folder | Text | nein | — |
poll_interval | Dauer, wie z. B. 30s oder 5m | nein | — |
tls | tlsconf.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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
listen | Text | ja | — |
tls_cert | Text | nein | — |
tls_key | Text | nein | — |
client_ca_file | Text | nein | — |
25.11 ECR-Einrichtung
ECRFacility ist die Organisation, die Fallberichte sendet.
Definiert als ECRFacility in internal/config.
| Schlüssel | Typ | Erforderlich | Standard |
|---|---|---|---|
name | Text | ja | — |
npi | Text | nein | — |
phone | Text | ja | — |
line | Text | nein | — |
city | Text | ja | — |
state | Text | ja | — |
postal_code | Text | nein | — |
25.12 EDIFACT-Optionen
EDIFACTOptions sind die Einstellungen, die nur für einen EDIFACT-Kanal gelten.
Definiert als EDIFACTOptions in internal/config.
| Schlüssel | Typ | Erforderlich | Standard |
|---|---|---|---|
envelope | Text | nein | — |
split | wahr oder falsch | nein | — |
acknowledge | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
provider | Text | ja | — |
tenant | Text | nein | — |
token_url | Text | nein | — |
client_id | Text | ja | — |
client_secret | Text | nein | — |
refresh_token | Text | nein | — |
scope | Text | nein | — |
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:
- aws: AWS HealthLake, der Anfragen mit Signature Version 4 für den Dienst "healthlake" akzeptiert - ohne Token. - azure: Azure Health Data Services, der ein Microsoft Entra ID-Token für die eigene Zielgruppe des FHIR-Dienstes akzeptiert, das mit dem client-credentials-Grant einer App-Registrierung abgerufen wird, die die Rolle FHIR Data Contributor besitzt. - client_credentials: jeder OAuth 2.0-Token-Endpunkt - Keycloak, Okta, ein SMART-Backend-Dienst mit einem Client-Geheimnis.
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
type | Text | ja | — |
region | Text | nein | — |
access_key_id | Text | nein | — |
secret_access_key | Text | nein | — |
session_token | Text | nein | — |
tenant_id | Text | nein | — |
token_url | Text | nein | — |
client_id | Text | nein | — |
client_secret | Text | nein | — |
scope | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
dir | Text | ja | — |
pattern | Text | nein | — |
poll_interval | Dauer, z. B. 30s oder 5m | nein | — |
after_read | Text | nein | — |
move_to | Text | nein | — |
error_dir | Text | nein | — |
stable_for | Dauer, z. B. 30s oder 5m | nein | — |
max_file_size | Ganzzahl | nein | — |
framed | wahr oder falsch | nein | — |
raw | wahr oder falsch | nein | — |
batch_size | Ganzzahl | nein | — |
sort_by | Text | nein | name |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
project | Text | nein | — |
credentials_file | Text | nein | — |
endpoint | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
bucket | Text | ja | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
url | Text | ja | — |
queue_manager | Text | ja | — |
queue | Text | ja | — |
username | Text | nein | — |
password | Text | nein | — |
tls | tlsconf.Settings (ein Block, weglassen, um nicht zu verwenden) | nein | — |
api_version | Text | nein | — |
timeout | Dauer, wie z. B. 30s oder 5m | nein | 30s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
mechanism | Text | ja | — |
username | Text | ja | — |
password | Text | ja | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
addr | Text | ja | — |
client_id | Text | nein | — |
username | Text | nein | — |
password | Text | nein | — |
tls | tlsconf.Settings (ein Block, weglassen, um nicht zu verwenden) | nein | — |
qos | ganze Zahl (ein Block, weglassen, um nicht zu verwenden) | nein | — |
timeout | Dauer, wie z. B. 30s oder 5m | nein | 30s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
transformations | Liste von ncpdp.Step | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
decrypt_with | Text | nein | — |
passphrase | Text | nein | — |
verify_with | Liste von Text | nein | — |
require_signature | wahr oder falsch | nein | — |
allow_unencrypted | wahr oder falsch | nein | — |
pass_plain | wahr oder falsch | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
encrypt_to | Liste von Text | nein | — |
sign_with | Text | nein | — |
passphrase | Text | nein | — |
armor | wahr oder falsch | nein | — |
no_compress | wahr oder falsch | nein | — |
file_name | Text | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
enabled | true oder false | nein | — |
max_attempts | ganze Zahl | nein | — |
backoff | Dauer, wie 30s oder 5m | nein | — |
max_backoff | Dauer, wie 30s oder 5m | nein | — |
max_depth | ganze Zahl | nein | — |
retain_hours | ganze Zahl | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
attempts | ganze Zahl | nein | — |
backoff | Dauer, z. B. 30s oder 5m | nein | — |
max_backoff | Dauer, z. B. 30s oder 5m | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
transformations | Liste von hl7v3.Schritten | nein | — |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
filter | Text | nein | — |
transformer | Text | nein | — |
preprocessor | Text | nein | — |
deploy | Text | nein | — |
undeploy | Text | nein | — |
postprocessor | Text | nein | — |
language | Text | nein | — |
timeout | Dauer, z. B. 30s oder 5m | nein | — |
include | Liste von Text | nein | — |
file_roots | Liste von Text | nein | — |
allow | Liste von Text | nein | — |
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:
- Der Shadow liefert nie aus. Seine Ziele werden nicht erstellt, sodass es keinen Code-Pfad von einem Shadow-Kanal zu einem Empfänger gibt und keine Einstellung kann einen durch Fehler erstellen. - Der Shadow beeinflusst den Live-Kanal nie. Er läuft nach der Lieferung und Bestätigung der Live-Nachricht und ein Shadow, das panikt, auswirft oder hängt, wird als Shadow-Fehler aufgezeichnet und nichts anderes.
Definiert als Shadow in internal/config.
| Schlüssel | Typ | Erforderlich | Standard |
|---|---|---|---|
channel | Text | ja | — |
sample | Zahl | nein | 1 |
compare | Liste von Text | nein | — |
ignore | Liste von Text | nein | — |
max_differences | ganze Zahl | nein | 100 |
timeout | Dauer, wie z. B. 30s oder 5m | nein | 5s |
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üssel | Typ | Erforderlich | Standard |
|---|---|---|---|
code | Text | ja | — |
scheme | Text | ja | — |
display | Text | nein | — |
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:
- Der deklarierte Inhaltstyp wird ignoriert. Die Bytes werden geschnüffelt und das Ergebnis muss in einer Zulassungsliste sein. Eine Datei namens logo.png, die HTML enthält, ist HTML. - SVG wird akzeptiert, weil das, was Unternehmen tatsächlich haben, ist, aber es ist ein ausführbares Dokumentenformat: es kann Skriptelemente, Ereignishandler-Attribute, externe Referenzen und eingebettete Fremdobjekte enthalten. Es wird neu geschrieben, um all diese zu entfernen, bevor es gespeichert wird, und die Neuschreibung wird durch das Einpflanzen jedes Angriffs in einem Test überprüft. - Es wird mit einer Content-Sicherheitsrichtlinie gesendet, die nichts erlaubt, mit deaktiviertem Schnüffeln und als anhängungsloses Inline-Bild nur. Sogar ein Sanitiser-Fehler sollte nicht zur Skriptausführung auf der eigenen Herkunft der Konsole werden. - Der hochgeladene Dateiname wird nie verwendet, um einen Pfad zu erstellen. Der gespeicherte Name wird aus dem geschnüffelten Typ abgeleitet, also kann ein Name wie ../../etc/perfuse nirgendwo entkommen.
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:
- aktiv-passiv: eine Lizenz, "Leader". Der Halter führt jeden Kanal und jeden Job aus, der einmal laufen muss (Abonnementbenachrichtigungen, Warnungen). Die anderen warten, und der erste, der es abläuft sieht, übernimmt. - aktiv-aktiv: der Leader führt die Jobs noch aus, und jeder Kanal hat eine Lizenz, die gleichmäßig auf die aktiven Server verteilt ist. Ein Server, der die Verbindung trennt, gibt seine Kanäle an die anderen ab; einer, der beitritt, nimmt seinen Anteil, sobald sie frei werden.
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:
- Die Zusammenfassung ist über das gesamte Dokument, mit Ausnahme jedes legalAuthenticator- und authenticator-Elements (Abschnitt 3.1.2), so dass spätere Signierer frühere Signaturen nicht brechen. Ausgedrückt in der Signatur als XPath-Filter 2.0-Subtraktions-Transformation, die jede XML-DSig-Implementierung auswerten kann. - Die Signatur ist XAdES-X-L (3.1.1, ESMD-1 bis ESMD-6): Das Signier-Zertifikat, die UTC-Signier-Zeit, eine Rolle aus der NUCC-Provider-Taxonomie, ein Signaturzweck aus ASTM E1762, der Zertifizierungspfad in CertificateValues und eine OCSP- oder CRL-Antwort in RevocationValues, mit den Zeitstempeln, auf denen X-L basiert. - Es wird base64 in sdtc:signatureText auf dem Teilnehmer, der signiert hat, mit einem Plain-Text-Vorschaubild (3.3, ESMD-7 bis ESMD-16), innerhalb von digitalSignature/authorizedSigner übertragen.
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.
- Eine Entscheidung wird nie upgegradet. Teilweise Zertifizierung wird nicht zu einer Genehmigung, und ein Antrag, den der Payer verweigert hat, zu prüfen, wird nicht zu einer Ablehnung. Beide dieser Kollabse sind im offensichtlichen Mapping verfügbar und beide sind im Richtung falsch, die jemandem Wochen kostet: Ein Widerspruch, der gegen eine Entscheidung eingereicht wird, die niemand getroffen hat, oder sechs Sitzungen, die gegen drei genehmigte gebucht werden. - Nichts wird erfunden, um ein erforderliches Feld zu füllen. Wo das Zielformat etwas verlangt, das die Quelle nicht enthält, meldet das Mapping es als Hinweis an, anstatt einen plausiblen Standardwert zu liefern. Eine erfundene Genehmigungsnummer ist schlimmer als eine fehlende. - Jedes Urteil wird gemeldet. Hinweise kommen mit dem Ergebnis zurück, sodass eine Person die Handvoll lesen kann, die eine Entscheidung benötigte, anstatt die gesamte Ausgabe. - Rundreisen werden getestet, anstatt angenommen. Ein Mapping, das ein Feld in einer Richtung verliert, wird durch Umwandlung in die andere Richtung und Vergleich gefunden, was der einzige Weg ist, ein Feld zu sehen, das niemand dachte, es zu behaupten.
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.
- ITI-44, Patienten-Identitäts-Feed HL7 V3: eine Quelle fügt einen Patienten hinzu (PRPA_IN201301UV02), ändert einen (PRPA_IN201302UV02) oder sagt, dass zwei Datensätze dieselbe Person sind (PRPA_IN201304UV02). Beantwortet mit MCCI_IN000002UV01. - ITI-45, PIXV3-Abfrage: die anderen Identifikatoren der Person, die einen hält (PRPA_IN201309UV02 -> PRPA_IN201310UV02). - ITI-47, PDQV3-Abfrage: die Personen, die einige Demografien entsprechen (PRPA_IN201305UV02 -> PRPA_IN201306UV02), mit Fortsetzung (QUQI_IN000003UV01) und Abbruch (QUQI_IN000003UV01_Cancel).
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:
- ELR: HL7 2.5.1 ORU^R01-Nachrichten, die Laborergebnisse an Gesundheitsbehörden übertragen (elr.go). - eCR: FHIR-basierte elektronische Erstanzeigen (eICR), wenn eine meldepflichtige Erkrankung diagnostiziert wird. - Impfstoffregister: VXU^V04, um verabreichte Impfungen zu melden, und VXQ^V01, um die Impfgeschichte eines Patienten abzufragen.
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:
- Das Festlegen von 'active' auf 'false' beendet jede Sitzung sofort, nicht erst bei der nächsten Ablaufzeit. Ein Browser-Tab, der auf einem Laptop geöffnet ist, der mit einem beendeten Mitarbeiter nach Hause gegangen ist, muss aufhören zu funktionieren, und eine Sitzung, die bis zum Ablauf überlebt, ist eine Sitzung, die die Entlassung überlebt. - Ein Fehler ist ein Fehler. SCIM hat keine Wiederholungssemantik, auf die sich eine Anwendung verlassen kann, sodass die Rückgabe von 200 für etwas, das nicht passiert ist, bedeutet, dass der Identitätsanbieter die Entziehung der Berechtigung als abgeschlossen registriert und nie wieder versucht. - Das Löschen eines Benutzers wird genauso behandelt wie die Deaktivierung: Der Zugriff endet. Die Audit-Historie wird unabhängig davon beibehalten, da ein Datensatz, der jemanden nennt, der nicht mehr existiert, schlimmer ist als einer, der als zurückgezogen markiert ist.
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:
- Ein Shadow kann nicht liefern. Es hält eine Transformationspipeline und keine Sender, sodass es keinen Codepfad von hier zu einem Empfänger gibt. Eine Einstellung kann keinen erstellen und ein Fehler kann keinen aktivieren. - Ein Shadow kann den Live-Kanal nicht beeinflussen. Es wird nach der Lieferung und Bestätigung der Live-Nachricht, seiner Panik und seiner Timeouts aufgerufen, die seine eigenen sind.
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
26.110 umlink
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:
- Ein Wert, der nicht zugeordnet werden kann, wird als Text erhalten, nie geraten. Ein lokaler Code, der in einen plausiblen Standard-Code umgewandelt wird, ist schlimmer als ein uncodierter Wert, weil der Empfänger ihn glaubt. - Jede Zuordnungsentscheidung, die ein Urteil erfordert, wird als Notiz gemeldet, damit ein Mensch diejenigen überprüfen kann, die wichtig sind, anstatt den gesamten Ausgang zu lesen. - Zeitstempel werden konvertiert, nicht kopiert. HL7-v2-Zeitstempel sind nicht ISO 8601, und ein dateTime, der eine lokale Zeit ohne Offset enthält, ist der häufigste Grund, warum eine konvertierte Ressource abgelehnt wird. - Einheiten behalten ihren ursprünglichen Text und erhalten nur dann einen UCUM-Code, wenn die Zuordnung sicher ist. Ein falscher Einheitscode ist ein Patientensicherheitsfehler, kein Formatierungsproblem.
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:
- Eine Datei, die geschrieben wird, und eine Datei, die fertig geschrieben wurde, sind nicht zu unterscheiden. Es gibt keine Sperre, keine Flagge und keine Benachrichtigung für diese Transporte - es gibt eine Größe und ein Änderungsdatum, und beides ist wahr für eine halb geschriebene Datei. Ein zu frühes Lesen sammelt eine halbe Nachricht, und HL7 hat keinen Terminator, so dass eine halbe Nachricht sehr oft immer noch parsebar ist. Die MSH ist intakt, die Segmente, die angekommen sind, sind wohlgeformt, diejenigen, die nicht angekommen sind, fehlen einfach. Sie wird akzeptiert, bestätigt, gespeichert, geliefert und nichts wird jemals erwähnen. - Eine Datei darf nicht gelöscht werden, bis jede Nachricht in ihr akzeptiert wurde, weil die Datei die einzige Kopie ist. - Eine Datei, die fehlgeschlagen ist, darf nicht auf dem nächsten Poll erneut aufgenommen werden und darf nicht stillschweigend fallen gelassen werden.
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:
- Der Signieralgorithmus ist bei der Registrierung festgelegt und mit dem Schlüssel gespeichert. Nichts beim Anmelden liest einen Algorithmus vom Client, weil das Algorithmus-Verwirrung ist und es hier keine Funktion gibt, die es könnte. - Der Ursprung wird genau verglichen, niemals durch Präfix oder Suffix. Ein Test, der alles akzeptiert, das mit der richtigen Domäne endet, akzeptiert auch eine Subdomäne eines Angreifers. - Eine Herausforderung ist einmalig und verfällt. Sie wird gelöscht, wenn sie verbraucht wird, so dass eine erfasste Behauptung nicht erneut abgespielt werden kann. - Die Attestation wird für nichts vertraut. Die Attestationsanweisung wird parseiert, um die Anmeldeinformationen zu extrahieren, und dann wird ihre Signatur ignoriert, weil eine ordnungsgemäße Überprüfung ein gewartetes Stammzertifikat erfordert und ein vorgetäuschter Nachweis schlimmer ist als ein nicht beanspruchter. - Die Signaturzählung wird überprüft, wenn der Authentifizierer eine liefert, und ihre Abwesenheit wird nicht als verdächtig behandelt. Viele Authentifizierer lassen sie legitimerweise bei Null.
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üssel | Vorkommen in |
|---|---|
access_key_id | AWS-Zugriff, FHIR-Authentifizierung, S3-Ziel |
account | Azure-Blob-Zugriff |
ack | HTTP-Quelle, SOAP-Quelle, Quelle |
ack_sender_id | X12-Optionen |
ack_sender_qualifier | X12-Optionen |
acknowledge | EDIFACT-Optionen, HL7v3-Optionen, X12-Optionen |
acks | Kafka-Ziel |
action | SOAP-Ziel |
addr | AMQP-Verbindung, Broker-Ziel, Broker-Quelle, MQTT-Verbindung |
address | AMQP-Verbindung, DICOM-Ziel, DICOM-Abfrage-Quelle, Ziel, Direkte Adresse, TCP-Ziel |
ae_title | DICOM-Quelle |
after_query | Datenbank-Quelle |
after_read | Azure-Blob-Quelle, Direkte IMAP, E-Mail-Quelle, Datei-Abfrage, GCS-Quelle, S3-Quelle, SFTP-Quelle |
allow | Skripte |
allow_clear_password | FTP-Ziel |
allow_unencrypted | AS2-Partner, PGP-Empfang |
allow_unsigned | AS2-Partner |
allowed_calling_ae | DICOM-Quelle |
allowed_senders | E-Mail-Quelle |
amqp | Ziel, Quelle |
anchors_file | Direkte Adresse |
api_version | IBMMQ-Verbindung |
append | Ziel, SFTP-Ziel |
application | Bestätigung |
armor | PGP-Versand |
arrives_as | X12-Optionen |
as2 | Ziel, Quelle |
attach | SMTP-Ziel |
attach_name | Direktes Ziel, SMTP-Ziel |
attachment_names | E-Mail-Quelle |
attachments | Kanal |
attempts | Wiederholung |
auth | FHIR-Ziel, PAS-Ziel |
authorities | MPI-Ziel |
azure_blob | Ziel, Quelle |
backoff | Warteschlangen-Konfiguration, Wiederholung |
base64 | SOAP-Quelle |
batch_size | Datenbank-Quelle, Datei-Abfrage |
baud | Serielle Quelle |
bcc | SMTP-Ziel |
bearer_token | CDA-Ziel, FHIR-Ziel, HTTP-Ziel, PAS-Ziel |
big_endian | TCP-Rahmen |
blob | Azure-Blob-Ziel |
body | SMTP-Ziel, SOAP-Ziel |
broker | Ziel, Quelle |
brokers | Kafka-Ziel, Kafka-Quelle |
bucket | GCS-Zugriff, S3-Ziel, S3-Quelle |
bundle_script | FHIR-Ziel |
called_ae | DICOM-Ziel, DICOM-Abfrage-Quelle |
calling_ae | DICOM-Ziel, DICOM-Abfrage-Quelle |
cc | SMTP-Ziel |
cda | Ziel |
cert_file | AS2-Ziel, AS2-Partner, AS2-Quelle, Direkte Adresse |
channel | Ziel, Schatten |
check_every | Vertrags-Verweis |
city | ECR-Einrichtung |
claim_us_core | FHIR-Ziel |
class | XDS-Ziel |
client_ca_file | Direkte XDR |
client_id | E-Mail-O-Auth, FHIR-Authentifizierung, MQTT-Verbindung |
client_secret | E-Mail-O-Auth, FHIR-Authentifizierung |
code | XDS-Code |
column | Datenbank-Quelle |
columns | Begrenzt |
comment | Begrenzt |
commit_after_delivery | Kafka-Quelle |
compare | Schatten |
compress | AS2-Ziel |
compression | Kafka-Ziel |
config | ELR-Ziel |
container | Azure-Blob-Zugriff |
content_type | AMQP-Ziel, AS2-Ziel, Azure-Blob-Ziel, Broker-Ziel, GCS-Ziel, HTTP-Ziel, S3-Ziel, XDS-Ziel |
contract | Kanal |
credentials_file | GCP-Zugriff |
dataType | Kanal |
data_bits | Serielle Quelle |
database | Ziel, Quelle |
decrypt_with | PGP-Empfang |
default_identifier_system | FHIR-Ziel |
delimited | Kanal |
delimiter | Begrenzt, TCP-Rahmen |
deploy | Skripte |
description | Kanal |
destination | Broker-Ziel, Broker-Quelle |
destinations | Kanal |
dicom | Kanal, Ziel, Quelle |
dicom_query | Quelle |
dicomweb | Ziel, Quelle |
dir | CDA-Ziel, Ziel, Dokument-Ziel, FTP-Ziel, Datei-Abfrage, SFTP-Ziel, SFTP-Quelle |
direct | Ziel, Quelle |
direct_from | XDS-Ziel |
direct_to | XDS-Ziel |
display | XDS-Code |
dns | Direktes Ziel |
document | Ziel |
domain | SMB-Quelle |
driver | Datenbank-Ziel, Datenbank-Quelle |
dsn | Datenbank-Ziel, Datenbank-Quelle |
duplicate_window | AS2-Quelle |
ecr | FHIR-Ziel |
edifact | Kanal |
element | SOAP-Quelle |
elr | Ziel |
email | Quelle |
emit_on_first_poll | DICOM-Abfrage-Quelle |
enabled | Kanal, Ziel, Warteschlangen-Konfiguration |
encrypt_to | PGP-Versand |
endpoint | AWS-Zugriff, Azure-Blob-Zugriff, GCP-Zugriff, S3-Ziel |
envelope | EDIFACT-Optionen, X12-Optionen |
error_dir | Datei-Abfrage, SFTP-Quelle |
error_folder | Direkte IMAP, E-Mail-Quelle |
error_prefix | Azure-Blob-Quelle, GCS-Quelle, S3-Quelle |
expect_reply | TCP-Ziel |
extract | Anhänge |
facility | Bestätigung, ECR-Einrichtung |
facility_id | SOAP-Ziel |
facility_type | XDS-Ziel |
fail_on_body | HTTP-Ziel |
fault_is_success | SOAP-Ziel |
fault_on_nak | SOAP-Quelle |
fhir | Ziel |
file | Vertrags-Verweis, Quelle |
file_name | AS2-Ziel, Ziel, Dokument-Ziel, FTP-Ziel, PGP-Versand, SFTP-Ziel |
file_roots | Skripte |
filter | Kanal, Begrenzt, Ziel, HL7v3-Optionen, Skripte |
flow_control | Serielle Quelle |
follow_redirects | HTTP-Ziel |
follow_symlinks | Datei-Quelle |
font_size | Dokument-Ziel |
format | Dokument-Ziel, S3-Ziel |
framed | Azure-Blob-Quelle, FTP-Ziel, Datei-Abfrage, GCS-Quelle, S3-Ziel, S3-Quelle, SFTP-Ziel, SFTP-Quelle |
framing | TCP-Rahmen |
from | AS2-Ziel, SMTP-Ziel |
from_beginning | Kafka-Quelle |
ftp | Ziel, Quelle |
gcs | Ziel, Quelle |
group | Kanal, Kafka-Quelle |
group_by | SNS-Ziel, SQS-Ziel |
has_header | Begrenzt |
header | SOAP-Ziel |
headers | Broker-Ziel, CDA-Ziel, DICO Mweb-Ziel, FHIR-Ziel, HTTP-Ziel, Kafka-Ziel, SOAP-Ziel, XDS-Ziel |
heartbeat | Broker-Quelle |
hl7v3 | Kanal |
host | Broker-Ziel, Broker-Quelle, Direkte IMAP, E-Mail-Quelle, FTP-Ziel, FTP-Quelle, SFTP-Ziel, SFTP-Quelle, SMB-Quelle, SMTP-Ziel |
hostname | AMQP-Verbindung |
http | Ziel, Quelle |
ibm_mq | Ziel, Quelle |
id | AS2-Partner, AS2-Quelle |
id_type | MPI-Ziel |
identifier_systems | CDA-Ziel, FHIR-Ziel |
idle_timeout | DICOM-Quelle, Quelle, TCP-Quelle |
ignore | Schatten |
imap | Direkte Quelle |
include | Skripte |
include_trigger_event | Bestätigung |
insecure_skip_host_key_check | SFTP-Ziel, SFTP-Quelle |
insecure_skip_verify | FTP-Ziel, FTP-Quelle, SMTP-Ziel, Web DAV-Quelle |
interval | DICOM-Abfrage-Quelle |
javascript | Ziel, Quelle |
kafka | Ziel, Quelle |
keep_alive | TCP-Ziel |
keep_blank_lines | Begrenzt |
keep_delimiter | TCP-Rahmen |
key | Azure-Blob-Zugriff, Kafka-Ziel, S3-Ziel |
key_column | Datenbank-Quelle |
key_file | AS2-Ziel, AS2-Quelle, Direkte Adresse, SFTP-Ziel, SFTP-Quelle |
key_passphrase | SFTP-Ziel, SFTP-Quelle |
known_hosts_file | SFTP-Ziel, SFTP-Quelle |
landscape | Dokument-Ziel |
language | Skripte |
ldap | Direktes Ziel |
length_bytes | TCP-Rahmen |
length_includes_header | TCP-Rahmen |
level | DICOM-Abfrage-Quelle |
limit | DICOM-Abfrage-Quelle |
line | ECR-Einrichtung |
listen | AS2-Quelle, DICO Mweb-Quelle, DICOM-Quelle, Direkte Quelle, Direkte XDR, HTTP-Quelle, SOAP-Quelle, Quelle, TCP-Quelle |
login | Broker-Ziel, Broker-Quelle |
mailbox | Direkte IMAP, E-Mail-Quelle |
match | DICOM-Abfrage-Quelle |
max_attempts | Datenbank-Quelle, Warteschlangen-Konfiguration |
max_backoff | Warteschlangen-Konfiguration, Wiederholung |
max_bytes | Direkte Quelle |
max_connections | Quelle, TCP-Quelle |
max_depth | Warteschlangen-Konfiguration |
max_differences | Schatten |
max_file_size | Datei-Abfrage, SFTP-Quelle |
max_message_size | AS2-Quelle, E-Mail-Quelle, HTTP-Quelle, Kafka-Quelle, SOAP-Quelle, Serielle Quelle, Quelle, TCP-Ziel, TCP-Quelle |
max_messages | Pub Sub-Quelle, SQS-Quelle |
max_object_bytes | DICO Mweb-Quelle, DICOM-Quelle |
max_object_size | Azure-Blob-Quelle, GCS-Quelle, S3-Quelle |
max_open_conns | Datenbank-Ziel |
mechanism | Kafka-SASL |
method | HTTP-Ziel |
move_to | Azure-Blob-Quelle, Direkte IMAP, E-Mail-Quelle, Datei-Abfrage, GCS-Quelle, S3-Quelle, SFTP-Quelle |
mpi | Ziel |
mqtt | Ziel, Quelle |
name | Kanal, Kanal-Ziel, Ziel, ECR-Einrichtung |
ncpdp | Kanal |
no_compress | PGP-Versand |
no_merge | MPI-Ziel |
non_persistent | IBMMQ-Ziel |
npi | ECR-Einrichtung |
oauth | E-Mail-O-Auth |
object | GCS-Ziel |
on_no_document | CDA-Ziel |
order_by | Pub Sub-Ziel |
over | Vertrags-Verweis |
overlap | DICOM-Abfrage-Quelle |
params | Datenbank-Ziel |
parity | Serielle Quelle |
partner_cert_file | AS2-Ziel |
partners | AS2-Quelle |
pas | Ziel |
pass_plain | PGP-Empfang |
passcode | Broker-Ziel, Broker-Quelle |
passphrase | PGP-Empfang, PGP-Versand |
password | AMQP-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 |
path | AS2-Quelle, DICO Mweb-Quelle, HTTP-Quelle, SOAP-Quelle |
path_style | S3-Ziel, S3-Quelle |
patient_domain | XDS-Ziel |
patient_root | DICOM-Abfrage-Quelle |
pattern | Datei-Abfrage, SFTP-Quelle |
payer | PAS-Ziel |
persistent | Broker-Ziel |
pgp | Ziel, Quelle |
phone | ECR-Einrichtung |
poll_interval | Azure-Blob-Quelle, Datenbank-Quelle, Direkte IMAP, E-Mail-Quelle, Datei-Abfrage, GCS-Quelle, IBMMQ-Quelle, Java-Script-Quelle, S3-Quelle, SFTP-Quelle |
port | Direkte IMAP, E-Mail-Quelle, Serielle Quelle |
postal_code | ECR-Einrichtung |
postprocessor | Skripte |
practice_setting | XDS-Ziel |
prefetch | AMQP-Quelle |
prefix | Azure-Blob-Quelle, GCS-Quelle, S3-Quelle |
preprocessor | Skripte |
profile | SOAP-Ziel, SOAP-Quelle |
project | GCP-Zugriff |
protocol | E-Mail-Quelle |
provider | E-Mail-O-Auth |
pubsub | Ziel, Quelle |
purpose | TEFCA-Ziel |
qos | MQTT-Verbindung |
query | Datenbank-Quelle |
query_timeout | Datenbank-Quelle |
queue | Ziel, IBMMQ-Verbindung |
queue_manager | IBMMQ-Verbindung |
queue_url | SQS-Ziel, SQS-Quelle |
quiet_after | Serielle Quelle |
quote | Begrenzt |
raw | Datei-Abfrage |
rctc | ECR-Ziel, ELR-Ziel |
read_timeout | HTTP-Quelle, SOAP-Quelle |
reassemble | Anhänge |
receipt | AS2-Ziel |
receipt_url | AS2-Ziel |
recipient_certs_dir | Direktes Ziel |
reconnect | AMQP-Quelle, Broker-Quelle, MQTT-Quelle, Pub Sub-Quelle |
record_length | TCP-Rahmen |
refresh_token | E-Mail-O-Auth |
region | AWS-Zugriff, FHIR-Authentifizierung, S3-Ziel |
reject_on_warning | FHIR-Ziel |
relaxed | Begrenzt |
reopen_after | Serielle Quelle |
reply | Serielle Quelle, TCP-Quelle |
reply_text | Serielle Quelle, TCP-Quelle |
request_mdn | Direktes Ziel |
require_agreement | CDA-Ziel |
require_signature | PGP-Empfang |
response_element | SOAP-Quelle |
response_namespace | SOAP-Quelle |
response_transformer | Ziel |
results_to | PAS-Ziel, TEFCA-Ziel |
retain | MQTT-Ziel |
retain_hours | Ziel, Warteschlangen-Konfiguration |
retry | Ziel |
return | DICOM-Abfrage-Quelle |
root | FTP-Quelle, Datei-Quelle, SMB-Quelle |
s3 | Ziel, Quelle |
sample | Schatten |
sas | Azure-Blob-Zugriff |
sasl | Kafka-Ziel, Kafka-Quelle |
scheme | XDS-Code |
scope | E-Mail-O-Auth, FHIR-Authentifizierung |
script | Kanal, Java-Script-Ziel, Java-Script-Quelle |
scripts | Kanal |
secret_access_key | AWS-Zugriff, FHIR-Authentifizierung, S3-Ziel |
security | Direkte IMAP, E-Mail-Quelle, FTP-Ziel, FTP-Quelle |
selector | Broker-Quelle |
sender_device | HL7v3-Optionen |
sender_oid | HL7v3-Optionen |
serial | Quelle |
server_side_encryption | S3-Ziel |
session_timeout | Kafka-Quelle |
session_token | AWS-Zugriff, FHIR-Authentifizierung, S3-Ziel |
sftp | Ziel, Quelle |
shadow | Kanal |
share | SMB-Quelle |
sign_with | PGP-Versand |
smb | Quelle |
smtp | Ziel |
smtp_host | Direktes Ziel, Direkte Quelle |
sns | Ziel |
soap | Ziel, Quelle |
sop_classes | DICOM-Quelle |
sort_by | Datei-Abfrage |
source | Kanal, ECR-Ziel |
source_id | XDS-Ziel |
split | Begrenzt, EDIFACT-Optionen, X12-Optionen |
sqs | Ziel, Quelle |
ssn_system | MPI-Ziel |
stable_for | Datei-Abfrage, SFTP-Quelle |
start_block | TCP-Rahmen |
starttls | SMTP-Ziel |
state | ECR-Einrichtung |
statement | Datenbank-Ziel |
stop_bits | Serielle Quelle |
storage_class | GCS-Ziel, S3-Ziel |
subject | AS2-Ziel, Direktes Ziel, SMTP-Ziel, SNS-Ziel |
subscription | Pub Sub-Quelle |
subscription_id | Broker-Quelle |
success_on_undefined | Java-Script-Ziel |
success_status | HTTP-Ziel |
suffix | Azure-Blob-Quelle, GCS-Quelle, S3-Quelle |
tables | Kanal |
take | E-Mail-Quelle |
tcp | Ziel, Quelle |
tefca | Ziel |
temp_suffix | Ziel, Dokument-Ziel, FTP-Ziel, SFTP-Ziel |
template | Datenbank-Quelle, Dokument-Ziel |
tenant | E-Mail-O-Auth |
tenant_id | FHIR-Authentifizierung |
text | Direktes Ziel |
tier | Azure-Blob-Ziel |
timeout | AMQP-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 |
timezone | FHIR-Ziel |
title | Dokument-Ziel |
tls | AMQP-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_cert | Direkte Quelle, Direkte XDR |
tls_key | Direkte Quelle, Direkte XDR |
to | AS2-Ziel, Direktes Ziel, SMTP-Ziel |
token | DICO Mweb-Ziel, DICO Mweb-Quelle, HTTP-Quelle, SOAP-Quelle, XDS-Ziel |
token_url | E-Mail-O-Auth, FHIR-Authentifizierung |
topic | Kafka-Ziel, MQTT-Ziel, MQTT-Quelle, Pub Sub-Ziel |
topic_arn | SNS-Ziel |
topics | Kafka-Quelle |
transfer_syntaxes | DICOM-Ziel, DICOM-Quelle |
transformations | Kanal, DICOM-Optionen, Begrenzt, HL7v3-Optionen, NCPDP-Optionen, Skript-Optionen, X12-Optionen |
transformer | Skripte |
trim_padding | TCP-Rahmen |
trim_space | Begrenzt |
type | Ziel, FHIR-Authentifizierung, Quelle |
undeploy | Skripte |
unencrypted | AS2-Ziel |
unsigned | AS2-Ziel |
unsigned_receipt | AS2-Ziel |
url | AS2-Ziel, CDA-Ziel, DICO Mweb-Ziel, FHIR-Ziel, HTTP-Ziel, IBMMQ-Verbindung, SOAP-Ziel, Web DAV-Quelle, XDS-Ziel |
user | FTP-Ziel, FTP-Quelle, SFTP-Ziel, SFTP-Quelle, SMB-Quelle, Web DAV-Quelle |
username | AMQP-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_send | FHIR-Ziel |
verify_with | PGP-Empfang |
version | CDA-Ziel, FHIR-Ziel, SOAP-Ziel, SOAP-Quelle |
visibility_timeout | SQS-Quelle |
wait_seconds | SQS-Quelle |
warnings_are_errors | SOAP-Ziel |
webdav | Quelle |
when | Bestätigung |
window | DICOM-Abfrage-Quelle |
write | CDA-Ziel |
wsdl | SOAP-Quelle |
x12 | Kanal |
x12_as | Ziel |
xdm | Direktes Ziel |
xdm_source_id | Direktes Ziel |
xdr | Direkte Quelle |
xds | Ziel |