deploy-ease-platform/backend/docs/deploy-record-status-rejected-analysis.md
2025-11-04 22:37:01 +08:00

5.8 KiB
Raw Blame History

部署记录状态CANCELLED vs REJECTED 分析

当前状态

CANCELLED已取消的使用场景

唯一使用场景:审批被拒绝

  • 位置:DeployRecordServiceImpl.updateStatusFromApproval()
  • 代码:record.setStatus(DeployRecordStatusEnums.CANCELLED);
  • 日志:"部署记录状态已更新为已取消(审批被拒)"

结论:当前 CANCELLED 只用于审批被拒绝的场景。

其他状态的使用场景

状态 使用场景 来源
TERMINATED 工作流被手动终止 工作流状态 TERMINATED
FAILED 工作流执行失败 工作流状态 FAILED
CANCELLED 审批被拒绝 审批事件 ApprovalResultEnum.REJECTED

问题分析

问题1语义不清晰

当前问题

  • CANCELLED(已取消)语义模糊,不能明确表示是"审批被拒绝"
  • 未来如果有手动取消部署功能,会产生歧义

对比

  • 工作流层面:ApprovalResultEnum.REJECTED(拒绝)
  • 部署记录层面:CANCELLED(已取消)
  • 不一致:两个层面使用不同的语义

问题2未来扩展性

未来可能的场景

  1. 手动取消部署:用户主动取消正在运行的部署
    • 应该使用什么状态?如果用 CANCELLED,会与"审批被拒绝"混淆
  2. 超时自动取消:部署超时自动取消
    • 应该使用什么状态?

方案对比

方案A保留 CANCELLED新增 REJECTED推荐

状态定义

public enum DeployRecordStatusEnums {
    // ... 其他状态 ...
    
    /**
     * 审批被拒绝(终态)
     */
    REJECTED("REJECTED", "审批被拒绝"),
    
    /**
     * 已取消(终态)
     * 用于:手动取消部署、超时自动取消等场景
     */
    CANCELLED("CANCELLED", "已取消"),
    
    // ... 其他状态 ...
}

优点

  1. 语义清晰:REJECTED 明确表示"审批被拒绝"
  2. 与工作流层面保持一致:ApprovalResultEnum.REJECTEDDeployRecordStatusEnums.REJECTED
  3. 保留扩展性:CANCELLED 可用于未来手动取消场景
  4. 状态语义明确,便于理解和维护

缺点

  • 需要新增枚举值
  • 需要修改相关代码
  • 需要数据库迁移(如果已有数据)

需要修改的地方

  1. 枚举类:新增 REJECTED
  2. DeployRecordServiceImpl.updateStatusFromApproval():改为 REJECTED
  3. isFinalState():添加 REJECTED
  4. 统计查询:REJECTED 计入失败计数
  5. fromWorkflowStatus():不需要修改(因为 REJECTED 不是从工作流状态转换来的)

方案B直接用 REJECTED 替代 CANCELLED

状态定义

public enum DeployRecordStatusEnums {
    // ... 其他状态 ...
    
    /**
     * 审批被拒绝(终态)
     */
    REJECTED("REJECTED", "审批被拒绝"),
    
    // 删除 CANCELLED
}

优点

  1. 语义清晰
  2. 与工作流层面保持一致
  3. 简化状态模型

缺点

  1. 失去扩展性:如果未来需要手动取消功能,需要再添加状态
  2. 如果未来需要区分"审批被拒绝"和"手动取消",需要再次修改

方案C保持现状不推荐

优点

  • 无需修改代码

缺点

  1. 语义不清晰
  2. 与工作流层面不一致
  3. 未来扩展困难

推荐方案

推荐采用方案A保留 CANCELLED新增 REJECTED

理由

  1. 语义清晰

    • REJECTED:明确表示"审批被拒绝"
    • CANCELLED:用于"手动取消"等场景
  2. 状态映射清晰

    审批层面ApprovalResultEnum.REJECTED
        ↓
    部署记录DeployRecordStatusEnums.REJECTED
    
  3. 未来扩展性

    • 如果未来需要手动取消部署功能,可以直接使用 CANCELLED
    • 如果不需要手动取消,CANCELLED 可以保留但不用
  4. 状态完整性

    • 终态包括:SUCCESSFAILEDREJECTEDCANCELLEDTERMINATEDPARTIAL_SUCCESS
    • 语义清晰,便于理解和维护

实施建议

步骤1新增 REJECTED 枚举

/**
 * 审批被拒绝(终态)
 */
REJECTED("REJECTED", "审批被拒绝"),

步骤2修改审批状态更新逻辑

} else {
    // 审批被拒绝,更新为审批被拒绝
    record.setStatus(DeployRecordStatusEnums.REJECTED);
    log.info("部署记录状态已更新为审批被拒绝: id={}, workflowInstanceId={}", 
            record.getId(), workflowInstanceId);
}

步骤3更新终态判断

private boolean isFinalState(DeployRecordStatusEnums status) {
    return status == DeployRecordStatusEnums.SUCCESS 
            || status == DeployRecordStatusEnums.FAILED
            || status == DeployRecordStatusEnums.REJECTED  // 新增
            || status == DeployRecordStatusEnums.CANCELLED
            || status == DeployRecordStatusEnums.TERMINATED
            || status == DeployRecordStatusEnums.PARTIAL_SUCCESS;
}

步骤4更新统计查询

-- 在统计查询中REJECTED 计入失败
SUM(CASE WHEN dr.status IN ('FAILED', 'REJECTED', 'CANCELLED', 'TERMINATED', 'PARTIAL_SUCCESS') 
    OR (dr.status = 'CREATED' AND TIMESTAMPDIFF(MINUTE, dr.create_time, NOW()) > 30) 
    THEN 1 ELSE 0 END) as failedCount

步骤5数据库迁移可选

如果已有审批被拒绝的记录,状态为 CANCELLED,可以考虑:

  • 保留现有数据(CANCELLED 继续表示审批被拒绝)
  • 或者迁移数据(将 CANCELLED 迁移为 REJECTED

结论

推荐新增 REJECTED 状态,用于明确表示"审批被拒绝",与工作流层面的 ApprovalResultEnum.REJECTED 保持一致。

保留 CANCELLED 状态,用于未来可能的手动取消部署功能。

这样既保证了语义清晰,又保留了扩展性。