新会话读完本文即可接手,不需回溯对话。 取代
CLOUD-SESSION-HANDOFF-20260816-v2.md。🔴 第 0 节必须先读完再动手 —— 长官原话:「每次换新会话就会变傻就会经常犯错,这个一定要教好。」
你不是不知道,是手边没有上一会话查过的事实,于是用推测填空 ——
而推测听起来跟事实一模一样,长官分不出来,只能等踩坑才发现。
每一行右边那列,都是拿真事故换来的。
| 事情 | ❌ 假判据 | ✅ 真判据 |
|---|---|---|
| 后端改动没问题 | 静态检查 / AST / py_compile 全过 | 本地真库真跑一遍(🔴 CI 不跑 pytest,实查 0 命中) |
| 降级保护有效 | 写了 try/except | 在里面注入必错 SQL,看主流程还活不活 |
| 接口能用 | service 层单测全绿 | 真打 HTTP |
| 前端改动生效 | 页面返回 200 | 抓 JS chunk 比对指纹 |
| 某串在产物里不存在 | grep -c 返回 0 |
对照组也返回 0 = 查法无效(JSX 插值会被打包成 .concat(),完整串永远搜不到) |
| 效果图跟代码一致 | 我复刻渲染出来了 | 复刻用的类名/结构/CSS 前提逐条对过真实代码 |
| 长官能打开链接 | 我自己 curl 通了 | 给公网域名 |
| 数据是真实的 | 库里有 N 行 | 看创建时间 / 是否全是测试渠道 |
| 功能做完了 | 后端接口+测试都绿 | 前端有没有渲染 |
| 发版成功 | 脚本 exit 0 | 流水线出现新 run + 部署 SUCCESS |
| 没破坏别的 | 全量跑绿 | 与基线逐条比对失败清单 |
自检报告里我自己写着「pytest 一次没跑、CI 也不跑」,结论却是「建议发,让 CI 兜底」——
明知没有验证还发,结果核心功能 500,让长官刷了 8 次页面排查。
👉 自己写下的风险,必须影响自己的决定;否则那份自检就是表演。
sqlalchemy asyncpg greenlet fastapi httpx redis,127.0.0.1:5432。在 settlement/backend 下可 import 真模型、连真库、调真 service。payment_orders 曾 0 条)→ 只跑一次可能没进循环体,必须造数据覆盖分支(用完删)。~/render-env/browse.js(playwright-core + chromium)。旧交接件写"云机无浏览器"是错的。status # 开局:分支/工作区/流水线/卡点
release-test "标题" # 发版(判据内置)。🔴 不要用 sudo release-to-test(非交互会静默取消)
deliver 文件名 # 交付:公网链接
| 项 | 状态 |
|---|---|
| 主线 | 门店签约并行化 v2 · 微信支付(批 B) |
| test | ✅ 已全量发(最新 MR #410 / settle-test run#159,8-16 20:07) |
| 待发 | 0(分支与 test 一致) |
| 分支 | feature/wechatpay-pay-core |
| worktree | /home/dev2/doctor-ai-brain/.claude/worktrees/bridge-cse_01AcGpTe1nKXvLXiYNPAGF53 |
| 生产 | 未动。发生产:sudo release-to-prod --mr <编号> |
接手第一件事:等长官验收反馈,别自己发版。
排查 500 时在中途摘掉了 join ServicePrice(当时怀疑是它),后来证明真凶是审计表那段 ——
商品名八成是被误伤的,但一直没加回去。
恢复方法(payment_records.py 微信分支):
1. 加回 stmt = stmt.add_columns(ServicePrice.name).outerjoin(ServicePrice, PaymentOrder.price_id == ServicePrice.id)
2. 循环解包改 5 元组:for order, profile, channel, parent_name, price_name in wx_rows:
3. 序列化补 "price_name": price_name
4. import 补回 ServicePrice
前端已有兜底(price_name ? ... : biz_type),不加也不报错。
按新规矩:单独一版 + 先本地真跑。
一个 500,背后是四个独立问题:
| # | 问题 | 教训 |
|---|---|---|
| 1 | 拿审计表 audit_logs 当业务数据源 |
审计表多半只授写权限、不给读 —— 那是合理设计 |
| 2 | try/except 不 rollback |
PG 里一条语句失败 → 整个事务作废 → 后续全挂。必须 async with session.begin_nested() |
| 3 | 一次发 6 处后端改动 | 出事无法定位,只能回滚 + 二分 |
| 4 | 退款 operator_id 取错键 |
token 里是 sub,不是 id/user_id → 一路兜底成 0 |
验证降级是否为真:在 SAVEPOINT 内注入 SELECT * FROM 不存在的表,看主流程还活不活(验完删掉注入代码)。
| # | 验什么 |
|---|---|
| 1 | 机构列表付款状态(PC + 手机端):老机构应显示「已支付」而非「未支付」 |
| 2 | 手机端机构列表筛选能不能用(原先点了没反应) |
| 3 | 门店进度页点「修改资料」→ 服务付款卡应收起;取消后恢复 |
| 4 | 渠道管理给二级配比一级高的比例 → 应被拦(409) |
| 5 | 真付一笔 → 渠道收益是否按新口径(普通二级时一级只拿差额) |
| 6 | 重新标记一笔退款 → 「操作人」才有值(老数据 refunded_by 存的是 0,不回填) |
页面路由(全部实测 200,都在 /settlement/ 前缀下):
store/minicup/{signup,review,payment,opening-result,service} ·
admin/minicup/{stores,payment-confirm,prices,revenue-ledger,channels} ·
platform/minicup/{stores,payment-confirm,revenue-ledger}
settlement_statements.total_amount 和红字冲销记录)settle-prod 流水线源 + 支付授权目录填 https://chat.tongban.love/(必须 https)border-box、类名写错、字段画少)→ 差点让长官以为有不存在的 buggrep 查法无效(对照组返 0 才发现)→ 幸亏每次都带了对照组{total} 实为 totalCount)、不存在的异常类 → 自查时才抓到📌 共同点:判据选错、或没查就说。第 0 节那张表就是这么来的。