fix(people,ephemeris): style /people and make the ephemeris readable (BUG-1039)

- /people had zero CSS rules for its people-archive classes. Add the
  approved layout: list -> detail below 1024px (data-view, ?person= history
  entry so Back returns to the list), two columns at 1024px and above;
  avatar rows with the current person highlighted, time cards with a
  rectified state, readable ayanamsa name, three quick actions; delete moves
  to the bottom of the edit view with unchanged confirm/count logic.
- Ephemeris: Chinese-first panchanga names from the brief's table only
  (panchanga-names-zh.ts, three listed aliases, unknown names stay
  Sanskrit), coloured 吉/中/凶 tags, N吉/M凶 counts and a fixed-rule day
  summary (pure function, no model call); the header ask button becomes a
  bottom hint card; transit rows show glyph, 「行星 在 星座」, house line and
  degree; the Lahiri note names the subject's own ayanamsa.
- API, engine and database unchanged; /people and /ephemeris stay Static.
- DESIGN, VOICE, BUG_HISTORY, CHANGELOG, BLOCKED, PROGRESS and a manual
  checklist updated. Two existing assertions changed, with 原值/新值/原因.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
Jesse_Chen
2026-09-26 06:58:41 +08:00
co-authored by Claude Opus 5.5
parent 13c70a162a
commit 2981da6fbc
18 changed files with 1942 additions and 191 deletions
+14
View File
@@ -13884,3 +13884,17 @@
- 防复发:BUG 记录写明这是死代码删除,不是年运算法变更。
- 相关记录:BUG-1028。
- 修复版本:`codex/round-0925-followup-20260925`,未部署。
## BUG-1039 | 星盘档案页 `/people` 没有任何样式
- 状态:investigating(已修复待部署;未在登录态真机复测)
- 首次发现 / 最近更新:2026-09-26 / 2026-09-26
- 影响面:`/people` 星盘档案页(列表、详情、添加/编辑、删除确认)。同轮顺带改星历页可读性(非 Bug,见任务书 D5–D10)。
- 用户现象:iPhone Safari 上名字、「本人」、另一人的名字和时间挤在一行,「添加一个人」悬在中间,详情字段是裸文字。
- 触发条件:打开 `/people`,任何账户、任何宽度。
- 根因:`frontend/src/components/people/people-page.tsx` 用了 `people-archive`、`people-archive-list`、`people-archive-detail`、`people-archive-row` 等类,`frontend/src/app/globals.css` 里没有一条对应规则。实现 BUG-1030 那一轮没写样式;验收只有源码断言和组件探针,没有登录态,这一页从未在真实浏览器里看过。
- 修复:按原型补齐 `/people` 样式与布局:小于 1024px 列表 → 详情(同路由切视图,顶部「‹ 返回」,并压一条 `?person=` 历史记录让浏览器返回回到列表);1024px 及以上左列表右详情。列表行是首字头像 + 名字(本人加「本人」标签)+ 等宽一行「出生日期 · 排盘时间 · 城市」+「›」,当前人物用强调色边与浅底;底部虚线「+ 添加一个人」与「还可以保存 N 个人」。详情是头部 + 两格时间卡(有校正结果时排盘卡走成功色并标「已校正」)+ 出生日期与中文岁差名 + 三个快捷入口;本人底部灰字「本人不能删除」,他人的删除挪进编辑视图底部,删除确认与计数逻辑不变。头像颜色按 id 取元素色 token。
- 验证:`tests/people-archive-view.test.tsx`(行结构、当前人物高亮、时间卡与已校正、本人无删除、删除只在编辑视图、组件里每个 `people-archive*` 类在 `globals.css` 都有规则、触控 44px、1023/1024 切换);本地 `next start` + 临时宿主页(虚构数据,未提交)在 Chrome 151 375 / 390 / 1280、亮 / 暗下截图,并用 CDP 验证列表 → 详情 → 浏览器返回 / 「‹ 返回」、无横向滚动、可见按钮均不低于 44px。
- 防复发:新增「组件用到的每个 `people-archive*` 类都必须在 `globals.css` 有规则」的合同测试,这类「写了类没写样式」的回归会在测试里失败。验收流程缺口:无登录态页面只做源码断言等于没看过页面;本轮起此类页面至少用本地宿主页在真实浏览器里截一次图,写进 PROGRESS。
- 相关记录:BUG-1030(本页由其引入)。
- 修复版本:`codex/people-ephemeris-ui-20260926`,未部署。
@@ -0,0 +1,73 @@
# PROGRESS · 星盘档案页补样式 + 星历页可读性(2026-09-26)
任务书:`docs/tasks/TASK-people-ephemeris-ui-20260926.md`。分支 `codex/people-ephemeris-ui-20260926`,worktree `.worktrees/people-ephemeris-ui-20260926`。执行方:Claude 子代理(产品授权直接执行)。未推送、未部署。
## 基线
- `origin/staging` = `65260ca7`(线上 `e84d6eb8` 之后只有文档提交)。
- 基线全量(同一台机器、Node v20.19.2):3883 条,61 失败(全是 Node 20 缺 `mock.module` 等环境缺口),27 跳过。
- BUG 编号:开工时 `docs/BUG_HISTORY.md` 最大 BUG-1037,BUG-1038 被并行单预留,本单 **BUG-1039**。
- 并行单 `TASK-new-chat-from-people-20260926` 的文件(`people-home-links.tsx`、`chat-session-url.ts`、`home-bootstrap-run.ts`、`app/(app)/page.tsx`)一律未动。`people-page.tsx` 里「和 TA 对话」仍是 `openPerson(selected.id, "/?newChat=1")` 一行,跳转目标由那一单改,合并时只会在这一行冲突。
## 改了什么
| 任务 | 文件 | 内容 |
| --- | --- | --- |
| T1 | `frontend/src/components/people/people-page.tsx` | 拆出无状态 `PeopleArchiveView`(同文件导出,便于组件测试);`data-view` 列表 / 详情切换;手机点人 `pushState(?person=<id>)`,`popstate` 与「‹ 返回」回列表,刷新详情地址直接打开;列表行、详情卡、时间卡、快捷入口;删除挪进编辑视图底部,确认 / 计数 / 失败句逻辑不变。 |
| T1 | `frontend/src/lib/people-archive-view.ts`(新) | 头像取色(按 id 取四个元素色)、首字、城市、行 meta、「已校正」判定、岁差中文名。 |
| T1 | `frontend/src/app/globals.css` | `people-archive*` 共 24 个类的规则;`@media (max-width: 1023px)` 只显示一栏,`@media (min-width: 1024px)` 两栏。 |
| T2 | `frontend/src/lib/panchanga-names-zh.ts`(新) | 任务书附表原样 + 三组别名;`panchangaNameZh` 查不到返回 null。 |
| T2/T3 | `frontend/src/lib/ephemeris-view.ts` | `panchangaDisplayRows`(中文主名 / 梵文副名,查不到记一次 `panchanga_name_zh_missing`)、`panchangaQualityCounts`、`panchangaComplete`、`panchangaDaySummary`(D7 纯函数)、`ephemerisAyanamsaNote`(D10)、`transitHouseLine`(D9);文案常量更新。 |
| T3/T4 | `frontend/src/components/ephemeris/ephemeris-page.tsx` | 顶栏不再有按钮;五要素总评 + 计数 + 彩色标签;行运行改版(符号、「在」、宫位副行、度°分′);底部提示卡。 |
| T3/T4 | `frontend/src/app/globals.css` | `.ephemeris-quality`(12% 同色底)、`.ephemeris-summary`、`.ephemeris-counts`、行运新行式、`.ephemeris-ask-card`;删掉行运表头和 `data-label` 堆叠;标签去字距、行距收紧;行星符号颜色复用 `.chart-page-planet-glyph` 的 `--color-planet-*` 规则。 |
| T5 | `docs/BUG_HISTORY.md`、`CHANGELOG.md`、`BLOCKED.md`、`frontend/DESIGN.md`(§15 新增「星盘档案页布局」、§16 重写)、`frontend/docs/VOICE.md`(总评句式、提示卡、档案页文案)、`docs/testing/people-ephemeris-ui-20260926.md` | 记录。 |
## 实现取舍(验收请看)
1. **中文名在视图层投影,不改接口。** 任务书 T2 写「`panchangaFromEngine` 输出中文主名与梵文副名」,同时红线 3 写「不改接口」。实际函数名是 `panchangaFactorsFromEngine`,它的输出就是 `/api/ephemeris` 的 `factors` 字段。为守红线,接口字段一字未改(`value` 仍是引擎名),中文主名 / 梵文副名由 `panchangaDisplayRows` 在客户端从 `panchanga-names-zh.ts` 查。「未知名记日志」因此在浏览器控制台,每个名字只记一次。
2. **星期不出副行。** 接口里星期本来就是中文(服务端 `VARA_ZH`),引擎原名是英文 Sunday,不是梵文;附表也没有星期。原型里的「土星日」不在附表里,没加。
3. **对照表与引擎拼写三处不一致,未擅自加别名(待裁决)。** 引擎 `scripts/muhurta.py` 输出 `Aindra`、`Variyana`、`Dhanishtha`,附表写的是 Indra、Variyan、Dhanishta。任务书只允许三组别名,所以这三个名字现在照写梵文(测试 `panchanga-names-zh.test.ts` 锁住了这一现状并注明待裁决)。真实 golden 2026-09-14 的瑜伽就是 `Aindra`。产品若同意,只需在 `PANCHANGA_NAME_ALIASES` 加三行别名、改那条测试。
4. **D10 的两个边界句。** 资料岁差是 Lahiri 时,「和星盘页的 Lahiri 不同」是错的,改写「五要素按 Lahiri 岁差算,和星盘页相同。」;读不到资料岁差时只写「五要素按 Lahiri 岁差算。」已写进 VOICE。岁差名取接口已有的 `transits.ayanamsa`(即资料设置),名字与设置里一致,不带「(默认)」。
5. **没有本命上升时的句子改了。** 原句「还没有本命上升,相对本命这一列空着。」里的「列」随表格一起没了,改为「还没有本命上升,先不写落在你的第几宫。」行运逆行保留为副行「· 逆行」(D9 没提,但删掉会丢事实)。
6. **「已校正」判定** = 状态 accepted / confirmed **且**有校正案例 id。只看状态会把旧资料读回时 `readProfile` 的 `confirmed` 兜底(有时间就算 confirmed)误标成已校正。
7. **当前人物 vs 正在看的详情。** 「当前正在看的人高亮」按顶栏当前人物(`useCurrentSubject`)上强调色;桌面右栏打开的那一行只用中性浅底 `is-open`,免得两行都是强调色。
8. **桌面五要素仍是五格一行**(DESIGN §16 原有),标签在上、名称与标签在下;767px 以下才是原型那种「左标签 · 中名称 · 右标签」行。原型里日期条下的「星期六 · 今天」副标题、迦那副行「· 通常避开」都不在决策里,没做。
9. 档案页「还可以保存 N 个人」「本人不能删除」按原型去掉了句末句号(VOICE 已写)。
## 验证
| 项 | 结果 |
| --- | --- |
| `./node_modules/.bin/tsc --noEmit` | 0 错 |
| `npm run lint` | 0 error / 127 warning(与既有一致,新文件无 warning) |
| 全量 `npm test`(Node 20.19.2) | 3915 条,3827 通过,61 失败,27 跳过。基线 3883 / 61 失败。失败测试名与基线逐条比对:新增 0、消失 0;测试名无消失,新增 32 条(`panchanga-names-zh` 7、`ephemeris-readable-panchanga` 13、`people-archive-view` 12) |
| 定向 | `ephemeris-page`、`ephemeris-readable-panchanga`、`panchanga-names-zh`、`people-archive-view`、`people-archive-regressions`、`chart-library-other-profile`、`adopted-birth-date`、`settings-mvp-contract`、`secondary-page-entry`、`viewport-breakpoint-contract`、`touch-target-contract`、`dark-theme-contract`、`design-token-contract` 全绿(`ephemeris-route` 的 6 条失败是基线同名 Node 20 缺口) |
| Python 源码合同 | `tests/test_birth_time_journey_contract.py`、`test_session_management_entrypoints.py`、`test_supabase_user_data_contract.py`、`test_daily_and_rectification_entrypoints.py`:25 passed(系统 python3 + pytest 9.1.1;本 worktree 无 `.venv`) |
| `npm run build -- --webpack` | 成功;`○ /`、`○ /people`、`○ /ephemeris`、`○ /chart` 仍 Static(`/reports` 为 ƒ,本单未碰) |
| 首屏 gzip(`build-manifest.json` rootMainFiles 4 个文件,zlib 默认级别) | 131253 字节,基线 130933,+0.24%(±2% 内;本单只改组件与 CSS,不进 rootMainFiles,差值应是口径 / 构建噪声) |
改动的既有断言(三栏也写在测试文件里):
| 位置 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `tests/ephemeris-page.test.tsx`「the Lahiri note sits under panchanga…」 | `EPHEMERIS_COPY.panchangaLahiriNote`(固定句「这一段按 Lahiri 岁差算,和星盘页用的岁差不是同一套。」) | `ephemerisAyanamsaNote("raman")`(「五要素按 Lahiri 岁差算,和星盘页的 Raman 不同。」) | D10 改句式并要求按资料实际岁差填名;位置断言不变 |
| `tests/ephemeris-page.test.tsx`「copy stays factual…」 | 整页 markup 不得含 `/运势\|适合\|不宜\|建议\|吉祥日/` | 去掉底部提示卡那一句问句后再断同一组词,另断问句只出现一次 | D8 定稿问句「想问这一天适不适合做某件事?」是邀请提问,不是宜忌结论;其余范围不放宽 |
## 浏览器截图(真实 Chrome 151,非登录态)
方式:本地 `next build --webpack` + `next start`,加一个**未提交**的临时宿主页 `/ui-harness-1039`:
- `?screen=people` 挂真实 `PeoplePage`,只把 `/api/account`、`/api/chart-profiles`、`/api/sessions` 三个读请求换成虚构数据(本人「示例甲」已校正、「示例乙」Lisbon/Lahiri、「示例丙」成都),列表 → 详情 → 返回走的是组件真实的 `pushState` / `popstate`。
- `?screen=ephemeris` 挂真实 `EphemerisView`:行运用真实引擎 golden(2026-09-15),五要素用虚构 Vishti/Purnima 组合以显示完整总评;另一张用真实 golden 五要素。
- CDP 驱动(`node --experimental-websocket`),设备像素比 2,`prefers-color-scheme` 亮 / 暗。每个宽度同时检查:页面与 `.secondary-page` 无横向滚动、可见按钮高度均 ≥ 44px、星历顶栏没有 `.ephemeris-ask`;手机宽度检查点人后 URL 带 `?person=`、`history.back()` 与「‹ 返回」都回到 `data-view="list"`。全部通过(`ui-1039/checks.json`)。
截图目录 `/tmp/claude-1000/-workspace-Jyotisha/725df462-ac7f-4544-90b7-60fba1501ed7/scratchpad/ui-1039/`(不在仓库里),宽度 × 主题各一组:
- 档案页:`people-{375,390,1280}-{light,dark}-list.png`(列表、当前人物高亮、虚线添加卡)、`people-{375,390}-{light,dark}-detail-self.png`(本人详情:已校正绿卡、Raman(默认)、三入口、「本人不能删除」)、`people-{375,390,1280}-{light,dark}-detail-other.png`(他人详情;1280 为两栏)、`people-{375,390,1280}-{light,dark}-edit-other.png`(编辑视图底部「删除这个人」)。
- 星历:`ephemeris-{375,390,1280}-{light,dark}-top.png`(总评、计数、彩色标签、中文主名梵文副名、岁差句、行运行)、`ephemeris-{375,390,1280}-{light,dark}-bottom.png`(九十天与底部提示卡)、`ephemeris-375-light-golden-top.png`(真实 golden 五要素:白分初五 / 亢宿 / 分离 / 巴瓦)。
## 环境缺口(未写成通过)
- Node 22 全量未跑(本机只有 Node 20.19.2),61 条基线失败为同一原因;需协调方在 Linux Node 22 复跑并比对名单。
- 无 Docker:本单不动表,未跑 `test:db`。
- 无受控登录账号:真实数据、iPhone Safari、左滑返回手势、读屏未验,见 `docs/testing/people-ephemeris-ui-20260926.md`。
- 未部署;BUG-1039 保持 `investigating`。
+1 -1
View File
@@ -209,7 +209,7 @@
| 任务书 | 进度 | 主题 | 状态 | 落点 |
| --- | --- | --- | --- | --- |
| `TASK-people-ephemeris-ui-20260926.md` | — | **星盘档案页补样式 + 星历可读性改版**(原型 https://claude.ai/artifact/FmPy9xZ7dQw9u7yrW4WzTw ,产品 09-26 确认):/people 样式 0 条(BUG-1039)→ 手机列表→详情、桌面两栏;星历五要素先中文后梵文(附唯一对照表)、吉凶彩色标签、固定规则当日总评(不调模型)、标题栏大按钮移到底部提示卡。必须真实浏览器截图验收。与 BUG-1038 单并行、文件不交叉 | 待领取 | — |
| `TASK-people-ephemeris-ui-20260926.md` | `PROGRESS-people-ephemeris-ui-20260926.md` | **星盘档案页补样式 + 星历可读性改版**(原型 https://claude.ai/artifact/FmPy9xZ7dQw9u7yrW4WzTw ,产品 09-26 确认):/people 样式 0 条(BUG-1039)→ 手机列表→详情、桌面两栏;星历五要素先中文后梵文(附唯一对照表)、吉凶彩色标签、固定规则当日总评(不调模型)、标题栏大按钮移到底部提示卡。必须真实浏览器截图验收。与 BUG-1038 单并行、文件不交叉 | 待验收(Claude 子代理 09-26 实现;全量失败名单与基线一致、Static 保持、Chrome 375/390/1280 亮暗截图;对照表三处引擎拼写待裁决) | 分支 `codex/people-ephemeris-ui-20260926`,未推送 |
| `TASK-round-0925-followup-20260925.md` | `PROGRESS-round-0925-followup-20260925.md` | **0925 收尾单**:西洋盘标签偏移 ≤30° + 第三圈;删除后只在当前人物里回退;人物接口故障降级为本人;P3 删旧面板、点击按最近行星、删除年运死调用 | 已验收(Claude 09-26:偏移 ≤30° 达成;删后回退按人、人物接口降级、账户单次请求、面板与死代码删除均通过;残留 0.73% 盘标签重叠为 P3) | `d08ffdc0` + 合同修复 `e84d6eb8`(d08ffdc0 的门禁 run 2901 红于一条引用已删面板文案的 Python 合同,Claude 经产品授权直接修复);已部署 run 2906,health 一致 |
| `TASK-chart-western-fix-20260925.md` | `PROGRESS-chart-western-fix-20260925.md` | **西洋盘 ASC/MC 重叠**:固定锚点避让、真实引擎64盘与固定种子512盘扫描、343px盘宽命中≥44px;raw golden;文档陈旧行更正 | 已验收(重叠 0%);新 P1 标签偏移最大 115° → 收尾单 D1(产品定 ≤30° + 第三圈) | `4d801e53`(已部署,health 核对一致) |
| `TASK-chart-dasha-western-redesign-20260924.md` | `PROGRESS-chart-dasha-western-redesign-20260924.md` | **大运 / 西洋盘改版**(原型 https://claude.ai/artifact/DYovEPMqD1xwNgna5xVTre ,产品 09-24 全部同意,相位线常显):大运「现在」卡 + 时间条 + 默认折叠(原 81/144 行平铺);西洋盘 520 三圈、行星避让 + 引线、宫号居宫中、ASC/MC 盘内、行星位置表、点选过滤相位。排在 chart-ephemeris-fixes T1 之后 | 已验收,1 P1(ASC/MC 标签不参与避让,约 34% 盘重叠)→ chart-western-fix | `5a2d9da9`(已部署) |
@@ -0,0 +1,34 @@
# 真机清单 · 星盘档案页样式 + 星历可读性(2026-09-26)
对应任务书 `docs/tasks/TASK-people-ephemeris-ui-20260926.md`,BUG-1039。部署到 staging 后,用自己的账号在 iPhone Safari 和电脑 Chrome 各走一遍。每条写「通过 / 不通过 + 截图」。
## 星盘档案 `/people`(手机)
1. 打开侧栏「星盘档案」:看到一张张人物卡片,不再挤成一行。每张卡有圆形头像、名字,本人后面有灰色「本人」小标签,下面一行是「出生日期 · 排盘时间 · 城市」,右边一个「›」。
2. 顶栏「当前星盘」是谁,谁的卡片就是橙色描边 + 浅橙底。切到别人后回到这页,高亮跟着换。
3. 最下面是虚线框「+ 添加一个人」,下面小字「还可以保存 N 个人」。N = 5 − 现有人数。存满 5 个人时框变灰、点不动,下面写「最多保存 5 个人的星盘」。
4. 点任意一个人:整页换成这个人的详情,顶部有「‹ 返回」。
5. 点「‹ 返回」回到列表;再点进一个人后,用 Safari 左滑返回(或浏览器返回键),也回到列表,而不是离开这一页。
6. 详情里:头像 + 名字 +「本人 · 出生地」(别人只写出生地);两格时间卡「填报时间」「排盘时间」。做过生时校正并采用的本人,排盘卡是绿色、写「排盘时间 · 已校正」;没校正过的人两张卡都是普通白卡。
7. 「岁差」写「Raman(默认)」这类名字,不出现小写的 raman。
8. 三个一样宽的按钮「和 TA 对话 / 看星盘 / 生成报告」都能点(「和 TA 对话」的去向以新建对话那一单为准)。
9. 本人详情最下面灰字「本人不能删除」,整页没有删除按钮。
10. 别人的详情有「和我合盘」和「编辑」。点「编辑」,表单最下面才有红色「删除这个人」;点它先显示「将同时删除 N 个对话和 M 份报告,无法恢复。」,取消后什么都不删。
11. 页面左右不能横着拖动;所有按钮手指好点,不会点到旁边的。
## 星盘档案 `/people`(电脑,窗口宽于 1024)
12. 左边列表、右边详情同时在;没有「‹ 返回」。点左边的人,右边换成他,被打开的那一行是灰底,当前人物仍是橙色。
13. 把窗口拉窄到手机宽度,变回「先列表、点进去看详情」。
## 星历 `/ephemeris`
14. 顶栏只剩「星历」和人名,**没有**右上角的「带这天去提问」大按钮。
15. 「今日五要素」卡片第一行是一句总评,例如「满月之日,整体偏吉;迦那落在毗湿提,重要的事避开。」下面两个小标签「N 吉」「M 凶」。换几天看看,句子跟着变,且只有这几种说法:满月之日 / 新月之日 / 月亮渐盈 / 月亮渐亏 + 整体吉 / 整体偏吉 / 吉凶参半 / 整体偏凶。
16. 五行里月相日、月宿、瑜伽、迦那先写中文(例如「白分初五」「亢宿 · 第 4 足」「分离」「巴瓦」),下面小字是梵文。遇到「Aindra」「Variyana」「Dhanishtha」这三个名字时目前只写梵文(对照表待产品裁决),记下日期。
17. 每行右边有彩色小标签:吉是绿色、凶是红色、中是黄色。
18. 卡片底下一行写「五要素按 Lahiri 岁差算,和星盘页的 Raman 不同。」——如果你的岁差设置改成了 KP,这里写 KP;改成 Lahiri 时写「和星盘页相同」。
19. 「当日行运」每行:彩色行星符号、「太阳 在 狮子座」、下面小字「落你的第 N 宫」(逆行的星再加「· 逆行」),右边是「29°33′」这样的度数。给一个还没填出生时间的人看,行运没有「落你的第几宫」,段首写「还没有本命上升,先不写落在你的第几宫。」
20. 滑到最底下:一张浅橙色提示卡,左边「想问这一天适不适合做某件事?」,右边按钮「带这天去提问」。点它回到对话,输入框里已经填好这一天的日期。
21. 切日期、切人物、弱网时,仍然没有转圈、骨架或「正在加载」。
22. 深色模式下以上颜色都看得清(设置 → 外观 → 深色)。