Operations 汇集了平台最危险的一组能力。GA 判断不能只看类和端点数量,而要证明路由真实可达、权限精确、审批失败关闭、执行结果可解释、数据库行为经过演练、证据不可抵赖。
1. 风险分层
层级越高,需要越强的权限、审批、SoD、计划绑定、互斥、审计和恢复证明。当前实现并未在所有维度随风险递增。
2. 19 个权限
| 资源 | 查看 | 管理/写 |
|---|---|---|
| governance | operations.governance.view | — |
| tenants | operations.tenants.view | — |
| adapters | operations.adapters.view | — |
| jobs | operations.jobs.view | operations.jobs.manage |
| config | operations.config.view | — |
| website analytics dead letters | view | manage |
| schema | operations.schema.view | apply / admin |
| backups | view / verify | create / restore |
| archive | view | manage |
| cache | operations.cache.view | operations.cache.manage |
Website analytics dead-letter 权限由 Operations catalog 拥有,但路由不在 Operations 模块目录。权限审计要按 owned permission 与 consumed endpoint 两个维度扫描。
3. 两层授权的漂移风险
手写端点以 RequirePermission(OperationsPermissions.*) 做 HTTP 级精确权限。请求类型又通过 ResourceDescriptor + AuthorizationAction 进入 Mediator 授权管道。
新增或迁移路由时,必须测试两层导出的权限码一致。例如 restore 是 backups + Delete + sensitivity restore;若派生规则与常量不一致,可能出现一层允许、一层拒绝或审计归类错误。
4. 审批适配器的实际降级
Production/Staging:要求工单号;能解析 OpsExtension Store 时要求 Incident 为 Resolved/Closed。
强制环境但 Store 不可解析:只检查工单号非空。
其他环境:ValidateAsync 直接 true。
审批工单没有绑定操作类型、目标数据库、脚本 hash、备份文件 hash、租户、原因或有效期。一个已关闭 Incident 在代码层可被复用于多个敏感操作。
5. 审计矩阵
| 操作 | 成功 | 业务失败 | 审计失败影响 |
|---|---|---|---|
| Schema apply | 执行后记录 | 无专门失败记录 | sink 异常可能覆盖成功 |
| Backup create | 记录 | 记录 | 被捕获,只告警 |
| Backup verify | 记录 | service failure 不记录 | sink 异常覆盖验证结果 |
| Restore | 记录 | 记录 | 被捕获,只告警 |
| Archive | 意图 + 完成两阶段 | 记录 | fail-closed:意图失败不执行(AuditUnavailable),完成失败返回 OutcomeUnknown |
| Cache invalidate | 意图 + 完成两阶段 | 记录 | fail-closed:审计失败不执行或返回 OutcomeUnknown |
| Job execute | 成功/失败/异常/取消 | 记录 | 只告警 |
| Job update/start/stop | 无显式 before/after | 无显式 | 依赖通用管道 |
这个矩阵说明归档与缓存失效的审计已经 fail-closed,但备份/恢复与作业类操作的审计仍是 best-effort,“所有危险操作有不可变审计证据”仍不成立。
6. 路由门禁
手写组有 9 条可靠映射(作业管理 4 条、归档 3 条、缓存治理 2 条)。Application 有 16 个嵌套 [GenerateEndpoint] 声明,但生成器只遍历命名空间顶层类型。
GA 必须从运行中的 EndpointDataSource 或 OpenAPI 获取清单,对每个声明验证方法、路径、认证、精确权限、限流、超时和返回契约。源码特性扫描只能作辅助。
7. 当前测试证据
已有覆盖包括:
- API Shell 治理、适配器、作业、配置权限与响应;
- 后台作业更新、启停、执行与审计;
- 作业 Catalog/Executor 完整性;
- 当前租户归档边界;
- Operations runtime surface manifest;
- 配置声明与生产 guard 对齐;
- adapter matrix consistency;
- Website analytics dead-letter 精确权限;
- 敏感响应中的 adapter/config 信息不被 masking 破坏。
8. 不能由现有测试证明的内容
- Schema/备份真实 HTTP 可达;
- SQL Server 漂移和 FullForce 端到端执行;
- 预览到执行期间的 TOCTOU;
- 双实例并发迁移、同秒备份覆盖;
- restore 自动验证、备份链与隔离恢复;
- OpsExtension 缺失时审批是否应该 fail closed;
- 强制 SoD;
- 调度修改跨实例收敛;
- ColdStorage 与延迟删除;
- 审计 sink 故障后的合规补偿。
9. 高价值合同测试示例
// ① 从真实 TestServer 取 EndpointDataSource,不解析源码特性。var routes = endpointDataSource.Endpoints .OfType<RouteEndpoint>() .Select(x => (Pattern: x.RoutePattern.RawText, Methods: x.Metadata .GetMetadata<HttpMethodMetadata>()?.HttpMethods)) .ToList();
// ② Schema/backup 每条商业路由必须恰好出现一次。routes.Count(x => x.Pattern == "/api/operations/backups/restore") .ShouldBe(1);
// ③ 再对匿名、错误权限、正确权限分别发请求。该测试能同时发现“有特性但未生成”和“双重映射导致歧义”。
10. 敏感操作合同示例
var intent = new SensitiveOperationIntent( Operation: "Schema.FullForce", Target: databaseFingerprint, PayloadHash: migrationScriptHash, RequestedBy: actorId, ExpiresAt: clock.UtcNow.AddMinutes(30));
// ① 审批服务验证状态、不同审批者、操作意图和有效期。var approval = await approvals.ValidateAsync(ticket, intent, cancellationToken);if (!approval.IsApproved) return Result.Failure(approval.Error);
// ② 执行前再次计算 hash;不一致就重新审批。这是 GA 目标模型,不是当前源码已有能力。
11. 运维指标
至少需要:
- endpoint request/result/latency,按能力和错误码;
- approval required/denied/degraded;
- schema drift 数、preview hash、executed/skipped/failed statements;
- backup duration/bytes/skipped/verify invalid/restore result;
- job desired-vs-observed、manual execution、duration、failure;
- archive rows/batches/lag/cold-storage pending;
- audit sink failure;
- adapter/config report freshness。
标签不得包含完整 SQL、备份路径、工单正文或租户秘密。
12. 故障诊断顺序
路由 404:先查运行态 endpoint 清单,再查生成器嵌套类型限制。
403:区分 HTTP permission、Mediator resource/action 与审批 gate,不要笼统增加管理员权限。
Schema HTTP 200 但结构不完整:检查 SkippedStatements,执行器可能把单句异常转为整体成功。
Log backup 成功但无文件:检查 Skipped 和 SQL Server recovery model。
恢复被允许但没有 SoD:检查环境、OpsExtension Store 与 EffectiveUserId。
作业 PUT 成功但 GET 未变化:当前 GET 读取代码 Catalog。
13. 发布前门禁
- 运行态路由清单与权限 catalog 一一对应;
- Production/Staging 缺 OpsExtension 时敏感操作失败关闭;
- 每类危险操作有不可复用、绑定意图的审批;
- 审计故障有告警、缓冲或阻断策略;
- Schema 在真实克隆库完成 preview/apply/re-detect 与部分失败演练;
- 备份在隔离环境完成 restore drill 并测量 RPO/RTO;
- 作业 desired/observed 收敛有版本证据;
- 归档热表、归档表、批次、冷存储和删除全链演练;
- 日志/响应不泄露绝对路径、连接串、SQL secret 或工单敏感字段。
14. P0 GA backlog
- 修复嵌套 GenerateEndpoint 发现并建立路由唯一性门禁;
- Schema immutable plan/hash/fingerprint/lease;
- 逐句结构化结果和失败策略;
- 审批绑定意图、有效期、SoD,并在后端缺失时 fail closed;
- Restore 强制验证与验证证据绑定;
- 备份并发文件名和单实例锁;
- 作业 GET desired/observed 一致模型;
- 所有敏感操作完整成功/失败/拒绝审计。
15. P1 GA backlog
- 数据库 Provider capability matrix;
- 异地加密备份、legal hold 与链感知 retention;
- 隔离恢复和自动恢复演练;
- 调度版本、ETag、reload ack 与 kill switch;
- ColdStorage 对象存储、checksum、查询和删除证明;
- adapter 主动健康与 Profile readiness 合并;
- 配置 schema/跨字段语义验证;
- 运维证据导出、保留、签名与合规报告。
详细任务同步到 Architecture-Hub 的 Operations Commercial GA Backlog。
16. 当前上线判断
治理、适配器、配置、租户、作业手动管理和租户归档可作为受控内部运维能力。Schema 和备份虽有 Application/Infrastructure 实现,但在路由、审批、计划绑定、并发和灾备演练补齐前,不应宣传为完整商业数据库控制面。
17. 验证命令
# Operations Application 行为。dotnet test tests/BitzOrcas.Application.Tests \ --filter 'FullyQualifiedName~Operations|FullyQualifiedName~BackgroundJobManagement|FullyQualifiedName~ArchiveTenantBoundary'
# 架构与运行面声明。dotnet test tests/BitzOrcas.Architecture.Tests \ --filter 'FullyQualifiedName~Operations|FullyQualifiedName~AdapterMatrix|FullyQualifiedName~BackgroundJobIntake'
# HTTP Shell 与作业管理。dotnet test tests/BitzOrcas.Integration.Tests \ --filter 'FullyQualifiedName~ApiShellTests|FullyQualifiedName~BackgroundJobManagementApiTests'