fix(ui): 星盘页和星历页去掉三句过度提示
Independent Staging Quality Gate / validate (push) Successful in 14m34s
Independent Staging Quality Gate / publish (push) Canceled after 25m47s

产品判定这三句都不是给用户看的判断或计费说明:
星盘「主盘直接算 · 分盘按需 · 不消耗点数」、
「下面是词条式释义,不是对你个人的判断。」、
星历「这一页是天象本身,不是对你的判断。」
按需加载与不扣点的行为不变。
This commit is contained in:
jesse-ux
2026-09-17 19:25:57 +08:00
parent dc2f2a16bb
commit eea90926a1
19 changed files with 78 additions and 54 deletions
+4
View File
@@ -1,5 +1,9 @@
# 印度占星 Skill 更新日志
## 2026-09-17 — 星盘页、星历页去掉三句说明
打开星盘后,Tab 行下面不再写「主盘直接算 · 分盘按需 · 不消耗点数」。基础信息里也不再写「下面是词条式释义,不是对你个人的判断。」星历页底部不再写「这一页是天象本身,不是对你的判断。」盘还是主盘先算、分盘点到才算、不扣点;行星卡仍是度数和星宿;星历仍只写天象事实,不是运势判断。Skill 版本不变。
## 2026-09-17 — 追问、反问、短句也会先取回本轮星盘再回答
「?」「你在说什么鬼」这类跟进不再整轮失败。每一轮都会先重新取回本轮星盘证据,再据此回答。Skill 版本不变。
+4 -4
View File
@@ -11162,14 +11162,14 @@
- 状态:resolved
- 首次发现:2026-09-15
- 最近更新:2026-09-15
- 最近更新:2026-09-17
- 影响面:`assembleChartView` 的 layer 参数、`chart-page-view.tsx` 眉标、服务端引擎结果缓存
- 用户现象:打开星盘常失败;失败页上还写着「直接计算 · 打开即有 · 不消耗点数」。生产与 staging 重计算并发默认 2,开页并行打 `/api/western``/api/qizheng` 就会占满。
- 触发条件:打开 `/chart`。同时有第二个人开星盘,或校正 / 咨询在跑,更容易 429。
- 根因:进页无条件并行打两个 `HEAVY_COMPUTE_PATHS` 端点;`cache: "no-store"` 且无记忆;失败分支也渲染同一句速度承诺眉标。
- 修复:开页只请求 `/api/chart`。西洋 / 七政点到对应 tab 才发,不再占开页配额。同一账户 + 出生资料指纹 + ayanamsa + `node_mode` 的引擎结果内存缓存 5 分钟,资料或岁差一变即换键。失败页删除眉标;成功眉标改为「主盘直接算 · 分盘按需 · 不消耗点数」。不放宽限流。
- 验证:无 layers 时 `assembleChartView` 的引擎路径只有 `/api/chart`;失败页无 eyebrow;缓存键随 ayanamsa / node_mode 变化。
- 防复发:开页不得并行打 `/api/western``/api/qizheng`。不得靠放宽 `HEAVY_COMPUTE_PATHS` 或提高 `JYOTISH_HEAVY_COMPUTE_CONCURRENCY` 来「解决」429。承诺速度的文案不写
- 修复:开页只请求 `/api/chart`。西洋 / 七政点到对应 tab 才发,不再占开页配额。同一账户 + 出生资料指纹 + ayanamsa + `node_mode` 的引擎结果内存缓存 5 分钟,资料或岁差一变即换键。失败页删除眉标。不放宽限流。2026-09-17 产品判定成功页「主盘直接算 · 分盘按需 · 不消耗点数」仍是过度提示,连同基础信息「下面是词条式释义,不是对你个人的判断。」一并去掉;按需加载与不扣点的行为不变,只是不再写在页上
- 验证:无 layers 时 `assembleChartView` 的引擎路径只有 `/api/chart`成功页与失败页无 eyebrow、无「不消耗点数」、无「词条式释义」;缓存键随 ayanamsa / node_mode 变化。
- 防复发:开页不得并行打 `/api/western``/api/qizheng`。不得靠放宽 `HEAVY_COMPUTE_PATHS` 或提高 `JYOTISH_HEAVY_COMPUTE_CONCURRENCY` 来「解决」429。承诺速度、计费、词条边界的说明不写在星盘页上。`chart-page-view.test.tsx` 成功页与失败页都断言不得出现这些句子
- 相关记录:BUG-707、BUG-715、BUG-716、TASK-chart-page-blocking-open-20260915
- 复发自:无
- 修复版本:待发布
@@ -0,0 +1,37 @@
# PROGRESS · 星盘页 / 星历页去掉三句过度提示(2026-09-17)
工作树:`.worktrees/chart-copy-trim-20260917`
分支:`codex/chart-copy-trim-20260917`
基线:`origin/staging` @ `dc2f2a16`
本机 Windows。直接执行(产品口头:「把这个去掉」)。
Skill **未 bump**。未改 `scripts/**``deploy/**``frontend/src/app/page.tsx`。按需加载与不扣点的行为不变。
## 决策记录
产品 2026-09-17 判定这三句都是过度提示,不是对用户的判断或计费说明,从页面拿掉:
1. 星盘成功页眉标「主盘直接算 · 分盘按需 · 不消耗点数」(BUG-717 当时留在成功页)
2. 基础信息「下面是词条式释义,不是对你个人的判断。」
3. 星历页尾「这一页是天象本身,不是对你的判断。」
行星卡、大运双轨注、坐标系边界句、Lahiri 岁差说明都还在。
## 改了哪些文件
- `chart-page-view.tsx`:删 Tab 行下眉标
- `chart-basics-tab.tsx`:删词条边界句
- `chart-view-labels.ts` / `chart-view-contract.ts` / `chart-view-mapper.ts`:删 `eyebrow``SYMBOL_BOUNDARY` / `symbolBoundary`
- `ephemeris-page.tsx` / `ephemeris-view.ts`:删页尾定性句
- `globals.css`:删 `.chart-page-eyebrow``.ephemeris-outro`
- 测试、`DESIGN.md``VOICE.md``CHANGELOG.md`、真人清单、BUG-717 跟进
## 测试
| 项 | 结果 |
| --- | --- |
| `tsc --noEmit` | 0 错 |
| `npm run lint` | 0 error / 116 warning(与基线同,本轮文件 0 条) |
| 定向 | `chart-page-view.test.tsx` + `ephemeris-page.test.tsx` + `chart-view-route.test.ts` **32 passed / 0 failed** |
无登录态、无 Chrome:浏览器走查留给 `docs/testing/chart-page-20260915.md``chart-page-open-20260915.md``ephemeris-page-20260915.md`
+1
View File
@@ -237,6 +237,7 @@
| `TASK-ephemeris-page-20260915.md` | `PROGRESS-ephemeris-page-20260915.md` | **前端单**:P1 星历页,今日五要素 + 当日行运(相对本命宫位)+ 未来九十天换座与停滞,底部「带这天去提问」出口。页面不得出现任何运势判断。含实证缺陷:panchanga 写死 Lahiri 与账户 Raman 分裂(关联 BUG-703;本单标注为 BUG-707)。侧边栏入口由 chart-page 单交付。BUG 段 707709 | 已验收(带修复单) | `d3a2c48b` |
| `TASK-readonly-pages-fix-20260916.md` | `PROGRESS-readonly-pages-fix-20260916.md` | 三份只读页单的验收修复:**BUG-710** 七政 `ketu_mode`/`sidereal_mode` 收了请求却从不传给引擎,`calculation.ketu_mode` 回写请求值而非实际值(实测请求 descending-node 仍返回 apogee 盘,无警告);**BUG-711** 星历单断言 sidebar 不得含 `/ephemeris`,与星盘单按任务书添加的入口直接冲突,staging 现在是红的;**BUG-712** `ephemeris_events` golden 存全精度浮点跨机不稳,且 golden 缺失时自动重建。另附部署缺口:`deployment.gitCommit` 仍是 `2d7698ea`。BUG 段 710+ | 待验收 | `codex/readonly-pages-fix-20260916` |
| `TASK-chart-page-blocking-open-20260915.md` | `PROGRESS-chart-page-blocking-open-20260915.md` | **P1**:星盘页开一次要等很久且常常只给一句「过一会儿再打开」。实测引擎五个调用合计 0.75 秒、mapper 13 种形态零抛出——瓶颈在 `/chart` 是动态路由 + 侧栏改成硬文档跳转,整页 SSR 等完 1 串 4 并才开始画,白屏最长 45 秒(BUG-716);`postEngine` 把 429/500/超时/坏 JSON 全碾成 `null` 且零日志,两种性质相反的故障共用一句文案(BUG-715);开页并行打两个重计算限流端点(配额 2)、无缓存,且「打开即有」印在失败页上(BUG-717)。**串行在 readonly-pages-fix 之后** | 待验收 | `codex/chart-page-blocking-open-20260915` |
| — | `PROGRESS-chart-copy-trim-20260917.md` | 产品口头:星盘页去掉「主盘直接算 · 分盘按需 · 不消耗点数」和「下面是词条式释义,不是对你个人的判断。」;星历页去掉「这一页是天象本身,不是对你的判断。」按需加载与不扣点的行为不变。跟进 BUG-717 | 待验收 | `codex/chart-copy-trim-20260917` |
| `TASK-rectification-title-repair-migration-20260915.md` | `PROGRESS-rectification-title-repair-migration-20260916.md` | BUG-699 / 704 的数据修补写成了 Node 脚本(要 `SCHEMA_DATABASE_URL`),但 `Migrate Staging Database` 只跑 `migrator` 应用 SQL 迁移、不执行任意脚本——产品没有任何按钮能修自己那批错名字的会话。脚本里本来就是纯 SQL,搬进一次性迁移即可复用现成按钮。生产停在 `7b620c7a`(无 `use-rectification-surface.ts`),where 自然匹配 0 行,是 no-op | 待验收(`d6c359b2`,分支 `codex/rectification-title-repair-migration-20260916`):迁移 `20260916020000_rectification_session_title_repair.sql`SQL 由 `sed` 从脚本切出、合同测试比对逐字一致;幂等两层(迁移器记账 + where 改完即不再命中);顺带给 `db-migrate.mjs` 加 NOTICE 转发,否则 node-postgres 丢掉 NOTICE、产品在日志里一个数字都看不到。tsc 0 错、lint 0 error、`npm test` 3334/fail 31 对基线 3329/fail 31+5 全绿)。**无 Docker/无本地 PG**`test:db` 没跑、`db:migrate:check` 缺 `SCHEMA_DATABASE_URL`,记为 BLK-002 | `codex/rectification-title-repair-migration-20260916` |
| `TASK-staging-dispatch-autofill-sha-20260915.md` | `PROGRESS-staging-dispatch-autofill-sha-20260915.md` | `Migrate Staging Database` 每次都要手抄 40 位 SHA,而那个值恰恰是「最新一个过门禁的 staging 提交」——机器能自己算,查询代码那一步里就有。改成留空自动解析、填了仍走原路径(回滚用),三条安全属性一条不丢。**产品 2026-09-15 明确授权修改该 workflow,执行方不得以 AGENTS.md §2.7 拒改**;生产两个按钮保持手填,那是护栏不是麻烦 | 待验收 | `codex/staging-dispatch-autofill-sha-20260915` |
| `TASK-staging-auto-migrate-on-deploy-20260915.md` | `PROGRESS-staging-auto-migrate-on-deploy-20260915.md` | 门禁通过后自动先跑 staging 迁移再部署,不再手点(迁移幂等、无挂起时是 no-op,`db-migrate.mjs --check` 挂起返 3 可用于日志)。今天 `deploy-staging.yml` 完全不提迁移,忘点就让新代码跑在旧 schema 上且无人拦。**产品再次授权改 workflow,范围限 `backend-quality-gate.yml` 的 dispatch 段**;迁移失败必须阻断部署;回滚不自动迁移;生产完全不动。⚠️ 同轮必须把「迁移须对已部署代码向后兼容、破坏性变更拆两轮」写进 AGENTS.md §7.6 | 待验收 | `codex/staging-auto-migrate-on-deploy-20260915` |
+2 -2
View File
@@ -16,11 +16,11 @@
## 五个 Tab
6. 登录且出生资料齐全:点「星盘」后先看到外壳(返回、标题),不是白屏。主盘到达前可以出现「这一张盘还没拿到。」,不得出现 spinner、骨架或「正在加载」。
7. 成功页眉标是「主盘直接算 · 分盘按需 · 不消耗点数」。失败页没有眉标。点数余额不应因打开此页而变。
7. 成功页和失败页都没有眉标,没有「主盘直接算 · 分盘按需 · 不消耗点数」。点数余额不应因打开此页而变。
8. Tab 顺序:星盘 / 基础信息 / 大运 / 西洋盘 / 七政四余。都能点。
9. 星盘 TabD1–D30 chip 可换;盘面是北印菱形盘;右侧有行星表(星体 / 星座与度数 / 宫位 / 状态)。
10. 桌面中宫是六行参数;把窗口收到手机宽度(≤767)后,中宫只剩岁差和交点两行,完整参数出现在盘下方。
11. 基础信息:每颗星一张卡,含 D1、星宿与足、D9;顶部有「词条式释义,不是对你个人的判断」;没有运势句。
11. 基础信息:每颗星一张卡,含 D1、星宿与足、D9;有「词条式释义,不是对你个人的判断」;没有运势句。
12. 大运:Vimshottari 与 Chara Dashakn_rao 变体)并列,当前段高亮。底部有「只有两条同时指向同一段时间才算证据」。不要出现 Narayana 这个名字。
13. 西洋盘:若端点未上线,看到静态说明(回归黄道、不能换算),整页其余 Tab 仍可用。
14. 七政四余:若端点未上线,静态说明里必须有三条——宿度自角宿起算、计都派别、庙旺未闭合。
+2 -2
View File
@@ -6,7 +6,7 @@
1. 登录后点侧栏「星盘」。**大约 1 秒内**能看到页面外壳:返回对话、标题「星盘」。不要整页白屏等到引擎全部算完。
2. 主盘还没到时,等待句是「这一张盘还没拿到。」没有转圈、骨架或「正在加载」。
3. 主盘到达后北印盘立刻可见。出生资料行出现。成功眉标是「主盘直接算 · 分盘按需 · 不消耗点数」,没有「打开即有」
3. 主盘到达后北印盘立刻可见。出生资料行出现。没有眉标,没有「打开即有」,没有「主盘直接算 · 分盘按需 · 不消耗点数」。
## 按需加载
@@ -18,7 +18,7 @@
## 失败文案
9. 失败页没有眉标,没有「打开即有」,没有「过一会儿再打开」。
9. 失败页没有眉标,没有「打开即有」,没有「过一会儿再打开」,也没有「不消耗点数」
10. 若刚好赶上引擎忙(429):「算盘的服务正忙,稍等几秒再打开就好。」稍等再开,有机会好。
11. 其它失败:「这张盘算不出来,我们已经记录下来了。」不要暗示等一会儿就会好。
+1 -1
View File
@@ -21,7 +21,7 @@
2. **看:** 月相日或月宿至少有一项不同。
3. **看:** 五要素下方有一句「这一段按 Lahiri 岁差算,和星盘页用的岁差不是同一套。」
4. **看:** 当日行运段没有这句。
5. **看:** 页面没有任何运势判断(没有「适合 / 不宜 / 运势」这类话)。
5. **看:** 页面没有任何运势判断(没有「适合 / 不宜 / 运势」这类话)。底部没有「这一页是天象本身,不是对你的判断。」
## C. 事件列表降级形态
+5 -5
View File
@@ -732,7 +732,7 @@ Admin 的 antd `<Spin>` 是独立设计系统,不在此表。
### 结构
页名「星盘」与出生资料一行在 `SecondaryHeader` 的 46px 顶栏里(§ Secondary page shell)。顶栏之下第一件东西是 Tab 行,眉标「主盘直接算 · 分盘按需 · 不消耗点数」跟在 Tab 行下方作为一行静默说明。等待外壳和失败页只有原因/等待句,没有眉标。不得写「打开即有」或任何速度承诺
页名「星盘」与出生资料一行在 `SecondaryHeader` 的 46px 顶栏里(§ Secondary page shell)。顶栏之下第一件东西是 Tab 行。不写眉标,不写「打开即有」、不写「主盘直接算 · 分盘按需 · 不消耗点数」,也不承诺打开速度。等待外壳和失败页只有原因/等待句
五个 Tab 按体系分:**星盘 / 基础信息 / 大运 / 西洋盘 / 七政四余**,画成**一条下划线式 Tab 行**:无边框、无卡面,当前项 2px 下划线 + 主文字色,整行一条 1px 底线。行内 `flex-wrap: nowrap` 且自身横向滚动,所以 375px 下它仍是一行,不折行、不换成第二排——底线画在滚动容器自己的 border 上,不会跟着内容滚走。五个等重的药丸按钮会读成五个可按的东西,Tab 行读成「一个控件 + 一个当前位置」。
@@ -762,7 +762,7 @@ Admin 的 antd `<Spin>` 是独立设计系统,不在此表。
- 西洋盘:回归黄道,宫位 Placidus;右栏第一张是边界卡。端点未上线时 Tab 仍在,渲染静态说明,整页不失败。
- 七政四余:宿度自角宿初度起算。必须同时出现计都派别与庙旺未闭合。端点未上线时同样只渲染静态说明。
「传统象征」是词条式释义,带边界句「不是对你个人的判断」,不得写成运势。大运 Tab 底部固定:「只有两条同时指向同一段时间才算证据,单轨命中要降一级来看。」Chara 的正式名称是 **Chara Dashakn_rao 变体)**,不要写成 Narayana。
「传统象征」是词条,不得写成运势。页面上不另写「词条式释义,不是对你个人的判断」——行星卡本身已经是度数、星宿、D9,没有判断句。大运 Tab 底部固定:「只有两条同时指向同一段时间才算证据,单轨命中要降一级来看。」Chara 的正式名称是 **Chara Dashakn_rao 变体)**,不要写成 Narayana。
### 等待态
@@ -780,14 +780,14 @@ Admin 的 antd `<Spin>` 是独立设计系统,不在此表。
独立 route `/ephemeris`。不扣点、不调模型。页面挂在 `app/(secondary)` 共享外壳上(§ Secondary page shell):页名「星历」与「带这天去提问」在 46px 顶栏里,`.ephemeris-body` 是唯一滚动的东西。
- **结构:** 日期条;今日五要素;当日行运;未来九十天;收尾一句。顺序固定。
- **结构:** 日期条;今日五要素;当日行运;未来九十天。顺序固定。页尾不另写定性句
- **日期条:** 居中的 ` 日期 `——日期是主语,两枚 44px 箭头按钮是它的把手。箭头字形 `aria-hidden`,可访问名仍是「前一天」「后一天」,读屏不丢方向。**「今天」只在非今日时出现**,作为日期下方一枚文字按钮;在今日时它整个不渲染,而不是渲染成一枚禁用按钮——灰掉的按钮仍要被读、仍要被 Tab 跳过。原本三个并排等宽按钮把「前一天 / 今天 / 后一天」读成三个平级动作,日期本身反而被挤出了这一组。
- **三段同一套卡片:** 五要素 / 行运 / 未来九十天三个 `.ephemeris-section` 各是一张卡(1px 描边 + `--radius-lg` + `--color-canvas`),卡内是行。原本三段的**内容**各自画框而**段落**不画框,于是三段看起来是三种不同的东西。框归段落,段内只有行。
- 切日期立刻换五要素和行运;没有 spinner、骨架或「正在加载」。数据未到时写静态句「这一天的五要素还没拿到。」「这一天的行运还没拿到。」
- **五要素:** `dl` 网格保留:桌面五格一行(星期、月相日、月宿含第几足、瑜伽、迦那),格子是段落卡内的浅底块,不再各自描边。767px 以下收成五行,标签左、值右。Yoga / Karana 的吉凶只照搬引擎标签(吉 / 中 / 凶),不写成建议。卡片下固定一行:「这一段按 Lahiri 岁差算,和星盘页用的岁差不是同一套。」行运段不加这句。
- **当日行运:** 九曜的星座、度数、相对本命宫位、顺逆。桌面表格,767px 以下每行改成带标签的堆叠。没有本命上升时,相对本命列为空,并写「还没有本命上升,相对本命这一列空着。」
- **未来九十天:** 按日期升序只写事实(「某星 进入 某座」「某星 停滞转顺 · 度数」)。`/api/ephemeris_events` 未上线时整段静态说明:「换座和停滞还没接上。这一页其余部分不受影响。」不得让整页失败。
- **出口:** 收尾句「这一页是天象本身,不是对你的判断。」原文不变,但不再是底部第四张卡——它是页尾一行三级色小字。一句话的卡片跟三张装数据的卡片等重是错的。主按钮「带这天去提问」在顶栏,把当前日期预填进对话草稿并回到 `/`
- **出口:** 主按钮「带这天去提问」在顶栏,把当前日期预填进对话草稿并回到 `/`不写「这一页是天象本身,不是对你的判断。」
- **等待:** 揭幕后不得再出现 spinner / 骨架 / 「正在加载」。未登录是静态「请先登录」加去登录,不是转圈。
- **文案:** 这一页是天象本身。不得写运势结论,不得把三套坐标系换算或叠加。
- **文案:** 不得写运势结论,不得把三套坐标系换算或叠加。不另印「这是天象本身」这类边界说明。
+3 -1
View File
@@ -63,7 +63,9 @@ Jyotisha 的可见文案是产品的一部分。正确性红线(真实性、
| 吻合率低时模型追问要不要把误差放到 ±2 小时 | 按你说的经历,出生时间可能比家人记的偏得更多。放宽后再比一次? | 放宽卡由服务端出,选项写「前后半小时 / 一小时 / 两小时」,不用偏移、误差、置信度、概率。 |
| 只知道傍晚时直接给分钟或采用卡 | 先切成三段(写起止钟点),比完再按分钟收。分不开就说「时段分不开,直接按分钟比」。 | 超过两小时的窗口先走子段,不在 4~6 小时上铺分钟卡。 |
| 记下精确到日的事后不问日子从哪来 | 刚才那个日子是查过记录,还是凭记忆? | 只问日级、只问一次;不答就跳过。 |
| 打开即有 / 直接计算 · 打开即有 · 不消耗点数 | 主盘直接算 · 分盘按需 · 不消耗点数 | 不承诺打开速度。失败页不写眉标。忙(429)说「算盘的服务正忙,稍等几秒再打开就好。」;其它失败说「这张盘算不出来,我们已经记录下来了。」不要说「过一会儿再打开」。 |
| 打开即有 / 直接计算 · 打开即有 · 不消耗点数 / 主盘直接算 · 分盘按需 · 不消耗点数 | (不写) | 星盘页不写成本、速度、计费说明。失败页不写。忙(429)说「算盘的服务正忙,稍等几秒再打开就好。」;其它失败说「这张盘算不出来,我们已经记录下来了。」不要说「过一会儿再打开」。 |
| 下面是词条式释义,不是对你个人的判断。 | (不写) | 基础信息 Tab 只放行星卡。词条本身不得写成运势,但不另印这句边界说明。 |
| 这一页是天象本身,不是对你的判断。 | (不写) | 星历页只放日期、五要素、行运、九十天事件。「带这天去提问」在顶栏。不另印定性句。 |
## 服务端探针 → Agent 题干
+1 -14
View File
@@ -2030,12 +2030,6 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
}
.chart-page-eyebrow {
width: min(1100px, 100%);
margin: 0 auto var(--space-6);
color: var(--color-ink-tertiary);
font-size: var(--type-caption);
}
.chart-page-body,
.ephemeris-body,
.report-center-body,
@@ -4851,8 +4845,7 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
/* ============================================================
Ephemeris page facts only, own scroll (html/body overflow hidden)
============================================================ */.ephemeris-hero,
.ephemeris-section,
.ephemeris-outro{
.ephemeris-section {
width: min(900px, 100%);
margin-inline: auto;
}
@@ -5004,12 +4997,6 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
color: var(--color-ink-tertiary);
font-size: var(--type-caption);
}
.ephemeris-outro {
margin: 0;
padding-bottom: var(--space-4);
color: var(--color-ink-tertiary);
font-size: var(--type-body-sm);
}
.ephemeris-ask { min-height: 44px; width: fit-content; }
.ephemeris-message {
display: flex;
@@ -4,7 +4,6 @@ import { formatDegree } from "./chart-format";
export function ChartBasicsTab({ view }: { view: ChartViewOk }) {
return (
<div className="chart-page-basics">
<p className="chart-page-boundary">{view.vedic.symbolBoundary}</p>
<div className="chart-page-basics-grid">
{view.vedic.planets.map((planet) => (
<article key={planet.name} className="chart-page-planet-card">
@@ -89,11 +89,6 @@ export function ChartPageView({
</button>
))}
</div>
{/* BUG-717 copy: a cost and speed promise that also prints on the
failure page. It used to sit in the hero as an eyebrow; the hero is
gone, the promise is not. It reads under the tab row now, because
the tab row is what the header hands off to. */}
<p className="chart-page-eyebrow">{CHART_VIEW_COPY.eyebrow}</p>
<section className="chart-page-panel" role="tabpanel">
{tab === "vedic" ? (
<ChartVedicTab
@@ -272,11 +272,6 @@ export function EphemerisView(props: {
</ol>
)}
</section>
{/* The closing note used to be a fourth boxed card competing with the
three that carry data. The sentence is unchanged; it is a quiet line
under the page now, and the action lives in the header. */}
<p className="ephemeris-outro">{EPHEMERIS_COPY.footerNote}</p>
</div>
</>
);
-1
View File
@@ -165,7 +165,6 @@ export const chartViewOkSchema = z.object({
boundary: z.string().min(1),
vargas: z.array(chartViewVargaSchema).min(1),
planets: z.array(chartViewPlanetRowSchema).min(1),
symbolBoundary: z.string().min(1),
}),
dasha: z.object({
vimshottari: chartViewDashaTrackSchema,
-3
View File
@@ -140,8 +140,6 @@ export const ANTARDASHA_DERIVED_NOTE = "分运按标准比例从大运边界推
export const CHARA_ANTARDASHA_DATE_NOTE = "分运时长来自引擎的十二等分;起止日期按大运边界推算,不是引擎单独返回的日历字段。";
export const SYMBOL_BOUNDARY = "下面是词条式释义,不是对你个人的判断。";
export const WESTERN_UNAVAILABLE_COPY = "西洋盘这一栏要等回归黄道端点上线。现在还没有,先空着——不会拿印度盘的度数改写成回归黄道。";
export const QIZHENG_UNAVAILABLE_COPY = "七政四余这一栏要等宿度端点上线。现在还没有,先空着。";
@@ -153,7 +151,6 @@ export const QIZHENG_RULES = [
] as const;
export const CHART_VIEW_COPY = {
eyebrow: "主盘直接算 · 分盘按需 · 不消耗点数",
busy: "算盘的服务正忙,稍等几秒再打开就好。",
unavailable: "这张盘算不出来,我们已经记录下来了。",
waitingChart: "这一张盘还没拿到。",
-2
View File
@@ -10,7 +10,6 @@ import {
PLANET_ORDER,
QIZHENG_UNAVAILABLE_COPY,
SIGN_ORDER,
SYMBOL_BOUNDARY,
VARGA_CHIP_ORDER,
VIMSHOTTARI_ORDER,
VIMSHOTTARI_YEARS,
@@ -653,7 +652,6 @@ export function buildChartView(bundle: ChartViewEngineBundle): ChartViewOk {
boundary: COORDINATE_BOUNDARY.vedic,
vargas,
planets: planetRows(chart, varga),
symbolBoundary: SYMBOL_BOUNDARY,
},
dasha: {
vimshottari,
-1
View File
@@ -20,7 +20,6 @@ export const EPHEMERIS_COPY = {
natalMissing: "还没有本命上升,相对本命这一列空着。",
eventsHeading: "未来九十天",
eventsUnavailable: "换座和停滞还没接上。这一页其余部分不受影响。",
footerNote: "这一页是天象本身,不是对你的判断。",
ask: "带这天去提问",
loginTitle: "请先登录",
loginBody: "登录后即可查看星历。",
+13 -6
View File
@@ -83,11 +83,11 @@ test("the five tabs render and can each be selected", async () => {
const view = await okView();
for (const tab of CHART_VIEW_TABS) {
const markup = withSidebarProvider(React.createElement(ChartPageView, { view, initialTab: tab.id }));
// 原值: 直接算 · 打开即有 · 不消耗点数
// 新值: 主盘直接算 · 分盘按需 · 不消耗点数
// 原因: BUG-717 「打开即有」是速度承诺,且印在失败页上
assert.equal(markup.includes(CHART_VIEW_COPY.eyebrow), true);
assert.doesNotMatch(markup, /打开即有/);
// 原值: 成功页必须含「主盘直接算 · 分盘按需 · 不消耗点数」;基础信息含「词条式释义」
// 新值: 成功页与失败页都不写这两句;基础信息只留行星卡
// 原因: 产品 2026-09-17 判定为过度提示,计费/速度说明和「不是对你个人的判断」都不印在页上
assert.doesNotMatch(markup, /chart-page-eyebrow|主盘直接算|分盘按需|不消耗点数|打开即有/);
assert.doesNotMatch(markup, /词条式释义|不是对你个人的判断/);
assert.match(markup, />星盘</);
assert.match(markup, />基础信息</);
assert.match(markup, />大运</);
@@ -95,7 +95,10 @@ test("the five tabs render and can each be selected", async () => {
assert.match(markup, />七政四余</);
assert.doesNotMatch(markup, /正在加载|骨架|spinner/i);
if (tab.id === "vedic") assert.match(markup, /D1/);
if (tab.id === "basics") assert.match(markup, /词条式释义/);
if (tab.id === "basics") {
assert.match(markup, /本命/);
assert.match(markup, /D9/);
}
if (tab.id === "dasha") {
assert.match(markup, /Vimshottari/);
assert.match(markup, /Chara Dashakn_rao 变体)/);
@@ -187,6 +190,10 @@ test("the parameters are one key/value table, not a per-breakpoint duplicate", (
".chart-page-center-extra",
".chart-page-params-below",
".chart-page-boundary-desktop",
// 原值: 这一组不含 .chart-page-eyebrow
// 新值: 成功页眉标已删,该类不得再有 CSS 规则
// 原因: 产品 2026-09-17 去掉「主盘直接算 · 分盘按需 · 不消耗点数」
".chart-page-eyebrow",
]) {
assert.equal(
declaredSelectors(globalStyles).has(dead),
+5 -1
View File
@@ -155,7 +155,11 @@ test("mobile CSS turns five panchanga cards into one stacked card", () => {
test("copy stays factual: no fortune-telling, no spinner, ask prefills the date", () => {
const markup = render(payloadFor("2026-09-15"));
assert.match(markup, new RegExp(EPHEMERIS_COPY.footerNote));
// 原值: 页尾必须含「这一页是天象本身,不是对你的判断。」
// 新值: 页面不得出现该句
// 原因: 产品 2026-09-17 判定为过度提示,与星盘页眉标同一类
assert.doesNotMatch(markup, /天象本身|不是对你的判断/);
assert.doesNotMatch(markup, /ephemeris-outro/);
assert.match(markup, new RegExp(EPHEMERIS_COPY.ask));
assert.match(markup, new RegExp(EPHEMERIS_COPY.previousDay));
assert.match(markup, new RegExp(EPHEMERIS_COPY.nextDay));