From 53c0b9eaee317be227f30e63ec6c9479026464dd Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Tue, 29 Sep 2026 07:53:01 +0800 Subject: [PATCH] docs(tasks): mobile chart overflow, confirmed-time edits reset, sky replay with share Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE --- docs/tasks/README.md | 1 + ...obile-chart-and-confirmed-edit-20260929.md | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 docs/tasks/TASK-mobile-chart-and-confirmed-edit-20260929.md diff --git a/docs/tasks/README.md b/docs/tasks/README.md index b19d8c74..f2acc35c 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -252,6 +252,7 @@ | `TASK-birth-sky-followup-20260928.md` | `PROGRESS-birth-sky-cover-20260928.md`(追加单) | **天空封面追加**:报告封面按生成时出生资料指纹绑定(方案 A,旧报告永不显示);首次建盘揭幕改群星汇聚过场(无按钮、3 秒预算、可点跳过、减弱动态只淡入淡出) | 已验收(Claude 2026-09-28),已推 staging | 新功能,不开 BUG | | `TASK-birth-sky-polish-20260928.md` | `PROGRESS-birth-sky-polish-20260928.md` | **天空封面第三轮**:星盘页弹层只留图;封面印「日期 时刻 · 城市」(推翻「不印出生资料」);过场放慢到约 6.5 秒;兑换弹窗改到首条付费消息被拒(402)时再弹;BUG-1080 过场被兑换弹窗挡住 | 已实现待验收(分支 `codex/birth-sky-pacing-20260928`,未推送);BUG-1080 investigating(Chrome 下「弹窗盖住过场」已排除,修复不依赖根因) | BUG-1080 | | `TASK-self-edit-avatar-menu-20260928.md` | `PROGRESS-self-edit-avatar-menu-20260928.md` | **本人可编辑 + 各页头像菜单 + 报告页去说明**:`/people` 本人可编辑出生资料(BUG-1081,`ab6c55f8` 漏掉);次级页头像弹同一账户菜单、弹窗项跳 `/?account=`;我的报告删顶部说明与统计 | 已实现待验收(分支 `codex/self-edit-avatar-menu-20260928`,未推送) | BUG-1081 | +| `TASK-mobile-chart-and-confirmed-edit-20260929.md` | `PROGRESS-mobile-chart-confirmed-edit-20260929.md` | **手机星盘 + 确认时间可改 + 天空定格**:iPhone 星盘被宽表撑出屏幕(BUG-1083);confirmed 状态改声明字段也重置排盘时间(推翻 BUG-264 约定);「那一刻的天空」改为重放汇聚→定格→右上角分享 | 待领取 | BUG-1083 | | `TASK-serif-headings-20260928.md` | `PROGRESS-serif-headings-20260928.md` | **全站标题改用自托管宋体、正文保持黑体**:产品推翻 BUG-737「CJK 不用衬线」结论(保留「声明的字体必须可加载」「不落系统宋体」两条);Noto Serif SC SemiBold 按通用规范汉字表 6500 字 unicode-range 切片自托管(改名 Jyotisha Serif SC),swap 不 preload;首页宋体流量 ≤300 KB;先于天空封面单 | 已实现待验收(分支 `codex/serif-headings-20260928`,未推送) | 不开新 BUG;BUG-737 追加说明 | | `TASK-cend-ui-claude-alignment-20260916.md` | `PROGRESS-cend-ui-r1/r2/r3-20260916.md` | **C 端界面向 claude.ai 产品界面对齐(三轮串行 R1→R2→R3,都动 `globals.css`,不得并行)**:根因是 `frontend/CLAUDE_DESIGN.md` 扒的是 **claude.com 营销官网**,它自己在 Known Gaps 里写明 claude.ai 产品界面不在范围内,而 `DESIGN.md:3` 把它当成了产品界面的实现契约。**R1**:`--font-display` 里 Tiempos Headline / StyreneB **从未加载**(无 `@font-face`、`public/` 无字体、`layout.tsx` 只 vendor 了 Inter),中文标题全站落到 **宋体 / SimSun**,波及 20 处含助手回答的 h2/h3(BUG-737);亮色强调色 `#85432f` 与暗色 `#d78064` 不同源,产品拍板亮色换 **Claude coral `#cc785c`**,**易漏点**是 `globals.css:16` 的 `--color-ring` 硬编码在 `@theme inline` 里不跟随 `:root`,另有第四个 `:root` 亮色块(`:4358`)必须同步(BUG-738);`.composer-footer` 常驻 44px + 顶栏 68px + `--composer-reserve` 148px,每屏固定吃掉 216px,模型选择器移进输入框内部、删掉底栏、顶栏收到 46px 并删「分析对象」副标题。**R2**:空状态是营销落地页(hero 卡 + 两张 132px 入口大卡 + 3 列 156px 主题卡),输入框被压在 **800px 以上**内容之下,重排成「问候 + 居中输入框 + 两枚入口 pill + 一排 chip」。**R3**:侧栏两个 `
` 拍平成一条「最近」、星盘的两个入口(侧栏分组 + 账户菜单)收敛到一处、删掉逐条助手头像。**决策记录 D3 推翻 DESIGN.md「报告强调色与应用同源」一句**(报告刻意保留深棕)。原型图 https://claude.ai/code/artifact/da275da6-2954-4f50-99aa-32bb8694d38b(三套画面 + 明暗,页面标题就是建议字体栈的实际渲染)。环境缺口:无登录态无 Chrome,四项真机观感留 `docs/testing/`。BUG 段 737–738 | 待领取 | — | | `TASK-cend-surfaces-claude-alignment-20260916.md` | `PROGRESS-cend-shell-20260916.md`、`PROGRESS-cend-report-20260916.md`、`PROGRESS-cend-rectification-20260916.md`、`PROGRESS-cend-chart-eph-20260916.md` | **次级页面对齐(上一单的续篇,R4→R5/R6,R7、R8 可并行)**:星盘 `/chart`、星历 `/ephemeris`、报告 `/reports` **各是脱离 app 外壳的独立全屏页**,顶部只有一个「返回对话」链接、侧栏整个消失,且三家各写了一套一模一样的 `*-shell`/`*-topbar`/`*-hero` 骨架——与上一单 E5 同根因(营销站 band 结构被套到产品界面)。**R4** 抽只读导航外壳 `AppNavRail`(只用现成的 `GET /api/sessions` + `GET /api/account`,会话行走 `sessionHref` 跳 `/?c=`;**刻意不带**重命名/删除/收藏/归档——那套连着 `Home()` 的乐观更新与回滚,搬过来会撞 useState 增长门禁)。**R5** 星盘五 tab 下划线化 + 参数合表 + 行星表横向滚动;星历日期导航改 `‹ 日期 ›`。**R6** 报告中心卡片网格改行式列表;阅读页加常驻目录。**R7** 生时校正把可信区间从盘面板标题行提成常驻条(窄屏 `.is-compact` 下盘面板是 overlay,现在默认看不到区间),五个 `technique-audit` 折叠块收成两段。**R8** 设置内容区收窄(880px 弹窗里表单铺了 690px)、套餐卡三修饰符收敛成两态。**已解锁**:原挡路的设置单已于 `111b4a84`(BUG-698)合入。**两条不得回退**:BUG-698 的 `@supports (height: 1dvh)` 写法(重复声明回退会被 Lightning CSS 折叠)、BUG-616/617 的报告盘面 grid 实现。默认不占 BUG 号 | **R4–R8 全部已实现并验收合入** | R4:抽出 `AppNavRail`(只读,两个 GET,零写操作)+ `SecondaryShell`,三个次级页并入 app 外壳并删掉各自的 shell/topbar/hero;四个路由渲染标记**完全不变**(`/` `/chart` `/ephemeris` 仍 Static);CSS gzip −0.25%。`/reports/[reportId]` 留给 R6 与目录一起做。两处自身健壮性问题被测试抓到:`usePathname()` 可为 null、`fetch` 可能不存在。差点弄丢 BUG-717 的 eyebrow 文案(已放回)。R8:表单分区收窄到 440px(列表分区不变)、套餐卡三修饰符收敛成互斥的 `is-current` / `is-recommended`,`--highlighted` 删除改为滚动定位;手机端 `order:-1` 改挂 `[data-plan-alias]`(版位不是状态)。测试 3350→3354(净增 4),失败清单与基线逐条一致;`/` 仍 Static;我的干净构建实测 CSS gzip −3 字节。**遗留待产品拍板**:`?plan=` 深链现在完全没有视觉指向,只有滚动位置。R6:报告中心卡片网格改行式列表、阅读页并入外壳并把目录挪到右侧常驻。**任务书 E10 过期**——目录在 `cfcd369d` 就已存在,本轮是挪位置定稿而非从零加。挂外壳带出一个真实打印风险已处理:`.chat-app`/`.chat-panel` 是 `height:100%;overflow:hidden`,裸 `window.print()` 会把九节报告裁成一页,阅读页因此多挂一条只在挂载期生效的 print 样式解锁外壳。「生成中的分节进度」做不了——`REPORT_LIST_COLUMNS` 不返回节数,按 VOICE.md 不许前端编。R7:区间常驻条与盘面折叠收敛。**任务书 E9 也不准确**——对话区顶部早有常驻条 `RectificationTimeline` 且窄屏可见,真正只在盘面标题行的是**代表分钟**;因此没另造第二条,在既有条上补齐代表分钟与已答题数(与盘面同一次 `workingRectificationTime()` 调用)。折叠块实际是 **8 个**不是 5 个。**触发让步顺序第 5 条**:收窄进度未做——服务端无该字段,且 `candidate_range` 会放宽(BUG-572),前端相减会把一次放宽报成收窄,已写进 `BLOCKED.md`。顺带修掉一个**静默失效的旧断言**(`slice(indexOf(A), indexOf(B))` 在 B 改名后变成几乎整份文件,四条 `doesNotMatch` 假通过)| diff --git a/docs/tasks/TASK-mobile-chart-and-confirmed-edit-20260929.md b/docs/tasks/TASK-mobile-chart-and-confirmed-edit-20260929.md new file mode 100644 index 00000000..10f8e2bd --- /dev/null +++ b/docs/tasks/TASK-mobile-chart-and-confirmed-edit-20260929.md @@ -0,0 +1,121 @@ +# TASK · 手机上星盘显示不全 + 已确认出生时间改资料后跟着变 + 「那一刻的天空」改为动画定格(2026-09-29) + +## 基线与依赖 + +- 基线:`origin/staging` = `da989c15`(本人编辑 + 头像菜单已部署)。开工前 `git fetch origin --prune`,基线 SHA 写进 PROGRESS。 +- 分支 / 工作树:`codex/mobile-chart-confirmed-edit-20260929` / `.worktrees/mobile-chart-confirmed-edit-20260929`。 +- 进度:`docs/tasks/PROGRESS-mobile-chart-confirmed-edit-20260929.md`。 +- 不改 `page.tsx`。同日若有别的单改 `globals.css` 里 `.chart-page-*` 或 `lib/account-profile-patch.ts`,先停下告知 Claude。 +- BUG 编号:开工时核对 `docs/BUG_HISTORY.md` 最大号(写作时 BUG-1082)。本单 M1 记 **BUG-1083**;M2 是产品决策,改的是 BUG-264 以来锁住的行为,在 BUG-264 下追加「2026-09-29 产品修订」,不另开号。 + +## 事实 + +### M1 · 手机上星盘显示不全(产品 2026-09-29 真机截图,iPhone,staging,星盘 → Bhava) + +- 北印度盘远大于屏幕,右侧与下方被裁掉。星盘卡片左边框可见,右边框在屏幕外。下面的参数表与行星表看不到。 +- 按截图倒推,盘面所在列约 **540px 宽**,屏幕约 390px。这与 `.chart-page-planet-table { min-width: 34rem; }`(`globals.css`,34rem = 544px)吻合。推测:宽表的最小内容宽度一路向上撑开了某层网格或弹性容器的列宽,盘面 `width:100%` 跟着变大。 +- 已排除:`.chart-page-varga-table-block`、`.chart-page-planet-table-wrap`、`.chart-page-vedic` 都已有 `min-width: 0`。**哪一层没收住还没找到**,候选有: + - `.chart-page-vedic-layout`(窄屏下只有 `display:grid`,没有 `grid-template-columns`,隐式列是 `auto`,本身也没有 `min-width:0`); + - `.chart-page-params`; + - 更外层的星盘页面板与 `SecondaryPageShell`。 +- 本命、D9、Bhava 各页的盘下都有宽表,所以很可能不止 Bhava 一页。9-28 的盘型改造(BUG-1076~1078)把行星表从 26rem 放宽到 34rem,这可能是诱因。 + +### M2 · 已确认的出生时间,改资料后排盘不变 + +- `lib/account-profile-patch.ts` `resolveAccountBirthTimeApplicationPatch`:当前 `birth_time_status === "confirmed"`(或 legacy 有分钟、状态为空)时直接 `return {}`。于是改了出生日期 / 时间 / 地点,`active_birth_time` 仍是旧的已确认分钟,星盘按旧时间排。 +- 锁定这条行为的是 `frontend/tests/account-api.test.ts` 的测试 “ordinary declaration edits clear stale candidate application but never overwrite confirmed active time”,来自 BUG-264。 +- 现在本人可以在 `/people` 编辑资料(BUG-1081),这个行为第一次对用户可见。 + +## 决策记录(产品 2026-09-29) + +1. **M2:用户改了出生资料,就按新资料排盘,即使原来是「确认」状态**(包括采用过校正结果)。产品原话:「用户改生日肯定是得到信息了」。 + - **这推翻了 BUG-264 起「已确认分钟不被普通资料修改覆盖」的约定**,以及 `account-api.test.ts` 上面那条测试的对应断言。执行方不得以既有约定为由拒改。 + - 只有**声明字段**(`declarationFields`:出生日期、时间与来源、时段 / 范围、地点代码等)真的变了才重置;只改称呼、岁差、性别、头像,**不得**动已确认时间。 + - 重置后与非确认状态的现有做法完全一致:给了精确的零误差时间就是 `accepted` + 新分钟,否则是 `reported`;`rectification_case_id` 清空。 +2. M1 是缺陷,按「手机上完整看到盘、表格在自己的框里横向滚动」修,不改桌面布局。 +3. **M4:星盘页点「那一刻的天空」,改为重放群星汇聚动画并定格在最后一帧,右上角「分享」才导出海报**。产品原话:「点击那一刻的天空,然后重新跑咱们的星星动画,最后定格到最后一帧,然后右上角可以分享,分享的时候才是咱们的海报」。 + - 这替换了 polish 单 P1 的「压暗页面 + 静态图 + 图下保存图片」弹层。 + - 首次建盘过场(首页)不变:仍然放完自动淡出。 + +## 硬红线 + +1. M1 只改 CSS / 结构,不改盘面绘制与数据;桌面 ≥1024px 的两栏布局不变。表格仍然是在自己的容器里横向滚动,不许为了不溢出把列挤坏或删列。 +2. M2 只改服务端派生(`account-profile-patch.ts` 与账户路由),客户端不得自己写 `active_*` 或 `birth_time_status`。 +3. M2 必须一并清掉跨午夜采用写入的 `active_birth_date`、`active_birth_timezone_offset`、`active_birth_provenance`(若当前行有值),不能留下「新日期 + 旧的已采用日期」的半截状态。先查清这三列由谁写入、谁读取,写进 PROGRESS。 +4. 查清 `profiles` 上当前生效的触发器(`guard_birth_time_journey` 等最新版本)会不会把重置改回 `confirmed`,结论写进 PROGRESS。本机没有 Docker 跑不了 `npm run test:db`,这一项写成环境缺口,并在真机清单里列一条 staging 实测。 +5. 改既有断言写「原值 / 新值 / 原因」三栏。**前端改动也要跑 Python quick 门禁**(上一单因为没跑,Python 合同测试在门禁 run 1584 上红了)。 +6. 不加依赖,不改表、不加迁移(若确认必须改触发器才能生效,先停下告知 Claude,不要自行加迁移)。 + +## 任务分解 + +### M1 · 手机上星盘完整显示(BUG-1083) + +- **先复现**:在无头 Chrome 里用真实组件和虚构数据(golden 夹具)搭星盘页,视口 390×844。本命、D9、Bhava、行运、D10 各截一张,量出每一层容器的实际宽度,找出第一个宽度超过视口的祖先,并写进 BUG-1083 的根因。 +- **修**:在找到的那一层收住宽度(例如补 `min-width: 0`,或窄屏下给网格 `grid-template-columns: minmax(0, 1fr)`)。同类布局 `.chart-page-dasha-columns`、`.chart-page-western-layout`、`.chart-page-basics-grid` 一并检查,同样有问题就一起修。 +- **验收**: + - 修复前后各截 390×844 的五张图,外加 1280×900 一张,确认桌面不变;截图放 scratchpad,路径写 PROGRESS。 + - 390 宽时页面没有横向滚动,盘面宽度 ≤ 视口,表格在自己的框里能横向滑动。 + - 加一条回归测试,锁住修复的那条 CSS 规则(按源码文本断言即可,写明对应 BUG-1083)。 + - 如果能在无头 Chrome 里断言 `document.documentElement.scrollWidth <= innerWidth`,就加上。 + +### M2 · 已确认时间,改声明字段后重置 + +- 改 `resolveAccountBirthTimeApplicationPatch`:去掉「confirmed 直接返回 {}」。改为:声明字段有变化时,confirmed 也走与 reported 相同的派生;没有变化时维持原样(包括 legacy 分钟)。 +- 按硬红线 3,把跨午夜三列也纳入重置。 +- 账户路由里依赖「confirmed 不变」的并发守卫(`applyAccountProfileConcurrencyGuards`)要核对仍然正确。 +- 客户端:`/people` 保存本人后,已有的缓存失效逻辑要能让星盘页拿到新的排盘时间。用单测证明保存后读取到的是新分钟。 +- **验收(测试)**: + - confirmed + 改出生时间(精确) → `accepted` + 新分钟,`rectification_case_id` 为 null; + - confirmed + 改成时段 → `reported`,`active_birth_time` 为 null; + - confirmed + 只改称呼 / 岁差 / 性别 → 不变; + - confirmed + 跨午夜三列有值 + 改日期 → 三列清空; + - legacy(状态空、有分钟)+ 改时间 → 重置;不改则不变。 + - `account-api.test.ts` 那条旧测试改名并改断言,三栏说明。 +- BUG-264 下追加「2026-09-29 产品修订」一段:写明原约定、新决定、影响(改资料会让已采用的校正结果失效)。 + +### M4 · 「那一刻的天空」:重放动画 → 定格 → 右上角分享 + +- 星盘页点「那一刻的天空」后,打开全屏层: + - 复用首页过场的同一套时间轴与绘制(`lib/birth-sky/converge.ts` `birthSkyRevealAt` + `drawBirthSky`,组件 `components/birth-sky/birth-sky-converge.tsx`),加一个「定格」模式:汇聚 → 文字淡入 → **停在最后一帧**,不淡出,不自动关闭。每次打开都从头重放。 + - 定格帧就是导出海报(沿用「最后一帧与导出封面逐调用一致」的测试)。 + - 播放中点一下,直接跳到定格帧,不关闭。 + - 系统开了「减少动态效果」:不汇聚,直接淡入到定格帧。 +- 按钮(定格前后都在,深色底上可读,44px 触控): + - 左上角 ×:关闭(Esc 也关闭)。 + - 右上角「分享」:导出海报 PNG,走现有 `saveBirthSkyImage`(能调系统分享就分享,不能就下载);失败提示沿用现有文案。 + - 不再有图下方的「保存图片」按钮。 +- 不等待:点按钮时若海报 PNG 还没画好,仍然先开始放动画;PNG 在后台画,「分享」按钮在 PNG 就绪前禁用,不加 spinner。星盘页已有的预取(`use-birth-sky-cover`)照用,入口按钮仍然只在数据就绪后出现。 +- 删掉 polish 单的静态图弹层(`birth-sky-dialog.tsx` 里只给它用的结构与样式),确认没有别处引用。首页过场的淡出行为不变。 +- **验收**: + - 测试:定格模式时间轴在终点停住,不淡出、不调用 onDone;点击跳到终点不关闭;reduced-motion 直接到终点;× 与 Esc 关闭;「分享」调用 `saveBirthSkyImage`,PNG 未就绪时禁用;首页过场仍会淡出并关闭(原测试保留)。 + - 无头 Chrome:390×844 与 1280×900 各截「播放中」与「定格」两张,放 scratchpad,路径写 PROGRESS。 + - DESIGN §17 与 VOICE(「分享」按钮文案)同步。 + +### M3 · 文档 + +- `frontend/DESIGN.md`:星盘页窄屏布局一句。 +- `CHANGELOG.md`:两条。 +- `docs/BUG_HISTORY.md`:BUG-1083;BUG-264 的修订段。 +- `docs/testing/mobile-chart-confirmed-edit-20260929.md`(新建真机清单): + - iPhone 上星盘页的本命、D9、Bhava、行运、D10 都能看到完整的盘,表格能左右滑; + - 用采用过校正结果的账号,在星盘档案里把出生时间改掉:星盘页按新时间排,报告封面对旧报告不再显示; + - 只改称呼:排盘时间不变; + - 星盘页点「那一刻的天空」:每次都重放汇聚,定格;右上角「分享」在手机上弹出系统分享、在电脑上下载;× 关闭。 + +## 验证 + +- `tsc --noEmit` 0 错;`npm run lint` 0 error。 +- `npm test` 全量:与基线比测试名清单,不得有测试名消失;失败清单与基线(24 条 Docker / DB / 部署)逐条同名。 +- **`python3 scripts/run_quality_gate.py --profile quick --skip-yoga-logic --skip-frontend-runtime`(与门禁同参数)必须通过**;`python3 scripts/commercial_privacy_artifact_scan.py --json` 为 pass。 +- `rm -rf .next && next build`:`/` 仍 `○ Static`;首屏 gzip 与基线同口径对比,变化在 ±2% 内。 + +## 让步顺序 + +1. 同类布局(大运 / 西洋盘 / 基础信息)没有复现问题的,可以不改。 +2. M1 的无头 Chrome `scrollWidth` 断言可以只留截图证据。 +3. M4 在 1280 宽下的截图可以只留定格一张。 +4. M1 手机上完整显示、M2 确认状态下改资料会重置、硬红线 3 的跨午夜三列、M4 定格帧 = 海报,**不可让步**。 + +## 交付 + +- M1、M2、M4+M3 分提交,**不推送**;由 Claude 独立验收后快进推 staging。