# FHIR 백엔드와 클리닉 시스템 통합 방법

> 튜토리얼: 클리닉 EMR을 환자의 FHIR R4 레코드에 연결 — 의사 디렉토리, 레코드 번호로 일치, 의사를 작성자로 하는 단일 트랜잭션으로서의 방문, 검사 보고서, 타사 제공업체의 데이터 및 웹훅.

Source: https://developers.anpheros.com/ko/guides/integrate-clinic-systems-fhir

**이 튜토리얼은 클리닉의 소프트웨어(EMR, 진료 관리 시스템 또는 예약 도구)를 Anpheros의 환자 HL7 FHIR R4 레코드에 연결합니다. 클리닉과 의사는 디렉토리에 등록되고, 환자는 클리닉의 레코드 번호로 일치되며, 방문은 의사를 작성자로 명시한 단일 트랜잭션으로 기록되고, 클리닉은 타사 제공업체가 추가하는 데이터에 대해 알게 됩니다.** 모든 요청은 무료 샌드박스에서 `curl` 처리되며, 응답은 플랫폼 자체의 것입니다.

통합은 클리닉 서버에서 실행되며, 클리닉이 등록하는 환자를 위한 프로젝트 API 키와, 이미 Anpheros 레코드를 보유한 사용자를 위한 승인된 OAuth 권한 부여가 필요합니다.

## 무엇이 무엇에 매핑되는가

| 클리닉 시스템에서 | FHIR R4에서 |
|---|---|
| 클리닉, 해당 부서 | `Organization` |
| 의사 또는 간호사 | `Practitioner` |
| 해당 클리닉에서 근무하는 해당 인력, 전문 분야 포함 | `PractitionerRole` |
| 환자 파일 및 해당 번호 | 클리닉 시스템의 `identifier`과 함께하는 `Patient` |
| 방문 | `Encounter` |
| 방문 중 측정된 활력 징후, 결과 | `Encounter`에 연결된 `Observation` |
| 진단 | `Condition` (ICD-10), `verificationStatus` 잠정 또는 확정 포함 |
| 처방, 현재 치료 | `MedicationStatement` (ATC) |
| 서신, 퇴원 요약, 스캔 | 파일과 함께하는 `DocumentReference` |
| 검사 결과 | [검사 커넥터](https://developers.anpheros.com/ko/guides/lab-connector)를 통해 `Observation`로 |

## 1단계: 병원 및 의사 등록

디렉토리 리소스에는 환자가 없습니다. 동일한 환경의 다른 프로젝트에서 이를 읽을 수 있으므로, 환자의 다른 제공자는 누가 무엇을 작성했는지 볼 수 있지만, 귀하의 프로젝트만 이를 변경할 수 있습니다.

```bash
export BASE=https://platform.anpheros.com/fhir/R4
export KEY=sk_test_…
H=(-H "Authorization: Bearer $KEY" -H "Content-Type: application/fhir+json")

curl -X POST $BASE/Organization "${H[@]}" -d '{"resourceType": "Organization", "active": true, "name": "Clinica Cardio Nord",
  "identifier": [{"system": "https://clinic.example/org", "value": "CCN"}]}'

curl -X POST $BASE/Practitioner "${H[@]}" -d '{"resourceType": "Practitioner", "active": true,
  "name": [{"family": "Popescu", "given": ["Ana"], "prefix": ["Dr."]}]}'

curl -X POST $BASE/PractitionerRole "${H[@]}" -d '{"resourceType": "PractitionerRole", "active": true,
  "practitioner": {"reference": "Practitioner/'$PRACTITIONER'"},
  "organization": {"reference": "Organization/'$ORG'"},
  "code": [{"text": "Cardiologist"}]}'
```

반환된 ID를 직원 기록 옆에 보관하십시오. 직원이 퇴사할 경우, `PractitionerRole`를 `"active": false`으로 설정하십시오. 해당 직원의 과거 작성 내용은 이름이 유지되며, 더 이상 귀하의 시스템을 통해 활동할 수 없습니다.

## 2단계: 환자 매칭

클리닉에서 등록하는 환자의 경우, 클리닉의 기록 번호를 식별자로 사용하여 `Patient`를 생성합니다.

```bash
curl -X POST $BASE/Patient "${H[@]}" -d '{"resourceType": "Patient",
  "identifier": [{"system": "https://clinic.example/mrn", "value": "MRN-20981"}],
  "name": [{"family": "Dinu", "given": ["Andrei"]}], "gender": "male", "birthDate": "1968-11-05"}'
```

이후에는 이름과 생년월일이 아닌 해당 번호로 환자를 찾습니다.

```bash
curl "$BASE/Patient?identifier=https://clinic.example/mrn|MRN-20981" -H "Authorization: Bearer $KEY"
```

**이미 Anpheros 기록이 있는 경우**, 환자 본인의 앱이나 다른 제공업체를 통해 클리닉에서 두 번째 기록을 생성하지 않습니다. 태블릿을 이용한 접수 데스크 또는 방문 전 전송된 링크를 통해 OAuth로 접근 권한을 요청하며, 이때 **기밀** 애플리케이션을 사용합니다(클리닉 서버에서 비밀 정보를 관리). 환자는 자신의 기록과 클리닉이 접근할 수 있는 기간을 선택합니다. 자세한 단계는 [SMART on FHIR을 이용한 환자 동의 구현 방법](https://developers.anpheros.com/ko/guides/smart-on-fhir-backend)에 나와 있으며, 토큰의 `patient` 필드는 파일과 함께 저장할 ID입니다.

## 3단계: 방문 기록을 단일 트랜잭션으로 작성

방문은 함께 속하는 여러 리소스를 생성합니다. 이 리소스들을 `transaction`으로 전송하여 한 번에 모두 저장하거나 전혀 저장하지 않도록 하고, 누가 작업 중인지 명시하십시오: `X-Anpheros-Acting-As`은 의사의 역할을 명명합니다. 이 역할은 Provenance에 작성자로 기록되고, 액세스 로그에 기록되며, 환자에게 이름으로 표시됩니다.

```bash
curl -X POST $BASE "${H[@]}" \
  -H "X-Anpheros-Acting-As: PractitionerRole/$ROLE" \
  -H "X-Anpheros-Author-Type: practitioner" \
  -H "X-Anpheros-Source-System: ccn-emr" -d '{
  "resourceType": "Bundle", "type": "transaction",
  "entry": [
    {"fullUrl": "urn:uuid:aa000000-0000-4000-8000-000000000001",
     "resource": {"resourceType": "Encounter", "status": "finished",
       "class": {"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "AMB", "display": "ambulatory"},
       "subject": {"reference": "Patient/'$PID'"},
       "serviceProvider": {"reference": "Organization/'$ORG'"},
       "participant": [{"individual": {"reference": "PractitionerRole/'$ROLE'"}}],
       "period": {"start": "2026-10-09T10:00:00Z", "end": "2026-10-09T10:30:00Z"}},
     "request": {"method": "POST", "url": "Encounter"}},
    {"resource": {"resourceType": "Observation", "status": "final",
       "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
       "code": {"coding": [{"system": "http://loinc.org", "code": "8867-4", "display": "Heart rate"}]},
       "subject": {"reference": "Patient/'$PID'"},
       "encounter": {"reference": "urn:uuid:aa000000-0000-4000-8000-000000000001"},
       "effectiveDateTime": "2026-10-09T10:10:00Z",
       "valueQuantity": {"value": 92, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"}},
     "request": {"method": "POST", "url": "Observation"}},
    {"resource": {"resourceType": "Condition",
       "subject": {"reference": "Patient/'$PID'"},
       "encounter": {"reference": "urn:uuid:aa000000-0000-4000-8000-000000000001"},
       "clinicalStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "active"}]},
       "verificationStatus": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", "code": "provisional"}]},
       "code": {"coding": [{"system": "http://hl7.org/fhir/sid/icd-10", "code": "I48.0", "display": "Paroxysmal atrial fibrillation"}]}},
     "request": {"method": "POST", "url": "Condition"}}
  ]}'
```

`transaction-response`은 Encounter, Observation 및 Condition에 대한 `201 Created`을 포함합니다. Observation과 Condition은 이제 실제 `Encounter/0ca25459-…`을 가리킵니다. 각 리소스의 Provenance는 의사의 역할, 클리닉 및 소스 시스템을 명명합니다:

```json
"agent": [{"who": {"reference": "PractitionerRole/e6d8c227-…",
                   "identifier": {"system": "https://anpheros.com/fhir/CodeSystem/author-type", "value": "practitioner"}},
           "onBehalfOf": {"reference": "Organization/c3a56a4b-…", "display": "Clinica Cardio Nord"}}],
"entity": [{"role": "source", "what": {"identifier": {"system": "ccn-emr"}}}]
```

진단은 확인될 때까지 `provisional`입니다. 나중에 `confirmed`로 업데이트하면 기록은 둘 다 유지합니다. 각 필드의 의미는 [Medical data provenance explained](https://developers.anpheros.com/ko/guides/medical-data-provenance)에서 설명합니다.

## 4단계: 검사실 결과 및 문서

클리닉 자체 검사실의 결과 또는 환자가 가져온 보고서는 보고서당 하나의 요청으로 랩 커넥터를 통해 처리됩니다.

```bash
curl -X POST "https://platform.anpheros.com/v1/patients/$PID/labs/import" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: x-application/hl7-v2+er7" -H "X-Anpheros-Source-System: ccn-lab" --data-binary @oru.hl7
```

편지 및 퇴원 요약은 문서입니다. `DocumentReference`을 통해 `/v1/patients/{id}/documents`을 생성하고 PDF를 업로드합니다. 원본 파일은 수정되지 않으며, 파일에서 추출된 값은 원본 파일을 가리킵니다. [FHIR 레코드에 검사실 결과 가져오기](https://developers.anpheros.com/ko/guides/import-lab-results-fhir) 및 [의료 데이터 API](https://developers.anpheros.com/ko/guides/medical-data-api)를 참조하십시오.

## 5단계: 다른 제공업체가 작성한 내용을 읽고 자신의 범위 내에서 유지하기

환자의 동의 하에, 해당 클리닉은 다른 클리닉, 실험실 및 환자가 추가한 내용을 포함하여 자신의 범위 내에 있는 전체 기록을 읽습니다. 자신이 작성한 내용만 변경할 수 있습니다. 다른 조직의 리소스를 업데이트하거나 삭제하면 `403`에 응답하며, 원본은 그대로 유지됩니다. 다른 제공업체가 작성한 내용을 수정하려면, 자신의 리소스(예: 자신의 평가가 포함된 새로운 `Condition`)를 작성하고 각 작성자의 정보와 함께 두 가지 모두 기록에 표시되도록 합니다.

방문 전에 `GET $BASE/Patient/$PID/$summary`은 모든 출처에서 가져온 기록의 국제 환자 요약(International Patient Summary)을 제공합니다: 문제, 약물, 알레르기 및 최근 활력 징후.

## 6단계: 새 데이터 알림 받기

클리닉 프로젝트에 대해 웹훅을 한 번 등록합니다.

```bash
curl -X POST https://platform.anpheros.com/v1/webhooks -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
     -d '{"url": "https://ccn.example/anpheros/hook", "events": ["resource.created", "resource.updated", "consent.revoked"]}'
```

다른 프로젝트가 클리닉에서 접근 가능한 레코드에 데이터를 작성하면, 이벤트는 `data.external: true`과 소스를 통해 이를 알립니다. 따라서 EMR은 폴링 없이 "다른 실험실의 새 결과"를 표시할 수 있습니다. `consent.revoked` 이벤트는 해당 개인이 클리닉의 접근을 철회했음을 의미합니다. 해당 레코드의 동기화를 중지하십시오. 서명, 재시도 및 페이로드는 [웹훅](https://developers.anpheros.com/ko/guides/webhooks)에서 다룹니다.

## 환자가 보는 내용

환자는 자신의 기록에서 방문 기록, 심박수, 잠정 진단 내용을 볼 수 있으며, 각 항목은 Clinica Cardio Nord의 Ana Popescu 박사가 추가한 것으로 표시됩니다. 환자의 연결 목록에서 해당 클리닉의 애플리케이션은 의료 전문가가 활동했을 때 이름과 함께 모든 접근 기록을 나열합니다. 이러한 투명성 덕분에 환자는 다음 클리닉에도 접근 권한을 부여할 의향이 있습니다.

## 운영 준비 체크리스트

- [ ] 조직, 실무자 및 실무자 역할 등록; 퇴사자는 비활성으로 설정
- [ ] 환자는 클리닉 식별자로 매칭, 이름으로는 절대 매칭하지 않음
- [ ] 기존 기록은 OAuth 동의를 통해 접근, 중복되지 않음
- [ ] 임상 직원의 모든 요청에는 `X-Anpheros-Acting-As` 포함
- [ ] 방문 기록은 트랜잭션으로 작성; 진단은 올바른 검증 상태로
- [ ] 모든 쓰기 작업 시 소스 시스템 설정; 랩 보고서는 커넥터를 통해
- [ ] 웹훅 엔드포인트에서 서명 확인; `consent.revoked` 처리
- [ ] 서명된 DPA(`sk_live_…` 키)가 있는 프로덕션 프로젝트; [가격](https://developers.anpheros.com/ko/guides/pricing) 참조

## 자주 묻는 질문

### Anpheros에 제 EMR을 위한 즉시 사용 가능한 커넥터가 있나요?
아니요. 특정 EMR 또는 실험실 시스템을 위한 즉시 사용 가능한 커넥터는 없습니다. 통합은 FHIR R4 및 REST API를 대상으로 구축되며, 일반적으로 EMR 옆에 작은 서비스로 구축됩니다. HL7 v2 실험실 메시지는 그대로 수락됩니다.

### 의사가 두 개의 클리닉에서 일할 수 있나요?
예. 한 명의 `Practitioner`은 각 조직에 `PractitionerRole`을 가질 수 있습니다. `X-Anpheros-Acting-As`에 명시된 역할은 각 쓰기가 어떤 클리닉에 기록되는지 결정합니다.

### 환자가 클리닉의 액세스를 취소하면 어떻게 되나요?
해당 기록에 대한 클리닉의 호출은 `401`을 반환하고, `consent.revoked` 웹훅이 전송됩니다. 클리닉이 작성한 내용은 출처와 함께 환자의 기록에 유지됩니다. 클리닉은 더 이상 해당 내용을 읽거나 변경할 수 없습니다.

## 관련 자료

- [Healthcare integrations](https://developers.anpheros.com/ko/guides/healthcare-integrations): 모든 통합 패턴 개요
- [Medical data provenance explained](https://developers.anpheros.com/ko/guides/medical-data-provenance)
- [How to implement patient consent with SMART on FHIR](https://developers.anpheros.com/ko/guides/smart-on-fhir-backend)
- [How to import laboratory results into a FHIR record](https://developers.anpheros.com/ko/guides/import-lab-results-fhir)
- [Healthcare data interoperability](https://developers.anpheros.com/ko/guides/interoperability)
