Files
wecom_it_smart_desk/docs/03-测试文档/05-缺陷单/BUG-通用-快速回复规则-路由目标筛选500-002.md
T
Simon 44e77dcb0e chore(docs): docs/ 目录全面重新编号 + 重组
**重构前**(旧编号 02-11):
- docs/02-产品需求/      → 00 产品规划/PRD
- docs/03-技术架构/      → 01-05 子目录散落
- docs/04-原型设计/      → 01-02 产品设计(HTML 原型)
- docs/05-原型设计/      → screens/
- docs/06-测试素材/      → 02-E2E / 03-功能 / 04-版本测试
- docs/07-项目管理/      → 任务说明书/日报/计划
- docs/08-安全审计/      → 审计报告
- docs/09-堡垒运维/      → toolbox / deploy
- docs/10-项目管理/      → 任务说明书(重复)
- docs/11-历史归档/      → deploy-nas-archived

**重构后**(新编号 00-07,语义化):
- docs/00-产品开发流程与文档管理规范.md
- docs/00-版本迭代总览.md
- docs/01-产品文档/      (PRD/原型/认证/会话/AI 服务/坐席/集成)
- docs/02-技术文档/      (技术方案/架构图/重构记录/前端改造/实现配置)
- docs/03-测试文档/      (E2E/功能用例/版本报告/缺陷单)
- docs/04-运维文档/      (部署运维/运维指南)
- docs/05-运营文档/      (品牌推广/用户手册)
- docs/06-安全审计/      (审计报告)
- docs/07-项目管理/      (任务说明书/日报/计划/看板)

**净收益**:
- 目录编号与产品文档管理规范对齐(按文档阶段 01-07 编号)
- 消除 02-产品需求 与 10-项目管理 的编号重叠
- 子目录按文档类型分组(如 01-产品文档/00-产品规划、01-产品文档/01-认证与登录)
- 把运维/安全/项目管理从 0X 散落改为 04/06/07

合计 494 文件 + 78495 行 / - 14076 行
2026-08-03 18:46:55 +08:00

9.8 KiB
Raw Blame History

缺陷单:快速回复规则「路由目标」筛选分类下拉菜单 500 错误

缺陷编号: BUG-通用-002 版本: v1.0 状态: [已关闭] 优先级: P1-High 发现日期: 2026-07-28 发现人: 宋献 指派人: 宋献 修复人: Duckula (AI助手) 关闭日期: 2026-07-28 处理方式: 自动处理和验证 关联需求: REQ-通用-002(快速回复规则后台管理) 关联文档:

  • PRD: docs/01-产品文档/00-产品规划/PRD-REQ-通用-002-快速回复规则后台管理-v1.2.md
  • 技术方案: docs/02-技术文档/技术方案-REQ-通用-002-快速回复规则后台管理.md
  • 任务说明书: docs/07-项目管理/任务说明书/任务说明书-131-快速回复规则后台管理.md
  • 故障手册: docs/04-运维文档/部署运维/00-标准故障排查手册.mdCASE-20260728-05

1. 基本信息

字段 内容
缺陷标题 管理后台 → 快速回复规则 → "路由目标" tab → 点击"业务分类"下拉菜单 → 提示"服务器内部错误,请稍后重试或联系管理员"
影响范围 管理员/运营人员使用「路由目标」筛选的全部场景(共 6 条 routing_target 规则无法按分类筛选)
涉及模块 管理后台(frontend-admin+ 后端 APIbackend FastAPI
涉及文件 src/backend/app/api/admin/quick_rules.pyQuickRuleResponse 模型)
src/backend/scripts/init_quick_rules.sqlrouting_target 初始数据)
触发条件 1. 登录管理后台 → /itadmin/quick-rules
2. 切换到"路由目标" Tab
3. 点击"业务分类"下拉菜单(前端会带 ?rule_type=routing_target&category=XXX/api/admin/quick-rules
预期行为 下拉菜单正常加载所有 6 条 routing_target 规则,下拉可选项覆盖已配置的 6 个分类
实际行为 下拉菜单触发 API 调用,后端返回 1005 通用错误,UI 弹窗"服务器内部错误,请稍后重试或联系管理员";其他 Tabgreeting、routing_prefilter)正常

2. 复现步骤

  1. 用管理员账号登录管理后台 https://itsupport.servyou.com.cn/itadmin/
  2. 进入「快速回复规则」页面(路由 /itadmin/quick-rules
  3. 切换到 "路由目标" Tab(默认显示 6 条记录)
  4. 点击任意筛选条件中的 "业务分类" 下拉菜单
  5. 观察前端弹窗 → 显示「服务器内部错误,请稍后重试或联系管理员」
  6. 检查浏览器 F12 → Network → /api/admin/quick-rules?rule_type=routing_target&category=XXX → HTTP 200 但 code:1005

影响截图

  • 页面:快速回复规则 → 路由目标 Tab
  • 区块:筛选条件行
  • 元素:业务分类下拉菜单

3. 根因分析

三层根因(缺一不可)

3.1 数据层(DB):routing_target 记录 priority 字段为 NULL

scripts/init_quick_rules.sql 第 80 行的 routing_target INSERT 语句 未指定 priority

-- 错误(routing_target 段):没有 priority 字段
INSERT INTO quick_rules (rule_type, category, keyword, extra_data, is_active) VALUES
('routing_target', '行政', '机票酒店前台', '{...}', true),
('routing_target', '人力资源', '人力资源共享服务咨询', '{...}', true),
...

greetingrouting_prefilter 段正确指定了 priority

-- 正确(greeting 段)
INSERT INTO quick_rules (rule_type, keyword, priority, is_active) VALUES
('greeting', '你好', 10, true),
...

结果DB 中 6 条 routing_target 记录 priorityNULL

3.2 模型层(Pydantic):QuickRuleResponse.priority 声明为非 Optional

app/api/admin/quick_rules.py:77 原始定义:

class QuickRuleResponse(BaseModel):
    """规则响应"""
    id: int
    rule_type: str
    category: Optional[str] = None
    keyword: str
    priority: int          # ← 未声明 Optional
    response_template: Optional[str] = None
    extra_data: Optional[dict] = None
    is_active: bool
    created_at: str

Pydantic 序列化时严格校验 priority 必须是 int,遇到 None → 抛 ValidationError

3.3 中间件层:catch_errors_and_log 捕获所有异常后返回 1005

全局 catch_errors_and_log 中间件捕获 Pydantic ValidationError 后,统一返回 1005 通用错误,前端无法区分 Pydantic 校验失败与其他 500 错误,被迫显示"服务器内部错误"。

错误日志(诊断依据)

pydantic_core._pydantic_core.ValidationError: 1 validation error for QuickRuleResponse
priority
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]

额外发现(隐藏 bug

排查中用 AST 校验发现,本地 quick_rules.py 上线前已存在 3 处遗留语法错误

  • 2 处 )) 文本多余括号
  • 1 处文件结尾 ) 缺失

若直接 upload,容器内 Python 启动会 SyntaxError。


4. 处理办法

项目 内容
处理策略 自动处理和验证
执行时机 立即(影响正常业务使用)
处理流程 1. 修复 QuickRuleResponse.priority 字段类型 + 5 个字段补 Optional
2. 修复 init_quick_rules.sql 补齐 priority
3. DB 实时回填 6 条 NULL 记录
4. 修复本地遗留语法错误
5. AST 静态校验 + 端到端 API 验证
验证方式 8 个 API 测试用例(rule_type + 6 个分类 + 1 个不存在的分类)
回滚方案 priority 字段从 v1.0int)回退到破坏前的状态会重新触发 bug;回滚 = 同步回退模型定义、SQL 脚本、DB 数据,仅建议在测试环境尝试

5. 修复方案

5.1 代码修复(3 处)

修复 1app/api/admin/quick_rules.py(第 77-89 行)

class QuickRuleResponse(BaseModel):
    """规则响应"""
    id: int
    rule_type: str
    category: Optional[str] = None
    keyword: str
    # priority 在 DB 中允许 NULLrouting_target 类型的 SQL 初始数据未指定 priority
    # 序列化时若为 None 则按 0 处理,避免 Pydantic ValidationError
    priority: Optional[int] = None
    response_template: Optional[str] = None
    extra_data: Optional[dict] = None
    is_active: bool
    created_at: str

修复 2scripts/init_quick_rules.sql(第 80 行)

-- 修复前
INSERT INTO quick_rules (rule_type, category, keyword, extra_data, is_active) VALUES

-- 修复后
INSERT INTO quick_rules (rule_type, category, keyword, extra_data, priority, is_active) VALUES

并为 6 条 routing_target 记录添加 0 作为 priority 值。

修复 3DB 实时回填

UPDATE quick_rules SET priority = 0 WHERE priority IS NULL;

修复 4(隐藏):本地语法错误

清理 2 处 )) 和 1 处 )


6. 验证结果

6.1 自动化 API 验证(8/8 通过)

测试用例 期望 实际 结果
rule_type=routing_target 6 条 6 条 PASS
category=行政 1 条 1 条 PASS
category=人力资源 1 条 1 条 PASS
category=财务 1 条 1 条 PASS
category=法务 1 条 1 条 PASS
category=行政-物业 1 条 1 条 PASS
category=IT服务 1 条 1 条 PASS
category=不存在的分类 0 条 0 条 PASS

6.2 后端日志验证

  • 修复前:pydantic_core._pydantic_core.ValidationError: ... priority Input should be a valid integer
  • 修复后:GET /admin/quick-rules?rule_type=routing_target&category=... HTTP/1.1 200 OK(无 ValidationError

6.3 真实浏览器验证

待用户在管理后台手动点击下拉菜单复测(端到端 UI 验证)。

6.4 AST 静态校验

  • 本地:python -c "import ast; ast.parse(open('quick_rules.py', encoding='utf-8').read())" OK
  • 容器内:python3 /tmp/check_syntax.py /app/app/api/admin/quick_rules.py OK

7. 关联信息

  • 关联需求: REQ-通用-002(快速回复规则后台管理)
  • 关联 PRD: docs/01-产品文档/00-产品规划/PRD-REQ-通用-002-快速回复规则后台管理-v1.2.md
  • 关联技术方案: docs/02-技术文档/技术方案-REQ-通用-002-快速回复规则后台管理.md
  • 关联任务说明书: docs/07-项目管理/任务说明书/任务说明书-131-快速回复规则后台管理.mdv1.3
  • 关联故障手册: docs/04-运维文档/部署运维/00-标准故障排查手册.mdCASE-20260728-05
  • 修复代码文件:
    • src/backend/app/api/admin/quick_rules.pyQuickRuleResponse 模型)
    • src/backend/scripts/init_quick_rules.sqlrouting_target 初始数据)
  • API 测试脚本: scripts/verify_api.py

8. 变更记录

日期 版本 变更内容 变更人 变更原因 影响范围
2026-07-28 v1.0 创建缺陷单,记录快速回复规则"路由目标"分类筛选 500 错误 宋献 / Duckula 用户反馈业务查询无法使用 管理后台 "快速回复规则" 页面
2026-07-28 v1.0 修复 QuickRuleResponse.priority 字段类型 + 修复 SQL 初始数据 + DB 实时回填 Duckula 数据库字段为 NULL 但 Pydantic 模型要求非空 后端 API + 数据库
2026-07-28 v1.0 修复本地遗留语法错误(2 处 )) + 1 处 ) Duckula AST 校验发现隐藏 bug quick_rules.py
2026-07-28 v1.0 端到端 API 验证(8/8 通过)+ AST 静态校验 Duckula 确认修复实际生效 验证脚本与容器部署
2026-07-28 v1.0 文档规范化整改:故障手册新增 CASE-20260728-05、任务说明书 v1.2→v1.3、缺陷单 README 追加清单 Duckula 规范化要求 BUG 修复需同步周边文档 文档体系

缺陷已关闭。本案例作为"CASE-20260728-05"收录于故障排查手册,供后续排查参考。