feature: Clinical Data Model Expansion & Observation Vocabulary
This commit is contained in:
@@ -39,6 +39,9 @@ public class EncounterConfiguration : IEntityTypeConfiguration<Encounter>
|
||||
v => v.ToDbString(),
|
||||
v => DepartmentExtensions.FromDbString(v))
|
||||
.IsRequired();
|
||||
builder.Property(e => e.RoomBed).HasColumnName("room_bed").HasMaxLength(20);
|
||||
builder.Property(e => e.AdmissionReason).HasColumnName("admission_reason").HasMaxLength(500);
|
||||
builder.Property(e => e.DischargeDiagnosis).HasColumnName("discharge_diagnosis").HasMaxLength(500);
|
||||
builder.Property(e => e.AttendingPhysician).HasColumnName("attending_physician").HasMaxLength(200).IsRequired();
|
||||
builder.Property(e => e.AdmittedAt).HasColumnName("admitted_at").HasDefaultValueSql("NOW()");
|
||||
builder.Property(e => e.DischargedAt).HasColumnName("discharged_at");
|
||||
|
||||
@@ -14,6 +14,13 @@ public class PatientConfiguration : IEntityTypeConfiguration<Patient>
|
||||
builder.Property(p => p.DateOfBirth).HasColumnName("date_of_birth");
|
||||
builder.Property(p => p.Gender).HasColumnName("gender").HasMaxLength(10).IsRequired();
|
||||
builder.Property(p => p.Status).HasColumnName("status").HasMaxLength(20).HasDefaultValue("active");
|
||||
builder.Property(p => p.BloodType).HasColumnName("blood_type").HasMaxLength(5)
|
||||
.HasConversion(
|
||||
v => v!.Value.ToDbString(),
|
||||
v => BloodTypeExtensions.FromDbString(v));
|
||||
builder.Property(p => p.Allergies).HasColumnName("allergies");
|
||||
builder.Property(p => p.EmergencyContactName).HasColumnName("emergency_contact_name").HasMaxLength(200);
|
||||
builder.Property(p => p.EmergencyContactPhone).HasColumnName("emergency_contact_phone").HasMaxLength(20);
|
||||
builder.Property(p => p.CreatedAt).HasColumnName("created_at").HasDefaultValueSql("NOW()");
|
||||
|
||||
// MRN uses exact-match unique index — MRN lookups are always equality checks,
|
||||
|
||||
@@ -13,12 +13,16 @@ public static class DataSeeder
|
||||
{
|
||||
Id = Guid.NewGuid(), Mrn = "MRN-000001", FirstName = "Jane", LastName = "Smith",
|
||||
DateOfBirth = new DateOnly(1975, 4, 12), Gender = "F",
|
||||
BloodType = BloodType.APositive, Allergies = "Penicillin",
|
||||
EmergencyContactName = "John Smith", EmergencyContactPhone = "555-0101",
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
};
|
||||
var patient2 = new Patient
|
||||
{
|
||||
Id = Guid.NewGuid(), Mrn = "MRN-000002", FirstName = "Robert", LastName = "Chen",
|
||||
DateOfBirth = new DateOnly(1962, 9, 3), Gender = "M",
|
||||
BloodType = BloodType.ONegative, Allergies = null,
|
||||
EmergencyContactName = "Linda Chen", EmergencyContactPhone = "555-0202",
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
};
|
||||
db.Patients.AddRange(patient1, patient2);
|
||||
@@ -28,14 +32,18 @@ public static class DataSeeder
|
||||
{
|
||||
Id = Guid.NewGuid(), PatientId = patient1.Id, EncounterType = EncounterType.Inpatient,
|
||||
Status = EncounterStatus.Active, Department = Department.Icu,
|
||||
AttendingPhysician = "Dr. Osei", AdmittedAt = DateTimeOffset.UtcNow.AddHours(-6),
|
||||
AttendingPhysician = "Dr. Osei",
|
||||
RoomBed = "ICU-4B", AdmissionReason = "Chest pain, rule out MI",
|
||||
AdmittedAt = DateTimeOffset.UtcNow.AddHours(-6),
|
||||
CreatedAt = DateTimeOffset.UtcNow.AddHours(-6)
|
||||
};
|
||||
var encounter2 = new Encounter
|
||||
{
|
||||
Id = Guid.NewGuid(), PatientId = patient2.Id, EncounterType = EncounterType.Inpatient,
|
||||
Status = EncounterStatus.Active, Department = Department.GeneralMedicine,
|
||||
AttendingPhysician = "Dr. Patel", AdmittedAt = DateTimeOffset.UtcNow.AddHours(-12),
|
||||
AttendingPhysician = "Dr. Patel",
|
||||
RoomBed = "GM-12A", AdmissionReason = "Pneumonia, fever for 3 days",
|
||||
AdmittedAt = DateTimeOffset.UtcNow.AddHours(-12),
|
||||
CreatedAt = DateTimeOffset.UtcNow.AddHours(-12)
|
||||
};
|
||||
db.Encounters.AddRange(encounter1, encounter2);
|
||||
@@ -76,7 +84,49 @@ public static class DataSeeder
|
||||
DisplayName = "White Blood Cell Count", Unit = "k/µL",
|
||||
CriticalLow = 2.0m, WarningLow = 4.0m, WarningHigh = 12.0m, CriticalHigh = 20.0m,
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
}
|
||||
},
|
||||
new AlertThreshold
|
||||
{
|
||||
Id = Guid.NewGuid(), ObservationCode = "SYSTOLIC_BP",
|
||||
DisplayName = "Systolic Blood Pressure", Unit = "mmHg",
|
||||
CriticalLow = 70m, WarningLow = 90m, WarningHigh = 160m, CriticalHigh = 180m,
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
},
|
||||
new AlertThreshold
|
||||
{
|
||||
Id = Guid.NewGuid(), ObservationCode = "DIASTOLIC_BP",
|
||||
DisplayName = "Diastolic Blood Pressure", Unit = "mmHg",
|
||||
CriticalLow = 40m, WarningLow = 60m, WarningHigh = 90m, CriticalHigh = 110m,
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
},
|
||||
new AlertThreshold
|
||||
{
|
||||
Id = Guid.NewGuid(), ObservationCode = "LACTATE_MMOL_L",
|
||||
DisplayName = "Serum Lactate", Unit = "mmol/L",
|
||||
CriticalLow = null, WarningLow = null, WarningHigh = 2.0m, CriticalHigh = 4.0m,
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
},
|
||||
new AlertThreshold
|
||||
{
|
||||
Id = Guid.NewGuid(), ObservationCode = "AVPU",
|
||||
DisplayName = "AVPU Consciousness Level", Unit = "score",
|
||||
CriticalLow = null, WarningLow = null, WarningHigh = null, CriticalHigh = 2m,
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
},
|
||||
new AlertThreshold
|
||||
{
|
||||
Id = Guid.NewGuid(), ObservationCode = "SUPPLEMENTAL_O2",
|
||||
DisplayName = "Supplemental Oxygen", Unit = "flag",
|
||||
CriticalLow = null, WarningLow = null, WarningHigh = null, CriticalHigh = null,
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
},
|
||||
new AlertThreshold
|
||||
{
|
||||
Id = Guid.NewGuid(), ObservationCode = "GLUCOSE_MG_DL",
|
||||
DisplayName = "Blood Glucose", Unit = "mg/dL",
|
||||
CriticalLow = 40m, WarningLow = 70m, WarningHigh = 180m, CriticalHigh = 400m,
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
},
|
||||
};
|
||||
db.AlertThresholds.AddRange(thresholds);
|
||||
|
||||
@@ -98,7 +148,25 @@ public static class DataSeeder
|
||||
Value = 97, Unit = "%", Source = ObservationSource.Device, RecordedAt = now.AddMinutes(-5), CreatedAt = now.AddMinutes(-5) },
|
||||
// Normal temp for encounter2
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter2.Id, ObservationCode = "TEMP_C",
|
||||
Value = 37.1m, Unit = "°C", Source = ObservationSource.Manual, RecordedAt = now.AddMinutes(-20), CreatedAt = now.AddMinutes(-20) }
|
||||
Value = 37.1m, Unit = "°C", Source = ObservationSource.Manual, RecordedAt = now.AddMinutes(-20), CreatedAt = now.AddMinutes(-20) },
|
||||
// Blood pressure
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter1.Id, ObservationCode = "SYSTOLIC_BP",
|
||||
Value = 128, Unit = "mmHg", Source = ObservationSource.Device, RecordedAt = now.AddMinutes(-25), CreatedAt = now.AddMinutes(-25) },
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter1.Id, ObservationCode = "DIASTOLIC_BP",
|
||||
Value = 82, Unit = "mmHg", Source = ObservationSource.Device, RecordedAt = now.AddMinutes(-25), CreatedAt = now.AddMinutes(-25) },
|
||||
// Normal lactate
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter1.Id, ObservationCode = "LACTATE_MMOL_L",
|
||||
Value = 1.2m, Unit = "mmol/L", Source = ObservationSource.Lab, RecordedAt = now.AddMinutes(-8), CreatedAt = now.AddMinutes(-8) },
|
||||
// AVPU = Alert (normal consciousness)
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter1.Id, ObservationCode = "AVPU",
|
||||
Value = 0, Unit = "score", Source = ObservationSource.Manual, RecordedAt = now.AddMinutes(-28), CreatedAt = now.AddMinutes(-28) },
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter2.Id, ObservationCode = "AVPU",
|
||||
Value = 0, Unit = "score", Source = ObservationSource.Manual, RecordedAt = now.AddMinutes(-18), CreatedAt = now.AddMinutes(-18) },
|
||||
// Room air (no supplemental oxygen)
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter1.Id, ObservationCode = "SUPPLEMENTAL_O2",
|
||||
Value = 0, Unit = "flag", Source = ObservationSource.Manual, RecordedAt = now.AddMinutes(-27), CreatedAt = now.AddMinutes(-27) },
|
||||
new() { Id = Guid.NewGuid(), EncounterId = encounter2.Id, ObservationCode = "SUPPLEMENTAL_O2",
|
||||
Value = 1, Unit = "flag", Source = ObservationSource.Manual, RecordedAt = now.AddMinutes(-17), CreatedAt = now.AddMinutes(-17) },
|
||||
};
|
||||
db.Observations.AddRange(observations);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user