feature: HL7 FHIR R4 Integration
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
[ApiController]
|
||||
[Route("fhir/Encounter")]
|
||||
[Produces("application/fhir+json")]
|
||||
[Authorize]
|
||||
public class FhirEncounterController : ControllerBase
|
||||
{
|
||||
private readonly IFhirService _fhir;
|
||||
|
||||
public FhirEncounterController(IFhirService fhir) => _fhir = fhir;
|
||||
|
||||
/// <summary>
|
||||
/// FHIR read: GET /fhir/Encounter/{id}
|
||||
/// </summary>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> Read(string id)
|
||||
{
|
||||
var encounter = await _fhir.GetEncounterAsync(Guid.Parse(id));
|
||||
if (encounter is null)
|
||||
return NotFound(FhirErrorHelper.NotFound("Encounter", id));
|
||||
|
||||
return Ok(encounter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FHIR search: GET /fhir/Encounter?patient=X&status=Y&date=Z
|
||||
/// Supports search by patient reference, status, and date range.
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Search(
|
||||
[FromQuery] string? patient,
|
||||
[FromQuery] string? status,
|
||||
[FromQuery] string? date,
|
||||
[FromQuery(Name = "_count")] int count = 20,
|
||||
[FromQuery(Name = "_offset")] int offset = 0)
|
||||
{
|
||||
var bundle = await _fhir.SearchEncountersAsync(patient, status, date, count, offset);
|
||||
return Ok(bundle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Hl7.Fhir.Model;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
[ApiController]
|
||||
[Route("fhir")]
|
||||
[Produces("application/fhir+json")]
|
||||
public class FhirMetadataController : ControllerBase
|
||||
{
|
||||
private readonly IFhirService _fhir;
|
||||
|
||||
public FhirMetadataController(IFhirService fhir) => _fhir = fhir;
|
||||
|
||||
/// <summary>
|
||||
/// FHIR metadata: GET /fhir/metadata
|
||||
/// Returns the server's CapabilityStatement describing supported
|
||||
/// resources, interactions, and search parameters.
|
||||
/// No authentication required (FHIR spec requirement).
|
||||
/// </summary>
|
||||
[HttpGet("metadata")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(typeof(CapabilityStatement), StatusCodes.Status200OK)]
|
||||
public IActionResult GetMetadata()
|
||||
{
|
||||
return Ok(_fhir.GetCapabilityStatement());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
[ApiController]
|
||||
[Route("fhir/Observation")]
|
||||
[Produces("application/fhir+json")]
|
||||
[Authorize]
|
||||
public class FhirObservationController : ControllerBase
|
||||
{
|
||||
private readonly IFhirService _fhir;
|
||||
|
||||
public FhirObservationController(IFhirService fhir) => _fhir = fhir;
|
||||
|
||||
/// <summary>
|
||||
/// FHIR read: GET /fhir/Observation/{id}
|
||||
/// </summary>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> Read(string id)
|
||||
{
|
||||
var observation = await _fhir.GetObservationAsync(Guid.Parse(id));
|
||||
if (observation is null)
|
||||
return NotFound(FhirErrorHelper.NotFound("Observation", id));
|
||||
|
||||
return Ok(observation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FHIR search: GET /fhir/Observation?patient=X&code=Y&date=Z&category=W
|
||||
/// Supports search by patient reference, LOINC code, date range, and category.
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Search(
|
||||
[FromQuery] string? patient,
|
||||
[FromQuery] string? code,
|
||||
[FromQuery] string? date,
|
||||
[FromQuery] string? category,
|
||||
[FromQuery] string? encounter,
|
||||
[FromQuery(Name = "_count")] int count = 50,
|
||||
[FromQuery(Name = "_offset")] int offset = 0)
|
||||
{
|
||||
var bundle = await _fhir.SearchObservationsAsync(
|
||||
patient, code, date, category, encounter, count, offset);
|
||||
return Ok(bundle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Hl7.Fhir.Model;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
[ApiController]
|
||||
[Route("fhir/Patient")]
|
||||
[Produces("application/fhir+json")]
|
||||
[Authorize]
|
||||
public class FhirPatientController : ControllerBase
|
||||
{
|
||||
private readonly IFhirService _fhir;
|
||||
|
||||
public FhirPatientController(IFhirService fhir) => _fhir = fhir;
|
||||
|
||||
/// <summary>
|
||||
/// FHIR read: GET /fhir/Patient/{id}
|
||||
/// Returns a single Patient resource by logical ID.
|
||||
/// </summary>
|
||||
[HttpGet("{id}")]
|
||||
[ProducesResponseType(typeof(Hl7.Fhir.Model.Patient), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(Hl7.Fhir.Model.OperationOutcome), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> Read(string id)
|
||||
{
|
||||
var patient = await _fhir.GetPatientAsync(Guid.Parse(id));
|
||||
if (patient is null)
|
||||
return NotFound(FhirErrorHelper.NotFound("Patient", id));
|
||||
|
||||
return Ok(patient);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FHIR search: GET /fhir/Patient?name=X&birthdate=Y&identifier=Z
|
||||
/// Supports search by name (contains), birthdate (exact), and MRN identifier.
|
||||
/// Returns a FHIR Bundle of type searchset.
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(Hl7.Fhir.Model.Bundle), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Search(
|
||||
[FromQuery] string? name,
|
||||
[FromQuery] string? birthdate,
|
||||
[FromQuery] string? identifier,
|
||||
[FromQuery(Name = "_count")] int count = 20,
|
||||
[FromQuery(Name = "_offset")] int offset = 0)
|
||||
{
|
||||
var bundle = await _fhir.SearchPatientsAsync(name, birthdate, identifier, count, offset);
|
||||
return Ok(bundle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FHIR $everything: GET /fhir/Patient/{id}/$everything
|
||||
/// Returns a Bundle containing the Patient resource, all Encounters,
|
||||
/// and all Observations for the patient.
|
||||
/// </summary>
|
||||
[HttpGet("{id}/$everything")]
|
||||
[ProducesResponseType(typeof(Bundle), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(OperationOutcome), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> Everything(string id)
|
||||
{
|
||||
var bundle = await _fhir.GetPatientEverythingAsync(Guid.Parse(id));
|
||||
if (bundle is null)
|
||||
return NotFound(FhirErrorHelper.NotFound("Patient", id));
|
||||
|
||||
return Ok(bundle);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user