Project

General

Profile

New feature / Change #8924

Updated by Olivier Bitsch 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): 

 ``` json 
 { 
   "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