fix errors of Degraded Operations Visibility
This commit is contained in:
@@ -27,7 +27,93 @@ public static class ScenarioReplayHelper
|
||||
public static async Task<(Guid PatientId, Guid EncounterId)> ReplayObservationsAsync(
|
||||
HttpClient client,
|
||||
ScenarioFile scenario,
|
||||
IServiceProvider services,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var result = await ReplayObservationsCoreAsync(client, scenario, ct);
|
||||
await WaitForOutboxDrainAsync(services, TimeSpan.FromSeconds(30), ct);
|
||||
await RunClinicalEnginesForEncounterAsync(services, result.EncounterId, ct);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replays persisted observations through the clinical detectors in encounter order.
|
||||
/// Scenario E2E tests use this after HTTP ingest so assertions do not depend on
|
||||
/// shared Kafka consumer lag across the integration suite.
|
||||
/// </summary>
|
||||
public static async Task RunClinicalEnginesForEncounterAsync(
|
||||
IServiceProvider services,
|
||||
Guid encounterId,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
using var scope = services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
|
||||
var encounter = await db.Encounters
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(e => e.Id == encounterId, ct)
|
||||
?? throw new InvalidOperationException($"Encounter {encounterId} not found");
|
||||
|
||||
var observations = await db.Observations
|
||||
.AsNoTracking()
|
||||
.Where(o => o.EncounterId == encounterId)
|
||||
.OrderBy(o => o.RecordedAt)
|
||||
.ThenBy(o => o.CreatedAt)
|
||||
.ToListAsync(ct);
|
||||
|
||||
var qsofa = scope.ServiceProvider.GetRequiredService<QsofaDetector>();
|
||||
var gcs = scope.ServiceProvider.GetRequiredService<GcsDetector>();
|
||||
var sofa = scope.ServiceProvider.GetRequiredService<SofaDetector>();
|
||||
|
||||
foreach (var obs in observations)
|
||||
{
|
||||
await qsofa.ProcessObservationAsync(
|
||||
encounterId, encounter.PatientId, obs.ObservationCode, obs.Value, ct);
|
||||
|
||||
var gcsResult = await gcs.ProcessObservationAsync(
|
||||
encounterId, encounter.PatientId, obs.ObservationCode, obs.Value, ct);
|
||||
if (gcsResult.Outcome == GcsOutcome.ScoreComputed)
|
||||
{
|
||||
await sofa.ProcessGcsScoredAsync(
|
||||
encounterId, encounter.PatientId, ct);
|
||||
}
|
||||
|
||||
await sofa.ProcessObservationAsync(
|
||||
encounterId,
|
||||
encounter.PatientId,
|
||||
obs.ObservationCode,
|
||||
obs.Value,
|
||||
obs.RecordedAt,
|
||||
ct);
|
||||
}
|
||||
|
||||
await qsofa.SyncAlteredMentationAsync(encounterId, encounter.PatientId, ct);
|
||||
}
|
||||
|
||||
public static async Task WaitForOutboxDrainAsync(
|
||||
IServiceProvider services,
|
||||
TimeSpan timeout,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var deadline = DateTime.UtcNow + timeout;
|
||||
while (DateTime.UtcNow < deadline)
|
||||
{
|
||||
using var scope = services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
var pending = await db.OutboxEvents.CountAsync(
|
||||
e => e.ProcessedAt == null && e.FailedAt == null, ct);
|
||||
if (pending == 0)
|
||||
return;
|
||||
await Task.Delay(250, ct);
|
||||
}
|
||||
|
||||
throw new TimeoutException("Timed out waiting for outbox relay to drain pending events");
|
||||
}
|
||||
|
||||
private static async Task<(Guid PatientId, Guid EncounterId)> ReplayObservationsCoreAsync(
|
||||
HttpClient client,
|
||||
ScenarioFile scenario,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var patientResp = await client.PostAsJsonAsync("/api/v1/patients", new
|
||||
{
|
||||
@@ -153,4 +239,4 @@ public static class ScenarioReplayHelper
|
||||
private record ApiEnvelope<T>(T Data);
|
||||
private record PatientDto(Guid Id);
|
||||
private record EncounterDto(Guid Id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user