Project

General

Profile

New feature / Change #8924

Updated by Gor Grigoryan 2 months ago

    ## Summary 
   FHIR API integration for Appointment and Encounter resources. 

   ## Description 
   As an external EMR system, I need FHIR R4 compliant API endpoints to create appointments and retrieve encounters, enabling interoperability with healthcare systems like OpenEMR. 

   ## Requirements 

   **FHIR Endpoints:** 
   POST     /api/fhir/Appointment             → Create appointment (returns FHIR Appointment) 
   GET      /api/fhir/Appointment             → List appointments (returns FHIR Bundle) 
   GET      /api/fhir/Appointment/:id         → Get appointment (returns FHIR Appointment) 
   PUT      /api/fhir/Appointment/:id         → Update appointment 
   DELETE /api/fhir/Appointment/:id         → Cancel appointment 

   GET      /api/fhir/Encounter               → List encounters (returns FHIR Bundle) 
   GET      /api/fhir/Encounter/:id           → Get encounter (returns FHIR Encounter) 

   **FHIR → Internal Model Mapping:** 

   | FHIR Resource | Internal Model | 
   |---------------|----------------| 
   | Appointment | Appointment + Consultation | 
   | Appointment.participant (Patient) | Participant (user, email, phone) | 
   | Appointment.participant (Practitioner) | Participant (doctor) | 
   | Encounter | Consultation | 

   **Appointment Mapping:** 
   

 | FHIR Field | Internal Field | 
   
 |------------|----------------| 
   
 | Appointment.start | Appointment.scheduled_at | 
   
 | Appointment.end | Appointment.end_expected_at | 
   
 | Appointment.status | Appointment.status | 
   
 | Appointment.serviceType | Type (Online/InPerson) | 
   
 | Appointment.participant[Patient] | Participant (beneficiary) | 
   
 | Appointment.participant[Practitioner] | Participant (doctor) | 
   
 | Appointment.reason | Consultation.description | 
   
 | Appointment.identifier | External reference (store in metadata) | 

   **Encounter Mapping:** 
   | FHIR Field | Internal Field | 
   |------------|----------------| 
   | Encounter.status | Consultation status | 
   | Encounter.period.start | Consultation.created_at | 
   | Encounter.period.end | Consultation.closed_at | 
   | Encounter.appointment | Reference to Appointment | 
   | Encounter.subject | Consultation.beneficiary | 
   | Encounter.participant | Consultation.owned_by (doctor) | 

   **Status Mappings:** 

   | FHIR Appointment | Internal Status | 
   |------------------|-----------------| 
   | proposed | - | 
   | booked | Scheduled | 
   | cancelled | Cancelled | 
   | fulfilled | (completed) | 

   | FHIR Encounter | Internal Status | 
   |----------------|-----------------| 
   | planned | pending | 
   | in-progress | active | 
   | finished | closed | 

   **Request Body Example (Create Appointment):** 
   ```json 
   { 
     "resourceType": "Appointment", 
     "status": "booked", 
     "start": "2025-01-15T10:00:00Z", 
     "end": "2025-01-15T10:30:00Z", 
     "serviceType": [{"coding": [{"code": "online"}]}], 
     "identifier": [{"system": "openemr", "value": "APT-12345"}], 
     "participant": [ 
       { 
         "actor": { 
           "reference": "#patient1", 
           "type": "Patient" 
         }, 
         "status": "accepted" 
       }, 
       { 
         "actor": { 
           "reference": "#practitioner1", 
           "type": "Practitioner" 
         }, 
         "status": "accepted" 
       } 
     ], 
     "contained": [ 
       { 
         "resourceType": "Patient", 
         "id": "patient1", 
         "name": [{"family": "Doe", "given": ["John"]}], 
         "telecom": [ 
           {"system": "email", "value": "john@example.com"}, 
           {"system": "phone", "value": "+1234567890"} 
         ] 
       }, 
       { 
         "resourceType": "Practitioner", 
         "id": "practitioner1", 
         "name": [{"family": "Smith", "given": ["Dr"]}], 
         "telecom": [{"system": "email", "value": "dr.smith@clinic.com"}] 
       } 
     ] 
   } 

   Response (FHIR Appointment): 
   { 
     "resourceType": "Appointment", 
     "id": "123", 
     "status": "booked", 
     "start": "2025-01-15T10:00:00Z", 
     "end": "2025-01-15T10:30:00Z", 
     ... 
   } 

   Validation Rules: 
   - Patient participant required with name and contact (email or phone) 
   - Practitioner participant required with email (must exist in system) 
   - Start date required and must be in future 
   - Cannot update after consultation started 

   Search Parameters: 
   - identifier - Search by external system ID 
   - appointment.identifier - Search encounters by appointment ID 

   Acceptance Criteria 

   - POST /fhir/Appointment creates Consultation + Appointment + Participants 
   - POST /fhir/Appointment returns valid FHIR Appointment response 
   - GET /fhir/Appointment returns FHIR Appointment or Bundle 
   - GET /fhir/Encounter returns FHIR Encounter or Bundle 
   - Search by external identifier works 
   - Invalid FHIR body returns 400 with validation errors 
   - Practitioner not in system returns 400 error 
   - Status mappings work bidirectionally 
   - Cannot modify appointment with active consultation 

   Notes 

   - Store original FHIR body for audit/reference 


   

   ---

Back