namespace Admin.NET.Plugin.AiDOP.Service.S8;
///
/// S8-RULE-GOVERNANCE-BATCH1:监控规则**运行参数**的部分更新载荷。
///
/// PATCH 语义(G1 的直接修复):每个字段都是可空的,
/// null / 未提供 = 保持原值。旧的 S8WatchRuleParamsPayload 用的是
/// "整块覆盖 + 缺字段即置 NULL",于是一次 {"enabled":false} 就把 params_json 抹成 NULL,
/// 规则的全部业务配置随之消失(本地 Rule 01 已实测发生:13:34 还在正常命中,
/// 13:40 一次关开关之后 params_json = NULL)。
/// 这里绝不再依赖"前端每次把整块数据带回来"这种客户端自觉。
///
/// 本批不支持"清空"语义:两个部门兜底字段传 null 表示"不改",
/// 而不是"清空"。要清空需要能区分「没传」与「显式传 null」,
/// 而 MVC 这里走的是 Newtonsoft 管线,可靠地做出这个区分需要额外的 Optional 包装 +
/// 自定义转换器。本批不引入 —— 清空能力没有当前需求,为它加一层反序列化魔法
/// 反而制造新的静默失败面。缺口已登记,需要时单独做。
///
/// Definition 字段一律拒绝,而不是忽略:见 。
/// 静默忽略会让调用方以为改成功了 —— 那是比报错更糟的失败形态。
///
public sealed class S8RuleParametersPayload
{
// ───────────────── 白名单:真正的运行策略 ─────────────────
/// 轮询间隔(秒)。取值域由该规则的 Definition 声明。
public int? PollIntervalSeconds { get; set; }
/// 连续命中 N 次才建单。
public int? TriggerCountRequired { get; set; }
/// 连续未命中 N 次才标 recovered。
public int? RecoverCountRequired { get; set; }
/// 宽限分钟。
public int? GraceMinutes { get; set; }
/// 严重度。必须在 Definition 的 AllowedSeverities 内。
public string? Severity { get; set; }
/// 发生部门兜底。
public long? DefaultOccurrenceDeptId { get; set; }
/// 责任部门兜底。
public long? DefaultResponsibleDeptId { get; set; }
// ───────────────── 毒丸:出现即拒绝 ─────────────────
//
// 这些属性存在的**唯一**目的是让旧客户端(或试图绕过治理的调用)得到明确的 400,
// 而不是一个"成功但什么都没发生"的 200。
//
// 为什么用显式属性而不是依赖序列化器的 unknown-member 拒绝:
// 本仓 MVC 走 AddNewtonsoftJson(Admin.NET.Web.Core/Startup.cs),
// System.Text.Json 的 [JsonUnmappedMemberHandling] 在此不生效;
// Newtonsoft 的 MissingMemberHandling 又是全局设置,改它会外溢到 S0–S7 所有接口。
// 声明毒丸属性是唯一既精确、又不依赖序列化器配置的做法。
/// 已退役。params_json 不再由本接口整块写入。
public string? ParamsJson { get; set; }
/// 已退役。启停走 /enable 与 /disable,见 AdoS8ConfigWatchRulesController。
public bool? Enabled { get; set; }
/// 已退役:由代码定义。
public string? DatasetCode { get; set; }
/// 已退役:由代码定义。
public string? RuleType { get; set; }
/// 已退役:由代码定义。
public string? SourceObjectType { get; set; }
/// 已退役:由代码定义。
public string? ExceptionTypeCode { get; set; }
/// 已退役:由代码定义。
public string? SceneCode { get; set; }
/// 已退役:由代码定义(原可经 /params 修改)。
public string? StageCode { get; set; }
/// 已退役:由代码定义(原可经 /params 修改)。
public string? OrderFlowCode { get; set; }
/// 已退役:由代码定义(原可经 /params 修改)。
public string? RuleMechanism { get; set; }
/// 已退役:由代码定义。
public string? DueAtField { get; set; }
/// 已退役:由代码定义。
public string? StatusField { get; set; }
/// 已退役:由代码定义(它决定去重身份)。
public string? ObjectIdField { get; set; }
/// 已退役:由代码定义。
public string? ObjectCodeField { get; set; }
/// 已退役:由代码定义。
public string[]? CompletedStates { get; set; }
///
/// 本次请求中出现的、已退役的 Definition 字段名。为空表示载荷合法。
///
public IReadOnlyList RejectedDefinitionFields
{
get
{
var found = new List();
void Check(string name, bool present) { if (present) found.Add(name); }
Check("paramsJson", ParamsJson != null);
Check("enabled", Enabled.HasValue);
Check("datasetCode", DatasetCode != null);
Check("ruleType", RuleType != null);
Check("sourceObjectType", SourceObjectType != null);
Check("exceptionTypeCode", ExceptionTypeCode != null);
Check("sceneCode", SceneCode != null);
Check("stageCode", StageCode != null);
Check("orderFlowCode", OrderFlowCode != null);
Check("ruleMechanism", RuleMechanism != null);
Check("dueAtField", DueAtField != null);
Check("statusField", StatusField != null);
Check("objectIdField", ObjectIdField != null);
Check("objectCodeField", ObjectCodeField != null);
Check("completedStates", CompletedStates != null);
return found;
}
}
}
///
/// S8-SCHED-FRONTEND-1:调度参数安全更新载荷(保留兼容)。
/// 三个字段现已并入 ,本类型仅供既有
/// PUT /{id}/schedule 路由继续工作;服务端实现已委托到同一条参数写入路径。
///
public sealed class S8WatchRuleSchedulePayload
{
public int PollIntervalSeconds { get; set; } = 300;
public int TriggerCountRequired { get; set; } = 1;
public int RecoverCountRequired { get; set; } = 1;
}