VEU.WathBody/3-app/2-cli/Server.WatchBody.Core/Metrics/MetricsConfig.cs

59 lines
2.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text.Json;
namespace Server.WatchBody.Core.Metrics;
/// <summary>
/// Пороги красных флагов (секция Safety, Р3-А); умолчания — документ
/// метрик (п. 2.1–2.3, правила 1 и 6). 🛡 В расчётном коде пороги не
/// хардкодятся — только эти значения.
/// </summary>
public class MetricsConfig
{
public int BpCancelSys { get; set; } = 150;
public int BpCancelDias { get; set; } = 90;
public int BpElevatedSys { get; set; } = 140;
public int BpElevatedDias { get; set; } = 95;
public int HrRestingRise { get; set; } = 8;
public int HrRestingDays { get; set; } = 2;
public int WellbeingLow { get; set; } = 2;
public int WellbeingDays { get; set; } = 2;
public int LightDayCount { get; set; } = 3;
public int KneePainMin { get; set; } = 1;
public int KneeRepeatSessions { get; set; } = 2;
public int HrBaselineDays { get; set; } = 14;
public int HrBaselineMin { get; set; } = 3;
/// <summary>Чтение секции Safety (отсутствует/частичная — умолчания).</summary>
public static MetricsConfig Load(JsonElement root)
{
var config = new MetricsConfig();
if (!root.TryGetProperty("Safety", out var safety) || safety.ValueKind != JsonValueKind.Object)
return config;
foreach (var property in typeof(MetricsConfig).GetProperties())
{
var name = char.ToLowerInvariant(property.Name[0]) + property.Name[1..];
if (!safety.TryGetProperty(name, out var value)) continue;
if (value.ValueKind != JsonValueKind.Number || !value.TryGetInt32(out var number))
throw new InvalidOperationException($"Safety.{name}: ожидалось целое число");
property.SetValue(config, number);
}
return config;
}
/// <summary>Ошибки конфигурации (фатальны при старте).</summary>
public List<string> Validate()
{
var errors = new List<string>();
// по документу метрик коридоры АД перекрываются
// (отмена: >150/90; «только кардио»: 140–150/90–95), поэтому
// bpElevatedDias (95) может быть больше bpCancelDias (90)
if (BpElevatedSys > BpCancelSys) errors.Add("Safety: bpElevatedSys > bpCancelSys");
foreach (var property in typeof(MetricsConfig).GetProperties())
{
var name = char.ToLowerInvariant(property.Name[0]) + property.Name[1..];
if ((int)property.GetValue(this)! <= 0) errors.Add($"Safety: {name} <= 0");
}
return errors;
}
}