Files
ai-customer-service/docs/RECTIFICATION_REVIEW_REPORT_V2.md
Your Name 142b991334 fix(config+app): production fail-fast + readiness收紧
1. config.go: AI_CS_ENV runtime mode with production restriction
   - New RuntimeConfig.Env field (AI_CS_ENV / AI_CS_RUNTIME_ENV)
   - production + Postgres.Enabled=false → Load() returns error
   - production + empty webhook secret → Load() returns error
   - normalizeRuntimeEnv: dev/dev/ → development, prod/production → production, test → test

2. app.go: probe.SetReady only when store is confirmed ready
   - Postgres.Enabled: probe.SetReady(true) after DB+migration OK
   - Memory mode: probe.SetReady(false) — not production-ready

3. health_handler_test.go: add probe live+ready state transition tests

4. config_test.go: add TestLoad_RejectsProdWhenPostgresDisabled,
   TestLoad_RejectsProdWhenWebhookSecretMissing

5. app_test.go: add TestNew_RejectsMemoryModeWithoutExplicitNonProdEnv,
   TestNew_AllowsMemoryModeInTestEnv, TestNew_WithPostgresEnabled_*
   for invalid DSN and migration-failure paths

Phase 1 (code gate) objectives met:
 prod cannot fall back to memory store
 readiness reflects actual store readiness
 both changes have test coverage
2026-05-04 07:38:10 +08:00

14 KiB
Raw Permalink Blame History

ai-customer-service 整改版审查报告 v2

角色框架:小龙 / PM / TechLead / QA / DevOps
审查目标:从“可跑通”提升到“生产可控、可灰度、可追责、不可默默降级”


0. 阶段门控结论

当前结论REQUEST_CHANGES
是否可直接按“生产已具备上线条件”放行:否

当前真实状态

  • 代码主链:已基本打通
  • 关键测试:已实跑通过
  • 生产落地控制:仍有明显缺口
  • 团队流程一致性:存在文档漂移与门禁失真

本轮阻塞上线的核心原因

  1. 默认允许 memory store 启动,存在生产级降级失控
  2. readiness 不能证明“生产依赖已就绪”
  3. QA / 上线文档与真实代码状态存在漂移
  4. 环境变量与部署文档口径不一致,存在实施误配风险
  5. 后台操作鉴权与运维级控制尚未形成完整闭环

1. 本次复核依据与已验证证据

1.1 已实际读取的关键实现

重点核查:

  • internal/app/app.go
  • internal/config/config.go
  • internal/http/router.go
  • internal/http/handlers/webhook_handler.go
  • internal/http/handlers/webhook_security.go
  • internal/http/handlers/health_handler.go
  • internal/http/handlers/session_handler.go
  • internal/http/handlers/ticket_handler.go
  • internal/service/dialog/service.go
  • internal/service/handoff/service.go
  • internal/store/postgres/*
  • internal/store/memory/*
  • db/migration/0001_init.up.sql

文档对照:

  • prd/PRODUCTION_CHECKLIST.md
  • test/QA_GATE_STATUS.md

1.2 已实际执行的验证

已通过 ASCII symlink 规避中文路径工具限制后执行:

go test -count=1 ./...
go test -count=1 ./test/e2e -run 'TestFullTicketFlow_E2E|TestSecurity_.*' -v
go test -count=1 ./test/integration -run 'TestHealthCheck_.*|TestDialogService_.*|TestTicketAssignResolve.*|TestSessionHandler.*' -v

实测结论

  • 全仓测试通过
  • 工单 E2E 主链通过
  • Webhook 安全 E2E 通过
  • Health/readiness 集成测试通过
  • Session / Dialog / Ticket 关键集成测试通过

2. 审查后的总判断

2.1 已落实部分

A. 功能主链已存在

  • webhook 收消息
  • dialog 识别意图
  • handoff 创建 ticket
  • ticket assign / resolve / close / get
  • stats / feedback / manual handoff 基本能力已落地

B. 基础安全入口已存在

  • webhook HMAC
  • timestamp 窗口校验
  • dedup 幂等
  • body limit
  • rate limit

C. Postgres 持久化路径已接通

  • AI_CS_POSTGRES_ENABLED=true 时走 postgres store
  • migration 启动执行
  • session / ticket / audit / dedup 均有 PG 实现

2.2 当前不能判定“生产可放心上线”的核心原因

A. 降级失控

生产默认可退化为 memory store且服务仍能成功启动并 ready。

B. readiness 语义过宽

只能证明“进程能收请求”,不能证明“生产依赖与安全前置条件已满足”。

C. 文档与代码状态漂移

团队已有“测试失败/允许上线”等结论与当前代码真实状态不一致。

D. 部署契约未收敛

文档写的环境变量名与代码真实读取项不完全一致。

E. 后台操作的真实性边界不足

ticket / session 相关后台接口仍偏内网占位实现,缺少真正的操作鉴权闭环。


3. 角色化整改方案

3.1 小龙CEO / 统筹者)整改责任

核心问题

当前团队最大问题不是“没人干活”,而是:

  • 修了代码但没同步门禁文档
  • 跑通了链路但仍以“允许上线”模糊放行
  • 角色产出没有被强制做事实校准

小龙必须承担的整改动作

XL-P0-1建立“代码事实高于报告”的门禁

今后任何“已完成 / 可上线 / 已通过”的结论,必须满足:

  1. 有实际文件证据
  2. 有实际命令输出
  3. 有当前版本时间点的校准
  4. 有至少一次小龙抽样自验
XL-P0-2重写阶段状态口径

把当前项目阶段结论统一收敛成三层:

  • 代码主链状态
  • 预生产验证状态
  • 生产上线状态

禁止再用单句“允许上线”覆盖全部层次。

XL-P1-1强制角色交付模板

后续 PM / TechLead / QA / DevOps 输出必须固定带:

  • 结论
  • 证据
  • 阻塞项
  • 下一阶段条件
  • 责任人
  • 时间要求
XL-P1-2增加“实施漂移复核点”

每次关键修复后,小龙必须做 3 件事:

  1. 复跑最小必要测试
  2. 复核关键配置契约
  3. 更新门禁文档状态

小龙验收标准

  • 所有“完成/通过”结论都有命令或文件证据
  • 文档状态与当前代码状态一致
  • 不再使用“允许上线”作为模糊总括结论
  • 每个整改项都有明确责任角色和验收人

3.2 PM产品经理整改责任

当前 PM 问题

不是没有文档,而是文档覆盖面和交付口径不够硬

  • 上线检查项有,但和代码契约未完全对齐
  • 对“Phase1 可上线”表述偏乐观
  • 对“dev fallback 与 prod 要求差异”没有明确写成产品/交付边界
  • 对“上线前必须真实环境验证”的门槛定义不够强

PM 必须承担的整改动作

PM-P0-1修正文档中的上线口径

将现有文档中的“允许上线”改成分层表述:

  • 代码级门禁通过
  • 仓库内测试门禁通过
  • 真实环境门禁未闭环
  • 仅允许进入预生产/灰度准备
PM-P0-2补“运行模式约束”

在 PRD / checklist / status 中明确写入:

  • memory mode 仅用于开发 / 测试
  • prod 环境不允许无持久化运行
  • 若缺少 DB / secret / 关键依赖,系统应 fail-fast不得 silent degrade
PM-P1-1补齐“上线运营口径与观察指标”

新增明确观察项:

  • 工单创建量是否异常偏低/偏高
  • handoff 比率是否异常
  • audit 写入是否持续
  • dedup 是否稳定
  • readiness 是否真实反映依赖状态
  • 实例重启后数据是否仍在
PM-P1-2统一环境变量文档契约

所有面向部署的文档,必须统一写成代码真实读取的变量名,例如:

  • AI_CS_POSTGRES_ENABLED
  • AI_CS_POSTGRES_DSN
  • AI_CS_POSTGRES_MIGRATION_DIR
  • AI_CS_WEBHOOK_SECRET
  • AI_CS_WEBHOOK_MAX_SKEW_SECONDS

禁止再用泛化口径替代真实配置契约。

PM 验收标准

  • 文档中不再出现“仅凭仓库内测试即可认定生产可上线”的表述
  • 文档中的环境变量名与 config.go 完全一致
  • 明确区分 dev/test 与 prod 运行要求
  • 上线观察指标、失败判定线、回滚触发条件都已写清

3.3 TechLead技术经理整改责任

当前 TechLead 问题

TechLead 已把主链做起来,但没有把“生产默认安全”做成系统约束

必须整改的技术项

TL-P0-1禁止生产默认退化到 memory store

目标:

  • 生产模式下,不允许 Postgres.Enabled=false 仍正常启动

建议实现方向:

  1. 增加运行模式,例如:
    • AI_CS_RUNTIME_MODE=dev|test|prod
  2. prod 模式下强制校验:
    • AI_CS_POSTGRES_ENABLED=true
    • AI_CS_POSTGRES_DSN 非空
    • migration dir 可用
  3. 不满足则 app.New() 直接返回错误

验收标准

  • prod 下未启用 Postgres 时服务启动失败
  • 错误信息明确说明缺失项
  • 有对应测试覆盖
TL-P0-2收紧 readiness 语义

当前 probe.SetReady(true) 太早,必须改。

建议:

  • 启动完成后不直接 ready
  • ready 的条件至少包含:
    • DB 已连接
    • migration 已成功
    • 关键配置已完整
    • 运行模式合法
    • 如启用 webhook auth则 secret 已配置

可选策略:

  • health 保持诊断信息
  • ready 专门作为流量门禁

验收标准

  • 缺 DB / 缺 secret / 缺关键配置时 ready=DOWN
  • ready 不再仅因为进程启动成功就返回 UP
  • 有集成测试覆盖关键失败场景
TL-P0-3统一配置契约与部署文档

TechLead 要输出一份代码视角的配置契约基线,作为 PM / DevOps / QA 的唯一来源。

至少包括:

  • 变量名
  • 默认值
  • 是否允许默认值出现在 prod
  • 是否阻断启动
  • 对应组件
  • 风险等级

示例字段:

  • AI_CS_POSTGRES_ENABLED
  • AI_CS_POSTGRES_DSN
  • AI_CS_POSTGRES_MIGRATION_DIR
  • AI_CS_WEBHOOK_SECRET
  • AI_CS_MAX_BODY_BYTES

验收标准

  • 有单独配置契约表
  • config.go 实际实现一致
  • 明确哪些默认值仅限 dev/test
TL-P1-1补后台接口鉴权设计

当前:

  • actor_id 主要来自 query param
  • 更接近内部占位实现,而不是正式后台控制面接口

需明确:

  • 是仅内网可调
  • 还是后台服务调用
  • 还是运营台使用
  • 对应认证方式是什么

至少补设计:

  • 内部 token / service auth / gateway auth
  • 操作审计字段真实性
  • actor 来源不可伪造

验收标准

  • ticket/session 后台接口有明确 auth 模式
  • actor_id 不再只是前端随便传
  • 权限边界写入设计文档
TL-P1-2补多实例与恢复场景验证设计

需要明确验证:

  • dedup 在多实例下是否稳定
  • ticket / session / audit 在重启后是否一致
  • migration 重复执行是否幂等
  • 故障恢复后 ready 恢复逻辑是否正确

3.4 QA质量经理整改责任

当前 QA 问题

QA 不是没工作,而是结论闭环不够硬

  • 文档中存在过时结论
  • “允许上线”没有严格区分代码门禁与生产门禁
  • 没把“memory fallback 风险”上升为真正阻断项

QA 必须承担的整改动作

QA-P0-1重做上线门禁文档

重写 QA_GATE_STATUS,按以下结构:

  1. 当前代码事实
  2. 实测命令
  3. 通过项
  4. 未通过项
  5. 文档漂移项
  6. 生产阻断项
  7. 下一阶段建议结论

必须明确区分:

  • 仓库内验证通过
  • 真实环境未验证
  • 生产阻断未解除
QA-P0-2把“降级失控”列为 Critical

以下情形必须判定为 Critical

  • prod 可在 memory mode 启动
  • ready 不能区分关键依赖缺失
  • 部署文档与配置契约不一致
  • 文档已允许上线,但真实环境门禁未验证
QA-P1-1建立“文档漂移检测”检查项

今后每次 QA 审查必须加一栏:

  • 代码状态 vs status 文档是否一致
  • 测试状态 vs 报告状态是否一致
  • 配置项 vs checklist 是否一致
QA-P1-2增加真实环境前置门禁

上线前 QA 必须强制检查:

  • 使用真实环境变量启动一次
  • ready / health 返回符合预期
  • Postgres migration 执行成功
  • webhook 签名真实联调成功
  • audit / ticket 实际入库成功

QA 验收标准

  • QA 报告明确区分代码门禁 / 生产门禁
  • 文档漂移项被单独列出
  • memory fallback 风险被列为 Critical 直到修复
  • 不再用“允许上线”掩盖真实环境未验证

3.5 DevOps运维 / SRE整改责任

当前 DevOps 问题

仓库中有上线清单,但还不是实际运维闭环。

DevOps 必须承担的整改动作

DO-P0-1形成真实部署基线

需要明确:

  • 启动命令
  • 必填环境变量
  • secret 注入方式
  • Postgres 连通性检查
  • migration 执行方式
  • readiness / liveness 探针路径
  • 灰度方式
  • 回滚方式
DO-P0-2把“关键配置缺失即启动失败”纳入部署标准

即使代码修完,部署侧也要加保护:

  • 若 prod 缺少 AI_CS_POSTGRES_DSN / AI_CS_WEBHOOK_SECRET
  • CI/CD 或启动脚本应直接 fail
DO-P1-1补监控与告警

最少补这些:

  • 5xx rate
  • webhook reject rate
  • handoff rate
  • ticket create rate
  • audit write error
  • DB connect / migration error
  • ready down duration
DO-P1-2补 runbook

必须有:

  • 启动失败排查
  • migration 失败回滚
  • DB 不可用处理
  • webhook auth 失败联调
  • 实例重启后数据一致性检查

DevOps 验收标准

  • 有真实部署基线文档
  • prod 关键配置缺失时不会“假成功启动”
  • 有最小监控告警集
  • 有回滚与故障 runbook

4. P0 / P1 / P2 总整治清单

P0上线前必须完成

  1. 禁止 prod 退化为 memory mode
  2. 收紧 readiness改成真实依赖门禁
  3. 修正文档:状态、测试、环境变量口径统一
  4. QA 重做门禁结论,撤销过宽“允许上线”表述
  5. 建立部署侧关键配置 fail-fast 机制

P1灰度前应完成

  1. 后台操作接口鉴权边界明确
  2. 真实环境 DB / migration / webhook 联调
  3. 监控告警最小闭环
  4. 文档漂移检测纳入 QA 常规项
  5. runbook 与回滚路径补齐

P2全量上线后持续补

  1. 更完整威胁建模
  2. 多实例一致性与恢复测试
  3. store/app 层覆盖率继续补齐
  4. 敏感字段脱敏、审计治理、保留策略完善
  5. 更细粒度容量与可观测性建设

5. 整改后阶段门禁定义

Gate A代码级通过

满足:

  • 主链测试通过
  • 安全测试通过
  • prod 不允许 memory fallback
  • readiness 逻辑收紧
  • 配置契约与代码一致

Gate B预生产通过

满足:

  • 真实 Postgres 联通
  • migration 成功
  • webhook 签名联调成功
  • audit / ticket 入库成功
  • ready / live 行为符合预期
  • 最小监控已接通

Gate C生产灰度通过

满足:

  • 5% 灰度稳定
  • handoff / ticket / audit 指标正常
  • 无异常 5xx / reject 激增
  • 回滚演练已通过

6. 最终整改版结论

ai-customer-service 当前应被定义为:
“代码主链可用,适合进入生产整改与预生产验证阶段;但尚不应被标记为生产可直接放心上线。”

更准确地说:

  • 不是没做成
  • 也不是 demo 空壳
  • 但现在离生产级放心放量,还差最后一层关键控制:禁止隐式降级、收紧 readiness、统一配置契约、修正文档漂移、补部署门禁。