From 5dc977ef2cb7b75f9862c43bf305505daa66b3e6 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Mon, 28 Sep 2026 14:13:30 +0800 Subject: [PATCH] docs(tasks): chart types, per-chart tables, qizheng hidden, ayanamsa, report buttons Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8 --- docs/tasks/README.md | 1 + ...chart-types-and-report-buttons-20260928.md | 147 ++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 docs/tasks/TASK-chart-types-and-report-buttons-20260928.md diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 0ad02120..6d6f91de 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -246,6 +246,7 @@ | `TASK-cost-accounting-gaps-20260927.md` | — | **成本记账补漏与缓存分价**:七处模型调用不入账(标题 / 摘要 / 校正意图 / 采用旁白 / 校正开场 / 生时引导 / 每日星语);缓存命中按全价算、单价表无缓存列;多事件账本 `metadata.cache` 被覆盖;失败运行无成本记录;测算页不显示 token 分位数;**后台模型表单没有单价输入框,单价只能是 0**。只加「记」不加「扣」,不动售价与会员参数 | 待领取 | BUG-1064~1069 预留;部署后由产品按 `docs/testing/cost-accounting-20260927.md` 采真实成本 | | `TASK-consult-answer-the-question-20260927.md` | `PROGRESS-consult-answer-the-question-20260927.md` | **普通对话回答问的那句话**:反差只写盘上、删「按我的理解答」、禁写动机句;追问轮 ≤ 200 字直接回答不重开四标题骨架(服务端按「本会话已有解读」切指令,不用正则);清单是核对项不是段落大纲;步骤栏「先抓住你真正在问的事」改「先回答你问的这件事」 | 已实现待验收(Claude 子代理直接执行) | 分支 `codex/consult-answer-the-question-20260927`(未推送);基线 `2ce3c216`;BUG-1070~1073;Skill 不 bump;真机清单 `docs/testing/consult-answer-the-question-20260927.md` | | `TASK-consult-first-frame-and-pacing-20260928.md` | `PROGRESS-consult-first-frame-and-pacing-20260928.md` | **普通对话发出即有反馈、正文按打字节奏放出**:客户端分类前静默(BUG-976 副作用)+ 服务端分类后才开流 → 发出后一两秒空白;服务端 160 字截留 + 客户端 settle 一帧全放 → 追问轮正文一下全出。D1 首帧「收到,正在看你的问题…」、D2 先建流、D3 每帧上限 + 限时收尾、D4 160 字阈值不动 | 已验收并部署 staging(真机欠) | 分支 `codex/consult-first-frame-and-pacing-20260928`(未推送);进度 `PROGRESS-consult-first-frame-and-pacing-20260928.md`;BUG-1074 / BUG-1075 | +| `TASK-chart-types-and-report-buttons-20260928.md` | `PROGRESS-chart-types-and-report-buttons-20260928.md` | **星盘盘型扩充 + 表格随盘换 + 七政隐藏 + 岁差 6 项 + 我的报告按钮配色**:分盘表一直显示 D1 数据(BUG-1076);盘型条 + 「星盘类型」面板共 23 种(加 月亮盘 / Bhava / 行运 / D40 / D45 / D60);Bhava 端点缺 MC 静默等宫(BUG-1077);报告深色主按钮黑字深红、禁用半透明(BUG-1078,只改报告范围) | 待领取 | — | | `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` 假通过)| | — (产品口头拍板,无任务书) | `PROGRESS-chart-glyphs-20260918.md` | **星盘改用行星符号,度数进行星表(非 Bug,无 BUG 号)**:北印星盘(星盘页 / 校正右栏 / 我的报告三处共用 `VedicChartSvg`)宫内不再画「水 19°」「罗逆 29°」这类文本——一宫三颗星就叠三行、字号压到 8。改成九个彩色符号(☉☽☿♀♂♃♄☊☋),每行最多 3 个、逆行改符号下同色横线、第 1 宫加 `As`、盘下两行图例。颜色只认星不表吉凶,罗计共用中性灰,`--color-planet-*` 九个 token 在 `:root` 与两个深色块各一份;颜色挂 `is-*` 修饰类而非行内 `style`(报告标记合同禁 `style=`)。符号字体是 vendored 的 9 字形 Noto Sans Symbols 子集(OFL,1.5 KB),`--font-planet-glyphs`,♀♂ 带 U+FE0E 防 iOS 画成表情。星盘页行星表四列扩到八列(行星 / 黄道经度 / 速度 / 宫位 / 星宿 / 宿主 / pada / 状态),度数精确到分,首行是上升(`vedic.ascendant` 新字段)。数据来源:`toNorthIndianChart()` 加结构化 `occupantGlyphs`;校正与报告两条路线的模型只有引擎/golden 显示文本,按首字解析并有测试锁住。**星宿未译中文**——仓库无对照表,印度 27 宿与中国二十八宿不同源,不自造 | 已实现,待验收 | `codex/chart-glyphs-20260918`:tsc 0 / lint 0 error(118 warning 不变)/ npm test 3471→3484 条、36 红与基线 `84b293fb` 逐条相同、0 新红 / `○ /` Static / 首屏 JS gzip 1,450,774→1,455,017(+0.29%),CSS gzip +2.23%(构成见 PROGRESS §2)。真机走查欠(iOS 符号呈现、深浅两主题配色、375px 横滚、打印) | diff --git a/docs/tasks/TASK-chart-types-and-report-buttons-20260928.md b/docs/tasks/TASK-chart-types-and-report-buttons-20260928.md new file mode 100644 index 00000000..2b57c5c7 --- /dev/null +++ b/docs/tasks/TASK-chart-types-and-report-buttons-20260928.md @@ -0,0 +1,147 @@ +# TASK · 星盘页盘型扩充与表格按盘换数据、七政隐藏、岁差扩充、我的报告按钮配色(2026-09-28) + +## 基线 + +- `origin/staging` = `2366da1c`(2026-09-28)。开工时 `git fetch origin --prune`,以最新 `origin/staging` 为基线,实际 SHA 写进 PROGRESS。 +- 分支 `codex/chart-types-20260928`,工作树 `.worktrees/chart-types-20260928`。 +- 进度记录 `docs/tasks/PROGRESS-chart-types-and-report-buttons-20260928.md`。 +- 同日其它任务书(`TASK-consult-first-frame-and-pacing-20260928`)改的是对话链路,与本单无文件交集。`frontend/src/app/globals.css` 为共享文件:本单只追加 / 修改 `chart-page-*` 与 `personal-report-*` / `report-export-*` 选择器,不动 `:root` 与主题 token 段。 + +## 事故实证(产品 2026-09-28 转述的真机反馈 + Claude 读码 / 实跑) + +产品转述四条:① 七政四余先隐藏,不作为当前主要对外内容,以后可作对话里的补充;② 导出按钮「黑字配深红底」看着不舒服;③ 岁差可选范围扩大;④ 星盘参考竞品图(盘型横条 + 「≡」弹出「星盘类型」三列网格:Rasi / D9 / Mo / Bhava / Transit / D2…D40),再加 D45、D60,**下面的表要随盘不同显示不同数据**。 + +读码与实跑确认的事实(行号按符号定位,基线 `2366da1c`): + +1. **分盘表永远是 D1 数据(BUG-1076)**。`frontend/src/components/chart-page/chart-vedic-tab.tsx` `ChartVedicTab`:表的 `` 用 `varga.id`,但 `` 渲染的是 `view.vedic.ascendant` 与 `view.vedic.planets`——两者都来自 `chart-view-mapper.ts` `planetRows(chart, …)` / `ascendantRow(chart)`,只读 `/api/chart` 的本命数据。切到 D9 / D10 时标题变了、星座度数宫位全是本命的。用户看到的是「D10 · 事业」下面一张 D1 表。 +2. **D40 / D45 / D60 引擎已支持,页面没请求**。`scripts/divisional_charts_extended.py` `VargaType` 含 40 / 45 / 60(以及 81 / 108 / 144);`_calculate_single_varga` 实跑返回每颗星的 `sign` / `degree`(分盘内度数)/ `house`(从分盘上升数)与分盘上升的 `sign` / `degree`。前端 `chart-view-labels.ts` `VARGA_CHIP_ORDER` 止于 30,`chart-view-load.ts` 按它请求 `/api/varga_full`,所以 D40 起全缺。 +3. **七政四余对用户只露在星盘页一处**:`chart-view-contract.ts` `CHART_VIEW_TABS` 的 `{ id: "qizheng" }`、`chart-page-view.tsx` 的 Tab 分支、`chart-qizheng-tab.tsx` / `qizheng-palace-grid.tsx`、`chart-view-load.ts` 的 `/api/qizheng` 懒加载层、`use-chart-page.ts` / `secondary-page-data.ts` 的缓存合并。其它页面、咨询回答、侧栏均无七政入口。 +4. **岁差**:`frontend/src/lib/ayanamsa.ts` `AYANAMSA_VALUES` 只有 `raman / lahiri / kp / true_pushya`;`scripts/ayanamsa_utils.py` `AYANAMSA_MODES` 支持 `lahiri / raman / kp(krishnamurti) / fagan_bradley / djwhal_khul / sassanian / true_citra / true_pushya`。**风险**:`resolveAyanamsa()` 遇到不认识的值静默回 `raman`,所以只加设置项不改枚举会让新选项在咨询 / 报告 / 星盘里悄悄变回 Raman。全仓 12 处经 `resolveAyanamsa` 或 `AYANAMSA_VALUES` 取值(`account-profile-patch.ts` 的 zod 枚举、`chart-view-load.ts`、`consultation-route-service.ts`、`server-owned-birth-profile.ts`、`birth-rectification-payload.ts` 等),另 `ephemeris-view.ts` 与 `personal-report-generation.ts` 各有一张显示名表。 +5. **我的报告按钮配色(BUG-1078)**:`components/ui/button.tsx` 的 `default` 变体是 `bg-primary text-primary-foreground`,深色主题下 = `#d78064` 底 + `--color-on-dark` `#241f1c` 近黑字;禁用态 `disabled:opacity-50` 把整颗按钮压到深底上,底色变暗红、黑字也半透明。「分块导出」抽屉的「导出选中 (n)」在未勾选时就是这个状态。导出套餐 `aria-pressed` 态是 `--color-action-soft` `#3a2620` 深红褐底。 +6. **Bhava Chalit 端点的 Sripati 宫头默认 MC 是假的(BUG-1077,待执行方确认后定性)**:`scripts/jyotish_api_server.py` `_compute_bhava_chalit`:`mc_lon` 缺省为 `(asc_lon + 270) % 360`,且只有 `placidus / koch` 才算出生 JD。实跑 `compare_rashi_vs_bhava(…, asc=101.37, mc=asc+270, 'sripati')` 得到 12 宫每宫 `span_degrees: 30.0`——Sripati 退化成等宫,Bhava 盘与 Rasi 盘宫位一样,"换宫"恒为 0。`/api/chart` 的印度侧响应不含 MC(`frontend/tests/fixtures/ephemeris-chart-natal.golden.json` 只有 `ascendant / planets / modules / calculation_contract`;MC 只在西洋层)。 +7. **行运已有现成算法**:`frontend/src/app/api/ephemeris/route.ts` `transitChartBody(birth, date)` 用 `/api/chart` 按日期算当天位置,`ephemeris-view.ts` `transitsFromEngine` / `natalHouseFromSigns` 把它投到本命宫位。 + +## 根因 + +- BUG-1076:09-15 星盘页首版把「行星宿度表」设计成 D1 专属表,后来加了分盘 chip 与 caption 却没给分盘出行数据;契约 `chartViewVargaSchema` 里只有画盘用的 `chart`,没有表格行。测试只断言 caption 随 chip 变,没有断言行内容。 +- 七政、D40+、岁差:功能边界问题,不是缺陷。 +- BUG-1078:深色主题主按钮沿用「亮珊瑚底 + 深字」保证对比度,但禁用态用整体透明度而不是换色,深底上呈暗红 + 半透明黑字;报告页是深色下唯一把禁用主按钮长期摆在眼前的位置(抽屉打开时默认未勾选)。 +- BUG-1077:端点把 MC 当可选参数并给了一个几何上不成立的默认值,调用方不传就静默得到等宫。 + +## 决策记录(产品 2026-09-28 拍板) + +- **D1 七政四余隐藏**:星盘页删掉七政 Tab 及其前端组件、懒加载层与契约字段;**保留**后端 `/api/qizheng`、`scripts/qizheng_chart_engine.py`、vendored stem-branch 与其 Python 测试,以后作对话补充时直接用。产品偏好「多余入口宁可删除」——前端文件删除而不是 `hidden`。 +- **D2 盘型**:印度「星盘」Tab 内的 chip 行改为竞品图样式:一条横向滑动的盘型条 + 行尾「≡」按钮,「≡」打开底部「星盘类型」面板(三列网格)。盘型共 23 个,顺序固定:**本命、D9、月亮盘、Bhava、行运、D2、D3、D4、D5、D6、D7、D8、D10、D11、D12、D16、D20、D24、D27、D30、D40、D45、D60**。月亮盘、Bhava、行运**本期都做**(产品明确「都做」)。 +- **D3 表格随盘换**:每种盘型一套列(见 T3–T5),数据全部由服务端投影给出,浏览器不计算(沿用 `ChartParamTable` 注释里的既有原则)。 +- **D4 岁差只做我们引擎已有的**,不引入引擎没有的(不加 Yukteshwar 等)。设置里放 6 个:**Raman(默认,不变)、Lahiri、KP、True Chitra、True Pushya、Fagan-Bradley**;Djwhal Khul、Sassanian 不放(产品原话「不必一次性把后台所有选项都暴露出来」)。生时校正仍固定 Raman,`AYANAMSA_SWITCH_HINT` 原句保留。 +- **D5 按钮配色只改「我的报告」**(`/reports` 列表、`/reports/[id]` 阅读页、分块导出抽屉、报告页 error / not-found),**不改全站 token、不改 `button.tsx`、不影响其它页面**。深色下实心主按钮改「深陶土底 + 白字」,禁用态改中性灰(不再半透明红),导出套餐选中态不再用深红褐底。 +- **D6** 分盘表**删掉星宿、宿主、足三列**:这三项是本命经度的属性,放进分盘表会是错数据。 + +## 硬红线 + +1. 不在浏览器计算任何星盘数据;月亮盘换算、分盘庙旺、行运落宫都在服务端(Python 引擎或 `chart-view-mapper.ts` 等服务端投影)完成。 +2. `scripts/jyotish_api_server.py` 不得增长(`tests/test_api_server_growth_contract.py`)。新逻辑进独立模块;如需改 `_compute_bhava_chalit`,只能改动既有行,不得净增。 +3. Bhava 盘**不得使用 `asc + 270` 这类默认 MC**。拿不到真实恒星黄道 MC → Bhava 层返回 `unavailable`、界面照既有失败句处理,并写进 `BLOCKED.md`;不得静默画出等宫。 +4. 行运盘用**与本命相同的岁差与交点模式**;界面写明计算时刻(日期 + 时区)。 +5. 懒加载不变:进页只请求 `/api/chart`;分盘、Bhava、行运在点到时才请求;月亮盘由已到的 D1 投影,不另发请求。已点过的层在同一会话复用模块缓存(沿用 `secondary-page-data.ts`)。 +6. 七政:只删前端;后端端点、引擎、vendor 与 Python 测试一行不删。 +7. 岁差:新增值必须同时进 `AYANAMSA_VALUES`、`account-profile-patch.ts` 枚举、`ephemeris-view.ts` 与 `personal-report-generation.ts` 显示名;`resolveAyanamsa` 的静默回退行为不改,但每个新值要有测试证明不会回退。默认值仍是 Raman。 +8. 按钮:`:root` / 主题 token、`components/ui/button.tsx`、非报告页面的任何样式不得改变。用 `git diff origin/staging -- frontend/src/components/ui/button.tsx` 为空 + 一条源码合同测试证明。 +9. `frontend/src/app/page.tsx` 不碰;`/` 保持 `○ Static`;首屏 gzip ±2%。 +10. 改既有断言写「原值 / 新值 / 原因」;测试总数不低于基线;fixture 来自真实引擎响应(golden)。 +11. 不升级依赖,不顺手修任务外 warning。 + +## 任务分解 + +### T1 七政四余隐藏 + +- 删 `CHART_VIEW_TABS` 的七政项、`chart-page-view.tsx` 七政分支、`chart-qizheng-tab.tsx`、`qizheng-palace-grid.tsx`、`chart-view-load.ts` 的 `/api/qizheng` 调用、`CHART_VIEW_LAYERS` 的 `qizheng`、契约里 `qizheng` 字段与 `layerFailures.qizheng`、mapper 的七政投影、`use-chart-page.ts` / `secondary-page-data.ts` 的合并分支、`globals.css` 里只被七政用的选择器。 +- 旧会话模块缓存里残留的 `qizheng` 字段不得让新契约 parse 失败(缓存按 schema 版本换键或解析时忽略多余字段,二选一写进 PROGRESS)。 +- **验收**:星盘页 Tab 为「星盘 / 基础信息 / 大运 / 西洋盘」四个;全前端 `grep -rn "qizheng\|七政" frontend/src` 只剩与本单无关的历史注释(逐条列在 PROGRESS);`/api/qizheng` Python 测试仍绿。 + +### T2 盘型条 + 「星盘类型」面板 + D40 / D45 / D60 + +- `VARGA_CHIP_ORDER` 扩到 `…30, 40, 45, 60`;`/api/varga_full` 一次请求 D2–D60。 +- 盘型条:23 项按 D2 顺序横向滚动(`nowrap` + 自身横滚,沿用 DESIGN 里 Tab 行的滚动写法),当前项样式沿用现 chip 的「浅底」;行尾固定「≡」按钮(`aria-label="全部盘型"`)。条上文字:`本命 / D9 / 月亮 / Bhava / 行运 / D2 …`。 +- 面板:标题「星盘类型」+ 关闭;三列网格,每格大字标签 + 一行小字用途(D 号盘的用途取引擎 `meaning`;本命「本命盘」、月亮盘「以月亮为第 1 宫」、Bhava「不等宫」、行运「今天」)。当前项实心高亮。点任一格 = 选中并关闭面板,同时把盘型条滚到该项可见。手机为底部抽屉;≥860px 与分块导出抽屉同规格(限宽 760 居中)。用原生 `` 或既有抽屉组件,Esc / 点遮罩关闭,焦点回到「≡」。 +- D45 / D60(以及 D40)表头下方加一句精度提示,仅当 `profile.birthTimeStatus` 不是已校正时出现,文案对照 VOICE,意思是「这张盘每格不到一度,出生时间差两三分钟就可能换格;先做生时校正再看更稳」。 +- **验收**:375px 下盘型条一行、页面不横滚;23 项齐全、顺序同 D2;面板可键盘操作;选 D60 后画出 D60 盘;`use-chart-page.ts` 的「分盘齐全」判断随新顺序更新并有测试。 + +### T3 分盘表按盘换数据(BUG-1076) + +- 契约:`chartViewVargaSchema` 增加 `ascendant`(分盘上升星座 + 分盘内度数)与 `rows[]`,每行 `name / label / sign / signLabel / degreeInSign / house / natalSign / natalSignLabel / dignity / vargottama / retrograde`。`retrograde` 取本命(分盘不改变顺逆)。 +- 庙旺落:由 Python 侧给出,单一来源。优先在 `scripts/divisional_charts_extended.py` 的分盘结果里为每颗星加 `dignity`(入旺 / 落陷 / 自宫 / 无),判定表复用 `jyotish_engine` 的 `EXALTATION` / `SIGN_LORDS` 等既有常量与 `_get_dignity_level` 的规则(不取三合度数段,分盘里不用 Moolatrikona),注意避免循环导入;若只能在 TS 侧做,必须引用一张与 Python 同源、有合同测试对齐的表,并在 PROGRESS 说明为何不在 Python 做。 +- Vargottama:该星分盘星座 = 本命星座。 +- 表格列(D2–D60):**行星 · 分盘星座度数 · 宫位(从分盘上升数)· 本命星座 · 庙旺 · 同位**;首行为分盘上升。本命盘表维持现八列不变。 +- **验收**:用 golden(真实 `/api/varga_full` 响应,含 D9 / D10 / D60)断言 D9 表每行星座与宫位等于引擎输出、且不等于 D1 行;D1 表逐字节同基线;新增测试「切 chip 后表格行内容变化」——这条测试在基线上应失败(先写失败测试再修,PROGRESS 贴失败输出)。 + +### T4 月亮盘 + 行运盘 + +- **月亮盘**:服务端从 D1 投影——月亮所在星座为第 1 宫,其余按星座顺序;北印度盘画法同 D1;表格列同本命盘八列,宫位按月亮起数,另在表头写「以月亮所在星座为第 1 宫」。不发新请求。 +- **行运盘**:新懒加载层 `transit`。把 `transitChartBody` 与 `transitsFromEngine` / `natalHouseFromSigns` 从 ephemeris 路由挪到 `frontend/src/lib/` 共享模块,星历页改为引用它(行为不变,星历测试全绿)。盘:以本命上升为第 1 宫,放入今天的行星位置。表格列:**行星 · 今天星座度数 · 顺逆 · 落本命第几宫 · 本命同名星所在宫**。表头写计算时刻(日期 + 时区标签)。岁差 / 交点与本命一致。 +- **验收**:月亮盘 golden 断言(月亮所在宫 = 1);行运层有 golden(真实 `/api/chart` 按日期响应,可复用 `ephemeris-chart-transit-*.golden.json`);429 / 超时走既有 `layerFailures` 文案;星历页测试无改动断言或按红线 10 说明。 + +### T5 Bhava 盘(BUG-1077) + +- 先确认 BUG-1077:写一条 Python 测试证明 `_compute_bhava_chalit` 不传 `mc_lon` 时 Sripati 各宫 `span_degrees` 全为 30。确认后在 BUG 历史登记,再修。 +- 修法由执行方选,但要满足红线 3:推荐在新模块(或 `bhava_chalit.py`)里用出生 JD + 经纬 + 与本命相同的岁差,从 swisseph 取恒星黄道 MC,再调用 Sripati;端点侧若需改动,只改既有行、不净增。不得改变其它调用方(报告链 `d1_sheet.bhava_chalit`)的结果,除非它们也在用假 MC——若是,写进 BUG-1077 的关联影响,另立单,不在本单改。 +- 新懒加载层 `bhava`。盘:按 Bhava 宫放行星(北印度盘外框同 D1)。表格:**行星 · 星座度数 · 星座宫 · Bhava 宫 · 换宫(是 / 否)**;下方一张 12 行宫头表:**宫 · 宫头星座度数 · 起点(sandhi)**。表头写宫制「Sripati」。 +- **验收**:一张真实盘的 golden 里 12 宫跨度不全等于 30°;至少一个换宫样例被界面标出;拿不到 MC 的路径有测试,返回 `unavailable` 而不是等宫。 + +### T6 岁差扩到 6 项 + +- `AYANAMSA_VALUES` / `AYANAMSA_OPTIONS` 增 `true_citra`、`fagan_bradley`,顺序:Raman(默认)、Lahiri、KP、True Chitra、True Pushya、Fagan-Bradley。每项一句说明,对照 VOICE;True Chitra 写「以角宿一实际位置定零点,与 Lahiri 很接近」,Fagan-Bradley 写「西方恒星占星常用,比 Lahiri 多约 0.9°」(执行方用引擎实算 1950 年两者差值核对后再写数字)。 +- `resolveAyanamsa` 接受 `true_chitra` 别名 → `true_citra`(与 Python `_canonical_ayanamsa_key` 一致)。 +- 显示名表(`ephemeris-view.ts`、`personal-report-generation.ts`、星盘页参数表)补齐。 +- **验收**:`ayanamsa.test.ts` 为 6 个值逐一断言 `resolveAyanamsa` 原样返回;`account-profile-patch` 接受 6 个、拒绝 `djwhal_khul`;星盘路由用 True Chitra 资料请求时发给引擎的 `ayanamsa` 为 `true_citra`(测试);设置页与人物档案页选项一致。 + +### T7 我的报告按钮配色(BUG-1078) + +- 在报告范围内(列表页、阅读页、分块导出抽屉、error / not-found)用一个作用域类重写按钮外观;`` 仍在 DOM 子树内,祖先类选择器可用。 +- 深色:实心主按钮(「导出选中」「继续等待」「去登录」等 `variant="default"`)= 深陶土底(用现有 `--color-action-on-dark` `#8f4a33` 或同色系,白字对比度 ≥ 4.5:1)+ 白字;禁用态 = 中性灰底 + 三级文字色,**不用整体透明度**;导出套餐选中态改为描边 + 主文字色(或中性浅底),不用深红褐底。 +- 浅色:实心主按钮保持现状(白字 / `#a9583e`);禁用态同样改中性灰。 +- **验收**:源码合同测试断言 `button.tsx` 与 `:root` token 段未变;报告页深浅两种主题下截图(本机 Chrome 或 `next build` + 无头浏览器,做不了写进环境缺口)存到 PROGRESS;对比度用数值写出。 + +### T8 文档 + +- `frontend/DESIGN.md`:星盘页一节改「四个 Tab」、盘型条与面板、各盘型表格列、精度提示;删七政段落(保留一句「七政四余 2026-09-28 起不在星盘页展示,后端保留」);报告页按钮一节。 +- `CONTEXT.md`:新增术语「月亮盘」「Bhava 盘」「行运盘」「盘型」。 +- `CHANGELOG.md`:一条,Skill 版本不 bump。 +- `docs/BUG_HISTORY.md`:BUG-1076 / 1077 / 1078。 +- `docs/testing/chart-types-and-report-buttons-20260928.md`:真机清单(iPhone 深色 / 浅色;盘型条横滑;面板选 D60;D9 表与 D1 表不同;行运时刻;Bhava 换宫;设置里 6 个岁差、切 True Chitra 后星盘参数表显示;报告抽屉未勾选时按钮是灰色)。 + +## 让步顺序(时间不够时从上往下让) + +1. T5 Bhava:若恒星黄道 MC 无法可靠取得,交付为 `unavailable` + `BLOCKED.md`,盘型条上保留入口并显示失败句(不得画等宫)。 +2. T4 行运盘的「本命同名星所在宫」一列。 +3. T2 面板里 ≥860px 的居中规格(先用手机抽屉样式)。 + +T1、T3、T6、T7 不让。 + +## 开工前置命令 + +```bash +cd /workspace/Jyotisha && git status -sb | head -1 +git fetch origin --prune +git worktree add -b codex/chart-types-20260928 .worktrees/chart-types-20260928 origin/staging +cd .worktrees/chart-types-20260928 +grep -oE "BUG-[0-9]+" docs/BUG_HISTORY.md | sort -t- -k2 -n | tail -1 # 应为 BUG-1075;若已被占用,顺延并在 PROGRESS 写明 +grep -n "BUG-716\|BUG-966\|BUG-1016\|BUG-1017\|分盘\|varga" docs/BUG_HISTORY.md | head -40 # 星盘页既有约束,逐条确认仍在 +cd frontend && npm ci && ./node_modules/.bin/tsc --noEmit && npm run lint && npm test 2>&1 | tail -5 # 记基线测试总数与失败名单 +cd .. && .venv/bin/python -m pytest tests -q -k "varga or bhava or qizheng or ayanamsa" 2>&1 | tail -5 +``` + +仓库标准 Node 22(`deploy/railway-web.Dockerfile`);本机若为 Node 20,`mock.module` 类用例假红,失败名单与基线逐条比对。 + +## BUG 编号 + +起点 **BUG-1076**(开工时核对 `docs/BUG_HISTORY.md` 最大号为 1075): + +- BUG-1076 星盘页分盘表格显示本命数据(P1,数据错) +- BUG-1077 `/api/bhava_chalit` 未传 MC 时 Sripati 静默退化为等宫(先 investigating,测试确认后定级) +- BUG-1078 我的报告深色主题主按钮黑字深红底、禁用态半透明(P3,视觉) + +## 交付 + +- 代码 + 文档同批一次推 `git push origin HEAD:staging`(快进),推后核对远端 SHA;门禁绿后核对 `https://staging.jyotisha.chat/api/health` 的 `deployment.gitCommit`。 +- 不提升 `main`、不改 workflow。