Files
2026-06-25 00:25:31 +08:00

80 lines
2.9 KiB
C#

using Microsoft.Extensions.Options;
public class MedicationCorrelationHelper
{
private readonly IMedicationService _medicationService;
private readonly MedicationCorrelationOptions _options;
public MedicationCorrelationHelper(
IMedicationService medicationService,
IOptions<MedicationCorrelationOptions> options)
{
_medicationService = medicationService;
_options = options.Value;
}
/// <summary>
/// Appends medication context to alert details if a correlated administration
/// exists within the lookback window. Returns the original details if none found.
/// </summary>
public async Task<string> TryAnnotateDetailsAsync(
Guid encounterId,
string observationCode,
string details,
CancellationToken ct = default)
{
var recent = await _medicationService.GetRecentForEncounterAsync(
encounterId, observationCode, _options.CorrelationWindowMinutes);
if (recent.Count == 0)
return details;
// Use the most recent correlated administration
var med = recent[0];
var minutesAgo = (int)(DateTimeOffset.UtcNow - med.AdministeredAt).TotalMinutes;
return $"{details} — note: {med.DrugName} {med.Dose}{med.DoseUnit} " +
$"({med.Route}) administered {minutesAgo} min ago";
}
public async Task<MedicationContext?> TryGetContextAsync(
Guid encounterId,
string observationCode,
CancellationToken ct = default)
{
var recent = await _medicationService.GetRecentForEncounterAsync(
encounterId, observationCode, _options.CorrelationWindowMinutes);
if (recent.Count == 0)
return null;
var med = recent[0];
return new MedicationContext
{
DrugName = med.DrugName,
Dose = $"{med.Dose}{med.DoseUnit}",
Route = med.Route,
AdministeredAt = med.AdministeredAt,
RelevanceNote = BuildRelevanceNote(med.DrugName, observationCode)
};
}
private string? BuildRelevanceNote(string drugName, string observationCode)
{
var drug = drugName.ToLowerInvariant();
return observationCode switch
{
"TEMP_C" when drug is "acetaminophen" or "ibuprofen"
=> "Antipyretic — may affect temperature trend",
"HEART_RATE" or "SYSTOLIC_BP" or "DIASTOLIC_BP"
when _options.DrugVitalMappings.TryGetValue(drug, out var codes)
&& codes.Contains(observationCode, StringComparer.OrdinalIgnoreCase)
=> "Cardiovascular agent — may affect blood pressure or heart rate",
"RESP_RATE" or "SPO2"
=> "Sedative/opioid — may affect respiratory parameters",
"GLUCOSE_MG_DL"
=> "Glucose management — may affect blood sugar",
_ => null
};
}
}