feature: Clinical Data Model Expansion & Observation Vocabulary

This commit is contained in:
voltsrage
2026-06-18 15:00:42 +08:00
parent 3b4c5c524b
commit 7d630fbbd9
33 changed files with 2636 additions and 36 deletions
@@ -32,7 +32,7 @@ public class EncounterService : IEncounterService
}
public async Task<EncounterStatusTransitionResult> TransitionStatusAsync(
Guid encounterId, EncounterStatus targetStatus)
Guid encounterId, EncounterStatus targetStatus, string? dischargeDiagnosis = null)
{
var encounter = await _db.Encounters
.Include(e => e.Patient)
@@ -50,7 +50,10 @@ public class EncounterService : IEncounterService
encounter.Status = targetStatus;
if (targetStatus == EncounterStatus.Discharged)
{
encounter.DischargedAt = DateTimeOffset.UtcNow;
encounter.DischargeDiagnosis = dischargeDiagnosis;
}
_db.OutboxEvents.Add(new OutboxEvent
{
@@ -66,6 +69,8 @@ public class EncounterService : IEncounterService
newStatus = targetStatus.ToDbString(),
department = encounter.Department.ToDbString(),
attendingPhysician = encounter.AttendingPhysician,
roomBed = encounter.RoomBed,
admissionReason = encounter.AdmissionReason,
admittedAt = encounter.AdmittedAt,
changedAt = DateTimeOffset.UtcNow
}),
@@ -1,6 +1,7 @@
public interface IEncounterService
{
Task<Encounter> GetByIdAsync(Guid id);
Task<EncounterStatusTransitionResult> TransitionStatusAsync(Guid encounterId, EncounterStatus targetStatus);
Task<EncounterStatusTransitionResult> TransitionStatusAsync(
Guid encounterId, EncounterStatus targetStatus, string? dischargeDiagnosis = null);
Task<object> GetTimelineAsync(Guid encounterId);
}
@@ -18,6 +18,10 @@ public class PatientService : IPatientService
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(patient);
@@ -84,6 +88,8 @@ public class PatientService : IPatientService
Status = EncounterStatus.Active,
Department = req.Department,
AttendingPhysician = req.AttendingPhysician,
RoomBed = req.RoomBed,
AdmissionReason = req.AdmissionReason,
AdmittedAt = DateTimeOffset.UtcNow,
CreatedAt = DateTimeOffset.UtcNow
};
@@ -103,6 +109,8 @@ public class PatientService : IPatientService
newStatus = encounter.Status.ToDbString(),
department = encounter.Department.ToDbString(),
attendingPhysician = encounter.AttendingPhysician,
roomBed = encounter.RoomBed,
admissionReason = encounter.AdmissionReason,
admittedAt = encounter.AdmittedAt,
changedAt = DateTimeOffset.UtcNow
}),
@@ -12,6 +12,11 @@ public static class PlausibilityValidator
["RESP_RATE"] = (1, 80),
["WBC_K_UL"] = (0.1m, 500),
["GLUCOSE_MG_DL"] = (10, 1500),
["SYSTOLIC_BP"] = (40, 300),
["DIASTOLIC_BP"] = (20, 200),
["LACTATE_MMOL_L"] = (0.1m, 30),
["AVPU"] = (0, 3),
["SUPPLEMENTAL_O2"] = (0, 1),
};
public static bool IsPlausible(string observationCode, decimal value, out string? reason)