Files
Jyotisha/docs/tasks/PROGRESS-self-edit-avatar-menu-20260928.md
T
Jesse_ChenandClaude Opus 5.5 4ed0e8e791
Independent Staging Quality Gate / validate (push) Failing after 7m28s
Independent Staging Quality Gate / publish (push) Skipped
docs(tasks): Claude acceptance for self edit + account menu
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 00:56:12 +08:00

115 lines
13 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.
# PROGRESS · 星盘档案本人编辑、各页头像菜单、我的报告去说明(2026-09-28)
任务书:`docs/tasks/TASK-self-edit-avatar-menu-20260928.md`。产品授权直接执行(Claude 子代理)。
- 基线:`origin/staging` = `adbb2054`(birth-sky-polish 已推 staging 后开工,串行)
- 分支 / 工作树:`codex/self-edit-avatar-menu-20260928` / `.worktrees/self-edit-avatar-menu-20260928`(三个本地提交,**未推送**)
- 环境:Node v22.14.0(`/exec-daemon/node`);系统 `python3`;无 Docker;无头 Chrome(本机 `/dev/shm` 只有 64MB,需 `--disable-dev-shm-usage`)
- BUG 编号:开工时最大 BUG-1080;本单 BUG-1081
## 结论
| 项 | 结果 | 提交 |
| --- | --- | --- |
| S1 本人可在星盘档案编辑(BUG-1081) | 完成 | 1 |
| S2 各页头像弹账户菜单 | 完成 | 2 |
| S3 我的报告去掉顶部说明区 | 完成 | 3 |
| S4 文档(DESIGN、VOICE、CHANGELOG、BUG_HISTORY、真机清单、索引、本文件) | 完成(DESIGN / VOICE 随 S1、S2 各自提交,见偏离 1) | 1–3 |
| 让步 | 未砍:只读模式余额照常显示;弹窗在首页 `hydrated && account` 后打开 | — |
## S1 · 本人可编辑(BUG-1081)
- `lib/self-profile-save.ts`:`selfProfilePatchBody`(原 `persistProfile` 的载荷,带 `birth_time_source`,**不带** `gender`)、`saveSelfProfile`(`PATCH /api/account`,返回应用服务端出生时间真值后的资料与 `chartBirth.fingerprint`)、`saveSelfGender`(单字段 `{ gender }`)。
- 首页 `use-profile-onboarding.ts` 的 `persistProfile` 改用 `saveSelfProfile`(行为不变)。无 UI 调用的 `saveProfile` 删除;它独用的 hook 参数 `setBirthTimeConsultationConsent`、`setRectificationError` 从 hook 类型与 `page.tsx` 调用处一并移除(`page.tsx` 里这两个 state 仍被别处使用)。
- `people-page.tsx`:本人详情底部「本人不能删除」下面加「编辑」;编辑视图与他人同一张 `ChartProfileForm`,标题「编辑我的资料」、说明「称呼和出生资料。」,无删除区。`saveSelf`:出生资料 `saveSelfProfile(draft)`,性别变了再 `saveSelfGender`;然后 `pinChartSnapshotIdentity`(星盘缓存按新指纹失效)、`clearHomeWarmSnapshot`(首页暖快照与今日卡)、`invalidateEphemerisPage`、布局 provider `setAccount`(资料与 `chartBirth.fingerprint`)、`invalidateSubjectCatalog` 后重读列表。失败时表单里显示服务端文案,没有就「保存失败,请重试」。
- 编辑他人后原来只 `invalidateSubjectCatalog` + 重读(已核实);本人多出的几项是因为本人资料还活在布局 provider、首页暖快照和星盘 / 星历缓存里。
- 删掉详情「性别」下的小字「在「设置 → 个人资料」里改」和它的 CSS 规则 `.people-archive-fact-note`。
- `.people-archive-foot` 加 `gap`、`justify-items: center`(灰字与按钮上下排)。
## S2 · 各页头像弹账户菜单
- `lib/account-dialog-intent.ts`:`/?account=profile|general|billing|logout` 的生成与解析,其他值一律忽略。
- `app-sidebar.tsx`:页脚在两种模式都是同一个 `Menu.Root`(全文件只有一个)。首页由 `controls` 控制开合,四项 `Menu.Item` 就地开弹窗;其他页菜单自持开合状态(`useState`,在 `AppSidebar` 里,不在 `Home()`),四项是 `Menu.LinkItem` + `AppLink` 到 `/?account=<dialog>`,点了收起手机抽屉。主题菜单不变、就地生效。余额「N 点」来自布局 provider 的账户,只读模式照常显示。账户还没读到时页脚是同尺寸的静态块(无链接、无转圈);未登录仍是「去登录」。
- `people-home-links.tsx` 新增 `AccountDialogDeepLink`:挂载时读一次 `?account=`、立刻 `replaceState` 去掉(非法值也去掉),`ready` 后调用 `openAccountDialog`(billing 带 `source: "account-menu"`,与首页菜单一致),之后不再触发。`page.tsx` 只多一行接线(import 合在同一行)。
- `page.tsx`:1364 → 1363 行;`Home()` 的 `useState` / `useRef` 数不变(未新增)。
## S3 · 我的报告
- 删 `.report-center-hero` 整段(说明段 + 统计行)与只给它用的 `latestReady`(`useMemo` import 随之移除);`hasGenerating` 仍给轮询用,保留。`globals.css` 删 `.report-center-hero*`、`.report-center-meta` 与移动端那条规则。生成按钮的 `title` 不动。
## 截图(本地宿主页,虚构资料,交付构建的编译 CSS)
- `/tmp/claude-1000/-workspace-Jyotisha/fb88e01e-1ced-4bcc-92fe-44c5bdcc878e/scratchpad/selfedit/people-menu-1280x800.png`(/people 本人详情,底部「本人不能删除」+「编辑」;侧栏账户菜单展开)
- 同目录 `people-menu-390x844.png`(手机抽屉里展开账户菜单)
- 两张图 CDP 读回:菜单四个弹窗项的 href 依次为 `/?account=profile|general|billing|logout`,无横向滚动。宿主页用 esbuild 打包真实组件,`next/navigation`、`next/link` 用本地 shim(未提交)。
## 验证
| 项 | 基线 `adbb2054` | 交付(第 3 个提交) |
| --- | --- | --- |
| `tsc --noEmit` | 0 错 | 0 错 |
| `npm run lint` | 0 error / 127 warning(polish 验收记录) | 0 error / 126 warning |
| `npm test` | tests 4322 · pass 4267 · fail 24 · cancelled 0 · skipped 31 | tests 4334 · pass 4279 · fail 24 · cancelled 0 · skipped 31 |
| 失败清单 | 24 条(Docker / PostgreSQL / 部署套件) | 与基线逐条同名 |
| 测试名对比(`frontend/AGENTS.md` 方法) | — | 消失 1(改名,见下表)、新增 13 |
| `python3 -m pytest tests/test_repo_privacy_markers.py` | — | 63 passed |
| `rm -rf .next && next build` | `/` ○ Static | `/` ○ Static;路由表与基线逐行相同 |
| `page.tsx` 行数 / `Home()` state·ref 数 | 1364 / — | 1363 / 不变 |
未跑 Python 快速门:本单没有改 `scripts/**` 或 `tests/**`(Python)。
### 首屏 gzip(`index.html` 引用的 `/_next/static/*.js|css` 逐个 gzip -9 求和;基线在临时 detached 工作树同机同脚本干净构建)
| | 基线 `adbb2054` | 交付 | 变化 |
| --- | ---: | ---: | ---: |
| JS | 650,972 B | 651,520 B | +548 B(+0.08%) |
| CSS | 66,126 B | 66,031 B | −95 B(−0.14%) |
JS 增量是首页 bundle 里的 `AccountDialogDeepLink`、`account-dialog-intent` 与侧栏只读菜单分支;CSS 减少是删掉的报告中心说明区与 `.people-archive-fact-note`。
## 改动的既有断言(原值 / 新值 / 原因,测试文件里同样写了注释)
| 测试 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `sidebar-contract` · read-only when `/` is not mounting it | 只读页脚是 `<AppLink className="profile-trigger" href="/">` | 不再有页脚链接;全文件一个 `Menu.Root`,两种模式都渲染;只读弹窗项是 `AppLink` 到 `accountDialogHref(dialog)` | S2 产品决定 |
| `home-warm-return-lifecycle` · warm return to bare / … | `followLink("林遥,打开账户")` | 断言页脚不再是该链接;用等价站内跳转 `followHref("/")`(记下目标再路由,与 `AppLink` 同步骤) | S2;测试守的是「暖回裸 `/` 落空白首页」 |
| `new-chat-from-people-lifecycle` · stashed rectification … not reopened | 等并点只读页脚链接回 `/` | 等页脚菜单按钮出现、断言无该链接,`followHref("/")` 回 `/` | 同上 |
| `new-chat-from-people-lifecycle` 测试工具 `button(label)` | 取第一个文本含 label 的按钮 | 跳过 `.profile-trigger`(页脚菜单按钮也含本人名字) | S2 后页脚是按钮;不改断言,只避免点错元素 |
| `profile-gender-ui` · detail card(**改名**:`…本人 points to 设置 → 个人资料` → `…本人 edits it in the same form as everyone`) | 本人 `<dd>未填<small …>在「设置 → 个人资料」里改</small></dd>`,本页无本人性别单选 | 本人 `<dd>未填</dd>`;详情卡无单选,本人编辑视图有 | BUG-1081 |
| `profile-gender-ui` · CSS 类清单 | 含 `people-archive-fact-note` | 去掉(类与规则已删) | BUG-1081 |
| `settings-mvp-contract` · chart library owns self-profile editing | `onSubmit={(event) => void saveOther(event)}` | `editingSelf ? saveSelf(event) : saveOther(event)`,且 `await saveSelfProfile(draft)` | BUG-1081 |
| `people-archive-regressions` · people delete … | `title={selectedId ? "编辑人物" : "添加一个人"}` | 前面多一档 `editingSelf ? "编辑我的资料"` | BUG-1081 |
| `consultation-entrypoint` · profile and place saves do not auto-start … | 切出 `saveProfile` 断言不评估 | 断言首页无 `saveProfile`;切出 `/people` 的 `saveSelf` 断言不评估 | `saveProfile` 删除 |
| `profile-onboarding-birth-sky-reveal` · only own onboarding place save triggers | 切出 `saveProfile` 断言不含 `onOwnBirthPlaceSaved` | 断言首页无 `saveProfile`(people-page 不触发由下方原循环锁住) | 同上 |
| `birth-time-consultation-consent` · source-aware consultation options | `match(page, /birthTimeConsultationOptionsCopy\(savedProfile\)/)` | `doesNotMatch`;录入表单那条断言不动 | 这句只在已删的 `saveProfile` 保存提示里 |
| `birth-time-guided-review-fixes` · terminal CJK copy … | `match` 「出生资料已保存。${…(savedProfile)}」 | `doesNotMatch`;其余断言不动 | 同上 |
| `personal-report-entry` · global report copy … | 报告中心源码四条 `match`(分钟即可生成 / 需要具体分钟 / 与某一次对话无关 / 后台继续处理) | 四条 `doesNotMatch`,另断言无 `report-center-hero` / `report-center-meta` / 报告概览;按钮 `title` 断言不动 | S3 |
测试工具改动(非断言):`tests/home-surface.ts` 的首页源码清单加 `src/lib/self-profile-save.ts`(`persistProfile` 的载荷与 `applyPersistedBirthTime` 行搬到这里,`profile-persistence` 的原断言继续命中);两份生命周期测试新增 `followHref` 帮手。
## 偏离任务书
1. **DESIGN / VOICE 随各自的 S1、S2 提交**,不全压在 S3+S4:AGENTS §7.5 要求改 UI 的提交同时更新 DESIGN。S4 提交里是 S3 的 DESIGN、CHANGELOG、真机清单、索引与本文件。
2. **首页 `saveProfile` 连带删掉两个 hook 参数**(`setBirthTimeConsultationConsent`、`setRectificationError`),它们只被 `saveProfile` 用;否则会留下未使用的参数。
3. **本人保存成功后不再显示「出生资料已保存。…」提示**:那句只在已无 UI 的 `saveProfile` 里;星盘档案保存后直接回到已更新的详情。若产品想要一句确认,另开单(详情卡现有的 notice 是错误样式,不宜复用)。
4. **本人编辑视图说明写「称呼和出生资料。」**,没写他人那句「填报的出生时间保存后不能再改」——本人资料走账户接口,可以再改。
## 另发现(不在本单范围,未改)
- **封面城市取不到**:库里中国地点标签以「中国 · 」开头(`lib/geoapify-location-service.ts` 生成 `中国 · 省 · 市 · 区`),而 polish 单的 `lib/birth-sky/caption.ts` `birthSkyCity` 要求第一段是省级名,遇到「中国」直接返回 null。所以中国出生地的封面实际只会印到时刻、不带城市。该代码已在 staging(`adbb2054`)。
- 账户接口在 `birth_time_status = confirmed` 时,声明字段变化不会重置状态(`resolveAccountBirthTimeApplicationPatch` 直接返回 `{}`),这是既有语义,本单未动;本人在星盘档案改时间后若原来是 confirmed,排盘仍按 confirmed 的时间。建议产品确认是否符合预期。
## 环境缺口
- 无登录态与真机:本人编辑的真实保存、跳首页开弹窗、手机抽屉行为只在单测、源码合同与本地宿主页截图上验证;真机清单 `docs/testing/self-edit-avatar-menu-20260928.md`(17 条)。
- 无 Docker:24 条 DB / 部署套件失败与基线逐条同名。
- 未推送、未部署。
## Claude 验收(2026-09-29,含 Claude 补修 `3d0f1cf6` BUG-1082)
独立重跑:`tsc` 0 错;lint 0 error / 126 warning;`npm test` 4335 · pass 4280 · fail 24,失败清单与 polish 验收逐条同名(Docker / DB / 部署);`rm -rf .next && next build` `/` ○ Static;首屏 gzip(Claude 口径,基线 `adbb2054` = 650,972 / 66,126)→ 651,520 / 66,031,JS +548 B(+0.08%),CSS −95 B;pytest(隐私 + birth_sky)通过。`page.tsx` 1364 → 1363,`useState`/`useRef` 70 → 70。看过 `/people` 390 宽菜单截图。
执行方报告的上一单缺陷(中国出生地 caption 永远没有城市)核实属实:存储标签以「中国 · 」开头。Claude 在本分支补一个提交修复并记 BUG-1082。
偏离裁定:1–4 接受。遗留给产品:本人 `birth_time_status = confirmed` 时,改出生时间不会移动已确认的排盘时间(账户路由既有行为),需产品决定。