# PRD — UI 自动化用例串行执行机制

## 需求背景

### 问题现象
并发执行 UI 自动化用例时，通过率仅 **20%**（1/5），单独执行时通过率可达 **60%**（3/5）。

### 根因分析
1. **Playwright 浏览器实例共享页面状态**
   - 当前实现中，多个执行记录可以同时运行
   - 并发执行时，多个用例共享同一个浏览器页面
   - 导致状态互相干扰（如一个用例点击菜单影响另一个用例的页面）

2. **执行服务未做串行控制**
   - `execution_service.py` 只实现了单个执行记录内用例串行
   - 未对多个执行记录的并发做限制

### 影响范围
- 所有 UI 自动化用例（`case_type='ui'`）
- 前端执行页面（用户点击执行按钮）

---

## 解决方案

### 核心设计
在 `execution_service.py` 中添加全局执行锁，确保同一时间只有一个 UI 执行任务在运行。

### 实现要点

1. **全局执行状态管理**
   ```python
   _execution_lock = threading.Lock()
   _running_execution_id: Optional[str] = None
   _running_execution_lock = threading.Lock()
   ```

2. **执行前检查**
   - 发起执行请求时，先检查是否有其他任务正在运行
   - 如有，直接拒绝并返回错误信息

3. **执行完成后释放锁**
   - 在 `finally` 块中释放锁，确保异常时也能释放

4. **新增 API 端点**
   - `GET /api/executions/running-status` - 查询当前是否有 UI 任务运行

---

## 改动文件

| 文件 | 改动说明 |
|------|---------|
| `backend/app/services/execution_service.py` | 添加全局执行锁、执行前检查、执行后释放 |
| `backend/app/models/execution.py` | 新增 `error_message` 字段，用于记录执行失败原因 |
| `backend/app/routers/executions.py` | 新增 `/running-status` API 端点，导出 `is_execution_running` |

---

## API 变更

### 新增：GET /api/executions/running-status

**描述**：查询当前是否有 UI 执行任务正在运行

**响应**：
```json
{
  "is_running": true,
  "execution_id": "exec_xxx"
}
```

---

## 错误处理

当有其他任务运行时，新执行请求会返回 400 错误：

```json
{
  "detail": "已有 UI 执行任务 exec_xxx 正在运行，请等待完成后再执行"
}
```

---

## 验收标准

1. 同一时间只能有一个 UI 执行任务运行
2. 执行完成后锁被正确释放
3. 异常情况也能正确释放锁
4. API 返回正确的运行状态

---

## 后续优化

1. **前端优化**：执行按钮在有任务运行时禁用，显示等待提示
2. **队列机制**：支持多个执行请求排队等待，而不是直接拒绝
3. **执行优先级**：支持高优先级任务插队

---

## 创建记录

- **创建时间**：2026-08-06
- **创建者**：czj
- **关联问题**：P0 - 实现用例串行执行机制