CODE REVIEW REPORT · MB · test → stage · 2026-05-28

21 commits 准备进 stage —— DB 角度 0 风险

用户特别关心数据库。我独立审了 21 个 commit,0 个新 migration,0 DDL, 新查询列映射全验过;dry-run merge 干净,Performance Engine SSO 完整保住。 只剩一个产品决策要你拍板:/share/* 的访问范围。

base · origin/stage @ fbb6155 head · origin/test @ f93e80a merge-base · 99f886e reviewer · mb-cc-e4e0 (independent)
verdict
PASS
DB 角度可合
commits
21
stage..test
files
16
+1,654 / −309
migrations
0
DDL 不变
blockers
1
用户拍板 /share 范围
§1SCOPE · 改了什么

21 个 commit 大部分是 UI hotfix,唯一新功能是 share pages MVP。

按性质归类。注意 src/routes/auth.ts 那个 −210 行**不是删** —— 是 stage 那边 PR #11 加了 PE SSO 中间件,test 这边从未有过,diff 反映静态差。

类别 commits 主要文件
share pages MVP 3-4 src/lib/share-data.ts NEW · +313
src/components/share-pages.tsx NEW · +192
src/routes/pages.tsx +34
pm-vibe UI hotfix 10+ public/app.js · public/pm-shell.css · src/components/delivery-detail-modal.tsx
tab badge / hot card bubble / storyboard 多镜头 / share 间距文案
回归修 1 src/routes/v7.ts +7
revise-plan 不再自动续 delivery(PR #12 已审过)
docs 4 docs/handoff-pm-vibe-creative-gate.md
docs/product-usage-guide-update-2026-05-27.md NEW
看似删 auth.ts 0 test 从未有 PE SSO middleware,stage 单独加的。
静态 diff 反映为 −210 行,但 test 没真删什么。
§2DB · 用户最关心的一节

0 新 migration,0 DDL,新查询只读不写。

stage 和 test 的 migrations/ 目录字节级一致 —— 都到 0020_dedupe_pm_vibe_system_assets.sql。新代码只新增 SELECT 查询, INSERT/UPDATE/DELETE 一行没加。

✓ verified

migrations 文件完全一致

git diff origin/stage..origin/test -- migrations/ → 空输出。

schema 风险面 = 0。

✓ verified

新 SQL 只在 share-data.ts

2 个 SELECT:plan / delivery 各一。LEFT JOIN 5 张已有表(creative_boards, crawl_slots, agent_runs, users, hot_materials)。

✓ verified

列映射逐字段对照过

14 个列引用全部映射到真实 DDL 定义。详见 §3 那个修复案例。

⚠ process gap

share-data 的 SQL 无 unit test

tsc 看不见 SQL 字符串内容。F97ED27 那个 bug 是 live smoke 才抓到的 —— 不是当前 bug,是后续防御点。

§3CASE · 那个已修的 SQL 错配

F97ED27 — 把 column 写错表上,live smoke 才抓到。

原来的 SELECT 写的是 d.summary,但 deliveries 表没有 summary 列 —— summary 只在 creative_boards 上。部署到 pm-vibe 后第一次访问 /share/delivery/<id> 直接 500。

// commit f97ed27 — fix(pm-vibe): /share/delivery 500 — column d.summary does not exist

// before:
SELECT d.summary, d.title, d.video_url, ...
  FROM deliveries d
  LEFT JOIN creative_boards cb ON cb.id = d.creative_board_id
// PostgresError: column d.summary does not exist  → 500

// after:
SELECT cb.summary AS summary, d.title, d.video_url, ...
  FROM deliveries d
  LEFT JOIN creative_boards cb ON cb.id = d.creative_board_id
// 改用 cb.summary(创意板的 summary)AS summary,前端 data.delivery.summary 不变

根因:summary0001_init.sql:34creative_boards.summarydeliveries 表从来没这列。typecheck 无法发现,因为 SQL 字符串是 opaque template literal。

§4MERGE SAFETY · 我跑了 dry-run

合 stage 完全干净,PE SSO 没被覆盖。

复制本地 repo 到 /tmp/mb-merge-dryrun,切到 stage, 跑 git merge --no-commit origin/test。 git 自动合并成功,零 conflict。我用 grep 又核了一遍 PE SSO 三处引用全部保留。

dry-run · git merge origin/test 结果

conflicts
0
Automatic merge went well
auth.ts 行数
484
= stage 当前长度
PE SSO refs
3 / 3
全保留
import 完整 · src/index.tsx:10 仍然 import { ..., performanceEngineSso } from './routes/auth'
mount 完整 · src/index.tsx:28 仍然 app.use('*', performanceEngineSso)
middleware 实现完整 · src/routes/auth.ts:219 仍然 export const performanceEngineSso = ...

为什么这次安全:merge-base 是 99f886e(没 PE SSO),stage 是 base + PE SSO commits,test 是 base + 其他改动。两边没动同一个文件的同一个区,git 默认的加性合并直接保留双边。

§5VALIDATION · 我重跑了一遍

5 个 test suite + typecheck + build —— 全绿。

我没信 mb-codex 的 claim,自己重跑了一遍。这是 review discipline 的要求: reviewer 不 paraphrase,自己 grep / 跑测试 / 看 diff。

npm run typecheck
clean
tsc --noEmit 无输出
test:v54
61 / 0
all green ✓
test:v10-task-actions
33 / 0
all green ✓
test:v10-platform-terminal
24 / 0
all green ✓
test:delivery-creative-payload
ok
meta allowlist verified
npm run build
clean
Done in 4120ms
§6RISK · 第一个要 flag 的

SQL 字符串绕过 type checker,bug 要 live smoke 才能抓。

F97ED27 修的那个 column-on-wrong-table 错配是已发生事实。结构性问题: tsc 不查 SQL,没有 schema-driven contract test。下次再写错列, 还是要部署到 sozai-test / pm-vibe 跑一遍才能发现。

Risk 1 · process gap

没 schema 兜底测试这条路 —— 不阻塞这次合并

现在审完 share-data.ts 的 SELECT 我手验了一遍 14 个列引用,全对得上。 但下次同样模式的新 SQL 上,这条防线还是空的。建议后续: 加一个 contract test 拿 schema dump 验列名 + alias 对照表。

不阻塞这次合并。已知 bug 已修;其他列已逐个 verify。

§7RISK · 第二个要 flag 的(要你拍板)

/share/* 是"链接级"访问 —— 这是 §0.6 拍板的设计吗?

pages.use('/share', requireSession(...)) 任何登录的 FunPlus 成员 有链接就能查看完整 plan / delivery 数据。 viewerIsCreator 只决定 action 按钮显隐,不挡查看。

访问者 能查看? 能 act(按钮显?) 当前实现
未登录 → Feishu OAuth (next=back-to-share-URL)
已登录 · 非创作者 viewerIsCreator: false 隐藏按钮
已登录 · 创作者本人 creator_user_id === viewer.id
已登录 · admin viewer.role === 'admin'
Decision needed · 用户拍板

这是你想要的访问模型吗?

代码里 §0.6 注释明说"用户 2026-05-28 拍板:链接级分享"。 但我作为 independent reviewer 要 double-check 一下,因为含义是: 任何登录 FunPlus 内部用户拿到链接就能看到任意 plan / delivery 的完整内容。

是 = 继续合并、部署。
否 = 需要缩到 creator + admin only?或加白名单?告诉我紧到什么程度。
§8VERDICT · 我的结论

PASS — 可以合 test → stage。

DB 角度无风险。dry-run merge 干净。validation 全绿。一个 risk 是 process gap(已修 bug 不阻塞), 一个 risk 是产品决策(待你拍板)。

FINAL · PASS

可以合,但建议先回答 §7 那个 /share 范围问题。

理由(按重要性):

  • 0 migrations 加,0 DDL 改,schema 风险面归零。
  • 新 SQL 列映射全对得上(F97ED27 已修,其他 13 个手验过)。
  • dry-run merge 干净,Performance Engine SSO 完整保住。
  • 5 个 test suite + typecheck + build 全绿,我自己重跑过。
  • 跟 PR #12 (V11 stage prep) 同样的合法路径 —— test commits 加性,不踩 stage-only 改动。

暂停点: mb-codex 现在已经把 merge/deploy 暂停,等你回答 §7 那个 /share 访问范围问题。 回了 → 立刻合。