namespace Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess; /// /// 向 Provider 取数的请求上下文。 /// /// 硬性设计约束: **必须由调用方显式传入**。 /// Provider 实现禁止从 HttpContext / 当前登录用户 / 全局单租户假设推导作用域, /// 也禁止把租户写成 SQL 字面量 —— 这两种做法正是既有 LEGACY_SQL 规则里的已知问题形态。 /// /// S8-TENANT-ONLY-BATCH5:Factory 已退出取数作用域。 /// 它此前是必填项(FactoryId <= 0 直接 dataset_scope_invalid), /// 但**没有任何 Provider 真的用它过滤** —— 唯一的 PURCHASE_DELIVERY Provider 的 WHERE /// 从一开始就只有 tenant_id。于是它是一道纯粹的形式门槛: /// 零工厂 / 多工厂租户会在这里被拒,而放行与否对取出的数据没有任何影响。 /// 现在作用域只认 Tenant,与真实数据边界一致。 /// public sealed class S8MonitoringDataRequest { /// 租户作用域。必填且必须 > 0。 public long TenantId { get; init; } /// 数据集编码(STANDARD_DATASET 模式)。 public string DatasetCode { get; init; } = string.Empty; /// 触发本次取数的规则 Id(仅用于日志与排查)。 public long RuleId { get; init; } /// 触发本次取数的规则编码(仅用于日志与排查)。 public string RuleCode { get; init; } = string.Empty; /// 规则类型 TIMEOUT / SHORTAGE / OUT_OF_RANGE,供 Provider 做能力校验。 public string RuleType { get; init; } = string.Empty; /// /// 作用域校验。缺失租户时显式失败,不允许 Provider 用默认值兜底 /// (兜底会让跨租户读取以"看起来正常"的方式发生)。 /// public void EnsureValid() { if (TenantId <= 0) throw new S8RuleEvaluatorException( "dataset_scope_invalid", $"数据集取数缺少有效 TenantId(rule={RuleCode}, dataset={DatasetCode})"); } }