docs: sync review reports, runbooks, and checklists

This commit is contained in:
Your Name
2026-05-11 12:19:15 +08:00
parent 67922c589a
commit 9319583ee3
16 changed files with 1450 additions and 31 deletions

View File

@@ -0,0 +1,290 @@
# ai-customer-service 最新审查报告2026-05-06
> 审查时间2026-05-06
> 代码基线:`ee3a31e77c00d47802e7b3a54057467b3a713400`
> 审查方式:小龙主审 + 双视角 QA 复核 + 现有门禁文档对照
> 目标:给出当前代码与放行状态的真实结论,回收过期结论,并把问题转成可执行整改基线。
> 配套任务板:`docs/REMEDIATION_TASK_BOARD_2026-05-06.md`
---
## 0. 阶段门控结论
### 总结论
- **代码级门禁PARTIAL / 不稳定**
- **sub2api 单平台主链PASS WITH RISKS**
- **newapi 平台能力FAIL**
- **真实共享预生产 Gate BFAIL**
- **生产灰度 Gate CFAIL**
### 是否可进入下一阶段
- **是否可按“整体生产可上线”口径放行:否**
- **是否可按“多平台能力已完成”口径汇报:否**
- **是否可按“sub2api 单平台代码级链路已可用”口径汇报:是,但必须同时声明关键风险与未完成门禁**
### 当前最小可接受口径
1. 代码级门禁已通过
2. sub2api 的 webhook → outbox → callback worker 主链已接通
3. newapi 当前未通过,不应按已接入汇报
4. 真实共享预生产 / 灰度环境证据未闭环,因此不能按生产可上线口径放行
---
## 1. 审查输入与证据来源
### 1.1 已读取的关键代码
- `cmd/ai-customer-service/main.go`
- `internal/app/app.go`
- `internal/http/router.go`
- `internal/http/handlers/platform_webhook_handler.go`
- `internal/http/handlers/platform_webhook_security.go`
- `internal/platformadapter/sub2api_adapter.go`
- `internal/platformadapter/newapi_adapter.go`
- `internal/service/platformevents/builder.go`
- `internal/service/platformdelivery/worker.go`
- `internal/store/postgres/platform_event_store.go`
### 1.2 已读取的关键文档
- `docs/CODE_REVIEW_REPORT.md`
- `docs/RECTIFICATION_REVIEW_REPORT_V2.md`
- `docs/REVIEW_REPORT_2026-05-04.md`
- `docs/P0_P1_P2_RECTIFICATION_EXECUTION_BOARD.md`
- `docs/PRODUCTION_LAUNCH.md`
- `test/QA_GATE_STATUS.md`
- `prd/PRODUCTION_CHECKLIST.md`
### 1.3 已采纳的实测依据
- 本轮主审曾捕获两次 `go test ./...` 失败信号:
- `test/e2e/sub2api_callback_flow_test.go:186`
- 一次实际 `event[0].type = message.processing`,预期 `message.received`
- 本轮复核再次实际 `event[0].type = reply.generated`,预期 `message.received`
- 两次都伴随 `platform callback event delivery failed``sql: database is closed`
- 曾有并行 QA 复核在当时现态仓库上复跑 `go test ./... -count=1`:通过
- 但本轮再次实测 `go test ./... -count=1`:失败
- 因此当前最真实口径应为:`go build ./...``go vet ./...` 通过;`go test ./...` 存在不稳定失败,代码级门禁不能再写成稳定 PASS
### 1.4 证据解释原则
- `go build ./...``go vet ./...` 当前可支持通过结论
- `go test ./...` 当前不能稳定支持通过口径,应视为不稳定失败状态
- 真实失败信号不能被抹掉,应作为当前事实与稳定性风险保留
- 不以历史报告或角色自报覆盖当前代码与命令事实
---
## 2. 当前真实状态
### 2.1 已成立的事实
1. `sub2api` 主链路已真实接通,不是只有定义没有调用
2. `newapi` 不是“待联调”,而是“入口未实现但装配可开”的未通过状态
3. 代码级门禁与本地/仓库内验证不能等同于真实预生产或生产放行
4. 当前最主要的阻塞,不再是早期报告中的旧 P0而是
- 平台能力口径失真
- callback / outbox 一致性与扩展性边界未收口
- 真实环境放行证据未闭环
### 2.2 已不应继续沿用的旧结论
以下表述对当前代码已不再成立,不应继续作为“当前事实”引用:
1. `RateLimiter` 存在 P0 并发写问题
2. ticket resolve/close 不区分不存在与状态冲突
3. 后台接口“完全无鉴权”
4. prod 默认仍可 fallback 到 memory
5. readiness 相关生产约束仍未收紧
说明:
- 这些项在旧报告中曾成立或部分成立,但已与当前代码和现有门禁文档不一致
- 继续引用会造成报告漂移
### 2.3 仍然成立的高层判断
1. 当前项目还不是完整 PRD 意义上的完整 AI 客服系统
2. 当前不能按“整体生产可上线”口径放行
3. 文档漂移仍是风险,只是漂移重心已经从早期代码 P0 转向旧报告口径过期
---
## 3. 关键调用链路核查
### 3.1 sub2api 主链路核查
#### 结论
- **PASS WITH RISKS**
#### 四层核查
1. 定义
- `PlatformAdapter` 接口存在
- `Sub2APIAdapter` 已实现
- `Worker``PlatformEventStore`、event builder 均存在
2. 装配
- `internal/app/app.go` 会在配置开启时注册 `sub2api` adapter
-`platformEvents != nil` 且配置满足时启动 `sub2api` worker
3. 调用
- `router``PlatformWebhookHandler`
- `PlatformWebhookHandler``registry.Resolve(platform)` → adapter `ParseInbound`
- `dialog.Process` 后进入 `BuildInboundEvents`
- `InsertPendingBatch` 写入 outbox
- worker `RunOnce` / `deliver` 发起 callback
4. 入口
- `/api/v1/customer-service/platforms/sub2api/webhook`
#### 结论解释
- 这条链路是实链路,不是“有结构、没接线”
- 但它仍然带有一致性、并发和稳定性风险,不能直接放大为“平台回调系统已生产级完成”
### 3.2 newapi 主链路核查
#### 结论
- **FAIL**
#### 直接证据
1. `internal/platformadapter/newapi_adapter.go:20-21`
- `ParseInbound` 直接返回 `501 not implemented`
2. `internal/app/app.go:129-130`
-`cfg.PlatformAdapters.NewAPI.Enabled` 时,仍会注册 `newapi` adapter
3. `internal/app/app.go:186-187`
- `startWorker("newapi", cfg.PlatformAdapters.NewAPI)` 仍可能启动 `newapi` callback worker
#### 结论解释
- 当前状态不是“newapi 已接通但未验证”,而是“配置上看似支持,真实入口未实现”
- 这是典型 `call_chain_gap + implementation_gap`
---
## 4. 自动化与验证结果结论
| 检查项 | 结论 | 说明 |
|---|---|---|
| 代码级门禁 | PARTIAL / 不稳定 | `go build ./...``go vet ./...` 当前通过;`go test ./... -count=1` 本轮再次失败于 `test/e2e/sub2api_callback_flow_test.go:186` |
| sub2api 主链存在性 | PASS | 入口、调用、outbox、worker 四层均可追踪 |
| newapi 平台能力 | FAIL | 入口未实现但装配仍可打开 |
| callback worker 基本投递能力 | PASS | 成功/失败/重试/死信路径存在 |
| callback_target 契约一致性 | FAIL | 字段存在,但 worker 不消费该字段 |
| outbox 并发投递安全性 | PARTIAL | `ListDue` 无 claim / `skip locked`,多实例下有重复投递窗口 |
| outbox 强一致性 | PARTIAL | 非严格 transactional outbox |
| 真实共享预生产 Gate B | FAIL | 当前仍缺真实共享预生产复跑与留痕 |
| 生产灰度 Gate C | FAIL | 当前仍缺真实监控接线、灰度稳定性与回滚证据 |
---
## 5. 问题清单
### Critical
#### C-01 真实共享预生产 / 生产放行证据未闭环
- 影响:不能按“生产可上线”口径放行
- 证据:
- `test/QA_GATE_STATUS.md`
- `prd/PRODUCTION_CHECKLIST.md`
- 当前状态:代码级通过,但真实共享预生产 Gate B 和生产 Gate C 仍未通过
- 建议:继续按 Gate B / Gate C 在真实共享环境复跑并留痕
### Important
#### I-01 newapi 平台入口未实现但仍可装配/启动 worker
- 影响:对外口径容易失真,误报为“平台已支持”
- 证据:
- `internal/platformadapter/newapi_adapter.go:20-21`
- `internal/app/app.go:129-130`
- `internal/app/app.go:186-187`
- 建议:二选一收口
1. 禁止未实现平台被注册/启动 worker
2. 补完整 newapi ingress 实现与对等测试
#### I-02 平台启用状态与真实可用能力未统一建模
- 影响:未完成平台也可能启动 callback worker形成半接通状态
- 证据:`internal/app/app.go:158-187`
- 建议:把 adapter 注册条件、worker 启动条件、入口可用条件收成同一门控
#### I-03 `callback_target` 契约与运行时行为不一致
- 影响:数据模型表达了能力,运行时并未支持,后续易造成静默错投或错误认知
- 证据:
- event builder 写入 `callback_target`
- `worker.go` 实际只使用 `Worker.CallbackURL`
- 建议:删除伪能力,或真正按 event target 路由
#### I-04 outbox 多实例并发投递风险未收口
- 影响:水平扩展时可能重复投递
- 证据:`internal/store/postgres/platform_event_store.go:78-86``ListDue` 仅查询,不做 claim / 锁定
- 建议:补 claim 机制、`FOR UPDATE SKIP LOCKED` 或显式限定单实例运行边界
#### I-05 严格事务外盒未成立
- 影响:业务主写成功但 outbox 写失败时,一致性不可保证
- 证据:业务处理与 `InsertPendingBatch` 不在同一事务中
- 建议:后续评估 transactional outbox 或明确记录一致性边界
#### I-06 sub2api callback E2E 已再次复现失败,说明链路存在现实不稳定性
- 影响:当前 `go test ./...` 不能稳定通过,代码级门禁不能再按稳定 PASS 对外汇报
- 证据:本轮复核再次在 `test/e2e/sub2api_callback_flow_test.go:186` 失败,实际出现 `reply.generated` 先于 `message.received`,并伴随 `sql: database is closed`
- 建议:先把该问题提升为当前优先闭环项,做定向稳定性定位与修复,再恢复代码级门禁口径
### Minor
#### M-01 旧 review 文档存在显著漂移
- 影响:继续引用会误导后续判断
- 典型文档:
- `docs/CODE_REVIEW_REPORT.md`
- `docs/PRODUCTION_EXECUTION_PLAN.md`
- 建议:以后续新报告和任务板为准,逐步回收旧结论
---
## 6. Gap Taxonomy Summary
| Gap Type | 具体表现 | 主责任方向 |
|---|---|---|
| design_gap | 平台启用 / 平台可用性门控未统一;多实例投递策略未正式定义 | TechLead |
| implementation_gap | newapi 入口未实现callback_target 运行时未消费 | Engineer |
| test_gap | newapi 缺对等测试sub2api callback E2E 已复现不稳定失败,需优先定位与修复 | QA / Engineer |
| evidence_gap | 真实共享预生产 / 灰度环境证据未闭环 | QA / DevOps |
| call_chain_gap | newapi 看似支持但入口未接通 | TechLead / Engineer |
| contract_gap | callback_target 字段与 worker 真实行为不一致 | TechLead |
---
## 7. 与旧报告的关系
### 7.1 可以继续保留的主结论
- 当前不能按“整体生产可上线”口径放行
- 代码级通过不等于预生产和生产放行通过
- 文档漂移仍需持续治理
### 7.2 必须回收的过期口径
- 旧版把若干已修复问题继续当作当前 P0
- 旧版把“无鉴权 / prod fallback / readiness 过宽”继续描述为当前代码事实
- 旧版若暗示“修完早期两个 P0 即可灰度”,现阶段已不再成立
### 7.3 新基线文件
后续应以以下文件作为当前基线:
- `docs/REVIEW_REPORT_2026-05-06.md`
- `docs/REMEDIATION_TASK_BOARD_2026-05-06.md`
- `test/QA_GATE_STATUS.md`
- `prd/PRODUCTION_CHECKLIST.md`
---
## 8. 后续执行建议
### 最短闭环顺序
1. 先定位并修复 `sub2api` callback E2E 不稳定失败,恢复 `go test ./...` 稳定通过能力
2. 收口平台能力矩阵
3. 收口平台启用 / worker 启动统一门控
4. 处理 newapi 假接通
5. 补 newapi 对等验证
6. 在共享预生产环境复跑 Gate B 并留痕
7. 在共享预生产 / 灰度环境补监控接线与回滚证据
### 对应任务板
- 详见:`docs/REMEDIATION_TASK_BOARD_2026-05-06.md`
---
## 9. 最终判定
**当前项目应被定义为:**
> **`go build ./...` 与 `go vet ./...` 当前通过,但 `go test ./...` 已再次实测失败说明代码级门禁并不稳定sub2api 单平台回调主链已可用,但仍带重要一致性/并发/稳定性风险newapi 当前未通过;真实共享预生产与生产放行门禁未闭环,因此不能按“整体生产可上线”或“多平台已完成”口径汇报。**
正式门控结论:
- **代码级门禁:部分通过 / 当前不稳定**
- **sub2api 单平台主链:通过,但带重要风险且 E2E 当前不稳定**
- **newapi 平台能力:未通过**
- **真实共享预生产门禁:未通过**
- **生产放行门禁:未通过**