Files
ai-customer-service/test/QA_CHECKLIST.md
Your Name cf46b27610 fix: P0-1 RateLimiter并发写安全 + P0-2工单操作错误码区分 + P1 rows.Close修复
P0-1 (limits.go): Allow()方法改为全程使用写锁保护counters map读写,避免RLock写入时的data race
P0-2 (ticket_workflow.go+ticket_handler.go): Assign/Resolve/Close操作先查询ticket存在性和状态,返回明确的CS_TICKET_4001/CS_TKT_4002/CS_TICKET_4092/CS_TICKET_4093错误码,handler根据错误前缀路由HTTP状态码
P1-1 (ticket_store.go): 移除GetStats中3处手动rows.Close(),只保留defer Close()
2026-05-01 20:56:25 +08:00

335 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI-Customer-Service 生产一期 QA 检查清单
> 生成时间2026-04-30
> 项目路径:/home/long/project/立交桥/projects/ai-customer-service
> 覆盖范围:文档-实现一致性 · 威胁建模 · AC/失败路径/安全/性能矩阵 · 灰度回滚 · 漂移检测 · 阻断条件
---
## 一、文档-实现一致性检查清单
### 1.1 接口路由一致性
| # | 文档接口INTERFACE.md | 代码实现 | 路由文件 | 状态 |
|---|--------------------------|----------|----------|------|
| 1 | `POST /api/v1/customer-service/webhook/{channel}` | ✅ 已实现 | `router.go``HandleChannel` | **一致** |
| 2 | `POST /api/v1/customer-service/webhook`(统一入口) | ✅ 已实现 | `router.go``Handle` | **一致** |
| 3 | `GET /api/v1/customer-service/tickets` | ✅ 已实现List 方法) | `router.go``/tickets` | **一致** |
| 4 | `GET /api/v1/customer-service/tickets/{id}` | ❌ **未实现** | 无 | **漂移** |
| 5 | `POST /api/v1/customer-service/tickets/{id}/assign` | ✅ 已实现 | `router.go``/tickets/*/assign` | **一致** |
| 6 | `POST /api/v1/customer-service/tickets/{id}/resolve` | ✅ 已实现 | `router.go``/tickets/*/resolve` | **一致** |
| 7 | `POST /api/v1/customer-service/tickets/{id}/close` | ✅ 已实现 | `router.go``/tickets/*/close` | **一致** |
| 8 | `GET /api/v1/customer-service/sessions/{id}` | ❌ **未实现** | 无 | **严重漂移** |
| 9 | `GET /api/v1/customer-service/sessions/{id}/messages` | ❌ **未实现** | 无 | **严重漂移** |
| 10 | `POST /api/v1/customer-service/sessions/{id}/feedback` | ❌ **未实现** | 无 | **严重漂移** |
| 11 | `POST /api/v1/customer-service/sessions/{id}/handoff` | ❌ **未实现**(仅通过 webhook 触发) | 无 | **严重漂移** |
| 12 | `GET /api/v1/customer-service/kb` | ❌ **未实现** | 无 | **漂移** |
| 13 | `POST /api/v1/customer-service/kb` | ❌ **未实现** | 无 | **漂移** |
| 14 | `GET /api/v1/customer-service/kb/{id}` | ❌ **未实现** | 无 | **漂移** |
| 15 | `PUT /api/v1/customer-service/kb/{id}` | ❌ **未实现** | 无 | **漂移** |
| 16 | `DELETE /api/v1/customer-service/kb/{id}` | ❌ **未实现** | 无 | **漂移** |
| 17 | `POST /api/v1/customer-service/kb/{id}/publish` | ❌ **未实现** | 无 | **漂移** |
| 18 | `POST /api/v1/customer-service/kb/search` | ❌ **未实现** | 无 | **漂移** |
| 19 | `GET /api/v1/customer-service/admin/dashboard` | ❌ **未实现** | 无 | **漂移** |
| 20 | `GET /api/v1/customer-service/admin/handoff-reasons` | ❌ **未实现** | 无 | **漂移** |
| 21 | `POST /api/v1/customer-service/admin/feedback-review` | ❌ **未实现** | 无 | **漂移** |
| 22 | `GET /api/v1/customer-service/tickets/stats` | ❌ **未实现** | 无 | **漂移** |
### 1.2 错误码一致性
| # | 文档错误码 | 代码实际错误码 | 状态 |
|---|-----------|---------------|------|
| 1 | `CS_SES_4001`(会话不存在) | 代码中无对应错误码(会话端点未实现) | **未使用** |
| 2 | `CS_SES_4002`(消息频率过高) | 代码中无对应错误码(速率限制未实现) | **未使用** |
| 3 | `CS_SES_4003`(身份校验已锁定) | 代码中无对应错误码 | **未使用** |
| 4 | `CS_IDT_4001`(身份信息不匹配) | 代码中无对应错误码 | **未使用** |
| 5 | `CS_IDT_4002`(验证码错误) | 代码中无对应错误码 | **未使用** |
| 6 | `CS_TKT_4001`(工单不存在) | 代码无 GET ticket/{id},无可触发路径 | **未使用** |
| 7 | `CS_TKT_4002`(工单已被分配) | `CS_TICKET_4091`(不等于文档) | **漂移** |
| 8 | `CS_KB_4001`(知识库条目不存在) | 知识库端点未实现 | **未使用** |
| 9 | `CS_KB_4002`(条目名称已存在) | 知识库端点未实现 | **未使用** |
| 10 | `CS_LLM_5001`LLM 服务不可用) | 代码中无对应错误码 | **未使用** |
| 11 | `CS_LLM_5002`LLM 超时) | 代码中无对应错误码 | **未使用** |
| 12 | `CS_AUTH_4001`(越权访问) | 代码中无对应错误码 | **未使用** |
### 1.3 业务逻辑一致性
| # | 文档要求 | 代码实现 | 一致性 |
|---|---------|---------|--------|
| 1 | 转人工后生成 P1 工单(敏感意图) | `handoff/service.go`:意图含 `NeedsHuman``Sensitive``ShouldHandoff=true``Priority=P1` | ✅ **一致** |
| 2 | 低置信度(<0.60)转人工 | `handoff/service.go``turnCount>=5 && confidence<0.7` → P2 工单(文档要求<0.60,代码使用<0.7 | ⚠️ **轻微漂移** |
| 3 | 对话上下文保留最近 6 轮 | `dialog/service.go`:超过 6 条时截断(`len(sess.Context)>6` | ✅ **一致** |
| 4 | 消息幂等去重 | `DedupRepository.TryRecord` 实现 | ✅ **一致** |
| 5 | HMAC 签名校验 | `webhook_security.go` 实现 HMAC-SHA256 | ✅ **一致** |
| 6 | 时间戳防重放 | `webhook_security.go` 有 MaxSkew 检查,无持久化 nonce | ⚠️ **部分一致** |
| 7 | content > 2000 字截断 | `webhook_handler.go` 返回 400不截断 | ⚠️ **漂移**(文档要求截断,代码拒绝) |
---
## 二、威胁建模到测试映射清单
### 2.1 威胁分类与测试覆盖
| 威胁类别 | 威胁项 | 测试函数 | 覆盖状态 | 说明 |
|---------|--------|---------|---------|------|
| **T1: Webhook 签名绕过** | T1.1: 无签名请求 | `webhook_handler_test.go:TestWebhookSecurityRejectsMissingSignature` | ✅ **已覆盖** | |
| | T1.2: 伪造签名 | 无测试 | ❌ **未覆盖** | |
| | T1.3: 时间戳重放(旧时间戳 within skew | 无测试 | ❌ **未覆盖** | |
| | T1.4: 篡改 body 后签名不匹配 | 无测试 | ❌ **未覆盖** | |
| **T2: 消息注入/重放** | T2.1: 重复 message_id 去重 | `dialog_service_test.go` 部分验证 | ⚠️ **部分覆盖** | dialog service 有去重,但无专门 E2E 测试 |
| | T2.2: 1 秒 10 消息频率攻击 | 无速率限制实现 | ❌ **未覆盖**(且功能不存在) |
| | T2.3: 超长消息 DoS>2000字 | `webhook_handler_test.go:TestWebhookRejectsLongContent` | ✅ **已覆盖** | |
| **T3: 意图注入/Prompt Injection** | T3.1: 恶意指令注入 | 无测试 | ❌ **未覆盖** | |
| | T3.2: 绕过关键词检测 | 无测试 | ❌ **未覆盖** | |
| **T4: 越权访问** | T4.1: 未授权用户访问他人工单 | 无 RBAC 测试 | ❌ **未覆盖** | |
| | T4.2: 跨用户会话隔离 | 无测试 | ❌ **未覆盖** | |
| | T4.3: 攻击者写操作返回 403 | 无测试 | ❌ **未覆盖** | |
| **T5: 审计绕过** | T5.1: 签名失败不记审计 | `webhook_handler_test.go:TestWebhookSecurityRejectsMissingSignature` 有审计检查 | ✅ **已覆盖** | |
| | T5.2: 非法 body 不记审计 | `webhook_handler_test.go:TestWebhookRejectsAndAuditsMissingFields` | ✅ **已覆盖** | |
| | T5.3: 工单状态变更审计 | `ticket_handler_test.go:TestTicketHandlerAssignAuditsStateChange` | ✅ **已覆盖** | |
| **T6: 错误信息泄露** | T6.1: 内部错误堆栈泄露 | 无测试 | ❌ **未覆盖** | |
| | T6.2: LLM 内部错误信息泄露 | 无测试 | ❌ **未覆盖** | |
| **T7: 适配层失控** | T7.1: NewAPI/Sub2API 消息格式异常 | 无测试 | ❌ **未覆盖** | |
| | T7.2: 渠道消息格式不匹配 | 无测试 | ❌ **未覆盖** | |
---
## 三、AC / 失败路径 / 安全 / 性能 / 灾备测试矩阵
### 3.1 AC 测试覆盖矩阵
| AC | 描述 | 测试函数 | 文件 | 覆盖状态 | 缺口说明 |
|----|------|---------|------|---------|---------|
| AC-01 | 多渠道消息接入 | `TestWebhook_MainPath`, `TestWebhook_InvalidPayload`, `TestWebhook_SignedRequestPath` | `webhook_e2e_test.go` | ⚠️ **部分覆盖** | 仅 widget 渠道测试Telegram/Discord/微信无测试 |
| AC-02 | 意图识别与知识库回复 | `TestDialogService_Process` | `dialog_service_test.go` | ⚠️ **部分覆盖** | 仅测试"查询额度"一条;无置信度边界、无 RAG 质量验证 |
| AC-03 | 用户数据只读查询 | 无测试 | - | ❌ **未覆盖** | supply-api 集成未实现 |
| AC-04 | 多轮对话与上下文保持 | 无专门测试 | - | ❌ **未覆盖** | 仅 dialog service 内隐验证,无独立测试 |
| AC-05 | 身份核验 | 无测试 | - | ❌ **未覆盖** | 身份核验功能未实现 |
| AC-06 | 大模型故障 Failover | 无测试 | - | ❌ **未覆盖** | 故障注入测试不存在 |
| AC-07 | 兜底回复与工单生成 | `TestWebhook_HandoffPath` | `webhook_e2e_test.go` | ⚠️ **部分覆盖** | 仅验证返回 200未验证工单内容 |
| AC-08 | 明确转人工 | `TestWebhook_HandoffPath` | `webhook_e2e_test.go` | ⚠️ **部分覆盖** | 仅触发意图,未验证工单生成内容 |
| AC-09 | 敏感意图自动转人工 | 无专门测试 | - | ❌ **未覆盖** | 无测试"退款"/"数据泄露"→P1 工单 |
| AC-10 | 工单后台分配与处理 | `TestTicketHandlerAssignAuditsStateChange`, `TestTicketHandlerResolveAuditsStateChange`, `TestTicketHandlerCloseRequiresResolution`, `TestTicketHandlerAssignPassesActorAndSourceIP`, `TestTicketHandlerClosePassesActorAndSourceIP` | `ticket_handler_test.go` | ✅ **已覆盖** | 测试较为完整 |
| AC-11 | 知识库条目管理 | 无测试 | - | ❌ **未覆盖** | 知识库端点未实现 |
| AC-12 | 对话埋点与监控 | 无测试 | - | ❌ **未覆盖** | metrics/tracing 未实现 |
| AC-13 | 权限边界 | 无测试 | - | ❌ **未覆盖** | RBAC 未实现 |
### 3.2 边缘/失败路径EC覆盖矩阵
| EC | 场景 | 测试函数 | 覆盖状态 | 缺口说明 |
|----|------|---------|---------|---------|
| EC-01 | 超长消息(>2000字 | `TestWebhookRejectsLongContent` | ✅ **已覆盖** | |
| EC-02 | 1秒10消息频率限制 | 无测试 | ❌ **未覆盖**(且功能不存在) | |
| EC-03 | 知识库无结果+低置信度 | 无测试 | ❌ **未覆盖** | |
| EC-04 | API Key 前缀匹配多账户 | 无测试 | ❌ **未覆盖** | |
| EC-05 | supply-api 超时 >3s | 无测试 | ❌ **未覆盖** | |
| EC-06 | 多渠道同时会话隔离 | 无测试 | ❌ **未覆盖** | |
| EC-07 | 用户发送图片/语音 | 无测试 | ❌ **未覆盖** | |
| EC-08 | 系统维护窗口期 | 无测试 | ❌ **未覆盖** | |
| EC-09 | 客服队列满员 | 无测试 | ❌ **未覆盖** | |
| EC-10 | 数据库连接池耗尽 | 无测试 | ❌ **未覆盖** | |
### 3.3 安全测试矩阵
| 安全测试项 | 测试函数 | 覆盖状态 | 说明 |
|-----------|---------|---------|------|
| Webhook HMAC 签名验证 | `TestWebhookSecurityRejectsMissingSignature`, `TestWebhookSecurityAcceptsSignedRequest` | ✅ **已覆盖** | |
| JSON schema/字段校验 | `TestWebhookRejectsUnknownFields`, `TestWebhookRejectsAndAuditsMissingFields` | ✅ **已覆盖** | |
| 请求体大小限制 | `TestWebhookRejectsLongContent` | ✅ **已覆盖** | |
| 幂等去重 | `dialog_service_test.go` 内隐验证 | ⚠️ **部分覆盖** | 无专门去重测试 |
| 速率限制 | 无测试 | ❌ **未覆盖** | 功能未实现 |
| RBAC 权限边界 | 无测试 | ❌ **未覆盖** | 功能未实现 |
| 审计日志完整性 | `TestWebhookRejectsAndAuditsMissingFields`, `ticket_handler_test.go` assign/resolve/close | ✅ **已覆盖** | 成功路径和 webhook 拒绝路径有覆盖 |
| 错误信息脱敏 | 无测试 | ❌ **未覆盖** | |
| Prompt Injection | 无测试 | ❌ **未覆盖** | |
| 跨用户会话隔离 | 无测试 | ❌ **未覆盖** | |
### 3.4 性能测试矩阵
| 性能指标 | 文档目标 | 测试函数 | 覆盖状态 |
|---------|---------|---------|---------|
| 对话首次响应 P99 < 5s | <5s | 无测试 | ❌ **未覆盖** |
| 意图识别 P99 < 5s | <5s | 无测试 | ❌ **未覆盖** |
| Token 查询 P99 < 3s | <3s | 无测试 | ❌ **未覆盖** |
| 工单看板加载 < 2s | <2s | 无测试 | ❌ **未覆盖** |
| 向量检索 P99 < 200ms | <200ms | 无测试 | ❌ **未覆盖** |
| 模型 Failover 切换 < 5s | <5s | 无测试 | ❌ **未覆盖** |
| 会话历史加载 < 1s | <1s | 无测试 | ❌ **未覆盖** |
### 3.5 灾备/恢复测试矩阵
| 灾备场景 | 测试函数 | 覆盖状态 |
|---------|---------|---------|
| 主模型 500 切换备用 | 无测试 | ❌ **未覆盖** |
| 主模型超时切换备用 | 无测试 | ❌ **未覆盖** |
| 双模型均故障 → 兜底回复 | 无测试 | ❌ **未覆盖** |
| PostgreSQL 故障 → 降级 | 无测试 | ❌ **未覆盖** |
| Redis 故障 → 降级 | 无测试 | ❌ **未覆盖** |
| 备份恢复演练 | 无测试 | ❌ **未覆盖** |
---
## 四、灰度与回滚演练检查表
### 4.1 灰度发布门禁
| # | 检查项 | 当前状态 | 是否可执行 | 备注 |
|---|--------|---------|-----------|------|
| 1 | 所有 AC 测试用例 100% 通过 | ❌ | 不可执行 | AC-03/04/05/06/09/12/13 完全无测试 |
| 2 | 单元测试覆盖率达标domain ≥70%, service/handler ≥80% | ❌ | 不可执行 | 无覆盖率报告 |
| 3 | 意图识别准确率测试20 个常见问题,正确率 ≥85% | ❌ | 不可执行 | 无准确率测试 |
| 4 | RAG 检索质量测试20 个查询Recall@3 ≥80% | ❌ | 不可执行 | 无 RAG 质量测试 |
| 5 | 模型 Failover 演练(主/备故障场景全部通过) | ❌ | 不可执行 | 无故障注入测试 |
| 6 | 安全渗透测试权限越界、Prompt Injection | ❌ | 不可执行 | 无渗透测试 |
| 7 | 性能基准测试通过 | ❌ | 不可执行 | 无性能测试 |
| 8 | OpenAPI 文档与实现一致 | ❌ | 不可执行 | 接口漂移 16+ 项 |
### 4.2 回滚演练检查
| # | 回滚场景 | 检查步骤 | 当前状态 |
|---|---------|---------|---------|
| 1 | 回滚 webhook 路由变更 | 1. 重启服务 2. POST /webhook → 200 3. 检查审计日志 | ⚠️ 部分可执行 |
| 2 | 回滚工单 API 变更 | 1. 分配工单 2. 检查 audit_store 写入 3. GET /tickets → 列表正常 | ⚠️ 部分可执行(无 GET ticket/{id} |
| 3 | 数据库 migration 回滚 | 1. 检查 migration 脚本 2. 验证 cs_* 表结构 | ⚠️ 有 migration 脚本但无回滚测试 |
| 4 | 配置变更回滚 | 1. 修改 AI_CS_WEBHOOK_SECRET 2. 验证签名校验 3. 回滚环境变量 4. 验证 | ⚠️ 配置可改但无自动化回滚测试 |
| 5 | 独立运行 → 集成运行切换 | 1. 独立模式启动 2. 检查 /actuator/health/live, /ready 3. 切换集成模式 4. 路由正常 | ❌ 集成模式未实现 |
---
## 五、实施漂移检测点
### 5.1 自动化漂移检测(建议 CI/CD 集成)
| # | 检测点 | 检测方法 | 当前状态 | 优先级 |
|---|--------|---------|---------|--------|
| D-01 | 接口路由漂移 | 启动服务 + OpenAPI 扫描 + 与 INTERFACE.md 对比 | ⚠️ 16+ 项漂移 | **P0** |
| D-02 | 错误码一致性 | 扫描所有 error code 与文档定义对比 | ⚠️ 多处漂移 | **P0** |
| D-03 | 测试覆盖率 | `go test -cover` 验证 domain/service/handler 覆盖率 | ❌ 未集成 | **P1** |
| D-04 | 审计事件完整性 | 扫描代码中 `audit.Add` 调用点与 TEST_DESIGN.md 审计要求对比 | ⚠️ 安全拒绝审计已有,但工单状态变更审计在 mock 中,真实实现待验证 | **P1** |
| D-05 | 意图识别关键词覆盖 | 扫描 intent/service.go 的关键词与 TEST_DESIGN.md AC-02 场景对比 | ⚠️ 意图识别硬编码关键词,无外部配置 | **P1** |
| D-06 | 超时配置一致性 | 扫描代码中 hardcoded timeout 与 TEST_DESIGN.md 性能基准对比 | ⚠️ 无统一超时配置 | **P1** |
| D-07 | 健康检查依赖完整性 | 检查 `/actuator/health/ready` 的依赖检查项(当前仅 postgres | ⚠️ 缺少 Redis/外部 API 依赖检查 | **P2** |
| D-08 | 速率限制配置 | 扫描代码确认是否有速率限制中间件 | ❌ 完全未实现 | **P2** |
### 5.2 手动漂移审计(上线前必须执行)
- [ ] 对比 `tech/INTERFACE.md` 全部 22 个端点与代码实现
- [ ] 对比 `tech/TEST_DESIGN.md` 全部 58 条测试用例与实际测试覆盖
- [ ] 审查 `internal/service/intent/service.go` 的硬编码关键词是否覆盖 AC-02 场景
- [ ] 审查错误码是否全局统一定义(非散落在 handler 中)
- [ ] 审查 webhook 幂等去重是否持久化(非仅内存)
---
## 六、上线阻断条件清单
> 以下任一条件未满足,**必须阻断上线**。
### 🔴 P0 阻断条件(必须全部解决)
| # | 阻断条件 | 当前状态 | 说明 |
|---|---------|---------|------|
| P0-01 | **工单状态流转审计完整性** | ⚠️ 部分通过 | `ticket_handler_test.go` 有测试,但真实 store 实现(`ticket_workflow.go`)的审计写入依赖待验证 |
| P0-02 | **安全拒绝事件审计完整性** | ✅ 已实现 | `webhook_handler.go` 已对所有拒绝场景写审计 |
| P0-03 | **接口路由与文档一致** | ❌ 未通过 | 16+ 接口未实现,上线后面向用户/API 的契约严重不完整 |
| P0-04 | **AC-07/AC-08 转人工工单生成完整性** | ⚠️ 部分通过 | E2E 测试仅验证返回 200未验证工单实际内容session_id/user_id/channel/priority |
| P0-05 | **错误码全局统一定义** | ❌ 未通过 | 错误码散落在 handler 中,无统一错误定义;`CS_TICKET_4091` 与文档 `CS_TKT_4002` 不一致 |
### 🟡 P1 阻断条件(上线前必须解决或明确延期范围)
| # | 阻断条件 | 当前状态 | 说明 |
|---|---------|---------|------|
| P1-01 | **意图识别准确率验证** | ❌ 未通过 | 无 AC-02 准确率测试,无法证明意图识别质量 |
| P1-02 | **RAG 检索质量验证** | ❌ 未通过 | 无 RAG 质量测试,无法证明知识库检索效果 |
| P1-03 | **Failover 故障切换验证** | ❌ 未通过 | 无 AC-06 故障注入测试,无法证明灾备能力 |
| P1-04 | **RBAC 权限边界验证** | ❌ 未通过 | 无 AC-13 权限测试,无法证明跨用户隔离 |
| P1-05 | **性能基准验证** | ❌ 未通过 | 无性能测试,无法证明 P99 延迟达标 |
| P1-06 | **EC-02 速率限制** | ❌ 未实现 | 生产环境无速率限制,面临 DoS 风险 |
---
## 七、现有测试覆盖度评估
### 7.1 测试文件清单
| 文件 | 测试函数数 | 覆盖的 AC | 覆盖的威胁 |
|------|----------|---------|-----------|
| `test/e2e/webhook_e2e_test.go` | 4 | AC-01部分, AC-07部分, AC-08部分 | T2.3 |
| `test/integration/dialog_service_test.go` | 1 | AC-02部分 | T2.1(隐含) |
| `internal/http/handlers/webhook_handler_test.go` | 6 | AC-01部分, AC-12部分 | T1.1, T2.3, T5.1, T5.2 |
| `internal/http/handlers/ticket_handler_test.go` | 5 | AC-10 | T5.3 |
| `internal/config/config_test.go` | 2 | - | - |
**总计18 个测试函数**
### 7.2 P0 缺口专项评估
| P0 缺口 | 是否有测试捕捉 | 测试函数 | 评估结论 |
|---------|--------------|---------|---------|
| 工单状态流转审计 | ✅ 有测试 | `TestTicketHandlerAssignAuditsStateChange`, `TestTicketHandlerResolveAuditsStateChange` | **已覆盖**(但仅在 mock 层面,真实 workflow store 集成测试缺失) |
| 安全拒绝审计 | ✅ 有测试 | `TestWebhookRejectsAndAuditsMissingFields`, `TestWebhookSecurityRejectsMissingSignature` | **已覆盖** |
| AC-07/08 工单内容完整性 | ⚠️ 部分 | `TestWebhook_HandoffPath` 仅验证 HTTP 200 | **未充分覆盖** |
### 7.3 核心链路测试覆盖度
```
Webhook 接收 → 签名校验 → JSON 解析 → 去重检查 → 意图识别 → 转人工判断 → 工单生成 → 审计写入
✅ ✅ ✅ ✅ ⚠️ ⚠️ ⚠️ ✅
```
```
Ticket Assign → 工单状态变更 → 审计写入
✅ ✅ ✅
```
```
Ticket Resolve → 工单状态变更 → 审计写入
✅ ✅ ✅
```
---
## 八、缺口优先级排序与修复建议
### 立即修复P0上线前必须
1. **补充 AC-07/08 E2E 测试**:验证转人工后工单的 `session_id``user_id``channel``priority` 字段完整性
2. **统一错误码**:将散落的错误码归一化为 `internal/domain/error/` 包,与文档一致
3. **补充接口路由**:至少提供 `GET tickets/{id}``POST sessions/{id}/handoff` 的最小实现,或在文档中明确说明为 Phase 2
### 尽快补齐P1本周内
4. **补充 AC-02 意图识别测试**:至少测试"退款"、"数据泄露"、"人工"、"额度" 4 条核心路径
5. **补充速率限制**:实现并测试 EC-02 频率限制
6. **补充配置覆盖度测试**:验证 `AI_CS_MAX_BODY_BYTES` 等关键环境变量
7. **补充性能基准测试**:至少验证 `/actuator/health/ready` 响应时间 < 100ms
### 中期完善P2上线后迭代
8. RAG 检索质量测试AC-11
9. Failover 故障注入测试AC-06
10. RBAC 权限边界测试AC-13
11. 监控/metrics 基础设施
---
## 九、测试执行命令
```bash
# 快速回归(当前可执行)
cd /home/long/project/立交桥/projects/ai-customer-service
go test ./test/e2e/... ./test/integration/... ./internal/http/handlers/... ./internal/config/... -v
# 覆盖率报告(需补齐)
go test ./... -coverprofile=coverage.out -covermode=atomic
go tool cover -html=coverage.out -o coverage.html
# 门禁检查(当前漂移 16+ 项,需修复后执行)
# ./scripts/qa-gate.sh # 待实现
```
---
*本文档为机器生成,每完成一个检查项请在 PR 中标注。*
*QA 负责人签名___________ 日期2026-04-30*