# PRD_需求文档_P1收尾三项

## 基本信息

| 项目 | 内容 |
|------|------|
| 文档类型 | 需求文档 |
| 创建日期 | 2026-07-14 |
| 负责人 | 研发组 |
| 优先级 | P1（高优先级） |
| 状态 | ✅ 全部完成 |

---

## 一、背景与目标

### 1.1 问题背景

P1-1/P1-2/P1-3 三项主任务已完成并部署，但遗留三处收尾工作：

| 编号 | 问题 | 影响 |
|------|------|------|
| 收尾-1 | routes 层错误响应未统一 | 33 处 jsonify 格式散乱，无错误码，前端难以统一处理 |
| 收尾-2 | routes 层零单元测试 | P1-3 重构的路由层无回归保障，改一处怕动全身 |
| 收尾-3 | submit/export 路由未鉴权 | 任何人（含未登录）可调用提交记录/导出报告，安全风险 |

另外 `Docs/PRD_需求文档_项目优化方向.md` 的 P1 状态显示"待开始"，与实际不符。

### 1.2 修复目标

1. **统一错误响应**：routes 错误响应全部走 `error_response`（带 code/message 对象格式），前端兼容适配
2. **路由层测试**：5 个 Blueprint 补 Flask test_client 单元测试
3. **补鉴权**：submit/export 加 `@login_required`
4. **文档同步**：优化方向文档 P1 状态更新

---

## 二、需求详情

### 2.1 收尾-1：统一错误响应

#### 现状

routes 层错误响应格式不统一：
```python
# 现状（无错误码）
return jsonify({"success": False, "error": "请输入问题描述"}), 400
```

#### 目标格式

```python
# 统一后（带错误码对象）
return jsonify(error_response(ErrorCodes.INVALID_PARAM, "请输入问题描述")), 400
# 返回：{"success": False, "error": {"code": 1001, "message": "请输入问题描述"}}
```

#### 涉及范围

| 文件 | 错误响应数 | 错误码映射 |
|------|-----------|-----------|
| `routes/auth.py` | 2 | INVALID_PARAM / UNAUTHORIZED |
| `routes/troubleshoot.py` | 6 | INVALID_PARAM / UNKNOWN_ERROR / SEARCH_QUERY_ERROR / AI_API_ERROR |
| `routes/cache.py` | 2 | CACHE_READ_ERROR / CACHE_WRITE_ERROR |
| `routes/export.py` | 1 | EXPORT_ERROR |
| `routes/submit.py` | 4 | INVALID_PARAM / RECORD_SUBMIT_ERROR |
| `decorators.py` | 2 | UNAUTHORIZED / FORBIDDEN |

#### 前端兼容

前端 5 处按 `data.error`（字符串）读，改对象后显示 `[object Object]`。需在前端加 `errMsg(e)` 工具函数兼容字符串/对象两种格式。

#### 错误码扩展

`utils/error_codes.py` 补 4 个：UNAUTHORIZED(1004) / FORBIDDEN(1005) / EXPORT_ERROR(1006) / RECORD_SUBMIT_ERROR(1007)。

#### 验收标准

- [x] routes 错误响应统一为 `{success, error:{code, message}}`
- [x] 前端 5 处兼容，错误提示正常显示
- [x] 成功响应格式不变（只统一错误响应）
- [x] SSE 流式错误格式不变（自有 type/message 体系）

---

### 2.2 收尾-2：路由层单元测试

#### 现状

P1-2 测了 search_engine/safety_filter/cache_manager 三个纯逻辑模块（94 用例），routes/ 5 个 Blueprint 零测试。

#### 需求规格

| 需求项 | 规格 |
|--------|------|
| 测试框架 | pytest + Flask test_client |
| 覆盖范围 | routes/ 5 个文件 |
| mock 策略 | AI 调用、缓存目录、索引重建、文件写入全部隔离 |
| 权限覆盖 | 未登录 401 / 普通用户 / 管理员 |

#### 测试用例规划

| 测试文件 | 用例数 | 覆盖场景 |
|---------|--------|---------|
| test_routes_auth.py | 11 | 登录成功/失败/空参、注销、user_info 权限、index 重定向 |
| test_routes_troubleshoot.py | 12 | troubleshoot/search/analyze 成功+空参、stream 正常+空参+缓存、health/projects/categories |
| test_routes_cache.py | 6 | stats/clear 的未登录/普通/管理员 |
| test_routes_export.py | 3 | 鉴权、导出成功、空参 |
| test_routes_submit.py | 5 | 鉴权、三个必填校验、提交成功 |

#### 验收标准

- [x] 5 个路由测试文件已编写
- [x] 测试可通过 `pytest` 运行（全绿）
- [x] 原 94 用例无回归（合计 131 全绿）
- [x] 测试不真实调用 AI API、不碰真实缓存/文件

---

### 2.3 收尾-3：submit/export 补鉴权

#### 现状

```python
@bp.route('/api/submit', methods=['POST'])
def submit_record():  # 无 @login_required，任何人可调用
```

#### 需求规格

| 路由 | 加装饰器 | 理由 |
|------|----------|------|
| `/api/submit` | `@login_required` | 写入知识库需登录身份 |
| `/api/export` | `@login_required` | 导出报告需登录身份 |

#### 验收标准

- [x] submit/export 未登录返回 401
- [x] 已登录用户正常调用

---

### 2.4 收尾-4：文档同步

- [x] `PRD_需求文档_项目优化方向.md` P1 三项状态改完成

---

## 三、影响范围

### 3.1 涉及文件

| 文件/目录 | 变更类型 |
|-----------|----------|
| `utils/error_codes.py` | 修改（补 4 个错误码） |
| `decorators.py` | 修改（接入 error_response） |
| `routes/*.py` | 修改（5 个文件接入 error_response + submit/export 加鉴权） |
| `templates/index.html` | 修改（加 errMsg 工具函数 + 5 处调用适配） |
| `templates/login.html` | 修改（加 errMsg + 1 处调用适配） |
| `tests/conftest.py` | 修改（补 app/client/auth_client/admin_client fixture） |
| `tests/test_routes_*.py` | 新增（5 个测试文件，37 用例） |
| `Docs/PRD_需求文档_项目优化方向.md` | 修改（P1 状态同步） |

### 3.2 风险评估

| 风险项 | 等级 | 缓解措施 |
|--------|------|----------|
| 前端兼容遗漏 | 中 | Explore 精确定位 5 处 + curl 验证错误提示 |
| 路由测试真调 AI API | 高 | conftest autouse mock call_claude_api/call_claude_api_stream |
| container 单例跨测试污染 | 中 | monkeypatch 替换 get_cache_manager 函数 |
| submit/export 加鉴权后前端 401 | 中 | 已记录：当前显示"未登录"提示，不自动跳转（低频操作可接受） |

---

## 四、验收清单

### 收尾-1 验收
- [x] routes 错误响应统一为对象格式
- [x] 前端兼容适配
- [x] error_codes 补 4 个新码

### 收尾-2 验收
- [x] 5 个路由测试文件（37 用例）
- [x] 全量 131 用例全绿

### 收尾-3 验收
- [x] submit/export 加 @login_required
- [x] 未登录返回 401

### 收尾-4 验收
- [x] 优化方向文档 P1 状态同步
