# Remediation 审批流优化设计

## 1. 背景

当前 Remediation Ticket 已经具备完整的基础审批能力：

- 创建 Ticket
- 提交当前阶段
- 生成审批
- 审批通过 / 驳回
- 推进到下一阶段
- 查询审批记录和进度

但从使用体验和系统设计上看，当前 Remediation 审批仍有几个明显短板：

- 状态流转语义不够清晰
- 审批人解析方式过于静态
- 页面无法稳定展示完整审批流
- 前端对审批阶段和审批人信息仍需自行推断

因此，本设计的目标是优先优化 Remediation 审批这块，围绕以下三个方面推进：

1. 优化状态流转模型
2. 将审批人做成可配置
3. 在 Remediation 页面完整展示审批流，包括每个节点由谁审批、当前状态、历史结果

## 2. 当前实现现状

## 2.1 当前接口与数据来源

当前 Remediation 详情页主要依赖以下接口：

- `GET /api/v1/devops/remediationtickets/:ticket_id`
- `GET /api/v1/devops/remediationtickets/:ticket_id/ticket_approvals`
- `GET /api/v1/devops/remediationtickets/:ticket_id/progress`
- `POST /api/v1/devops/remediationtickets/:ticket_id/submit`
- `POST /api/v1/devops/remediationtickets/:ticket_id/approve`
- `POST /api/v1/devops/remediationtickets/:ticket_id/reject`

相关 controller 入口见：

- [remediationticket_controller.go](/Users/xie/GolandProjects/devops-work/devops-work/pkg/controller/remediationticket/remediationticket_controller.go)
- [remediationticket.go](/Users/xie/GolandProjects/devops-work/devops-work/pkg/controller/remediationticket/remediationticket.go)

## 2.2 当前状态模型

当前系统实际上同时依赖四类信息来表达审批状态：

- `ticket.phase`
- `ticket.status`
- `ticket.appr_id`
- `remediation_ticket_approvals`

Ticket 级状态来自：

- `pending`
- `approving`
- `approved`
- `rejected`
- `closed`

定义见：

- [entity/remediation_ticket.go](/Users/xie/GolandProjects/devops-work/devops-work/entity/remediation_ticket.go)

阶段推进主要由 actor 和 approval service 协同完成：

- `actor_pending.go`
- `actor_approving.go`
- `actor_rejected.go`

## 2.3 当前审批人解析方式

当前审批人主要来自后端配置文件，并通过 helper 在运行时解析：

- region_tse_leader：按 biz region 选固定邮箱
- rdg_sla_owner：按 cluster type 选固定邮箱
- 其他阶段：固定 person

实现位置：

- [helpers.go](/Users/xie/GolandProjects/devops-work/devops-work/pkg/service/remediationticket/helpers/helpers.go)
- [config_services.go](/Users/xie/GolandProjects/devops-work/devops-work/pkg/infra/config/config_services.go)

## 2.4 当前页面展示问题

当前前端页面已经有：

- 详情信息区
- 当前阶段交互面板
- 部分步骤展示

但仍有以下不足：

- 无法稳定展示完整审批流
- 无法直接看到每个节点的审批人
- 页面展示依赖对 `ticket + approval` 的组合推断
- 当前节点之外的信息不完整
- 审批历史、reject 原因、节点状态缺少统一视图

## 3. 问题定义

## 3.1 状态流转表达不清晰

当前系统里：

- `phase` 表示流程走到哪里
- `status` 表示当前 ticket 的状态
- `appr_id` 表示关联中的审批
- `ticket_approvals` 表示阶段间的审批记录

这在后端实现上可以工作，但对前端和使用者来说并不直观：

- 要理解一个 ticket 卡在哪，必须同时看多份数据
- 页面必须自行推断“当前审批节点”
- 系统很难直接输出一条清晰的审批流视图

## 3.2 审批人配置不灵活

当前审批人解析方式的问题：

- 主要依赖固定邮箱
- 缺少 group / role / 多 approver 支持
- Global Desk 等阶段扩展性不足
- 配置改动缺少统一抽象

## 3.3 审批流缺少完整投影视图

当前系统虽然有：

- progress
- ticket approvals

但缺少一个统一的“审批流视图”接口。

结果是：

- 前端无法直接渲染完整流程
- 每个阶段的 approver 不完整
- 历史节点和未来节点展示不一致

## 4. 设计目标

本次优化目标如下：

### 4.1 短期目标

- 在页面中展示完整审批流
- 可以看到每个节点的审批人
- 可以看到当前节点、历史节点、驳回节点、未来节点的状态
- 审批人不再只依赖硬编码邮箱

### 4.2 中期目标

- 统一审批流投影视图
- 统一审批人解析逻辑
- 降低前端对流程推断的依赖

### 4.3 长期目标

- 为声明式 workflow 重构铺路
- 为更复杂的审批策略、多 approver、动态角色提供基础

## 5. 设计原则

- 后端负责输出真实、完整、可渲染的审批流视图
- 前端不再自行推断流程结构
- 审批人与流程定义解耦
- 优先兼容当前表结构和接口，避免一次性重构
- 第一阶段先补“投影视图”，第二阶段再优化核心流转模型

## 6. 方案概述

本次设计分三部分：

1. 新增审批流聚合视图
2. 抽象审批人解析器
3. 重整状态流转表达

## 7. 新增审批流聚合视图

## 7.1 新增接口

建议新增接口：

- `GET /api/v1/devops/remediationtickets/:ticket_id/approval_flow`

该接口不是替代现有接口，而是聚合：

- ticket
- progress
- ticket approvals
- approval service 状态
- phase definition
- approver resolution

供前端直接渲染完整审批流。

## 7.2 返回结构建议

建议返回结构如下：

```json
{
  "ticket_id": 123,
  "current_phase": "rdg_sla_owner",
  "current_status": "approving",
  "nodes": [
    {
      "phase": "created",
      "label": "Creator",
      "current": false,
      "status": "approved",
      "approvers": [
        {
          "type": "user",
          "id": "alice@pingcap.com",
          "name": "Alice",
          "email": "alice@pingcap.com"
        }
      ],
      "approval_id": 1001,
      "operator": "alice@pingcap.com",
      "operated_at": "2026-04-15T10:00:00Z",
      "message": ""
    }
  ]
}
```

## 7.3 节点状态定义

建议统一以下节点级状态：

- `unreached`
- `pending`
- `approving`
- `approved`
- `rejected`
- `skipped`

说明：

- `pending`：阶段已到达，当前责任人可提交
- `approving`：已发起审批，等待审批人处理
- `approved`：该节点已完成
- `rejected`：该节点审批被驳回
- `unreached`：尚未到达
- `skipped`：流程分支未经过该节点

## 7.4 聚合逻辑

后端生成审批流时，按 phase definition 遍历所有节点：

- 对已到达阶段，从 ticket approvals / progress / approval 状态中恢复节点状态
- 对当前阶段，从 ticket 当前 `phase + status` 投影节点状态
- 对未来阶段，标记为 `unreached`
- 对未经过的分支节点，标记为 `skipped`

这样前端只消费统一视图，不再直接拼接多个接口。

## 8. 审批人配置化设计

## 8.1 当前问题

当前审批人逻辑耦合在 helper 中，且以固定邮箱为主，不利于扩展。

## 8.2 目标

支持以下 approver 配置类型：

- 固定用户
- 固定用户组
- 按 region 解析
- 按 cluster type 解析

## 8.3 建议配置模型

建议新增更明确的审批人配置定义，例如：

```yaml
remediationTicket:
  approvalFlow:
    region_tse_leader:
      approvers:
        - type: region_role
          mapping:
            APAC: tse_leader_apac
            EMEA: tse_leader_emea
            JP: tse_leader_jp
            NA: tse_leader_na
    rdg_sla_owner:
      approvers:
        - type: cluster_type_role
          mapping:
            serverless: rdg_sla_owner_serverless
            dedicated_multi_tidb: rdg_sla_owner_dedicated
            dedicated_single_tidb: rdg_sla_owner_dedicated
    global_deal_desk:
      approvers:
        - type: user_group
          group: global_deal_desk
```

## 8.4 新增 Resolver 抽象

建议新增：

- `ApproverResolver`

职责：

- 输入：ticket + phase + config
- 输出：approver list

输出不仅用于发送 approval，也用于审批流展示。

这一步非常关键，因为页面想展示“每个节点谁在审批”，前提就是系统必须能稳定解析出“该节点理论审批人列表”。

## 8.5 落地策略

第一阶段不必接组织系统，只需：

- 允许固定 user / fixed group / region mapping / cluster type mapping
- 为后续接角色系统预留接口

## 9. 状态流转优化设计

## 9.1 当前问题

当前 `ticket.status` 同时承担了：

- 是否可提交
- 是否等待审批
- 是否被驳回
- 是否终态

这会导致 ticket 级状态和节点级状态混杂。

## 9.2 建议方向

短期不强改数据库，先做“投影视图层优化”。

即：

- 保留当前 `ticket.phase + ticket.status + appr_id`
- 在 service 层统一映射为 node-level state

中长期再考虑把：

- ticket-level lifecycle
- node-level approval state

拆开表达。

## 9.3 Ticket 级与 Node 级职责建议

建议区分：

### Ticket 级

- `active`
- `succeed`
- `closed`

### Node 级

- `pending`
- `approving`
- `approved`
- `rejected`
- `unreached`
- `skipped`

本次设计第一阶段不强制落地新的 ticket status，而是先在聚合接口里用这一层抽象对外表达。

## 10. 前端展示方案

## 10.1 页面目标

在 Remediation 页面中完整展示：

- 全部审批节点
- 每个节点的审批人
- 当前节点
- 节点状态
- 历史审批结果
- reject message

## 10.2 页面结构建议

建议在详情页新增或替换为：

### A. 审批流总览区

使用纵向步骤或时间线展示所有 phase：

- Phase 名称
- 审批人列表
- 节点状态
- 审批时间
- 审批结果

### B. 当前节点详情区

当节点为当前节点时，展示：

- 当前责任人
- 当前 approver
- 待提交 / 待审批 / 已驳回提示

### C. 审批历史区

按 approval record 展示：

- from phase
- to phase
- approver
- 操作结果
- message
- 时间

## 10.3 前端实现原则

- 前端不再用 `ticket + ticket_approvals` 自己推理完整流程
- 优先消费新的 `approval_flow` 接口
- `RemediationTicketSteps`、`RemediationInteractPanel`、callout 区统一基于 flow model 渲染

## 11. 数据与接口改造范围

## 11.1 后端新增

- `ApprovalFlowNode` DTO
- `RemediationApprovalFlow` DTO
- `GetApprovalFlow(ticketId)` service
- `GET /remediationtickets/:ticket_id/approval_flow` controller
- `ApproverResolver` 抽象

## 11.2 后端暂不强制改动

- remediation ticket 主表结构
- 当前 actor / phase 核心执行链路
- approval service 接口

## 11.3 前端新增

- `RemediationApprovalFlowPanel`
- 基于 flow 的完整审批流展示

## 11.4 前端调整

- 现有 `RemediationTicketSteps`
- 现有 `RemediationInteractPanel`
- approval history 展示逻辑

## 12. 分阶段实施计划

## 12.1 第一阶段：完整审批流可视化

### 目标

先解决“看不见”的问题。

### 范围

- 新增 `approval_flow` 聚合接口
- 页面展示完整流程
- 展示每个节点审批人、状态、历史结果

### 收益

- 用户能一眼看出卡在哪个节点
- 用户能看到每个节点是谁在审批
- 现有审批体验显著提升

## 12.2 第二阶段：审批人配置化

### 目标

让 approver 解析脱离硬编码邮箱。

### 范围

- 引入 `ApproverResolver`
- 支持 fixed user / group / region / cluster type
- 支持 Global Desk 多 approver

### 收益

- 配置灵活性提升
- 扩展更多阶段更容易

## 12.3 第三阶段：状态流转模型收敛

### 目标

让 ticket-level 与 node-level 状态表达更清晰。

### 范围

- 收敛 status 语义
- 减少前端对 `appr_id` 的直接依赖
- 为声明式 workflow 铺路

### 收益

- 状态机更易理解
- 后续流程演进更低风险

## 13. 风险与注意事项

### 13.1 风险一：聚合接口与现有逻辑不一致

需要确保新的 `approval_flow` 是对现有 ticket / approval 真实状态的正确投影。

### 13.2 风险二：审批人配置化后与原 helper 结果不一致

建议第一阶段保留现有 helper 作为默认 resolver，实现逻辑一致后再替换。

### 13.3 风险三：前端展示改造范围较大

建议先新增 flow panel，而不是一开始就完全替换现有 steps / interact panel。

## 14. 推荐优先顺序

1. 新增 approval flow 聚合接口
2. 页面渲染完整审批流
3. 抽象 approver resolver
4. 配置化审批人
5. 收敛状态流转模型

## 15. 结论

Remediation 审批当前最主要的问题不是“没有流程”，而是：

- 流程真实状态不能被完整看见
- 审批人规则扩展性不足
- 状态表达不够清晰

因此最合理的改造路径不是直接推翻现有状态机，而是：

- 先补齐完整审批流投影视图
- 再把审批人配置化
- 最后逐步收敛状态流转模型

这样既能尽快改善用户体验，也能为后续更大规模的 workflow 重构提供稳定基础。
