新会话读完本文即可接手,不需回溯对话。 取代
CLOUD-SESSION-HANDOFF-20260817-v3.md。🔴 第 0 节必须先读完再动手 —— 长官原话:「每次换新会话就会变傻就会经常犯错,这个一定要教好。」
y,而 pitfall-release-script-silent-cancel每一行右边都是真事故换来的。带 🆕 的是 8-18 这一轮新交的学费。
| 事情 | ❌ 假判据 | ✅ 真判据 |
|---|---|---|
| 后端改动没问题 | 静态检查 / import ok | 本地真库真跑(CI 不跑 pytest) |
| 跑全量测试 | 直接 pytest | 先起核心服务 8010,否则 13 条必红(见 0.4) |
| 没弄坏别的 | 与基线失败清单比对 | 全绿(基线 0 红 / 775 绿 / 12 跳过) |
| 🆕 发版成功了 | 脚本 exit 0 / 输出好看 | 流水线出现新 run + SUCCESS。裸跑 release-to-test 会停在「本次发版内容」静默中止 → 必须 printf 'y\n' \| sudo release-to-test "标题" |
| 🆕 桥同步完了 | git ls-remote <mirror> refs/heads/feature/xxx 返空 = 没同步 |
该写法实测查不到(我连查 6 次全空,分支其实早在桥上)。用 git ls-remote /srv/git/mirror.git \| awk '$2=="refs/heads/feature/xxx"{print $1}' |
| 🆕 存量数据是 0 | 长官/人报的数 | 机器验。8-17 长官说 test「待确认金额」=0,实际 1 张 → 迁移守门在 test 拦下、连红两次。拿不到库权限就把守门写进迁移让它在真环境自己数 |
| migration 没问题 | 本地 upgrade 成功 | 本地是超级用户、权限比 test 大。碰核心表或建外键先停;必跑 升级→回滚→再升级 |
| 🆕 画的流程图对 | 我读过那段代码 | 每个按钮都要 grep 出"什么条件下出现、是不是正常路径"。8-18 把「执行开通」这个兜底按钮画成改动前的正常步骤,长官一眼看出。代码原文:payment_vouchers.py:589「到账确认后自动开通…「执行开通」按钮永远是兜底」 |
| 🆕 方案里是这么定的 | 凭印象引用 | grep 方案原文再说。8-18 我说"平台仍可改价",是自己加的,跟 §五G/§五I「全价不折算」冲突 |
| 🆕 排期顺序合理 | 依赖关系看着通 | 先查"这两步用的是不是同一个数据源"。我建议"先做前端微信入口",查证发现微信按单价×数量扣、订单金额是手填的,两者无对账 → 会收错钱 |
| 🆕 图渲染出来了 | 截图有了 | 用 Read 看一遍。且 ①别用 emoji(云机缺字体→空方框)②--shot 不能和会改页面的 --script 同跑(量溢出脚本会隐藏标注,截图就截到没标注的状态 —— 我交付过一张这样的错图) |
| 🆕 摘掉一个状态/功能干净了 | 代码里查不到了 | 列出"处于该状态的存量对象还能被怎么处置"。8-18 废「待确认金额」时把报价和取消两个入口都摘了 → 存量单谁都动不了、迁移永远过不去,只能临时加清理通路 |
| 🆕 探测得出结论了 | 命令返回了空/失败 | 0 命中前先用对照组自证查法有效。8-18 用 /dev/tcp 探 test 库端口报"不通",但对照组 443 也不通(云机走 HTTP 代理,这方法本身无效)—— 这种情况下不能下任何结论 |
| 降级保护有效 | 写了 try/except | 注入必错 SQL 看主流程活不活(PG 里语句失败会让整个事务 aborted) |
| 删干净了 | grep 关键词 0 命中 | 断言标识符用原文匹配;剥注释的正则会被 JSX 的 image/* 咬掉整页 |
| 长官能打开链接 | 我自己 curl 通了 | 给公网域名 https://dev-tokyo.tail3912a6.ts.net/<文件名>(内网 8812 长官打不开) |
| 功能做完了 | 后端接口+测试都绿 | 前端有没有渲染 |
📌 共同点:判据选错、或没查就说、或只想"改完的样子"没想"存量怎么办"。
127.0.0.1:5432/doctor_ai_brainbash
cd 仓库根 && source /tmp/core-env.sh
nohup python3 -m uvicorn app.main:app --host 127.0.0.1 --port 8010 > /tmp/core-8010.log 2>&1 &bash
cd settlement/backend && SETTLEMENT_JWT_SECRET=local-test-secret \
CORE_API_BASE=http://127.0.0.1:8010 SETTLEMENT_SERVICE_TOKEN=local-core-bridge-token \
python3 -m pytest tests/contract/settlement -q -p no:randomlyDATABASE_URL="postgresql+asyncpg://postgres:postgres@localhost:5432/doctor_ai_brain"Could not parse SQLAlchemy URLsettlement/web 下 ./node_modules/.bin/tsc --noEmitnpx tsc(会抓到别的包)。新 worktree 常没有 node_modules:package.json md5),不要重装(2 核 3.4G)sudo test-inspect ps|health|trace|ls|envkeys(刻意不给 logs、不能查库)~/render-env/browse.js(--script 要 module.exports = async (page, log) => {})--noproxy)status # 开局:分支/工作区/流水线/卡点
printf 'y\n' | sudo release-to-test "标题" # 发版(必须喂 y)· 🔴 必须长官现场令
deliver 文件名 # 交付:公网链接
sudo release-pipeline-status settle-test # 查流水线 + 失败日志
sudo test-inspect trace settlement-api # 看 test 异常
| 项 | 状态 |
|---|---|
| 主线 | 门店签约并行化 v2 · 微信支付 · 批 E |
| 批 E | 拆 6 件,已发 2 件(E-1/E-2)· E-3 是下一件 |
| test | ✅ MR #431 / settle-test run#180 SUCCESS(08-18 01:25) |
| 待发 test | 0(分支与 test 一致) |
| 生产 | 🔴 未动,48 个 MR 压着(#381~#431) |
| 分支 | feature/batch-e-auto-provision · HEAD b69d5fef |
| worktree | /home/dev2/doctor-ai-brain/.claude/worktrees/bridge-cse_01QC8iJF5ddipNc5EZbJ4Aut |
| 测试基线 | 0 红 / 775 绿 / 12 跳过 |
| 数据库 | 结算独立 alembic,head = phase70_000_drop_pending_amt |
| # | 内容 | 状态 | 备注 |
|---|---|---|---|
| E-1 | 服务端自动定价 + 废「待确认金额」 | ✅ 上 test | 含 migration phase70(带存量守门) |
| E-2 | 微信到账 → 服务订单「待开通」+ 拉起自动开通 | ✅ 上 test | 无场景可触发,等 E-3 |
| E-3 | 门店点了拉起微信(前端) | ⬜ 下一件 | 后端零件全现成,见 §4 |
| E-4 | 增购/续费凭证流退役 | ⬜ | 🔴 必须最后:微信入口没在 test 真付通前,凭证是门店唯一退路 |
| E-5 | 平台侧账号密码查看 | ⬜ | 独立 3 次 · 焚毁方案 A |
| E-6 | 开通失败兜底 | ⬜ | 显示失败原因 + 「重新开通」按钮 |
改动前:门店申请 → 平台手填金额 → 门店上传凭证 → 平台确认到账 → 系统自动开通 → 已完成
改动后:门店申请(系统自己算钱,直接「待付款」) → 门店上传凭证 → 平台确认到账 → 系统自动开通 → 已完成
+E-2 已就位:微信回调可替代"平台确认到账"这一步(但缺微信入口,暂不触发)
🔴 自动开通早就有(payment_vouchers.py:589 注释:「到账确认后自动开通…「执行开通」按钮永远是兜底」)。
E-2 的真实贡献只是把"平台确认到账"换成"微信回调自动确认"。别再把兜底按钮当正常步骤。
service_orders.pyauto_order_amount() 服务端算钱 = 上架单价 × 席位数is_active + order_by(name) 取第一条 ——/wxpay/price 和首开支付页 prices[0] 同一条。改任一侧必须同时改另一侧,amount_due → 400(拒而不静默忽略)confirm_order_amount 退役(409,端点保留)service_days != 365 → 400(所有入口,8-18 自检收紧)LEGACY_CLEANUP_STATUSES(临时件,见 §5)models/settlement.py — CHECK + 在途唯一索引 where + 列默认值,三处同步去掉废态migrations/versions/phase70_000_drop_pending_amount.py — 手写(禁 autogenerate,会 DROP 45 张表)wechatpay_funds.py — _advance_service_order():只从「待付款」推进;其他状态留审计不推进wechatpay.py — 回调 commit 后拉起后台开通;host 从 WECHATPAY_NOTIFY_URL 解析(不取请求头)后端零件全是现成的,E-3 是纯前端活:
| 需要什么 | 现成件 |
|---|---|
| 取价 | GET /api/store/service/wxpay/price(fetchStorePrices) |
| 下单 | POST /api/store/service/wxpay/prepay,biz_type 已认 "增购"/"续费",可带 service_order_id |
| 支付守卫 | require_store_pay 已放行 store_service scope(注释明写"增购/续费") |
| 拉起收银台 | invokeWechatPay()(含 WeixinJSBridgeReady 等待 + PC 微信拦截) |
| 微信授权 | startWxAuth() / exchangeWxCodeFromUrl() / bindStoreWxIdentity() |
| 回跳地址 | 🔴 buildStoreWxAuthReturnUrl(pathname, "t", linkToken, shareToken) —— 必须用它 |
🔴 两个必须注意的坑:
1. 门店端会把 token 从地址栏抹掉(存 history.state),而微信授权是整页跳转 →
history.state 必然丢 → 回跳后判「链接已失效」(8-15 长官在 test 实测过)。
所以回跳地址必须用 buildStoreWxAuthReturnUrl 自己带上 ?t=
2. 门店服务页当前没有 openid(grep 0 命中)。要先授权 → bindStoreWxIdentity 写回档案 → 再 prepay
建议 E-3 一并加两道守门(原计划放这里):
- prepay 前校验 服务订单 amount_due == 单价 × 数量,不等则拒(防历史脏单被收错钱)
- prepay 前再校验一次永久席位(长官 8-17 批;复用 _reject_non_renewable_seats)
批 E-1 上 test 时被存量单挡住,临时加了清理通路:
service_orders.py — LEGACY_CLEANUP_STATUSES = ("待确认金额",) + cancel_service_order 放行list_legacy_pending_amount_orders()service_management.py — GET /stores/service-orders/legacy-pending-amountadmin/minicup/stores/page.tsx — 顶部橙色清理条 + 「取消这张单」按钮🔴 删除条件:test 与生产都确认 select count(*) from store_service_orders where status='待确认金额' = 0
且 phase70 已应用后,四处一起删。
做完 E-1+E-2+E-3 一起,长官能从申请→付款→自动开通整条走一遍。E-4 单独放最后。
48 个 MR(#381~#431)。前置三件:
1. 切 settle-prod 流水线源(root)—— 现仍指旧独立仓 tongban-settlement.git,最后 run#7 是 08-10
2. 微信支付授权目录填 https://chat.tongban.love/(必须 https)
3. 🔴 生产 nginx reload(root · CI 不 reload)
⚠️ 发生产时 phase70 守门会再数一次存量。长官 8-18 说生产无存量单,
但 8-17 他也说 test 是 0、实际有 1 —— 以守门实跑为准,它会挡住部署不会弄坏数据;
真有存量,生产上也能用同一条清理条点掉。
service_days 只许 365(短期单需先定短期价)y(记忆里明明写着)/dev/tcp 探端口,对照组也失败却下了结论--shot 与改页面的 --script 同跑,交付了一张标注全消失的图📌 第 0 节那张判据表就是这么来的。
~/reports/CLOUD-SESSION-HANDOFF-20260818.md~/reports/门店签约并行化方案v2-微信支付版-20260813.md云机环境 · 非验收证据。