Skip to content

Latest commit

 

History

History
276 lines (189 loc) · 7.6 KB

File metadata and controls

276 lines (189 loc) · 7.6 KB

流程模板版本控制问题检查报告

🔍 检查范围

  • API 接口中的版本参数处理
  • 流程实例创建时的版本验证
  • 版本查询逻辑的一致性
  • 数据一致性和并发问题

⚠️ 发现的问题

1. StartWorkflowInput.Version 缺少验证 ⚠️ 高风险

位置: WorkflowAppService.cs 第 77 行

问题描述:

  • StartWorkflowInput.Version 没有验证是否为有效版本号(> 0)
  • 如果传入 Version = 0 或负数,会直接查询数据库,可能导致:
    • 查询到错误的版本
    • 或者查询失败但错误信息不够明确

当前代码:

var entity = await _wkDefinition.GetDefinitionAsync(new Guid(input.Id), input.Version)
    ?? throw new UserFriendlyException(message: $"不存在Id为:[{input.Id},{input.Version}]流程模板!");

建议修复:

// 验证版本号
if (input.Version <= 0)
{
    throw new UserFriendlyException(message: $"版本号必须大于0,当前值:{input.Version}");
}

var entity = await _wkDefinition.GetDefinitionAsync(new Guid(input.Id), input.Version)
    ?? throw new UserFriendlyException(message: $"不存在Id为:[{input.Id}], 版本为:[{input.Version}]的流程模板!");

2. GetDefinitionAsync 默认版本可能不存在 ⚠️ 中风险

位置: HxDefinitionController.cs 第 41 行

问题描述:

  • GetDefinitionAsync(Guid id, int version = 1) 默认版本为 1
  • 如果模板的第一个版本不是 1(例如从版本 2 开始),会返回错误
  • 用户可能不知道应该使用哪个版本号

当前代码:

[HttpGet]
[Route("details")]
public Task<WkDefinitionDto> GetAsync(Guid id, int version = 1)
{
    return _appService.GetDefinitionAsync(id, version);
}

建议修复:

  • 方案 1:移除默认值,强制要求传入版本号
  • 方案 2:如果版本未提供,返回最新版本(但需要明确文档说明)

3. GetAsync(Guid id) 返回最新版本可能引起混淆 ⚠️ 低风险

位置: HxDefinitionController.cs 第 30 行

问题描述:

  • GetAsync(Guid id) 只返回最新未归档版本
  • 如果用户期望获取特定版本,可能会混淆
  • API 文档需要明确说明此行为

当前代码:

[HttpGet]
public Task<WkDefinitionDto?> GetAsync(Guid id)
{
    return _appService.GetAsync(id);
}

建议:

  • 在 API 文档中明确说明此方法返回最新未归档版本
  • 或者重命名为 GetLatestAsync(Guid id) 以明确语义

4. 版本注册检查在查询之后 ✅ 已修复

位置: WorkflowAppService.cs 第 83-95 行

问题描述:

  • 先查询数据库获取模板定义
  • 然后检查是否已归档
  • 最后才检查是否已注册到引擎(在 StartWorkflowAsync 中)
  • 如果版本未注册到引擎,错误信息不够明确

修复方案:

  1. ✅ 在 IHxWorkflowManager 接口中添加 IsRegistered 方法
  2. ✅ 在 HxWorkflowManager 中实现该方法
  3. ✅ 在查询模板定义后,立即检查是否已注册到引擎
  4. ✅ 提供更明确的错误信息,包含模板 ID 和版本号

修复后的流程:

  1. 验证版本号(第 66 行)
  2. 查询模板定义(第 83 行)
  3. 检查是否已归档(第 86 行)
  4. 检查是否已注册到引擎(第 91 行) ← 新增,提前检查
  5. 检查权限(第 96 行)
  6. 调用 StartWorkflowAsync(第 100 行)

修复代码:

// 在 IHxWorkflowManager 接口中添加
bool IsRegistered(string id, int version);

// 在 HxWorkflowManager 中实现
public virtual bool IsRegistered(string id, int version)
{
    return _registry.IsRegistered(id, version);
}

// 在 WorkflowAppService.StartAsync 中使用
// 检查版本是否已注册到工作流引擎(提前检查,提供更明确的错误信息)
if (!_hxWorkflowManager.IsRegistered(input.Id, input.Version))
{
    throw new UserFriendlyException(message: $"流程模板 Id为:[{input.Id}],版本为:[{input.Version}] 未注册到工作流引擎,无法启动实例。请确保模板已正确创建并注册。");
}

5. GetDefinitionAsync 默认版本处理不一致 ⚠️ 低风险

位置: WkDefinitionAppService.cs 第 1186 行

问题描述:

  • GetDefinitionAsync(Guid id, int version = 1) 默认版本为 1
  • 如果版本不存在,错误信息不够友好

当前代码:

public virtual async Task<WkDefinitionDto> GetDefinitionAsync(Guid id, int version = 1)
{
    var entity = await _definitionRespository.GetDefinitionAsync(id, version)
        ?? throw new UserFriendlyException(message: $"Id为:{id}模板不存在!");
    // ...
}

建议:

  • 错误信息应该包含版本号:$"Id为:{id},版本为:{version}的模板不存在!"
  • 如果版本未提供且默认版本不存在,可以考虑返回最新版本

✅ 已正确处理的场景

1. 流程实例创建时版本设置 ✅

  • HxPersistenceProvider.CreateNewWorkflow 正确使用 workflow.Version
  • ToPersistable 方法正确设置实例版本

2. 版本归档检查 ✅

  • StartAsync 中已检查版本是否已归档
  • 已归档版本不能用于创建新实例

3. 权限检查 ✅

  • 创建实例前检查用户是否有权限

4. 通过实例获取模板定义 ✅

  • 所有通过 instance.WkDefinition 访问的地方都正确
  • 直接查询时都使用了 instance.Version

🔧 建议的修复方案

优先级 1:高优先级修复

  1. 添加版本号验证

    // 在 StartAsync 方法开始处添加
    if (input.Version <= 0)
    {
        throw new UserFriendlyException(message: $"版本号必须大于0,当前值:{input.Version}");
    }
  2. 改进错误信息

    • 所有涉及版本查询的错误信息都应包含版本号
    • 提供更明确的错误提示

优先级 2:中优先级优化 ✅ 已修复

  1. 版本注册检查提前

    // 在 StartAsync 中,查询模板后立即检查注册状态
    if (!_hxWorkflowManager.IsRegistered(input.Id, input.Version))
    {
        throw new UserFriendlyException(message: $"流程模板 Id为:[{input.Id}],版本为:[{input.Version}] 未注册到工作流引擎,无法启动实例。请确保模板已正确创建并注册。");
    }
  2. API 接口改进

    • 考虑移除 GetDefinitionAsync 的默认版本参数
    • 或者提供 GetLatestAsync 方法明确语义

优先级 3:低优先级改进

  1. API 文档完善

    • 明确说明各 API 的版本参数行为
    • 说明默认值的使用场景
  2. 日志记录

    • 记录版本查询操作
    • 记录版本不匹配的情况

📋 检查清单

  • API 接口版本参数处理
  • 流程实例创建时版本验证
  • 版本查询逻辑一致性
  • 错误信息完整性
  • 并发控制(需要进一步检查)
  • 事务处理(需要进一步检查)

📝 总结

主要问题:

  1. StartWorkflowInput.Version 缺少验证(高风险)- 已修复
  2. ✅ 版本注册检查在查询之后(中风险)- 已修复
  3. ✅ 错误信息不够明确(中风险)- 已修复
  4. ⚠️ 默认版本处理可能引起混淆(中风险)- 建议在 API 文档中说明

已完成的修复:

  • ✅ 添加版本号验证,确保版本号 > 0
  • ✅ 改进错误信息,包含版本号
  • ✅ 提前检查版本注册状态,提供更明确的错误信息
  • ✅ 在 IHxWorkflowManager 接口中添加 IsRegistered 方法

建议:

  • 考虑优化 API 接口设计,明确版本参数行为
  • 完善 API 文档,说明默认值的使用场景