AnpherosAnpheros PlatformDevelopers

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Jak importować wyniki laboratoryjne do repozytorium FHIR

Samouczek: importuj raport laboratoryjny jako CSV i jako HL7 v2 ORU^R01 do FHIR R4 Observations z kodami LOINC i zakresami referencyjnymi, obsługuj niezmapowane markery i ponowne wysyłanie raportów, oraz śledź każdy wynik do jego laboratorium.

Ten samouczek przedstawia raport laboratoryjny w postaci pliku CSV oraz wiadomości HL7 v2 ORU^R01, importuje go do rekordu HL7 FHIR R4 pacjenta w jednym żądaniu dla każdego formatu i pokazuje, co otrzymasz w zamian: zasoby laboratoryjne Observation z kodami LOINC, zakresami referencyjnymi i pochodzeniem. Obejmuje również dwa problemy, z którymi boryka się każda integracja laboratoryjna: znaczniki, których nie można zmapować automatycznie, oraz raporty, które są wysyłane dwukrotnie. Wszystko działa na darmowym środowisku piaskownicy z syntetycznym pacjentem.

Dlaczego wyniki badań laboratoryjnych są trudne do przechowywania

Wynik badania laboratoryjnego wydaje się prosty: parametr, wartość, jednostka, zakres referencyjny, data. W praktyce każde laboratorium nazywa parametry na swój sposób („Hemoglobina glicozilata”, „HbA1c”, „Glycated haemoglobin”), używa przecinków lub kropek do zapisu dziesiętnego, zapisuje zakresy jako 4,0-5,6, <5 lub >3.5 i wysyła ten sam wynik ponownie, gdy coś się nie powiedzie. Przechowywane jako tekst swobodny, wyniki te nie mogą być porównywane w czasie, wykresowane, udostępniane innej aplikacji ani przekazywane modelowi AI z pewnością.

Rekord FHIR przechowuje każdy wynik jako Observation z kodem LOINC, jednostką UCUM, wartością, zakresem referencyjnym i datą, a także przechowuje informacje o tym, kto go wysłał w zasobie Provenance. Łącznik laboratoryjny wykonuje tę konwersję za Ciebie.

 lab report (CSV, HL7 v2, JSON)
        │  POST /v1/patients/{id}/labs/import
        ▼
 ┌──────────────────────────────────────────────┐
 │ parse rows → map marker to LOINC → parse     │
 │ value, unit, range → stable id per row       │
 └──────────────────────────────────────────────┘
        │
        ▼
 Observation (category laboratory) + Provenance (author_type import, source system, report id)
        │
        ├─► the patient's app and every app they consented to
        └─► webhooks: resource.created per Observation

Zanim zaczniesz

Potrzebujesz klucza sandbox (sk_test_…) z platform.anpheros.com/dashboard (Uzyskaj klucz sandbox). Przykłady używają curl; SDK mają te same wywołania (labs.importCsv, labs.importHl7, labs.importItems).

export BASE=https://platform.anpheros.com
export KEY=sk_test_…
# Elena Ionescu, a synthetic patient with type 2 diabetes
export PID=$(curl -s "$BASE/fhir/R4/Patient?identifier=https://anpheros.com/fhir/sid/sandbox-persona|p02" \
  -H "Authorization: Bearer $KEY" | jq -r '.entry[0].resource.id')

Krok 1: importowanie raportu CSV

Tak może wyglądać eksport raportu przez rumuńskie laboratorium: średniki, przecinki dziesiętne, rumuńskie nazwy kolumn i daty jako DD.MM.YYYY. Konektor rozpoznaje nazwy kolumn rumuńskie i angielskie.

cat > report.csv <<'EOF'
Analiza;Rezultat;UM;Interval de referinta;Data
Hemoglobina glicozilata (HbA1c);6,9;%;4,0-5,6;01.10.2026
Glicemie;131;mg/dL;70-100;01.10.2026
TSH;2,1;mUI/L;0,4-4,0;01.10.2026
Marker foarte rar;12;U/L;0-20;01.10.2026
EOF

curl -X POST "$BASE/v1/patients/$PID/labs/import" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: text/csv" -H "X-Anpheros-Source-System: labx" \
     -H "Idempotency-Key: report-2026-10-01-elena" --data-binary @report.csv

Odpowiedź (201):

{"created": 4, "skipped": 0, "unmapped": ["Marker foarte rar"], "warnings": [],
 "observations": [
  {"id": "ff0bbb44-…", "marker": "Hemoglobina glicozilata (HbA1c)", "code": "4548-4", "system": "http://loinc.org", "value": 6.9, "unit": "%", "date": "2026-10-01"},
  {"id": "ebe5522f-…", "marker": "Glicemie", "code": "2345-7", "system": "http://loinc.org", "value": 131.0, "unit": "mg/dL", "date": "2026-10-01"},
  {"id": "bace44a8-…", "marker": "TSH", "code": "3016-3", "system": "http://loinc.org", "value": 2.1, "unit": "mUI/L", "date": "2026-10-01"},
  {"id": "26fd2270-…", "marker": "Marker foarte rar", "code": "marker_foarte_rar", "system": "urn:anpheros:lab-code", "value": 12.0, "unit": "U/L", "date": "2026-10-01"}]}

HbA1c, glukoza i TSH zostały zmapowane do LOINC na podstawie ich nazw. Przecinki dziesiętne zamieniły się w liczby, a zakresy stały się referenceRange. Jeden wiersz powrócił w unmapped. Jest on nadal przechowywany pod własnym kodem laboratorium (urn:anpheros:lab-code) z dokładnym tekstem z raportu, dzięki czemu nic nie zostało utracone.

Krok 2: obsługa niezmapowanych znaczników

Niektóre nazwy wymagają decyzji. "Glicemie" (glukoza we krwi) jest dobrym przykładem: LOINC ma jeden kod dla glukozy w surowicy lub osoczu (2345-7, próbka żylna pobrana w laboratorium) i inny dla glukozy w pełnej krwi (2339-0, na przykład z nakłucia palca). W raporcie laboratoryjnym sama nazwa "Glicemie" jest mapowana na surowicę lub osocze. Nazwa zawierająca "capilar", "capillary" lub "sânge integral" jest mapowana na pełną krew:

{"created": 1, "skipped": 0, "unmapped": [], "warnings": [],
 "observations": [{"id": "00480a6d-…", "marker": "Glicemie capilara", "code": "2339-0", "system": "http://loinc.org", "value": 140.0, "unit": "mg/dL", "date": "2026-10-02"}]}

Dla znaczników, których konektor nie rozpoznaje, wyszukaj kod:

curl "$BASE/v1/terminology/loinc?q=glucose" -H "Authorization: Bearer $KEY"
{"data": [
  {"system": "http://loinc.org", "code": "2339-0", "display": "Glucose [Mass/volume] in Blood", "display_ro": "Glicemie (sânge)", "category": "laboratory", "unit": "mg/dL"},
  {"system": "http://loinc.org", "code": "2345-7", "display": "Glucose [Mass/volume] in Serum or Plasma", "display_ro": "Glicemie (ser)", "category": "laboratory", "unit": "mg/dL"}],
 "total": 2}

Następnie wyślij kod w kolumnie LOINC. Kod w raporcie zawsze ma pierwszeństwo przed nazwą. Zachowaj to mapowanie dla każdego laboratorium po swojej stronie i dodaj kolumnę do każdego raportu z niego:

Analiza;Rezultat;UM;Interval de referinta;Data;LOINC
Glicemie;99;mg/dL;70-100;04.10.2026;2339-0

Znaczniki, których LOINC w ogóle nie obejmuje, takie jak wymyślony "Marker foarte rar", mogą pozostać pod kodem laboratorium. Są one wyświetlane pacjentowi i włączane do dokumentacji. Nie można ich porównywać z wynikami innych laboratoriów.

Krok 3: wysłanie tego samego raportu dwukrotnie

Laboratoria wysyłają raporty ponownie. Każdy wiersz otrzymuje stabilny identyfikator zbudowany z identyfikatora raportu, kodu, daty i wartości, więc drugie zaimportowanie tego samego raportu niczego nie tworzy:

{"created": 0, "skipped": 4, "unmapped": ["Marker foarte rar"], "warnings": [], "observations": []}

Wiersze, które uległy zmianie, na przykład poprawiona wartość, są importowane jako nowe wyniki. Nagłówek Idempotency-Key dodaje drugą gwarancję: ponowna próba sieciowa z tym samym kluczem zwraca pierwszą odpowiedź bez zmian.

Krok 4: import wiadomości HL7 v2 ORU^R01

Większość systemów informatycznych laboratoriów komunikuje się w standardzie HL7 v2. Wyślij wiadomość w oryginalnym formacie (tekst ER7, segmenty oddzielone CR lub LF):

MSH|^~\&|LABX|LAB1|ANPHEROS|EHR|202610010930||ORU^R01|MSG00077|P|2.5.1
PID|1||12345||Ionescu^Elena||19850903|F
OBR|1||R-77|24331-1^Lipid panel^LN|||202610010800
OBX|1|NM|2093-3^Cholesterol [Mass/volume] in Serum or Plasma^LN||212|mg/dL|<200|H|||F|||202610010800
OBX|2|NM|2085-9^HDL Cholesterol^LN||52|mg/dL|>40|N|||F|||202610010800
curl -X POST "$BASE/v1/patients/$PID/labs/import" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: x-application/hl7-v2+er7" --data-binary @oru.hl7
{"created": 2, "skipped": 0, "unmapped": [], "warnings": [],
 "observations": [
  {"id": "b562045b-…", "marker": "Cholesterol [Mass/volume] in Serum or Plasma", "code": "2093-3", "system": "http://loinc.org", "value": 212.0, "unit": "mg/dL", "date": "2026-10-01T08:00:00Z"},
  {"id": "9b3274e4-…", "marker": "HDL Cholesterol", "code": "2085-9", "system": "http://loinc.org", "value": 52.0, "unit": "mg/dL", "date": "2026-10-01T08:00:00Z"}]}

OBX-3 z systemem kodowania LN jest używany bezpośrednio jako LOINC. OBX-7 staje się zakresem referencyjnym, a OBX-8 (H, N) interpretacją. OBR-3 (R-77) jest zachowywane jako identyfikator raportu w metadanych pochodzenia. Pacjentem jest ten z adresu URL: segment PID nie jest używany do wyszukiwania pacjenta, więc błędny PID nie może przypisać wyników do innej osoby.

Posiadasz już przetworzone wyniki? Wyślij JSON: {"date": "2026-10-01", "origin": "report-77", "items": [{"marker": "Ferritin", "value": 38, "unit": "ng/mL", "ref_low": 15, "ref_high": 150}]}. Ferrytyna jest mapowana na LOINC 2276-4.

Krok 5: Odczyt wyników jako FHIR

curl "$BASE/fhir/R4/Observation?patient=$PID&code=http://loinc.org|4548-4&_sort=-date&_count=1" \
     -H "Authorization: Bearer $KEY"

Zaimportowane HbA1c, tak jak są przechowywane:

{
  "resourceType": "Observation",
  "id": "62b1b0c0-…",
  "meta": {"versionId": "1", "lastUpdated": "2026-10-12T20:05:57.011Z"},
  "identifier": [{"system": "urn:anpheros:lab-import", "value": "c52d3cd6449291d34f6bef1516d0ac05"}],
  "status": "final",
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "laboratory"}]}],
  "code": {"coding": [{"system": "http://loinc.org", "code": "4548-4", "display": "Hemoglobin A1c/Hemoglobin.total in Blood"}],
           "text": "Hemoglobina glicozilata (HbA1c)"},
  "subject": {"reference": "Patient/…"},
  "effectiveDateTime": "2026-10-01",
  "valueQuantity": {"value": 6.9, "unit": "%"},
  "referenceRange": [{"low": {"value": 4.0, "unit": "%"}, "high": {"value": 5.6, "unit": "%"}}]
}

Nazwa LOINC to standardowa angielska nazwa. code.text zachowuje własne sformułowanie laboratorium, dzięki czemu pacjent nadal widzi to, co było na papierowym raporcie. Więcej informacji o zasobach i wyszukiwaniu można znaleźć w przewodniku po platformie FHIR oraz systemach kodowania FHIR.

Krok 6: Sprawdź, kto wysłał

curl "$BASE/v1/patients/$PID/provenance/Observation/62b1b0c0-…" -H "Authorization: Bearer $KEY"
{"data": [{"version": 1, "activity": "CREATE", "recorded": "2026-10-12T20:05:57.011000Z",
           "author_type": "import", "author": "proj_…", "source_system": "labx", "origin_id": null,
           "fhir": "Provenance/f15c4fee-…"}], "total": 1}

author_type: import i source_system: labx pozostają z wartością. Kiedy aplikacja AI odczyta później ten wynik za pomocą API kontekstu, zostanie on oznaczony jako [import/labx], dzięki czemu model będzie mógł odróżnić wynik laboratoryjny od wartości wprowadzonej przez pacjenta.

Co dalej

Często zadawane pytania

Jakie formaty raportów laboratoryjnych można zaimportować do FHIR?

CSV z wierszem nagłówka (akceptowane przecinek, średnik lub tabulator, przecinek dziesiętny), wiadomości HL7 v2 ORU^R01 oraz JSON. Raporty PDF można przechowywać jako dokumenty; wyodrębnione z nich wartości wskazują z powrotem na dokument.

Co się dzieje ze znacznikami bez kodu LOINC?

Są one przechowywane pod własnym kodem laboratorium z dokładnym tekstem z raportu i wymienione w unmapped. Dodaj kolumnę LOINC dla tego laboratorium, a zostaną one zmapowane. Kod w raporcie zawsze ma pierwszeństwo przed nazwą.

Czy bezpieczne jest ponowne wysłanie raportu?

Tak. Każdy wiersz ma stabilny identyfikator zbudowany z raportu, kodu, daty i wartości, dzięki czemu zaimportowane już wiersze są pomijane; zmienione wiersze są importowane jako nowe wyniki.

Czy laboratorium może importować wyniki dla dowolnego pacjenta?

Nie. Laboratorium importuje do pacjentów, których projekt zostało utworzone lub których rekordy dana osoba udostępniła mu za pośrednictwem OAuth. Inni pacjenci dla niego nie istnieją (404).

Powiązane

Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card

Product updates by email

New features, guides and the end of the beta. One email a month at most.

Send me occasional Anpheros Platform updates by email (new features, API changes, guides). I'll confirm by email and can unsubscribe in one click from any email. Privacy