VEU.WathBody/3-app/2-cli/Server.WatchBody.Core/Programs/ProgressionConfig.cs

53 lines
2.9 KiB
C#
Raw Permalink 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.Programs;
/// <summary>
/// Пороги правил прогрессии/делоада/перерывов (секция Progression);
/// умолчания — requirements разд. 3 и Ф-14.1. 🛡 В расчётном коде
/// пороги не хардкодятся — только эти значения (Р3-А).
/// </summary>
public class ProgressionConfig
{
public decimal BaseStepKg { get; set; } = 2.5m;
public decimal IsoStepKg { get; set; } = 1.0m;
public int BackoffPercent { get; set; } = 5;
public int DeloadMaxWeeks { get; set; } = 6;
public int MissDaysForBreak { get; set; } = 4;
public decimal ReturnMinFactor { get; set; } = 0.6m;
public decimal ReturnMaxFactor { get; set; } = 0.9m;
/// <summary>Чтение секции Progression (отсутствует/частичная — умолчания).</summary>
public static ProgressionConfig Load(JsonElement root)
{
var config = new ProgressionConfig();
if (!root.TryGetProperty("Progression", out var section) || section.ValueKind != JsonValueKind.Object)
return config;
foreach (var property in typeof(ProgressionConfig).GetProperties())
{
var name = char.ToLowerInvariant(property.Name[0]) + property.Name[1..];
if (!section.TryGetProperty(name, out var value)) continue;
if (value.ValueKind != JsonValueKind.Number || !value.TryGetDecimal(out var number))
throw new InvalidOperationException($"Progression.{name}: ожидалось число");
property.SetValue(config, Convert.ChangeType(number, property.PropertyType));
}
return config;
}
/// <summary>Ошибки конфигурации (фатальны при старте).</summary>
public List<string> Validate()
{
var errors = new List<string>();
// IsoStepKg — коридор метрик «+0,5–1 кг» (О-3-А): 0.25–5
if (IsoStepKg < 0.25m || IsoStepKg > 5m) errors.Add("Progression: isoStepKg вне [0.25; 5]");
if (BaseStepKg < 0.5m || BaseStepKg > 10m) errors.Add("Progression: baseStepKg вне [0.5; 10]");
if (BackoffPercent < 1 || BackoffPercent > 20) errors.Add("Progression: backoffPercent вне [1; 20]");
if (DeloadMaxWeeks < 3 || DeloadMaxWeeks > 12) errors.Add("Progression: deloadMaxWeeks вне [3; 12]");
if (MissDaysForBreak < 2) errors.Add("Progression: missDaysForBreak < 2");
if (ReturnMinFactor < 0.3m || ReturnMinFactor > 0.9m) errors.Add("Progression: returnMinFactor вне [0.3; 0.9]");
if (ReturnMaxFactor <= 0.5m || ReturnMaxFactor > 1m) errors.Add("Progression: returnMaxFactor вне (0.5; 1]");
if (ReturnMinFactor > ReturnMaxFactor) errors.Add("Progression: returnMinFactor > returnMaxFactor");
return errors;
}
}