---
# System prepended metadata

title: Epic FHIR API Mapping Document

---

# Epic FHIR API Mapping Document

## Overview

This document maps Epic FHIR R4 API endpoints to the frontend and backend requirements for the Empower Healthcare platform. It provides concrete field mappings, API endpoints, and data flows needed for implementation.

**FHIR Version:** R4
**Authentication:** OAuth 2.0 / SMART on FHIR
**Base URL Pattern:** `https://{epic-host}/api/FHIR/R4/`

## High-Level Architecture

```mermaid
graph TB
    Frontend[React Frontend] --> Backend[FastAPI Backend]
    Backend --> FHIR[FHIR Gateway]
    Backend --> ML[ML Service]
    Backend --> Cache[Redis Cache]
    FHIR --> Epic[Epic FHIR Server]
    Backend --> Snowflake[Snowflake DW]
    ML --> Snowflake
```

---

## 1. Patient Demographics and Encounter Data

### Frontend Components: PatientInfo, PatientDetails, PatientClassTimeline

#### Patient Demographics Mapping

| Frontend Field | Component   | FHIR Resource | FHIR Path                         | API Endpoint      |
| -------------- | ----------- | ------------- | --------------------------------- | ----------------- |
| name           | PatientInfo | Patient       | name[0].given[0] + name[0].family | GET /Patient/{id} |
| gender         | PatientInfo | Patient       | gender                            | GET /Patient/{id} |
| age            | PatientInfo | Patient       | (calculated from birthDate)       | GET /Patient/{id} |
| dateOfBirth    | PatientInfo | Patient       | birthDate                         | GET /Patient/{id} |
| mrn            | PatientInfo | Patient       | identifier (type=MR)              | GET /Patient/{id} |
| har            | PatientInfo | Patient       | identifier (type=VN or custom)    | GET /Patient/{id} |

#### Patient Details Mapping

| Frontend Field       | Component      | FHIR Resource | FHIR Path                                 | API Endpoint                             |
| -------------------- | -------------- | ------------- | ----------------------------------------- | ---------------------------------------- |
| financialClass       | PatientDetails | Coverage      | class.display                             | GET /Coverage?patient={id}&status=active |
| primaryPayer         | PatientDetails | Coverage      | payor[0].display                          | GET /Coverage?patient={id}&status=active |
| plan                 | PatientDetails | Coverage      | subscriberId                              | GET /Coverage?patient={id}&status=active |
| patientClass         | PatientDetails | Encounter     | class.code                                | GET /Encounter/{id}                      |
| admissionDate        | PatientDetails | Encounter     | period.start                              | GET /Encounter/{id}                      |
| dischargeDate        | PatientDetails | Encounter     | period.end                                | GET /Encounter/{id}                      |
| lengthOfStay         | PatientDetails | Encounter     | (calculated from period)                  | GET /Encounter/{id}                      |
| dischargeDisposition | PatientDetails | Encounter     | hospitalization.dischargeDisposition.text | GET /Encounter/{id}                      |

#### Patient Class Timeline Mapping

| Frontend Field      | Component            | FHIR Resource | FHIR Path                       | API Endpoint        |
| ------------------- | -------------------- | ------------- | ------------------------------- | ------------------- |
| classHistory        | PatientClassTimeline | Encounter     | classHistory[].class.display    | GET /Encounter/{id} |
| classHistory.period | PatientClassTimeline | Encounter     | classHistory[].period.start/end | GET /Encounter/{id} |

#### API Endpoints Summary

```markdown
GET /Patient/{id}

- Returns: Patient resource with demographics
- Required Scopes: patient/Patient.read or user/Patient.read

GET /Patient?identifier={system}|{value}

- Search by MRN: identifier=urn:oid:1.2.840.114350.1.13.0.1.7.5.737384.0|{MRN}
- Returns: Bundle of Patient resources

GET /Encounter/{id}

- Returns: Full encounter with admission/discharge details
- Required Scopes: patient/Encounter.read

GET /Encounter?patient={id}&status=in-progress

- Returns: Active encounters for patient
- Use: Find current admission

GET /Coverage?patient={id}&status=active

- Returns: Active insurance coverage
- Use: Financial class and payer information
```

### Resource Relationship Diagram

```mermaid
graph LR
    Patient[Patient Resource] --> Encounter[Encounter Resource]
    Patient --> Coverage[Coverage Resource]
    Encounter --> Location[Location]
    Coverage --> Payor[Organization - Payor]
    Encounter --> Participant[Practitioner]
```

---

## 2. Clinical Documentation and Diagnoses

### Frontend Components: ClinicalDocumentationSummary, NewDiagnosisIdentified, ChartChanges

#### Diagnosis Mapping

| Frontend Field      | Component                    | FHIR Resource         | FHIR Path                     | API Endpoint                                  |
| ------------------- | ---------------------------- | --------------------- | ----------------------------- | --------------------------------------------- |
| code                | ClinicalDocumentationSummary | Condition             | code.coding[0].code (ICD-10)  | GET /Condition?patient={id}&encounter={encId} |
| description         | ClinicalDocumentationSummary | Condition             | code.coding[0].display        | GET /Condition?patient={id}&encounter={encId} |
| previousCode        | NewDiagnosisIdentified       | Condition             | (from version history)        | GET /Condition/{id}/\_history                 |
| previousDescription | NewDiagnosisIdentified       | Condition             | (from version history)        | GET /Condition/{id}/\_history                 |
| badges (POA)        | ClinicalDocumentationSummary | Condition             | extension[presentOnAdmission] | GET /Condition?patient={id}&encounter={encId} |
| badges (CC/MCC)     | ClinicalDocumentationSummary | (Backend calculation) | N/A - calculated from ICD-10  | Backend logic                                 |

#### Supporting Documentation Mapping

| Frontend Field         | Component                    | FHIR Resource     | FHIR Path                            | API Endpoint                                           |
| ---------------------- | ---------------------------- | ----------------- | ------------------------------------ | ------------------------------------------------------ |
| type: 'Labs'           | ClinicalDocumentationSummary | Observation       | category.coding[0].code='laboratory' | GET /Observation?patient={id}&category=laboratory      |
| type: 'Clinical Notes' | ClinicalDocumentationSummary | DocumentReference | type.coding[0].code                  | GET /DocumentReference?patient={id}&type=progress-note |
| type: 'Medication'     | ClinicalDocumentationSummary | MedicationRequest | medicationCodeableConcept            | GET /MedicationRequest?patient={id}&encounter={encId}  |
| author                 | ClinicalDocumentationSummary | (Any resource)    | (resource).author or performer       | (varies by resource)                                   |
| date                   | ClinicalDocumentationSummary | (Any resource)    | recordedDate or effectiveDateTime    | (varies by resource)                                   |
| description            | ClinicalDocumentationSummary | (Any resource)    | text.div or specific field           | (varies by resource)                                   |

#### Chart Changes Mapping

| Frontend Field        | Component    | FHIR Resource     | FHIR Path                | API Endpoint                          |
| --------------------- | ------------ | ----------------- | ------------------------ | ------------------------------------- |
| type: 'diagnosis'     | ChartChanges | Condition         | code.coding + versioning | GET /Condition/{id}/\_history         |
| type: 'clinical-note' | ChartChanges | DocumentReference | content.attachment.data  | GET /DocumentReference/{id}/\_history |
| type: 'lab'           | ChartChanges | Observation       | valueQuantity            | GET /Observation/{id}/\_history       |
| previousValue         | ChartChanges | (Any)             | (from previous version)  | GET /{resource}/{id}/\_history        |
| currentValue          | ChartChanges | (Any)             | (from current version)   | GET /{resource}/{id}                  |
| badges                | ChartChanges | (Meta)            | meta.tag or custom       | Backend calculation                   |

#### API Endpoints Summary

```markdown
GET /Condition?patient={id}&encounter={encounterId}

- Returns: All diagnoses for specific encounter
- Filter: &category=encounter-diagnosis
- Required Scopes: patient/Condition.read

GET /Condition?patient={id}&clinical-status=active

- Returns: Active conditions across all encounters
- Use: Current problem list

GET /Condition/{id}/\_history

- Returns: Version history of condition
- Use: Track diagnosis changes over time

GET /DocumentReference?patient={id}&type=progress-note

- Returns: Clinical notes/progress notes
- Types: consultation, discharge-summary, history-and-physical
- Required Scopes: patient/DocumentReference.read

GET /DocumentReference/{id}

- Returns: Single document with content
- content.attachment.url → fetch actual document
- content.attachment.data → base64 encoded content (if available)

GET /DiagnosticReport?patient={id}&category=LAB

- Returns: Lab reports with grouped results
- Use: Structured lab report summaries
- Required Scopes: patient/DiagnosticReport.read
```

#### Epic-Specific Extensions for Conditions

| Extension            | URL                                                                     | Purpose                             |
| -------------------- | ----------------------------------------------------------------------- | ----------------------------------- |
| Present on Admission | <http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition-poa> | POA indicator                       |
| Diagnosis Rank       | <http://fhir.epic.com/StructureDefinition/condition-rank>               | Primary/secondary ranking           |
| Diagnosis Date       | (varies)                                                                | When diagnosis was made vs recorded |

---

## 3. DRG Analysis and Procedures

### Frontend Components: DRGAnalysisMain, DRGAnalysisTab, DRGAnalysisTracker

#### DRG Data Mapping

| Frontend Field          | Component       | FHIR Resource   | FHIR Path                    | API Endpoint                              |
| ----------------------- | --------------- | --------------- | ---------------------------- | ----------------------------------------- |
| workingDRG.code         | DRGAnalysisMain | Claim           | item[0].revenue.coding (DRG) | GET /Claim?patient={id}&encounter={encId} |
| workingDRG.description  | DRGAnalysisMain | Claim           | (lookup from DRG code)       | Backend DRG table                         |
| workingDRG.weight       | DRGAnalysisMain | (Not in FHIR)   | N/A                          | Backend DRG table                         |
| workingDRG.gmlos        | DRGAnalysisMain | (Not in FHIR)   | N/A                          | Backend DRG table                         |
| workingDRG.assignedBy   | DRGAnalysisMain | Claim           | enterer.display or provider  | GET /Claim/{id}                           |
| workingDRG.assignedDate | DRGAnalysisMain | Claim           | created                      | GET /Claim/{id}                           |
| recommendedDRG          | DRGAnalysisMain | (ML Prediction) | N/A                          | Backend ML Service                        |
| aiConfidenceScore       | DRGAnalysisMain | (ML Prediction) | N/A                          | Backend ML Service                        |
| baselineDRG             | PatientDetails  | Encounter       | (Epic extension or Claim)    | GET /Encounter/{id} or GET /Claim         |

#### Procedure Mapping

| Frontend Field   | Component                    | FHIR Resource | FHIR Path                  | API Endpoint                                  |
| ---------------- | ---------------------------- | ------------- | -------------------------- | --------------------------------------------- |
| cptCode          | ClinicalDocumentationSummary | Procedure     | code.coding[0].code (CPT)  | GET /Procedure?patient={id}&encounter={encId} |
| description      | Various                      | Procedure     | code.coding[0].display     | GET /Procedure?patient={id}&encounter={encId} |
| author/performer | Various                      | Procedure     | performer[0].actor.display | GET /Procedure?patient={id}&encounter={encId} |
| date             | Various                      | Procedure     | performedDateTime          | GET /Procedure?patient={id}&encounter={encId} |

#### API Endpoints Summary

```markdown
GET /Claim?patient={id}&use=claim&encounter={encId}

- Returns: Claim resources with DRG assignments
- Note: May not be real-time, typically billing cycle
- Required Scopes: patient/Claim.read

GET /Claim?patient={id}&status=active

- Returns: Active claims
- Use: Current DRG assignment

GET /Procedure?patient={id}&encounter={encounterId}

- Returns: Procedures performed during encounter
- Filter: &category=procedure for actual procedures
- Required Scopes: patient/Procedure.read

GET /Procedure?patient={id}&date=ge{date}

- Returns: Procedures after specified date
- Use: Recent procedures
```

#### Important Notes on DRG Data

**DRG data is NOT standard FHIR.** Options for obtaining DRG information:

1. **Epic-Specific Extension on Encounter:**
   - Epic may include DRG in Encounter.hospitalization extension
   - URL: `http://fhir.epic.com/StructureDefinition/encounter-drg`

2. **Claim Resource (Post-Billing):**
   - Claim.item[].revenue.coding with DRG code
   - May have significant delay (billing cycle)

3. **Epic Proprietary API (if available):**
   - `GET /api/epic/v1/Encounter/{id}/drg`
   - Requires Epic customer agreement

4. **Backend Calculation (Recommended):**
   - Fetch Conditions + Procedures
   - Use backend DRG grouper logic
   - Store in Snowflake for historical tracking

#### Backend DRG Processing Flow

```mermaid
sequenceDiagram
    participant FE as Frontend
    participant BE as Backend API
    participant FHIR as Epic FHIR
    participant ML as ML Service
    participant SF as Snowflake

    FE->>BE: Get DRG Analysis for Encounter
    BE->>FHIR: GET /Encounter/{id}
    BE->>FHIR: GET /Condition?encounter={id}
    BE->>FHIR: GET /Procedure?encounter={id}
    BE->>SF: Query historical DRG assignments
    BE->>ML: Request DRG prediction
    ML->>SF: Fetch training data
    ML-->>BE: Return predicted DRG + confidence
    BE-->>FE: Return working DRG + recommended DRG
```

---

## 4. Labs, Observations, and Vitals

### Frontend Components: ClinicalDocumentationSummary (supporting docs)

#### Observation Mapping

| Frontend Field   | Component                | FHIR Resource | FHIR Path                   | API Endpoint                                       |
| ---------------- | ------------------------ | ------------- | --------------------------- | -------------------------------------------------- |
| Labs description | Supporting Documentation | Observation   | code.coding[0].display      | GET /Observation?patient={id}&category=laboratory  |
| Lab value        | Supporting Documentation | Observation   | valueQuantity.value + unit  | GET /Observation?patient={id}&category=laboratory  |
| Lab code         | Backend                  | Observation   | code.coding[0].code (LOINC) | GET /Observation?patient={id}&category=laboratory  |
| Vital signs      | Supporting Documentation | Observation   | valueQuantity               | GET /Observation?patient={id}&category=vital-signs |
| Lab date         | Supporting Documentation | Observation   | effectiveDateTime           | GET /Observation?patient={id}&category=laboratory  |
| Lab author       | Supporting Documentation | Observation   | performer[0].display        | GET /Observation?patient={id}&category=laboratory  |

#### Key LOINC Codes for Common Labs

| Lab Test                 | LOINC Code | Typical Units |
| ------------------------ | ---------- | ------------- |
| WBC Count                | 6690-2     | 10\*3/uL      |
| Creatinine               | 2160-0     | mg/dL         |
| Lactate                  | 2524-7     | mmol/L        |
| Blood Glucose            | 2339-0     | mg/dL         |
| Hemoglobin               | 718-7      | g/dL          |
| Platelets                | 777-3      | 10\*3/uL      |
| Sodium                   | 2951-2     | mmol/L        |
| Potassium                | 2823-3     | mmol/L        |
| Temperature              | 8310-5     | degF or degC  |
| Blood Pressure Systolic  | 8480-6     | mm[Hg]        |
| Blood Pressure Diastolic | 8462-4     | mm[Hg]        |
| Heart Rate               | 8867-4     | /min          |
| Respiratory Rate         | 9279-1     | /min          |
| SpO2                     | 2708-6     | %             |

#### API Endpoints Summary

```markdown
GET /Observation?patient={id}&category=laboratory

- Returns: Lab results
- Add: &date=ge{date} for recent labs
- Add: &code={LOINC} for specific test
- Required Scopes: patient/Observation.read

GET /Observation?patient={id}&category=vital-signs

- Returns: Vital signs (BP, temp, HR, RR, SpO2)
- Add: &date=ge{date} for recent vitals

GET /Observation?patient={id}&code={LOINC}

- Returns: Specific lab test results
- Example: code=2160-0 for creatinine

GET /DiagnosticReport?patient={id}&category=LAB&encounter={encId}

- Returns: Grouped lab results
- Use: Full lab panels with interpretation
```

---

## 5. Medications

### Frontend Components: ClinicalDocumentationSummary (supporting docs)

#### Medication Mapping

| Frontend Field         | Component                | FHIR Resource            | FHIR Path                                | API Endpoint                               |
| ---------------------- | ------------------------ | ------------------------ | ---------------------------------------- | ------------------------------------------ |
| Medication name        | Supporting Documentation | MedicationRequest        | medicationCodeableConcept.text           | GET /MedicationRequest?patient={id}        |
| Medication code        | Backend                  | MedicationRequest        | medicationCodeableConcept.coding[0].code | GET /MedicationRequest?patient={id}        |
| Medication description | Supporting Documentation | MedicationRequest        | dosageInstruction[0].text                | GET /MedicationRequest?patient={id}        |
| Prescriber             | Supporting Documentation | MedicationRequest        | requester.display                        | GET /MedicationRequest?patient={id}        |
| Date prescribed        | Supporting Documentation | MedicationRequest        | authoredOn                               | GET /MedicationRequest?patient={id}        |
| Administration records | Backend                  | MedicationAdministration | effectiveDateTime + dosage               | GET /MedicationAdministration?patient={id} |

#### API Endpoints Summary

```markdown
GET /MedicationRequest?patient={id}&encounter={encounterId}

- Returns: Medications ordered during encounter
- Add: &status=active for active orders
- Required Scopes: patient/MedicationRequest.read

GET /MedicationRequest?patient={id}&status=active

- Returns: Current active medications
- Use: Medication reconciliation

GET /MedicationAdministration?patient={id}&encounter={encId}

- Returns: Actual medication administrations
- Use: Confirm medications were given
- Required Scopes: patient/MedicationAdministration.read
```

---

## 6. Utilization Review and Queries

### Frontend Components: UtilizationReviewSummary, Queries

#### Utilization Review Mapping

| Frontend Field              | Component                | FHIR Resource | FHIR Path                 | API Endpoint                                  |
| --------------------------- | ------------------------ | ------------- | ------------------------- | --------------------------------------------- |
| Decision criteria diagnosis | UtilizationReviewSummary | Condition     | code.coding + text        | GET /Condition?patient={id}&encounter={encId} |
| Inpatient-only procedure    | UtilizationReviewSummary | Procedure     | code.coding[0].code (CPT) | GET /Procedure?patient={id}&encounter={encId} |
| Patient class validation    | UtilizationReviewSummary | Encounter     | class.code                | GET /Encounter/{id}                           |
| Procedure description       | UtilizationReviewSummary | Procedure     | code.text or display      | GET /Procedure?patient={id}&encounter={encId} |

#### Query Workflow Mapping

| Frontend Field         | Component | FHIR Resource        | FHIR Path                | API Endpoint                                  |
| ---------------------- | --------- | -------------------- | ------------------------ | --------------------------------------------- |
| Query status           | Queries   | CommunicationRequest | status                   | GET /CommunicationRequest?subject={patientId} |
| Query type             | Queries   | CommunicationRequest | category.text            | GET /CommunicationRequest?subject={patientId} |
| Query recipient        | Queries   | CommunicationRequest | recipient[0].display     | GET /CommunicationRequest?subject={patientId} |
| Query sentBy           | Queries   | CommunicationRequest | sender.display           | GET /CommunicationRequest?subject={patientId} |
| Query sentDate         | Queries   | CommunicationRequest | authoredOn               | GET /CommunicationRequest?subject={patientId} |
| Query response         | Queries   | Communication        | payload[0].contentString | GET /Communication?based-on={commReqId}       |
| Response received date | Queries   | Communication        | sent                     | GET /Communication?based-on={commReqId}       |

#### API Endpoints Summary

```markdown
GET /ServiceRequest?patient={id}&status=active&encounter={encId}

- Returns: Active service requests/orders
- Use: Identify procedures ordered
- Required Scopes: patient/ServiceRequest.read

GET /CommunicationRequest?subject={patientId}

- Returns: Clinical queries sent
- Add: &status=active for pending queries
- Required Scopes: user/CommunicationRequest.read

POST /CommunicationRequest

- Creates: New clinical query
- Body: CommunicationRequest resource
- Required Scopes: user/CommunicationRequest.write

GET /Communication?based-on={communicationRequestId}

- Returns: Responses to specific query
- Use: Track query responses
- Required Scopes: user/Communication.read
```

#### Utilization Review Backend Logic

**Inpatient-Only Procedures:** Backend must maintain list of inpatient-only CPT codes and validate patient class matches. Not available via FHIR API.

**Medicare Short Stay Warning:** Calculate from Encounter.period duration + Encounter.class.code + Coverage.payor (Medicare).

---

## 7. Complete FHIR Resource Quick Reference

### All Required FHIR Resources

| FHIR Resource            | Frontend Use              | Backend Use                         | API Endpoint Pattern                       |
| ------------------------ | ------------------------- | ----------------------------------- | ------------------------------------------ |
| Patient                  | PatientInfo demographics  | Patient search, identity            | GET /Patient/{id}                          |
| Encounter                | PatientDetails, Timeline  | Encounter context, length of stay   | GET /Encounter/{id}                        |
| Coverage                 | Financial class, payer    | Authorization, financial validation | GET /Coverage?patient={id}                 |
| Condition                | Diagnoses, ICD-10 codes   | CDI analysis, DRG grouping          | GET /Condition?patient={id}                |
| Procedure                | CPT codes, procedures     | DRG grouping, coding validation     | GET /Procedure?patient={id}                |
| Observation              | Labs, vitals              | Clinical indicators, ML features    | GET /Observation?patient={id}              |
| MedicationRequest        | Medication lists          | Treatment tracking, CDI support     | GET /MedicationRequest?patient={id}        |
| MedicationAdministration | Med administration        | Actual treatments given             | GET /MedicationAdministration?patient={id} |
| DocumentReference        | Clinical notes            | NLP, documentation changes          | GET /DocumentReference?patient={id}        |
| DiagnosticReport         | Lab reports               | Structured lab data                 | GET /DiagnosticReport?patient={id}         |
| Claim                    | DRG assignments (delayed) | DRG history, billing validation     | GET /Claim?patient={id}                    |
| ServiceRequest           | Orders                    | Procedure validation                | GET /ServiceRequest?patient={id}           |
| CommunicationRequest     | Query workflow            | Query tracking                      | GET /CommunicationRequest                  |
| Communication            | Query responses           | Response tracking                   | GET /Communication                         |
| Practitioner             | Provider names            | Provider identification             | GET /Practitioner/{id}                     |
| Organization             | Payers, facilities        | Reference data                      | GET /Organization/{id}                     |
| Location                 | Encounter locations       | Department tracking                 | GET /Location/{id}                         |

---

## 8. Backend Data Flow for CDI Review

```mermaid
sequenceDiagram
    participant FE as Frontend
    participant BE as Backend
    participant FHIR as Epic FHIR
    participant ML as ML Service
    participant Cache as Redis

    FE->>BE: Load patient encounter
    BE->>Cache: Check cached data
    alt Cache hit
        Cache-->>BE: Return cached data
    else Cache miss
        BE->>FHIR: GET /Patient/{id}
        BE->>FHIR: GET /Encounter/{id}
        BE->>FHIR: GET /Condition?encounter={id}
        BE->>FHIR: GET /Procedure?encounter={id}
        BE->>FHIR: GET /Observation?patient={id}&category=laboratory
        BE->>FHIR: GET /MedicationRequest?encounter={id}
        BE->>Cache: Cache results (15 min TTL)
    end
    BE->>ML: Request DRG prediction + CDI opportunities
    ML-->>BE: Return AI recommendations
    BE-->>FE: Return complete CDI review data
```

---

## 9. Backend Integration Architecture

```mermaid
graph TB
    subgraph Frontend
        UI[React Components]
    end

    subgraph Backend
        API[FastAPI Endpoints]
        FHIR_Client[FHIR Client Service]
        Transform[Data Transform Layer]
        Auth[JWT Auth Service]
        Cache[Redis Cache]
    end

    subgraph External
        Epic[Epic FHIR Server]
        ML[ML Service]
        Snowflake[Snowflake DW]
    end

    UI --> API
    API --> Auth
    API --> FHIR_Client
    FHIR_Client --> Cache
    FHIR_Client --> Epic
    API --> Transform
    Transform --> ML
    Transform --> Snowflake
    ML --> Snowflake
```

---

## 10. OAuth 2.0 Scopes Required

### Patient Context (Patient-Facing Apps)

```
patient/Patient.read
patient/Encounter.read
patient/Condition.read
patient/Observation.read
patient/MedicationRequest.read
patient/Procedure.read
patient/DocumentReference.read
patient/DiagnosticReport.read
patient/Coverage.read
```

### User Context (Provider-Facing Apps) - RECOMMENDED

```
user/Patient.read
user/Encounter.read
user/Condition.read
user/Observation.read
user/MedicationRequest.read
user/MedicationAdministration.read
user/Procedure.read
user/DocumentReference.read
user/DiagnosticReport.read
user/Coverage.read
user/Claim.read
user/ServiceRequest.read
user/CommunicationRequest.read
user/CommunicationRequest.write
user/Communication.read
user/Practitioner.read
user/Organization.read
user/Location.read
```

### System Context (Backend Service/Bulk Export)

```
system/Patient.read
system/Encounter.read
system/Condition.read
system/Observation.read
system/MedicationRequest.read
system/Procedure.read
```

---

## 11. Epic-Specific Considerations

### Error Codes Reference

| Error Code | Description                | Handling Strategy                  |
| ---------- | -------------------------- | ---------------------------------- |
| 4100       | Invalid parameter          | Validate parameters before sending |
| 4101       | No results found           | Return empty array, not error      |
| 4102       | Invalid resource ID        | Validate ID format, return 404     |
| 4107       | Patient merged             | Follow redirect, update local ID   |
| 4111       | Required parameter missing | Add required parameters            |
| 4118       | User not authorized        | Check OAuth scopes, return 403     |
| 4130       | Break-the-glass required   | Implement BTG flow if needed       |

### Pagination Strategy

Epic returns paginated results in FHIR Bundle format:

```json
{
  "resourceType": "Bundle",
  "type": "searchset",
  "total": 150,
  "link": [
    {
      "relation": "self",
      "url": "..."
    },
    {
      "relation": "next",
      "url": "https://fhir.epic.com/..."
    }
  ],
  "entry": [...]
}
```

**Implementation:**

- Use `_count` parameter to set page size (default: 50, max: varies)
- Follow `link[relation=next].url` for next page
- Stop when no `next` link present

### Rate Limiting

- Epic rate limits vary by customer and app type
- Typical: 100-1000 requests/minute per user
- Implement exponential backoff: 1s, 2s, 4s, 8s
- Cache frequently accessed data (Patient, Encounter)
- Use batch requests where supported

### SMART on FHIR Launch Sequence

1. **EHR-Initiated Launch:**
   - Epic sends launch request to app with `iss` and `launch` parameters
   - App redirects to authorization endpoint
   - User authenticates and authorizes
   - App receives authorization code
   - App exchanges code for access token
   - Token includes patient/encounter context

2. **Standalone Launch:**
   - App initiates OAuth flow
   - User selects patient after authentication
   - No automatic context

---

## 12. Implementation Priorities

### Phase 1: Core Patient Data

1. Patient demographics (Patient resource)
2. Current encounter (Encounter resource)
3. Active diagnoses (Condition resource)
4. Recent labs (Observation resource)

### Phase 2: CDI Features

1. Clinical notes (DocumentReference)
2. Procedures (Procedure resource)
3. Medications (MedicationRequest)
4. DRG data (Claim or backend calculation)

### Phase 3: Advanced Features

1. Query workflow (CommunicationRequest)
2. Chart change tracking (resource versioning)
3. Utilization review logic (backend validation)
4. ML integration (backend service)

---

## Appendix A: Sample FHIR Requests

### Get Patient by ID

```
GET https://fhir.epic.com/api/FHIR/R4/Patient/eM8.8NLHyp7kxdEKE1.WwQ3
Authorization: Bearer {access_token}
Accept: application/fhir+json
```

### Search Conditions for Encounter

```
GET https://fhir.epic.com/api/FHIR/R4/Condition?patient=eM8.8NLHyp7kxdEKE1.WwQ3&encounter=eMTI.cGa2GmBp8N8R6gVy0Bw3
Authorization: Bearer {access_token}
Accept: application/fhir+json
```

### Get Recent Lab Results

```
GET https://fhir.epic.com/api/FHIR/R4/Observation?patient=eM8.8NLHyp7kxdEKE1.WwQ3&category=laboratory&date=ge2024-07-01
Authorization: Bearer {access_token}
Accept: application/fhir+json
```

---

## Appendix B: Non-FHIR Data Requirements

These data elements are **not available** via Epic FHIR APIs and must be handled in backend:

| Data Element                  | Source             | Implementation              |
| ----------------------------- | ------------------ | --------------------------- |
| DRG Weight                    | CMS DRG tables     | Backend lookup table        |
| DRG GMLOS                     | CMS DRG tables     | Backend lookup table        |
| DRG Recommendations           | ML predictions     | Backend ML service          |
| AI Confidence Scores          | ML predictions     | Backend ML service          |
| ICD-10 CC/MCC classification  | CMS CC/MCC lists   | Backend validation service  |
| Inpatient-only procedure list | CMS/Medicare rules | Backend validation tables   |
| Coding productivity metrics   | Internal tracking  | Snowflake analytics         |
| User role permissions         | Internal RBAC      | Backend auth service        |
| Historical DRG changes        | Internal tracking  | Snowflake historical tables |

---

## Summary

This document provides comprehensive mapping between your frontend components and Epic FHIR R4 APIs. Key takeaways:

1. **17 FHIR resources** are required for full functionality
2. **DRG data** is not standard FHIR - requires backend calculation or Epic extensions
3. **ML predictions** are backend-only - FHIR provides input data
4. **OAuth scopes** should use `user/*` context for provider-facing app
5. **Caching strategy** is critical - implement Redis for frequently accessed data
6. **Error handling** must account for Epic-specific error codes
7. **Pagination** is required for all list operations

The architecture supports both real-time FHIR API calls for active patient reviews and bulk export to Snowflake for historical analytics and ML training.
