--- title: "FHIR REST API" category: "fhir-api" group: "architecture" version: "2.0.0" releaseDate: "2024-11-21" status: "completed" description: "RESTful FHIR API endpoints voor data-uitwisseling - patiënten, contactmomenten, diagnoses en behandelplannen" --- ## Overview Het Mini-EPD biedt een **RESTful FHIR API** voor uitwisseling van GGZ-gegevens. De API volgt de FHIR R4 specificatie en ondersteunt standaard HTTP methods (GET, POST, PUT) voor CRUD operaties. **Waarom een FHIR API?** - ✅ **Data-uitwisselbaarheid** - Andere systemen kunnen jouw data lezen/schrijven - ✅ **Standaard compliant** - Volgt internationale FHIR R4 specificatie - ✅ **Toekomstbestendig** - Compatible met MedMIJ, Koppeltaal, LSP - ✅ **Veilig** - Bearer token authenticatie, RLS policies, audit logging **API Base URL:** ``` https://jouw-domein.nl/api/fhir/ ``` **Response Format:** - Content-Type: `application/fhir+json` - FHIR R4 compliant JSON - Errors via FHIR OperationOutcome --- ## Implementatie Status ### ✅ Epic 2: Voltooid (21 november 2024) **Patient API** - CRUD voor patiëntgegevens - GET, POST, PUT volledig werkend - Zoeken op naam, BSN, geboortedatum - FHIR Bundle responses **Practitioner API** - Behandelaren beheer - GET, POST werkend - Zoeken op naam, BIG, AGB - Nederlandse identificatie systemen ### ⏳ Epic 3-7: In Planning **Encounter API** - Contactmomenten (Q1 2025) **Condition API** - Diagnoses DSM-5/ICD-10 (Q1 2025) **Observation API** - ROM-metingen & risico's (Q1 2025) **CarePlan API** - Behandelplannen 🎯 (Q1 2025) --- ## Patient API **Status:** ✅ **Actief** (sinds 21 november 2024) ### Endpoints #### GET /api/fhir/Patient - Lijst van patiënten **Beschrijving:** Ophalen van alle patiënten met optionele zoekfilters. **Query Parameters:** - `name` - Zoeken op voor- of achternaam (case-insensitive) - `identifier` - Zoeken op BSN - `birthdate` - Zoeken op geboortedatum (YYYY-MM-DD) **Response:** ```json { "resourceType": "Bundle", "type": "searchset", "total": 3, "entry": [ { "resource": { "resourceType": "Patient", "id": "550e8400-e29b-41d4-a716-446655440000", "identifier": [ { "system": "http://fhir.nl/fhir/NamingSystem/bsn", "value": "123456789", "use": "official" } ], "name": [ { "use": "official", "family": "de Vries", "given": ["Jan", "Peter"] } ], "gender": "male", "birthDate": "1985-03-15", "telecom": [ { "system": "phone", "value": "+31612345678", "use": "mobile" } ], "active": true } } ] } ``` **Gebruik:** ```bash # Alle patiënten GET /api/fhir/Patient # Zoeken op naam GET /api/fhir/Patient?name=vries # Zoeken op BSN GET /api/fhir/Patient?identifier=123456789 ``` --- #### GET /api/fhir/Patient/[id] - Specifieke patiënt **Beschrijving:** Ophalen van één specifieke patiënt op basis van ID. **Path Parameters:** - `id` - UUID van de patiënt **Response:** ```json { "resourceType": "Patient", "id": "550e8400-e29b-41d4-a716-446655440000", "identifier": [ { "system": "http://fhir.nl/fhir/NamingSystem/bsn", "value": "123456789", "use": "official" } ], "name": [ { "use": "official", "family": "de Vries", "given": ["Jan", "Peter"], "prefix": ["Dhr."] } ], "gender": "male", "birthDate": "1985-03-15", "telecom": [ { "system": "phone", "value": "+31612345678", "use": "mobile" }, { "system": "email", "value": "jan.devries@example.com" } ], "address": [ { "use": "home", "line": ["Hoofdstraat 123"], "city": "Amsterdam", "postalCode": "1012 AB", "country": "NL" } ], "generalPractitioner": [ { "display": "Dr. Jansen", "identifier": { "system": "http://fhir.nl/fhir/NamingSystem/agb-z", "value": "12345678" } } ], "active": true, "meta": { "lastUpdated": "2024-11-21T10:30:00Z" } } ``` **Gebruik:** ```bash GET /api/fhir/Patient/550e8400-e29b-41d4-a716-446655440000 ``` **Error Response (404):** ```json { "resourceType": "OperationOutcome", "issue": [ { "severity": "error", "code": "not-found", "diagnostics": "Patient with id 550e8400-... not found" } ] } ``` --- #### POST /api/fhir/Patient - Nieuwe patiënt aanmaken **Beschrijving:** Aanmaken van een nieuwe patiënt vanuit FHIR JSON. **Request Body:** ```json { "resourceType": "Patient", "identifier": [ { "system": "http://fhir.nl/fhir/NamingSystem/bsn", "value": "987654321", "use": "official" } ], "name": [ { "use": "official", "family": "Jansen", "given": ["Marie"] } ], "gender": "female", "birthDate": "1990-06-20", "telecom": [ { "system": "phone", "value": "+31687654321", "use": "mobile" } ], "active": true } ``` **Response (201 Created):** ```json { "resourceType": "Patient", "id": "660e8400-e29b-41d4-a716-446655440001", "identifier": [ { "system": "http://fhir.nl/fhir/NamingSystem/bsn", "value": "987654321", "use": "official" } ], "name": [ { "use": "official", "family": "Jansen", "given": ["Marie"] } ], "gender": "female", "birthDate": "1990-06-20", "telecom": [ { "system": "phone", "value": "+31687654321", "use": "mobile" } ], "active": true, "meta": { "lastUpdated": "2024-11-21T14:25:00Z" } } ``` **Headers:** - `Location: /api/fhir/Patient/660e8400-e29b-41d4-a716-446655440001` **Gebruik:** ```bash POST /api/fhir/Patient Content-Type: application/fhir+json { "resourceType": "Patient", ... } ``` **Validatie:** Verplichte velden: - `resourceType` moet "Patient" zijn - `name` moet aanwezig zijn - `gender` moet aanwezig zijn - `birthDate` moet aanwezig zijn **Error Response (400 Bad Request):** ```json { "resourceType": "OperationOutcome", "issue": [ { "severity": "error", "code": "invalid", "diagnostics": "Missing required field: birthDate" } ] } ``` --- #### PUT /api/fhir/Patient/[id] - Patiënt bijwerken **Beschrijving:** Bijwerken van een bestaande patiënt. **Path Parameters:** - `id` - UUID van de patiënt **Request Body:** ```json { "resourceType": "Patient", "id": "550e8400-e29b-41d4-a716-446655440000", "identifier": [ { "system": "http://fhir.nl/fhir/NamingSystem/bsn", "value": "123456789", "use": "official" } ], "name": [ { "use": "official", "family": "de Vries-Bakker", "given": ["Jan", "Peter"] } ], "gender": "male", "birthDate": "1985-03-15", "telecom": [ { "system": "phone", "value": "+31698765432", "use": "mobile" } ], "active": true } ``` **Response (200 OK):** Volledige bijgewerkte Patient resource. **Gebruik:** ```bash PUT /api/fhir/Patient/550e8400-e29b-41d4-a716-446655440000 Content-Type: application/fhir+json { "resourceType": "Patient", "id": "550e8400-e29b-41d4-a716-446655440000", ... } ``` **Validatie:** - ID in URL moet overeenkomen met ID in body (indien aanwezig) - Patiënt moet bestaan (anders 404) --- ## Practitioner API **Status:** ✅ **Actief** (sinds 21 november 2024) ### Endpoints #### GET /api/fhir/Practitioner - Lijst van behandelaren **Beschrijving:** Ophalen van alle behandelaren met optionele zoekfilters. **Query Parameters:** - `name` - Zoeken op voor- of achternaam - `identifier` - Zoeken op BIG-nummer of AGB-code **Response:** ```json { "resourceType": "Bundle", "type": "searchset", "total": 2, "entry": [ { "resource": { "resourceType": "Practitioner", "id": "770e8400-e29b-41d4-a716-446655440002", "identifier": [ { "system": "http://fhir.nl/fhir/NamingSystem/big", "value": "12345678901", "use": "official" }, { "system": "http://fhir.nl/fhir/NamingSystem/agb-z", "value": "87654321", "use": "official" } ], "name": [ { "use": "official", "family": "Bakker", "given": ["Sarah"], "prefix": ["Dr."] } ], "telecom": [ { "system": "phone", "value": "+31201234567", "use": "work" }, { "system": "email", "value": "s.bakker@ggz-instelling.nl", "use": "work" } ], "qualification": [ { "code": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/v2-0360", "display": "GZ-psycholoog" } ], "text": "GZ-psycholoog" } } ], "active": true } } ] } ``` **Gebruik:** ```bash # Alle behandelaren GET /api/fhir/Practitioner # Zoeken op naam GET /api/fhir/Practitioner?name=Bakker # Zoeken op BIG of AGB GET /api/fhir/Practitioner?identifier=12345678901 ``` --- #### GET /api/fhir/Practitioner/[id] - Specifieke behandelaar **Beschrijving:** Ophalen van één specifieke behandelaar. **Response:** Volledige Practitioner resource met BIG, AGB, kwalificaties en contactgegevens. **Gebruik:** ```bash GET /api/fhir/Practitioner/770e8400-e29b-41d4-a716-446655440002 ``` --- #### POST /api/fhir/Practitioner - Nieuwe behandelaar aanmaken **Beschrijving:** Aanmaken van een nieuwe behandelaar vanuit FHIR JSON. **Request Body:** ```json { "resourceType": "Practitioner", "identifier": [ { "system": "http://fhir.nl/fhir/NamingSystem/big", "value": "98765432109", "use": "official" } ], "name": [ { "use": "official", "family": "de Jong", "given": ["Peter"] } ], "qualification": [ { "code": { "text": "Psychiater" } } ], "active": true } ``` **Response (201 Created):** Volledige Practitioner resource met gegenereerd ID. **Gebruik:** ```bash POST /api/fhir/Practitioner Content-Type: application/fhir+json { "resourceType": "Practitioner", ... } ``` --- ## Encounter API **Status:** ⏳ **In Planning** (Epic 3 - Q1 2025) ### Geplande Endpoints #### GET /api/fhir/Encounter - Contactmomenten **Doel:** Ophalen van alle contactmomenten met zoekfilters. **Query Parameters (gepland):** - `patient` - Filter op patiënt ID - `date` - Filter op datum - `type` - Type contact (intake, behandeling, crisis) - `status` - Status (planned, in-progress, finished) **Use Case:** ```bash # Alle contacten van patiënt GET /api/fhir/Encounter?patient=550e8400-e29b-41d4-a716-446655440000 # Contacten van deze maand GET /api/fhir/Encounter?date=ge2024-11-01&date=le2024-11-30 # Alleen intakes GET /api/fhir/Encounter?type=intake ``` **Response (voorbeeld):** ```json { "resourceType": "Bundle", "type": "searchset", "total": 5, "entry": [ { "resource": { "resourceType": "Encounter", "id": "880e8400-...", "status": "finished", "class": { "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "AMB", "display": "Ambulatory (polikliniek)" }, "type": [ { "coding": [ { "code": "intake", "display": "Intakegesprek" } ] } ], "subject": { "reference": "Patient/550e8400-...", "display": "Jan de Vries" }, "participant": [ { "individual": { "reference": "Practitioner/770e8400-...", "display": "Dr. Sarah Bakker" } } ], "period": { "start": "2024-11-15T10:00:00Z", "end": "2024-11-15T11:00:00Z" }, "reasonCode": [ { "text": "Depressieve klachten" } ] } } ] } ``` --- #### POST /api/fhir/Encounter - Contact aanmaken **Doel:** Nieuw contactmoment registreren. **Gebruik (voorbeeld):** ```bash POST /api/fhir/Encounter Content-Type: application/fhir+json { "resourceType": "Encounter", "status": "planned", "class": { "code": "AMB" }, "type": [ { "coding": [ { "code": "behandeling", "display": "Behandelsessie" } ] } ], "subject": { "reference": "Patient/550e8400-..." }, "participant": [ { "individual": { "reference": "Practitioner/770e8400-..." } } ], "period": { "start": "2024-12-01T14:00:00Z" } } ``` --- #### PUT /api/fhir/Encounter/[id] - Contact bijwerken **Doel:** Status en gegevens van contactmoment bijwerken (bijv. van "planned" naar "finished"). --- ## Condition API **Status:** ⏳ **In Planning** (Epic 4 - Q1 2025) ### Geplande Endpoints #### GET /api/fhir/Condition - Diagnoses **Doel:** Ophalen van diagnoses per patiënt. **Query Parameters (gepland):** - `patient` - Filter op patiënt ID - `clinical-status` - Filter op status (active, remission, resolved) - `code` - Filter op DSM-5/ICD-10 code **Use Case:** ```bash # Alle diagnoses van patiënt GET /api/fhir/Condition?patient=550e8400-... # Alleen actieve diagnoses GET /api/fhir/Condition?patient=550e8400-...&clinical-status=active # Specifieke diagnose (F32.2) GET /api/fhir/Condition?code=F32.2 ``` **Response (voorbeeld):** ```json { "resourceType": "Bundle", "type": "searchset", "total": 2, "entry": [ { "resource": { "resourceType": "Condition", "id": "990e8400-...", "clinicalStatus": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/condition-clinical", "code": "active" } ] }, "verificationStatus": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", "code": "confirmed" } ] }, "category": [ { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/condition-category", "code": "encounter-diagnosis" } ] } ], "severity": { "coding": [ { "code": "24484000", "display": "Severe" } ] }, "code": { "coding": [ { "system": "http://hl7.org/fhir/sid/icd-10", "code": "F32.2", "display": "Depressieve episode, ernstig zonder psychotische kenmerken" } ] }, "subject": { "reference": "Patient/550e8400-...", "display": "Jan de Vries" }, "encounter": { "reference": "Encounter/880e8400-...", "display": "Intake 15-11-2024" }, "onsetDateTime": "2024-09-01", "recordedDate": "2024-11-15T10:30:00Z", "recorder": { "reference": "Practitioner/770e8400-...", "display": "Dr. Sarah Bakker" } } } ] } ``` --- #### POST /api/fhir/Condition - Diagnose toevoegen **Doel:** Nieuwe diagnose registreren met DSM-5/ICD-10 code. --- #### PUT /api/fhir/Condition/[id] - Diagnose bijwerken **Doel:** Status wijzigen (bijv. van "active" naar "remission"). --- ## Observation API **Status:** ⏳ **In Planning** (Epic 6 - Q1 2025) ### Geplande Endpoints #### GET /api/fhir/Observation - Metingen & ROM-scores **Doel:** Ophalen van observaties, ROM-metingen en risico-inschattingen. **Query Parameters (gepland):** - `patient` - Filter op patiënt ID - `category` - Type observatie (survey, risk-assessment, vital-signs) - `code` - LOINC code voor specifieke meting (bijv. PHQ-9) - `date` - Datum filter **Use Case:** ```bash # Alle ROM-metingen van patiënt GET /api/fhir/Observation?patient=550e8400-...&category=survey # PHQ-9 scores GET /api/fhir/Observation?patient=550e8400-...&code=44249-1 # Recente metingen (laatste 30 dagen) GET /api/fhir/Observation?patient=550e8400-...&date=ge2024-10-22 ``` **Response (voorbeeld - PHQ-9):** ```json { "resourceType": "Bundle", "type": "searchset", "total": 3, "entry": [ { "resource": { "resourceType": "Observation", "id": "aa0e8400-...", "status": "final", "category": [ { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "survey" } ] } ], "code": { "coding": [ { "system": "http://loinc.org", "code": "44249-1", "display": "PHQ-9 total score" } ] }, "subject": { "reference": "Patient/550e8400-...", "display": "Jan de Vries" }, "effectiveDateTime": "2024-11-15T10:45:00Z", "performer": [ { "reference": "Practitioner/770e8400-...", "display": "Dr. Sarah Bakker" } ], "valueQuantity": { "value": 18, "unit": "score", "system": "http://unitsofmeasure.org", "code": "{score}" }, "interpretation": [ { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", "code": "H", "display": "High" } ], "text": "Matig-ernstige depressie" } ] } } ] } ``` --- #### POST /api/fhir/Observation - Meting toevoegen **Doel:** Nieuwe ROM-score of observatie registreren. **Gebruik (voorbeeld - GAD-7):** ```json { "resourceType": "Observation", "status": "final", "category": [ { "coding": [ { "code": "survey" } ] } ], "code": { "coding": [ { "system": "http://loinc.org", "code": "69737-5", "display": "GAD-7 total score" } ] }, "subject": { "reference": "Patient/550e8400-..." }, "effectiveDateTime": "2024-11-21T14:00:00Z", "valueQuantity": { "value": 12, "unit": "score", "code": "{score}" }, "interpretation": [ { "text": "Matige angst" } ] } ``` --- ## CarePlan API **Status:** 🎯 **In Planning** (Epic 5 - Q1 2025) - **HOOFDDOEL** ### Geplande Endpoints #### GET /api/fhir/CarePlan - Behandelplannen **Doel:** Ophalen van behandelplannen met doelen en activiteiten. **Query Parameters (gepland):** - `patient` - Filter op patiënt ID - `status` - Filter op status (draft, active, completed) - `category` - Type behandelplan **Use Case:** ```bash # Alle behandelplannen van patiënt GET /api/fhir/CarePlan?patient=550e8400-... # Alleen actieve plannen GET /api/fhir/CarePlan?patient=550e8400-...&status=active ``` **Response (voorbeeld - volledig behandelplan):** ```json { "resourceType": "Bundle", "type": "searchset", "total": 1, "entry": [ { "resource": { "resourceType": "CarePlan", "id": "bb0e8400-...", "identifier": [ { "system": "urn:oid:2.16.840.1.113883.2.4.3.11.999.7.6", "value": "BP-2024-001" } ], "status": "active", "intent": "plan", "category": [ { "coding": [ { "code": "ggz-behandelplan", "display": "GGZ Behandelplan" } ] } ], "title": "Behandelplan Depressie", "description": "Cognitieve gedragstherapie voor ernstige depressieve episode", "subject": { "reference": "Patient/550e8400-...", "display": "Jan de Vries" }, "period": { "start": "2024-11-20", "end": "2025-05-20" }, "created": "2024-11-20T09:00:00Z", "author": { "reference": "Practitioner/770e8400-...", "display": "Dr. Sarah Bakker" }, "addresses": [ { "reference": "Condition/990e8400-...", "display": "F32.2 - Depressieve episode, ernstig" } ], "goal": [ { "description": { "text": "PHQ-9 score verlagen naar < 10 binnen 12 weken" }, "target": [ { "measure": { "coding": [ { "system": "http://loinc.org", "code": "44249-1" } ] }, "detailQuantity": { "value": 10, "comparator": "<", "unit": "score" }, "dueDate": "2025-02-12" } ] }, { "description": { "text": "Herstel dagelijks functioneren (werk/sociaal)" } } ], "activity": [ { "detail": { "code": { "text": "Individuele Cognitieve Gedragstherapie (CGT)" }, "status": "in-progress", "scheduledTiming": { "repeat": { "frequency": 1, "period": 1, "periodUnit": "wk" } }, "performer": [ { "reference": "Practitioner/770e8400-...", "display": "Dr. Sarah Bakker" } ], "description": "Wekelijkse CGT sessies, totaal 12 sessies" } }, { "detail": { "code": { "text": "ROM-meting PHQ-9" }, "status": "scheduled", "scheduledTiming": { "repeat": { "frequency": 1, "period": 4, "periodUnit": "wk" } }, "description": "Elke 4 weken PHQ-9 invullen" } } ] } } ] } ``` --- #### POST /api/fhir/CarePlan - Behandelplan aanmaken **Doel:** Nieuw behandelplan opstellen met doelen en interventies. **Gebruik (voorbeeld):** ```json { "resourceType": "CarePlan", "status": "active", "intent": "plan", "title": "Behandelplan Angststoornis", "subject": { "reference": "Patient/550e8400-..." }, "addresses": [ { "reference": "Condition/cc0e8400-...", "display": "F41.1 - Gegeneraliseerde angststoornis" } ], "goal": [ { "description": { "text": "GAD-7 score < 5 binnen 16 weken" }, "target": [ { "detailQuantity": { "value": 5, "comparator": "<" }, "dueDate": "2025-03-15" } ] } ], "activity": [ { "detail": { "code": { "text": "Exposure therapy" }, "status": "not-started", "scheduledTiming": { "repeat": { "frequency": 1, "period": 1, "periodUnit": "wk" } } } } ] } ``` --- #### PUT /api/fhir/CarePlan/[id] - Behandelplan bijwerken **Doel:** Status, doelen of activiteiten van behandelplan bijwerken. **Belangrijke use cases:** - Status wijzigen (draft → active → completed) - Nieuwe doelen toevoegen - Activiteiten bijwerken - Voortgang registreren --- ## API Documentatie & Testing **Status:** ⏳ **In Planning** (Epic 7 - Q1 2025) ### Swagger/OpenAPI Documentatie **Geplande features:** - Interactieve API documentatie op `/api/docs` - Try-it-out functionaliteit voor alle endpoints - Request/response voorbeelden - Schema validatie **Voorbeeld URL:** ``` https://jouw-domein.nl/api/docs ``` ### FHIR Validator **Doel:** Automatische validatie van alle FHIR requests/responses tegen FHIR R4 spec. **Implementatie (gepland):** - @hapi/fhir validator integratie - Strikte validatie mode (optioneel) - Duidelijke error messages bij validatiefouten --- ## Authenticatie & Autorisatie ### Bearer Token Authenticatie **Huidige implementatie:** - Supabase Auth sessies - RLS (Row Level Security) op database niveau - Behandelaren zien alleen eigen patiënten **Headers:** ``` Authorization: Bearer {supabase-session-token} Content-Type: application/fhir+json ``` ### Toekomstige uitbreiding **SMART-on-FHIR (gepland):** - OAuth2 authenticatie - Scopes voor granulaire toegangscontrole - Support voor externe apps (MedMIJ, Koppeltaal) **Scopes (voorbeeld):** - `patient/*.read` - Lezen van alle patiënt resources - `patient/Patient.read` - Alleen Patient lezen - `patient/CarePlan.write` - CarePlans aanmaken/wijzigen --- ## Error Handling ### FHIR OperationOutcome Alle errors worden geretourneerd als FHIR OperationOutcome resource: **400 Bad Request - Validatiefout:** ```json { "resourceType": "OperationOutcome", "issue": [ { "severity": "error", "code": "invalid", "diagnostics": "Missing required field: birthDate" } ] } ``` **404 Not Found - Resource niet gevonden:** ```json { "resourceType": "OperationOutcome", "issue": [ { "severity": "error", "code": "not-found", "diagnostics": "Patient with id 550e8400-... not found" } ] } ``` **500 Internal Server Error - Serverfout:** ```json { "resourceType": "OperationOutcome", "issue": [ { "severity": "error", "code": "exception", "diagnostics": "Database connection failed" } ] } ``` ### HTTP Status Codes | Code | Betekenis | Gebruik | |------|-----------|---------| | 200 | OK | Succesvolle GET/PUT | | 201 | Created | Succesvolle POST | | 400 | Bad Request | Validatiefout | | 401 | Unauthorized | Geen/ongeldige authenticatie | | 403 | Forbidden | Geen toegang tot resource | | 404 | Not Found | Resource bestaat niet | | 500 | Internal Server Error | Serverfout | --- ## Data-uitwisseling Scenario's ### Scenario 1: Behandelplan Delen **Use Case:** Een patiënt verhuist naar een andere GGZ-instelling. Het behandelplan moet worden gedeeld. **Workflow:** ```bash # Stap 1: Export behandelplan GET /api/fhir/CarePlan/bb0e8400-... → Volledige FHIR JSON response # Stap 2: Opslaan als bestand careplan-export.json # Stap 3: Import in andere instelling POST https://andere-instelling.nl/api/fhir/CarePlan Content-Type: application/fhir+json { "resourceType": "CarePlan", ... (volledige careplan data) } # Stap 4: Succes! 201 Created Location: /api/fhir/CarePlan/nieuwe-id ``` **Resultaat:** ✅ Behandelplan succesvol overgedragen tussen instellingen --- ### Scenario 2: MedMIJ Patiëntenportaal **Use Case (toekomst):** Patiënt opent PGO-app en vraagt toegang tot eigen dossier. **Workflow:** ```bash # Patiënt authoriseert app via OAuth2 # App vraagt toestemming voor: # - Lezen van diagnoses # - Lezen van behandelplan # - Lezen van ROM-scores # App haalt data op: GET /api/fhir/Condition?patient=[id] GET /api/fhir/CarePlan?patient=[id] GET /api/fhir/Observation?patient=[id]&category=survey # Patiënt ziet in app: # - Diagnose: F32.2 - Depressieve episode, ernstig # - Behandelplan: CGT 12 sessies # - ROM-scores: PHQ-9 timeline (18 → 14 → 10) ``` **Resultaat:** ✅ Patiënt heeft inzage in eigen dossier via standaard PGO-app --- ### Scenario 3: Koppeltaal eHealth App **Use Case (toekomst):** Behandelaar schrijft mindfulness app voor als onderdeel van behandelplan. **Workflow:** ```bash # Behandelaar maakt CarePlan met activity: POST /api/fhir/CarePlan { "activity": [ { "detail": { "code": { "text": "Mindfulness oefeningen via MindDistrict" }, "status": "scheduled", "scheduledTiming": { "repeat": { "frequency": 3, "period": 1, "periodUnit": "wk" } } } } ] } # Koppeltaal sync: # - Mini-EPD stuurt CarePlan activity naar Koppeltaal # - Koppeltaal activeert opdracht in MindDistrict app # - Patiënt ziet opdracht in app # - Voortgang komt terug naar Mini-EPD via Observation ``` **Resultaat:** ✅ Naadloze integratie tussen EPD en eHealth app --- ## Performance & Schaalbaarheid ### Optimalisaties **Database Indexes:** - Index op `patient_id` voor snelle patient queries - Index op `identifier` velden (BSN, BIG, AGB) - Index op `status` velden voor filtering **Paginering:** ```bash # Standaard: max 50 resultaten GET /api/fhir/Patient # Custom page size GET /api/fhir/Patient?_count=20 # Volgende pagina (geplande feature) GET /api/fhir/Patient?_count=20&_offset=20 ``` **Response Time Targets:** - GET single resource: < 100ms - GET search (50 results): < 500ms - POST/PUT: < 200ms --- ## Roadmap ### ✅ Fase 1: Patient & Practitioner (Voltooid - November 2024) - Patient API (GET/POST/PUT) - Practitioner API (GET/POST) - FHIR transforms - Basic error handling ### ⏳ Fase 2: Encounters & Conditions (Q1 2025) - Encounter API (GET/POST/PUT) - Condition API (GET/POST/PUT) - Timeline integratie ### 🎯 Fase 3: CarePlans (Q1 2025) - HOOFDDOEL - CarePlan API (GET/POST/PUT) - Goals embedded in JSONB - Activities embedded in JSONB - Voortgang monitoring ### ⏳ Fase 4: Observations (Q1 2025) - Observation API (GET/POST) - ROM-metingen (PHQ-9, GAD-7) - Risico-inschattingen ### 🔮 Fase 5: API Polish (Q1 2025) - Swagger/OpenAPI documentatie - FHIR validator integratie - Paginering - Advanced search ### 🔮 Fase 6: Integraties (Q2 2025) - MedMIJ aansluiting - Koppeltaal support - SMART-on-FHIR OAuth2 --- ## Voor Functioneel Beheerders ### Wat betekent dit voor jou? **Als behandelaar:** - Je hoeft niets van deze API te weten - UI abstracteert alle complexiteit - Gewoon werken met patiënten en behandelplannen **Als ICT-beheerder:** - API is volledig FHIR-compliant - Integraties zijn goed gedocumenteerd - Export/import is standaard **Als management:** - Geen vendor lock-in - Toekomstbestendige architectuur - Compatible met MedMIJ/Koppeltaal ### Veelgestelde Vragen **Q: Moet ik als behandelaar de API gebruiken?** A: Nee, de UI doet dit automatisch. De API is voor integraties met andere systemen. **Q: Kan ik data exporteren naar Excel?** A: Ja, via de API kun je FHIR JSON ophalen en omzetten naar CSV/Excel. **Q: Hoe veilig is de API?** A: Authenticatie via tokens, RLS policies, encryptie, audit logging. **Q: Werkt dit met ons huidige EPD?** A: Als het EPD FHIR ondersteunt, ja. Anders via export/import. --- ## Technische Referenties **FHIR Specificaties:** - FHIR R4: https://hl7.org/fhir/R4/ - RESTful API: https://hl7.org/fhir/R4/http.html - Search: https://hl7.org/fhir/R4/search.html **Project Documentatie:** - Transform library: `lib/fhir/transforms/` - API routes: `app/api/fhir/` - Bouwplan: `docs/bouwplan-pragmatisch-fhir.md` **Tools:** - FHIR Validator: https://validator.fhir.org/ - Postman FHIR Collection: https://www.postman.com/fhir --- **Laatst bijgewerkt:** 21 november 2024 **Versie:** 2.0.0 **Status:** In Progress - Patient & Practitioner API Actief