docs(tasks): post-merge review fix brief for ui-kit K0-K7 and onboarding 2-4 (agent loop)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
This commit is contained in:
Jesse_Chen
2026-10-26 22:36:12 +08:00
co-authored by Claude Opus 5.5
parent 24d6c9414d
commit 2e690f654c
2 changed files with 117 additions and 0 deletions
+1
View File
@@ -40,6 +40,7 @@
| `TASK-rectification-explicit-open-20261023.md` | `PROGRESS-rectification-explicit-open-20261023.md` | **明说要校正只回一句话(issue #103)**:找会话直接读一张对服务角色撤权的表、必然失败被吞(真正进行中的也续不上);`candidate_accepted` 被算作进行中挡住入口和提议卡;兜底只给一句话。产品选 C;只改入口口径、经 RPC 找会话、删兜底,不改共享状态集合、不动表。BUG-1423 | 已合入 staging | 分支 `codex/rectification-explicit-open-20261023` |
| `TASK-chart-table-span-20261023.md` | `PROGRESS-chart-table-span-20261023.md` | **星盘页本命 / 月亮行星表挤进左栏(issue #102)**:#87 给表包了 `ChartSymbolHelp` 后跨栏规则失配;根因修法是 `VedicLayout` 用固定整行容器承载表格,跨栏只认容器;加结构断言防复发。BUG-1422 | 已合入 staging | 分支 `codex/chart-table-span-20261023` |
| `TASK-ui-kit-migration-20261023.md` | `PROGRESS-ui-kit-0-base-20261023.md`;`PROGRESS-ui-kit-1-shell-20261023.md`;`PROGRESS-ui-kit-2-chat-20261023.md`;`PROGRESS-ui-kit-3-chart-20261023.md`;`PROGRESS-ui-kit-4-people-20261023.md`;`PROGRESS-ui-kit-5-pages-20261023.md`;`PROGRESS-ui-kit-6-rectification-20261023.md`;`PROGRESS-ui-kit-7-cleanup-20261023.md` | **界面统一换成组件库**:shadcn base-nova(补 `shadcn/tailwind.css`)· Lucide · Motion · react-resizable-panels · dnd-kit · Zustand;lint 拦手写控件(白名单只减不增);对话旁星盘面板;会话、档案拖动排序(动表);长相不变。产品 2026-10-23 拍板 D1~D8;8 个 issue(K0~K7)串行,取代全站动效 #98 #100 #101 | K0–K7 已在测试环境,待验收 | 原型 https://claude.ai/artifact/PGnWsjHhu38KJseEfEMNWG |
| `TASK-ui-kit-onboarding-fix-20261026.md` | — | **组件库 K0~K7 与启程(二)~(四)事后验收**:桌面首屏后整页重挂、中英切换看不出选中、提示层每次 DOM 变化全页扫描、启程动效对所有人生效且会藏内容、清单数据只拉一次、拖动排序 N 个请求与部分失败、缺真库重读测试、首屏超 2%、依赖卫生、补回削弱的测试、启程(二)三处未做 | 待执行(#111 承载) | `codex/ui-kit-onboarding-fix-20261026` |
| —(门禁修复,无新任务书) | `PROGRESS-birth-journey-contract-20261025.md` | **测试分支过不了门禁,网站停在完整数据版(二)**:BUG-1439 出生时间合同;BUG-1440 测试画布;BUG-1441 侧栏流式检查等第一次补画结束再数帧。页面不改 | 已合入 staging,等门禁 | `codex/gate-birth-journey-contract-20261025` |
| `TASK-onboarding-journey-20261022.md` | `PROGRESS-onboarding-1-data-20261022.md`;`PROGRESS-onboarding-2-intake-20261022.md`;`PROGRESS-onboarding-4-motion-20261022.md` | **新用户启程**:建档加「先看谁的盘」(自己 / 帮别人看,本人资料可后补)、人物关系字段、首问免费(服务端原子)、起步三问、启程清单(七项从数据推导,收费项标价,老用户可见)、八条一次性提示(含星盘四页签)、启程流程专用动效。产品 2026-10-22 拍板 D1~D6;动表经产品同意进循环,拆四个 issue 串行。BUG-1420 已被文档去重占用,本轮首问免费记 BUG-1421。(一)T1+T2 在 `codex/onboarding-1-data-20261022`。(二)T3+T4 记 BUG-1431,在 `codex/onboarding-2-intake-20261022`。(四)T7 在 `codex/onboarding-4-motion-20261022` | (一)(二)(三)已在 staging;(四)本分支待验收 | 原型 https://claude.ai/artifact/PcTwMVb9RD611R3qStxv3U |
| `TASK-site-motion-20261022.md` | — | **全站动效**:换页按侧栏方向滑入、选中块跟随、页签、盘型切换星体移宫、换人、翻日期、列表补位、弹窗从触发处长出、抽屉、顶部提示、点数滚动、中英交叉淡入;重写 DESIGN §6(推翻 180 ms 上限与 Spatial Instant),不引动画库,先验证 View Transitions。产品 2026-10-22 拍板;三个 issue,排在启程(三)之后、启程(四)之前;**2026-10-23 被 ui-kit-migration 取代** | 已取代 | 原型 https://claude.ai/artifact/7u9goivnmTNSGTNWNeVMQd |
@@ -0,0 +1,116 @@
# 修复单:组件库迁移与新用户启程(二~四)事后验收(issue #96 #97 #99 #104~#111,2026-10-26)
- 被验范围:`origin/staging` 上 `4d63475ca`(#96)~ `d0cf53c45`(BUG-1441)共 14 个提交。产品 10-24 要求「先合进测试环境、验收稍后做」,这是那次的事后验收。
- 原任务书:`TASK-onboarding-journey-20261022.md`(T3~T7)、`TASK-ui-kit-migration-20261023.md`(K0~K7)。
- 执行方:Grok。**一个分支** `codex/ui-kit-onboarding-fix-20261026`,从最新 `origin/staging` 开,一条修复一个提交;**只推这个分支,验收通过前不要再直接推 staging**(「先合后验」只适用于 10-24 那一批)。
- BUG 编号:开工时核对最大号 +1(当前 staging 到 BUG-1443)。
- 承载 issue:#111(本单进度与回报都写在 #111);其余 issue 等本单合入后一起转真机。
## 验收方法与结论(Claude)
四个子代理逐个提交读 diff,Claude 对下面标「已复核」的条目亲自核对了 staging 源码。全量前端测试、构建、真库测试在 Linux 复跑中(本机需先补装新依赖),结果出来后追加到 #111。
通过、无需改的:#110(校正选项卡迁移,键值、停止、只读状态都不变);三个门禁修复提交(BUG-1439~1441)改测试都带三栏,没有丢掉「流式时侧栏不重画」等真保证;合盘「开始前确认扣点」只是界面一步,服务端扣点与价格来源没变,不会重复扣;#102 星盘表整行、BUG-1083 手机不横滚仍成立;`Home()` 的 useState / useRef 没有增长;测试资料都是虚构的。
## 必修(按严重程度)
### U1 · 桌面端首屏后整页重挂(#105、#106,已复核)
- `components/shell-frame.tsx`:可拖分栏的代码块到达前返回普通 `div` 包 `children`,到达后改成 `<Resizable.ResizablePanelGroup>…<ResizablePanel>{children}`。父元素类型和层级都变了,React 会把整个 `Home()` 和侧栏**卸载再重挂**:每次桌面加载、每次窗口跨过移动端断点都会发生,启动 effect 跑两次、揭幕可能再闪一次、正在流式的回答丢失。
- `components/chat-chart-frame.tsx`:`column` 从 `<div className="chat-chart-frame">` 里挪进 `<Split>`,同样整列重挂(转录、输入框、校正组件的本地状态和滚动锚都丢)。第一次打开、以及记住「已打开」的每次加载都会发生。
修法:`children` 在两种状态下必须处在**同一位置、同一组祖先元素类型**之下(例如永远渲染同一个外层容器,分栏只作为兄弟节点或用 CSS 切换;或者分栏组件在服务端与首帧就同步渲染,不懒加载)。不得用 `key` 强行保持来掩盖。
验收:加测试:渲染 `ShellFrame` / `ChatChartFrame`,在分栏模块「到达」前后,子组件的挂载计数器只增加一次(mount 1 次、unmount 0 次);跨断点切换同样只 mount 一次。
### U2 · 中英切换看不出选中了哪个(#108、#109,已复核)
`globals.css` 里旧的 `.report-language-switch button`(约 4456 行)、`.report-export-segment button`(约 4050 行)、`.synastry-lang button`(约 4733 行)不在任何 CSS layer 里,`background: transparent` 压过组件库的 `data-active:` 样式;而选中样式只认 `[aria-pressed="true"]` / `[aria-checked="true"]`,新的 Tabs 两个都不设。结果:报告页语言切换、导出抽屉的语言分段、合盘报告的语言按钮,中文和 English 看起来一样,#90 定的主题色选中态没了;导出的「整篇报告 / 自选章节」卡片也丢了主题色边框(`.report-export-mode[aria-checked]` 被删)。
修法:删掉这几组旧规则(或改成按 `[data-active]` / `[aria-selected="true"]` 写),选中态回到 #90 的口径:边框与文字用 `--color-action-strong` / `--color-action`,背景保持中性;「整篇 / 自选」卡片的选中边框同样恢复。星盘页 #107 已用 `[data-active]`,照它的写法。DESIGN.md 同步。
验收:加测试:渲染三处切换,选中项与未选中项的 computed 类 / 属性不同,且选中项命中主题色规则;源码里不再有这三组只认 `aria-pressed` / `aria-checked` 的选中规则。
### U3 · 一次性提示层对每次 DOM 变化全页扫描(#97,已复核)
`components/onboarding-hint-layer.tsx` 对 `document.body` 开 `MutationObserver`(`childList: true, subtree: true`),每次变化跑 5 次 `querySelector` 加一次 `querySelectorAll`。回答流式时每个字都触发,**对所有用户、一直挂着**。
修法:没有待出提示(全部已看过、清单已关、或条件都不满足)时不挂观察器;需要时只观察锚点所在的容器,或改成在各锚点组件里用 ref 回调上报,不扫全页;流式期间(红线 6 本来就不出提示)暂停观察。
验收:加测试:`hintsSeen` 全满或清单已关时,观察器数量为 0;流式渲染 200 个片段时 `scan` 调用次数为 0。
### U4 · 启程动效对所有用户生效,且会把内容藏起来等动画代码(#99,已复核挂载位置)
- `OnboardingMotionHost` 挂在 `app/(app)/layout.tsx`,对所有用户每个会话都播:追问胶囊进场、档案卡进场、星盘 / 大运画出来、任何合盘报告的 1.2 秒靠拢动画。D6 写明「**只限启程流程**」。
- `onboarding-run.ts` 的 `playEnter` / `playSynastry` 先把元素设成 `opacity: 0`,再去异步加载 Motion 代码块;网络慢时合盘报告或追问胶囊会一直看不见,直到代码下载完(违反红线 4:动效不能拿来填等待,更不能藏内容)。
修法:只在启程流程里播(例如清单未关闭且对应项未完成,或账户在首问完成前),其他用户一律不播;先拿到动画函数再隐藏元素,加载失败或超过 300 ms 未到就直接显示、不播。
验收:老用户(清单已关)fixture 下,上面四处动画的调用次数为 0;Motion 模块加载失败时元素 `opacity` 不是 0。
### U5 · 启程清单的数据只拉一次、且对所有人都拉(#97)
`lib/onboarding-journey.tsx` 的 `loadRemote` 每个 `userId` 在布局里跑一次:清单已关或进站已满的用户也跑;拉报告要本人 + 最多 19 人、每人 3 页串行;之后不再刷新,所以侧栏内跳转里加人、做合盘、生成报告后,`person` / `syn` / `report` 不打勾,`syn-ready` 提示要整页刷新才出。
修法:清单已关或已满时不拉;需要时一次请求拿「有没有至少一份报告 / 合盘」(服务端计数或 `limit 1`),不分页翻全部;在加人、合盘、报告完成这几个成功回调里刷新这三项。
验收:测试:清单已关的账户不发这组请求;加一个人后不刷新页面,`person` 项变成已完成。
### U6 · 拖动排序一次发 N 个请求,部分失败后屏幕与数据库不一致(#105 会话、#108 档案)
- `hooks/use-session-management.ts::reorderSessions`:第一次拖动时整组都算「变了」,每行一个请求并发;组里超过 40 条就撞 `sessionWrite` 每分钟 40 次的限流,部分 429 后整体回退,而且那一分钟里消息同步也被挤掉。
- `people-page.tsx::persistArchiveOrder`:最多 19 个 PATCH 并发,任何一个失败屏幕回到旧顺序,但已成功的几行留在库里,刷新后看到一个用户没选过的顺序。
- `lib/session-groups.ts::sortSessions`:有序号的排在没序号的前面,拖过一次之后,新开的对话和刚活跃的对话掉到组底,而不是组顶(任务书没有这条改变)。
修法:排序改成**一个请求写整组顺序**(服务端在一个事务里更新,失败整体回滚;路由仍按 `user_id` 限定、档案仍只限 `role='other'`),前端失败时回退即与库一致;新对话的排序规则保持「最新在上」,只有用户拖过的行按用户顺序。
验收:真库测试:写一组顺序后重读一致;模拟其中一行无权(别人的)时整组不变;会话组 60 条拖一次只发 1 个请求。
### U7 · 两个改表轮次缺「写入后重读」的真库测试(#105、#108)
现有 DB 测试只查列存在与授权。任务书要的是「写入顺序 → 重读 → 一致」,以及「不能改别人的」。随 U6 一起补进 `frontend/tests/database-*.test.ts`,必须真跑 `npm run test:db`(Windows 已知失败名单逐条比对)。
### U8 · 首屏体积超出 ±2%(#96、#97 等)
各提交各用各的基线:#96 +2.50%、#97 +4.21%、K1 +1.47%、K2 +0.72%(K2 用的是 gzip-9,口径不同)。以 `0f66d92d4`(这批之前的 staging)为基线、用同一口径重量一次(`npm run build` 后,取 `.next/server/app/index.html` 引用的全部 `/_next/static/*.js|css`,每个 `gzip -9` 后字节数相加);超过 2% 的部分,把启程清单、提示层、动效改成用到时再加载(任务书本来就这样要求),量完写进 PROGRESS。
### U9 · 依赖卫生(#104、#109)
- `input-otp` 写的是 `^1.5.0`,改成精确版本(任务书 D1)。
- 新加的 `cn`(shadcn 官方包,Claude 已核对来源与校验和,不是恶意包)不在任务书名单里,而且现在有两个 `cn` 实现并存:`src/components/ui/*` 用 `import { cn } from "cn"`,原有组件用 `@/lib/utils`。统一成一个(推荐留 `@/lib/utils`,按 `components.json`),删掉另一个依赖。
- `package-lock.json` 有 150 个包的地址改成了 `registry.npmmirror.com`。门禁本来就走镜像,所以不阻塞;但锁文件里的地址请改回 `registry.npmjs.org`(镜像只在安装时配置),保证别处也能复现。
### U10 · 补回被削弱的测试(#107、#109、#105、BUG-1439)
- 星盘盘型抽屉:点格子关闭、按 Esc 关闭,从源码文本检查改回渲染交互测试。
- 导出抽屉:Esc / 点遮罩关闭的测试和响应式 CSS 断言被删,补回。
- 登录页:K5 验收要求的交互测试(输入邮箱 → 发码 → 输码)补上。
- `chart-page-view.test.tsx` 大运打开次数从 `===` 改成了 `>=`,改回精确值或写清为什么不能精确。
- 外观菜单的勾选断言现在查的是共享组件文件,改回查外观菜单自己渲染出勾。
- `account-dialog-overlay.test.ts` 从渲染断言改成源码正则,改回渲染断言。
### U11 · 启程(二)的三处没做到(#96)
- 资料只有别人的账户:主题目录没加载完时 `isProfileComplete(profile, EMPTY_SUBJECT_CATALOG)` 判成「没建完档」,揭幕后可能闪出「看谁的盘」,热启动永远走冷路径(`home-bootstrap-run.ts::resolveLanding`、`home-warm-start.ts`)。目录未到时按「未知」处理,不得判成未建档。
- 起步第 1 问的「只有月亮」那一档实际走不到:星座只从今日星语取,而没有出生分钟时今日星语不请求。按任务书 T4 改为从已有的本命资料取月亮星座,不新增请求。
- 帮别人看时天空过场的副句「那一刻,{名字}的上升在……」没做(T3),补上。
## 小问题(顺手改,不单独验收)
- `react-client-lifecycle-test-support.ts` 一导入就设全局 `document`,七个做服务端渲染的测试文件因此不再模拟真实服务端;改成只在需要的测试里设。
- `.theme-menu-check` 已是死样式,删掉。
- 校正的 `skip_probe` 选中时停止按钮 `aria-pressed=false`;6 个没人用的旧校正组件按「多余入口宁可删除」直接删掉。
- 提示与动效共用 `"menu"` / `"hint"` 键,导致只有第一个闪 / 弹;按项区分。
- 清单「去做」用 `location.assign` 整页刷新,改成客户端跳转。
- `nudgeComposer` 的 `setTimeout` 卸载时清掉。
## 流程
#111 回报里写了「没有跑全量前端测试,也没有跑 Python 快速门」,紧接着 staging 门禁连红三次(BUG-1439~1441),测试环境停发约 10 小时。AGENTS §10:改动含前端就跑全量 `npm test`;含 `tests/**` 就跑快速门。本单交回前两样都要跑,回报里写退出码和失败数(与已知名单逐条比对)。
## 交回前必跑
- `tsc --noEmit`、`npm run lint`、全量 `npm test`(失败与已知名单逐条比)、`npm run build`(`/` 仍 Static、首屏按 U8 口径)。
- `npm run test:db`(U6、U7 改了表的读写路径)。
- Python 快速门 `run_quality_gate.py --profile quick`。
- `docs/testing/ui-kit-migration-20261023.md`、`onboarding-journey-20261022.md` 补上本单的真机步骤(桌面加载不闪、中英切换能看出选中、老用户无启程动画)。