1 Wprowadzenie

Perfuse przenosi komunikaty kliniczne między systemami, które nie zostały zaprojektowane do komunikowania się ze sobą. Laboratorium wysyła wyniki w HL7 v2; system zarządzania praktyką oczekuje ich z innymi pozycjami pól, innym identyfikatorem pacjenta i potwierdzeniem w ciągu pięciu sekund. Coś musi siedzieć pośrodku, a tym czymś jest silnik integracji.

Ten podręcznik opisuje, co robi Perfuse, każdą opcję, którą akceptuje, i — gdzie decyzja nie jest oczywista — dlaczego działa w taki sposób.

1.1 Do czego służy Perfuse

Jeden interfejs między dwoma systemami klinicznymi jest zwykle wyceniany w dziesiątkach tysięcy, z piętnastoma do dwudziestu procent więcej każdego roku w utrzymaniu. Większość tego kosztu nie jest pracą; jest to, że praca wymaga kogoś, kto ma doświadczenie w HL7, a większość praktyk nie zatrudnia takiej osoby.

Perfuse został zbudowany na założeniu, że osoba konfigrująca go ma problem do rozwiązania i nie ma wcześniejszego doświadczenia w HL7. To założenie jest widoczne w konkretnych miejscach:

Rozdział o testowaniu i ten o migracji istnieją, ponieważ odpowiedź na „dlaczego mam ufać temu” musi być dowodem, który zbierasz sam, a nie twierdzeniem złożonym tutaj.

1.2 Co się w nim znajduje

Wszystko poniżej jest w jednym pliku binarnym. Każda linia nazwuje rozdział, który ją opisuje.

1.3 Standardy i wersje

Która wersja każdego standardu jest implementowana przez Perfuse i w jaki sposób to sprawdzono. „Sprawdzono” to nazwa zewnętrznego narzędzia lub odniesienia, które oceniło wynik; jeśli nic zewnętrznego nie oceniło go, to tak się stwierdza. Wyniki pochodzą z danych testowych, a nie z witryny produkcyjnej.

1.3.1 Wiadomości i dokumenty

StandardWersjaSprawdzono
HL7 v2dowolna wersja: wiadomości są odczytywane przez ich separatory, a nie schemat wersji; potwierdzenia domyślnie 2.5.1NIST HL7 v2 validator; rzeczywisty ruch Mirth i OIE
HL7 v2 do FHIRmapowanie HL7 V2-to-FHIR (ADT, ORU, SIU, MDM, VXU i segmenty w nich)walidator HL7 FHIR przeciwko US Core, UK Core, FR Core, ISiK, nl-core i HL7 Europe
FHIRR4 (4.0.1), z R4B i R5 odczytywane i zapisywanewalidator HL7 FHIR; Inferno
C-CDA i CDAC-CDA 2.1ONC SITE (przykłady C-CDA wysłane i odebrane za pośrednictwem XDR); nie przez schematron CDA
HL7 v3PIX i PDQ (IHE ITI-44, 45, 47)schematy IHE NE2008 i przykładowe wiadomości
DICOM i DICOMwebDIMSE C-STORE, C-FIND, C-MOVE, C-GET, C-ECHO; QIDO-RS, WADO-RS, WADO-URI, STOW-RSOrthanc
X12 (HIPAA)005010: 837, 835, 270/271 (X279A1), 276/277 (X212), 834, 278 wniosek (X217) i zapytanie (X215); 275 w 006020 (X314)przewodniki towarzystw ubezpieczeniowych; przykłady CMS esMD
CAQH CORE łącznośćvC2.2.0 SOAP i MIME, vC4.0.0 z MTOMsystem UM napisany zgodnie z regułami CAQH
NCPDPTelekomunikacja D.0; SCRIPT 2023011 (i 2017071) z ePA; Real-Time Prescription Benefit v13napisane z publicznych przewodników towarzystwa Surescripts i ich przykładów; nie przeciwko licencjonowanym schematom NCPDP
UN/EDIFACTskładnia 3 i 4, CONTRLpydifact 0.1.8
IHE udostępnianie dokumentówXDS.b, XCA, XDR, MHD 4.2.2, PIXm, PDQm, XDMNIST XDS Toolkit; ONC SITE
Bezpośrednia komunikacja zabezpieczonaOświadczenie o zastosowaniu 1.2, XDR i XDM dla Direct, DNS i LDAP odkrywanie certyfikatówONC SITE; Narzędzie odkrywania certyfikatów ONC (18 z 18)
AS2RFC 4130, kompresja RFC 5402pyas2lib
Podpisywane załącznikiHL7 DSDR, XAdES-X-Lxmlsec1, OpenSSL

1.3.2 Przewodniki implementacji FHIR

PrzewodnikWersjaSprawdzono
US Corekonwersje do 9.0.0 (USCDI v6); serwer FHIR przeciwko 6.1.0 i 7.0.0walidator HL7; Inferno US Core
SMART App Launch2.2Inferno: 80 z 80 (publiczna aplikacja)
Bulk Data Access2.0.0Inferno: 48 z 48
Subscriptions R5 Backportdla R4rzeczywisty odbiorca HTTP; testy powiadomień zestawu PAS
Da Vinci CRD2.2.1 i 2.1.0Inferno 2.2.1: 92 przejdź, zero niepowodzeń; 2.1.0 według własnych przykładów przewodnika
Da Vinci DTR2.2.0 i 2.1.0Inferno 2.2.0: 43 przejdź, 2 niepowodzenia (wada zestawu); 2.1.0 według własnych przykładów przewodnika
Da Vinci PAS2.2.1 i 2.1.0Inferno 2.2.1: 82 z 84; 2.1.0 według własnych przykładów przewodnika
Da Vinci PAS, wysyłanie (strona dostawcy)2.2.1referencyjna implementacja płatnika HL7 Da Vinci PAS; nie jest to płatnik produkcyjny
Da Vinci PDex2.2.0Inferno PDex 2.0: płatnik do płatnika 19 z 19
Da Vinci HRex $member-match1.2.0Inferno PDex płatnik do płatnika
Da Vinci ATR2.1.0nie sprawdzono za pomocą zewnętrznego narzędzia
Da Vinci CDex $submit-attachment2.1nie sprawdzono za pomocą zewnętrznego narzędzia
Da Vinci Plan-Net1.1.0Inferno: 199 przejdź, 10 niepowodzeń (wada zestawu)
Da Vinci US Drug Formulary2.1.0walidator HL7
ISiK (niemieckie szpitale), serwer FHIRStufe 5, moduł podstawowyzestaw testowy ISiK gematik 3.0.9: 421 z 421
PACIO Transitions of Care, Medication Profile, Advance Directives, Functioning1.0.0, 1.0.0, 2.0.0-ballot, 2.0.0zestawy Inferno PACIO z danymi PACIO: każde niepowodzenie w danych lub zestawie. Dokument C-CDA do TOC: walidator HL7 na przykładach HL7, jeden błąd pozostał, własne
CARIN Blue Button2.2.0walidator HL7
eCR2.1.2walidator HL7
ELRHL7 2.5.1 ELR Release 1 z errataminarzędzie ELR ONC: 28 z 28
International Patient Summary2.0.0walidator HL7
DEQM5.0.0walidator HL7
SQL on FHIRv2oficjalny zestaw testowy: 144 z 144
SMART Health Cards i LinksKarty 1.4, Linki STU 1przykładowa karta specyfikacji; opublikowana biblioteka widoku SMART Health Links
UDAP SecuritySTU 1rzeczywisty serwer autoryzacji i społeczność zaufania
TEFCA Facilitated FHIRSOP v2.0nie sprawdzono przeciwko rzeczywistemu QHIN

1.3.3 Profile narodowe i europejskie

Sprawdzono przez konwersję opublikowanych lub wymyślonych wiadomości HL7 v2 i walidację każdego zasobu; pełne wyniki i powody każdego niepowodzenia znajdują się w folderze conformance/national repozytorium.

ProfilWersjaZasoby ważne
UK CoreSTU2 2.0.2185 z 187
FR Core2.2.0138 z 156
ISiK Basismodul4.0.3 (Stufe 4)18 z 47; 42 z 47 z własnym skryptem bundle szpitala
Nictiz nl-core0.12.1-beta.1 (zib 2020)12 z 24; 18 z 24 z własnym skryptem bundle szpitala
HL7 Europe Laboratory Report2.1.0106 z 426 (przewodnik oczekuje dokumentu, a wynik v2 nie jest)
HL7 Europe Hospital Discharge Report1.0.068 z 69

Żadne z powyższych nie jest certyfikacją. Perfuse nie został certyfikowany przez ONC, CMS, gematik, Nictiz, NHS England lub kogokolwiek innego.

1.4 Co zastępuje

Perfuse pokrywa obszar zajmowany przez Mirth Connect i może importować eksporty kanałów Mirth bezpośrednio. Rozdział o migracji opisuje, co przekłada się czysto, co wymaga decyzji oraz jak udowodnić, że wynik pasuje przed przełączeniem.

Różnice, które mają znaczenie w codziennym użyciu, to debugowanie i cisza. W Mirth, widzenie, co transformer zrobił z komunikatem, zwykle oznacza ponowne wdrożenie kanału z dodanym logowaniem. W Perfuse, każdy zarejestrowany komunikat może być odtworzony przez bieżącą konfigurację i zbadany krok po kroku, bez dotykania uruchomionego kanału. I tam, gdzie alert Mirth na „brak ruchu” jest stałym progiem, który jest bezużyteczny w przypadku każdego karmienia, które jest ciche w nocy, Perfuse uczy się, jaki wygląda normalny tydzień dla każdego karmienia, i alertuje przeciwko temu.

1.5 Jak czytać ten podręcznik

Pierwsze rozdziały są pojęciowe i warto je przeczytać w kolejności: kanały, przepływ komunikatów, a następnie transformacja. Wszystko, co następuje, może być czytane według potrzeby.

Rozdziały odniesienia znajdujące się pod koniec listują każdy klucz konfiguracyjny, jego typ, czy jest wymagany oraz jego wartość domyślną. Rozdziały te są generowane z kodu źródłowego, więc nie mogą opisywać opcji, które nie istnieją, ani pomijać tych, które istnieją. Jeśli klucz pojawia się w pliku konfiguracyjnym, ale nie w indeksie, to nie jest to klucz Perfuse.

1.6 Konwencje

Konfiguracja jest w formacie YAML. Większość kluczy jest w postaci snake_case w sieci — max_message_size, idle_timeout — i ten podręcznik zawsze podaje postać sieciową, ponieważ to jest to, co wpisujesz. Istnieje jeden długoletni wyjątek, dataType w kanale, który jest w postaci camelCase; jest on opisany w ten sposób w odniesieniu do kanału i akceptowany tylko w tym sposobie pisania.

Odwołania do pól w HL7 używają zwykłej notacji: PID-5 jest piątym polem segmentu PID, PID-5.1 jego pierwszym składnikiem, a PID-3(2) drugą powtórką trzeciego pola. Ścieżka napisana bez powtórki adresuje każdą powtórkę (patrz ścieżki).

Czas trwania jest zapisany jako liczba i jednostka — 30s, 5m, 2h. Goła liczba nie jest czasem trwania i zostanie odrzucona, zamiast próby jej odgadnięcia.

2 Wprowadzenie

Perfuse jest pojedynczym plikiem wykonywalnym z wbudowanym interfejsem sieciowym. Nie ma serwera aplikacji do zainstalowania, nie ma bazy danych do przygotowania i nie ma oddzielnego konsoli administracyjnej.

2.1 Uruchamianie

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

-channels to katalog plików YAML, po jednym dla każdego kanału. -db to plik SQLite zawierający zapisane wiadomości, użytkowników i historię inspekcji; jest tworzony, jeśli nie istnieje.

Podczas pierwszego uruchomienia bez skonfigurowanych użytkowników, tworzone jest konto administratora i jego hasło jest zapisywane w dzienniku raz. Hasło to nie może być później odzyskane.

Uruchamianie bez -tls-cert i -tls-key obsługuje zwykły HTTP. To jest dopuszczalne na adresie pętli zwrotnej dla pierwszego spojrzenia i nie jest dopuszczalne gdzie indziej: interfejs sieciowy zawiera poświadczenia i zawartość wiadomości, obie są czytelne w sieci bez TLS. Zobacz bezpieczeństwo.

2.2 Pierwszy kanał

Kanał potrzebuje nazwy, źródła i co najmniej jednego miejsca docelowego. Najmniejszy użyteczny kanał odbiera HL7 za pośrednictwem MLLP i zapisuje każdą wiadomość w pliku:

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

Zapisz to jako channels/first-feed.yaml i zostanie on automatycznie wykryty bez potrzeby ponownego uruchomienia.

Trzy rzeczy dotyczące tego pliku są warte zauważenia, ponieważ są one kształtem każdego kanału:

2.3 Tworzenie kanału z interfejsu

Wszystko powyższe można zrobić z interfejsu sieciowego zamiast, i dla pierwszego kanału jest to lepsza droga, ponieważ formularz nie pozwoli Ci wyprodukować pliku, który nie zostanie załadowany.

Budowniczy oferuje trzy sposoby wejścia:

  1. Z wiadomości, którą ktoś Ci wysłał. Wklej próbkę, którą laboratorium lub dostawca wysłał pocztą elektroniczną. Perfuse czyta ją i proponuje kanał, wraz z trzema oddzielnymi listami: to, co próbka pokazuje, to, co zostało zgadnięte, i to, czego żadna próbka nie może powiedzieć. To jest opisane w testowaniu.
  2. Z czegoś, co już działa. Zestaw kompletnych kanałów, które potrzebują tylko wypełnionych adresów.
  3. Z niczego. Pusty formularz. Dostępny, ale jest to najwolniejszy z trzech i najłatwiejszy do popełnienia błędu.

2.4 Weryfikowanie, czy działa przed podłączeniem czegokolwiek

Dwie rzeczy można zrobić przed istnieniem systemu wysyłającego.

Wyślij wiadomość ręcznie z interfejsu — nadawca wiadomości akceptuje wklejany tekst i raportuje, co się z nią stało, w tym, które miejsca docelowe ją zaakceptowały i co każda transformacja zrobiła.

Lub wygeneruj ruch testowy. Jeśli kanał obsłużył jakiekolwiek wiadomości, Perfuse może nauczyć się ich kształtu i wyprodukować więcej wiadomości podobnych do nich, w tych samych proporcjach, bez żadnej oryginalnej zawartości. Zobacz testowanie.

2.5 Co dalej

3 Interfejs sieciowy

Perfuse jest zbudowany na założeniu, że wszystko można zrobić z poziomu przeglądarki, a funkcja, która może być dostępna tylko przez edycję pliku, jest traktowana jako wada. Ten rozdział jest przewodnikiem po tym, co znajduje się za każdą częścią nawigacji, zorganizowanym w sposób, w jaki jest zorganizowany interfejs: według pytania, które zadajesz.

Pasek nawigacyjny zawiera Pulpit nawigacyjny i Kanały bezpośrednio, ponieważ to tam zaczynają się i kończą większość sesji. Wszystko inne jest pogrupowane, a grupy są nazwane według pytań, a nie według podsystemów — nie idziesz do „podsystemu audytu”, idziesz i dowiadujesz się, kto co zmienił.

3.1 Czytanie nagłówka

Pięć rzeczy w nagłówku jest łatwo przeoczyć.

Każdy widok ma adres. Pasek adresu podąża za widokiem — #/channels, #/messages, #/settings — więc przeładowanie powoduje powrót do niego, zakładka otwiera go, link wysłany do kolegi ląduje na nim, a przycisk wstecz przechodzi między widokami, zamiast opuszczać konsolę. Adres nazywający widok powyżej Twojej roli otwiera pulpity nawigacyjne zamiast.

Wyszukiwanie, lub ⌘K. Wyszukuje w kanałach, ustawieniach, wiadomościach i podręczniku, co oznacza, że zwykle jest szybsze niż nawigowanie — szczególnie w przypadku ustawienia, którego nazwę pół pamietasz.

Motyw. Trzy z nich: Midnight, Dark i Light. Midnight to prawie czarny i jest tym, czego zwykle potrzebuje wyświetlacz na ścianie w pomieszczeniu serwerowni; Dark to miękki neutralny szary; Light to dla laptopa obok okna. Wybór jest przechowywany w przeglądarce, a nie w stosunku do konta, ponieważ motyw jest właściwością miejsca, w którym ktoś siedzi, a nie kim są — ten sam operator chce Midnight na ścianie i Light w pociągu. Własna preferencja maszyny jest konsultowana raz, aby wybrać rozsądną wartość domyślną pierwszy raz.

Język. Konsola jest dostępna w języku angielskim (UK lub US porządek dat), niemieckim, francuskim, niderlandzkim, hiszpańskim, włoskim, portugalskim, polskim, szwedzkim, duńskim, norweskim lub fińskim, z datami i liczbami zapisanymi w sposób właściwy dla danego obszaru językowego. Wybór jest przechowywany w przeglądarce, a język przeglądarki jest używany do momentu wybrania innego. Tłumaczenia zostały wykonane przez maszynę i nie zostały jeszcze sprawdzone przez native speakerów; angielski jest językiem referencyjnym, a wybór języka informuje o tym. Kod, komunikaty, ładunki, nazwy kanałów i wszystko, co jest wpisywane, nigdy nie są tłumaczone. Podręcznik jest publikowany w tych samych językach pod adresem https://perfuse.health/manual/<language>/ (własna Dokumentacja tego serwera jest w języku angielskim).

Podręcznik. Dokument, który czytasz, obsługiwany przez uruchomiony serwer. Jest to ten sam plik, który binarny może zapisać na dysku, więc zawsze opisuje wersję przed Tobą, a nie najnowszy wydany.

3.2 Monitor — czy działa i co się stało

3.2.1 Pulpit nawigacyjny

Stan każdego kanału, przepływność i wszystko, co jest obecnie nie tak. To jest ekran, który powinien być otwarty.

3.2.2 Wiadomości

Każda wiadomość, która przybyła, w co została przekształcona, na każde miejsce przeznaczenia i co się z nią stało. Można wyszukiwać, w tym za pomocą wyrażenia filtrującego, więc „pokaż mi te od tego nadawcy, które zostały odrzucone” jest zapytaniem, a nie popołudniem.

Wiadomość można odtworzyć stąd i ponownie przetworzyć za pomocą *bieżącej* konfiguracji, a nie tej, która była aktywna w czasie, kiedy to zepsuło — co jest sposobem potwierdzenia, że naprawa działa przeciwko ruchowi, który ją złamał. Zobacz sklep wiadomości, aby dowiedzieć się, co jest przechowywane i przez jaki czas.

3.2.3 Kolejka

Co czeka na dostarczenie i dlaczego. Kolejka, która nie jest opróżniana, jest najbardziej przydatnym wczesnym ostrzeżeniem, jakie produkuje silnik integracji, i warto ją sparować z regułą alarmową, aby nikt nie musiał obserwować. Zobacz dostarczanie.

3.2.4 Alerty

Co się wydarzyło i jakie są reguły. Reguły są edytowane tutaj, a nie w pliku. Zobacz alarmowanie.

3.2.5 Mierniki

Przepływność, opóźnienia i wskaźniki błędów w czasie. Przydatne do pytań o pojemność i, częściej, do pakietów zarządu — co jest powodem, dla którego logo witryny pojawia się na nim, jeśli zostało przesłane.

3.2.6 SQL na FHIR

Widoki SQL na FHIR: wybierz przykład lub zapisany widok, lub napisz jeden, uruchom go na FHIR sklepie serwera (wszyscy pacjenci lub jeden) lub nad zasobami wklejanymi, zobacz wiersze z ich typami i pobierz CSV, NDJSON lub Parquet. Zapisz zachowuje go dla FHIR punktu końcowego $sql-run. Zobacz formaty wiadomości.

3.2.7 Miary jakości

Cyfrowe miary jakości: wybierz przykład lub Miarę w FHIR sklepie, lub napisz jeden z kryteriami FHIRPath. Wybierz okres pomiaru i raport (podsumowanie, podsumowanie z listami pacjentów lub jeden pacjent) i ocenij go nad FHIR sklepem lub wklejanymi zasobami. Ekran pokazuje liczbę każdej populacji i pacjentów, wynik i warstwy. Pobierz MeasureReport zapisuje FHIR wynik, a Zapisz do FHIR sklepu zachowuje Miarę dla Measure/$evaluate-measure. Miary w CQL są odrzucane: Perfuse nie ma silnika CQL. Zobacz cyfrowe miary jakości.

3.2.8 Mapa przepływu

Obraz tego, jak wiadomości naprawdę się poruszają: które źródła karmią które kanały, a które miejsca docelowe osiągają.

Jego wartość nie jest dekoracją. Każda własność gromadzi kanał, o którym nikt nie pamięta, i miejsce docelowe, o którym nikt nie zdawał sobie sprawy, że wciąż otrzymuje, i oba są widoczne tutaj w sposób, w jaki nie są widoczne na liście plików kanałów.

3.2.9 Pulpity zespołowe

Pulpit nawigacyjny dla każdego rodzaju osoby, która obserwuje interfejsy: Operacje, Połączenia, Analityk interfejsu, Upoważnienie, Obrazowanie, Cykl przychodu, Laboratoryjne, Prywatność i bezpieczeństwo, a także zwykły podsumowanie departamentu. Kafelki pokazują liczby, stany i czasy, nigdy wiadomości lub pacjenta, więc pulpit nawigacyjny może być wysłany do menedżera lub wyświetlony na ekranie bez zwiększania liczby osób, które mają dostęp do danych pacjentów.

Każda osoba otwiera pulpit swojej grupy katalogowej lub roli. -dashboards dashboards.yaml mapuje je:

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

Grupa wygrywa nad rolą, a każdy niezgodny otwiera się na Operacje. Układ kafelków ukrywa i ponownie układa kafelki, wybór kanału filtruje je, a Zapisz jako mój widok zachowuje go jako własny pulpit nawigacyjny do momentu Reset.

Eksport do Grafana pobiera pulpit nawigacyjny jako JSON Grafana za pomocą /metrics, z zmienną źródła danych i filtrem kanału, dla wszystkich, którzy potrzebują więcej niż lekka konfiguracja. Każdy kafelek bez metryki za nim zostaje pominięty, a opis eksportu nazwa ich.

Kafelka Połączenia sprawdza każde sieciowe miejsce docelowe w warstwach. Wyszukuje nazwę, otwiera połączenie TCP, ukończa TLS, gdzie jest używany, i czyta ostatnią dostawę i awarię z rzeczywistego ruchu. Każda awaria mówi, co to znaczy, na przykład „odrzucony: silnik partnera jest prawdopodobnie zatrzymany”, „przekroczony limit czasu: zapora sieciowa lub tunel VPN, który jest wyłączony” lub „certyfikat z urzędu, którego ten serwer nie ufa”. Nic nie jest wysyłane do partnera, z jednym wyjątkiem: rejestr immunizacji, który nie miał ruchu przez siedem dni, jest pytany o CDC connectivityTest, który niczego nie wysyła. Z -vpn tunnels.yaml kafelka Tunele VPN obok niego czyta stan każdego partnera tunelu z AWS Site-to-Site VPN, połączenia bramy VPN Azure lub strongSwan na tym hoście, więc limit czasu może być odróżniony od tunelu, który jest wyłączony. Porównuje również obie strony IKE i ustawienia IPsec, ponieważ chmura raportuje nasze, a plik wymienia ich, i mówi, gdzie nie mogą się zgodzić. Arkusz połączenia pobiera ustawienia partnera obok siebie jako Markdown, aby je wysłać; nigdy nie zawiera współdzielonego klucza. Dane, które pulpit nawigacyjny potrzebuje, które jeszcze nie są rejestrowane, są wymienione pod Nie mierzone jeszcze zamiast rysowania pustych kafelków.

Pulpity departamentowe obliczają własne dane na serwerze, a każdy z nich mówi, jakie okno i źródło obejmuje:

3.2.10 Udostępnianie tego, co zawiera naprawdę kanał

Profiluj ten kanał raportuje, co naprawdę przychodzi: które wydarzenia wyzwalające, które pola są wypełnione i jak często, jakie kształty mają wartości, oraz które kody nadawca naprawdę używa. Ostatni z nich jest zwykle najbardziej przydatnym pojedynczym faktem w nim.

Profil może być pobrany i wysłany do kogoś innego. Potrzebuje nazwy i — wymagane — które system wyprodukował kanał, ponieważ pytanie, które obcy pyta o udostępniony profil, brzmi, czy opisuje ich system, a pole opcjonalne sprawiłoby, że „Nieznany” byłby najczęstszą odpowiedzią w każdej udostępnionej kolekcji.

Nie zawiera danych pacjentów, i jest to sprawdzane, a nie założone. Profil jest statystyczny: liczby, stawki, długości, kształty. Wartości są przechowywane tylko dla pól, które standard definiuje jako tabele kodów, ponieważ wartość tabeli kodów nie jest identyfikująca. Wartości identyfikatorów są nigdy nie wymienione.

Dwie rzeczy wynikają z tego, że jest to obietnica, a nie nadzieja. Serwer odbudowuje profil z przechowywanych wiadomości podczas eksportu, zamiast wysyłać ten, który jest na Twoim ekranie — więc to, co opuszcza budynek, zostało zmontowane przez profiler, który ma test potwierdzający tę właściwość, a nie przez przeglądarkę. A eksport odmawia całkowicie, jeśli profil kiedykolwiek wymienia wartości dla pola, które nie jest tabelą kodów, nazywając pole, ale nie wartości.

Profil, który przychodzi z innego miejsca, jest sprawdzany w ten sam sposób podczas importu, z innego powodu: został wyprodukowany przez kogoś, kogo staranność jest nieznana, a pokazywanie identyfikatorów pacjentów byłoby ujawnieniem przez ten serwer. Importowanie go nie zmienia nic — profil opisuje kanał, a to, co z nim zrobić, to oddzielna decyzja.

3.3 Kompiluj — zmień to, co robi kanał, i przetestuj to przed uruchomieniem

3.3.1 Kanały

Budowniczy kanałów. Źródła, miejsca docelowe, filtry, transformacje, skrypty i testy, z wygenerowanym YAML wyświetlanym obok formularza podczas pracy — więc plik nigdy nie jest tajemnicą, a każdy, kto woli plik, może czytać wraz z nim.

Zobacz kanały, aby dowiedzieć się, z czego składają się części, oraz transformacja, aby dowiedzieć się, co robią kroki.

3.3.2 Skrypty

Stacja robocza dla skryptów, oddzielna od budowniczego, ponieważ pisanie skryptu i podłączanie skryptu to różne czynności.

Wszystkie siedem slotów jest oferowanych — filtr, transformatory, preprocesor, postprocesor, zapisywacz, cykl życia i czytelnik — i wybór odpowiedniego slotu ma znaczenie, ponieważ slot decyduje o tym, co skrypt otrzymuje i co ma zwrócić. Sprawdzanie skryptu jako niewłaściwego typu nie jest obejściem; kompiluje ono inną rzecz.

Dostępne są JavaScript, Lua i WebAssembly. Zobacz transformacja.

3.3.3 Umowy

Oczekiwania dotyczące wyglądu kanału, utworzone i sprawdzone tutaj, a także z perfuse contract. Zobacz wiersz polecenia.

3.3.4 Tabele

Tabele odniesienia i zestawy kodów: mapowania, które przekształcają kody jednego systemu w kody innego. Edytowalne tutaj, aby dodanie kodu nie było wdrożeniem.

3.3.5 Maper AI

Proponuje mapowania pól z oceną ufności dla każdego, i wstrzymuje się od zgadywania. Pomimo nazwy nie używa modelu językowego i nie wykonuje połączenia sieciowego: sugestie pochodzą z reguł, nazw pól i zawartości próbki, na tym serwerze. Proponuje również kanał z jednej próbki wiadomości i stwierdza wyraźnie, czego próbka nie może mu powiedzieć. Ta druga część jest częścią, która czyni ją godną zaufania — propozycja, która wygląda na kompletną, zachęca do uwierzenia w rzeczy, których wiadomość nigdy nie powiedziała.

3.3.6 Place zabaw

Miejsce do testowania wiadomości i transformacji. Wklej wiadomość, zastosuj kroki, zobacz wynik.

Nic nie jest wysyłane nigdzie po załadowaniu strony, co jest powodem, dla którego istnieje w tej formie: jest bezpieczne wklejanie czegoś rzeczywistego, z zastrzeżeniem, że pozostaje w przeglądarce.

3.3.7 Cień

Uruchamia ruch przez kandydującą konfigurację obok żywej i raportuje różnice, aby zmiana mogła być udowodniona przed zaufaniem. Ten sam pomysł co perfuse compare, zastosowany do zmiany, a nie do migracji. Zobacz testowanie.

3.4 Wymiana — standardy, których ten serwer używa do komunikacji z innymi organizacjami

3.4.1 Laboratorium FHIR

Przekonwertuj HL7 v2 na FHIR, zwaliduj zasób i zbadaj wynik. Próbki obejmują przyjęcia, wyniki laboratoryjne, spotkania, notatki kliniczne, szczepienia i wizytę, która może być zgłoszona. Walidacja obejmuje US Core, który jest profilem, przeciwko któremu amerykańskie regulacje są pisane, więc to odpowiada na pytanie „czy to, co do nas wysłano, jest naprawdę zgodne” bez przyjęcia czegokolwiek.

Raport przypadku zdrowia publicznego tworzy eCR eICR, który destination case reporting wysyła dla wiadomości. Pokazuje, jaki kod wyzwolenia sprawił, że wizyta była zgłaszana, co raport musiał oznaczyć jako brakujące, i sam dokument. Wiadomość z niczym niezgłaszanym otrzymuje powód zamiast tego. Nic nie jest wysyłane stąd.

3.4.2 Subskrypcje

Subskrypcje FHIR oraz czy ich powiadomienia są dostarczane: zdarzenia, zaakceptowane, oczekujące oraz ostatni powód odrzucenia. Subskrypcje są tworzone przez klientów FHIR za pomocą interfejsu API FHIR, a nie z tej strony, i poświadczenia, które podali serwerowi, nigdy nie są wyświetlane. Zobacz formaty wiadomości.

3.4.3 Dokumenty

Dokumenty kliniczne — CDA i drukowalna forma dokumentu. Przydatne, gdy wymieniany obiekt jest podsumowaniem wypisu, a nie wiadomością.

3.4.4 Udostępnianie dokumentów

Rejestr i repozytorium IHE XDS.b uruchomione z -xds: ile dokumentów, pacjentów i zestawów przesłanych zawiera i ile zostało zastąpionych; adresy repozytorium, rejestru, bramy XCA i MHD; wyszukiwanie dokumentów pacjenta w tym rejestrze lub innym (rejestr ITI-18 lub brama ITI-38, z tokenem dla niego); oraz publikowanie dokumentu CDA ręcznie, z typem placówki i ustawieniami praktyki, które dokument nie mówi. Zobacz formaty wiadomości.

3.4.5 Bezpośrednie

Bezpośrednia komunikacja zabezpieczona. Adresy Direct tego serwera wyświetlają każdy adres, który kanał wysyła lub otrzymuje, wraz z certyfikatem, datą wygaśnięcia, zaufanymi kotwicami oraz wszelkimi błędami (brakujący plik, wygasły certyfikat). Książka adresowa przechowuje korespondentów oraz certyfikaty, do których ich poczta jest szyfrowana: wklej jeden z ich HISP lub Zapisz z certyfikatem z DNS; certyfikat, który nie jest dla adresu lub jego domeny, jest odrzucany. Znajdź certyfikat w DNS pyta bez zapisywania. Zobacz formaty wiadomości.

SMART Health Links i Karty, dla *Zabij klipboard* CMS. Odbierz link SMART Health odczytuje link lub kod QR, który pacjent pokazuje podczas zapisu, weryfikuje karty zdrowia w środku i wysyła dalej do kanału. Udostępnij rekord wizyty tworzy link, który jest hostowany przez ten serwer, opcjonalnie z kodem dostępu, oraz kod QR dla pacjenta; Użyj podsumowania pacjenta wypełnia je podsumowaniem pacjenta z Międzynarodowego podsumowania pacjenta z magazynu FHIR tego serwera. Linki hostowane przez ten serwer wyświetlają je wraz z częstotliwością, z jaką każdy z nich został pobrany, datą wygaśnięcia oraz liczbą pozostałych prób kodu dostępu, oraz odwołuje jeden. Weryfikuj kartę SMART Health sprawdza podpis i wystawcę karty we własnym zakresie. Zobacz CMS-0057 dla opcji serwera, których potrzebuje.

3.4.7 Obrazowanie

Archiwum, które ten serwer przechowuje podczas uruchamiania z -dicomweb-archive: liczby badań, serii, przypadków i używanego miejsca, adres DICOMweb oraz blok danych dla widoku OHIF, oraz wyszukiwanie badań według nazwy pacjenta, identyfikatora, numeru przyjęcia i daty utworzonego przy użyciu tego samego żądania QIDO-RS, jakiego używa widok. Badanie otwiera się do serii i przypadków, a przypadki pobierane są jako pliki DICOM. Nic nie jest renderowane: Perfuse przenosi obrazy, a widok je wyświetla. Bez archiwum ekran wyświetla informację, jak je włączyć. Zobacz DICOMweb.

3.4.8 TEFCA

Ślad audytowy dla wymiany za pośrednictwem Kwalifikowanej Sieci Informacji o Zdrowiu oraz reguły celu użycia, które ją regulują.

Dwa transporty, które znajdują się w różnych fazach, a ekran wyświetla, który z nich jest który. Jeden flaga obejmujący oba byłby błędny w którąkolwiek stronę, w którą był zaokrąglony.

Zaimplementowano ułatwiony FHIR, który nigdy nie komunikował się z prawdziwą QHIN. Postępuje zgodnie z procedurą operacyjną Sequoia Project obowiązującą od 8 marca 2026: odkryj metadane partnera UDAP, zweryfikuj je, zarejestruj się dynamicznie, uzyskaj token dostępu zawierający cel użycia oraz wykonaj zapytanie. UDAP jest infrastrukturą kluczy publicznych nad OAuth 2.0 — społeczność zaufania wydaje certyfikaty X.509 swoim członkom, a członek uwierzytelnia się, podpisując JWT za pomocą klucza prywatnego i dołączając łańcuch certyfikatów.

Warstwa zabezpieczeń jest weryfikowana w stosunku do implementacji kogoś innego, co jest jedyną weryfikacją, która ma tu jakiekolwiek znaczenie. Rejestracja podpisana przez tę wersję została wysłana do żywej serwera referencyjnego i odrzucona z unapproved_software_statement — Untrusted: Certificate is not a member of community. Aby wyprodukować tę odpowiedź, serwer odkodował żądanie, sparsował oświadczenie oprogramowania jako JWT, sprawdził jego podpis, przeanalizował łańcuch certyfikatów i podjął decyzję o członkostwie. To jest różnica między zostaniem odrzuconym u drzwi a otrzymaniem nieczytelnej wiadomości.

To, co pozostaje, nie może być wykonane stąd. Certyfikat, który dowodzi członkostwa w społeczności, pochodzi z procesu QHIN onboarding i nie jest czymś, co produkuje oprogramowanie. Dopóki nie istnieje, żadna wymiana z prawdziwym partnerem nie zostanie ukończona.

W jaki sposób kanał pyta. Miejsce docelowe typu tefca pyta o zestaw partnerów FHIR w ustawieniach Ustawienia, TEFCA (tefca.partnerFHIRBase) dla każdego pacjenta w wiadomości: przez identyfikator, gdy wiadomość go posiada (PID-3 lub identyfikator pacjenta FHIR), w przeciwnym razie przez nazwisko z datą urodzenia, a nigdy samą nazwę, ponieważ błędne dopasowanie nazwy zwraca rekord kogoś innego bez błędu. Miejsce docelowe ustawia cel użycia (leczenie, płatność, operacje, zdrowie publiczne, dostęp indywidualny); cel, którego uczestnik nie deklaruje, jest odrzucany przed wysłaniem czegokolwiek. Cele są przekazywane jako kody celu wymiany TEFCA (T-TRTMNT, T-PYMNT, T-HCO, T-PH, T-IAS, system urn:oid:2.16.840.1.113883.3.7204.1.5.2.1), lub z tefca.purposeCodes: hl7 jako kody celu użycia HL7 dla społeczności, które je używają. Znaleziony pakiet jest odpowiedzią miejsca docelowego i może być przekazany do innego kanału za pomocą results_to. Każde zapytanie, w tym odrzucone, jest rejestrowane w śladzie na tym ekranie, który nazywa partnera.

Cała ścieżka, od odkrycia do tokenu, który serwer FHIR partnera akceptuje, jest testowana w stosunku do serwera referencyjnego udap-dotnet (patrz weryfikacja).

Starszy exchange QHIN-to-QHIN zbudowany na profilach IHE nie jest zaimplementowany. Próba jest odrzucana z błędem, który tak mówi, a odrzucenie jest rejestrowane jako niepowodzenie. To jest celowe, a nie oczekujące na porządne rozwiązanie: zablokowana wymiana zgłaszająca sukces umieściłaby wpisy w śladzie audytowym dla wymian, które nigdy nie miały miejsca, a ślad, który nie zgadza się z tym, co się wydarzyło, jest gorszy niż żaden, ponieważ ślad jest tym, co jest wierzone.

Na przestrzeni całego, punkty końcowe używane do wymiany pochodzą z podpisanej części metadanych partnera, a nie z ciała dokumentu. Weryfikacja podpisu, a następnie odczytanie punktów końcowych z niepodpisanej kopii byłaby skomplikowanym sposobem zaufania sieci: atakujący, który może przepisać odpowiedź, pozostawia element podpisany, wskazuje punkt tokenu na własny serwer i zbiera asercje klienta od wszystkich, którzy sprawdzili podpis i potem zignorowali to, co obejmował.

Pakiet kotwicy zaufania jest wymagany, a jego brak jest odrzucany podczas uruchamiania. Sprawdzenie podpisanego metadanych partnera przeciwko certyfikatowi, który przybył wraz z nim, dowodzi tylko tego, że jedna strona utworzyła oba — błąd, który został popełniony wcześniej w SAML, gdzie weryfikator wolał certyfikat osadzony i uwierzytelnił atakującego jako administratora, podczas gdy wszystkie testy przeszły pomyślnie. Dołącz pośrednie do pakietu: serwer UDAP musi wysłać tylko swój certyfikat liścia, a publiczny serwer referencyjny robi dokładnie to.

3.5 Płatnicy — roszczenia, uprzednie autoryzacje, leki i reguły płatnika CMS

3.5.1 Roszczenia i autoryzacje

Utwórz załącznik roszczenia X12 275 w formie 006020, którą CMS-0053-F przyjmuje, z wklejonej C-CDA lub przesłanego pliku PDF, TIFF lub JPEG, i zobacz, jak jest odczytywany. Przeczytaj 275 i pobierz dokument wewnątrz. Przekonwertuj decyzję X12 278 na odpowiedź Da Vinci PAS ClaimResponse. Nic na tej stronie nie jest przechowywane ani wysyłane. Zobacz formaty wiadomości, aby dowiedzieć się, z czego jest zbudowany 275 i co nie robi.

3.5.2 Leki

Formularz leków załadowany z -formulary oraz dwa standardy NCPDP odpowiedzi z niego. Formularz wyświetla plany i leki wraz z poziomem i wymaganiami, oraz gdzie znajdują się publiczne API Da Vinci US Drug Formulary i punkty końcowe NCPDP. Sprawdź cenę (RTPB) ustala cenę leku dla członka jako żądanie Real-Time Prescription Benefit wystawcy: status pokrycia, ograniczenia w słowach z kodami, udział członka i planu, oraz tańsze alternatywy. Autoryzacja wcześniej (ePA) wysyła inicjację SCRIPT do własnego punktu końcowego serwera, wyświetla zestaw pytań jako formularz, wysyła odpowiedzi i wyświetla decyzję; poniżej, każdy przypadek z informacjami o stanie i czy wystawca został poinformowany, odpowiedzi przypadku, przycisk do ponownego wysłania niewysłanej decyzji oraz liczby leków, które proponuje CMS-0062-P. Zobacz CMS-0057.

3.5.3 CMS-0057

Strona płatnika reguły interoperacyjności i uprzedniej autoryzacji CMS, jako pięć narzędzi:

oraz co jeszcze potrzebują każde z nich.

poświadczyć mniej jednostek. Zobacz kolejkę do sprawdzenia.

Przekonwertowane dane nie są przechowywane ani wysyłane.

3.5.4 Sieć wyrównana z CMS

Gotowość do ram interoperacyjności CMS: każdy z 26 kryteriów, pogrupowanych tak, jak je grupuje CMS, z tym, co Perfuse zapewnia, czy jest włączone, ustawienie, które je włącza, oraz co należy do organizacji. Liczby na górze filtrowania listy. Zobacz CMS-0057.

3.6 Administruj — kto może co zrobić i jak jest skonfigurowany ten serwer

3.6.1 Użytkownicy

Konta, role (monitor, viewer, operator, editor, admin) i grupy kanałów. Każda osoba ma grupy kanałów edytowane w miejscu na liście; pusty oznacza każdy kanał, a lab=editor, adt daje inną rolę w jednej grupie. Administrator ograniczony do niektórych grup widzi tylko osoby z tych grup. Nagłówek pokazuje Twoje własne grupy obok Twojej roli, gdy masz jakąś. Zobacz bezpieczeństwo.

Poświadczenia maszynowe są również tutaj. Token jest dla maszyny, a nie dla osoby: nie wygasa i nie jest wpływany przez nikogo, kto się wyloguje, co jest potrzebne serwerowi, który sonduje swojego sąsiada. Przechowuje się tylko skrót, więc token jest wyświetlany tylko raz, gdy jest tworzony i nie może być odzyskany — skradziony zestaw danych nie daje żadnego użytecznego tokenu. Nadaj mu najniższą rolę, która robi to, co potrzebne.

Z włączonym MCP, sekcja ta wyświetla również adres, do którego łączy się agent AI, konfigurację klienta do skopiowania i każde narzędzie z rolą, której potrzebuje; wydanie tokenu z Pozwól agentowi AI działać z nim daje mu zakres mcp:write. Zobacz bezpieczeństwo.

3.6.2 Najemcy

Na serwerze współdzielonym, lista operatora platformy organizacji: każda z nich ma liczbę kanałów i przechowywanej wielkości obok limitów (kanały, wiadomości na minutę, przechowywanie), które są ustawiane w miejscu. Wyświetlane tylko dla roli platformy. Zobacz bezpieczeństwo dla informacji o tym, co robi każdy limit.

3.6.3 Certyfikaty

Certyfikaty TLS w użyciu i kiedy wygasają. Daty wygaśnięcia są punktem: certyfikat, który wygasł w niedzielę, jest klasą awarii, która jest całkowicie możliwa do uniknięcia i rutynowo nie jest unikana.

3.6.4 Aktywność

Kto zmienił co i kiedy. Każda zmiana konfiguracji jest rejestrowana, co pozwala odpowiedzieć na pytanie "zaczęło się to dziać we wtorek".

3.6.5 Ochrona danych

Żądania osoby zgodnie z RODO i brytyjskim RODO, przechowywanie danych, rejestry kasowania, przechowywanie i rejestr działań przetwarzania; tylko administratorzy. Zobacz ochronę danych.

3.6.6 Flota

Każda instancja Perfuse na jednej stronie.

Mirth sprzedaje to jako odrębny produkt; tutaj jest to plik konfiguracyjny i token tylko do odczytu. Powód, dla którego warto go posiadać, jest wąski i ważny: zablokowany serwer nie wygląda jak cichy. Pulpit jednej instancji nie może powiedzieć, że drugi serwer przestał raportować, a widok floty również nie.

3.6.7 Migruj

Upuść eksport kanału Mirth lub OIE i zobacz, ile Twoich kanałów działałoby tutaj bez zmian. Ta sama analiza, co perfuse explain i perfuse translate, bez potrzeby terminala. Zobacz migrację.

3.6.8 Ustawienia

Każde ustawienie serwera, z kontrolką dla każdego — w tym te, które tradycyjnie znajdują się tylko w pliku. Każde z nich wskazuje, czy zaczyna obowiązywać natychmiast, czy wymaga ponownego uruchomienia, oraz czy zostało ustawione jawnie, czy pozostaje na wartości domyślnej.

Ustawienia obejmują każdą opcję perfuse serve, która włącza funkcję: punkt końcowy FHIR i jego wersję, API płatników, PAS i reguły CRD, mostek X12 278, eCR, serwer autoryzacji SMART, TLS i podpisywanie, metryki, flotę i VPN. Są one pogrupowane jako FHIR, Płatnicy, Zdrowie publiczne, SMART, Bezpieczeństwo itd. Każda z nich jest również wyświetlana z flagą, do której odpowiada.

Uruchamianie ponownie z konsoli. Ustawienie oznaczone jako *Wymaga ponownego uruchomienia* jest zapisywane natychmiast, ale odczytywane tylko podczas uruchamiania serwera. Podczas gdy jakiekolwiek z nich czekają, baner na górze Ustawień wyświetla je wraz z przyciskiem Uruchom ponownie serwer (edycja logowania i pliki ustawień oferują ten sam przycisk po zapisie). Pyta najpierw, ponieważ każdy kanał zatrzymuje się na kilka sekund: każdy kończy wiadomość, którą obsługuje, tak jak robi to podczas zatrzymywania usługi, a nadawcy ponownie wysyłają wszystko, co przychodzi tymczasem. Konsola następnie czeka, aż serwer odpowie ponownie i odczyta ustawienia na nowo. Tylko administrator może uruchomić ponownie, a każde ponowne uruchomienie jest rejestrowane w dzienniku aktywności jako server.restart.

W systemie Linux i macOS proces zastępuje się świeżą kopią tego samego programu i argumentów, zachowując identyfikator procesu, więc systemd, launchd lub środowisko uruchomieniowe kontenera nie zauważa niczego. W systemie Windows serwer uruchamia się ponownie w tym samym procesie, który zachowuje usługę systemu Windows pod menedżerem usług. Jeśli serwer nie odpowiedział po dwóch minutach, konsola mówi o tym; powodem jest log serwera.

Flagi i plik ustawień. Pierwszy raz, gdy serwer uruchamia się, flagi, które otrzymał, są zapisywane w pliku ustawień. Od tego momentu plik ma pierwszeństwo przed flagami, więc zmiana ustawienia jest wykonywana w konsoli (lub w pliku), a nie przez edycję polecenia usługi. Flagę, której plik jeszcze nie wymienia, zapisuje się, gdy serwer uruchamia się z nią. Usunięcie flagi z polecenia w późniejszym czasie nie wyłącza jej funkcjonalności: należy ją wyłączyć w Ustawieniach.

SNMP ma panel poniżej ustawień: czy agent odpowiada i na jakim adresie, sieci, które obsługuje, ile alertów trap zostało wysłanych lub nie powiodło się, oraz Pobierz MIB dla bieżącego OID. Wartości są ustawiane w Monitorowaniu, SNMP.

Marka jest również tutaj: witryna może ustawić nazwę produktu, hasło, kolor akcentu i przesłać logo. Logo pojawia się następnie w nagłówku, na stronie logowania, na pulpicie i na ekranach raportowania. Jeśli nie zostanie przesłane logo, nic nie zostanie podmienione — niezmarkowana instalacja pozostaje niezmarkowana, zamiast nabyć dekorację.

3.7 Co oznaczają kolory

Cztery rejestry, a każdy mówi coś innego. Różnica jest warta podkreślenia, ponieważ jest to różnica między ekranem, który można przeczytać na pierwszy rzut oka, a tym, na którym wszystko konkurowało o uwagę.

Zwykły tekst jest faktem dotyczącym sposobu, w jaki działa Perfuse. Większość interfejsu. Nic nie jest pokolorowane, aby powiedzieć, że jest ważne.

Zielony oznacza, że coś się powiodło właśnie teraz, dzięki czemuś, co zrobiłeś. Pojawia się po akcji i nie utrzymuje się.

Bursztynowy jest ostrzeżeniem: wartym wiedzy przed podjęciem działania, a nie błędem. Funkcja, która nie jest włączona, ustawienie, którego zmiany są audytowane, konwersja, która przybliża raczej niż odtwarza, transport, który Perfuse obsługuje, ale nie może w pełni zweryfikować. Bursztynowy jest kolorem "przeczytaj to, zanim kontynuujesz".

Czerwony oznacza, że coś jest nie tak w tym momencie. Wartość, która została odrzucona, żądanie, które nie powiodło się, certyfikat, który wygasł, krytyczny alert, który jest uruchomiony. Nic innego nie używa go.

Dlatego ostatnia reguła jest taka, że ekran nie otwiera się na czerwono. Czerwony jest jedynym kolorem, który niesie instrukcję — zatrzymaj się, i może to być coś, co zrobiłeś — a ekran, który wydaje go na dekorację, nie ma nic do powiedzenia, gdy wprowadzony tekst jest naprawdę niepoprawny. Nie zawsze tak było: ekran użytkownika kiedyś otwierał się z "serwer wysłał odpowiedź, której nie można było odczytać" na każdej instalacji, która nie skonfigurowała passkey, a ekran ustawień oznaczał wartości audytowane tym samym kolorem, co odrzucony. Test w web/src/RedMeansWrong.test.ts teraz kończy się niepowodzeniem, jeśli fraza opisująca coś nieobecnego lub przybliżonego jest podana w stylu czerwonym.

Wewnątrz pola kodu słownictwo jest inne. Tam czerwony jest typem tokenu — nazwą segmentu HL7, elementem XML — i nie niesie żadnego osądu w ogóle.

4 Kanały

Kanał jest jednym przepływem wiadomości: skąd pochodzą, opcjonalne zmiany i jeden lub więcej miejsc, do których trafiają. Jest to jednostka konfiguracji, jednostka monitorowania i jednostka wdrożenia. Wszystko inne w Perfuse istnieje, aby służyć kanałom.

4.1 Anatomia

Plik kanału składa się z następujących części, w kolejności, w jakiej są stosowane:

CzęśćKluczWymaganyCo robi
TożsamośćnametakNadaje nazwę kanałowi. Musi być unikalna.
Typ danychdataTypenieOkreśla, jak parsować wiadomości. Domyślnie jest to HL7 v2.
ŹródłosourcetakOkreśla, skąd pochodzą wiadomości. Dokładnie jeden.
FiltrowaniefilternieDecyduje, które wiadomości zaakceptować.
PrzekształceniatransformationsnieUporządkowane zmiany w wiadomości.
Miejsca docelowedestinationstakOkreśla, gdzie trafiają wiadomości. Jeden lub więcej.

Oprócz tego istnieją części, które mają zastosowanie do całego kanału: scripts, shadow, contract, tables, attachments, group i enabled. Każda z nich jest opisana w dokumentacji kanału.

4.2 Jedno źródło, wiele miejsc docelowych

Ta asymetria jest zamierzona i warto ją zrozumieć na początku, ponieważ jest to najczęstsze źródło nieporozumień, gdy przychodzi się z innego silnika.

Kanał ma dokładnie jedno źródło. Jeśli wiadomości pochodzą z dwóch miejsc, to są to dwa kanały. Próba wyrażenia tego jako jeden kanał powoduje utworzenie konfiguracji, w której awaria w którymkolwiek transporcie wygląda tak samo z zewnątrz, a ruch z dwóch kanałów jest mieszany w statystykach — więc spadek w jednym jest ukryty przez drugi.

Kanał ma dowolną liczbę miejsc docelowych, a są one niezależne. Awaria jednego nie powoduje zatrzymania innych, a każde ma własną kolejkę, własną politykę ponawiania i własny rekord dostarczania. Wiadomość, która dotarła do trzech z czterech miejsc docelowych, jest rejestrowana jako dokładnie taka, a nie jako sukces lub porażka.

4.3 Miejsca docelowe nie tworzą łańcucha

Każde miejsce docelowe otrzymuje wiadomość w postaci, w jakiej była po przekształceniach kanału. Miejsce docelowe nie otrzymuje wyjścia z poprzedniego miejsca docelowego.

To ma znaczenie, gdy miejsce docelowe ma własne przekształcenia, co może się zdarzyć. Przekształcenia te są stosowane tylko do kopii tego miejsca docelowego. Częstym błędem jest umieszczenie zmiany w pierwszym miejscu docelowym i oczekiwanie, że drugie je zobaczy.

Jeśli naprawdę potrzebujesz łańcucha — wyjście jednego przepływu zasilającego inny — użyj miejsca docelowego kanału, które wysyła do innego kanału o nazwie. To jest jawne, pojawia się w historii wiadomości jako dwa kanały i może być monitorowane jako dwie rzeczy, co ukryty łańcuch nie może.

4.4 Nazewnictwo

Nazwa jest tożsamością kanału wszędzie: w pliku, w magazynie wiadomości, w alertach, w rejestrze inspekcji i w adresie URL. Zmiana jej nie jest przemianowaniem; jest to nowy kanał, a historia starego kanału pozostaje pod starym nazwą.

group jest oddzielnym elementem i służy do organizowania interfejsu. Grupa nie ma wpływu na zachowanie, a grupowanie kanałów nie powoduje, że dzielą one coś.

W wdrożeniu wielofunkcyjnym umieść obiekt w nazwie, a nie tylko w grupie. Wdrożenia Mirth na kilku stronach niezawodnie dryfują do niezgodnego nazewnictwa, a moment, w którym staje się to bolesne, jest incydentem o drugiej w nocy, gdzie lista kanałów ma cztery elementy o nazwie adt-inbound.

4.5 Włączanie i wyłączanie

enabled: false zatrzymuje uruchomienie kanału bez jego usunięcia. Jego konfiguracja, historia i statystyki pozostają.

Wyłączony kanał nie jest wstrzymany. Jego źródło nie nasłuchuje, więc nadawca próbujący połączyć się otrzymuje odmowę połączenia, a nie zawieszone połączenie. Dla MLLP jest to prawidłowe zachowanie — nadawca będzie buforował i ponawiał — ale oznacza to, że log błędów nadawcy wypełni się, więc wyłączony kanał nie jest zamiennikiem zaaranżowania przerwy z kimś, kto wysyła.

4.6 Gdzie znajdują się kanały

Jeden plik YAML na kanał, w katalogu podanym przez -channels. Nazwa pliku nie jest nazwą kanału; klucz name jest. Zalecane jest trzymanie ich takich samych, a nic nie egzekwuje tego.

Pliki są odczytywane ponownie bez restartu. Plik, który nie jest w stanie sparsować, jest zgłaszany, a poprzednio załadowana wersja nadal działa, więc błąd składniowy nie może wyłączyć działającego kanału.

Kanał edytowany w interfejsie sieciowym jest zapisywany z powrotem do swojego pliku. Jeśli pliki te są w kontroli wersji — co jest zalecane — oczekuj commitów z zmian konfiguracyjnych dokonanych za pośrednictwem interfejsu, a nie edytuj ręcznie pliku w tym samym czasie, gdy ktoś ma go otwarty w budowniczym.

4.7 Szyfrowanie własnego nasłuchiwania kanału

Kanał, który nasłuchuje na porcie, jest własnym serwerem, a jego TLS jest oddzielony od TLS w interfejsie sieciowym Perfuse. Ustawienie jednego nie ustawia drugiego. Dla źródła HTTP ustawienia znajdują się pod TLS i limity w źródle.

Włączenie TLS wymaga podania certyfikatu i klucza prywatnego. Wymaganie certyfikatu klienta powoduje, że staje się to mutualne TLS: nadawca musi przedstawić certyfikat podpisany przez wskazaną władzę, co jest uwierzytelnieniem, więc odbiornik z włączoną funkcją nie potrzebuje również współdzielonego tokenu — choć posiadanie obu nie jest błędem.

Władza jest pytana tylko raz, gdy certyfikat klienta jest wymagany, i jest pomijana w pliku do tego czasu. Kanał nazywający władzę, która nie jest konsultowana, wygląda tak, jakby nadawcy byli weryfikowani, gdy tak nie jest.

Odbiornik MLLP ma te same ustawienia pod Szyfruj ten odbiornik, z jedną różnicą wartą wymienienia: w MLLP certyfikat klienta jest jedyną dostępną metodą uwierzytelnienia. Nie ma tokenu ani nagłówka, więc odbiornik bez niego akceptuje wiadomości z dowolnego hosta, który może dotrzeć do portu.

Dwa limity znajdują się obok niego. Przestań czytać po określonym czasie, ponieważ nadawca, który otwiera połączenie i przestaje pisać, w przeciwnym razie utrzymuje połączenie otwarte. I największa zaakceptowana wiadomość, w bajtach, ponieważ zero oznacza brak limitu, a limit jest wtedy pamięcią — nadawca, który publikuje gigabajt, jest odrzucany, zamiast być pochłonięty.

4.8 Walidacja

Kanał jest sprawdzany, gdy się ładuje, a sprawdzenia są odmowami, a nie ostrzeżeniami, gdzie alternatywą byłoby uruchomienie kanału, który działa i robi coś złego.

Przykłady rzeczy, które są odrzucane bezwzględnie: miejsce przeznaczenia bez typu, transformacja odnosząca się do ścieżki, która nie może istnieć w deklarowanym typie danych, tryb potwierdzenia, którego transport źródłowy nie może dostarczyć, i recepta na leki z listy II z powtórzeniami.

Różnica, którą Perfuse próbuje utrzymać, polega na tym, że wszystko, co mogłoby wyprodukować wiarygodnie wyglądający błędny wynik, jest odrzucane, a wszystko, co jest po prostu niezwykłe, jest dozwolone i zgłaszane. Kanał, który nie może być błędny, jest bardziej wartościowy niż kanał, który się uruchamia.

5 Przepływ wiadomości

Ten rozdział opisuje jedną wiadomość od momentu jej przybycia do momentu jej dostarczenia lub poddania się. Zrozumienie tego porządku jest najszybszym sposobem, aby dowiedzieć się, gdzie zmiana należy, i dlaczego coś nie dzieje się.

5.1 Kolejność zdarzeń

Arrival de-frame Parse Record as received Filter Transform Destination A Destination B Destination C unparseable filtered Filtered is a normal outcome, not an error. Unparseable is recorded and stops. The acknowledgement is sent after delivery by default, so a sender is not told "received" before it is true.
  1. Arrival. The source accepts the bytes. For a stream transport this includes de-framing — finding where one message ends and the next begins.
  2. Parse. The bytes become a tree according to the channel's dataType. A message that cannot be parsed stops here and is recorded as a parse failure.
  3. Record. The message is written to the message store as received, before anything modifies it. This is what makes replay and reprocessing possible.
  4. Filter. If the channel has a filter, it decides whether to accept the message. A rejected message is recorded as filtered, which is a normal outcome and not an error.
  5. Transform. The channel's transformations run in order, each against the result of the last.
  6. Fan out. Each destination gets a copy of the transformed message, applies its own transformations if it has any, and delivers.
  7. Record the outcome. Per destination: delivered, queued, failed, or filtered.
  8. Acknowledge. If the source expects an acknowledgement, it is generated and sent. By default this happens here, after delivery — see below.

5.2 Kiedy potwierdzenie jest wysyłane

To jest najważniejsze ustawienie w kanale, ponieważ decyduje, co nadawca jest obiecywany. To jest ack.when, i ma dwie wartości.

on_delivery jest domyślnym. Potwierdzenie jest wysyłane tylko po tym, jak każde włączone miejsce przeznaczenia zaakceptuje wiadomość. Pozytywne potwierdzenie oznacza zatem, że dane faktycznie dotarły gdzieś, co jest najsilniejszym twierdzeniem, które silnik w środku może uczciwie złożyć.

on_receipt potwierdza, jak tylko wiadomość jest sparsowana i umieszczona w kolejce, zanim jakiekolwiek miejsce przeznaczenia zostanie zapisane.

Perfuse domyślnie używa on_delivery, ponieważ obiecywanie dostarczenia i potem utraty wiadomości jest gorsze niż opóźnienie. Pod on_receipt wiadomość, która została potwierdzona, może nadal zostać utracona, jeśli proces umrze z zadaniami w kolejce — nadawca uważa, że jest dostarczona, nic w górę nie prześle jej ponownie, a jedynym zapisem, że istniała, jest w sklepie Perfuse.

5.3 Kiedy wybrać on_receipt

Przypadek dla niego jest rzeczywisty i dotyczy limitów czasu. Nadawca MLLP, który nie otrzyma potwierdzenia w ciągu kilku sekund, zwykle wysyła ponownie, więc powolne miejsce przeznaczenia pod on_delivery powoduje duplikaty zamiast opóźnień. Jeśli jedno miejsce przeznaczenia jest powolnym archiwum lub systemem, który jest regularnie niedostępny, on_delivery łączy limit czasu nadawcy z najgorszym przypadkiem tego miejsca przeznaczenia.

Wymiana jest jawna: on_receipt przenosi ryzyko z duplikatów na utratę. Wybranie go oznacza zaakceptowanie, że potwierdzona wiadomość może być utracona w przypadku awarii, i warto ją łączyć z alertowaniem głębokości kolejki, aby zauważyć, że kolejka, która przestała się wylewać. Zobacz alertowanie.

Pod oboma ustawieniami pozytywne potwierdzenie nie jest obietnicą, że odbierający system *przetworzył* wiadomość — tylko to, że zaakceptował bajty. Jeśli potrzebujesz wiedzieć, jaki był wynik, musi on pochodzić z systemu odbierającego, i żaden silnik integracyjny nie może go dostarczyć.

5.4 Gdzie wiadomość jest rejestrowana

Przed filtrem, a zatem przed jakąkolwiek transformacją. Trzy konsekwencje:

Przekształcona forma jest również rejestrowana, dla każdego miejsca docelowego, obok wyniku. Magazyn zawiera więc to, co dotarło, co zostało wysłane i co się stało — co jest potrzebne do śledztwa.

5.5 Awaria na każdym etapie

EtapJak wygląda awariaCo się dzieje
PrzyjścieBłąd ramki, połączenie przerwane w trakcie wiadomościZarejestrowane, połączenie zamknięte, nadawca ponawia próbę
ParsowanieNie jest ważne dla deklarowanego typuZarejestrowane jako awaria parsowania, negatywne potwierdzenie, jeśli źródło oczekuje go
FiltrowanieSam filtr generuje błądTraktowane jako odmowa, zarejestrowane z błędem
PrzekształcenieNiepowodzenie jednego z krokówZależy od on_error kroku; zobacz przekształcenie
DostarczenieNiedostępne miejsce przeznaczenia lub odrzucenieW kolejce i ponawiane zgodnie z zasadami miejsca przeznaczenia; zobacz dostarczenie

Istotna asymetria: błąd parsowania jest trwały, a błąd dostarczania zwykle nie. Ponowne próby dostarczania nieprawidłowej wiadomości nigdy nie pomogą, więc nie są ponawiane. Ponowne próby niedostępnego miejsca docelowego zwykle pomogą, więc są ponawiane.

5.6 Kolejność

W ramach jednego miejsca docelowego, wiadomości są dostarczane w kolejności, w jakiej dotarły, a wiadomość, która kończy się niepowodzeniem i wchodzi do kolejki, zachowuje swoje miejsce — późniejsze wiadomości czekają za nią, zamiast ją wyprzedzać.

Jest to odpowiedni domyślny ustawienia dla danych klinicznych, gdzie przyjęcie, po którym następuje wypisanie, dostarczane w złej kolejności jest gorsze niż oba są spóźnione. Oznacza to również, że jedna zatruta wiadomość może zablokować kolejkę, co jest powodem, dla którego warto ostrzegać o głębokości kolejki.

Pomiędzy miejscami docelowymi nie ma gwarancji kolejności, ponieważ są one niezależne. Dwa miejsca docelowe nie muszą otrzymywać tej samej wiadomości w tym samym czasie, a szybkie miejsce może być kilka wiadomości przed wolnym miejscem.

Kolejność między kanałami nie jest w ogóle gwarantowana. Jeśli dwa źródła muszą być stosowane w określonej kolejności względem siebie, ta kolejność musi być wymuszona przez system odbiorczy, ponieważ nic pomiędzy nimi nie może wiedzieć, która z dwóch niezależnie przychodzących wiadomości wystąpiła pierwsza.

5.7 Współbieżność

Źródło może obsługiwać kilka połączeń jednocześnie, ograniczonych przez max_connections. Wiadomości z różnych połączeń są przetwarzane współbieżnie.

Oznacza to, że kolejność przyjścia dwóch wiadomości wysłanych jednocześnie przez dwa połączenia nie jest określona i nie może być — naprawdę dotarły w tym samym czasie. Nadawca, który potrzebuje kolejności, musi użyć jednego połączenia, co robi prawie każdy z nich.

6 Przekształcenie

Przekształcenia zmieniają wiadomość. Są to lista, są wykonywane w kolejności, a każdy z nich widzi wynik poprzedniego.

Przekształcenia Perfuse są deklaratywne: każdy krok nazwuje operację i pole, do którego się odnosi. Nie ma języka skryptowego w zwykłej ścieżce. Jest to celowe ograniczenie, a uzasadnienie znajduje się w why not a script poniżej.

6.1 Kroki

KrokCo robi
setZapisuje wartość literałową do ścieżki, tworząc ją, jeśli nie istnieje.
copyKopiuje jedną ścieżkę do innej, z opcjonalną wartością domyślną, gdy źródło jest nieobecne.
clearOpróżnia pole, pozostawiając je obecne.
removeUsuwa pole całkowicie.
mapWyszukuje bieżącą wartość w tabeli i ją zastępuje.
replacePodstawia wyrażenie regularne w polu.
padWypełnia wartość do stałej szerokości.
dateKonwertuje datę lub znacznik czasu między formatami.
trimObcina otaczające białe znaki.
caseKonwertuje do wielkich lub małych liter.

Każdy krok akceptuje również description, które pojawia się w śladzie i w interfejsie, oraz when, które czyni krok warunkowym.

Krok jest zapisany jako nazwa operacji z własnym blokiem:

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 i value nie są rodzeństwem. set przyjmuje blok zawierający path i value. Zapisywanie set: PID-3.4 z value: obok niego jest najczęstszym błędem w ręcznie napisanym kanale i powoduje błąd ładowania, a nie cichą nieprawidłową konfigurację.

6.2 Wyczyszczenie, usunięcie i różnica

clear pozostawia pole obecne i puste. remove usuwa je całkowicie.

Dla HL7 ta różnica jest realna i dochodzi do odbiorcy. Puste pole mówi „mam to pole i nie ma wartości”. Nieobecne pole nie mówi nic w ogóle. Niektóre systemy odbiorcze traktują pierwsze jako polecenie, aby wykasować przechowywaną wartość, a drugie jako polecenie, aby ją pozostawić — co jest różnicą między usunięciem zarejestrowanej alergii pacjenta a niezmienieniem jej.

Jeśli nie wiesz, które odbiorca chce, zapytaj. Odgadnięcie ma pięćdziesięcioprocentową szansę na ciche zniszczenie danych po drugiej stronie.

6.3 Warunki

when przyjmuje wyrażenie i krok jest wykonywany tylko wtedy, gdy jest ono prawdziwe:

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

Krok, którego warunek jest fałszywy, jest rejestrowany jako pominięty, a to jest raportowane oddzielnie od kroku, który został wykonany i nie zmienił niczego. Ta różnica jest celem debugera krokowego i jest opisana w debugowaniu: fałszywy warunek i brak pola wyglądają identycznie z zewnątrz i oznaczają przeciwne rzeczy.

6.4 Ścieżki

Ścieżka adresuje pole: PID-5 jest piątym polem PID, PID-5.1 jego pierwszym składnikiem, PID-3(2) drugą powtórką PID-3, a OBX(3)-5 piątym polem trzeciego segmentu OBX.

Dwie zachowania warte poznania:

6.5 Błędy

Większość kroków nie ma nic, co mogłoby zawieść. Ustawienie wartości, wyczyszczenie pola lub skopiowanie z nieobecnego pola ze standardową wartością są wszystkie zdefiniowane dla każdego wejścia.

date jest wyjątkiem, ponieważ wartość, która nie jest datą, którą rozpoznaje, nie ma poprawnej konwersji. Przyjmuje on_error:

Domyślnie jest fail, ponieważ znacznik czasu, który niekonwertuje się cicho, jest gorszy niż wiadomość, która nie dotarła. Data w niewłaściwym formacie nadal wygląda jak data, więc przechodzi walidację odbiorcy i ląduje w rekordzie jako niewłaściwy dzień.

keep jest uzasadnione, gdy odbiorca toleruje oba formaty, a gdy jest używany, ślad oznacza zmianę jako zamierzoną, więc nie czyta się jak krok, który awaryjnie zamilkł.

6.6 Kolejność ma znaczenie, a ślad ją pokazuje

Każdy krok widzi dane wyjściowe poprzedniego kroku. Dwa konsekwencje, które łapią ludzi:

Oba są widoczne w widoku krokowym, który pokazuje całą wiadomość po każdym kroku, a nie tylko zmianę. Zobacz debugowanie.

6.7 Sugestie mapowań i to, co z nimi zrobić

AI Mapper proponuje mapowania między zestawem pól źródłowych a zestawem docelowych. Jego definicją jest to, że odstępuje: poniżej progu ufności wstrzymuje się od zgadywania, ponieważ pewne błędne mapowanie w systemie klinicznym jest gorsze niż brak mapowania w ogóle.

6.7.1 Daj mu coś, o czym może być pewny

Nazwa sama w sobie jest słabym dowodem, nawet gdy dokładnie się zgadza. PatientMRN przeciw PatientMRN uzyskuje wynik 68, który odstępuje przy domyślnym progu 70.

Silnik wie, co oznacza ścieżka HL7 — powie Ci PID-7 is Date/Time of Birth i oceni Twoją nazwę pola względem tego, a nie względem ciągu PID-7, który nie ma wspólnych znaków z niczym. Lokalnie zdefiniowany segment Z oznacza wszystko, co zdecydowało Twoje miejsce, więc nic nie jest twierdzone o tym.

To daje mapowanie w większości. Aby je dokończyć, dostarcz obie połowy:

Z tymi danymi silnik może zobaczyć, że wartości zgadzają się z rodzajem docelowym, a sugestia opiera się na czymś więcej niż tylko nazwie.

6.7.2 Zatwierdzenie jest jednym przyporządkowaniem na raz

Każda sugestia ma własną skrzynkę zatwierdzeń. Nie ma „zaakceptuj wszystko powyżej 80%”, celowo: silnik już wykorzystał ufność, aby zdecydować, czy zaproponować przyporządkowanie, a co pozostaje, to sąd o tym polu w tym kanale. Liczba nie jest tym sądem.

Wstrzymanie się nie może być zatwierdzone w ogóle. Nie ma skrzynki, nawet wyłączonej, a ekran mówi, że silnik nie wie. Jeśli znasz odpowiedź, mapuj ją ręcznie — to inny akt niż zgadzanie się z sugestią.

Sugestia poniżej Twojego progu jest wyświetlana bez skrzynki, oznaczona jako poniżej niej. Warto przeczytać — bliskie przyporządkowanie jest często tym, którego chcesz, a ukrywanie go pozostawiłoby Cię w niepewności, czy silnik brał je pod uwagę — ale nie do zatwierdzenia, ponieważ Twój próg jest linią, którą narysowałeś.

6.7.3 Dwie rzeczy do zrobienia z tym, co zatwierdziłeś

Dodaj je do kanału zmienia każde przyporządkowanie w krok kopiowania. Działa to tylko wtedy, gdy źródłem jest ścieżka w wiadomości, taka jak ZPI-1, ponieważ krok kopiuje z jednego miejsca w wiadomości do innego. Kroki są umieszczane w pliku kanału i zaczynają obowiązywać, gdy zostanie ponownie załadowany — nic nie zmienia się w ruchu do tego czasu. Opis każdego kroku rejestruje ufność, z jaką został on zaproponowany, i to, że osoba go zatwierdziła, co sprawia, że jest on rozliczalny sześć miesięcy później.

Pobierz jako przepis jest odpowiedzią na bardziej powszechny przypadek: przyporządkowanie z nazwy kolumny, klucza JSON lub nazwy pola producenta. Są to prawdziwe przyporządkowania, a kanał nie może odczytać takiego pola bezpośrednio, więc krok nie może go wyrazić. Przepis rejestruje je jako zatwierdzone i może być udostępniony.

6.8 Dlaczego nie skrypt

Mirth umieszcza transformator JavaScript w centrum każdego kanału i jest to najbardziej elastyczny projekt dostępny. Perfuse oferuje skryptowanie — zobacz klucz scripts w odniesieniu do kanału — ale nie robi tego zwykłej ścieżki, z trzech powodów, które wynikają z tego, co się nie udaje w praktyce.

Declaratywny krok może być inspekcjony. Perfuse może powiedzieć, że krok odczytuje PID-5 i zapisuje PID-8, zanim go uruchomi, i może więc pokazać ślad na poziomie pola, ostrzec, że krok adresuje ścieżkę, której deklarowany typ danych nie może zawierać, i wygenerować powtórkę na krok.

Declaratywny krok może być rozważany przez interfejs. Budowniczy może zaoferować pola, które istnieją w ruchu tego kanału, a zmiana kroku może być sprawdzona z prawdziwymi historycznymi wiadomościami przed zapisaniem.

I declaratywny krok nie może zrobić czegoś niezwiązanego z wiadomością. Skrypt może wywołać sieć, odczytać system plików lub zależeć od czasu dnia. Gdy kanał, który działał przez dwa lata, zaczyna produkować błędne dane wyjściowe, przyczyna leżąca poza wiadomością jest najtrudniejszym przypadkiem do zdiagnozowania, a usunięcie tej możliwości jest warte więcej niż elastyczność, którą to kosztuje.

Gdzie prawdziwa transformacja nie może być wyrażona deklaratywnie, użyj skryptu i zaakceptuj, że ślad pokaże go jako jeden nieprzezroczysty krok.

6.9 Co skrypt jest dozwolony do zrobienia

Skrypt jest odmówiony wszystkiego poza wiadomością, chyba że jest udzielony, a udzielenia są w sekcji Skrypty budowniczego. To jest celowo inaczej niż Mirth, który daje każdemu skryptowi wszystkie — więc tam, transformator może cicho zacząć odczytywać system plików po kopiowaniu i wklejeniu.

Istnieją trzy.

Odczyt i zapis plików wymaga od Ciebie podania katalogów, których może używać, a kanał udzielający dostępu do plików bez nich jest odrzucany podczas ładowania. To wymaganie jest całą różnicą między dostępem do plików a nieograniczonym dostępem do plików: udzielenie mu bez katalogów kiedyś dotarło do całego systemu plików, w tym bazy danych Perfuse, która zawiera hasła haseł, hasło konta usługi LDAP i tajemnicę klienta OIDC. Tworzenie kanału wymaga tylko roli edytora, więc eskalacja została ukończona w momencie, gdy administrator uruchomił kanał.

Zapytanie bazy danych używa połączeń skonfigurowanych na kanale. Skrypt z tym może odczytać wszystko, co te poświadczenia mogą.

Route messages to other channels pozwala skryptowi wysłać wiadomość do innego kanału, co jest sposobem, w jaki pętla między dwoma kanałami staje się możliwa.

Udzielenie możliwości kanałowi bez skryptów nie robi nic, a wygenerowany plik pomija cały blok w tym przypadku.

6.10 Obsługa daty, która nie odpowiada jej formatowi

Krok daty konwertuje z jednego formatu na inny, a interesującym pytaniem jest to, co się dzieje, gdy wartość nie odpowiada formatowi, który twierdzi, że ma.

Domyślnie jest to zatrzymanie wiadomości, i jest to odpowiedni domyślny: sygnatura czasowa, która cicho nie przekonwertowała, jest akceptowana w dół i potem źle odczytana, co jest gorsze niż wiadomość, która głośno nie powiodła się i siedzi tam, gdzie ktoś może ją zobaczyć.

Pozostawienie wartości takiej, jaka jest przechodzi ją w oryginalnym formacie. Poniżej widzi dwie formaty w jednym polu, co jest awarią, której krok istniał, aby ją zapobiec — ale jest to odpowiedni wybór, gdzie pole jest opcjonalne i partner wysyła je niekonsekwentnie.

Opróżnienie pola jest uczciwe i lepsze niż błędny format, ale odbiorca, który wymaga pola, odrzuca wiadomość zamiast.

6.11 Języki skryptowe

Trzy są akceptowane, a który wybrać zależy głównie od tego, czy migrujemy. Wartość jest umieszczona w kluczu language skryptu:

WartośćCo to jest
javascriptDomyślny. Skrypt bez oznaczenia jest traktowany jako JavaScript.
luaLepszy wybór, gdy nikt nie migruje.
wasmZestaw bajtów skompilowanego modułu WebAssembly, a nie źródła.

JavaScript jest domyślny, a skrypt bez oznaczenia jest traktowany jako JavaScript. Jest tutaj z powodu obowiązku zgodności, a nie preferencji: skrypty Mirth są napisane w JavaScript i witryna przechodząca ma tysiące linii kodu. Obejmuje to obsługę E4X, dawnej rozszerzenia języka, które skrypty Mirth używają do XML i które musi być przetłumaczone, zanim cokolwiek będzie mogło być sparsowane.

Lua (lua) jest lepszym wyborem dla każdego, kto nie migruje. Mniejsza środowisko uruchomieniowe, brak łańcucha prototypów do nadużywania i tabele indeksowane liczbami całkowitymi, które lepiej odpowiadają adresowaniu segmentów i pól niż tabele JavaScript. Jego standardowa biblioteka jest wystarczająco mała, aby ją wyliczyć, co sprawia, że piaskownica jest łatwiejsza do zaufania.

WebAssembly (wasm) nie jest językiem, ale skompilowanym modułem, a pole wymaga bajtów pliku .wasm zamiast źródła. Użyj go, gdy transformacja już istnieje w skompilowanym języku lub gdy jest wystarczająco ciężka, aby koszt czasu uruchomieniowego miał znaczenie.

Jego kontrakt jest celowo najprostszym dostępnym: moduł odczytuje wiadomość ze standardowego wejścia i zapisuje wynik na standardowym wyjściu. Bajty wejściowe, bajty wyjściowe — co każdy łańcuch narzędziowy już robi, i co ktoś testujący moduł na własnej linii poleceń już ma. Alternatywą był eksportowany moduł nad pamięcią liniową, który jest szybszy i wymaga, aby każdy autor modułu zgodził się co do alokacji, kodowania ciągów i zwalniania pamięci; dla czegoś, co jest uruchamiane raz na wiadomość, ten handel nie jest wart.

Cokolwiek moduł zapisuje na standardowym wyjściu błędu staje się liniami logowania, więc może wyjaśnić się w sposób, w jaki skrypt wywołuje logger.

Niezerowy kod zakończenia oznacza, że moduł *nie powiódł się*, co nie jest takie samo, jak filtr decydujący o odrzuceniu wiadomości. Moduł filtru mówi true lub false na standardowym wyjściu. Łączenie ich sprawiłoby, że moduł awaryjny byłby nie do odróżnienia od tego, który celowo odrzuca ruch.

6.11.1 Co oznacza wyjście

Reguły są takie same dla wszystkich trzech języków, a nie nowe dla każdego środowiska uruchomieniowego, więc widoczne zachowanie skryptu — co może zobaczyć, co może zrobić, jak długo może potrwać, co oznacza werdykt filtru — jest zdefiniowane raz.

Dla transformatora, preprocesora lub pisarza puste wyjście oznacza, że wiadomość nie została zmieniona. Spadanie z końca skryptu pozostawia wiadomość w spokoju; traktowanie braku wyjścia jako „wiadomość jest teraz pusta” spowodowałoby odrzucenie ruchu z technicznego powodu.

Moduły WebAssembly są skompilowane, gdy kanał jest ładowany, a nie przy pierwszej wiadomości. Skompilowanie nie jest bezpłatne — moduł zbudowany z języka, który przywozi własne środowisko uruchomieniowe, może zająć setki milisekund — i płacenie za to w czasie ładowania oznacza, że pierwsza wiadomość przez kanał nie jest tajemniczo wolniejsza niż reszta.

6.12 Współdzielone tabele mapowania

Inna połowa tego samego problemu: kody płci i klasy pacjenta są tłumaczone identycznie we wszystkich kanałach, które ich dotykają, a tabela wewnątrz kanału jest tabelą tylko dla tego kanału.

# 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

Pochodzenie jest punktem. Większość tego, co utrudnia utrzymanie interfejsu, polega na tym, że nikt nie wie, *dlaczego* mapowanie jest w taki, a nie inny sposób, a osoba, która wiedziała, odeszła. Mapowanie z powodem może być dyskutowane; bez powodu staje się czymś, czego nikt nie odważy się zmienić i usunąć.

Tabele są tworzone i zmieniane w Buduj → Tabele, a także w pliku. Zapisywanie tabeli, która jest w mocy, restartuje uruchomione kanały, które ładują jej plik, więc następny komunikat używa jej; wersja robocza nie restartuje niczego.

6.12.1 Wersje i daty obowiązywania

Tabela może przechowywać kilka edycji pod jedną nazwą, z których każda ma swój własny version. Edycja, którą używa komunikat, jest wybierana, gdy komunikat przychodzi: spośród zatwierdzonych edycji, których daty obejmują ten dzień (UTC), ta, która zaczęła się najpóźniej. Zatem zmiana kodu uzgodniona na pierwszy dzień następnego miesiąca jest wprowadzana teraz i samoczynnie wchodzi w życie.

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

(przechowywany dla zapisu, używany przez nic).

rozpoczynające się tego samego dnia, są odrzucane podczas ładowania pliku.

datuje ją od dziś, więc zastępuje tę, która obowiązuje. Ta, która sama zaczęła się dzisiaj, jest wycofana, ponieważ dwie edycje rozpoczynające się tego samego dnia nie pozostawiają żadnej reguły.

w przeciwnym razie używane są te z tabeli.

kim ją zapisano i kim zatwierdzono, a Porównaj z wersją obowiązującą pokazuje, co edycja dodaje, usuwa i zmienia.

6.12.2 Potwierdzenie

Z Ustawienia → Dane → Tabele mapowania „Zmiany w tabeli mapowania wymagają zatwierdzenia przez drugą osobę” (data.tableApproval) włączone, każde zapisywanie jest wersją roboczą, a osoba, która ją zapisuje, nie może jej zatwierdzić: ktoś inny to robi, opcjonalnie podając dzień, w którym wchodzi w życie. Zatwierdzona edycja nie może być edytowana na miejscu; Nowa wersja z tej kopiuj ją do następnej wersji. Zatwierdzenie, wycofanie i usunięcie wersji roboczej są zapisywane w rejestrze inspekcji, a zatwierdzenie restartuje uruchomione kanały, które ładują plik.

6.12.3 Wartości bez mapy

Każda wartość, której szukał krok mapowania i nie znalazł, jest liczbana, per tabela, z kanałami, przez które przeszła, i kiedy została po raz pierwszy i ostatni raz zobaczona. Ekran Tabele wyświetla je, najczęstsze jako pierwsze. Mapuj otwiera tabelę z tą wartością już dodaną jako wiersz; Odrzuć usuwa ją, aż do momentu, iedy zostanie ponownie zobaczona. Wartości dłuższe niż 64 znaki nie są rejestrowane (nie są kodami), a lista zachowuje to, co zostało zobaczone w okresie przechowywania wiadomości. Lista jest przechowywana w terminology.db obok głównej bazy danych.

6.12.4 Systemy kodów

Opublikowane systemy kodów mogą być importowane z plików ich wydawców, pod Systemy kodów na ekranie Tabele (administratorzy) lub z POST /api/terminology/import?format=… i plikiem jako treścią:

FormatPlikSystem
loincLoinc.csv z wydania tabeli LOINChttp://loinc.org
icd10cmplik zamówienia CMS (icd10cm_order_*.txt) lub plik kodówhttp://hl7.org/fhir/sid/icd-10-cm
rxnormRXNCONSO.RRF z pełnego wydania RxNormhttp://www.nlm.nih.gov/research/umls/rxnorm
snomedmigawka opisu RF2 (sct2_Description_Snapshot-en_*.txt)http://snomed.info/sct
snomed-rf2cały pakiet wydania SNOMED CT RF2 (zip publikowany przez narodowe centrum wydawnicze)http://snomed.info/sct, wersja http://snomed.info/sct/{module}/version/{date}
clamlplik ClaML: WHO ICD-10, ICD-10-GM i OPS (BfArM), CIM-10 FR (ATIH)z tytułu pliku lub podanego system
icd11prosta tabulacja MMS ICD-11 WHO (rozdzielana tabulatorami, z kolumnami Code i Title)http://id.who.int/icd/release/11/mms
csvdowolny plik rozdzielany, z system, codeColumn i displayColumn (CPT, HCPCS, lokalne kody, narodowe tabele)podany system

Żaden nie jest dostarczany z Perfuse: LOINC, SNOMED CT, RxNorm i CPT mają własne licencje, a ekran prosi importera o potwierdzenie, że organizacja posiada je (zarejestrowane z importem). Zimportowane kody są używane na trzy sposoby:

podczas zapisywania, a kody, które nie są w systemie, są wymienione w edycji;

dla nich (patrz opcje serwera FHIR). Kody ICD-10-CM są akceptowane z lub bez kropki.

Edycje i klasyfikacje narodowe. Edycja SNOMED CT jest importowana z całości pakietu RF2: pojęcia ze swoim rzeczywistym statusem, każdy aktywny opis i zestawy odniesień językowych. Edycja jest znaleziona z pakietu (narodowy moduł z największą liczbą pojęć; edition ją nazywa zamiast) i staje się identyfikatorem wersji URI. language wybiera, którego preferowany termin jest wyświetlany dla każdego pojęcia (sv, da, nl, de, fr, en-GB, en-US ...; angielski w przeciwnym razie), a każdy językowy preferowany termin i w pełni określona nazwa są przechowywane jako nazwy: $lookup zwraca je, a displayLanguage wybiera jeden (de-CH cofa się do de). Edycje nazwane przez Perfuse (Międzynarodowa, Wielka Brytania, Niemcy, Holandia, Szwecja, Dania, Belgia, Irlandia, Norwegia, Szwajcaria, Estonia, Hiszpania) są wymienione przez GET /api/terminology/editions, identyfikatory modułów nie są sprawdzane przeciwko opublikowanemu źródłu oznaczonego jako takie; każda inna edycja jest również importowana, nazwana przez swój moduł.

Pliki ClaML są odczytywane w kodowaniach UTF-8, ISO-8859-1, ISO-8859-15 lub Windows-1252, zgodnie z deklaracją XML. Tytuł każdej kategorii jest jej preferowaną rubryką (zawierającą zakodowane terminy); modyfikator (piąty znak w przypadku miejsca złamania, na przykład) tworzy dodatkowe kody z tytułem modyfikatora po tytule kategorii, chyba że kategoria wyklucza go; blocks=true importuje rozdziały i bloki. Kolumny w tabeli ICD-11 są wyszukiwane według nazwy, ponieważ ich kolejność uległa zmianie między wersjami, a myślniki wskazujące na poziom są usuwane z tytułów. Plik z ogranicznikiem wymaga delimiter (,, ;, | lub tab), encoding (utf-8, iso-8859-1, iso-8859-15, windows-1252) oraz noHeader=true, a kolumny są następnie numerowane od 1. Konsola oferuje ustawienia dla plików UK ICD-10 5th Edition i OPCS-4 (TRUD), francuskiej tabeli etykiet CIM-10 FR (ATIH) oraz eksportu ICD-10-BE; wydawcy tych plików nie zawsze dokumentują ich kolumny, dlatego należy je sprawdzić w nagłówku pliku.

Daty obowiązywania. effective=YYYY-MM-DD importuje wersję, która obowiązuje od tego dnia (na przykład ICD-10-GM co roku 1 stycznia): do tego czasu wyszukiwanie, które nie określa wersji, zwraca wersję już obowiązującą, a ekran wyświetla datę.

ICD-11 od WHO. Z zarejestrowanym klientem w icd.who.int (Ustawienia → Dane → Systemy kodów, serve -icd11-client-id i -icd11-client-secret; -icd11-release, domyślnie 2025-01), kody ICD-11, które nie są importowane, są wyszukiwane w API WHO ICD (codeinfo, a następnie tytuł encji) i przechowywane przez dzień. Postkoordynowany kod (NC72.2&XK9K) jest sprawdzany w całości, więc kombinacja ICD-11, której nie zezwala, jest odrzucana, a jego nazwy wyświetlania każdej części ("Złamanie szyjki kości udowej (prawa)").

ICD-11 bez wysyłania kodów. WHO publikuje to samo API jako kontener (whoicd/icd-api, bezpłatnie, Intel i Arm). Uruchom go w swojej sieci i podaj jego adres (serve -icd11-url http://icd-api.local, lub Adres API ICD w tych samych ustawieniach); nie jest wymagany klient, a żaden kod nie opuszcza Twojej sieci. Przetestowane z tym kontenerem (wersja 2.6.0, wydanie 2025-01 w języku angielskim i francuskim).

7 Filtrowanie

Filtr decyduje, które wiadomości akceptuje kanał. Jest to jeden wyrażenie na kanale, oceniany po przetworzeniu i zarejestrowaniu wiadomości, przed jakąkolwiek transformacją.

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

Wiadomość, którą filtr odrzuca, jest rejestrowana z wynikiem filtered. Jest to normalny wynik, a nie błąd, i nie wywołuje alertu ani nie powoduje negatywnej potwierdzenia.

7.1 Filtrowany nie jest tym samym co nieudany

Ta różnica jest warta podkreślenia, ponieważ łączenie ich może ukryć prawdziisty problem.

Filtrowana wiadomość została poprawnie odrzucona: nie była przeznaczona dla tego kanału. Nieudana wiadomość była taka, którą ten kanał powinien był obsłużyć, ale nie mógł. Jeśli obie były rejestrowane w ten sam sposób, kanał, który zaczyna filtrować każdą wiadomość, wyglądałby dokładnie jak kanał, który filtruje większość swojego ruchu, co jest normalnym stanem wielu kanałów.

Dlatego statystyki liczą je oddzielnie, reguły alertów traktują je inaczej, a interfejs wyświetla je w różnych kolorach. Wzrost liczby filtrowanych wiadomości może oznaczać, że nadawca zaczął wysyłać coś nowego; wzrost liczby nieudanych wiadomości oznacza, że coś jest nie tak.

7.2 Co filtr może odczytać

Dowolne pole w sparsowanej wiadomości, przy użyciu tych samych ścieżek, których używają transformacje. Filtrowanie odbywa się przed transformacjami, więc filtr widzi wiadomość tak, jak przybyła — a nie tak, jak zostanie wysłana.

To kolejność jest celowa. Filtrowanie, które czyta wartości po transformacji, decydowałoby o przyjęciu wiadomości na podstawie zmian wprowadzonych pod założeniem, że została przyjęta, co jest sprzeczne i powoduje, że kanały zachowują się w zależności od kolejności dwóch rzeczy, które wydają się niezależne.

7.3 Wyrażenia

Porównania: ==, !=, a dla liczb <, <=, >, >=.

Członkostwo: in ("A01", "A03"), co jest jaśniejsze niż łańcuch || i jest formą, którą produkuje konstruktor.

Połączenie: &&, || i nawiasy. Negacja z !.

Niewystępowanie: ścieżka, która nie jest obecna, jest niezgodna z dowolną wartością, w tym z pustym łańcuchem. Aby jawnie przetestować niewystępowanie, porównaj z absent. Ma to znaczenie, ponieważ brak pola i puste pole są różne, jak opisano w transformation, a filtr, który traktuje je w ten sam sposób, zaakceptuje wiadomości, które zostały napisane, aby je wykluczyć.

7.4 Błąd w filtrze jest odmową

Jeśli filtr sam w sobie nie może być oceniony — sformatowane wyrażenie, które przeszło walidację, lub porównanie, które nie może być wykonane — wiadomość jest odrzucona, a błąd jest rejestrowany przeciwko niej.

Odrzucenie zamiast akceptacji jest bezpieczniejsze z dwóch, ale żadne z nich nie jest dobre, a wynik jest rejestrowany oddzielnie od zwykłej odmowy filtru, aby mógł być zaalarmowany. Filtrowanie, które kończy się błędem na każdej wiadomości, cicho upuszcza cały strumień, i nie powinno wyglądać jak filtr, który działa.

7.5 Filtruj na źródle, gdzie możesz

Filtr działa po tym, jak wiadomość przekroczyła sieć i została sparsowana. Niektóre źródła mogą filtrować wcześniej i taniej:

Filtrowanie na źródle jest decyzją wydajnościową, a nie poprawnościową, i ma jeden koszt: wiadomość, która została zfiltrowana na brokerze, nigdy nie jest rejestrowana przez Perfuse, więc nie pojawia się w magazynie wiadomości i nie może być zinspekcjonowana później. Jeśli potrzebujesz udowodnić, co nadawca wysłał, zrób to tutaj, a nie tam.

7.6 Testowanie filtru

Filtr może być sprawdzony z prawdziwym historycznym ruchem przed zapisaniem. Interfejs raportuje, ile z ostatnich N zarejestrowanych wiadomości filtr zaakceptuje, odrzuci i wywoła błąd — co jest najszybszym sposobem, aby dowiedzieć się, że wyrażenie, które wygląda dobrze, nic nie akceptuje.

Ślad również pokazuje, dla każdej wiadomości, które pola filtr odczytał i jakie wartości znalazł. Filtrowanie, które niespodziewanie odrzuca wszystko, zwykle czyta ścieżkę, która nie istnieje w tym strumieniu, a ślad ją nazywa.

8 Formaty wiadomości

Typ kanału dataType decyduje, jak bajty są przekształcane w wiadomość. Ma wpływ na analizę, znaczenie ścieżek, sposób zapisu wiadomości oraz które przekształcenia są ważne.

WartośćFormat
hl7HL7 v2, standard rozdzielany znakiem pipe. Domyślny.
hl7v3Dokumenty HL7 v3 i CDA, które są w XML.
x12ASC X12, używany do kwalifikowalności i roszczeń.
ncpdpStandard telekomunikacyjny NCPDP D.0 dla roszczeń aptecznych.
scriptNCPDP SCRIPT, elektroniczne przepisy. XML.
dicomObiekty obrazowania DICOM.
delimitedCSV i inne teksty rozdzielane.
rawBrak parsowania. Wejście w postaci bajtów, wyjście w postaci bajtów.

8.1 HL7 v2

Domyślny, a większość przykładów w tej dokumentacji używa go. Segmenty zakończone znakiem powrotu karetki, pola przez |, składniki przez ^, powtórzenia przez ~.

Dwie rzeczy dotyczące kodowania są warte poznania, ponieważ powodują błędy bez ostrzeżeń.

Rozdzielacze nie są stałe. Zadeklarowane są w MSH-1 i MSH-2 każdej wiadomości, a Perfuse odczytuje je stamtąd, zamiast przyjmować pipe. Nadawca, który używa innego separatora pól, parsuje poprawnie.

Konsekwencją jest to, że wiadomość, której separatory zostały zastąpione — najczęściej przez procesor tekstu lub klienta poczty elektronicznej zastępujący wyglądem typograficznym — jest analizowana idealnie w pola, które są wszystkie błędne. Nic nie powoduje błędu. To jest powód, dla którego próbka czytnika opisana w testing raportuje, który znak separatora znaleziono, i odmawia wyrażenia zaufania, gdy jest to niezwykłe.

Gdy ktoś wysyła Ci próbkę, a kanał utworzony na jej podstawie produkuje nonsense, sprawdź separatory przed wszystkim innym. Poproś o załącznik w postaci zwykłego tekstu zamiast wiadomości wklejonej do treści wiadomości e-mail.

8.2 HL7 v3 i CDA

XML zamiast rozdzielanego. Ścieżki są ścieżkami elementów i atrybutów zamiast pozycji pól.

W v3 wartość jest prawie zawsze atrybutem, a nie tekstem elementu. Porównanie, które czyta tylko tekst elementu, zgłasza, że dwa dokumenty są identyczne, gdy data urodzenia, płeć i każdy identyfikator się różnią. Porównanie Perfuse czyta oba, i to jest powód: alternatywa powoduje błędy bez ostrzeżeń.

Opcje hl7v3 są w odniesieniu do formatu.

8.3 X12

Segmenty zakończone konwencjonalnie przez ~, z rozdzielaczami zadeklarowanymi w segmencie ISA. Podobnie jak HL7, są one odczytywane z wiadomości, a nie założone.

Struktura X12 składa się z kopert w kopertach — wymiany, grupy funkcjonalnej, zestawu transakcyjnego — i jednej wymiany może zawierać wiele transakcji.

Domyślnie interchange jest jedną wiadomością. Cały plik otrzymuje jeden rekord, jeden wynik i jeden wiersz w interfejsie, niezależnie od ilu transakcji zawiera.

8.3.1 X12 XML Mirth

Mirth Connect i Open Integration Engine wyświetlają X12 jako XML: korzeń X12Transaction (lub EDIMessage, gdy dane wejściowe nie zaczynają się od ISA) przenoszący separatory jako atrybuty i jeden element na segment i element nazwany ISA.01, NM1.03.1 itd. Kanały i odbiornicy zbudowane dla Mirth odczytują i zapisują tę postać. Perfuse również odczytuje i zapisuje tę samą postać:

Format został napisany z obserwowanego wyjścia i opublikowanego formatu Open Integration Engine 4.6, i jest sprawdzany w stosunku do niego: 25 wygenerowanych wymian i 4 przechowywane przykłady wychodzą bajt po bajcie tak, jak OIE je zapisuje, i z powrotem (patrz weryfikacja). DOCTYPE jest odrzucany, jak w każdym XML, który Perfuse odczytuje.

8.3.2 Dzielenie interchange

Ustawienie split powoduje, że każdy zestaw transakcyjny staje się wiadomością samą w sobie, z własnym rekordem, własnymi metrykami i własnym wierszem. Operator szukający jednego roszczenia znajdzie wtedy jednego roszczenia, a nie pliku czterystu.

Jest wyłączone domyślnie, ponieważ włączenie go mnoży wszystko w dół strumienia — liczbę wiadomości, wiersze, progi alarmowe — a próg dostosowany do plików, który nagle liczy roszczenia, nie będzie już oznaczał tego, co poprzednio. To powinno być decyzją, którą ktoś podjął, a nie domyślnym ustawieniem, które odziedziczył.

split i acknowledge nie mogą być ustawione jednocześnie, a kanał z oboma jest odrzucany podczas ładowania. Potwierdzenie jest oświadczeniem o całej wymianie, więc dzielenie wyśle je po jednym dla każdego zestawu transakcyjnego, a partner otrzymujący kilka 999 z tym samym funkcjonalnym grupowaniem nie ma sposobu, aby je uzgodnić.

8.3.3 Gdy liczby nie sumują się

X12 deklaruje własne liczby — ile segmentów, ile transakcji — a klucz envelope mówi, co zrobić, gdy nie zgadzają się one z tym, co jest rzeczywiście obecne. Te liczby są jedynym mechanizmem, który X12 ma do wykrywania, że połowa pliku roszczeń przybyła.

WartośćZachowanie
requireOdrzuć interchange. Domyślny.
warnPrzetwórz go, i zapisz błąd przeciwko wiadomości.
ignoreW ogóle nie sprawdzaj.

warn istnieje dla realnej sytuacji: oprogramowanie niektórych partnerów generowało błędne liczby przez lata w inaczej kompletnych plikach, a witryna, która musi przetwarzać te pliki, potrzebuje sposobu, aby to powiedzieć głośno w konfiguracji, zamiast wyłączać walidację w całości.

ignore jest nazwany, aby być niekomfortowy. Ustawienie go wyrzuca jedyny sposób, w jaki X12 daje Ci zauważenie pliku, który został obcięty, a obcięty plik roszczeń jest nie do odróżnienia od małego.

8.3.4 Transakcje Perfuse odczytuje jako dane strukturalne

Dowolna wymiana X12 może być trasowana, filtrowana i adresowana według ścieżki. Transakcje te są dodatkowo analizowane na pola o nazwach, więc kanał może zapytać, co płatnik zdecydował, zamiast pytać, który element znajduje się na pozycji czwartej.

TransakcjaCo zawiera
835Informacje o rozliczeniu: co zostało zapłacone, co zostało odrzucone i powody korekty.
275Załączniki do roszczeń: dokumentacja kliniczna wspierająca roszczenie.
277Status roszczenia, w tym wniosek płatnika o dodatkową dokumentację.
278Wcześniejsza autoryzacja: wniosek o przegląd i decyzja płatnika.
999Funkcjonalne potwierdzenie, które Perfuse również generuje.
271Kwalifikowalność: czy pacjent jest objęty ubezpieczeniem, oraz kwoty współpłacenia, współubezpieczenia, franszyzy i wydatków ponad limit, w sieci i poza nią.
834Zapisywanie: członkowie dodani, zmienieni i usunięci, z każdą linią ubezpieczenia i jej datami.
837Roszczenia, profesjonalne i instytucjonalne (przeczytaj o konwersji CARIN CMS-0057).

Perfuse tworzy również 270 zapytanie o uprawnienia i 276 zapytanie o status roszczenia, w Payers → Claims & auth lub za pomocą POST /api/x12/eligibility/build i /api/x12/claimstatus/build. Oba są wersjami HIPAA 5010 (005010X279A1, 005010X212), odczytywane i sprawdzane przed wyświetleniem, a żadne z nich nie jest wysyłane z tej strony: dostarczanie jednego z nich jest zadaniem kanału, gdzie określany jest partner handlowy i jego poświadczenia.

8.3.5 Kwalifikowalność i reguła zawartości danych CAQH CORE

271 to lista segmentów EB, z których każdy reprezentuje pojedynczy fakt: aktywne ubezpieczenie, opłata w wysokości 25 dolarów za rodzaj usługi 30 w sieci lub 800 dolarów indywidualnego dedykowanego wydatku. Czytelnik łączy je w odpowiedź, jakiej oczekuje recepcja - "aktywne ubezpieczenie w ramach Gold PPO 2000; opłata w sieci 25 dolarów; indywidualny dedykowany wydatek w sieci 800 dolarów" - i określa odrzucenie (segment AAA) słowami, wraz z tym, co płatnik mówi, co należy zrobić dalej.

Perfuse sprawdza również odpowiedź względem reguły dotyczącej zawartości danych o uprawnieniach i korzyściach CAQH CORE: dla zapytania o ubezpieczenie planu zdrowotnego (rodzaj usługi 30), aktywna odpowiedź powinna zawierać daty planu, nazwę planu, opłatę, ubezpieczenie, dedykowany wydatek i pozostały dedykowany wydatek zarówno w sieci, jak i poza nią, oraz podstawowe rodzaje usług (1, 33, 35, 47, 48, 50, 86, 88, 98, AL, MH, UC). Każdy z nich jest wymieniony jako spełniony lub brakujący. Jest to interpretacja reguły przez Perfuse, przydatna do odpowiedzi na pytanie „dlaczego ten płatnik nigdy nie mówi nam o dedykowanym wydatku?” - nie jest to certyfikacja CORE, którą przeprowadzają autoryzowani dostawcy testów CAQH.

8.3.6 Wcześniejsza autoryzacja

Perfuse implementuje wcześniejszą autoryzację dwa razy, celowo.

Strona FHIR to to, co CMS-0057-F wymaga od płatników do udostępnienia do 1 stycznia 2027. 278 to to, co płatnicy akceptują dzisiaj, a reguła nie zastępuje go — Da Vinci PAS jest w praktyce mapowaniem na tę transakcję, ponieważ 278 to to, co mówi system zarządzania wykorzystaniem. Silnik czytający tylko połowę FHIR może rozmawiać z systemami, które będą istnieć, a nie z tymi, które istnieją.

Odpowiedź 278 zawiera numer autoryzacji, i to jest pole, dla którego cała transakcja istnieje. Bez niego usługa certyfikowana nie jest rozliczalna: roszczenie wchodzi bez numeru autoryzacji i jest odrzucone z powodu braku jednego, co czyta się w dół jako odrzucenie kliniczne.

Odrzucenie i odmowa rozpatrzenia nie są tym samym

Jest to najdroższe pomylenie w transakcji, a Perfuse raportuje obie oddzielnie.

Co przybyłoCo to znaczyCo robić
HCR z akcją A3Płatnik rozpatrzył wniosek i nie zaakceptuje go.Odwołać się lub zmienić plan opieki.
Segment AAAPłatnik nie rozpatrzył go — pacjent nie znaleziony, wnioskodawca nie rozpoznany, przegląd nie jest objęty. Nic nie zostało zdecydowane.Poprawić wniosek i wysłać go ponownie.

Oba są odczytywane jako „niezatwierdzone” przez każdego, kto skanuje, a poprawne działania są przeciwne. Odwoływanie się od czegoś, co nikt nie rozstrzygnął, nie daje nic; ponowne przesyłanie odrzucenia powoduje to samo odrzucenie. Parsed outcome określa, co się stało — denied wobec not-considered — a AAA04 zawiera własne zalecenie płatnika, czy wniosek jest w ogóle odzyskiwalny.

Częściowa certyfikacja jest zgłaszana jako partially-certified, a nie jako złożona do zatwierdzenia. Istnieje numer autoryzacji do rozliczenia, więc jest uznawana za zatwierdzoną, ale ilość zatwierdzona nie jest taka sama jak ilość wnioskowana — a praktyka rezerwująca sześć sesji przeciwko trzem zatwierdzonym odkrywa to podczas czwartego roszczenia.

Kod akcji, którego Perfuse nie rozpoznaje, jest zgłaszany jako unknown, a nie jako oczekujący. Oczekujący jest odczytywany jako „czekaj”, a czekanie jest niewłaściwą akcją dla większości tego, czym może być nieznany kod.

Kanał może trasować decyzję bezpośrednio:

filter: HCR-1 == "A3"

Konwertowanie między dwoma

Perfuse konwertuje sparsowaną 278 w Da Vinci PAS ClaimResponse i raportuje każdy osąd, który konwersja wymagała, zamiast tylko wyniku. Konwersja postępuje zgodnie z trzema regułami:

Zmniejszenie do słownictwa trzech stanów — zatwierdzone, odrzucone, oczekujące — jest dostępne i wyraźne o tym, co odrzuca. Zmniejszenie odmowy do rozpatrzenia daje „odrzucone” i mówi słowami, że właściwą akcją jest poprawiona ponowna zgłoszenie, a nie apelacja.

Sprawdzono przeciwko PAS 2.2.1, a nie tylko przeciwko sobie

The ClaimResponse jest ukształtowany do profilu Da Vinci PAS 2.2.1 i został sprawdzony z oficjalnym walidatorem HL7 załadowanym z opublikowanym pakietem PAS. Pierwsza wersja została sprawdzona tylko przez własne testy Perfuse, a walidator odrzucił ją z sześcioma do ośmiu błędami na zasób. Każdy z nich to coś, co punkt końcowy PAS płatnika również odrzucił:

Co było nie takGdzie PAS umieszcza to
Decyzja była w adjudication.category i reason.Rozszerzenie reviewAction, na rozstrzygnięciu, którego kategoria jest submitted.
Kod powodu nazwany elementem X12 1034.Zewnętrzna lista kodów X12 886.
Oczekujący wniosek odpowiedział outcome: queued.outcome dotyczy przetwarzania i PAS zezwala tylko complete, error i partial. Oczekiwanie to complete, z akcją przeglądu A4.
processNote.type był CodeableConcept.R4 ma kod: print.
patient, created, insurer i request były nieobecne.Wszystkie cztery są wymagane. Są podane jako odniesienia do identyfikatora, ponieważ odpowiedź stoi samodzielnie, a nie w pakiecie.

Poprawiony wynik jest ważny bez błędów dla certyfikacji, odrzucenia i oczekiwania. Ostrzeżenia, które pozostają, to walidator mówiący, że nie może załadować systemów kodów X12, które X12 licencjonuje. Numer autoryzacji jest przenoszony w reviewAction.number, gdzie własny przykład przewodnika umieszcza go, i w preAuthRef, gdy odpowiedź ma tylko jeden.

Walidator nie jest częścią make check, ponieważ potrzebuje Javy i pobrania przewodnika oraz jego zależności. To, co znalazł, jest przechowywane przez test: każda reguła, którą egzekwował, jest potwierdzona, więc zmiana, która ponownie wprowadza jeden z tych błędów, kończy się niepowodzeniem.

The Claims & auth view konwertuje wklejony 278 i pokazuje decyzje, notatki i zasób.

8.3.7 Załączniki i dlaczego wymagają specjalnego przetwarzania

CMS-0053-F czyni 275 standardem HIPAA dla załączników do roszczeń, z wymaganą zgodnością do 26 maja 2028 r. Przenosi dokument — notatkę operacyjną, raport obrazowy, zeskanowany formularz — powiązany z roszczeniem, które wspiera.

The 277 jest drugą połową tej samej rozmowy. Płatnik otrzymuje roszczenie, decyduje, że potrzebuje dokumentacji, i wysyła 277 z prośbą o nią; dostawca odpowiada 275.

Kanał może trasować na kodzie statusu bezpośrednio, ponieważ STC01 jest złożonym i jego drugi składnik to status. Napisany w postaci kanonicznej, ponieważ składnik jest adresowany kropką, a dwie notacje nie mogą być mieszane — STC-1.2 to element 1, składnik 2:

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

To są kody, które niezmiennie oznaczają, że dokument jest wymagany. Kategoria statusu w STC-1.1 jest celowo nie używana sama: R4 oznacza wniosek o dokumentację w niektórych przewodnikach implementacyjnych i „przekazany gdzie indziej” w innych, więc filtr na samej kategorii umieściłby ostateczne roszczenia w kolejce do śledzenia.

Dwa identyfikatory decydują, czy załącznik jest kiedykolwiek skojarzony ze swoim roszczeniem, a oba są raportowane: numer kontroli załącznika, który dostawca umieścił na oryginalnym roszczeniu, aby powiedzieć, że dokumentacja nastąpi, i numer śledzenia, który odpowiada prośbie płatnika. Załącznik, który przychodzi z żadnym z nich, jest plikowany i nigdy nie jest połączony z niczym, podczas gdy roszczenie się starzeje.

Dokument wewnątrz 275 nie jest interpretowany. Perfuse raportuje jego bajty i to, co nadawca mówi, że są. Załącznik może być plikiem PDF, TIFF, dokumentem CDA lub wiadomością HL7, a kanał, który potrzebuje treści, może przekazać te bajty do formatu, który je czyta.

Formularz 006020, który jest tym, który reguła przyjmuje

CMS-0053-F przyjmuje wersję 006020, a jego 275 różni się od formularza 005010 w dwóch istotnych sposobach.

Perfuse rozpakowuje encję i raportuje dokument wewnątrz niej, wraz z jego typem zawartości i nazwą pliku. Raportowane bajty są dokładnie tymi, które nadawca zawinął. Encja, która nie może być rozpakowana, pozostawia surowy ładunek w miejscu, z notatką mówiącą, dlaczego.

Budowanie 275. Perfuse również buduje załączniki 006020X314: jeden niespodziewany, który towarzyszy roszczeniu, lub odpowiedź na żądanie płatnika 277. Różnica polega na BGN01 02 przeciwko 11, oraz na tym, czy TRN02 zawiera PWK06 roszczenia, czy TRN02 277. Każda zbudowana wymiana jest ponownie analizowana przed jej zwróceniem, a odpowiedź mówi, czy dokument wewnątrz jest tym, który wszedł.

Struktura pochodzi z dwóch opublikowanych przewodników towarzyszących dla 006020X314: przewodnika CMS esMD i UnitedHealthcare. Nie pochodzi z raportu technicznego X12, który X12 udostępnia na podstawie licencji, a który ten projekt nie posiada.

Nie ma walidacji przeciwko raportowi technicznemu. Przewodnik partnera rządzi.

8.3.8 Podpisy elektroniczne na załącznikach

CMS-0053-F również przyjmuje standard podpisu, w 45 CFR 162.2002(e): Przewodnik implementacji HL7 dla CDA Release 2, Podpisy cyfrowe i delegowanie praw, Release 1. Stosuje się do podpisów umieszczonych na informacjach o załączniku, gdy są one wysyłane w transakcji załącznika HIPAA, od 26 maja 2028 r. Płatnik nie może żądać więcej, niż przewiduje przewodnik.

Perfuse podpisał C-CDA w ten sposób na swojej drodze do 275, i sprawdza podpisy na każdym C-CDA w 275, który czyta.

Jeśli jakakolwiek z tych rzeczy jest niedostępna, podpis jest nadal tworzony i obowiązuje. Wynik nazwuje formę XAdES, której osiągnął, i mówi, co go powstrzymało przed osiągnięciem X-L: na przykład certyfikat samopodpisany (brak urzędu certyfikacji do zapytania) lub brak władzy znaczników czasu.

Klucz to -signing-cert i -signing-key. Umieść certyfikaty urzędu certyfikacji po certyfikacie sygnatariusza w tym samym pliku, aby ścieżka podróżowała z podpisem. Dla podpisu, który ma znaczenie, jak DSDR, certyfikat powinien nazwać klinicystę, z jego NPI, zamiast serwera. Podpisywanie jest akcją administracyjną, jak podpisywanie każdego dokumentu.

Przewodnik nie nazwał przestrzeni nazw dla własnych elementów. Perfuse umieszcza digitalSignature, authorizedSigner i SignaturePurpose w urn:hl7-org:sdtc. Podaje również cel jako typ zobowiązania XAdES z OID ASTM, który narzędzia XAdES rozumieją. Delegowanie praw, gdzie delegat podpisał się z asercją SAML od upoważnionego sygnatariusza, nie jest produkowane, a otrzymany jest zgłaszany jako niezweryfikowany.

Numer NPI dostawcy jest sprawdzany pod kątem cyfry kontrolnej. Płatnik dopasowuje załącznik do roszczenia częściowo na podstawie tego numeru, a błędnie wpisany numer pozostawia załącznik niedopasowany, podczas gdy roszczenie jest odrzucane z powodu braku dokumentacji.

Widok Roszczenia & auth tworzy 275 z wklejonego C-CDA lub przesłanego pliku, opcjonalnie podpisanego C-CDA, i czyta jeden z powrotem z wynikami każdego podpisu. Nic na tej stronie nie wysyła niczego: wymiana jest zwracana do dostarczenia przez kanał, który jest miejscem, gdzie należy partner, poświadczenia i ślad audytowy.

8.3.9 Segmenty binarne

Segment BIN zawiera surowe bajty, a surowe bajty zawierają separatory. Każdy inny segment X12 kończy się na terminatorze segmentu, więc zwykły parser znajduje segmenty, wyszukując jeden bajt; załącznik nie może być znaleziony w ten sposób. PDF zawierający ~ zostałby podzielony na kawałki, a każdy kawałek jest segmentem strukturalnie poprawnym — więc dokument jest obcięty, każdy segment po nim jest nieprawidłowo wyrównany, i nic nie zgłasza błędu.

Perfuse czyta liczbę bajtów, którą deklaruje segment, i pobiera dokładnie tyle bajtów. Dwa konsekwencje warte poznania:

Własny przewodnik esMD deklaruje 16 bajtów dla tego samego ładunku 53-bajtowego, który jego tabela poprawnie liczy jako 53. Perfuse odmawia tego przykładu, jak powinien. Test zawiera zarówno przykład z tabeli, jak i błąd w przykładzie, więc zmiana w którąkolwiek stronę jest zauważalna.

8.4 FHIR

8.4.1 W czym staje się komunikat HL7 v2

Typ komunikatu decyduje o tym, co jest produkowane, a każda konwersja raportuje podejmowane oceny jako notatki obok paczki.

v2FHIR
ADTPacjent, wizyta, gdy jest wizyta, stan na podstawie DG1 diagnozy (również wymieniony w wizycie diagnosis, przyjmujący jako AD), procedura na podstawie PR1 i nietolerancja na podstawie AL1. A28, A31, A29 i A24 dotyczą osoby, więc nie powodują wizyty ani diagnoz, ale zawierają nietolerancje.
ORUDiagnosticReport na podstawie OBR, z obserwacjami i próbką, oraz zamówieniem jako ServiceRequest (jego wnioskodawca OBR-16 lub ORC-12, jego status ORC-5); OBR-32 jest interpretatorem wyników, OBR-34 i OBR-35 wykonawcami. Wyniki są grupowane pod OBR przed nimi według pozycji, ponieważ OBX-4 nie jest niezawodny.
ORM, OML, OMGServiceRequest.
SIUWizyta, z pacjentem, praktykami z AIP i lokalizacjami z AIL.
MDMDocumentReference zawierający dokument.
VXUSzczepienie, jedno na RXA.

Wszystko inne produkuje Pacjenta i ostrzeżenie z nazwą typu, który nie został zamapowany.

Rezerwacja. Rezerwacja, ponowna rezerwacja, anulowanie i brak pojawienia się wszystkie lądują na tym samym spotkaniu. Jego tożsamość pochodzi z własnych numerów spotkania w SCH-1 i SCH-2, a nie z komunikatu, więc anulowanie aktualizuje rezerwację. Alternatywą byłoby drugie, anulowane spotkanie obok żywego, co pokazuje, że pacjent zarezerwował się na slot, który nie istnieje.

Dokumenty. Notatki tekstowe (TX, FT, ST) zachowują swoje przerwy wiersza, w tym puste wiersze, ponieważ pusta powtórka w notatce jest przerwą akapitu.

To jest to, o co prosi ramowa struktura interoperacyjności CMS 14: notatki z wykresu i dokumenty kliniczne zwracane jako załączniki FHIR.

Szczepienia. Dawka jest nigdy zgłaszana jako podana, gdy komunikat mówi inaczej.

Niewygodny wprowadzany. Każdy z nich jest zgłaszany w notatkach, a nie decyduje się o tym w ciszy:

Identifier.period. Władza przydzielająca z ISO OID (AUSHIC&2.16.840.1.113883.3.879&ISO) staje się urn:oid:. Kod typu spoza tabeli HL7 0203 jest przechowywany jako tekst, a nie jest oznaczony jako taki.

W przypadku innego zdarzenia, takiego jak A08, nic nie jest scalane, a ostrzeżenie informuje, że poprzedni identyfikator jest nadal aktywny.

strefę czasową, w przeciwnym razie przesunięcie na MSH-7 (v2 zakłada czas lokalny nadawcy), w przeciwnym razie UTC. Czas urodzenia jest wyjątkiem: bez przesunięcia z którychkolwiek z trzech jest pomijany, zamiast być oznaczony jako UTC, ponieważ błędne przesunięcie może przenieść urodzenie na inny dzień. birthDate jest przechowywany, a ostrzeżenie informuje, że czas został pominięty i że ustawienie strefy czasowej dla kanału go zachowuje.

się DocumentReference, na które Observation wskazuje w derivedFrom, ponieważ Observation R4 nie ma wartości załącznika. Porównanie SN = jest pomijane jako zbędne; <> zachowuje tekst, ponieważ żadna ilość nie może powiedzieć „nie równa się”.

ponieważ R4 wymaga klasy.

8.4.2 To, co dodaje witryna: skrypt bundle

Narodowy profil często chce tego, czego nie ma wiadomość HL7 v2: numer IK szpitala lub kod ODS, jaki poziom kontaktu jest odwiedziny (ISiK), czy dana nazwa jest imieniem, czy inicjałem (holenderski nl-core). Perfuse nie zgaduje tych informacji. Skrypt bundle_script miejsca docelowego fhir to miejsce, w którym strona może je dodać: JavaScript uruchamiany na każdym przekonwertowanym zestawie, jako bundle, przed jego walidacją i wysłaniem. To, co skrypt pozostawia, jest tym, co jest wysyłane, sprawdzane jak każda konwersja, a skrypt, który wyrzuca wyjątek, powoduje niepowodzenie wiadomości, tak jak każdy inny transformator. Konsola ma to pod *Dodaj to, co twoje systemy wiedzą* miejsca docelowego.

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.

Bundle przechodzi przez model Perfuse w drodze powrotnej, więc zmiany skryptu są sprawdzane i zapisywane w wersji FHIR miejsca docelowego. Członkowie, których model nie ma pola, są przechowywani tak, jak je skrypt napisał, wewnątrz typów danych również.

8.4.3 US Core 9.0.0 i USCDI v6

-us-core (i claim_us_core na miejscu docelowym fhir) umieszcza profil US Core w meta.profile, ale tylko w przypadku zasobu, który został sprawdzony pod kątem tego profilu i uznany za zgodny. Zasób, który nie spełnia wymagań, jest nadal konwertowany i wysyłany bez roszczenia, a uwaga podaje powód, taki jak „US Core wymaga typu spotkania, a to Spotkanie nie ma”. Kontrole są przepisywane z US Core 9.0.0, wersji zatwierdzonej przez proces ONC 2026 Standards Version Advancement Process dla USCDI v6. Obejmują one Pacjenta, Spotkanie, laboratoryjne Observation i DiagnosticReport, Specimen, Pracownika, Organizację, Lokalizację, Szczepienie, DocumentReference, spotkanie-diagnoza Condition i AllergyIntolerance.

To, co konwerter przenosi, według klasy danych USCDI v6:

USCDI v6OdJako
Dane demograficzne pacjentaPIDImię, data urodzenia, płeć, adres, telefon i e-mail, identyfikatory. Rasa i etniczność (PID-10, PID-22) w rozszerzeniach US Core, gdy są zakodowane w CDC Race and Ethnicity. Preferowany język (PID-15) jako BCP 47
Informacje o wizyciePV1Wizyta z typem, klasą, okresem, lokalizacją i uczestnikami
Informacje o placówcePV1-3Lokalizacja, z placówką jako zarządzającą Organizacją
Problemy, data rozpoczęciaDG1Stan (diagnoza wizyty). DG1-5 jest datą rozpoczęcia, zgodnie z mapą HL7 v2 na FHIR
Alergie i nietolerancje, reakcjaAL1Nietolerancja z kategorią, krytycznością i reakcją
LaboratoryjneORUDiagnosticReport, obserwacje, próbka (z SPM), ServiceRequest
ZamówieniaORM, OMLServiceRequest
SzczepieniaVXUSzczepienie
Notatki kliniczneMDMDocumentReference
Członkowie zespołu opiekiPV1, TXA, DG1Praktyk

Nie są przenoszone, ponieważ wiadomości v2 tego typu nie zawierają ich, lub Perfuse nie mapuje ich: Lekarstwa, Procedury, Cele i Preferencje, Oceny Stanu Zdrowia, Plan Opieki, Rodzinna Historia Medyczna, Urządzenia Medyczne (UDI), Informacje o Ubezpieczeniu Zdrowotnym, WSkaźniki Witale jako odrębny profil oraz Pochodzenie.

8.4.4 R4 w obie strony

Serwer FHIR deklarujący R4 akceptuje R4. Nie było to prawdą w przypadku Spotkań aż do tej wersji. Serwer konwertował to, co służył, do R4, ale czytał to, co otrzymywał, jakby było już w jego wewnętrznej formie, więc R4 Spotkanie zostało odrzucone z kodem 400. Tak samo było z każdym pakietem, jaki wyprodukowała własna konwersja ADT Perfuse, ponieważ każdy z nich zawiera Encounter.class, który R4 zapisuje jako pojedyncze kodowanie.

Zostało to znalezione pierwszy raz, gdy coś opublikowało przekonwertowane ADT do własnego serwera R4 Perfuse. Test teraz robi to dla każdego typu wiadomości, który został zamapowany, a inny sprawdza, czy wszystko, co zostało napisane jako R4, jest odczytywane bez zmian.

8.4.5 Międzynarodowy Podsumowanie Pacjenta

GET /fhir/Patient/{id}/$summary, lub GET /fhir/Patient/$summary?identifier=system|value, zwraca Międzynarodowe Podsumowanie Pacjenta (HL7 IPS 2.0.0): pakiet FHIR document zawierający Composition, który wylicza aktywne problemy pacjenta, alergie, leki, szczepienia, wyniki, parametry życiowe, procedury, urządzenia, choroby przeszłe, wywiad rodzinny i plany opieki, każdy z czytelną narracją. Jest to krótki rekord, który klinicyista, który nie spotkał się z pacjentem, czyta jako pierwszy, a także podsumowanie, które Europejska Przestrzeń Danych Zdrowia wymienia między krajami od 2029 roku.

Zostało ono zbudowane z tego, co przechowuje sklep FHIR, i nic nie zostało wymyślone:

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.

Exchange → Health links → Share wypełnia treść podsumowaniem pacjenta: wpisz identyfikator FHIR pacjenta i wybierz Użyj jego podsumowania pacjenta, a następnie przeczytaj je i utwórz link. Budowanie jest rejestrowane jako fhir.summary.

8.4.6 Podsumowania transferu dla opieki poacute (PACIO)

Gdy pacjent opuszcza szpital i udaje się do domu opieki, oddziału rehabilitacji lub opieki zdrowotnej w domu, elektroniczna dokumentacja medyczna (EHR) szpitala wysyła dokument C-CDA: podsumowanie przeniesienia, podsumowanie wypisu lub CCD. Perfuse konwertuje ten dokument w podsumowanie przeniesienia zgodnie z przewodnikiem PACIO Transitions of Care (hl7.fhir.us.pacio-toc 1.0.0): jeden pakiet FHIR R4 document, zawierający US Core 8.0.1, który system odbiorczy może zarchiwizować bez konieczności odczytywania XML przez nikogo.

Trzy sposoby, aby to zrobić:

Sprawdzono z oficjalnym walidatorem FHIR przeciwko profilowi Bundle TOC 1.0.0, przykładom C-CDA (podsumowaniu transferu, podsumowaniu wyjścia i CCD) HL7. Jeden błąd, który zgłasza, jest w przewodniku: każdy znak życiowy odpowiada zarówno jego simple-observation, jak i vital-signs Bundle entry slices, więc nie może być uniknięty przez żadnego nadawcę. Nie wykonano jeszcze: przekształcenie sekcji tylko tekstowych (status funkcjonalny, status psychiczny, plan opieki, urządzenia) w zasoby zakodowane i dokumentu TOC DocumentReference przewodnika, który indeksuje przechowywane podsumowanie transferu.

8.4.7 Subskrypcje

Z -fhir-subscriptions punkt końcowy FHIR wysyła powiadomienia, gdy utworzono lub zmieniono spotkanie lub wizytę. Postępuje zgodnie z FHIR Subscriptions R5 Backport IG dla R4, który jest używany przez CMS Interoperability Framework criterion 15 i TEFCA's FHIR roadmap do powiadomień o spotkaniach i wizytach.

Klient tworzy Subscription z nazwą tematu i opcjonalnym filtrem, takim jak Encounter?patient=Patient/123. Tematy są wymienione w oświadczeniu o możliwościach:

TematWyzwalaczFiltry
https://perfuse.health/fhir/SubscriptionTopic/encounterUtworzenie lub aktualizacja spotkaniapatient, status, class
https://perfuse.health/fhir/SubscriptionTopic/appointmentUtworzenie lub aktualizacja wizytypatient, status

Filtr, który nazywa cokolwiek innego, jest odrzucany, a nie ignorowany. Zignorowany filtr to subskrypcja, która powiadamia o każdym pacjencie, gdy klient poprosił o jednego.

Właściwości, wokół których zbudowana jest implementacja:

To, co klient może zmusić serwer do zrobienia, jest ograniczone celowo:

Jest wyłączone, chyba że zostanie poproszone, ponieważ raz włączone, klient FHIR może zmusić ten serwer do wysłania danych pacjenta do adresu URL wybranego przez klienta. Wymaga punktu końcowego R4, który akceptuje zapisy, i odmawia uruchomienia w przeciwnym razie.

Nie zaimplementowane, więc nikt nie musi się dowiedzieć, próbując:

Widok Subskrypcje pokazuje temat subskrypcji, filtr i punkt końcowy, ile zdarzeń miało miejsce, ile zostało zaakceptowanych i ile czeka, oraz ostatni powód, dla którego zostało odrzucone. Wartości nagłówka i ciąg zapytania punktu końcowego są wyłączone, ponieważ to tam żyją poświadczenia subskrybenta.

8.5 Standard telekomunikacyjny NCPDP

Roszczenia aptek. Nagłówek o stałej szerokości, po którym następują zmienne segmenty.

Dwa istotne szczegóły, oba łatwe do popełnienia błędu i wytwarzające prawdopodobne wyniki:

Nagłówek ma dokładnie 56 bajtów i jest o stałej szerokości. Krótki nagłówek nie może być wykryty samą długością, ponieważ obcięty nagłówek wraz z następującymi po nim segmentami nadal przekracza 56 bajtów. Wykrywanie odbywa się przez to, że poprawny nagłówek nigdy nie zawiera bajtu separatora, więc nagłówek jest skanowany w celu jego wykrycia, a wiadomość, która go zawiera, jest odrzucana z liczbą bajtów, o które jest za krótka.

0x1E i 0x1C są markerami początku grupy i pola, a nie separatorami. Traktowanie ich jako separatorów przesuwa każde pole o jedną pozycję w lewo, a większość wynikających z tego wartości pozostaje prawdopodobna — ilość ląduje tam, gdzie oczekiwano zaopatrzenia na dzień, a oba są liczbami.

Kanały NCPDP i SCRIPT są wykluczone z ramki MLLP, a to jest egzekwowane, a nie zalecane. Roszczenie może zawierać prawomocnie 0x1C, który jest własnym bajtem końca bloku MLLP, więc ramkowanie roszczenia skróciłoby je na pierwszym markerze pola.

8.6 NCPDP SCRIPT

E-prescriptions, w XML. Wewnętrzny pakiet nazywa się eprescribe, ponieważ script został zajęty przez silnik JavaScript.

Głównym problemem bezpieczeństwa jest flaga zastąpienia, a czyta się ją odwrotnie od intuicji: w sieci 0 oznacza, że zastąpienie jest dopuszczalne, a 1 oznacza wydanie zgodnie z zapisem.

Brak flagi zastąpienia jest odrzucany, a nie ustawiany domyślnie. Obie możliwe wartości domyślne docierają do pacjenta — jedna może wydać generyk, gdzie lekarz wymagał marki, a druga uniemożliwia zastąpienie, na które zezwolił lekarz — więc nie ma bezpiecznego założenia, a wiadomość zostaje zatrzymana.

Przepis na lek z listy II z uzupełnieniami jest odrzucany, a konstruktor nie wygeneruje go.

Odrzucenia i ostrzeżenia są przechowywane jako oddzielne listy, a nie jako jedna lista oznaczona stopniem nasilenia, ponieważ czytelnik, który musi sprawdzić pole stopnia nasilenia, aby wiedzieć, czy wiadomość została wysłana, ostatecznie nie sprawdzi go.

Elektroniczna uprzednia autoryzacja (PAInitiationRequest, PARequest, PAAppealRequest, PACancelRequest) i Real-Time Prescription Benefit są obsługiwane przez stronę płatnika pod /ncpdp/script i /ncpdp/rtpb, z formularza leków; zobacz CMS-0057.

8.7 DICOM

Obrazowanie. Perfuse może otrzymywać obiekty DICOM, wysyłać zapytania do zdalnego archiwum i przechowywać je w archiwum, za pomocą klasycznych usług sieciowych DICOM lub za pośrednictwem DICOMweb, i może utrzymywać własne archiwum dla programów do wyświetlania.

DICOM nie jest formatem wiadomości w tym samym sensie, co inne — obiekty są duże, a użycie rąk wskazuje więcej niż analiza ładunku. Tytuły called_ae i calling_ae są najczęstszą przyczyną, dla której pierwsze połączenie nie powiedzie się, a awaria wygląda jak problem sieciowy, a nie konfiguracyjny.

8.7.1 Co akceptuje nasłuchujący C-STORE

Otwarty, nasłuchujący DICOM akceptuje wszystko od każdego, kto może dotrzeć do portu. Cztery ustawienia pod To, co ten nasłuchujący akceptuje, zawężają to, a pierwsze z nich jest tym, które warto zrozumieć.

Tylko akceptuj te tytuły AE wywołujące jest ograniczeniem. *Wywołany* tytuł AE — ten obok adresu — jest nazwą, którą nadaje nadawca, więc identyfikuje ten nasłuchujący, a nie nadawcę, i nie jest ograniczeniem. Każdy, kto może dotrzeć do portu, może użyć poprawnego tytułu AE wywołanego, ponieważ jest on opublikowany dla nich. Bez listy dozwolonych nadawców każdy host w sieci może wysłać obrazy do kanału klinicznego.

Tylko akceptuj te klasy SOP i tylko akceptuj te składnie transferu przyjmują oddzielone przecinkami identyfikatory UID. Pusty akceptuje każdy rodzaj obiektu i negocjuje każde kompresję, jaką oferuje nadawca, co obejmuje rodzaje, których nie mogą obsłużyć miejsca docelowe tego kanału. Odrzucanie na poziomie stowarzyszenia jest bardziej czytelne dla nadawcy niż akceptowanie obiektu i awaria po późniejszym.

Największy obiekt akceptowany jest w bajtach, a zero oznacza brak ograniczenia. Całościowe obrazy i długie serie sięgają gigabajtów, więc ograniczenie jest gdzie indziej w pamięci.

8.7.2 DICOMweb

DICOMweb to DICOM nad HTTP: QIDO-RS wyszukuje, WADO-RS i WADO-URI pobierają, a STOW-RS przechowuje. Przeglądarki, takie jak OHIF, obsługują tylko DICOMweb, podobnie jak usługi chmury do obrazowania (Google Cloud Healthcare, Azure Health Data Services, AWS HealthImaging). Perfuse wykorzystuje go w trzech miejscach.

Archiwum obrazowania. Uruchom serwer z -dicomweb-archive DIR (Ustawienia › Dane › Archiwum obrazowania) i będzie on przechowywał obiekty w tym folderze, indeksowane w SQLite, i udostępniał je pod /dicomweb na adresie konsoli: QIDO-RS na poziomie badania, serii i instancji, WADO-RS dla obiektów, metadanych, klatek i danych masowych, WADO-URI pod /dicomweb/wado, oraz STOW-RS. Odczyt wymaga roli widza, a przechowywanie roli operatora, z sesją lub tokenem API; każdy odczyt i przechowywanie są rejestrowane w Aktywności jako dicomweb.read lub dicomweb.store. Konto ograniczone do najemcy lub grup kanałów jest odrzucane, ponieważ archiwum należy do całego serwera. Obiekty są przechowywane dokładnie tak, jak zostały odebrane, więc to, co widz otrzymuje, jest identyczne z tym, co zostało przechowywane. Klatki są zwracane w składni transferu, w której zostały przechowywane; żądanie, które wymagałoby transkodowania, odpowiada 406 zamiast przekonwertowanego obrazu.

Wyszukiwanie według atrybutu, którego archiwum nie indeksuje, odpowiada 400 zamiast ignorowania warunku i zwracania większej liczby badań, niż zostało poproszone. Indeksowane: nazwa pacjenta (wzorce, i dopasowanie nieostre z fuzzymatching=true), identyfikator pacjenta, data urodzenia, płeć, data i godzina badania (zakresy), numer akcesji, identyfikator badania, opis, lekarz kierujący, badanie, seria i SOP instance UIDs (listy), modalność, część ciała, numer serii i opis, SOP class, numer instancji, wiersze, kolumny i liczba klatek.

Źródło. type: dicomweb nasłuchuje STOW-RS, pod /dicom-web/studies domyślnie (ścieżka, którą używają Orthanc i dcm4chee), i wysyła każdy obiekt przez kanał jako wiadomość DICOM. Kanał wymaga dataType: dicom. Ustaw token noszący lub nazwę użytkownika i hasło: bez nich każdy, kto może dotrzeć do portu, może wysyłać obrazy do kanału. Odpowiedź wylicza każdy obiekt jako przechowywany lub nieudany, z powodem niepowodzenia DICOM, aby nadawca wiedział, które obiekty należy wysłać ponownie.

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}

Punkt docelowy znajduje się w dostawie, pod archiwami DICOMweb.

Wskazywanie OHIF na archiwum

Użyj źródła danych DICOMweb z qidoRoot i wadoRoot ustawionymi na adres archiwum (ekran Obrazowanie wyświetla go, wraz z całym blokiem źródła danych do skopiowania), wadoUriRoot na adres archiwum, po którym następuje /wado, imageRendering i thumbnailRendering na wadors, oraz supportsFuzzyMatching ustawiony na true. Widz na innym pochodzeniu wymaga tego pochodzenia w -dicomweb-cors (Dozwolone pochodzenia przeglądarki, które mogą wywołać ją), a jego żądania wymagają tokenu API w nagłówku Authorization, ponieważ przeglądarka na innym pochodzeniu nie wysyła ciasteczka sesji konsoli. Udostępnianie OHIF z tego samego pochodzenia za pomocą serwera proxy odwrotnego unika obu.

Przetestowane z Orthanc z wtyczką DICOMweb, w obu kierunkach: miejsce przeznaczenia przechowuje w Orthanc, a klient DICOMweb Orthanc wyszukuje archiwum Perfuse i pobiera badanie identyczne z tym, które zostało przechowywane. OHIF 3 wyświetla badania archiwum i wyświetla ich klatki z ustawieniami powyżej. OHIF i kilku innych klientów wysyła type= niezacytowane w nagłówkach Accept i Content-Type, co nie jest dozwolone przez RFC 2045; Perfuse akceptuje to.

8.8 IHE udostępnianie dokumentów: XDS.b, XCA, XDR, MHD, PIXm i PDQm

Dokumenty kliniczne udostępniane między organizacjami w sposób, w jaki robią to wymiany informacji o zdrowiu, Carequality i eHealth Exchange: repozytorium zawiera je, rejestr indeksuje ich metadane, a społeczność odpowiada na zapytania innych społeczności za pośrednictwem bramy. Uruchom serwer z -xds REPOSITORY-OID (Ustawienia › Dane › Udostępnianie dokumentów) i jest to wszystko trzy, w bazie danych tego serwera, pod następującymi adresami, z których każdy akceptuje token API jako token nośnika (rola widza do zapytania i pobrania, rola operatora do przesłania; większość domen powiązań dodaje wzajemne TLS na przedzie):

AdresAktorTransakcje
/xds/repositoryRepozytorium dokumentówITI-41 Udostępnij i zarejestruj zestaw dokumentów-b, ITI-43 Pobierz zestaw dokumentów
/xds/registryRejestr dokumentówITI-18 Zapytanie przechowywane w rejestrze (wszystkie trzynaście zapytań przechowywanych), ITI-42 Zarejestruj zestaw dokumentów-b
/xca/gatewayBramka odpowiedzi XCAITI-38 Zapytanie międzybramkowe, ITI-39 Pobierz międzybramkowo, z -xds-home-community urn:oid:...
/mhdOdbiorca i odpowiednik dokumentu MHDITI-65 Udostępnij zestaw dokumentów, ITI-66 Znajdź listy, ITI-67 Znajdź odniesienia do dokumentów, ITI-68 Pobierz dokument
/mhd/PatientDostawca PDQm i menedżer PIXmITI-78 Zapytanie o dane demograficzne pacjenta, ITI-83 Patient/$ihe-pix, z magazynu FHIR Pacjenci
/pixv3Menedżer PIX (HL7 v3)ITI-44 Karmienie tożsamości pacjenta HL7 V3, ITI-45 Zapytanie PIXV3, z indeksu pacjentów (-mpi)
/pdqv3Dostawca PDQ (HL7 v3)ITI-47 Zapytanie PDQV3, z kontynuacją i anulowaniem, z indeksu pacjentów

Transakcje SOAP są SOAP 1.2 z WS-Addressing i MTOM/XOP, gdzie dokumenty podróżują (dokument w linii jako base64 jest również akceptowany). Nieudana transakcja jest odpowiedzią na RejestrResponse z kodami błędów IHE, a nie błędem SOAP: XDSDuplicateUniqueIdInRegistry, XDSNonIdenticalHash, XDSPatientIdDoesNotMatch, XDSMissingDocument, XDSRegistryMetadataError (z polem, które jest brakujące), XDSStoredQueryMissingParam, XDSUnknownStoredQuery, XDSUnknownRepositoryId, XDSUnknownCommunity i UnresolvedReferenceException. Zastąpienie (RPLC, XFRM_RPLC) deprecjonuje dokument, który zastępuje, który następnie odpowiada tylko na zapytania dotyczące zdezaktualizowanych dokumentów; APND, XFRM i signs są przechowywane jako stowarzyszenia. Hash i rozmiar są obliczane przez repozytorium i sprawdzane w stosunku do tego, co podaje przesłanie. Dokumenty i metadane na żądanie (ITI-57) nie są obsługiwane, a przesłanie, które o nie prosi, jest odrzucane z powodem.

MHD to ten sam rejestr w FHIR: dokument dostarczony za pośrednictwem MHD jest znaleziony przez ITI-18 i za pośrednictwem XCA, a jeden dostarczony za pośrednictwem XDS.b jest znaleziony przez ITI-67. Identyfikator DocumentReference to identyfikator UUID wpisu, jego masterIdentifier to unikalny identyfikator, a adres załącznika to adres ITI-68 dokumentu. Pacjenci są rozwiązywani w identyfikatorze domeny powiązania z magazynu FHIR: pierwszy identyfikator, którego system to urn:oid:, lub pacjent przeniesiony w Bundle. PIXm odpowiada na każdy inny identyfikator pacjenta z tym podanym (sourceIdentifier=system|value, zawężony przez targetSystem), a 404 dla tego, którego nie zna; PDQm wyszukuje przez identyfikator, nazwę, datę urodzenia, płeć, adres i łącze.

Publikowanie. Destynacja xds kanału publikuje każdy dokument kliniczny, jaki otrzymuje, dokument CDA lub jeden przeniesiony w wiadomości HL7 v2, do dowolnego repozytorium XDS.b z ITI-41. Metadane są odczytywane z dokumentu: pacjent (identyfikator w patient_domain, władza przydzielająca domeny powiązania), tytuł, typ (jako typeCode i, chyba że ustawiony, classCode), czas tworzenia i usługi, autor, poufność, język i format (C-CDA 2.1 lub 1.1 strukturalna treść, XDS-SD lub mimeTypeSufficient, z jego szablonami); i uzupełnione o to, czego dokument nie mówi: identyfikator nadawcy source_id, facility_type i practice_setting każdego rejestru wymagają. Odpowiedź rejestru RegistryResponse decyduje o dostawie: niepowodzenie lub błąd w PartialSuccess to nieudana dostawa z kodami błędów rejestru.

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. Dodaj direct_from (Twój adres Direct) i direct_to (adresy odbiorców) i to samo miejsce docelowe wysyła XDR jako transport Direct, jak opisano w *XDR i XDM dla Direct Messaging* projektu Direct: blok adresowania Direct (urn:direct:addressing) w nagłówku SOAP nazwuje nadawcę i odbiorców, a intendedRecipient podania nazwuje każdego odbiorcę (||^^Internet^address). Wskaż url na punkt końcowy XDR odbiorcy lub HISP, który akceptuje XDR. XDR podróżuje przez TLS, zwykle z certyfikatem klienta (tls), i nie jest S/MIME. Źródło direct również akceptuje XDR (patrz poniżej Direct).

    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 i PDQ w wersji 3 HL7. Z indeksem pacjentów włączonym (-mpi), /pixv3 jest menedżerem PIX, a /pdqv3 jest dostawcą PDQ przez SOAP 1.2, dla szpitali i wymian, które nadal mówią profile v3 IHE. Źródło karmi pacjentów z ITI-44 (dodany rekord PRPA_IN201301UV02, zmodyfikowany PRPA_IN201302UV02, rozwiązany duplikat PRPA_IN201304UV02): pierwszy identyfikator pacjenta jest jego rekordem, inne i te w asOtherIDs są identyfikatorami, które niesie, a scalenie zagnieżdża identyfikator poprzedniego rekordu w przeżywającego, jak HL7 v2 A40. ITI-45 (PRPA_IN201309UV02) odpowiada innymi identyfikatorami osoby posiadającej jeden, zawężone przez dataSource, w Patient.id; zapytany identyfikator wraca tylko w powtarzającym się zapytaniu. ITI-47 (PRPA_IN201305UV02) dopasowuje dane demograficzne (nazwę, płeć, czas urodzenia, identyfikator, adres, łącze) z własnym dopasowaniem indeksu, minimumDegreeMatch jako wynik na 100, otherIDsScopingOrganization ograniczający domeny, i initialQuantity paginujący odpowiedź: reszta przychodzi z QUQI_IN000003UV01 przez dziesięć minut, lub jest odrzucany przez anulowanie. Odpowiedzi podążają za przypadkami transakcji: nieznany pacjent lub domena to AE z błędem 204 i lokalizacją parametru, znany pacjent z niczym w domenach zapytanych jest NF. v3 nazywa władzę tylko OID, więc identyfikator, którego system jest adresem URL bez OID za nim (niektóre numery krajowe) jest pomijany w odpowiedziach v3 i przekazywany przez FHIR; ustaw system identyfikatora przedsiębiorstwa na OID (urn:oid:..., w ustawieniach indeksu) dla EUID i opiekuna, aby się pojawić. Rola widza zapytuje, a rola operatora karmi; każda transakcja jest audytowana z identyfikatorem, a nie nazwą. Płaszczka v3 wysłana jako application/xml jest odpowiedzią tego samego rodzaju, co jest przydatne do testowania ręcznego.

Wymiana › Udostępnianie dokumentów pokazuje, co rejestr zawiera i gdzie jest on osiągalny, znajduje dokumenty pacjenta w tym rejestrze lub innym (rejestr ITI-18 lub brama ITI-38), pobiera jeden i publikuje dokument CDA ręcznie z metadanymi, które dałaby mu destynacja.

Weryfikowany przeciwko NIST XDS Toolkit 7.13.0, referencyjnej implementacji IHE: Perfuse's ITI-41, ITI-18 i ITI-43 przeciwko symulatorowi Rejestru/Magazynu (zaakceptowany bez błędów walidacji, dokument pobrany jest identyczny), oraz symulatorowi Bramy Inicjującej, który wysyła zapytania i pobiera z Perfuse's Responding Gateway za pośrednictwem XCA, bez błędów w logu. Każda wiadomość SOAP, którą Perfuse zapisuje, waliduje się przeciwko schematom ebXML Registry 3.0 i XDS.b, oraz MHD DocumentReference i SubmissionSet przeciwko IHE MHD 4.2.2 z walidatorem HL7 FHIR. XDR z xds miejsca docelowego z blokiem adresowania Direct został zaakceptowany przez symulator Odbiorcy Dokumentu narzędzia, którego walidacja metadanych znalazła jedną wadę opisaną w docs/verification.md, oraz przez walidator XDR ONC SITE, checklistę Direct XDR (h)(2) testów certyfikacji. Odpowiedzi PIX i PDQ v3 walidują się przeciwko schematom HL7 V3 IHE (NE2008 multicacheschemas), oraz własne przykładowe wiadomości IHE (karmienie ITI-44, scalanie, zapytanie ITI-45, zapytanie ITI-47, kontynuacja i anulowanie) są odpowiedzią zgodnie z opublikowanymi odpowiedziami. Nie sprawdzono jeszcze przeciwko niezależnej implementacji PIX lub PDQ v3, Gazelle lub Connectathon.

8.9 Bezpośrednia komunikacja zabezpieczona

Direct to sposób, w jaki amerykańscy dostawcy usług medycznych wysyłają sobie nawzajem skierowania, podsumowania i wyniki za pomocą bezpiecznej poczty e-mail: każda wiadomość jest podpisana certyfikatem nadawcy i zaszyfrowana do odbiorcy (S/MIME), oraz podróżuje między Dostawcami Usług Informacji o Zdrowiu (HISP), którzy wydają adresy i gwarantują ich autentyczność. Perfuse jest systemem krawędziowym obok Twojego HISP, a nie HISP: HISP wydaje Twój adres, jego certyfikat i klucz, oraz przechowujesz pakiet zaufania (taki jak DirectTrust). Perfuse przestrzega Direct Applicability Statement for Secure Health Transport 1.2, Implementation Guide for Delivery Notification, IHE XDM (ITI TF-1 Annex 15) dla dokumentów z metadanymi, Certificate Discovery for Direct Project Implementation Guide (DNS i LDAP), oraz XDR i XDM dla 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

Odbieranie. Źródło direct to serwer SMTP, do którego HISP dostarcza pocztę na Twój adres. Akceptuje tylko pocztę na ten adres (wszystko inne jest odrzucane na poziomie RCPT), wymaga STARTTLS, gdy podano certyfikat, i otwiera każdą wiadomość przed jej odczytaniem: odszyfrowuje ją przy użyciu Twojego klucza, weryfikuje podpis przy użyciu Twoich kotwic i sprawdza, czy certyfikat podpisujący jest dla adresu Nadawcy lub jego domeny. Wiadomość, która nie jest zaszyfrowana S/MIME, jest podpisana przez nadawcę, którego nie ufasz, lub jest podpisana certyfikatem dla kogoś innego, jest odrzucana na poziomie DATA z powodem, więc HISP ją zachowuje i zgłasza ją do nadawcy; Perfuse nigdy nie akceptuje tego, co później odrzuca. Dokumenty pakietu XDM stają się wiadomościami (sprawdzanymi pod kątem sum kontrolnych w metadanych); w przeciwnym razie każza załącznik staje się wiadomością, lub tekst, gdy nie ma załączników. Z ustawionym smtp_host każda odebrana wiadomość jest odpowiedziana sygnowaną, zaszyfrowaną notyfikacją "przetworzona" (MDN), a notyfikacje przychodzące dla tego, co wysłano, są rejestrowane.

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

Z skrzynki pocztowej HISP. HISP, który zatrzymuje pocztę zamiast ją dostarczać, daje adresowi skrzynkę pocztową IMAP: imap odczytuje ją (TLS lub STARTTLS, każde sondowanie to nowa sesja), otwiera każdą wiadomość jak powyżej, przenosi to, co zostało pobrane, do move_to (lub kasuje je) i to, co nie mogło być otwarte, do error_folder, tak aby nic nie było odczytywane dwukrotnie. listen może być wtedy pominięty. HISP, którego serwer pocztowy ma certyfikat prywatny, jest ufały z tls.ca_file (jego certyfikat lub certyfikat jego autoryzacji) i tls.server_name; weryfikacja nie może być wyłączona.

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

XDR. xdr przyjmuje XDR w /xdr na własnym adresie HTTPS, tak jak HISP wysyła Direct przekonwertowane na SOAP lub partner wysyła punkt do punktu: żądanie ITI-41 Provide and Register, którego dokumenty stają się komunikatami. Przesyłanie, którego blok adresowania Direct nazwał inny adres, jest odrzucane, a jeden, który kanał nie przyjmuje, jest odpowiedzią z niepowodzeniem Rejestru, mówiącą, dlaczego. client_ca_file wymaga certyfikatu klienta od tych władz. XDR jest chroniony przez TLS, a nie S/MIME, więc źródło, które przyjmuje tylko XDR, potrzebuje adresu, ale nie jego certyfikatu, klucza ani kotwic. Każdy dokument staje się komunikatem dataType kanału: dokumenty CDA wymagają raw (przekazywane tak, jak są) lub hl7v3, ponieważ domyślny, hl7, oczekuje HL7 v2 i odmawia im.

    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

Wymiana › Direct wyświetla adresy Direct, które Twoje kanały wysyłają i otrzymują, wraz z certyfikatami, datą wygaśnięcia i kotwicami; przechowuje książkę adresową korespondentów (imię, organizacja, notatki i certyfikat, wklejone z ich HISP lub znalezione w DNS lub LDAP, oraz odrzucone, gdy nie jest dla tego adresu lub domeny); oraz wyszukuje certyfikaty adresu w DNS lub LDAP bez zapisywania ich. Książka jest katalogiem direct-certs obok bazy danych, jeden plik PEM na adres lub domenę, który destynacja odczytuje, chyba że określa własny recipient_certs_dir.

Weryfikowany przeciwko OpenSSL 4.0 cms i smime w obu kierunkach: to, co Perfuse podpisywuje i szyfruje, OpenSSL weryfikuje i odszyfruje (PKCS#1 v1.5 i OAEP transport klucza), a Perfuse otwiera to, co OpenSSL podpisywuje i szyfruje (AES-128 i AES-256). Wiadomość utworzona z openssl smime i dostarczona przez SMTP jest otrzymywana, otwierana i zapisywana przez kanał, a ta, którą Perfuse wysyła do innego przez zastępczego HISP, który odpowiada z MDN, którą nadawca otwiera. Certyfikaty są znalezione w OpenLDAP 2.4 (związane z adresem i domeną, napisane przez własne ldapadd OpenLDAP); wiadomość Direct jest odczytywana z skrzynki pocztowej IMAP GreenMail i otwierana, a ta, która nie jest Direct, jest przenoszona do folderu błędów; XDR z miejsca docelowego xds jest pobierany przez źródło direct i odrzucany, gdy jest adresowany do kogoś innego, i akceptowany przez NIST XDS Toolkit's Document Recipient i ONC SITE's XDR validator; SITE's Direct XDR Edge Test Tool wysłał obie swoje minimalne i pełne wiadomości metadanych do źródła direct, które je pobrało. Przeciwko narzędziu Direct Certificate Discovery Tool ONC, miejsce docelowe Direct wybiera odpowiedni certyfikat lub żaden, we wszystkich 18 przypadkach odkrycia (D1 do D18: wygasłe, odwołane i wydane AIA certyfikaty, priorytet i waga SRV, niedostępny katalog). Źródło Direct odczytuje wiadomość z własnego HISP SITE (Apache James) przez IMAP z STARTTLS. Jeszcze nie przetestowane: wymiana SMTP z HISP SITE (AWS zatrzymuje pocztę wychodzącą na porcie 25 dla nowych kont) lub z akredytowanym HISP.

8.10 SQL na widokach FHIR

ViewDefinition (HL7 SQL na FHIR v2) zamienia każdy zasób FHIR jednego typu w wiersze nazwanych kolumn, każda kolumna jest wyrażeniem FHIRPath, aby dane FHIR mogły być odczytywane jako tabele przez DuckDB, Athena, Spark, magazyn danych lub arkusz kalkulacyjny. Perfuse uruchamia je za pomocą własnego silnika FHIRPath: column, zagnieżdżone select, forEach, forEachOrNull, repeat i unionAll, where, constant (każdy typ wartości[x]), kolumny collection, %rowIndex oraz klucze łączenia getResourceKey() i getReferenceKey(type).

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

Monitor › SQL na FHIR uruchamia widok nad magazynem FHIR tego serwera (jeden pacjent lub wszyscy) lub nad zasobami wklejanymi (NDJSON z eksportu wsadowego, Bundle, tablica JSON), wyświetla wiersze i pobiera je jako CSV, NDJSON lub Parquet. Rozpoczyna się od pięciu przykładowych widoków (dane demograficzne pacjenta, obserwacje z wartością, ciśnienie krwi, stany, spotkania) i zapisuje widoki do katalogu views obok bazy danych, jeden plik JSON każdy.

Punkt końcowy FHIR odpowiada na specyfikację $sql-run na poziomie systemu, za pomocą GET lub POST, dla ViewDefinition podanego w linii (subjectResource), przez subjectReference (ViewDefinition/<name>, zapisany widok) lub przez subjectCanonical (zapisany widok url), z _format (csv, ndjson (domyślnie), json lub parquet), header, patient, _since, _limit i resource, aby uruchomić nad zasobami wysłanymi z żądaniem zamiast magazynu. Jest to odczyt: token SMART potrzebuje zakresu odczytu dla typu zasobu widoku, token związany z jednym pacjentem otrzymuje tylko wiersze tego pacjenta, a zakresy szczegółowe zawężają zasoby odczytywane, tak jak robi to wyszukiwanie. Więcej niż milion wierszy wymaga _limit, patient lub _since.

perfuse sof -view v.json [-format csv|ndjson|json|parquet] [-o out] files... uruchamia widok nad plikami FHIR bez serwera: pliki NDJSON eksportu wsadowego, Bundles lub tablice.

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"

Pliki Parquet mają jedną grupę wierszy i nieściskane strony PLAIN; wartości logiczne są BOOLEAN, typy całkowite INT64, dziesiętne DOUBLE, a wszystko inne to łańcuchy UTF-8 (kolumna kolekcji jako jej JSON).

Weryfikowane z oficjalnym zestawem testowym SQL na FHIR (144 testy repozytorium sql-on-fhir.js tests/, uruchamianych przy każdym budowaniu: wszystkie przechodzą), a dane wyjściowe Parquet odczytywane z powrotem przez DuckDB 1.5.6 z odpowiednimi typami i wartościami. Nieobsługiwane: SQLQuery i SQLView Libraries (SQL nad tabelami widoków), $sql-export, _format=fhir oraz parametry source i group; każdy z nich jest odrzucany z powodem.

8.11 Cyfrowe miary jakości

Cyfrowa miara jakości liczy pacjentów w każdej populacji FHIR Measure w okresie pomiaru (początkowa populacja, mianownik, wykluczenia mianownika i wyjątki, licznik, wykluczenia licznika) i ocenia wynik. Odpowiedź jest FHIR MeasureReport, ukształtowana zgodnie z wytycznymi Da Vinci Data Exchange for Quality Measures (DEQM). To jest kierunek, w którym idą programy eCQM CMS i cyfrowe HEDIS NCQA.

W Perfuse kryteria populacji są FHIRPath ("language": "text/fhirpath"), uruchamiane przez ten sam silnik co SQL on FHIR. Każde kryterium jest oceniane raz na pacjenta. Jego punkt centralny jest to Bundle rekordu pacjenta (kompartament Pacjenta), i ma następujące zmienne: %subject (Pacjent), %periodStart i %periodEnd (okres, jako daty) i %"Measurement Period". Kryterium daje true lub false; pojedyncza wartość, która istnieje, jest uważana za 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()"
  }
}

Populacje zagnieżdżają się zgodnie z specyfikacją Measure. Pacjent jest w mianowniku tylko wtedy, gdy jest w początkowej populacji. Wykluczenie mianownika usuwa pacjenta przed oceną licznika. Wyjątek mianownika liczy się tylko dla pacjenta niebędącego w liczniku. Wynik proporcji to (licznik − wykluczenia licznika) / (mianownik − wykluczenia − wyjątki); wynik dla stosunku to licznik / mianownik; kohorta ma liczbę i nie ma wyniku. Podział kryteriów jednego poziomu dzieli każdą populację według ich wartości (płeć, na przykład).

Perfuse nie ma silnika CQL. Opublikowane CMS eCQMs i cyfrowe miary HEDIS są napisane w CQL, więc nie mogą być uruchomione tak, jak są. Miara, której kryteria są CQL, jest odrzucana z tym powodem. Napisz logikę jako FHIRPath zamiast tego. Odrzucane w ten sam sposób są oceny zmiennych ciągłych, stratyfikatory wieloskładnikowe i tematy Group lub Practitioner.

Monitor › Miary jakości ocenia miarę nad magazynem FHIR tego serwera lub nad wklejonymi zasobami, za okres. Oferuje trzy raporty: podsumowanie, podsumowanie z pacjentami w każdej populacji lub jeden pacjent. Ekran wyświetla populacje, wynik i straty, oraz pobiera MeasureReport. Rozpoczyna się od trzech przykładów: ciśnienie krwi pod kontrolą, diabetes z testem HbA1c i pacjenci widziani w okresie. Są to przykłady ilustracyjne, napisane dla tego podręcznika, i nie są miarami eCQM CMS ani HEDIS. Zapisz do magazynu FHIR sprawdza Miarę i zapisuje ją jako zasób Measure.

Punkt końcowy FHIR odpowiada na Measure/[id]/$evaluate-measure i Measure/$evaluate-measure?measure=<url>, za pomocą GET lub POST zasobu Parameters. Parametry:

Raport jest zwracany, a nie przechowywany. Operacja jest odczytem, więc token SMART potrzebuje dostępu do odczytu Measure i Patient. Token związany z jednym pacjentem otrzymuje indywidualny raport o tym pacjencie i żadnym innym.

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... ocenia miarę nad plikami FHIR (NDJSON, Bundles, tablice) bez serwera. -measure example:example-bp-control uruchamia przykład dostarczony z systemem, a -examples wyświetla listę dostępnych przykładów.

Zweryfikowane. Walidator HL7 FHIR sprawdza dostarczone Miary przeciwko FHIR R4, bez błędów. Sprawdza również raport podsumowania, indywidualny i lista podmiotów MeasureReport przeciwko profilom DEQM 5.0.0, również bez błędów. Niezweryfikowane: równoważność z opublikowanymi eCQM, ponieważ żadne z nich nie mogą być uruchomione tutaj bez CQL.

8.12 Indeks pacjentów (MPI)

Główny indeks pacjentów łączy rekordy przechowywane przez każdy system dla osoby (numer pacjenta w szpitalu, numer w klinice, numer w laboratorium) w jeden identyfikator przedsiębiorstwa, EUID. Jest wyłączony, dopóki ktoś nie zdecyduje się go utworzyć, ponieważ jest to tabela nazw pacjentów, dat urodzenia i identyfikatorów: włącz Ustawienia → Dane → Indeks pacjentów (lub serve -mpi) i zrestartuj. Znajduje się w mpi.db obok głównej bazy danych.

Karmienie go. Dodaj miejsce docelowe typu mpi (Indeks pacjentów w budowniczym) do kanałów, które przenoszą rejestracje. Czyta PID każdej wiadomości HL7 v2 lub pacjenta FHIR na kanale surowym. Własny identyfikator rekordu jest powtórzeniem PID-3 typu MR (id_type go zmienia); inne, oraz PID-19, stają się jego innymi identyfikatorami. Władza przydzielająca z uniwersalnym identyfikatorem (PID-3.4.2 z typem ISO) staje się urn:oid:...; ta z przestrzenią nazw jest mapowana przez authorities, lub staje się urn:perfuse:aa:<namespace>. A40, A34, A18 lub A39 łączy osobę posiadającą identyfikator MRG-1 z osobą posiadającą PID-3 (no_merge je ignoruje).

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

Dopasowywanie. Nowy rekord jest łączony w tej kolejności:

  1. Zaufane identyfikatory. Rekord dzielący identyfikator z systemem wymienionym jako zaufany (identyfikator narodowy, numer przedsiębiorstwa) jest tą samą osobą, bez oceny. Nigdy nie wymieniaj systemu, który jest współdzielony przez rodzinę, takiego jak numer subskrybenta płatnika.
  2. Ocena. W przeciwnym razie osoby, których rekordy mogą się pokrywać, są znalezione przez blokowanie (ten sam dźwięk nazwy rodziny i rok urodzenia, ta sama data urodzenia, lub ten sam numer telefonu) i oceniane z wagami Fellegi-Suntera nad nazwą rodziny i imieniem (Jaro-Winkler i Soundex, akcenty i znaki ignorowane, nazwy zamienione zauważone), datą urodzenia (zamieniony dzień i miesiąc to częściowa zgodność), płcią, kodem pocztowym, numerem telefonu i adresem. Tylko pola, które oba rekordy posiadają, są brane pod uwagę. Ocena jest dowodem znalezionym jako udział w możliwym dowodzie. Blokowanie używa pięciu kluczy, aby jeden błąd nie ukrywał osoby: dźwięk nazwy rodziny i rok urodzenia, data urodzenia, numer telefonu, dźwięki obu nazw (w dowolnej kolejności), oraz kod pocztowy z dźwiękiem nazwy.
  3. Decyzja. Domyślnie nic nie łączy się na podstawie oceny sama. Rekord oceniony na poziomie lub powyżej progu przeglądu (60%) staje się nową osobą, a możliwe dopasowanie czeka w kolejce przeglądu; te na poziomie lub powyżej progu automatycznego (90%) z nazwą rodziny i datą urodzenia obu zgodnych są oznaczone jako *pewne*. Łączenie dwóch osób w jedną (nałożenie) umieszcza wyniki jednego pacjenta w wykresie innego pacjenta, więc automatyczne łączenie jest przełącznikiem, który administrator włącza (Łącz pewne dopasowania bez pytania nikogo), gdy kolejka pokazała, że pewne są prawidłowe. Z włączonym, pewne dopasowanie łączy się, gdy żadna inna osoba nie uzyska tak wysokiej oceny. Poniżej progu przeglądu rekord jest nową osobą.

Numery narodowe. Numer NHS (i Szkocji CHI oraz numer opieki zdrowotnej i pielęgnacji w Irlandii Północnej), numer PPSN i IHI w Irlandii, numer KVNR w Niemczech, numer SVNR w Austrii, numer AHV w Szwajcarii, numer BSN w Holandii, numer rejestru narodowego w Belgii, numer matricule w Luksemburgu, numer INS we Francji (NIR i NIA), numer codice fiscale we Włoszech, numer DNI/NIE i CIP-SNS w Hiszpanii, numer SNS w Portugalii, numery osobiste w krajach nordyckich (Szwecja, Dania, Norwegia z numerem D, Finlandia, Islandia), numery bałtyckie, numer PESEL w Polsce, numery urodzenia w Czechach i na Słowacji, oraz numery węgierskie, rumuńskie, bułgarskie, chorwackie, słoweńskie i greckie są znane indeksowi. Każdy jest przechowywany w jeden sposób: pod systemem schematu, bez spacji i kropek, więc numer NHS wysłany jako urn:oid:2.16.840.1.113883.2.1.4.1|999 000 0018 przez jeden system i jako https://fhir.nhs.uk/Id/nhs-number|9990000018 przez inny system jest jednym identyfikatorem. Powtórzenie PID-3 wiadomości HL7 v2, którego typ identyfikatora jest NN i trzyliterowy kod kraju (NNDEU, NNNLD), jest odczytywane jako główny numer tego kraju, a typ NH z władzy NHS jako numer NHS. Każdy numer jest testowany na poprawność: jeden, który nie przejdzie testu, jest przechowywany w rekordzie, zgłaszany (zamaskowany) w odpowiedzi i nigdy nie jest używany do łączenia lub wyszukiwania, ponieważ błędny cyfra zwykle tworzy numer innej osoby. Numer CPR w Danii jest sprawdzany tylko pod kątem daty, ponieważ numery wydane od 2007 roku nie muszą przechodzić starego testu modułu 11.

Lista ustawień wyświetla każdy schemat wraz z jego formatem, sprawdzeniem i systemem, w którym jest przechowywany. Systemy pobrane z krajowych przewodników FHIR (UK Core, fhir.de, Nictiz, CH Core, ANS, HL7 Italia, MedCom, szwedzki, norweski i fiński rejestr OID) są oznaczone jako takie; pozostałe są domyślnymi wartościami, które można zmienić na wartości krajowe, co może być wykonane przez stronę dla każdego schematu (stara wartość jest nadal rozpoznawana). Zaufanie do schematu jest jednym kliknięciem. Krajowe numery są wyświetlane w pełni edytorom i powyżej domyślnie oraz maskowane (ostatnie kilka znaków) dla wszystkich innych; Kto widzi numery w pełni zmienia to, w dół do widzów lub w górę do administratorów tylko. Gdzie prawo kraju ogranicza użycie numeru (francuski Référentiel INS, irlandzki PPSN, belgijski numer rejestru narodowego, niemiecki §290 SGB V), ustawienia mówią o tym. GET /api/mpi/schemes wyświetla schematy, a POST /api/mpi/check sprawdza jeden numer bez zapisywania go. FHIR $match i PIXm odpowiadają na autoryzowane żądania klientów z numerami w pełni.

Data zapisana w formacie dzień-miesiąc lub miesiąc-dzień (08/15/1972) jest zachowywana w takiej postaci i nie jest dopasowywana do formatu rok-pierwszy: porządki amerykański i europejski nie zgadzają się, a zgadywanie połączyłoby nieodpowiednie osoby.

Ekran indeksu pacjenta (Build) wyświetla liczby, znajduje osoby po nazwie, numerze, EUID lub dacie urodzenia i otwiera każdą osobę: ich rekordy, każdy identyfikator oraz historia tego, co się z nimi stało i kto to zrobił. Edytorzy decydują o przeglądach (Ta sama osoba łączy je; Różne osoby trzyma je oddzielnie na zawsze), przenoszą rekord do innej osoby, usuwają rekord (Nie ta osoba), a łączą dwie osoby. Administratorzy ustawiają progi, zaufane systemy identyfikatorów, numery krajowe i system EUID. Każde wyszukiwanie i odczyt osoby są zapisywane w rejestrze audytu.

Odpowiadanie innym. POST /fhir/Patient/$match (operacja FHIR, jak IHE PDQm ITI-119 ją używa) przyjmuje Pacjenta i zwraca osoby, które mogą być nim, najlepsze jako pierwsze, każdy Pacjent, którego id jest EUID, z każdym identyfikatorem, search.score, oraz rozszerzeniem stopnia dopasowania (certain, probable, possible); onlyCertainMatches i count są honorowane. PIXm (/mhd/Patient/$ihe-pix, ITI-83) odpowiada z indeksu: każdy identyfikator każdego rekordu połączonego z osobą, oraz EUID. Tak robią również PIX i PDQ w HL7 v3 (/pixv3, /pdqv3; zobacz dokumenty IHE), które również je zasilają.

Interfejs API to /api/mpi (podsumowanie i wyszukiwanie), /api/mpi/persons/{euid}, /api/mpi/find, /api/mpi/reviews, /api/mpi/records (rejestr, link, unlink), /api/mpi/merge i /api/mpi/settings.

Wagi. Domyślne wagi Fellegi-Sunter pochodzą z literatury o łączeniu rekordów dla danych rejestracji szpitalnej. Oszacuj z naszych rekordów (w ustawieniach, administratorzy; POST /api/mpi/estimate) dopasowuje je do indeksu strony z oczekiwaną maksymalizacją, bez potrzeby przeglądanych par: m (zgodność wśród prawdziwych dopasowań) z par, które blokada łączy, u (zgodność przypadkowa) z 20 000 par losowo wybranych, ponieważ pary zablokowane zgadzają się w nazwach i datach przez konstrukcję. Oszacowanie jest wyświetlane obok używanych wag i nie zmienia nic, dopóki nie jest użyte i zapisane. Pole porównywane na zbyt małej liczbie par zachowuje swoją domyślną wartość. Dopasowanie zakłada, że pola są niezależne od klasy, co nie jest całkowicie prawdą, więc traktuj dużą zmianę z podejrzeniem.

Pomierzone. Na zestawie danych FEBRL 3 (5 000 syntetycznych rekordów 2 000 osób, duplikaty z błędami pisarskimi, pola zamienione, brakujące wartości i pseudonimy; PERFUSE_TEST_FEBRL), zarejestrowane w kolejności pliku z przeglądającym odpowiadającym na każdą parę w kolejce poprawnie:

Połączone sameUmieszczone przed przeglądającym z odpowiednią osobąPominięteBłędne połączenia
Automatyczne łączenie wyłączone (domyślnie)02 649 z 3 0003510
Włączone, domyślne wagi1 6371 0123510
Włączone, wagi oszacowane z rekordów1 6221 0703080

Żaden rekord nie był nigdy połączony z niewłaściwą osobą, a żadna z 2 000 nowych osób nie była niepotrzebnie umieszczona w kolejce. Pominięte osoby różnią się prawie we wszystkich polach (data urodzenia i adres oba źle wpisane, na przykład) i mają wynik poniżej progu przeglądu. FEBRL jest syntetyczny i ma niewiele osób o tym samym imieniu; rzeczywisty indeks ma ich więcej, więc jego kolejka przeglądu będzie dłuższa, a te liczby są dolną granicą staranności, a nie obietnicą.

8.13 Ograniczone

CSV i jego krewniacy. Opcje znajdują się na źródle w budowniczym, a odniesienie do formatu listuje klucze plików.

Ścieżki adresują kolumny. Nazwana kolumna jest dostępna, gdy wiersz nagłówka jest deklarowany lub nazwy są podane; w przeciwnym razie kolumny są pozycyjne.

8.13.1 Nazwanie kolumn

Istnieją dwa sposoby, a są one wykluczające się. Albo pierwszy wiersz pliku nazywa je — pierwszy wiersz nazywa kolumny — albo sami je wymieniasz, w porządku. Deklarowanie nagłówka oznacza, że wiersz nie jest traktowany jako dane.

Jeśli żadna z nich nie jest ustawiona, kolumny mogą być adresowane tylko przez pozycję, więc filtr napisany przeciwko nazwie nie ma nic do dopasowania. Włączenie nagłówka usuwa listę nazw zamiast zachować obie: z nagłówkiem nazwy pochodzą z pliku, więc lista pozostawiona z tyłu byłaby ignorowana, a kanał, który czyta tak, jakby wybrał nazwy, gdy plik wybrał je, jest trudniejszy do debugowania niż ten, który odmawia.

8.13.2 Co widzi filtr lub skrypt

Jeden dokument ograniczony staje się wieloma wiadomościami, więc trzeba to stwierdzić, zanim napiszesz którykolwiek z nich.

Z dzieleniem włączonym, wszystko działa na wiersz. Declaratywne kroki, filtr i skrypt transformatywny widzą jeden wiersz, a ścieżka oznacza *ten* wiersz kolumny. Filtr, który odrzuca wiersz, odrzuca tylko ten wiersz, a otrzymana liczba jest wierszami, a nie dokumentami.

Z dzieleniem wyłączonym, wiadomość jest cały dokument i zapis, który przekracza wiersze, jest odrzucany, a nie stosowany do pierwszego. To odrzucenie jest celowe: ciche zapisywanie do wiersza jeden jest zachowaniem, które produkuje plik, który wygląda na przekształcony i nie jest.

8.13.3 Trzy, które zmieniają to, co uważa się za błąd

Akceptuj wiersze z niewłaściwą liczbą kolumn jest wyłączone domyślnie. Wiersz z zbyt wieloma lub zbyt małymi kolumnami jest wtedy błędem, co jest tym, co łapie plik, którego kształt zmienił się bez ostrzeżenia. Włączenie go akceptuje wiersz i pozostawia brakujące kolumny puste.

Przytnij spacje wokół każdej wartości naprawia powszechny przypadek wartości wypełnionej do szerokości kolumny. Pozostaw to wyłączone, gdzie spacje końcowe są istotne, co zdarza się czasem w identyfikatorze.

Zachowaj puste linie jako wiersze jest wyłączone domyślnie i zwykle powinno być. Włączone, pusta linia staje się wierszem pustych kolumn, co ma znaczenie tylko wtedy, gdy liczba musi dokładnie odpowiadać plikowi.

8.14 Surowy

Żadnego parsowania. Wiadomość to bajty.

Użyj tego, gdy zawartość nie jest czymś, co Perfuse rozumie i nie potrzebuje: PDF przenoszony między systemami, format własny, już utworzony dokument przekazywany niezmieniony.

Koszt to to, że nic, co zależy od struktury, nie działa — żadna transformacja na poziomie pola, żaden filtr na polu, żadne porównanie na poziomie pola w sprawdzaniu parzystości. Kanał surowy jest rurą i szczerze mówi o tym, że jest nią.

8.15 Wybór

Jeśli wiadomość jest w wersji HL7 v2, użyj hl7, nawet jeśli masz zamiar przekazać ją bez zmian. Analiza daje Ci ślad, statystyki na poziomie pól, możliwość filtrowania później oraz możliwość porównywania. Użycie raw na treści, którą można przeanalizować, nie daje nic i powoduje utratę wszystkich tych funkcjonalności.

Użyj raw, gdy analiza zakończyłaby się niepowodzeniem lub byłaby nieprawdziwa w odniesieniu do zawartości.

CMS *Kill the Clipboard* prosi dostawców o zaakceptowanie rekordów pacjenta z kodu QR podczas rejestracji i o przekazanie rekordu wizyty w ten sam sposób. Kod QR zawiera SMART Health Link (shlink:/...): adres, 256-bitowy klucz i opcjonalnie etykietę, datę wygaśnięcia i flagę hasła. Wymiana → Linki zdrowotne odczytuje jeden.

Odbieranie. Wklej link lub zeskanuj go za pomocą kamery, gdzie przeglądarka może (Chrome i Edge). Perfuse pobiera manifest, odszyfrowuje każdy plik za pomocą klucza z linku, podsumowuje każdy pakiet FHIR - kim jest pacjent, ile zasobów każdego rodzaju - i sprawdza każdą SMART Health Card w środku przeciwko opublikowanemu kluczowi wydawcy. *Dostarcz do kanału* przekazuje zawartość FHIR do kanału jako wiadomość, co pozwala jej dotrzeć do EHR. Pobieranie jest ograniczone do polityki wyprowadzania na czas połączenia, odmawia się plain HTTP, a odpowiedź serwera, który nie jest serwerem manifestu, nigdy nie jest wyświetlana, ponieważ adres pochodzi z obcego kodu QR.

Udostępnianie. *Udostępnij* szyfruje pakiet FHIR, hostuje go i wyświetla link oraz jego kod QR raz. Serwer zachowuje ciphertext, a nie klucz - nie może otworzyć tego, co hostuje, i nie może pokazać linku ponownie. Hasło jest hashowane; dziesięć błędnych haseł wyłącza link. Linki wygasają po 30 dniach domyślnie, mogą być unieważnione i wyświetlają, jak często i przez kogo były pobierane. Uruchom serwer z -public-url ustawionym na adres https, który telefon pacjenta może osiągnąć; adres URL manifestu, który buduje, musi pasować do specyfikacji 128 znaków.

Weryfikacja karty. *Weryfikuj karte* przyjmuje numeryczny shc:/ QR (jeden fragment lub kilka), plik .smart-health-card lub JWS i stwierdza, czy podpis pasuje do klucza wystawcy.

8.17 UN/EDIFACT

dataType: edifact odczytuje wymiany UN/EDIFACT (ISO 9735): ORDERS, INVOIC, DESADV, IFTSTA i resztę, w tym europejskie wiadomości dotyczące ochrony zdrowia i laboratoryjne. Ciąg znaków ostrzegawczych usługi (UNA) jest honorowany, wraz z znakiem zwalniania i, dla wersji składni 4, separatorem powtarzania; grupy funkcjonalne (UNG/UNE) są opcjonalne. Wymiana jest dostarczana dokładnie tak, jak ją napisał nadawca.

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

Koperta. Liczba segmentów UNT i odniesienie, liczba wiadomości UNE i odniesienie, oraz liczba i odniesienie UNZ są porównywane z tym, co zawiera wymiana. Z require, domyślnie, niezgodność odmawia wymiany (jest to sposób, w jaki przerwany transfer jest wyświetlany); warn akceptuje ją i rejestruje ostrzeżenie; ignore nie sprawdza.

Ścieżki, dla filtrów kanału i miejsca przeznaczenia, liczą elementy i składniki od 1 w kolejności, w jakiej segment jest zapisywany, tak jak przewodniki implementacyjne je numerują: BGM-2 (numer dokumentu), BGM-1.1, NAD(2)-2.1 (strona drugiego NAD), LIN-3(2).1 (powtórzenie), UNB-2.1 (nadawca), UNH-2.1 (typ wiadomości). Ścieżka bez wystąpienia adresuje każdy z nich.

Dzielenie dostarcza jedną wymianę na wiadomość, każdą z oryginalnym UNB (i nagłówkiem grupy) i trailerami, które liczą jeden, więc zamówienie może być filtrowane, wyszukiwane i ponawiane samodzielnie. Filtry miejsca przeznaczenia widzą każdy kawałek. Miejsce przeznaczenia pliku nazywa pliki według typu wiadomości (ORDERS_INVOIC-20261017.edi), a ${control_id} jest odniesieniem do wymiany.

STER. KONTROLNY. Z acknowledge: contrl, nadawca wysyłający za pomocą HTTP otrzymuje odpowiedź z składnią CONTRL i raportem usługi: akcja UCI 7 kiedy wymiana została odczytana i dostarczona, 4 kiedy została odrzucona lub nie mogła być dostarczona (wtedy HTTP 400 lub 502). Nie można jej łączyć z split, ponieważ CONTRL odpowiada na całą wymianę. Przy użyciu AS2 potwierdzenie odbioru przez partnera jest potwierdzeniem.

Nie jest oferowane: katalogi wiadomości (które segmenty ORDERS D.96A zezwalają), więc struktura jest sprawdzana, a nie zawartość; transformacje, które przepisują dokument partnera; oraz skrypty filtrujące lub transformatory (preprocesor jest uruchamiany przed parsowaniem). Sprawdzono w stosunku do pydifact 0.1.8, niezależnego parsera, w obu kierunkach.

9 Potwierdzenia

Potwierdzenie informuje nadawcę, co się stało. Dla HL7 v2 za pośrednictwem MLLP jest to wiadomość ACK; nadawca nie wyśle następnej wiadomości, dopóki nie dotrze, i zwykle ponownie wyśle, jeśli nie dotrze.

Błędne potwierdzenia są najczęstszym sposobem, w jaki integracja cicho traci dane, ponieważ nadawca, który jest potwierdzany, nie ma powodu do skargi.

9.1 Czas

Opisane w przepływie wiadomości, a podsumowanie jest: ack.when jest on_delivery domyślnie, co oznacza, że potwierdzenie jest wysyłane tylko po tym, jak każde włączone miejsce przeznaczenia zaakceptuje wiadomość. on_receipt wysyła je tak szybko, jak tylko wiadomość jest przeanalizowana i umieszczona w kolejce.

9.2 Co Perfuse wysyła

AA, gdy wiadomość została zaakceptowana, AE, gdy została odrzucona z powodu, o którym nadawca mógł coś zrobić, i AR, gdy została odrzucona z powodu, o którym nadawca nie mógł nic zrobić.

Różnica między AE a AR polega na tym, kto musi coś zrobić. AE oznacza, że wiadomość miała problem - pole, które nie mogło być przeanalizowane jako data, brakujący wymagany segment - i nadawca może to poprawić i ponownie wysłać. AR oznacza, że Perfuse nie mógł zaakceptować go niezależnie od zawartości, co zwykle oznacza problem z konfiguracją lub dostępnością na tym końcu. Nadawca, który ponownie wysyła po AR, otrzyma tę samą odpowiedź.

9.3 Identyfikacja tego silnika

ack.application i ack.facility wypełniają MSH-3 i MSH-4 potwierdzenia.

Gdy oba są puste, potwierdzenie jest lustrzanym odbiciem oryginalnego odbiorcy — używa tego samego, co wiadomość przychodząca miała w MSH-5 i MSH-6. To jest to, czego większość nadawców oczekuje, i jest to ustawienie domyślne z tego powodu.

Ustaw je explicite, gdy nadawca je waliduje, lub gdy wiele instancji Perfuse obsługuje ten sam kanał i musisz wiedzieć, który z nich odpowiedział.

9.4 Zdarzenie wyzwalające

ack.include_trigger_event wysyła ACK^A01 zamiast gołego ACK.

Niektórzy odbiorcy wymagają tego, a inni odrzucają, co jest powodem, dla którego jest to opcja explicite bez domyślnego ustawienia. Jeśli nadawca odmawia twoich potwierdzeń i treść wygląda dobrze, to jest pierwsza rzecz do sprawdzenia.

9.5 Negatywne potwierdzenia nie są niepowodzeniami do ukrycia

Potwierdzenie negatywne (NACK) traktowane jako sukces jest jednym z najbardziej szkodliwych błędów konfiguracyjnych i jest na tyle powszechne, aby je nazwać. Zdarza się to, gdy destination wysyła z powrotem negatywne potwierdzenie, a strona nadawcza rejestruje *transmisję* jako pomyślną, ponieważ bajty wyszły i coś wróciło.

Perfuse odczytuje potwierdzenie, które otrzymuje od destination MLLP, i rejestruje wynik odpowiednio. AE lub AR z systemu podrzędnego jest awarią dostarczenia, jest powtarzany zgodnie z zasadą destination, i liczy się do współczynnika awarii, który wyzwala alarmy.

Jeśli migrujesz z innego silnika, warto to zweryfikować explicite na własnym ruchu, zamiast przyjmować. Sprawdzanie równości pokaże to: miejsce przeznaczenia, które starego silnika zostało zarejestrowane jako dostarczone, a Perfuse rejestruje jako nieudane, zwykle oznacza, że stary silnik ignorował NACK.

9.6 Limit czasu

Czekanie na potwierdzenie jest ograniczone. Gdy nie przychodzi ono na czas, dostarczenie jest awarią i jest umieszczane w kolejce do powtórzenia.

Limit czasu nie jest taki sam jak odrzucenie i jest rejestrowany inaczej. Odrzucenie oznacza, że druga strona rozważyła wiadomość i ją odrzuciła; limit czasu oznacza, że nie wiesz, czy została przetworzona. Ta różnica decyduje o tym, czy powtórzenie jest bezpieczne: powtarzanie po odrzuceniu jest bezcelowe, a powtarzanie po limicie czasu naraża na duplikat. Perfuse powtarza po limicie czasu, ponieważ brakująca wiadomość kliniczna jest zwykle gorszy niż duplikat, a system odbiorczy jest zwykle w stanie wykryć powtarzany identyfikator kontrolny wiadomości.

Czy ten handel jest odpowiedni dla danego kanału, jest sądem, i jest warte podjęcia celowo dla wszystkiego, gdzie duplikat ma konsekwencje kliniczne — zamówienie, podanie leku — zamiast akceptowania domyślnego ustawienia cicho.

9.7 Źródła, które nie potwierdzają

Nie każdy transport ma ten pojęcie. Źródło pliku nie ma gdzie wysłać potwierdzenia; źródło brokera potwierdza do brokera, a nie do oryginalnego nadawcy; źródło HTTP odpowiada kodem statusu.

Gdzie źródło nie może dostarczyć trybu potwierdzenia, o który prosi kanał, kanał jest odrzucany podczas ładowania, zamiast zaczynania i cicho nie potwierdzania. Kanał, który uważa, że potwierdza, a nie potwierdza, jest gorszy niż ten, który nie zaczyna.

9.8 Potwierdzenia X12

Wszystko powyżej dotyczy HL7 v2. X12 ma własne potwierdzenia, i w przeciwieństwie do v2 są wyłączone domyślnie: puste ustawienie oznacza brak.

To ustawienie domyślne jest bezpieczne, ponieważ partner handlowy, który nie oczekuje potwierdzenia i otrzymuje je, może traktować je jako niespodziewane połączenie. Klucz acknowledge na kanale X12 przyjmuje jedną z czterech wartości:

WartośćCo jest wysłane
noneNic. Domyślnie.
999Potwierdzenie implementacji. Zastępuje 997 dla transakcji HIPAA.
997Potwierdzenie funkcjonalne. Starsze, i nadal to, czego oczekują wiele połączeń płatników.
ta1Potwierdzenie wymiany, dotyczące koperty, a nie jej zawartości.

Które potwierdzenie wysłać, jest właściwością relacji partnerskiej handlowej, a nie wiadomości, co jest powodem, dla którego musi być skonfigurowane i nie może być wnioskowane. 999 zastępuje 997 dla transakcji HIPAA, ale wiele partnerów — starsze połączenia płatników — jest ustawionych do oczekiwania 997 i będzie traktować 999 jako nierozpoznany plik.

Wysłanie złego potwierdzenia jest gorsze niż wysłanie żadnego. Odpowiada na pytanie, które nikt nie zadał, pozostawiając prawdziwe pytanie otwarte, a nadawca nie ma sposobu, aby odróżnić.

9.9 Potwierdzenia HL7 v3

Kanał HL7 v3 wysyła potwierdzenie domyślnie, co jest przeciwieństwem X12 i warte zauważenia.

Powodem jest transport, a nie standard: interakcja v3 zwykle przychodzi przez połączenie synchroniczne, przy czym aplikacja wysyłająca czeka na odpowiedź, a nadawca, który nie otrzymuje nic, zwykle ponawia próbę. To jest sposób, w jaki pacjent zostaje zarejestrowany trzykrotnie.

Wyłączenie jest możliwe i musi być wykonane jawnie — „nie ustawiono” i „ustawiono na false” są celowo różne, więc domyślna wartość pozostaje, chyba że ktoś powiedział inaczej.

10 Dostarczanie, kolejkowanie i ponawianie

Miejsce docelowe, do którego nie można się połączyć, jest przypadkiem normalnym, a nie wyjątkiem. Systemy są uruchamiane ponownie, sieci przestają działać, a silnik interfejsu szpitala jest niedostępny podczas własnego okna konserwacji. Dostarczanie jest oparte na tym.

10.1 Kolejka na miejsce docelowe

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

Każde miejsce docelowe ma swoją własną kolejkę. Miejsce docelowe, które ulega awarii, nie wpływa na inne, a każde z nich ma własną głębokość, wiek i stan ponawiania.

Kolejkowanie odbywa się na podstawie miejsca docelowego, a nie kanału, ponieważ awaria dotyczy miejsca docelowego. Kolejka na poziomie kanału utrudniłaby dostarczanie do trzech działających systemów, ponieważ czwarty jest wyłączony, a obie sytuacje — jedno niedostępne miejsce docelowe, wszystkie cztery niedostępne — wyglądałyby tak samo w statystykach.

10.2 Ustawienia kolejki

queue on a destination:

KluczCo robi
enabledCzy wiadomości, które nie powiodły się, są kolejkowane w ogóle.
max_attemptsIle razy należy spróbować, zanim się poddaje.
backoffCzekaj przed pierwszą ponowną próbą.
max_backoffGórna granica rosnącego czasu oczekiwania.
max_depthNajwiększa liczba wiadomości do przechowywania. Brak ustawienia oznacza brak limitu.
retain_hoursJak długo dostarczona wiadomość jest przechowywana. Brak ustawienia oznacza przechowywanie przez czas nieokreślony.

Dwa ostatnie elementy były nieobecne w tej tabeli i w konstruktorze, a są to para, która zapobiega wypełnieniu dysku. Kolejka bez nich rośnie, aż system plików jest pełny, a awaria ta pojawia się jako coś niezwiązanego z awarią — niepowodzenie zapisu w innym miejscu — zamiast jako problem z kolejką.

Czas oczekiwania rośnie między próbami aż do max_backoff. Rosnący, a nie stały, ponieważ miejsce docelowe, które jest wyłączone, zwykle jest wyłączone na kilka minut, a nie sekund, a ponawianie prób co sekundę przez dziesięć minut powoduje kilkaset wpisów w dzienniku, które zakopują ten, który się liczy.

10.3 Zachowanie kolejności

W ramach miejsca docelowego wiadomości są dostarczane w kolejności przybycia, a wiadomość, która nie powiedzie się, zachowuje swoje miejsce. Późniejsze wiadomości czekają za nią, zamiast ją wyprzedzać.

Jest to odpowiedni domyślny ustawienie dla danych klinicznych — przyjęcie i wypisanie zastosowane w złej kolejności jest gorsze niż oba są spóźnione — i ma konsekwencję wartą zrozumienia: jedna wiadomość, która zawsze kończy się niepowodzeniem, zatrzymuje wszystko, co jest za nią.

Dlatego głębokość kolejki i wiek kolejki są oddzielnymi warunkami alarmowymi. Głęboka kolejka, która się wypuszcza, jest zajętym systemem. Kolejka, której najstarsza wiadomość stale się starzeje, jest zablokowana, a rodzaje alertów queue-depth, queue-age i queue-stuck odróżniają je.

Wiadomość trująca — taka, która nigdy nie powiedzie się, niezależnie od tego, jak często jest ponawiana — jest konkretną awarią, na którą jest wrażliwy ten projekt. max_attempts to ogranicza szkody: po tym wiadomość jest rejestrowana jako nieudana, a kolejka przechodzi dalej. Ustawienie max_attempts bardzo wysoko w nadziei na ostateczny sukces przekształca jedną nieudaną wiadomość w zatrzymany kanał.

10.4 Gdy kolejkowanie jest wyłączone

Z queue.enabled ustawionym na false, nieudane dostarczanie jest po prostu nieudanym dostarczaniem. Zostaje ono zarejestrowane i nie jest ponawiane.

Jest to odpowiedni wybór, gdy spóźnione dane są gorsze niż brak danych — wyświetlanie w czasie rzeczywistym, system powiadomień, wszystko, gdzie wiadomość dostarczona czterdzieści minut po zdarzeniu byłaby myląca, a nie po prostu opóźniona.

Jest to zły wybór dla wszystkiego, co trafia do rekordu, gdzie wiadomość jest równie ważna godzinę później.

10.5 Ponawianie a kolejkowanie

Istnieją dwa mechanizmy i działają one na różnych poziomach.

retry w miejscu docelowym określa natychmiastowe próby w ramach jednego dostarczania — połączenie, które kończy się niepowodzeniem, jest ponawiane po krótkiej przerwie, bez opuszczania ścieżki dostarczania. To obsługuje przejściowe awarie: przerwane połączenie, chwilowa odmowa.

queue określa, co się dzieje, gdy te natychmiastowe próby są wyczerpane. Wiadomość opuszcza ścieżkę dostarczania i jest ponawiana później według dłuższego harmonogramu.

Oba istnieją, ponieważ awarie są różne. Reset połączenia na pierwszej próbie zwykle znika na drugiej, a przechodzenie przez kolejkę dla niego dodałoby kilka minut opóźnienia do awarii, która trwała kilka milisekund. Miejsce docelowe, które zostało wyłączone na konserwację, nie wróci w ciągu trzech natychmiastowych prób, a uderzanie w nie jest bezcelowe.

10.6 Co HTTP endpoint uważa za dostarczone

Punkt końcowy HTTP ma trzy ustawienia, które decydują, czy wiadomość jest traktowana jako wysłana, a wszystkie trzy znajdują się w punkcie końcowym w konstruktorze.

Kody stanu, które oznaczają dostarczenie. Pusty oznacza dowolny kod 2xx. Niektóre punkty końcowe odpowiadają 202 Accepted dla czegoś, co jeszcze nie zostało przetworzone, a niektóre odpowiadają 200 z błędem w treści — to drugie jest tym, do czego służy *Traktuj jako nieudane, jeśli odpowiedź zawiera*.

Postępuj zgodnie z przekierowaniami. Wyłączone domyślnie i celowo. Przekierowanie może wskazywać na inny host, więc postępowanie zgodnie z nim wysyła wiadomość w miejsce, które nikt nie skonfigurował, i zgłasza sukces.

Token nośnika. Wysłany jako nagłówek Authorization. Zostaje przechowywany z kanałem i nigdy nie jest ponownie wyświetlany, więc pozostawienie pola pustego podczas edytowania istniejącego kanału zachowuje token już zapisany, zamiast go czyścić.

10.7 Nazwanie i przycinanie folderu archiwum

Miejsce przeznaczenia pliku domyślnie dołącza do jednego pliku na dzień i typ wiadomości (20261012-ADT_A01.hl7), ramki MLLP, więc plik odtwarza się za pomocą perfuse send. Cztery ustawienia w miejscu przeznaczenia zmieniają to.

Nazwa pliku (file_name) tworzy jeden plik na wiadomość, nazwany z ${date}, ${timestamp}, ${control_id}, ${message_type} i ${destination}. Nazwa, która jest już zajęta (ten sam identyfikator kontrolny dwa razy), otrzymuje unikalny sufiks zamiast nadpisywać wiadomość tam.

Dołącz (append: true) zapisuje każdą wiadomość do pliku Nazwa pliku, który nazwuje, więc ${date}.hl7 to jeden plik na dzień dla każdego typu.

Sufiks podczas zapisu (temp_suffix, jeden plik na wiadomość tylko) domyślnie .part i jest usuwany przez przemianowanie, gdy plik jest kompletny. Każdy, kto zbiera te pliki, nie powinien pobierać niekompletnego pliku, a przemianowanie w folderze jest atomowe. Zmień to tylko wtedy, gdy kolektor filtruje na innym rozszerzeniu.

Usuń po (retain_hours) przycina pliki w folderze starsze niż podana liczba godzin, sprawdzana co najwyżej co dziesięć minut, gdy przychodzą wiadomości. Tylko zwykłe pliki bezpośrednio w folderze są usuwane, nigdy podfolder. Pusty lub zero zachowuje je na zawsze, co jest domyślnym ustawieniem i jest decyzją, a nie zaniedbaniem — ale archiwum, które nikt nie przycina, wypełnia dysk, a pełny dysk zatrzymuje kanał, a nie archiwizację.

10.8 Wysyłanie do serwera FHIR

Trzy ustawienia decydują, ile jest sprawdzane przed wysłaniem paczki.

Oświadczenie o zgodności z US Core dodaje profil do każdego zasobu. Oświadczaj to tylko wtedy, gdy zasób zawiera to, co profil wymaga, ponieważ odbiorca może sprawdzić poprawność oświadczenia i odrzucić paczkę, która w przeciwnym razie zostałaby zaakceptowana.

Sprawdź poprawność przed wysłaniem sprawdza każdy zasób tutaj, zamiast uczyć się od odbiorcy. Odrzucenie na drugim końcu mówi ci mniej, później i często tylko w logu, którego nie możesz przeczytać.

Traktuj ostrzeżenia jako odrzucenia ma wpływ tylko wtedy, gdy walidacja jest włączona, a kontrola jest niedostępna, dopóki nie jest. Jest wystarczająco surowy, aby zatrzymać paczkę, którą odbiorca zaakceptowałby, więc należy ją umieścić na kanale, który jest wprowadzany, a nie w służbie.

10.8.1 Usługi FHIR hostowane

Blok fhir punktu końcowego auth loguje się do usług hostowanych, gdzie wklejony token nośnika przestaje działać w ciągu godziny:

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 podpisać każde żądanie dla AWS HealthLake z wersją 4 podpisu, z regionem odczytanym z adresu URL. azure otrzymuje token Microsoft Entra ID dla Azure Health Data Services z tenant_id, client_id i client_secret - rejestracji aplikacji posiadającej rolę FHIR Data Contributor - z adresem URL usługi FHIR jako jego odbiorcą. client_credentials robi to samo przeciwko dowolnemu adresowi URL tokenu OAuth 2.0 token_url. Tokeny są ponownie wykorzystywane, aż do minute przed ich wygaśnięciem. Te same opcje znajdują się pod Logowanie do hostowanej usługi w konstruktorze kanału.

10.8.2 Raportowanie przypadków zdrowia publicznego

Zaznacz Raportuj warunki raportowania do zdrowia publicznego na miejscu przeznaczenia FHIR, a wyśle raporty przypadków zamiast pakietów. Każda wiadomość jest sprawdzana pod kątem kodu wyzwania warunku raportowania: diagnozy, badania laboratoryjnego lub zakodowanego wyniku. Jeśli go ma, wiadomość staje się HL7 eCR 2.1.2 eICR, zawinięta w wiadomość eCR i opublikowana w adresie URL $process-message. Jeśli go nie ma, nic nie jest wysłane i nic nie zawodzi; miejsce przeznaczenia liczy ją jako nieraportowaną.

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 to Kod wyzwalacza warunków raportowania, jako zestaw wartości FHIR lub pakiet eRSD. Wymaga licencji UMLS, więc nie jest dołączony; bez niego krótki przykładowy wbudowany jest używany, tylko do testowania. source to miejsce, w którym agencja wysyła swoją odpowiedź na raportowanie. Obiekt jest wymagany, ponieważ eCR prosi o jego numer telefonu i adres, a wiadomość w wersji 2 nie ma ich.

Raport mówi, co wiadomość nie miała, zamiast wymyślać to, i każda luka jest rejestrowana. Wypróbuj wiadomość w panelu Raport przypadku zdrowia publicznego laboratorium FHIR, zanim wskazujesz żywy kanał na agencję.

10.8.3 Wyniki laboratoryjne do zdrowia publicznego: ELR

perfuse elr -config elr.yaml results.hl7 przekształca wyniki laboratoryjne w wiadomości ELR HL7 2.5.1, które otrzymują departamenty zdrowia stanu, po jednej dla każdej wiadomości z wynikiem raportowalnym i tylko dla zamówień, które je zawierają: pełna morfologia krwi obok pozytywnego testu SARS-CoV-2 nie jest sprawą zdrowia publicznego. Kody wyzwalacza są takie same, jak raportowanie przypadków, RCTC, które ładujesz lub wbudowany przykład.

ELR nazywa każdego po OID lub numerze CLIA, który nie jest przekazywany przez źródło i odbiorcę, więc pochodzą one z pliku:

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}

Zamawiający obiekt, wykonujący laboratorium i władze przypisujące są używane tylko wtedy, gdy wiadomość laboratoryjna je pomija, a każde użycie jest notatką. To, co tylko laboratorium wie, nigdy nie jest wypełnione: wynik bez typu próbki idzie ze pustym SPM-4 i notatką, mówiącą o tym, ponieważ zgadywana próbka w raporcie do zdrowia publicznego jest gorsza niż luka, o której stan może zapytać. Zaczynaj z processing: T, podczas gdy zespół onboardingu stanu testuje kanał.

To, co laboratorium otrzymało poprawnie, jest przechowywane tak, jak zostało wysłane. Zamówienie podrzędne (panel wrażliwości lub test refleksyjny, którego OBR-29 nazwa rodzica i który nie ma własnego ORC) jest wysyłane bez zmian, bez ORC lub próbki, a podrzędny bez własnego wyniku raportowanego jest wysyłany z wynikiem rodzica, ponieważ wrażliwość nie ma znaczenia bez kultury, do której należy. Notatka po PID pozostaje z pacjentem, a ORC-14, numer telefonu do kontaktu, jest kopiowany z OBR-17, gdy laboratorium umieściło go tam. Wszystkie 28 przykładowych wiadomości opublikowanych przez ONC dla narzędzia certyfikacji ELR są ważne i nie zawierają błędów.

MSH-2 jest zapisywany jako ^~\&#, pięć znaków wymaganych przez erratę ELR Release 1 i sprawdzanych przez narzędzie certyfikacji ONC. Jeśli przewodnik Twojego stanu pokazuje starsze cztery, dodaj encoding_characters: "^~\\&" do pliku.

Aby wysłać je z kanału zamiast z linii poleceń, podaj miejsce docelowe, które osiąga stan, z blokiem elr nazywającym ten sam plik. Każdy wynik laboratoryjny jest przekształcany podczas wysyłania, a ten, który nie ma nic raportowanego, nie jest wysyłany w ogóle, co jest uznawane za dostarczone, a nie nieudane: stan poprosił o wyniki raportowane tylko.

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

Blok ten ma zastosowanie na kanale HL7 v2, do miejsc docelowych, które dostarczają samą wiadomość (mllp, http, tcp, plik, sftp, ftp, S3, Azure Blob, soap, brokerzy wiadomości lub inny kanał); kanał odmawia załadowania w przeciwnym razie, a gdy plik jest nieobecny lub nie zawiera ustawień wysyłającego zakładu, odbierającej aplikacji lub odbierającego zakładu. Notatki są zapisywane w dzienniku z kontrolnym ID wiadomości.

Plik ELR jest towarzyszem kanału, a nie kanałem: perfuse check i ekran kanałów pomijają go, zamiast raportować kanał, który nie może być załadowany. W budowniczym kanału te same dwie ustawienia są pod miejscem docelowym, w Raporcie laboratoryjnym (ELR 2.5.1); pole kodu wyzwalacza otwiera się po nazwaniu pliku ELR, a zapisywanie odmawia pliku, który nie jest obok kanału.

10.8.4 Archiva DICOMweb

type: dicomweb przechowuje każdy obiekt za pomocą STOW-RS: Orthanc, dcm4chee, chmury usług obrazowania lub własne archiwum serwera Perfuse. Podaj korzeń usługi (https://pacs.example/dicom-web); /studies jest dodawany, a adres URL, który już kończy się na /studies, jest odrzucany, zamiast wysyłać do /studies/studies. Uwierzytelnij się za pomocą token (token nośnika) lub username i password; headers dodaje inne, takie jak nagłówek projektu usługi chmury. Kanał wymaga dataType: dicom.

Odpowiedź serwera decyduje o wyniku, a nie sam kod stanu. Obiekt, którego odpowiedź wymienia jako nieudany, jest nieudaną dostawą z powodem niepowodzenia DICOM, a tak samo jest w przypadku 202, który nie wymienia nic jako przechowywane: serwer przyjął żądanie i nie zachował nic z niego. Limit czasu domyślnie wynosi dwie minuty, ponieważ duży zestaw jest powolny.

10.8.5 Repozytoria dokumentów (IHE XDS.b)

type: xds publikuje każdy dokument kliniczny w repozytorium XDS.b za pomocą ITI-41 Provide and Register: dokument CDA lub dokument przenoszony przez wiadomość HL7 v2 (MDM, ORU). Metadane pochodzą z dokumentu i ustawień miejsca docelowego (source_id, patient_domain, facility_type, practice_setting), a odpowiedź repozytorium RegistryResponse decyduje o dostawie. Zobacz dokument udostępniania IHE.

10.8.6 Rejestry szczepień

Każdy rejestr immunizacji w Stanach Zjednoczonych (IIS) akceptuje wiadomości HL7 2.5.1 na tym samym interfejsie SOAP, który CDC opublikował w 2011 roku (przestrzeń nazw urn:cdc:iisb:2011). Ma dwie operacje: connectivityTest, która udowadnia punkt końcowy, i submitSingleMessage, która przenosi wiadomość. VXU^V04 zgłasza zastrzyk i wraca jako ACK; QBP^Q11 prosi o historię i prognozę pacjenta i wraca jako RSP^K11.

Wybierz Rejestr szczepień (usługa internetowa CDC IIS) jako usługę miejsca docelowego SOAP lub napisz 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 tworzy kopertę, więc nie ma ciała do zapisania. Nazwa użytkownika i hasło są umieszczane wewnątrz żądania, gdzie CDC WSDL je umieszcza, a nie w uwierzytelnianiu HTTP. Wersja to SOAP 1.2, powiązanie WSDL, chyba że ustawisz version: "1.1" dla rejestru, którego przewodnik tego wymaga. Gdzie rejestr wymaga certyfikatu klienta, ustaw tls miejsca docelowego, jak dla każdego połączenia HTTPS.

Potwierdzenie rejestru decyduje o tym, czy wiadomość została dostarczona, a nie status HTTP. Rejestr odpowiada odrzuconemu zastrzykowi z kodem HTTP 200 i AR w środku, więc miejsce docelowe, które ufa statusowi, zgłosi utraconą immunizację jako dostarczoną.

Rejestr odpowiadaRekordy Perfuse
AA (lub CA)Dostarczono.
AE, którego segmenty ERR są wszystkie ostrzeżeniami (ERR-4 W lub I)Dostarczono. Ostrzeżenia są w odpowiedzi.
AE z dowolnym ERR-4 E lub ERR bez ciężkościNiepowodzenie, z lokalizacją, kodem i tekstem każdego ERR w błędzie.
AR lub CRNiepowodzenie, w ten sam sposób.
Błąd SOAP (niepoprawne hasło, za duży rozmiar wiadomości)Niepowodzenie, z powodem rejestru.
Coś, co nie jest wiadomością HL7Niepowodzenie.

warnings_are_errors: true (Traktuj ostrzeżenia jako niepowodzenia) powoduje, że każde AE czeka na osobę. Odpowiedź, którą skrypty odpowiedzi i wywołujący HTTP oczekujący na kanale czytają, jest wiadomością HL7 rejestru: ACK lub RSP z historią i prognozą. examples/iis zawiera trzy kanały do rozpoczęcia: VXU z EHR przez MLLP, zapytania QBP przez HTTP i lokalne miejsce docelowe dla rejestru.

Pulpit Połączenia prosi rejestr o connectivityTest, gdy nic nie zostało wysłane przez siedem dni. Ta operacja istnieje do tego celu i nie wysyła nic, więc jest to jedyne sprawdzenie na poziomie aplikacji, które Perfuse wykonuje. Udowadnia adres, TLS i powiązanie SOAP, a nie nazwę użytkownika i hasło; tylko rzeczywiste wysłanie testuje je.

Źródło SOAP może odpowiedzieć w ten sam sposób: Odpowiedz jako rejestr immunizacji, lub profile: cdc-iis na źródle. Odbija connectivityTest, pobiera wiadomość z submitSingleMessage, zwraca potwierdzenie kanału w return i służy CDC WSDL w ?wsdl. Nazwa użytkownika i hasło, gdy są ustawione, są sprawdzane przeciwko tym w żądaniu, a niepoprawna para otrzymuje SecurityFault WSDL. Wiadomość, którą kanał odrzuca, wraca jako NAK, nigdy jako błąd, jak mówi przewodnik CDC. Użyj go jako podwójnego testu lub aby otrzymać zgłoszenia w sposób, w jaki robi to rejestr.

Niewyjaśnione: stanowe części procesu onboardingu. Każdy rejestr ma swój własny punkt końcowy, proces konta i lokalny profil przewodnika 2.5.1 (wymagane pola RXA i OBX, kwalifikowalność VFC, kody odmowy). Są to treści wiadomości, które kształtują transformacje kanału; nie ma wbudowanego punktu końcowego stanu. Perfuse został przetestowany przeciwko sobie i przeciwko zarejestrowanym odpowiedziom rejestru, a nie przeciwko żywemu rejestrowi stanu.

10.9 Gdy transport mówi tak, a wiadomość nie dotarła

"Czy to dotarło" to często nie jest pytanie, na które transport może odpowiedzieć. Odbiornik MLLP zwraca potwierdzenie aplikacji, którego znaczenie jest w jego tekście. Odbiornik HTTP zwraca 200 z dokumentem błędu. W obu przypadkach transport się powiódł, a wiadomość nie dotarła.

Zbadaj odpowiedź na miejscu przeznaczenia przyjmuje skrypt danej odpowiedzi odbiorcy. Zwróć false lub wyrzuć, a dostawa zostanie oznaczona jako niepowodzenie — co oznacza, że zostanie ponowione, umieszczone w kolejce i pojawi się w liczbie niepowodzeń zamiast być cicho liczone jako dostarczone.

Jest oferowany tylko na miejscach przeznaczenia, które otrzymują odpowiedź. Na tym, które nie mogą, jest odrzucany podczas ładowania, a nie pozostawiony, aby nigdy nie działał.

10.10 Co oznacza wynik dostawy

WynikZnaczenie
DeliveredMiejsce przeznaczenia zaakceptowało wiadomość. Dla MLLP otrzymano pozytywne potwierdzenie.
QueuedDostarczenie nie powiodło się i wiadomość zostanie ponowiona.
FailedDostarczenie nie powiodło się i nie zostanie ponowione, albo z powodu wyłączonej kolejki, albo wyczerpania prób.
FilteredMiejsce przeznaczenia odrzuciło wiadomość za pomocą własnego filtra. Nie jest to błąd.

Są rejestrowane na każdym miejscu przeznaczenia na każdą wiadomość, więc wiadomość, która dotarła do trzech z czterech miejsc przeznaczenia, jest rejestrowana jako dokładnie taka. Nie ma poziomu kanału "powodzenie", ponieważ nie miałoby znaczenia.

10.11 Wolna dostawa

Miejsce przeznaczenia, które akceptuje wiadomości, ale zajmuje dużo czasu, jest odrębnym problemem od tego, które nie powiodło się, i jest łatwo przeoczyć, ponieważ każdy wynik jest powodzeniem.

Istnieje rodzaj alertu slow-delivery dla tego. Warto go ustawić na wszystkim, gdzie potwierdzenie nadawcy czeka na dostawę, ponieważ miejsce przeznaczenia, którego czas odpowiedzi cicho podwoił, w końcu przekroczy limit czasu nadawcy i zacznie produkować ponowne wysyłanie — i w tym momencie objaw pojawia się w górę, w systemie, który możesz nie administrować.

10.12 Pisanie do bazy danych

type: database uruchamia instrukcję na każdą wiadomość z wartościami połączonymi z wiadomości.

Znaczniki są własnymi sterowników — $1 dla postgres, ? dla mysql i sqlite, @p1 dla sqlserver — i Perfuse nie przebudowuje ich. To jest celowe: warstwa tłumacząca, która źle uzna znacznik, związałaby nazwę pacjenta z niewłaściwą kolumną, a wynik wyglądałby jak prawidłowe dane, a nie błąd.

Instrukcja napisana w niewłaściwym dialekcie jest odrzucana, gdy jest zapisywana, nazywając styl, jaki sterownik chce. Przed tym sprawdzeniem błąd pojawił się jako syntax error at or near "," z serwera, gdy przychodziła wiadomość, co nazywa instrukcję, którą napisałeś, i wysyła cię szukać literówki zamiast w dialekcie.

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

Zacytowany parametr jest stałą, a nie ścieżką, co jest tym, jak kanał zapisuje swoją własną nazwę lub kod systemu źródłowego obok danych wiadomości.

Wartości są zawsze wiązane jako parametry. Odwołanie ${...} w instrukcji jest odrzucane: nazwa zawierająca apostrof złamie instrukcję, a wartość wrogiego wartości ją przebuduje.

10.13 Wysyłanie do surowego gniazda

type: tcp zapisuje do gniazda z wybranym przez Ciebie formatowaniem, co jest tym, czego zwykle oczekuje urządzenie lub instrument laboratoryjny. MLLP jest jednym z kilku formatowań; ten cel oferuje pozostałe.

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

Formatowanie nie ma domyślnej wartości, celowo. Zapisywanie z niewłaściwym formatowaniem nie powoduje błędu. Na drugim końcu odbierane są wiadomości podzielone w niewłaściwych miejscach lub oczekuje się terminatora, który nigdy nie przychodzi, a objaw pojawia się w systemie odbierającym, a nie tutaj.

framingCo zapisuje
mllp0x0b przed, 0x1c 0x0d po. To samo ramowanie, które używa destination MLLP.
delimiteddelimiter po każdej wiadomości oraz opcjonalny start_block przed nią.
fixedRekordy wypełnione lub obcięte do record_length.
lengthPrefiks length_bytes. Zarówno big_endian, jak i length_includes_header mają dwie konwencje w użyciu i różnica jest niesłyszalna.
wholeJedna wiadomość na połączenie, zamykane w celu oznaczenia końca.

Akceptowane są tylko ustawienia używane przez wybrane formatowanie. Długość rekordu w strumieniu rozdzielanym jest odrzucana, a nie ignorowana, ponieważ ustawienie, które jest ignorowane w milczeniu, jest ustawieniem, które ktoś uważa za obowiązujące.

expect_reply zmienia to, co jest dostarczane. Bez niego, sukces oznacza, że bajty dotarły do bufora wysyłania systemu operacyjnego — co peer, który awaryjnie zakończył się chwilę później, nigdy nie odczytał.

10.14 Amazon S3, SQS i SNS

Kanał może odczytywać z kolejki SQS lub prefiksu kosza S3, a następnie dostarczać do SQS, SNS lub S3. Wszystkie pięć są podpisywane przez HTTP bez użycia zestawu SDK AWS w binarnym, a wszystkie pięć przyjmują te same ustawienia dostępu: region, access_key_id, secret_access_key (zapisz ${AWS_SECRET_ACCESS_KEY}, aby odczytać środowisko), opcjonalny session_token oraz endpoint dla LocalStack, MinIO lub punktu końcowego VPC. W Kanałach → Nowy kanał wybierz *Odczytujemy z kolejki Amazon SQS*, *Zbieramy obiekty z kosza Amazon S3* lub typy miejsc przeznaczenia SQS, SNS i S3.

Nic nie jest potwierdzone do AWS, dopóki kanał nie obsłuży go. Wiadomość SQS jest kasowana później i w przeciwnym razie pojawia się ponownie, gdy upływa jej limit czasu widoczności, więc polityka ponownego przesyłania kolejki jest tym, co przenosi ją do kolejki martwych list, jeśli nie powiedzie się. Obiekt S3 przechodzi do processed/ później lub do error/, jeśli nie można go obsłużyć, więc jeden zły plik nie zatrzymuje reszty.

W kolejce FIFO lub temacie wiadomości są grupowane według pacjenta domyślnie - SQS zachowuje kolejność wewnątrz grupy i nigdzie indziej - oraz usunięte zduplikowane według treści, więc ponowne próby nie są dostarczane dwa razy.

Archiwum S3 można zapisać bezpośrednio na Glacier z storage_class, oraz jako JSON lines dla Amazon Athena z format: ndjson; perfuse athena drukuje tabelę. Dokumentacja zawiera wszystkie ustawienia.

10.15 AMQP 1.0 i Azure

AMQP 1.0 to co Azure Service Bus i Event Hubs mówią, a RabbitMQ 4, ActiveMQ i Artemis obok innych protokołów. Źródło amqp odbiera z kolejki lub subskrypcji i akceptuje każdą wiadomość tylko wtedy, gdy kanał ją obsłużył; ta, która nie mogła być obsłużona, jest wydana jako nieudana dostawa, więc broker ponownie ją dostarcza i, po przekroczeniu limitu kolejki, umieszcza ją w martwej liście. Miejsce przeznaczenia amqp zgłasza powodzenie tylko wtedy, gdy broker akceptuje wiadomość. Dla Service Bus: addr to <namespace>.servicebus.windows.net:5671 z tls, username to nazwa zasad dostępu współdzielonego, password to jego klucz, a address to nazwa kolejki lub <topic>/subscriptions/<name>, aby otrzymać.

Azure Blob Storage: azure_blob destination zapisuje blob na wiadomość w wybranym poziomie dostępu - Hot, Cool, Cold lub Archive - oraz azure_blob source pobiera blob z prefiksu, przenosząc je do processed/ lub error/ tak jak source S3. Preferowany jest token SAS ograniczony do kontenera zamiast klucza konta.

10.16 MQTT

Źródło mqtt subskrybuje filtr tematu (+ pasuje do jednego poziomu, # do każdego poziomu poniżej) na dowolnym brokerze MQTT 3.1.1: Mosquitto, EMQX, HiveMQ, AWS IoT Core, Azure Event Grid. Przy QoS 1, domyślnie, każda wiadomość jest potwierdzana tylko wtedy, gdy kanał ją obsłużył. MQTT nie ma sposobu, aby odmówić pojedynczej wiadomości, więc ta, która nie mogła być obsłużona, pozostaje niepotwierdzona, a połączenie jest ponownie nawiązane; broker zachowuje sesję pod identyfikatorem klienta (perfuse-<channel>, chyba że client_id mówi inaczej) i wysyła ją ponownie, jako pierwszą w kolejce. QoS 0 jest co najwyżej raz: wszystko, co jest wysyłane, gdy Perfuse jest wyłączony, jest tracone. Miejsce przeznaczenia mqtt publikuje i, przy QoS 1, zgłasza powodzenie, gdy broker otrzyma wiadomość.

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 chce certyfikat klienta: podaj tls.cert_file i tls.key_file.

10.17 IBM MQ

ibm_mq odczytuje i zapisuje kolejki IBM MQ za pomocą interfejsu API REST (mqweb), który IBM MQ 9.1.5 i późniejsze wersje dostarczają na każdej platformie, w tym z/OS, więc nie jest instalowany żaden klient MQ obok Perfuse. Użytkownik potrzebuje roli MQWebUser i uprawnień do umieszczania, pobierania i przeglądania kolejki. Źródło przegląda pierwszą wiadomość, przekazuje ją do kanału i usuwa ją według jej identyfikatora wiadomości tylko wtedy, gdy została obsłużona; wiadomość, która nie powiedzie się, pozostaje pierwsza w kolejce. Uruchom jeden czytnik na kolejkę. Miejsce przeznaczenia umieszcza trwałe wiadomości (chyba że non_persistent), z identyfikatorem kontrolnym HL7 jako identyfikatorem korelacji.

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 to v3 dla MQ 9.3 i późniejszych (domyślnie), v2 dla 9.1.5 do 9.2. Menedżer kolejki z kanałem AMQP może być również osiągnięty za pomocą łącznika amqp.

10.18 Google Cloud Pub/Sub i Cloud Storage

Source pubsub ściąga z subskrypcji i potwierdza każdą wiadomość raz, gdy została obsłużona; ta, która nie powiodła się, jest zwrócona natychmiast (jej termin potwierdzenia jest ustawiony na zero), wraz z resztą partii, więc Pub/Sub dostarcza ją ponownie i, poza zasadą dead-letter subskrypcji, dead-letteruje ją. Destination pubsub publikuje z typem wiadomości HL7 i id kontrolnym jako atrybuty; order_by: patient ustawia klucz porządkujący z PID-3.1, więc subskrypcja z porządkiem wiadomości utrzymuje wiadomości każdego pacjenta w porządku.

Destination gcs zapisuje obiekt na wiadomość, nazwany jak klucz S3, w wybranej klasie magazynowania (STANDARD, NEARLINE, COLDLINE, ARCHIVE). Source gcs pobiera obiekty z prefiksu i przenosi je do processed/ lub error/ tak jak source S3.

Oba logują się jako konto usługi: credentials_file to jego klucz JSON. Pozostaw go pusty na Google Cloud (maszyna wirtualna, GKE lub Cloud Run), aby użyć konta usługi dołączonego tam. endpoint określa emulator (emulator Pub/Sub, fake-gcs-server), który nie wymaga poświadczeń.

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

10.19 Odczytywanie skrzynki pocztowej (IMAP i POP3)

Source email odczytuje skrzynkę pocztową i przekształca to, co znajduje, w wiadomości: każde załączniki (take: attachments, domyślnie, wąskie za pomocą wzorców attachment_names), tekst emaila (take: body) lub cały email (take: raw) dla skryptu do rozmontowania. Laboratoria, centra obrazowania i małe praktyki nadal wysyłają wyniki w ten sposób.

Każda kontrola loguje się, odczytuje najstarszą nieprzeczytaną pocztę i wylogowuje się. Przez IMAP poczta jest pobierana bez oznaczenia jej jako przeczytanej, przekazywana do kanału i tylko wtedy, gdy każda wiadomość z niej została zaakceptowana, jest przenoszona do move_to (Przetworzona), oznaczona jako przeczytana (after_read: flag) lub usunięta. Poczta, która nie powiodła się lub która nie została pobrana (nadawca spoza allowed_senders, brak załącznika pasującego do attachment_names, większa niż max_message_size), przechodzi do error_folder (Błąd) z powodem w logu. Obie foldery są tworzone, gdy są nieobecne. POP3 nie ma folderów ani flag, więc kasuje: kasowania są zatwierdzane przez QUIT na końcu kontroli, więc sesja, która się rozłącza, nie kasuje niczego i przetworzona poczta może być odczytana ponownie (nigdy nie tracona). Poczta POP3, która nie jest pobrana, pozostaje na serwerze i jest zgłaszana raz.

Logowanie jest hasłem (${MAIL_PASSWORD}; hasło aplikacji dla Gmail) lub OAuth 2.0 za pomocą SASL XOAUTH2, które Microsoft 365 wymaga (już wyłączyło logowanie hasłem) i Gmail preferuje:

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]

Z client_secret i bez refresh_token używany jest dostęp app-only do Microsoft 365 (grant client-credentials, zakres https://outlook.office365.com/.default): administrator rejestruje aplikację, przyznaje jej IMAP.AccessAsApp i ogranicza ją do jednej skrzynki pocztowej za pomocą głównego serwisu Exchange. Z refresh_token (zgoda osoby) używany jest delegowany zakres IMAP.AccessAsUser.All lub POP.AccessAsUser.All, a obrócony token odświeżania jest przechowywany przez cały okres istnienia procesu. Gmail potrzebuje refresh_token: Google nie oferuje dostępu app-only do skrzynki pocztowej.

allowed_senders przyjmuje adresy i domeny. Linia From w emailu może być sfałszowana, więc zatrzymuje przypadkową i zbędną pocztę, nie atakując; karmienie, które musi być zaufane, należy umieścić w Direct (S/MIME podpisane), SFTP lub VPN. security to tls (993 lub 995, domyślnie), starttls (143 lub 110) lub none, które jest dozwolone tylko do localhost. Kontrole są oddalone o co najmniej 10 sekund (60 domyślnie), ponieważ usługi pocztowe ograniczają konta, które sprawdzają częściej.

Przetestowany przeciwko GreenMail 2.1.3 (IMAPS, IMAP, POP3S i POP3: odmowa logowania z błędnym hasłem, pobieranie bez oznaczenia jako przeczytanej, MOVE, flaga, usunięcie, odmowa zbyt dużej poczty przed jej odczytaniem) i przeciwko IMAP Gmail z hasłem aplikacji (utwórz folder, dołącz, pobierz, MOVE, usunięcie). OAuth został przetestowany przeciwko punktowi końcowemu tokena tylko: nie przeciwko Microsoft ani Google.

10.20 AS2

AS2 (RFC 4130) to jest sposób, w jaki wiele płatników, instytucji rozliczeniowych i dostawców wymieniają dane EDI: żądanie HTTP POST, którego treść jest podpisywana certyfikatem nadawcy i szyfrowana dla odbiorcy, a w odpowiedzi otrzymuje się potwierdzenie (MDN) zawierające skrót tego, co dotarło. S/MIME jest tym samym kodem, który wykorzystuje bezpośrednia wiadomość. Obydwie strony znajdują się w konstruktorze kanału: Partnerzy handlowi wysyłają nam EDI za pośrednictwem AS2 jako źródło, Partner handlowy za pośrednictwem AS2 jako miejsce docelowe.

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

Odbieranie. Wiadomość do dowolnego innego AS2-To lub od nadawcy niebędącego w partners jest odrzucana z kodem 403 i bez potwierdzenia. Wiadomość partnera musi być podpisana i zaszyfrowana, chyba że jego wpis ustawia allow_unsigned lub allow_unencrypted. Ładunek jest odszyfrowywany, sprawdzana jest jego sygnatura w stosunku do certyfikatu partnera (partnerzy zwykle wymieniają się certyfikatami wygenerowanymi samodzielnie, co jest w porządku: certyfikat jest zaufaniem), a następnie przekazywany do kanału zgodnie z jego formatem wiadomości. Partner otrzymuje potwierdzenie, o które poprosił: w odpowiedzi lub opublikowane na adresie URL Receipt-Delivery-Option; podpisane, gdy poprosił o podpisane. Wiadomość, która nie powiedzie się, otrzymuje potwierdzenie z podaniem powodu (decryption-failed, authentication-failed, insufficient-message-security, unexpected-processing-error).

Wysyłanie. Każda wiadomość jest podpisywana (SHA-256) i zaszyfrowana (AES-256-CBC). Z receipt: sync, domyślnie, jest uważana za dostarczoną tylko wtedy, gdy potwierdzenie jest weryfikowane w stosunku do partner_cert_file, mówi processed i zawiera ten sam skrót (MIC) co to, co zostało wysłane; wszystko inne jest nieudaną dostawą i jest powtarzane. receipt: async prosi o potwierdzenie na receipt_url, które musi być źródłem AS2 na tym serwerze, który wymienia partnera: wiadomość jest uważana za dostarczoną, gdy partner zaakceptuje żądanie, a potwierdzenie, które później się nie zgadza, jest rejestrowane jako błąd. receipt: none prosi o nic. unsigned, unencrypted i unsigned_receipt łagodzą każdą część dla umowy, która tak mówi; username i password dodają uwierzytelnianie podstawowe HTTP dla bram, które je wymagają. Typ zawartości jest taki sam jak format kanału (application/edi-x12 dla X12), chyba że content_type ustawia inny.

Triple DES, AES-128 i AES-192 są odczytywane tak samo jak AES-256, ponieważ partnerzy nadal je wysyłają, a także jest odczytywany strumieniowy BER (nieokreślone długości) napisany przez bramki Java.

Kompresja (RFC 5402). Zaszyfrowana wiadomość jest odczytywana w dowolny sposób, w jaki została zbudowana: skompresowana przed podpisaniem lub szyfrowaniem, lub cała podpisywana wiadomość jest skompresowana. Skrót potwierdzenia (MIC) jest zgodny z RFC: nad tym, co zostało podpisane, gdy jest podpisane, nad zawartością nieskompresowaną, gdy nie jest podpisane. Wiadomość, która rozwinie się ponad dziesięć razy większą niż max_message_size źródła, jest odrzucana z decompression-failed, aby kilka kilobajtów nie mogło zażądać gigabajtów pamięci. Miejsce docelowe kompresuje z compress: true, przed podpisaniem i szyfrowaniem, jak to robią większość bramek; najpierw pytaj partnera.

Wiadomość wysłana dwukrotnie. Partner, który nigdy nie otrzymał naszego potwierdzenia, wysyła wiadomość ponownie z tym samym Message-ID (RFC 4130 sekcja 7.5). Źródło pamięta każde Message-ID partnera dla duplicate_window (domyślnie 720h, 30 dni; co najmniej godzina) i odpowiada na ponowne wysłanie potwierdzeniem processed bez ponownego przekazywania go. Zapis jest przechowywany w bazie danych, aby restart nie zapomniał go. Wiadomość, której przetwarzanie nie powiodło się, nie jest pamiętana, więc powtórne wysłanie partnera jest przetwarzane. Kopie, które przychodzą w tym samym momencie, czekają na siebie nawzajem, a tylko pierwsza jest przekazywana dalej. Jeśli zapis nie może być odczytany, wiadomość jest odrzucana z unexpected-processing-error i partner powtarza ją później, zamiast ryzykować drugą kopię. Wiadomość bez Message-ID nie może być rozpoznana i jest rejestrowana jako taka.

Interoperacyjność jest testowana z pyas2lib 1.4.3 w obu kierunkach, z Triple DES i AES-256, skompresowanymi i nie, z synchronicznymi potwierdzeniami podpisami włącznie.

10.21 OpenPGP

Płatnicy, instytucje rozliczeniowe i agencje państwowe często przyjmują i wysyłają pliki tylko za pomocą OpenPGP. Blok pgp w źródle otwiera to, co przychodzi; jeden w miejscu docelowym chroni to, co wychodzi. Obydwa są w konstruktorze kanału: Wiadomości zaszyfrowane Open PGP pod źródłem, Zaszyfruj za pomocą OpenPGP na każdym miejscu docelowym.

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}

Pliki z kluczami są odczytywane względem pliku kanału i są odczytywane i odblokowane, gdy kanał jest ładowany: brakujący klucz lub błędne hasło zatrzymuje kanał tam, a nie na pierwszym pliku.

Wiadomości są zapisywane z AES-256 w formacie RFC 4880 starszych odbiorców i nowszy format RFC 9580 jest odczytywany. Kryptografia to ProtonMail/go-crypto; Perfuse nie implementuje żadnej prymitywnej. Interoperacyjność jest testowana z GnuPG w obu kierunkach: gpg odszyfrowuje i weryfikuje to, co Perfuse zapisuje, a Perfuse otwiera i weryfikuje to, co gpg zapisuje.

10.22 Dostarczanie do innego kanału

Miejsce docelowe kanału przekazuje wiadomość do innego kanału według nazwy. Kanał odbierający traktuje ją jak każde inne przybycie: zapisuje ją, filtruje, przekształca i rozdziela.

To jest obsługiwany sposób budowania łańcucha. Jest to celowo widoczne — dwa kanały, dwa zestawy statystyk, dwa wpisy w historii wiadomości — ponieważ ukryty łańcuch wewnątrz jednego kanału to łańcuch, którego nikt nie może monitorować.

Wiadomość jest przekazywana w pamięci zamiast przez sieć, więc nie ma ramki, potwierdzenia ani limitu czasu między dwoma.

10.23 Co się dzieje, gdy proces jest zabity

Pierwsze pytanie, które zadaje każdy, kto uruchomił silnik interfejsu, i to, na które rzadko otrzymuje się odpowiedź, ponieważ uczciwa odpowiedź jest zwykle zawstydzająca.

Zostało ono udzielone przez zabicie procesu za pomocą SIGKILL w trakcie partii — co wygląda jak awaria zasilania, zabójstwo z powodu braku pamięci i reset hypervisora — i zliczono, co przetrwało w porównaniu z tym, co zostało obiecane.

Właściwość poddawana testowi nie jest „nic nie zostaje utracone”. Nie jest to osiągalne i twierdzenie, że tak jest, byłoby kłamstwem. Jest to węższa obietnica, na którą naprawdę liczy nadawca: wiadomość, która została potwierdzona pozytywnie, jest wiadomością, która dotarła.

Z ack.when: on_delivery, które jest domyślne, każde miejsce docelowe jest zapisywane przed wysłaniem potwierdzenia, więc AA jest oświadczeniem dotyczącym miejsca docelowego, a nie kolejki. Wiadomość zabita przed jej potwierdzeniem może zostać utracona, i jest to poprawne: nadawca nie został obiecany nic i wyśle ją ponownie.

10.23.1 Potwierdzanie przy dostarczeniu

Pięć przebiegów, zakończonych po 5, 25, 40, 75 i 110 wiadomościach z 120.

PotwierdzoneObecne w dół strumienia późniejPotwierdzone, ale brakujące
2552550

Obietnica dotrzymana na każdym punkcie zabójstwa, i nic nie zostało zdublowane. Dublowanie byłoby akceptowalne, a utrata nie: ponownie wysłany A08 to niedogodność, którą odbiorcy absorbują, a wynik laboratoryjny, który milcząco nigdy nie dotarł, jest zdarzeniem zagrażającym bezpieczeństwu pacjenta.

10.23.2 Potwierdzanie przy odbiorze

on_receipt odpowiada tak szybko, jak tylko wiadomość jest umieszczona w kolejce, zanim jakiekolwiek miejsce docelowe zostanie zapisane. Rozdział ten zawsze mówił, że potwierdzona wiadomość może nadal zostać utracona w ten sposób. Oto rozmiar tego.

Zakończone poPotwierdzoneObecne w dół strumieniaUtracone
5514
2525124
7575273
1101102108

Podstawowo wszystko, co jest w locie. Ustawienie nie jest wadą, i istnieją kanały, w których jest to właściwy wybór, ale powinno być wybrane ze świadomością, że awaria odrzuca to, co zostało potwierdzone i nie zostało jeszcze zapisane, i że jest to prawie cały wybuch.

Nic nie odzyskano po ponownym uruchomieniu, ponieważ perfuse run nie ma trwałego magazynu. Miejsce docelowe, które nie może stracić wiadomości podczas awarii, wymaga queue.enabled, które wymaga bazy danych dostarczanej przez perfuse serve — i perfuse run teraz odmawia takiego kanału, zamiast rozpocząć go bez kolejki.

10.23.3 Nadawca, który umiera w połowie wiadomości

Najniebezpieczniejszy z tych błędów, ponieważ przycięte wiadomości HL7 zwykle nadal są analizowane. Segregmenty przed przycięciem są kompletne i dobrze sformułowane, więc odbiorca nie ma możliwości wiedzy, że PID i PV1 dotarły, a segmenty OBX zawierające wyniki nie dotarły.

Ramka została otwarta, sześć dziesiątych wiadomości wysłano, a połączenie zostało zresetowane zamiast zamknięte. Częściowa wiadomość nie została dostarczona, nasłuchiwacz przetrwał, a dobrze sformatowana wiadomość wysłana natychmiast po niej została zaakceptowana normalnie, więc fragment nie został przeniesiony do następnej wiadomości.

Log połączenia raportuje teraz, ile bajtów niekompletnej ramki zostało porzuconych, dla każdego trybu awarii, a nie tylko dla czystego zamknięcia. Wcześniej awaryjny nadawca, zabity proces i wyciągnięty kabel wszystkie rejestrowały messages=0 i nic więcej, co nie może odróżnić pustej kontroli zdrowia od wyniku laboratoryjnego wyrzuconego dziewięć dziesiątych drogi.

10.23.4 Pełny dysk

Wykrywany jest wyczerpanie miejsca i rejestrowany, a nie połykany. Dwie rzeczy o tym są warte poznania.

Nadawca nie otrzymuje natychmiastowej odrzucenia. Dostarczanie jest powtarzane zgodnie z normalnym harmonogramem — jeden sekund, dwa, cztery, osiem — a negatywne potwierdzenie przychodzi około piętnaście sekund później. Nadawca, którego własne limit czasu jest krótsze niż to, widzi zablokowane połączenie, a nie AE, i stwierdzi, że sieć jest winna, a nie dysk.

A także wolumin zgłaszający zero wolnych bajtów może nadal akceptować małe operacje dołączania przez jakiś czas, because dodanie kilkuset bajtów do pliku, którego ostatni blok ma miejsce, nie wymaga nowej alokacji. Pierwszy błąd zapisu występuje później niż moment, w którym dysk został wypełniony.

10.23.5 Co nie zostało przetestowane

Miejsce docelowe katalogu traci uprawnienie do zapisu. Nie mogło być wstrzyknięte za pomocą chmod: silnik trzyma plik wyjściowy otwarty, a zmiana trybu pliku nie wpływa na opisany wcześniej plik. Prawidłowe przetestowanie wymaga ponownego zamontowania wolumenu w trybie tylko do odczytu lub usunięcia go spod procesu, co nie zostało zrobione. Jest tutaj nazwane, a nie pominięte, ponieważ luka, o której nikt nie wspomina, brzmi jak luka, której nikt nie szukał.

11 Alarmowanie

Nic poza Perfuse nie powie ci, że kanał przestał działać. Nadawca jest potwierdzany i jest zadowolony; odbiorca nie ma sposobu, aby wiedzieć, że wiadomość została wysłana. Alarmowanie jest jedyną rzeczą, która stoi między złamanym interfejsem a kimś, kto zauważy to tygodnie później.

11.1 Rodzaje alarmów

RodzajWyzwalany, gdy
error-rateNiepowodzenia przekraczają proporcję ruchu.
queue-depthKolejka ma więcej niż N wiadomości w oczekiwaniu.
queue-ageNajstarsza wiadomość w kolejce jest starsza niż określony czas.
queue-stuckKolejka nie jest opróżniana w ogóle.
no-trafficNic nie przychodzi przez określony okres.
below-rhythmRuch jest znacznie poniżej tego, co zwykle robi ten kanał *w tym czasie tygodnia*.
channel-downKanał, który powinien działać, nie działa.
script-errorsSkrypt nie powiodło się.
rows-quarantinedŹródło bazy danych odstawia wiersze na bok.
slow-deliveryDostawy są udane, ale zajmują zbyt dużo czasu.
contractWiadomość narusza deklarowany kontrakt kanału.
phi-volumeKanał przenosi kilka razy więcej niż zwykle w ciągu godziny.
phi-after-hoursKanał, który przenosi tylko dzienny ruch, przenosi niektóre w nocy.
phi-new-destinationKanał dostarcza do adresu, do którego nie wysyłał wcześniej.
phi-bulk-readsJedna osoba odczytuje więcej niż N różnych rekordów pacjentów w ciągu minuty.

Ostatnie cztery monitorują dostęp do danych pacjentów i są opisane poniżej.

11.2 Milczenie jest najtrudniejszą rzeczą do wykrycia

Kanał, który przestał otrzymywać dane, nie generuje błędów. Nie ma nic do policzenia. Dlatego też istnieje no-traffic i dlatego nie jest wystarczający sam w sobie.

no-traffic jest stałym progiem: alarmuj, jeśli nic nie przychodzi przez, powiedzmy, dwie godziny. W przypadku kanału, który nigdy nie milknie, działa to. W przypadku kanału laboratoryjnego kliniki jest to bezużyteczne — kanał jest cichy każdej nocy i przez cały weekend, więc próg dwugodzinny powoduje alarm o 1 nad ranem każdej nocy, a próg wystarczająco długi, aby przetrwać weekend, nie zauważy awarii we wtorek rano do wtorkowego popołudnia.

Nie ma jednej liczby, która spełnia oba warunki. To nie jest problem dostrojenia; to jest to, że pytanie „czy ten kanał przestał działać” nie może być odpowiedzią przez stałą, gdy normalne zachowanie kanału zmienia się o czynnik sto w ciągu tygodnia.

11.3 Wykrywanie rytmu

below-rhythm porównuje bieżący ruch z tym, co normalnie robi ten kanał w tej godzinie tego dnia tygodnia.

Perfuse uczy się każdego kanału z własnej zapisanej historii: 168 godzinnych wiadomości, od poniedziałku, tak aby tydzień roboczy był ciągły. Dla każdej wiadomości przechowuje medianę, niski i wysoki poziom, podłogę i liczbę obserwacji, na których się opiera.

Próg jest udziałem normalnym, domyślnie 0.8 (80 procent w konsoli) — alert, gdy ruch spada poniżej czterech piątych tego, co jest normalne dla tej godziny.

11.3.1 Mediana, a nie średnia

Jednorazowy wypływ 40 000 wiadomości przeciwko normalnym 300 przenosi średnią wystarczająco daleko, aby kanał mógł całkowicie umilknąć bez spadku poniżej niej. Mediana nie jest poruszona przez jedną niezwykłą godzinę, co jest właśnie potrzebne.

11.3.2 Podłoga jest percentylem, a nie minimum

Czy rytm kanału jest wystarczająco niezawodny, aby alarmować, decyduje o tym jego dolny koniec, a nie górny. Alarm braku wystrzeliwuje, gdy ruch jest *niski*, więc tylko dolny koniec może powiedzieć, czy wyprodukuje fałszywe pozytywy. Wczesna wersja tego porównywała górny koniec z medianą i myliła się w obie strony jednocześnie: zdyskwalifikowała idealnie stabilny kanał na miesiąc po jednym wypłynięciu i przeszła przez kanał, który naprawdę miał wahania między dwiema a dziewięcioma setkami wiadomości w tej samej godzinie, ponieważ jego górny koniec był tylko trzykrotnie wyższy od mediany.

Podłoga jest dwudziestym percentylem, a nie minimum, ponieważ minimum jest ciągnięte do zera przez jedną święto. I percentyl nie jest interpolowany — każda liczba w alarmie o 2 nad ranem powinna być liczbą, którą kanał rzeczywiście wyprodukował, a nie średnią z dwóch liczb, których nie wyprodukował.

11.3.3 Powie, gdy nie może powiedzieć

Kanał bez historii w ogóle jest pomijany, zamiast traktowany jako kanał, który przestał działać. Nowy kanał nie powinien wyglądać jak uszkodzony.

Gdzie historia jest zbyt cienka lub zbyt kapryśna, aby wspierać osąd, reguła odmawia wystrzału, zamiast zgadywać. „Nie mogę szczerze powiedzieć” to pierwszorzędna odpowiedź tutaj i jest preferowana zamiast alarmu, który jest prawidłowy nieco częściej niż przypadkowo.

Godziny nieobecne w oknie uczenia są rejestrowane jako prawdziwe zera, a nie jako brakujące dane. Połowa sygnału w kanale kliniki to *kiedy jest on słusznie cichy*, i traktowanie tych godzin jako nieznanych wyrzuciłoby to.

11.4 Ustawianie alarmów

Z interfejsu, pod Alertami, na kanał lub we wszystkich. Każda reguła ma rodzaj, próg i miejsce, w którym wysyłać alert. Reguły są zapisywane w alerts.yaml obok bazy danych (lub pliku -alerts nazwanym) i obowiązują natychmiast; do pierwszego zapisu mają zastosowanie reguły wbudowane. Plik można również edytować ręcznie: zmiana jest pobierana w ciągu trzydziestu sekund, a plik, który nie może być już wczytany, jest zgłaszany w logu, a reguły w mocy są utrzymywane.

Warto to zrobić przed uruchomieniem kanału, a nie po pierwszym incydencie. Konkretne zestawy, które warto mieć na każdym kanale klinicznym:

  1. below-rhythm — kanał umilkł, gdy nie powinien być cichy.
  2. error-rate — wiadomości przychodzą i nie powiodło się.
  3. queue-age — coś jest zakleszczone, a nie po prostu zajęte.
  4. channel-down — kanał nie działa w ogóle.

Pierwszy to ten, który złapie awarię, której nikt inny nie zgłosi.

11.5 Monitorowanie dostępu do danych pacjentów

Naruszenie zwykle nie ogłasza się. Wygląda to jak kanał przenoszący więcej niż zwykle, ruch o trzeciej w nocy na kanale, który działa tylko w godzinach biurowych, nowy adresat, lub jeden osoba otwierająca pacjenta po pacjencie. Perfuse monitoruje te cztery, włączone domyślnie (serve -watch-access=false wyłącza je), i zgłasza to, co widzi za pomocą reguł alertów powyżej, więc jest ono konfigurowane, potwierdzone i dostarczane jak każdy inny alert.

Nic nie jest oceniane dla kanału, dopóki nie przeszedł 200 wiadomości, ponieważ "niezwykłe" nie oznacza nic bez wzorca. Wzorzec jest uczony z ostatnich dwóch tygodni magazynu wiadomości, gdy serwer się uruchamia, więc ponowne uruchomienie nie sprawia, że każdy kanał staje się nowy. Wszystko, co jest widoczne, jest przechowywane przez piętnaście minut, a następnie alert samoczynnie się czyści.

Tylko obserwuje i raportuje. Nigdy nie zatrzymuje wiadomości ani nie odmawia odczytu: są to heurystyki, a kanał zatrzymany z powodu błędnej oceny jest problemem klinicznym. Każdy alert mówi, co zostało zobaczone i co może być niewinne, ponieważ większość z nich będzie niewinna.

Administratorzy widzą, co monitor nauczył się na ekranie Alertów, pod Obserwacja dostępu do danych pacjentów: wzorzec każdego kanału (nadal uczony, tylko w dzień lub w dzień i w nocy), ile miejsc docelowych on zna, i wszystko, co zostało zobaczone w ciągu ostatnich piętnastu minut, w tym to, co jest poniżej progu reguły.

11.6 Gdzie idą alarmy

Alerty mogą być wysyłane jako JSON do webhook (-alert-webhook: Slack, Teams, Mattermost, PagerDuty, Alertmanager lub wszystko, co akceptuje POST), wysyłane jako pułapki SNMPv2 do menedżerów SNMP (-snmp-traps, zobacz SNMP), lub zapisywane do logu dla kolektora. Nie ma własnej dostawy poczty elektronicznej: skieruj webhook do przekaziciela, jeśli alerty muszą przyjść jako e-mail.

Alarm, który jest tylko zapisany w logu, który nikt nie czyta, nie jest alarmem. Jeśli Perfuse jest jedyną rzeczą, która zauważy zatrzymany kanał, alarm musi dotrzeć do osoby.

12 Magazyn wiadomości

Każda wiadomość otrzymana przez Perfuse jest rejestrowana, w postaci oryginalnej, zanim zostanie zmodyfikowana. Zostaje również zapisane, co zostało wysłane do każdego miejsca przeznaczenia i co się z tym stało. Magazyn jest plikiem SQLite określonym przez -db.

12.1 Co jest przechowywane

Dla każdej wiadomości: surowe bajty, jak przybyły, kiedy przybyły, jaki kanał, sparsowany typ wiadomości i zdarzenie wyzwalające, oraz wynik filtrowania.

Dla każdego miejsca przeznaczenia dla każdej wiadomości: bajty, które zostały wysłane, wynik, czas potrzebny do wykonania, oraz ewentualne błędy lub negatywne potwierdzenia otrzymane.

To jest kształt, jaki wymaga śledztwo. „Co oni do nas wysłali”, „co my im wysłaliśmy” i „co oni powiedzieli o tym” to trzy różne pytania i każde z nich jest zadawane.

12.2 Wyszukiwanie

Przez kanał, przez zakres czasu, przez wynik, przez typ wiadomości i zdarzenie wyzwalające, oraz przez wartość pola.

Wyszukiwanie pól działa na sparsowanej wiadomości, więc wyszukiwanie numeru rekordu znajduje go wszędzie tam, gdzie to pole istnieje w wiadomości, zamiast dopasowywać cyfry gdziekolwiek w tekście. Wyszukiwanie tekstowe 12345 w wiadomości zawierającej ilość 12345 znajduje wiadomość, która nie ma nic wspólnego z pacjentem, którego szukamy.

12.3 Ponowne odtwarzanie i ponowne przetwarzanie

Ponieważ oryginał jest zachowany, wiadomość może być ponownie przetworzona z bieżącą konfiguracją.

Ślad pobiera zarejestrowaną wiadomość i pokazuje, co kanał zrobiłby z nią teraz, bez wysyłania niczego. Opisano w debugowaniu.

Ponowne przetworzenie naprawdę ponownie uruchamia ją, w tym dostarczanie. To jest to, co naprawia partię wiadomości, które nie powiodły się, ponieważ miejsce przeznaczenia było nieprawidłowo skonfigurowane: popraw konfigurację, wybierz dotknięte wiadomości, ponownie przetwórz.

Ponowne przetwarzanie dostarcza ponownie. Jeśli wiadomości częściowo powiodły się pierwszy raz, ponowne przetwarzanie wyprodukuje duplikaty w miejscach przeznaczenia, które już je miały. Perfuse rejestruje, które miejsca przeznaczenia powiodły się, więc ponowne przetwarzanie może być ograniczone do tych, które nie powiodły się — zrób to zamiast ponownego przetwarzania wszystkiego, chyba że system odbiorczy deduplikuje na podstawie identyfikatora kontrolnego wiadomości.

12.4 Przestarzałość

Ślad starej wiadomości względem bieżącej konfiguracji odpowiada na hipotetyczne: co by się *stało* teraz. To jest zwykle to, czego chcesz, ale nie zawsze — jeśli badasz, co poszło nie tak w zeszłym tygodniu, kanał może ulec zmianie od tego czasu.

Perfuse wykrywa to i mówi o tym. Ślad wiadomości, która przybyła przed ostatnim edytowaniem kanału, jest oznaczony jako taki, aby odpowiedź nie była mylona z odtworzeniem tego, co naprawdę się stało.

12.5 Przechowywanie

Magazyn rośnie. cleanup.periodDays kontroluje, jak długo wiadomości są przechowywane.

Dwie rzeczy do rozważenia. Wiadomości kliniczne mogą podlegać wymogom przechowywania, które są dłuższe niż cokolwiek, co byś wybrał z powodów operacyjnych, a magazyn nie jest systemem ewidencji — system odbiorczy jest. Kopia Perfuse istnieje w celu diagnozowania i ponownego przetwarzania, a oba te potrzeby maleją gwałtownie po kilku tygodniach.

Okres przechowywania również decyduje o tym, ile danych historia ma do dyspozycji learner rytmu. Zobacz alerting: krótszy okres przechowywania niż kilka tygodni powoduje, że nie jest w stanie odróżnić cichej niedzieli od zatrzymanego źródła.

12.6 Magazyn zawiera dane kliniczne

Jest to część Perfuse, która zawiera informacje o pacjentach i powinna być traktowana jako taka: przechowywana na zaszyfrowanym nośniku, zabezpieczona jako dane kliniczne i kontrolowana pod względem dostępu. Zobacz bezpieczeństwo.

Wygenerowane wiadomości testowe opisane w testowaniu istnieją częściowo po to, aby te dane nie musiały opuścić środowiska, aby odtworzyć problem w innym miejscu.

13 Debugowanie

Pytanie jest prawie zawsze takie same: ta wiadomość przychodzi, coś poszło nie tak, gdzie się zmieniła? Perfuse odpowiada na nie, odtwarzając nagraną wiadomość za pomocą bieżącej konfiguracji i pokazując każdy krok.

Nic nie jest wysyłane podczas śledzenia. Kanał działa niezakłócony, a nie jest wymagane ponowne wdrożenie.

13.1 Śledzenie wiadomości

Wybierz dowolną nagraną wiadomość i śledź ją. Wynik pokazuje, w kolejności:

13.2 Krok po kroku

Widok krokowy uruchamia każdą transformację oddzielnie i robie zdjęcie całej wiadomości po każdej z nich. Ponumerowana belka kroków, pokolorowana według tego, co się stało, i wiadomość, jaka była w każdym punkcie.

Cała wiadomość, a nie tylko zmiana, ponieważ zmiana często nie jest tam, gdzie jest problem — krok, który poprawnie zmodyfikował pole, na wiadomości, na której wcześniejszy krok już wcześniej wstawił coś nie takiego, wygląda idealnie poprawnie w izolacji.

13.3 Cztery rezultaty i różnica, która ma znaczenie

RezultatZnaczenie
changedKrok został uruchomiony i zmodyfikował wiadomość.
no-effectKrok został uruchomiony, a wiadomość nie została zmieniona.
skippedWarunek when kroku był fałszywy, więc krok nie został uruchomiony.
failedKrok zakończył się błędem.

no-effect i skipped są raportowane oddzielnie, a to jest punkt całej funkcji.

Z zewnątrz są identyczne: wiadomość jest taka sama po obu. Oznaczają przeciwne rzeczy. skipped oznacza, że warunek działał zgodnie z tym, co zostało napisane, a ta wiadomość nie była jedną, do której się stosował — zwykle poprawnie. no-effect oznacza, że krok został uruchomiony i nie znalazł nic do zrobienia, co zwykle oznacza, że jest skierowany do pola, które nie istnieje.

Silnik, który raportuje oba jako "nic się nie stało" pozostawia cię niezdolnym do rozróżnienia działającego warunku od złamanego ścieżki, a to jest najczęstszy błąd transformacji.

Krok raportujący no-effect w każdej wiadomości jest prawie zawsze złym ścieżką. Nagłówek kroku liczy, ile kroków nie znalazło nic, co jest najszybszym sposobem, aby to zauważyć: kanał z trzema krokami i trzema wynikami no-effect w ogóle nie transformuje.

13.4 Testowanie zmiany przed jej zapisaniem

Budowniczy może uruchomić kandydującą konfigurację na nagranych danych ruchu i raportować, co byłoby inne. To jest najbezpieczniejszy sposób, aby zmienić żywy kanał: zrób edycję, zobacz, co robi ostatnim kilkuset prawdziwym wiadomościom, a następnie zapisz.

To jest również sposób, aby dowiedzieć się, że zmiana, która wygląda oczywiście poprawnie, wpływa na wiadomości, o których nie myślałeś — krok warunkowy na jednym zdarzeniu wyzwalającym, na kanale, który okazuje się przenosić cztery.

13.5 Co śledzenie nie może ci powiedzieć

Uruchamia bieżącą konfigurację. Jeśli kanał został edytowany od czasu przyjścia wiadomości, śledzenie jest hipotetyczne, a nie odtworzeniem, i Perfuse oznacza to w ten sposób, zamiast pozwolić, aby ta różnica przeszła niezauważona.

Nie ćwiczy również transportu. Śledzenie pokazuje, co byłoby wysłane, a nie czy miejsce przeznaczenia zaakceptowałoby ją — wiadomość, która jest poprawna, a miejsce przeznaczenia, które odmawia połączeń, produkują czyste śledzenie i nieudane dostarczenie. Te są widoczne w rekordzie dostarczenia zamiast.

13.6 Skrypty

Skrypt jest jednym nieprzezroczystym krokiem w śledzeniu. Perfuse może pokazać, co weszło i co wyszło, i nie może pokazać, co się stało pomiędzy lub które pola zostały przeczytane.

Jest to konkretny koszt korzystania ze skryptu zamiast deklaracyjnych kroków i jest wart rozważenia przy wyborze. Zobacz transformacja.

14 Testowanie

Standardowa rada dotycząca testowania interfejsu jest taka, aby zbudować przykładowe wiadomości, które odzwierciedlają twoje własne środowisko — twoje laboratoryjne kody, twoją mieszankę przypadków, twoje zwyczaje nadawcy — i aby usunąć dane pacjenta ręcznie. To jest powolne, a robienie tego niekompletnie jest normalnym wynikiem.

Perfuse oferuje trzy rzeczy zamiast: wygenerowany ruch, który pasuje do kształtu kanału bez jego zawartości, kanał zaproponowany z próbki, którą ktoś ci wysłał, i porównanie z silnikiem, który zastępujesz.

14.1 Wygenerowany testowy ruch

Jeśli kanał obsłużył wiadomości, Perfuse może wygenerować więcej wiadomości podobnych do nich.

Co jest wiernym odwzorowaniem:

Co nie jest wiernym odwzorowaniem, a jest to stwierdzone zamiast zakładane: spójność kliniczna. Wygenerowany pacjent ma niezwiązany numer rekordu, ciąg znaków w kształcie nazwy i diagnozę bez żadnego związku z obserwacją. Te wiadomości ćwiczą interfejs. Nie są one zestawem testowym do walidacji logiki klinicznej i nie mogą być używane do tego celu.

14.1.1 Dlaczego nie zawiera on rzeczywistych danych

Argument jest strukturalny, a nie twierdzenie o wysiłku. Jedynym wejściem generatora jest profil ruchu kanału, a profil zawiera wskaźniki wypełnienia, kształty, długości, liczbę powtórzeń i częstotliwość segmentów. Nie zawiera on wartości.

Jedynym wyjątkiem są pola tabel kodów, a kod nie identyfikuje nikogo.

Jest to silniejsza gwarancja niż anonimizacja rzeczywistych wiadomości, która jest procesem, który może być wykonany niekompletnie i zwykle jest. Tutaj nie ma ścieżki, przez którą nazwa mogłaby dotrzeć do wyjścia, ponieważ nazwa nigdy nie była w wejściu.

Każda wygenerowana wiadomość jest parsowana przed jej zwróceniem — nieparsowalny korpus spowodowałby, że ktoś szukałby błędu w swoim interfejsie, który jest w rzeczywistości błędem generatora — i każda z nich jest oznaczona T w MSH-11, z celowo syntetyczną aplikacją nadawcy i obiektu.

Wiadomość testowa, która nie jest oznaczona jako taka, zostanie ostatecznie znaleziona w systemie produkcyjnym przez kogoś, kto nie ma sposobu wiedzy, czy była to nie prawdziwa wiadomość. T i syntetyczny nadawca nie są kosmetyczne.

14.2 Tworzenie kanału z próbki

Wklej wiadomość, którą laboratorium, szpital lub dostawca wysłał Ci e-mailem, a Perfuse proponuje kanał dla niej. Nic nie musi być uruchomione wcześniej.

Obsługuje to, co ludzie rzeczywiście wklejają: kilka wiadomości w jednym bloku, dowolne zakończenie linii, ramki MLLP, które przetrwały kopiowanie, oraz notatkę pokrywającą wiadomość. Odrzucenie próbki, ponieważ przybyła z zakończeniami linii systemu Windows, byłoby przeszkodą, a nie sprawdzaniem.

14.2.1 Trzy listy

Propozycja jest dostarczana z tym, co próbka pokazuje, co zostało odgadnięte, oraz tym, czego próbka nie może powiedzieć — trzy oddzielne listy, równo ważone w interfejsie.

Są one oddzielne, ponieważ czytelnik, który nie może powiedzieć, które jest którym, musi zweryfikować wszystko lub zaufać wszystkiemu, a oba są gorsze niż wiedza, gdzie szukać.

Z jednej wiadomości granice są nazwane konkretnie, a nie ogólnie: które pola są opcjonalne, które segmenty się powtarzają, które kody istnieją poza tymi, które są tutaj, czy nadawca kiedykolwiek wysyła inne zdarzenie wyzwalające. Ogólna ostrożność jest słowem, które ludzie przeskakują.

Pewność jest słowem — niska, umiarkowana, rozsądna — nigdy procent. Procent sugeruje obliczenie, a to jest sąd o tym, ile próbek istnieje.

Z-segmenty są wskazywane przez nazwę, ponieważ lokalny segment jest tym, o czym nie wspomina specyfikacja, a najczęstszym powodem, dla którego kanał zbudowany z szablonu standardowego nie działa.

14.2.2 Ostrzeżenie o separatorze

Jeśli separator pól próbki nie jest zwykłym |, to pojawia się najpierw, a pewność spada do niskiej.

Powodem jest prawdziwa niezauważalna awaria. HL7 pobiera separator pól z samej wiadomości, więc próbka, której pionowe kreski zostały zastąpione przez typograficzne podobieństwa — co robi procesor tekstu — parsuje się idealnie w pola, które są wszystkie błędne. Nic nie błędnie nigdzie.

Odrzucenie takiej próbki byłoby błędne, ponieważ nadawca może słusznie używać innego separatora. Zatem jest on oznaczony, znak jest nazwany, a prosi się o załącznik w postaci zwykłego tekstu.

14.3 Porównywanie z dawnym silnikiem

Przed przeniesieniem strumienia na żywo, pytanie brzmi, czy Perfuse wytwarza taki sam wynik jak rzecz, która działała przez lata. Żadna ilość jakości projektu nie odpowiada na to. Zobacz migrację.

14.4 Weryfikacja względem rzeczywistych implementacji, w kontenerach

Trzy testy są uruchamiane przeciwko rzeczywistym implementacjom, a nie przeciwko własnej wizji protokołu Perfuse. Znajdują się one poza make check, ponieważ wymagają środowiska kontenerowego, a test, który wymaga Dockera, jest testem, który ludzie przestają uruchamiać.

scripts/interop-up.sh uruchamia je wszystkie i wypisuje, co każdy z nich odblokowuje.

KontenerTestyCo znaleziono
Keycloak 26web/e2e-saml/, i internal/saml fixtureWada. Kanoniczna forma sygnatury była obliczana z pominięciem prefiksów przestrzeni nazw, więc żaden prawdziwy dostawca tożsamości nie mógłby nigdy podpisać nikogo
Microsoft Entrainternal/saml testy na żywo i fixtureDwie wady, obie w otoczeniu protokołu. Konto zostało utworzone pod nieprzezroczystym NameID Entra, ponieważ logika nazwy czytelnej chciała roszczenia e-mail i Entra nie wysyła żadnego. I konto SAML zostało zapisane jako OIDC, ponieważ sklep wywnioskował protokół z wydawcy, który wygląda identycznie dla obu
HAPI FHIRgo test ./internal/engine/ -run HAPIWada. Nieprzypisana władza przydzielająca wyprodukowała system identyfikatora ogłaszający OID i przenoszący słowo, które HAPI zaakceptowało bez skargi
ActiveMQgo test ./internal/engine/ -run RealBrokerPoprawne, w tym przypadku ramowania null-byte. Potwierdzone przez własne interfejs zarządzania brokera, a nie przez funkcję zwracającą nil
nginx, certyfikaty klientago test ./internal/engine/ -run ClientCertificatePoprawne
Orthanc (rzeczywisty PACS)go test ./internal/engine/ -run RealPACSPoprawne. C-STORE przychodzi i nazwa pacjenta, identyfikator, data badania, modalność i klasa SOP wszystkie przetrwają
PostgreSQLgo test ./internal/engine/ -run RealPostgresPoprawne, i spowodowało lepszy błąd: instrukcja w niewłaściwych placeholderach dialektów jest teraz odrzucana podczas zapisu, a nie staje się błędem składniowym na serwerze, gdy przychodzi wiadomość
OpenSSH sftp-servergo test ./internal/engine/ -run OpenSSHServerPoprawne. Istniejące testy SFTP używają tej samej biblioteki Go na obu końcach; OpenSSH to inna implementacja i ta na końcu prawie każdego rzeczywistego strumienia
Mirth 4.5.2go test ./internal/mirth/ -run RealMirthPoprawne teraz. Jedyny fixture używany do tej pory był napisany ręcznie i Mirth nie mógł go załadować; scripts/mirth-author-channel.sh powoduje, że Mirth tworzy kanał, i Perfuse go czyta

Każdy z nich pomija zamiast zawodzić, gdy kontener jest nieobecny, więc make check przechodzi na maszynie bez Dockera.

Dlaczego jest to oddzielone od reszty zestawu. Każdy inny test tych funkcji miał obie połowy napisane tutaj: dokument, który ten kod podpisał, odczytany przez kod, który go podpisał. To jest zgodność z samym sobą, i jest warta mniej, niż się wydaje.

Kanoniczny SAML jest przypadkiem, który udowadnia punkt. Nosił tysiąc linii testów, pięć z nich specjalnie o kanoniczalizacji, i wszystkie one przeszły, podczas gdy żaden prawdziwy dostawca tożsamości nie mógłby nigdy podpisać nikogo — kanoniczna forma, którą sygnatura obejmuje, była obliczana z pominięciem prefiksów przestrzeni nazw, i jedynym sposobem, aby to znaleźć, było podanie dokumentu Perfuse, który nie został napisany.

Dwa z ośmiu testów znaleźli wady, a trzeci spowodował prawdziwą poprawę. Trzy nie znaleźli nic złego. To proporcja jest argumentem za utrzymaniem wszystkich z nich: test, który przechodzi, powiedział coś, czego w przeciwnym razie nie wiedzielibyśmy, i nie było sposobu, aby to przewidzieć, które z nich będą.

Jeden wzorzec wart nazwania, ponieważ pojawił się w obu wadach: akceptacja nie jest weryfikacją. HAPI zaakceptował uszkodzony system identyfikatora i zapisywał go; wada pojawiła się dopiero podczas odczytywania zasobu. Odbiorca, który toleruje coś, nie jest dowodem, że jest to prawidłowe, tylko że ten odbiorca był łagodny.

Dwa przechwycone asercje są zatwierdzone, w internal/saml/testdata/keycloak-assertion.xml i entra-response.xml, z testami nad oboma — aby ten konkretny regres został złapany bez kontenera.

Oba są potrzebne, a nie jeden jest zapasowy. Keycloak prefiksuje swoje asercje i sygnatury, Entra nie, i to są dwa przeciwne przypadki w kanoniczalizacji — co jest dokładnie tam, gdzie wada była. Test asercji każdego dokumentu nadal obejmuje swój własny przypadek, ponieważ zastępczy przechwyt, który mógłby być prefiksowany, cicho połowicznie zmniejszyłby pokrycie bez zawodzenia czegokolwiek. Ogólna lekcja nie uogólnia się tak tanio: dla wszystkiego innego kontener jest sprawdzany.

14.5 Diagnozowanie testu, który zawodzi raz i nigdy więcej

Test, który zawodzi w pełnym uruchomieniu i przechodzi samodzielnie szesnaście razy, nie jest testem niestabilnym. To jest test, który dzielił coś z uruchomieniem, i sposób, aby to znaleźć, to zmierzyć tę wspólną rzecz, a nie test.

Dwa instrumenty istnieją do tego, i oba są przeznaczone do uruchomienia obok pełnego zestawu:

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

Każdy odkrywa porty uruchomienia z własnego pliku stanu ustawień i próbkuje co 500 milisekund, aż serwer wyjdzie. Zapisują każdą próbkę, a nie tylko błędy, co czyni je użytecznymi: błąd pojawia się w uruchomieniu, w którym nic nie zawiodło, więc wada, która pojawia się raz na trzy uruchomienia, staje się mierzalna w każdym

Ustaw PERFUSE_E2E_KEEP=1, aby zachować katalog tymczasowy, który zawiera bazę danych w stanie, w jakim została pozostawiona, oraz log serwera dla całego przebiegu. Log serwera jest zwykle odpowiedzią. W jednym z badanych przypadków zarejestrował on zatrzymanie kanału i ponowne podłączenie jego nasłuchiwania 421 milisekund później, a odmowa połączenia sondy znalazła się w tym oknie.

Przeczytaj ślad zamiast error-context.md, który był pusty więcej niż jeden raz, gdzie ślad zawierał prawdziwą wiadomość.

Skopiuj artefakty przed ponownym uruchomieniem czegokolwiek. Pomyślny przebieg czyści test-results, więc ślad niepowodzenia, które badasz, znika w momencie, gdy próbujesz go odtworzyć. Gdy raz zostanie utracony, pytanie, które miałoby odpowiedzieć, nie może być już odpowiedziane.

Zatrzymaj kontenery interop najpierw. Zatrzymaj je przed pełnym uruchomieniem przeglądarki i uruchom je za pomocą ./scripts/interop-up.sh później, jeśli nadal są potrzebne.

Osiem kontenerów zajmuje około 9,8 GB pamięci, a na maszynie bez znacznie więcej niż tego pozostaje za mało dla procesów Chromium, node i łańcucha narzędzi Go razem. To, co produkuje, nie jest błędem braku pamięci, ale renderowaniem, które przestaje być planowane: jeden zarejestrowany ślad pokazuje przerwę 60,2 sekundy bez ramki, podczas której Playwright czekał, aż przycisk stanie się "widoczny, włączony i stabilny" i nie mógł uzyskać dwóch kolejnych klatek animacji do porównania. Serwer był zdrowy przez cały czas, najwolniejsze żądanie w całym przebiegu wynosiło 154 milisekundy.

To niepowodzenie jest czytane jako wada w teście, który akurat był uruchomiony. Warto wiedzieć, jaki jest jego kształt: każde żądanie szybkie, strona wizualnie zamarznięta, pętla ponawiania nigdy nie osiąga drugiej iteracji, a całość przechodzi w izolacji.

Tylko jeden przebieg na raz. Suite udostępnia jeden serwer, jedną sesję zalogowaną w web/e2e/.auth/admin.json i jeden plik stanu nazywający proces serwera. Żadne z nich nie jest na przebieg, więc drugi przebieg rozpoczynający się podczas pierwszego nadpisuje plik stanu, a którykolwiek demontaż zakończy się pierwszy, zabija serwer drugiego przebiegu i kasuje jego sesję.

To, co wygląda jak nic niepodobne do przyczyny. Wyprodukowało przebieg 279 niepowodzeń, których pierwsza wiadomość była ENOENT: no such file or directory, open './e2e/.auth/admin.json', przebieg, który zakończył się wcześnie, zgłaszając 217 przejść, i dwa testy niepowodzące z bind: address already in use — żadne z nich nie sugerują dwóch przebiegów walczących. Suite teraz pobiera blokadę i odmawia rozpoczęcia, nazywając proces, który ją trzyma. Blokada pozostawiona przez przerwany przebieg jest przejęta zamiast blokowania na zawsze, ponieważ środek bezpieczeństwa, który blokuje suite, jest tym, co ktoś kasuje wraz z bezpieczeństwem.

Powiązana pułapka, teraz naprawiona: dwa specyfikatory nazwały swoje porty nasłuchiwania wprost, więc serwer pozostawiony przez przerwany przebieg sprawił, że nie powiodły się one w czymś, z czym nie miały nic wspólnego. Porty są teraz pytane o system operacyjny.

Nie odpowiedz na to powtórzeniami. Test, który przechodzi podczas drugiej próby, znalazł prawdziwy wyścig i ukrył go, a playwright.config.ts ustawia retries: 0 z tego powodu.

Jedna ostrożność: próbkowanie co 100 milisekund spowodowało uruchomienie dwudziestu procesów na sekundę, wydłużyło przebieg o połowę, i spowodowało niepowodzenie dwóch testów na limitach czasu, które nie miały z nimi nic wspólnego. Narzędzie, które zmienia to, co mierzy, produkuje wyniki dotyczące samego siebie.

14.6 Co jeszcze potrzebuje prawdziwej infrastruktury

Kilka części Perfuse jest zaimplementowanych i nigdy nie było wykonywanych przeciwko prawdziwej rzeczy. Są one wymienione tutaj, zamiast pozostawione do odkrycia:

Funkcje w tym rozdziale i następnym istnieją, aby mogliście zbierać własne dowody, zamiast brać czyjeś słowo.

14.7 Pomierzone przeciwko publicznym korpusom zgodności

Suite testowa, której fixture zostały napisane tutaj, dowodzi zgodności z samym sobą. To są inne ludzie danych.

14.7.1 FHIR R4, własne przykłady specyfikacji

Wszystkie 2,912 plików przykładowych opublikowanych ze specyfikacją FHIR R4 — każdy przykład, jaki autorzy standardu napisali.

WynikLiczba
Zasoby zwalidowane bez ustaleń13,723
Zasoby zgłoszone jako nieprawidłowe0
Pliki odrzucone jako niezaimplementowany typ zasobu753
Wpisy pakietu pominięte jako niezaimplementowany typ1,348

Żaden zasób nie został zwalidowany niepoprawnie. Każdy błąd jest jawnym odmówieniem nazwania typu, którego nie można odczytać — 672 ValueSet, 80 ConceptMap i jeden Parameters. Walidator, który cicho przechodzi to, czego nie rozumie, jest gorszy niż ten, który mówi o tym.

Korpus znalazł wadę, co jest powodem uruchomienia go. Walidacja paczki wydrukowała „Walidacja paczki z pliku nie jest jeszcze obsługiwana” i kontynuowała. Było to fałszywe w obu kierunkach: pakiety, których wpisy przypadkowo były typami, które parser mógł trzymać, już były walidowane, a pakiet, który był naprawdę niepoprawny, wyprodukował tę samą linię, nic nie policzył i zakończył się zerem — w tym pod -strict, które istnieje, aby to mogło bramkę budowy. Czterdzieści dwie własne pakiety specyfikacji były pomijane.

Pakiety są teraz walidowane wpis po wpisie, z trzema wynikami trzymanymi osobno: wpis, który jest niepoprawny, nie powiedzie się i nazwie pole, wpis typu, którego ten build nie może odczytać, jest liczony jako pominięty i zgłaszany, a pakiet, który nie zawiera żadnych treści zasobu, nie jest żaden. Ten sam korpus przeszedł od 2,100 sprawdzonych zasobów do 13,723.

14.7.2 HL7 v2, korpus testowy HAPI

Nakładki wiadomości z HAPI, referencyjnej implementacji Java HL7 v2 — celowo niewygodny materiał, w tym uuencoded ładunki, ucieczki separatorów i powtarzające się grupy.

59 wiadomości, 59 przeanalizowanych, żadna odrzucona. Siedem typów wiadomości w korpusie, które każdy system opisuje jako jedną rzecz, co jest celem istnienia perfuse profile.

14.7.3 Co nie zostało uruchomione

DICOM przeciwko publicznemu zestawowi zgodności, oraz X12 przeciwko opublikowanemu korpusowi. Żadne z nich nie zostało wykonane i nie powinno być wnioskowane z dwóch powyższych.

15 Migracja z Mirth

Potrzeba dwóch rzeczy, aby zastąpić działający silnik: kanały muszą zostać przeniesione, a ktoś musi być w stanie pokazać, że zastąpienie produkuje ten sam wynik. Perfuse robi to pierwsze, importując własne eksporty Mirth, a drugie, porównując dwa silniki na własnym ruchu.

Wszystko w tym rozdziale ma równie zastosowanie do Open Integration Engine i BridgeLink. Mirth Connect przestał być open source na wersji 4.6 w marcu 2025; OIE (hostowany przez Eclipse Foundation) i BridgeLink (Innovar Healthcare) są forkami, które kontynuują linię open-source, a oba zapisują te same formaty eksportu. Importer jest testowany przeciwko wszystkim trzem poniżej.

15.1 Importowanie kanałów

Perfuse odczytuje każdy eksport, który te silniki zapisują:

EksportZ AdministratoraCo jest przenoszone
KanałEksportuj kanałKanał
Grupa kanałówEksportuj grupęKażdy kanał w niej, każdy zachowujący grupę
Szablony koduEksportuj szablony koduKażda biblioteka jako jeden plik skryptu
Kopie zapasowe serweraKopie zapasowe konfiguracji, lub GET /api/server/configurationWszystko z powyższych na raz

Wskazać perfuse translate na dowolny z nich lub upuścić jeden na Administruj → Migrate:

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

Biblioteka szablonów kodu staje się lib/<library>.js obok kanałów, a każdy kanał, dla którego Mirth włączył tę bibliotekę, otrzymuje scripts.include: [lib/<library>.js] — dzięki temu transformer wywołujący funkcję witryny, taką jak formatMRN(), nadal ją znajduje. Kanał, dla którego biblioteka nie była włączona, nie ją dołącza, ponieważ jego skrypty nie mogły jej zobaczyć w Mirth. Fragmenty kodu przeciągane i upuszczane są pomijane: Mirth wkleja je tylko ręcznie do kroku, więc nie są to kod, który działa samodzielnie. W przeglądarce import kanału najpierw zapisuje biblioteki, które on zawiera.

Pisarz kanału nazywa kanał, do którego dostarcza, według identyfikatora. W grupie lub kopii zapasowej cel jest w tym samym dokumencie, więc staje się miejscem przeznaczenia channel nazywającym ten kanał; z eksportu jednego kanału jest on zgłaszany, abyś mógł go wypełnić. Skrypty globalne serwera nie mają odpowiednika w Perfuse i są zgłaszane, a nie pomijane.

Raport mówi, dla każdego kanału, czy został on przetłumaczony czysto, przetłumaczony z ostrzeżeniami, czy nie mógł być odczytany.

Nagłówek jest ułamkiem z jego mianownikiem — „37 z 40 gotowych” — ponieważ „37 gotowych” nie mówi nic o tym, co jeszcze musisz zrobić.

Kanał, który nie mógł być odczytany, jest innym problemem niż ten, który nie mógł być przetłumaczony. Pierwszy oznacza, że sam XML nie został sparsowany i jest zwykle eksportem trunwowanym lub częściowym; drugi oznacza, że zawartość kanału ma coś, czego nie ma odpowiednik w Perfuse. Import rozdziela je.

15.2 Co się tłumaczy i co wymaga decyzji

Źródła, miejsca docelowe, filtry i zwykłe kroki transformacji są tłumaczone bezpośrednio. Konnectory, które się tłumaczą: TCP/MLLP (i surowy TCP z ramką), HTTP, Plik, Baza danych, JavaScript, DICOM, Usługa internetowa (SOAP), SMTP i Czytelnik/Pisarz kanału. JMS i Pisarz dokumentu nie są tłumaczone i są zgłaszane jako blokery.

Krok Mapper, który ustawia zmienną, wkłada ją do mapy, którą jego zakres nazywa — channelMap domyślnie — dokładnie tak, jak robi to Mirth, więc późniejsze kroki, które ją czytają za pomocą $('name'), ją znajdują.

Transformery JavaScript nie są, ogólnie. Kanały Mirth często zawierają znaczny kod w transformerze, a nie ma automatycznego przekształcenia z dowolnego JavaScript w deklaracyjne kroki. Importer zgłasza je, zamiast próbować tłumaczenia, które mogłoby być subtelnie błędne: źle przetłumaczony transformer jest gorszy niż ten, który jest oznaczony dla człowieka, ponieważ będzie działał.

Gdzie skrypt naprawdę musi pozostać skryptem, Perfuse może go uruchomić — zobacz klucz scripts w dokumencie kanału — przy koszcie śladu na poziomie kroku opisanym w debugowaniu

15.3 Przeciwko czemu tester importu został przetestowany

Pięć silników, z których każdy tworzy własne dokumenty: Mirth 4.5.2, OIE 4.5.2, 4.6.0 i 4.7.0, oraz BridgeLink 26.9.0. scripts/mirth-engine-corpus.sh kompiluje mały program przeciwko własnym bibliotekom każdego silnika i ma własny serializator, który zapisuje trzy zwykłe kanały — kanał MLLP z maperem, skrypt wywołujący bibliotekę szablonów kodu i filtr; kanał HTTP do bazy danych; kanał plikowy z MLLP — plus bibliotekę i grupę kanałów. Ładuje je do uruchomionego silnika i pobiera własną kopię zapasową serwera silnika. Wyniki są zatwierdzane pod internal/mirth/testdata/engines/, a zestaw testowy utrzymuje importer dla każdego z nich na każdym budowaniu: każda kopia zapasowa jest odczytywana, tłumaczona, ładowana, a kanał ADT jest uruchamiany z dwoma komunikatami w celu sprawdzenia, czy biblioteka wypełnia numer rekordu, a filtr odrzuca wynik.

Własne eksporty Perfuse idą w przeciwnym kierunku — kanały Perfuse importowane do każdego uruchomionego silnika i sprawdzane, czy silnik nie przechowuje ich jako nieprawidłowe. Wszystkie pięć akceptują każdy transport, który Perfuse eksportuje. Open Integration Engine 4.7.0 dodał dwa ustawienia HTTP bez odpowiednika tutaj: nadawca HTTP związany z wybranym adresem lokalnym jest zgłaszany jako ostrzeżenie, a limit nagłówka żądania odbiornika HTTP tylko wtedy, gdy jest powyżej 1 MB, które Perfuse akceptuje.

Pierwsze uruchomienie przeciwko temu korpusowi ujawniło cztery wady, wszystkie naprawione: tłumacz odrzucał źródła HTTP i plikowe jako „tylko MLLP jest obsługiwane” długo po tym, jak Perfuse miał oba; odczytywał adres nadawcy HTTP z pola, którego żaden z silników nie zapisuje; tłumaczył rozmiar bufora gniazda Mirth jako limit wiadomości 64 KB; a zmienna mapera stała się globalną zmienną JavaScript, której $('mrn') nigdy nie widział, więc biblioteka wypełniała pusty ciąg.

Jedno-kanałowa konfiguracja, która rozpoczęła to, została również wyeksportowana przez Mirth 4.5.2, napisaną przez samego Mirtha, a nie napisaną tutaj. Ta różnica dała jej miejsce: jedyna konfiguracja w tym repozytorium była kiedyś napisana ręcznie, a prawdziwy Mirth nie załaduje jej — API akceptuje POST, a następnie przechowuje kanał jako This channel is invalid. Verify all required extensions are loaded correctly, z każdym connectorem miejsca docelowego odrzuconym.

Pisanie go ręcznie nigdy nie było możliwe, a powód jest wart poznania, jeśli produkujesz własne eksporty. Serializator Mirth ignoruje elementy, których nie rozpoznaje, więc błędna nazwa elementu nie powoduje błędu — po prostu konektor nie jest tam później. Nie ma nic do odczytania i nic do skorygowania.

scripts/mirth-author-channel.sh tworzy jeden przy użyciu własnych klas modelu Mirth i jego własnego serializatora, a następnie wysyła go do uruchomionego serwera i kończy się niepowodzeniem, jeśli serwer odrzuca go. Importer Perfuse odczytuje wynik: nazwa, transport źródłowy i miejsca docelowe wszystkie przetrwają.

15.4 Udowodnienie, że pasuje

To jest część, która decyduje, czy migracja nastąpi, i potrzebuje dowodów, a nie zaufania.

Perfuse porównuje swój własny wynik z wynikiem starego silnika, wiadomość po wiadomości, w Twoim ruchu. Co potrzebuje, to pary: wiadomość, tak jak przybyła, i wiadomość, którą stary silnik wyprodukował z niej. Oba są w własnym magazynie wiadomości Mirth i mogą być wyeksportowane z przeglądarki wiadomości.

Perfuse nie może dotknąć Mirth, i ten podręcznik nie będzie udawał, że tak jest. Narzędzie, które twierdzi, że weryfikuje migrację bez zobaczenia rzeczywistego wyniku starego silnika, weryfikowałoby nic. Dostarczanie par jest uczciwym kształtem ćwiczenia.

15.4.1 Cztery liczby, a nie wskaźnik zaliczenia

WynikZnaczenie
IdentycznyDokładnie taki sam.
Tylko kosmetycznyRóżni się w sposób, który nie niesie informacji — puste pola końcowe, końcowy terminator.
Różni sięWartość pola jest inna.
Nie może być uruchomionyPerfuse nie mógł przetworzyć wiadomości w ogóle.

Są to cztery liczby, ponieważ oznaczają cztery różne rzeczy i łączenie ich ukrywa te, które wymagają decyzji.

Identyczny oznacza dokładnie taki sam, a nie równoważny. Słabszy test pozwoliłby na różnice w kolejności segmentów lub separatorach końcowych, a to są właśnie te, które system zewnętrzny odrzuca.

Różnice kosmetyczne są liczone oddzielnie, a nie są włączane do kolumny dobrej. Rzeczywiście nie niosą informacji, więc traktowanie ich jako niepowodzeń zakopie prawdziwe ustalenia pod tysiącami niczego — ale nie są identyczne, i odbiorca wykonujący własną ścisłą analizę może się nie zgodzić.

„Nie może być uruchomiony” jest oddzielony od „różni się”, ponieważ jest to zwykle luka konfiguracyjna, którą importer nie mógł wypełnić, a nie decyzja mapowania. Jeśli wszystko jest w tej kolumnie, wyrok tak mówi i mówi, abyś popatrzył na konfigurację przed przeczytaniem czegokolwiek innego.

15.4.2 Różnice są grupowane według pola

Przebieg pięćdziesięciu tysięcy wiadomości, który zgłasza cztery tysiące różnic, powiedział ci nic, czego możesz użyć. Ten sam przebieg, który zgłasza, że PID-8 różni się w każdej wiadomości, ponieważ stary silnik napisał Male, gdzie Perfuse pisze M, powiedział ci dokładnie jedną rzecz do podjęcia decyzji.

Więc każde znalezienie jest polem z liczbą, i mówi, czy różnica jest systematyczna — ta sama para wartości za każdym razem — czy czy zawartość pola różni się.

Ta różnica jest najbardziej użyteczną rzeczą w raporcie. Jedna odrębna para wartości w czterech tysiącach wiadomości to jedna decyzja mapowania. Cztery tysiące odrębnych par to różnica zawartości, co jest innym i znacznie gorszym problemem, i nie mogą one wyglądać tak samo.

Znalezienia są uporządkowane według liczby wiadomości, które dotyczą, więc największa pojedyncza przyczyna jest pierwsza.

15.4.3 Wyrok nie zaokrągla

Podaje dokładne liczby: 49 993 z 50 000, a nie „ponad 99%”. Te siedem są cały punkt biegu.

Zostało napisane, aby można było je cytować w wniosku o zmianę, ponieważ to tam kończy się numer.

15.5 Zalecana sekwencja

  1. Importuj kanały i rozwiąż wszystkie problemy zgłoszone jako nieczytelne.
  2. Dla każdego kanału przejrzyj ostrzeżenia. Większość z nich to skrypty.
  3. Eksportuj kilka tysięcy par wiadomości z Mirth dla najbardziej zajętego kanału i uruchom porównanie.
  4. Pracuj przez wyniki. Systematyczne są to jedne decyzje.
  5. Uruchom ponownie, aż jedynymi różnicami będą te, które uznałeś za poprawne.
  6. Uruchom Perfuse w trybie cieniowym obok Mirth na żywej transmisji, dostarczając nigdzie i porównując ponownie przez okres, który obejmuje weekend i koniec miesiąca.
  7. Przełącz jeden kanał, a nie wszystkie.

15.6 Co działa tylko na oprogramowaniu jednego dostawcy

Ekran migracji odpowiada na drugie pytanie, i warto je zadać, zanim będziesz miał jakiekolwiek zdanie na temat Perfuse: ile Twojej logiki integracji może działać tylko na oprogramowaniu, które posiadasz.

Każdy kanał otrzymuje wyrok Przenośność, z tego samego skanu, który produkuje notatki migracyjne. Działa przeciwko eksportowi kanału, więc nie wymaga niczego zainstalowanego i nie zmienia niczego.

15.6.1 Różnica jest cały punkt

Większość Java w skryptach Mirth nie jest zablokowana. SimpleDateFormat, HashMap, Apache Commons — wszystko to działa wokół silnika JavaScript z 2009 roku, wszystko to zwykłe, wszystko to z bezpośrednimi odpowiednikami. Kanał z trzema stoma takimi odniesieniami jest w pełni przenośny, a narzędzie, które zgłaszało „300 odniesień do Javy, jesteś uwięziony” kłamałoby ci.

Zablokowanie jest specyficznie połączone z wywołaniami, które potrzebują serwera dostawcy: com.mirth.connect.* i jars dostawcy. Pięć z nich i jesteś uwięziony. Pięćset innych i jesteś wolny.

Więc wyrok zaczyna się od liczby, która ma znaczenie, i mówi w tym samym zdaniu, że większa liczba nie jest tym. Gdzie są wywołania dostawcy, są one wymienione przez nazwę — liczba jest twierdzeniem, a lista jest czymś, co twój własny inżynier może sprawdzić.

Trzecia kategoria jest trzymana oddzielnie: możliwość, która istnieje, ale nie z skryptu. Uruchomienie kanału z JavaScript nie ma odpowiednika tutaj, i istnieje punkt końcowy API, który robi dokładnie to samo. Nazywanie tego zablokowaniem byłoby przesadą.

15.6.2 Wywołania Javy, które działają niezmienione

Najczęstsze z tych klas Java są uruchamiane tak, jak są napisane. Perfuse nie ma środowiska uruchomieniowego Java, więc są to klasy JavaScript z tymi samymi nazwami i metodami, wystarczającymi dla sposobu, w jaki skrypty kanałów je wykorzystują; importPackage(java.util) i importClass(...) wprowadzają je do zakresu ich krótkimi nazwami, jak w Rhino (własne Date, Map, Set, Math, String i Boolean JavaScript nigdy nie są zastępowane: te Java są nadal dostępne przez pełne nazwy). Raport migracji liczy każde z tych wywołań jako już obsługiwane.

PakietKlasy
java.utilArrayList, LinkedList, Vector, List, Collection, HashMap, LinkedHashMap, Hashtable, TreeMap, Properties, HashSet, LinkedHashSet, TreeSet, Arrays, Collections, Date, Calendar, GregorianCalendar, UUID, Base64, regex.Pattern (z Matcher), concurrent.ConcurrentHashMap
java.langString, StringBuilder, StringBuffer, Integer, Long, Short, Byte, Double, Float, Boolean, Math, System (czas i separator linii tylko)
java.text, java.math, java.net, java.nioSimpleDateFormat i DateFormat (litery wzorca Mirth), BigDecimal (jako podwójna), URLEncoder, URLDecoder, StandardCharsets
Apache Commonslang3.StringUtils i lang.StringUtils (około sześćdziesiąt metod), StringEscapeUtils, codec.binary.Base64

Zachowują się jak Java tam, gdzie skrypty od nich zależą: Integer.parseInt("x") rzuca NumberFormatException, String.replaceAll i split przyjmują wyrażenia regularne, podczas gdy replace jest literalne, mapy kluczy ciągów według wartości, TreeMap i TreeSet iterują w porządku, a SimpleDateFormat.parse zwraca datę, na której getTime() działa. Metoda, którą skrypt wywołuje, a odpowiednik jej nie ma, kończy się niepowodzeniem w tej linii, nazywając ją; każda inna klasa Java kończy się niepowodzeniem według nazwy, jak poprzednio. BigDecimal jest tutaj podwójnym, więc nie zachowuje dokładnej arytmetyki dziesiętnej Java: sprawdź skrypty, które z niej korzystają dla pieniędzy.

15.6.3 Zewnętrzne skrypty są zgłaszane jako nieznane

Krok, który uruchamia zewnętrzny plik skryptu, odnosi się do ścieżki na starej serwerze, a plik nie jest w eksporcie. Nic nie można powiedzieć o tym, co zawiera, więc jest on liczony jako nieznany, a nie założony w którąkolwiek stronę. Pobierz te pliki, zanim wnioskujesz cokolwiek — w obie strony.

15.6.4 Własne zablokowanie Perfuse, stwierdzone w tym samym oddechu

Ten rozdział byłby nieuczciwy bez tego.

Perfuse jest Apache 2.0, co jest nieodwołalne dla kodu już wydanego. Możesz rozgałęzić to, co istnieje dzisiaj, i nikt nie może wycofać tego. Kanały są plikami YAML, a skrypty są zwykłym JavaScript, więc nie ma powierzchni własnościowej, którą można by nazwać — smak Mirth Java zależności jest strukturalnie niedostępny tutaj, co jest miejscem, w którym ograniczenie jest prawdziwie cechą.

Co to nie obiecuje: że przyszła wersja pozostaje otwarta, że usługa hostowana istnieje w cenie, którą lubisz, lub że migracja z Perfuse nic nie kosztuje. Przenoszenie warstwy integracji oznacza ponowne testowanie każdego kanału przeciwko rzeczywistemu ruchowi. To, co wybierasz, to czy artefakty, które budujesz, są czytelne i przenośne, oraz czy wyjście zależy od licencji, którą kontroluje ktoś inny.

15.6.5 Konfigurowanie kroku 6

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

Sekcja Cień rozpoczyna porównanie. Wybierz kanał, który jest uruchomiony, wybierz kandydata do porównania z listy i uruchom.

Trzy rzeczy o tym są warte wiedzy, zanim będziesz polegał na tych liczbach.

Kandydat jest wybierany z listy, a nie wpisywany. Nazwa cienia określa plik kanału, a nazwa, która nie rozwiązuje problemu, powoduje, że kanał *live* jest nieprawidłowy — Perfuse odmawia kanału w całości, gdy coś, na co się odnosi, jest złamane. Tak więc literówka nie powoduje ostrzeżenia, ale sprawia, że uruchomiony kanał znika.

Udział jest procentem. Zmniejszaj go tylko na zajętym kanale i wiedz, co to kosztuje: próbkowanie redukuje pracę i zaufanie w tej samej proporcji, a wiadomość, która pokazałaby różnicę, jest niezwykła.

Pola do zignorowania są zwykle potrzebne. Kanał, który stawia znacznik czasu lub numer sekwencyjny, różni się w każdej wiadomości, co powoduje, że wskaźnik różnic wynosi 100% i nie mówi nic. MSH-7 i MSH-10 są typową parą.

Porównanie jest zapisywane w pliku kanału natychmiast po jego uruchomieniu i zaczyna obserwować, gdy kanał zostanie ponownie załadowany — ekran mówi o tym, zamiast twierdzić, że już działa. Zatrzymanie porównania pozostawia kanał kandydujący na miejscu, ponieważ kandydat jest tym, co ma zostać uruchomione.

Krok 6 jest tym, którego nie można skrócić. Różnice, które mają znaczenie, zwykle występują w ruchu, który pojawia się tylko okazjonalnie — rzadkie zdarzenie wyzwalające, miesięczna partia, nadawca, który zachowuje się inaczej o północy — a próbka pobrana w ciągu popołudnia nie będzie ich zawierać.

15.7 Powrót w drugą stronę

Kanał można wyeksportować jako plik kanału Mirth z przeglądarki: Kanały, a następnie Do Mirth na kanale, który chcesz.

Istnieje to, ponieważ zastrzeżenie dotyczące zastąpienia działającego silnika rzadko dotyczy tego, czy zastąpienie jest dobre. Chodzi o to, co się stanie, jeśli decyzja okaże się błędna, a eksport, który wraca tą samą drogą, jest najtańszą odpowiedzią na to.

Przeczytaj, co mówi dialog, zanim weźmiesz plik. Format Mirth nie ma miejsca na filtr Perfuse, łańcuch transformacji, umowę ani porównanie cienia, więc wyeksportowany kanał robi mniej niż ten, z którego pochodzi. Transporty i ich adresy są przekonwertowane; logika nie. Każda strata jest wymieniona z nazwy przed zaoferowaniem pliku, a ten sam wykaz trafia do opisu kanału, aby osoba, która go importuje, również to zobaczyła.

Kanał, którego Mirth nie może wyrazić, jest odrzucany zamiast przybliżany. Punkt docelowy S3 nie ma odpowiednika w Mirth, a kanał, który został zaimportowany czysto, dostarczając w inne miejsce niż wiadro, byłby gorszy niż w ogóle nie ma pliku. Odmowa wymienia punkt docelowy, który jest winny.

Definicje łączników nie są pisane na podstawie odczytu formatu Mirth. scripts/mirth-dump-connector-templates.sh ma własny serializator Mirth, który produkuje wartości domyślne dla każdej klasy łączników, a Perfuse zastępuje wartości w tych dokumentach — odmawiając każdej ustawienia, której szablon nie zawiera już. To ma znaczenie ze względu na to, jak Mirth odpowiada na kanał, który nie może być sparsowany: nie odmawia importu. Zamiast tego przechowuje kanał, którego opis został zastąpiony przez „Ten kanał jest nieprawidłowy. Sprawdź, czy wszystkie wymagane rozszerzenia są załadowane poprawnie” i którego punkty docelowe zostały dyskretnie odrzucone. Eksportownik sprawdzony względem własnego wyjścia, a nie względem serwera, przechodzi każdy test, podczas gdy produkuje dokumenty, które są wyrzucane, co jest dokładnie tym, co się tu stało, zanim eksporty zostały wypróbowane na uruchomionym Mirth.

To, co przekracza dzisiaj: MLLP i TCP w obie strony, HTTP w obie strony, odczyt i zapis plików, odczyt i zapis baz danych, DICOM w obie strony, a także punkty docelowe SMTP, SOAP i JavaScript. Każda para jest weryfikowana przez importowanie do prawdziwego Mirth 4.5.2 i sprawdzenie, czy serwer nie zamienił cicho kanału.

16 CMS-0057 dla płatników

Ostateczne przepisy CMS dotyczące interoperacyjności i uprzedniej autoryzacji (CMS-0057-F) wymagają od płatników objętych tymi przepisami — organizacji Medicare Advantage, programów Medicaid i CHIP stanowych oraz ich planów ubezpieczeniowych, a także wydawców QHP na federalnych giełdach — uruchomienia czterech interfejsów API FHIR od 1 stycznia 2027 r. oraz opublikowania metryk uprzedniej autoryzacji na ich publicznej stronie internetowej co roku od 2026 r.

Perfuse zapewnia cztery interfejsy API na swoim punkcie końcowym FHIR oraz konwersje, które je wypełniają: rozliczone roszczenia jako CARIN Blue Button, uprzednie autoryzacje jako Da Vinci PDex, a roczne metryki w układzie szablonu CMS. Widok CMS-0057, pod Exchange, mówi, który z czterech ten egzemplarz może odpowiedzieć i co każdy z nich jeszcze potrzebuje, oraz wykonuje wszystkie trzy konwersje w przeglądarce.

Leki są poza zakresem przez cały czas, tak jak w przepisach dotyczących uprzedniej autoryzacji: nie ma roszczeń farmaceutycznych, nie ma formularza, a wiersz metryk nazywający lek jest odrzucany zamiast zliczany.

16.1 Cztery interfejsy API

APICo obsługujePrzewodnikiWłączone przez
Dostęp pacjentaŻądania, dane kliniczne i uprzednie autoryzacje członka do aplikacji, którą wybieraCARIN Blue Button 2.2.0, PDex 2.2.0, US Core, SMART App Launch-fhir i wydawca SMART (-smart-issuer)
Dostęp dostawcyTo samo dla przypisanych członków dostawcy, w partiachPDex 2.2.0, Da Vinci ATR 2.1.0, Bulk Data-fhir-payer-apis i -fhir-bulk-export
Payer-to-PayerRekord członka do innego płatnika, po dopasowaniu ichHRex 1.2.0 $member-match, PDex 2.2.0-fhir-payer-apis
Autoryzacja wstępnaCo potrzebuje zamówienie, dokumentacja, a następnie żądanie i decyzjaDa Vinci CRD, DTR i PAS 2.2.x (2.2.1, 2.2.0, 2.2.1) i 2.1.0, z tłumaczeniem X12 278-fhir, zapisywalne, i -crd-rules

Interfejs API Patient Access nie wymaga własnej operacji: jest to zwykłe odczytywanie i wyszukiwanie punktu końcowego FHIR, zabezpieczone przez SMART, z zasobami CARIN i PDex w sklepie. Wyszukiwanie ExplanationOfBenefit obsługuje parametry o nazwach CARIN — patient, identifier, type, service-date, billable-period-start, provider, insurer, coverage — a Coverage obsługuje subscriber-id, identifier i payor.

16.1.1 Dwie wersje przewodników: 2.1.0 i 2.2.x

CMS-0057-F zaleca CRD, DTR i PAS 2.0.1 i 2.1.0. Wersje 2.0.1 opierają się na US Core 3.1.1, które wygasło 1 stycznia 2026 r., więc 2.1.0 jest wersją, którą system EHR zbudowany zgodnie z tą regułą najprawdopodobniej obsługuje; najnowsze to CRD 2.2.1, DTR 2.2.0 i PAS 2.2.1. Perfuse odpowiada na obie. Określa, którą wersję mówiący używa, najpierw najbardziej szczegółową:

  1. z żądania: rozszerzenie CDS Hooks CRD davinci-crd.requestedVersion ("2.1"), lub wersja na profilu Da Vinci, który wejście DTR lub PAS twierdzi (profile-pas-request-bundle|2.1.0);
  2. z rejestracji mówiącego: davinci_version: "2.1" na kliencie SMART (-smart-clients) lub kliencie CDS (-cds-clients);
  3. z serwera: serve -davinci-version 2.1; domyślnie jest to 2.2.
clients:
  - issuer: https://ehr.example.org
    jwks_url: https://ehr.example.org/.well-known/jwks.json
    davinci_version: "2.1"

Każda odpowiedź jest ustalona i przechowywana w formie 2.2.x i przepisywana dla wywołującego 2.1.0, tak jak jest wysyłana, więc reguły, kolejka przeglądu, link X12 278 oraz metryki są takie same dla obu. Przepisanie obejmuje różnice w sposobie zapisu wersji: CRD 2.1.0 nie ma indeterminate (Perfuse mówi warunkowe, z powodem) i nie ma kategorii w szczegółach pokrycia; DTR 2.1.0 nazywa pakiet PackageBundle i pozostawia QuestionnaireResponse aplikacji; PAS 2.1.0 odpowiada na $inquire z jednym Bundle i nie ma rozszerzeń recenzenta i transmisji. Pełna lista oraz sprawdzenie przeciwko każdej przewodnikowi 2.1.0 jest w conformance/davinci21. Powiadomienie PAS postępuje zgodnie z -davinci-version, ponieważ subskrypcja nie określa, jaką wersję odczytuje jej właściciel.

16.2 Wymagania i dokumentacja dotyczące ubezpieczenia: CRD i DTR

Interfejs API upoważnienia wcześniej jest w praktyce trzema przewodnikami Da Vinci razem. CRD mówi klinicystom, podczas gdy zamówienie jest jeszcze wersją roboczą, czy jest objęte, czy wymaga upoważnienia wcześniej i jakie dokumenty są wymagane. DTR przekazuje EHR kwestionariusz, który gromadzi te dokumenty. PAS składa wniosek i zwraca decyzję. Perfuse obsługuje wszystkie trzy jako płatnik.

-crd-rules rules.yaml obsługuje CRD za pomocą CDS Hooks w /cds-services: wszystkie sześć haków CRD, order-sign, order-select, order-dispatch, appointment-book, encounter-start i encounter-discharge, każdy z prefetchem dla aktywnego pokrycia pacjenta. Dwa haki spotkania również prefetchują spotkanie i odpowiadają na spotkanie samo w sobie, dopasowane do jego typu i typu usługi, tak jak appointment-book odpowiada na spotkanie. Reguły są polityką płatnika, przechowywaną w pliku, ponieważ zmieniają się bez wydania oprogramowania:

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

Każde zamówienie otrzymuje aktualizację systemActions z rozszerzeniem coverage-information CRD - które EHR przechowuje w zamówieniu i później wysyła z upoważnieniem wcześniej - oraz kartę, którą czyta klinicysta. Zamówienie, którego kod nie ma reguły, jest odpowiedzią conditional, nigdy nie zakłada się, że jest objęte; wniosek bez ubezpieczenia w ogóle otrzymuje kartę, mówiącą o tym. examples/crd/ ma plik reguł i pasujący do niego kwestionariusz.

Reguła może również zawierać resztę informacji, które CRD pozwala płatnikowi podać:

Co EHR nie pobiera wcześniej, Perfuse odczytuje z serwera EHR fhirServer za pomocą tokenu, który wysłał. Jeśli to nie powiedzie się, odpowiedź jest indeterminate z powodem technical CRD, nigdy nie jest zgadywana. Pokrycie, które wygasło lub nie jest aktywne, jest odpowiedzią not-covered, no-active-coverage.

members: fhir w pliku reguł rozwiązuje ubezpieczenie przeciwko własnym rekordom płatnika w magazynie FHIR tego serwera (uruchom go z -fhir), te same rekordy, które $member-match czyta:

z tym numerem.

Odkrywanie deklaruje davinci-crd.version i opcję konfiguracyjną coverage-info. Gdy klient wyłącza tę opcję, odpowiedź jest pusta. Tokeny JWT EHR są sprawdzane zgodnie z definicją CDS Hooks, z iss, aud, exp, iat i jti i bez sub, a powtarzający się jti jest odrzucany.

Połączenia uwierzytelniają się za pomocą tokenu JWT, który EHR podpisał dla każdego połączenia, od wydawcy wymienionego w -cds-clients z jego adresem URL JWKS - który jest tym, jak CDS Hooks je opisuje - lub za pomocą tokenu API Perfuse. Odkrywanie jest otwarte, jak wymaga tego CDS Hooks.

DTR: załaduj kwestionariusze do punktu końcowego FHIR, a POST /fhir/Questionnaire/$questionnaire-package zwróci je jako pakiety DTR, z bibliotekami CQL, które wymieniają. Żądanie może nazwać kwestionariusz lub wysłać zamówienie i pozwolić jego coverage-information określić, który.

Próba: Płatnicy → Roszczenia i autoryzacja → Wymagania dotyczące ubezpieczenia (CRD) wysyła zamówienie do reguł tego serwera lub do adresu URL usługi CDS płatnika i wyświetla karty i informacje o ubezpieczeniu.

16.3 Roszczenia jako CARIN Blue Button

perfuse cms0057 carinbb łączy każde roszczenie w 837 z jego płatnością w 835, według numeru konta pacjenta, który 835 jest wymagany do powtórzenia, i zapisuje transakcję FHIR dla każdego: ExplanationOfBenefit z pacjentem, ubezpieczeniem, organizacjami i praktykami, na które powołuje się.

perfuse cms0057 carinbb -system https://fhir.your-plan.org/identifier -network innetwork \
    claims.837 remittance.835

Profil postępuje zgodnie z roszczeniem: profesjonalne roszczenia (837P) stają się C4BB-ExplanationOfBenefit-Professional-NonClinician, a instytucjonalne (837I) stają się wewnętrzne lub zewnętrzne, w zależności od typu rachunku. Każdy wpis jest PUT z identyfikatorem pobranym z identyfikatorów źródłowych, tak aby załadowanie tego samego roszczenia dwukrotnie zaktualizowało je, zamiast utworzyć drugą kopię.

Trzy rzeczy nie są zawarte w żadnym pliku X12, a każda z nich jest obsługiwana przez wskazanie, że ich nie ma, zamiast zgadywać:

Diagnozy są zapisywane z kropką dziesiętną (J02.9, a nie J029), ponieważ tak opublikowano system kodowania i serwer terminologiczny zapytany o inne pisownię mówi, że nie istnieje. Identyfikator członka zależnego jest identyfikatorem subskrybenta, który jest tym, co 837 zawiera, i notatki mówią o tym. NPI z niepoprawnym cyfrą kontrolną jest zgłaszany przed odrzuceniem przez US Core.

16.4 Uprzednie autoryzacje jako PDex

perfuse cms0057 priorauth konwertuje odpowiedź Da Vinci PAS ClaimResponse — lub pakiet odpowiedzi PAS, który ją zawiera — na PDex ExplanationOfBenefit dotyczący uprzedniej autoryzacji, który jest obsługiwany przez wszystkie trzy API danych.

perfuse cms0057 priorauth pas-response.json pas-claim.json

PAS Claim jest opcjonalny i prawie zawsze jest potrzebny. ExplanationOfBenefit musi określić, pod jakim ubezpieczeniem została podjęta decyzja, a tylko wniosek zawiera tę informację; bez niej konwersja zostaje zatrzymana i o tym informuje. Czynność przeglądu — zatwierdzenie, odrzucenie, zawieszenie, wraz z numerem autoryzacji i powodem — przechodzi z rozszerzenia PAS do PDex, a kod usługi X12 pozostaje pod adresem URI, do którego jest powiązany przez PDex.

16.5 API dostępu do danych dostawców i API pomiędzy płatnikami

Z -fhir-payer-apis punkt końcowy FHIR obsługuje trzy dodatkowe operacje:

Eksporty stosują reguły wykluczeń podczas eksportowania. Roszczenia tracą informacje o płatnościach i kwotach kosztów, oraz zachowują usługi, kody, daty i dostawców; profil CARIN jest usuwany z meta.profile, ponieważ zasób nie spełnia już jego wymagań. API pomiędzy płatnikami również pomija odrzucone uprzednie autoryzacje. Członkowie posiadający aktywną zgodę na opt-out dostępu do danych dostawców PDex są pomijani w eksportach dostawców, a log rejestruje liczbę takich członków. Parametr patient może być ograniczony tylko do członków grupy; podanie innej osoby jest odrzucane.

Dostęp do eksportu grupy jest decydowany przez uwierzytelnianie punktu końcowego. Zakresy SMART określają, jakie rodzaje zasobów może odczytać token, a nie, do której grupy, więc każdy dostawca potrzebuje tokenu, który może dotrzeć tylko do swojej własnej listy atrybucji. Token API może być ograniczony do grup podczas tworzenia — perfuse token create -label riverside-provider-access -fhir-groups riverside-attributed, lub pole Ogranicz do grup FHIR w sekcji Użytkownicy → Poświadczenia maszynowe — i na punkcie końcowym FHIR może odczytać te grupy, uruchomić $davinci-data-export lub $export na nich i pobrać to, co wyeksportowano, i nic więcej. Inna grupa dostawcy zwraca odpowiedź „nie znaleziono” zamiast „zabroniono”, więc token nie dowiaduje się, jakie inne listy atrybucji istnieją; każde inne żądanie, w tym dopasowanie członków i zwykłe wyszukiwanie, jest odrzucane. Ograniczenie dotyczy tokenów API; token z wydawcy SMART nie ma ograniczenia grupy. Gdy SMART jest również skonfigurowany, tokeny API są odrzucane, chyba że Ustawienia → FHIR → Akceptuj tokeny API Perfuse obok tokenów SMART są włączone (patrz: Bezpieczeństwo, *Kto może wywołać punkt końcowy FHIR*); token dostawcy z ograniczeniem grupy wymaga tego.

16.6 Katalog dostawców: Plan-Net

CMS-0057 również prosi płatników o katalog dostawców, a punkt końcowy FHIR obsługuje go dla Da Vinci Plan-Net 1.1.0 bez możliwości wyłączenia: ładuje Praktyków, Role Praktyków, Organizacje, Powiązania Organizacji, Lokalizacje, Usługi Opieki Zdrowotnej, Planów Ubezpieczenia i Punkty Końcowe, a aplikacje członków mogą wyszukiwać je. Każdy parametr wyszukiwania Plan-Net jest indeksowany - rola sieci i usługi, obszar pokrycia planu, organizacja uczestnicząca w powiązaniu, organizacja partof - wraz z include i łańcuchami odwrotnymi (_has), których używają zapytania przewodnika, a oświadczenie o możliwościach wymienia profile Plan-Net.

Pakiet testowy Plan-Net Inferno przechodzi 199 testów. 10 testów, które nie powiodły się, to łańcuchy do przodu, w których zestaw pobiera wartość wyszukiwania z pierwszej organizacji, którą widział, zamiast tej, na którą odnoszą się wyszukiwane zasoby; jest to zgłaszane do zestawu (jego problem 34), a serwer odpowiada poprawnie na te zapytania, gdy podano wartość, którą przechowuje dane.

16.7 Metriki uprzedniej autoryzacji

perfuse cms0057 metrics odczytuje plik CSV z decyzjami wyeksportowanymi z systemu zarządzania wykorzystaniem i tworzy stronę publiczną, którą wymaga CMS, w układzie *Raportowanie metryk uprzedniej autoryzacji — Przegląd i szablon*.

perfuse cms0057 metrics -year 2025 -org "Springfield Health Plan" -services services.csv \
    decisions.csv > prior-authorization-metrics-2025.html

Kolumny są znalezione według nagłówka: priority, received, decided i decision są wymagane, a request_id, line_of_business, extended, appealed, appeal_decision, service_code i service_description są odczytywane, gdy są obecne. Żądanie należy do roku, w którym zostało podjęte; żądanie, które nadal czeka, jest wyświetlane jako wykluczone, nigdy nie jest liczone. Każdy wiersz, który nie może być odczytany, jest zgłaszany wraz z numerem wiersza.

Arytmetyka postępuje zgodnie ze szablonem: dla standardowych i przyspieszonych żądań oddzielnie, udział zatwierdzony i odrzucony, zatwierdzony i odrzucony w ramach terminu decyzji, zatwierdzony po przedłużeniu czasu przeglądu, oraz zatwierdzony po odwołaniu — spośród odwołań, a nie spośród żądań — wraz z średnim i medianowym czasem od otrzymania do decyzji. Mediana poniżej dnia jest zapisywana w godzinach, a nie zaokrąglana do „0 dni”, co jest wyraźnie wymagane przez szablon. Częściowo zatwierdzone żądania są liczone jako zatwierdzone, ponieważ szablon nie ma kategorii dla nich, a strona podaje, ile ich było. Metryki są raportowane na poziomie linii biznesowej, który jest poziomem wymaganym przez CMS.

Strona jest samodzielna — nie zawiera skryptu, zewnętrznego arkusza stylów ani czcionki — ponieważ jest publikowana na publicznej stronie internetowej przez osobę, która ją utrzymuje, a wszystko, co ładuje z innego miejsca, jest czymś, co może ulec awarii lub śledzić odwiedzającego. -format csv i -format json dają te same numery dla innych zastosowań. Bez -services strona zawiera powiadomienie, że lista elementów i usług wymagających uprzedniej autoryzacji jest niekompletna, ponieważ CMS wymaga tego na tej samej stronie.

16.8 Leki: formularz, Real-Time Prescription Benefit i elektroniczna uprzednia autoryzacja

CMS-0062-P (zaproponowany 14 kwietnia 2026 r.) wprowadziłby leki do uprzedniej autoryzacji: dotknięci płatnicy wspieraliby elektroniczną uprzednią autoryzację NCPDP SCRIPT, standard NCPDP Formulary & Benefit i NCPDP Real-Time Prescription Benefit od 1 października 2027 r., decydowaliby o wnioskach o leki w ciągu 24 godzin (przyspieszone) i 72 godzin (standardowe), podawaliby konkretny powód każdej odmowy i raportowaliby metryki leków od 2028 r. Medicare Part D już wymaga elektronicznej uprzedniej autoryzacji SCRIPT. Jeden plik, formularz, odpowiada na to wszystko:

perfuse serve -fhir -pas -crd-rules payer-rules.yaml -formulary formulary.yaml

examples/formulary/formulary.yaml to przykład, w którym leki są rzeczywistymi pojęciami RxNorm z NDC, których lista jest sprawdzana przeciwko RxNav. Plik nazywa płatnika, jego plany (każdy z formularzem, który używa, jego identyfikatorami grupy i udziałami w kosztach według korzyści aptecznych i poziomu) i jego formularze. Każdy lek jest pojęciem RxNorm SCD lub SBD z jego grupą RxNorm (SCDG lub SBDG, które wymaga interfejs API Formulary), jego NDC, poziomem i limitami: prior_authorization, step_therapy, quantity_limit (ilość w określonej liczbie dni, oraz maksymalna dzienna), not_covered, alternatives (kody RxNorm, najbardziej preferowane jako pierwsze), notes i questionnaire, kanoniczny URL kwestionariusza FHIR, o który prosi uprzednia autoryzacja. cost_30_day to koszt planu 30-dniowego zaopatrzenia, którego współubezpieczenie jest procentem; bez niego współubezpieczenie jest cytowane jako procent, nigdy jako wymyślona kwota. Cały plik jest sprawdzany podczas ładowania, każdy problem jest wyświetlany na raz. Członek jest znaleziony przez listę members pliku, przez grupę lub za pośrednictwem sklepu FHIR: Coverage, którego subscriberId jest identyfikatorem członka, a którego class typu plan jest identyfikatorem planu. Płatnicy › Leki wyświetla formularz, wycenia lek i uruchamia uprzednią autoryzację od końca do końca.

16.8.1 API formularza leków Da Vinci US

Opublikowany w /formulary/fhir jako Da Vinci US Drug Formulary 2.1.0: każdy plan to PayerInsurancePlan, każdy formularz to Formulary (oba InsurancePlan), każdy lek to FormularyDrug (MedicationKnowledge), a każda pozycja to FormularyItem (Basic). Wyszukiwania przewodnika są obsługiwane (Basic?code=formulary-item&formulary=...&drug-tier=...&pharmacy-benefit-type=...&period=..., subject:MedicationKnowledge.code, InsurancePlan?formulary-coverage=..., coverage-type, MedicationKnowledge?code=...&doseform=...) z _include=Basic:subject, Basic:formulary i InsurancePlan:formulary-coverage. Jest to publiczne, bez poświadczeń, tak jak wymaga tego CMS od formularza płatnika: jest on obsługiwany ze sklepu własnego, w pamięci, który zawiera tylko formularz, więc nie może dotrzeć do rekordu pacjenta. Jest tylko do odczytu. Wykluczony lek nie jest publikowany, ponieważ interfejs API wyświetla, co formularz obejmuje; RTPB i ePA nadal odpowiadają na niego jako nieobjęte. Weryfikowany za pomocą walidatora HL7 FHIR wobec pakietu przewodnika 2.1.0 z sprawdzoną terminologią: każdy zasób wygenerowany z przykładu nie ma błędów.

16.8.2 Real-Time Prescription Benefit

POST /ncpdp/rtpb przyjmuje RTPBRequest (NCPDP RTPB v13) z tokenem API roli operatora i odpowiada RTPBResponse z formularza: statusu objęcia ubezpieczeniem, statusu formularza, szacowanego udziału członka i planu oraz ograniczeń objęcia ubezpieczeniem, z maksymalnie pięcioma objętymi alternatywami wycenianymi w ten sam sposób. Kody ograniczeń i status, do którego każdy z nich się odnosi, są zgodne z publicznymi zaleceniami wdrożeniowymi NCPDP dla RTPB: 75 wymagana autoryzacja, 608 terapia stopniowa, 76 przekroczone limity planu, 7X dni dostawy przekraczającej limit planu (np. lek nie dostępny pocztą), 70 nie objęty, wszystkie *z objęciem i ograniczeniami* (CR) z wyjątkiem 70 (NC). Członek z zatwierdzoną autoryzacją w pliku otrzymuje CC i AB8, zgodnie z wytycznymi Surescripts, aby uniknąć ponownego pytania lekarza. Żądanie, które nie może być wycenione, jest oznaczone jako NotProcessed z kodem odrzucenia NCPDP: 52 dla członka nie znalezionego, E7 i 19 dla brakującej ilości lub dni dostawy. Korzyść apteczna jest odczytywana z żądania: wypełnienie powyżej 34 dni jest uważane za trzymiesięczną dostawę, a typ apteki M jest uważany za zamówienie pocztowe.

16.8.3 Elektroniczna uprzednia autoryzacja (NCPDP SCRIPT)

POST /ncpdp/script przyjmuje PAInitiationRequest, PARequest, PAAppealRequest i PACancelRequest z tokenem API roli operatora i odpowiada na każde z nich odpowiedzią:

WniosekOdpowiedź
PAInitiationRequestClosed gdy nie jest potrzebna: CC nie wymaga uprzedniej autoryzacji, FN w ramach limitu ilości, FM nie objęty lub nie na formularzu, FQ zatwierdzenie w pliku, CD nie ma takiego członka, CG jeden już w trakcie. W przeciwnym razie Open, z ID przypadku i zestawem pytań.
PARequestDecyzja jako wniosek PAS: Approved z numerem autoryzacji i okresem, Denied z powodem, lub Open podczas przeglądu.
PAAppealRequestOdrzucony przypadek rozpatrzony ponownie, ze względu na powód w PANote (odwołanie bez niego jest proszone o to).
PACancelRequestApproved podczas gdy przypadek jest otwarty lub podczas przeglądu, a wniosek PAS jest anulowany; Denied raz jest zdecydowany.

Zestaw pytań jest kwestionariuszem FHIR leku z magazynu FHIR, tym samym, który wypełnia DTR: wartość logiczna staje się wyborem tak/nie, wybór staje się wyborem, liczba staje się liczbą, data staje się datą, a wszystko inne staje się tekstem dowolnym; grupy są spłaszczane w kolejności, a enableWhen nie jest przenoszony, ponieważ SCRIPT gałęzi się według wyboru, a nie według warunku. Lek bez kwestionariusza jest pytany o trzy pytania tekstowe: rozpoznanie, co było próbowane i dlaczego ten lek. PARequest staje się żądaniem Da Vinci PAS: Claim dla leku (RxNorm i NDC), MedicationRequest, o który się prosi, pacjent, lekarz, płatnik i ubezpieczenie, oraz odpowiedzi jako QuestionnaireResponse, z załącznikami jako DocumentReference. Następnie jest podejmowana decyzja, tak jak w przypadku każdej autoryzacji wstępnej na tym serwerze: plik reguł, usługa decyzyjna (-pas-decider-url), lub kolejka recenzentów, gdzie jest oznaczony jako Lek i zatrzymany do ram czasowych leku. Usługa decyzyjna widzi żądanie leku dokładnie tak, jak widzi je klient PAS z systemu EHR. Zalecamy Vaglio, silnik decyzyjny BioDream (PolyForm Shield), który ma polityki lekowe ze stopniową terapią; silnik własny płatnika jest podłączany przez tę samą -pas-decider-url, a nie jest potrzebny dla pliku reguł i recenzentów do podjęcia decyzji.

Decyzja podjęta po odpowiedzi na żądanie (recenzenta, apelacji) jest wysyłana do lekarza jako niespodziewana PAResponse lub PAAppealResponse, przekierowana do kanału o nazwie -epa-reply-channel, który dostarcza ją do sieci. Bez niego lub gdy dostarczenie nie powiedzie się, przypadek stwierdza, że lekarz nie został poinformowany, a ekran wysyła ją ponownie.

Płatnicy › Leki › Autoryzacja wstępna wysyła wiadomości, które system lekarza wysyła do własnego punktu końcowego serwera (rozpoczęcie, odpowiedź na pytania, wyświetlenie decyzji), wyświetla każdy przypadek z tym, co lekarz został poinformowany, oraz wyświetla dane lekowe, które proponuje CMS-0062-P: zatwierdzone, odrzucone i oczekujące, odwołane i zatwierdzone lub odrzucone w odwołaniu, średni i medianowy czas w godzinach od żądania do decyzji oraz ile z nich zostało podjętych z opóźnieniem. Leki refundowane z korzyści medycznej za pomocą PAS (kod HCPCS J z MedicationRequest lub przedmiot zakodowany w RxNorm lub NDC) są również liczone jako leki w danych PAS.

To, na czym polega, wyrażone w prosty sposób. Schematy i przewodniki wdrożeniowe NCPDP są objęte licencją. Nazwy elementów i ich kolejność są zgodne z publicznymi przewodnikami towarzyszącymi Surescripts ePA i RTPB oraz ich przykładami, a także z publicznymi zaleceniami wdrożeniowymi NCPDP dla RTPB. Dwa elementy, których publiczne materiały nigdy nie pokazują, są zapisywane w wzorcu SCRIPT stosowanym gdzie indziej i powinny być sprawdzone przeciwko objętej licencją kopii przed certyfikacją: Closed/ReasonCode i Denied/DenialReason. Żadna wiadomość nie została sprawdzona przeciwko XSD NCPDP lub certyfikacji sieci. Plik Formularza i Korzyści NCPDP nie jest produkowany: jego pełny układ jest w objętej licencją przewodniku NCPDP, a częściowy plik zostanie odrzucony przez sieć, która go ładuje.

16.9 Co zostało sprawdzone i przeciwko czemu

Wyniki CARIN i PDex zostały zwalidowane z oficjalnym walidatorem FHIR, załadowanym z opublikowanymi pakietami (hl7.fhir.us.carin-bb#2.2.0, hl7.fhir.us.davinci-pdex#2.2.0): profesjonalne, szpitalne i ambulatoryjne roszczenia oraz dwie decyzje PAS, bez błędów. Wejścia PDex były własnymi przykładami przewodnika PAS, a nie kształtami napisanymi tutaj, aby zgadzały się z konwerterem. Walidator znalazł pięć wad w pierwszym przebiegu — wśród nich, że CARIN wymaga wersji profilu w meta.profile i wersji systemu kodowania typu roszczenia na instytucjonalnych roszczeniach — i każda z nich jest naprawiona i objęta testem.

Budowanie tego ujawniło wadę starszą niż ono: magazyn FHIR upuszczał każdy element, którego jego wewnętrzny model nie deklarował, więc ExplanationOfBenefit tracił swoje elementy, diagnozy, rozstrzygnięcia i płatności po drodze. Magazyn teraz zachowuje wszystko, co niesie zasób, a test ładuje roszczenie CARIN przez serwer i odczytuje je z powrotem w całości.

Wyjście CRD - zaktualizowane zamówienie oraz odpowiedź CDS Hooks przeciwko własnemu modelowi logicznemu CRD - oraz wyjście pakietu DTR są walidowane w oficjalnym walidatorze HL7 przeciwko CRD 2.2.1 i DTR 2.2.0 bez błędów.

DTR tutaj jest stroną płatnika w wersji 2.2.0. $questionnaire-package pobiera kwestionariusze o podanych nazwach, te nazwane CRD na zamówieniu lub identyfikatorze asercji CRD zwróconym (context, podczas gdy ten sam proces obsługuje CRD), i zwraca każdy z nich jako pakiet z kwestionariuszem do wypełnienia, bibliotekami CQL i ich zależnościami. Zestawy wartości, których odpowiedzi używają, podróżują w pakiecie, gdy są ładowane (PUT /fhir/ValueSet/{id}), a $expand wyświetla ich kody. $log-questionnaire-errors zapisuje, co aplikacja DTR zgłasza do rejestru serwera.

Adaptacyjne kwestionariusze: napisz cały kwestionariusz raz, z rozszerzeniem SDC questionnaireAdaptive i enableWhen na pytaniach, które mają zastosowanie tylko czasem. Pakiet przekazuje aplikacji pusty szkielet, a każde wywołanie $next-question dodaje następne pytanie, które ma zastosowanie do odpowiedzi dotychczasowych, aż do momentu, gdy nie ma już nic do zapytania i odpowiedź jest oznaczona jako ukończona. Kolejność i gałęzie są własnymi regułami płatnika; pytania, które nie mają zastosowania, nigdy nie są wyświetlane.

Logowanie się jako klient: klienci DTR i PAS docierają do płatnika za pomocą usług Backend SMART - podpisanego JWT wymienionego na token w serwerze autoryzacji płatnika. Wskaż Perfuse na ten serwer za pomocą -smart-issuer (i -smart-jwks, jeśli jego adres nie rozwiązuje się z Perfuse), i przekaż -smart-backend-services, aby dokument odkrycia powiedział o tym. Suite DTR Inferno przechodzi tę drogą z Keycloak jako serwerem autoryzacji.

Perfuse może być również serwerem autoryzacji: serve -fhir -smart-clients clients.yaml wydaje tokeny Backend Services w /auth/token dla klientów wymienionych w pliku, każdy z kluczami publicznymi, których używa do podpisywania swoich oświadczeń, oraz zakresami systemu, które mogą być im przyznane, a punkt końcowy FHIR akceptuje je. Nie jest wymagany oddzielny serwer tożsamości dla klientów maszynowych płatnika.

Z -smart-users users.yaml użytkownicy i klinicyści logują się, aby autoryzować aplikacje, co jest wymagane przez Patient Access API: aplikacja wysyła osobę do /auth/authorize, osoba loguje się, klinicysta wybiera pacjenta, a obie strony widzą, o co aplikacja prosi, i mogą odznaczyć dowolne z tych elementów. Członek jest przydzielany tylko do swojej własnej dokumentacji, niezależnie od tego, o co aplikacja prosi. Każda osoba w pliku nazywa zasób FHIR, którym jest, Patient/… lub Practitioner/…, oraz hash hasła z perfuse smart hash; samo hasło nigdy nie jest zapisywane.

Ludzie mogą logować się za pomocą dostawcy tożsamości organizacji: -smart-oidc oidc.yaml określa dostawcę (wydawcę, identyfikator klienta i miejsce, w którym znajduje się sekret), a strona logowania oferuje „Zaloguj się za pomocą” obok hasła. Każda osoba jest połączona z podmiotem dostawcy, oidc_subject w pliku użytkowników, więc plik nadal decyduje, kto może autoryzować aplikacje i jaki zasób FHIR są; konto połączone z nikim jest odrzucane. Kody, tokeny odświeżania i unieważnienia są przechowywane w bazie danych, więc ponowne uruchomienie nie wyloguje nikogo.

Użytkownicy → Aplikacje SMART w konsoli wyświetla listę zarejestrowanych aplikacji i osób, oraz dodaje, edytuje i usuwa je. Każde zapisywanie jest sprawdzane tak, jak pliki są na starcie, zapisywane do nich i używane od razu. Aplikacja poufna zapisana bez sekretu otrzymuje jeden, wyświetlany raz; hasło jest ustawiane tam i nigdy nie jest ponownie wyświetlane. Usunięcie aplikacji lub osoby natychmiast zatrzymuje tokeny dostępu już wydane dla niej lub przyznane przez nich, a nie po ich wygaśnięciu, oraz tokeny odświeżania z nimi.

Zakresy mogą być drobnoziarniste, tak jak definiują je SMART App Launch 2 i US Core: patient/Observation.rs?category=laboratory odczytuje tylko te Obserwacje, które znalazłaby wyszukiwarka. Zatwierdzenie, które jest filtrowane dla typu, stosuje swój filtr do każdego wyszukiwania i każdego odczytu tego typu; niezatwierdzone dla typu lub dla * podnosi go. Filtrowanie, które nie może być odczytane, niczego nie przyznaje, zamiast wszystkiego.

16.10 Decyzje dotyczące wcześniejszych wniosków o autoryzację: PAS

serve -fhir -pas -crd-rules rules.yaml odpowiada na Da Vinci PAS 2.2.1 w POST /fhir/Claim/$submit i POST /fhir/Claim/$inquire. Decyzje pochodzą z tego samego pliku reguł, co odpowiedzi CRD, więc kolejność, w której klinicysta jest informowany o potrzebie autoryzacji, jest decydowana przez regułę, która tak powiedziała:

  - 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

Każdy element otrzymuje akcję przeglądu X12: A1 certyfikowany, A3 niecertyfikowany, A4 wstrzymany, A6 zmodyfikowany, C anulowany (typ certyfikacji 3). Linia, która nie nazwała żadnej usługi, nie jest decydowana, ale odpowiedzią z błędem (X12 901 AG, popraw i ponownie wyślij). Odpowiedź powtarza to, co powtarza odpowiedź 278 — numery śledzenia elementów, daty usług, daty spotkania, identyfikatory transmisji ze zmienionymi nadawcą i odbiorcą — i przyznaje każdej linii własny numer referencyjny administracyjny płatnika. Usługa, której nie nazwała żadna reguła, jest wstrzymana, nigdy nie zatwierdzona: decyzja, której nikt nie zapisał, jest decyzją dla osoby.

Wstrzymane wnioski oczekują na recenzenta, który odpowiada za pomocą POST /fhir/Claim/$decide:

{"resourceType": "Parameters", "parameter": [
  {"name": "claimResponse", "valueString": "<the ClaimResponse id>"},
  {"name": "decision", "valueCode": "approve"},
  {"name": "reason", "valueString": "Reviewed with the plan of care."},
  {"name": "reviewer", "valueString": "<the reviewer's NPI>"}]}

decision może być również modify: certyfikowany, ale nie tak, jak poproszono, z quantity (valueDecimal, jednostki certyfikowane) i/lub alternative (valueCoding, usługa zatwierdzona zamiast). Odpowiedź wtedy mówi A6 Zmodyfikowany, ze szczegółami certyfikacji lub alternatywą jako dodanym elementem, oraz numerem autoryzacji. item (valueInteger, wielokrotny) ogranicza decyzję do niektórych linii. Decyzja staje się nową wersją odpowiedzi, oznaczoną jako przeglądana przez osobę, oraz z -fhir-subscriptions jest dostarczana w temacie PAS (PASSubscriptionTopic, filtrowanym przez org-identifier, identyfikator organizacji wnioskującej) jako pełne wiązanie odpowiedzi PAS, w tej samej transakcji, która ją rejestruje. $inquire zwraca bieżącą odpowiedź na każdy wniosek, jaki dostawca złożył w sprawie tego członka; zapytanie innego dostawcy nie znajduje niczego. $decide wymaga zakresu zapisu; $inquire jest odczytem.

Wnioski i każda wersja ich odpowiedzi są przechowywane w pas_requests i pas_responses w bazie danych serwera.

16.10.1 Kolejka recenzenta

W konsoli internetowej Płatnicy → CMS-0057 → Kolejka recenzenta wyświetla listę wstrzymanych wniosków, które najwcześniej powinny być rozpatrzone: wniosek przyspieszony (Claim.priority stat) jest rozpatrywany w ciągu 72 godzin od jego przybycia, standardowy w ciągu 7 dni. Wybranie jednego z nich wyświetla członka, dostawcę, każdą usługę z jednostkami, o które poproszono, i stanem, o co odpowiedź poprosiła, oraz każdy dokument otrzymany dla niego, z dokumentami w postaci zwykłego tekstu wyświetlanymi w linii. Edytor rejestruje decyzję tam: zatwierdzenie, odrzucenie lub modyfikację (jednostki certyfikowane lub inna usługa zatwierdzona zamiast), z powodem i numerem NPI recenzenta. Modyfikacja musi certyfikować mniej jednostek, niż poproszono; tyle samo lub więcej jest zatwierdzeniem i jest odrzucane jako modyfikacja. Usługa zatwierdzona zamiast rozpoczyna się w systemie kodowania tej, o którą poproszono. Jest to ta sama decyzja, którą podejmuje $decide, więc subskrypcja dostawcy dostarcza ją. Odczyt wniosku i podjęcie decyzji są oba zapisywane w rejestrze audytu.

Monitor → Pulpity zespołowe → Autoryzacja wcześniej wyświetla, za ostatnie 30 dni, ile standardowych i przyspieszonych wniosków zostało rozpatrzonych w ramach czasowych CMS-0057, rozpatrzonych z opóźnieniem, wciąż oczekujących w czasie i spóźnionych teraz, z medianą czasu rozpatrywania, oraz jak usługi, o które poproszono, zostały odpowiedzi: zatwierdzone, zmodyfikowane, odrzucone lub wciąż wstrzymane. Te dwie kafelki są odczytywane z samych wniosków, więc nie są w eksporcie pulpitu Grafana, który mówi o tym w swoim opisie.

16.10.2 Otrzymywanie dokumentów, o które wnioskuje wniosek oczekujący

Odpowiedź wstrzymana prosi o dokumenty z zadaniem i jednym CommunicationRequest na dokument. Kwestionariusz jest wymagany zgodnie z opisem PAS: CommunicationRequest z jednym kodem LOINC 102089-0, pod numerem śledzenia linii, dla której jest (itemTraceNumber, który ClaimResponse powtarza; linia wysłana bez niego otrzymuje jeden). Ten numer śledzenia to kontekst DTR: $questionnaire-package z ustawionym tylko context zwraca kwestionariusz. Dostawca wysyła to, co zostało poproszone, z Da Vinci CDex $submit-attachment (POST /fhir/$submit-attachment): TrackingId jest własnym numerem śledzenia wniosku (pierwszym identyfikatorem ClaimResponse, który jest również identyfikatorem zadania), lub identyfikatorem CommunicationRequest, AttachTo jest preauthorization, a MemberId musi być członkiem wniosku. Każde załączniki DocumentReference lub QuestionnaireResponse są przechowywane z wnioskiem i wyświetlane jego recenzentowi; przychodzący dokument niczego nie decyduje.

16.10.3 Decyzja w systemie zarządzania wykorzystaniem X12

Większość płatników decyduje o uprzednich autoryzacjach w systemie UM, który mówi X12 278. Z -pas-278-url, Perfuse jest frontem FHIR tego systemu: każde $submit jest wysyłane jako jeden wniosek 278 (005010X217), każdy element jest zdarzeniem pacjenta. Każdy z nich zawiera to, co PAS nazywa dla niego: typ przeglądu (extension-serviceItemRequestType, UM01: usługi zdrowia, przyjęcia lub opieki specjalistycznej), typ certyfikacji (extension-certificationType, UM02), typ usługi, miejsce świadczenia usług (UM04), poziom usług (extension-levelOfServiceCode, UM06: wybór, pilny lub nagły; priorytet stat zastępuje pilny), data, daty przyjęcia i wypisu w przypadku przeglądu przyjęcia, diagnozy, świadczeniodawca, który wykona usługę, oraz procedura i ilość, jako usługa profesjonalna (SV1) lub, na roszczeniu instytucjonalnym, usługa szpitala (SV2). Kod akcji i numer autoryzacji odpowiedzi 278 stają się działaniem przeglądu elementu: zatwierdzone, w części lub zmodyfikowane, odrzucone, anulowane lub nierozpatrzone (wstrzymane do przeglądu, z powodami odrzucenia). Nie konsultuje się lokalnych zasad.

perfuse serve -fhir -pas -pas-278-url https://um.example/x12/278 -pas-278-receiver ACMEUM \
  -pas-278-token-env UM_TOKEN

System UM, który najpierw wstrzymuje, a potem decyduje, wysyła swoją późniejszą odpowiedź 278 do POST /fhir/Claim/$decide-278; każde zdarzenie jest dopasowane do swojego żądania przez numer śledzenia, który Perfuse wysłał, i jest decydowane tak, jakby $decide je decydował. Jeśli system UM nie może być dotknięty lub odpowiada czymś, co nie jest odpowiedzią 278, każdy element jest wstrzymany do recenzenta, a dostawca jest informowany tylko o tym; powód jest w logu serwera.

Zapytania, na które system UM odpowiada

Zapytanie $inquire dostawcy musi znaleźć autoryzację, niezależnie od tego, w jaki sposób została ona zażądana: faksem, przez portal płatnika, telefonicznie lub w 278 innym podmiocie, który ją wysłał. Perfuse przechowuje tylko te zapytania, które przyszły przez niego; system UM przechowuje je wszystkie. Dlatego też w przypadku systemu UM, który odpowiada w czasie rzeczywistym (każdy transport z wyjątkiem sftp), każde $inquire jest również wysyłane tam jako zapytanie 278 (005010X215: BHT02 28, członek, dostawca, numer autoryzacji z insurance.preAuthRef Claim, gdy jest dostępny, oraz daty zdarzeń z billablePeriod lub daty usług z pozycji, w przeciwnym razie rok po obu stronach od dziś). Każda autoryzacja, której odpowiedź nie zawiera Perfuse (dopasowana przez numery śledzenia, które wysłał i numery autoryzacji, które już podał), jest zwracana jako kolejny pakiet odpowiedzi na zapytanie o roszczenie: decyzja systemu UM dla każdej pozycji usługi, numer autoryzacji i okres, oraz uwaga, w której miejscu została znaleziona. Żadne roszczenie nie jest tworzone dla autoryzacji, której nikt nie złożył w FHIR: jego ClaimResponse.request zawiera powód braku danych, zgodnie z profilem PAS. Zapytanie odczytuje tylko; nic w rekordach Perfuse nie ulega zmianie. Jeśli system UM jest niedostępny lub odpowiada z TA1 lub 999, dostawca otrzymuje to, co Perfuse posiada, a stan łącza wskazuje, dlaczego.

Jak 278s docierają do systemu UM

Przewodnik połączeń systemu UM mówi, jak akceptuje 278s, a -pas-278-transport (Ustawienia, Płatnicy, Link zarządzania wykorzystaniem) postępuje zgodnie z tym:

TransportCo jest wysyłaneUwierzytelnienie
x12 (domyślny)278 POSTed jako application/edi-x12; odpowiedź to treść odpowiedziToken bearer, OAuth, HTTP Basic, certyfikat klienta
core-soapCAQH CORE czas rzeczywisty SOAP 1.2 koperta (COREEnvelopeRealTimeRequest, typ ładunku X12_278_Request_005010X217E1_2, lub X12_278_Request_005010X215 dla zapytania): Reguła połączenia vC2.2.0 z ładunkiem w kopercie, który używany jest przez większość płatników i CMS esMD, lub -pas-278-core-version C4.0.0 z ładunkiem jako załącznikiem MTOMvC2.2.0: nazwa użytkownika i hasło (WS-Security UsernameToken) lub certyfikat klienta. vC4.0.0: certyfikat klienta i token OAuth
core-mimeCAQH CORE vC2.2.0 HTTP MIME multipart koperta, ładunek jako część plikuNazwa użytkownika i hasło koperty, lub certyfikat klienta
sftpKażdy 278 umieszczony w folderze na serwerze SFTP systemu UM (-pas-278-sftp, -pas-278-sftp-outbound); odpowiedzi zebrane z innego (-pas-278-sftp-inbound, każde -pas-278-sftp-every)Klucz SSH lub hasło; klucz serwera musi być w -pas-278-sftp-known-hosts

Certyfikat klienta to -pas-278-cert i -pas-278-key; -pas-278-ca ufa własnej władzy certyfikacji płatnika. OAuth to -pas-278-oauth-token-url, -pas-278-oauth-client-id i sekret, pobrany za pomocą grantu client-credentials i przechowywany do minute przed wygaśnięciem. Hasła, tokeny i sekrety są zawsze nazwane przez zmienną środowiskową (-pas-278-password-env, -pas-278-token-env, -pas-278-oauth-secret-env, -pas-278-sftp-password-env), lub wpisane w ekranie ustawień, gdzie są przechowywane w pliku ustawień (dostępnym tylko dla konta serwera) i nigdy nie są ponownie wyświetlane.

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

Przez SFTP każde żądanie jest wstrzymane, aż do czasu otrzymania odpowiedzi: odpowiedź 278 decyduje o elementach, a Perfuse umieszcza 999 akceptujące w folderze nadawanym. Plik, którego nie można odczytać, pozostaje w folderze wejściowym dla osoby i jest ponownie oferowany podczas następnego odczytu.

Kiedy system UM nie może odczytać żądania

System UM, który nie może odczytać 278, odpowiada TA1 (kopertą) lub 999 (transakcją) zamiast decyzją. Perfuse odczytuje, co i jak się nazywa, odkłada każdy element („zarządzanie wykorzystaniem nie mogło odczytać wniosku”) i rejestruje to. Payer, CMS-0057, Kolejka recenzenta wyświetla link: co zostało wysłane w ciągu ostatnich siedmiu dni, każda wymiana według numeru kontrolnego, i co się z nią stało (odpowiedź; potwierdzenie, odpowiedź do przyjścia; odrzucona, z segmentem, elementem i kodem 999; nieosiągnięta). Każda wymiana ma swój własny numer kontrolny, jeden więcej niż poprzedni, który jest tym, co TA1 lub 999 nazywa, gdy odpowiada.

16.10.4 Decyzja na podstawie dowodów klinicznych, z usługą decyzyjną

Plik reguł decyduje o kodzie usługi: kod nie potrzebuje autoryzacji, nie jest objęty, lub jest przekazywany do recenzenta. Czy ten pacjent spełnia kryteria dla niego, jest to inne pytanie, na które odpowiedź jest udzielana na podstawie warunków, odpowiedzi kwestionariusza i dokumentów, które dostawca wysłał wraz z żądaniem. Z -pas-decider-url, każdy element, który reguły pozostawiają do recenzenta, jest najpierw przekazywany do usługi decyzyjnej, takiej jak Vaglio, która odczytuje ten sam pakiet żądania PAS za pośrednictwem opublikowanego pakietu pas Perfuse. Publiczny Vaglio, na wymyślonych żądaniach, działa obok instancji testowej Perfuse pod adresem https://vaglio.perfuse.health:8443 (zaloguj się jako demo, hasło try-vaglio-demo; może on spojrzeć na wszystko i niczego nie zmienić): każda decyzja tam ma swoje uzasadnienie, list w języku zwykłym i potwierdzenie, które każdy może sprawdzić.

perfuse serve -fhir -pas -crd-rules payer-rules.yaml -pas-decider-url https://vaglio.example/api/pas/decide \
  -pas-decider-token-env VAGLIO_TOKEN

Adres URL musi być https lub zwykłym http do tej maszyny (localhost, 127.0.0.1), ponieważ przenosi rekord pacjenta i token. Vaglio sam odpowiada tylko na https; gdy używa certyfikatu z własnej władzy, przekaż tę władzę za pomocą -pas-decider-ca DATA/tls/ca.crt (lub jakąkolwiek wewnętrzną władzę płatnika, z której pochodzi certyfikat usługi). Usługa otrzymuje pakiet żądania jako dostawca go wysłał, POST <url>?item=<sequence> (application/fhir+json), i odpowiada {"decision": "approve" | "deny" | "pend", "why": "...", "requested": ["..."]}, lub 404 gdy decyduje niczego dla tego elementu, co pozostawia odpowiedź reguł. why jest notatką procesu odpowiedzi i jest wymagana dla odmowy, która w przeciwnym razie jest wstrzymana; requested jest powiedziane dostawcy jako informacja, której potrzebuje wstrzymany wniosek. Wstrzymanie może również zawierać "questionnaire": "<canonical>" i "attachments": ["<LOINC>", ...], które są pytane w odpowiedzi CDex Task i CommunicationRequests obok dowolnego kwestionariusza DTR lub załączników, o które prosi reguła (kwestionariusz reguły wygrywa, ponieważ zadanie prosi o jeden; kod, który nie jest kształtem LOINC, jest odrzucany i zalogowany). Reguła, która zatwierdza lub odrzuca, jest polityką ubezpieczeniową płatnika i nie jest wysyłana do usługi. Awaria, limit czasu lub odpowiedź, która nie jest jedną z trzech decyzji, wstrzymuje element do recenzenta, z powodem w logu serwera: nic tutaj nie zmienia awarii w zatwierdzenie. Nie można go łączyć z -pas-278-url, gdzie system UM odpowiada na każdy element.

Porada przed wysłaniem. Z -crd-advisor-url obok -crd-rules, CRD również prosi usługę decyzyjną, co poprzednia autoryzacja wniosku dla każdego zamówienia, które jej potrzebuje, byłaby powiedziana, gdy rekord stoi, i pokazuje odpowiedź jako jedną więcej kartę: "Przed wysłaniem: wniosek o to wymaga: ...", lub "zostałby zatwierdzony", z tym, co jest jeszcze potrzebne, kwestionariuszem, który o to pyta, i tym, co by go zatwierdziło. Vaglio odpowiada na /api/pas/advise, z tym samym tokenem i władzą, co powyżej:

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 wysyła POST <url> z {"service": {"system": "...", "code": "..."}, "resources": [ ... ]}, zasoby są przed-wyborem (pacjent jako pierwszy, pokrycie wykluczone), i czyta {"decides": true, "answer": "approve" | "pend" | "deny", "summary": "...", "missing": [...], "questionnaire": "...", "toApprove": [[...]], "policyTitle": "..."}. Jest to porada i nic nie zmienia: informacje o pokryciu, inne karty i decyzja PAS są tym, co mówią reguły. Czekaj najwyżej trzy sekundy, a brak odpowiedzi, awaria lub "decides": false pozostawia odpowiedź dokładnie taką, jaką jest bez niej. Perfuse nigdy nie potrzebuje usługi decyzyjnej.

Żądanie przenosi X-PAS-Request-Id, identyfikator, przez który odpowiedź jest znana. Usługa z własnymi recenzentami, która wstrzymuje element, może wysłać swoją decyzję później jako każdy recenzent: Claim/$decide z tym identyfikatorem jako claimResponse, sekwencją elementu i decyzją oraz powodem. Subskrypcja dostawcy dostarcza ją tak, jakby została zrobiona w kolejce recenzenta.

Subskrypcja z zawartością id-only mówi dostawcy, jaka odpowiedź się zmieniła, nie mówiąc, co to jest: focus powiadomienia jest Bundle/<id>. GET /fhir/Bundle/<id> zwraca najnowszy pakiet odpowiedzi PAS, GET /fhir/Bundle/<id>/_history/<n> wersję, którą powiadomienie wysłało, a GET /fhir/ClaimResponse/<id> samą ClaimResponse. Token związany z jednym pacjentem jest powiedziany, że nie istnieje, jak w przypadku każdego rekordu poza jego pacjentem.

ZWERYFIKOWANO z oficjalnym pakietem testowym Inferno PAS Server v2.2.1 (patrz weryfikacja). Nie wysłano, chociaż PAS oznacza je jako wymagane: ClaimResponse.adjudication z akcją przeglądu, ClaimResponse.extension:authorizedProvider oraz ClaimResponse.item.extension:communicatedDiagnosis, ponieważ rozszerzenia, których potrzebują, nie są dozwolone w tym miejscu przez ich własny kontekst w PAS 2.2.1, a walidator odrzuca odpowiedź zawierającą je; oraz request.extension:DataAbsentReason, ponieważ Perfuse zawsze wie o wniosku. 278s wysłane do systemu zarządzania wykorzystaniem (powyżej) są sprawdzane przeciwko własnym przykładom wniosków PAS 2.2.1, opublikowanym przykładom esMD 278 CMS i sprawdzarce 278 napisanej z publicznych przewodników towarzyszących, a każdy transport jest sprawdzany przeciwko systemowi zastępczemu UM napisanemu z zasad łączności CAQH (patrz weryfikacja); jeszcze nie przeciwko prawdziwemu systemowi UM lub domu clearingowego, i nie certyfikowany CORE. Niezaimplementowane: załączniki wysyłane z powrotem z CDex.

Plik reguł jest sprawdzany pod kątem własnych niezmienników CRD podczas ładowania: kwestionariusz wymaga dokumentacji, usługa, która nie jest objęta ubezpieczeniem, nie może wymagać autoryzacji, satisfied należy do jednego przypadku, a nie reguły, oraz wszystko, co warunkowe, musi podać powód.

Niezweryfikowane: eksporty i dopasowanie członków do implementacji innego płatnika, metryki w stosunku do opublikowanych danych płatnika oraz CRD w stosunku do klienta CDS Hooks rzeczywistego EHR.

16.11 Wysyłanie wniosków o uprzednią autoryzację do płatnika (dla dostawców)

Wszystko powyżej odpowiada na wnioski, jako płatnik. Strona dostawcy jest odwrotna: system EHR lub aplikacja DTR tworzy paczkę wniosku Da Vinci PAS, a coś musi ją wysłać do płatnika, zachować odpowiedź i ją przekazać. Miejsce docelowe pas robi to.

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

Każda wiadomość musi być pełną paczką wniosku PAS na kanale surowym. Perfuse publikuje ją bez zmian w {payer}/Claim/$submit: płatnik decyduje o wniosku wraz z pacjentem, ubezpieczeniem i wspierającymi zasobami w paczce, a wniosek odbudowany z podsumowania straciłby je. Poza tą maszyną adres płatnika musi być https.

Decyzja jest dostarczonym żądaniem, niezależnie od tego, co mówi. Akceptacja, odrzucenie i oczekiwanie są wszystkie rejestrowane i żadna z nich nie jest powtarzana, ponieważ powtarzanie odrzucenia skutkuje ponownym wysłaniem tego samego żądania. To, co powoduje niepowodzenie dostarczenia i jest powtarzane, jest płatnikiem, który nie podjął decyzji: status błędu, OperationOutcome (jego tekst jest błędem) lub ClaimResponse, którego wynik jest error. Decyzja jest odczytywana punkt po punkcie z kodów akcji przeglądu PAS (X12 306: A1 zatwierdzony, A2 częściowo, A3 odrzucony, A4 wstrzymany, A6 zmodyfikowany); odpowiedź bez kodu jest wyświetlana jako "brak kodu decyzji" zamiast być traktowana jako akceptacja. Odrzucenie bez powodu w żadnym miejscu jest odrzucane jako nie spełniające wymogów CMS-0057.

Odpowiedź płatnika jest odpowiedzią miejsca docelowego, więc Zbadaj odpowiedź może ją ocenić, a results_to przekazuje ją do innego kanału. Każdy wniosek jest wymieniony na CMS-0057, Wnioski wysłane do płatników: kiedy został wysłany, pacjent, usługa, decyzja i odniesienie płatnika (preAuthRef), które późniejsze zapytanie nazywa. Lista jest przechowywana w prior-auth.json obok bazy danych (maksymalnie 10 000 wniosków; najstarsze zdecydowane idą pierwsze, wniosek w zawieszeniu nigdy nie idzie), a każdy najemca widzi tylko swoje.

Weryfikowany względem implementacji referencyjnej płatnika HL7 Da Vinci PAS (obraz docker hlseven/davinci-prior-auth): wniosek wysłany przez uruchomiony kanał jest zawieszony przez niego z jego odniesieniem, a odpowiedź pojawia się na ekranie (zobacz weryfikację). Jeszcze nie wypróbowany względem płatnika produkcyjnego. Nie zbudowany: kontynuowanie wniosku w zawieszeniu za pomocą $inquire lub otrzymanie późniejszej odpowiedzi płatnika przez subskrypcję; kanał może to robić dzisiaj z miejscem docelowym http lub fhir.

16.12 Sieci wyrównane z CMS

Ramowy program interoperacyjności CMS (Ekosystem technologii zdrowia CMS) prosi sieci danych zdrowotnych o samo-potwierdzenie 26 kryteriów i umieszczenie na liście jako Sieci zgodne z CMS; EHR, dostawcy, płatnicy i aplikacje łączą się z nimi. Kryteria 13 do 16 obowiązują od 4 lipca 2026 r.: interfejsy API FHIR na US Core z pełnym CapabilityStatement i Bulk Data, dokumenty jako załączniki FHIR do czytania przez ludzi, powiadomienia o spotkaniach i wizytach za pomocą subskrypcji FHIR oraz lokalizator rekordu.

Administruj › Sieć zgodna z CMS wyświetla każde kryterium z tym, co Perfuse zapewnia dla niego, oraz stan tego serwera, odczytany z tego, co jest włączone tutaj:

StatusZnaczenie
Gotowy tutajPerfuse zapewnia to i jest włączone.
Gotowy, z lukąJest włączone, a część kryterium jest poza nim (nazwana na ekranie).
Zbudowany, nie włączonyPerfuse zapewnia to; ekran podaje ustawienie lub flagę, która je włącza.
Twoja sprawaCzęść organizacji: porozumienie, certyfikacja, publikowanie w National Provider Directory.
Nie zbudowanyOprogramowanie miałoby to robić, a Perfuse nie.

Czworo, które obowiązują od tego serwera:

KryteriumW PerfuseWłącz
13 Interfejsy API FHIR, US Core, Bulk DataPunkt końcowy FHIR z CapabilityStatement i $export-fhir, -fhir-bulk-export
14 Dokumenty jako załączniki FHIRDocumentReference z Binary i IHE MHD nad rejestrem XDS-fhir (MHD również -xds)
15 Powiadomienia o spotkaniach i wizytachSubskrypcje oparte na tematach (R5 Backport dla R4) z karm ADT i SIU-fhir-subscriptions
16 Lokalizator rekorduRejestr XDS.b, XCA dla innych społeczności, PIXm-xds, -xds-home-community

Ekran jest arkuszem do potwierdzenia, a nie certyfikatem: CMS przegląda sieci, które podejrzewa o nie spełnianie kryteriów, a własny tekst ramowego programu jest autorytatywny. Nie zbudowane dzisiaj: otwarte zapytania o lukę w jakości (kryterium 8), zapytanie płatnika o dane spotkania roszczenia (9), raportowanie metryk zapytań do katalogu dostawców krajowych (19), sprawdzanie dostawców w tym katalogu (6), odczytywanie praw kierowcy lub cyfrowych kart ubezpieczeniowych (3, 23) oraz egzekwowanie ogólnej polityki zgody na każde odczytanie (5). IAL2 identyfikacja tożsamości jest usługą tożsamości; Perfuse akceptuje tokeny wybranej przez Ciebie usługi.

17 Bezpieczeństwo

Perfuse obsługuje dane kliniczne. Ten rozdział opisuje, co robi w tym zakresie i co pozostawia Tobie.

17.1 Bezpieczeństwo transportu

TLS w interfejsie sieciowym jest konfigurowany z -tls-cert i -tls-key. Bez nich interfejs jest zwykłym HTTP, co jest akceptowalne na adresie pętli zwrotnej dla pierwszego spojrzenia i nigdzie indziej — przenosi poświadczenia i zawartość wiadomości, obie czytelne w sieci.

TLS w transporcie kanałów jest na poziomie źródła i miejsca docelowego, pod blokiem tls. Dostępne ustawienia są w odniesieniu do źródła i odniesieniu do miejsca docelowego.

insecure_skip_verify akceptuje każdy certyfikat. Istnieje, ponieważ systemy szpitalne rutynowo przedstawiają certyfikaty, które nie będą weryfikowane, a odmowa połączenia oznaczałaby odmowę integracji. Jest nazwany, aby być wyraźnym, a używanie go oznacza, że połączenie jest szyfrowane, ale nie uwierzytelnione — masz ochronę przed biernym przechwytywaniem i żadną przed serwerem pośrednim.

Połączenie TLS bez weryfikacji nie jest takie samo jak połączenie z weryfikacją, a rozróżnienie jest warte zapisania gdzieś, gdzie Twoi audytorzy je znajdą. Lepszym rozwiązaniem jest prawie zawsze uzyskanie certyfikatu końcowego i zaufanie mu explicite zamiast ufać wszystkiemu.

17.2 Uwierzytelnianie i role

Użytkownicy są przechowywani w bazie danych. Każdy z nich ma jedną z pięciu ról, a każda rola obejmuje wszystko, co zawarte w rolach powyżej niej:

RolaMoże
MonitorZobaczyć, czy wszystko działa: status kanału, liczby, mapa przepływu, alerty, pulpity i głębokość kolejki. Bez zawartości wiadomości, plików kanałów ani wiadomości w kolejce.
WidzRównież odczytać wiadomości, pliki kanałów, ślady i rejestr aktywności.
OperatorRównież ponownie wysłać: ponownie przetworzyć wiadomość, odtworzyć kanał i ponowić dostarczanie do kolejki.
EdytorRównież utworzyć i zmienić kanały oraz uruchomić porównania.
AdminRównież uruchomić i zatrzymać kanały, wyczyścić kolejki oraz zarządzać ludźmi, tokenami i ustawieniami serwera.

Szósta rola, Platforma, należy do osoby, która zarządza współdzielonym serwerem: tworzy najemców i ustawia ich limity, oraz nie posiada kanałów własnych.

Monitor jest dla biura pomocy technicznej lub dla ekranu operacyjnego na ścianie: wszystko, co jest potrzebne do zobaczenia, że kanał przestał działać, oraz nic, co nie nazywa pacjenta. Widz może odczytywać zawartość wiadomości, co jest danymi klinicznymi; jest to rola o niskich uprawnieniach do *konfiguracji*, a nie do prywatności. Operator oddziela naprawę nieudanej dostawy w nocy od zmiany tego, co robi kanał: osoba, która ponownie wysyła, nie musi mieć możliwości przepisywania kanału.

17.2.1 Powtarzające się błędne hasła

Błędne hasła i nieudane logowania z użyciem klucza są liczone według adresu, z którego pochodzi połączenie, a po kilku w rzeczy ciągu ten adres musi czekać, zanim będzie mógł spróbować ponownie (odpowiedź to 429, z Retry-After). Konta nie są zamykane według nazwy, ponieważ pozwoliłoby to komukolwiek zablokować administratora celowo.

Adres jest własnym adresem połączenia, nigdy tym, który żądanie podaje w X-Forwarded-For, który nadawca pisze. Za reverse proxy na tej samej maszynie Perfuse używa ostatniej wpisu X-Forwarded-For zamiast, tego, który proxy dodał, aby każdy klient był nadal liczbą oddzielną. Proxy na innej maszynie dociera do Perfuse z jednego adresu, i wszyscy jego klienci dzielą jeden licznik: ograniczaj logowania w tym proxy.

17.2.2 Grupy kanałów

Osoba (lub token API) może być ograniczona do niektórych grup kanałów: wtedy widzi i wykonuje działania tylko na kanałach, których group jest jednym z ich własnych. Jest to rozwiązanie grupy szpitali na jednym serwerze, gdzie analitycy każdego obiektu opiekują się własnymi kanałami, a centralny zespół, bez ograniczeń, opiekuje się wszystkimi. Rhapsody nazywa to szafą.

Limit dotyczy wszędzie jednocześnie, ponieważ jest stosowany do żądania, a nie zapamiętany przez każdy ekran: lista kanałów, pulpit nawigacyjny i mapa przepływu, wiadomości i ich wyszukiwanie, liczby i wykresy, kolejka, alerty, metryki, certyfikaty, umowy i użycie zestawu kodów. Kanał spoza grupy osoby nie istnieje dla nich; pytanie o niego pod nazwą odpowiada *nie znaleziono*, więc jego nazwa nie jest potwierdzona. Kanał bez grupy jest widoczny tylko dla osób bez limitu.

Zapisywanie kanału zachowuje go wewnątrz grupy osoby: nie mogą utworzyć kanału w innej grupie ani przenieść go poza swoją własną. To, co każda placówka udostępnia - tabele kodów, biblioteki skryptów, decyzje o uprzedniej autoryzacji - mogą odczytywać, ale nie zmieniać. Dane serwerowe (uprzednia autoryzacja, użycie tokenów, tunele) są wyświetlane tylko osobom bez limitu, oraz metryki i alerty dotyczące całego serwera, a nie kanału.

Administrator ograniczony do grup jest własnym administratorem placówki. Zarządza ludźmi i tokenami swoich grup, uruchamia i zatrzymuje ich kanały oraz czyści ich kolejki. Koledze, którego dodaje, przydziela grupy, chyba że nazwie niektóre z nich, nie może dać grupy, której nie posiada, oraz nigdy nie widzi ani nie zmienia nikogo bez limitu. Wszystko inne, co może zrobić administrator, zmienia cały serwer - ustawienia, logowanie, ponowne uruchomienie, reguły alertów, marka, flota, serwer SMART - i jest mu odmówione.

Grupy są ustawiane w Użytkownicy (i dla tokenów w Tokeny), jako lista rozdzielona przecinkami. Każda zmiana jest rejestrowana w dzienniku aktywności i obowiązuje od następnego żądania osoby.

Inna rola w każdej grupie

Osoba może posiadać różne role w każdej ze swoich grup: lab=editor, adt w Użytkownicy edytuje kanały laboratorium i ma wybraną rolę obok niego - powiedzmy widza - w kanałach przyjęć. Widzi kanały obu grup na każdym ekranie. Zapisywanie, uruchamianie lub ponowne wysyłanie kanału w grupie, w której jego rola jest zbyt niska, jest odrzucane z rolą, którą posiada tam; nie udaje, że kanał jest nieobecny, ponieważ może go zobaczyć. Jego rola u góry ekranu jest najwyższą, którą posiada, co otwiera ekrany, które ta rola używa, oraz każda akcja na tych ekranach jest nadal zawężona do grup, w których ją posiada.

Tylko osoby ograniczone do grup kanałów mogą mieć jedną. Ktoś, kto widzi każdy kanał, ma jedną rolę, ponieważ "edytor kanałów laboratorium" dla osoby bez limitu byłby edytorem wszystkiego, co należy do żadnej grupy, oraz stron serwerowych. Administrator placówki może przydzielić rolę na grupę tylko w grupach, które administruje, oraz nigdy powyżej swojej własnej roli tam.

17.3 Kto może wywołać punkt końcowy FHIR

Punkt końcowy FHIR (serve -fhir) sprawdza jeden z dwóch rodzajów tokenów:

Po skonfigurowaniu SMART, akceptowane są tylko tokeny SMART, więc każdy wywołujący jest ograniczony do swoich zakresów. Token API ma rolę i nie ma zakresów: token widza może odczytać każdy rekord pacjenta. Płatnik, który włączył SMART, aby ograniczyć każdą aplikację do tego, co zostało jej przyznane, nie powinien mieć sposobu na dostęp, który nie jest ograniczony.

Niektóre strony wymagają obu - wewnętrznego kanału roszczeń, który posiada token API i nie ma klienta SMART, obok aplikacji członkowskich, które logują się za pomocą SMART. Dla nich Ustawienia → FHIR → Akceptuj tokeny interfejsu API Perfuse obok tokenów SMART (-fhir-api-tokens podczas uruchamiania) pozwala na tokeny API. Jest wyłączone domyślnie, obowiązuje od następnego żądania w obie strony i zmiana jest zapisywana w rejestrze audytowym. Token jest rozróżniany przez jego kształt: token SMART jest podpisanym JWT, a token API nigdy nie jest, więc jeden jest nigdy nie sprawdzany jako inny. Gdzie możesz, nadaj takiemu systemowi klienta usług backend SMART z tylko tymi zakresami systemu, których potrzebuje.

17.3.1 Punkt końcowy FHIR otwarty dla obcych

Publiczny serwer testowy wydaje poświadczenia, które mogą zapisywać, ponieważ testowanie upoważnienia wcześniej lub subskrypcji wymaga zapisów. Dwa limity uniemożliwiają jednej aplikacji psucie wszystkiego, oba dostępne pod Ustawienia → FHIR i oba wyłączone domyślnie:

Własny punkt końcowy szpitala nie potrzebuje żadnego z nich.

17.4 Agenci AI: serwer MCP

Z Ustawienia › Bezpieczeństwo › Agenci AI (MCP) włączone (lub serve -mcp), Perfuse obsługuje Model Context Protocol pod adresem /mcp, aby agenci AI, tacy jak Claude, ChatGPT lub asystenci IDE, mogli pytać o to, co się dzieje. Jest wyłączone domyślnie, a wyłączenie powoduje zatrzymanie każdego agenta podczas następnego połączenia.

Agent łączy się z tokenem interfejsu API z Administruj › Użytkownicy › Poświadczenia maszynowe jako token nośnik, nigdy z sesją przeglądarki osoby (co jest odrzucane, więc agent nigdy nie działa z pełnym dostępem osoby). Konfiguracja klienta wygląda następująco:

{ "mcpServers": { "perfuse": { "type": "http", "url": "https://perfuse.example/mcp",
    "headers": { "Authorization": "Bearer <token>" } } } }
NarzędzieRolaCo robi
server_status, list_channels, queue, alertsmonitorCzy wszystko działa, bez zawartości wiadomości
get_channel, search_messages, get_message, find_patient, fhir_searchviewerKanały, wiadomości (z zawartością), wiadomości pacjenta w różnych formatach, wyszukiwanie FHIR
retry_delivery, reprocess_messageoperator, i mcp:writePonowne wysłanie wiadomości z kolejki, ponowne przetworzenie wiadomości
start_channel, stop_channeladmin, i mcp:writeUruchomienie lub zatrzymanie kanału

Każdy narzędzie jest obsługiwane przez tę samą trasę lub wyszukiwanie FHIR, które wykorzystuje ekran osoby, wywoływane za pomocą tokenu agenta, więc rola tokenu, grupy kanałów i najemca decydują o tym, co widzi, dokładnie tak jak w konsoli; a fhir_search otrzymuje dostęp tokenu do punktu końcowego FHIR (który może odmówić tokenom API; patrz sekcja FHIR powyżej). Agentowi oferowane są tylko narzędzia, których może używać. Domyślnie jest to odczyt: narzędzie, które zmienia coś, wymaga również zakresu mcp:write tokenu („Pozwól agentowi AI działać z nim” podczas wydawania tokenu), więc token wydany dla agenta raportującego nie może być nakłoniony do działania przez podpowiedź. Odpowiedzi tokenu monitorującego mają usunięte treści wiadomości, niezależnie od tego, co zwraca trasa.

Każde połączenie jest w Activity jako mcp.tool z nazwą tokenu, narzędziem, jego argumentami i wynikiem (ok, refused, invalid, rate-limited lub status HTTP); mcp.connect rejestruje, który klient się połączył. Każdy token może wykonać 60 połączeń narzędzi na minutę (Połączenia narzędzi na minutę z jednego tokenu); powyżej tego limitu połączenie jest odpowiedzią z błędem, który agent może przeczytać, i nic nie jest robione. Żądanie ze strony przeglądarki na innym pochodzeniu jest odrzucane, co MCP prosi serwera, aby zatrzymać ponowne wiązanie DNS. Transport to Streamable HTTP MCP, odpowiedzi jako JSON bez strumienia zdarzeń; akceptowane są wersje protokołu 2025-06-18, 2025-03-26 i 2024-11-05. Wiadomości i zasoby FHIR zawierają dane pacjenta: odpowiedzi agenta idą do modelu, na którym działa, więc podaj token agentowi tylko wtedy, gdy ten model jest dozwolony do ich zobaczenia, i podaj mu najniższą rolę, która robi to.

17.5 Konto demonstracyjne

serve -demo-account demo:PASSWORD tworzy wspólnego użytkownika dla publicznego serwera demonstracyjnego, a strona logowania wyświetla nazwę użytkownika i hasło z przyciskiem, który loguje się przy ich użyciu. Konto jest przeglądającym, więc może przeglądać wszystko i niczego nie zmieniać. W przeciwieństwie do innego przeglądającego, może również otwierać ekrany administratorów (użytkownicy, tokeny maszyn, ustawienia, ochrona danych, równorzędni floty), tylko do odczytu: demonstracja jest oceniana przez swoje ekrany. Odczytuje je jak przeglądający kanały, z każdymi poświadczeniami wyświetlanymi jako ustawionymi lub nie, nigdy bez ich wartości, a każda zmiana jest odrzucana. Może również naciskać przyciski sprawdzające, które nie zmieniają niczego i nie docierają poza serwer: sprawdzanie skryptu i walidacja oraz parsowanie edytora kanału. Nie może zmieniać hasła ani dodawać passkey, ponieważ pierwszy odwiedzający, który to zrobi, zablokuje wszystkich po nich. Każdy start przywraca je jako przeglądającego z opublikowanym hasłem. Hasło musi mieć co najmniej 12 znaków, jak każde inne. Używaj go tylko na serwerze zawierającym dane testowe: każdy, kto czyta stronę logowania, może przeczytać każdą wiadomość na serwerze.

17.6 Audyt

Zmiany konfiguracji, logowania i dostępu do zawartości wiadomości są rejestrowane z informacjami o kim, czym i kiedy.

Rejestr audytu jest w tej samej bazie danych co wiadomości. Jest to wygodne i jest to ograniczenie: ktoś, kto może modyfikować bazę danych, może modyfikować rejestr audytu. Jeśli Twoje wymagania obejmują audyt niezmienny, rejestr musi być wysłany w miejscu tylko do dodawania, a własny wyjście rejestru Perfuse jest sposobem na to.

17.7 Tajemnice w konfiguracji

Hasła, kody i klucze pojawiają się w konfiguracji kanału, co oznacza, że są one w plikach YAML.

Dwie konsekwencje. Pliki wymagają uprawnień systemu plików, które odzwierciedlają ich zawartość, a jeśli są w kontroli wersji — co jest zalecane — repozytorium zawiera poświadczenia i musi być traktowane odpowiednio.

Gdzie wartość jest tajemnicą, interfejs wyświetla ją jako tajemnicę, a API nie zwraca jej po zapisaniu. To chroni ją przed odczytaniem przez kogoś lub przedostaniem się do zrzutu ekranu. Nie chroni jednak pliku.

17.8 Co jest w bazie danych

Sklep wiadomości przechowuje wiadomości w postaci otrzymanej, co w przypadku klinicznego kanału informacyjnego oznacza dane identyfikujące pacjenta. Powinien być on umieszczony na zaszyfrowanym nośniku, zabezpieczonym jako dane kliniczne z odpowiednim okresem przechowywania i kontrolą dostępu na poziomie systemu plików, a także za pośrednictwem ról Perfuse.

cleanup.periodDays ogranicza czas, przez jaki jest przechowywany. Zobacz sklep wiadomości w celu zrozumienia napięcia między tym a posiadaniem wystarczającej historii do rytmicznej alarmowania.

17.9 Ochrona danych (RODO i brytyjskie RODO)

Ekran Ochrona danych (Administruj, tylko administratorzy) odpowiada na żądania osoby zgodnie z RODO i brytyjskim RODO. Nie podejmuje żadnych decyzji w imieniu kontrolera: czy żądanie musi być spełnione, a czy ma zastosowanie wyjątek, jest decyzją kontrolera, zarejestrowaną wraz z żądaniem.

Znalezienie przechowywanych informacji. Osoba jest identyfikowana przez identyfikatory: system|value (numer NHS, numer MRN z jego władzą przydzielającą) lub sam numer. Z indeksem pacjenta te identyfikatory rozszerzają się na każdy numer każdego rekordu powiązanego z tą samą osobą, więc żądanie cytujące jeden numer szpitala znajduje rekordy zapisane pod innymi numerami. Zobacz, co jest przechowywane, a następnie wyszukuje każde miejsce przechowywania danych pacjentów:

SklepZnaleziony przez
Wiadomościindeks tożsamości (Ustawienia → Dane → Indeks identyfikatorów pacjentów); bez niego wiadomości nie mogą być znalezione przez identyfikator
Kolejka dostarczaniaodczytanie identyfikatorów każdej wiadomości w kolejce
Sklep FHIRzasoby Pacjenta zawierające identyfikator i każdy zasób, którego odwołania indeksowane wskazują na jeden
Wcześniejsze żądania autoryzacjiidentyfikatory pacjenta żądania
Indeks pacjentaidentyfikator lub EUID

Jeśli coś nie jest dostępne, podaje informację: ślady wysłane do kolektora (-trace-endpoint), log audytowy (zapisany: jest to zapis tego, kto co zrobił, w tym to żądanie), oraz kopie zapasowe.

Żądania. Żądanie jest rejestrowane z jego rodzajem (dostęp, Artykuł 15; przenośność, Artykuł 20; usunięcie, Artykuł 17; ograniczenie, Artykuł 18), kim jest osoba, której dotyczy, zgodnie z zapisami kontrolera, identyfikatorami oraz notatką (w jaki sposób potwierdzono tożsamość, rozszerzenie i jego powód). Jest ono wymagane w ciągu jednego miesiąca od otrzymania (Artykuł 12(3)); opóźnione żądanie jest wyświetlane na czerwono.

Zamknięte żądanie zachowuje tylko ostatnie znaki numeru osoby: pozostaje jako zapis odpowiedzi bez powielania kopii. Każdy krok jest w logu audytowym z zamaskowanymi numerami.

Prawne zabezpieczenia. Zabezpieczenie określa osobę przez identyfikatory, z powodem oraz opcjonalną datą zakończenia. Dopóki jest w mocy, usunięcie jest odrzucane, a okno przechowywania sklepu wiadomości oszczędza wiadomości osoby (rekordy i treści) do momentu, gdy zabezpieczenie zostanie zniesione.

Kopie zapasowe i rejestr usunięć. Wykonana kopia zapasowa przed usunięciem nadal zawiera usunięte dane, aż do ich wygaśnięcia. Każde usunięcie jest zapisywane w rejestrze: kiedy, przez kogo, zatwierdzone przez kogo, ile danych zostało usuniętych z każdego sklepu oraz identyfikatory osoby jako hashowane SHA-256 z solą zamiast w postaci jawnej. Po przywróceniu kopii zapasowej Ponownie zastosuj usunięcia haszuje identyfikatory przechowywane w przywróconych sklepach z każdą pozycją rejestru oraz kasuje każdą osobę wymienioną w rejestrze. Krótkie numery mogą być odnalezione z ich hashów, próbując każdej wartości, więc rejestr jest sam w sobie danymi osobowymi i jest przechowywany z ochroną bazy danych.

Przechowywanie. Ekran wyświetla, jak długo każdy rodzaj rekordu jest przechowywany i co go zmienia: rekordy wiadomości i ich treści według okien przechowywania, kolejka do momentu dostarczenia lub usunięcia, sklep FHIR, poprzednie żądania autoryzacji oraz indeks pacjenta do momentu usunięcia (rekordy kliniczne nie są kasowane według harmonogramu), log audytowy jest przechowywany.

Rejestr przetwarzania (Artykuł 30). Rejestr przetwarzania pobiera, jako Markdown lub CSV, to, co serwer wie o przetwarzaniu: kontroler, oficer ochrony danych oraz gdzie dane są przechowywane (Ustawienia → Dane → Ochrona danych), przechowywanie każdego rodzaju rekordu oraz jedna aktywność przetwarzania na kanał z tym, co jest otrzymywane, skąd, do jakich miejsc przeznaczenia oraz hostów, do których są wysyłane. Cele, podstawy prawne oraz kategorie podmiotu danych są pozostawione do wypełnienia przez kontrolera i tak wskazują. Komórka CSV zaczynająca się od =, +, - lub @ jest zapisywana z poprzedzającym apostrofem, aby arkusz kalkulacyjny nie wykonywał jej.

Gdzie dane są przechowywane. Gdzie dane są przechowywane (Ustawienia → Dane → Ochrona danych) stwierdza, w słowach, które regulator może sprawdzić, gdzie serwer, jego baza danych oraz kopie zapasowe są uruchomione; ekran Ochrony danych oraz rekord pokazują to. Wersja robocza umowy o przetwarzaniu danych dla organizacji BioDream jest w docs/legal/dpa-template.md; jest to wersja robocza dla prawnika, a nie porada prawna.

Interfejs API to /api/privacy (podsumowanie), /api/privacy/find, /api/privacy/requests (i /{id}/approve, /{id}/export, /{id}/erase, /{id}/close), /api/privacy/holds, /api/privacy/reapply oraz /api/privacy/register.

17.10 Najemcy

Najemca jest granicą izolacji: kanały, wiadomości, użytkownicy i ustawienia należą do jednego, a nic nie przekracza.

Istnieje to dla dostawcy usług, który uruchamia kanały dla kilku praktyk. Nie używaj go do oddzielenia departamentów w ramach jednej organizacji, które muszą widzieć nawzajem swoje dane: izolacja jest realna i nie ma widoku między najemcami. Do tego celu użyj grup kanałów (powyżej), które dzielą ludzi jednej organizacji, pozwalając centralnej grupie zobaczyć wszystko.

17.10.1 Ograniczenia

Operator platformy ustawia limity dla każdego najemcy w Tenants, aby jeden klient nie mógł zagłuszyć resztę współdzielonego serwera. Pozostaw limit pusty, jeśli nie jest wymagany.

Żaden z nich nie traci wiadomości. Przy przekroczeniu limitu lub limitu przechowywania otrzymana wiadomość jest odmawiana w taki sam sposób, jak zajęty odbiorca odmawia wiadomości, zanim cokolwiek zostanie zapisane lub dostarczone: MLLP nie otrzymuje potwierdzenia (nie jest to odrzucenie, które niektórzy nadawcy traktują jako "nie wysyłaj ponownie"), HTTP otrzymuje 429 z Retry-After, SOAP otrzymuje 503, DICOM otrzymuje status, który można ponowić, a kolejka, wiadro lub plik pozostają tam, gdzie były. Nadawca wysyła ponownie, jak każdy silnik integracji i EHR. Nic, co już jest zapisane, nie jest kasowane, aby zrobić miejsce. Zwiększony limit obowiązuje w ciągu minuty, a każda zmiana limitów jest rejestrowana w logu aktywności.

17.11 Dane testowe

Wygenerowane wiadomości opisane w testing istnieją częściowo jako kontrola prywatności. Odtwarzanie problemu w innym miejscu, wysłanie przykładu do dostawcy lub zaludnienie środowiska testowego to wszystko rzeczy, które w przeciwnym razie są wykonywane z użyciem rzeczywistych wiadomości.

Wynik generatora nie zawiera danych pacjentów dzięki konstrukcji, a nie dzięki redagowaniu. Preferuj go zamiast ręcznie wyłuskanych prawdziwych wiadomości, co jest procesem, który można wykonać niekompletnie i zwykle jest.

17.12 Logowanie jednokrotne

Trzy mechanizmy i konta lokalne obok wszystkich z nich.

OpenID Connect (-oidc), katalog przez LDAP (-ldap) i SAML 2.0 (-saml). Każdy z nich jest konfigurowany z Administruj → Logowanie i zapisywany do pliku, którego nazwę określa flaga, więc ekran i plik są dwoma widokami jednej rzeczy, a nie dwoma miejscami, które trzeba utrzymywać w zgodzie.

Konta lokalne są zawsze dostępne i nie mogą być wyłączone. To jest celowe: silnik integracji na miejscu, którego jedynym sposobem wejścia jest dostawca tożsamości, staje się niedostępny dokładnie wtedy, gdy dostawca tożsamości jest niedostępny, a interfejs kliniczny nie jest dobrym miejscem, aby się o tym dowiedzieć. Ekran logowania informuje, ile istnieje lokalnych administratorów, zanim zachęci do polegania na czymś innym.

17.12.1 Co decyduje o mapowaniu grupy

Wszystkie trzy mapują grupy z katalogu na role Perfuse, a ktoś w grupach pasujących do więcej niż jednej otrzymuje najbardziej uprzywilejowaną. To jest jedyna bezpieczna strona do rozwiązania — alternatywa to osoba tracąca dostęp, do którego ma prawo, ponieważ jest również w mniejszej grupie.

Można udzielić którejkolwiek z sześciu ról: monitor, widz, operator, edytor, administrator i platforma.

Grupa może być również ograniczona do niektórych grup kanałów, w drugim polu wiersza (channel_groups w pliku). Gdy jakakolwiek grupa nazwie jedną, każde logowanie ustawia kanały grupy osoby z grup, które przyznały jej rolę: osoba w grupie, która edytuje kanały laboratorium i w innej, która wyświetla każdy kanał, jest edytorem kanałów laboratorium i niczym więcej. Najwyższa rola nigdy nie jest łączona z najszerszym zasięgiem, ponieważ żadna grupa nie przyznaje tego. Grupa z pustym polem daje każdy kanał. Dopóki żadna grupa nie nazwie żadnego, logowanie pozostawia kanały grupy tak, jak je ustawił administrator w Użytkownicy.

Gdy każda grupa, której osoba odpowiada, nazwie kanały grupy, każda grupa kanałów otrzymuje najwyższą rolę wśród grup, które ją nazwały: z Lab-Interfaces (edytor, laboratorium) i Clinical-IT (widz, laboratorium i adt), osoba edytuje kanały laboratorium i wyświetla kanały przyjęć, jakby były ustawione ręcznie. Gdy jedna z grup daje każdy kanał, nie ma listy, która mogłaby przechowywać rolę na grupę, i stosuje się powyższa reguła.

roles:
  editor: [Lab-Interfaces]
  operator: [Night-Desk]
  viewer: [Clinical-IT]
  channel_groups:
    Lab-Interfaces: [lab, pathology]
    Night-Desk: [adt]

To jest plik OpenID Connect i SAML. Plik katalogu mapuje każdą grupę na jedną rolę (roles: {Lab-Interfaces: editor}), a channel_groups znajduje się obok roles.

Mapowanie, które nie przyznaje nic nikomu, jest odrzucane, a nie zapisywane. Konfiguracja, która uwierzytelnia ludzi i odsyła ich wszystkich, wygląda tak samo jak uszkodzony produkt z zewnątrz: pełna podróż zostaje ukończona, a wszyscy są odrzuceni bez wyjaśnienia, dlaczego.

Tworzenie konta podczas pierwszego logowania jest wyłączone domyślnie. Z wyłączoną opcją, ktoś musi istnieć w Perfuse, zanim będzie mógł się zalogować, więc katalog decyduje, kim są, a Perfuse decyduje, kto ma dostęp.

17.12.2 SAML, konkretnie

Części, które warto wiedzieć przed skonfigurowaniem:

17.12.3 Co każdy dostawca wysyła

Atrybut grupy jest miejscem, w którym logowania idą nie tak, a trzej najczęscy dostawcy każdy nazywają go inaczej.

DostawcaZwykle wysyłaUwagi
KeycloakgroupsWymaga dodania mapera członkostwa w grupie do klienta.
Entra IDadres URI roszczenia kończący się /claims/groupsWysyła identyfikatory obiektów grupy, chyba że aplikacja jest skonfigurowana do wysyłania nazw. Mapuj identyfikatory lub zmień dostawcę.
Oktato, co zostało skonfigurowane dla aplikacjiZwykle groups, z filtrem decydującym, które są wysyłane.
ADFSadres URI roszczeniaSygnuje odpowiedź zamiast twierdzenia, które Perfuse akceptuje.

Adres URI roszczenia może być wprowadzony przez jego ostatni segment: wpisanie groups znajduje http://schemas.microsoft.com/ws/2008/06/identity/claims/groups. Nazwa, która kończy się tylko słowem, nie pasuje — excluded_groups nie jest groups.

Członkostwo w grupie, które przychodzi jako jedna wartość oddzielona przecinkami, jest traktowane jako pojedyncza nazwa grupy i nie pasuje do niczego. To jest poprawna interpretacja standardu, a dzielenie na przecinki oznaczałoby, że grupa, która słusznie zawiera jedną, staje się cichaczem dwiema. Jeśli Twój dostawca wysyła to, zmień to tam.

Test na ekranie logowania sprawdza wszystko, co można sprawdzić bez osoby: ustawienia, certyfikat i czy można zbudować żądanie logowania. Mówi wyraźnie, że nie może udowodnić, że ktoś może się zalogować, ponieważ wymaga to prawdziwego twierdzenia o prawdziwej osobie, a jedynym sposobem, aby to uzyskać, jest to, aby próbowali.

17.13 Konta udostępnione przez dostawcę tożsamości: SCIM

Z -scim (Ustawienia → Logowanie → Konta automatyczne), dostawca tożsamości, taki jak Okta, Microsoft Entra ID lub Google Workspace, tworzy, aktualizuje i usuwa konta Perfuse samodzielnie pod adresem /scim/v2/Users, dzięki czemu osoba, która opuszcza organizację, traci dostęp, gdy konto katalogowe jest wyłączone, a nie gdy ktoś sobie o tym przypomni. Dostawca uwierzytelnia się za pomocą tokenu API z rolą administratora, utworzonego w Użytkownicy → Poświadczenia maszynowe, wysyłanego jako token nośnikowy.

17.14 Co Perfuse nie robi

Nie szyfruje bazy danych w stanie spoczynku. Użyj szyfrowania systemu plików lub woluminu.

Nie zarządza własnymi certyfikatami ani ich odnawianiem. Wskaż pliki i zarządzaj nimi za pomocą tego, co już używasz.

SAML został zweryfikowany z dwoma niezależnymi dostawcami, każdym z prawdziwym logowaniem przeglądarki, prawdziwym potwierdzeniem i prawdziwą sesją: Keycloak 26 i Microsoft Entra. Dwa sprawy są ważniejsze niż dwa razy tyle, co jedna, ponieważ te dwie nie zgadzają się w sposób, który okazał się istotny — Keycloak zapisuje swoje potwierdzenie z prefiksami przestrzeni nazw, a Entra zapisuje te same elementy bez nich, a jednym defektem w tej dziedzinie było obsługiwanie prefiksów.

Zacznij od odczytania metadanych dostawcy. Ustawienia, a następnie Logowanie, a następnie karta SAML: podaj adres URL metadanych lub wklej dokument, a adres logowania i certyfikat podpisywania zostaną wypełnione automatycznie. Każdy dostawca SAML publikuje jeden z nich — Okta, Entra, AWS IAM Identity Center, Keycloak, ADFS — i jest to różnica między konfigurowaniem dostawcy a przepisywaniem go. Robienie tego ręcznie oznacza znalezienie certyfikatu wewnątrz XML, usunięcie znaków nowej linii z base64 i otoczenie go nagłówkami PEM, gdzie jeden zbędny znak spacji powoduje błąd podpisu, który nie mówi nic o formacie.

To, co wraca, jest opisane, a nie zrzucane: podmiot każdego certyfikatu, wygaśnięcie i odcisk palca SHA-256, aby można było sprawdzić go w porównaniu z tym, co pokazuje konsola samego dostawcy. Wygasły certyfikat jest nazwany wygasłym, a nie pozostawiony jako data do porównania oczami. Nic nie jest zapisywane przez odczyt — zastosowanie go do formularza jest oddzielnym kliknięciem, ponieważ dokument, który ktoś wkleił, nie jest jeszcze decyzją o tym, co zaufać.

Adres URL metadanych jest pobierany tylko przez https, a adres jest sprawdzany w stosunku do tej samej polityki, która zarządza miejscami przeznaczenia kanału, więc nie można go użyć do odczytania poświadczeń instancji chmury przez serwer. Przekierowania nie są śledzone, ponieważ dozwolony adres przekierowujący do zablokowanego przejdzie prosto obok tego sprawdzenia.

Jeśli konfigurujesz Entra, pięć rzeczy nie będzie odpowiadać temu, co pokazują przykłady. Nie wysyła żadnego roszczenia e-mail. Jego NameID jest nieprzezroczystym identyfikatorem, a nie adresem. Nie wysyła żadnego roszczenia grupy, chyba że aplikacja jest jawnie skonfigurowana do emitowania jednego, więc mapowanie roli napisane przeciwko grupom odmawia każdego logowania. Gdy grupy są emitowane, są one identyfikatorami GUID obiektów, a nie nazwami, chyba że twoja dzierżawa synchronizuje z lokalnym Active Directory. A nazwy jego roszczeń mieszczą się pod schemas.microsoft.com/identity, gdzie większość dokumentacji pokazuje schemas.xmlsoap.org. Perfuse obsługuje wszystkie pięć; są wymienione, ponieważ pierwsze cztery wyglądałyby inaczej na błędy w Perfuse, gdy są Entra.

Ta różnica nie jest teoretyczna tutaj. Pierwsze prawdziwe potwierdzenie Keycloak nie powiodło się, ponieważ kanoniczna forma, którą obejmuje podpis, była obliczana z pominięciem prefiksów przestrzeni nazw. Żadny prawdziwy dostawca tożsamości nie mógłby podpisać nikogo, a pięć testów kanoniczacji pakietu przeszło przez cały czas — każdy z nich został podpisany i zweryfikowany za pomocą tego samego kodu, więc udowodniły tylko, że zgadza się ze sobą. Jeśli jesteś pierwszym, który wskazuje innego dostawcę na to, spodziewaj się znaleźć coś, a log serwera nazwie etap, który nie powiódł się.

18 Operacje

18.1 Wdrożenie

Jeden plik wykonywalny i dwie ścieżki: katalog plików kanału i plik bazy danych. Nie ma wymaganego serwera aplikacji, oddzielnego warstwy sieci web i brokera wiadomości.

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

Uruchom go pod nadzorem usług hosta — systemd, launchd, środowisko uruchomieniowe kontenera. Oczekuje, że zostanie ponownie uruchomiony, jeśli wyjdzie.

18.2 Gdzie mogą iść dane (rezydencja danych)

serve -residency (Ustawienia → Dane → Gdzie mogą być wysyłane dane) nazwa chmur, do których serwer może wysyłać lub odczytywać dane: obszary (eea, uk, ch) i kodów regionów (eu-central-1, uksouth, europe-west2), oddzielone przecinkami. eea to regiony AWS, Azure i Google Cloud w Europejskim Obszarze Gospodarczym (Frankfurt, Irlandia, Paryż, Sztokholm, Mediolan, Hiszpania; Holandia, Niemcy, Francja, Szwecja, Norwegia, Włochy, Hiszpania; Belgia, Holandia, Niemcy, Włochy, Francja, Finlandia, Hiszpania, Polska), uk to regiony w Wielkiej Brytanii, ch to regiony w Szwajcarii.

Po ustawieniu kanał jest odrzucany, gdy jest zapisywany i gdy jest ładowany, jeśli łącznik nazwie region spoza listy: źródło lub miejsce docelowe S3, SQS lub SNS region (lub jego endpoint, gdy jest to nazwa hosta AWS), lub każde miejsce docelowe, którego adres jest nazwą hosta AWS zawierającą region (sqs.us-east-1.amazonaws.com, adres URL API Gateway). Serwer odmawia uruchomienia z kolektorem śladów lub webhookiem alertu w innym regionie. Łącznik wskazujący na host, który nie nazwał regionu (własny system szpitala, MinIO w sieci szpitala), nie jest oceniany: rekord przetwarzania na ekranie Ochrona danych wyświetla każdy host, do którego każdy kanał wysyła dane, do sprawdzenia przez kontrolera. Pulpit i ekran Ochrona danych mówią, gdzie mogą być wysyłane dane.

Hostowanie w UE i Wielkiej Brytanii. deploy/hosted zawiera OpenTofu (lub Terraform) dla jednego serwera hostowanego na organizację we Frankfurcie, Irlandii lub Londynie: serwer, jego bazę danych PostgreSQL i kopie zapasowe, bucket kopii zapasowych, logi i rekordy sesji wsparcia, wszystko zaszyfrowane kluczem w Regionie, nic nie jest replikowane do innego Regionu, wsparcie tylko za pośrednictwem Menedżera sesji i Perfuse uruchomiony z -residency. Jego README mówi, co buduje, co nie jest objęte, co zostało zweryfikowane (zweryfikowane i zaplanowane przeciwko prawdziwemu koncie; jeszcze nie zastosowane) i jakie są koszty według ceny katalogowej w każdym Regionie.

18.3 Konfiguracja jako pliki

Kanały są plikami, co oznacza, że mogą być w kontroli wersji, przeglądane przed wdrożeniem i porównywane po incydencie.

Pliki są odczytywane ponownie bez restartu. Plik, który nie jest w stanie sparsować, jest zgłaszany, a poprzednio załadowana wersja nadal działa, więc błąd składniowy nie może wyłączyć działającego kanału.

Kanał edytowany w interfejsie sieciowym jest zapisywany z powrotem do swojego pliku. Jeśli te pliki są w kontroli wersji, oczekuj commitów z zmian konfiguracyjnych dokonanych za pośrednictwem interfejsu, i nie edytuj ręcznie pliku, gdy ktoś ma go otwarty w budowniczym.

18.4 Kopia zapasowa

Dwie rzeczy do zabezpieczenia, a one mają różne właściwości.

Katalog kanału jest mały, rzadko się zmienia i jest tym, czego potrzebujesz, aby odbudować usługę. Zabezpiecz go jako konfigurację; kontrola wersji jest zwykle wystarczająca.

Baza danych zawiera wiadomości, użytkowników i historię inspekcji. Jest duża, ciągle się zmienia i zawiera dane kliniczne — więc potrzebuje zabezpieczenia jako dane kliniczne, z retencją i szyfrowaniem, które to implikuje. Utrata jej nie zatrzymuje usługi, ale traci możliwość zbadania wszystkiego, co już się wydarzyło, i historii, na której polega uczący się rytm.

18.5 Zachowanie po ponownym uruchomieniu

Po ponownym uruchomieniu kanały są ładowane, a źródła zaczynają nasłuchiwać. Wstrzymane dostawy są wznowione.

Rzecz, którą trzeba zrozumieć, to to, co się dzieje z pracą w locie. Pod domyślnym potwierdzeniem on_delivery, wiadomość, która nie została jeszcze potwierdzona, nie jest potwierdzona, więc nadawca ją ponownie wyśle — co jest prawidłowym wynikiem. Pod on_receipt, wiadomość, która została potwierdzona, ale nie została jeszcze dostarczona, jest w kolejce i wznowiona; jeśli kolejka jest wyłączona, jest tracona. Zobacz przepływ wiadomości.

18.6 Uaktualnianie

Zamień binarny plik i zrestartuj. Schemat bazy danych jest migrowany do przodu automatycznie podczas startu.

Migracje są tylko do przodu. Nie ma cofnięcia, więc wycofanie się do poprzedniego binarnego pliku po tym, jak schemat został przeniesiony, wymaga poprzedniej bazy danych. Zrób kopię przed uaktualnieniem — to jest jeden operacyjny środek ostrożności, o który warto być dyscyplinowanym.

18.7 Monitorowanie

Alarmowanie z Perfuse jest objęte w alarmowaniu i to powie ci, że kanał przestał działać.

Z zewnątrz monitoruj proces, dysk, na którym znajduje się baza danych, i czy interfejs sieciowy odpowiada. Baza danych rośnie, a pełny dysk zatrzymuje nagrywanie wiadomości, co jest trybem awaryjnym bez innego ostrzeżenia.

18.7.1 SNMP

Dla narzędzi monitorowania, które mówią SNMP (Nagios, Zabbix, PRTG, SolarWinds, LibreNMS), Perfuse uruchamia agenta SNMPv2c tylko do odczytu i wysyła pułapkę, gdy alert zostanie wyzwolony lub rozwiązany. Ustaw to pod Ustawienia → Monitorowanie → SNMP, lub za pomocą flag:

perfuse serve -snmp-listen :161 -snmp-community 'long-random-community' -snmp-allow 10.0.5.0/24 \
  -snmp-traps nms.example.org,10.0.5.9:1162

18.7.2 Inwentaryzacja każdego interfejsu

-inventory interfaces.md (Ustawienia → Monitorowanie → Inwentaryzacja) zapisuje dokument Markdown, który wylistuje każdy kanał - jego format, czy jest uruchomiony, co otrzymuje i co wysyła - a następnie opisuje każdy kanał, i przepisuje go co -inventory-every (dzień domyślnie). Ma być zatwierdzony obok plików kanałów lub przekazany audytorowi i przeczytany bez uruchomienia aplikacji.

18.8 Pojemność

Górna granica przepustowości Perfuse nie została zmierzona na prawdziwym sprzęcie pod prawdziwym ruchem, i ten podręcznik nie wydrukuje liczby, której nie może poprzeć.

Co można powiedzieć: architektura jest jednym gorutynem na połączenie z kolejkami per-destination, więc przepustowość rośnie wraz z miejscami przeznaczenia, a nie jest serializowana przez jednego pracownika; nagrywanie wiadomości jest zapisem SQLite na wiadomość, co sprawia, że dysk jest najbardziej prawdopodobną pierwszą ograniczeniem; a sklep z wiadomościami rośnie liniowo z ruchem, więc retencja jest ustawieniem, które rządzi długoterminowym użyciem dysku.

Jeśli rozmiar jest dostosowywany do dużego źródła danych, należy zmierzyć go przy użyciu własnego ruchu za pomocą wygenerowanego korpusu testowego opisanego w testing. To jest uczciwa odpowiedź, a także lepsza niż liczba z czyjegoś innego sprzętu.

18.9 Miejsce, w którym instalacja uległa awarii

Aktywność wyświetla panel widoczny dla administratorów, pokazujący, co Perfuse odmówił zrobić — pogrupowane według wiadomości, najczęstsze jako pierwsze — i jak daleko instalacja posunęła się w kierunku działającego kanału.

Istnieje, ponieważ każde inne twierdzenie dotyczące łatwości użycia tego oprogramowania pochodzi od osób, które je napisały. Odmowa nie: ktoś chciał czegoś, serwer powiedział nie, i żadna ze stron nie zgadywała. Jest to jedyny dowód w produkcie, który nie pochodzi od BioDream LLC.

Lejek nazywa krok, który jeszcze nie nastąpił, zamiast pozostawiać znaczniki czasu do porównania. Stan wart obserwacji to wiadomości przychodzą, ale żadna nie została dostarczona do miejsca przeznaczenia — kanał może przyjmować ruch przez tygodnie i nie dostarczyć go, i z każdego innego ekranu wygląda to tak, jakby działał.

Nic, co ktoś wpisał, nie jest rejestrowane. Tabela zawiera trasę żądania z identyfikatorami zastąpionymi przez {id}, stan i zdanie serwera. Wiadomość walidacyjna nazywa pole i regułę, co jest użyteczną częścią; wartość, która złamała regułę, jest bardzo często danymi pacjenta, a tabela tych danych byłaby gorszym obciążeniem niż tarcie, które mierzy.

Dwa celowe wykluczenia. 5xx to błąd w tym oprogramowaniu i jest już zalogowany jako taki — łączenie ich obu zakopie przypadki, w których ktoś nie mógł zrozumieć, co wpisać, pod przypadkami, w których nic, co wpisano, nie pomogłoby. A wygasły sesja produkuje serię 401, które nie mówią nic o używalności i utopią każde znalezienie, które tak.

Czytanie raportu również obcina tabelę do pięciu tysięcy ostatnich wierszy. Odmowy są odpowiedziami 4xx, więc rośnie powoli, a odczyt jest naturalnym momentem, aby uporządkować: nie ma timera i nic, co działa, gdy nikt nie patrzy.

GET /api/friction zwraca tę samą rzecz dla każdego, kto woli ją czytać jako JSON.

18.10 Dzienniki

Perfuse zapisuje dane do standardowego wyjścia, gdzie zostaną zebrane przez nadzorcę lub środowisko uruchomieniowe kontenera.

Szczegóły na poziomie wiadomości trafiają do sklepu wiadomości zamiast do dziennika, celowo. Wiersz dziennika na wiadomość w zajętym źródle danych to szum, który ukrywa wiersze, które mają znaczenie, a sklep jest wyszukiwalny w sposób, w jaki plik dziennika nie jest.

Dziennik zawiera to, czego sklep nie może: uruchomienie i zatrzymanie, wyniki ładowania konfiguracji, zmiany stanu kanału i błędy, które nie są przypisane do określonej wiadomości.

18.11 Uruchamianie dwóch wystąpień

Dwa lub więcej serwerów mogą działać jako jeden klaster: gdy serwer, który uruchamia kanał, zatrzymuje się, inny serwer przejmuje go w ciągu kilku sekund, a następna próba nadawcy dociera do niego. Używają one wspólnej bazy danych PostgreSQL zamiast każdego z nich przechowywać plik SQLite, i uzgadniają między sobą, za pomocą niej, który z nich uruchamia co.

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

Uruchom każdy serwer w ten sam sposób z własną nazwą i adresem. Konto bazy danych musi utworzyć tabele i, raz, rozszerzenie citext (lub administrator uruchamia CREATE EXTENSION citext wcześniej). Każdy serwer przechowuje własne pliki w -data: swój dziennik, swój identyfikator węzła i swoje kopie konfiguracji.

Dwa sposoby udostępniania pracy.

Kto uruchamia co, i nigdy nie ma dwóch w tym samym momencie. Każda część pracy to dzierżawa w bazie danych, odnawiana co piątą część -cluster-lease (15 s domyślnie). Serwer, który nie może odnowić jej (uległ awarii, jego sieć uległa awarii, baza danych jest niedostępna), zatrzymuje tę pracę samodzielnie, gdy jego własny zegar mówi, że dzierżawa jest prawie skończona, z trzecią częścią dzierżawy do dyspozycji. Inny serwer bierze dzierżawę tylko po tym, jak jego własny zegar obserwował licznik dzierżawy przez całą dzierżawę. Żaden zegar nie jest porównywany z innym, więc zegary serwerów i bazy danych nie muszą się zgadzać; muszą tylko działać w mniej więcej tym samym tempie, co robi każdy zegar. Między starym posiadaczem a nowym jest krótka luka z nikim, kto nie słucha, co nadawca widzi jako odmowę połączenia i ponawia; nigdy nie ma momentu, w którym dwóch słucha na jednym kanale lub dwóch pracowników opróżnia jedną kolejkę.

Serwer zamykany w sposób czysty lub administrator wybierający Oddaj na liderze, przekazuje natychmiast zamiast po dzierżawie.

Co każdy serwer udostępnia. Komunikaty, kolejka dostarczania, konta i sesje, dziennik inspekcji, magazyn FHIR, tabele terminologiczne i indeks pacjentów są w bazie danych, więc niezależnie od tego, który serwer uruchamia kanał, znajduje kolejkę, którą pozostawił poprzedni. Pliki kanałów, plik ustawień, reguły alertów, pliki logowania jednokrotnego, logo, certyfikaty Direct i zapisane widoki są przechowywane w ten sam sposób na każdym serwerze za pomocą bazy danych: każdy z nich trzyma własną kopię na swoim dysku, zmiana na dowolnym serwerze (w konsoli, ręcznie, przez git pull) dociera do innych w ciągu dwóch sekund, a kanał zmieniony na innym serwerze restartuje się z nowym plikiem. Ten sam plik zmieniony na dwóch serwerach jednocześnie zachowuje wersję, która dotarła do bazy danych jako pierwsza, a drugą obok niego jako NAME.conflict-SERVER. Ustawienia, które mają zastosowanie tylko podczas restartu (baza danych komunikatów, porty, na których nasłuchuje konsola), są stosowane przez każdy serwer podczas następnego restartu, a dziennik mówi o tym. To, co nazwuje coś na jednej maszynie, pozostaje na linii poleceń serwera i poza plikiem współdzielonym: certyfikat i klucz (-tls-cert, -tls-key), adres nasłuchiwania SNMP i nazwa serwera w śladach. Ustawienia wyświetla je jako ustawione na każdym serwerze.

Uruchom i zatrzymaj. Uruchomienie lub zatrzymanie kanału na dowolnym serwerze ma zastosowanie do klastra: serwer, który go uruchamia, uruchamia go lub zatrzymuje w ciągu jednej sekundy, a odpowiedź mówi, który serwer to robi.

Wygładzanie obciążenia przednim. Adres kanału musi dotrzeć do serwera, który go uruchamia. Wskaż nadawcę na wirtualny adres (wygładzanie obciążenia, pływający IP, nazwę DNS z krótkim TTL) i pozwól wygładzaniu obciążenia sprawdzić /readyz?channel=NAME, który odpowiada 200 tylko na serwerze uruchamiającym ten kanał, i 503 na innych. Dla konsoli, /readyz jest 200 na każdym żywym serwerze; /readyz?role=leader tylko na liderze.

Na AWS Network Load Balancer, użyj grupy docelowej na kanał z kontrolą zdrowia HTTPS na /readyz?channel=NAME, interwałem 5 sekund i progiem 2, i włącz przełączanie strefy wygładzania obciążenia. Z wyłączonym przełączaniem, węzeł wygładzania obciążenia w strefie, w której nie uruchamia się kanał, widzi tylko niezdrowe cele i wysyła do wszystkich z nich, a nadawca, który rozwiązał ten węzeł, czeka, aż kanał wróci do jego strefy (95 sekund w teście). Ustaw opóźnienie wyrejestrowania na 0, ponieważ serwer, który przestaje uruchamiać kanał, nie ma nic do opróżnienia.

Co zostało przetestowane. Dwa serwery na PostgreSQL 16, nadawca przesyłający 300 wiadomości, ponawiający wysyłanie, aż do odpowiedzi, i serwer uruchamiający kanał zabity sygnałem SIGKILL dwa razy (pierwszy, a następnie drugi po powrocie pierwszego). Każda potwierdzona wiadomość dotarła do odbiorcy, w obu próbowanych kształtach: dostarczona przed potwierdzeniem i zakolejkowana w udostępnionym magazynie, podczas gdy odbiorca odmówił (185 potwierdzonych wiadomości czekało w kolejce przy zabiciu; ocalały serwer dostarczył je wszystkie). Przejęcie awaryjne zajęło 3 do 4 sekund na 3-sekundowym leasingu. Możliwe jest powtórzenie i zostało raz zobaczone w 600: wiadomość, którą umierający serwer dostarczył i nie mógł potwierdzić, którą nadawca ponowił.

To samo zostało zrobione na AWS: dwa serwery Linux (ARM) i jeden Windows Server 2022 w trzech strefach dostępności, Amazon RDS PostgreSQL 16 przez TLS z sprawdzonym certyfikatem (sslmode=verify-full), wewnętrzny Network Load Balancer z przodu i nadawcy ponawiający wysyłanie, aż do odpowiedzi:

TestWiadomościPotwierdzone, ale utraconePowtórzeniaNajdłużej czekał nadawca
Aktywny-pasywny, serwer uruchamiający kanał zabity dwa razy (Linux, potem Windows), odbiorca odmawiający w międzyczasie2,0000015 s
Serwer Linux lider odcięty od bazy danych (firewall), jego proces pozostawiony uruchomiony3,0000116 s
Serwer Windows lider odcięty od bazy danych3,0000020 s
Lider zabity, podczas gdy zegar jednego serwera działał 2 minuty szybciej, a innego 90 sekund wolniej2,0000018 s
Aktywny-aktywny, cztery kanały przez trzy serwery, jeden zabity i przywrócony6,0000224 s

Z domyślnym leasingiem 15 sekund, serwer odcięty od bazy danych zatrzymał swój kanał 10 sekund po ostatnim odnowieniu, a następny serwer uruchomił go 6 do 8 sekund później: nigdy nie oba na raz. Zniekształcone zegary nie zmieniły nic, ponieważ nie porównuje się żadnego zegara z innym.

Nie jeszcze. Klaster służy jednej organizacji: -cluster z -multi-tenant jest odrzucany. Słuchacze przechodzą z kanałem, więc wygładzanie obciążenia jest dostarczane przez witrynę.

Serwer samodzielnie nadal działa tak, jak zawsze, na SQLite, bez klastra w ogóle.

18.12 Więcej niż jeden serwer

Witryna z dwoma instancjami ma pytanie, na które nie może odpowiedzieć żadna pojedyncza konsola: czy wszystko działa? Mirth pobiera opłatę za odpowiedź. To jest widok floty.

Jedna instancja jest wyznaczona jako miejsce, w którym szukamy. Zapytuje inne i pokazuje każdy kanał na każdym serwerze w jednej tabeli, z podsumowaniem we wszystkich.

18.12.1 Dodawanie równej instancji

Ustawienia → Flota, lub PUT /api/fleet/peers. Równy potrzebuje nazwy, adresu URL i tokenu wydanego przez samego siebie.

Nazwa jest wymagana i nie jest adresem URL, ponieważ adres URL nie jest czymś, co ktokolwiek rozpoznaje o trzeciej w nocy.

Token musi być utworzony na równym, pod Użytkownicy, i powinien mieć zakres widza. Dodanie równego bez niego jest odrzucane z tymi instrukcjami, zamiast akceptowania i potem niepowodzenia cicho przy każdym zapytaniu. Czytanie stanu zdrowia innej instancji jest najmniejszym przywilejem, jaki istnieje, i jest to jedyny, którego potrzebuje widok floty.

18.12.2 Kontrolowanie równego, który jest wyłączony

allow_control pozwala na uruchamianie i zatrzymywanie kanałów tego równego z tego miejsca. Jest wyłączone domyślnie i każde użycie jest rejestrowane według nazwy.

Dwa przywileje są celowo oddzielne. Czytanie stanu zdrowia innego serwera jest nieistotne; zatrzymywanie jego kanałów podczas transfuzji nie jest, i to drugie nigdy nie powinno przyjść cicho dołączone do pierwszego.

18.12.3 Co mówi raport

Każdy serwer raportuje łączną liczbę kanałów, ile z nich jest uruchomionych, zatrzymanych lub wystąpił błąd, głębokość kolejki oraz wiek najstarszego oczekującego komunikatu, ile alertów jest aktywnych oraz czy jest opróżniany w celu wyłączenia.

Podsumowanie liczy serwery na trzy sposoby: dostępne, niedostępne i nieokreślone. Trzeci obejmuje równych, których stan zdrowia nikt nie zna — jeszcze nie zapytany, odmawiający tokenu lub uruchamiający wersję, którą ten nie może odczytać. Jest on trzymany oddzielnie od niedostępnych, ponieważ „nie wiemy” nie jest „jest w dół”, a łączenie ich razem jest tym, jak strona floty zaczyna kłamać.

Z tego samego powodu podsumowanie zawiera knownFrom: ile instancji faktycznie odczytało cyfry kanału i kolejki. Dwanaście kanałów uruchomionych w całej flocie oznacza coś innego, gdy dwa z pięciu serwerów nie odpowiedziały, a suma sama nie może powiedzieć tak.

Niedostępny równy mówi, dlaczego w terminach, na które operator może działać. Odmowa połączenia jest zgłaszana jako host, który jest w górę, z niczym nie nasłuchującym na tym porcie, co jest innym problemem niż host, który w ogóle nie odpowiada.

18.12.4 Odchył czasu

Podsumowanie raportuje największą różnicę między zegarami serwerów w nim. Warta liczby własnej: korelowanie incydentu w całych dwóch instancjach, których zegary nie zgadzają się przez cztery minuty, produkuje sekwencję zdarzeń, które nie miały miejsca.

18.12.5 Co równe dowiaduje się o tobie

Liczby i stawki. Raport, który jedna instancja daje innej, nie zawiera identyfikatorów wiadomości, szczegółów na poziomie kanału i żadnych danych pacjentów.

To jest to, co powoduje, że widok floty nie jest scentralizowanym zbiorcem danych klinicznych: instancja agregująca dowiaduje się, ile kanałów jest uruchomionych i niczego więcej o tym, co przez nie przepływa. Jeśli chcesz uzyskać wiadomości, otwierasz konsolę samego serwera, gdzie log audytowy rejestruje to, że to zrobiłeś.

18.12.6 Równe wskazujące na siebie

Odmówiono. Instancja sondująca własny adres za pomocą własnego stosu HTTP pojawia się dwa razy w własnym widoku floty i podwaja liczbę każdego kanału, który posiada.

18.12.7 TLS w sieciach wewnętrznych

insecure_skip_verify akceptuje certyfikat peer'a bez jego weryfikacji. Istnieje dlatego, że infrastruktura szpitala działa na prywatnych urzędach certyfikacji, a odmowa pracy w ogóle spowodowałaby, że ludzie przeszliby na zwykły HTTP, co jest gorsze. Nazwano to w ten sposób, aby nie można było go pomylić z dobrym pomysłem.

19 Wiersz poleceń

Wszystko, co Perfuse robi do uruchomionego systemu, jest dostępne z interfejsu webowego, i jest to celowe: funkcja, która potrzebuje terminala, jest traktowana jako wada, a nie wybór projektowy. Polecenia tutaj są dla pracy, która dzieje się *wokół* uruchomionego systemu — przed jego istnieniem, gdy decydujesz, czy mu ufać, i gdy potrzebujesz przekazać coś komuś innemu

Kilka z nich w ogóle nie dotyka serwera. perfuse explain, perfuse profile, perfuse deident i perfuse translate czytają pliki i zapisują pliki, więc są przydatne na laptopie przeciwko majątkowi, który nadal działa całkowicie na czymś innym

Uruchom każde polecenie z -h dla jego flag. Ten rozdział mówi, do czego służy każde z nich

Polecenia wyświetlone tutaj są ilustracyjne, a nie wyczerpujące. -h jest generowany z kodu i nie może się zestarzeć; lista skopiowana do prozy może

19.1 Uruchamianie kanałów

19.1.1 perfuse serve

Uruchamia interfejs sieciowy i API, a domyślnie również uruchamia kanały. Jest to polecenie używane przez instalację.

Każda opcja, którą akceptuje, jest wymieniona w Opcjach serwera, generowana z programu. Odmawia obsługi zwykłego HTTP dla wszystkiego poza pętlą zwrotną, chyba że zostanie przekazany parametr -insecure. Nie jest to konfigurowalna uprzejmość: ruch kliniczny i ciasteczko sesji po niezaszyfrowanym połączeniu LAN jest zdarzeniem, które należy zgłosić, a flaga istnieje, aby mówienie tak było decyzją, którą ktoś podjął, a nie domyślną, którą odziedziczył. Zobacz bezpieczeństwo.

19.1.2 perfuse run

Uruchamia kanały z plików YAML bez interfejsu sieciowego i bazy danych. Przydatne w kontenerze, który powinien wykonywać tylko jedną rzecz, oraz przydatne, gdy chcesz zobaczyć zachowanie kanału bez uruchamiania niczego innego.

19.1.3 perfuse check

Weryfikuje definicje kanałów i drukuje, co one robią, bez ich uruchamiania. Druga połowa jest punktem: kanał, który się ładuje, nie jest koniecznie tym kanałem, który miałeś na myśli, a czytanie podsumowania w języku angielskim tego, co plik będzie robił, łapie błąd, którego nie może zobaczyć walidacja.

Zakończa się niezerowym kodem w przypadku błędu, więc należy do niego włączyć wszelkie sprawdzenia konfiguracji przed jej dotarciem do serwera. Parametr -quiet nic nie drukuje w przypadku powodzenia, do tego użytku.

-allow-metadata-egress zezwala na miejsca docelowe wskazujące na adresy metadanych instancji chmury. Te adresy zawierają poświadczenia maszyny, więc kanał, który może być nakłoniony do wysłania tam, jest wyciekiem poświadczeń; sprawdzenie odmawia im, chyba że się inaczej postanowi.

19.1.4 perfuse test

Uruchamia testy napisane przeciwko definicjom kanałów. Test wysyła wiadomość przez rzeczywisty filtr kanału, rzeczywiste transformacje i rzeczywiste skrypty, w rzeczywistej kolejności, z zastąpioną tylko siecią — więc to, co tutaj przechodzi, to to, co robi kanał.

Testy znajdują się w plikach *_test.yaml lub *.test.yaml obok kanałów. Zobacz testowanie.

19.2 Migracja z innego silnika

Te trzy są tymi, które należy uruchomić najpierw, zanim się zdecyduje. Zobacz migracja.

19.2.1 perfuse explain

Czyta eksporty Mirth, Open Integration Engine i BridgeLink — kanał, grupę kanałów lub całą kopię zapasową serwera — i opisuje, co robi każdy kanał i co blokuje migrację. Niczego nie zmienia i nie wymaga instalacji Perfuse, co czyni ją najtańszym możliwym pierwszym krokiem: wskazać ją na eksport Twojego majątku i przeczytać, co wraca.

-strict kończy się niezerowym kodem, jeśli cokolwiek jest zablokowane, więc może bramkować potok. -json emituje te same wyniki dla maszyny.

19.2.2 perfuse translate

Konwertuje eksporty Mirth, Open Integration Engine i BridgeLink na pliki kanałów Perfuse: jeden kanał, grupa kanałów, eksport biblioteki szablonów kodu lub cała kopia zapasowa serwera.

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

Biblioteki szablonów kodu są zapisywane w lib/ obok kanałów, a każdy kanał Mirth miał włączoną bibliotekę, która ją zawiera. Zobacz migracja.

Nic nie jest cicho upuszczane. Każda część kanału jest albo tłumaczona, przenoszona jako skrypt, który działa niezmieniony, albo zgłaszana jako wymagająca interwencji człowieka. Trzecia kategoria jest uczciwa — tłumacz, który wyprodukował czysto wyglądający plik dla każdego wejścia, ukrywałby decyzje, które najbardziej potrzebujesz podjąć.

19.2.3 perfuse compare

Uruchamia ten sam ruch przez dwa silniki i zgłasza, gdzie się nie zgadzają, pogrupowane według pola.

To jest polecenie, które odpowiada na pytanie "dlaczego mam ufać temu z danymi pacjentów", i odpowiada na nie za pomocą zebranych dowodów, a nie oświadczeń złożonych tutaj. Jest to zalecany ostatni krok przed przełączeniem i zalecany pierwszy krok w każdej dyskusji na temat tego, czy Perfuse jest gotowy.

19.3 Zrozumienie kanału

19.3.1 perfuse profile

Odczytuje wiadomości i raportuje, co tak naprawdę w nich jest: które pola są zawsze wypełnione, które nigdy nie są, rzeczywiste zestawy wartości pól zakodowanych, liczniki powtórzeń i które segmenty Z pojawiają się.

Wartości są raportowane tylko dla pól, których wartości tworzą mały zestaw kodów, więc profil rzeczywistego ruchu nie staje się plikiem pełnym danych pacjentów.

Zapisywanie profilu i porównywanie go później pozwala dowiedzieć się, że nadawca coś zmienił:

perfuse profile -save last-month.json corpus/ perfuse profile -against last-month.json new/

19.3.2 perfuse contract

Przekształca wynik tego myślenia w coś egzekwowalnego. Umowa określa, jak powinien wyglądać kanał, aby dzień, w którym ulega zmianie, został powiadomiony, zamiast dowiadywać się tygodnie później od odbiorcy, który upadł — wiadomości są nadal ważne HL7, gdy pole znika, więc nic innego nie zauważa.

perfuse contract promote -o adt.contract.yaml corpus/ perfuse contract check adt.contract.yaml today/

promote generuje punkt wyjścia, a nie odpowiedź. Przeczytaj ją i usuń większość z niej: każda linia rejestruje, czy została zmierzona czy podjęta, co mówi ci, które linie należy zachować.

19.4 Wytwarzanie wiadomości

19.4.1 perfuse generate

Wytwarza syntetyczne wiadomości HL7 v2. Wszystko jest wymyślone — oczywiście fikcyjne nazwy, sekwencyjne identyfikatory, wymyślone adresy — więc dane wyjściowe są bezpieczne do zatwierdzenia, wysłania i dołączenia do biletu.

Może wysyłać bezpośrednio do kanału, zamiast zapisywać plik, co jest najszybszym sposobem udowodnienia, że nasłuchuje:

perfuse generate -n 100 -send 127.0.0.1:6661

19.4.2 perfuse deident

Odczytuje rzeczywiste wiadomości i zapisuje korpus, który zachowuje ich strukturę, ich kody i ich interwały, oraz niczego, co identyfikuje pacjenta. To jest różnica między możliwością wysłania komuś powtórzenia a brakiem tej możliwości.

Nie jest to ten sam narzędzie co perfuse generate, a różnica ma znaczenie. Wygenerowane wiadomości są wymyślone i dlatego bezpieczne, ale nierzeczywiste; deidentyfikowany korpus jest *pochodny od rzeczywistego ruchu*, więc odtwarza dziwactwa, które naprawdę łamią interfejsy.

Dwie właściwości warte zrozumienia przed użyciem:

-keep-local-segments przechodzi segmenty Z bez zmian i jest niebezpieczne. Segmenty Z są dokładnie tam, gdzie strony umieszczają nazwy, notatki i tekst wolny, więc zachowanie ich pokonuje cel narzędzia. Istnieje, ponieważ problem strukturalny jest czasem *w* segmencie Z, a wtedy potrzebujesz korpusu, który nie może być udostępniony.

19.5 Przenoszenie wiadomości ręcznie

19.5.1 perfuse listen

Akceptuje HL7 v2 za pośrednictwem MLLP i potwierdza to. Odbiorca, który istnieje tak długo, jak potrzebujesz, aby udowodnić, że nadawca może dotrzeć do tej maszyny w ogóle.

19.5.2 perfuse send

Wysyła wiadomości HL7 v2 za pomocą MLLP z plików.

MLLP nie ma uwierzytelniania i nie ma szyfrowania, w Perfuse ani gdzie indziej. Oba te polecenia, oraz każde źródło i miejsce docelowe MLLP, podlegają temu: dostęp jest ograniczony na poziomie sieci lub w ogóle nie jest ograniczony.

19.6 FHIR

19.6.1 perfuse fhir

Konwertuje HL7 v2 na FHIR, waliduje FHIR lub udostępnia go, w zależności od podpolecenia.

Polecenie walidujące jest przydatne samo w sobie: poinformuje, czy zasób, który ktoś wysłał, spełnia wymagania US Core, który jest profilem, przeciwko któremu jest napisany amerykański regulamin. Możliwość udzielenia odpowiedzi bez przyjęcia silnika jest celem.

19.6.2 perfuse x12

Konwertuje X12 (lub inne rozdzielone EDI) na XML Mirth Connect i Open Integration Engine, a także odwrotnie: perfuse x12 xml FILE i perfuse x12 from-xml FILE, standardowe wejście, gdy nie podano pliku. Wyjście jest tym, co OIE 4.6 zapisuje, bajt po bajcie, więc można je porównać z tym, co wyprodukował serwer Mirth lub zostało podane do systemu zbudowanego na jego podstawie. Kanał robi to samo z x12.arrives_as: xml i x12_as: xml miejsca docelowego; zobacz X12.

19.6.3 perfuse sof

Uruchamia zapytanie SQL na widoku FHIR ViewDefinition nad plikami FHIR (NDJSON eksportu wsadowego, Bundles lub tablice JSON; - dla stdin) i zapisuje tabelę: -view FILE (wymagany), -format csv|ndjson|json|parquet (domyślnie csv), -header=false, i -o FILE (wymagany dla Parquet). Zobacz Widoki SQL na FHIR.

19.6.4 perfuse measure

Ewaluuje miarę jakości z kryteriami FHIRPath nad plikami FHIR (NDJSON pełnego eksportu, Bundle lub tablice JSON; - dla stdin) i zapisuje MeasureReport. Flagi:

Zobacz cyfrowe miary jakości.

19.6.5 Flagi FHIR w perfuse serve

FlagiSkutek
-fhirUdostępnij punkt końcowy FHIR w /fhir. Włączone domyślnie.
-fhir-versionWersja, która jest obsługiwana. Domyślnie R4.
-fhir-read-onlyOdmów writes.
-fhir-api-tokensZ konfiguracją SMART, akceptuj tokeny API Perfuse, a także tokeny SMART (wyłączone domyślnie; również w ustawieniach → FHIR).
-fhir-bulk-exportWłącz $export. Wyłączone domyślnie.
-fhir-subscriptionsWłącz subskrypcje tematów: powiadomienia o spotkaniach i powiadomieniach o spotkaniach do punktów końcowych, które klienci FHIR wybierają. Wyłączone domyślnie; wymaga R4 i zapisywalnego punktu końcowego.
-fhir-subscriptions-allow-httpPozwól subskrypcjom dostarczać do zwykłego http. Dla odbiorcy testowego, nigdy dla danych pacjentów w sieci.
-fhir-patient-directory-searchPozwól tokenowi ograniczonemu do jednego pacjenta wyszukiwać katalog (pracownicy, organizacje, lokalizacje), w ramach jego zakresów. Wyłączone domyślnie.
-fhir-declaresPrzewodniki, które deklaruje ten serwer w swoim oświadczeniu o możliwościach, oddzielone przecinkami: adres CapabilityStatement przewodnika, lub adres Type=profile. Oświadczenie dla klientów i zestawów testowych; nie zmienia niczego, co magazyn akceptuje.

Sklep przechowuje dokumenty, a także zasoby: dokument, kolekcja lub wiązka wiadomości przesłana do /fhir/Bundle/{id} jest przechowywana w całości, odczytywana z każdym wpisem w wersji obsługiwanej i znaleziona przez type, identifier, timestamp i composition. Transakcja przesłana tam jest przechowywana jako rekord i nie jest stosowana; POST do /fhir stosuje ją.

Odpowiedzi są w formacie JSON, chyba że klient prosi o XML (Accept: application/fhir+xml lub _format=xml). Perfuse odczytuje tylko JSON: treść wysłana jako XML otrzymuje 415. Dokument Bundle wysłany do /fhir jest przechowywany, gdy serwer ten posiada, według identyfikatora, pacjenta i spotkania, których Kompozycja wymienia, i odrzucany z 422 w przeciwnym razie. Binarny odczyt z Accept ustawiony na jego własny typ zawartości odpowiada samą zawartością.

19.7 Konfigurowanie i obsługa

19.7.1 perfuse init

Tworzy układ katalogów, przykładowy kanał oraz definicję usługi dla systemu operacyjnego, na którym jest uruchomiony. Nic istniejącego nie jest zastępowane, chyba że przekazano -force.

perfuse init -dir /opt/perfuse -service systemd

19.7.2 perfuse service

Rejestruje Perfuse jako usługę systemu Windows, usuwa ją lub raportuje, czy jest zainstalowana i uruchomiona. Tylko w systemie Windows; w systemie Linux odpowiednikiem jest plik jednostki, który perfuse init może napisać. Zobacz operacje.

19.7.3 perfuse token

Wydaje poświadczenia dla maszyn zamiast ludzi. Token nie wygasa i nie jest dotknięty przez nikogo, kto się wylogowuje, co jest potrzebne przez serwer, który sonduje swojego sąsiada, i co jest celowo nie jest sesją przeglądarki.

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

Tylko skrót jest przechowywany, więc token jest wyświetlany raz, gdy jest tworzony i nie może być później odzyskany. Skradziony zestaw danych nie daje więc żadnego użytecznego tokenu. Nadaj tokenowi najniższą rolę, która wykonuje zadanie: flota potrzebuje viewer, a nic, co tylko czyta, nie powinno posiadać niczego więcej.

-fhir-groups riverside-attributed,riverside-north ogranicza token do tych grup FHIR, dla eksportu dostawcy CMS-0057 Provider Access: na punkcie końcowym FHIR może odczytać te grupy i wyeksportować je, i niczego więcej. Zobacz CMS-0057 dla płatników.

19.7.4 perfuse athena

Drukuje Amazon Athena CREATE EXTERNAL TABLE dla archiwum S3 napisanego z format: ndjson, używając partycji projekcji na części dt=YYYY-MM-DD klucza, więc żaden crawler nie musi działać, gdy dni są dodawane.

perfuse athena -bucket hospital-archive -destination archive

Wydrukowany zamiast uruchomiony, ponieważ tworzenie tabeli wymaga uprawnień do Athena i Glue, których ten program nie powinien posiadać.

19.7.5 perfuse sbom

Wyświetla wszystko, co jest połączone z binarnym plikiem, odczytanym z samej budowy, a nie z go.mod — więc opisuje binarny plik przed tobą, a nie to, o co ktoś kiedyś poprosił.

-json emituje CycloneDX, a -spdx emituje znacznik-wartość SPDX, co jest zwykle tym, o co pyta przegląd zakupów lub bezpieczeństwa. Kod przeglądarki osadzony w binarnym pliku jest włączony, ponieważ recenzent dopasowujący binarny plik do zaleceń musi wiedzieć, że zawiera aplikację React.

19.7.6 perfuse version

Wydrukuje wersję i commit, z którego została zbudowana. Warto dodać do biletu: „obecna” wersja nie jest wersją, a dwie maszyny, które zostały zainstalowane tydzień temu, często nie uruchamiają tego samego budowania.

20 Opcje serwera

Każda opcja, którą perfuse serve akceptuje, wygenerowana z samego programu, więc ta lista nie może nazwać opcji, która nie istnieje, ani pominąć żadnej. Większość z nich jest również ustawieniem w interfejsie sieciowym, nazwanym w ostatniej kolumnie: wartość zapisana tam wygrywa z flagą przy następnym uruchomieniu, a flaga pozostaje sposobem ustawienia jej z definicji usługi. Adres nasłuchiwania, baza danych i katalog kanału pozostają flagami tylko, ponieważ mówią, gdzie serwer znajduje to, co miałby edytować.

Tajemnice nigdy nie są flagami. Opcja, która wymaga hasła lub tokenu, nazywa zmienną środowiskową, która ją zawiera.

20.1 Wszystkie opcje

OptionTakesDefaultWhat it doesIn the console
-addrstring127.0.0.1:8080, or 127.0.0.1:8443 with -tls-certaddress to serve the interface on—
-alert-severitystringwarningminimum severity to send to the webhook: warning or criticalSettings › Alerts › Delivery: Only send alerts at least this serious
-alert-webhookstring—POST alerts to this URL as JSON. Works with Slack, Teams, Mattermost, Alertmanager or anything that accepts a webhook. The payload carries channel names, counts and thresholds; never message contentSettings › Alerts › Delivery: Send alerts to this address
-alertsstring—YAML file of alert rules. Default: alerts.yaml beside the database, written when the rules are first saved in the console; until then a conservative default set is used—
-allow-metadata-egresson/off—permit destinations pointed at cloud instance metadata addresses, which hold this machine's credentialsSettings › Security › What may leave: Allow destinations at cloud instance metadata addresses
-cds-clientsstring—the EHRs trusted to call the CDS services with signed JWTs (issuer and jwks_url)Settings › Payers › Prior authorization: EHRs trusted to call the CDS services
-channelsstring./channelsdirectory holding channel files—
-clusterstring—share the work with other servers on the same PostgreSQL -db: active-passive (one runs everything, another takes over when it stops) or active-active (channels spread over all)—
-cluster-leaseduration15show long a crashed server holds its work before another takes it over; renewed five times as often—
-crd-advisor-castring—a PEM file of certificate authorities to trust for -crd-advisor-url beside the system's (Vaglio's is its DATA/tls/ca.crt)Settings › Payers › Decision service: Certificate authorities to trust for the advice service
-crd-advisor-token-envstring—name of an environment variable holding a bearer token for -crd-advisor-url (the token itself is never a flag)Settings › Payers › Decision service: Environment variable holding the advice service's token
-crd-advisor-urlstring—with -crd-rules, ask the decision service at this URL (such as Vaglio's /api/pas/advise) what a prior authorization request for each order needing one would be told as the record stands, shown as one more CRD card; the prefetched record is POSTed to it. No answer, or any failure, leaves the cards as they are without itSettings › Payers › Decision service: Advice before submitting (CRD)
-crd-rulesstring—a Da Vinci CRD rules file: serve coverage requirements over CDS Hooks at /cds-servicesSettings › Payers › Prior authorization: Coverage rules file (Da Vinci CRD)
-dashboardsstring—a file mapping directory groups and roles to the dashboard each opens onSettings › Monitoring › Dashboards: Which dashboard each group opens on (file)
-datastring—directory for this server's own files (settings, alerts, sign-in configuration, the log): default beside -db when it is a file, the current directory when it is a PostgreSQL URL—
-davinci-versionstring2.2the Da Vinci CRD, DTR and PAS release answered when neither a request nor its client's registration says: 2.2 (CRD 2.2.1, DTR 2.2.0, PAS 2.2.1) or 2.1 (2.1.0)—
-dbstring./perfuse.dbdatabase for users, messages and stored resources: a file, or a postgres:// URL for servers that share one store (a cluster)—
-demo-accountstring—for a public demonstration server: username:password of a shared viewer account shown on the sign-in page—
-dicomweb-archivestring—keep imaging objects in this directory and serve them over DICOMweb (QIDO-RS, WADO-RS, WADO-URI, STOW-RS) at /dicomwebSettings › Data › Imaging archive: Keep images in this folder and serve them over DICOMweb
-dicomweb-corsstring—comma-separated browser origins, such as an OHIF viewer's, allowed to call /dicomwebSettings › Data › Imaging archive: Browser origins allowed to call it
-drain-forduration—after SIGTERM, report not-ready for this long before shutting down (for rolling deploys)Settings › Engine › Shutdown: Wait for in-flight messages on shutdown
-ecr-agencystring—play a public health agency for testing eCR: answer case reports at $process-message with a Reportability Response, using the agency YAML file given (name, phone, address, endpoint; optional rctc, reply)Settings › Public health › Case reporting: Act as a test public health agency
-ecr-responseson/off—accept eCR Reportability Responses at the FHIR endpoint's $process-message, storing each as DocumentReference/<id> derived from the eICR it answersSettings › Public health › Case reporting: Receive Reportability Responses
-engineon/offtruerun the channel engine in this process, so the interface can start, stop and monitor channels—
-epa-payer-idstring—this payer's identifier on the prescribing network, the From of every RTPB and ePA response (default: the formulary's payer id)Settings › Payers › Drug formulary: Payer ID on the prescribing network
-epa-reply-channelstring—route ePA decisions made after the request was answered (a reviewer's, an appeal's) to this channel, which delivers them to the prescriber's networkSettings › Payers › Drug formulary: Channel that sends later ePA decisions
-fhiron/offtrueserve a FHIR endpoint at /fhirSettings › FHIR › The FHIR server: Serve a FHIR endpoint at /fhir
-fhir-api-tokenson/off—with SMART configured, accept Perfuse API tokens on the FHIR endpoint as well (unscoped; the console's FHIR settings can switch it)Settings › FHIR › Access: Accept Perfuse API tokens beside SMART tokens
-fhir-bulk-exporton/off—enable $export, which produces a file holding every record the FHIR endpoint servesSettings › FHIR › Bulk data: Bulk Data export ($export)
-fhir-declaresstring—guides this FHIR server declares in its capability statement, comma-separated: a CapabilityStatement address, or Type=profile addressSettings › FHIR › Capability statement: Guides this server declares
-fhir-max-resourcesint—for a public server: refuse new FHIR resources once this many are held (0: no limit)Settings › FHIR › Access: Most resources held
-fhir-member-match-without-consenton/off—let $member-match answer without an active Consent; the Payer-to-Payer API is opt-in, so only for testingSettings › Payers › CMS-0057-F: Answer $member-match without the member's consent
-fhir-openon/off—serve the FHIR endpoint with no authentication at all, exposing every stored recordSettings › FHIR › Access: Let anyone read the FHIR endpoint without signing in
-fhir-patient-directory-searchon/off—let a token limited to one patient search the directory (practitioners, organisations, locations) within its scopesSettings › FHIR › Access: Let a patient's app search the directory
-fhir-payer-apison/off—enable the CMS-0057 payer operations: $member-match (Payer-to-Payer) and Group $davinci-data-export (Provider Access); the Group exports also need -fhir-bulk-exportSettings › Payers › CMS-0057-F: The CMS-0057-F payer APIs
-fhir-read-onlyon/off—refuse writes to the FHIR endpointSettings › FHIR › Access: Refuse writes to the FHIR endpoint
-fhir-subscriptionson/off—enable topic-based subscriptions, which send encounter and appointment notifications to URLs FHIR clients chooseSettings › FHIR › Notifications: FHIR subscriptions (encounter and appointment notifications)
-fhir-subscriptions-allow-httpon/off—let subscriptions deliver to plain-http endpoints; for a test receiver, never for patient data on a networkSettings › FHIR › Notifications: Allow subscriptions to notify plain-HTTP addresses
-fhir-versionstring4.0.1FHIR release to serve: R4, R4B or R5Settings › FHIR › The FHIR server: FHIR version clients see
-fhir-writes-per-minuteint—for a public server: writes one client address may make to the FHIR endpoint a minute (0: no limit)Settings › FHIR › Access: Writes a minute from one client
-fleet-labelstring—how this instance names itself in a fleet view (default: hostname)Settings › Fleet › This server: Name for this server
-formularystring—publish this drug formulary over the Da Vinci US Drug Formulary API at /formulary/fhir and answer NCPDP Real-Time Prescription Benefit and SCRIPT electronic prior authorization from itSettings › Payers › Drug formulary: Drug formulary file
-icd11-client-idstring—a WHO ICD API client: ICD-11 codes not imported are looked up thereSettings › Data › Code systems: WHO ICD API client ID
-icd11-client-secretstring—the WHO ICD API client's secretSettings › Data › Code systems: WHO ICD API client secret
-icd11-releasestring2025-01the ICD-11 MMS release the WHO ICD API is asked aboutSettings › Data › Code systems: ICD-11 release to ask for
-icd11-urlstring—the ICD API's address when it is not the WHO's: the WHO's ICD-API container on your network needs no clientSettings › Data › Code systems: ICD API address
-index-identityon/offtrueindex patient identifiers from message contents so a message can be found by MRN, name or accession in any format; has no effect when -store-payloads is offSettings › Data › What is kept: Index patient identifiers
-insecureon/off—serve over plain HTTP on a non-loopback address (not recommended)—
-inventorystring—write a Markdown inventory of every interface to this file, and keep it currentSettings › Monitoring › Inventory: Write an interface inventory to
-inventory-everyduration24h0m0show often to rewrite the interface inventorySettings › Monitoring › Inventory: Rewrite the inventory every
-json-logson/off—emit structured JSON logsSettings › Monitoring › Logging: Write logs as JSON
-ldapstring—YAML file configuring directory (LDAP) sign-in (default: ldap.yaml beside the database, once saved in the console)—
-log-filestring—append the log, and the first administrator's one-time password, to this file (mode 0600) instead of the console. A Windows service has no console, so there it defaults to perfuse.log beside the database—
-mcpon/off—serve the Model Context Protocol at /mcp, so AI agents with an API token can read status, messages, the queue, alerts and the FHIR store with that token's own accessSettings › Security › AI agents (MCP): Let AI agents connect over MCP
-measure-reporterstringPerfusethe reporting organisation's name on MeasureReports from $evaluate-measure when the request names no reporter—
-metrics-openon/off—serve /metrics to anybody who can reach the port. Only safe where that port is genuinely private: metric labels name your channels, and on a multi-tenant server they name every tenant'sSettings › Security › Metrics: Serve /metrics without a token
-metrics-tokenstring—credential the Prometheus scrape endpoint requires. Give the scraper the same value in bearer_token_file. Without this, only a signed-in operator can read /metricsSettings › Security › Metrics: Token a metrics scraper presents
-mpion/off—keep a patient index (master patient index) in mpi.db beside the database: patient records from every system linked into one enterprise identifier per person, fed by mpi destinations and the PIX v3 identity feed, answering Patient/$match, PIXm, PIX v3 (/pixv3) and PDQ v3 (/pdqv3)Settings › Data › Patient index: Keep a patient index
-multi-tenanton/off—keep each tenant's channels in their own subdirectory of -channels, so one server can run integration for several organisations without them being able to see each other—
-node-addressstring—this server's console URL as the other servers and a load balancer reach it—
-node-namestring—this server's name in the cluster (default: an id kept in -data)—
-oidcstring—YAML file configuring OpenID Connect sign-in (default: oidc.yaml beside the database, once saved in the console)—
-pason/off—serve Da Vinci PAS 2.2.1 and 2.1.0 (Claim/$submit, $inquire, $decide) on the FHIR endpoint; decisions come from -crd-rules, and what no rule decides is pended for a reviewer. With -fhir-subscriptions, the PAS topic delivers each pended request's resultSettings › Payers › Prior authorization: Da Vinci PAS prior authorization server
-pas-278-castring—a PEM file of certificate authorities to trust for the UM system beside the system'sSettings › Payers › Utilization management link: Certificate authorities to trust for the UM system
-pas-278-certstring—a PEM client certificate for X.509 mutual TLS with the UM system (CORE's authentication)Settings › Payers › Utilization management link: Client certificate file
-pas-278-core-receiverstring—the CORE envelope's ReceiverID, as the UM system's connectivity guide gives it (default: -pas-278-receiver)Settings › Payers › Utilization management link: CORE envelope ReceiverID
-pas-278-core-rule-versionstring—what to write in the CORE envelope's CORERuleVersion when the UM system's guide asks for something other than the version itself (CMS esMD's sample says v2.2.0)Settings › Payers › Utilization management link: CORERuleVersion written in the envelope
-pas-278-core-senderstring—the CORE envelope's SenderID, as the UM system's connectivity guide gives it (default: -pas-278-sender)Settings › Payers › Utilization management link: CORE envelope SenderID
-pas-278-core-versionstring2.2.0the CAQH CORE Connectivity Rule the UM system runs, for core-soap and core-mime: 2.2.0 (payload in the envelope) or C4.0.0 (payload as an MTOM attachment; SOAP only)Settings › Payers › Utilization management link: CAQH CORE Connectivity Rule
-pas-278-keystring—the private key (PEM) for -pas-278-certSettings › Payers › Utilization management link: Client certificate key file
-pas-278-oauth-client-idstring—the OAuth client ID for -pas-278-oauth-token-urlSettings › Payers › Utilization management link: OAuth client ID
-pas-278-oauth-scopestring—the scope asked for with the OAuth token, when the UM system wants oneSettings › Payers › Utilization management link: OAuth scope
-pas-278-oauth-secret-envstring—name of an environment variable holding the OAuth client secret (the secret itself is never a flag)Settings › Payers › Utilization management link: Environment variable holding the OAuth client secret
-pas-278-oauth-token-urlstring—an OAuth 2.0 token endpoint: a token got with the client-credentials grant is sent as a bearer token (CORE vC4.0.0's authorization)Settings › Payers › Utilization management link: OAuth token endpoint
-pas-278-password-envstring—name of an environment variable holding the password for -pas-278-user (the password itself is never a flag)Settings › Payers › Utilization management link: Environment variable holding the password
-pas-278-payer-idstring—the UMO's payer ID (NM1*X3) when the request's insurer carries no identifierSettings › Payers › Utilization management link: Payer ID for the 278s
-pas-278-productionon/off—mark the 278s sent as production (ISA15 P) rather than testSettings › Payers › Utilization management link: Mark the 278s as production
-pas-278-receiverstring—ISA08/GS03 receiver ID on the 278s sent to the UM systemSettings › Payers › Utilization management link: Receiver ID on the 278s
-pas-278-senderstringPERFUSEISA06/GS02 sender ID on the 278s sent to the UM systemSettings › Payers › Utilization management link: Sender ID on the 278s
-pas-278-sftpstring—host:port of the UM system's SFTP server, for -pas-278-transport sftpSettings › Payers › Utilization management link: SFTP server
-pas-278-sftp-everyduration1m0show often the SFTP inbound folder is readSettings › Payers › Utilization management link: Read the SFTP inbound folder every
-pas-278-sftp-inboundstring—the SFTP folder the UM system's 278 responses, 999s and TA1s are collected fromSettings › Payers › Utilization management link: SFTP inbound folder
-pas-278-sftp-keystring—an OpenSSH private key file for the SFTP user, instead of a passwordSettings › Payers › Utilization management link: SFTP key file
-pas-278-sftp-known-hostsstring—an OpenSSH known_hosts file holding the SFTP server's key; required, so requests never go to whoever answersSettings › Payers › Utilization management link: SFTP known_hosts file
-pas-278-sftp-outboundstring—the SFTP folder the 278 requests (and the 999s for the answers) are put inSettings › Payers › Utilization management link: SFTP outbound folder
-pas-278-sftp-password-envstring—name of an environment variable holding the SFTP password (the password itself is never a flag)Settings › Payers › Utilization management link: Environment variable holding the SFTP password
-pas-278-sftp-userstring—the SFTP user nameSettings › Payers › Utilization management link: SFTP user
-pas-278-token-envstring—name of an environment variable holding a bearer token for the UM system (the token itself is never a flag)Settings › Payers › Utilization management link: Environment variable holding the token
-pas-278-transportstringx12how the 278s reach the UM system: x12 (POSTed as application/edi-x12), core-soap (a CAQH CORE SOAP envelope), core-mime (CAQH CORE HTTP MIME multipart), or sftp (batch files over -pas-278-sftp, answers collected from its inbound folder)Settings › Payers › Utilization management link: How the 278s travel
-pas-278-urlstring—forward every PAS request to the payer's utilization management system as an X12 278 request sent to this URL (by -pas-278-transport), and answer with its 278 response; later 278 responses go to Claim/$decide-278Settings › Payers › Utilization management link: Send PAS requests on to the UM system at
-pas-278-userstring—user name for the UM system: CORE's UserName (WS-Security UsernameToken in SOAP), or HTTP Basic for x12Settings › Payers › Utilization management link: User name
-pas-decider-castring—a PEM file of certificate authorities to trust for -pas-decider-url beside the system's, such as the payer's own authority or the decision service's (Vaglio's is its DATA/tls/ca.crt)Settings › Payers › Decision service: Certificate authorities to trust for the decision service
-pas-decider-token-envstring—name of an environment variable holding a bearer token for -pas-decider-url (the token itself is never a flag)Settings › Payers › Decision service: Environment variable holding the decision service's token
-pas-decider-urlstring—ask the decision service at this URL (such as Vaglio) to decide each PAS item on the request's clinical evidence, when -crd-rules leave it to a reviewer; the PAS request Bundle is POSTed to it. Cannot be combined with -pas-278-urlSettings › Payers › Decision service: Decision service URL
-passkey-allowed-modelsstring—comma-separated authenticator AAGUIDs that may enrol; requires -passkey-attestation-roots—
-passkey-attestation-rootsstring—a PEM file of authenticator vendor certificates; passkey attestation is verified against these—
-passkey-domainstring—the bare domain passkeys are registered for, such as perfuse.example.org. No scheme, no port, no path. Setting it turns passkeys on; leaving it empty leaves them offSettings › Sign-in › Passkeys: Domain passkeys are bound to
-passkey-namestringPerfusethe name an authenticator shows a person when they register a passkeySettings › Sign-in › Passkeys: Name shown on the device
-passkey-originsstring—comma-separated origins the console is reached at, with scheme and port: https://perfuse.example.org. Defaults to https:// plus the domainSettings › Sign-in › Passkeys: Other origins passkeys are accepted from
-peersstring—YAML file listing other Perfuse instances to show in a fleet viewSettings › Fleet › Fleet: Other Perfuse servers to show (file)
-public-urlstring—the https address patients' phones and other organisations reach this server at, for the SMART Health Links it hosts (default: the listen address)Settings › FHIR › The FHIR server: Address others reach this server at
-rctcstring—eCR trigger codes for the case report preview: a FHIR ValueSet or Bundle of them, such as the eRSDSettings › Public health › Case reporting: Trigger codes file (RCTC or eRSD)
-residencystring—cloud regions this server's data may go to or come from: areas (eea, uk, ch) and region codes (eu-central-1), comma-separated; channels with connectors elsewhere are refusedSettings › Data › Data protection: Where data may go (cloud regions)
-retention-daysint30how long to keep recorded messages; 0 keeps them for ever, which will eventually fill the diskSettings › Data › How long it is kept: Delete records after
-samlstring—YAML file configuring SAML 2.0 sign-in (default: saml.yaml beside the database, once saved in the console)—
-scimon/off—accept SCIM 2.0 provisioning from an identity provider at /scim/v2. Okta, Entra ID and Google Workspace use it to create accounts and, more importantly, to disable them when somebody leavesSettings › Sign-in › Automatic accounts: Let the identity provider manage accounts
-scim-default-rolestringviewerrole for an account the identity provider does not describe. Defaults downward on purpose: an account whose role could not be determined should be able to read and nothing else—
-settingsstring—settings file the web interface may edit (default: perfuse-settings.yaml beside the database)—
-shl-allow-httpon/off—let a received SMART Health Link point at plain HTTP; for testing onlySettings › Public health › Health links: Allow SMART Health Links over plain HTTP
-signing-certstring—certificate for signing documents (defaults to -tls-cert)Settings › Security › Document signing: Certificate for signing documents
-signing-keystring—key for signing documents (defaults to -tls-key)Settings › Security › Document signing: Key for signing documents
-smart-audiencestring—the audience a SMART token must be issued for, normally the FHIR base URLSettings › SMART › Authorization: Audience tokens must name
-smart-authorizestring—the authorization endpoint to advertise to SMART appsSettings › SMART › Authorization: Authorization endpoint
-smart-backend-serviceson/off—advertise that the SMART authorization server issues backend-services (client_credentials, signed JWT) tokensSettings › SMART › Built-in server: Backend Services (system-to-system tokens)
-smart-clientsstring—run Perfuse's own SMART authorization server at /auth for the apps registered in this YAML fileSettings › SMART › Built-in server: Registered apps file (turns on the built-in server)
-smart-issuerstring—accept SMART on FHIR access tokens from this authorization serverSettings › SMART › Authorization: Accept SMART access tokens from this authorization server
-smart-jwksstring—where to fetch the SMART issuer's signing keys, when not from its published metadata (split DNS, a private address)Settings › SMART › Authorization: Key set file
-smart-jwks-uristring—the authorization server's public key set URL, advertised to SMART apps (needed to claim OpenID Connect sign-in)Settings › SMART › Authorization: Key set address
-smart-keystringsmart-signing.keythe built-in authorization server's RSA signing key (PEM, mode 0600), created if missingSettings › SMART › Built-in server: Signing key file
-smart-oidcstring—with -smart-users, let people sign in at this OpenID Connect provider (YAML: issuer, client_id, client_secret_file or client_secret_env, label); each is linked by oidc_subjectSettings › SMART › Built-in server: Sign people in through the OpenID Connect provider
-smart-tokenstring—the token endpoint to advertise to SMART appsSettings › SMART › Authorization: Token endpoint
-smart-usersstring—with -smart-clients, the people who may sign in to authorize apps (YAML: username, password_hash, fhir_user)Settings › SMART › Built-in server: People who sign in to authorize apps (file)
-snmp-allowstring—comma-separated networks or addresses the SNMP agent answers, such as 10.0.5.0/24; required with -snmp-listenSettings › Monitoring › SNMP: Networks that may ask
-snmp-base-oidstring1.3.6.1.4.1.8072.9999.9999.16, Net-SNMP's experimental spacewhere Perfuse's values sit, under your enterprise numberSettings › Monitoring › SNMP: Base OID
-snmp-communitystring—the SNMPv2c community (a password sent in clear: at least 6 characters, not public or private)Settings › Monitoring › SNMP: SNMP community
-snmp-contactstring—sysContact the SNMP agent reportsSettings › Monitoring › SNMP: Contact (sysContact)
-snmp-listenstring—answer SNMPv2c GET/GETNEXT/GETBULK on this UDP address, such as :161 (off when empty). Read-only: channel states, counts and queue depthsSettings › Monitoring › SNMP: Answer SNMP on this address
-snmp-locationstring—sysLocation the SNMP agent reportsSettings › Monitoring › SNMP: Location (sysLocation)
-snmp-trapsstring—comma-separated managers (host or host:port, default port 162) that receive an SNMPv2 trap when an alert fires or resolvesSettings › Monitoring › SNMP: Send traps to
-store-messageson/offtruerecord every message handled, which is what makes the message browser workSettings › Data › What is kept: Keep a record of each message
-store-payloadson/offtruestore message contents as well as their outcomes; turn this off where PHI must not be held at restSettings › Data › What is kept: Keep message contents
-tls-certstring—TLS certificate fileSettings › Security › Encryption: TLS certificate file
-tls-keystring—TLS private key fileSettings › Security › Encryption: TLS private key file
-trace-endpointstring—OTLP/HTTP base URL to export message traces to, for example http://localhost:4318Settings › Monitoring › Tracing: Send traces to
-trace-instancestring—name for this instance in traces; defaults to the hostname, which is what distinguishes replicasSettings › Monitoring › Tracing: This instance's name in traces
-trace-samplefloat1fraction of traces to record, 0 to 1—
-tsa-urlstring—RFC 3161 time-stamping authority for DSDR signatures on claims attachmentsSettings › Security › Document signing: Time-stamping authority
-vpnstring—partner VPN tunnels to report on the Connections dashboard (YAML: AWS Site-to-Site VPN, Azure VPN Gateway or strongSwan, and both sides' settings); see examples/vpn.yamlSettings › Monitoring › Connections: VPN tunnels to watch (file)
-watch-accesson/offtruewatch traffic and reads of patient data for what a breach looks like (bursts, night traffic, new destinations, bulk reads) and raise alerts—
-xdsstring—keep clinical documents here as an IHE XDS.b registry and repository with this repository uniqueId (an OID), answering ITI-41, ITI-42, ITI-18 and ITI-43 at /xds/repository and /xds/registrySettings › Data › Document sharing (IHE XDS): Keep documents here as an XDS registry and repository
-xds-home-communitystring—this community's home community id (urn:oid:...), so /xca/gateway answers XCA ITI-38 and ITI-39 for itSettings › Data › Document sharing (IHE XDS): Home community id, for XCA

21 Odwołanie do kanału

Każdy klucz, który może pojawić się na najwyższym poziomie pliku kanału. Są one wyodrębnione z źródła, więc ten rozdział nie może opisać opcji, która nie istnieje, ani pominąć tej, która istnieje.

21.1 Kanał

Kanał to jeden skonfigurowany przepływ wiadomości: miejsce, w którym wiadomości przychodzą, opcjonalny filtr i jedno lub więcej miejsc, do których są wysyłane.

Zdefiniowane jako Channel w internal/config.

KluczTypWymaganyDomyślny
nameteksttak—
descriptiontekstnie—
grouptekstnie—
attachmentsZałączniki (blok, pomijaj, aby wyłączyć)nie—
delimitedDelimited (blok, pomijaj, aby wyłączyć)nie—
tableslista tekstunie—
contractContractRef (blok, pomijaj, aby wyłączyć)nie—
enabledtrue lub false (blok, pomijaj, aby wyłączyć)nie—
dataTypeDataTypeniehl7
hl7v3HL7v3Options (blok, pomijaj, aby wyłączyć)nie—
x12X12Options (blok, pomijaj, aby wyłączyć)nie—
ncpdpNCPDPOptions (blok, pomijaj, aby wyłączyć)nie—
edifactEDIFACTOptions (blok, pomijaj, aby wyłączyć)nie—
scriptScriptOptions (blok, pomijaj, aby wyłączyć)nie—
dicomDICOMOptions (blok, pomijaj, aby wyłączyć)nie—
sourceŹródłotak—
filtertekstnie—
transformationslista transform.Stepnie—
scriptsSkrypty (blok, pomijaj, aby wyłączyć)nie—
shadowShadow (blok, pomijaj, aby wyłączyć)nie—
destinationslista Destinationtak—

21.1.1 nazwa

Nazwa identyfikuje kanał w logach i metrykach.

Wymagana i unikalna.

21.1.2 grupa

Grupa to część, do której należy ten kanał, służy do organizacji listy, która stała się zbyt długa do odczytania.

Kosmetyczna przy pięciu kanałach i strukturalna przy dwustu: kanały witryny dzielą się na systemy, z którymi rozmawiają, lub zespoły, które je posiadają, a płaska lista dwustu nazw jest nieprzydatna, niezależnie od jakości reszty interfejsu.

Zwykły ciąg znaków, a nie obiekt grupy z własnym plikiem, ponieważ grupa nie ma zachowania. W momencie, gdy ma plik, nabywa ustawienia, a ustawienia na grupie oznaczają, że zachowanie kanału zależy od czegoś, co nie jest napisane w kanale - co jest właściwością, która sprawia, że konfiguracja Mirth jest trudna do zrozumienia. Grupy tutaj są tylko etykietą.

21.1.3 załączniki

Załączniki przenoszą duże ładunki poza wiadomość i przywracają je przed dostarczeniem.

Opcja włączona na kanał: karmienie zwykłych wiadomości ADT nie ma nic do wyodrębnienia i nie powinno płacić za maszynę.

21.1.4 delimited

Delimited konfiguruje kanał z ogranicznikami.

Jedynie istotne, gdy typ danych jest ograniczony.

21.1.5 tabel

Tabele nazw plików udostępnionych tabel mapowania, do których odnosi się przekształcenie według nazwy.

Udostępnione, ponieważ podatek domeny jest w dużej mierze ponownym pochodzeniem mapowania, które ktoś już wyprowadził: kody płci i klasy pacjentów w witrynie są tłumaczone identycznie w każdym kanale, który ich dotyka, a tabela w kanale jest tabelą, którą może używać tylko ten kanał.

21.1.6 włączone

Włączone domyślnie.

Wyłączony kanał jest ładowany i walidowany, ale nie uruchamiany, więc plik, który jest tymczasowo wyłączony, jest nadal sprawdzany przez CI.

21.1.7 typ danych

Typ danych to format wiadomości, które ten kanał otrzymuje.

Domyślnie jest to hl7, więc każdy kanał napisany przed jego istnieniem nadal działa.

21.1.8 x12

X12 zawiera ustawienia, które mają znaczenie tylko na kanale X12.

Ustawienie go na jakimkolwiek innym typie jest odrzucane, a nie ignorowane.

21.1.9 skrypt

Skrypt konfiguruje kanał NCPDP SCRIPT.

Jego kroki znajdują się tutaj, a nie w głównych transformacjach, z tego samego powodu, co inne formaty nie-v2: typy kroków różnią się w zależności od formatu, więc jeden klucz mógłby oznaczać różne rzeczy w zależności od typu danych.

21.1.10 dicom

Obrazowanie konfiguruje nazwane kroki transformacji kanału DICOM.

Nazywane Obrazowaniem, a nie DICOM, ponieważ źródło i miejsce przeznaczenia już mają pole DICOM i trzy pola o tej samej nazwie na różnych poziomach to sposób, w jaki ktoś ustawia niepoprawne.

21.1.11 filtr

Filtr to wyrażenie, które musi być spełnione, aby wiadomość mogła być przekazana dalej.

Wiadomość, która nie spełnia warunku, jest nadal potwierdzana: nadawca nie zrobił nic złego, po prostu nie jesteśmy zainteresowani.

21.1.12 transformacje

Transformacje to deklaracyjne zmiany stosowane do zaakceptowanych wiadomości, w kolejności, przed uruchomieniem skryptu.

To jest warstwa przeznaczona do wykonania zwykłej pracy: każdy krok jest walidowany podczas ładowania pliku, pojawia się w diffie i może być przeglądany przez kogoś, kto nie czyta JavaScript.

21.1.13 skrypty

Skrypty zawierają kod JavaScript dla przypadków, które deklaracyjne kroki nie mogą wyrazić, i to jest to, co skrypty kanału Mirth wprowadzają niezmienione.

Kanał ze skryptem jest oznaczony jako taki w interfejsie, ponieważ jego zachowanie nie może być ustalone przez odczytanie konfiguracji.

21.1.14 cieniowanie

Cieniowanie uruchamia kandydującą wersję tego kanału obok niego i raportuje, gdzie się różnią.

Nic, co robi, nie może dotknąć odbiorcy.

22 Odwołanie do źródła

W każdy sposób, w jaki kanał może otrzymywać wiadomości, oraz każdy klucz, który każdy z nich akceptuje. Kanał ma dokładnie jeden źródło.

22.1 Źródło AMQP

Źródło AMQP otrzymuje z kolejki lub subskrypcji.

Wiadomość jest akceptowana tylko po tym, jak kanał ją obsłużył. Ta, której nie można było obsłużyć, jest zwalniana jako nieudana dostawa, więc broker ponownie ją dostarcza i - w przypadku Service Bus, poza maksymalną liczbą dostaw w kolejce - umieszcza ją w martwym liście.

Zdefiniowane jako AMQPSource w internal/config.

KluczTypWymaganyDomyślny
prefetchliczba całkowitanie10
reconnectczas trwania, np. 30s lub 5mnie5s

22.1.1 prefetch

Prefetch to liczba wiadomości, które broker może wysłać z wyprzedzeniem.

Domyślnie wynosi 10. Nadal są one obsługiwane pojedynczo, w kolejności.

22.1.2 reconnect

Reconnect to czas oczekiwania po utracie połączenia.

Defaults to 5s.

22.2 Źródło AS2

Źródło AS2 otrzymuje AS2 (RFC 4130): EDI wysłane przez HTTP, podpisanego i zaszyfrowanego za pomocą S/MIME, odpowiedzi z potwierdzeniem (MDN) zawierającym skrót tego, co przybyło.

Payload jest tym, co kanał obsługuje; X12 i EDIFACT są zwykle używane.

Zdefiniowane jako AS2Source w internal/config.

KluczTypWymaganyDomyślny
listenteksttak—
pathtekstnie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—
idteksttak—
cert_fileteksttak—
key_fileteksttak—
partnerslista partnerów AS2tak—
max_message_sizeliczba całkowitanie—
duplicate_windowczas trwania, np. 30s lub 5mnie—

22.2.1 path

Ścieżka jest ścieżką URL, do której partnerzy wysyłają.

Default /as2.

22.2.2 tls

TLS obsługuje HTTPS.

Większość partnerów wymaga tego w umowie, oprócz S/MIME.

22.2.3 id

ID to nasz identyfikator AS2, który partnerzy wysyłają w AS2-To.

Wiadomość do dowolnego innego jest odrzucana.

22.2.4 partnerzy

Partnerzy to ci, którzy mogą wysyłać tutaj.

Wiadomość od każdego innego jest odrzucana.

22.2.5 duplicate_window

DuplicateWindow to czas, przez jaki pamiętany jest identyfikator Message-ID partnera, tak aby wiadomość wysłana ponownie (partner nie otrzymał naszego potwierdzenia i ponowił próbę) była odpowiedzią potwierdzeniem i nie była przekazywana dwukrotnie (RFC 4130 sekcja 7.5).

Default 30 days.

22.3 Azure Blob Źródło

AzureBlobSource pobiera obiekty blob z prefiksu kontenera.

Zdefiniowane jako AzureBlobSource w internal/config.

KluczTypWymaganyDomyślny
prefixteksttak—
suffixtekstnie—
after_readtekstnie—
move_totekstnieprocessed/
error_prefixtekstnieerror/
poll_intervalczas trwania, np. 30s lub 5mnie30s
max_object_sizeliczba całkowitanie16 MiB
framedtrue lub falsenie—

22.3.1 move_to

MoveTo to miejsce, gdzie przenosi się obsłużony obiekt blob.

Domyślnie ustawiony na processed/.

22.3.2 error_prefix

ErrorPrefix to miejsce, gdzie przenosi się obiekt blob, który nie może być obsłużony, aby nie blokował reszty.

Domyślnie ustawiony na error/.

22.3.3 poll_interval

PollInterval między listami.

Defaults to 30s.

22.3.4 max_object_size

MaxObjectSize odmawia przyjęcia większego obiektu blob, który pozostaje tam, gdzie jest.

Domyślnie ustawiony na 16 MiB.

22.4 Broker Źródło

BrokerSource odczytuje wiadomości z brokera wiadomości.

Czytnik JMS Mirth, dostępny przez STOMP, ponieważ JMS jest interfejsem API Javy, a nie protokołem. Zobacz internal/stomp, aby dowiedzieć się, dlaczego STOMP, a nie OpenWire.

Zdefiniowane jako BrokerSource w internal/config.

KluczTypWymaganyDomyślny
addrteksttak—
destinationteksttak—
logintekstnie—
passcodetekstnie—
hosttekstniehost adresu
selectortekstnie—
subscription_idtekstnienazwa kanału
heartbeatczas trwania, np. 30s lub 5mnietrzydzieści sekund
reconnectczas trwania, np. 30s lub 5mniepięć sekund
timeoutczas trwania, np. 30s lub 5mnietrzydzieści sekund
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—

22.4.1 addr

Adres to host i port brokera.

Wymagane. 61613 to zwykły port STOMP.

22.4.2 destination

Destination to kolejka lub temat, z którego odczytywane są dane.

Required.

Brokerzy zapisują te dane różnie - /queue/name w ActiveMQ, nazwa bez ścieżki w RabbitMQ - więc są one przekazywane bez zmian, zamiast być montowane w tym miejscu. Odgadnięcie oznaczałoby pracę na jednym brokerze i ciche odczytywanie niczego na innym.

22.4.3 login

Login i Passcode uwierzytelniają.

Większość brokerów odmawia połączenia anonimowego.

22.4.4 passcode

Login i Passcode uwierzytelniają.

Większość brokerów odmawia połączenia anonimowego.

22.4.5 host

Host to host wirtualny.

Domyślnie jest to host adresu.

22.4.6 selector

Selector filtruje wiadomości na brokerze.

Selektor JMS, przekazywany bez interpretacji. Filtrowanie na brokerze, a nie w tym miejscu, oznacza, że wiadomości, których ten kanał nie chce, nigdy nie przekraczają sieci - co w przypadku współdzielonej kolejki jest różnicą między odczytaniem stu wiadomości dziennie a stu tysiącami.

22.4.7 subscription_id

SubscriptionID nazwuje subskrypcję.

Domyślnie jest to nazwa kanału.

Nazwana, a nie wygenerowana, ponieważ trwała subskrypcja jest identyfikowana przez nią: wygenerowana subskrypcja tworzyłaby nową subskrypcję przy każdym ponownym uruchomieniu i pozostawiałaby stare subskrypcje, które gromadzą wiadomości, których nikt nie czyta.

22.4.8 heartbeat

Heartbeat utrzymuje połączenie.

Domyślnie jest to trzydzieści sekund.

Włączone domyślnie, w przeciwieństwie do domyślnego ustawienia klienta, ponieważ źródło utrzymuje otwarte połączenie przez tygodnie. Bez sygnałów serca połączenie przez zapory sieciową, której trasa została cicho usunięta, wygląda idealnie zdrowo z tego końca, a wiadomości po prostu przestają przychodzić, bez logowania.

22.4.9 reconnect

Reconnect to czas oczekiwania przed ponownym połączeniem po awarii.

Domyślnie jest to pięć sekund.

22.4.10 limit czasu

Granice limitu czasu podczas łączenia.

Domyślnie jest to trzydzieści sekund.

22.5 Źródło zapytania DICOM

DICOMQuerySource przesłuchuje archiwum za pomocą C-FIND i emituje wiadomość dla każdego nowego badania.

Mirth nie ma równoważnego łącznika. Jego obsługa DICOM jest odbiornikiem i nadawcą - może odbierać obrazy przesłane do niego i przesyłać je dalej, i to wszystko. Zapytanie archiwum o to, co zawiera, było wnioskowane na ich forach od 2015 roku.

To, co sprawia, że jest warte posiadania, nie jest zapytanie, ale automatyzacja: wstępne pobieranie, które działa o trzeciej rano, uzgodnienie, które zauważa, że archiwum nie zawiera badania, które RIS mówi, że istnieje, lista pracy utworzona z tego, co było rzeczywiście zeskanowane, a nie z tego, co zostało zamówione. Są to zadania, które strony wykonują obecnie za pomocą zaplanowanego skryptu poza silnikiem, co oznacza, że są niewidoczne dla niego - brak ponownych prób, brak alertów, brak historii wiadomości.

Zdefiniowane jako DICOMQuerySource w internal/config.

KluczTypWymaganyDomyślny
addressteksttak—
called_aeteksttak—
calling_aetekstnie—
leveltekstnieSTUDY
patient_rootprawda lub fałsznie—
matchmapa tekstu do tekstunie—
returnlista tekstunie—
intervalczas trwania, np. 30s lub 5mtak—
windowczas trwania, np. 30s lub 5mnie—
overlapczas trwania, np. 30s lub 5mniegodzina
limitliczba całkowitanie500
timeoutczas trwania, np. 30s lub 5mniedwa minuty
tlstlsconf.Ustawienia (blok, pomijaj, aby wyłączyć)nie—
emit_on_first_pollprawda lub fałszniefalse

22.5.1 adres

Adres to host i port archiwum.

Required.

Nazwany, aby dopasować do miejsca przeznaczenia DICOM, a nie skrócony. Dwa były "adres" i "addr" przez popołudnie, co jest rodzajem niekonsekwencji, której ktoś piszący ręcznie plik kanału popełnia raz i potem nieufnie podchodzi do całego formatu.

22.5.2 called_ae

CalledAE to tytuł AE archiwum.

Wymagany w praktyce: większość archiwów odmawia skojarzenia skierowanego do czegoś innego, a to odmówienie jest odczytywane jako awaria, a nie jako błąd konfiguracyjny.

22.5.3 calling_ae

CallingAE to tytuł AE przedstawiany przez Perfuse.

Archiwa często go używają do kontroli dostępu.

22.5.4 poziom

Poziom to poziom zapytania: PACJENT, BADANIE, SERIA lub OBRAZ.

Domyślnie jest to BADANIE.

BADANIE jest domyślnym, ponieważ jest to to, czego prawie każde przydatne zapytanie chce, i dlatego, że alternatywy zaskakują ludzi: poziom OBRAZU wobec dużego CT zwraca jeden odpowiedź na plaster, co jest setkami na badanie.

22.5.5 dopasuj

Dopasuj to klucze zapytania.

Wartość filtruje; pusta wartość prosi o zwrócenie pola.

Klucze są nazwane, a nie ponumerowane - "PatientID" zamiast "0010,0020" - ponieważ plik kanału jest czytany przez ludzi, a numer tagu w pliku konfiguracyjnym jest wyszukiwaniem, które każdy czytelnik musi wykonać.

22.5.6 zwróć

Pola Return są polami, które należy zwrócić bez filtrowania ich.

Oddzielone od Match pustą wartością, chociaż są one zakodowane w ten sam sposób, ponieważ intencja jest inna i czytelnik może zobaczyć, które klucze zawężają wyszukiwanie, a które są zbierane.

22.5.7 interwał

Interwał określa, jak często należy przeprowadzać sondowanie.

Required.

22.5.8 okno

Okno określa, jak daleko wstecz każde sondowanie sięga, jako zakres daty badania.

Zero wyłącza całkowicie filtrowanie dat.

Okno jest tym, co utrzymuje to w granicach. Bez niego każde sondowanie prosi archiwum o wszystko, co kiedykolwiek posiadało, a następnie odrzuca to, co widziało wcześniej - co działa w teście archiwum i jest niegrzeczne wobec prawdziwego archiwum zawierającego miliony badań.

22.5.9 nakładanie

Nakładanie ponownie wysyła zapytanie o ten okres, który już został przesondowany.

Domyślnie ustawiony na jedną godzinę.

Konieczne raczej niż ostrożne. Badanie może być zarejestrowane z datą wczorajszą, nasz zegar i zegar archiwum nie muszą się zgadzać, a granica sondowania, która dokładnie pokrywa się z przybyciem, traci je. Nakładanie ponownie wysyła zapytanie, a już widziany sprawdzian zatrzymuje duplikat - więc koszt nakładania jest nieznacznie większym zapytaniem, a koszt braku nakładania jest cicho pominiętym badaniem.

22.5.10 limit

Limit ogranicza liczba dopasowań akceptowanych z jednego sondowania.

Defaults to 500.

Ograniczenie zamiast braku ograniczenia, ponieważ źle wpisany klucz dopasowania zmienia to w "daj mi wszystko", a pierwszym objawem tego wobec prawdziwego archiwum jest pytanie administratora archiwum, kto uderza w nie.

22.5.11 limit czasu

Limit czasu ogranicza jedno sondowanie.

Domyślnie ustawiony na dwie minuty.

22.5.12 emit_on_first_poll

EmitOnFirstPoll wysyła komunikaty dla wszystkiego, co pierwsze sondowanie znajdzie.

Domyślnie ustawiony na false.

False ma znaczenie. Wskazywanie tego na archiwum, które już zawiera milion badań i powodowanie, że wysyła komunikat dla każdego, nie jest przydatnym pierwszym uruchomieniem, i jest to rodzaj błędu, który jest zauważalny w dół strumienia, a nie tutaj. Pierwsze sondowanie rejestruje, co istnieje i nie emituje nic; drugie sondowanie i dalej raportuje, co jest nowe.

22.6 Źródło DICOM

DICOMSource otrzymuje obiekty obrazowania jako dostawca klasy usługi C-STORE.

To, na co szpital wskazuje aparat lub PACS. Mirth nazywa to słuchaczem DICOM i wykonuje tylko C-STORE, więc jest to równość, a nie podzbiór.

Zdefiniowane jako DICOMSource w internal/config.

KluczTypWymaganyDomyślny
listenteksttak—
ae_titletekstnie—
allowed_calling_aelista tekstunie—
sop_classeslista tekstunie—
transfer_syntaxeslista tekstunie—
max_object_bytesliczba całkowitanie—
idle_timeoutczas trwania, np. 30s lub 5mnie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—

22.6.1 listen

Listen to jest adresem, na którym ma być obsługiwany.

Wymagany. 104 to zarejestrowany port DICOM; 11112 to powszechny alternatyw, gdy wiązanie portu uprzywilejowanego nie jest możliwe.

22.6.2 ae_title

AETitle to nazwa, którą ten punkt końcowy nazywa siebie.

Zdecydowanie zalecane, a nie wymagane, i ostrzegane, gdy jest nieobecne. Jedynym mechanizmem kontroli dostępu na punkcie końcowym DICOM jest często tytuł AE, więc punkt końcowy, który akceptuje dowolny tytuł, akceptuje wszystko, co może do niego dotrzeć.

22.6.3 allowed_calling_ae

AllowedCallingAE lista tytułów AE dozwolonych do połączenia.

Pusty lista akceptuje dowolnego nadawcę.

To jest mechanizm kontroli dostępu, jaki ma DICOM. PACS jest zwykle konfigurowany do akceptowania jednego nazwanego tytułu wywołującego i odrzucania wszystkiego innego, a ten koniec nie miał równorzędnego: sprawdzany był tytuł wywołany - który jest nazwą, którą nadawca wybiera, więc każdy może go poprawnie wysłać - podczas gdy to, kto wywoływał, było rejestrowane w dzienniku i w przeciwnym razie ignorowane.

Pusty lista nadal akceptuje wszystko, ponieważ urządzenie, którego nikt nie wymienił, jest normalnym stanem pierwszej instalacji, a odmowa domyślnie złamałaby każde wdrożenie w dniu jeden. Zamiast tego ostrzega, a ostrzeżenie wymienia tytuły, które się połączyły, więc ktoś może wypełnić to na podstawie tego, co faktycznie przybyło.

22.6.4 sop_classes

SOPClasses ogranicza rodzaje obiektów do zaakceptowania.

Pusty lista akceptuje dowolny.

Pusty jest rozsądną wartością domyślną w tym miejscu, ponieważ ten silnik przekazuje obiekty, zamiast je interpretować, więc odmowa nieznanego klasy odmówiłaby ważne obrazy bez korzyści.

22.6.5 transfer_syntaxes

TransferSyntaxes ogranicza kodowania do zaakceptowania, w preferowanym porządku.

Pusty lista akceptuje trzy nieściskane.

22.6.6 max_object_bytes

MaxObjectBytes ogranicza jeden otrzymany obiekt.

Zero stosuje wartość domyślną.

22.6.7 idle_timeout

IdleTimeout zamyka stowarzyszenie, które poszło cicho.

Zero oznacza nigdy, co jest zwykle słuszne - modalność utrzymuje powiązanie otwarte między badaniami.

22.6.8 tls

TLS szyfruje połączenia przychodzące i może wymagać certyfikatu klienta.

Warto to powiedzieć wprost: Mirth potrzebuje swojego płatnego rozszerzenia SSL Manager do tego, a fork społeczności nie może go w ogóle dostarczyć. DICOM przenosi nazwy pacjentów w swoich metadanych, więc to jest jedno z miejsc, w którym bycie przepisanym zamiast forkowanym jest prawdziwą zaletą, a nie stylistyczną.

22.7 Źródło Mweb DICO

DICOMwebSource akceptuje żądania STOW-RS.

Zdefiniowane jako DICOMwebSource w internal/config.

KluczTypWymaganyDomyślny
listenteksttak—
pathtekstnie/dicom-web
tokentekstnie—
usernametekstnie—
passwordtekstnie—
max_object_bytesliczba całkowitanie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—

22.7.1 listen

Listen to jest adresem, na którym ma być obsługiwany.

Required.

22.7.2 path

Ścieżka to korzeń usługi.

Obiekty są akceptowane w ścieżce/studies i ścieżce/studies/{uid}. Domyślnie jest to /dicom-web, co używają Orthanc i dcm4chee, więc nadawca skonfigurowany dla jednego z nich potrzebuje tylko zmienionego hosta.

22.7.3 token

Token, jeśli jest ustawiony, jest wymagany jako token nośnikowy.

Nazwa użytkownika i hasło wymagają uwierzytelniania HTTP Basic.

22.7.4 nazwa użytkownika

Token, jeśli jest ustawiony, jest wymagany jako token nośnikowy.

Nazwa użytkownika i hasło wymagają uwierzytelniania HTTP Basic.

22.7.5 hasło

Token, jeśli jest ustawiony, jest wymagany jako token nośnikowy.

Nazwa użytkownika i hasło wymagają uwierzytelniania HTTP Basic.

22.8 Źródło bazy danych

DatabaseSource odczytuje wiersze z bazy danych i przekształca każdy z nich w wiadomość.

To jest sposób, w jaki wiele interfejsów szpitalnych faktycznie zaczyna się. System departamentu nie ma możliwości HL7, więc ktoś zapisuje wiersze do tabeli buforowej, a silnik interfejsu sonduje ją. To nie jest glamour, a jest wszędzie.

To jest również najczęstszy sposób, w jaki kanał Mirth zatrzymuje się, a powodem jest zwykle ta sama forma: wiersz, który nie może być przetworzony, jest odczytany, nie powiedzie się i jest odczytany ponownie, na zawsze, ponieważ nic nie oznaczyło go. Kanał wygląda na żywy. Kolejka wygląda na pustą. Nic się nie porusza, a każda wiadomość za złym wierszem czeka na wiersz, który nigdy nie powiedzie się.

Większość projektu tutaj dotyczy tego.

Zdefiniowane jako DatabaseSource w internal/config.

KluczTypWymaganyDomyślny
driverteksttak—
dsnteksttak—
queryteksttak—
after_querytekstnie—
key_columntekstnie—
templatetekstnie—
columntekstnie—
poll_intervalczas trwania, np. 30s lub 5mnie—
batch_sizeliczba całkowitanie100
max_attemptsliczba całkowitanie3
query_timeoutczas trwania, np. 30s lub 5mnie30s

22.8.1 sterownik

Sterownik określa nazwę bazy danych.

See SupportedDrivers.

22.8.2 dsn

DSN to ciąg połączenia.

Wolą jest odniesienie do zmiennej środowiskowej zamiast literalu, ponieważ zwykle zawiera ono hasło, a kanały są przeznaczone do użycia w git.

22.8.3 zapytanie

Zapytanie wybiera wiersze oczekujące na wysłanie.

Required.

Muszą to być wybrane wiersze. Zapytanie, które wykonałoby polecenia zapisu w trybie cichym, uruchamiałoby się według harmonogramu bez rekordu zmian.

22.8.4 po_zapytaniu

AfterQuery oznacza wiersz jako przetworzony i uruchamia się z kluczem wiersza powiązanym z nim.

Strongly recommended.

Bez tego każde zapytanie ponownie odczytuje każdy wiersz, który nadal pasuje do zapytania, więc samo zapytanie musi wykluczyć wiersze przetworzone w inny sposób. Jeśli żadna z nich nie jest prawdziwa, kanał ponownie wysyła te same wiersze na zawsze, co jest burzą duplikatów, a nie zatorami i jest wręcz gorsze.

22.8.5 kolumna_klucza

KeyColumn identyfikuje wiersz dla AfterQuery, kwarantanny i deduplikacji.

Wymagane, gdy AfterQuery jest ustawione.

22.8.6 szablon

Szablon tworzy wiadomość z wiersza.

Wymagane jest albo to, albo kolumna.

Odwołania do kolumn używają ${nazwa_kolumny}. Brakujące kolumny są błędem podczas ładowania, a nie pustym ciągiem w wiadomości klinicznej.

22.8.7 rozmiar_partii

BatchSize ogranicza wiersze pobrane podczas zapytania.

Defaults to 100.

Ograniczone, ponieważ nieograniczone pierwsze zapytanie do tabeli, którą ktoś wypełniał przez rok, odczytałoby całą jej zawartość do pamięci i wysłałoby ją, co powodowałoby, że migracja zalewałaby żywego odbiorcę.

22.8.8 maksymalna_liczba_prób

MaxAttempts określa, ile razy pojedynczy wiersz może nie powieść się, zanim zostanie poddany kwarantannie i zapytanie przejdzie dalej.

Defaults to 3.

To ustawienie zapobiega zatorom. Ponowne próby bez ograniczeń nie są odpornością; jest to jeden zły wiersz, który zatrzymuje karmienie szpitala.

22.8.9 limit_czasu_zapytania

QueryTimeout ogranicza pojedyncze zapytanie.

Defaults to 30s.

22.9 Bezpośrednie źródło

DirectSource odbiera pocztę Direct, którą HISP dostarcza: nasłuchiwacz SMTP dla tego adresu pocztowego.

Każda wiadomość jest odszyfrowana, jej podpis jest sprawdzany względem kotwic i jej sygnatariusz względem Nadawcy, a jej zawartość jest przekazywana dalej: dokumenty pakietu XDM, w przeciwnym razie każza załącznik, w przeciwnym razie tekst.

Zdefiniowane jako DirectSource w internal/config.

KluczTypWymaganyDomyślny
listentekstnie—
tls_certtekstnie—
tls_keytekstnie—
max_bytesliczba całkowitanie—
smtp_hosttekstnie—
usernametekstnie—
passwordtekstnie—
imapDirectIMAP (blok, pomijaj, aby wyłączyć)nie—
xdrDirectXDR (blok, pomijaj, aby wyłączyć)nie—

22.9.1 smtp_host

SMTPHost, Username i Password to serwer podania HISP, używany do wysłania powiadomienia o „przetworzonym” dostarczeniu (MDN) do nadawcy, gdy wiadomość została pobrana.

Bez niego nie jest wysyłane powiadomienie.

22.9.2 nazwa użytkownika

SMTPHost, Username i Password to serwer podania HISP, używany do wysłania powiadomienia o „przetworzonym” dostarczeniu (MDN) do nadawcy, gdy wiadomość została pobrana.

Bez niego nie jest wysyłane powiadomienie.

22.9.3 hasło

SMTPHost, Username i Password to serwer podania HISP, używany do wysłania powiadomienia o „przetworzonym” dostarczeniu (MDN) do nadawcy, gdy wiadomość została pobrana.

Bez niego nie jest wysyłane powiadomienie.

22.10 Źródło poczty elektronicznej

EmailSource odczytuje pocztę z skrzynki pocztowej i przekształca załączniki, treści lub całe wiadomości w wiadomości.

Zdefiniowane jako EmailSource w internal/config.

KluczTypWymaganyDomyślny
protocoltekstnie—
hostteksttak—
portliczba całkowitanie—
securitytekstnie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—
usernameteksttak—
passwordtekstnie—
oauthEmailOAuth (blok, pomijaj, aby pominąć)nie—
mailboxtekstnie—
taketekstnie—
attachment_nameslista tekstównie—
allowed_senderslista tekstównie—
after_readtekstnie—
move_totekstnie—
error_foldertekstnie—
poll_intervalczas trwania, np. 30s lub 5mnie—
max_message_sizeliczba całkowitanie—

22.10.1 hasło

Hasło może być ${ENV}; dla Gmaila hasło aplikacji.

Ignorowane z oauth.

22.10.2 attachment_names

AttachmentNames ogranicza, które załączniki są pobierane, według wzorca nazwy pliku (*.hl7).

Pusty pobiera każdy załącznik.

22.10.3 allowed_senders

AllowedSenders ogranicza, której poczty są odczytywane: adresy i domeny.

Nagłówek From może być sfałszowany, więc to utrzymuje przypadki i pocztę okazjonalną, a nie atakującego.

22.10.4 move_to

MoveTo to folder, do którego przenoszone są przetworzone poczty; Domyślnie jest to folder „Przetworzono”.

Utworzone, gdy brakuje.

22.11 Źródło FTP

FTPSource gromadzi pliki z serwera FTP lub FTPS.

Dlaczego FTP jest nadal tutaj

To trzydzieści lat po zaleconej wymianie i wiele systemów szpitalnych nadal eksportuje do niego: urządzenia, których oprogramowanie układowe nigdy nie zostanie zaktualizowane, systemy rozliczeniowe, których dostawca pobiera opłatę za zmianę. Odmowa mówienia w tym języku nie powoduje, że te systemy znikają, oznacza to, że silnik integracji nie może być używany.

FTPS jest domyślny. To ten sam protokół z TLS, większość serwerów, które przetrwały, obsługuje go, i jest to o wiele łatwiejsza rozmowa z zespołem ds. bezpieczeństwa niż zwykłe FTP.

Zdefiniowane jako FTPSource w internal/config.

KluczTypWymaganyDomyślny
hostteksttak—
usertekstnie—
passwordtekstnie—
securityftpconn.Securitynieexplicit
insecure_skip_verifytrue or falsenie—
roottekstnie—
timeoutczas trwania, np. 30s lub 5mnietrzydzieści sekund

22.11.1 host

Host to serwer, z opcjonalnym portem.

Przyjmuje się port 21.

22.11.2 użytkownik

Użytkownik i hasło uwierzytelniają.

Oba mogą być pominięte dla serwera anonimowego.

Anonimowy FTP jest nadal używany do publikowania niektórych publicznych kanałów referencyjnych, więc pusty użytkownik jest prawidłową konfiguracją, a nie przeoczeniem i nie jest odrzucany. Na serwerze, który oczekuje poświadczeń, pominięcie ich powoduje awarię logowania w czasie połączenia, co jest zgłaszane wobec kanału, a nie ponawiane w trybie cichym.

22.11.3 hasło

Użytkownik i hasło uwierzytelniają.

Oba mogą być pominięte dla serwera anonimowego.

Anonimowy FTP jest nadal używany do publikowania niektórych publicznych kanałów referencyjnych, więc pusty użytkownik jest prawidłową konfiguracją, a nie przeoczeniem i nie jest odrzucany. Na serwerze, który oczekuje poświadczeń, pominięcie ich powoduje awarię logowania w czasie połączenia, co jest zgłaszane wobec kanału, a nie ponawiane w trybie cichym.

22.11.4 zabezpieczenie

Zabezpieczenie jest jawne, niejawne lub brak.

Domyślnie jest jawne, co oznacza FTPS z negocjacją AUTH TLS na zwykłym porcie. "Brak" to zwykły FTP i musi być wyraźnie wymagany.

22.11.5 korzeń

Korzeń to katalog, względem którego są względne wszystkie ścieżki, i co jest egzekwowane.

Serwer nie ma pojęcia o tym: serwer FTP z chęcią zaakceptuje ../.. jako ścieżkę. Więc to powstrzymuje move_to przed zapisaniem gdziekolwiek konto może się dostać.

22.11.6 limit czasu

Limit czasu ogranicza jedną operację, a nie cały poll.

Domyślnie jest to trzydzieści sekund.

Operacja po operacji, ponieważ poll, który wylistuje katalog i pobierze dwadzieścia plików, wykonuje dwadzieścia jeden operacji, a jeden budżet dla wszystkich z nich przerwałby prawidłowy transfer dużego pliku.

22.12 Źródło plików

FileSource odczytuje pliki z katalogu, który serwer może zobaczyć.

Konktor, który strona próbuje najpierw

Analizator zapisuje wyniki do folderu. System rozliczeniowy upuszcza partię w nocy. Radiologia eksportuje raporty do katalogu, który ktoś zamontował lata temu. Żadne z nich nie wymaga protokołu, a silnik integracyjny, który nie może odczytać folderu, nie przejdzie oceny w pierwszym popołudniu.

Zdefiniowane jako FileSource w internal/config.

KluczTypWymaganyDomyślny
rootteksttak—
follow_symlinkstrue or falsenie—

22.12.1 korzeń

Korzeń ogranicza każdą ścieżkę, którą ten źródło dotyka.

Required.

Oddzielnie od Dir, aby move_to i error_dir mogły być względne i nadal zawarte. Podany tylko Dir, error_dir „../failed” byłby poza wszystkim, co źródło zostało udzielone, i odmowa byłaby arbitralna, ponieważ nie byłoby nic do odmowy.

22.13 Źródło GCS

GCSSource pobiera obiekty z prefiksu kosza, jak źródła s3 i azure_blob.

Definiowany jako GCSSource w internal/config.

KluczTypWymaganyDomyślny
prefixteksttak—
suffixtekstnie—
after_readtekstnie—
move_totekstnieprocessed/
error_prefixtekstnieerror/
poll_intervalczas trwania, np. 30s lub 5mnie30s
max_object_sizeliczba całkowitanie16 MiB
framedtrue lub falsenie—

22.13.1 move_to

MoveTo to miejsce, gdzie trafia obiekt po przetworzeniu, gdy after_read jest ustawiony na move.

Domyślnie ustawiony na processed/.

22.13.2 error_prefix

ErrorPrefix to miejsce, gdzie trafia obiekt, który nie mógł być przetworzony.

Domyślnie ustawiony na error/.

22.13.3 poll_interval

PollInterval to częstotliwość, z jaką prefix jest wyświetlany.

Defaults to 30s.

22.13.4 max_object_size

MaxObjectSize pozostawia większe obiekty w ich miejscu.

Domyślnie ustawiony na 16 MiB.

22.14 Źródło HTTP

Źródło HTTP akceptuje wiadomości za pośrednictwem HTTP.

Jest to słuchacz, a nie sondowanie: coś wysyła wiadomość i otrzymuje potwierdzenie zwrotne, co jest sposobem, w jaki nowoczesna połowa szpitala integruje się, gdy MLLP nie jest dostępny.

Definiowany jako HTTPSource w internal/config.

KluczTypWymaganyDomyślny
listenteksttak—
pathtekstnie"/"
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—
tokentekstnie—
max_message_sizecała liczbanie—
read_timeoutczas trwania, np. 30s lub 5mnie—
ackAcknie—

22.14.1 listen

Listen to jest adresem, na którym ma być obsługiwany.

Required.

22.14.2 path

Ścieżka to URL, na którym akceptowane są wiadomości.

Defaults to "/".

22.14.3 token

Token, gdy jest ustawiony, jest wymagany w nagłówku Authorization: Bearer.

Nie ma domyślnego ustawienia i przełącznika trybu anonimowego: punkt końcowy HTTP w sieci szpitala bez uwierzytelniania jest decyzją, która musi być widoczna w pliku, więc pozostawienie tego pustego jest zgłaszane jako ostrzeżenie podczas ładowania.

22.14.4 max_message_size

MaxMessageSize ogranicza treść wiadomości przychodzącej.

Zero stosuje wartość domyślną.

22.15 Źródło IBMMQ

Źródło IBMMQ odczytuje kolejkę.

Definiowany jako IBMMQSource w internal/config.

KluczTypWymaganyDomyślny
poll_intervalczas trwania, np. 30s lub 5mnie2s

22.15.1 poll_interval

PollInterval to czas oczekiwania, gdy kolejka jest pusta lub po wiadomości, która nie mogła być przetworzona.

Defaults to 2s.

22.16 Źródło JavaScript

Źródło JavaScript konfiguruje źródło, które uruchamia skrypt na timerze i podaje zwrócone wiadomości do kanału.

Jest to odpowiednik Mirth "JavaScript Reader".

Skrypt jest uruchamiany w maszynie wirtualnej goja z tym samym piaskownikiem, co skrypty transformatory: msg nie jest dostępny (nie ma jeszcze wiadomości przychodzącej), ale globalMap, configurationMap, logger i DateUtil są obecne. Skrypt musi zwrócić ciąg znaków (jedną wiadomość) lub tablicę ciągów znaków (wiele). Zwrócenie niczego lub pusta tablica oznacza, że sondowanie nie wyprodukowało wiadomości, co jest normalne.

Definiowany jako JavaScriptSource w internal/config.

KluczTypWymaganyDomyślny
scriptteksttak—
poll_intervalczas trwania, np. 30s lub 5mnie—
timeoutczas trwania, np. 30s lub 5mnie—

22.16.1 poll_interval

PollInterval określa, jak często skrypt jest uruchamiany.

Zero oznacza 5 sekund.

22.16.2 limit czasu

Timeout ogranicza pojedyncze wykonanie skryptu.

Zero oznacza 30 sekund.

22.17 Źródło Kafka

KafkaSource odczytuje wiadomości z tematu Kafka.

Zdefiniowane jako KafkaSource w internal/config.

KluczTypWymaganyDomyślny
brokerslista tekstutak—
topicslista tekstutak—
groupteksttak—
from_beginningtrue lub falsenie—
commit_after_deliverytrue lub false (blok, pomijaj, aby pominąć)nie—
max_message_sizeliczba całkowitanielimit kanału
session_timeoutczas trwania, np. 30s lub 5mnieczterdzieści pięć sekund
timeoutczas trwania, np. 30s lub 5mnietrzydzieści sekund
saslKafkaSASL (blok, pomijaj, aby pominąć)nie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—

22.17.1 brokers

Brokers to lista serwerów startowych.

Required.

Jest to lista, a nie jeden adres, ponieważ pojedynczy serwer startowy jest jednym punktem awarii podczas uruchamiania: klaster przetrwa utratę go, a ten kanał by nie.

22.17.2 topics

Topics to tematy do odczytu.

Wymagane jest co najmniej jedno.

22.17.3 grupa

Group to grupa konsumentów.

Required.

Nazwana, a nie wygenerowana, i wymagana, a nie domyślna, ponieważ jest to to, co pamięta, jak daleko ten kanał odczytał. Wygenerowana grupa zaczynała by od początku - lub od końca, tracąc wszystko - przy każdym ponownym uruchomieniu, i pozostawiłaby starej grupie zastrzeżone offsety, których nikt by nie odczytał. Wymaganie jej sprawia, że osoba nazywa rzecz, która musi pozostać taka sama w trakcie ponownych uruchomień.

22.17.4 from_beginning

FromBeginning odczytuje temat od jego początku, gdy grupa nie ma zastrzeżonego offsetu.

Wyłączone domyślnie, aby nowy kanał wskazujący na temat z dwuletnią historią nie odtwarzał dwóch lat zdarzeń pacjentów w systemie na żywo w dniu, w którym został włączony. Pierwsza osoba, która to zrobi, robiłaby to w produkcji, ponieważ tam jest temat z historią.

22.17.5 commit_after_delivery

CommitAfterDelivery zatwierdza offset tylko po tym, jak wiadomość została obsłużona.

Włączone domyślnie, a powodem jest cała różnica między utratą wiadomości a zobaczeniem jej dwa razy. Zatwierdzanie po odczycie oznacza, że awaria między zatwierdzeniem a dostarczeniem powoduje cichą utratę wiadomości, i nic gdziekolwiek nie rejestruje, że istniała. Zatwierdzanie po dostarczeniu oznacza, że awaria w tym samym oknie ponownie dostarcza ją, co jest widoczne i co odbiorniki HL7 są zaprojektowane do tolerowania - duplikat A08 to niedogodność, a brakujący wynik laboratoryjny to zdarzenie związane z bezpieczeństwem pacjenta.

22.17.6 max_message_size

MaxMessageSize ogranicza jeden rekord.

Domyślnie jest to limit kanału.

22.17.7 limit_czasu_sesji

LimitCzasuSesji określa, jak długo koordynator grupy czeka, zanim założy, że ten konsument jest nieobecny i ponownie przydzieli jego partycje.

Domyślnie wynosi czterdzieści pięć sekund.

22.17.8 limit czasu

Limit czasu łączenia i żądań metadanych.

Domyślnie jest to trzydzieści sekund.

22.18 Źródło MQTT

MQTTSource subskrybuje filtr tematu.

Zdefiniowane jako MQTTSource w internal/config.

KluczTypWymaganyDomyślny
topicteksttak—
reconnectczas trwania, np. 30s lub 5mnie5s

22.18.1 reconnect

Ponowne łączenie to oczekiwanie po utracie połączenia lub po wiadomości, która nie mogła być obsłużona.

Defaults to 5s.

22.19 Źródło Pub Sub

PubSubSource ściąga z subskrypcji Pub/Sub.

Zdefiniowane jako PubSubSource w internal/config.

KluczTypWymaganyDomyślny
subscriptionteksttak—
max_messagesliczba całkowitanie10
reconnectczas trwania, np. 30s lub 5mnie5s

22.19.1 maksymalna_liczba_wiadomości

MaksymalnaLiczbaWiadomości określa, ile wiadomości jest ściąganych na raz.

Nadal są one obsługiwane pojedynczo, w kolejności. Domyślnie wynosi 10.

22.19.2 reconnect

Ponowne łączenie to oczekiwanie po błędzie.

Defaults to 5s.

22.20 Źródło S3

S3Source pobiera obiekty z kosza.

Zdefiniowane jako S3Source w internal/config.

KluczTypWymaganyDomyślny
bucketteksttak—
path_styleprawda lub fałsznie—
prefixtekstnie—
suffixtekstnie—
after_readtekstnie—
move_totekstnieprocessed/
error_prefixtekstnieerror/
poll_intervalczas trwania, np. 30s lub 5mnie30s
max_object_sizeliczba całkowitanie16 MiB
framedprawda lub fałsznie—

22.20.1 prefiks

Prefiks ogranicza, które obiekty są odczytywane, np. przychodzące/.

Pusty odczyt całego kosza jest odrzucany z po_odbiorze: przenieść, chyba że przenieść_do jest poza nim - w przeciwnym razie przeniesione obiekty byłyby odczytywane ponownie.

22.20.2 po_odbiorze

AfterRead jest przeniesienie (domyślnie) lub usunięcie.

Nie ma pozostawienia: wiadro nie ma pliku, który poller mógłby zapamiętać po ponownym uruchomieniu, więc pozostawienie obiektów oznacza odczytywanie ich wszystkich ponownie za każdym razem, gdy Perfuse jest uruchamiany.

22.20.3 move_to

MoveTo jest prefiksem, do którego przenoszony jest obiekt, który został obsłużony.

Domyślnie ustawiony na processed/.

22.20.4 error_prefix

ErrorPrefix to miejsce, do którego przenoszony jest obiekt, który nie mógł być obsłużony, aby jeden złej plik nie blokował reszty.

Domyślnie ustawiony na error/.

22.20.5 poll_interval

PollInterval między listami.

Defaults to 30s.

22.20.6 max_object_size

MaxObjectSize odrzuca wszystko, co jest większe.

Domyślnie ustawiony na 16 MiB.

22.20.7 ramiona

Framed odczytuje kilka komunikatów MLLP z jednego obiektu.

W przeciwnym razie obiekt jest jedną wiadomością.

22.21 Źródło SFTP

SFTPSource zbiera wiadomości z katalogu na serwerze SFTP.

Bardzo powszechne i rzadko omawiane. System laboratoryjny lub radiologiczny zapisuje plik co kilka minut, serwer SFTP go przechowuje, a coś musi przyjść i go pobrać. Połowa kanałów opisanych jako "wysyłamy do ciebie HL7" jest tym.

Część, o którą warto dbać, nie jest transferem. Jest to fakt, że plik, który jest zapisywany, i plik, który został zakończony, wyglądają identycznie za pośrednictwem SFTP, więc poll, który jest nawet nieznacznie zbyt gorliwy, zbiera połowę wiadomości. To powoduje, że wiadomość HL7 jest obcięta, ale często nadal możliwa do sparsowania, co jest najgorszym możliwym wynikiem: jest akceptowana, potwierdzana, przechowywana i dostarczana, a brakująca połowa nigdy nie jest wspominana ponownie.

Zdefiniowane jako SFTPSource w internal/config.

KluczTypWymaganyDomyślny
hostteksttak22
userteksttak—
passwordtekstnie—
key_filetekstnie—
key_passphrasetekstnie—
known_hosts_filetekstnie—
insecure_skip_host_key_checkprawda lub fałsznie—
dirteksttak—
patterntekstniewszystko
poll_intervalczas trwania, np. 30s lub 5mnie—
after_readtekstnie—
move_totekstnie—
error_dirtekstnie—
stable_forczas trwania, np. 30s lub 5mnie5s
framedprawda lub fałsznie—
max_file_sizecała liczbanie64MB
timeoutczas trwania, np. 30s lub 5mnie60s

22.21.1 host

Host to serwer, z opcjonalnym portem.

Defaults to 22.

22.21.2 hasło

Hasło uwierzytelnia się za pomocą hasła.

Prefer KeyFile.

22.21.3 plik_klucza

PlikKlucza to klucz prywatny.

Lepszy wybór, a także ten, o który proszą zespoły bezpieczeństwa szpitali.

22.21.4 plik_znanych_hostów

PlikZnanychHostów weryfikuje tożsamość serwera.

Wymagany, chyba że ustawiono InsecureSkipHostKeyCheck. Bez niego nie ma nic, co mogłoby odróżnić prawdziwy serwer od czegokolwiek, co odpowiada na ten adres, a poświadczenia są przekazywane przed zauważeniem.

22.21.5 pomijanie_weryfikacji_klucza_hosta

InsecureSkipHostKeyCheck akceptuje dowolny klucz hosta.

Istnieje, ponieważ odrzucenie go na początku powoduje, że ludzie idą do skryptu powłoki z StrictHostKeyChecking=no, co jest gorsze we wszystkich aspektach, w tym audytowalności. Ostrzega głośno i nigdy nie jest domyślnym ustawieniem.

22.21.6 wzorzec

Wzorzec wybiera pliki według wzorca glob.

Domyślnie wybiera wszystko.

22.21.7 move_to

MoveTo to katalog zdalny, do którego pliki są przenoszone po odczycie.

Wymagane, gdy AfterRead jest ustawiony na "move".

22.21.8 stabilny_dla

StableFor określa, jak długo rozmiar i czas modyfikacji pliku muszą pozostawać niezmienione, zanim plik zostanie odczytany.

Defaults to 5s.

To ustawienie zapobiega odczytywaniu połowy wiadomości. Zero oznacza odczytywanie wszystkiego, co jest dostępne, co działa poprawnie, dopóki plik nie jest wystarczająco duży lub sieć nie jest wystarczająco wolna, aby zapisywanie trwało dłużej niż poll.

22.21.9 ramiona

Framed oznacza, że plik zawiera wiadomości sformatowane w MLLP.

Gdy jest ustawiony na false, plik jest dzielony na granice MSH.

22.21.10 maksymalny_rozmiar_pliku

MaxFileSize odmawia odczytu pliku większego niż określona liczba bajtów.

Domyślnie 64MB.

22.21.11 limit czasu

Limit czasu określa pojedyncze połączenie.

Defaults to 60s.

22.22 Źródło SMB

SMBSource zbiera pliki z udziału plików systemu Windows.

Zdefiniowane jako SMBSource w internal/config.

KluczTypWymaganyDomyślny
hostteksttak—
shareteksttak—
usertekstnie—
passwordtekstnie—
domaintekstnie—
roottekstnie—
timeoutczas trwania, np. 30s lub 5mnietrzydzieści sekund

22.22.1 host

Host to serwer, z opcjonalnym portem.

Założono port 445.

22.22.2 udział

Udział to nazwa udziału tylko: „dane” w \\server\dane.

Ścieżka tutaj jest odrzucana, a nie obcinana.

22.22.3 użytkownik

Użyty i Hasło to konto systemu Windows.

Wymagane w praktyce.

Udział, do którego można uzyskać dostęp bez podawania poświadczeń, jest na tyle rzadki w domenie, że pusty użytkownik tutaj jest o wiele bardziej prawdopodobnym błędem niż udział gościnny - ale jest akceptowany, ponieważ odrzucenie go zablokuje jedną konfigurację, w której jest poprawny. Gdy konto należy do domeny, ustaw również Domenę: uwierzytelnianie konta domeny bez niej kończy się niepowodzeniem w sposób, który wygląda jak błędne hasło.

22.22.4 hasło

Użyty i Hasło to konto systemu Windows.

Wymagane w praktyce.

Udział, do którego można uzyskać dostęp bez podawania poświadczeń, jest na tyle rzadki w domenie, że pusty użytkownik tutaj jest o wiele bardziej prawdopodobnym błędem niż udział gościnny - ale jest akceptowany, ponieważ odrzucenie go zablokuje jedną konfigurację, w której jest poprawny. Gdy konto należy do domeny, ustaw również Domenę: uwierzytelnianie konta domeny bez niej kończy się niepowodzeniem w sposób, który wygląda jak błędne hasło.

22.22.5 domeyna

Domena jest to domena Windows lub grupa robocza.

Pusty jest zwykle odpowiedni dla konta lokalnego.

22.22.6 limit czasu

Limit czasu ogranicza jedną operację.

Domyślnie jest to trzydzieści sekund.

Warto podnieść w przypadku udziału w sieci rozciągniętej na link między witrynami. Operacja SMB na odległym serwerze jest wolniejsza niż ta sama operacja lokalna o wystarczająco, aby domyślny limit czasu dostosowany do sieci LAN powodował czasem limitu, który wygląda jak niedostępny udział.

22.23 Źródło SOAP

SOAPSource akceptuje wiadomości zawinięte w kopercie SOAP.

Odpowiednik miejsca przeznaczenia SOAP, a rzadszy kierunek: większość integracji szpitalnej ma Perfuse wywołujące usługę, a nie odwrotnie. Istnieje, ponieważ Web Service Listener Mirth również istnieje, a witryna, której system wysyłający mówi tylko SOAP, nie może się przenieść bez niego.

Celowo nie jest to ogólny framework usług internetowych. Akceptuje kopertę, wyjmuje wiadomość z niej i odpowiada kopertą. Nie ma WS-Security, MTOM, WS-Addressing i wygenerowanych powiązań - te same pominięcia co w miejscu przeznaczenia, z tego samego powodu: półimplementacja WS-Security jest gorsza niż brak.

Zdefiniowane jako SOAPSource w internal/config.

KluczTypWymaganyDomyślny
listenteksttak—
profiletekstnie—
pathtekstnie"/"
versiontekstnie1
elementtekstnie—
base64true lub falsenie—
response_elementtekstnie"AckResponse"
response_namespacetekstnie—
wsdltekstnie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—
tokentekstnie—
usernametekstnie—
passwordtekstnie—
max_message_sizecała liczbanie—
read_timeoutczas trwania, np. 30s lub 5mnie—
ackAcknie—
fault_on_naktrue lub falsenie—

22.23.1 listen

Listen to jest adresem, na którym ma być obsługiwany.

Required.

22.23.2 profil

Nazwa profilu wskazuje standardową usługę, którą ten punkt końcowy implementuje.

Pusty akceptuje dowolną kopertę, tak jak skonfigurowano poniżej.

"cdc-iis" odpowiada jak rejestry szczepień, na interfejsie CDC (urn:cdc:iisb:2011): connectivityTest jest powtarzany, submitSingleMessage's hl7Message jest wiadomością, a potwierdzenie kanału jest zwracane w odpowiedzi, a WSDL jest obsługiwany w ?wsdl, a nazwa użytkownika i hasło, gdy są ustawione, są sprawdzane w stosunku do tych w treści (gdzie WSDL je umieszcza) zamiast w stosunku do uwierzytelniania HTTP. Dla testowego dublera rejestru lub dla witryny, która otrzymuje zgłoszenia w sposób, w jaki robią to rejestry.

22.23.3 path

Ścieżka jest ścieżką URL, na której akceptowane są koperty.

Defaults to "/".

22.23.4 wersja

Wersja jest wersją SOAP, w której odpowiedź jest wysyłana, „1.1” lub „1.2”.

Defaults to 1.1.

Żądania są akceptowane w obu wersjach, ponieważ nadawca, który popełnia błąd w tym, jest powszechny i odrzucenie go nie nauczy nikogo niczego. Ustawienie kontroluje odpowiedź, gdzie popełnienie błędu oznacza, że nadawca nie może odczytać odpowiedzi.

22.23.5 element

Nazwa elementu wskazuje element wewnątrz treści SOAP, który zawiera wiadomość.

Pusty oznacza cały tekst treści.

Nazwany zamiast zgadywany, ponieważ treść może zawierać kilka elementów - wiadomość obok identyfikatora nadawcy i znacznika czasu - i pobranie całej treści spowodowałoby, że silnik otrzymałby fragment XML, gdzie oczekiwał HL7.

22.23.6 base64

Base64 dekoduje zawartość elementu przed potraktowaniem jej jako wiadomości.

Powszechny w rzeczywistych usługach, ponieważ HL7 zawiera znaki powrotu karetki i nadawcy, którzy nie myśleli o tym, kończą się XML, który je uszkadza. Jeśli zawartość dekoduje jako base64, ale nie była przeznaczona do tego, wynik nie jest wiadomością, a silnik tak mówi - dlatego jest to jawne, a nie wyczuwane.

22.23.7 element odpowiedzi

ResponseElement nazwę elementu, który zawija potwierdzenie w odpowiedzi.

Domyślnie jest to "AckResponse".

22.23.8 wsdl

WSDL to plik podawany w słuchanym miejscu z ?wsdl.

Pusty oznacza, że nie jest obsługiwany.

Plik zamiast czegoś wygenerowanego. Wygenerowany WSDL opisywałby to, co ten punkt końcowy akceptuje, co jest prawie nigdy tym, przeciwko czemu system wysyłający został zbudowany - a WSDL, który jest prawie poprawny, kosztuje więcej czasu niż brak WSDL w ogóle, ponieważ wygląda na autorytatywny.

22.23.9 nazwa użytkownika

Nazwa użytkownika i hasło, gdy są ustawione, wymagają uwierzytelniania HTTP podstawowego.

Zaoferowane obok tokenu, ponieważ nadawcy SOAP oczekują przeważnie uwierzytelniania podstawowego, a witryna, której system wysyłający nie może być zmieniony, potrzebuje opcji, której już używa.

22.23.10 hasło

Nazwa użytkownika i hasło, gdy są ustawione, wymagają uwierzytelniania HTTP podstawowego.

Zaoferowane obok tokenu, ponieważ nadawcy SOAP oczekują przeważnie uwierzytelniania podstawowego, a witryna, której system wysyłający nie może być zmieniony, potrzebuje opcji, której już używa.

22.23.11 max_message_size

MaxMessageSize ogranicza treść wiadomości przychodzącej.

Zero stosuje wartość domyślną.

22.23.12 błąd_na_nak

FaultOnNak odpowiada negatywne potwierdzenie błędem SOAP zamiast normalną odpowiedzią zawierającą NAK.

Wyłączone domyślnie, co jest właściwą domyślną wartością i wartą wyjaśnienia. HL7 już ma sposób, aby powiedzieć „Otrzymałem to i odrzuciłem”, a jest to NAK - udana wymiana zgłaszająca odrzuconą wiadomość. Zamiana tego samego w błąd transportu mówi nadawcy, że jego żądanie było nieprawidłowe, co nie jest prawdą, a wiele klientów odpowiada przez ponowne próby bez końca.

Istnieje, ponieważ niektórzy nadawcy patrzą tylko na status HTTP i w przeciwnym razie traktowaliby odrzucenie jako sukces.

22.24 Źródło SQS

SQSSource odczytuje z kolejki SQS.

Wiadomość jest kasowana tylko po tym, jak kanał ją obsłużył - dostarczył, odfiltrował lub awaryjnie w sposób, w jaki kanał zapisuje. Do tego czasu pozostaje w kolejce, niewidoczna przez visibility_timeout, i wraca, jeśli Perfuse zostanie zatrzymany. Więc wiadomość nigdy nie ginie; cena jest taka, że może przyjść dwa razy, co sama SQS już zezwala.

Zdefiniowane jako SQSSource w internal/config.

KluczTypWymaganyDomyślny
queue_urlteksttak—
wait_secondscała liczbanie20: pusta kolejka kosztuje jeden żądanie co dwadzieścia sekund
max_messagescała liczbanie10
visibility_timeoutczas trwania, taki jak 30s lub 5mnieustawienie własne kolejki

22.24.1 visibility_timeout

VisibilityTimeout to czas, przez jaki odebrana wiadomość pozostaje ukryta, gdy jest przetwarzana.

Domyślnie jest to ustawienie własne kolejki.

22.25 Źródło szeregowego

SerialSource odczytuje wiadomości z portu szeregowego.

Dlaczego łącznik szeregowy w 2026

Ponieważ sprzęt jest nadal tam. Analizator gazowy krwi kupiony w 2009 roku z czujnikiem i gniazdem 25-pinowym, monitor łóżkowy, waga w jednostce dializy, starsza maszyna znieczulająca. Żaden z nich nie otrzyma portu Ethernet, kilka z nich kosztuje sześciocyfrową kwotę, a alternatywą dla odczytywania ich jest ktoś, kto wpisuje wyniki do formularza.

Mirth ma połączenie szeregowe. Perfuse nie miał nic, a strona z jednym z nich nie miała w ogóle trasy.

Ramowanie jest współdzielone z łączem TCP

Ramowanie jest takie samo, niezależnie od tego, skąd pochodzą bajty: analizer, który komunikuje się za pomocą STX/ETX przez gniazdo, komunikuje się również za pomocą STX/ETX przez kabel. Dlatego też ponownie wykorzystuje bloku ramowania TCP zamiast definiować własne, co oznacza również, że urządzenie przeniesione z kabla szeregowego do adaptera szeregowo-Ethernet zachowuje swoją konfigurację ramowania.

Co różni się w przypadku linii szeregowej

Nie ma połączenia. Gniazdo informuje, kiedy peer się rozłączył; kabel nie. Odłączony kabel, wyłączone urządzenie i urządzenie, które nie ma nic do powiedzenia, są nierozróżnialne - wszystkie trzy to cisza. Dlatego też istnieje quiet_after: bez czegoś, co mówi „ten kabel był cichy przez dłużej, niż powinien”, martwy kanał wygląda dokładnie jak cicha noc.

Zdefiniowane jako SerialSource w internal/config.

KluczTypWymaganyDomyślny
portteksttak—
baudliczba całkowitatak—
data_bitsliczba całkowitanie8
paritytekstnienone
stop_bitstekstnie1
flow_controltekstnienone
max_message_sizeliczba całkowitanie—
quiet_afterczas trwania, np. 30s lub 5mnie—
replytekstnie—
reply_texttekstnie—
reopen_afterczas trwania, np. 30s lub 5mnie—

22.25.1 baud

Baud to prędkość.

Wymagany, ponieważ zgadywanie produkuje bajty zamiast błędu.

Błędna prędkość baud nie powoduje błędu. Dostarcza wiarygodnie wyglądający śmieć: bajty ramowania pojawiają się losowo, okazjonalne serie kodują się jako znaki drukowalne, a parser zezwalający na pewne błędy akceptuje część z nich. Nie ma domyślnej prędkości baud.

22.25.2 parity

Parity to none, odd, even, mark lub space.

Domyślnie ustawiony na none.

22.25.3 stop_bits

StopBits to 1, 1,5 lub 2, zapisywane jako „1”, „1,5” lub „2”.

Defaults to 1.

22.25.4 flow_control

FlowControl to none, hardware lub software.

Domyślnie ustawiony na none.

Warto ustawić poprawnie, zamiast pozostawić domyślny. Z oczekiwanym kontrolą sprzętową, ale niezkonfigurowaną, urządzenie przestaje wysyłać w połowie długiego komunikatu, a wynikiem jest komunikat obcięty zamiast błędu.

22.25.5 quiet_after

QuietAfter rejestruje ostrzeżenie, kiedy nic nie zostało odebrane przez ten czas.

Jedyny sposób, aby zauważyć martwy kanał szeregowy. Odłączony kabel i cicha noc są tą samą ciszą, więc ktoś musi powiedzieć, jak długo jest za długo dla tego urządzenia.

22.25.6 reopen_after

ReopenAfter to czas, jaki należy czekać, zanim ponownie otworzy się port, który nie powiódł się.

Adapter szeregowy USB odłączony i ponownie podłączony pojawia się jako ten sam ścieżka urządzenia, ale inny uchwyt jądra, więc stary zwraca błędy na zawsze. Ponowne otwarcie jest jedynym odzyskiwaniem, a robienie tego w pętli wypełnia log.

22.26 Źródło

Źródło to miejsce, w którym kanał otrzymuje wiadomości.

Zdefiniowane jako Source w internal/config.

KluczTypWymaganyDomyślny
typeSourceTypetak—
listenteksttak—
max_message_sizeliczba całkowitanie—
idle_timeoutczas trwania, np. 30s lub 5mnie—
max_connectionsliczba całkowitanie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—
httpHTTPSource (blok, pomijaj, aby pominąć)nie—
soapSOAPSource (blok, pomijaj, aby pominąć)nie—
dicomwebDICOMwebSource (blok, pomijaj, aby pominąć)nie—
directDirectSource (blok, pomijaj, aby pominąć)nie—
dicomDICOMSource (blok, pomijaj, aby pominąć)nie—
fileFileSource (blok, pomijaj, aby pominąć)nie—
tcpTCPSource (blok, pomijaj, aby pominąć)nie—
ftpFTPSource (blok, pomijaj, aby pominąć)nie—
smbSMBSource (blok, pomijaj, aby pominąć)nie—
webdavWebDAVSource (blok, pomijaj, aby pominąć)nie—
serialSerialSource (blok, pomijaj, aby pominąć)nie—
dicom_queryDICOMQuerySource (blok, pomijaj, aby pominąć)nie—
brokerBrokerSource (blok, pomijaj, aby pominąć)nie—
kafkaKafkaSource (blok, pomijaj, aby pominąć)nie—
sqsSQSSource (blok, pomijaj, aby pominąć)nie—
s3S3Source (blok, pomijaj, aby pominąć)nie—
amqpAMQPSource (blok, pomijaj, aby pominąć)nie—
azure_blobAzureBlobSource (blok, pomijaj, aby pominąć)nie—
emailEmailSource (blok, pomijaj, aby pominąć)nie—
as2AS2Source (blok, pomijaj, aby pominąć)nie—
pgpPGPReceive (blok, pomijaj, aby pominąć)nie—
mqttMQTTSource (blok, pomijaj, aby pominąć)nie—
ibm_mqIBMMQSource (blok, pomijaj, aby pominąć)nie—
pubsubPubSubSource (blok, pomijaj, aby pominąć)nie—
gcsGCSSource (blok, pomijaj, aby pominąć)nie—
databaseDatabaseSource (blok, pomijaj, aby pominąć)nie—
sftpSFTPSource (blok, pomijaj, aby pominąć)nie—
javascriptJavaScriptSource (blok, pomijaj, aby pominąć)nie—
ackAcknie—

22.26.1 typ

Typ to transport.

Zaimplementowano tylko mllp.

22.26.2 max_message_size

MaxMessageSize ogranicza jedną wiadomość przychodzącą.

Zero używa domyślnego ustawienia transportu.

22.26.3 idle_timeout

IdleTimeout zamyka połączenie, które było ciche przez ten czas.

Zero oznacza nigdy, co jest zwykle słuszne: kanał szpitalny utrzymuje połączenie otwarte przez miesiące i milknie w nocy.

22.26.4 max_connections

MaxConnections ogranicza jednoczesne połączenia.

Zero oznacza brak ograniczeń.

22.27 Źródło TCP

TCPSource nasłuchuje na gnieździe wiadomości, które niekoniecznie są HL7.

Dlaczego jest to oddzielne od źródła mllp

MLLP to jeden rodzaj ramki, a Perfuse zawsze mówił w tym języku. Dużo sprzętu nie robi tego: analizator laboratoryjny, waga, monitor łóżkowy, starszy system rozliczeniowy. Każdy z nich ma swoją własną konwencję, a łącznik TCP Mirth pokrywa wszystkie z nich, więc strona z kanałem gniazda, który nie był HL7, nie mogła używać Perfuse w ogóle.

Zdefiniowane jako TCPSource w internal/config.

KluczTypWymaganyDomyślny
listenteksttak—
max_message_sizeliczba całkowitanie—
idle_timeoutczas trwania, np. 30s lub 5mnie—
max_connectionsliczba całkowitanie—
replytekstnie—
reply_texttekstnie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—

22.27.1 idle_timeout

IdleTimeout zamyka połączenie, które było ciche przez ten czas.

Zero oznacza nigdy, co jest zwykle słuszne: kanał urządzenia utrzymuje połączenie otwarte przez miesiące i milknie w nocy.

22.27.2 max_connections

MaxConnections ogranicza jednoczesne połączenia.

Zero oznacza brak ograniczeń.

22.27.3 odpowiedź

Odpowiedź to to, co wysyłać po każdej wiadomości: nic, ack lub stały ciąg.

Większość surowych kanałów oczekuje niczego. Niektóre oczekują jednego bajtu ACK. Urządzenie, które oczekuje odpowiedzi i nie otrzymuje jej, zwykle ponawia tę samą wiadomość na zawsze, więc warto być wyraźnym w tej kwestii.

22.28 Źródło Web DAV

WebDAVSource gromadzi pliki z kolekcji WebDAV.

Pojawia się w systemach zarządzania dokumentami, SharePoint, Nextcloud i portalach dostawców, które udostępniają folder przekazywania plików za pośrednictwem HTTPS, ponieważ jest to jedyny port wychodzący, który jest dozwolony przez firewalle ich klientów.

Zdefiniowany jako WebDAVSource w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
usertekstnie—
passwordtekstnie—
insecure_skip_verifyprawda lub fałsznie—
timeoutczas trwania, np. 30s lub 5mniesześćdziesiąt sekund

22.28.1 użytkownik

Użytkownik i hasło uwierzytelniają się za pomocą podstawowej autoryzacji HTTP.

Podstawowa autoryzacja wysyła hasło w nagłówku, który jest chroniony tylko przez TLS, więc powinny one być używane z adresem URL https. Przy użyciu http są one czytelne dla wszystkiego na ścieżce, a serwer nie wyśle żadnego ostrzeżenia.

22.28.2 hasło

Użytkownik i hasło uwierzytelniają się za pomocą podstawowej autoryzacji HTTP.

Podstawowa autoryzacja wysyła hasło w nagłówku, który jest chroniony tylko przez TLS, więc powinny one być używane z adresem URL https. Przy użyciu http są one czytelne dla wszystkiego na ścieżce, a serwer nie wyśle żadnego ostrzeżenia.

22.28.3 limit czasu

Limit czasu ogranicza jeden żądanie.

Domyślnie wynosi sześćdziesiąt sekund.

Dłużej niż domyślne ustawienia dla FTP i SMB, celowo. Lista kolekcji WebDAV jest jednym żądaniem PROPFIND, które serwer może długo przygotowywać dla dużego katalogu, i nie ma częściowego wyniku, na który można by się oprzeć.

23 Odwołanie do miejsca docelowego

Każy sposób, w jaki kanał może wysyłać wiadomości, oraz każdy klucz, który każdy z nich akceptuje. Kanał może mieć dowolną liczbę miejsc docelowych, i są one niezależne: awaria jednego z nich nie powoduje awarii innych.

23.1 Miejsce docelowe AMQP

AMQPDestination wysyła do kolejki lub tematu i zgłasza powodzenie tylko wtedy, gdy broker zaakceptował wiadomość.

Zdefiniowany jako AMQPDestination w internal/config.

KluczTypWymaganyDomyślny
content_typetekstnietyp danych kanału

23.1.1 content_type

ContentType jest wysyłany z każdą wiadomością.

Domyślnie jest to typ danych kanału.

23.2 Miejsce docelowe AS2

AS2Destination wysyła każdą wiadomość jako AS2: podpisane naszym kluczem, zaszyfrowane do certyfikatu partnera, wysłane do adresu URL partnera i, domyślnie, dostarczane tylko wtedy, gdy podpisana potwierdzenie odbioru partnera nazwie ten sam skrót.

Zdefiniowany jako AS2Destination w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
fromteksttak—
toteksttak—
cert_filetekstnie—
key_filetekstnie—
partner_cert_filetekstnie—
unsignedtrue lub falsenie—
unencryptedtrue lub falsenie—
compresstrue lub falsenie—
receipttekstnie—
unsigned_receipttrue lub falsenie—
receipt_urltekstnie—
content_typetekstnie—
file_nametekstnie—
subjecttekstnie—
usernametekstnie—
passwordtekstnie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—

23.2.1 compress

Kompresja kompresuje ładunek (zlib, RFC 5402) przed podpisaniem i szyfrowaniem.

Każdy odbiorca AS2, który ogłasza wersję 1.1 lub nowszą, odczytuje ją; poproś partnera, zanim włączysz ją.

23.2.2 potwierdzenie_nieszyfrowane

UnsignedReceipt żąda potwierdzenia, które nie jest podpisywane.

Wyłączone: żąda się podpisanego potwierdzenia, a nieszyfrowanego odmawia się.

23.2.3 content_type

ContentType to typ MIME ładunku.

Domyślnie według typu danych kanału: application/edi-x12, application/edifact, application/hl7-v2, w przeciwnym razie application/octet-stream.

23.3 Cel magazynu obiektów Azure

AzureBlobDestination zapisuje każdą wiadomość jako blok obiektu.

Zdefiniowane jako AzureBlobDestination w internal/config.

KluczTypWymaganyDomyślny
blobtekstnie${date}/${channel}/${control_id}
tiertekstnie—
content_typetekstnie—

23.3.1 obiekt

Nazwa obiektu określa nazwę każdego obiektu, z placeholderami celu S3.

Domyślnie ${date}/${channel}/${control_id}.hl7.

23.3.2 poziom

Poziom to Hot, Cool, Cold lub Archive.

Archive jest offline: odczytanie obiektu oznacza jego ponowne hydratowanie, co zajmuje godziny.

23.4 Cel pośrednika

BrokerDestination publikuje wiadomości w pośredniku wiadomości.

Zapisywacz JMS Mirth.

Zdefiniowane jako BrokerDestination w internal/config.

KluczTypWymaganyDomyślny
addrteksttak—
destinationteksttak—
logintekstnie—
passcodetekstnie—
hosttekstniehost adresu
content_typetekstnietext/plain dla HL7
headersmapa tekstu do tekstunie—
persistenttrue lub false (blok, pomiń, aby pozostawić)nietrue
timeoutczas trwania, taki jak 30s lub 5mnie—
tlstlsconf.Ustawienia (blok, pomiń, aby pozostawić)nie—

23.4.1 addr

Adres to host i port brokera.

Required.

23.4.2 destination

Cel to kolejka lub temat, do którego publikuje się.

Required.

23.4.3 login

Login i Passcode uwierzytelniają.

Większość brokerów odmawia połączenia anonimowego.

23.4.4 passcode

Login i Passcode uwierzytelniają.

Większość brokerów odmawia połączenia anonimowego.

23.4.5 host

Host to host wirtualny.

Domyślnie jest to host adresu.

Warto jawnie ustawić na pośredniku, który hostuje wiele wirtualnych hostów, gdzie domyślny ląduje publikację na tym, który odpowiada na nazwę serwera - kolejka, która istnieje, akceptuje wiadomość i jest odczytywana przez nikogo.

23.4.6 content_type

ContentType jest wysyłany z każdą wiadomością.

Domyślnie text/plain dla HL7.

23.4.7 nagłówki

Nagłówki są wysyłane z każdą wiadomością.

Konfiguracja tylko, nigdy zawartość wiadomości. Nagłówek pobrany z pola umieściłby identyfikator pacjenta w metadanych brokera, które są rejestrowane, indeksowane i widoczne dla każdej innej aplikacji w kolejce.

23.4.8 trwały

Trwały prosi brokera o przetrwanie restartu.

Domyślnie ustawiony na true.

True, ponieważ nie-trwała wiadomość zostaje utracona podczas restartu brokera, a to nie jest rozsądnym domyślnym ustawieniem dla danych klinicznych. False istnieje dla prawdziwie przejściowego kanału - monitorującego pulsu - i musi być wybrany.

23.5 Miejsce docelowe CDA

CDADestination konfiguruje miejsce docelowe CDA: pobiera dokument kliniczny przenoszony wewnątrz wiadomości HL7 v2, konwertuje go i zapisuje lub publikuje wynik.

Istnieje to, ponieważ dokument prawie nigdy nie przychodzi sam. Przychodzi zakodowany w base64 wewnątrz MDM^T02, a każdy silnik, który traktuje tę wiadomość jako nieprzezroczystą bryłę, pozostawia dokument nieprzeczytany. Posiadanie obu końców tego jest celem.

Zdefiniowany jako CDADestination w internal/config.

KluczTypWymaganyDomyślny
urltekstnie—
dirtekstnie—
writetekstnie—
versiontekstnieR5
identifier_systemsmapa tekstu do tekstunie—
require_agreementtrue lub falsenie—
on_no_documenttekstnie—
headersmapa tekstu do tekstunie—
bearer_tokentekstnie—

23.5.1 url

URL to serwer FHIR, do którego zostanie opublikowany przekonwertowany pakiet.

Pozostaw to puste, aby zamiast tego zapisać do katalogu. Jeden z nich jest wymagany.

23.5.2 dir

Katalog zapisuje dane wyjściowe do plików zamiast publikować je.

Użyteczne dla strefy przyjmowania, którą inny proces pobiera, oraz do zobaczenia, co produkuje konwersja, zanim wskaże ją na żywy serwer.

23.5.3 write

Write wybiera, co zostanie zapisane lub opublikowane:

fhir przekonwertowany pakiet transakcji (domyślnie) dokument oryginalny dokument w postaci niezmienionych bajtów, oba oba, z dokumentem obok pakietu przenoszenie podsumowania przejścia opieki PACIO: jeden dokument FHIR R4 Bundle dla miejsca, do którego pacjent zostanie przeniesiony (dom opieki, jednostka rehabilitacyjna, opieka zdrowotna w domu), wysłany do url/Bundle lub zapisany w katalogu

"dokument" jest wart posiadania samodzielnie: strona, która chce mieć swoje CDA na dysku dla zespołu rejestrów, nie potrzebuje konwersji FHIR w ogóle.

23.5.4 identifier_systems

IdentifierSystems mapuje korzeń OID z dokumentu na URI, tak aby MRN stał się przestrzenią nazw.

CDA identyfikuje ludzi za pomocą OID, a FHIR za pomocą URI, i nic nie może wywnioskować jednego z drugiego.

23.5.5 require_agreement

RequireAgreement odmawia dokumentowi, którego narracja i wpisy zakodowane są sprzeczne ze sobą.

Wyłączone domyślnie i celowo. Sprawdzenie jest cenne, ale jest to ocena dokumentu napisanego przez kogoś innego, a kanał, który w milczeniu odrzuca prawdziwe dokumenty kliniczne, ponieważ generator C-CDA nadawcy jest niedbały, jest gorszy niż ten, który przechodzi je z ostrzeżeniem. Strona, która obejrzała swoje własne wyniki i zdecydowała, że chce bramkę, może ją włączyć.

23.5.6 on_no_document

OnNoDocument decyduje, co się dzieje, gdy wiadomość nie zawiera dokumentu klinicznego:

pomiń nie dostarczaj nic i zgłoś sukces (domyślnie) niepowodzenie potraktuj to jako niepowodzenie dostarczenia

Domyślnie jest to pomiń, ponieważ kanał przenoszący mieszaną paszę ADT i MDM inaczej nie powiedzie się przy każdym przyjęciu. Kanał dedykowany dokumentom powinien ustawić niepowodzenie, ponieważ wiadomość dokumentowa bez dokumentu w środku jest prawdziwym problemem po stronie nadawcy.

23.5.7 bearer_token

BearerToken jest wysyłany jako nagłówek Authorization.

Wolą jest odniesienie do zmiennej środowiskowej zamiast literalu w pliku, który trafia do git.

23.6 Docelowy kanał

ChannelDestination kieruje do innego kanału na tym samym serwerze.

Zdefiniowany jako ChannelDestination w internal/config.

KluczTypWymaganyDomyślny
nameteksttak—

23.7 Docelowy DICOM

DICOMDestination wysyła obiekty obrazowe jako użytkownik klasy usługi C-STORE.

Mirth nazywa to nadawcą DICOM.

Zdefiniowany jako DICOMDestination w internal/config.

KluczTypWymaganyDomyślny
addressteksttak—
called_aetekstnie—
calling_aetekstnie—
transfer_syntaxeslista tekstównie—
timeoutczas trwania, np. 30s lub 5mnie—
tlstlsconf.Settings (blok, pomijaj, aby wyłączyć)nie—

23.7.1 adres

Adres to zdalny host i port.

Required.

23.7.2 called_ae

CalledAE to to, jak zdalny siebie nazywa, a CallingAE to to, jak siebie nazywa ten koniec.

Oba są ważne. Strony konfigurują PACS do akceptowania jednego określonego tytułu wywołującego i odrzucania wszystkiego innego, więc niezgodność jest najczęstszym powodem, dla którego pierwsze połączenie nie powiedzie się - i niepowodzenie wygląda jak problem sieciowy.

23.7.3 calling_ae

CalledAE to to, jak zdalny siebie nazywa, a CallingAE to to, jak siebie nazywa ten koniec.

Oba są ważne. Strony konfigurują PACS do akceptowania jednego określonego tytułu wywołującego i odrzucania wszystkiego innego, więc niezgodność jest najczęstszym powodem, dla którego pierwsze połączenie nie powiedzie się - i niepowodzenie wygląda jak problem sieciowy.

23.7.4 transfer_syntaxes

TransferSyntaxes ogranicza to, co się oferuje, w preferowanym porządku.

Pusty oferuje własną kodowanie obiektu, a następnie niejawne VR little endian jako zapasowe.

23.7.5 limit czasu

Timeout ogranicza jedną operację przechowywania.

Zero stosuje wartość domyślną.

23.8 DICO Mweb Destination

DICOMwebDestination przechowuje każdy obiekt za pomocą STOW-RS.

Zdefiniowane jako DICOMwebDestination w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
tokentekstnie—
usernametekstnie—
passwordtekstnie—
headersmapa tekstu do tekstunie—
tlstlsconf.Settings (blok, pomijaj, aby wyłączyć)nie—
timeoutczas trwania, np. 30s lub 5mnie—

23.9 Miejsce docelowe bazy danych

DatabaseDestination zapisuje każdą wiadomość w bazie danych.

Zdefiniowane jako DatabaseDestination w internal/config.

KluczTypWymaganyDomyślny
driverteksttak—
dsnteksttak—
statementteksttak—
paramslista tekstunie—
timeoutczas trwania, np. 30s lub 5mnie30s
max_open_connsliczba całkowitanie4

23.9.1 sterownik

Sterownik określa nazwę bazy danych.

See SupportedDrivers.

23.9.2 instrukcja

Instrukcja jest wykonywana raz na wiadomość, z Paramami powiązanymi z nią w kolejności.

Zastępniki są własne dla sterownika: $1 dla postgres, ? dla mysql i sqlite, @p1 dla sqlserver. Perfuse nie przebudowuje ich, ponieważ warstwa tłumacząca, która źle zinterpretuje zastępnik, powiąże nazwę pacjenta z niewłaściwą kolumną i wynik będzie wyglądał jak prawidłowe dane.

23.9.3 parametry

Parametry są ścieżkami HL7 lub wyrażeniami ${...}, powiązanymi z instrukcją w kolejności.

Wartości są zawsze powiązane jako parametry i nigdy nie są interpolowane w SQL. To nie dotyczy tylko wstrzyknięcia: O'Brien jest powszechnym nazwiskiem, a złączona kwerenda jest przerwana na apostrofie.

23.9.4 limit czasu

Timeout ogranicza pojedynczą instrukcję.

Defaults to 30s.

23.9.5 max_open_conns

MaxOpenConns ogranicza pulę.

Defaults to 4.

23.10 Miejsce docelowe

Miejsce docelowe to jedno miejsce, do którego kanał wysyła wiadomości.

Zdefiniowane jako Destination w internal/config.

KluczTypWymaganyDomyślny
nameteksttak—
typeDestinationTypetak—
enabledtrue lub false (blok, pomijaj, aby pozostawić wyłączone)nie—
filtertekstnie—
addresstekstnie—
dirtekstnie—
file_nametekstnie—
temp_suffixtekstnie"
appendtrue lub falsenie—
retain_hoursliczba całkowitanie—
tlstlsconf.Settings (blok, pomijaj, aby pozostawić wyłączone)nie—
fhirFHIRDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
cdaCDADestination (blok, pomijaj, aby pozostawić wyłączone)nie—
httpHTTPDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
databaseDatabaseDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
sftpSFTPDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
tcpTCPDest (blok, pomijaj, aby pozostawić wyłączone)nie—
smtpSMTPDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
channelChannelDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
s3S3Destination (blok, pomijaj, aby pozostawić wyłączone)nie—
ftpFTPDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
documentDocumentDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
soapSOAPDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
dicomwebDICOMwebDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
xdsXDSDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
directDirectDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
as2AS2Destination (blok, pomijaj, aby pozostawić wyłączone)nie—
mpiMPIDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
tefcaTEFCADestination (blok, pomijaj, aby pozostawić wyłączone)nie—
pasPASDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
x12_astekstnie—
dicomDICOMDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
javascriptJavaScriptDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
brokerBrokerDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
kafkaKafkaDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
sqsSQSDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
snsSNSDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
amqpAMQPDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
azure_blobAzureBlobDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
mqttMQTTDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
ibm_mqIBMMQDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
pubsubPubSubDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
gcsGCSDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
elrELRDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
pgpPGPSend (blok, pomijaj, aby pozostawić wyłączone)nie—
response_transformertekstnie—
timeoutczas trwania, np. 30s lub 5mnie—
retryRetrynie—
queueQueueConfig (blok, pomijaj, aby pozostawić wyłączone)nie—

23.10.1 nazwa

Nazwa identyfikuje miejsce docelowe w logach i metrykach.

Wymagane w kanale.

23.10.2 file_name

Nazwa pliku, dla miejsca docelowego pliku, tworzy jeden plik na wiadomość (${timestamp}, ${date}, ${control_id}, ${message_type}, ${destination}).

Pusty zachowuje domyślny: jeden plik na dzień i typ wiadomości, dołączony do.

23.10.3 temp_suffix

TempSuffix to nazwa pliku przenoszonego dla każdej wiadomości, usunięta przez przemianowanie po zakończeniu, aby wszystko, co zbiera pliki, nigdy nie czytało połowy z nich.

Domyślnie ".part".

23.10.4 retain_hours

RetainHours usuwa pliki w Dir starsze niż ten.

Zero zachowuje je na zawsze.

23.10.5 x12_as

X12As to xml dla miejsca docelowego na kanale X12, który otrzymuje interchange jako XML Mirth Connect i Open Integration Engine, dla odbiorcy zbudowanego na podstawie tego, co Mirth wysłał do niego.

Pusty lub x12 wysyła X12.

23.10.6 elr

ELR sprawia, że to jest publiczne laboratorium zdrowia raportowania miejsce docelowe: każdy wynik laboratoryjny (ORU^R01) jest przekształcony w ELR 2.5.1 wiadomość zawierającą tylko zamówienia z wynikiem raportowalnym, i to jest dostarczane; wiadomość z niczym raportowalnym nie jest wysłana w ogóle.

Stosuje się do miejsc docelowych, które dostarczają wiadomość HL7 v2, tak jak jest (mllp, http, plik, sftp i reszta), na kanale HL7.

23.10.7 response_transformer

ResponseTransformer sprawdza, co odbiorca odpowiedział i może oznaczyć dostawę jako nieudaną.

Istnieje, ponieważ „czy to dotarło” jest często pytaniem, na które transport nie może odpowiedzieć: odbiorca MLLP zwraca potwierdzenie aplikacji, którego znaczenie jest w jego tekście, a odbiorca HTTP zwraca 200 z dokumentem błędu. W obu przypadkach transport się powiódł, a wiadomość nie dotarła.

Ma znaczenie tylko w miejscu docelowym, które otrzymuje odpowiedź. W miejscu, które nie może, jest odrzucone podczas ładowania, zamiast pozostawionego nigdy nie uruchomionego.

23.10.8 kolejka

Kolejka zapewnia trwałość dostarczania: wiadomość, która nie może być dostarczona teraz, jest przechowywana na dysku i ponawiana, aż będzie mogła być dostarczona.

Wyłączone domyślnie.

23.11 Bezpośrednie miejsce przeznaczenia

BezpośrednieMiejscePrzeznaczenia wysyła każdą wiadomość jako Direct: podpisuje ją jako ten adres, szyfruje ją do certyfikatu każdego odbiorcy i przesyła ją do HISP za pomocą SMTP.

Zdefiniowane jako DirectDestination w internal/config.

KluczTypWymaganyDomyślny
tolista tekstówtak—
subjecttekstnie—
texttekstnie—
attach_nametekstnie—
xdmprawda lub fałsznie—
xdm_source_idtekstnie—
recipient_certs_dirtekstnie—
dnstekstnie—
ldaptekstnie—
smtp_hostteksttak—
usernametekstnie—
passwordtekstnie—
request_mdnprawda lub fałsznie—
timeoutczas trwania, np. 30s lub 5mnie—

23.11.1 do

Do to adresy Direct odbiorców.

Odwołania do pól są zastępowane, więc odbiorca może pochodzić z wiadomości.

23.11.2 recipient_certs_dir

KatalogCertyfikatówOdbiorców przechowuje certyfikaty odbiorców (PEM, jeden plik na adres lub domenę, address.pem lub domain.pem) znalezione z wyprzedzeniem; pusty odczytuje książkę adresową serwera Direct (ekran Direct).

Odbiorcy, których nie ma, są wyszukiwani w DNS (rekordy CERT). Direct nie wysyła do odbiorcy, którego certyfikat nie może być znaleziony.

23.11.3 ldap

LDAP to katalog, w którym wyszukuje się certyfikat odbiorcy, gdy DNS nie ma go (host:port, port 389): to drugi sposób, jaki zezwala przewodnik Direct certificate discovery.

Pusty katalog znajduje katalog domeny odbiorcy za pomocą rekordu DNS SRV (_ldap._tcp), jak mówi przewodnik; "off" nigdy nie pyta katalogu.

23.12 Miejsce przeznaczenia dokumentu

MiejscePrzeznaczeniaDokumentu renderuje każdą wiadomość w postaci dokumentu.

Zdefiniowane jako DocumentDestination w internal/config.

KluczTypWymaganyDomyślny
dirteksttak—
formatFormatDokumentuniepdf
templateteksttak—
titletekstnie—
file_nametekstnie—
font_sizeliczbanie10
landscapetrue lub falsenie—
temp_suffixtekstnie"
timeoutczas trwania, np. 30s lub 5mnie30s

23.12.1 format

Format to pdf lub tekst.

Domyślnie jest to pdf.

23.12.2 szablon

Szablon to treść dokumentu z odwołaniami do ścieżek wiadomości w stylu ${PID-5.1}.

Wymagany. Nie ma sensownego domyślnego: dokument bez szablonu byłby albo surową wiadomością, której nikt nie chce wydrukować, albo pusty.

23.12.3 font_size

Rozmiar czcionki w punktach.

Domyślnie jest to 10, co mieści 80 znaków w szerokości A4.

23.12.4 temp_suffix

TempSuffix jest dołączany podczas zapisu i usuwany przez przemianowanie.

Domyślnie ".part".

Taka sama uprzejmość jak każde inne miejsce przeznaczenia pliku, i tu jeszcze bardziej się liczy: obserwator drukowania, który pobiera niepełny plik PDF, produkuje stronę niczego, i nikt nie bada pustej strony.

23.12.5 limit czasu

Limit czasu ogranicza jeden zapis.

Defaults to 30s.

23.13 Miejsce przeznaczenia ECR

ECRDestination konfiguruje elektroniczne raportowanie przypadków.

Zdefiniowane jako ECRDestination w internal/config.

KluczTypWymaganyDomyślny
rctctekstnie—
sourceteksttak—
facilityECRFacilitytak—

23.13.1 rctc

RCTC jest zestawem wartości FHIR lub kolekcją takich zestawów, jak na przykład eRSD, zawierającą kodowanie wyzwalające.

Bez niego Perfuse używa krótkiego wbudowanego przykładu, który jest przeznaczony do testowania: agencje oczekują RCTC.

23.14 Miejsce przeznaczenia ELR

ELRDestination konfiguruje elektroniczne raportowanie laboratoryjne.

Zdefiniowane jako ELRDestination w internal/config.

KluczTypWymaganyDomyślny
configteksttak—
rctctekstnie—

23.14.1 config

Konfiguracja jest plikiem ELR perfuse elr -config, który czyta: aplikacje i urządzenia wysyłające i odbierające według OID, tryb przetwarzania oraz to, co wypełnia luki w danych laboratoryjnych (zamawiająca placówka, wykonujące laboratorium, przydzielające władze).

Ścieżka względna jest odczytywana z katalogu pliku kanału.

23.14.2 rctc

RCTC jest zestawem wartości FHIR lub kolekcją takich zestawów, jak na przykład eRSD, zawierającą kodowanie wyzwalające.

Bez niego Perfuse używa krótkiego wbudowanego przykładu, który jest przeznaczony do testowania: agencje oczekują RCTC. Względem pliku kanału, jak Konfiguracja.

23.15 Miejsce przeznaczenia FHIR

FHIRDestination konfiguruje konwersję do FHIR i dostarczanie do serwera FHIR.

Zdefiniowane jako FHIRDestination w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
versiontekstnieR5
timezonetekstnie—
default_identifier_systemtekstnie—
identifier_systemsmapa tekstu do tekstunie—
claim_us_coretrue lub falsenie—
validate_before_sendtrue lub false (blok, pomijaj, aby pozostawić wyłączone)nietrue: wysyłanie zasobu, który serwer odrzuci, marnuje budżet ponownych prób i ukrywa prawdziwy problem za błędem transportu
reject_on_warningtrue lub falsenie—
headersmapa tekstu do tekstunie—
bearer_tokentekstnie—
authFHIRAuth (blok, pomijaj, aby pozostawić wyłączone)nie—
ecrECRDestination (blok, pomijaj, aby pozostawić wyłączone)nie—
bundle_scripttekstnie—

23.15.1 url

URL jest podstawowym adresem URL serwera FHIR, na przykład "https://fhir.example.org/fhir".

Pakiet jest wysyłany bezpośrednio do niego.

23.15.2 wersja

Wersja jest wersją FHIR, którą należy wyprodukować: R4, R4B lub R5. Domyślnie jest to R5, najnowsza opublikowana wersja.

Wdrożenie, które komunikuje się z EHR, prawie zawsze chce R4 i powinno to określić, ponieważ ciche obniżanie wersji ukryłoby prawdziwą decyzję dotyczącą interoperacyjności.

23.15.3 strefa czasowa

Strefa czasowa jest stosowana do znaczników czasu HL7 v2, które nie mają przesunięcia. v2 pozwala na czas lokalny bez przesunięcia, a FHIR nie, więc coś musi dostarczyć jednego.

Gdy nie jest ustawiona, używane jest przesunięcie, które nadawca umieścił w MSH-7, ponieważ v2 zakłada, że czas lokalny jest czasem nadawcy; wiadomość, której MSH-7 nie ma przesunięcia, cofa się do UTC.

23.15.4 system_identyfikatora_domyślnego

DomyślnySystemIdentyfikatora przypisuje nazwom, których władza przydzielająca nie ma skonfigurowanego URI.

Bez systemu, MRN jest niejednoznaczny między placówkami.

23.15.5 roszczenie_us_core

ClaimUSCore dodaje profil US Core 9.0.0 do każdego wytworzonego zasobu, który został sprawdzony i spełnia wymagania.

Zasób, który nie spełnia wymagań, jest wysyłany bez roszczenia, z notatką, dlaczego.

23.15.6 walidacja_przed_wysłaniem

ValidateBeforeSend odmawia wysłania paczki, która nie przejdzie walidacji.

Domyślnie ustawione na true: wysłanie zasobu, który serwer odrzuci, marnuje budżet ponownych prób i ukrywa prawdziisty problem za błędem transportu.

23.15.7 odrzucenie_na_ostrzeżeniu

RejectOnWarning również odmawia na ostrzeżenia, takie jak brakujący identyfikator US Core.

Wyłączone domyślnie, ponieważ ostrzeżenie jest sądem o zgodności z profilem, a nie o ważności.

23.15.8 bearer_token

BearerToken jest wysyłany jako nagłówek Authorization.

Wolą jest odniesienie do zmiennej środowiskowej, ${NAME}, zamiast literalu w pliku, który trafia do git.

23.15.9 ecr

ECR sprawia, że to jest publiczne miejsce docelowe raportowania przypadków zdrowia.

Każda wiadomość jest sprawdzana pod kątem kodów wyzwalających; ta, która ma jakiekolwiek, jest wysyłana jako eCR 2.1 eICR, zawinięta w wiadomość eCR, do adresu URL $process-message, a ta, która nie ma żadnego, nie jest w ogóle wysyłana.

23.15.10 skrypt_pakietu

BundleScript to skrypt JavaScript uruchamiany dla każdego przekonwertowanego Bundle przed jego walidacją i wysłaniem: bundle to Bundle jako obiekt, edytowany na miejscu.

Jest to sposób, w jaki witryna dodaje to, co jej własne systemy wiedzą, a wiadomość v2 nie mówi - kod IKNR lub ODS organizacji, poziom kontaktu profilu narodowego - bez zgadywania go przez konwerter. Skrypt, który wyrzuca wyjątek, powoduje awarię wiadomości, tak jak każdy inny transformatator. Nie jest uruchamiany dla raportów przypadków (ecr).

23.16 Miejsce docelowe FTP

FTPDestination wysyła plik na wiadomość.

Zdefiniowane jako FTPDestination w internal/config.

KluczTypWymaganyDomyślny
hostteksttak21
usertekstnie—
passwordtekstnie—
securityFTPSecurityniejawny zamiast brak
insecure_skip_verifyprawda lub fałsznie—
allow_clear_passwordprawda lub fałsznie—
dirteksttak—
file_nametekstnie—
temp_suffixtekstnie"
framedprawda lub fałsznie—
timeoutczas trwania, np. 30s lub 5mnie60s

23.16.1 host

Host to serwer, z opcjonalnym portem.

Domyślnie ustawione na 21, lub 990 dla niejawnych TLS.

23.16.2 użytkownik

Użytkownik i hasło uwierzytelniają.

Pusty użytkownik oznacza anonimowego.

23.16.3 hasło

Użytkownik i hasło uwierzytelniają.

Pusty użytkownik oznacza anonimowego.

23.16.4 zabezpieczenie

Zabezpieczenia wybierają TLS: jawne, niejawne lub brak.

Domyślnie ustawione na jawne zamiast brak, ponieważ domyślnie ustawienie na prosty FTP sprawiłoby, że niebezpieczny wybór byłby najciszej, a strona, która naprawdę nie ma TLS, powinna to napisać.

23.16.5 insecure_skip_verify

InsecureSkipVerify akceptuje dowolny certyfikat.

Potrzebne częściej, niż ktokolwiek by chciał: te serwery często mają samopodpisany certyfikat wygenerowany wiele lat temu, który nikt nie może ponownie wydać. Nazwane oddzielnie, aby wybór był zamierzony i widoczny w pliku, a nie ukryty w trybie "zabezpieczenia: luzne".

23.16.6 allow_clear_password

AllowClearPassword zezwala na hasło za pośrednictwem prostego FTP.

Odmawiane domyślnie, ponieważ wysyła poświadczenia przez sieć w postaci jawnej tekstu przy każdej dostawie. Niektóre analizatory naprawdę nie mają TLS, więc musi to być możliwe - ale musi to być napisane, aby było to decyzją, którą ktoś podjął, a nie domyślnym ustawieniem, które odziedziczył. Nazwa jest celowo niekomfortowa do wpisania.

23.16.7 temp_suffix

TempSuffix jest dołączany podczas zapisywania pliku i usuwany przez przemianowanie, gdy jest on kompletny.

Domyślnie ".part".

Osoba, która zbiera te pliki, jest zwykle zaplanowanym zadaniem, które pobiera wszystko, co znajduje, a bez przemianowania ostatecznie pobiera połowę wiadomości.

23.16.8 limit czasu

Limit czasu ogranicza jeden transfer.

Defaults to 60s.

23.17 Miejsce docelowe GCS

GCSDestination zapisuje każdą wiadomość jako obiekt.

Zdefiniowane jako GCSDestination w internal/config.

KluczTypWymaganyDomyślny
objecttekstnie${date}/${channel}/${control_id}
storage_classtekstnie—
content_typetekstnie—

23.17.1 obiekt

Obiekt to nazwa obiektu, z tymi samymi znacznikami, co klucz s3.

Domyślnie ${date}/${channel}/${control_id}.hl7.

23.18 Miejsce docelowe HTTP

HTTPDestination wysyła wiadomości do punktu końcowego HTTP.

Najczęstsza rzecz, którą kanał Mirth robi, a Perfuse nie mógł, i najczęstszy blok, który tłumacz raportuje. Większość użycia jest nieglamurarna: wysłanie wiadomości do wewnętrznego API, wysłanie jej do usługi internetowej, która otacza system legacy, wysłanie jej do czegoś, co ktoś napisał popołudniu.

Zdefiniowane jako HTTPDestination w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
methodtekstnie—
content_typetekstnie—
headersmapa tekstu do tekstunie—
bearer_tokentekstnie—
usernametekstnie—
passwordtekstnie—
tlstlsconf.Ustawienia (blok, pomijaj, aby wyłączyć)nie—
success_statuslista liczb całkowitychniedowolna 2xx
fail_on_bodylista tekstunie—
follow_redirectsprawda lub fałsznie—

23.18.1 url

URL to miejsce, gdzie należy wysłać.

Required.

23.18.2 metoda

Metoda domyślnie jest ustawiona na POST.

PUT jest dozwolony dla punktu końcowego, który tego potrzebuje.

GET i DELETE są odrzucane: to wysyła treść wiadomości, a transport, który cicho porzuciłby wiadomość z powodu wyboru metody, byłby bardzo cichym sposobem na utratę danych.

23.18.3 content_type

ContentType domyślnie jest ustawiony na application/hl7-v2+er7, który jest zarejestrowanym typem dla wiadomości HL7 v2 rozdzielonej pipe.

Wiele punktów końcowych woli tekst/plain zamiast tego.

23.18.4 bearer_token

BearerToken jest wysyłany jako nagłówek Authorization.

Wolą jest odniesienie do zmiennej środowiskowej zamiast literalu w pliku, który trafia do git.

23.18.5 stan powodzenia

SuccessStatus wylicza kody stanu, które są uważane za dostarczone.

Domyślnie jest to dowolny kod 2xx.

Można go konfigurować, ponieważ punkty końcowe nie zgadzają się co do tego, jak wygląda powodzenie: niektóre odpowiadają kodem 200 z błędem w treści, a niektóre odpowiadają kodem 202 dla kolejki, którą zaakceptowały wiadomość.

23.18.6 zakończ się niepowodzeniem na podstawie treści

FailOnBody traktuje odpowiedź zawierającą którąkolwiek z tych ciągów jako niepowodzenie, niezależnie od kodu stanu.

Istnieje to, ponieważ punkt końcowy odpowiadający kodem 200 z "ERROR: patient not found" w treści jest powszechny, a traktowanie go jako dostarczonego oznacza, że wiadomość jest tracona i nikt o tym nie wie.

23.18.7 postępuj zgodnie z przekierowaniami

FollowRedirects pozwala na przekierowanie żądania.

Wyłączone domyślnie: przekierowanie w przypadku zapisu spowodowałoby ponowny post danych klinicznych w miejscu, które nigdy nie zostało nazwane w konfiguracji.

23.19 Punkt docelowy IBMMQ

IBMMQDestination umieszcza każdą wiadomość w kolejce.

Zdefiniowane jako IBMMQDestination w internal/config.

KluczTypWymaganyDomyślny
non_persistenttrue lub falsenie—

23.19.1 non_persistent

NonPersistent wysyła wiadomości, które nie przetrwają ponownego uruchomienia menedżera kolejki.

Wyłączone domyślnie.

23.20 Punkt docelowy JavaScript

JavaScriptDestination uruchamia skrypt zamiast wysyłania go gdzieś.

Mirth's JavaScript Writer, i jest używany o wiele więcej niż jego pozycja na liście funkcji sugeruje. Jest to sposób na ucieczkę: gdy witryna musi porozmawiać z czymś, co nie jest objęte przez żaden konektor, lub zastosować logikę, którą nie wyraża żadna transformacja, piszą JavaScript Writer. Migrowanie, które nie może uruchomić tych skryptów, nie może przenieść kanałów, które je mają, co w dojrzałym systemie Mirth jest dużą frakcją.

Celowo nie jest to ogólny host skryptowy. Skrypt otrzymuje wiadomość i te same pomocniki, co transformer; to, czego nie otrzymuje, to sposób na dotarcie do systemu plików lub sieci, ponieważ to jest to, do czego służą inne punkty docelowe, a skrypt, który otwiera własne gniazdo, jest niewidoczny dla każdej ponownej próby, kolejki i metryki w silniku.

Zdefiniowane jako JavaScriptDestination w internal/config.

KluczTypWymaganyDomyślny
scriptteksttak—
timeoutczas trwania, np. 30s lub 5mnie—
success_on_undefinedtrue lub false (blok, pomijaj, aby pozostawić wyłączone)nietrue

23.20.1 skrypt

Skrypt to kod, który ma być uruchomiony.

Required.

23.20.2 limit czasu

Limit czasu ogranicza jedną wykonywanie.

Zero stosuje wartość domyślną.

Ograniczony, ponieważ skrypt docelowy znajduje się na ścieżce dostarczania: pętla nieskończona w jednym nie powoduje tylko awarii wiadomości, ale blokuje kolejkę za nią.

23.20.3 success_on_undefined

SuccessOnUndefined traktuje skrypt, który nie zwraca nic, jako powodzenie.

Domyślnie ustawiony na true.

True jest odpowiednim domyślnym ustawieniem i wartym wyjaśnienia. Skrypty JavaScript Mirth w większości wykonują swoją pracę i nie zwracają nic, więc wymaganie jawnej wartości zwrotnej złamałoby je wszystkie podczas importu. Ustawienie false jest dla witryny, która chce, aby skrypt był jawny co do tego, czy działał.

23.21 Kafka Destination

KafkaDestination publikuje wiadomości w temacie Kafka.

Zdefiniowany jako KafkaDestination w internal/config.

KluczTypWymaganyDomyślny
brokerslista tekstutak—
topicteksttak—
keytekstnie—
ackstekstnieall
compressiontekstniesnappy
headersmapowanie tekstu na tekstnie—
timeoutczas trwania, np. 30s lub 5mnietrzydzieści sekund
saslKafkaSASL (blok, pomijaj, aby pozostawić wyłączone)nie—
tlstlsconf.Settings (blok, pomijaj, aby pozostawić wyłączone)nie—

23.21.1 brokers

Brokers to lista serwerów startowych.

Required.

23.21.2 topic

Temat to miejsce, w którym publikowane są wiadomości.

Required.

23.21.3 key

Klucz to szablon dla klucza rekordu, który decyduje o partycji.

To pole sprawia, że Kafka jest bezpieczny dla klinicznego kanału informacyjnego, i warto być precyzyjnym co do tego, dlaczego. Kafka gwarantuje kolejność w ramach partycji i nigdzie indziej. Rekordy z tym samym kluczem zawsze lądują w tej samej partycji, więc kluczowanie według identyfikatora pacjenta utrzymuje zdarzenia tego pacjenta w kolejności, podczas gdy pozwala innym pacjentom działać równolegle.

Bez klucza nie ma takiej gwarancji. W porównaniu z rzeczywistym brokerm, trzydzieści niekluczonych rekordów trafiło do jednej partycji zamiast rozprzestrzeniać się: klient trzyma partię razem i wybiera nową partycję między partiami. Tak więc kolejność jest zachowana przypadkowo i łamie się na granicy, której nikt nie może zobaczyć, co jest gorsze niż łamanie się w sposób ciągły - odczyt A03 przed A01, okresowo, pod obciążeniem.

Ścieżka HL7, oceniana w stosunku do wychodzącej wiadomości: PID-3.1 kluczuje według pacjenta.

23.21.4 acks

Acks to liczba brokerów, które muszą potwierdzić zapis: "all", "leader" lub "none".

Domyślnie ustawiony na all, co jest jedynym ustawieniem, które przetrwa awarię brokera między zapisem a replikacją. "none" to tryb fire-and-forget i spowoduje utratę wiadomości; istnieje, ponieważ ktoś przenoszący niekliniczną telemetrię może słusznie go chcieć, a odmowa go wprost oznaczałaby, że napisałby własnego producenta zamiast.

23.21.5 compression

Kompresja to "none", "gzip", "snappy", "lz4" lub "zstd".

Domyślnie ustawiony na snappy.

Włączony domyślnie, ponieważ HL7 jest wysoko kompresowalnym tekstem, a zwykle przewodem jest ograniczenie. Snappy zamiast zstd jako domyślne: jest najtańszy w CPU, a łącznik na ścieżce dostarczania nie powinien być tym, co nasyca rdzeń.

23.21.6 nagłówki

Nagłówki są nagłówkami rekordu do ustawienia.

Wartości są szablonami ocenianymi dla każdej wiadomości.

23.21.7 limit czasu

Limit czasu ogranicza jedną publikację.

Domyślnie jest to trzydzieści sekund.

23.22 Cel MPI

Cel MPI rejestruje każdą wiadomość pacjenta w indeksie pacjentów serwera: HL7 v2 PID (połączenie A40 łączy), lub pacjent FHIR na kanale surowym.

Indeks decyduje, które rekordy są tą samą osobą; zobacz ekran indeksu pacjentów.

Zdefiniowane jako MPIDestination w internal/config.

KluczTypWymaganyDomyślny
authoritiesmapowanie tekstu na tekstnie—
id_typetekstnie—
ssn_systemtekstnie—
no_mergetrue lub falsenie—

23.22.1 władze

Władze mapują przestrzeń nazw władzy przydzielającej (PID-3.4.1) na jej system identyfikatora, dla nadawców, którzy nie podają uniwersalnego identyfikatora.

Niezmapowane stają się urn:perfuse:aa:<namespace>.

23.22.2 id_type

Typ ID jest typem identyfikatora (PID-3.5) własnego numeru rekordu.

Default MR.

23.22.3 ssn_system

System SSN nazywa identyfikator PID-19.

Default http://hl7.org/fhir/sid/us-ssn.

23.23 Cel MQTT

Cel MQTT publikuje w temacie.

Zdefiniowane jako MQTTDestination w internal/config.

KluczTypWymaganyDomyślny
topicteksttak—
retaintrue lub falsenie—

23.23.1 topic

Temat jest publikowany.

Nie może zawierać symboli wieloznacznych.

23.24 Miejsce docelowe PAS

PASDestination wysyła każdą wiadomość, pakiet żądania Da Vinci PAS, do Claim/$submit płatnika, dla dostawcy, którego systemy tworzą żądanie (EHR, DTR) i potrzebują go wysłać, zarejestrować decyzję i przekazać odpowiedź.

Zdefiniowane jako PASDestination w internal/config.

KluczTypWymaganyDomyślny
payerteksttak—
bearer_tokentekstnie—
authFHIRAuth (blok, pomijaj, aby pominąć)nie—
results_totekstnie—

23.24.1 bearer_token

BearerToken to statyczny token, ${ENV} dozwolony.

Auth to poświadczenia klienta OAuth zamiast, lub Azure, jako miejsce docelowe FHIR.

23.24.2 auth

BearerToken to statyczny token, ${ENV} dozwolony.

Auth to poświadczenia klienta OAuth zamiast, lub Azure, jako miejsce docelowe FHIR.

23.25 Cel Pub Sub

Cel PubSubDestination publikuje w temacie Pub/Sub.

Zdefiniowane jako PubSubDestination w internal/config.

KluczTypWymaganyDomyślny
topicteksttak—
order_bytekstnie—

23.26 Miejsce docelowe S3

S3Destination zapisuje każdą wiadomość jako obiekt.

Zdefiniowane jako S3Destination w internal/config.

KluczTypWymaganyDomyślny
bucketteksttak—
regionteksttak—
keytekstnieścieżka z podziałem na daty plus identyfikator sterujący
access_key_idtekstnie—
secret_access_keytekstnie—
session_tokentekstnie—
endpointtekstnie—
path_styletrue lub falsenie—
server_side_encryptiontekstnie—
content_typetekstnieapplication/hl7-v2 dla HL7 i text/plain w przeciwnym razie
framedtrue lub falsenie—
timeoutczas trwania, np. 30s lub 5mnie60s
storage_classtekstnie—
formattekstnie—

23.26.1 key

Szablon klucza obiektu, używający tych samych znaczników ${date}, ${timestamp}, ${control_id}, ${message_type} i ${channel} co miejsce docelowe pliku i SFTP.

Domyślnie jest to ścieżka z podziałem na daty plus identyfikator sterujący.

Podział na daty jest domyślny, ponieważ alternatywa - wszystkie obiekty w jednej płaskiej prefiksie - powoduje, że wiadro jest wolne do listy i niemożliwe do cyklu życia według wieku, i nikt nie odkrywa tego, aż do momentu, gdy jest w nim cztery miliony obiektów.

23.26.2 access_key_id

AccessKeyID i SecretAccessKey uwierzytelniają.

Każdy z nich może nazwać zmienną środowiskową zamiast przechowywać wartość, używając postaci ${NAME}.

23.26.3 secret_access_key

AccessKeyID i SecretAccessKey uwierzytelniają.

Każdy z nich może nazwać zmienną środowiskową zamiast przechowywać wartość, używając postaci ${NAME}.

23.26.4 path_style

PathStyle adresuje wiadro jako ścieżkę, a nie poddomenę.

Większość magazynów zgodnych z S3 wymaga tego.

23.26.5 content_type

ContentType oznacza obiekt.

Domyślnie jest to application/hl7-v2 dla HL7 i text/plain w przeciwnym razie.

23.26.6 limit czasu

Limit czasu ogranicza jeden upload.

Defaults to 60s.

23.26.7 storage_class

StorageClass to klasa magazynu S3, z której każdy obiekt jest zapisywany: STANDARD_IA, INTELLIGENT_TIERING, GLACIER_IR, GLACIER, DEEP_ARCHIVE itd.

To jest sposób, w jaki archiwum trafia prosto do Glacier - S3 nie ma oddzielnego interfejsu API Glacier do wywołania.

23.26.8 format

Format to hl7 (domyślny: każdy obiekt to wiadomość) lub ndjson: każdy obiekt to jeden wiersz JSON z wiadomością i polami wartymi zapytania, pod kluczami z podziałem na daty, tak aby Amazon Athena mogła zapytać archiwum.

Zobacz perfuse athena.

23.27 Miejsce docelowe SFTP

SFTPDestination zapisuje każdą wiadomość do pliku na serwerze SFTP.

Zdefiniowane jako SFTPDestination w internal/config.

KluczTypWymaganyDomyślny
hostteksttak22
userteksttak—
passwordtekstnie—
key_filetekstnie—
key_passphrasetekstnie—
known_hosts_filetekstnie—
insecure_skip_host_key_checktrue or falsenie—
dirteksttak—
file_nametekstnieznacznik czasu plus ID sterujący
temp_suffixtekstnie"
framedtrue or falsenie—
appendtrue or falsenie—
timeoutczas trwania, np. 30s lub 5mnie60s

23.27.1 host

Host to serwer, z opcjonalnym portem.

Defaults to 22.

23.27.2 hasło

Hasło uwierzytelnia się za pomocą hasła.

Prefer KeyFile.

23.27.3 file_name

Szablon nazwy pliku nadaje nazwę.

Domyślnie jest to znacznik czasu plus ID sterujący.

23.27.4 temp_suffix

TempSuffix jest dołączany podczas zapisywania pliku i usuwany przez przemianowanie po jego ukończeniu.

Domyślnie ".part".

Ten sam luz, którego potrzebuje ten konektor w drodze do środka. Każdy, kto zbiera te pliki, ma identyczny problem, a przemianowanie w katalogu jest atomowe na każdym serwerze wartym użycia.

23.27.5 limit czasu

Limit czasu określa pojedyncze połączenie.

Defaults to 60s.

23.28 Miejsce docelowe SMTP

SMTPDestination konfiguruje dostarczanie pocztą elektroniczną.

Zdefiniowane jako SMTPDestination w internal/config.

KluczTypWymaganyDomyślny
hostteksttak—
fromteksttak—
tolista tekstutak—
cclista tekstunie—
bcclista tekstunie—
subjecttekstnie—
bodytekstnie—
attachtrue or falsenie—
attach_nametekstnieID sterujący z
usernametekstnie—
passwordtekstnie—
starttlstrue or false (blok, pomijaj, aby wyłączyć)nie—
insecure_skip_verifytrue or falsenie—
timeoutczas trwania, np. 30s lub 5mnie—

23.28.1 host

Host to serwer pocztowy z opcjonalnym portem.

Założono port 587, który jest przeznaczony do wysyłania z STARTTLS - port, który nowoczesny serwer oczekuje od klienta. Port 25 jest serwer-serwer i jest zwykle zablokowany lub nieuwierzytelniony.

23.28.2 od

Od jest nadawcą koperty.

Wymagane, ponieważ wiadomość bez nadawcy jest dyskretnie odrzucana przez wiele infrastruktur pocztowych, co sprawia, że jest to najtrudniejszy możliwy błąd do zdiagnozowania.

23.28.3 do

Do, CC i BCC to odbiorcy.

Co najmniej jeden adres Do jest wymagany.

23.28.4 cc

Do, CC i BCC to odbiorcy.

Co najmniej jeden adres Do jest wymagany.

23.28.5 bcc

Do, CC i BCC to odbiorcy.

Co najmniej jeden adres Do jest wymagany.

23.28.6 treść

Treść to tekst wiadomości.

Odwołania do pól są zastępowane, jak w temacie. Gdy jest pusty, sama wiadomość jest treścią.

23.28.7 attach_name

AttachName nadaje nazwę załącznikowi.

Domyślnie jest to ID sterujący z sufiksem .hl7.

23.28.8 nazwa użytkownika

Nazwa użytkownika i hasło uwierzytelniają na serwerze.

Albo oba, albo żadne.

23.28.9 hasło

Nazwa użytkownika i hasło uwierzytelniają na serwerze.

Albo oba, albo żadne.

23.28.10 starttls

StartTLS uaktualnia połączenie przed uwierzytelnieniem.

Domyślnie jest włączone, a wyłączenie go z ustawionym nazwą użytkownika jest odrzucane, a nie dozwolone: wysłanie hasła przez niezaszyfrowane połączenie nie jest wartym oferowania kompromisu.

23.28.11 insecure_skip_verify

InsecureSkipVerify akceptuje dowolny certyfikat.

Nazwany bez dwuznaczności, ponieważ to jest to, co robi.

23.29 Miejsce docelowe SNS

SNSDestination publikuje każdą wiadomość w temacie SNS.

Zdefiniowane jako SNSDestination w internal/config.

KluczTypWymaganyDomyślny
topic_arnteksttak—
subjecttekstnie—
group_bytekstnie—

23.29.1 subject

Temat jest wysyłany z subskrypcjami e-mail.

Opcjonalnie; ${message_type} i ${control_id} są wypełnione.

23.30 Miejsce docelowe SOAP

SOAPDestination wysyła żądanie SOAP dla każdej wiadomości.

Zdefiniowane jako SOAPDestination w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
profiletekstnie—
facility_idtekstnie—
warnings_are_errorstrue lub falsenie—
actiontekstnie—
versiontekstnie1
bodyteksttak—
headertekstnie—
headersmapa tekstu do tekstunie—
usernametekstnie—
passwordtekstnie—
tlstlsconf.Settings (blok, pomiń, aby wyłączyć)nie—
fault_is_successlista tekstunie—
timeoutczas trwania, taki jak 30s lub 5mnie30s

23.30.1 profil

Nazwa profilu określa standardową usługę, której kopertę Perfuse buduje samodzielnie.

Pusty to zwykłe wywołanie SOAP z treścią zapisaną w tym pliku.

"cdc-iis" to interfejs rejestru szczepień CDC (urn:cdc:iisb:2011), którym używa każdy rejestr stanowy w USA: wiadomość jest wysyłana w submitSingleMessage, nazwa użytkownika i hasło są wysyłane w treści zgodnie z WSDL (a nie jako uwierzytelnienie HTTP), domyślnie SOAP 1.2, a potwierdzenie rejestru HL7 decyduje, czy wiadomość została dostarczona. Rejestr odpowiada odrzuconemu strzałowi z kodem HTTP 200 i AR w środku, więc bez tego odrzucenie jest czytane jako sukces.

23.30.2 facility_id

FacilityID to cdc-iis facilityID, identyfikator rejestru dla organizacji, która wysyła.

Opcjonalnie w WSDL; niektóre rejestry wymagają go.

23.30.3 warnings_are_errors

WarningsAreErrors, dla cdc-iis, traktuje potwierdzenie AE zawierające tylko ostrzeżenia jako niepowodzenie.

Wyłączone domyślnie: rejestry wysyłają AE dla "zaakceptowane z ostrzeżeniami", a ciężkość ERR mówi, czy coś zostało utracone.

23.30.4 akcja

Akcja to SOAPAction.

Wymagane przez większość usług 1.1.

23.30.5 treść

Treść to XML, który jest umieszczony wewnątrz koperty, z odniesieniami w stylu ${PID-5.1} do ścieżek wiadomości.

Wymagane, chyba że profil je tworzy. Nie ma użytecznej wartości domyślnej: nazwy elementów pochodzą z własnego schematu usługi i żaden silnik nie może ich zgadnąć.

23.30.6 nagłówek

Nagłówek to XML dla elementu Nagłówek koperty.

Omitowany całkowicie, gdy jest pusty, ponieważ niektóre usługi odrzucają pusty nagłówek.

23.30.7 błąd_jako_sukces

FaultIsSuccess wylicza kody błędów, które są uważane za dostarczone.

Potrzebne częściej, niż powinno być. Usługa, która odpowiada na ponowne wysłanie „już wysłano” mówi, że wiadomość dotarła, a bez tego witryna musi napisać przekształtnik odpowiedzi, aby powiedzieć to - lub co gorsza, obserwuje kolejkę, która ponawia próby przez cały czas przeciwko odbiorcy, który już ma wiadomość.

23.30.8 limit czasu

Limit czasu ogranicza jeden wywołanie.

Defaults to 30s.

23.31 Miejsce docelowe SQS

SQSDestination wysyła każdą wiadomość do kolejki SQS.

Zdefiniowane jako SQSDestination w internal/config.

KluczTypWymaganeDomyślne
queue_urlteksttak—
group_bytekstnie—

23.31.1 queue_url

QueueURL określa nazwę kolejki.

Jeden z końców .fifo jest kolejką FIFO i jest grupowany i usunięty z duplikatów.

23.32 Miejsce docelowe TCP

TCPDest wysyła wiadomości do gniazda z konfigurowalnym ramowaniem.

Zdefiniowane jako TCPDest w internal/config.

KluczTypWymaganeDomyślne
addressteksttak—
max_message_sizecała liczbanie—
timeoutczas trwania, taki jak 30s lub 5mnie—
expect_replyprawda lub fałsznie—
keep_aliveprawda lub fałsznie—
tlstlsconf.Settings (blok, pomijaj, aby wyłączyć)nie—

23.32.1 expect_reply

ExpectReply czeka na powrót bajtów przed zgłoszeniem sukcesu.

Włączone domyślnie, ale warto się nad tym zastanowić. Gdy jest wyłączone, „dostarczony” oznacza, że bajty dotarły do bufora wysyłania systemu operacyjnego, który peer, który awarii chwilę później, nigdy nie odczyta. Gdy jest włączone, peer, który nigdy nie odpowiada, powoduje, że każda wiadomość wygasa.

23.32.2 keep_alive

KeepAlive utrzymuje połączenie otwarte na wszystkie wiadomości, zamiast nawiązywać połączenie na każdą wiadomość.

Większość urządzeń oczekuje tego; niektóre odmawiają przyjęcia drugiej wiadomości na tym samym połączeniu. Wyłączone domyślnie, ponieważ połączenie na każdą wiadomość jest zachowaniem, które działa wszędzie, ale kosztem ustanowienia połączenia każdego razu.

23.33 Miejsce docelowe TEFCA

TEFCADestination prosi partnera TEFCA o rekordy pacjenta dla każdej wiadomości.

To, kim jest ten serwer w sieci, jego certyfikat i partner są ustawieniami serwera (Ustawienia, TEFCA), ponieważ należą do organizacji i jej umowy z QHIN. To, co decyduje kanał, to kiedy prosić i dlaczego: cel użycia jest częścią kanału, a nie tego, kto jest zalogowany, więc każde zapytanie, które kanał wykonuje, podaje ten sam powód, a ślad audytowy można odczytać przeciwko niemu.

Zdefiniowane jako TEFCADestination w internal/config.

KluczTypWymaganyDomyślny
purposeteksttak—
results_totekstnie—

23.33.1 purpose

Cel to cel użycia: leczenie, płatność, operacje, zdrowie_publiczne lub dostęp_indywidualny.

Muszą to być te, które deklaruje uczestnik.

23.33.2 results_to

ResultsTo nazwuje kanał na tym serwerze, który otrzymuje każdy pakiet, który partner zwraca, jako wiadomość własną.

Pusty trzyma pakiet jako odpowiedź tego miejsca docelowego tylko, dla transformatora odpowiedzi do odczytania.

23.34 Cel XDS

XDSDestination publikuje każdy dokument kliniczny w repozytorium dokumentów IHE XDS.b z ITI-41 Provide and Register.

Metadane są odczytywane z dokumentu CDA (pacjent, tytuł, typ, czas, autor, poufność, język) i uzupełnione z tych ustawień, które określają, co dokument nie może: kto go wysyła, jaki rodzaj placówki i praktyki pochodzi, oraz który z identyfikatorów pacjenta jest domeną powiązania.

Zdefiniowane jako XDSDestination w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
source_idteksttak—
patient_domaintekstnie—
facility_typeXDSCodetak—
practice_settingXDSCodetak—
classXDSCode (blok, pomijaj, aby wyłączyć)nie—
content_typeXDSCode (blok, pomijaj, aby wyłączyć)nie—
tokentekstnie—
usernametekstnie—
passwordtekstnie—
headersmapa tekstów do tekstównie—
tlstlsconf.Settings (blok, pomijaj, aby wyłączyć)nie—
timeoutczas trwania, np. 30s lub 5mnie—
direct_fromtekstnie—
direct_tolista tekstównie—

23.34.1 patient_domain

PatientDomain jest OID przydzielonej władzy powiązania: identyfikator pacjenta z tym korzeniem jest zarejestrowany.

Bez niego dokument, którego pacjent ma jeden identyfikator, wysyła ten identyfikator, a dokument z kilkoma identyfikatorami jest odrzucany.

23.34.2 token

Token lub nazwa użytkownika/hasło uwierzytelniają; nagłówki są dodawane do każdego żądania.

Większość domen powiązania używa wzajemnego TLS (tls) zamiast.

23.34.3 nazwa użytkownika

Token lub nazwa użytkownika/hasło uwierzytelniają; nagłówki są dodawane do każdego żądania.

Większość domen powiązania używa wzajemnego TLS (tls) zamiast.

23.34.4 hasło

Token lub nazwa użytkownika/hasło uwierzytelniają; nagłówki są dodawane do każdego żądania.

Większość domen powiązania używa wzajemnego TLS (tls) zamiast.

23.34.5 nagłówki

Token lub nazwa użytkownika/hasło uwierzytelniają; nagłówki są dodawane do każdego żądania.

Większość domen powiązania używa wzajemnego TLS (tls) zamiast.

23.34.6 tls

Token lub nazwa użytkownika/hasło uwierzytelniają; nagłówki są dodawane do każdego żądania.

Większość domen powiązania używa wzajemnego TLS (tls) zamiast.

23.34.7 direct_from

DirectFrom i DirectTo sprawiają, że przesłanie XDR jest transportowane jako Direct: blok adresowania Direct nazywający adres nadawcy Direct i odbiorców, oraz odbiorców w przesłaniu intendedRecipient.

HISP, który przyjmuje XDR, dostarcza go jako pocztę Direct lub do własnego punktu końcowego XDR odbiorcy.

23.34.8 direct_to

DirectFrom i DirectTo sprawiają, że przesłanie XDR jest transportowane jako Direct: blok adresowania Direct nazywający adres nadawcy Direct i odbiorców, oraz odbiorców w przesłaniu intendedRecipient.

HISP, który przyjmuje XDR, dostarcza go jako pocztę Direct lub do własnego punktu końcowego XDR odbiorcy.

24 Odwołanie do formatu

Opcje określające, w jaki sposób wiadomości są parsowane i zapisywane, dla formatów, które wymagają więcej niż nazwy.

24.1 Załączniki

Załączniki konfigurują przenoszenie dużych ładunków poza wiadomość.

Wiadomość zawierająca zeskanowany raport lub plik PDF jest zwykła w przepływach dokumentów, a ładunek jest rutynowo setki razy większy niż wiadomość wokół niego. Pozostawiony w linii oznacza, że magazyn rośnie w tempie dokumentów, a nie ruchu, wiadomość w kolejce do pięciu miejsc przeznaczenia jest kopiowana pięć razy, a interfejs przesyła megabajty, aby pokazać komuś nazwę pacjenta.

Mirth nazywa to obsługującymi załączniki. To jest odpowiednik, i jest to opcja włączona na kanał, ponieważ karmienie zwykłych wiadomości ADT nie ma nic do wyodrębnienia i nie powinno płacić za maszynę.

Zdefiniowane jako Attachments w internal/config.

KluczTypWymaganyDomyślny
extractlista attach.Ruletak—
reassembletrue lub false (blok, pomiń, aby pozostawić)nietrue

24.1.1 reassemble

Reassemble umieszcza ładunki z powrotem przed dostarczeniem.

Domyślnie ustawiony na true.

Domyślnie jest włączone, ponieważ odbiorca oczekujący dokumentu musi otrzymać dokument; wiadomość zawierająca dosłowny token byłaby zapisana jako raport i nikt by się nie dowiedział, aż ktoś otworzył rekord.

Wyłączenie jest przeznaczone dla przypadku, w którym celem kanału jest usunięcie dokumentów - przekazywanie metadanych do systemu, który nie ma dla nich zastosowania, gdzie wysłanie ich stanowiłoby kwestię prywatności, a nie przepustowości.

24.2 Ograniczone

Delimited konfiguruje kanał z ogranicznikami.

Typ danych Mirth Delimited: CSV, rozdzielany tabulatorem i długi ogon formatów, których używa analityk laboratoryjny lub biuro usługowe.

Zdefiniowane jako Delimited w internal/config.

KluczTypWymaganyDomyślny
delimitertekstnie—
quotetekstniecudzysłów
commenttekstnie—
has_headerprawda lub fałsznie—
columnslista tekstunie—
trim_spaceprawda lub fałsznie—
relaxedprawda lub fałsznie—
splitprawda lub fałsz (blok, pomijaj, aby pozostawić)nieprawda
keep_blank_linesprawda lub fałsznie—
filtertekstnie—
transformationslista kroków.Stepnie—

24.2.1 separator

Separator oddziela kolumny jako znak lub nazwę.

Nazwa jest akceptowana, ponieważ tabulator nie może być wpisany do pliku YAML w sposób niejednoznaczny, a plik konfiguracyjny zawierający niewidoczny znak jest nieczytelny dla osoby, która go otwiera.

24.2.2 cudzysłów

Cudzysłów otacza wartości zawierające separator.

Domyślnie jest to cudzysłów; "none" wyłącza go.

24.2.3 rozdział

Rozdział tworzy oddzielne wiadomości dla każdego wiersza.

Domyślnie ustawiony na true.

To jest decyzja, która kształtuje kanał rozdzielany i zasługuje na to, aby być wyrażona na głos. Plik z pięcioma tysiącami wyników jest albo jedną wiadomością, albo pięcioma tysiącami. Jedna wiadomość oznacza jedno potwierdzenie, jeden wpis w przeglądarce i jeden błąd, który powoduje awarię całego pliku. Pięć tysięcy oznacza, że każdy wiersz jest filtrowany, przekształcany, dostarczany i ponawiany oddzielnie, a jeden zły wiersz nie powoduje awarii pozostałych.

Dzielenie jest domyślnym ustawieniem, ponieważ obsługa wiersza po wierszu jest tym, czego prawie każda strona chce, a alternatywa jest odkrywana późno: kanał, który wyglądał dobrze podczas testowania z trzywierszowym plikiem, zawodzi całą nocną transmisję z powodu jednej nieprawidłowej linii.

24.2.4 zachowaj_puste_wiersze

ZachowajPusteWiersze powoduje, że puste wiersze nie są pomijane.

Pomijanie jest domyślnym ustawieniem, ponieważ każdy plik kończy się znakiem nowej linii, a rekord pustych pól nie jest rekordem. To istnieje dla rzadkiego formatu, w którym pusta linia ma znaczenie.

24.2.5 filtr

Filtr decyduje, które wiadomości są kontynuowane, napisane przeciwko nazwom kolumn.

Tutaj, a nie na kanale, ponieważ filtr na poziomie kanału kompiluje ścieżki HL7. Dwa ustawienia o nazwie filtr byłyby mylące, ale jedno ustawienie, które oznacza różne rzeczy w zależności od dataType, jest gorsze: kanał rozdzielany, który w milczeniu skompilował swój filtr jako HL7, nie dopasowałby się do niczego i upuściłby wszystko, co jest awarią, której zapobiega odmowa na poziomie najwyższym.

24.2.6 transformacje

Transformacje są deklarowanymi krokami, odnoszącymi się do kolumn, a nie pól HL7.

Oddzielne od transformacji kanału z tego samego powodu, co filtr, i jest to układ, którego już używają X12 i NCPDP.

24.3 Opcje HL7v3

Opcje HL7v3 są ustawieniami, które mają zastosowanie tylko do kanału HL7 w3.

Zdefiniowane jako HL7v3Options w internal/config.

KluczTypWymaganyDomyślny
filtertekstnie—
acknowledgeprawda lub fałsz (blok, pomijaj, aby pozostawić)nie—
sender_devicetekstnie—
sender_oidtekstnie—
transformationslista kroków hl7v3.Stepnie—

24.3.1 filtr

Filtr wyklucza wiadomości, używając ścieżek v3.

To pole jest własne, a nie zwykły filtr kanału, ponieważ są to dwa różne języki przeciwko różnym modelom wiadomości. Udostępnianie pola oznaczałoby, że filtr v2 nigdy nie pasowałby do kanału v3, lub że filtr v3 nie mógłby być przetworzony jako v2 - a drugi jest lepszy tylko dlatego, że kończy się głośnym błędem.

Kanał, który ustawia oba, jest odrzucany podczas ładowania, ponieważ jeden z nich musiałby być zignorowany, a nie ma uczciwego sposobu wyboru.

24.3.2 potwierdzenie

Potwierdzenie wysyła potwierdzenie MCCI_IN000002UV01.

Włączone domyślnie, w przeciwieństwie do X12. Interakcja v3 za pomocą synchronicznego transportu oczekuje potwierdzenia - aplikacja wysyłająca zwykle czeka na nie - a nadawca, który nie otrzymuje nic, zwykle powtarza, co powoduje, że pacjent jest zarejestrowany trzykrotnie.

Wskazuje, aby „nie ustawiono” i „ustawiono na false” były różne: domyślnie jest włączone, a ktoś, kto je wyłączy, powinien to powiedzieć.

24.3.3 nadawca_urządzenia

NadawcaUrządzenia to identyfikator urządzenia, który umieszczamy w potwierdzeniu.

Wymagane podczas potwierdzania. Potwierdzenie v3 nazwuje urządzenie, z którego pochodzi, a odbiorca, który nie rozpoznaje naszego, może je odrzucić - co wygląda dokładnie jak nie wysłanie go.

24.3.4 transformacje

Przekształcenia zmieniają zawartość dokumentu v3.

To pole jest własne, a nie zwykłe przekształcenia kanału, z tego samego powodu, dla którego filtr jest: są to różne słownictwa przeciwko różnym modelom wiadomości. Kroki v2 adresują segmenty i pola, których dokument v3 nie ma, więc udostępnianie pola oznaczałoby, że krok nie robi nic.

Nazwy kroków odpowiadają nazwom v2, tam gdzie znaczenie jest takie same, aby ktoś, kto napisał jeden kanał, mógł napisać inny. To, co jest inne, to to, czego potrzebuje v3, a v2 nie może wyrazić - głównie to, że usunięcie wartości ma trzy różne znaczenia, więc clear, nullflavor i remove są trzema krokami zamiast jednego.

24.4 Ramowanie TCP

RamowanieTCP to sposób, w jaki granice wiadomości są znalezione na surowym gnieździe.

Współdzielone przez źródło TCP i miejsce przeznaczenia TCP, a także przez źródło szeregowe, ponieważ ramowania są takie same, niezależnie od tego, skąd pochodzą bajty. Laboratoryjny analizator, który mówi STX/ETX przez gniazdo, mówi również STX/ETX przez szeregowe połączenie.

Zdefiniowane jako TCPFraming w internal/config.

KluczTypWymaganyDomyślny
framingteksttak—
delimitertekstnie—
start_blocktekstnie—
keep_delimiterprawda lub fałsznie—
record_lengthliczba całkowitanie—
trim_paddingprawda lub fałsz (blok, pomijaj, aby wyłączyć)nie—
length_bytesliczba całkowitanie—
big_endianprawda lub fałsznie—
length_includes_headerprawda lub fałsznie—

24.4.1 ramowanie

Ramowanie to mllp, rozdzielone, stałe, długość lub całość.

Wymagane, bez domyślnego. Odczyt strumienia z błędnym ramowaniem produkuje wiadomości, które wyglądają prawdopodobnie, zamiast błędu, więc zgadywanie jest gorsze niż pytanie.

24.4.2 początek_bloku

PoczątekBloku opcjonalnie zaczyna wiadomość.

Bajty przed nim są odrzucane jako szum z częściowego połączenia.

24.4.3 zachowaj_separację

KeepDelimiter zawiera separator w wiadomości.

Wyłączone domyślnie: jest to ramowanie, a nie zawartość.

24.4.4 trim_padding

TrimPadding usuwa spację i NUL z końca rekordu o ustalonej długości.

Włączone domyślnie.

24.5 Opcje X12

X12Options to ustawienia, które dotyczą tylko kanału X12.

Zdefiniowane jako X12Options w internal/config.

KluczTypWymaganyDomyślny
envelopeEnvelopePolicyniewymagany
splittrue lub falsenie—
acknowledgetekstnie—
ack_sender_idtekstnie—
ack_sender_qualifiertekstnie—
arrives_astekstnie—
transformationslista x12.Stepnie—

24.5.1 envelope

Envelope określa, co zrobić, gdy samozadeklarowane liczby nie zgadzają się z tym, co jest obecne.

Domyślnie ustawiony na wymagany.

24.5.2 rozdział

Split wysyła jedną wiadomość na zestaw transakcji zamiast jedną na plik.

Wyłączone domyślnie. Jeden 837 może zawierać setki roszczeń, więc włączenie tego mnoży wszystko w dół strumienia - liczbę wiadomości, potwierdzenia, wiersze, progi alertów - i powinno to być decyzją, którą ktoś podjął, a nie domyślną, którą odziedziczył.

24.5.3 potwierdzenie

Acknowledge określa, które potwierdzenie ma zostać wysłane z powrotem: 999, 997, ta1 lub żadne.

To jest właściwość relacji partnera handlowego, a nie wiadomości, więc musi być skonfigurowane. 999 zastępuje 997 dla transakcji HIPAA, ale wiele partnerów - starsze połączenia płatników, zwłaszcza - jest skonfigurowanych do oczekiwania 997 i będzie traktować 999 jako niezidentyfikowany plik. Wysłanie niewłaściwego jest gorsze niż wysłanie żadnego, ponieważ odpowiada na pytanie, które nikt nie zadał, i pozostawia prawdziwe otwarte.

Pusty oznacza brak, co jest bezpiecznym domyślnym ustawieniem: partner, który nie oczekuje potwierdzenia i otrzymuje je, może traktować je jako niespodziewaną wymianę.

24.5.4 ack_sender_id

AckSenderID i AckSenderQualifier to nasz własny identyfikator wymiany, stający się ISA06 i ISA05 każdego potwierdzenia.

Wymagane, gdy Acknowledge jest ustawiony, i odmówione podczas ładowania w przeciwnym razie. Muszą to być wartości, które partner handlowy skonfigurował dla nas, i nie ma sposobu, aby je zgadnąć: wymiana, której ISA06 partner nie rozpoznaje, jest odrzucana, zanim ktokolwiek ją przeczyta, więc błędna wartość produkuje ciszę, która wygląda dokładnie jak nie wysyłanie niczego - i ktoś spędza tydzień, szukając w niewłaściwym miejscu.

24.5.5 ack_sender_qualifier

AckSenderID i AckSenderQualifier to nasz własny identyfikator wymiany, stający się ISA06 i ISA05 każdego potwierdzenia.

Wymagane, gdy Acknowledge jest ustawiony, i odmówione podczas ładowania w przeciwnym razie. Muszą to być wartości, które partner handlowy skonfigurował dla nas, i nie ma sposobu, aby je zgadnąć: wymiana, której ISA06 partner nie rozpoznaje, jest odrzucana, zanim ktokolwiek ją przeczyta, więc błędna wartość produkuje ciszę, która wygląda dokładnie jak nie wysyłanie niczego - i ktoś spędza tydzień, szukając w niewłaściwym miejscu.

24.5.6 arrives_as

ArrivesAs to xml, gdy źródło dostarcza wymianę jako XML, który Mirth Connect i Open Integration Engine zapisują dla X12 (korzeń X12Transaction, elementy o nazwie CLM.05.1), jako silnik, który jest migrowany z jednego, lub system zbudowany przeciwko niemu, go wysyła.

Zostaje on przekonwertowany z powrotem na X12, zanim cokolwiek innego się wydarzy. Pusty lub x12 to X12.

24.5.7 transformacje

Transformacje to deklaracyjne zmiany stosowane do zaakceptowanych wymian.

Oddzielne od transformacji na poziomie kanału z tego samego powodu, co v3: te adresują pola HL7 przez parser, który czyta segment-pole-składnik-podskładnik, a X12 nie ma podskładnika, traktuje powtarzające się segmenty jako zwyczajne, a nie wyjątkowe, i jest napisany CLM01 przez osoby, które go konfigurują. Wspólny parser musiałby akceptować obie notacje i byłby wtedy niejednoznaczny w obu.

Nazwy kroków są tymi samymi, które kroki HL7 i v3 używają, więc to, czego autor już nauczył się, przenosi się.

25 Odwołanie do zachowania

Potwierdzenie, kolejkowanie, ponowienie, sondowanie, skryptowanie i ustawienia cienia. Dotyczą one niezależnie od transportu używanego przez kanał.

25.1 Połączenie AMQP

AMQPConnection określa, gdzie i jako kto się łączyć.

Zdefiniowane jako AMQPConnection w internal/config.

KluczTypWymaganyDomyślny
addrteksttak—
addressteksttak—
usernametekstnie—
passwordtekstnie—
hostnametekstniehost addr
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—
timeoutczas trwania, np. 30s lub 5mnie30s

25.1.1 nazwa użytkownika

Nazwa użytkownika i hasło uwierzytelniają się za pomocą SASL PLAIN; oba puste oznaczają ANONYMOUS.

Dla Service Bus, nazwa polityki i klucz.

25.1.2 hasło

Nazwa użytkownika i hasło uwierzytelniają się za pomocą SASL PLAIN; oba puste oznaczają ANONYMOUS.

Dla Service Bus, nazwa polityki i klucz.

25.1.3 nazwa hosta

Nazwa hosta jest wysyłana do brokera, który Service Bus trasuje.

Domyślnie jest to host addr.

25.1.4 tls

TLS szyfruje połączenie.

Wymagane dla Service Bus i Event Hubs.

25.1.5 limit czasu

Limit czasu wiąże łączenie i każde oczekiwanie na brokera.

Defaults to 30s.

25.2 Partner AS2

AS2Partner jest partnerem handlowym, od którego źródło AS2 akceptuje wiadomości.

Zdefiniowane jako AS2Partner w internal/config.

KluczTypWymaganyDomyślny
idteksttak—
cert_fileteksttak—
allow_unsignedtrue lub falsenie—
allow_unencryptedtrue lub falsenie—

25.2.1 cert_file

CertFile to certyfikat partnera (PEM), używany do podpisów.

Często samopodpisany: partnerzy AS2 wymieniają certyfikaty bezpośrednio, zamiast przez władzę.

25.2.2 allow_unsigned

AllowUnsigned i AllowUnencrypted akceptują wiadomość od tego partnera, która nie jest podpisana lub nie jest zaszyfrowana.

Wyłączone: taka wiadomość jest odrzucana z potwierdzeniem, podającym powód.

25.2.3 allow_unencrypted

AllowUnsigned i AllowUnencrypted akceptują wiadomość od tego partnera, która nie jest podpisana lub nie jest zaszyfrowana.

Wyłączone: taka wiadomość jest odrzucana z potwierdzeniem, podającym powód.

25.3 Dostęp AWS

Dostęp do AWS jest sposobem, w jaki łącznik dociera do AWS: region, dla którego jest podpisywany, klucze i opcjonalne zastąpienie punktu końcowego.

Poświadczenia mogą być literalne lub odniesieniami ${ENV_VAR}, w ten sposób powinny być dostarczane. Nie ma łańcucha poświadczeń instance-metadata, celowo: patrz internal/awsv4.

Zdefiniowane jako AWSAccess w internal/config.

KluczTypWymaganyDomyślny
regionteksttak—
access_key_idtekstnie—
secret_access_keytekstnie—
session_tokentekstnie—
endpointtekstnie—

25.3.1 secret_access_key

SecretAccessKey to sekret, literalny lub ${AWS_SECRET_ACCESS_KEY}.

Wolą odniesienie: ten plik wchodzi do kontroli wersji.

25.3.2 session_token

SessionToken jest przeznaczony tylko dla tymczasowych poświadczeń.

Wygasają one, a łącznik przestaje działać, gdy to nastąpi.

25.4 Potwierdzenie

Ack konfiguruje generowanie potwierdzeń.

Zdefiniowane jako Ack w internal/config.

KluczTypWymaganyDomyślny
whenAckWhennie—
applicationtekstnie—
facilitytekstnie—
include_trigger_eventtrue or falsenie—

25.4.1 include_trigger_event

IncludeTriggerEvent wysyła ACK^A01 zamiast ACK.

Niektórzy odbiorcy wymagają tego, a inni odrzucają to, więc jest to jawne.

25.5 Dostęp do obiektu blob platformy Azure

AzureBlobAccess to konto, kontener i poświadczenie.

Zdefiniowane jako AzureBlobAccess w internal/config.

KluczTypWymaganyDomyślny
accountteksttak—
containerteksttak—
keytekstnie—
sastekstnie—
endpointtekstnie—

25.5.1 key

Klucz to klucz konta lub ${AZURE_STORAGE_KEY}.

Ustaw go lub sas.

25.5.2 sas

SAS to ciąg zapytania sygnatury dostępu współdzielonego lub odniesienie ${...}.

Preferowany: może być ograniczony do tego kontenera.

25.6 Odwołanie do umowy

ContractRef wskazuje kanał na jego umowę.

Zdefiniowane jako ContractRef w internal/config.

KluczTypWymaganyDomyślny
fileteksttak—
check_everytekstnie15 minut
overliczba całkowitanie500

25.6.1 check_every

CheckEvery to częstotliwość, z jaką należy ponownie sprawdzić, jako czas trwania.

Domyślnie wynosi 15 minut.

Skutecznie ograniczony do interwału oceny alertu, który wynosi 30 sekund domyślnie, ponieważ sprawdzenie jest wykonywane z tej pętli, a nie z własnego timera - więc umowa, która żąda 3s, otrzymuje 30s. Jest to celowe: jeden timer jest łatwiejszy do zrozumienia niż dwa, a także utrzymuje wynik umowy w zgodzie z odczytem, do którego jest dołączony. Warto wiedzieć, zanim ktoś ustawia krótki interwał i stwierdzi, że jest on uszkodzony.

Nie na wiadomość. Budowanie profilu oznacza odczytanie ostatniego ruchu, a robienie tego na każdej wiadomości spowodowałoby, że przepustowość kanału zależałaby od ilości historii, którą posiada - co jest rodzajem charakterystyki wydajności, która pojawia się tylko w produkcji, sześć miesięcy później.

25.6.2 over

Over to liczba ostatnich wiadomości do profilowania.

Defaults to 500.

Liczba, a nie okno czasowe, ponieważ cichy kanał i zajęty kanał wymagają tej samej ilości dowodów, aby uzasadnić szybkość, a okno czasowe daje im bardzo różne ilości.

25.7 Opcje DICOM

DICOMOptions konfiguruje kanał obrazowy.

Dlaczego kroki są nazwane, a nie ścieżki

Każdy inny format otrzymuje pisarza ścieżki. DICOM celowo nie otrzymuje, a powodem jest pixel danych: obiekt jest binarny, ogólny pisarz tagów może ustawić dowolny tag na dowolne bajty, a błąd tam nie powoduje odrzucenia wiadomości - powoduje otwarcie i błędnego obrazu. Radiolog czytający badanie nie ma sposobu, aby to stwierdzić.

Tak więc cztery rzeczy, których potrzebują strony, to nazwane akcje z ograniczonymi efektami: de-identyfikacja, przepisanie tytułu AE, usunięcie prywatnych tagów, ustawienie instytucji. Każda wie, które tagi dotyka, i żadna nie może dotknąć danych pikseli.

Dlaczego ten blok istnieje teraz

internal/dicom przenosił steps.go i transform.go przez jakiś czas - cztery akcje, dicom.Apply i testy. Nic ich nie odnosiło. Pięćset linii bez wywołania, co sekcja 7 kolejki nazywa: implementacja bez wywołania jest nie do odróżnienia od funkcji, która nie istnieje. Ten blok i wywołanie silnika są połączeniami, a nie funkcją.

Zdefiniowane jako DICOMOptions w internal/config.

KluczTypWymaganyDomyślny
transformationslista dicom.Stepnie—

25.8 Bezpośredni adres

DirectAddress to bezpośredni adres, który serwer posiada: jego certyfikat i klucz, oraz kotwice, którym ufa.

Ten sam blok jest używany do wysyłania (podpisywania jako ten adres) i odbierania (odszyfrowywania dla niego).

Zdefiniowane jako DirectAddress w internal/config.

KluczTypWymaganyDomyślny
addressteksttak—
cert_fileteksttak—
key_fileteksttak—
anchors_fileteksttak—

25.8.1 cert_file

CertFile i KeyFile to certyfikat adresu (PEM, z łańcuchem po nim) i klucz prywatny (PEM).

HISP lub jego władza rejestrująca je wydaje; są tożsamością adresu.

25.8.2 plik_klucza

CertFile i KeyFile to certyfikat adresu (PEM, z łańcuchem po nim) i klucz prywatny (PEM).

HISP lub jego władza rejestrująca je wydaje; są tożsamością adresu.

25.8.3 anchors_file

AnchorsFile to kotwice zaufania (PEM): urzędy certyfikacji, których nadawcy i odbiorcy tego adresu ufają, takie jak pakiet DirectTrust.

Wiadomość podpisana przez cokolwiek innego jest odrzucana.

25.9 Direct IMAP

DirectIMAP to skrzynka pocztowa HISP, z której czyta źródło Direct.

Zdefiniowane jako DirectIMAP w internal/config.

KluczTypWymaganyDomyślny
hostteksttak—
portliczba całkowitanie—
securitytekstnie—
usernameteksttak—
passwordtekstnie—
mailboxtekstnie—
after_readtekstnie—
move_totekstnie—
error_foldertekstnie—
poll_intervalczas trwania, np. 30s lub 5mnie—
tlstlsconf.Settings (blok, pomijaj, aby pominąć)nie—

25.9.1 move_to

MoveTo to katalog, do którego przenoszone są odebrane wiadomości; domyślnie jest to Processed.

Utworzone, gdy brakuje.

25.9.2 tls

TLS ufa plikowi CA (lub własnemu certyfikatowi HISP) i określa serwer oczekiwany w nim, dla HISP, którego certyfikat IMAP nie pochodzi z publicznej władzy.

Certyfikat jest zawsze weryfikowany.

25.10 Direct XDR

DirectXDR to punkt końcowy, w którym źródło Direct przyjmuje XDR.

Zdefiniowane jako DirectXDR w internal/config.

KluczTypWymaganyDomyślny
listenteksttak—
tls_certtekstnie—
tls_keytekstnie—
client_ca_filetekstnie—

25.11 Obiekt ECR

ECRFacility jest organizacją wysyłającą raporty przypadków.

Zdefiniowane jako ECRFacility w internal/config.

KluczTypWymaganyDomyślny
nameteksttak—
npitekstnie—
phoneteksttak—
linetekstnie—
cityteksttak—
stateteksttak—
postal_codetekstnie—

25.12 Opcje EDIFACT

EDIFACTOptions są ustawieniami, które dotyczą tylko kanału EDIFACT.

Zdefiniowane jako EDIFACTOptions w internal/config.

KluczTypWymaganyDomyślny
envelopetekstnie—
splittrue lub falsenie—
acknowledgetekstnie—

25.12.1 potwierdzenie

Acknowledge odpowiada nadawcy wysyłającemu za pomocą HTTP z CONTRL w odpowiedzi: zaakceptowane (akcja 7), gdy interchange został przeczytany i dostarczony, odrzucone (4) w przeciwnym razie.

Default none.

25.13 Email O Auth

EmailOAuth loguje się za pomocą OAuth 2.0 (SASL XOAUTH2), który jest wymagany przez Microsoft 365 i Gmail zamiast hasła.

Zdefiniowane jako EmailOAuth w internal/config.

KluczTypWymaganyDomyślny
providerteksttak—
tenanttekstnie—
token_urltekstnie—
client_idteksttak—
client_secrettekstnie—
refresh_tokentekstnie—
scopetekstnie—

25.13.1 client_secret

ClientSecret może być ${ENV}.

Bez refresh_token wybiera grant poświadczeń klienta aplikacji Microsoft.

25.13.2 refresh_token

RefreshToken może być ${ENV}: skrzynka pocztowa, na którą osoba wyraziła zgodę.

Wymagane dla Gmail.

25.14 FHIR Auth

FHIRAuth to sposób, w jaki miejsce docelowe FHIR uwierzytelnia się w usłudze FHIR hostowanej.

Trzy ustawienia domyślne, ponieważ usługi hostowane to miejsce, w którym token nośnika wklejony do pliku przestaje działać w ciągu godziny:

Tokeny są pobierane w razie potrzeby i ponownie wykorzystywane do minute przed ich wygaśnięciem.

Zdefiniowane jako FHIRAuth w internal/config.

KluczTypWymaganyDomyślny
typeteksttak—
regiontekstnie—
access_key_idtekstnie—
secret_access_keytekstnie—
session_tokentekstnie—
tenant_idtekstnie—
token_urltekstnie—
client_idtekstnie—
client_secrettekstnie—
scopetekstnie—

25.14.1 region

Region to region AWS.

Odczytywany z adresu URL HealthLake, gdy nie jest podany.

25.14.2 token_url

TokenURL to punkt końcowy tokenu OAuth, dla client_credentials.

Dla azure jest pochodny z najemcy.

25.14.3 client_id

ClientID i ClientSecret identyfikują aplikację.

Tajemnica może być odniesieniem ${ENV}, co jest sposobem, w jaki powinna być podana.

25.14.4 client_secret

ClientID i ClientSecret identyfikują aplikację.

Tajemnica może być odniesieniem ${ENV}, co jest sposobem, w jaki powinna być podana.

25.14.5 scope

Zakres jest żądany z tokenem.

Dla azure domyślnie jest adres URL usługi FHIR, po którym następuje /.default, co jest jego publicznością.

25.15 File Poll

FilePoll to część źródła zbierającego pliki, która nie ma nic wspólnego z transportem.

Współdzielony przez źródła lokalne, FTP, SMB i WebDAV, a także przez SFTP. Każde z tych ustawień istnieje z powodu sposobu, w jaki pliki się psują, a nie z powodu różnic w transporcie, dlatego należą one razem: witryna, która wypracowała odpowiednie ustawienie stable_for dla swojego analizatora, nie powinna musieć go ponownie ustalać, gdy analizator przenosi się do udziału.

Zdefiniowane jako FilePoll w internal/config.

KluczTypWymaganyDomyślny
dirteksttak—
patterntekstnie—
poll_intervalczas trwania, taki jak 30s lub 5mnie—
after_readtekstnie—
move_totekstnie—
error_dirtekstnie—
stable_forczas trwania, taki jak 30s lub 5mnie—
max_file_sizeliczba całkowitanie—
framedprawda lub fałsznie—
rawprawda lub fałsznie—
batch_sizeliczba całkowitanie—
sort_bytekstniename

25.15.1 wzorzec

Wzorzec wybiera pliki według wzorca glob.

Pusty oznacza każdy plik.

25.15.2 katalog_błędów

ErrorDir to miejsce, gdzie trafia plik, który nie mógł być przetworzony.

Oddzielony od MoveTo celowo. Katalog zawierający tylko niepowodzenia jest czymś, co ktoś może obserwować, a mieszanie niepowodzeń z archiwum oznacza, że jedynym sposobem na ich znalezienie jest odczytanie każdego pliku.

25.15.3 surowy

Raw traktuje cały plik jako jedną wiadomość, niezależnie od zawartości.

Ustawienie, które sprawia, że ten konektor jest przydatny do czegoś innego niż HL7. Bez niego partia CSV, plik roszczenia X12 lub plik PDF jest dzielony na linie rozpoczynające się od MSH i nie produkuje nic, a komunikat o błędzie mówi, że plik nie jest HL7 - co jest prawdą, ale nie jest istotne, ponieważ plik nigdy nie miał być HL7.

25.15.4 rozmiar_partii

BatchSize określa liczbę plików, które jeden poll może odczytać.

Zero oznacza brak limitu.

Istnieje dla pierwszego pollu po awarii. Katalog zawierający czterdzieści tysięcy plików, które nagromadziły się w nocy, zostanie w przeciwnym razie odczytany w jednej passie, co utrzymuje pętlę poll przez tyle czasu, ile potrzeba, i sprawia, że kanał wydaje się zawieszony. Odczytywanie ograniczonej liczby plików na poll utrzymuje kanał responsywny i kolejkę widocznie się opróżniającą.

25.15.5 sortuj według

SortBy określa kolejność plików w ramach pollu: nazwa, modyfikowany lub żaden.

Domyślnie ustawiony na nazwę. Kolejność ma większe znaczenie, niż się wydaje: strumień ADT, w którym A08 aktualizacje przychodzą przed A01 przyjęciem, produkuje pacjentów, którzy jeszcze nie istnieją. Kolejność listy katalogu jest arbitralna w większości systemów plików, więc pozostawienie jej niesortowanej oznacza, że kolejność zmienia się między pollami bez widocznego powodu.

25.16 Dostęp do GCP

GCPAccess to sposób uwierzytelniania w Google Cloud.

Zdefiniowany jako GCPAccess w internal/config.

KluczTypWymaganyDomyślny
projecttekstnie—
credentials_filetekstnie—
endpointtekstnie—

25.16.1 plik poświadczeń

CredentialsFile to klucz JSON konta usługi.

Pusty używa konta usługi dołączonego do maszyny wirtualnej, GKE pod lub usługi Cloud Run, na której działa Perfuse (serwer metadanych), chyba że Endpoint nazwuje emulator.

25.17 Dostęp do GCS

GCSAccess to wiadro Cloud Storage.

Zdefiniowany jako GCSAccess w internal/config.

KluczTypWymaganyDomyślny
bucketteksttak—

25.18 Połączenie IBMMQ

IBMMQConnection to kolejka osiągalna za pomocą interfejsu API REST menedżera kolejki.

Zdefiniowane jako IBMMQConnection w internal/config.

KluczTypWymaganyDomyślny
urlteksttak—
queue_managerteksttak—
queueteksttak—
usernametekstnie—
passwordtekstnie—
tlstlsconf.Settings (blok, pomij to, aby wyłączyć)nie—
api_versiontekstnie—
timeoutczas trwania, np. 30s lub 5mnie30s

25.18.1 nazwa użytkownika

Nazwa użytkownika i hasło są użytkownikiem mqweb z rolą MQWebUser; hasło może być ${ENV}.

Pozostaw oba puste, gdy certyfikat klienta (tls.cert_file) uwierzytelnia.

25.18.2 hasło

Nazwa użytkownika i hasło są użytkownikiem mqweb z rolą MQWebUser; hasło może być ${ENV}.

Pozostaw oba puste, gdy certyfikat klienta (tls.cert_file) uwierzytelnia.

25.18.3 limit czasu

Limit czasu ogranicza każde żądanie.

Defaults to 30s.

25.19 Kafka SASL

KafkaSASL uwierzytelnia w klastrze Kafka.

Zdefiniowane jako KafkaSASL w internal/config.

KluczTypWymaganyDomyślny
mechanismteksttak—
usernameteksttak—
passwordteksttak—

25.19.1 mechanizm

Mechanizm to "plain", "scram-sha-256" lub "scram-sha-512".

PLAIN wysyła hasło w postaci czytelnej w sieci, więc powinno być używane z TLS. SCRAM nie, dlatego warto wymienić różnicę tutaj, zamiast traktować te trzy jako wymienne.

25.19.2 hasło

Hasło to hasło SASL.

Obsługuje odniesienia ${ENV} jak każdy inny sekret tutaj, więc poświadczenia klastra nie muszą być zapisane w pliku kanału.

25.20 Połączenie MQTT

MQTTConnection to sposób, w jaki można dotrzeć do brokera MQTT 3.1.1: Mosquitto, EMQX, HiveMQ, AWS IoT Core, Azure Event Grid.

Zdefiniowane jako MQTTConnection w internal/config.

KluczTypWymaganyDomyślny
addrteksttak—
client_idtekstnie—
usernametekstnie—
passwordtekstnie—
tlstlsconf.Settings (blok, pomij to, aby wyłączyć)nie—
qoscała liczba (blok, pomij to, aby wyłączyć)nie—
timeoutczas trwania, np. 30s lub 5mnie30s

25.20.1 client_id

ClientID nazwuje sesję.

Źródło zachowuje swoje wiadomości podczas ponownych połączeń tylko pod stałym identyfikatorem klienta; domyślnie jest to perfuse-<channel>.

25.20.2 nazwa użytkownika

Nazwa użytkownika i hasło uwierzytelniają; każde z nich może być puste.

Hasło może być ${ENV}.

25.20.3 hasło

Nazwa użytkownika i hasło uwierzytelniają; każde z nich może być puste.

Hasło może być ${ENV}.

25.20.4 limit czasu

Limit czasu wiąże łączenie i każde oczekiwanie na brokera.

Defaults to 30s.

25.21 Opcje NCPDP

NCPDPOptions to ustawienia, które dotyczą tylko kanału roszczeń aptecznych.

Zdefiniowane jako NCPDPOptions w internal/config.

KluczTypWymaganyDomyślny
transformationslista ncpdp.Stepnie—

25.21.1 transformacje

Transformacje są deklaracyjnymi zmianami stosowanymi do każdej transmisji przed dostarczeniem.

Ten sam słownik, co każdy inny format - ustaw, skopiuj, wyczyść, mapuj, zastąp, obetnij, przypadek, każdy z opcjonalnym warunkiem - ponieważ silnik krokowy w internal/steps jest ogólny. To, co się różni, to notacja: ścieżka jest zapisana jako D1 lub 07-D7, przy użyciu standardowych dwuliterowych identyfikatorów pól.

25.22 Odbiór PGP

PGPReceive otwiera to, co źródło otrzymuje za pomocą OpenPGP: odszyfrowane naszym kluczem tajnym i sprawdzane pod kątem podpisu przeciwko kluczom publicznym nadawców.

Zdefiniowane jako PGPReceive w internal/config.

KluczTypWymaganyDomyślny
decrypt_withtekstnie—
passphrasetekstnie—
verify_withlista tekstunie—
require_signaturetrue lub falsenie—
allow_unencryptedtrue lub falsenie—
pass_plaintrue lub falsenie—

25.22.1 decrypt_with

DecryptWith to plik naszego klucza tajnego.

Wymagane, chyba że allow_unencrypted jest włączone i wiadomości są tylko podpisywane.

25.22.2 passphrase

Passphrase odblokowuje DecryptWith, gdy jest chroniony.

Preferowany jest odniesienie do zmiennej środowiskowej, ${NAME}.

25.22.3 verify_with

VerifyWith to pliki kluczy publicznych nadawców.

Podpis przez któregokolwiek z nich jest sprawdzany i rejestrowany.

25.22.4 pass_plain

PassPlain pozwala na przepuszczenie wiadomości, która nie jest w ogóle PGP, bez zmian, dla folderu, który otrzymuje oba.

Wyłączone: taka wiadomość jest odrzucana, więc nadawca, który zapomniał zaszyfrować, jest informowany.

25.23 Wysyłanie PGP

PGPSend zabezpiecza to, co miejsce docelowe dostarcza za pomocą OpenPGP: szyfrowane do klucza publicznego odbiorcy, podpisywane naszym, lub oba.

Płatnicy, centra rozliczeniowe i agencje rządowe często przyjmują pliki za pomocą SFTP tylko w ten sposób.

Zdefiniowane jako PGPSend w internal/config.

KluczTypWymaganyDomyślny
encrypt_tolista tekstunie—
sign_withtekstnie—
passphrasetekstnie—
armortrue lub falsenie—
no_compresstrue lub falsenie—
file_nametekstnie—

25.23.1 encrypt_to

EncryptTo to pliki kluczy publicznych odbiorców (zabezpieczone lub binarne).

Wiadomość może być odczytana przez dowolnego z nich. Pusty: wiadomość jest tylko podpisywana.

25.23.2 sign_with

SignWith to nasz plik klucza tajnego, służący do podpisania każdej wiadomości.

Pusty: tylko szyfrowany.

25.23.3 passphrase

Hasło odblokowuje SignWith, gdy jest on chroniony.

Preferowany jest odniesienie do zmiennej środowiskowej, ${NAME}.

25.24 Konfiguracja kolejki

QueueConfig włącza trwałe kolejkowanie dla miejsca docelowego.

Bez niego, miejsce docelowe, które jest wyłączone przez dwie minuty, traci wszystko, co zostało do niego wysłane w tym czasie: ponowne próby wykonują się w pamięci, a gdy się skończą, wiadomość jest rejestrowana jako nieudana i znika. Z QueueConfig wiadomość jest na dysku i zachowuje swoją pozycję, aż odbiorca wróci.

Jest wyłączony domyślnie, co jest świadomym wyborem, a nie ostrożnością. Kolejka zmienia znaczenie potwierdzenia i zmienia zachowanie kolejności podczas awarii, a obie te rzeczy operator powinien wybrać świadomie, zamiast odkryć.

Zdefiniowany jako QueueConfig w internal/config.

KluczTypWymaganyDomyślny
enabledtrue lub falsenie—
max_attemptscała liczbanie—
backoffczas trwania, np. 30s lub 5mnie—
max_backoffczas trwania, np. 30s lub 5mnie—
max_depthcała liczbanie—
retain_hourscała liczbanie—

25.24.1 maksymalna_liczba_prób

MaxAttempts to liczba prób, jaką kolejka wykonuje, zanim oznaczy wiadomość jako nieudaną i przejdzie do następnej.

Zero oznacza nieograniczoną liczbę prób, co jest uzasadnione dla kanału, który nie może stracić niczego, ale powinno być wybrane, a nie dziedziczone.

25.24.2 max_backoff

MaxBackoff ogranicza rosnące opóźnienie.

Domyślnie jest to jedna minuta, a nie coś większego, ponieważ odbiorca, który wraca po krótkiej awarii, powinien być szybko znaleziony: godzinny limit zamienia dwuminutowy błąd w godzinę zaległości.

25.24.3 max_depth

MaxDepth odmawia nowych wiadomości, gdy jest ich tyle w oczekiwaniu, więc odbiorca, który był wyłączony przez tydzień, nie może wypełnić dysku.

Zero oznacza brak limitu.

Gdy limit zostanie osiągnięty, wiadomość jest oznaczona jako nieudana, a nie kolejkowana, a nadawca jest o tym powiadamiany — co jest uczciwą odpowiedzią, ponieważ nie obiecujemy już jej dostarczyć.

25.24.4 retain_hours

RetainHours to czas, przez jaki dostarczone i porzucone elementy są przechowywane, zanim zostaną usunięte.

Są one przechowywane, aby ktoś obserwujący spadek zaległości mógł zobaczyć, co się dzieje, oraz aby porzucona wiadomość mogła być znaleziona później.

25.25 Ponowna próba

Ponowna próba kontroluje ponowne dostarczanie po awarii.

Zdefiniowany jako Retry w internal/config.

KluczTypWymaganyDomyślny
attemptsliczba całkowitanie—
backoffczas trwania, np. 30s lub 5mnie—
max_backoffczas trwania, np. 30s lub 5mnie—

25.25.1 próby

Próby to łączna liczba prób, w tym pierwszej.

Zero oznacza wartość domyślną.

25.25.2 backoff

Backoff to czas oczekiwania przed drugą próbą.

Zwiększa się dwukrotnie za każdym razem, do MaxBackoff.

25.26 Opcje skryptu

ScriptOptions konfiguruje kanał NCPDP SCRIPT.

Dlaczego SCRIPT otrzymuje blokadę, gdy jego filtr jest na poziomie najwyższym

Filtr kanału dla każdego typu danych jest filtrem na poziomie najwyższym, ponieważ internal/expr jest ogólny dla typu wiadomości: jeden klucz, skompilowany przeciwko dowolnemu drzewu lub roszczeniu, które kanał przenosi. Kroki nie mogą być układane w ten sposób. Krok v2 odnosi się do segmentu i pola, krok X12 odnosi się do elementu o stałej szerokości, a typy są różne, więc jeden klucz yaml musiałby zawierać dowolny typ danych, co jest polem, które oznacza różne rzeczy w zależności od innego pola, a tryb awaryjny jest krokiem, który milcząco nie robi nic.

Zatem postępujemy zgodnie z hl7v3, x12, ncpdp i rozdzielonymi: kroki znajdują się w bloku formatu, a klucz transformacji na poziomie najwyższym jest odrzucany na kanale SCRIPT zamiast akceptowany i ignorowany.

Zdefiniowane jako ScriptOptions w internal/config.

KluczTypWymaganyDomyślny
transformationslista hl7v3.Stepnie—

25.26.1 transformacje

Transformacje to deklaracyjne kroki, odwołujące się do recepty jako drzewa XML.

hl7v3.Step zamiast własnego typu, i to nie jest lenistwo. Recepta i dokument v3 są oba XML, gramatyka ścieżki jest taka sama, a internal/eprescribe już pożycza hl7v3.Path dla swojego filtra z komentarzem, który tak mówi - v3 i CDA już go używają, a trzecia kopia byłaby trzecim zestawem odpowiedzi na to, co //a/b[2]@c oznacza.

Kroki, które przenoszą znaczenie tylko v3, są odrzucane podczas ładowania, zamiast być dostępne w milczeniu. nullflavor jest tym: zapisuje atrybut v3, określający, dlaczego wartość jest nieobecna, co recepta nie ma odpowiednika, a krok, który by go napisał, wyprodukowałby dokument, którego odbiorca nie rozumie.

25.27 Skrypty

Skrypty zawierają JavaScript dołączony do kanału.

Zdefiniowane jako Scripts w internal/config.

KluczTypWymaganyDomyślny
filtertekstnie—
transformertekstnie—
preprocessortekstnie—
deploytekstnie—
undeploytekstnie—
postprocessortekstnie—
languagetekstnie—
timeoutczas trwania, np. 30s lub 5mnie—
includelista tekstównie—
file_rootslista tekstównie—
allowlista tekstównie—

25.27.1 filtr

Filtr jest uruchamiany po filtrze wyrażenia, jeśli istnieje, i musi zwrócić wartość logiczną.

Skrypt filtru Mirth jest wstawiany tutaj bez zmian.

25.27.2 transformer

Transformer jest uruchamiany po deklaracyjnych krokach i może modyfikować wiadomość.

Skrypt transformer Mirth jest wstawiany tutaj bez zmian.

25.27.3 preprocesor

Preprocesor uruchamia się przed przetworzeniem wiadomości, odczytuje tekst jako „wiadomość” i zwraca tekst do przetworzenia.

Preprocesor Mirth jest tutaj umieszczony bez zmian.

To jest jedyny miejsce, w którym można naprawić wiadomość, która nie została przetworzona. Strony internetowe używają go do usunięcia zbędnych znaków z bramki szeregowej, terminatora segmentu, który przybył jako znak nowej linii lub wypełnienia pola przez dostawcę czymś nielegalnym w jego pozycji. Bez niego Perfuse odrzuca ruch, który Mirth akceptuje dzisiaj.

25.27.4 wdrożyć

Wdrożenie uruchamia się raz, gdy kanał zostaje uruchomiony, przed zaakceptowaniem jakichkolwiek danych.

To jest miejsce, w którym strony internetowe mogą rozgrzać pamięć podręczną wyszukiwania lub sprawdzić, czy coś, na czym polegają, jest dostępne. Uruchamia się ono przed powiązaniem źródła, więc skrypt wdrożeniowy, który nie powiedzie się, zatrzymuje kanał przed rozpoczęciem, zamiast pozwolić mu zaakceptować wiadomości, których nie może obsłużyć.

25.27.5 wycofać

Wycofanie uruchamia się raz, gdy kanał zostaje zatrzymany.

Po zatrzymaniu źródła i po zakończeniu przetwarzania wiadomości w locie, więc widzi kanał, który jest naprawdę bezczynny. Jego awaria nie może zatrzymać zatrzymania: kanał, który nie mógł być zamknięty, ponieważ skrypt czyszczenia wyrzucił wyjątek, byłby gorszy niż ten, który zalogował i zamknął.

25.27.6 postprocesor

Postprocesor uruchamia się po przetworzeniu wiadomości i nie może jej zmienić.

Wiadomość i to, co się z nią stało, są widoczne, więc może powiadomić, policzyć lub zarejestrować. Nie może zmienić tego, co zostało wysłane: w momencie, gdy jest uruchamiany, wysyłanie już się odbyło, a skrypt, który wydawał się zmieniać dostarczoną wiadomość, kłamałby na jej temat.

25.27.7 język

Język to język skryptowy, w którym te skrypty są napisane: javascript lub lua.

Dlaczego jeden ustawienie dla całego bloku zamiast jednego na skrypt

Skrypty kanału współdzielą mapę kanału i mapę łącznika, i są odczytywane razem przez tego, kto je utrzymuje. Filtrowanie w Lua obok transformatora w JavaScript oznaczałoby dwa języki w jednym przeglądzie, współdzielące stan przez mapę, której wartości musiałyby mieć takie same znaczenie w obu. Strony, które chcą tego, mogą podzielić kanał.

Dlaczego domyślnie jest to javascript

Każdy skrypt napisany przed istnieniem tego ustawienia jest napisany w JavaScript i nie mówi nic o swoim języku. Ustawienie lua jako domyślne spowodowałoby ciche przetłumaczenie wszystkich skryptów; wymaganie pola odmówiłoby im. Żadne z nich nie jest akceptowalne dla ustawienia dodanego później.

25.27.8 limit czasu

Limit czasu ogranicza każdy skrypt.

Zero oznacza pięć sekund.

Nie ma celowo żadnego sposobu, aby go wyłączyć. Mirth pozwala transformatorem na pętle bez końca, co zatrzymuje kanał, a interfejs, który przestaje akceptować przyjęcia z powodu literówki, nie jest czymś, co można zaoferować jako opcję.

25.27.9 dołączyć

Dołączanie nazw plików udostępnia wspólny kod źródłowy skryptu dostępnego dla każdego skryptu na tym kanale, w języku, który nazwę języka określa skrypty.język.

To są szablony kodu Mirth. Strona z czterdziestoma kanałami zwykle ma jedną bibliotekę, do której odwołuje się każdy kanał, a bez niej migracja oznacza kopiowanie tej biblioteki do czterdziestu plików - czterdziestu miejsc do naprawy następnym razem, gdy się zmieni.

Ścieżki są względne w stosunku do pliku kanału, więc biblioteka obok kanałów podróżuje z nimi. Jest to lista, ponieważ alternatywą jest jeden ogromny plik, a biblioteki mają tendencję do dzielenia się według tematu.

Pliki muszą być w języku kanału. Było to tylko JavaScript przez jakiś czas, i nie z powodu odmowy: kanał Lua odczytywał pliki, odmawiał brakującego, a następnie środowisko uruchomieniowe nie instalowało żadnego z nich, więc każde wywołanie biblioteki kończyło się niepowodzeniem przy pierwszej wiadomości z nil global - dokładnym błędem, którego uniknięcie jest celem odmowy powyżej. Obecnie oba języki instalują bibliotekę, a biblioteka, która nie jest analizowana, jest odrzucana podczas ładowania z nazwą pliku.

25.27.10 file_roots

FileRoots to katalogi, do których FileUtil może odczytywać i zapisywać.

Wymagane zawsze, gdy „file” jest dozwolone. Udzielanie dostępu do plików bez określania katalogów oznaczało wcześniej cały system plików: skrypt mógł odczytać własną bazę danych Perfuse, która zawiera hashe haseł, hasło konta usługi LDAP i sekret klienta OIDC. Tworzenie kanału wymaga tylko roli edytora, więc eskalacja została ukończona w momencie, gdy administrator go uruchomił.

25.27.11 allow

Allow udziela możliwości skryptowi, które w przeciwnym razie zostałyby odrzucone: „file”, „database”, „route”.

Mirth udziela wszystkich tych uprawnień każdemu skryptowi; wymaganie, aby były one określone, oznacza, że transformer nie może cicho zacząć odczytywać systemu plików po kopiowaniu i wklejaniu.

25.28 Cień

Shadow uruchamia kandydującą wersję kanału obok wersji live i raportuje, gdzie się różnią.

To jest odpowiedź na pytanie, które sprawia, że praca z interfejsem jest przerażająca: jak można wiedzieć, czy zmiana jest bezpieczna? Nie poprzez czytanie jej. Transformacja jest programem działającym na wiadomościach, których różnorodność nikt nie skatalogował, a przypadek, który ją łamie, jest zawsze tym, o którym nikt nie pomyślał - pacjent z dwoma identyfikatorami, wynik z pustym polem jednostek, A08, który przychodzi przed A01.

Test kanału dowodzi przypadków, o których ktoś pomyślał. Tryb shadow dowodzi przypadków, które naprawdę przychodzą, w stosunku do rzeczywistego ruchu, zanim zmiana przeniesie którąkolwiek z nich.

Dwie właściwości sprawiają, że jest to bezpieczne, a obie są strukturalne, a nie konfigurowalne:

Zdefiniowane jako Shadow w internal/config.

KluczTypWymaganeDomyślne
channelteksttak—
sampleliczbanie1
comparelista tekstównie—
ignorelista tekstównie—
max_differencescała liczbanie100
timeoutczas trwania, np. 30s lub 5mnie5s

25.28.1 channel

Channel to ścieżka do pliku kanału kandydującego.

Oddzielny plik, a nie blok wstawiony, celowo: kandydat ma zostać kanałem live, więc powinien być artefaktem, który jest przeglądany, zatwierdzany i promowany, a nie fragmentem, który musi być wyodrębniony.

25.28.2 sample

Sample to ułamek wiadomości do shadow, od 0 do 1. Domyślnie jest to 1.

Wartość tę należy obniżyć tylko na zajętym kanale, a warto zrozumieć ją przed tym: próbkowanie redukuje koszt i redukuje ufność w dokładnie tej samej proporcji, a wiadomość, która pokazałaby różnicę, jest niezwykła.

25.28.3 compare

Compare ogranicza porównanie do tych ścieżek pól.

Puste porównuje wszystko.

25.28.4 ignore

Ignoruj wykluczone ścieżki z porównania.

Potrzebne w praktyce, ponieważ kanał, który dodaje znacznik czasu lub numer sekwencyjny, różni się w każdej wiadomości i zgłaszałby wskaźnik różnic na poziomie 100%, nie dostarczając przy tym żadnych przydatnych informacji.

25.28.5 max_differences

MaxDifferences określa liczbę różniących się wiadomości, które są przechowywane do inspekcji.

Defaults to 100.

25.28.6 limit czasu

Limit czasu określa jeden przebieg cienia.

Defaults to 5s.

Oddzielony od limitu czasu kanału, i krótszy. Kandydat z zabugowanym skryptem nie powinien gromadzić goroutine'ów za ruchem na żywo.

25.29 Kod XDS

XDSCode to zakodowana wartość w ustawieniach miejsca przeznaczenia: kod, schemat kodowania (OID) i wyświetlanie.

Zdefiniowane jako XDSCode w internal/config.

KluczTypWymaganyDomyślny
codeteksttak—
schemeteksttak—
displaytekstnie—

26 Jak działa każdy komponent

Perfuse jest zbudowany z małych pakietów, z których każdy ma jeden cel. Rozdział ten jest opisem każdego z nich, w którym opisano, co robi i dlaczego jest zbudowany w taki, a nie inny sposób, przy czym opis pochodzi z samego źródła. Gdzie decyzja ma powód, który nie jest oczywisty, powód ten jest tu podany, zamiast w wiadomości commit, której nikt nie znajdzie.

26.1 fhir

Pakiet fhir implementuje zasoby FHIR, serializację i walidację.

Obsługa wersji jest pierwszą decyzją projektową, ponieważ sam „FHIR” nie identyfikuje formatu przesyłanego. R5 jest najnowszym opublikowanym wydaniem i jest domyślnym wydaniem tutaj. R4 to to, co instalowana baza i amerykańskie przepisy regulacyjne rzeczywiście konsumują, więc jest w pełni obsługiwane, a nie traktowane jako starsze. R6 jest w głosowaniu w momencie pisania i został celowo niezaimplementowany: wysyłanie zgadywanej, nieopublikowanej specyfikacji byłoby gorsze niż jej niewspieranie.

Model zasobu jest ukształtowany jak R5. Tam, gdzie R4 się różni, różnica jest stosowana podczas serializacji, a nie poprzez przechowywanie dwóch równoległych zestawów struktur, co jest sposobem, w jaki kod źródłowy kończy się z dwoma subtelnie rozbieżnymi definicjami Pacjenta.

Source: github.com/biodream-llc/perfuse/fhir

26.2 główny

Polecenie xmlordergen zapisuje kolejność elementów FHIR XML, z pakietu core StructureDefinitions.

go run ./fhir/xmlordergen hl7.fhir.r4.core-4.0.1.tgz | gzip -9 -n > fhir/xmlorder_r4.txt.gz

Obiekty JSON mogą zawierać swoje elementy w dowolnej kolejności; XML nie: każdy element musi pojawić się w kolejności określonej przez jego definicję. Każda linia wyjściowa jest ścieżką i jej dziećmi w tej kolejności, każde dziecko z informacjami, jak znaleźć swoje własne dzieci: "@Ścieżka" (element zdefiniowany w linii, kręgosłup), "#Ścieżka" (ten sam co inny element), lub jego typy.

Source: github.com/biodream-llc/perfuse/fhir/xmlordergen

26.3 hl7

Pakiet hl7 odczytuje wiadomości HL7 w wersji 2.

Nie ma zależności poza standardową biblioteką, a test wymusza to. Nie wykonuje operacji wejścia/wyjścia sieciowego, nie zapisuje plików i nie uruchamia goroutine'ów, więc można go bezpiecznie używać z dowolnego miejsca.

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”

Ścieżki są notacją, której ludzie już używają, gdy mówią o HL7: segment, pole, a następnie opcjonalny komponent i podkomponent, jak na przykład PID-5.1 lub OBX-5.2.3. Powtórzenia są adresowane za pomocą nawiasów kwadratowych, jak na przykład PID-3[2].1.

Get zwraca błąd dla ścieżki, którą nie może sparsować; MustGet zwraca pusty ciąg zamiast tego. Obie są bezpieczne w przypadku braku segmentów i pól, ponieważ prawdziwy kanał jest pełen obu i parser, który panikuje na brakujące dane, jest bezużyteczny w tym zadaniu. Brak jest nie błędem — wiadomość, która po prostu nie zawiera PID-8, zwraca „” zamiast awarii.

Brak i pusty

HL7 rozróżnia pole, które nie zostało wysłane, od pola, które zostało wysłane celowo puste, a klinicznie mogą one oznaczać różne rzeczy - „brak zarejestrowanych alergii” nie jest tym samym co „brak znanych alergii”. Value.Exists raportuje różnicę tam, gdzie wywołujący ją potrzebują, podczas gdy String spłaszcza oba do „” w przypadku typowym.

Kopiowanie i jeden sposób, aby to źle zrobić

Parse kopiuje swój wejście, więc zwrócony Message pozostaje ważny, niezależnie od tego, jak nadawca ponownie wykorzystuje swoją buforowaną pamięć. To kosztuje około 3% i jeden przydział na wiadomość.

WithZeroCopy pomija kopię i zamiast tego przechowuje odniesienie do fragmentu nadawcy. Jest szybszy i sprawia, że Message jest niebezpieczny do użycia po ponownym zapisie tego fragmentu. Odczyt do ponownie wykorzystanego bufora jest normalnym, wydajnym sposobem odczytu z sieci w Go, więc pułapka łapie staranne kodowanie, a objawem jest cichy, błędny wartość pola zamiast błędu - dane jednego pacjenta pod nazwą innego pacjenta. Używaj go dla danych wejściowych, które są niezmienne lub przetrwają Message, i nie w innych przypadkach.

Acknowledgements

AckFor tworzy ACK lub NAK dla wiadomości, w tym dla tej, która nie powiodła się podczas parsowania, co jest przypadkiem, który ma największe znaczenie: nadawca potrzebuje odpowiedzi, nawet jeśli to, co wysłał, nie było wiadomością. Zobacz AckOptions.

Co ten pakiet nie robi

Nie zapisuje ani nie modyfikuje wiadomości. Nie ma pojęcia o strukturze wiadomości poza segmentami, więc nie powie Ci, że PV1 należy do określonej grupy wizyt. Nie waliduje przeciwko tabelom wersji. Są to celowe pominięcia, a nie przeoczenia: jest to indeksator dla rzeczywistego ruchu, który często nie jest zgodny ze standardem i musi być nadal kierowany.

Source: github.com/biodream-llc/perfuse/hl7

26.4 przyjmij

Pakiet przyjmij ogranicza ilość pracy w locie na raz.

Silnik uruchamia goroutine na cel na wiadomość. Goroutine są tanie; to, co trzymają, nie jest. Każda wysyłka na zewnątrz trzyma gniazdo na końcu dalekim i opisnik pliku tutaj, i trzyma je przez cały budżet ponownych prób - z ustawieniami domyślnymi, pięć prób z limitem czasu trzydziestu sekund plus piętnaście sekund zwrotu, czyli prawie trzy minuty. Kilka setek nadawców przeciwko jednemu odbiorcy, który ucichł, jest więc kilkoma setkami opisników trzymanych przez minuty, i proces kończy się niepowodzeniem.

Kończenie się jest awarią, której warto zapobiec, ponieważ nie pojawia się tam, gdzie występuje. Pojawia się jako "za dużo otwartych plików" w miejscu niezwiązanym: baza danych nie może otworzyć swojego dziennika, interfejs przestaje akceptować, log nie może być zapisany. Silnik wygląda na uszkodzony w trzech miejscach na raz i przyczyną jest system partnerski, który przestał odpowiadać.

Dwa limity, a drugi ma większe znaczenie niż pierwszy:

Całkowity, aby proces pozostał w ramach swojego budżetu opisników.

Limit na cel, aby jeden odbiorca nie mógł zużyć całości. Bez niego jeden zawieszony partner powoduje awarię wszystkich innych kanałów, co jest gorsze niż brak limitu w ogóle: promień rażenia rośnie z jednego interfejsu do wszystkich.

Source: github.com/biodream-llc/perfuse/internal/admit

26.5 alarmy

Pakiet alarmy obserwuje metryki i mówi, kiedy coś jest nie tak.

Chodzi o to, że nikt nie powinien musieć patrzeć na pulpit. "Transakcje nieudane pozostają w kolejce bez terminowego zbadania" to udokumentowane awarie operacyjne w tym rodzaju oprogramowania, a powodem jest zawsze to samo: informacje były na ekranie, przed którym nikt nie stał o czwartej rano.

Trzy decyzje kształtują to.

Alarm musi sam się wyłączyć. Powiadomienie, które uruchamia się i nigdy nie rozwiązuje, szkoli ludzi do ignorowania powiadomień. Każda reguła tutaj jest oceniana w odniesieniu do bieżącego stanu, więc powracający odbiorca zamyka alarm, który otworzył.

Alarmy są tłumione przez czas trwania, a nie przez liczbę. "Współczynnik błędów powyżej 5% właśnie teraz" uruchamia się na jednej niefortunnej wiadomości podczas cichej godziny. "Powyżej 5% przez dwie minuty" nie. Każda reguła zawiera czas trwania i nic nie uruchamia się, dopóki stan nie utrzyma się przez ten czas.

To, co jest wysyłane, nie zawiera danych pacjenta. Alarm zawiera nazwę kanału, nazwę celu, liczbę i próg. Pochodzą one z konfiguracji i z liczenia. Webhook idzie do pokoju czatu, pokój czatu ma przewijany tekst, a przewijany tekst nie jest miejscem, gdzie powinien się znaleźć identyfikator pacjenta.

Source: github.com/biodream-llc/perfuse/internal/alerts

26.6 amqp

Pakiet amqp jest klientem AMQP 1.0: jeden połączenie, jeden sesja, łącza wysyłające i odbierające, ustalone po tym, jak odbiorca to potwierdzi.

AMQP 1.0 to to, co Azure Service Bus i Event Hubs mówią, co RabbitMQ 4 mówi rodzinnie, i co ActiveMQ i Artemis mówią obok STOMP. Napisane tutaj z tego samego powodu, dla którego klient STOMP i sygnatariusz AWS: pełna biblioteka klienta byłaby większością listy zależności binarnych dla czterech performatyw, które mają znaczenie.

Co robi: SASL PLAIN lub ANONYMOUS (Service Bus przyjmuje nazwę i klucz dostępu współdzielonego jako PLAIN), TLS, otwórz/rozpocznij/dołącz, przepływ oparty na kredytach, transfer podzielony na ramki, gdy przekracza maksymalny rozmiar ramki peerów, i dyspozycje - zaakceptowane, wydane, odrzucone. Nadawca czeka na dyspozycję brokera przed zgłoszeniem powodzenia, więc "wysłane" oznacza, że broker przyjął opiekę. Puste ramki utrzymują połączenie żywe wewnątrz limitu czasu bezczynności peerów, który Service Bus egzekwuje.

Co nie robi: transakcje, wiele sesji, odzyskiwanie łączy i adnotacje wiadomości poza ich odczytem.

Source: github.com/biodream-llc/perfuse/internal/amqp

26.7 analizuj

Pakiet analyze przekształca sparsowany kanał Mirth w coś, co człowiek może wykorzystać: zwykły opis tego, co robi kanał, oraz szczery wykaz tego, co nie przetrwa migracji.

Zasada projektowa polega na tym, że wynik musi być wystarczająco szczegółowy, aby można było go wykorzystać. „Ten kanał używa JavaScript” to nie jest wynik. „Destynacja 1 wywołuje java.util.Date, które nie ma odpowiednika poza JVM” to jest.

Source: github.com/biodream-llc/perfuse/internal/analyze

26.8 api

Pakiet api obsługuje interfejs HTTP wykorzystywany przez interfejs sieciowy.

Istotny ogranicznik projektowy: kanały są odczytywane z plików na dysku i zapisywane do plików na dysku. Interfejs API jest edytorem tych plików, a nie oddzielnym systemem przechowywania, który zdarza się wyeksportować w formacie YAML. Kanał utworzony w przeglądarce i jeden napisany ręcznie są tym samym artefaktem, co sprawia, że „eksport do udostępnienia” jest trywialny i zachowuje git jako historię rekordu.

Source: github.com/biodream-llc/perfuse/internal/api

26.9 as2

Pakiet as2 jest Applicability Statement 2 (RFC 4130): EDI przez HTTP, podpisywany i szyfrowany za pomocą S/MIME, z podpisem potwierdzenia (MDN), który nazywa skrót tego, co dotarło.

Płatnicy i partnerzy handlowi wykorzystują go do X12 i EDIFACT.

S/MIME jest wewnętrzny/cms, ten sam kod, który wykorzystuje Direct messaging. To, co jest tutaj, jest własne AS2: jego nagłówki, sprawdzenie integralności wiadomości (MIC) i potwierdzenie.

Source: github.com/biodream-llc/perfuse/internal/as2

26.10 attach

Pakiet attach przenosi duże ładunki poza wiadomość i umieszcza je z powrotem.

Wiadomość HL7 zawierająca zeskanowany raport lub plik PDF jest zwykła w przepływach dokumentów, a ładunek jest rutynowo setki razy większy niż sama wiadomość. Przechowywanie go w linii oznacza, że magazyn wiadomości rośnie w tempie dokumentów, a nie ruchu, wiadomość oczekująca w kolejce dla pięciu destynacji jest kopiowana pięć razy, a interfejs musi przesyłać megabajty, aby pokazać komuś nazwę pacjenta.

Zatem ładunek jest wyodrębniony, przechowywany raz według zawartości i zastępowany w wiadomości tokenem. Mirth nazywa to attachment handlers i jest to udokumentowana funkcja migracji, dlatego format tokena jest zaprojektowany tak, aby był rozpoznawalny, a nie mądry.

Co ten pakiet nie decyduje

Nie wykonuje on przechowywania i we/wy. Wyodrębnienie produkuje przepisaną wiadomość i ładunki; magazyn w innym miejscu decyduje, gdzie one trafiają. To rozdzielenie sprawia, że test wyodrębnienia jest wykonalny bez bazy danych, a także pozwala na uruchomienie tej samej logiki w środowisku WASM, gdzie nie ma bazy danych w ogóle.

Source: github.com/biodream-llc/perfuse/internal/attach

26.11 authlimit

Pakiet authlimit ogranicza nieudane próby uwierzytelnienia według adresu źródłowego.

Istnieje, ponieważ dwie nasłuchiwania potrzebowały tego samego i jedna z nich nie miała nic. Serwer FHIR otrzymał ogranicznik, gdy otrzymał uwierzytelnienie; logowanie do konsoli nie miało nic, a pomiary wykazały dwadzieścia prób hasła na sekundę wobec konta administratora bez opóźnienia i bez blokady. W tym tempie słabe hasło jest tracone w ciągu nocy, a jedyną śladem jest log pełen identycznych ostrzeżeń.

Celowo nie jest to ogólny ogranicznik tempa. Ogranicza niepowodzenia, a nie żądania: zajęty, prawidłowy klient nie jest nigdy dotknięty, a jedyną rzeczą, która się kumuluje, jest to, że jest błędny.

Source: github.com/biodream-llc/perfuse/internal/authlimit

26.12 awsmsg

Pakiet awsmsg komunikuje się z Amazon SQS i SNS za pomocą standardowej biblioteki i współdzielonego podpisu w wersji 4.

Ten sam argument, co w przypadku s3put: zestaw SDK AWS podwoiłby rozmiar listy materiałów dla czterech wywołań API. SQS wykorzystuje swój protokół JSON (AWS JSON 1.0, X-Amz-Target AmazonSQS.<Action>), który AWS dokumentuje jako bieżący; SNS wykorzystuje swój protokół zapytań, który jest jedynym, jaki posiada. Oba działają wobec LocalStack i punktów końcowych VPC za pomocą zastępczego punktu końcowego.

Source: github.com/biodream-llc/perfuse/internal/awsmsg

26.13 awsv4

Pakiet awsv4 podpisywuje żądania do AWS za pomocą podpisu w wersji 4, wykorzystując tylko standardową bibliotekę.

Zaczął się wewnątrz s3put. SQS, SNS i odczyt z S3 wymagają tego samego podpisu z inną nazwą usługi i z ciągiem zapytania, a druga kopia kodu podpisu byłaby drugim miejscem, w którym może wystąpić błąd - niezgodność podpisu odczytuje się dokładnie jak błędne poświadczenia. Dlatego też znajduje się tutaj, sprawdzony wobec opublikowanych wektorów testowych AWS, a każdy łącznik AWS wykorzystuje go.

Poświadczenia są statycznymi kluczami lub standardowymi zmiennymi środowiskowymi. Nie ma łańcucha poświadczeń instance-metadata, co oznacza wywołania IMDS, buforowanie i odświeżanie, co powoduje, że mała implementacja przestaje być mała, a Perfuse odmawia adresów metadanych jako miejsc docelowych domyślnie.

Source: github.com/biodream-llc/perfuse/internal/awsv4

26.14 azblob

Pakiet azblob odczytuje i zapisuje Azure Blob Storage za pomocą standardowej biblioteki: autoryzacja Shared Key lub SAS za pośrednictwem połączeń HTTP.

Ten sam powód co s3put: zestaw SDK Azure jest duży, a operacje potrzebne silnikowi integracji to pięć - umieszczenie, pobranie, lista, usunięcie i ustawienie poziomu dostępu. Podpisywanie klucza współdzielonego jest określone dokładnie („Autoryzuj za pomocą klucza współdzielonego”, Azure Storage REST), a Azurite, emulator Microsoftu, sprawdza to w taki sam sposób, jak usługa.

Source: github.com/biodream-llc/perfuse/internal/azblob

26.15 branding

Pakiet branding przechowuje logo i nazwę produktu klienta, aby instalacja mogła przedstawiać się jako ich własny produkt, a nie jako Perfuse.

Dlaczego logo nie jest ustawieniem

Wszystko inne, co operator może zmienić, jest skalarem w pliku ustawień. Logo to kilkaset kilobajtów danych binarnych, a umieszczenie go tam oznaczałoby base64 w pliku YAML, który osoba ma możliwość odczytać i edytować ręcznie. Zamiast tego znajduje się obok tego pliku, a tylko jego obecność jest widoczna za pośrednictwem powierzchni ustawień.

Część, która ma znaczenie: przesłany obraz jest niezaufanym wejściem

Logo jest przesyłane przez administratora, a następnie udostępniane każdej przeglądarce, która ładuje konsolę, w tym na stronie logowania przed uwierzytelnieniem. To sprawia, że jest to najbardziej rozpowszechniony element zawartości dostarczony przez atakującego w produkcie, więc jest traktowany odpowiednio:

Source: github.com/biodream-llc/perfuse/internal/branding

26.16 cda

Pakiet cda odczytuje dokumenty kliniczne.

Projekt zaczyna się od tego, jak te dokumenty rzeczywiście podróżują, co nie jest jako pliki. Podsumowanie wyładowania opuszcza EHR wewnątrz wiadomości HL7 v2 MDM^T02, z całym dokumentem zakodowanym w base64 w OBX-5 i opisanym przez segment TXA. To jest tysiące wiadomości dziennie w średnim szpitalu, i to dlatego ten pakiet znajduje się obok parsera HL7 v2, a nie w zestawie narzędzi dokumentowych: połowa v2 jest już tutaj, więc potok od „wiadomość przybyła” do „FHIR DocumentReference istnieje” jest krótki.

Trzy rzeczy są celowo w zakresie, a jedna jest celowo poza zakresem.

W zakresie: odczytanie dokumentu i powiedzenie, co on zawiera w prostych słowach; sprawdzenie, czy ludzkie narracje i wpisy zakodowane są zgodne; oraz konwersja do FHIR. Sprawdzenie narracji jest tym niezwykłym. Każdy sekcja C-CDA przenosi tę samą informację dwa razy, raz jako tekst dla klinicysty i raz jako kod dla maszyny, i mają one być zgodne. W praktyce często nie są, i nic nie sprawdza tego - nie narzędzia certyfikacji, nie silniki. Kiedy tekst mówi, że pacjent jest uczulony na penicylinę, a wpis zakodowany mówi coś innego, jeden z dwóch czytelników działa na podstawie błędnej informacji. To jest wada bezpieczeństwa pacjenta, która jest mechanicznie wykrywalna, więc jest wykrywana tutaj.

Poza zakresem: generowanie zgodnych C-CDA. Pisanie jednego oznacza spełnienie kilkuset reguł szablonu i Schematron, oraz wytwarzanie dokumentów, które są 95% prawidłowe, ale nie przeszłyby certyfikacji w sposób, który byłby okropny do debugowania. Odczyt, sprawdzenie i konwersja to największa część wartości dla ułamka ryzyka.

Source: github.com/biodream-llc/perfuse/internal/cda

26.17 channeltest

Pakiet channeltest uruchamia testy przeciwko definicji kanału.

Kanał jest programem. Filtruje, przepisuje i kieruje wiadomościami klinicznymi i jest edytowany pod presją przez ludzi, którzy nie mogą go przetestować przeciwko produkcji. Brak sposobu testowania jest największym powodem, dla którego praca z interfejsami jest straszna, a „zmieniłem transformer i nic nie wyglądało inaczej w przeglądarce wiadomości” nie jest testem.

Główna decyzja jest taka, że test uruchamia wiadomość przez rzeczywistą ścieżkę transformacji — ten sam filtr, te same kroki deklaracyjne, ten sam silnik skryptowy, w tym samym porządku — z zastąpionym tylko transportem. Test, który ćwiczyłby ponowną implementację, przeszedłby, podczas gdy kanał awarii, co gorsze, niż brak testu w ogóle, ponieważ aktywnie wprowadza w błąd.

Source: github.com/biodream-llc/perfuse/internal/channeltest

26.18 chanscope

Pakiet chanscope zawęża odczyty i zapisy na kontekście do niektórych kanałów.

Zależy to od kontekstu, a nie jest parametrem każdego zapytania, ponieważ istnieją dziesiątki zapytań w sklepie wiadomości i kolejce dostarczania, a limit jest właściwością tego, kto pyta, a nie pytania. Interfejs API ustawia go raz na żądanie dla osoby ograniczonej do niektórych grup kanałów; każde liczenie, lista, wykres, wyszukiwanie i działanie kolejki zgadza się z innymi, więc nikt nie jest informowany o łącznej liczbie czterdziestu niepowodzeń i nie jest wyświetlany czwórka.

Source: github.com/biodream-llc/perfuse/internal/chanscope

26.19 klaster

Pakiet klaster pozwala kilku serwerom Perfuse dzielić jeden magazyn PostgreSQL i decydować, które z nich uruchamiają co.

Problem, który rozwiązuje

Jeden serwer to jeden punkt awarii: gdy zatrzymuje się, zatrzymuje się każde interfejs. Dwa serwery na jednej bazie danych rozwiązują ten problem tylko wtedy, gdy nigdy nie uruchamiają tego samego kanału, ponieważ dwa nasłuchiwacze MLLP na jednym kanale na przemian z nadawcą, dwa pracownicy kolejki dostarczają tę samą wiadomość dwa razy, a dwa ankieterzy DICOM zgłaszają ten sam przebieg.

How

Lease to wiersz określający, kto posiada coś, z licznikiem, który jego posiadacz przesuwa przy każdym odnowieniu, co kilka sekund. Żaden zegar nie jest porównywany z innym: posiadacz, który nie może odnowić (awaria, odcięcie od bazy danych), zatrzymuje to, co objęte lease, gdy jego własny zegar sygnalizuje, że lease jest prawie gotowy, a inny serwer przejmuje je tylko po tym, jak jego własny zegar obserwował licznik przez cały lease. Każdy mierzy przedział czasu na własnym zegarze, więc zegary serwerów i bazy danych nie muszą się zgadzać; muszą tylko działać w przybliżeniu z tą samą szybkością. Zegar, który skacze (wirtualna maszyna resynchronizuje, administrator ustawia czas), nie zmienia nic: pierwsza wersja używała zegara bazy danych do wygaśnięcia, a test wykazał bazę danych, której zegar skoczył trzynaście sekund i przekazał każdy lease nowemu serwerowi, podczas gdy stare serwery nadal je uruchamiały.

Pomiędzy zatrzymaniem posiadacza a rozpoczęciem przez następnego istnieje krótka luka z nikim, kto nie uruchamia, co kosztuje nadawcę kilka sekund odmówionych połączeń i nigdy nie chwili z dwoma.

Two modes:

Każdy lease zawiera epokę, liczoną w górę za każdym razem, gdy jego posiadacz się zmienia, co nazywa posiadaniem w historii.

Source: github.com/biodream-llc/perfuse/internal/cluster

26.20 cms

Pakiet cms jest Cryptographic Message Syntax (RFC 5652) w postaci S/MIME i Direct secure messaging: SignedData (sygnuj wiadomość, zweryfikuj ją i powiedz, kto ją podpisał) i EnvelopedData (zaszyfruj wiadomość do certyfikatów odbiorców, odszyfruj ją naszym kluczem).

Tylko to, co wymaga Direct Applicability Statement i jego Implementation Guide: RSA z SHA-256 (SHA-1 akceptowane tylko do odczytu, ponieważ starsze HISPs nadal je wysyłają), transport klucza RSA z PKCS#1 v1.5 lub OAEP, oraz AES-128 lub AES-256 w trybie CBC. Kryptografia jest standardową biblioteką; ten pakiet jest ASN.1 wokół niej.

Source: github.com/biodream-llc/perfuse/internal/cms

26.21 cms0057

Pakiet cms0057 zawiera płatnicze części reguły CMS Interoperability i Prior Authorization (CMS-0057-F), które dotyczą danych, a nie transportu: rozliczone roszczenia jako zasoby CARIN Blue Button ExplanationOfBenefit, uprzednie autoryzacje jako zasoby Da Vinci PDex ExplanationOfBenefit, dopasowanie członków HRex do API Payer-to-Payer, lista członków za API Provider Access i metryki uprzedniej autoryzacji, które płatnik musi publikować co roku.

Punkty końcowe FHIR, które obsługują te elementy, znajdują się w fhirserver; ten pakiet decyduje, co się w nich znajduje.

Leki są poza zakresem przez cały czas, tak jak w postanowieniach dotyczących uprzedniej autoryzacji reguły: brak ExplanationOfBenefit dla apteki, brak formularza, brak NCPDP.

Source: github.com/biodream-llc/perfuse/internal/cms0057

26.22 codeset

Pakiet codeset zawiera tabele mapowania, które przetrwają kanał, który ich najpierw potrzebował.

Podatkowanie domeny polega głównie na ponownym pochodzeniu mapowania, które ktoś już wyprowadził. Kody płci, klasy pacjentów, statusy zamówień i identyfikatory obiektów w każdym kanale, który ich dotyka, są tłumaczone w ten sam sposób, a dziś każde z tych tłumaczeń jest oddzielną tabelą wewnątrz oddzielnego kanału. Czterdzieści kanałów oznacza czterdzieści kopii i czterdzieści miejsc do naprawy następnym razem, gdy system odbiorczy ulegnie zmianie.

Więc tabela staje się obiektem nazwanym, odniesionym przez nazwę. Tyle jest oczywiste i jest to mniejsza połowa wartości.

Połowa, której nikt nie buduje

Większa połowa to pochodzenie. Większość tego, co sprawia, że interfejs jest trudny do utrzymania, nie jest mapowaniem - jest to to, że nikt nie wie *dlaczego*. „Usuńmy wiodące zera, ponieważ kolumna MRN laboratorium jest numeryczna” jest wiedzą, która istnieje w głowie jednej osoby i opuszcza budynek, gdy osoba ta odchodzi na emeryturę, a pozostałe mapowanie staje się czymś, czego nikt nie odważy się zmienić i nikt nie odważy się usunąć.

Więc każda tabela rejestruje, kto zdecydował i kiedy, każdy wpis może rejestrować własny powód, a oba przetrwają do pliku, który trafia do kontroli wersji. Mapowanie z powodem może być argumentowane. Mapowanie bez powodu staje się superstycją.

Dlaczego plik jest oddzielony od kanału

Ponieważ jest współdzielony. Tabela w kanale jest tabelą, którą może używać tylko ten kanał, co jest problemem. I współdzielona tabela wymaga własnej historii: „kto zmienił mapowanie płci i kiedy” to pytanie o tabelę, a nie o kanał, który akurat był edytowany tego dnia.

Source: github.com/biodream-llc/perfuse/internal/codeset

26.23 zgodność

Pakiet zgodności implementuje przepływ pracy powiadomień o zdarzeniach ADT CMS wymagany przez 42 CFR 482.24(d) od maja 2021.

Szpitale muszą elektronicznie powiadamiać ustanowionych dostawców pacjentów — lekarzy pierwszego kontaktu, specjalistów, placówek opieki poacute — gdy pacjent jest przyjęty, wypisany lub przeniesiony. Regulacja ta istnieje, ponieważ pacjenci wpadają w lukę podczas przejść: lekarz pierwszego kontaktu, który nie wie o wypisie, nie może zaplanować wizyty follow-up, która zapobiega ponownemu przyjęciu.

Ten pakiet zapewnia mechanizm do: - śledzenia, którzy dostawcy są ustanowieni dla każdego pacjenta. - kierowania zdarzeń ADT do odpowiednich dostawców o odpowiedniej priorytecie. - rejestrowania każdego wysłanego powiadomienia, ze statusem dostarczenia, do audytów ankieterów CMS. - generowania raportów zgodności pokazujących wskaźniki powiadomień i niepowodzeń.

Wymagana jest bezpieczeństwo wątku w całym procesie, ponieważ wiadomości ADT przychodzą jednocześnie z wielu kanałów i potok powiadomień działa równolegle.

Source: github.com/biodream-llc/perfuse/internal/compliance

26.24 config

Pakiet konfiguracji ładuje definicje kanałów z plików.

Konfiguracja znajduje się w plikach, a nie w bazie danych, co jest główną różnicą między Perfuse a Mirth. Mirth przechowuje kanały w swojej własnej bazie danych, dlatego kontrola wersji jest oddzielnym produktem, dlatego promowanie kanału z testu do produkcji jest trudne, i dlatego nikt nie może odpowiedzieć na pytanie „co się zmieniło w zeszłym tygodniu” bez połączenia z pomocą techniczną. Pliki dają git, diffs, przegląd, CI i promocję środowiska bez dodatkowych maszyn.

Walidacja jest celowo ścisła i występuje podczas ładowania: nieznane pola są błędem, wyrażenia filtrujące są kompilowane, adresy są sprawdzane. Kanał, który nie może być zrozumiany, musi odmówić uruchomienia, zamiast działać w sposób, który nikt nie zamierzał.

Source: github.com/biodream-llc/perfuse/internal/config

26.25 umowa

Pakiet umowy zmienia to, jak wygląda kanał, w to, jak powinien wyglądać.

Profil odpowiada na pytanie „co otrzymuję”. To jest przydatne raz. Drogi problem pojawia się w dniu, gdy się zmienia: uaktualnienie dostawcy powoduje usunięcie pola, pojawia się nowy kod, segment zaczyna się powtarzać. Żadne z nich nie jest błędem - wiadomości są nadal ważne HL7 i każdy silnik na świecie je akceptuje - więc nikt nie zauważa, aż odbiorca upadnie, zwykle tygodnie później, i dochodzenie zaczyna się od niewłaściwego końca.

Umowa to profil napisany jako oczekiwanie, a następnie sprawdzony. To jest testowanie umowy, które jest rozwiązane w ogóle w oprogramowaniu i prawie całkowicie nieobecne w integracji opieki zdrowotnej.

Dlaczego jednostka jest stawką, a nie wiadomością

Oczywisty projekt polega na sprawdzeniu każdej wiadomości i zgłoszeniu błędu, gdy któraś nie powiedzie się. To powoduje system, którego nikt nie może używać. Rzeczywiste kanały zawierają proporcję prawdziwie dziwnych wiadomości - testową wiadomość od dostawcy, pacjenta bez zarejestrowanej płci, ręczne wprowadzenie - i alarmowanie o każdej z nich szkoli ludzi, aby ignorowali alarmy, w którym momencie funkcja jest gorsza niż nic, ponieważ zużywa uwagę, której potrzebuje.

Więc oczekiwanie dotyczy proporcji w oknie: „PID-3 jest wypełniony w co najmniej 99% wiadomości”. Jedna dziwna wiadomość nigdy nie powoduje alarmu. Pięć procent wiadomości tracących swój numer medycznego tak.

Umowa opisuje to, co przychodzi, a nie to, co wychodzi

To jest różnica, którą ludzie najpierw mylą, w tym ja podczas testowania integracji. Perfuse przechowuje wiadomość, tak jak przychodzi - jest to celowe, ponieważ przechowywana wiadomość jest dowodem tego, co wysłał nadawca - więc umowa jest sprawdzana w stosunku do przychodzącego kanału, a nie w stosunku do wyjścia transformacji kanału.

To jest właściwa domyślna wartość o dużym marginesie: rzeczą, która zmienia się bez ostrzeżenia, jest system nadawcy, a celem umowy jest zauważenie. Ale oznacza to, że oczekiwanie napisane o wartości mapowanej („po mapowaniu tylko kody laboratoryjne powinny pozostać”) nie powiedzie się natychmiast i myląco, ponieważ kody, które wymienia, nigdy nie pojawiają się w profilowanym ruchu. Cokolwiek dotyczy tego, co wychodzi, należy do testu kanału, który uruchamia rzeczywiste transformacje.

Dlaczego naruszenie nazwuje tolerancję, którą złamało

„PID-3 nie powiódł się” nie mówi nikomu nic. „PID-3 został wypełniony w 94,2% ostatnich 500 wiadomości; umowa wymaga 99%” mówi im, jak źle jest, jak pewni mogą być, i czy warto kogoś budzić. Liczby są wiadomością.

Source: github.com/biodream-llc/perfuse/internal/contract

26.26 crd

Pakiet crd jest usługą Da Vinci Coverage Requirements Discovery (CRD 2.2.1): stroną płatnika w rozmowie CDS Hooks, która mówi klinicystom, podczas gdy zamówienie jest jeszcze wersją roboczą, czy jest objęte, czy wymaga uprzedniej autoryzacji, i jakie dokumenty płatnik będzie chciał.

Interfejs API Prior Authorization CMS-0057 jest w praktyce trzema przewodnikami Da Vinci: CRD, aby powiedzieć, co jest wymagane, DTR, aby zebrać to, PAS, aby przesłać to. Perfuse miał PAS. To jest pierwszy z pozostałych dwóch; pakiet $questionnaire DTR jest na punkcie końcowym FHIR.

Decyzje dotyczące pokrycia finansowego pochodzą z pliku reguł, ponieważ są one polityką płatnika i zmieniają się bez wydania nowej wersji oprogramowania: kod (lub lista kodów) i to, co do niego ma zastosowanie - czy jest objęte pokryciem, czy nie, czy wymagana jest uprzednia autoryzacja, czy nie, dokumentacja oraz kwestionariusz DTR, który ją gromadzi. Zamówienie, które nie odpowiada żadnej regule, jest odpowiedzią "warunkową" i "nieoznaczoną", co jest tym, co CRD mówi, aby zwrócić, gdy usługa nie może podjąć decyzji - nigdy nie jest to zgadywanie, czy jest objęte pokryciem.

Odpowiedzi są zgodne z przewodnikiem: systemAction aktualizuje każde zamówienie z rozszerzeniem coverage-information, które EHR przechowuje w zamówieniu i później wysyła z uprzednią autoryzacją; oraz karta na zamówienie, aby klinicysta mógł ją zobaczyć.

Source: github.com/biodream-llc/perfuse/internal/crd

26.27 pulpity

Pakiet pulpity definiuje pulpity, które Perfuse dostarcza dla każdego rodzaju osoby, która je obserwuje, oraz w jaki sposób osoba otrzymuje jeden: przez swoją rolę, przez grupę katalogową, którą plik pulpitu mapuje, lub przez widok, który został zapisany.

Pulpity składają się z kafelków, a kafelki pokazują tylko agregaty - liczby, stawki, czasy, stany. Żaden z nich nie pokazuje wiadomości, pacjenta ani identyfikatora, więc pulpit można udostępnić menedżerowi działu lub umieścić na ekranie ściany bez poszerzania zakresu osób, które mają dostęp do danych pacjenta. Kafel, który wymaga danych, których Perfuse jeszcze nie rejestruje, nie jest fałszowany: pulpit wyświetla go w sekcji Planowane.

Pełna elastyczność jest zadaniem Grafany, a nie tego pakietu. Każdy kafel, który ma metrykę za sobą, jest eksportowany jako panel Grafany za pośrednictwem /metrics Perfuse, więc witryna, która chce więcej niż lekką konfigurację, może przenieść pulpit tam.

Source: github.com/biodream-llc/perfuse/internal/dashboards

26.28 davinci

Pakiet davinci określa, jaki wydanie przewodników Da Vinci dotyczących uprzedniej autoryzacji (CRD, DTR, PAS) obsługuje klient.

Perfuse odpowiada na dwa: 2.2 (CRD 2.2.1, DTR 2.2.0, PAS 2.2.1), najnowszy, oraz 2.1 (CRD, DTR i PAS 2.1.0), wersja, na którą wskazuje zalecana lista punktów CMS-0057-F, gdy podstawa US Core 3.1.1 wydań 2.0.1 wygasła. Te dwie wersje różnią się kształtami, które klient odczytuje po nazwie - parametry pakietu DTR (PackageBundle w 2.1, packagebundle w 2.2), odpowiedź $inquire PAS (jeden Bundle w 2.1, Parametry w 2.2), rozszerzenia, które istnieją tylko w jednej z nich - więc jedna odpowiedź nie może obsłużyć obu, a serwer musi wiedzieć, z którym rozmawia.

Wersja jest określana w następującej kolejności, od najbardziej szczegółowej: przez samą żądanie (CRD's davinci-crd.requestedVersion; wersja na profilu, który wejście deklaruje, profile|2.1.0), następnie przez rejestrację klienta (davinci_version na kliencie SMART lub CDS), a na końcu przez ustawienie serwera (serve -davinci-version), które domyślnie jest ustawione na najnowszą wersję.

Source: github.com/biodream-llc/perfuse/internal/davinci

26.29 dbtime

Pakiet dbtime formatuje znaczniki czasu tak, aby sortowanie ich jako tekstu sortowało je jako czas.

Każdy magazyn w Perfuse przechowuje znaczniki czasu jako TEXT w SQLite i opiera się na porównaniu łańcuchowym do porządkowania i zapytań zakresowych: ORDER BY received_at DESC, WHERE expires_at < ?, WHERE at >= ?. Jest to rozsądny projekt - pozwala na odczyt bazy danych za pomocą powłoki sqlite3 - ale działa tylko wtedy, gdy forma tekstu jest o stałej szerokości.

time.RFC3339Nano nie jest. Jego dokumentacja mówi, że usuwa końcowe zera z pola sekund, więc ten sam zegar wytwarza ciągi o różnej długości:

20:56:33.12345Z <- 123450 mikrosekund, usunięte końcowe zero 20:56:33.123456Z <- 123456 mikrosekund

Porównywane jako tekst, pierwszy jest *większy*, ponieważ po wspólnym prefiksie "12345" ma 'Z', gdzie drugi ma '6', a 'Z' sortuje powyżej każdej cyfry. Tak więc wcześniejszy moment czasu jest sortowany później. Około jeden na dziesięć sąsiadujących par jest dotkniętych, co jest powodem, dla którego pojawiło się to jako przerywana awaria testowa, a nie jako oczywiście uszkodzona funkcja.

To, co tak naprawdę złamało: rejestr audytowy i przeglądarka wiadomości oba są uporządkowane według znacznika czasu i mogą więc wyświetlać wpisy z tego samego sekundy w niewłaściwej kolejności. Ślad audytowy jest artefaktem zgodności, a przeglądarka wiadomości jest sposobem, w jaki ktoś odtwarza, co się stało, więc w obu przypadkach kolejność jest punktem.

Układ poniżej używa .000000000 zamiast .999999999. Oba drukują nanosekundy; różnica polega na tym, że zera są istotne w pierwszym, a w drugim są pomijane.

Source: github.com/biodream-llc/perfuse/internal/dbtime

26.30 delimited

Pakiet delimited parsuje rekordy oddzielone i podzielone przez skonfigurowane znaki.

Jest to typ danych Delimited z Mirth: CSV, oddzielone tabulatorem, oddzielone pipe, pliki o stałej szerokości kolumny i długi ogon formatów, które emituje laboratorium analityczne lub biuro usługowe, ponieważ ktoś to napisał w 1994 roku i działa.

Celowo nie jest to ogólna biblioteka CSV. To, co tutaj ma znaczenie, to to, co healthcare feed robi, czego nie robi dobrze sformatowany CSV: wiersz nagłówka, który może lub nie być obecny, pusty wiersz końcowy, który nie może stać się pustym rekordem, kolumny odwołujące się do nazwy, aby transformacja nie złamała się, gdy dostawca wstawia jeden, oraz możliwość traktowania całego pliku jako jednej wiadomości lub każdego wiersza jako własnej.

Ostatnie z nich jest decyzją, która kształtuje wszystko inne. Plik pięciu tysięcy wyników jest albo jedną wiadomością, albo pięcioma tysiącami, a te dwa nie są wymienne: jedna wiadomość oznacza jedno potwierdzenie i jeden błąd dla całego pliku, a pięć tysięcy oznacza, że każdy wiersz może być filtrowany, transformowany i ponawiany samodzielnie.

Source: github.com/biodream-llc/perfuse/internal/delimited

26.31 dicom

Pakiet dicom odczytuje zestawy danych DICOM.

DICOM to miejsce, w którym żyje radiologia, a szpitalny silnik integracji, który nie może mówić w tym języku, jest wykluczony z obrazowania w całości. Mirth ma odbiornik i nadajnik DICOM, więc jest to blokada migracji dla każdego miejsca, które wykonuje pracę modalną.

Zakres, wyrażony w prosty sposób

Ten pakiet parsuje zestawy danych: informacje o pliku meta, elementy, składnię transferu i wartości, które mają znaczenie dla routingu i identyfikacji. Nie odszyfrowuje danych pikseli i nigdy nie będzie, jeśli chodzi o ten pakiet - silnik integracji przenosi obrazy, nie wyświetla ich, a dekoder jest dużym zestawem pracy specyficznej dla formatu, którego jedynym celem tutaj byłoby zwiększenie rozmiaru binarnego.

Odczytywanie metadanych bez dotykania pikseli jest również tym, co sprawia, że jest to szybkie w ruchu, który ma znaczenie: tomografia komputerowa klatki piersiowej to setki megabajtów pikseli za dwoma kilobajtami informacji, na których się opiera każdy.

Dlaczego wartości reprezentacji są obsługiwane w sposób jawny

Element DICOM przenosi dwuliterową reprezentację wartości mówiącą, jak odczytać jego wartość, a reguły różnią się w zależności od VR w sposób, który nie może być zgadnięty: niektóre mają długość dwóch bajtów, a niektóre czterech, niektóre są wypełnione spacją, a niektóre znakiem null, a ciągi numeryczne mogą zawierać wiele wartości oddzielonych ukośnikami. Niepoprawne odczytanie nie powoduje błędu, ale wyświetla wiarygodnie wyglądającą niepoprawną wartość - nazwę pacjenta odczytaną z połowy daty lub identyfikator badania o jeden bajt przesunięty.

Source: github.com/biodream-llc/perfuse/internal/dicom

26.32 dicomweb

Pakiet dicomweb obsługuje DICOMweb (DICOM PS3.18): QIDO-RS do wyszukiwania, WADO-RS i WADO-URI do pobierania, STOW-RS do przechowywania, za pośrednictwem HTTP.

To jest sposób, w jaki przeglądarki, usługi AI i archiwa chmury dostęp do obrazowania obecnie: OHIF, Google Cloud Healthcare, Azure Health Data Services, AWS HealthImaging, interfejsy DICOMweb Orthanc i dcm4chee. Silnik integracyjny, który obsługuje tylko protokół sieciowy z 1993 roku (DIMSE: C-STORE, C-FIND), może dostarczyć PACS, ale nie przeglądarce.

Pakiet składa się z czterech części: czytnika zestawu danych, który przechodzi przez cały obiekt, w tym sekwencje, i wie, gdzie znajdują się dane pikseli bez ich ładowania; model JSON DICOM (PS3.18 F.2); multipart/related, który jest sposobem, w jaki DICOMweb przenosi wiele obiektów w jednym żądaniu; oraz archiwum z indeksem, które jest tym, co QIDO i WADO odpowiadają.

Source: github.com/biodream-llc/perfuse/internal/dicomweb

26.33 direct

Pakiet direct jest bezpośrednim przesyłaniem wiadomości zabezpieczonych jako system krawędziowy: wiadomość do adresu Direct jest podpisywana certyfikatem tego adresu i szyfrowana do odbiorcy, jako S/MIME, i wysyłana do HISP za pomocą SMTP; wiadomość otrzymana z HISP (za pomocą SMTP lub pobrana za pomocą IMAP) jest odszyfrowywana, a jej podpis jest sprawdzany względem anchorów zaufania przed odczytaniem.

Przestrzega Direct Project Applicability Statement for Secure Health Transport 1.2 i specyfikacji XDM (IHE ITI TF-1 Annex 15) dla dokumentów z metadanymi. Nie jest to HISP: akredytacja HISP, jego polityka certyfikatów i katalog pozostają z HISP.

Source: github.com/biodream-llc/perfuse/internal/direct

26.34 drug

Pakiet drug obsługuje kody i ilości, które identyfikują lek.

Wydzielony z farmaceutycznych standardów, które je przenoszą, ponieważ ten sam kod leku pojawia się w roszczeniu NCPDP, przepisie SCRIPT, segmencie HL7 RXE i żądaniu FHIR MedicationRequest, a konwersja, która istnieje w jednym z tych miejsc, jest konwersją, której pozostałe trzy nie potrzebują.

Source: github.com/biodream-llc/perfuse/internal/drug

26.35 dsdr

Pakiet dsdr podpisywuje i weryfikuje dokumenty CDA zgodnie z przewodnikiem implementacyjnym HL7 dla CDA Release 2: Digital Signatures and Delegation of Rights, Release 1 (październik 2014) - standardem podpisu elektronicznego, który HIPAA przyjmuje dla załączników roszczeń w CMS-0053-F, 45 CFR 162.2002(e), z zgodnością od 26 maja 2028.

To, o co prosi przewodnik, i gdzie jest to robione:

Tam, gdzie przewodnik milczy, podjęte wybory są nazwane: nie podaje przestrzeni nazw dla własnych elementów (digitalSignature, authorizedSigner, SignaturePurpose), więc umieszcza je w urn:hl7-org:sdtc; a cel jest również stwierdzony jako wskazanie typu zobowiązania XAdES z OID ASTM, które narzędzia XAdES czytają, a własny element przewodnika nie.

Delegacja praw (podpisany z zastrzeżeniem SAML) nie jest produkowana; podpis zawierający jeden jest zgłaszany jako taki.

Source: github.com/biodream-llc/perfuse/internal/dsdr

26.36 e4x

Pakiet e4x powoduje, że skrypty Mirth Connect działają bez zmian.

Skrypty Mirth są pisane dla Rhino, który implementuje E4X: XML jest rodzimym typem z własną składnią. Silnik tutaj to goja, który nie, a luka nie jest tylko bieżącą. Trzy części E4X to *składnia*, więc parser goja odrzuca plik bezwzględnie, zanim jakikolwiek model obiektu mógłby pomóc:

dla każdego (var seg w msg..OBX) { } // for-each, i operator potomka var z = <ZZZ><ZZZ.1>wartość</ZZZ.1></ZZZ>; // literal XML var id = node.@root; // odniesienie do atrybutu

Ten plik przepisuje je na zwykły ECMAScript, który goja parsuje, pozostawiając semantykę czasowi wykonywania obiektu w xml.go. Wszystko inne dotyczące E4X - dostęp do właściwości według nazwy elementu, indeksowanie powtórzeń, przypisanie, toString - jest już ważną składnią JavaScript i nie wymaga przepisywania.

Przepisanie jest wykonywane za pomocą prawdziwego leksera, a nie wyrażeń regularnych, ponieważ alternatywa powoduje uszkodzenie działających skryptów. Wzorzec dla operatora potomka znajduje jeden wewnątrz "http://example.org", wzorzec dla literałów XML znajduje jeden w "a < b && c > d", a skrypt, który zmienia znaczenie w sposób niejawny, jest o wiele gorszy niż ten, który odmawia załadowania.

Source: github.com/biodream-llc/perfuse/internal/e4x

26.37 edifact

Pakiet edifact odczytuje i zapisuje wymiany UN/EDIFACT (ISO 9735): ciąg usługi UNA, koperta wymiany UNB/UNZ, opcjonalne grupy funkcyjne UNG/UNE, oraz wiadomości UNH/UNT, z znakiem wydania i, dla wersji składni 4, separatorem powtórzeń.

Sprawdza liczbę i odniesienia koperty, adresuje elementy danych dla filtrów, dzieli wymianę na jedną na wiadomość i tworzy potwierdzenie CONTRL.

Czyta dowolny typ wiadomości (ORDERS, INVOIC, IFTSTA, MEDRPT ...); nie zawiera katalogów, które określają, które segmenty może zawierać dany typ wiadomości, więc sprawdza strukturę, a nie zawartość.

Source: github.com/biodream-llc/perfuse/internal/edifact

26.38 wyjście

Pakiet wyjścia decyduje, czy ten silnik może połączyć się na zewnątrz z adresem.

Istnieje, ponieważ miejsce docelowe może być skierowane gdziekolwiek, a jeden zestaw zamienia to w sposób odczytania sieci wewnętrznej: miejsce docelowe SOAP z przekształtnikiem odpowiedzi zwraca odpowiedź odbiorcy do skryptu, więc edytor może utworzyć kanał, który pobiera wewnętrzny adres URL i zapisuje treść do logu lub wiadomości.

Demonstrated rather than theorised: a SOAP destination aimed at a local HTTP server put that server's response body into a channel log line.

Odpowiedź proporcjonalna nie polega na zakazie połączeń wychodzących - dostarczanie wiadomości do skonfigurowanych punktów końcowych jest całym celem oprogramowania, a edytor ma je skonfigurować. Polega na odmowie konkretnych adresów, które nigdy nie są miejscem docelowym wiadomości i zawsze są magazynem poświadczeń.

Source: github.com/biodream-llc/perfuse/internal/egress

26.39 silnik

Pakiet silnik uruchamia skonfigurowane kanały.

Kanał składa się z źródła, filtra i zestawu miejsc docelowych. Zadaniem środowiska wykonawczego jest uczciwe informowanie o tym, co się stało z każdą wiadomością: potwierdzenie powinno znaczyć to, co określa konfiguracja, wiadomość, która została odfiltrowana, powinna być odróżnialna od tej, która została dostarczona, a wiadomość, która nie mogła być dostarczona, nie powinna być zgłaszana jako zaakceptowana.

Source: github.com/biodream-llc/perfuse/internal/engine

26.40 epa

Pakiet epa to NCPDP SCRIPT elektroniczna wcześniejsza autoryzacja, strona płatnika: PAInitiationRequest, PARequest, PAAppealRequest i PACancelRequest wchodzą, a ich odpowiedzi wychodzą.

CMS-0062-P proponuje, aby dotknięci płatnicy wspierali go od 1 października 2027 r., a Medicare Part D już tego wymaga. Żądanie jest decydowane w taki sam sposób, jak każda wcześniejsza autoryzacja na tym serwerze: staje się żądaniem Da Vinci PAS (roszczenie, MedycynaRequest i odpowiedzi lekarza jako QuestionnaireResponse) i trafia do tego samego pliku reguł, usługi decyzyjnej i kolejki przeglądu. Formularz określa, które leki wymagają tego i jakie pytania zadawać, z tego samego kwestionariusza FHIR Da Vinci DTR.

Schematy NCPDP są objęte licencją. Nazwy elementów i ich kolejność tutaj są zgodne z publicznym przewodnikiem towarzyszącym Surescripts ePA i jego przykładami; dwa elementy, których publiczny materiał nigdy nie pokazuje (powód wewnątrz Closed i wewnątrz Denied), są zgodne z modelem SCRIPT używanym gdzie indziej i są nazwane w podręczniku, aby płatnik mógł je sprawdzić przeciwko swojej kopii schematu.

Source: github.com/biodream-llc/perfuse/internal/epa

26.41 eprescribe

Pakiet eprescribe odczytuje i zapisuje NCPDP SCRIPT, standard, w jakim przepisywane są recepty.

Nazwany zgodnie z tym, co robi, a nie ze standardem, ponieważ wewnętrzny/skrypt to już silnik JavaScript, a dwa pakiety o nazwie skrypt w jednym drzewie to błąd czekający na wystąpienie w linii importu.

SCRIPT jest XML, w przeciwieństwie do standardu telekomunikacyjnego, który przenosi wynikające z tego roszczenie. Lekarz wysyła NEWRX do apteki; apteka wysyła z powrotem RXFILL, aby powiedzieć, co się stało, REFREQ, aby poprosić o uzupełnienie, lub RXCHG, aby poprosić o zmianę. Każdy z nich jest wiadomością tutaj.

Gdzie jest niebezpieczeństwo

Dwa pola w receptach są niebezpieczne, gdy są źle odczytane, a nie gdy są brakujące.

Substitutions jest pierwszym. Zero oznacza, że zamiana jest dozwolona, a jeden oznacza wydanie zgodnie z zapisem. Czyta się do tyłu dla kogoś, kto oczekuje flagi, gdzie jeden oznacza tak, a popełnienie błędu powoduje wydanie generycznego, gdzie lekarz wymagał marki - lub odmówienie zamiany, która była dozwolona, co jest tym samym błędem kosztującym pacjenta pieniądze. Dlatego ten pakiet odmawia zgadania: brakujący element Substitutions jest błędem, a nie domyślnym, ponieważ oba domyślne są błędne.

Liczba uzupełnień jest drugim. Przepis na lek z harmonogramu II nie może być uzupełniony w ogóle, a system przenoszący liczbę uzupełnień z szablonu niekontrolowanego wytwarza wyglądającą poprawnie receptę, którą apteka musi odrzucić.

Co nie zostało zweryfikowane

Struktura wiadomości jest zgodna z opublikowanymi nazwami elementów SCRIPT. Żadna wiadomość z tego pakietu nie została wysłana przez rzeczywistą sieć routingu, taką jak Surescripts, a certyfikacja przez jedną z nich jest procesem handlowym, a nie technicznym. To parsuje i tworzy format; nie twierdzi, że jest certyfikowany.

Source: github.com/biodream-llc/perfuse/internal/eprescribe

26.42 równoważny

Pakiet equiv dowodzi, że dwa silniki są zgodne lub wskazuje dokładnie, gdzie się różnią.

To jest odpowiedź na jedyne pytanie, które blokuje migrację. Zespół interfejsu nie odmawia nowego silnika, ponieważ brakuje mu funkcji, ale dlatego, że nie mogą być pewni, czy będzie działał tak samo na ruch, jaki już mają, a błąd oznacza, że wyniki badań nie docierają do lekarzy. Żadne porównanie funkcji nie odpowiada na to. Dowody tak.

Zamierzonym zastosowaniem jest równoległy przebieg. Oba silniki otrzymują te same wiadomości produkcyjne; dotychczasowy silnik nadal dostarcza, a Perfuse dostarcza nikomu, co jest tym, czym są już kanały cieniowe. Po dwóch tygodniach porównuje się dane wyjściowe tutaj, a rozmowa zmienia się z „zaufaj temu” na „oto trzy wiadomości spośród czterystu tysięcy, gdzie się różnimy, i dlaczego”.

Grupowanie to cała funkcja

Naiwna różnica 400 000 wiadomości produkuje 400 000 wyników i zostaje zamknięta bez odczytania. Prawie każda rzeczywista różnica ma jedną przyczynę: format daty, kod placówki, jeden krok przekształcenia, który nikt nie przeniósł. Dlatego też różnice są grupowane według przyczyny - ścieżki w wiadomości i rodzaju różnicy - i raportowane raz z liczbą. Trzy tysiące różnic z jednej przyczyny to jeden wynik, a nie trzy tysiące. To pojedyncze decyzja jest tym, co sprawia, że raport jest czytelny, a czytelny raport to różnica między migracją, która postępuje, a taką, która zatrzymuje się.

Wartości są wyłączone domyślnie

Rzeczywisty ruch to dane pacjentów, więc raport porównawczy to miejsce, w którym mogą wyciekać dane PHI do biletu, e-maila lub slajdu. Domyślnie ten raport wyświetla ścieżki, rodzaje i liczby - nigdy wartości. To wystarcza do znalezienia przyczyny: „MSH-7 różni się w 3 000 z 3 000 wiadomości” mówi analitykowi, że jest to format daty bez pokazywania jednej daty.

Wartości można włączyć celowo, ponieważ ostatecznie ktoś musi zobaczyć jedną, a udawanie, że tak nie jest, tylko popychałoby ich do gorszego narzędzia. To jest jawne opt-in, a raport mówi na jego twarzy, że zawiera zawartość wiadomości.

Source: github.com/biodream-llc/perfuse/internal/equiv

26.43 expr

Powiązanie HL7 v2.

To jest logika, która dawniej mieszkała w linii w eval.go. Zachowuje niezmienione zachowanie - celowo, ponieważ filtr v2 jest tym, co każdy kanał HL7 uruchamia, a celem gramatyki ogólnej było dodanie formatów, a nie zmiana tego.

Source: github.com/biodream-llc/perfuse/internal/expr

26.44 fdlimit

Pakiet fdlimit sprawdza, ile deskryptorów plików może otworzyć ten proces, i zwiększa limit, jeśli może.

Istnieje to z powodu kształtu awarii, której zapobiega. Każde połączenie przychodzące jest deskryptorem, a także każda dostawa w locie. Odbiorca, który przestał odpowiadać, trzyma deskryptor przez cały budżet ponownych prób - z ustawieniami domyślnymi, pięć prób z limitem czasu trzydziestu sekund plus piętnaście sekund zwłoki, czyli prawie trzy minuty. Kilka set połączeń z jednym zawieszonym odbiorcą to więc kilka set deskryptorów trzymanych przez kilka minut.

Wyczerpanie się nie powoduje ładnego błędu w miejscu, w którym się wyczerpało. Powoduje „zbyt wiele otwartych plików” gdzie indziej całkowicie: baza danych nie może otworzyć swojego dziennika, interfejs sieciowy przestaje akceptować, plik dziennika nie może być zapisany. Silnik wydaje się być uszkodzony w trzech niepowiązanych miejscach na raz, a prawdziwa przyczyna jest systemem partnerskim, który ucichł. To jest połączenie pomocy, które ten pakiet istnieje, aby uniknąć.

Dwa rzeczy dzieją się podczas uruchamiania. Miękki limit jest zwiększony do limitu twardego, co zwykle usuwa problem całkowicie - miękki limit domyślny jest często kilkuset, podczas gdy limit twardy jest dziesiątkami tysięcy. Następnie zgłasza się, jaki limit jest dostępny, aby silnik mógł ograniczyć własną współbieżność wewnątrz siebie, zamiast odkrywać ją, uderzając w nią.

Source: github.com/biodream-llc/perfuse/internal/fdlimit

26.45 fhirpath

Pakiet fhirpath ocenia FHIRPath (HL7 FHIRPath N1, 2.0.0) nad zasobami FHIR przechowywanymi jako JSON.

Nie ma modelu FHIR: typ elementu jest znany, gdy JSON FHIR mówi (sufiks elementu wyboru, taki jak valueQuantity, resourceType zasobu) lub wnioskowany z wartości JSON w przeciwnym razie. To obejmuje to, czego potrzebuje SQL na widokach FHIR i CQL-wolne środki jakości; nawigacja, która zależy od modelu (własny typ prymitywu, gdy nie jest to wybór), jest odpowiedzią z kształtu wartości.

Source: github.com/biodream-llc/perfuse/internal/fhirpath

26.46 fhirserver

Pakiet fhirserver implementuje serwer FHIR REST.

Istnieje to, ponieważ użyteczny koniec v2-to-FHIR mapper jest gdzieś, aby umieścić wynik. Możliwość przekształcenia wiadomości to demo; możliwość przekształcenia jej, przechowywania i następnie znalezienia pacjenta ponownie przez identyfikator to produkt.

To jest prawdziwy serwer FHIR w częściach, które mają znaczenie dla tego: oświadczenie o zdolności, utworzenie, odczyt, aktualizacja, usunięcie, wyszukiwanie parametrów, które ludzie naprawdę używają, oraz transakcje pakietów stosowanych atomowo. To nie jest kompletny serwer FHIR — brak historii, brak łańcuchowego wyszukiwania, brak _include — i mówi o tym w swoim własnym oświadczeniu o zdolności, zamiast pozwolić klientowi odkryć luki.

Source: github.com/biodream-llc/perfuse/internal/fhirserver

26.47 formulary

Pakiet formulary to formularz leków płatnika: które leki każdy plan obejmuje, na jakim poziomie i z jakimi ograniczeniami (uprzednia autoryzacja, terapia stopniowa, limity ilościowe), oraz co członek płaci.

Jeden plik jest jednym źródłem informacji o leku: API Da Vinci US Drug Formulary (opublikowany jako FHIR), odpowiedzi NCPDP Real-Time Prescription Benefit i elektroniczna autoryzacja NCPDP SCRIPT (czy lek wymaga autoryzacji i jakie pytania zadawać). Formularz, który istniał w trzech miejscach, odpowiadałby na to samo pytanie na trzy różne sposoby.

Source: github.com/biodream-llc/perfuse/internal/formulary

26.48 ramowanie

Ramkowanie pakietu odczytuje i zapisuje wiadomości w strumieniu bajtów, który nie jest MLLP.

Dlaczego istnieje oddzielnie od mllp

MLLP jest jednym z typów ramkowania: 0x0B przed, 0x1C 0x0D po. Jest to to, co HL7 v2 używa przez TCP, a Perfuse zawsze mówił w tym języku.

Dużo sprzętu nie robi tego. Analizator laboratoryjny, waga, monitor łóżkowy, starszy system rozliczeniowy - każdy z nich ma swoją własną konwencję, a konwencje są wszystkie proste wariacje na te same trzy pomysły: separator gdzieś, stała długość rekordu lub długość zapisana przed ładunkiem.

Konnektor TCP Mirth pokrywa to, a Perfuse nie miał nic, więc strona z kanałem socket, który nie był HL7, nie mógł go w ogóle używać.

Błąd, którego ten pakiet jest napisany, aby uniknąć

Odczytywanie ze strumienia i zgadywanie, gdzie kończy się wiadomość, jest cały problem. Zgaduj krótko i wiadomość jest przecięta na pół; zgaduj długo i dwie wiadomości przychodzą jako jedna. Oba produkują dane wyjściowe, które często wyglądają prawdopodobnie, co jest gorsze niż błąd, więc każdy tryb tutaj jest jawny co do tego, co kończy wiadomość, i żaden z nich nie powraca do innego.

Wiadomość bez ramkowania w ogóle jest prawidłową konfiguracją - niektóre urządzenia otwierają połączenie, wysyłają jedną wiadomość i zamykają - ale nie może być łączony z czymś innym i nie może być używany na połączeniu, które pozostaje otwarte, więc jest nazwany i walidowany, zamiast być traktowany jako domyślny.

Source: github.com/biodream-llc/perfuse/internal/framing

26.49 ftpconn

Pakiet ftpconn wysyła pliki przez FTP i FTPS, używając tylko standardowej biblioteki.

FTP jest stary, gadatliwy i nie jest dobrym protokołem. Jest to również nadal sposób, w jaki wiele systemów szpitalnych akceptuje pliki, zwykle dlatego, że drugi koniec jest analizatorem laboratoryjnym lub usługą biurową, której oprogramowanie nie zostało dotknięte od czasu, gdy działało. Odmowa obsługi nie powoduje, że te systemy stają się nowoczesne; powoduje, że Perfuse staje się niezdatny do użycia w tych miejscach.

Zaimplementowany tutaj, a nie pobrany jako zależność, z tego samego powodu, co S3: lista ośmiu zależności jest prawdziwym argumentem z kimś, kto przegląda oprogramowanie przed zainstalowaniem go w szpitalu. Kanał sterujący FTP jest tekstem zorientowanym na linię przez TCP, więc jest to kilkaset linii net i crypto/tls.

Co jest obsługiwane, a co jest odrzucane

Tryb bierny tylko. Tryb aktywny wymaga, aby serwer otworzył połączenie z powrotem do klienta, co każdy szpitalny firewall zbudowany w tym wieku blokuje, a oferowanie go oznaczałoby, że ludzie konfigurowaliby go, a następnie debugowaliby firewall.

Jawny FTPS (AUTH TLS) jest obsługiwany i jest domyślny, gdy TLS jest wymagany. Niejawny FTPS na porcie 990 jest również obsługiwany, ponieważ niektóre analizatory mówią tylko w tym języku.

Zwykły FTP jest obsługiwany i ostrzega. Wysyła hasło w postaci jawnej, a strona, która musi go używać, powinna zostać powiadomiona raz, zamiast pozostawić ją do odkrycia z przechwytywania pakietu.

Source: github.com/biodream-llc/perfuse/internal/ftpconn

26.50 gcp

Pakiet gcp rozmawia z Google Cloud Pub/Sub i Cloud Storage przez ich interfejsy API REST, z OAuth 2.0 Google zrobiony tutaj: klucz konta usługi podpisał JWT (RS256, crypto/rsa), który jest wymieniony na token dostępu, lub, na Google Cloud, serwer metadanych wydaje go.

Bez SDK Google.

Emulatory (emulator Pub/Sub, fake-gcs-server) nie wymagają poświadczeń: ustaw punkt końcowy i pozostaw puste poświadczenia.

Source: github.com/biodream-llc/perfuse/internal/gcp

26.51 generate

Pakiet generate tworzy syntetyczne wiadomości HL7 v2.

Dwa użycia. Ktoś, kto próbuje Perfuse, potrzebuje ruchu, aby na niego spojrzeć, a test kanału potrzebuje fikcyjnego elementu, który jest wystarczająco realistyczny, aby ćwiczyć rzecz, która jest testowana. Generator jest rozszerzeniem płatnym w Mirth, co mówi, że ludzie chcą go.

Wszystko tutaj jest wymyślone. Nazwy pochodzą z ustalonej listy oczywiście fikcyjnych, identyfikatory są sekwencyjne w ramach uruchomienia, a adresy są wymyślone. To nie jest uwaga, jest to projekt: generator, który produkowałby wiadomości wyglądające prawdopodobnie, w końcu wprowadziłby jedną do fikcyjnego elementu, raportu o błędzie, a następnie do repozytorium.

Realizm jest wydatkowany tam, gdzie ma to znaczenie dla testowania i nigdzie indziej. Sygnatury czasowe zawierają przesunięcia, powtarzające się pola są rzeczywiście powtarzane, imię czasem ma inicjał pośredni, a czasem go nie ma, a mniej więcej co dwunasta wiadomość jest celowo niewygodna: brakujące pole opcjonalne, niezwykły, ale legalny separator, pusty składnik. Podawanie kanałowi tylko doskonale sformatowanych wiadomości mówi bardzo niewiele.

Source: github.com/biodream-llc/perfuse/internal/generate

26.52 hl7dict

Pakiet hl7dict nazywa pola segmentów HL7 v2.

Istnieje on dla jednego ekranu: widoku wiadomości, który może powiedzieć, że PID-5.1 to nazwisko pacjenta, zamiast pozostawiać to do ręcznego liczenia. Każdy, kto debugował interfejs, liczył w ten sposób, i jest to najczęstsze źródło błędów off-by-one, które umieszcza wartość w niewłaściwym polu.

To nie jest cały standard. HL7 v2 ma setki segmentów i tysiące pól, a te, które są tutaj, to te, które pojawiają się w ruchu ADT, ORU, ORM i SIU. Nieznane pole jest zgłaszane jako nieznane, zamiast próbować go odgadnąć.

Source: github.com/biodream-llc/perfuse/internal/hl7dict

26.53 hl7v3

Pakiet hl7v3 odczytuje wiadomości HL7 w wersji 3.

Wersja 3 to coś innego niż wersja 2 nosząca tę samą nazwę. Wersja 2 to potok rozdzielony znakami pipe, którego znaczenie jest pozycyjne; wersja 3 to XML wygenerowany z modelu informacji referencyjnych, gdzie znaczenie jest przenoszone przez nazwy elementów i przez niewielki zestaw typów danych, które się powtarzają wszędzie. Prawie nic nie przenosi się między nimi poza słownictwem klinicznym.

W praktyce wersja 3 przychodzi w jednej z dwóch form. Albo jest to dokument CDA, który jest pochodny od wersji 3 i obsługiwany przez pakiet cda, albo jest to transakcja IHE - w szczególności PIX i PDQ w wersji 3, co jest sposobem, w jaki wiele szpitali rozwiązuje identyfikatory pacjentów w systemach. Ten pakiet jest skierowany do drugiego.

Dlaczego typy danych są na początku

Najważniejszą rzeczą w wersji 3 jest to, że element może być obecny i wyraźnie pusty, z podanym powodem. Data urodzenia z nullFlavor="ASKU" oznacza, że pacjent został poproszony i odmówił odpowiedzi. Data urodzenia z nullFlavor="NAV" oznacza, że wartość istnieje, ale nie jest dostępna teraz, więc pytanie ponownie później może się udać. Data urodzenia, która po prostu jest nieobecna, oznacza, że nikt niczego nie zarejestrował.

Zmniejszanie ich do pustego łańcucha jest błędem, którego ten pakiet jest zaprojektowany, aby go uniknąć. To nie jest kosmetyczna strata: system, który otrzymuje pustą datę urodzenia, gdzie źródło powiedziało "pacjent odmówił", zwykle traktuje ją jako brakujące dane do śledzenia, a dopasowanie demograficzne, które powinno zostać pozostawione nierozwiązane, zostaje rozwiązane przez człowieka, który zgaduje. Dlatego każdy typ danych tutaj rozróżnia nieobecne, puste z powodem i obecne.

Source: github.com/biodream-llc/perfuse/internal/hl7v3

26.54 hl7xml

Pakiet hl7xml konwertuje wiadomości HL7 v2 do i z kształtu XML, który używa Mirth Connect, i z powrotem do kodowania ER7.

Kształt nie jest wyborem projektowym. Skrypty Mirth są napisane przeciwko wyjściu własnego serializatora ER7-to-XML, więc zawierają wyrażenia takie jak

msg['PID']['PID.5']['PID.5.1'].toString()

i obietnica, że istniejący skrypt działa bez zmian, jest zachowana tylko wtedy, gdy drzewo, które przechodzi, ma dokładnie te same nazwy elementów, zagnieżdżanie i zachowanie powtarzania. Każda decyzja poniżej jest więc „co robi Mirth”, a nie „co byłoby ładniejsze”.

Dwa, które mają największe znaczenie:

Każde pole jest otoczone numerowanymi elementami składowymi, nawet gdy pole ma tylko jeden składnik, więc PID-5 z wartością "Doe" nadal wytwarza <PID.5><PID.5.1>Doe</PID.5.1></PID.5>. Skrypty indeksują prosto do .1 stale i drzewo, które umieściłoby tekst na elemencie pola, złamałoby prawie wszystkie z nich.

MSH zachowuje standardowe numery pól HL7, gdzie MSH-1 to separator pól, a MSH-9 to typ wiadomości. Parser w internal/hl7 indeksuje MSH z przesunięciem, ponieważ separator zajmuje pozycję, której nie dzieli żaden dzielnik, a to przesunięcie zatrzymuje się tutaj: skrypt mówiący MSH.9 oznacza typ wiadomości.

Source: github.com/biodream-llc/perfuse/internal/hl7xml

26.55 ibmmq

Pakiet ibmmq wysyła do i odczytuje z kolejek IBM MQ za pomocą interfejsu API REST menedżera kolejek (mqweb), który jest dostarczany z IBM MQ 9.1.5 i późniejszymi wersjami na każdej platformie, w tym z/OS.

Nie potrzebuje on biblioteki klienta MQ: rodzimy protokół MQI jest własnością IBM i nie jest udokumentowany, a interfejs API REST jest obsługiwanym sposobem dostępu do MQ bez niego. (IBM MQ mówi również AMQP 1.0 na kanale AMQP; łącznik amqp Perfuse pokrywa tę trasę.)

Odczyt jest przynajmniej raz: pierwsza wiadomość jest przeglądana, przekazywana do wywołującego i usuwana przez jej identyfikator wiadomości tylko raz, gdy wywołujący ją obsłuży. Wiadomość, która nie mogła być obsłużona, pozostaje w kolejce, jako pierwsza w kolejności.

Source: github.com/biodream-llc/perfuse/internal/ibmmq

26.56 identity

Znajdowanie wiadomości według tego, co się o niej wie, niezależnie od formatu, w jakim przybyła.

Istniejąca funkcja wyszukiwania treści dopasowuje metadane, oferuje dopasowanie podciągu do ładunku i może ocenić wyrażenie filtrujące - ale wyrażenie jest oceniane tylko dla HL7 v2, a każde wyrażenie wymaga znajomości ścieżki. Zatem znalezienie ruchu jednego pacjenta wymagało znajomości tego, że tożsamość znajduje się w PID-3 w przypadku przyjęcia HL7 v2, w Patient.identifier w zasobie FHIR, w (0010,0020) w przypadku wystąpienia DICOM i w NM109 pętli NM1*IL w roszczeniu 837. Cztery formaty, cztery słowniki, a podczas incydentu wyszukiwany komunikat może znajdować się w którymkolwiek z nich.

Ten pakiet mapuje niewielki zestaw pojęć - o kim jest komunikat, jaki wizyt, jaki badanie, jaki roszczenie - na miejsce, w którym każdy format je przechowuje, aby wyszukiwanie mogło być przeprowadzane dla „MRN 12345” zamiast dla ścieżki. Pojęcia są celowo niewielkie: są to rzeczy, które ludzie mają w ręku, gdy muszą znaleźć komunikat, który jest numerem z połączenia telefonicznego lub nazwą z reklamacji.

Dlaczego ekstrakcja następuje raz, podczas rejestrowania

Alternatywą jest parsowanie ładunków w czasie zapytania, co robi wyszukiwanie wyrażeń. To działa i jest uczciwe w odniesieniu do ograniczonego skanowania, ale nie może odpowiedzieć na „każdy komunikat o tym pacjencie w czterech kanałach i przez dwa miesiące” bez odczytania każdego wiersza. Ekstrakcja raz do tabeli indeksowanej zmienia to w wyszukiwanie indeksu.

To jest eskalacja prywatności i jest opcjonalne

Nazwy pacjentów i identyfikatory obecnie znajdują się w kolumnie nieprzezroczystego ładunku. Indeksowanie ich sprawia, że są one możliwe do zapytania, co jest celem, i również sprawia, że są one możliwe do wyliczenia, co jest prawdziwą zmianą w ekspozycji: baza danych, która mogła być tylko przeszukiwana, może teraz być poproszona o „wylistowanie każdego pacjenta”. To jest decyzja dla witryny, a nie dla tego pakietu, więc ekstrakcja jest przełączalna, a każde wyszukiwanie za jej pomocą jest rejestrowane w dzienniku inspekcji PHI.

Source: github.com/biodream-llc/perfuse/internal/identity

26.57 iis

Pakiet iis mówi transportem, którym dzieli się każdy amerykański rejestr szczepień: usługą SOAP CDC IIS.

W 2011 roku zespół ekspertów zwołany przez CDC i Amerykańskie Stowarzyszenie Rejestru Szczepień wybrał jeden interfejs SOAP do przesyłania komunikatów HL7 v2 do systemów informacji o szczepieniach, a rejestry przyjęły go. WSDL jest mały - dwie operacje, connectivityTest i submitSingleMessage - a komunikat HL7 (VXU, aby zgłosić strzał, QBP^Q11, aby poprosić o historię pacjenta) podróżuje jako tekst ucieczki wewnątrz treści SOAP. Odpowiedź wraca w ten sam sposób: ACK lub RSP^K11 zawierający historię i prognozę.

Generyczne miejsce przeznaczenia SOAP mogłoby być skonfigurowane do wykonania tego, ale każda witryna musiałaby wpisać tę samą kopertę, uzyskać prawidłową przestrzeń nazw, umieścić poświadczenia w treści zamiast w uwierzytelnianiu HTTP, a następnie odczytać potwierdzenie HL7 z odpowiedzi, aby dowiedzieć się, czy rejestr zachował rekord. Rejestr odpowiada odrzuconemu strzałowi z kodem HTTP 200 i AR; traktowanie kodu 200 jako powodzenia jest tym, jak szczepienia cicho nie są zgłaszane. Więc ten pakiet robi kopertę CDC i ocenia potwierdzenie raz.

To, czego nie robi: nazwa użytkownika i hasło WSDL są poświadczeniami aplikacji rejestru i są wysyłane tak, jak mówi WSDL, w treści. Wzajemne TLS, gdzie rejestr je wymaga, jest ustawieniem miejsca przeznaczenia TLS, tak jak w przypadku każdego połączenia HTTPS. Nic tutaj nie jest specyficzne dla jednego stanu; tam, gdzie stany się różnią (identyfikator obiektu wymagany lub nie, SOAP 1.1 akceptowany lub nie, ostrzeżenia wysyłane jako AE), ustawienia miejsca przeznaczenia tak mówią.

Source: github.com/biodream-llc/perfuse/internal/iis

26.58 kafka

Kafka jako klient, a nie jako coś, co ma zastąpić.

System opieki zdrowotnej, który ma szkielet zdarzeń, ma szkielet Kafki, a systemy zbudowane w ciągu ostatniej dekady publikują na nim zamiast na brokerze JMS. Więc ten łącznik istnieje, aby uczynić Perfuse świadomym krawędzią kogoś innego platformy zdarzeń: odczytuje komunikaty kliniczne z tematów i publikuje je na tematach, i celowo nie próbuje być platformą przesyłania strumieniowego. Okienkowanie, łączenie, przetwarzanie strumieniowe i rejestry schematów są ekosystemem Kafki i pozostają tam.

Dlaczego zależność, kiedy STOMP i MLLP zostały napisane ręcznie

Zasada w tym repozytorium mówi, że zależność musi kupić możliwości, a nie wygodę, i musi być czystym Go, aby jeden binarny statyczny mógł nadal skompilować się do każdego celu. franz-go jest czystym Go i nie zawiera cgo, co zostało sprawdzone w odniesieniu do wszystkich sześciu celów.

Protokół Kafki nie jest protokołem STOMP. STOMP jest protokołem tekstowym, który mieści się w kilkuset wierszach. Kafka jest wersjonowanym protokołem binarnym wokół siedemdziesięciu typów żądań, a część, która tutaj najbardziej się liczy - grupy konsumentów - jest protokołem koordynacji rozproszonej z fazami dołączenia, synchronizacji, bicia serca i zatwierdzenia przesunięcia oraz tańcem ponownego bilansowania między nimi. Uzyskanie tego subtelnie niepoprawnego nie powoduje oczywistego błędu: powoduje partycję, której nikt nie czyta, lub dwóch konsumentów czytających tę samą partycję. W kanale klinicznym są to brakujący wynik laboratoryjny i zdublowany zamówienie. To jest możliwość, i nie jest warte ręcznego wykonywania, aby zaoszczędzić zależność.

Source: github.com/biodream-llc/perfuse/internal/kafka

26.59 ldap

Pakiet ldap mówi wystarczająco dużo LDAP, aby uwierzytelnić osobę i przeczytać jej grupy.

Szpitale prawie zawsze korzystają z Active Directory, a AD komunikuje się za pomocą LDAP. OpenID Connect jest lepszym rozwiązaniem, gdy jest dostępny - zobacz internal/oidc, oraz notatkę tam o tym, że Mirth nie ma logowania jednokrotnego w żadnej cenie - ale silnik integracyjny często znajduje się na izolowanej sieci VLAN, gdzie przeglądarka nie może dotrzeć do dostawcy tożsamości. To właśnie do tego służy.

Własnoręcznie wykonany BER, zamiast zależności, z tego samego powodu, co DICOM i STOMP: kodowanie jest małe, a to, co przychodzi na tym gnieździe, decyduje o tym, czy ktoś dostanie się do systemu, który przenosi dane pacjentów.

encoding/asn1 w bibliotece standardowej nie jest tutaj użyteczny. Celuje w DER i odrzuca tagi specyficzne dla kontekstu oraz niejawne tagowanie, które LDAP używa na całej długości, więc części, które mają znaczenie, wymagałyby ręcznego wykonania i tak.

Source: github.com/biodream-llc/perfuse/internal/ldap

26.60 skrzynka pocztowa

Pakiet skrzynka pocztowa odczytuje pocztę z serwerów IMAP4rev1 (RFC 3501) i POP3 (RFC 1939), logując się za pomocą hasła lub OAuth 2.0 (SASL XOAUTH2, jak wymagają Microsoft 365 i Gmail), i rozdziela wiadomości (RFC 5322 i MIME), tak aby załącznik lub treść wiadomości mogła stać się wiadomością na kanale.

Tylko to, czego potrzebuje kanał przychodzący: wybierz skrzynkę pocztową, znajdź nieprzeczytane wiadomości, pobierz je w całości, a następnie przenieś, oznacz lub usuń je. Tylko biblioteka standardowa; TLS to crypto/tls.

Source: github.com/biodream-llc/perfuse/internal/mailbox

26.61 mapper

Pakiet mapper sugeruje mapowania pól między systemami z wynikami ufności.

Jest to silnik mapowania oparty na regułach. Brak LLM, brak połączeń sieciowych, brak zewnętrznych zależności. Uruchamia się offline w tym samym pliku wykonywalnym i nigdy nie wysyła danych pacjentów gdziekolwiek.

Silnik łączy wiele sygnałów - nieostre dopasowanie ciągów znaków w nazwach pól, rozpoznawanie wzorców identyfikatorów opieki zdrowotnej, wyszukiwanie systemów kodowania i dane historyczne akceptacji - w jedną wartość ufności na sugestię. Gdy ufność jest poniżej progu konfiguracyjnego, mapper wstrzymuje się, zamiast zgadywać źle, ponieważ błędne mapowanie w opiece zdrowotnej może skierować dane do niewłaściwego pola, co jest wadą bezpieczeństwa pacjentów.

Wstrzymanie jest podstawową decyzją projektową. System, który zawsze generuje odpowiedź, uczy użytkowników, aby przestali sprawdzać, a za pierwszym razem, gdy jest źle, nikt nie zauważa, aż wynik laboratoryjny trafia do pola notatki. System, który mówi „nie wiem”, zmusza do decyzji ludzkiej dokładnie wtedy, gdy potrzebna jest decyzja ludzka.

Source: github.com/biodream-llc/perfuse/internal/mapper

26.62 miara

Pakiet miara ocenia FHIR Miary (cyfrowe miary jakości) których kryteria populacji są FHIRPath i zapisuje wynik jako FHIR MeasureReport: podsumowanie, indywidualne lub lista podmiotów, z stratyfikatorami i wynikiem proporcji.

Każde kryterium jest oceniane raz na pacjenta, z naciskiem na pacjenta Bundle (jego kompartment) i te zmienne: %subject (Pacjent), %periodStart i %periodEnd (okres pomiaru, jako DateTimes) i %„Okres pomiaru” (to samo, co Okres). Kryteria w CQL są odrzucane z powodem: Perfuse nie ma silnika CQL.

Source: github.com/biodream-llc/perfuse/internal/measure

26.63 metryki

Pakiet metryki zbiera to, co silnik robi, i zachowuje wystarczającą historię, aby ją narysować.

Silnik interfejsu jest obserwowany, a nie tylko uruchamiany. Gdy oddział mówi, że wyniki przestały przychodzić dwadzieścia minut temu, pytanie brzmi, co się zmieniło dwadzieścia minut temu, a to nie może być odpowiedzią na liczniki bieżące. Dlatego zachowuje serie, a nie sumy, w pamięci, z ustalonym rozdzielczością.

Trzy decyzje kształtują to.

Opóźnienie jest przechowywane jako histogram, a nie średnia. Średni czas dostarczania jest prawie bezużyteczny w tym obszarze: liczba, która ma znaczenie, to czy najwolniejsze kilka procent wiadomości jest wystarczająco wolne, aby naruszyć zobowiązanie do czasu reakcji, a średnia ukrywa właśnie to. Wiadro jest wykładnicze i ustalone w czasie budowy, więc zapisywanie trwania jest porównaniem i inkrementem bez alokacji.

Seria są ograniczonymi buforami pierścieniowymi, rozmiarem podczas tworzenia kolektora. Nic tutaj nie rośnie bez ograniczeń, ponieważ silnik interfejsu działa przez miesiące, a system metryk, który wymaga ponownego uruchomienia, jest gorszy niż żaden.

Kardynalność jest ograniczona. Wartość etykiety pobrana z danych wiadomości - na przykład aplikacja wysyłająca - może przyjmować tysiące wartości, jeśli ktoś źle skonfigurował kanał, a nieograniczone etykiety są standardowym sposobem, w jaki monitorowanie psuje to, co monitoruje. Poza limitem wartości są scalane do wiadra „inny” i limit sam w sobie jest raportowany.

Source: github.com/biodream-llc/perfuse/internal/metrics

26.64 mirth

Analiza Javy dla zaimportowanych kanałów Mirth.

Dlaczego to istnieje

Mirth uruchamia Rhino na JVM, więc skrypt Mirth może wywołać dowolną Javę na ścieżce klas, w tym własne klasy serwera Mirth. Perfuse uruchamia goja i nie ma środowiska wykonawczego Javy. Odmawia tych wywołań z błędem, który wymienia klasę - ale to odmówienie występuje, gdy skrypt jest uruchamiany, co dla łącznika źródłowego oznacza, gdy przychodzi pierwsza prawdziwa wiadomość.

Więc migracja wyglądała tak: import zakończył się powodzeniem w ciszy, kanał został wdrożony, a pierwsza wiadomość z kabla nie powiodła się. Migracja, która wygląda na czystą i łamie się przy pierwszym ruchu, jest gorsza niż ta, która odmawia na progu, ponieważ osoba, która to zrobiła, już powiedziała swoim kolegom, że działa.

To znajduje te wywołania podczas importu i mówi, co z nimi zrobić.

Dlaczego cztery werdykty, a nie dwa

"Używa Javy" to jeden kawałek informacji i nie ten, który jest odpowiedni, ponieważ Java, którą używa prawdziwy kanał Mirth, należy do grup o całkowicie różnej ilości pracy. Około połowa tego, co strony naprawdę piszą, to SimpleDateFormat i HashMap, które JavaScript obsługuje natywnie. Część z nich to udokumentowane API skryptowe Mirth, które Perfuse już implementuje pod tymi samymi nazwami. Trochę z nich chce uruchomić i zatrzymać kanały, co Perfuse może zrobić za pomocą swojego interfejsu API REST, ale nie udostępnia go skryptom. A część z nich to vendor jar, który nigdy nie będzie uruchomiony tutaj.

Raportowanie ich jako jednej liczby nie mówi migratorowi nic o tym, czy jego popołudnie, czy jego kwartał jest na szali.

Source: github.com/biodream-llc/perfuse/internal/mirth

26.65 mirthlive

Pakiet mirthlive znajduje uruchomione silniki Mirth, z którymi rozmawiają testy interoperacyjności.

Mirth Connect przestał być otwartym oprogramowaniem w wersji 4.6 (marzec 2025). Strony, które go opuszczają, idą do jednego z trzech miejsc: Mirth 4.5.2, ostatniego otwartego wydania, które nadal uruchamiają; Open Integration Engine, fork hostowany przez Eclipse; lub BridgeLink, fork Innovar, który numeruje swoje wydania według roku (26.9.0). Kanał, który Perfuse eksportuje, musi być ładowany we wszystkich z nich, a kanał, który którykolwiek z nich eksportuje, musi być importowany tutaj, więc każdy test uruchamiany na żywo jest uruchamiany raz na silnik, który odpowiada.

Silniki są znajdowane przez zapytanie, a nie konfigurowane: ./scripts/interop-up.sh uruchamia je na stałych portach, a silnik, który nie jest uruchomiony, jest zgłaszany jako pominięty, a nie cicho przechodzący. PERFUSE_MIRTH_ENGINES zastępuje listę jako pary nazwa=url, oddzielone przecinkami.

Tylko testy importują to. Żyje na zewnątrz pliku _test.go, ponieważ dwa pakiety je dzielą.

Source: github.com/biodream-llc/perfuse/internal/mirth/mirthlive

26.66 mpi

Pakiet mpi to indeks główny pacjentów: pobiera rekordy pacjentów z każdego systemu źródłowego (każdy zidentyfikowany przez jego władzę i numer), decyduje, które należą do tej samej osoby, i nadaje każdej osobie identyfikator przedsiębiorstwa (EUID).

Pewne dopasowania łączą się same; niepewne czekają w kolejce przeglądu na decyzję osoby; każde połączenie, rozłączenie, scalenie i decyzja są rejestrowane z osobą, która je podjęła.

Dopasowanie jest deterministyczne najpierw (identyfikator z systemu, któremu strona ufa, że jest unikalny dla osoby, taki jak krajowy identyfikator lub numer przedsiębiorstwa) i probabilistyczne w przeciwnym razie: wagę Fellegi-Suntera nad nazwą, datą urodzenia, płcią, kodem pocztowym, telefonem i adresem, z Jaro-Winklerem dla nazw. Nie decyduje o niczym klinicznym: mówi, które rekordy są tą samą osobą, z powodami, dla osoby do potwierdzenia, gdy nie jest pewna.

Source: github.com/biodream-llc/perfuse/internal/mpi

26.67 mqtt

Pakiet mqtt to klient MQTT 3.1.1: łączy się (z TLS, nazwą użytkownika i hasłem lub certyfikatem klienta), publikuje na QoS 0 lub 1, subskrybuje i potwierdza każdą odebraną wiadomość QoS 1 tylko raz, gdy wywołujący mówi, że została obsłużona.

Napisany przeciwko standardowi OASIS MQTT 3.1.1, a nie zaimportowany, jak inne protokoły przewodowe Perfuse. 3.1.1 to wersja, którą mówi każdy broker: Mosquitto, EMQX, HiveMQ, VerneMQ, wtyczka MQTT RabbitMQ, kanał telemetryczny IBM MQ, AWS IoT Core i Azure Event Grid.

Dostarczanie: wiadomość odebrana na QoS 1 jest potwierdzona (PUBACK) tylko wtedy, gdy Ack jest wywołany. Wywołujący, który nie może obsłużyć wiadomości, zamyka połączenie; z sesją trwałą (CleanSession false) broker wysyła ją ponownie, oznaczoną jako duplikat, gdy klient ponownie łączy się. MQTT 3.1.1 nie ma negatywnego potwierdzenia, więc to jest jedyny sposób, aby poprosić o ponowne wysłanie wiadomości.

Source: github.com/biodream-llc/perfuse/internal/mqtt

26.68 msgstore

Znajdowanie przechowywanej wiadomości według tego, co ktoś wie o niej.

Wyszukiwanie, które osoba naprawdę potrzebuje, to "oto jest numer z połączenia telefonicznego, pokaż mi każdą wiadomość o tym". Przed tym oznaczało to albo dopasowanie podciągu w ładunkach, co jest grep i wolne, albo wyrażenie filtrujące, które wymaga wiedzy, że tożsamość mieszka w PID-3 w HL7 v2 i gdzie indziej w innych trzech formatach na tym samym serwerze.

Tożsamość jest wyodrębniana raz, gdy wiadomość jest rejestrowana i indeksowana, więc jest to wyszukiwanie, a nie skanowanie. Koszt jest płacony na ścieżce rejestrowania, raz na wiadomość, zamiast na każde wyszukiwanie.

Source: github.com/biodream-llc/perfuse/internal/msgstore

26.69 natid

Pakiet natid zna krajowe identyfikatory pacjentów i osób w Wielkiej Brytanii i Europie: ich formaty, ich cyfry kontrolne, system identyfikatora, który nazwę każdego kraju FHIR nazywa, i ile z nich może być wyświetlone.

Istnieje dla indeksu pacjentów. Krajowy numer to najmocniejszy dowód, że dwa rekordy są tą samą osobą, i również najłatwiejszy do popełnienia błędu: podwójnie wpisany cyfra daje numer, który należy do kogoś innego, a jeden źródło wysyła numer NHS pod OID, podczas gdy inne wysyła go pod adresem URL FHIR. Więc każdy identyfikator, który indeks przechowuje, przechodzi przez to: jego cyfra kontrolna jest testowana (błędna jest nigdy używana do łączenia), jego spacowanie jest usuwane, a jego system jest zapisany w jeden sposób.

Co jest weryfikowane, a co nie, jest powiedziane na podstawie schematu. Algorytmy są publiczne; identyfikatory systemu URI są własne kraju, gdzie krajowy przewodnik FHIR nazywa jeden (SystemVerified), i udokumentowany domyślny w przeciwnym razie, który strona zmienia na swoją wartość krajową w Ustawienia → Indeks pacjentów. Nic tutaj nie decyduje o niczym klinicznym.

Source: github.com/biodream-llc/perfuse/internal/natid

26.70 ncpdp

Zapisywanie pola w transmisji NCPDP.

Dlaczego zapis odmawia niejednoznaczną ścieżkę

Odczyt zwraca każdą wartość, którą ścieżka adresuje, ponieważ filtr pytający, czy istnieje jakikolwiek konflikt DUR, powinien zobaczyć wszystkie z nich. Zapis nie może działać w ten sposób. Jeśli D7 adresuje kody produktów dwóch roszczeń w jednej transmisji, ustawienie D7 nie ma jednego znaczenia: zapisywanie obu spowoduje zmianę leku, o którym nikt nie pytał, a zapisywanie pierwszego spowoduje ciche pozostawienie drugiego.

Dlatego zapis odmawia ścieżki, która adresuje więcej niż jedną wartość, a błąd nazywa kwalifikowaną formę, która byłaby niejednoznaczna. Jest to ten sam powód, dla którego kroki transformacji nie mają akcji usuwania: tam, gdzie uczciwa odpowiedź brzmi, że konfiguracja jest niejednoznaczna, mówienie o tym bije wybór jednego.

Source: github.com/biodream-llc/perfuse/internal/ncpdp

26.71 oidc

Pakiet oidc weryfikuje tożsamości OpenID Connect.

Napisany przeciwko standardowej bibliotece, a nie zależności JWT. Autoryzacja jest miejscem, w którym nieprzeanalizowana zależność jest najmniej akceptowalna, weryfikacja podpisu dla algorytmów, które mają znaczenie, to około sto linii crypto/rsa i crypto/ecdsa, a Perfuse już zawiera wystarczająco dużo, aby dodanie więcej wymagało powodu, a nie nawyku.

Zakres jest celowo wąski: potwierdź, że dostawca tożsamości poświadczył osobę, i zgłoś, co powiedział o nich. Wszystko inne - co mogą zrobić, jak długo trwa sesja - pozostaje z Perfuse, ponieważ dostawca tożsamości wie, kim jest ktoś, a nie co wolno im robić w silniku integracji.

Source: github.com/biodream-llc/perfuse/internal/oidc

26.72 parity

Pakiet parity porównuje, co Perfuse produkuje, z tym, co wyprodukował zastępowany silnik.

Dlaczego to istnieje

Perfuse może importować kanał Mirth i może śledzić, co zrobiłby z wiadomością. Żadne z nich nie odpowiada na pytanie, które ktoś naprawdę ma przed przeniesieniem strumienia na żywo, czyli: czy to wyprodukuje ten sam wynik, co rzecz, która działała przez sześć lat?

Żadna ilość jakości projektu nie odpowiada na to. Jedyna uczciwa odpowiedź to dowód, a dowód musi pochodzić z własnego wyjścia starego silnika na ruchu witryny.

Dlaczego pary muszą być dostarczone

To nie może sięgać do Mirth, a udawanie, że tak jest, byłoby najgorszym rodzajem funkcji. To, czego potrzeba, to pary: wiadomość, tak jak przybyła, i wiadomość, którą stary silnik wyprodukował z niej. Oba są w sklepie wiadomości Mirth i mogą być wyeksportowane z przeglądarki wiadomości, co jest rzeczą, którą administrator już wie, jak zrobić.

To ograniczenie jest stwierdzone, a nie ukryte. Narzędzie, które twierdzi, że weryfikuje migrację bez zobaczenia wyjścia starego silnika, weryfikowałoby nic.

Dlaczego różnice są grupowane, a nie wymienione

Uruchomienie ponad pięćdziesięciu tysięcy wiadomości, które zgłasza cztery tysiące różnic, nie powiedziało nikomu nic, co mogliby podjąć. To samo uruchomienie, które zgłasza, że PID-8 różni się w każdej wiadomości, ponieważ stary silnik mapował M na Mężczyznę, powiedziało im dokładnie jedną rzecz do podjęcia decyzji.

Dlatego wyniki są grupowane według pola, z liczbą, przykładem i parami wartości różnorodnych. Jedna decyzja na wynik jest jednostką, którą ktoś może przetworzyć.

Source: github.com/biodream-llc/perfuse/internal/parity

26.73 pas278

Pakiet pas278 mapuje między Da Vinci uprzednią autoryzację a transakcją X12 278.

Dlaczego to istnieje

CMS-0057-F wymaga, aby płatnicy udostępniali interfejs API FHIR uprzedniej autoryzacji do 1 stycznia 2027 r. Nie zastępuje to X12 278, i nigdy nie miało: system zarządzania wykorzystaniem płatnika decyduje o autoryzacjach i mówi 278. Tak więc płatnik spełniający regułę tłumaczy FHIR na 278 i z powrotem, a dostawca, który dzisiaj wysyła 278, będzie jutro wysyłał FHIR do tych samych płatników, którzy nadal akceptują oba.

To tłumaczenie jest tym, co warto posiadać. Silnik, który zawiera obie modele i nie może przekonwertować ich, pozostawia najtrudniejszą część pracy - i część, w której błędy są drogie - komuś, kto go integruje.

Reguły, których ten pakiet przestrzega, stwierdzone, a nie sugerowane

Napisane z tego samego powodu, dla którego v2fhir pisze swoje: mapowanie jest miejscem, w którym projekty interoperacyjności zawodzą, a niepowodzenia są ciche.

Source: github.com/biodream-llc/perfuse/internal/pas278

26.74 pdf

Pakiet pdf tworzy proste dokumenty tekstowe, wykorzystując tylko standardową bibliotekę.

Mirth's Document Writer renderuje HTML do PDF, co wymaga silnika układu. To nie jest to. To wytwarza prosty, paginowany dokument tekstowy z czcionką o stałej szerokości i istnieje, ponieważ rzeczywiste wymaganie w prawie każdym miejscu, które używa tego łącznika, to "umieść ten raport na udziale, aby ktoś mógł go wydrukować" - streszczenie wypisu, raport wyników, codzienne uzgodnienie. Są to teksty.

Odmowa tej funkcji całkowicie pozostawiłaby bloker migracji poziomu 2. Włączenie silnika renderującego HTML kosztowałoby więcej niż cała reszta binarnego pliku i spowodowałoby pojawienie się strumienia CVE, co odwróciłoby argumentację listy materiałów. Więc: tekst, szczerze opisany jako tekst, a miejsce, które rzeczywiście potrzebuje wyjścia typeset, jest lepiej obsługiwane przez miejsce docelowe pliku i narzędzie zaprojektowane do tego.

Dlaczego pisać PDF w ogóle, zamiast pliku tekstowego

Ponieważ odbiorca jest zwykle osobą z drukarką i udziałem systemu Windows, a plik .txt wydrukowany z udziału traci paginację, marginesy i często znaki końca linii. PDF jest drukowany w ten sam sposób wszędzie, co jest całkowitą przyczyną, dla której ktokolwiek poprosił o jeden.

Source: github.com/biodream-llc/perfuse/internal/pdf

26.75 pgp

Pakiet pgp szyfruje, podpisywuje, odszyfrowuje i weryfikuje wiadomości OpenPGP (RFC 9580 i RFC 4880 dla starszych równych), dla płatników, izb rozliczeniowych i agencji rządowych, które wymieniają pliki za pośrednictwem SFTP lub poczty e-mail pod PGP.

Kryptografia jest github.com/ProtonMail/go-crypto, utrzymana gałąź golang.org/x/crypto/openpgp; nic tutaj nie implementuje prymitywu. Ten pakiet ładuje tylko klucze i decyduje, co musi zawierać wiadomość.

Source: github.com/biodream-llc/perfuse/internal/pgp

26.76 pixv3

Pakiet pixv3 to wersja HL7 v3 indeksu pacjentów: profile IHE Patient Identifier Cross-referencing i Patient Demographics Query, których większość szpitali spoza świata FHIR nadal używa.

Odpowiedzi pochodzą z tego samego indeksu pacjentów co PIXm, PDQm, Patient/$match i ekran indeksu, więc rekord wprowadzony w wersji v3 jest znaleziony za pomocą FHIR i odwrotnie. Wiadomości są pisane ręcznie, w kolejności schematu, z powodu hl7v3.Ack.

Source: github.com/biodream-llc/perfuse/internal/pixv3

26.77 priorauth

Pakiet priorauth implementuje workflow autoryzacji wstępnej po stronie dostawcy, wymagany przez CMS-0057. Przesyła wnioski o autoryzację wstępną do API FHIR płatników, śledzi odpowiedzi i konwertuje między typami wewnętrznymi a zasobami FHIR.

Source: github.com/biodream-llc/perfuse/internal/priorauth

26.78 privacy

Pakiet privacy odpowiada na wnioski podmiotu danych na podstawie RODO i brytyjskiego RODO: znajdź wszystko, co ten serwer przechowuje o osobie, podaj to im (artykuły 15 i 20), usuń to (artykuł 17) i zachowaj to, co obejmuje prawny zakaz (prawny zakaz).

Dociera do każdego miejsca, w którym Perfuse przechowuje dane pacjentów: sklep wiadomości (przez jego indeks tożsamości), kolejka dostarczania, sklep FHIR (zasoby Pacjenta osoby i wszystko, co się do nich odnosi, z ich historią), przechowywane wnioski o autoryzację wstępną oraz indeks pacjentów, którego linki rozszerzają jeden identyfikator na wszystkie numery osoby. To, czego nie może dotknąć, nazywa: ślady wysłane do kolektora, dziennik inspekcji (zachowany jako zapis tego, kto co zrobił) i kopie zapasowe, które przechowują to, co zostało usunięte, aż do ich wygaśnięcia - więc każde usunięcie jest zapisywane w rejestrze, jako hashowane sól identyfikatorów, a nie identyfikatory, i może być ponownie zastosowane do przywróconej kopii.

Nic nie decyduje w imieniu nikogo. Czy wniosek musi być przyznany, a czy wyjątek ma zastosowanie, jest decyzją kontrolera; usunięcie wymaga zatwierdzenia przez drugiego administratora, a prawny zakaz odmawia go bezwzględnie.

Source: github.com/biodream-llc/perfuse/internal/privacy

26.79 publichealth

Pakiet publichealth implementuje dwukierunkowe raportowanie zdrowia publicznego: elektroniczne raportowanie przypadków (eCR), elektroniczne raportowanie laboratoryjne (ELR) oraz zapytania do rejestru szczepień.

Każdy szpital jest zobowiązany prawem do zgłaszania pewnych stanów — gruźlicy, odry, zapalenia wątroby, COVID-19, chorób przenoszonych drogą płciową, chorób pokarmowych — do agencji zdrowia publicznego stanu i lokalnych. Zgłaszanie odbywa się przez trzy odrębne interfejsy:

Pakiet jest dwukierunkowy: raportuje na zewnątrz (ELR, eCR, VXU) i zapytuje z powrotem (VXQ/VXR). Wszystkie operacje są w czasie rzeczywistym, a nie w nocy partii.

Wątkowa bezpieczeństwo: SubmissionLog jest bezpieczny dla jednoczesnego użycia. Funkcje budownicze są czyste i bezpieczne do wywołania z dowolnego goroutine.

Source: github.com/biodream-llc/perfuse/internal/publichealth

26.80 published

Pakiet published zawiera strażniki dla importowalnych pakietów Perfuse, w jednym miejscu.

hl7 był pierwszym opublikowanym pakietem i zawiera własną kopię tych kontroli. fhir i pas zostały opublikowane, aby usługa decyzyjna, taka jak Vaglio, czytała wnioski FHIR i PAS przy użyciu dokładnie tego samego kodu, który używa Perfuse, a nie kopii, która dryfuje: czterech czytelników kodów akcji X12 w tym repozytorium kiedyś się nie zgadzało, a jeden czytał odmowę jako zatwierdzenie. Strażnicy są przechowywani tutaj, a nie kopiowani do każdego pakietu, z tego samego powodu.

Source: github.com/biodream-llc/perfuse/internal/published

26.81 kolejka

Pakiet queue jest trwałą, per-destination kolejką dostarczania.

Bez tego, miejsce docelowe, które jest wyłączone przez dwie minuty, traci wszystko, co zostało do niego wysłane w tym czasie: ponowne próby występują w pamięci, a gdy się one wyczerpią, wiadomość jest rejestrowana jako nieudana i znika. Z tym, wiadomość jest na dysku i zachowuje swoje miejsce, aż miejsce docelowe wróci.

Dwa decyzje projektowe kształtują wszystko inne.

Kolejność jest zachowana dla każdego miejsca docelowego, co oznacza, że kolejkowane miejsce docelowe przestaje używać szybkiej ścieżki. HL7 jest strumieniem zdarzeń dotyczących tych samych pacjentów: A01 przyjmuje, A03 wypisuje. Jeśli nieudane A01 trafia do kolejki, a następne A03 jest dostarczane bezpośrednio, system odbiorczy widzi wypis pacjenta, którego nigdy nie przyjęto. Dlatego też, gdy coś jest kolejkowane dla miejsca docelowego, wszystko dla tego miejsca docelowego kolejkuje się za nim, aż kolejka się opróżni. To kosztuje przepustowość podczas awarii i nie jest opcjonalne, ponieważ alternatywą jest cicha, kliniczna bzdura. To również jest konkretna rzecz, która szwankuje w innych silnikach, gdy ktoś włącza współbieżne wątki kolejki, aby szybciej opróżnić zaległości.

Wiadomość w kolejce jest wiadomością zaakceptowaną. Nadawca jest informowany o AA, ponieważ bajty są na dysku i fsynced przed wysłaniem potwierdzenia. Mówienie AE sprawiłoby, że poprawnie funkcjonująca kolejka przechowywania i przekazywania wyglądałaby jak błąd i zachęcałaby nadawcę do ponownego wysłania tego, co już posiadamy.

Source: github.com/biodream-llc/perfuse/internal/queue

26.82 rezydencja

Rezydencja pakietu określa, gdzie mogą się znaleźć dane tego serwera: chmury regionów, które witryna zezwala (EEA, Wielka Brytania, Szwajcaria lub regiony nazwane pojedynczo), oraz czy region łącznika jest jednym z nich.

Perfuse sprawdza to, co może wiedzieć. Łącznik AWS nazywa swój region (S3, SQS, SNS), a nazwa hosta AWS zawiera jeden (sqs.eu-west-2.amazonaws.com); są one sprawdzane, gdy kanał jest zapisywany i ładowany, więc kanał nie może wysyłać danych pacjentów do wiadra w Wirginii z serwera, którego dane muszą pozostać we Frankfurcie. Zwykła nazwa hosta (własny system szpitala, słuchacz MLLP partnera) nie mówi nic o tym, gdzie się znajduje, i nie jest tu oceniana: rekord przetwarzania wyświetla każdego hosta, do którego kanał wysyła, aby kontroler mógł to sprawdzić.

Source: github.com/biodream-llc/perfuse/internal/residency

26.83 rtpb

Pakiet rtpb odpowiada na żądania NCPDP Real-Time Prescription Benefit z formularza: jaki lek będzie kosztował tego członka w tej aptece, czy wymaga uprzedniej autoryzacji lub pierwszego kroku, oraz które alternatywy kosztują mniej.

CMS-0062-P proponuje RTPB dla dotkniętych płatników od 1 października 2027 r. XML to NCPDP RTPB w13 (PBv13). Schemat NCPDP jest objęty licencją, więc nazwy elementów i kolejność podążają za publicznymi przykładami Surescripts RTPB i publicznymi zaleceniami wdrożeniowymi NCPDP (kody ograniczeń pokrycia i stan pokrycia, do którego każdy z nich się odnosi); odpowiedź nie jest sprawdzana pod kątem XSD tutaj, a certyfikacja sieciowa jest miejscem, w którym to się dzieje.

Source: github.com/biodream-llc/perfuse/internal/rtpb

26.84 s3put

Pakiet s3put zapisuje obiekty w S3, używając tylko standardowej biblioteki.

Oczywisty sposób rozmawiania z S3 to zestaw SDK AWS, a SDK jest ogromne. Ten projekt sprzedaje binarny plik statyczny z ośmioma zależnościami bezpośrednimi i listą materiałów, która mieści się na jednym ekranie - to jest prawdziwy argument z osobą, która przegląda oprogramowanie przed zainstalowaniem go w szpitalu, a wymiana go na jeden łącznik byłaby złym interesem.

Co S3 tak naprawdę potrzebuje, to HTTP PUT i podpis. Wersja 4 podpisu jest w pełni określona, jest deterministyczna, a AWS publikuje wektory testowe dla niej. Zatem jest to zaimplementowane tutaj: około dwieście linii wobec crypto/hmac i net/http, bez nowej zależności i niczego do poprawienia, gdy SDK ma zalecenie.

Co to celowo nie robi

Brak wieloczęściowego przekazywania, brak ponownych prób na własną rękę, brak łańcucha poświadczeń poza statycznymi kluczami i standardowymi zmiennymi środowiskowymi. Wiadomość HL7 to kilka kilobajtów, więc wieloczęściowe rozwiązanie rozwiązuje problem, którego ten nie ma; silnik już ponawia próby; a łańcuch poświadczeń roli instancji oznaczałby wywołania IMDS, buforowanie i logikę odświeżania, co jest miejscem, w którym mała implementacja przestaje być mała. Jeśli ktoś potrzebuje tych rzeczy, uczciwa odpowiedź to miejsce docelowe pliku i narzędzie synchronizacji, a nie pół-wybudowany SDK.

Działa z wszystkim, co mówi w API S3 - MinIO, Ceph, Wasabi, Backblaze - ponieważ jest to po prostu podpisywany HTTP. To jest efekt uboczny, który się ma, ponieważ magazyn obiektów szpitala często nie jest AWS.

Source: github.com/biodream-llc/perfuse/internal/s3put

26.85 saml

Wyłączna kanonikalizacja XML (exc-c14n) zgodnie z https://www.w3.org/TR/xml-exc-c14n/

To jest postać kanoniczna bajtów, którą podpisywanie XML podpisuje. Źle to robiąc, sprawia, że ważne podpisy wyglądają na nieważne i - co gorsza - implementacja, która to robi w większości prawidłowo, przejdzie testowanie wobec własnych podpisów, podczas gdy odrzuci prawdziwe odpowiedzi IdP.

Przepisy, które mają znaczenie dla SAML: - Deklaracje przestrzeni nazw są renderowane tylko wtedy, gdy są widocznie wykorzystywane przez element lub jego atrybuty. - Dziedziczone przestrzenie nazw, których element używa, ale nie deklaruje, są renderowane tak, jakby były deklarowane w tym elemencie. - Atrybuty są sortowane: deklaracje przestrzeni nazw jako pierwsze (sortowane według prefiksu), a następnie inne atrybuty (sortowane według pełnej nazwy: URI przestrzeni nazw, a następnie nazwa lokalna). - Puste elementy używają start-tag/end-tag, nigdy nie zamykają się samodzielnie. - Węzły tekstowe są wyprowadzane żywo; CDATA jest zastępowana przez jej zawartość z ucieczką encji. - Instrukcje przetwarzania i komentarze poza elementem dokumentu są wykluczone.

Source: github.com/biodream-llc/perfuse/internal/saml

26.86 scim

Pakiet scim implementuje SCIM 2.0, protokół, który dostawcy tożsamości używają do obsługi kont.

Okta, Entra ID, Google Workspace i OneLogin wszystkie obsługują ten standard. Administrator dodaje kogoś do grupy w dostawcy tożsamości, a w ciągu minuty pojawia się tu konto z odpowiednią rolą. Jeśli kogoś usuną, konto znika.

Odłączanie jest punktem

Inicjowanie obsługi jest wygodne. Odłączanie jest powodem, dla którego warto to zbudować, i jest to połowa, która się nie powodzi.

Gdy ktoś opuszcza organizację, dostawca tożsamości jest systemem, który dowiaduje się o tym jako pierwszy - zwykle dlatego, że dział HR rozwiązuje umowę i dostawca jest sterowany przez rekord HR. Następnie informuje każdą połączoną aplikację o wyłączeniu konta. Jeśli ten wywołanie nie powiedzie się lub zakończy się powodzeniem bez usunięcia dostępu, były pracownik zachowuje dostęp do klinicznego silnika integracji i nikt się nie dowiaduje, ponieważ nikt nie monitoruje czegoś, co nie nastąpiło.

Tak więc najważniejsze części tego pakietu to te, które sprawiają, że odłączanie jest realne:

Dlaczego jest to oddzielny pakiet

Kształty SCIM nie są kształtami Perfuse. Ma własny format błędów, własną kopertę listy, własny język patchowania i własne opinie o wielkości liter atrybutów. Przechowywanie tłumaczenia w jednym miejscu oznacza, że obsługa może dotyczyć tego, co dzieje się z kontem, a nie JSON.

Source: github.com/biodream-llc/perfuse/internal/scim

26.87 skrypt

Skrypt pakietu uruchamia skrypt Mirth Connect JavaScript.

Celem jest to, aby skrypty kanału przenosiły się nietknięte. Jest to ćwiczenie zgodności, a nie ćwiczenie projektowe, więc kształt wszystkiego tutaj jest dyktowany przez to, co Mirth ujawnia: msg i tmp jako drzewa E4X, sześć map z metodami Map Java, rodzina funkcji wyszukiwania $, logger i garść obiektów pomocniczych, których nazwy metod i ciągi formatowania dat są Java.

Trzy decyzje są nasze, a nie Mirth, i każda jest zamierzoną zmianą:

Skrypt uruchamia się z limitem czasu i jest przerywany, gdy go przekroczy. Mirth pozwoli skryptowi na pętle bez końca, co powoduje, że kanał się zatrzymuje; interfejs, który przestaje przyjmować przyjęcia z powodu błędu w transmutatorze, nie jest akceptowalny, więc zawsze jest limit czasu.

Odmowa interoperacyjności z Java z błędem nazwy klasy zamiast zwrócenia niezdefiniowanego. Skrypt sięgający do Packages.java.sql nie może być doprowadzony do skutku tutaj, a przydatny wynik to wiadomość mówiąca dokładnie to w linii, w której się to dzieje, a nie NullPointerException trzy linie później.

Dostęp do plików i bazy danych jest wyłączony, chyba że kanał go włączy. Mirth przyznaje oba skryptom domyślnie. Transmutator, który może odczytać dowolny plik, do którego proces może odczytać, jest rozsądną rzeczą do pragnienia i nierozsądnym domyślnym ustawieniem.

Source: github.com/biodream-llc/perfuse/internal/script

26.88 Ustawienia

Pakiet ustawień jest jedyną opisem wszystkiego dotyczącego serwera Perfuse, które operator może zmienić.

Dlaczego to istnieje

Przed tym pakietem około trzydzieści rzeczy były flagami wiersza poleceń i niczym więcej. Zmiana czasu przechowywania wiadomości oznaczała edycję definicji usługi i ponowne uruchomienie, co w szpitalu oznacza bilecik zmiany - tak więc w praktyce nikt ich nie zmienił, a domyślne ustawienie wybrane w pierwszym popołudniu stało się ustawieniem na zawsze.

Dlaczego jeden rejestr zamiast formularza

Oczywisty sposób budowy strony ustawień polega na napisaniu formularza. To powoduje, że dwie opisy każdego ustawienia - jeden na serwerze, który je waliduje, i jeden w interfejsie, który je renderuje - dryfują. Dryfowanie jest ciche: pole, które serwer przestał akceptować, nadal ma kontrolę, więc ktoś je ustawia, widzi, że zostało zapisane, i nie robi nic.

Tak więc ustawienie jest deklarowane raz, tutaj, z wszystkim, co jest potrzebne do sprawdzenia i narysowania go: jaki rodzaj wartości jest, jaki kontrola mu odpowiada, do której grupy należy, co oznacza, i czy zmiana go ma efekt natychmiastowy. Interfejs prosi o ten opis i renderuje to, co mu powiedziano. Dodanie ustawienia to jeden wpis w tym pakiecie i w ogóle żadna praca interfejsu.

TestEverySettingIsFullyDescribed egzekwuje części, które człowiek musi dostarczyć, ponieważ ustawienie bez tekstu pomocy jest ustawieniem, które ktoś zgaduje.

Dlaczego plik zamiast bazy danych

Ustawienia mieszczą się w pliku YAML, który interfejs edytuje na miejscu, odpowiadając, jak kanały i reguły alertów już działają. Trzy powody, w kolejności ważności: kontrola zmian szpitala chce konfiguracji, która może być porównywana i umieszczana w kontroli wersji; operator z maszyną, ale nie z aplikacją, może przeczytać plik i nie może odczytać bazy danych; oraz przywrócenie ustawień z dnia poprzedniego nie powinno wymagać, aby aplikacja działała.

Dlaczego tylko flagi nasionują

Plik wygrywa, gdy istnieje, a flagi dostarczają początkowej zawartości. Alternatywa - flagi zawsze wygrywają - sprawiłaby, że interfejs byłby nieprawdziwy, ponieważ wszystko, co kiedykolwiek przekazywane jest na linii poleceń, mogłoby być edytowane, zapisywane i ignorowane w milczeniu.

Flaga, która nie zgadza się z plikiem, jest zgłaszana podczas uruchamiania, z nazwą obu wartości, ponieważ w przeciwnym razie flaga pozostaje w definicji usługi przez lata, a następna osoba, która ją przeczyta, uwierzy w nią.

Source: github.com/biodream-llc/perfuse/internal/settings

26.89 sftpconn

Pakiet sftpconn otwiera połączenia SFTP.

Wydzielony z konektorów, ponieważ interesującą częścią jest uwierzytelnianie i weryfikacja klucza hosta, a obie są identyczne, niezależnie od tego, czy kanał zbiera pliki, czy je zapisuje. Dwie kopie by się rozbiegły, a ta, która by się rozbiegła, byłaby tą, która przestałaby weryfikować.

Source: github.com/biodream-llc/perfuse/internal/sftpconn

26.90 cieniowanie

Pakiet shadow porównuje kandydujący kanał z żywym.

Sam porównanie jest łatwą częścią. Cała wartość leży w dwóch gwarancjach, a obie są egzekwowane przez konstrukcję, a nie przez konfigurację:

Cokolwiek mniej niż to sprawi, że tryb cienia stanie się sposobem na złamanie produkcji podczas próby uniknięcia złamania produkcji.

Source: github.com/biodream-llc/perfuse/internal/shadow

26.91 shl

Pakiet shl implementuje SMART Health Links i SMART Health Cards: kody QR, o które prosi CMS "Kill the Clipboard", które dostawcy powinni zaakceptować podczas check-in i zwrócić wraz z rekordem wizyty.

SMART Health Link (SMART Health Links STU 1) to shlink:/ po którym następuje base64url JSON: adres URL manifestu, 256-bitowy klucz i opcjonalnie data wygaśnięcia, etykieta i flagi (P passcode, L długoterminowy, U jeden plik za pomocą GET). Odbiorca wysyła do adresu URL manifestu i otrzymuje pliki, z których każdy jest szyfrowany JWE z tym kluczem - alg dir, enc A256GCM, opcjonalnie kompresja DEFLATE - zawierający FHIR JSON, SMART Health Cards lub token dostępu SMART. Serwer, który hostuje pliki, nigdy nie widzi klucza: podróżuje tylko w łączu, które jest własnością pacjenta.

SMART Health Card (SMART Health Cards Framework 1.4) to podpisany pakiet FHIR: kompaktowy JWS, ES256, z ładunkiem DEFLATE-kompresowanym, nazywającym swojego emitenta, którego klucz publiczny znajduje się w <iss>/.well-known/jwks.json. Podróżuje jako numeryczny kod QR shc:/ lub plik .smart-health-card.

Tylko standardowa biblioteka: crypto/aes, crypto/cipher, crypto/ecdsa i compress/flate obejmują wszystko, a biblioteka JOSE przyniosłaby znacznie większą powierzchnię dla dwóch algorytmów.

Source: github.com/biodream-llc/perfuse/internal/shl

26.92 smartauth

Pakiet smartauth jest serwerem autoryzacji SMART App Launch: wydaje tokeny dostępu, które punkt końcowy FHIR Perfuse akceptuje.

Napisany przeciwko standardowej bibliotece, jak internal/oidc, który weryfikuje to, co ten podpisuje. Tokeny są JWT podpisanymi RS256, jednym algorytmem, na którym może polegać każdy klient SMART i reguły tokenów ID specyfikacji.

Source: github.com/biodream-llc/perfuse/internal/smartauth

26.93 snmp

Pakiet snmp to mały agent SNMPv2c tylko do odczytu: GET, GETNEXT i GETBULK przez UDP wobec tabeli wartości, które wypełnia wywołujący, oraz pułapki SNMPv2.

Wiadomości są zakodowane BER (X.690) tutaj; nic w tym nie jest kryptografią (ciąg społeczności v2c jest hasłem w postaci zwykłego tekstu, dlatego agent odpowiada tylko na sieci, o których został poinformowany).

Source: github.com/biodream-llc/perfuse/internal/snmp

26.94 soap

Pakiet soap wysyła żądania SOAP i czyta błędy SOAP, używając tylko standardowej biblioteki.

SOAP to sporo ceremonii wokół HTTP POST, i nadal jest to sposób, w jaki wiele szpitali middleware akceptuje dane - systemy administracji pacjentów, repozytoria dokumentów, usługi regionalnych rejestrów, wszystko, co zostało określone w dekadzie, kiedy to było odpowiedzią. Mirth ma łącznik usługi internetowej, więc jest to bloker migracji Tier 2, a nie coś miłego.

Dlaczego nie wygenerowany klient

Zwykłe podejście polega na pobraniu WSDL i wygenerowaniu typów Go z niego. To jest odpowiedź dla aplikacji rozmawiającej z jedną znaną usługą, a nieodpowiednia tutaj: miejsce docelowe silnika integracji jest konfigurowane przez kogoś, kto edytuje kanał, a nie ponownie skompilowany, więc koperta musi być zmontowana w czasie wykonywania z szablonu, który może zobaczyć i zmienić. Oznacza to również, że nie ma kroku generowania kodu i niczego, co trzeba ponownie wygenerować, gdy drugi koniec opublikuje nowe WSDL.

Co to celowo nie robi

Brak parsowania WSDL, brak WS-Security, brak MTOM, brak WS-Addressing. Każdy z nich jest samodzielną specyfikacją, a udawanie, że się ją wspiera, podczas gdy szczegóły są błędne, jest gorsze niż nieoferowanie jej w ogóle - sygnatura, która prawie się weryfikuje, nie różni się od ataku na drugim końcu. WS-Security w szczególności jest miejscem, gdzie półimplementacja mogłaby wyrządzić prawdziwą szkodę.

To, co jest tutaj: koperty SOAP 1.1 i 1.2, szablonizowane ciało, nagłówek SOAPAction i wykrywanie błędów, które czyta ciąg błędu zamiast raportować "500".

Source: github.com/biodream-llc/perfuse/internal/soap

26.95 sof

Pakiet sof uruchamia SQL na FHIR v2 ViewDefinitions: widok zamienia każdy zasób FHIR jednego typu w wiersze o nazwanych kolumnach, za pomocą FHIRPath, tak aby dane FHIR mogły być odczytywane jako tabele przez silniki SQL, arkusze kalkulacyjne i miary jakości.

Postępuje zgodnie z algorytmem przetwarzania ViewDefinition (kolumna, wybór, forEach, forEachOrNull, powtórzenie, unionAll, gdzie, stałe, %rowIndex, getResourceKey i getReferenceKey) i jest sprawdzany względem oficjalnych testowych fixture sql-on-fhir.

Source: github.com/biodream-llc/perfuse/internal/sof

26.96 sqldb

Pakiet sqldb otwiera połączenia z bazą danych dla źródła i miejsca docelowego.

Sterowniki są zarejestrowane tutaj i nigdzie indziej, więc istnieje tylko jedno miejsce, które decyduje, do czego Perfuse może się połączyć.

Source: github.com/biodream-llc/perfuse/internal/sqldb

26.97 sqlitedb

Pakiet sqlitedb otwiera SQLite w sposób, w jaki potrzebuje go serwer: jedno połączenie do zapisu i kilka do odczytu.

Powodem jest tryb awaryjny, który pojawia się dopiero po uruchomieniu wdrożenia przez jakiś czas. SQLite w trybie WAL pozwala czytelnikom działać obok pisarza, ale pulpit połączeń Go znajduje się powyżej SQLite, więc pulpit o jednym połączeniu serializuje wszystko, niezależnie od tego, co pozwalałaby baza danych. Przeglądarka wiadomości skanuje kolumnę ładunku, a każda przychodząca wiadomość czeka za nią.

Zmierzone na tej maszynie, zapis trwa 104µs, gdy sklep jest bezczynny, i 2,6 ms, gdy przeglądarka skanuje cztery tysiące wiadomości: dwadzieścia pięć razy wolniej. To skaluje się z tabelą, więc przy kilku setkach tysięcy przechowywanych wiadomości raport zmienia się w sekundy opóźnienia dostarczania, a zapis znajduje się na ścieżce potwierdzenia. Nadawca widzi limit czasu, wysyła ponownie, a ktoś spędza poranek szukając problemu w sieci.

Podział puli nie kosztuje nic i usuwa interakcję: raporty otrzymują własne połączenia, a pisarz zachowuje jedno dla siebie, ponieważ SQLite pozwala na dokładnie jednego pisarza.

Source: github.com/biodream-llc/perfuse/internal/sqlitedb

26.98 steps

Declaratywne kroki transformacji dla dowolnego formatu wiadomości.

Dlaczego jest to współdzielone

Słownictwo kroków - ustaw, skopiuj, wyczyść, mapuj, zamień, obetnij, przypadek, każdy z opisem i opcjonalnym warunkiem - nie ma nic wspólnego z konkretnym formatem. Różnią się tylko trzy rzeczy między formatami: w jaki sposób zapisywana jest ścieżka, w jaki sposób odczytywana jest wartość i w jaki sposób jest zapisywana z powrotem.

To jest ten sam wniosek, jaki osiągnęła gramatyka filtrów w internal/expr, i z tego samego powodu. X12 miał silnik kroków i NCPDP potrzebował jednego; kopiowanie go spowodowałoby powstanie drugiego silnika o czterystu liniach, który trzeba by ręcznie utrzymywać, a potem trzeciego dla ograniczonego. Zachowanie, które się liczy, jest na tyle subtelne, że kopia nie utrzymałaby go - powodem, dla którego wynik jest odczytywany ponownie po każdym zapisie, jest na przykład to, że wymagał prawdziwej wady, aby go odkryć.

Co dostarcza format

Akcesor: kompilator ścieżki, kompilator warunku i opcjonalny veto na kroki, których nie może honorować. Nic więcej.

Source: github.com/biodream-llc/perfuse/internal/steps

26.99 stomp

Pakiet stomp komunikuje się za pomocą STOMP 1.2 z brokera wiadomości.

To jest to, co "wsparcie JMS" musi oznaczać w programie, który nie jest Javą. JMS jest interfejsem API, a nie protokołem, więc nie ma nic do zaimplementowania: to, czego potrzebuje strona, to aby Perfuse mógł porozumieć się z brokera stojącym za ich aplikacjami JMS.

STOMP zamiast OpenWire, a uzasadnienie jest warte zapisania, ponieważ oczywista odpowiedź jest błędna. OpenWire jest rodzimym protokołem ActiveMQ i binarną serializacją poleceń JMS - tygodnie pracy, specyficzne dla jednej rodziny brokera, i nieudokumentowane, poza implementacją. ActiveMQ automatycznie wykrywa STOMP, AMQP i MQTT na tym samym porcie, na którym obsługuje OpenWire, więc protokół tekstowy może dotrzeć do tych samych brokerów. STOMP obejmuje ActiveMQ Classic, Artemis i RabbitMQ; AMQP 1.0 dodałby Azure Service Bus i IBM MQ i jest najbardziej sensownym następnym, zamiast OpenWire.

Napisane przeciwko standardowej bibliotece. Klient brokera nie jest miejscem dla zależności, której tryby awaryjne są czyimś do wyjaśnienia, a ramowanie tutaj jest wystarczająco małe, aby kosztować mniej niż czytanie ich śledzenia problemów.

Source: github.com/biodream-llc/perfuse/internal/stomp

26.100 magazyn

Magazyn pakietu przechowuje dane, które są prawdziwie stanowe: użytkownicy, sesje i ślad audytowy.

Kanały są celowo umieszczane poza tym miejscem. Żyją w plikach, ponieważ to daje git, różnice, przegląd kodu i promocję środowiska za darmo. Umieszczenie kanałów w bazie danych jest decyzją, która zmusza do kupowania każdego z nich oddzielnie, i jest to powód, dla którego istnieje produkt trzeciej strony, który służy wyłącznie do przenoszenia kanałów Mirth między jego bazą danych a repozytorium git.

Więc podział jest następujący: konfiguracja w plikach, tożsamość i historia w SQLite.

Source: github.com/biodream-llc/perfuse/internal/store

26.101 tefca

Pakiet tefca implementuje części uczestnictwa w TEFCA, które nie wymagają połączenia z QHIN.

Co jest rzeczywiste

Weryfikacja celu użycia, weryfikacja konfiguracji oraz ślad audytowy - w tym jego trwałość, interfejs zapytań i obowiązek rejestrowania nieudanych prób, a także udanych. Ta ostatnia część nie jest technicznością: seria nieudanych dostaw do jednego odbiorcy jest tym, jak pojawia się niepoprawnie skonfigurowany partner, a seria nieudanych zapytań dotyczących różnych pacjentów jest tym, jak pojawia się sondowanie.

Co nie jest

Sieć. Nie ma transportu QHIN w tym zestawie, więc nie występuje wymiana, a każda funkcja wymiany odmawia z powodu ErrExchangeNotImplemented zamiast zwracać sukces.

Ten podział nie zawsze był wyraźny, a sposób, w jaki to poszło nie tak, jest wart zapamiętania. Wszystkie cztery funkcje wymiany wcześniej walidowały swoje dane wejściowe, nie wykonywały połączeń sieciowych i zwracały sukces; funkcja Deliver zwracała odpowiedź zaakceptowaną z identyfikatorem śledzenia utworzonym z zegara. Warstwa audytu następnie rejestrowała każdą z nich jako zakończoną wymianę - w dzienniku, który istnieje, aby udowodnić, co zostało wymienione, kiedy ktoś pyta o to miesiące później. Cztery testy potwierdzały to zachowanie i przechodziły.

Co wymaga ukończenia

Rejestracja z Siecią Zdrowia Informacji Kwalifikowanych, wzajemnie uwierzytelniony TLS przy użyciu certyfikatów wydanych w ramach tego procesu, oraz albo profile IHE, z których zaczął się Wspólny Porozumienie, lub ułatwiony FHIR zgodnie z procedurą operacyjną projektu Sequoia, obowiązującą od 8 marca 2026 r. Żadna z tych rzeczy nie może być napisana spekulatywnie: jest testowana przeciwko prawdziwej QHIN lub nie jest testowana, a niewdrożona implementacja wymiany jest tym samym defektem, co brak implementacji w lepszym przebraniu.

Source: github.com/biodream-llc/perfuse/internal/tefca

26.102 najemca

Pakiet najemca zapewnia reguły tożsamości i izolacji dla operacji wielonajemców.

HIE, clearinghouse lub dostawca usług zarządzanych uruchamia jeden silnik w imieniu wielu organizacji. Mirth nie może tego zrobić - jeden wystąpień służy jednej organizacji, a dostawca usług zarządzanych kończy się uruchamianiem pięćdziesięciu maszyn wirtualnych i pięćdziesięciu baz danych.

Co należy do najemcy

Jego kanały, jako katalog plików. Jego użytkownicy. Jego wiadomości, kolejka, ślad audytowy i zasoby FHIR. Jego etykiety metryk. Nic nie jest współdzielone, poza procesem, portami nasłuchiwania, które zostały mu przydzielone, i platformą administratorów.

Izolacja jest strukturalna, a nie pamiętana

Niebezpieczna awaria tutaj nie jest awarią. Jest to najemca A widzący wiadomości najemcy B, co jest naruszeniem raportowalnym, a nie błędem. Projekt, w którym każde zapytanie wymaga parametru tenant_id, zawodzi pierwszy raz, kiedy ktoś pisze zapytanie i zapomina o jednym, i to zapytanie wygląda idealnie poprawnie w przeglądzie.

Więc najemca nie jest parametrem. Dostęp do danych odbywa się przez uchwyt, który już go przenosi, i nie ma sposobu, aby dotrzeć do tabel bez niego. Zapominanie nie jest dostępne.

Source: github.com/biodream-llc/perfuse/internal/tenant

26.103 terminologia

Pakiet terminologia przechowuje opublikowane systemy kodów (LOINC, SNOMED CT, RxNorm, ICD-10-CM, CPT i lokalne) do wyszukiwania kodów i tabel mapowania wartości, których nie miał, dla kogoś do mapowania.

Systemy kodów są importowane z plików, których wydawcy dystrybuują. Kilka z nich jest licencjonowanych (LOINC wymaga bezpłatnego konta, SNOMED CT licencji stowarzyszonej, RxNorm licencji UMLS, CPT licencji AMA), więc żaden z nich nie jest dostarczany z Perfuse: administrator, który posiada licencję, przesyła plik, a Perfuse rejestruje, kto go zaimportował i kiedy.

Source: github.com/biodream-llc/perfuse/internal/terminology

26.104 tlsconf

Pakiet tlsconf tworzy konfigurację TLS z plików i opisuje certyfikaty.

Jest to darmowy odpowiednik rozszerzenia Mirth, za które teraz się płaci. Większość wartości nie leży w szyfrowaniu, które jest tylko kilku linijek kodu, ale w części, która uniemożliwia wdrożenie czegoś, co wydaje się bezpieczne, ale tak naprawdę nie jest: odmowa pominięcia weryfikacji w trybie cichym, naleganie na sprawdzenie certyfikatu klienta, gdy jest on wymagany, oraz wyraźne powiadomienie, gdy certyfikat jest bliski wygaśnięcia.

Wygasły certyfikat na interfejsie jest prawdziwym awarią szpitala i występuje, ponieważ nikt nie został poinformowany. Część opisowa tego pakietu istnieje właśnie z tego powodu.

Source: github.com/biodream-llc/perfuse/internal/tlsconf

26.105 tomirth

Pakiet tomirth zapisuje kanał Perfuse jako kanał Mirth w formacie XML.

Dlaczego ten pakiet istnieje. Zastrzeżenie dotyczące przyjęcia nowego silnika integracji rzadko jest „czy jest on dobry”. Jest to „co się stanie, jeśli się mylimy i będziemy zablokowani”, a najtańszą odpowiedzią na to jest możliwość wycofania się. Perfuse może odczytywać kanały Mirth od samego początku; do tej pory nie mógł ich zapisać, co sprawiło, że gwarancja była jednorazowa i nie stanowiła zbyt wielkiej gwarancji.

Jak uniknąć pułapki, która uczyniła pierwszą próbę bezużyteczną. XML Mirth jest wyjściem XStream, a XStream odczytuje atrybuty klasy i wersji jako instrukcje: element, którego nie rozpoznaje, jest odrzucany bez słowa, a kanał, którego nie można złożyć, jest przechowywany z opisem zastąpionym przez „Ten kanał jest nieprawidłowy. Sprawdź, czy wszystkie wymagane rozszerzenia są załadowane poprawnie” i jego miejsca docelowe są odrzucane. Nic w tej odpowiedzi nie wymienia elementu winnego. Eksportujący, który komponuje bloki właściwości z odczytu formatu, zawodzi więc w sposób, który jest drogi w diagnozie, co się stało: to repozytorium zawierało eksportującego z dziewięcioma testami, które przeszły pomyślnie, ale Mirth odrzucił jego wyjście, ponieważ każdy test porównywał je z naszym własnym parserem zamiast z serwerem.

Żadne z bloków właściwości nie są komponowane tutaj. Skrypt scripts/mirth-dump-connector-templates.sh ma ObjectXMLSerializer Mirth seryjizować domyślne właściwości każdej klasy właściwości łącznika, a te dokumenty są zatwierdzane w katalogu templates/. Ten pakiet zastępuje wartości w nich, a mirth.SetRawProperty odmawia każdej ścieżki, której szablon nie zawiera już - więc błąd jest błędem nazwy ścieżki, w momencie eksportu, a nie kanałem, który znika podczas importu.

Co to nie zrobi. Transport, którego nie ma odpowiednika w Mirth, jest odrzucany przez nazwę, a nie przybliżany. Eksport, który cicho przekształciłby miejsce docelowe S3 w zapisywacz plików, byłby gorszy niż brak eksportu w ogóle, ponieważ kanał zostałby zaimportowany czysto i dostarczony do niewłaściwego miejsca.

Source: github.com/biodream-llc/perfuse/internal/tomirth

26.106 trace

Pakiet trace wytwarza rozproszone ślady dla wiadomości poruszających się przez kanał i eksportuje je za pomocą OTLP/HTTP z kodowaniem JSON.

Dlaczego istnieje zamiast zestawu SDK OpenTelemetry: zestaw SDK plus eksportujący OTLP ściąga około sześćdziesiąt modułów i dodaje tyle samo do binarnego pliku, co cała reszta tego programu. To, co jest naprawdę potrzebne, jest wąskie - propagacja kontekstu śladu W3C, model span, próbkowanie główne i partiony POST HTTP - a OTLP/JSON jest udokumentowanym stabilnym kodowaniem, które może być wytworzone za pomocą samej standardowej biblioteki. Ten sam handel, co wybór lib/pq zamiast pgx: weź mniejszą rzecz, gdy tylko część dużej rzeczy jest potrzebna.

Konsekwencja warta stwierdzenia: nie ma automatycznego instrumentarium i eksportera specyficznego dla dostawcy. Spany są tymi, które ten program tworzy celowo, i trafiają do dowolnego punktu końcowego OTLP - kolektora, Jaeger, Grafana Tempo, Honeycomb, Datadog's OTLP ingest.

Właściwość, która ma większe znaczenie niż spany

Wiadomość często przychodzi z nagłówkiem traceparent z systemu, który ją wysłał, i wychodzi w kierunku systemu, który nagra jeden ze swoich. Kontynuowanie tego śladu zamiast rozpoczęcia nowego jest tym, co umożliwia pojedynczy widok „EHR wysłał to, silnik przekształcił, rejestr odrzucił” w ogóle. Problemy interfejsu są prawie zawsze zgłaszane jako „wysłaliśmy to i nic się nie stało”, a to pytanie jest nieodpowiednie bez identyfikatora, który przetrwa skok.

Śledzenie nigdy nie powinno wpływać na dostawę

Każda operacja tutaj jest najlepsza. Spany są upuszczane, gdy bufor jest pełny, awarie eksportu są liczone i nigdy nie są ponawiane w ścieżce wiadomości, a żadne wywołanie nie blokuje sieci. Upuszczony span jest niedogodnością. Wiadomość opóźniona lub utracona, ponieważ tylne śledzenie było wolne, jest incydentem klinicznym, więc handel jest zawsze niekwestionowany.

Source: github.com/biodream-llc/perfuse/internal/trace

26.107 transform

Pakiet transform stosuje deklaracyjne zmiany do wiadomości.

Jest to warstwa przeznaczona do przenoszenia zwykłej pracy, przy czym skryptowanie jest traktowane jako wyraźna klapa awaryjna. Różnica nie jest stylistyczna. Krok deklarowany w YAML może być sprawdzony przed jego uruchomieniem, wyświetlony w diffie, przeglądany przez kogoś, kto nie czyta JavaScriptu, i zgłoszony; skrypt może być tylko wykonywany i miał nadzieję. Większość tego, co transformatorzy Mirth naprawdę robią, jest nudna - kopiowanie pola, wypełnienie identyfikatora, mapowanie kodu przez tabelę, wyczyszczenie czegoś, co nie powinno opuścić budynku - i wszystko to należy do tego miejsca.

Każdy krok wyraźnie określa swój cel i każdy krok jest odwracalny w tym sensie, że mówi, co zrobił, ponieważ najdroższa awaria w interfejsie jest transformacją, o której nikt nie wiedział, że się dzieje.

Source: github.com/biodream-llc/perfuse/internal/transform

26.108 translate

Pakiet translate konwertuje kanał Mirth na definicję kanału Perfuse.

perfuse explain raportuje, co blokuje migrację. Wykonuje większość migracji, co jest odrębnym i znacznie większym twierdzeniem, więc celowo jest ostrożny w tym, co twierdzi.

Trzy reguły kształtują całość.

Nic nie jest milcząco odrzucane. Każda część kanału źródłowego jest albo tłumaczona, przenoszona bez zmian jako skrypt, albo zgłaszana jako wymagająca interwencji człowieka. Tłumacz, który cicho pomijałby krok, wyprodukowałby kanał, który zaczyna się, działa i traci dane — najgorszy możliwy wynik i powód, dla którego ludzie nieufnie podchodzą do narzędzi migracyjnych.

Deklaratywne tam, gdzie jest pewność, skrypt tam, gdzie nie jest. Krok Mapper, który kopiuje pole, staje się krokiem deklaratywnym, ponieważ jest czytelny i sprawdzalny. Krok JavaScript staje się skryptem, ponieważ Perfuse uruchamia niezmieniony skrypt JavaScript Mirth, a przepisanie go na coś, co wygląda na równoważne, jest dokładnie tym miejscem, w którym tłumacz wprowadziłby różnicę, której nikt by nie zauważył.

Wynik jest przeznaczony do odczytu. Zawiera komentarze wyjaśniające, skąd co pochodzi i co zostało pozostawione dla osoby. Migracja jest przeglądana przez kogoś, kto musi ją zatwierdzić, a niewyjaśniona ściana YAML nie może być przeglądana.

Source: github.com/biodream-llc/perfuse/internal/translate

26.109 udap

Pakiet udap implementuje klienta połowę HL7 Security for Scalable Registration, Authentication, and Authorization — specyfikację TEFCA's Facilitated FHIR exchange.

UDAP jest infrastrukturą kluczy publicznych przymocowaną do OAuth 2.0. Społeczność zaufania wydaje certyfikaty X.509 swoim członkom; członek udowadnia, kim jest, podpisując JWT za pomocą klucza prywatnego i dołączając łańcuch certyfikatów w nagłówku JWT. To zastępuje współdzielony sekret klienta w zwykłym OAuth, który nie skaluje się do tysięcy organizacji, które nigdy się nie spotkały.

Dlaczego ten pakiet w ogóle istnieje. TEFCA exchange nie może być w pełni zweryfikowany bez prawdziwego QHIN: dołączenie do niego wymaga onboardingu i wydanych certyfikatów i nie może być sfałszowane. Ale profil zabezpieczeń pod spodem jest opublikowanym przewodnikiem implementacji HL7 z publicznymi serwerami referencyjnymi, a jeden z nich odpowiada w otwartym Internecie. Więc część, która może być zweryfikowana, jest tutaj zweryfikowana, a część, która nie może, jest odrzucana na granicy, zamiast zgadywana.

Różnica jest ważna ze względu na to, co się stało z SAML w tym repozytorium: tysiąc linii testów przeszło, pięć z nich specjalnie o kanonikalizacji podpisu, podczas gdy żaden prawdziwy dostawca tożsamości nie mógł uwierzytelnić nikogo. Oba połowy zostały napisane tutaj i zgadzały się ze sobą. Lekcja wzięta z tego jest taka, że implementacja zabezpieczeń nie jest warta niczego, dopóki coś, co ktoś inny napisał, nie zaakceptuje lub nie odrzuci jej.

Odwołania do specyfikacji: - HL7 UDAP Security STU 1: http://hl7.org/fhir/us/udap-security/STU1/ - TEFCA SOP Facilitated FHIR Implementation v2.0, obowiązujący od 8 marca 2026

Source: github.com/biodream-llc/perfuse/internal/udap

Pakiet umlink przenosi X12 278 do systemu zarządzania wykorzystaniem płatnika i z powrotem, oraz sposób, w jaki te systemy są dostępne w praktyce: X12 w treści HTTPS POST; CAQH CORE'a koperta SOAP (Connectivity Rule vC2.2.0, ta, której większość płatników i CMS używa w esMD, oraz vC4.0.0); CAQH CORE'a koperta HTTP MIME multipart (vC2.2.0); oraz pliki wsadowe przez SFTP.

Napisane z opublikowanych przez CAQH zasad łączności (vC2.2.0 i vC4.0.0), ich schematu XML i WSDL, oraz przewodnika towarzyszącego esMD X12N 278 CMS. Nie jest to certyfikat CORE: certyfikacja jest przeprowadzana przez autoryzowanych dostawców testowych CAQH.

Połączenia w czasie rzeczywistym zwracają odpowiedź, którą system UM podał, co może być odpowiedzią 278 lub, gdy nie mógł odczytać żądania, 999 lub TA1: wywołujący odczytuje, który. Połączenie wsadowe zwraca ErrAnswerLater, gdy plik zostanie dostarczony, a Poll zbiera to, co wraca.

Source: github.com/biodream-llc/perfuse/internal/umlink

26.111 v2fhir

Pakiet v2fhir mapuje wiadomości HL7 v2 na zasoby FHIR.

Mapowanie jest tym, gdzie projekty interoperacyjności naprawdę zawodzą, więc reguły, których ten pakiet przestrzega, są stwierdzone, a nie implicite:

Source: github.com/biodream-llc/perfuse/internal/v2fhir

26.112 vcs

Pakiet vcs odczytuje historię plików kanałów z git.

Historia kanału jest rozszerzeniem płatnym gdzie indziej, i jest rozszerzeniem płatnym, ponieważ te silniki trzymają kanały w bazie danych, więc śledzenie zmian oznacza budowanie systemu śledzenia zmian. Perfuse trzyma kanały w plikach, więc historia już istnieje i istnieje od pierwszego commitu. Ten pakiet musi tylko ją odczytać.

Wysyła polecenia do git zamiast osadzać bibliotekę git. Biblioteka dodałaby dużą zależność do binarnego pliku, którego punkt sprzedaży jest posiadanie czterech, i nic by nie kupiła: wdrożenie, które trzyma swoje kanały pod kontrolą wersji, ma git zainstalowany, a to, które nie, otrzymuje wyraźną „nie jest to repozytorium git” zamiast subtelnie różnej implementacji tego samego.

Source: github.com/biodream-llc/perfuse/internal/vcs

26.113 vfs

Pakiet vfs jest małym zestawem operacji na plikach, których potrzebuje łącznik pollingu.

Dlaczego interfejs zamiast czterech łączników

Perfuse gromadzi pliki z lokalnego dysku, serwera SFTP, serwera FTP, udziału systemu Windows i serwera WebDAV. Przeniesienie różni się w każdym przypadku. Wszystko, co tak naprawdę decyduje o tym, czy wiadomości przetrwają, nie:

Napisane raz na transport, te reguły byłyby subtelnie różne pięć razy, a różnice pojawiłyby się tylko jako wiadomości, które zniknęły na jednym miejscu. Dlatego są napisane raz, tutaj, nad najmniejszym interfejsem, który je obsługuje.

Co jest celowo nieobecne

Brak zapisu, poza tym, co wymaga usunięcia. Wysyłanie plików to inny problem z innymi trybami awarii - częściowo zapisany plik na drugim końcu, który istniejący nadawca obsługuje, zapisując w tymczasowej nazwie i przemianowując. Złożenie obu kierunków w jeden interfejs sprawiłoby, że każdy z nich byłby trudniejszy do zrozumienia.

Brak rekursji. Sondujący, który schodzi do podkatalogów, zbiera katalog archiwum, do którego właśnie przeniósł plik.

Source: github.com/biodream-llc/perfuse/internal/vfs

26.114 sieć vpn

Pakiet vpn raportuje stan tuneli sieci VPN między stronami, po których przepływa ruch partnera - AWS Site-to-Site VPN, połączenia Azure VPN Gateway i strongSwan - i przechowuje arkusz połączeń każdego partnera: ustawienia tunelu obu stron i czy są zgodne.

Tunel, który jest wyłączony, wygląda, z punktu widzenia silnika interfejsu, dokładnie jak partner, którego silnik jest zatrzymany: połączenia wygasają. Mówienie „tunel jest wyłączony” zamiast tego jest różnicą między wywołaniem zespołu sieciowego a wywołaniem partnera.

Tylko do odczytu. Nic tutaj nie zmienia tunelu, a żaden współdzielony klucz nigdy nie jest odczytywany, przechowywany ani wyświetlany.

Source: github.com/biodream-llc/perfuse/internal/vpn

26.115 sieć web

Pakiet web służy do obsługi frontendu zbudowanego wewnątrz binarnego pliku.

Zasoby są osadzane, a nie dostarczane obok, więc wdrożenie pozostaje jednym plikiem. To jest ten sam powód, dla którego silnik unika cgo: operator powinien móc skopiować binarny plik na serwer i uruchomić go, bez JVM, instalatora i katalogu zasobów, które mogą wyjść z synchronizacji z plikiem wykonywalnym.

Zbudowany wynik jest zatwierdzony, aby go build działał na sprawdzeniu bez zainstalowanego Node. Odbuduj go za pomocą make web.

Source: github.com/biodream-llc/perfuse/internal/web

26.116 webauthn

Pakiet webauthn weryfikuje passkey.

Passkey to para kluczy, które przechowuje urządzenie uwierzytelniające - Touch ID, Windows Hello, YubiKey, telefon - gdzie prywatna połowa nigdy nie opuszcza urządzenia. Logowanie oznacza, że serwer wysyła losowe wyzwanie, urządzenie uwierzytelniające podpisuje je po sprawdzeniu, czy użytkownik jest obecny, a serwer weryfikuje podpis w stosunku do przechowanego klucza publicznego podczas rejestracji.

Właściwość, która ma znaczenie, nie polega na tym, że jest wygodna. Polega na tym, że nie ma nic do phishingu. Hasło można wpisać na przekonującej kopii strony logowania; podpis passkey jest związany z pochodzeniem, dla którego został utworzony, więc kopia otrzymuje podpis, którego serwer nie może użyć. Dla silnika integracji, który przechowuje interfejsy szpitala, jest to różnica, której wartością jest posiadanie.

Co ta implementacja odmawia robić

Specyfikacja jest permissive w miejscach, w których bycie permissive jest tym, jak implementacje są złamane. Ta nie jest:

Source: github.com/biodream-llc/perfuse/internal/webauthn

26.117 usługa windows

Pakiet usługi windows uruchamia Perfuse jako usługę systemu Windows.

Ten plik jest połową, która jest wszędzie indziej. Istnieje, aby cmd/perfuse mogło wywołać ten pakiet bez owijania każdego miejsca wywołania w tagu kompilacji: polecenie podstawowe jest zawsze skompilowane, a na Linuksie lub macOS wyjaśnia, że usługi są pomysłem systemu Windows, zamiast nie istnieć.

Odmowa z klarownym zdaniem jest lepsza niż ukrywanie polecenia podstawowego. Ktoś, kto wykonuje instrukcje systemu Windows na niewłaściwej maszynie, jest informowany o tym, co się naprawdę dzieje, i odpowiednik dla ich platformy.

Source: github.com/biodream-llc/perfuse/internal/winservice

26.118 x12

Odczyt i zapis wartości w ścieżce.

Dlaczego jest to oddzielne od ścieżki

plik path.go decyduje, co oznacza wyrażenie ścieżki. Plik ten rozwiązuje jeden problem w odniesieniu do rzeczywistego wymiany. Został oddzielony, ponieważ reguły parsowania są warte przeczytania bez obsługi bajtów, a parser jest używany przez walidator konfiguracji, który nie ma wiadomości do rozwiązania.

Dlaczego zapis ponownie parsuje zamiast edytować bajty w miejscu

Elementy Segment są podsłojami Segment.raw, a Message.segs indeksuje Message.raw. Edycja wartości w miejscu zmienia długość wszystkiego, co po nim, więc każdy z tych słojów wymagałby dostosowania, a każdy, który został pominięty, byłby czytany poprawnie, aż do momentu, gdy nie był.

Zatem zapis odbudowuje segment, odbudowuje wymianę i parsuje ją ponownie. To kosztuje jeden parsing na zmienioną wiadomość i gwarantuje, że Message zwrócone stąd jest dokładnie tym, co produkuje parsing jego własnych bajtów. Nie ma stanu, w którym indeksy i bajty się nie zgadzają, ponieważ taki stan jest nieprzedstawialny.

Source: github.com/biodream-llc/perfuse/internal/x12

26.119 x12xml

Pakiet x12xml konwertuje X12 (i inne rozdzielone EDI) na XML, który Mirth Connect i Open Integration Engine zapisują dla niego, i z powrotem.

Dlaczego ten XML, a nie jeden z naszych własnych

Punkt XML postaci X12 to systemy, które już go używają. Strona przenosząca się z Mirth ma odbiorców zbudowanych przeciwko temu, co emituje typ danych EDI/X12 Mirth, skrypty, które przechodzą msg['CLM']['CLM.05']['CLM.05.1'], i silniki przesyłowe, które wysyłają X12 jako ten XML. Bardziej uporządkowana forma nasza własna nie służyłaby im. Zatem ten zapisuje dokładnie to, co Open Integration Engine 4.6 zapisuje, i czyta dokładnie to, co on czyta, a testy porównują dwa bajty po bajcie z własnym serializatorem OIE.

Wcześniejsza wersja tego pakietu wymyśliła swoją własną formę (korzeń X12Interchange, elementy o nazwie CLM05) i powiedziała, że pasuje do Mirth. Nie pasowało; nigdy nie było porównane z Mirth, i nic w Perfuse go nie używało.

The format

Korzeń jest X12Transaction, gdy wiadomość zaczyna się od segmentu ISA, w przeciwnym razie jest to EDIMessage, przenoszący trzy separatory jako atrybuty (segmentDelimiter, elementDelimiter, subelementDelimiter). Każdy segment jest elementem nazwanym przez jego identyfikator. Każdy element danych to SEG.NN, ponumerowany od 01 (ISA.01, CLM.05) i zawiera swoje składniki jako SEG.NN.1, SEG.NN.2 itd.: zawsze co najmniej SEG.NN.1 dla elementu z wartością, żaden dla pustego.

Separatory są odczytywane z ISA, gdy jest on obecny: separator elementów z pozycji 3, separator składników z pozycji 104, a terminator segmentu z pozycji 105, z następującym znakiem nowej linii wliczonym w jego skład. W przeciwnym razie są to ~ * i:. Separator powtarzania (ISA11) nie jest interpretowany, co jest również zachowaniem OIE: powtarzany element zachowuje swoje ^ w jednej wartości.

Jest to ponowna implementacja zachowania, napisana na podstawie obserwacji danych wyjściowych OIE oraz jego udokumentowanego formatu; nie zawiera kodu Mirth.

Source: github.com/biodream-llc/perfuse/internal/x12xml

26.120 xds

Pakiet xds jest IHE cross-enterprise document sharing: rejestrem dokumentów XDS.b i repozytorium (ITI-41 Provide and Register, ITI-18 Registry Stored Query, ITI-43 Retrieve Document Set), bramką XCA Responding Gateway nad tym samym magazynem (ITI-38, ITI-39) oraz stroną klienta każdego z nich, więc kanał może opublikować dokument w repozytorium innej organizacji, a konsola może zapytać rejestru lub społeczności.

Metadane są ebXML Registry 3.0 (ebRIM), tak jak XDS.b definiuje je w IHE ITI TF-3 rozdziale 4. Są modelowane tutaj jako struktury Go, których tagi XML przenoszą przestrzenie nazw, więc wiadomość jest czytana w ten sam sposób, niezależnie od prefiksów, które nadawał nadawca, i zapisywana z poprawnymi przestrzeniami nazw.

Source: github.com/biodream-llc/perfuse/internal/xds

26.121 xmldsig

Pakiet xmldsig implementuje podpisy cyfrowe XML i profil XAdES.

Dlaczego jest to napisane zamiast pożyczone

Podpisany dokument kliniczny jest artefaktem prawnym. Stwierdza, że osoba o nazwie, o określonym czasie, wzięła odpowiedzialność za określony zestaw bajtów. Błąd w tym kierunku jest poważny: podpis, który nie może być zweryfikowany, sprawia, że ważny dokument wygląda na sfałszowany, a weryfikator, który jest zbyt hojny, akceptuje dokument, który ktoś zmienił.

Kanonikalizacja jest cały problem

XML ma wiele sekwencji bajtów, które oznaczają to samo. Kolejność atrybutów nie jest istotna, prefiksy przestrzeni nazw mogą być przemianowane, puste elementy mogą być zapisane na dwa sposoby, a białe znaki wewnątrz znacznika są dowolne. Podpis jest nad bajtami, więc przed tym, jak cokolwiek zahaszować, obie strony muszą się zgodzić na dokładnie jedną sekwencję bajtów dla danego dokumentu. To porozumienie jest kanonikalizacją, i to jest tam, gdzie implementacje idą nie tak, ponieważ każdy błąd produkuje podpis, który weryfikuje się przeciwko własnemu wyjściu i nie powiedzie się przeciwko wyjściu każdego innego.

Zatem ten plik jest kanonikalizacją, samodzielnie, ze swoimi własnymi testami. Nic o podpisach nie pojawia się tutaj.

Wyłączne zamiast włączne, domyślnie

Kanonikalizacja włączna ściąga deklaracje przestrzeni nazw, które są w zakresie, w tym te, których element podpisany nigdy nie używa. To powoduje, że podpis jest złamany, gdy dokument jest później osadzony wewnątrz czegoś, co deklaruje niezwiązaną przestrzeń nazw na przodku, co jest dokładnie tym, co się dzieje, gdy CDA jest umieszczona wewnątrz koperty SOAP lub osłony metadanych IHE. Kanonikalizacja wyłączna obejmuje tylko deklaracje, których element faktycznie używa, i jest tym, co profile wymiany dokumentów określają z tego samego powodu.

Source: github.com/biodream-llc/perfuse/internal/xmldsig

26.122 xtree

Pakiet xtree jest drzewem XML, które może być modyfikowane.

Trzy bardzo różne funkcje muszą modyfikować XML: transformacje HL7, które Mirth modeluje jako XML, ponieważ takie są skrypty, na których są one oparte; dokumenty kliniczne, które są rodzime dla XML; oraz deklaracyjne kroki transformacji. Wszystkie te funkcje korzystają z tego samego drzewa, zamiast tworzyć własne, ponieważ alternatywą byłoby posiadanie trzech modeli, które nie zgadzają się co do znaczenia pustego elementu.

Celem projektowym jest wiernopodobieństwo do semantyki E4X, ponieważ skrypty Mirth są oparte na E4X, a cały cel uruchamiania ich bez zmian polega na tym, że zachowują się tak samo. To powoduje dwie decyzje, które w przeciwnym razie wyglądałyby dziwnie: węzeł zachowuje wskaźnik do swojego rodzica, ponieważ E4X udostępnia funkcję parent(), a dzieci są uporządkowane z dozwolonymi duplikatami, ponieważ powtórzenie pola HL7 jest dosłownie powtórzonym elementem, a skrypty indeksują je według pozycji.

Source: github.com/biodream-llc/perfuse/internal/xtree

26.123 Pakiet pas odczytuje żądania Da Vinci Prior Authorization Support (PAS) w postaci paczek.

Pakiet pas jest czytany przez serwer PAS Perfuse, opublikowany w taki sposób, aby każdy, kto decyduje o uprzedniej autoryzacji - czy to są reguły płatnika, system zarządzania wykorzystaniem, czy usługa decyzyjna, taka jak Vaglio - mógł odczytać żądanie z tym samym kodem i tym samym uzyskać odpowiedzi na to, co zawiera żądanie. Dwa czytniki jednego formatu wiadomości to dwa zdania na temat niej.

Nie ma on zależności poza standardową biblioteką. Żądanie jest przechowywane jako odkodowany JSON (mapa[string]dowolna) zamiast jako typowane zasoby, ponieważ paczka PAS zawiera dowolne zasoby wspierające, które dostawca wybrał do wysłania, a czytnik, który odrzucił to, czego nie modelował, ukryłby dowody przed decyzją.

req, problems := pas.Read(bundle, false) jeśli długość(problems) > 0 { // odmów: żądanie nie może być poprawnie odpowiedzi } dla _, svc := range req.Services() { // svc.Codes, svc.Item, i req.Resolve dla wszystkich elementów, na które się odnosi }

Wydaje się, że jest to fragment kodu, który nie wymaga tłumaczenia.

Source: github.com/biodream-llc/perfuse/pas

27 Indeks kluczy konfiguracyjnych

Każdy klucz w porządku alfabetycznym, wraz z blokami, w których może się pojawić. Klucz, który pojawia się w kilku blokach, oznacza to samo w każdym z nich; tam, gdzie nie, bloki są dokumentowane oddzielnie, a różnica jest tam stwierdzona.

27.1 Wszystkie klucze

KluczPojawia się w
access_key_idDostęp do AWS, Autoryzacja FHIR, Miejsce docelowe S3
accountDostęp do magazynu obiektów Azure
ackŹródło HTTP, Źródło SOAP, Źródło
ack_sender_idOpcje X12
ack_sender_qualifierOpcje X12
acknowledgeOpcje EDIFACT, Opcje HL7v3, Opcje X12
acksMiejsce docelowe Kafka
actionMiejsce docelowe SOAP
addrPołączenie AMQP, Miejsce docelowe brokera, Źródło brokera, Połączenie MQTT
addressPołączenie AMQP, Miejsce docelowe DICOM, Źródło zapytania DICOM, Miejsce docelowe, Adres bezpośredni, Miejsce docelowe TCP
ae_titleŹródło DICOM
after_queryŹródło bazy danych
after_readŹródło obiektów Azure, Bezpośredni IMAP, Źródło e-mail, Sonda plików, Źródło GCS, Źródło S3, Źródło SFTP
allowSkrypty
allow_clear_passwordMiejsce docelowe FTP
allow_unencryptedPartner AS2, Odbiór PGP
allow_unsignedPartner AS2
allowed_calling_aeŹródło DICOM
allowed_sendersŹródło e-mail
amqpMiejsce docelowe, Źródło
anchors_fileAdres bezpośredni
api_versionPołączenie IBMMQ
appendMiejsce docelowe, Miejsce docelowe SFTP
applicationPotwierdzenie
armorWysyłanie PGP
arrives_asOpcje X12
as2Miejsce docelowe, Źródło
attachMiejsce docelowe SMTP
attach_nameMiejsce docelowe bezpośrednie, Miejsce docelowe SMTP
attachment_namesŹródło e-mail
attachmentsKanał
attemptsPonowienie
authMiejsce docelowe FHIR, Miejsce docelowe PAS
authoritiesMiejsce docelowe MPI
azure_blobMiejsce docelowe, Źródło
backoffKonfiguracja kolejki, Ponowienie
base64Źródło SOAP
batch_sizeŹródło bazy danych, Sonda plików
baudŹródło szeregowego
bccMiejsce docelowe SMTP
bearer_tokenMiejsce docelowe CDA, Miejsce docelowe FHIR, Miejsce docelowe HTTP, Miejsce docelowe PAS
big_endianRamowanie TCP
blobMiejsce docelowe obiektów Azure
bodyMiejsce docelowe SMTP, Miejsce docelowe SOAP
brokerMiejsce docelowe, Źródło
brokersMiejsce docelowe Kafka, Źródło Kafka
bucketDostęp do GCS, Miejsce docelowe S3, Źródło S3
bundle_scriptMiejsce docelowe FHIR
called_aeMiejsce docelowe DICOM, Źródło zapytania DICOM
calling_aeMiejsce docelowe DICOM, Źródło zapytania DICOM
ccMiejsce docelowe SMTP
cdaMiejsce docelowe
cert_fileMiejsce docelowe AS2, Partner AS2, Źródło AS2, Adres bezpośredni
channelMiejsce docelowe, Cień
check_everyOdniesienie do umowy
cityObiekt ECR
claim_us_coreMiejsce docelowe FHIR
classMiejsce docelowe XDS
client_ca_fileBezpośrednie XDR
client_idAutoryzacja e-mail, Autoryzacja FHIR, Połączenie MQTT
client_secretAutoryzacja e-mail, Autoryzacja FHIR
codeKod XDS
columnŹródło bazy danych
columnsWartości rozdzielane
commentWartości rozdzielane
commit_after_deliveryŹródło Kafka
compareCień
compressMiejsce docelowe AS2
compressionMiejsce docelowe Kafka
configMiejsce docelowe ELR
containerDostęp do obiektów Azure
content_typeMiejsce docelowe AMQP, Miejsce docelowe AS2, Miejsce docelowe obiektów Azure, Miejsce docelowe brokera, Miejsce docelowe GCS, Miejsce docelowe HTTP, Miejsce docelowe S3, Miejsce docelowe XDS
contractKanał
credentials_fileDostęp do GCP
dataTypeKanał
data_bitsŹródło szeregowego
databaseMiejsce docelowe, Źródło
decrypt_withOdbiór PGP
default_identifier_systemMiejsce docelowe FHIR
delimitedKanał
delimiterWartości rozdzielane, Ramowanie TCP
deploySkrypty
descriptionKanał
destinationMiejsce docelowe brokera, Źródło brokera
destinationsKanał
dicomKanał, Miejsce docelowe, Źródło
dicom_queryŹródło
dicomwebMiejsce docelowe, Źródło
dirMiejsce docelowe CDA, Miejsce docelowe, Miejsce docelowe dokumentu, Miejsce docelowe FTP, Sonda plików, Miejsce docelowe SFTP, Źródło SFTP
directMiejsce docelowe, Źródło
direct_fromMiejsce docelowe XDS
direct_toMiejsce docelowe XDS
displayKod XDS
dnsMiejsce docelowe bezpośrednie
documentMiejsce docelowe
domainŹródło SMB
driverMiejsce docelowe bazy danych, Źródło bazy danych
dsnMiejsce docelowe bazy danych, Źródło bazy danych
duplicate_windowŹródło AS2
ecrMiejsce docelowe FHIR
edifactKanał
elementŹródło SOAP
elrMiejsce docelowe
emailŹródło
emit_on_first_pollŹródło zapytania DICOM
enabledKanał, Miejsce docelowe, Konfiguracja kolejki
encrypt_toWysyłanie PGP
endpointDostęp do AWS, Dostęp do obiektów Azure, Dostęp do GCP, Miejsce docelowe S3
envelopeOpcje EDIFACT, Opcje X12
error_dirSonda plików, Źródło SFTP
error_folderBezpośredni IMAP, Źródło e-mail
error_prefixŹródło obiektów Azure, Źródło GCS, Źródło S3
expect_replyMiejsce docelowe TCP
extractZałączniki
facilityPotwierdzenie, Miejsce docelowe ECR
facility_idMiejsce docelowe SOAP
facility_typeMiejsce docelowe XDS
fail_on_bodyMiejsce docelowe HTTP
fault_is_successMiejsce docelowe SOAP
fault_on_nakŹródło SOAP
fhirMiejsce docelowe
fileOdniesienie do umowy, Źródło
file_nameMiejsce docelowe AS2, Miejsce docelowe, Miejsce docelowe dokumentu, Miejsce docelowe FTP, Wysyłanie PGP, Miejsce docelowe SFTP
file_rootsSkrypty
filterKanał, Wartości rozdzielane, Miejsce docelowe, Opcje HL7v3, Skrypty
flow_controlŹródło szeregowego
follow_redirectsMiejsce docelowe HTTP
follow_symlinksŹródło plików
font_sizeMiejsce docelowe dokumentu
formatMiejsce docelowe dokumentu, Miejsce docelowe S3
framedŹródło obiektów Azure, Miejsce docelowe FTP, Sonda plików, Źródło GCS, Miejsce docelowe S3, Źródło S3, Miejsce docelowe SFTP, Źródło SFTP
framingRamowanie TCP
fromMiejsce docelowe AS2, Miejsce docelowe SMTP
from_beginningŹródło Kafka
ftpMiejsce docelowe, Źródło
gcsMiejsce docelowe, Źródło
groupKanał, Źródło Kafka
group_byMiejsce docelowe SNS, Miejsce docelowe SQS
has_headerWartości rozdzielane
headerMiejsce docelowe SOAP
headersMiejsce docelowe brokera, Miejsce docelowe CDA, Miejsce docelowe DICO Mweb, Miejsce docelowe FHIR, Miejsce docelowe HTTP, Miejsce docelowe Kafka, Miejsce docelowe SOAP, Miejsce docelowe XDS
heartbeatŹródło brokera
hl7v3Kanał
hostMiejsce docelowe brokera, Źródło brokera, Bezpośredni IMAP, Źródło e-mail, Miejsce docelowe FTP, Źródło FTP, Miejsce docelowe SFTP, Źródło SFTP, Źródło SMB, Miejsce docelowe SMTP
hostnamePołączenie AMQP
httpMiejsce docelowe, Źródło
ibm_mqMiejsce docelowe, Źródło
idPartner AS2, Źródło AS2
id_typeMiejsce docelowe MPI
identifier_systemsMiejsce docelowe CDA, Miejsce docelowe FHIR
idle_timeoutŹródło DICOM, Źródło, Źródło TCP
ignoreCień
imapBezpośrednie źródło
includeSkrypty
include_trigger_eventPotwierdzenie
insecure_skip_host_key_checkMiejsce docelowe SFTP, Źródło SFTP
insecure_skip_verifyMiejsce docelowe FTP, Źródło FTP, Miejsce docelowe SMTP, Źródło Web DAV
intervalŹródło zapytania DICOM
javascriptMiejsce docelowe, Źródło
kafkaMiejsce docelowe, Źródło
keep_aliveMiejsce docelowe TCP
keep_blank_linesWartości rozdzielane
keep_delimiterRamowanie TCP
keyDostęp do obiektów Azure, Miejsce docelowe Kafka, Miejsce docelowe S3
key_columnŹródło bazy danych
key_fileMiejsce docelowe AS2, Źródło AS2, Adres bezpośredni, Miejsce docelowe SFTP, Źródło SFTP
key_passphraseMiejsce docelowe SFTP, Źródło SFTP
known_hosts_fileMiejsce docelowe SFTP, Źródło SFTP
landscapeMiejsce docelowe dokumentu
languageSkrypty
ldapMiejsce docelowe bezpośrednie
length_bytesRamowanie TCP
length_includes_headerRamowanie TCP
levelŹródło zapytania DICOM
limitŹródło zapytania DICOM
lineObiekt ECR
listenŹródło AS2, Źródło DICO Mweb, Źródło DICOM, Źródło bezpośrednie, Bezpośrednie XDR, Źródło HTTP, Źródło SOAP, Źródło, Źródło TCP
loginMiejsce docelowe brokera, Źródło brokera
mailboxBezpośredni IMAP, Źródło e-mail
matchŹródło zapytania DICOM
max_attemptsŹródło bazy danych, Konfiguracja kolejki
max_backoffKonfiguracja kolejki, Ponowienie
max_bytesŹródło bezpośrednie
max_connectionsŹródło, Źródło TCP
max_depthKonfiguracja kolejki
max_differencesCień
max_file_sizeSonda plików, Źródło SFTP
max_message_sizeŹródło AS2, Źródło e-mail, Źródło HTTP, Źródło Kafka, Źródło SOAP, Źródło szeregowego, Źródło, Miejsce docelowe TCP, Źródło TCP
max_messagesŹródło Pub Sub, Źródło SQS
max_object_bytesŹródło DICO Mweb, Źródło DICOM
max_object_sizeŹródło obiektów Azure, Źródło GCS, Źródło S3
max_open_connsMiejsce docelowe bazy danych
mechanismSASL Kafka
methodMiejsce docelowe HTTP
move_toŹródło obiektów Azure, Bezpośredni IMAP, Źródło e-mail, Sonda plików, Źródło GCS, Źródło S3, Źródło SFTP
mpiMiejsce docelowe
mqttMiejsce docelowe, Źródło
nameKanał, Miejsce docelowe kanału, Miejsce docelowe, Obiekt ECR
ncpdpKanał
no_compressWysyłanie PGP
no_mergeMiejsce docelowe MPI
non_persistentMiejsce docelowe IBMMQ
npiObiekt ECR
oauthŹródło e-mail
objectMiejsce docelowe GCS
on_no_documentMiejsce docelowe CDA
order_byMiejsce docelowe Pub Sub
overOdniesienie do umowy
overlapŹródło zapytania DICOM
paramsMiejsce docelowe bazy danych
parityŹródło szeregowego
partner_cert_fileMiejsce docelowe AS2
partnersŹródło AS2
pasMiejsce docelowe
pass_plainOdbiór PGP
passcodeMiejsce docelowe brokera, Źródło brokera
passphraseOdbiór PGP, Wysyłanie PGP
passwordPołączenie AMQP, Miejsce docelowe AS2, Miejsce docelowe DICO Mweb, Źródło DICO Mweb, Miejsce docelowe bezpośrednie, Bezpośredni IMAP, Źródło e-mail, Miejsce docelowe FTP, Źródło FTP, Miejsce docelowe HTTP, Połączenie IBMMQ, SASL Kafka, Połączenie MQTT, Miejsce docelowe SFTP, Źródło SFTP, Źródło SMB, Miejsce docelowe SMTP, Miejsce docelowe SOAP, Źródło SOAP, Źródło Web DAV, Miejsce docelowe XDS
pathŹródło AS2, Źródło DICO Mweb, Źródło HTTP, Źródło SOAP
path_styleMiejsce docelowe S3, Źródło S3
patient_domainMiejsce docelowe XDS
patient_rootŹródło zapytania DICOM
patternSonda plików, Źródło SFTP
payerMiejsce docelowe PAS
persistentMiejsce docelowe brokera
pgpMiejsce docelowe, Źródło
phoneObiekt ECR
poll_intervalŹródło obiektów Azure, Źródło bazy danych, Bezpośredni IMAP, Źródło e-mail, Sonda plików, Źródło GCS, Źródło IBMMQ, Źródło Java Script, Źródło S3, Źródło SFTP
portBezpośredni IMAP, Źródło e-mail, Źródło szeregowego
postal_codeObiekt ECR
postprocessorSkrypty
practice_settingMiejsce docelowe XDS
prefetchŹródło AMQP
prefixŹródło obiektów Azure, Źródło GCS, Źródło S3
preprocessorSkrypty
profileMiejsce docelowe SOAP, Źródło SOAP
projectDostęp do GCP
protocolŹródło e-mail
providerDostawca OAuth
pubsubMiejsce docelowe, Źródło
purposeMiejsce docelowe TEFCA
qosPołączenie MQTT
queryŹródło bazy danych
query_timeoutŹródło bazy danych
queueMiejsce docelowe, Połączenie IBMMQ
queue_managerPołączenie IBMMQ
queue_urlMiejsce docelowe SQS, Źródło SQS
quiet_afterŹródło szeregowego
quoteWartości rozdzielane
rawSonda plików
rctcMiejsce docelowe ECR, Miejsce docelowe ELR
read_timeoutŹródło HTTP, Źródło SOAP
reassembleZałączniki
receiptMiejsce docelowe AS2
receipt_urlMiejsce docelowe AS2
recipient_certs_dirMiejsce docelowe bezpośrednie
reconnectŹródło AMQP, Źródło brokera, Źródło MQTT, Źródło Pub Sub
record_lengthRamowanie TCP
refresh_tokenAutoryzacja e-mail
regionDostęp do AWS, Autoryzacja FHIR, Miejsce docelowe S3
reject_on_warningMiejsce docelowe FHIR
relaxedWartości rozdzielane
reopen_afterŹródło szeregowego
replyŹródło szeregowego, Źródło TCP
reply_textŹródło szeregowego, Źródło TCP
request_mdnMiejsce docelowe bezpośrednie
require_agreementMiejsce docelowe CDA
require_signatureOdbiór PGP
response_elementŹródło SOAP
response_namespaceŹródło SOAP
response_transformerMiejsce docelowe
results_toMiejsce docelowe PAS, Miejsce docelowe TEFCA
retainMiejsce docelowe MQTT
retain_hoursMiejsce docelowe, Konfiguracja kolejki
retryMiejsce docelowe
returnŹródło zapytania DICOM
rootŹródło FTP, Źródło plików, Źródło SMB
s3Miejsce docelowe, Źródło
sampleCień
sasDostęp do obiektów Azure
saslMiejsce docelowe Kafka, Źródło Kafka
schemeKod XDS
scopeAutoryzacja e-mail, Autoryzacja FHIR
scriptKanał, Miejsce docelowe Java Script, Źródło Java Script
scriptsKanał
secret_access_keyDostęp do AWS, Autoryzacja FHIR, Miejsce docelowe S3
securityBezpośredni IMAP, Źródło e-mail, Miejsce docelowe FTP, Źródło FTP
selectorŹródło brokera
sender_deviceOpcje HL7v3
sender_oidOpcje HL7v3
serialŹródło
server_side_encryptionMiejsce docelowe S3
session_timeoutŹródło Kafka
session_tokenDostęp do AWS, Autoryzacja FHIR, Miejsce docelowe S3
sftpMiejsce docelowe, Źródło
shadowKanał
shareŹródło SMB
sign_withWysyłanie PGP
smbŹródło
smtpMiejsce docelowe
smtp_hostMiejsce docelowe bezpośrednie, Źródło bezpośrednie
snsMiejsce docelowe
soapMiejsce docelowe, Źródło
sop_classesMiejsce docelowe DICOM, Źródło DICOM
sort_bySonda plików
sourceKanał, Miejsce docelowe ECR
source_idMiejsce docelowe XDS
splitWartości rozdzielane, Opcje EDIFACT, Opcje X12
sqsMiejsce docelowe, Źródło
ssn_systemMiejsce docelowe MPI
stable_forSonda plików, Źródło SFTP
start_blockRamowanie TCP
starttlsMiejsce docelowe SMTP
stateObiekt ECR
statementMiejsce docelowe bazy danych
stop_bitsŹródło szeregowego
storage_classMiejsce docelowe GCS, Miejsce docelowe S3
subjectMiejsce docelowe AS2, Miejsce docelowe bezpośrednie, Miejsce docelowe SMTP, Miejsce docelowe SNS
subscriptionŹródło Pub Sub
subscription_idŹródło brokera
success_on_undefinedMiejsce docelowe Java Script
success_statusMiejsce docelowe HTTP
suffixŹródło obiektów Azure, Źródło GCS, Źródło S3
tablesKanał
takeŹródło e-mail
tcpMiejsce docelowe, Źródło
tefcaMiejsce docelowe
temp_suffixMiejsce docelowe, Miejsce docelowe dokumentu, Miejsce docelowe FTP, Miejsce docelowe SFTP
templateŹródło bazy danych, Miejsce docelowe dokumentu
tenantAutoryzacja e-mail
tenant_idAutoryzacja FHIR
textMiejsce docelowe bezpośrednie
tierMiejsce docelowe obiektów Azure
timeoutPołączenie AMQP, Miejsce docelowe brokera, Źródło brokera, Miejsce docelowe DICO Mweb, Miejsce docelowe DICOM, Źródło zapytania DICOM, Miejsce docelowe bazy danych, Miejsce docelowe, Miejsce docelowe bezpośrednie, Miejsce docelowe dokumentu, Miejsce docelowe FTP, Źródło FTP, Połączenie IBMMQ, Miejsce docelowe Java Script, Źródło Java Script, Miejsce docelowe Kafka, Źródło Kafka, Połączenie MQTT, Miejsce docelowe S3, Miejsce docelowe SFTP, Źródło SFTP, Źródło SMB, Miejsce docelowe SMTP, Miejsce docelowe SOAP, Skrypty, Cień, Miejsce docelowe TCP, Źródło Web DAV, Miejsce docelowe XDS
timezoneMiejsce docelowe FHIR
titleMiejsce docelowe dokumentu
tlsPołączenie AMQP, Miejsce docelowe AS2, Źródło AS2, Miejsce docelowe brokera, Źródło brokera, Miejsce docelowe DICO Mweb, Źródło DICO Mweb, Miejsce docelowe DICOM, Źródło DICOM, Miejsce docelowe, Bezpośredni IMAP, Źródło e-mail, Miejsce docelowe HTTP, Źródło HTTP, Połączenie IBMMQ, Miejsce docelowe Kafka, Źródło Kafka, Połączenie MQTT, Miejsce docelowe SOAP, Źródło SOAP, Źródło, Miejsce docelowe TCP, Źródło TCP, Miejsce docelowe XDS
tls_certŹródło bezpośrednie, Bezpośrednie XDR
tls_keyŹródło bezpośrednie, Bezpośrednie XDR
toMiejsce docelowe AS2, Miejsce docelowe bezpośrednie, Miejsce docelowe SMTP
tokenMiejsce docelowe DICO Mweb, Źródło DICO Mweb, Źródło HTTP, Źródło SOAP, Miejsce docelowe XDS
token_urlAutoryzacja e-mail, Autoryzacja FHIR
topicMiejsce docelowe Kafka, Miejsce docelowe MQTT, Źródło MQTT, Miejsce docelowe Pub Sub
topic_arnMiejsce docelowe SNS
topicsŹródło Kafka
transfer_syntaxesMiejsce docelowe DICOM, Źródło DICOM
transformationsKanał, Opcje DICOM, Wartości rozdzielane, Opcje HL7v3, Opcje NCPDP, Opcje skryptów, Opcje X12
transformerSkrypty
trim_paddingRamowanie TCP
trim_spaceWartości rozdzielane
typeMiejsce docelowe, Autoryzacja FHIR, Źródło
undeploySkrypty
unencryptedMiejsce docelowe AS2
unsignedMiejsce docelowe AS2
unsigned_receiptMiejsce docelowe AS2
urlMiejsce docelowe AS2, Miejsce docelowe CDA, Miejsce docelowe DICO Mweb, Miejsce docelowe FHIR, Miejsce docelowe HTTP, Połączenie IBMMQ, Miejsce docelowe SOAP, Źródło Web DAV, Miejsce docelowe XDS
userMiejsce docelowe FTP, Źródło FTP, Miejsce docelowe SFTP, Źródło SFTP, Źródło SMB, Źródło Web DAV
usernamePołączenie AMQP, Miejsce docelowe AS2, Miejsce docelowe DICO Mweb, Źródło DICO Mweb, Miejsce docelowe bezpośrednie, Bezpośredni IMAP, Źródło e-mail, Miejsce docelowe HTTP, Połączenie IBMMQ, SASL Kafka, Połączenie MQTT, Miejsce docelowe SMTP, Miejsce docelowe SOAP, Źródło SOAP, Miejsce docelowe XDS
validate_before_sendMiejsce docelowe FHIR
verify_withOdbiór PGP
versionMiejsce docelowe CDA, Miejsce docelowe FHIR, Miejsce docelowe SOAP, Źródło SOAP
visibility_timeoutŹródło SQS
wait_secondsŹródło SQS
warnings_are_errorsMiejsce docelowe SOAP
webdavŹródło
whenPotwierdzenie
windowŹródło zapytania DICOM
writeMiejsce docelowe CDA
wsdlŹródło SOAP
x12Kanał
x12_asMiejsce docelowe
xdmMiejsce docelowe bezpośrednie
xdm_source_idMiejsce docelowe bezpośrednie
xdrŹródło bezpośrednie
xdsMiejsce docelowe