dev2 · 2026-08-20 · 【实测】= 云机命令跑出来的 · 云机环境·非验收证据
| 项 | 结果 |
|---|---|
| 11 维 verify | 全绿 ✅ |
| 🔴 阻断项 | #476 不能单独发 —— 依赖 #368,生产上没有 |
| #375 | 不用发了 —— root 已随工具修复带上生产 |
| 建议 | #367 + #368 + #476 三个一起发(加法精确闭合·零夹带) |
| 生产状态 | 未被动过,失败尝试无残留分支 |
#476 merge commit = ecdff68c53f25e59b5c32c5324aaa92c0a79dcbf
git merge-base --is-ancestor → ✅ 是 origin/test 祖先
对照组:origin/main 判为「不是 test 祖先」 → 证明该命令会返 false,查法有效
#476: 2 commits / 2 files
app/api/api_v1.py
web/app/(dashboard)/admin/orgs/page.tsx
新增 _seat_owning_org_ids(column, keyword) 抽取函数 + experience_store_name 查询参数。
原 seat_username 逻辑被重构进同一函数,行为等价(通配符 % _ \ 转义照旧)。
experience_store_name 列生产上已存在main: app/models/user.py:52 experience_store_name = Column(String(50), ...) 命中 1
对照组 test: 同一行 同一位置 命中 1
main 上迁移: migrations/versions/phase62_002_experience_store_seat.py 已存在
⇒ 不需要新迁移,生产库该列在早前发版时已建。
改的全是既有常量与既有 effect(ORG_SEARCH_FIELDS / SEAT_FIELD_CARRY / 防抖反查)。
「全部」模式分两次请求取并集(接口两参同传是 AND,而「全部」要 OR)。
store_namemain seats/page.tsx:63 { value: "store_name", label: "门店名称", ... }
对照组 test 同一行 同一内容
⇒ 带过去的字段名生产侧接得住。
4 个文件全清点:
app/api/api_v1.py
web/app/(dashboard)/admin/orgs/page.tsx
scripts/release_main.py
tests/scripts/test_release_main.py
settlement/ 命中 0 ✅ migrations/ 命中 0 ✅ nginx 命中 0 ✅
对照组:昨天那批 nginx 命中 1 → 证明查法有效
select 已导入main app/api/api_v1.py:13 from sqlalchemy import select, func
root 于 2026-08-20 发布 release/tooling-fix-20260820 → main
main 有 test 无: 86f4ef6d fix(release-tool): 生产 MR description 超限截断
b585c388 feat(release): dev 自助合并发 test(= #375 的内容)
判据 grep -c '_API_MERGE_SUBJECT_RE': main 2 / test 2(此前 main 为 0)
⇒ 生产上的发版工具已是新版,#375 从发版清单剔除。
main app/api/api_v1.py 中 experience_store_name 命中 0 ← 期望 0
对照组 test 同文件命中 4 ← 证明查法有效
{"commit_ids": ["28dff8ec...", "8f7a6b0f..."],
"changed_files": ["app/api/api_v1.py", "web/app/(dashboard)/admin/orgs/page.tsx"]}
与手验逐字一致。
$ sudo release-to-prod --mr 476 --branch release/org-search-store-name-20260820
❌ cherry-pick 8f7a6b0f 冲突且不止进度表文档,已中止
冲突文件=['web/app/(dashboard)/admin/orgs/page.tsx']
工具拦得对,不是工具坏了。
#476 依赖的 SEAT_FIELD_CARRY 常量:
main 命中 0 ← 生产上根本没有
test 命中 2 ← 对照组
main 上已知存在的 ORG_SEARCH_FIELDS 命中 4 ← 证明查法有效
SEAT_FIELD_CARRY 由 MR #368(81208bf7 feat(admin): 机构页检索条件带进席位页,长官 8-10)
引入,#368 从未发生产。#476 在它之上加一行 experience_store_name: "store_name",
底座不在 → 必冲突。
上次筛法只认 /change/N 长格式的合并记录,但 Codeup 还有一种短格式
Merge #N into test,我整批漏掉了。
长格式提到的 MR: 98 个
短格式提到的: 138 个
只有短格式、被我漏掉的: 172~374 共 138 个
这 138 个里大部分已通过 release/mr-* 发过生产(cherry-pick 换了 SHA,所以仍出现在差集里),
但至少 #367 / #368 是真没发的(SEAT_FIELD_CARRY 物理 0 命中坐实)。
⚠️ 其余 136 个我没有逐个验,不排除还有漏网。
seats/page.tsx 的差异 #368 补不满,差 3 行,来自 #367
(3fe59336 fix(admin-seats): 操作列收窄 260→112px · 修「设备」列被 sticky 遮挡)。
| 文件 | main→test 总差异 | #367 | #368 | #476 | 闭合 |
|---|---|---|---|---|---|
orgs/page.tsx |
54+ / 13- | — | 20+ / 2- | 34+ / 11- | ✅ 精确 |
seats/page.tsx |
25+ / 6- | 3+ / 1- | 22+ / 5- | — | ✅ 精确 |
| 6 个测试文件 | 逐个比对 | — | 全部独家贡献 | — | ✅ 6/6 |
加法精确等于总差异 ⇒ 这三个 MR 覆盖该范围全部改动,零夹带、零缺失。
4 commits / 9 files
app/api/api_v1.py ← 唯一后端文件
web/app/(dashboard)/admin/orgs/page.tsx
web/app/(dashboard)/admin/orgs/[id]/seats/page.tsx
web/__tests__/ 下 6 个测试文件
settlement/ 0 · migrations/ 0 · nginx 0
50c2c8d0 fix(admin-seats): 补回被发生产打回的检索字段下拉 + 记账该文件的发版陷阱
事故:2026-08-09 发 Phase70 到生产,用 --accept-test-side 解冲突,
而 git checkout --theirs 取的是**被 pick 的 commit 的历史快照**,不是 test 终态
→ 前端「检索字段下拉」被打回。三方符号实证:发版前 8 / 事故后 0 / test 8
✅ 该坑已由 root 堵上:可信副本 release_main.py:680-684 明写
「--theirs 是历史快照不是终态,故显式点名的文件 cherry-pick 全完成后一律 checkout test 终态」。
本次方案不依赖 --accept-test-side(三个 MR 点名后加法已闭合,不需要它)。
上次失败尝试残留分支数: 0 ← 中止发生在 push 之前
长官此前点名的是 #476。现在物理证明它必须和 #367、#368 一起发。
按「发版令一次一用、必须现场点名 MR」的红线,我不自行扩大范围。
请长官定:
#367 + #368 + #476 —— 加法闭合,两个页面都落到 test 终态#368 + #476 —— 席位页会少那 3 行操作列宽修复(纯样式,不影响功能)云机环境 · 非验收证据。