- API 接口中的版本参数处理
- 流程实例创建时的版本验证
- 版本查询逻辑的一致性
- 数据一致性和并发问题
位置: 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}]的流程模板!");位置: 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:如果版本未提供,返回最新版本(但需要明确文档说明)
位置: HxDefinitionController.cs 第 30 行
问题描述:
GetAsync(Guid id)只返回最新未归档版本- 如果用户期望获取特定版本,可能会混淆
- API 文档需要明确说明此行为
当前代码:
[HttpGet]
public Task<WkDefinitionDto?> GetAsync(Guid id)
{
return _appService.GetAsync(id);
}建议:
- 在 API 文档中明确说明此方法返回最新未归档版本
- 或者重命名为
GetLatestAsync(Guid id)以明确语义
位置: WorkflowAppService.cs 第 83-95 行
问题描述:
先查询数据库获取模板定义然后检查是否已归档最后才检查是否已注册到引擎(在StartWorkflowAsync中)如果版本未注册到引擎,错误信息不够明确
修复方案:
- ✅ 在
IHxWorkflowManager接口中添加IsRegistered方法 - ✅ 在
HxWorkflowManager中实现该方法 - ✅ 在查询模板定义后,立即检查是否已注册到引擎
- ✅ 提供更明确的错误信息,包含模板 ID 和版本号
修复后的流程:
- 验证版本号(第 66 行)
- 查询模板定义(第 83 行)
- 检查是否已归档(第 86 行)
- 检查是否已注册到引擎(第 91 行) ← 新增,提前检查
- 检查权限(第 96 行)
- 调用
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}] 未注册到工作流引擎,无法启动实例。请确保模板已正确创建并注册。");
}位置: 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}的模板不存在!" - 如果版本未提供且默认版本不存在,可以考虑返回最新版本
HxPersistenceProvider.CreateNewWorkflow正确使用workflow.VersionToPersistable方法正确设置实例版本
StartAsync中已检查版本是否已归档- 已归档版本不能用于创建新实例
- 创建实例前检查用户是否有权限
- 所有通过
instance.WkDefinition访问的地方都正确 - 直接查询时都使用了
instance.Version
-
添加版本号验证
// 在 StartAsync 方法开始处添加 if (input.Version <= 0) { throw new UserFriendlyException(message: $"版本号必须大于0,当前值:{input.Version}"); }
-
改进错误信息
- 所有涉及版本查询的错误信息都应包含版本号
- 提供更明确的错误提示
-
版本注册检查提前 ✅
// 在 StartAsync 中,查询模板后立即检查注册状态 if (!_hxWorkflowManager.IsRegistered(input.Id, input.Version)) { throw new UserFriendlyException(message: $"流程模板 Id为:[{input.Id}],版本为:[{input.Version}] 未注册到工作流引擎,无法启动实例。请确保模板已正确创建并注册。"); }
-
API 接口改进
- 考虑移除
GetDefinitionAsync的默认版本参数 - 或者提供
GetLatestAsync方法明确语义
- 考虑移除
-
API 文档完善
- 明确说明各 API 的版本参数行为
- 说明默认值的使用场景
-
日志记录
- 记录版本查询操作
- 记录版本不匹配的情况
- API 接口版本参数处理
- 流程实例创建时版本验证
- 版本查询逻辑一致性
- 错误信息完整性
- 并发控制(需要进一步检查)
- 事务处理(需要进一步检查)
主要问题:
- ✅
StartWorkflowInput.Version缺少验证(高风险)- 已修复 - ✅ 版本注册检查在查询之后(中风险)- 已修复
- ✅ 错误信息不够明确(中风险)- 已修复
⚠️ 默认版本处理可能引起混淆(中风险)- 建议在 API 文档中说明
已完成的修复:
- ✅ 添加版本号验证,确保版本号 > 0
- ✅ 改进错误信息,包含版本号
- ✅ 提前检查版本注册状态,提供更明确的错误信息
- ✅ 在
IHxWorkflowManager接口中添加IsRegistered方法
建议:
- 考虑优化 API 接口设计,明确版本参数行为
- 完善 API 文档,说明默认值的使用场景