---
{
  "title": "Aidbox + MatrixCare EHR-Integration (Schritt für Schritt)",
  "description": "So integrieren Sie das MatrixCare EHR mit Aidbox mithilfe einer warteschlangenbasierten Architektur, FHIR-Mappings und resilienter Synchronisierung – mit einem realen Projektmuster.",
  "date": "2022-07-18",
  "author": "Artem Alekseev",
  "reading-time": "6 min read",
  "tags": [
    "Integrations",
    "Aidbox"
  ],
  "seo-tags": [
    "fhir",
    "fhir integration",
    "fhir server",
    "fhir platform",
    "ehr integration",
    "matrixcare"
  ]
}
---
## Zusammenfassung
Bislang gibt es kein Allheilmittel für den Aufbau einer funktionierenden ETL-Pipeline zur Übertragung eines [HL7v2](/blog/getting-started-with-hl7-messaging-over-mllp-using-a-vpn)-Nachrichten-Feeds aus einem EHR in FHIR-Daten – und das gilt auch für MatrixCare EHR, sobald Anpassungsmöglichkeiten ins Spiel kommen. In diesem Artikel zeigen wir anhand von Beispielen, wie wir die Integrationsprobleme gelöst haben und welche Werkzeuge wir dabei eingesetzt haben (Spoiler: [Aidbox](https://www.health-samurai.io/aidbox)). Außerdem beschreiben wir die grundlegenden Prinzipien der HL7v2-zu-FHIR-Systemkonfiguration – zum Nutzen all jener, die ihr eigenes System von Grund auf aufbauen möchten.

FHIR-Daten sind ein ideales Informationsmodell für:
- Datenaggregation für weiterführende Analysen;
- die Schaffung eines FHIR-App-Stores für das Gesundheitswesen und die Bereitstellung von Daten für Smart Apps;
- die schrittweise Weiterentwicklung der bestehenden Anwendung oder die Suche nach individuellen Lösungen für spezielle Aufgaben.

Um Ihnen einen kurzen Überblick über das Gesamtsystem zu verschaffen, sehen Sie sich bitte dieses Diagramm an, das die vollständige ETL-Pipeline für MatrixCare EHR von Health Samurai zeigt:

![MatrixCare & Aidbox Integration pipeline](image-1.avif)

## Allgemeine Architektur
In diesem Beitrag besprechen wir MatrixCare EHR, obwohl aufmerksame Leserinnen und Leser möglicherweise bemerken werden, dass die beschriebene Erfahrung vollständig auf jedes andere EHR übertragbar ist – denn nahezu jedes System, das für die Ausführung einer effektiven ETL-Pipeline entwickelt wurde, arbeitet nach denselben Prinzipien.

Die Übernahme von Daten aus einer externen Quelle beginnt also mit der **QUELLE** dieser Daten!

## Datenquelle
![MatrixCare HL7v2 Feed](image-2.avif)

Unsere Datenquelle ist MatrixCare EHR. Es erzeugt RAW [HL7v2-Nachrichten](https://www.hl7.org/implement/standards/product_brief.cfm?product_id=185). Falls Sie vergessen haben oder nicht wissen, wie rohe HL7v2-Nachrichten aussehen, hier ein kurzes Beispiel. Es handelt sich um ein recht altes Datenformat, das im Wesentlichen aus einer Zeichenkette besteht, die in Segmente (und Untersegmente) unterteilt ist, wobei jedes davon nützliche medizinische Informationen speichert.

Zeichenketten sind nicht der praktischste Datentyp, weshalb sie üblicherweise in für Menschen und Maschinen lesbare Datenstrukturen (JSON, YAML oder EDN) geparst werden. Es gibt Open-Source-Parser für HL7v2-Nachrichten (z. B. [v2 to FHIR](https://github.com/HL7/v2-to-fhir/tree/master/mappings), [HL7v2 to FHIR converter by Linux For Health](https://github.com/LinuxForHealth/hl7v2-fhir-converter)), jedoch bietet [Aidbox](https://www.health-samurai.io/aidbox) eine integrierte Funktion zum [Parsen von Nachrichten und zur persistenten Speicherung des Ergebnisses](https://www.health-samurai.io/docs/aidbox/modules-1/hl7-v2-integration).

Unsere Quelle erzeugt eine große Anzahl von HL7v2-Nachrichten wie diese:
![HL7v2 Message Example](image-3.avif)

MatrixCare EHR sendet eine ADT-Nachricht (Admit, Discharge, Transfer) im HL7v2-Format. Es verwendet Version 2.5 des HL7-Standards. Eine Nachricht besteht aus folgenden Segmenten:
- MSH (Message Header), NK1 (Next of Kin), AL1 (Allergies), DG1 (Diagnosis), PV1 (Patient Visit), PV2 (Patient Visit Additional), GT1 (Guarantor)
- Für jedes Segment gibt es eine umfassende Dokumentation, z. B.: [https://hl7-definition.caristix.com/v2/HL7v2.5.1/Segments/MSH](https://hl7-definition.caristix.com/v2/HL7v2.5.1/Segments/MSH)

## Warteschlange
![MatrixCare & Amazon SQS Integration](image-4.avif)

Es ist kaum vorstellbar, ein komplexes System ohne Datenstrukturen zu betreiben, die einen geordneten Zugriff ermöglichen. Medizinische Systeme verwenden Warteschlangen für folgende Zwecke:
- **Verzögerte Verarbeitung** – niemand erwartet, dass alle Systeme alle eingehenden Daten sofort verarbeiten; es genügt zu wissen, dass dies zu einem vorhersehbaren Zeitpunkt in naher Zukunft geschehen wird;
- **Skalierbarkeit** – wir können weitere Consumer hinzufügen, um Daten schneller zu verarbeiten;
- **Lastspitzen** – wir können nicht davon ausgehen, dass der Datenfluss stets linear verläuft.

In unserem Beispiel verwenden wir Amazon SQS (obwohl wir unseren Application Adapter so konfigurieren können, dass er mit nahezu jedem Warteschlangendienst zusammenarbeitet). Amazon SQS verfügt über einige interessante Funktionen. Neben dem parallelen Zugriff, einem Deduplizierungsmechanismus, Long Polling und einer übersichtlichen Visualisierung gibt es eine Funktion, die uns am meisten überzeugt. Es handelt sich dabei um die **DLQ** oder **Dead-Letter-Queue.** Wenn beim Verarbeiten einer Nachricht etwas Unerwartetes passiert, versucht SQS, die Nachricht an den Consumer zuzustellen, aber nach mehreren Versuchen wird sie in der DLQ gespeichert, von wo aus sie manuell oder programmatisch verarbeitet werden kann (Spoiler: Ja, unsere **Lilly** **Adapter**-Anwendung verfügt über eine **API zur Wiederverarbeitung von DLQ-Nachrichten – POST "/$sqs-dlq-reprocess"**).

## Wo die Magie beginnt!
![Amazon SQS & DLQ & Aidbox Integration](image-5.avif)

Nach der **Extraktion** der HL7v2-Nachricht müssen wir eine Transformation nach FHIR durchführen. Dafür haben wir tatsächlich eine Video-Anleitung:
- [https://www.youtube.com/watch?v=iSDX4UZpYO4](https://www.youtube.com/watch?v=iSDX4UZpYO4)

Wie bereits erwähnt, gibt es verschiedene Open-Source-Parser für HL7v2, aber Aidbox bietet integrierte Funktionen, um die **gesamte ETL-Pipeline** abzudecken:
- Persistente Speicherung eingehender Nachrichten in der Datenbank (Aidbox DB [https://www.health-samurai.io/docs/aidbox/storage-1/database](https://www.health-samurai.io/docs/aidbox/storage-1/database)), um Datenverlust oder Datenfehler zu vermeiden;
- Parsen der Nachricht in für Menschen und Maschinen lesbare Datenstrukturen (HL7v2-Parser [https://www.health-samurai.io/docs/aidbox/modules-1/hl7-v2-integration](https://www.health-samurai.io/docs/aidbox/modules-1/hl7-v2-integration));
- Parsen der Nachricht in FHIR-Daten mithilfe der JUTE-Mapping-Sprache (Data-DSL von Health Samurai [https://github.com/HealthSamurai/jute.clj](https://github.com/HealthSamurai/jute.clj));
- Persistente Speicherung der erstellten FHIR-Ressourcen in einer Datenbank (wieder AidboxDB).

So läuft der Prozess genau ab:
- **Lilly Adapter** stellt einen Listener (oder Consumer) bereit, der kontinuierlich bei SQS nach neuen Nachrichten fragt und, sofern welche vorhanden sind, die Verarbeitung der HL7v2-Nachricht einleitet,
- neue eingehende HL7v2-Nachrichten werden in der HL7v2Message-Ressource gespeichert: src: "HL7V2MESSAGE" status: received
- **Aidbox** stellt einen **Job** bereit, der auf neue Nachrichten mit dem Status **'received'** wartet,

![HL7v2 to Aidbox](image-6.avif)

- nachdem die Nachricht vom Aidbox-System erkannt wurde, wird sie von [**Aidbox**](https://www.health-samurai.io/fhir-server) **geparst**: Die rohe HL7v2-Nachricht wird in eine für Menschen lesbare Datenstruktur umgewandelt, die als YAML oder JSON zurückgegeben werden kann, und wird unter dem Schlüssel **'parsed'** in derselben HL7v2Message-Ressource gespeichert:

![HL7v2 statuses within Aidbox](image-7.avif)

- das Feld **config** muss ebenfalls unterstützt werden – **config** legt fest, welcher Satz von **Mappings** (mehr dazu unter [https://www.health-samurai.io/docs/aidbox/tools/mappings](https://www.health-samurai.io/docs/aidbox/tools/mappings)) angewendet wird. **Config** wird in der HL7v2Config-Ressource gespeichert, Mappings werden als Mapping-Ressource gespeichert;
- die **geparsten** Daten sind also die Eingabedaten für die **Mappings**, und das Ergebnis der Mapping-Anwendung wird im Feld **outcome** gespeichert:

> outcome = all_mappings_from_hl7v2config(parsed_field_data)

- Je nachdem, ob sowohl der Parse-Vorgang als auch die Ressourcenerstellung erfolgreich verlaufen, wird der **Status** der Nachricht von **'received'** auf **'processed'** geändert. Schlägt der Vorgang fehl, wird der Status **'error'** vergeben. Die **Lilly Adapter**-Anwendung verfügt über eine API zur Nachrichtenwiederverarbeitung. Sie kann Nachrichten nach verschiedenen Kriterien wie Status, Ereignistyp, Zeitraum usw. erneut verarbeiten. Der Status **'processed'** bedeutet, dass alle erforderlichen FHIR-Ressourcen erfolgreich erstellt wurden:

![FHIR mapping](image-8.avif)

## Ein wenig mehr zu den Mappings
**Mappings** erfüllen mehrere Funktionen:
- Sie ermöglichen die **Transformation** von **geparsten** Daten in ein Ergebnis (Outcome) gemäß der in den Mappings definierten **benutzerdefinierten** Logik;
- Sie stellen einen Mechanismus zur **persistenten Datenspeicherung** bereit (manche vertreten die Auffassung, dass FHIR für den Datenaustausch und nicht für die Datenspeicherung entwickelt wurde – wir sehen das jedoch anders: [https://www.health-samurai.io/articles/should-you-use-fhir-resources-as-your-data-storage-format](https://www.health-samurai.io/articles/should-you-use-fhir-resources-as-your-data-storage-format));
- Der Satz der auf das geparste Feld angewendeten Mappings wird über die HL7v2Config-Ressource konfiguriert, mehr dazu hier: [https://www.health-samurai.io/docs/aidbox/modules-1/hl7-v2-integration](https://www.health-samurai.io/docs/aidbox/modules-1/hl7-v2-integration).

Mappings werden in einer speziellen DSL geschrieben, die vom Health Samurai-Team entwickelt wurde – der **JUTE**-Mapping-Sprache. Es handelt sich um eine schlanke und gut dokumentierte DSL mit nahezu keiner Lernkurve, die so gestaltet ist, dass Sie **nicht einmal Programmierkenntnisse benötigen**, um Ihre Mappings zu schreiben. Dennoch werden Sie gelegentlich auf komplexe Fälle stoßen, die anspruchsvollere Mappings erfordern.

Link: [https://github.com/HealthSamurai/jute.clj](https://github.com/HealthSamurai/jute.clj)

Sie fragen sich vielleicht, wie die Anwendung von Mappings zur **persistenten Datenspeicherung** führt. Wir versuchen, das zu erklären:
![Aidbox Mapping Resource example / JUTE](image-9.avif)

Mappings müssen ein Feld **'request'** enthalten, das tatsächlich einem Aidbox-API-Aufruf entspricht, der als Ergebnis der Mapping-Anwendung ausgeführt wird. Infolge der Mapping-Anwendung werden Ressourcen erstellt und in der Aidbox-Datenbank persistent gespeichert.

Um zu erkunden, wie Aidbox Ihre Integration mit MatrixCare EHR verbessern kann, testen Sie die [kostenlose Version von Aidbox](https://www.health-samurai.io/aidbox#run). Sie bietet eine vollständige Umgebung zum Testen und Verfeinern von Integrationsprozessen und stellt alle erforderlichen Werkzeuge ohne Funktionseinschränkungen bereit.

## Zusammenfassung
Hier sind die Schritte, die Sie unternehmen müssen, um eine Integration mit MatrixCare einzurichten:

- Stellen Sie eine Instanz bereit, die Nachrichten von MatrixCare abruft (das kann nahezu jede Instanz sein, einschließlich Kafka oder RabbitMQ, aber wir haben hier Amazon SQS verwendet);
- finden Sie eine Möglichkeit, diese Nachricht zu verarbeiten (aus einer Warteschlange oder direkt vom EHR);
- parsen Sie die HL7v2-Nachricht von einer Zeichenkette in eine Datenstruktur;
- transformieren Sie das geparste HL7v2 in FHIR-Ressourcen;
- speichern Sie das Ergebnis.

Sie könnten das Rad zwar neu erfinden, aber [Aidbox](https://www.health-samurai.io/fhir-server) ist bereits so konfiguriert, dass die gesamte Magie in sich selbst stattfindet. Wir speichern Nachrichten persistent, parsen sie, übersetzen sie in das FHIR-Format und speichern dann das Ergebnis persistent. Wie Sie bemerkt haben mögen, ist die Adapter-Anwendung schlank, und Sie könnten durchaus Ihre eigene Version davon entwickeln – wir halten dies jedoch nicht für notwendig.

Mappings (die zur Transformation von Daten aus geparsten HL7v2-Nachrichten in FHIR-Ressourcen verwendet werden) sind ein **Anpassungspunkt**. Jedes EHR wird wahrscheinlich einen eigenen Satz von Mappings benötigen, aber wir haben auch einige vorgefertigte Mappings für MatrixCare EHR, die hilfreich sein könnten. Wir können an jedem Punkt des Integrationsprozesses Unterstützung leisten.

---

**Autor: Artem Alexeev**

[![Aidbox FHIR Platform Free Trial](image-10.avif)](https://www.health-samurai.io/aidbox)

Siehe auch: [Umgang mit der Integration von Altsystemen](/blog/tackling-legacy-system-integration-with-fhir).