Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
115 lines
13 KiB
Markdown
115 lines
13 KiB
Markdown
# 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` 时,改出生时间不会移动已确认的排盘时间(账户路由既有行为),需产品决定。
|