use axum::extract::{FromRef, Path, Query, State}; use axum::response::IntoResponse; use axum::Json; use serde::Deserialize; use uuid::Uuid; use crate::state::HealthState; /// GET /fhir/R4/metadata — FHIR CapabilityStatement pub async fn capability_statement() -> Result where HealthState: FromRef, S: Clone + Send + Sync + 'static, { let stmt = serde_json::json!({ "resourceType": "CapabilityStatement", "status": "active", "date": chrono::Utc::now().format("%Y-%m-%d").to_string(), "kind": "instance", "fhirVersion": "4.0.1", "format": ["application/fhir+json"], "rest": [{ "mode": "server", "resource": [ { "type": "Patient", "interaction": [{"code": "read"}, {"code": "search-type"}], "operation": [{"name": "everything"}] }, { "type": "Observation", "interaction": [{"code": "read"}, {"code": "search-type"}], "operation": [{"name": "lastn"}] }, { "type": "Device", "interaction": [{"code": "read"}, {"code": "search-type"}] }, { "type": "DiagnosticReport", "interaction": [{"code": "read"}, {"code": "search-type"}] }, { "type": "Encounter", "interaction": [{"code": "read"}, {"code": "search-type"}] }, { "type": "Practitioner", "interaction": [{"code": "read"}, {"code": "search-type"}] }, { "type": "Appointment", "interaction": [{"code": "read"}, {"code": "search-type"}] }, { "type": "Task", "interaction": [{"code": "read"}, {"code": "search-type"}] }, ], "operation": [ { "name": "everything", "definition": "/fhir/R4/Patient/{id}/$everything" }, { "name": "lastn", "definition": "/fhir/R4/Observation/$lastn" }, ] }] }); Ok(Json(stmt)) } #[derive(Debug, Deserialize)] pub struct SearchParams { pub patient: Option, pub category: Option, #[serde(rename = "_count")] pub count: Option, #[serde(rename = "_offset")] pub offset: Option, } // ── Patient ──────────────────────────────────────────────────────────── pub async fn search_patients( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn get_patient( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "OperationOutcome", "issue": [{"severity": "information", "code": "not-found", "diagnostics": "Patient not implemented yet"}] }))) } pub async fn patient_everything( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } // ── Observation ──────────────────────────────────────────────────────── pub async fn search_observations( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn observation_lastn( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } // ── Device ───────────────────────────────────────────────────────────── pub async fn search_devices( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn get_device( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "OperationOutcome", "issue": [{"severity": "information", "code": "not-found", "diagnostics": "Device not implemented yet"}] }))) } // ── Practitioner ─────────────────────────────────────────────────────── pub async fn search_practitioners( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn get_practitioner( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "OperationOutcome", "issue": [{"severity": "information", "code": "not-found", "diagnostics": "Practitioner not implemented yet"}] }))) } // ── Appointment ──────────────────────────────────────────────────────── pub async fn search_appointments( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn get_appointment( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "OperationOutcome", "issue": [{"severity": "information", "code": "not-found", "diagnostics": "Appointment not implemented yet"}] }))) } // ── DiagnosticReport ─────────────────────────────────────────────────── pub async fn search_diagnostic_reports( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn get_diagnostic_report( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "OperationOutcome", "issue": [{"severity": "information", "code": "not-found", "diagnostics": "DiagnosticReport not implemented yet"}] }))) } // ── Encounter ────────────────────────────────────────────────────────── pub async fn search_encounters( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn get_encounter( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "OperationOutcome", "issue": [{"severity": "information", "code": "not-found", "diagnostics": "Encounter not implemented yet"}] }))) } // ── Task ─────────────────────────────────────────────────────────────── pub async fn search_tasks( State(_state): State, Query(_params): Query, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "Bundle", "type": "searchset", "total": 0, "entry": [] }))) } pub async fn get_task( State(_state): State, Path(_id): Path, ) -> Result { Ok(Json(serde_json::json!({ "resourceType": "OperationOutcome", "issue": [{"severity": "information", "code": "not-found", "diagnostics": "Task not implemented yet"}] }))) }