test(contract): 让前端源码合同跟上搬家,快速门 Python 段恢复全绿(BUG-736)
三条断言过期,不是保证丢了:
- 149e1ec4 把创建路由改走 chatSessionCreateInsertRow(...),`user_id: user.id`
字面量消失。按三栏改成路由断 `userId: user.id`、write-contract 断
`user_id: input.userId`,两处都断,不放宽。
- 状态下沉第二批把合盘搬进新建的 use-synastry.ts,而 _home_surface() 只拼
OPTIONAL_HOME_HOOKS 白名单,于是 fetch("/api/synastry" 与「未能存入历史」
在并集里找不到。白名单补上该 hook 并注明新增 Home 级 hook 必须同步登记。
为什么没被拦住:这几条是 Python 测试,断言对象却是前端源码;前端轮次的验收
口径不含快速门,AGENTS §10 又只要求「任何 Python 改动」跑快速门——纯前端改动
落在两张网中间。验收方两轮都只跑前端套件,带红合入。防复发写进 BUG-736。
验证:test_supabase_user_data_contract.py 8 条全绿;快速门 pytest 段
792 passed / 1 skipped / 0 failed(此前 3 failed)。整体仍退出 1,剩余唯一
原因是本机无 rsync、无 Docker 的既有环境缺口。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
co-authored by
Claude Opus 5
parent
7ae6df3ebb
commit
dc8cae316e
@@ -11460,3 +11460,20 @@
|
||||
- 相关记录:BUG-721(同一形状的第三个实例)、BUG-734(同一轮的另一处)、BUG-733(同进程差分怎么写)
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-736 | 纯前端改动打红 Python 源码合同,快速门连续两轮带红合入
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-16
|
||||
- 最近更新:2026-09-16
|
||||
- 影响面:`tests/test_supabase_user_data_contract.py`、`scripts/run_quality_gate.py --profile quick`、`frontend/src/app/api/sessions/route.ts`、`frontend/src/hooks/use-synastry.ts`
|
||||
- 用户现象:无(门禁问题,用户不可感知)。
|
||||
- 触发条件:纯前端轮次移动了 `page.tsx` / 路由里的字面量或把逻辑搬进新 hook。
|
||||
- 根因:`test_supabase_user_data_contract.py` 用正则扫前端源码,`_home_surface()` 只拼 `OPTIONAL_HOME_HOOKS` 白名单里的文件。两轮改动各打红一批断言:`149e1ec4` 把创建路由改走 `chatSessionCreateInsertRow(...)`,`user_id: user.id` 字面量消失;状态下沉第二批把合盘搬进新建的 `use-synastry.ts`,它不在白名单里,于是 `fetch("/api/synastry"` 与 `未能存入历史` 在并集里找不到。**三条都是断言过期,归属校验与云端持久化保证本身没丢。**
|
||||
- 为什么没被拦住:这几条是 **Python 测试**,但断言对象是**前端源码**。前端轮次的验收口径(tsc / lint / `npm test` / `next build`)不含 Python 快速门,而 AGENTS §10 只要求「任何 Python 改动」跑快速门——纯前端改动落在两张网中间。验收方(Claude)两轮都只跑了前端套件,未跑快速门,因此带红合入。
|
||||
- 修复:`OPTIONAL_HOME_HOOKS` 补 `use-synastry.ts` 并加注释说明新增 Home 级 hook 必须同步登记;`user_id: user.id` 断言按「原值 / 新值 / 原因」三栏改成 `userId: user.id`(路由)+ `user_id: input.userId`(`chat-session-write-contract.ts`),两处都断,不放宽。
|
||||
- 验证:`.venv/bin/python -m pytest tests/test_supabase_user_data_contract.py` 8 条全绿;`run_quality_gate.py --profile quick` 的 pytest 段 **792 passed / 1 skipped / 0 failed**(此前 3 failed)。快速门整体仍退出 1,剩余唯一原因是本机无 `rsync` 与无 Docker 的既有环境缺口。
|
||||
- 防复发:**改动 `page.tsx`、Home 级 hook 或 `frontend/src/app/api/**` 的轮次,验收必须另跑 `run_quality_gate.py --profile quick`**,不能只跑前端套件——有 Python 测试把前端源码当断言对象。新增 Home 级 hook 必须同步登记进 `OPTIONAL_HOME_HOOKS`。取门禁退出码不得隔着管道(`| tail` 会把退出码换成 `tail` 的)。
|
||||
- 相关记录:BUG-729~731(创建路由改造)、BUG-464(会话持久化归属)
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
@@ -57,6 +57,10 @@ OPTIONAL_HOME_HOOKS = (
|
||||
_FRONTEND_SRC / "hooks" / "use-consultation-run.ts",
|
||||
_FRONTEND_SRC / "hooks" / "use-profile-onboarding.ts",
|
||||
_FRONTEND_SRC / "hooks" / "use-rectification-surface.ts",
|
||||
# 状态下沉把合盘从 page.tsx 搬进了自己的 hook(2026-09-16)。首页表面是这
|
||||
# 些文件的并集,新 hook 不进这张白名单,下面的合盘断言就会在代码完全正确
|
||||
# 的情况下变红。新增 Home 级 hook 时必须同步加进来。
|
||||
_FRONTEND_SRC / "hooks" / "use-synastry.ts",
|
||||
)
|
||||
|
||||
|
||||
@@ -133,14 +137,20 @@ def test_chat_page_uses_authenticated_cloud_persistence() -> None:
|
||||
assert '.from("profiles")' not in source
|
||||
assert '.from("chat_sessions")' not in source
|
||||
assert 'await writeChatSession(session.id, values, mode)' in source
|
||||
assert 'mode === "create" ? "/api/sessions"' in (
|
||||
write_contract = (
|
||||
Path(__file__).resolve().parents[1]
|
||||
/ "frontend"
|
||||
/ "src"
|
||||
/ "lib"
|
||||
/ "chat-session-write-contract.ts"
|
||||
).read_text(encoding="utf-8")
|
||||
assert 'user_id: user.id' in create_route
|
||||
assert 'mode === "create" ? "/api/sessions"' in write_contract
|
||||
# 原值: assert 'user_id: user.id' in create_route
|
||||
# 新值: 路由传 userId,由 chat-session-write-contract 落成 user_id
|
||||
# 原因: 创建路由改走 chatSessionCreateInsertRow(...)(BUG-729~731 那一轮),
|
||||
# 字面量搬了家;归属校验本身没变,断言要跟着搬,不是放宽。
|
||||
assert 'userId: user.id' in create_route
|
||||
assert 'user_id: input.userId' in write_contract
|
||||
assert '.eq("user_id", user.id)' in item_route
|
||||
assert '.upsert(' not in source
|
||||
assert 'await persistSession(userSession)' not in source
|
||||
|
||||
Reference in New Issue
Block a user