# PROGRESS · 拆分首页巨石组件·第三批:onboarding/profile 与校正胶水(2026-09-01) 工作树:`.worktrees/home-split-batch3-20260901` 分支:`codex/home-split-batch3-20260901` 基线:`origin/staging` @ `80e77361`(含报告语气 PR #48 与出生精度 PR #49)。`551d6317` 之后 **没有** 未验收的 `page.tsx` 改动:`git log 551d6317..origin/staging -- frontend/src/app/page.tsx` 为空。 不要写成 `PROGRESS.md`。本轮未提交、未推送。 React Compiler 仍关。未引入 context/store。无手写 `useCallback`/`useMemo`。自定义 hook 内部 **0** 个 `useState` / `useRef` / `useEffect`。`site-styles` import 仍在 `page.tsx` 顶。`const BirthTimeRectification = dynamic(...)` 未动。 脏树未碰:`yinduzhanxing` @ `codex/minute-rectification-p0`、`.worktrees/fix-general-daily-20260815` 仍有本地 `page.tsx` 残留。 ## 度量 | 项 | 拆前(第二批后 2445 / staging 同文件) | 拆后 | 说明 | | --- | ---: | ---: | --- | | `frontend/src/app/page.tsx` 行数 | 2445 | 1997 | 目标 ≤2000,达标 | | `useState(` Home / profile hook / rectification hook | 26 / — / — | 26 / 0 / 0 | 独占 state 未下移 | | `useRef(` Home / profile / rectification | 19 / — / — | 19 / 0 / 0 | 同上 | | `useEffect(` Home / profile / rectification | 20 / — / — | 20 / 0 / 0 | 拉取/恢复 effect 仍在 Home | | `/` 路由 | `○ Static` | `○ Static` | webpack `next build --webpack` | | 首屏 JS gzip -9 | 第二批 501104 B | 503980 B = 492.2 KB | +2876 B / **+0.57%**(±2% 内) | | 前端测试 | staging 高于 2428 | **2460** | fail=0 skipped=0 | gzip 相对第二批的 +0.57% 含 `80e77361` 已合入的语气/精度前端,不单是本次搬家。同 SHA 干净树未再打一份对照包。 本批按任务书收官:starter 三函数、合盘起草、composer 小函数仍留在 `Home`。 ## Hook 调用顺序(红线 1) `useRouter` → `useState`×26 → `useRef`×19 → `useBirthTimeGuidedJourney` → `useSessionManagement` → `useProfileOnboarding` → `useRectificationSurface` → `useEffect`×8 → `useConversationScrollAnchor` → `useConsultationRun` → 其余 `useEffect` 新增的两个 hook **内部零 React hook**。`useState`/`useRef`/`useEffect` 在 Home 里的相对次序与搬前相同。 | 调用点 | 位置 | 原因 | | --- | --- | --- | | `useSessionManagement` | `useBirthTimeGuidedJourney` 之后 | 第二批已定;`openRectificationSession` 经模块级 holder 转发给尚未声明的校正 hook | | `useProfileOnboarding` | session hook 之后、第一条 `useEffect` 之前 | 账户/引导函数要给校正 hook 与咨询 hook | | `useRectificationSurface` | profile hook 之后、第一条 `useEffect` 之前 | `persistSession` / `updateSession` / `refreshAccount` / `openAccountDialog` 已齐 | 依赖方向:session → Home → profile / rectification / consult。四个 hook 文件 **不得、也没有** 互相 import。 跨声明顺序的回调用 **模块级 `{ current }` 对象**,不是新的 `useRef`(避免改变 Home hook 数量): - `rectificationSessionOpener`:session hook 的 `openRectificationSession` 转发到校正 hook - `guidedBirthTimeReady` / `editDeclaredBirthTimeDetailsHolder`:`useBirthTimeGuidedJourney` 早于 profile hook,原函数声明提升不再可用 `setDraft` 等仍是 `Home` 内 function declaration(JS 提升),可出现在 hook 参数里。 ## 任务 1–2 · 搬家 函数体相对 `80e77361:frontend/src/app/page.tsx` 去缩进后逐行 **IDENTICAL**(22/22): | 文件 | 行 | 内容 | | --- | ---: | ---: | | `frontend/src/hooks/use-profile-onboarding.ts` | 424 | `refreshAccount` … `signOut` | | `frontend/src/hooks/use-rectification-surface.ts` | 306 | `refreshRectificationEntrySummary` … `handleRectificationMessagesChange`(含 `resumeRectificationSession.current =`) | 公证抽样(全部 22 个,不少于 4):`refreshAccount` 19、`persistProfile` 41、`saveOnboardingName` 22、`openRectificationCase` 105、以及其余 18 个均为 IDENTICAL。改名清单:**零**。 仍留在 Home:`chooseSuggestedQuestion` / `startSuggestedConsultation` / `startDailyStarlanguageConsultation`、`draftSynastryQuestionFromChart` 及之后、`copyAssistantMessage` / `handleComposerKeyDown`。`send`/`submit` 已在第二批进咨询 hook。 ## 合同测试路径(同一 token,只换读取面) 拼接件扩容:可选 `use-profile-onboarding.ts` / `use-rectification-surface.ts`。 | 测试 | 原路径 | 新路径 | | --- | --- | --- | | `profile-state.test.ts` `refreshAccount` 切片 | 已是 `homeSurface` | 仍 `homeSurface`(函数已进 profile hook;去掉未用的 `readFileSync`) | | `profile-persistence.test.ts` `persistProfile` | 已是 `homeSurface` | 仍 `homeSurface` | | `birth-time-assessment-loading.test.ts` `saveOnboardingBirth`/`Place` | `page.tsx` + overlay | `homeSurface` + overlay | | `birth-time-guided-review-fixes.test.ts` 终端 CJK | `homeSurface` | 仍 `homeSurface` | | `chat-navigation-a11y` sign-out 切片 | `homeSurface`,终点 `chooseSuggestedQuestion`(仍在 page,拼在 hook **之前**) | 终点改为 profile hook 的 `return { refreshAccount`(断言内容未改) | | `rectification-agentic-entry` `handleRectificationProfileIncomplete` | 终点 `draftSynastryQuestionFromChart`(仍在 page) | 终点改为仍相邻的 `handleRectificationMessagesChange` | | `tests/test_daily_and_rectification_entrypoints.py` `openRectificationFromHomepage` | `PAGE`+starter+cloud | 若存在则拼接 rectification hook | | 三个 Python `_home_surface()` | 可选 session/consult hook | 再列入两个新 hook | ## 验证 - `./node_modules/.bin/tsc --noEmit`:通过。 - 全量 `npm test`:**2460 pass / 0 fail / 0 skipped**。 - Python:`test_session_management_entrypoints.py`、`test_supabase_user_data_contract.py`、`test_birth_time_journey_contract.py`、`test_daily_and_rectification_entrypoints.py` 全绿。 - `./node_modules/.bin/next build --webpack`:`┌ ○ /` Static。首屏 JS gzip-9 503980 B vs 第二批 501104 B(+0.57%)。 - 行为抽查:无登录态浏览器点选会话 / 发送咨询。搬家由源码合同锁住。 未改 `.gitea/workflows/**`。未动数据库。未提升 `main`。未重开 React Compiler。未提交。 ## 明确未做 - 合盘起草与 composer 小函数(任务书本批不动)。 - 未把 onboarding/profile/rectification **state** 下移进 hook。 - 引擎运行时治理在独立 worktree `engine-runtime-hygiene-20260901`,不碰 `page.tsx`。