Skip to content
bitzorcas
中EN

Reference

DocumentStructure 测试、运维与商业 GA 门禁

汇总 DocumentStructure 当前测试证据、授权与事务缺口、模板/表达式/回收站故障注入、容量、指标、恢复和商业发布清单。

Last updated

DocumentStructure 已有图校验、租户 Store 和部分读侧测试,但商业 GA 必须证明模板应用不会留下半棵树、收藏不会泄漏失权资源、Purge 不会绕过保留/法律留存,并且双 ORM 行为一致。

1. 当前自动化证据

测试面已覆盖
Command重复节点 ID、缺父节点、持久 ID 回传
Query模板列表调用 Store、回收站查询调用 Port
StoreEffectiveTenant 传播、收藏主键租户过滤、旧节点快照
ArchitectureInfrastructure ORM 中立、默认端口、跨模块实现位置
IntegrationDocumentStructure Store parity 纳入双 ORM 体系

缺少:真实 HTTP 权限、环/深度边界、并发名称/更新、Apply 目标授权、部分失败回滚、Scriban 安全/取消、收藏目标授权、Restore/Purge 竞态和容量恢复。

2. 最小回归组合

Terminal window
# 应用层图校验和读用例。
dotnet test tests/BitzOrcas.Application.Tests/BitzOrcas.Application.Tests.csproj \
--filter "FullyQualifiedName~DocumentStructure"
# Store 与 Documents 回收站单元证据。
dotnet test tests/BitzOrcas.Unit.Tests/BitzOrcas.Unit.Tests.csproj \
--filter "FullyQualifiedName~DocumentStructure|FullyQualifiedName~DocumentRecycleBinStore"
# 架构边界与默认端口。
dotnet test tests/BitzOrcas.Architecture.Tests/BitzOrcas.Architecture.Tests.csproj \
--filter "FullyQualifiedName~DocumentStructure"

发布候选还必须运行两种真实 ORM 的模板多表事务、唯一冲突和回收站级联场景,不能用 Substitute Store 代替发布证据。

3. HTTP 授权矩阵

场景预期
匿名任一路由401/统一认证错误
无模板 Viewlist/get/preview 拒绝
有 View 无 Applyapply 拒绝
租户 A 访问租户 B TemplateIdNotFound
有模板权限但无 KB 管理权apply 拒绝且无分类
无目标资源访问权添加收藏拒绝
无 KB 权限查询回收站拒绝
普通 Delete 权限执行 Purge按高风险策略拒绝

必须确认请求类型约定最终映射到 docs.folder-template.* / docs.recycle-bin.*,并为 Favorite 建立明确权限;只断言 IAuthorizedRequest 存在不够。

4. 图与版本测试

覆盖空 ID、重复 ID、自环、双节点环、缺父、深度 10 成功/11 失败、1/100/1000 节点、同级 SortOrder、过长字段、空 Name、未知 TargetType。更新还要测格式异常版本、并发双写、名称唯一冲突、快照 JSON schema 和中途删除/插入失败回滚。

目标:模板更新失败不破坏当前版本
// 在删除旧节点后、插入新节点前注入持久化失败。
storeFaults.FailNextNodeInsert(new IOException("storage unavailable"));
var result = await sender.Send(updateCommand, cancellationToken);
result.IsFailure.ShouldBeTrue();
// 旧根、CurrentVersion、节点集合和版本历史必须保持一致。
await evidence.AssertTemplateVersionAsync(
updateCommand.Id, "1.0.0", expectedOldNodes, cancellationToken);

5. Apply 故障注入

依次在目标授权、Compile、Render、第一个/中间/最后一个 Category Save、事务提交和响应返回前注入失败。每次断言:数据库无部分树或补偿完成;幂等记录可恢复;重复请求不重复创建;错误包含稳定 code,不泄漏 NamingContext。

目标:并发重放只产生一棵分类树
// 同一业务意图的并发请求必须复用相同 ApplicationId。
var command = NewApplyCommand(applicationId: "apply-2026-0042");
// 同时发起请求,用数据库唯一约束验证并发门禁。
var results = await Task.WhenAll(
sender.Send(command, cancellationToken).AsTask(),
sender.Send(command, cancellationToken).AsTask());
results.ShouldAllBe(result => result.IsSuccess);
results[0].Value!.CreatedCategoryIds.ShouldBe(results[1].Value!.CreatedCategoryIds);
await evidence.AssertSingleTreeAsync(command.TargetId, command.ApplicationId, cancellationToken);

ApplicationId 当前不存在;这是 GA 目标测试,不是现状示例。

6. Scriban 安全测试

测试未知变量、语法错误、巨大输出、深层循环、超时、取消、敏感上下文、禁止函数/对象、Unicode 和同名渲染。Preview 返回逐节点 diagnostics;Apply 默认在任何必需表达式失败时零写入。

记录编译/渲染耗时与错误码,不记录表达式中的 Secret 或完整上下文。若编译器支持缓存,缓存键必须包含租户安全边界、表达式哈希、引擎和策略版本。

7. 收藏测试

覆盖 RequireUserId、允许类型、目标不存在、跨租户目标、当前无权、后续失权/删除、重复 active、软删后重加、并发重复、分组筛选、本人/他人删除和大列表分页。双 ORM 必须对唯一与软删恢复给出相同行为。

8. 回收站测试

对 Document/Category 分别覆盖不存在、未删除、跨 KB、跨租户、父已删除、名称冲突、分类子树、附件/版本、Search 索引、收藏引用、重复 Restore、重复 Purge、Restore/Purge 并发、保留期与 Legal Hold。

Purge 中途失败要有可恢复 Job/报告;事件消费者要能重放而不重复删除外部对象。

9. 容量基线

至少测:模板 1/10/100/1000 节点,租户 10/1000/100000 模板,用户 10/1000/10000 收藏,回收站 1万/百万项,分类级联 10/1000/10万对象。记录 P50/P95/P99、数据库 round trips、事务日志、锁、分配、编译耗时和事件积压。

当前模板列表逐模板 Count 节点,是 N+1;模板数量上升时应改成批量聚合 Read Store。

10. 指标与告警

  • template create/update/delete/conflict;
  • graph validation error by code、node count/depth;
  • preview compile/render/fallback duration;
  • apply duration、planned/created/failed/compensated nodes;
  • application id replay/conflict;
  • favorite add/conflict/unresolved/denied/list size;
  • recycle query/restore/purge、cascade size、legal-hold denial;
  • transaction rollback、outbox lag、dead letter。

告警重点是 apply partial、compensation failed、Purge unauthorized/failed、unresolved favorite 激增、Scriban 超时和跨租户拒绝异常增长。

11. 备份与恢复

备份包括模板根、当前节点、历史快照、收藏、Documents 回收站事实和相关 Outbox。恢复后验证父引用、CurrentVersion/快照一致、收藏自然键唯一、软删过滤、回收站树完整和 Search/Files 消费者可重建。

历史快照没有 schema version 时,恢复升级存在风险;GA 前必须给旧快照迁移和不可解析隔离策略。

12. GA 阻断项

  1. Apply 未验证目标实例和 TargetType;
  2. 逐节点写没有事务/补偿故障证据;
  3. unresolved remaining 可部分成功;
  4. 没有应用幂等键;
  5. Scriban 同步阻塞、忽略取消、吞错;
  6. 版本无查询/diff/回滚/schema version/并发控制;
  7. 收藏不验证目标或授权,UserId 可回退 0;
  8. Favorite 权限未显式治理;
  9. 回收站对象授权、Purge 保留/法律留存不足;
  10. 跨模块恢复/Purge 事件一致性未证明;
  11. 模板列表 N+1 和大树容量无基线;
  12. HTTP、双 ORM、并发、故障、恢复和运维证据缺失。

13. 分阶段落地

P0:目标授权、原子/补偿 Apply、完整结果、幂等、异步 Scriban、收藏 owner 授权、回收站对象策略。P1:版本产品、并发控制、批量读模型、Purge Job/保留、事件与观测。模板组合、共享收藏和高级蓝图属于后续产品能力。

14. 扫尾命令

Terminal window
# 高风险现状:预期在 P0 后归零或只留已登记兼容入口。
rg -n "GetAwaiter\(\)\.GetResult|CancellationToken.None|UserId\?\.ToString\(\) \?\? \"0\"" \
src/Platform/DocumentStructure -g '*.cs'
# 逐节点跨模块写:目标是改为 owner contract 后归零。
rg -n "IRepository<DocumentCategory>|SaveAsync\(category" \
src/Platform/DocumentStructure -g '*.cs'

DocumentStructure 总览 · 模板应用与预览 · 收藏与回收站

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%