feature: Ward Gateway Service (Local-First Clinical Path)

This commit is contained in:
voltsrage
2026-06-23 16:45:38 +08:00
parent d8e142fffe
commit 1bf8359097
100 changed files with 5474 additions and 4 deletions
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore;
public static class GatewayDbResetHelper
{
public static async Task ResetAsync(GatewayDbContext db)
{
for (var attempt = 0; ; attempt++)
{
try
{
await db.Database.ExecuteSqlRawAsync(@"
DELETE FROM buffered_sync_items;
DELETE FROM sync_outbox;
DELETE FROM clinical_alerts;
DELETE FROM observations;
DELETE FROM encounters;
DELETE FROM patients;
DELETE FROM alert_thresholds;
DELETE FROM gateway_sync_state;
");
return;
}
catch when (attempt < 5)
{
await Task.Delay(1000);
}
}
}
}
@@ -0,0 +1,69 @@
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Redis;
public static class GatewayTestSeeder
{
public static async Task<(Guid PatientId, Guid EncounterId)> SeedActiveEncounterAsync(
IServiceProvider services)
{
using var scope = services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<GatewayDbContext>();
await GatewayDbResetHelper.ResetAsync(db);
var now = DateTimeOffset.UtcNow;
var patient = new ReplicaPatient
{
Id = Guid.NewGuid(),
Mrn = "MRN-GW-001",
FirstName = "Gateway",
LastName = "Test",
DateOfBirth = new DateOnly(1970, 1, 1),
Gender = "F",
SyncedAt = now
};
var encounter = new ReplicaEncounter
{
Id = Guid.NewGuid(),
PatientId = patient.Id,
EncounterType = EncounterType.Inpatient,
Status = EncounterStatus.Active,
Department = Department.Icu,
AttendingPhysician = "Dr. Gateway",
RoomBed = "ICU-01",
AdmittedAt = now,
SyncedAt = now
};
db.Patients.Add(patient);
db.Encounters.Add(encounter);
db.AlertThresholds.Add(new ReplicaAlertThreshold
{
Id = Guid.NewGuid(),
ObservationCode = "HEART_RATE",
DisplayName = "Heart Rate",
Unit = "bpm",
CriticalLow = 30,
WarningLow = 50,
WarningHigh = 100,
CriticalHigh = 150,
SyncedAt = now
});
db.SyncState.Add(new GatewaySyncState
{
Id = Guid.NewGuid(),
InitialSyncCompleted = true,
LastEncounterSyncAt = now
});
await db.SaveChangesAsync();
var redis = scope.ServiceProvider.GetRequiredService<IConnectionMultiplexer>();
var cache = redis.GetDatabase();
await cache.StringSetAsync(
"threshold:HEART_RATE",
JsonSerializer.Serialize(new ThresholdCacheEntry(
"HEART_RATE", 30, 50, 100, 150)));
return (patient.Id, encounter.Id);
}
}