Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
9.7 KiB
9.7 KiB
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 核实;行号按符号定位)
- 全站没有任何地方能改本人的出生资料(回归):
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-20260924D1 写的是「户主本人也是其中一个,统一列表、统一操作;户主不可删」,并没有说「本人不可编辑」。
- 除首页外点头像直接回首页(是当初的设计,不是代码写错):
components/app-sidebar.tsx页脚:只有首页通过registerShellControls注册了controls,这时才渲染Menu.Root账户菜单;其他页走只读分支,是一个AppLink href="/",注释写「The account menu and its dialogs live on/」。- 出处:侧栏统一单(BUG-744~746);BUG_HISTORY 里写过「次级页点头像应当跳回首页而不是没反应」。
- 「我的报告」页顶部有一段说明和一行统计:
components/personal-report/personal-report-center.tsx的.report-center-hero,内容是「有填报到分钟的出生时间即可生成……你无需停留等待。」和「共 N 份 · 已完成 N 份 · ……」。
决策记录(产品 2026-09-28)
- 本人在
/people可以编辑:和他人使用同一张ChartProfileForm,保存走本人原来的PATCH /api/account。本人仍然不能删除。- 这推翻了
people-page.tsx里「本人 has no edit view here」的做法。
- 这推翻了
- 所有页面点头像都弹出同一个账户菜单,推翻侧栏统一单里「次级页头像 = 回首页链接」的约定:
- 切换主题:在当前页直接生效(
ThemePreferenceMenu本来就不依赖首页)。 - 「个人资料」「通用设置」「账户与点数」「退出登录」:在首页照旧直接打开弹窗;在其他页跳到首页,并自动打开对应的弹窗。
- 不把弹窗搬到每一页(那样首页首屏会多一个加载态,违反 AGENTS §6「揭幕后不得出现加载」),留作以后评估。
- 切换主题:在当前页直接生效(
- 「我的报告」去掉整个顶部说明区:说明段和统计行都删。页面从「报告记录」列表开始。生成按钮的
title悬停提示不动。
硬红线
- 本人出生资料只经
PATCH /api/account写入,并照accountProfilePatchSchema提交birth_time_source。不得把本人写进chart_profiles,不得在客户端伪造active_*或校正结果字段。 page.tsx行数不增长;Home()的useState/useRef数不增长。新逻辑放进hooks/或lib/或组件;删掉page.tsx里已经没人用的saveProfile解构。- 首页仍是
○ Static;首屏 gzip ±2%;揭幕后不出现 spinner / 骨架。 - 账户菜单只有一份实现(同一个
Menu.Popup),不准复制出第二份菜单。 - 改既有断言写「原值 / 新值 / 原因」三栏;动组件前先 grep
frontend/tests/里按源码文本断言的合同测试(sidebar-contract.test.ts、people-archive-view.test.tsx、personal-report-entry.test.ts等)。 - 不改表、不加迁移、不加依赖。隐私:测试只用虚构资料。
任务分解
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。
- 余额「N 点」:只读模式下若拿不到
- 首页:写一个类似
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 --noEmit0 错;npm run lint0 error。npm test全量:与基线比测试名清单,不得有测试名消失;失败清单与基线逐条同名(无 Docker 的 24 条)。rm -rf .next && next build:/仍○ Static;首屏 gzip 与基线同口径对比,在 ±2% 内(同一脚本在基线与交付各建一次)。python3 -m pytest tests/test_repo_privacy_markers.py -q。
让步顺序
- S2 的余额数字在只读模式下可以不显示。
- S2 跳转后打开弹窗若和首页揭幕时序冲突,可以等揭幕完成后再打开,但不得加等待态。
- S1 本人可编辑、S3 删除说明区不可让步。
交付
- 按 S1 / S2 / S3+S4 分提交,不推送;由 Claude 独立验收后快进推 staging。