diff --git a/BLOCKED.md b/BLOCKED.md index dc0760ad..6c7eb569 100644 --- a/BLOCKED.md +++ b/BLOCKED.md @@ -1,5 +1,13 @@ # BLOCKED +## TASK-chart-types(T1–T5 星盘):真机、真实 Chrome 与 `.venv` 缺口(2026-09-28) + +- 无登录态与 Chrome:盘型条横滑、「星盘类型」面板(原生 `` 的 Esc / 遮罩 / 焦点回收)、375px 不横滚、月亮盘「As」位置只在服务端渲染 markup 与最小 DOM harness(`react-client-lifecycle-test-support.ts`,不模拟布局与原生 dialog)上验证。按 `docs/testing/chart-types-and-report-buttons-20260928.md` 星盘一节真机走。 +- 本机无 Docker:24 条 DB / 部署套件失败,与开工基线逐条同名(清单见 PROGRESS)。 +- 本工作树无 `.venv`(主检出的 `.venv` 软链指向不存在的路径):Python 测试用系统 `python3`(pyswisseph 2.10.03)。基线即红的 10 条(`test_varga_vedastro_mode` 9 条、`test_ayanamsa_mode_ownership` 1 条)同名不变。 +- Bhava / 行运真实引擎耗时与 429 频率未测;部署后看 `/api/bhava_chalit` 与带日期的 `/api/chart` 的 `chart_view_engine_failed` 日志。 +- 未推送、未部署。 + ## TASK-consult-first-frame-and-pacing:真实 PostgreSQL 寒暄结算测试、真机与真实耗时待验(2026-09-28) - 本机无 Docker:BUG-976 那组真实 PostgreSQL 寒暄结算测试(`database-local-business.test.ts` 等 24 条 DB / 部署套件)未跑,失败清单与开工基线逐条同名。本单没有改 `complete_consultation_free` / `cancel_consultation_credit` 的调用点与参数,寒暄流 `streamSmalltalkResponse` 也未改,只是被外层流逐字节中继;假模型层补了「流内完成、免费结算调用一次」的断言(`consult-first-frame-and-pacing-20260928.test.tsx` ②)。以门禁 DB job 为准。 diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a1b0ea..03168e6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # 印度占星 Skill 更新日志 +## 2026-09-28 — 星盘页:23 种盘型、每张盘有自己的表,七政四余先不展示(待验收) + +- 「星盘」Tab 里的分盘按钮换成一条可横滑的盘型条,行尾「≡」打开「星盘类型」面板(三列,共 23 种):本命、D9、月亮盘、Bhava、行运、D2–D30,以及新增的 D40、D45、D60。 +- 下面的表跟着盘换(BUG-1076):以前切到 D9 只换了表头、数字仍是本命。分盘表改为「行星 · 分盘星座 · 宫位 · 本命星座 · 庙旺 · 同位」,不再列星宿和 pada;本命表不变。 +- 月亮盘以月亮所在星座为第 1 宫;Bhava 盘按 Sripati 不等宫重新归宫并列出宫头;行运盘把今天中午的行星放进本命宫位,岁差与交点和本命相同。 +- 计算侧修了 Bhava 宫头:以前没传天顶就按等宫算,「换宫」永远为 0(BUG-1077);现在用出生时刻的恒星黄道天顶,拿不到就明确报错,星盘页那一栏只显示失败句。 +- D40 / D45 / D60 在出生时间没校正时提醒「出生时间差两三分钟就可能换一格」。 +- 七政四余 Tab 先不展示;计算接口保留,以后放进对话里用。 +- Skill 版本不 bump(Skill 文本未改)。不改数据库。 + ## 2026-09-28 — 普通对话发出即有反馈,回答按打字节奏写出(待验收) - 按下发送的那一帧,回答行就带着步骤栏,第一行是「收到,正在看你的问题…」;服务端也先开流、首字节就是这句,读会话、预留点数、判断是不是寒暄这些步骤都在流里做。以前这一两秒整行空白(BUG-1074)。发「你好」这类寒暄会先闪一下这一行,服务端判定是寒暄后收掉,只留一句回复。 diff --git a/CONTEXT.md b/CONTEXT.md index 2edd09a9..6f5174d8 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -63,3 +63,19 @@ _避免使用_:设为默认、active chart **领域别名**: 生时校正里,健康在证据账本和焦点层记为 `health`,计划层、引擎探针和盘外提示用 `health_pressure`;职业焦点落库为 `other`(题号仍是 `collect:occupation:`),计划层与账本用 `occupation`。比较时两侧都要先归并,不能按字面相等。数据库 `target_domain` 约束不改。 _避免使用_:把 `health` 和 `health_pressure` 当成两个领域、把职业拒答当成 `other` 领域 + +**盘型**: +星盘页「星盘」Tab 里可选的一张印度盘:本命(D1)、各分盘(D2–D60)、月亮盘、Bhava 盘、行运盘,共 23 种。每种盘型有自己的一张表。 +_避免使用_:分盘(泛指全部盘型时)、chip + +**月亮盘**: +本命盘改以月亮所在星座为第 1 宫重新数宫(Chandra Lagna)。星座、度数与本命相同,只有宫位变。 +_避免使用_:Moon chart 当作分盘、D1 的变体盘名 + +**Bhava 盘**: +按 Sripati 宫制把本命行星按不等宫的宫界(sandhi)重新归宫的盘;宫头由出生时刻的上升与恒星黄道天顶(MC)三等分象限得出。拿不到真实天顶时不出这张盘。 +_避免使用_:宫位盘、等宫盘 + +**行运盘**: +某一天(星盘页是今天)中午出生地时区的行星位置,放进本命盘的宫位(本命上升为第 1 宫),岁差与交点和本命相同。 +_避免使用_:流年盘、过运盘(泛指) diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index e2b10906..30b9e8bb 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -14467,3 +14467,33 @@ - 相关记录:BUG-473、BUG-1053、BUG-1074;`TASK-consult-first-frame-and-pacing-20260928`。 - 复发自:无 - 修复版本:staging `79c5e566`(2026-09-28 部署核对:`/api/health` `deployment.gitCommit` = 79c5e566,未登录 `/api/account` = 401;Claude 验收门禁见 PROGRESS;真机清单 7 条与 `first_byte` 耗时待产品)。 + +## BUG-1076 | 星盘页分盘表格显示的是本命数据:切到 D9 / D10 只换了表头 + +- 状态:待验收(回归测试已过;分支 `codex/chart-types-20260928` 本地提交,未推 staging、未部署) +- 首次发现 / 最近更新:2026-09-28 / 2026-09-28 +- 影响面:`frontend/src/components/chart-page/chart-vedic-tab.tsx`(表格)、`frontend/src/lib/chart-view-contract.ts`(`chartViewVargaSchema`)、`frontend/src/lib/chart-view-mapper.ts`(`buildVargas`)。线上 `/chart` 自 09-15 首版起即如此。 +- 现象:产品转述真机反馈「下面的表中的数据也要根据星盘不同显示不同的表中数据」。实测切到 D9 时表头写「D9 · 配偶/灵性」,每一行星座、度数、宫位、星宿仍是 D1。 +- 触发条件:星盘页选任意非 D1 分盘。 +- 根因:表格 `` 渲染的是 `view.vedic.ascendant` / `view.vedic.planets`(`planetRows(chart)` 只读 `/api/chart` 本命数据),只有 `` 用了 `varga.id`;契约里分盘只有画盘用的 `chart`,没有表格行。原测试只断言 caption 随 chip 变,没断言行内容。 +- 修复:契约给 D2 起的分盘加 `ascendant` 与 `rows`(分盘星座、分盘内度数、从分盘上升数的宫位、本命星座、庙旺、同位 / Vargottama、本命顺逆);分盘表改六列「行星 · 分盘星座 · 宫位 · 本命星座 · 庙旺 · 同位」,删掉星宿 / 宿主 / 足(那是本命经度的属性,放进分盘是错数据)。庙旺用 `frontend/src/lib/vedic-chart-tables.json`,表与 `jyotish_engine` 的 `EXALTATION / DEBILITATION / SIGN_LORDS` 和 `_get_dignity_level` 的判定顺序由 `tests/test_chart_page_vedic_tables_contract.py` 逐格钉住(不在 Python 响应里加字段,是为了不改被报告、咨询、golden 共用的 `varga_full` 形状)。D1 表不变。 +- 验证:`frontend/tests/chart-varga-table.test.tsx` 先写先红(基线 5dc977ef 上 D9 太阳行是「双子 1°32′」,断言要「天秤」),修后绿;D1 表与基线渲染逐字节相同(`fixtures/chart-d1-table-baseline.html` 由基线提交渲染);D9 土星「自宫 + 同位」、太阳「落陷」;每张非 D1 分盘 9 行。`chart-view-varga-dignity.test.ts` 钉判定顺序。 +- 防复发:分盘表的行必须来自该分盘自己的 `rows`;新增盘型的测试必须断言行内容,不能只断言标题。 +- 相关记录:BUG-704~706(星盘页首版)、BUG-1016(骨架);`TASK-chart-types-and-report-buttons-20260928` T3。 +- 复发自:无 +- 修复版本:本地 `ab6ee94e`(未推送)。 + +## BUG-1077 | `/api/bhava_chalit` 缺 MC 时 Sripati 静默退化成等宫 + +- 状态:待验收(回归测试已过;分支 `codex/chart-types-20260928` 本地提交,未推 staging、未部署) +- 首次发现 / 最近更新:2026-09-28 / 2026-09-28 +- 影响面:`scripts/jyotish_api_server.py` `_compute_bhava_chalit`(直接调用该端点的任何调用方)。报告链 `jyotish_engine._build_natal_foundation_modules` 自己用 `swe.houses_ex(..., FLG_SIDEREAL)` 取 MC,不受影响;CLI `bhava_chalit.cmd_bhava_chalit` 也自己算 MC,不受影响。 +- 现象:不传 `mc_lon` 时,12 宫 `span_degrees` 全是 30.0,Bhava 宫与星座宫完全相同,「换宫」恒为 0。**即使请求里带齐出生年月日时与经纬也一样**——端点只给 placidus / koch 算 JD。 +- 触发条件:`house_system` 为 sripati(默认)或 porphyry,且请求不带 `mc_lon`。 +- 根因:`mc_lon = self._normalize_degree(body, 'mc_lon', (asc_lon + 270) % 360)`:缺省 MC 取上升减 90°,四个象限各恰好 90°,三等分后就是等宫。 +- 修复:新模块 `scripts/bhava_chalit_mc.py` `resolve_bhava_mc_lon`:显式 `mc_lon` 优先;否则有出生时刻与地点就用 `swe.houses_ex(jd, lat, lon, b'R', FLG_SWIEPH | FLG_SIDEREAL)` 在请求岁差下取恒星黄道 MC(与报告链同一调用);再否则 sripati / porphyry 直接 400,不猜。不需要 MC 的宫制(equal / whole_sign / placidus / koch)行为不变。端点只改了既有一行的位置(净增 0 行,类方法数不变)。星盘页 Bhava 层另有一道防线:`mapBhava` 遇到宫制回退、缺 MC、或 MC 恰等于 `asc + 270` 一律返回 unavailable,不画等宫。 +- 验证:`tests/test_api_server_security.py` 三条新测试先写先红(基线上「缺 MC 与出生时刻应 400」未抛出、「带出生时刻时跨度不全为 30」得到 `[30.0, 30.0, …]`),修后绿;MC 与独立的 `houses_ex` 调用差 < 1e-3°,同一调用的上升与引擎本命上升差 < 0.01°;equal 宫制无出生时刻仍可用。真实响应存为 `frontend/tests/fixtures/chart-view-bhava-golden.json`(星盘页 golden 的虚构盘:太阳、水星、土星换宫)。`frontend/tests/chart-bhava.test.tsx` 断言占位 MC 与宫制回退都不出盘。 +- 防复发:任何取 Bhava 宫头的新调用方都经 `bhava_chalit_mc.resolve_bhava_mc_lon`,不得再给 MC 写几何默认值。 +- 相关记录:BUG-320(Bhava 进换升表);`TASK-chart-types-and-report-buttons-20260928` T5。 +- 复发自:无 +- 修复版本:本地 `c35e0195`(未推送)。 diff --git a/docs/tasks/PROGRESS-chart-types-and-report-buttons-20260928.md b/docs/tasks/PROGRESS-chart-types-and-report-buttons-20260928.md new file mode 100644 index 00000000..ec4852ae --- /dev/null +++ b/docs/tasks/PROGRESS-chart-types-and-report-buttons-20260928.md @@ -0,0 +1,114 @@ +# PROGRESS · 星盘盘型扩充与表格随盘换、七政隐藏(T1–T5)+ 相关文档(2026-09-28) + +任务书:`docs/tasks/TASK-chart-types-and-report-buttons-20260928.md`。本记录只覆盖 **T1–T5 与 T8 的星盘部分**(直接执行模式,Claude fork 子代理)。T6 岁差、T7 我的报告按钮配色由另一执行方在另一分支做,本分支没有碰 `ayanamsa.ts`、`account-profile-patch.ts`、报告与导出相关文件和样式;BUG-1078 归对方。 + +## T1–T5 chart + +### 基线与环境 + +- 基线:`origin/staging` = `5dc977ef`(任务书提交)。分支 `codex/chart-types-20260928`,工作树 `.worktrees/chart-types-20260928`。**本地提交,未推送。** +- Node:`/exec-daemon/node` v22.14.0(仓库标准 Node 22),经 scratchpad 里的 `node` 软链放到 PATH 前面;`npm ci` 装本工作树自己的 `node_modules`(不是软链,Turbopack 可正常 build)。 +- Python:本工作树没有 `.venv`(主检出的 `.venv` 软链指向不存在的路径),用系统 `python3`(pytest 9.1.1、pyswisseph 2.10.03)。 +- 开工核对:`docs/BUG_HISTORY.md` 最大号 BUG-1075,本单用 1076、1077。检索了 BUG-716 / 966 / 1016 / 1017(星盘页等待态、骨架)与 Bhava 相关记录(BUG-320),骨架、25 秒客户端期限、懒加载、缓存按账户与资料指纹换键这些约束都还在,本单没有动它们。 + +### 基线测试(开工实测) + +| 套件 | 结果 | +| --- | --- | +| `tsc --noEmit` | 0 错 | +| `npm run lint` | 0 error / 127 warning | +| `npm test` | tests 4212,pass 4158,fail 24,skipped 30,cancelled 0 | +| 24 条失败 | 全是 DB / 部署 / staging 环境套件(无 Docker):admin customer reset…、service and restricted admin database identities…、Owner recovery grants…、staging backups are encrypted…、billing order adjustments…、billing, subscriptions, usage authorization…、saving a published product forks…、database env validator…、migration runner is serialized…、foundation grants no direct runtime table DML…、local PostgreSQL applies…、personal report job migration…、personal report sections enforce owner-read RLS…、stdin PostgreSQL scripts…、redeem security…、self-hosted identity migration…、database roles have no cluster privileges、server compose defaults to local images…、staging env validator rejects selector drift…、Better Auth supports shared user OTP/password sessions…、database drops secret refs…、live staging sync preserves env…、live staging sync repairs nested deploy-tree drift…、admin code functions reject immutable codes… | +| Python `-k "varga or bhava or qizheng or ayanamsa or growth"` | 10 条失败:`test_varga_vedastro_mode` 9 条(D2/D4/D7/D16/D20/D27/D30/D45/D60 与 VedAstro 官方 golden 比对)+ `test_ayanamsa_mode_ownership`(`scripts/research/dasha_shift_per_minute.py` 自己调 `set_sid_mode`)。都与本单无关 | + +### 每项做了什么 + +**T1 七政四余隐藏(`af27709d`,后续清理 `f5149d10`)** + +- 删:`CHART_VIEW_TABS` 的七政项、`chart-page-view.tsx` 七政分支与 `selectTab` 请求、`chart-qizheng-tab.tsx`、`qizheng-palace-grid.tsx`、`chart-view-load.ts` 的 `/api/qizheng` 调用、`CHART_VIEW_LAYERS` 的 `qizheng`、契约 `chartViewQizhengOkSchema` / `qizheng` 字段 / `layerFailures.qizheng`、mapper `mapQizheng` / `unavailableQizheng` / `palaceBranch`、labels 里的 `QIZHENG_*` 与 `COORDINATE_BOUNDARY.qizheng`、hook 与 `secondary-page-data.ts` 的合并分支、`globals.css` 里只给七政用的选择器。 +- 印度盘与西洋盘的边界句原来写「和…七政宿度不是同一套」,页面上已没有七政,改成只点名另一套(「它和西洋回归黄道不是同一套坐标…」「它和印度盘的恒星黄经不是同一套…」)。 +- **保留**:`/api/qizheng`、`scripts/qizheng_chart_engine.py`、vendored stem-branch、`tests/test_qizheng_*.py`(全绿)。 +- 缓存:客户端缓存只在内存(`secondary-page-data.ts` 模块变量),zod 对象默认丢弃多余字段,所以不需要换缓存版本;**部署窗口内已打开的旧页签**拿到新响应会因旧 schema 要求 `qizheng` 而判为 `response_schema_failure`,刷新即好,与任何契约改动同类。 +- `frontend/src` 里 `qizheng` / `七政` 已无匹配(`grep -rn "qizheng\|七政" frontend/src` 为空)。 + +**T3 分盘表随盘换(BUG-1076,`ab6ee94e`)** + +- 先写失败测试:`frontend/tests/chart-varga-table.test.tsx`。在修复前运行,失败输出(节选):`not ok 1 - a divisional chart's table carries that chart's signs, degrees and houses` / `error: 'D9 Sun is in Libra'` / `actual: …双子 1°32′…11宫…Mrigashira…入友(Friendly Sign)` ——D9 表里的太阳是 D1 的「双子 1°32′」。 +- 契约 `chartViewVargaSchema` 加可选 `ascendant` 与 `rows`(D2 起才有);mapper `vargaRows` 用引擎的分盘星座、分盘内度数、`house`(从分盘上升数),加本命星座、庙旺、同位、本命顺逆。 +- 庙旺:`frontend/src/lib/vedic-chart-tables.json`(引擎常量的镜像)+ `chart-view-varga.ts` `vargaDignity`(入旺 → 自宫 → 落陷,与 `_get_dignity_level` 同序,分盘里不算 Moolatrikona 度数段、不算 Neecha Bhanga 与友敌)。`tests/test_chart_page_vedic_tables_contract.py` 逐格(9 星 × 12 座)对照 `jyotish_engine._get_dignity_level`,并对照 `VargaType.meaning`。**为什么不在 Python 响应里加 `dignity`**:`varga_full` 的形状被报告、咨询和多份 golden 共用,改它的爆炸半径远大于本单;判定表由合同测试钉死同源。 +- UI:分盘六列「行星 · 分盘星座 · 宫位 · 本命星座 · 庙旺 · 同位」,首行分盘上升;删星宿 / 宿主 / 足。本命表抽成 `NatalTable`,渲染与基线逐字节相同(`fixtures/chart-d1-table-baseline.html` 由基线 `5dc977ef` 在一次性工作树里渲染得到)。 + +**T2 盘型条 + 「星盘类型」面板 + D40 / D45 / D60(`2071dc7c`)** + +- `VARGA_CHIP_ORDER` 加 40、45、60(`/api/varga_full` 一次取 20 张,含 D1);`CHART_TYPE_ORDER` 23 项,顺序同 D2。 +- `chart-type-picker.tsx`:横滑条(`.chart-page-type-strip`,nowrap + overflow-x auto + min-width 0)+ 条外的「≡」(44×44);面板是原生 ``(`showModal`,`onCancel` 关、点遮罩关、卸载时焦点回到打开前的元素),三列格子,用途小字取 `vargaMeaning`。面板里选中后把条上对应按钮 `scrollIntoView({ inline: "nearest" })`(在点击处理里做,不在 effect 里)。样式框与报告「分块导出」抽屉同规格,≥860px 居中 720px。 +- D40 / D45 / D60 在 `birthTimeStatus !== "confirmed"` 时表上方加精度提示句。 +- golden:`chart-view-golden.json` 的 `varga_full.result` 追加 D40 / D45 / D60。来源:同一份 golden 的 `chart.planets[*].lon` 与 `ascendant.lon` 经 `DivisionalChartsCalculator._calculate_single_varga`;先用同样输入重算 D9 / D10 / D30,与已存的逐字段相等,再追加。`sourceCommand` 已注明。原有键一字未改(diff 只有新增)。 + +**T4 月亮盘 + 行运盘(`3f6bcb08`)** + +- 月亮盘:mapper `moonChart` 从 D1 投影(不发请求),`vedic.moon = { moonSign, ascendantHouse, chart, planets }`,行只重数宫位。`VedicChartSvg` 加可选 `ascendantHouse`(默认 1,其它调用方行为不变;有测试钉住 D1 仍只在 1 宫画「As」),月亮盘把「As」画在本命上升所在宫。 +- 行运:`transitChartBody` 从 `app/api/ephemeris/route.ts` 挪到 `src/lib/transit-chart-body.ts`,星历页改为引用(行为不变,星历测试全绿);行运行复用星历的 `transitsFromEngine`。新懒加载层 `transit`:按 `asOf` 当天 12:00、出生地时区、与本命相同的岁差和交点请求 `/api/chart`。 +- **发现并处理的坑**:服务端引擎缓存键是「账户 + 人物 + 出生资料 + path」,不含请求体。行运也打 `/api/chart`,不区分就会被直接回本命盘。`ChartViewEnginePost` 加可选 `cacheScope`,缓存键 path 槽用 `chartViewEngineCachePath(path, scope)`(行运 scope = `transit:<日期>`);有测试钉住本命 / 今天 / 明天三个键互不相同。 +- 表:行运五列「行星 · 今天的位置 · 速度 · 落本命 · 本命同星」,表头写「行运 · 日期 12:00(时区)」。 + +**T5 Bhava 盘(BUG-1077,`c35e0195`)** + +- 先确认 BUG-1077:`tests/test_api_server_security.py` 新增三条(缺 MC 且无出生时刻应 400;带出生时刻时 MC 来自 `houses_ex` 且跨度不全为 30;equal 宫制无出生时刻仍可用)。修复前运行:前两条失败,`Failed: DID NOT RAISE BadRequest`、`AssertionError: [30.0, 30.0, 30.0, 30.0, 30.0, 30.0, …]`——**连带齐出生时刻的请求也是等宫**。 +- MC 来源:新模块 `scripts/bhava_chalit_mc.py`。显式 `mc_lon` 优先;否则用出生年月日时 + 经纬 + 时区(沿用 handler 的 `_parse_timezone` / `_birth_hour_decimal`)算 JD,在 `temporary_ayanamsa(<请求岁差>)` 下 `swe.houses_ex(jd, lat, lon, b'R', FLG_SWIEPH | FLG_SIDEREAL)` 取 `ascmc[1]`——与报告链 `_build_natal_foundation_modules` 同一调用;都没有时 sripati / porphyry 直接 400。测试断言:MC 与独立 `houses_ex` 差 < 1e-3°,同一调用算出的上升与引擎本命上升差 < 0.01°(证明同一坐标框架)。 +- `jyotish_api_server.py`:把 `mc_lon = …(asc_lon + 270)…` 这一行挪到宫制校验之后并改成调用模块,**净增 0 行**(10935 → 10935),类方法数不变,`JyotishAPIHandler.__new__` 计数不变(新测试复用既有 `_handler()`)。报告链与 CLI 自己算 MC,不受影响,也没改。 +- 前端 `bhava` 懒加载层:`/api/bhava_chalit`,body = 本命 followUp + `house_system: "sripati"` + `mode: "compare"`(覆盖掉出生 payload 里给西洋盘用的 `house_system: "P"`),不传 `mc_lon`。`mapBhava` 遇到宫制回退、缺 MC、或 MC 恰等于 `asc + 270` 一律 unavailable(第二道防线)。盘:每颗星放进它的 Bhava 宫。表:「行星 · 黄道经度 · 星座宫 · Bhava 宫 · 换宫」(换宫行浅底)+ 12 行「宫 · 宫头 · 起点(sandhi)」。 +- golden:`frontend/tests/fixtures/chart-view-bhava-golden.json` 是修复后真实 `_compute_bhava_chalit` 对星盘页实际请求体的响应(`sourceCommand` 注明);这张虚构盘太阳、水星、土星换宫。占位 MC / 宫制回退两条负面测试是在真实响应上改一个字段模拟旧 bug,不作为合同 fixture。 + +**T8(星盘部分)**:`frontend/DESIGN.md` §15(四个 Tab、七政一句、盘型条与面板、每种盘型的表、等待态两行);`CONTEXT.md` 加「盘型 / 月亮盘 / Bhava 盘 / 行运盘」;`CHANGELOG.md` 一条(Skill 不 bump);`docs/BUG_HISTORY.md` BUG-1076 / 1077(状态「待验收」,部署后再改 resolved);`docs/testing/chart-types-and-report-buttons-20260928.md` 星盘一节 13 条;`BLOCKED.md` 一节;`docs/tasks/README.md` 本单一行改为「T1–T5 已实现待验收」。 + +### 改动的既有断言(原值 / 新值 / 原因) + +| 文件 · 断言 | 原值 | 新值 | 原因 | +| --- | --- | --- | --- | +| `chart-page-view.test.tsx` · 每个 Tab 的 markup | 必须含「七政四余」;七政 Tab 须含角宿 / 计都派别 / 庙旺 | 不得含「七政四余」;七政分支删除 | D1 七政隐藏 | +| 同上 · 测试名 | the five tabs render… | the four tabs render… | 同上 | +| 同上 · 等待外壳禁用 Tab 数 | `5` | `CHART_VIEW_TABS.length`,并断言 `=== 4` | 同上 | +| 同上 · unavailable 栏说明 | 西洋 + 七政各一次 | 只断言西洋(改名 unavailable western tab stays explanatory) | 同上 | +| 同上 · 表格包裹 | `[vedicTab, westernTab, qizhengTab]` | `[vedicTab, westernTab]` | 文件已删 | +| 同上 · 失败为终态 | western / qizheng / chara | western / chara(改名) | D1 | +| 同上 · pending 为静态句 | qizheng / chara | chara(改名) | D1 | +| `chart-view-route.test.ts` · 默认开页 | `body.qizheng.status === "unavailable"` | `"qizheng" in body === false` | 契约删字段 | +| 同上 · 全部 layer | 会打 `/api/qizheng` | 不打;测试改名 western stays unavailable… | D1 | +| 同上 · 七政 ketuMode 取引擎字段 | 整条 | 删除;引擎侧 ketu_mode 合同仍由 `tests/test_qizheng_api_productization.py` 守 | D1 | +| 同上 · 边界句 | `COORDINATE_BOUNDARY.qizheng` 含「角宿」 | 该键不存在;印度 / 西洋边界句不含「七政」 | D1 | +| `chart-view-engine.test.ts` · 层解析 | `qizheng` 被保留 | 与未知层一样丢弃 | D1 | +| `chart-page-hook.test.ts` · 429 逐层 | varga / chara / western / qizheng | varga / chara / western / bhava / transit | D1 + T4 + T5 | +| 同上 · `packet` 桩 | `/api/chart` 一律回本命 | 带 `cacheScope` 的 `/api/chart` 走 failure / 行运 golden;`/api/bhava_chalit` 回 Bhava golden | 行运也打 `/api/chart` | +| `ephemeris-route.test.ts` · `skip_vedastro_main_entry_overview` 源码计数 | route.ts 里 2 次 | route.ts 1 次 + `transit-chart-body.ts` 1 次;按实际请求逐条断言不变 | T4 共用 `transitChartBody` | +| `chart-view-zero-year.test.ts` | bundle 带 `qizheng: null` | 去掉(类型字段已删,无断言变化) | D1 | +| `react-client-lifecycle-test-support.ts`(测试支撑,非断言) | — | `HostElement` 加空的 `scrollIntoView()` | 面板选中后滚动条目;最小 DOM 没有这个方法 | + +测试名消失的 7 条全部是上表里的改名或删除:the five tabs…、unavailable western and qizheng tabs…、western qizheng and chara failures…、qizheng and chara pending…、western and qizheng stay unavailable…、qizheng ketuMode follows the engine field…、real assemble to fetch to hook preserves qizheng engine 429。新增 27 个测试名。 + +### 交付时实测 + +| 项 | 基线 | 交付 | 结论 | +| --- | --- | --- | --- | +| `tsc --noEmit` | 0 | 0 | 通过 | +| `npm run lint` | 0 error / 127 warning | 0 error / 127 warning | 通过(warning 数不变) | +| `npm test` 总数 | 4212 | 4232 | 通过(+20) | +| `npm test` 失败 | 24 | 24,名单与基线逐条同名,新增失败 0 | 通过(环境缺口:无 Docker) | +| `npm test` cancelled / 退出码 | 0 / 1 | 0 / 1 | 退出码 1 来自同一批 24 条 | +| 星盘相关套件(13 个既有文件 + 5 个新文件 + 星历 3 个) | — | 171 / 171 | 通过 | +| Python 定向(`test_api_server_security.py`、`test_api_server_growth_contract.py`、`test_chart_page_vedic_tables_contract.py`、`test_bhava_chalit.py`、`test_repo_privacy_markers.py`) | — | 213 passed | 通过 | +| Python `-k "varga or bhava or qizheng or ayanamsa or growth or chart_page"` | 10 失败 | 同 10 条同名 | 通过 | +| `next build`(Turbopack) | — | exit 0;`/`、`/chart`、`/ephemeris`、`/people` 均 ○ Static | 通过 | +| 首屏 gzip(rootMainFiles,level 9;基线在一次性工作树 `5dc977ef` 上同法 build) | 130,872 B(6 个文件) | 130,872 B(6 个文件) | 0.00%,通过 | +| `run_quality_gate.py --profile quick`(系统 python3) | — | 编译、JSON、审计、BPHS 不变量与 pytest 段全过(973 passed、1 skipped);最后的 `npm test` 段 24 条失败,名单与基线逐条同名,因此 gate 退出 1 | Python 段通过;整门红来自无 Docker 的基线失败(环境缺口) | + +### 环境缺口(不是「通过」) + +- 无登录态与 Chrome:盘型条横滑、原生 ``(Esc / 遮罩 / 焦点)、375px 不横滚、月亮盘「As」位置只在 SSR markup 与最小 DOM harness 上验证;真机按 `docs/testing/chart-types-and-report-buttons-20260928.md` 星盘一节。 +- 无 Docker:24 条 DB / 部署套件,名单与基线同。 +- 无 `.venv`:用系统 `python3`。 +- Bhava / 行运在 staging 的真实耗时与 429 频率未测。 + +### 让步 + +没有用让步顺序:T5 Bhava 拿到了真实 MC,T4 行运「本命同星」一列与 T2 ≥860px 居中都做了。 diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 6d6f91de..c774222e 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -246,7 +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-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,只改报告范围) | T1–T5(星盘)已实现待验收;T6 / T7 另一执行方 | `codex/chart-types-20260928`(BUG-1076 / 1077,本地未推) | | `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/testing/chart-types-and-report-buttons-20260928.md b/docs/testing/chart-types-and-report-buttons-20260928.md new file mode 100644 index 00000000..cf82fdee --- /dev/null +++ b/docs/testing/chart-types-and-report-buttons-20260928.md @@ -0,0 +1,23 @@ +# 星盘盘型 / 分盘表 / 七政隐藏 真机清单(2026-09-28) + +状态:待真机。自动化做了什么、没做什么见 `docs/tasks/PROGRESS-chart-types-and-report-buttons-20260928.md`。只用受控账户与明确虚构的出生资料;不借他人登录态;只记脱敏结果。 + +本文件本节只覆盖星盘页(T1–T5);岁差与「我的报告」按钮(T6 / T7)由另一执行方补在后面。 + +## 星盘(T1–T5) + +| 项目 | 操作 | 通过标准 | 结果 | +| --- | --- | --- | --- | +| 七政隐藏 | 打开 `/chart` | Tab 只有「星盘 / 基础信息 / 大运 / 西洋盘」四个;全页没有「七政」字样 | 待验 | +| 盘型条 | iPhone 375 / 390 宽,浅色与深色各一次 | 盘型条一行、可横滑、页面不横滚;顺序为 本命 · D9 · 月亮 · Bhava · 行运 · D2 … D60;行尾「≡」始终可见 | 待验 | +| 星盘类型面板 | 点「≡」 | 底部弹出「星盘类型」三列格子共 23 个,当前项高亮;D60 格下写「前世业力」;点遮罩、点关闭、按 Esc 都能关;桌面宽 ≥860px 是居中对话框 | 待验 | +| 从面板选远处的盘 | 在面板里点 D60 | 面板关闭,盘型条滚到 D60 且高亮,画出 D60 盘与表 | 待验 | +| 分盘表随盘换(BUG-1076) | 依次点 本命、D9、D10 | 三张表的行内容各不相同;D9 / D10 表为六列「行星 · 分盘星座 · 宫位 · 本命星座 · 庙旺 · 同位」,没有星宿 / 宿主 / pada;本命表仍是原八列 | 待验 | +| 精度提示 | 出生时间未校正的资料点 D40 / D45 / D60;再用已校正的资料点 D60 | 未校正时表上方有「这张盘每格不到一度…先做生时校正再看,会更稳。」;已校正时没有;D9 等其它盘都没有 | 待验 | +| 月亮盘 | 点「月亮」 | 盘的第 1 宫是月亮所在星座、月亮在 1 宫;「As」出现在本命上升所在的那一宫(不在 1 宫,除非月亮与上升同座);表头写「以月亮所在星座(X)为第 1 宫」;不出现等待骨架 | 待验 | +| 行运盘 | 冷点「行运」 | 先有空盘骨架 +「这一张盘还没拿到。」,随后出盘;表头写今天日期 12:00 与时区;与「星历」页当日行运的星座、落宫一致 | 待验 | +| Bhava 盘(BUG-1077) | 冷点「Bhava」 | 出盘;宫头表 12 行、各宫起点不是整齐的每 30°;至少有一张测试盘能看到「换宫:是」的行(浅底);若服务返回失败,只显示失败句,不画盘 | 待验 | +| 忙与失败 | 受控环境让 Bhava / 行运 返回引擎忙 | 显示「算盘的服务正忙,稍等几秒再打开就好。」,不永久等待;再点可重试 | 待验 | +| 暖进 | 打开过 D60、Bhava、行运后离开再回来 | 直接显示,不重放骨架;后台刷新后这些盘仍在 | 待验 | +| 换人物 | 切到另一位人物 | 月亮盘 / Bhava / 行运都换成新人物的,不残留上一位 | 待验 | +| 无障碍 | 键盘 Tab 到「≡」回车 | 焦点进入面板;关闭后焦点回到「≡」;读屏念出「全部盘型」「星盘类型」 | 待验 | diff --git a/frontend/DESIGN.md b/frontend/DESIGN.md index 262526fd..addd1fdb 100644 --- a/frontend/DESIGN.md +++ b/frontend/DESIGN.md @@ -941,15 +941,23 @@ Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 独立 route `/chart`,不进 `page.tsx`。外壳先画、主盘先到、其余 tab 按需。不扣点、不调模型。盘面从现有路径复用 `VedicChartSvg`,不搬家。 -`/chart` 是静态壳:首字节不取决于引擎。进页只请求 `/api/chart`。分盘(`/api/varga_full`)、大运 Chara(`/api/dasha/chara`)、西洋(`/api/western`)、七政(`/api/qizheng`)在用户点到对应 tab / 非 D1 chip 时才请求。未点的 tab 不发请求。 +`/chart` 是静态壳:首字节不取决于引擎。进页只请求 `/api/chart`。分盘(`/api/varga_full`,D2–D60 一次取齐)、大运 Chara(`/api/dasha/chara`)、西洋(`/api/western`)、Bhava(`/api/bhava_chalit`)、行运(按当天日期的 `/api/chart`)在用户点到对应 tab / 盘型时才请求。月亮盘从已到的 D1 投影,不发请求。未点的不发请求。 + +**七政四余 2026-09-28 起不在星盘页展示**(TASK-chart-types D1):Tab、组件、懒加载层与契约字段已删,后端 `/api/qizheng`、引擎与 vendor 保留,以后作对话里的补充。 ### 结构 页名「星盘」与出生资料一行在 `SecondaryHeader` 的 46px 顶栏里(§ Secondary page shell)。顶栏之下第一件东西是 Tab 行。不写眉标,不写「打开即有」、不写「主盘直接算 · 分盘按需 · 不消耗点数」,也不承诺打开速度。等待外壳和失败页只有原因/等待句。 -五个 Tab 按体系分:**星盘 / 基础信息 / 大运 / 西洋盘 / 七政四余**,画成**一条下划线式 Tab 行**:无边框、无卡面,当前项 2px 下划线 + 主文字色,整行一条 1px 底线。行内 `flex-wrap: nowrap` 且自身横向滚动,所以 375px 下它仍是一行,不折行、不换成第二排——底线画在滚动容器自己的 border 上,不会跟着内容滚走。五个等重的药丸按钮会读成五个可按的东西,Tab 行读成「一个控件 + 一个当前位置」。 +四个 Tab 按体系分:**星盘 / 基础信息 / 大运 / 西洋盘**,画成**一条下划线式 Tab 行**:无边框、无卡面,当前项 2px 下划线 + 主文字色,整行一条 1px 底线。行内 `flex-wrap: nowrap` 且自身横向滚动,所以 375px 下它仍是一行,不折行、不换成第二排——底线画在滚动容器自己的 border 上,不会跟着内容滚走。一排等重的药丸按钮会读成几个可按的东西,Tab 行读成「一个控件 + 一个当前位置」。 -分盘 chip(D1–D30)只出现在印度「星盘」Tab 内部,不得把西洋盘或七政四余做成第 13 个 chip。chip 比 Tab **低一级**:无描边、无卡面、caption 字号、三级文字色,当前项只有一块浅底。它是一个 Tab 内部的筛选器,不是第二层导航。Tab 与 chip 的触摸目标仍是 44px。 +### 盘型条与「星盘类型」面板(2026-09-28,TASK-chart-types D2) + +印度「星盘」Tab 内部是一条**盘型条**,共 23 种,顺序固定:本命、D9、月亮盘、Bhava、行运、D2–D8、D10、D11、D12、D16、D20、D24、D27、D30、D40、D45、D60。条上文字短:「本命 / D9 / 月亮 / Bhava / 行运 / D2 …」。条用既有 chip 的样子(比 Tab **低一级**:无描边、无卡面、caption 字号、三级文字色,当前项只有一块浅底),`flex-wrap: nowrap` 且自身横向滚动(`.chart-page-type-strip`),375px 下一行、页面不横滚。西洋盘不做成盘型。 + +条尾固定一个「≡」(`.chart-page-type-menu`,44×44,`aria-label="全部盘型"`),在滚动容器外面,不会被滚走。点它打开原生 ``「星盘类型」:标题 + 关闭,三列网格(`.chart-page-type-grid`),每格大字标签 + 一行小字用途(D 号盘的用途取引擎 `VargaType.meaning`,与 `vedic-chart-tables.json` 同源;本命「D1」、月亮盘「以月亮为第 1 宫」、Bhava「不等宫」、行运「今天」)。当前格主文字色描边 + 浅底。点任一格 = 选中、关面板、把条滚到该项。手机是底部抽屉,≥860px 是居中 720px,框与报告「分块导出」抽屉同规格。Esc、点遮罩关闭,焦点回到「≡」。Tab、chip、「≡」、格子触摸目标均 ≥ 44px(格子 56px)。 + +D40 / D45 / D60 的表格上方,出生时间不是「已校正」时多一句:「这张盘每格不到一度,出生时间差两三分钟就可能换一格。先做生时校正再看,会更稳。」 侧栏在「新建对话」之后、「我的报告」之前加「星盘」「星历」两个入口;折叠轨(64px)仍用既有 `report-nav-button` 图标行,当前项用白玻璃面 + 2px 深棕标记,不新造选中态。星历入口指向 `/ephemeris`(由另一单交付,合入前 404 是预期)。 @@ -961,7 +969,7 @@ Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 桌面(≥1024)盘面与参数表左右并排,行星表是跨两列的整行——它的列宽需要完整版心。 -盘内 SVG 文字用 CSS 提到 16px viewBox 单位,使约 318px 盘宽下实际像素不低于 12px。Tab、分盘 chip 均 44px。 +盘内 SVG 文字用 CSS 提到 16px viewBox 单位,使约 318px 盘宽下实际像素不低于 12px。Tab、盘型 chip 均 44px。 ### 星盘档案与当前人物(2026-09-25修复) @@ -988,7 +996,7 @@ Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 ### 行星表 -三张 `.chart-page-planet-table`(印度盘宿度、西洋相位、七政十一曜)**每一张**都包在 `.chart-page-planet-table-wrap` 里:`min-width: 0` + `overflow-x: auto`。375px 下表格在自己的盒子里横滚,页面不横滚。`min-width: 0` 和 overflow 一样是必需的——grid item 默认按内容定宽,少了它表格会把页面撑宽而不是滚动。印度盘那张从四列扩到八列后 `min-width` 由 `26rem` 提到 `34rem`。 +每一张 `.chart-page-planet-table`(本命、分盘、月亮盘、Bhava 两张、行运、西洋相位)都包在 `.chart-page-planet-table-wrap` 里:`min-width: 0` + `overflow-x: auto`。375px 下表格在自己的盒子里横滚,页面不横滚。`min-width: 0` 和 overflow 一样是必需的——grid item 默认按内容定宽,少了它表格会把页面撑宽而不是滚动。印度盘那张从四列扩到八列后 `min-width` 由 `26rem` 提到 `34rem`。 **印度盘行星表的八列(2026-09-18)。** 盘里不再写的东西全部落在这里: @@ -1005,7 +1013,19 @@ Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 第一行是上升。上升是盘点不是星体,引擎不返回它的星宿 / pada / 宿主,这三格写「—」而不是填一个看起来合理的值。数字列 `tabular-nums`,符号列与宿主列居中。 -本轮不新增第二层页签:星盘页已有五个 Tab,参照里「宫位 / 大运 / 星力 / 瑜伽」等页签的内容后续另立单。 +本轮不新增第二层页签:参照里「宫位 / 大运 / 星力 / 瑜伽」等页签的内容后续另立单。 + +**每种盘型一套表(2026-09-28,BUG-1076)。** 以前切到 D9 只换表头、行仍是 D1。现在: + +| 盘型 | 列 | 说明 | +| --- | --- | --- | +| 本命 | 上面八列 | 不变(与基线渲染逐字节相同) | +| D2–D60 | 行星 · 分盘星座(度°分′)· 宫位 · 本命星座 · 庙旺 · 同位 | 宫位从该分盘上升数;庙旺只写「入旺 / 自宫 / 落陷」,其余「—」;同位 = 与本命同星座(Vargottama)。**没有星宿 / 宿主 / 足**:那是本命经度的属性。逆行在行星格后标「逆」(分盘不改顺逆)。首行是分盘上升 | +| 月亮盘 | 本命八列 | 宫位从月亮所在星座数;表头「月亮盘 · 以月亮所在星座(X)为第 1 宫」;盘上「As」画在本命上升落的那一宫(`VedicChartSvg` 的 `ascendantHouse`,其它盘默认 1 宫不变) | +| Bhava | 行星 · 黄道经度 · 星座宫 · Bhava 宫 · 换宫;另一张「宫 · 宫头 · 起点(sandhi)」12 行 | Sripati。换宫的行用 `--color-selected` 浅底。拿不到真实 MC 时这一栏走失败句,不画等宫(BUG-1077) | +| 行运 | 行星 · 今天的位置 · 速度 · 落本命 · 本命同星 | 表头写计算时刻「行运 · YYYY-MM-DD 12:00(时区)」,上方一句「以本命上升为第 1 宫,放的是这一天中午的行星位置。岁差和交点与本命相同。」 | + +说明句 + 表格包在 `.chart-page-varga-table-block` 里,作为一个 grid 项在 ≥1024 时跨两列。 ### 三套坐标系 @@ -1013,7 +1033,7 @@ Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 - 印度盘:恒星黄道,岁差用资料里选的那一套。 - 西洋盘:回归黄道,宫位 Placidus;右栏第一张是边界卡。端点未上线时 Tab 仍在,渲染静态说明,整页不失败。 -- 七政四余:宿度自角宿初度起算。必须同时出现计都派别与庙旺未闭合。端点未上线时同样只渲染静态说明。 +- 七政四余:2026-09-28 起不在页面上(见上)。 「传统象征」是词条,不得写成运势。页面上不另写「词条式释义,不是对你个人的判断」——行星卡本身已经是度数、星宿、D9,没有判断句。大运 Tab 底部固定:「只有两条同时指向同一段时间才算证据,单轨命中要降一级来看。」Chara 的正式名称是 **Chara Dasha(kn_rao 变体)**,不要写成 Narayana。 @@ -1050,13 +1070,14 @@ Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 ### 等待态 -2026-09-24 产品决策有限推翻 09-18 方案一(BUG-716 / 966):`SecondaryPageShell` 标题、note 槽与撑满内容区不变,主盘未到时正常渲染 body 和禁用的 Tab 行;仅 D1、非 D1 分盘与西洋盘位置显示既有 SVG 空模型的骨架与原等待句。骨架无星体、度数、星座标签,几何不得复制;容器 `aria-busy=true`,装饰盘对读屏隐藏。中性 token、opacity 0.35 ↔ 0.6 / 2.4s ease-in-out,减弱动态效果时静止 0.5;不旋转、不扫光。大运、七政表格仍为静态句,首页、侧栏、星历、报告不适用此例外。首次请求(含预取)和按需层均有 25 秒客户端期限;失败移除骨架,再点该 Tab/chip 清失败并重试。401 先显式呈现登录句再跳转。同一会话再次进入直接用模块缓存,不重放等待句。出生资料保存成功后,缓存按账户和资料指纹换键,旧盘不得留在页上冒充新的日期或时间。 +2026-09-24 产品决策有限推翻 09-18 方案一(BUG-716 / 966):`SecondaryPageShell` 标题、note 槽与撑满内容区不变,主盘未到时正常渲染 body 和禁用的 Tab 行;仅 D1、非 D1 分盘与西洋盘位置显示既有 SVG 空模型的骨架与原等待句。骨架无星体、度数、星座标签,几何不得复制;容器 `aria-busy=true`,装饰盘对读屏隐藏。中性 token、opacity 0.35 ↔ 0.6 / 2.4s ease-in-out,减弱动态效果时静止 0.5;不旋转、不扫光。大运表格仍为静态句,首页、侧栏、星历、报告不适用此例外。Bhava、行运与分盘同在盘位上,沿用盘位骨架(2026-09-28)。首次请求(含预取)和按需层均有 25 秒客户端期限;失败移除骨架,再点该 Tab/chip 清失败并重试。401 先显式呈现登录句再跳转。同一会话再次进入直接用模块缓存,不重放等待句。出生资料保存成功后,缓存按账户和资料指纹换键,旧盘不得留在页上冒充新的日期或时间。 | 时刻 | 文案 | | --- | --- | | 外壳已出、主盘未到 | 北印度空盘骨架 + 这一张盘还没拿到。 | | 已点西洋,尚未返回 | 西洋空盘骨架 + 这一栏还没拿到。 | -| 已点大运 / 七政,尚未返回 | 静态句:这一栏还没拿到。 | +| 已点大运,尚未返回 | 静态句:这一栏还没拿到。 | +| 已点 Bhava / 行运,尚未返回 | 北印度空盘骨架 + 这一张盘还没拿到。 | | 已点非 D1 分盘,分盘包还没返回 | 北印度空盘骨架 + 这一分盘还没拿到。 | | 客户端超时 | 这张盘等了太久没有回来,再打开一次试试。 | | 分盘 / 按需层失败 | 按原因显示既有失败句;不留等待句或骨架 |