feature: FHIR R4 Inbound Facade

This commit is contained in:
voltsrage
2026-06-21 13:53:38 +08:00
parent 9f96f54007
commit a43db52813
42 changed files with 2873 additions and 3 deletions
@@ -4,8 +4,13 @@ using Microsoft.EntityFrameworkCore;
public class PatientService : IPatientService
{
private readonly AppDbContext _db;
private readonly IExternalIdentifierService _identifiers;
public PatientService(AppDbContext db) => _db = db;
public PatientService(AppDbContext db, IExternalIdentifierService identifiers)
{
_db = db;
_identifiers = identifiers;
}
public async Task<Patient> RegisterAsync(RegisterPatientRequest req)
{
@@ -122,6 +127,61 @@ public class PatientService : IPatientService
return encounter;
}
public async Task<Patient> RegisterOrUpdateByIdentifierAsync(FhirPatientUpsertRequest req)
{
var existingId = await _identifiers.ResolveInternalIdAsync(
ExternalResourceType.Patient, req.IdentifierSystem, req.IdentifierValue);
if (existingId.HasValue)
{
var patient = await _db.Patients.FindAsync(existingId.Value)
?? throw new NotFoundException("Patient not found.", "PATIENT_NOT_FOUND");
patient.FirstName = req.FirstName;
patient.LastName = req.LastName;
patient.DateOfBirth = req.DateOfBirth;
patient.Gender = req.Gender;
patient.BloodType = req.BloodType;
patient.Allergies = req.Allergies;
patient.EmergencyContactName = req.EmergencyContactName;
patient.EmergencyContactPhone = req.EmergencyContactPhone;
await _db.SaveChangesAsync();
return patient;
}
// Use hospital identifier value as MRN when it fits the column constraint (max 20 chars).
var mrn = req.IdentifierValue.Length <= 20
? req.IdentifierValue
: await GenerateMrnAsync();
var newPatient = new Patient
{
Id = Guid.NewGuid(),
Mrn = mrn,
FirstName = req.FirstName,
LastName = req.LastName,
DateOfBirth = req.DateOfBirth,
Gender = req.Gender,
BloodType = req.BloodType,
Allergies = req.Allergies,
EmergencyContactName = req.EmergencyContactName,
EmergencyContactPhone = req.EmergencyContactPhone,
CreatedAt = DateTimeOffset.UtcNow
};
_db.Patients.Add(newPatient);
await _db.SaveChangesAsync();
await _identifiers.LinkAsync(
ExternalResourceType.Patient,
newPatient.Id,
req.IdentifierSystem,
req.IdentifierValue);
return newPatient;
}
private async Task<string> GenerateMrnAsync()
{
var count = await _db.Patients.CountAsync();