这一组查询适合构建运维总览,但它们输出的是诊断投影,不是业务健康结论。正确的控制台必须把“已经注册”“默认实现”“真实可用”“配置完整”和“依赖连通”区分开。
1. 四条查询路径
四条路径都不写数据。治理和适配器查询是当前进程快照;租户查询依赖持久化 Store;配置查询读取已经构建的 IConfiguration。
2. 治理报告如何生成
GetGovernanceReportAsync 每次创建 AppModuleBoundaryVerifier 与 AppModuleDependencyGraph,基于 AppModuleRegistry 计算:
- 已注册模块总数;
- 每个模块的直接依赖;
- 缺失依赖违规消息;
- 是否存在循环模块;
- 一段 Mermaid 依赖图文本。
它没有保存历史快照、差异、批准记录或责任人。若需要“本次部署比上次多了什么依赖”,应由发布流水线保存 manifest 并做 diff。
3. 治理报告使用示例
var report = (await operations.GetGovernanceReportAsync(cancellationToken)) .GetValueOrThrow();
// ① 缺失依赖和循环都属于发布阻断项。if (report.HasCircularDependencies || report.MissingDependencies.Count > 0) return Result.Failure(ReleaseErrors.InvalidModuleGraph);
// ② 保存结构化节点;Mermaid 只用于展示,不作为唯一证据。await evidence.SaveAsync(report.Modules, cancellationToken);return Result.Success();4. 租户分页不是全局导出
GetTenants.Query 默认 PageIndex=0、PageSize=20。负页码归零;页大小小于等于零或大于 100 时回退 20,不是钳制到 100。
Handler 把参数传给 ITenantStore.ListAsync。返回值只有摘要列表,没有总行数、next token 或快照版本。调用方不能据此实现无遗漏的全量扫描,也不能把空页解释成系统无租户。
5. 租户查询示例
GET /api/operations/tenants?pageIndex=0&pageSize=50Authorization: Bearer <token-with-operations.tenants.view>// ① 负页码归零。var pageIndex = request.PageIndex < 0 ? 0 : request.PageIndex;
// ② 非法或过大的 pageSize 回退 20,而不是改成 100。var pageSize = request.PageSize is <= 0 or > 100 ? 20 : request.PageSize;return await operations.GetTenantsAsync(pageIndex, pageSize, cancellationToken);6. 适配器报告探测什么
OperationsService列出约 35 个 Application 可见 Port,包括文件、事件、Feature、租户、Identity 辅助 Store、审计、通知、文档、Webhook、Billing、Website、Tickets 与 Chat。
它调用 IServiceProvider.GetService(portType)。因此结果回答“容器能解析出什么对象”,不是“对象背后的数据库、队列或第三方服务可连通”。
Infrastructure 私有 Port 不在这张表内;它不是完整依赖清单。
7. 外部连接器就绪度报告是另一张表
GET /api/operations/connectors 返回的外部连接器就绪度报告与上面的适配器报告维度不同。它按 8 个业务连接器(Legal 五个:ElectronicSignature、EnterpriseInfo、LegalDatabase、Express、SfLegalDocument;Tools 三个:IManage、Ocr、Crawler)逐项给出 Provider、Status(Configured/NotConfigured/Unavailable)、AdapterRegistered、AdapterImplementation、ConfigurationSection、ChangesRequireRestart 与 DependentCapabilities。
两份报告的区别:适配器报告回答”容器能否解析这个内部 Port”,按实现类名前缀分类;连接器就绪度回答”这个外部系统的配置段是否存在、适配器是否注册”,当 Provider SDK 缺失时以 fail-closed 的 Unavailable 代理呈现。控制台应把两者分开:前者反映装配拓扑,后者反映外部集成边界。两者都不做真实连通探针,ChangesRequireRestart 固定为 true 表示改完配置必须重启。
8. 分类规则与误判
普通 Port 主要按实现类型短名前缀分类:
| 前缀 | 状态 |
|---|---|
Unavailable* 或 unavailable proxy | Unavailable |
InMemory*、Memory*、Null* | Default |
Cap*、Redis*、Cidr*、SignalR* | Production |
Local* | Production (Local) |
| 其他 | Unknown |
这是一种命名约定检查。一个名为 Redis 的适配器即使连接断开仍会显示 Production;一个成熟适配器若命名不符合前缀则会显示 Unknown。
9. Runtime License 是例外
IRuntimeLicenseProvider 不按类型名分类,而是返回 Provider 当前六态。未注册时明确是 Unavailable。
控制台应单独呈现 License 状态、原因与时间;不要把它与普通 adapter 的命名分类混成同一个绿色图标。
10. 配置声明从哪里来
API Host 的 ConfigDiagnosticRegistry.Create 扫描已加载、名称以 BitzOrcas 开头的程序集:
- 类级与公开实例属性上的
[ConfigKey]; - Host 额外声明的连接串、Redis、RabbitMQ、OTel、Persistence、Audit、Payment、FileStorage、Webhook 与 Runtime License 键;
- 同键保留第一次出现的声明。
若反射扫描发生 ReflectionTypeLoadException,该程序集会整体跳过,不会在报告中产生扫描失败项。
11. 诊断只检查值形态
每个声明最终由 CheckConfig 读取 IConfiguration[key]:
- 空值 →
missing; - 长度不足 →
too-short; - 其他 →
configured; - secret 只显示长度,不显示值。
它不解析 URI、Cron、CIDR、Provider 枚举,不打开连接,也不确认多个键之间是否一致。
12. 无声明源时的回退
当 IConfigDiagnosticSpecSource 未注册或返回空列表,只检查 Jwt:Secret、Jwt:Issuer、Jwt:Audience 三项。
因此单元测试或 Shell 组合中的“配置全部正常”不能代表生产组合。运维界面应显示声明总数与声明来源,避免把三项回退报告误解成全面检查。
13. 控制台呈现建议
把结果分成四列:声明状态、装配状态、主动健康、发布要求。
IWebhookDeadLetterQueue composition: Production # 类型名分类 readiness: Healthy # 主动探针 configuration: Complete # 配置诊断 requiredByProfile: true # 当前产品 Profile 要求当前 Operations 只提供前两类中的一部分;其余需要组合 Runtime Health、Profile manifest 和发布证据。
14. 安全与隐私
适配器类型名会暴露内部拓扑;配置键会暴露启用的供应商与组件。手写端点要求精确查看权限,但响应仍应经过缓存禁用、审计和敏感输出审查。
租户列表是平台级数据,不能依据当前租户自动缩小。分配 operations.tenants.view 时应按平台管理员角色治理。
15. 已有测试与缺口
现有测试覆盖治理/适配器/作业/配置的 API Shell 权限与响应、配置声明和 runtime surface manifest 对齐。
仍需补:扫描程序集失败可见性、适配器命名误判、主动探针聚合、租户分页一致性、配置 schema 语义验证、敏感响应缓存策略、声明源只有三项时的醒目标记。
16. 源码核查
# 服务投影与 Host 配置声明来源。sed -n '1,560p' \ src/Platform/Operations/BitzOrcas.Platform.Operations.Application/Services/OperationsService.cssed -n '1,320p' \ src/Hosts/BitzOrcas.Api/Composition/ConfigDiagnosticRegistration.cs
# 运行态 manifest 与配置 guard 的一致性测试。dotnet test tests/BitzOrcas.Architecture.Tests \ --filter FullyQualifiedName~OperationsRuntimeSurfaceTests