Files
Jyotisha/docs/tasks/TASK-report-reader-polish-20260929.md
T

91 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK · 报告页打磨(生成入口、到底部、导出、目录、表格、字段文案)· 2026-09-29
> 执行方:coding agent。验收:Claude。
> 分支 `codex/report-reader-polish-20260929`,worktree `.worktrees/report-reader-polish-20260929`,基于 `origin/staging`。
> **串行关系**:本单先做、先合入 staging。`TASK-report-english-edition-20260929.md` 改同一批文件(`report-actions.tsx`、`report-export-drawer.tsx`、`pl9_reader_export.py`),必须基于本单合入后的 staging 开工。
## 0. 基线
- 基线 commit:`origin/staging` = `5febb111`(开工时以实测为准,写进进度记录)。
- 进度记录:`docs/tasks/PROGRESS-report-reader-polish-20260929.md`。
## 1. 事故实证(产品截图 2026-09-29,行号按符号定位)
| # | 现象 | 代码位置 |
|---|---|---|
| P1 | `/reports` 的「生成报告」是标题栏右上角的小描边按钮,空状态里又写「点击'生成完整报告'」,按钮名和文案对不上 | `personal-report-center.tsx` → `PersonalReportCenter` 中的 `<SecondaryPageShell actions={<GeneratePersonalReportButton …/>}>` 与 `.report-center-empty` 段;`generate-personal-report-button.tsx` → `GeneratePersonalReportButton`(`variant="outline" size="sm"`) |
| P2 | 报告详情页没有「到底部」的入口;正文按章节懒渲染,未渲染的章节只占一个 h2 高度,直接 `scrollTo(bottom)` 会停在半路 | `personal-report-markdown-view.tsx` → `LazyMarkdownSection`(IntersectionObserver,`rootMargin: "280px 0px"`) |
| P3 | 导出入口是 ghost 样式、只有图标的按钮,很难发现 | `report-actions.tsx` → `ReportActions`(`size="icon" variant="ghost" aria-label="导出报告"`) |
| P4 | 目录里一级标题(如「强度、关系与 Ashtakavarga 技术页」)和二级标题字号、颜色完全相同,二级只缩进 `--space-3`。一级标题没被选中时,看上去像上一组的子项 | `globals.css` → `.personal-report-toc a`、`.personal-report-toc li[data-level="3"]` |
| P5 | 标题里出现用户看不懂的「字段」:「Birth Chart 星主与状态字段」「Birth Particulars 原版补充字段」「Special Lagnas and Points 原版补充字段」,以及替换表里的 `field_状态 → 字段状态` | `scripts/pl9_reader_export.py`:`'#### p6 Birth Chart 星主与状态字段'`、`'#### p3 Birth Particulars 原版补充字段'`、`'#### p17 Special Lagnas and Points 原版补充字段'`;`_strip_pl9_user_engineering_markers` 末尾的 `text.replace("field_状态", "字段状态")` |
| P6 | 同一张表的「状态」列出现重复:「入旺(入旺)」「落陷(落陷)」「入敌(敌对星座)」。表头 `RL / NL / SL / SS / SB`、`Planet` 用户看不懂 | 同上表的行渲染(`row.get('status')`)经 `_strip_pl9_user_engineering_markers` 的 `glossary_terms` 逐词替换后,括号内外被翻成同一个词。**上游 status 字符串的原始形状由执行方先打印确认再修**,不得猜 |
| P7 | 报告内表格没有任何底色,只有很淡的横线,行与行分不清 | `globals.css` → `.markdown-table th/td`(仅 `border-bottom`);报告页包在 `.personal-report-table-wrap` 里 |
| P8 | 分块导出弹窗只显示字数,不显示文件大小;图盘块里带着整段 SVG,字数和文件大小差得很远 | `report-export-drawer.tsx` → `ReportExportDrawer` 的 `.report-export-count`;`report-export-blocks.ts` → `buildReportExportBlocks`(`chars = Array.from(text).length`,图盘块 text 含 SVG) |
## 2. 根因
都是呈现层的遗漏,不涉及计算:入口放在了标题栏的次要位置;懒渲染没有配套「到底部」;导出做成了只有图标的次要按钮;目录层级只靠 12px 缩进区分;引擎侧的工程词(field、字段)和英文缩写表头直接透给了用户;中文化是逐词替换,没有处理「译文(原文)」译完后两边相同的情况;表格样式沿用了聊天气泡里的极简样式。
## 3. 决策记录(产品 2026-09-29 授权)
1. **生成入口挪进页面主体,按产品图一的布局**:页面上半部分是一块「生成报告」卡片,按钮居中,说明文字放在按钮下方;下半部分是「过往的报告」列表。**标题栏右上角的「生成报告」按钮删除**,不保留两个入口(产品偏好:多余入口宁可删除)。卡片在有报告、没报告时都显示;没报告时,下半部分显示一句轻提示,不再重复一个大空状态。
2. 报告详情页加「到底部」悬浮按钮,位置在右下角。点击时先让所有 `LazyMarkdownSection` 立即渲染,**在同一次点击内**滚到文末。不得出现先停在半路、要再点一次的情况。滚到接近底部时按钮隐藏;可以同时提供「回到顶部」,但**一次只显示一个**按钮。
3. 导出按钮改成带文字的「导出」按钮(带图标、描边或实心,按 `DESIGN.md` 的次级主操作规格),留在操作栏右侧。英文版导出提示**不在本单做**,由英文版任务书负责。
4. 目录:一级标题加粗、用 `--color-ink`,组与组之间留间距;二级标题缩进加大到约 `--space-5`、用 `--color-ink-secondary`。当前项高亮样式不变。
5. 「字段」一词从用户可见标题里全部去掉,用下面的新标题(中文口径对照 `VOICE.md`):
| 原标题 | 新标题 |
|---|---|
| p6 Birth Chart 星主与状态字段 | 行星主星与状态 |
| p3 Birth Particulars 原版补充字段 | 出生资料补充 |
| p17 Special Lagnas and Points 原版补充字段 | 特殊上升与派生点补充 |
| `field_状态 → 字段状态` | 改为「状态」 |
6. 「行星主星与状态」一表的表头改成中文:`Planet → 行星`、`RL → 星座主`、`NL → 星宿主`、`SL → 分主`、`SS → 分分主`、`SB → 力量`。表下加一行小字说明这几个名称的含义,不超过一句。状态列同义重复时只保留一个(「入旺(入旺)」→「入旺」);括号内是不同信息的保留(如「入敌(敌对星座)」要先确认上游原文再决定)。
7. 表格加淡底色,**只作用于报告阅读页和打印**,聊天气泡里的 `.markdown-table` 不动:表头一层淡底,正文隔行一层更淡的底(斑马纹),颜色取现有 token 的 `color-mix`,不新增硬编码色值;深色模式同样适用。打印时底色保留,但要更浅,保证黑白打印可读。
8. 分块导出弹窗显示预估文件大小:取**真实要下载的字节数**,即 `new TextEncoder().encode(joinExportBlocks(selected)).length`,按 KB / MB 取整显示,例如「约 186 KB」。不按字数估算。全篇大小和已选大小都显示。
## 4. 硬红线
1. 不改报告的计算与数值;Python 改动只限 §3-5、§3-6 的标题、表头和状态去重。`report-reader-main-fictional.json` golden 除这几处文案外,逐字节不变(执行方用 diff 证明)。
2. 不新增第二套滚动跟随;「到底部」是报告页自己的按钮,不接入 `useConversationScrollAnchor`。揭幕后不得出现 spinner 或骨架。
3. 不动数据库、不动迁移、不动 `.gitea/`。
4. 改 UI 的同一提交内更新 `frontend/DESIGN.md`(报告中心、报告阅读页、表格三处);新文案对照 `frontend/docs/VOICE.md`。
5. AGENTS §7-8:动类名、文案、组件之前先 `git grep -n "<符号>" -- tests/ frontend/`。至少要查:`GeneratePersonalReportButton`、`report-center-empty`、`还没有个人报告`、`生成完整报告`、`导出报告`、`report-export-count`、`personal-report-toc`、`星主与状态`、`原版补充字段`、`字段状态`、`markdown-table`。被牵连的断言按「原值 / 新值 / 原因」三栏写进进度记录。
## 5. 任务分解
| 编号 | 内容 | 验收标准 |
|---|---|---|
| R1 | 报告中心改版(§3-1) | 标题栏不再有生成按钮;主体上方是生成卡片,下方是「过往的报告」;无报告、有报告、生成中三种状态的截图或组件测试各一份;原按钮的防重复点击、错误提示逻辑不变(`classifyCreateResponse` 测试照过) |
| R2 | 到底部按钮(§3-2) | 组件测试:未渲染章节存在时点击,所有章节变成已渲染,且触发一次滚到底部;接近底部时按钮不显示 |
| R3 | 导出按钮(§3-3) | 按钮有可见文字「导出」;键盘可达;打印时隐藏(沿用 `personal-report-screen-only`) |
| R4 | 目录层级(§3-4) | 一级、二级样式可区分;`DESIGN.md` 写明规格 |
| R5 | 字段文案与表头(§3-5、§3-6) | Python 定向测试断言新标题和新表头;golden 中不再出现「字段」二字,也没有 `X(X)` 形式的同义重复 |
| R6 | 表格底色(§3-7) | 仅报告页生效;聊天页表格的计算样式不变(写一条选择器作用域断言或截图对比) |
| R7 | 导出大小(§3-8) | 单测:选中块的显示大小等于 `TextEncoder` 字节数的格式化结果;含 SVG 的图盘块大小明显大于字数 |
## 6. 让步顺序
时间不够时按这个顺序往后砍:R6 → R4 → R2。R1、R3、R5、R7 必须交付。
## 7. 开工前置命令
```bash
git fetch origin --prune
git worktree add -b codex/report-reader-polish-20260929 .worktrees/report-reader-polish-20260929 origin/staging
cd .worktrees/report-reader-polish-20260929
grep -oE "BUG-[0-9]{4}" docs/BUG_HISTORY.md | sort -u | tail -1 # 核对最大号
cd frontend && npm test 2>&1 | grep -E "^(not )?ok [0-9]+ - " | sed -E 's/^(not )?ok [0-9]+ - //' | sort > /tmp/names-before.txt
```
## 8. BUG 编号
开工时 `BUG_HISTORY.md` 最大号为 BUG-1089,BUG-1090/1091 已被 holdout 任务书预留。本单从 **BUG-1092** 起,预计用到 BUG-1094:P5 + P6 各记一条,P1~P4、P7、P8 合记一条「报告页可用性」。开工时如果号已被占用,顺延,并在进度记录写明。
## 9. 交付
- 推 staging 前:`tsc --noEmit` 0 错;`npm run lint` 0 error;`npm test` 测试名单与开工时对比,只增不减;`npm run build` 后 `/` 仍是 Static;首屏 gzip 在 ±2% 内;`.venv/bin/python -m pytest tests/<相关文件>` 通过;`run_quality_gate.py --profile quick` 通过。
- 真机清单写进 `docs/testing/report-reader-polish-20260929.md`(桌面端、手机端各走一遍 R1~R3、R6)。
- `CHANGELOG.md` 记一条。