Files
Jyotisha/docs/tasks/TASK-self-edit-avatar-menu-20260928.md
T

103 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK · 星盘档案可编辑本人、各页头像弹账户菜单、我的报告去掉提示(2026-09-28)
## 基线与依赖
- **串行**:本单改 `frontend/src/app/(app)/page.tsx`,必须等 `TASK-birth-sky-polish-20260928`(分支 `codex/birth-sky-pacing-20260928`)由 Claude 验收并推上 staging 之后再开工。开工时 `git fetch origin --prune`,以当时的 `origin/staging` 为基线,SHA 写进 PROGRESS。
- 分支 / 工作树:`codex/self-edit-avatar-menu-20260928` / `.worktrees/self-edit-avatar-menu-20260928`。
- 进度记录:`docs/tasks/PROGRESS-self-edit-avatar-menu-20260928.md`。
- BUG 编号:开工时核对 `docs/BUG_HISTORY.md` 最大号。polish 单占用 BUG-1080,本单从 **BUG-1081** 起;若开工时已被占用,顺延并在 PROGRESS 写明。
## 事实(Claude 2026-09-28 在 `origin/staging` 核实;行号按符号定位)
1. **全站没有任何地方能改本人的出生资料**(回归):
- `ab6c55f8`(星盘档案 P1,2026-09-25)的提交说明写「/people replaces the settings chart pane」:设置弹窗里原来的星盘资料块被 `/people` 取代,首页那块表单(`chart-library-panel.tsx`)随后在 `d08ffdc0` 作为「没有引用」的文件删掉。
- `components/people/people-page.tsx`:只有 `role === "other"` 有「编辑」按钮;本人那一格只显示「本人不能删除」。常量 `SELF_GENDER_NOTE` 上方注释写「本人 has no edit view here」。
- 设置 → 个人资料(`components/profile-panel.tsx`)只能改头像和性别。
- 服务端能力还在:`PATCH /api/account`,由 `lib/account-profile-patch.ts` 的 `accountProfilePatchSchema` 校验,要求改出生资料时必须同时提交 `birth_time_source`。
- 首页 hook `use-profile-onboarding.ts` 里的 `saveProfile` 已经没有任何 UI 调用。`page.tsx` 只从 hook 里解构出它,并没有用。
- 能证明这是漏掉而不是有意:生时校正的用户文案 `declaredWindowLockedReply`(`lib/rectification-agentic/user-copy.ts`)里写着「请先到资料里改出生时间」,但用户找不到这个地方。
- 星盘档案任务书 `TASK-people-archive-p1-20260924` D1 写的是「户主本人也是其中一个,统一列表、统一操作;户主不可删」,并没有说「本人不可编辑」。
2. **除首页外点头像直接回首页**(是当初的设计,不是代码写错):
- `components/app-sidebar.tsx` 页脚:只有首页通过 `registerShellControls` 注册了 `controls`,这时才渲染 `Menu.Root` 账户菜单;其他页走只读分支,是一个 `AppLink href="/"`,注释写「The account menu and its dialogs live on `/`」。
- 出处:侧栏统一单(BUG-744~746);BUG_HISTORY 里写过「次级页点头像应当跳回首页而不是没反应」。
3. **「我的报告」页顶部有一段说明和一行统计**:`components/personal-report/personal-report-center.tsx` 的 `.report-center-hero`,内容是「有填报到分钟的出生时间即可生成……你无需停留等待。」和「共 N 份 · 已完成 N 份 · ……」。
## 决策记录(产品 2026-09-28)
1. **本人在 `/people` 可以编辑**:和他人使用同一张 `ChartProfileForm`,保存走本人原来的 `PATCH /api/account`。本人仍然不能删除。
- 这推翻了 `people-page.tsx` 里「本人 has no edit view here」的做法。
2. **所有页面点头像都弹出同一个账户菜单**,推翻侧栏统一单里「次级页头像 = 回首页链接」的约定:
- 切换主题:在当前页直接生效(`ThemePreferenceMenu` 本来就不依赖首页)。
- 「个人资料」「通用设置」「账户与点数」「退出登录」:在首页照旧直接打开弹窗;在其他页跳到首页,并自动打开对应的弹窗。
- 不把弹窗搬到每一页(那样首页首屏会多一个加载态,违反 AGENTS §6「揭幕后不得出现加载」),留作以后评估。
3. **「我的报告」去掉整个顶部说明区**:说明段和统计行都删。页面从「报告记录」列表开始。生成按钮的 `title` 悬停提示不动。
## 硬红线
1. 本人出生资料只经 `PATCH /api/account` 写入,并照 `accountProfilePatchSchema` 提交 `birth_time_source`。不得把本人写进 `chart_profiles`,不得在客户端伪造 `active_*` 或校正结果字段。
2. `page.tsx` 行数不增长;`Home()` 的 `useState` / `useRef` 数不增长。新逻辑放进 `hooks/` 或 `lib/` 或组件;删掉 `page.tsx` 里已经没人用的 `saveProfile` 解构。
3. 首页仍是 `○ Static`;首屏 gzip ±2%;揭幕后不出现 spinner / 骨架。
4. 账户菜单只有一份实现(同一个 `Menu.Popup`),不准复制出第二份菜单。
5. 改既有断言写「原值 / 新值 / 原因」三栏;动组件前先 grep `frontend/tests/` 里按源码文本断言的合同测试(`sidebar-contract.test.ts`、`people-archive-view.test.tsx`、`personal-report-entry.test.ts` 等)。
6. 不改表、不加迁移、不加依赖。隐私:测试只用虚构资料。
## 任务分解
### S1 · 本人可在星盘档案编辑(BUG-1081)
- `people-page.tsx`:本人也有「编辑」按钮,位置同他人;编辑视图复用 `ChartProfileForm`(显示岁差与性别,和他人一致)。本人的编辑视图**没有**删除区。
- 保存:把 `use-profile-onboarding.ts` 里 `saveProfile` 用到的持久化逻辑(`persistProfile` 及其载荷构造)抽成 `lib/` 里的纯函数或小 hook,供 `/people` 调用;首页若已不再需要 `saveProfile`,从 hook 和 `page.tsx` 一起删掉。
- 保存成功后,刷新 `/people` 列表里的本人数据,并让用到本人资料的缓存失效(侧栏、当前人物、星盘页),和编辑他人后的做法一致。执行方先查清编辑他人时刷新了哪些,照做。
- 出生资料一改,照原 `saveProfile` 的做法重置 `birthTimeConsultationConsent` 这类依赖出生资料的本地状态。首页重新挂载时会从 `/api/account` 重新读取,这一点要核实。
- 失败时在表单里提示,文案对照 VOICE。
- 「性别在设置 → 个人资料里改」这句小字:表单里已经能改性别,删掉。
- **验收**:
- 测试:本人有「编辑」按钮;本人编辑视图无删除;保存调用 `PATCH /api/account` 且带 `birth_time_source`;不写 `chart_profiles`;失败有提示。
- BUG-1081 写全:现象、触发、根因(`ab6c55f8` 取代设置里的资料块时漏了本人编辑)、修复、验证、防复发(加一条合同测试:全站至少有一个本人出生资料编辑入口),并说明旧测试为什么没拦住。
### S2 · 各页头像弹出账户菜单
- `app-sidebar.tsx`:只读分支不再渲染 `AppLink href="/"`,改成和首页同一个 `Menu.Root`。菜单项的回调在没有 `controls` 时改成跳转:`/?account=profile|general|billing|logout`。
- 余额「N 点」:只读模式下若拿不到 `credits`,这一格不显示数字,不要显示 0。
- 首页:写一个类似 `NewChatDeepLink` 的小组件或 hook,读取一次 `?account=` 意图,在账户就绪后打开对应弹窗,然后用 `history.replaceState` 去掉这个参数(刷新或后退都不会再弹)。放在 `page.tsx` 之外,`page.tsx` 只接一行线。
- 未登录时参数无效,照常走登录。
- **验收**:
- 测试:只读模式渲染菜单而不是链接;四个菜单项在只读模式各自跳到对应的 `?account=`;首页读取意图后打开对应弹窗并清掉参数;非法值忽略。
- `sidebar-contract.test.ts` 里锁「只读 = 链接到 /」的断言按新行为改写,三栏说明。
- 无头 Chrome:在 `/people` 视口 1280×800 与 390×844 各截一张菜单展开图,放 scratchpad,路径写进 PROGRESS。
### S3 · 我的报告去掉顶部说明区
- `personal-report-center.tsx`:删 `.report-center-hero` 整段,以及只给它用的 `hasGenerating` / `latestReady` 计算(先确认没有别处在用)。`globals.css` 里只给它用的样式一并删。
- `personal-report-entry.test.ts` 的 “global report copy …” 测试:对 `reportCenterSource` 的四条 `match` 改成 `doesNotMatch`(锁住不再出现),三栏说明。对 `componentSource` 的断言不动。
- **验收**:报告页首屏直接是「报告记录」;测试通过。
### S4 · 文档
- `frontend/DESIGN.md`:侧栏页脚在各页的行为;`/people` 本人可编辑;报告页顶部。
- `frontend/docs/VOICE.md`:新增或删除的文案。
- `CHANGELOG.md`:一条。
- `docs/BUG_HISTORY.md`:BUG-1081。
- `docs/testing/self-edit-avatar-menu-20260928.md`(新建真机清单):
- 在 `/people` 改本人出生时间,回首页,再打开星盘页核对已更新;
- 在 `/chart`、`/people`、`/reports`、`/ephemeris` 各点一次头像,菜单都弹出;点「账户与点数」跳首页并打开点数弹窗;刷新后不再弹;
- 在次级页切换主题,立即生效;
- 我的报告顶部没有说明段。
## 验证
- `tsc --noEmit` 0 错;`npm run lint` 0 error。
- `npm test` 全量:与基线比测试名清单,不得有测试名消失;失败清单与基线逐条同名(无 Docker 的 24 条)。
- `rm -rf .next && next build`:`/` 仍 `○ Static`;首屏 gzip 与基线同口径对比,在 ±2% 内(同一脚本在基线与交付各建一次)。
- `python3 -m pytest tests/test_repo_privacy_markers.py -q`。
## 让步顺序
1. S2 的余额数字在只读模式下可以不显示。
2. S2 跳转后打开弹窗若和首页揭幕时序冲突,可以等揭幕完成后再打开,但不得加等待态。
3. S1 本人可编辑、S3 删除说明区不可让步。
## 交付
- 按 S1 / S2 / S3+S4 分提交,**不推送**;由 Claude 独立验收后快进推 staging。