namespace Admin.NET.Plugin.AiDOP.Service.S8.Rules.DataAccess;
///
/// 数据集可用性诊断项。回答"这个数据集当前能不能用、能用于哪类规则",
/// 不预览任何业务数据。
///
public sealed class S8DatasetDiagnosticDto
{
public string DatasetCode { get; init; } = string.Empty;
public string DisplayName { get; init; } = string.Empty;
public string Kind { get; init; } = string.Empty;
public string? Description { get; init; }
/// 声明状态:DEFINED / DISABLED。
public string DeclaredStatus { get; init; } = string.Empty;
/// 有效状态:READY / PROVIDER_MISSING / DISABLED。
public string EffectiveStatus { get; init; } = string.Empty;
public bool ProviderRegistered { get; init; }
public string? ProviderType { get; init; }
/// 目录声明支持的规则类型(仅机制层)。
public IReadOnlyList DeclaredRuleTypes { get; init; } = Array.Empty();
/// 真正可用的规则类型:机制支持 + canonical 字段齐备 + Provider 已注册且能力一致。
public IReadOnlyList UsableRuleTypes { get; init; } = Array.Empty();
/// 各规则类型缺失的 canonical 字段,供配置界面提示。
public IReadOnlyDictionary> MissingFieldsByRuleType { get; init; }
= new Dictionary>();
}
///
/// 数据集诊断服务。为后续规则配置界面提供"哪些数据集当前可用于哪类规则"的依据,
/// 使配置方不必先建规则再靠报错试探。
///
public class S8DatasetDiagnosticsService : ITransient
{
private readonly IS8DatasetCatalog _catalog;
private readonly S8MonitoringDataProviderRegistry _registry;
public S8DatasetDiagnosticsService(IS8DatasetCatalog catalog, S8MonitoringDataProviderRegistry registry)
{
_catalog = catalog;
_registry = registry;
}
/// 列出全部已定义数据集(含尚无 Provider 的)。
public IReadOnlyList List() =>
_catalog.All.Select(Describe).OrderBy(x => x.DatasetCode, StringComparer.OrdinalIgnoreCase).ToList();
/// 描述单个数据集;未定义返回 null(与"已定义但无 Provider"区分)。
public S8DatasetDiagnosticDto? Describe(string? datasetCode)
{
var definition = _catalog.Find(datasetCode);
return definition == null ? null : Describe(definition);
}
private S8DatasetDiagnosticDto Describe(S8DatasetDefinition definition)
{
var registered = _registry.IsRegistered(definition.DatasetCode);
var provider = registered ? _registry.Resolve(definition.DatasetCode) : null;
var effectiveStatus = !definition.IsActive
? S8DatasetStatus.Disabled
: registered
? S8DatasetStatus.Ready
: S8DatasetStatus.ProviderMissing;
var declared = S8RuleTypeFieldRequirements.KnownRuleTypes
.Where(rt => definition.Capabilities.Supports(rt))
.ToList();
// 可用 = 目录能力齐备 && (若已注册)Provider 能力也齐备。
var usable = declared
.Where(rt => definition.Capabilities.CanServe(rt))
.Where(rt => provider == null || provider.Capabilities.CanServe(rt))
.ToList();
var missing = new Dictionary>(StringComparer.OrdinalIgnoreCase);
foreach (var ruleType in declared)
{
var gaps = definition.Capabilities.MissingFieldsFor(ruleType);
if (gaps is { Count: > 0 }) missing[ruleType] = gaps;
}
return new S8DatasetDiagnosticDto
{
DatasetCode = definition.DatasetCode,
DisplayName = definition.DisplayName,
Kind = definition.Kind,
Description = definition.Description,
DeclaredStatus = definition.Status,
EffectiveStatus = effectiveStatus,
ProviderRegistered = registered,
ProviderType = provider?.GetType().Name,
DeclaredRuleTypes = declared,
UsableRuleTypes = usable,
MissingFieldsByRuleType = missing
};
}
}