feature: Sepsis Engine Refactor: Remove SIRS, Rewire qSOFA + Bundle

Frontend: GCS Entry, SOFA Display, Sepsis UI Refactor
This commit is contained in:
voltsrage
2026-06-21 03:56:27 +08:00
parent 93ea473d2b
commit bf46e6554a
48 changed files with 2686 additions and 714 deletions
@@ -34,13 +34,10 @@ public class SepsisEngineService : BackgroundService
};
using var consumer = new ConsumerBuilder<string, string>(config).Build();
// Subscribes to observation.recorded only.
// The es-indexer consumes all three topics; the sepsis engine only needs one.
// Subscribing to a superset of needed topics would waste CPU deserializing
// alert and encounter events that this engine discards immediately.
consumer.Subscribe(_kafkaOptions.Topics.ObservationRecorded);
_logger.LogInformation("SepsisEngineService started — consumer group: sepsis-engine");
_logger.LogInformation(
"SepsisEngineService started — consumer group: sepsis-engine (qSOFA screening only)");
try
{
@@ -54,19 +51,9 @@ public class SepsisEngineService : BackgroundService
var evt = JsonSerializer.Deserialize<SepsisObservationEvent>(
result.Message.Value, EventJsonOptions)!;
// Create a scope per message — both detectors are scoped and
// each owns a fresh DbContext when creating alerts.
using var scope = _services.CreateScope();
var sirsDetector = scope.ServiceProvider.GetRequiredService<SirsDetector>();
var qsofaDetector = scope.ServiceProvider.GetRequiredService<QsofaDetector>();
var sirsOutcome = await sirsDetector.ProcessObservationAsync(
evt.EncounterId,
evt.PatientId,
evt.ObservationCode,
evt.Value,
stoppingToken);
var qsofaOutcome = await qsofaDetector.ProcessObservationAsync(
evt.EncounterId,
evt.PatientId,
@@ -74,19 +61,12 @@ public class SepsisEngineService : BackgroundService
evt.Value,
stoppingToken);
if (sirsOutcome.Outcome == SirsOutcome.AlertCreated)
_logger.LogWarning(
"SEPSIS_WARNING created via SepsisEngine " +
"— encounter={EncounterId} code={Code} value={Value}",
evt.EncounterId, evt.ObservationCode, evt.Value);
if (qsofaOutcome.Outcome == QsofaOutcome.AlertCreated)
_logger.LogWarning(
"QSOFA_WARNING created via SepsisEngine " +
_logger.LogInformation(
"QSOFA_SCREEN created via SepsisEngine " +
"— encounter={EncounterId} code={Code} value={Value}",
evt.EncounterId, evt.ObservationCode, evt.Value);
// Commit only after successful processing.
consumer.Commit(result);
}
catch (OperationCanceledException)
@@ -98,8 +78,6 @@ public class SepsisEngineService : BackgroundService
_logger.LogError(ex,
"SepsisEngine failed on topic={Topic} offset={Offset} — not committing",
result?.Topic, result?.Offset.Value);
// Back off before retrying so a persistent failure (e.g., Redis down)
// does not spin the loop at maximum throughput.
await Task.Delay(2000, stoppingToken);
}
}