=== Summary: 675 files | 7 generated | 484 fresh | 4605 untracked | 4268 adopted | 355 marked | 466 validated-ok | 2+0 stale (sig+body) | 0 skipped | 0 failed | elapsed 11:08:11.442 (40091.44s) ===

This commit is contained in:
julian
2026-06-28 02:50:05 -07:00
parent a19fb90902
commit 586f02a2ca
654 changed files with 5260 additions and 0 deletions
@@ -18,6 +18,7 @@ namespace adas_core.Application.Customizations.HRYC;
/// Resp_Type, and Hour_Balance) from incoming raw observations and active configurations loaded from
/// <see cref="ApiSettings"/>.
/// </summary>
/// <!-- aidoc:v1 sig=1b16cfc -->
public class CalculatedObservations : ICalculatedObservations
{
private readonly IOptions<ApiSettings> _apiSettings;
@@ -42,6 +43,7 @@ public class CalculatedObservations : ICalculatedObservations
/// from <see cref="ApiSettings"/>.
/// </summary>
/// <param name="serviceProvider">The application's service provider used to resolve the required dependencies and configuration.</param>
/// <!-- aidoc:v1 sig=409f903 body=cf624d7 -->
public CalculatedObservations(IServiceProvider serviceProvider)
{
_observationService = serviceProvider.GetRequiredService<Lazy<IObservationService>>(); //observationService;
@@ -86,6 +88,8 @@ public class CalculatedObservations : ICalculatedObservations
/// A <see cref="Task{T}"/> that resolves to the (possibly transformed) observation,
/// or <see langword="null"/> when the input observation has no name.
/// </returns>
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Documentation claims the method returns null 'when the input observation has no name', but the method always returns the (possibly transformed) obs parameter; the code never returns null, so the null branch described in <returns> does not exist." -->
public async Task<T?> Map<T>(T obs, bool onlyByName) where T : BasePatientObservation
{
_logger.LogTrace("Mapping {name} observation {obs}", obs.Name, obs);
@@ -148,6 +152,7 @@ public class CalculatedObservations : ICalculatedObservations
/// <param name="treatment">The treatment to map.</param>
/// <returns>Never returns a result.</returns>
/// <exception cref="NotImplementedException">Always thrown because treatment mapping is not implemented in the HRYC customization.</exception>
/// <!-- aidoc:v1 sig=adce250 body=bfa6f2f -->
public Task<PatientTreatment> Map(PatientTreatment treatment)
{
throw new NotImplementedException();
@@ -161,6 +166,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="pumpObservation">The pump observation to map.</param>
/// <returns>A task containing the same <see cref="PumpObservation"/> instance that was passed in.</returns>
/// <!-- aidoc:v1 sig=50be4c1 body=e481734 -->
public async Task<PumpObservation> Map(PumpObservation pumpObservation)
{
return await Task.FromResult(pumpObservation);
@@ -174,6 +180,7 @@ public class CalculatedObservations : ICalculatedObservations
/// <param name="activeMedicines">The list of active medicines (ignored).</param>
/// <param name="patientId">The unique identifier of the patient (ignored).</param>
/// <returns>A completed task.</returns>
/// <!-- aidoc:v1 sig=b7a50a4 body=6805ef5 -->
public Task CalculateMedicineObservation(List<Medicine> activeMedicines, ObjectId patientId)
{
return Task.CompletedTask;
@@ -185,6 +192,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="patientId">The unique identifier of the patient (ignored).</param>
/// <returns>A completed task.</returns>
/// <!-- aidoc:v1 sig=7d38721 body=6805ef5 -->
public Task CalculateActiveBolus(ObjectId patientId)
{
return Task.CompletedTask;
@@ -196,6 +204,8 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="id">The unique identifier of the patient (ignored).</param>
/// <returns>A completed task containing an empty <see cref="IEnumerable{PatientTreatment}"/>.</returns>
/// <!-- aidoc-review:v1 severity=low kind=wrong_returns
/// "The cref references IEnumerable{PatientTreatment}, but the actual return type is IEnumerable{PatientTreatment?} (element type is nullable)." -->
public Task<IEnumerable<PatientTreatment?>> GetActiveTreatmentsByPatient(ObjectId id)
{
return Task.FromResult(new List<PatientTreatment?>().AsEnumerable());
@@ -207,6 +217,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="diagnosis">The <see cref="PatientDiagnosis"/> to map.</param>
/// <returns>A task containing the same <see cref="PatientDiagnosis"/> instance that was passed in.</returns>
/// <!-- aidoc:v1 sig=8ddf601 body=ad326e6 -->
public Task<PatientDiagnosis> Map(PatientDiagnosis diagnosis)
{
return Task.FromResult(diagnosis);
@@ -224,6 +235,8 @@ public class CalculatedObservations : ICalculatedObservations
/// A task that resolves to the (possibly time-shifted) <see cref="PatientObservation"/>.
/// Returns the input unchanged when its <c>Name</c> is null or empty, logging the error.
/// </returns>
/// <!-- aidoc-review:v1 severity=medium kind=wrong_summary
/// "Summary states the time is shifted 'when it arrives with the same (down-to-the-second) timestamp' as the latest observation, but the code actually shifts whenever the last observation's second-truncated time is greater than OR equal to the new observation's (DateTime.Compare >= 0), i.e., it also corrects cases where the new observation arrives earlier than the latest one." -->
public async Task<PatientObservation?> FixTimeInconsistencyWithLast(PatientObservation newObservation)
{
if (string.IsNullOrEmpty(newObservation.Name))
@@ -262,6 +275,7 @@ public class CalculatedObservations : ICalculatedObservations
/// A task that resolves to the resulting list of observations (with <c>Vent_Rate</c> removed
/// when it was inserted synchronously, or the original list otherwise).
/// </returns>
/// <!-- aidoc:v1 sig=e508c09 body=d3232c6 -->
public async Task<List<PatientObservation>> PreMapList(List<PatientObservation> listToInsert)
{
var ventRate = listToInsert.FirstOrDefault(obs => obs.Name == "MDC_VENT_RESP_RATE");
@@ -312,6 +326,7 @@ public class CalculatedObservations : ICalculatedObservations
/// <param name="obs">The patient observation that triggered the alarm.</param>
/// <param name="alarmToInsert">The alarm metadata to be inserted alongside the observation.</param>
/// <returns>A task containing the same <see cref="PatientObservation"/> instance that was passed in.</returns>
/// <!-- aidoc:v1 sig=405db8e body=ea790e4 -->
public Task<PatientObservation> MapSourceAlarm(PatientObservation obs, PatientObservationAlarm alarmToInsert)
{
return Task.FromResult(obs);
@@ -327,6 +342,7 @@ public class CalculatedObservations : ICalculatedObservations
/// <param name="code">The optional alarm code from <see cref="AlarmEnum.Name"/>.</param>
/// <returns>Never returns a result.</returns>
/// <exception cref="NotImplementedException">Always thrown because this overload is not used in the HRYC customization.</exception>
/// <!-- aidoc:v1 sig=90426a4 body=bfa6f2f -->
public Task SendAlarm(PatientObservation obs, string name, AlarmEnum.Name? code)
{
throw new NotImplementedException();
@@ -339,6 +355,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> whose <c>Name</c> is <c>NEWS</c>.</param>
/// <returns>A task that represents the asynchronous alarm evaluation.</returns>
/// <!-- aidoc:v1 sig=a2f90ec body=b1f8d11 -->
private async Task CalculateNews(BasePatientObservation obs)
{
var pobs = (PatientObservation)obs;
@@ -382,6 +399,8 @@ public class CalculatedObservations : ICalculatedObservations
/// <param name="obs">The base patient observation that triggered the alarm (used to derive <c>PatientId</c> and <c>Time</c>).</param>
/// <param name="name">The <see cref="AlarmEnum.Name"/> describing the alarm kind (for example, <c>NewsOff</c>, <c>NewsWarning</c>, <c>NewsAlert</c>).</param>
/// <returns>A task that represents the asynchronous alarm dispatch.</returns>
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Summary states 'The alarm observation is always persisted', but the method returns early without calling InsertObservation when configObs is null (and also when an exception is thrown), so persistence is not guaranteed." -->
private async Task SendAlarm(BasePatientObservation obs, AlarmEnum.Name name)
{
var pobs = (PatientObservation)obs;
@@ -444,6 +463,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="color">The beacon colour to apply.</param>
/// <param name="patient">The patient whose associated beacon should be updated.</param>
/// <!-- aidoc:v1 sig=aced090 body=6297307 -->
private void SendBeaconCode(AlarmEnum.BeaconColor color, Patient patient)
{
if (!patient.PointOfCareId.HasValue)
@@ -478,6 +498,8 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation (<c>SpO2</c>, <c>FiO2</c>, or <c>FR</c>).</param>
/// <returns>A task that represents the asynchronous calculation operation.</returns>
/// <!-- aidoc-review:v1 severity=low kind=stale_summary
/// "Documentation states observations must be 'within the last 10 minutes', but the code checks `o.Time.CompareTo(DateTime.UtcNow.AddMinutes(10)) <= 0` (10 minutes in the future), which is a much more permissive check that allows any past observation and does not enforce a 10-minute-ago cutoff." -->
private async Task CalculateIrox(BasePatientObservation obs)
{
try
@@ -560,6 +582,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation (<c>FR</c> or <c>Vent_Rate</c>).</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=0c7e3f7 body=e68f279 -->
private async Task CalculateRespRate(BasePatientObservation obs)
{
var pobs = (PatientObservation)obs;
@@ -627,6 +650,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Hydric_Balance</c>.</param>
/// <returns>A task that resolves to the (possibly time-shifted) base patient observation.</returns>
/// <!-- aidoc:v1 sig=443610d body=4a73250 -->
private async Task<BasePatientObservation> CalculateHydricBalance(BasePatientObservation obs)
{
var pobs = (PatientObservation)obs;
@@ -650,6 +674,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Hour_Balance</c>.</param>
/// <returns>A task that resolves to the (possibly time-shifted) base patient observation.</returns>
/// <!-- aidoc:v1 sig=23cf188 body=8e46c30 -->
private async Task<BasePatientObservation> CalculateHourBalance(BasePatientObservation obs)
{
var pobs = (PatientObservation)obs;
@@ -677,6 +702,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Hydric_Balance</c>.</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=721b70b body=271caec -->
private async Task CalculateHydricBalanceCalculated(BasePatientObservation obs)
{
//Hydric_Balance_Calculated
@@ -753,6 +779,8 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Resp_Mode</c>.</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc-review:v1 severity=low kind=stale_summary
/// "Summary references identifier 'InvasiveVentilation' (in <c> tags) but the actual field is '_codesForInvasiveVentilation'." -->
private async Task CalculateVentilationMode(BasePatientObservation obs)
{
_logger.LogDebug("CalculateVentilationMode {obs}", obs);
@@ -800,6 +828,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Weight_Current</c>.</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=cb420e5 body=6df7b22 -->
private async Task CalculateWeight_DiffObservation(BasePatientObservation obs)
{
var toSearchList = new List<string>();
@@ -839,6 +868,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation (<c>Diuresis</c> or <c>Weight_Current</c>).</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=c96d1b4 body=0dfe456 -->
private async Task CalculateDiureis_WeightObservation(BasePatientObservation obs)
{
var toSearchList = new List<string>();
@@ -891,6 +921,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>AllergiesObs</c> and a collection-valued <c>Value</c> of <see cref="PatientAllergiesValue"/>.</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=16bb26b body=661f911 -->
private async Task CalculateAllergiesObservation(BasePatientObservation obs)
{
try
@@ -967,6 +998,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>DrainagesObs</c> and a <see cref="PatientDrainagesValue"/>-typed <c>Value</c>.</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=2e0f71d body=98b8c9e -->
private async Task CalculateDrainagesObservation(BasePatientObservation obs)
{
var pobs = (PatientObservation)obs;
@@ -1013,6 +1045,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation (<c>PEEP</c> or <c>Pleateu_Pressure</c>).</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=fe22b05 body=bc944b3 -->
private async Task CalculateDelta_PressureObservation(BasePatientObservation obs)
{
var toSearchList = new List<string>();
@@ -1071,6 +1104,7 @@ public class CalculatedObservations : ICalculatedObservations
/// </summary>
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Daily_Balance</c>.</param>
/// <returns>A task that represents the asynchronous insert operation.</returns>
/// <!-- aidoc:v1 sig=e959764 body=2322c22 -->
private async Task CalculateDaily_BalanceObservation(BasePatientObservation obs)
{
if (obs.Time.ToLocalTime().Hour == 8)
@@ -1098,6 +1132,7 @@ public class CalculatedObservations : ICalculatedObservations
/// <see langword="true"/> when the observation has an <c>Expires</c> value and the current time
/// is past the expiration instant; otherwise, <see langword="false"/>.
/// </returns>
/// <!-- aidoc:v1 sig=c7c5c82 body=4c62b98 -->
private static bool CheckExpired(PatientObservation obs)
{
if (obs.Expires == null) return false;