Files
Jyotisha/docs/tasks/TASK-report-language-switch-stale-20260930.md
T

102 lines
6.6 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-30
> 执行方:coding agent。验收:Claude。
> 分支 `codex/report-language-switch-stale-20260930`,worktree `.worktrees/report-language-switch-stale-20260930`,基线 `origin/staging`。
> BUG 编号:**BUG-1126**(Claude 写单时已登记为 investigating;开工时核对 `docs/BUG_HISTORY.md` 最大号,若已被占用顺延并同步改本单)。
> 纯前端改动,不需要 AGENTS §9 预检。
## 0. 基线
- 写单时 `origin/staging` = `da3ed2f3`(staging `/api/health` `deployment.gitCommit` 同为 `da3ed2f3`)。
- 开工前先 `git fetch origin --prune`,以实测 `origin/staging` 为准,写进 `docs/tasks/PROGRESS-report-language-switch-stale-20260930.md`。
## 1. 事故实证
产品 2026-09-30 在 staging 实测,桌面 Dia 与 iPhone 两台设备都能复现:
- 进报告页后点「English」:地址栏会变成 `?lang=en`,开关也显示 English 已选中,但正文、目录(标题仍是「目录」)还是中文版。
- 直接带 `?lang=en` 打开:正文是英文;这时点「中文」,开关会变,正文仍是英文。
- 导出面板里的「中文 / English」和导出的英文文件都正常,说明英文版数据已经完整送到浏览器。
Claude 复现情况(staging 线上 JS + 无头 Chrome;报告接口用虚构出生资料的真实引擎输出替换,也伪造了登录态):
| 响应里有什么 | 点切换后 |
| --- | --- |
| 只有 `longformMarkdown` / `longformMarkdownEn` | 正常:正文区块始终 1 份,目录变 Contents |
| 再加上 `factTables` / `factTablesEn`(真实报告都有) | **复现**:`.personal-report-md-layout` 1 → 2 → 3 份,旧语言那份一直留在最上面;开发版 React 报 `Encountered two children with the same key` |
## 2. 根因
`frontend/src/components/personal-report/personal-report-page.tsx` → `PersonalReportPage` 的 markdown-ready 分支,在 `.personal-report-reader-body` 下同级渲染:
```tsx
<PersonalReportMarkdownView key={shown} … />
{state.calculationCharts && <ReportCalculationCharts … />}
{factTables && <ReportFactTables key={shown} … />}
```
两个同级元素的 key 都是 `shown`("zh" / "en"),发生重复。每次换语言,React 按 key 对齐时旧节点清不掉,旧语言的正文留在页面上,新语言的正文追加到后面,所以读者看到的一直是第一次渲染的那个语言。开关读的是同一个 `shown`,所以只有开关在变。
- 引入提交:`b2ad772e`(英文版上线,两处 `key={shown}` 同时加入)。
- 既有测试没拦住:`frontend/tests/report-english-edition.test.tsx` 只单独测了 `ReportActions`(开关)、`classifyReportEnvelope` 和导出面板,没有把整页连同核对表一起渲染再切换。
**Claude 已验证修复方向**:把两个 key 改成互不相同(例如 `markdown-${shown}` / `facts-${shown}`)后,同一复现环境里切换一次就换成英文、正文区块 1 份、0 个含汉字的章节。验证后已还原,没有提交任何代码。
## 3. 决策记录
1. 产品 2026-09-30 反馈「切换不管用」。修复只动 key,不改英文版的生成、存储、接口,也不改切换的交互。
2. 沿用 `TASK-report-english-edition-20260929.md` 决策 6:切换只换正文、目录、图盘标签、核对表,应用外壳保持中文。本单不推翻任何既有决策。
## 4. 硬红线
1. 只改 `personal-report-page.tsx` 里这两处 key,加测试和记录;不顺手重构阅读页,不动 `PersonalReportMarkdownView` 的懒渲染和保留章节逻辑(BUG-1106~1108)。
2. 不改 `report-english-edition.test.tsx` 的既有断言;如果必须改,写「原值 / 新值 / 原因」三栏。
3. 测试 fixture 用仓库里已有的真实引擎虚构盘 golden(`report-reader-main-fictional*.json`、`report-density-fictional-engine.json`),不手造形状(AGENTS §7-4)。
4. 不动数据库、不升级依赖、不改 workflow。
## 5. 任务分解
### T1 · 去掉重复 key
`PersonalReportMarkdownView` 与 `ReportFactTables` 的 key 改成互不相同,且仍随语言变化(保证换语言时两者都会重新挂载)。同一父级下其他带 key 的子元素一并检查。
验收:`personal-report-page.tsx` 中 `.personal-report-reader-body` 的直接子元素没有重复 key。
### T2 · 整页切换回归测试(先红后绿)
新增测试:渲染 `PersonalReportPage`,mock `fetch` 返回 ready 报告,同时带 `longformMarkdown`、`longformMarkdownEn`、`factTables`、`factTablesEn`(用 golden 组装),然后:
1. 以 `initialLanguage="zh"` 打开 → 点 English → 断言正文区块只有 1 份、目录标题是 Contents、第一个 h2 是英文、正文不含汉字;
2. 再点中文 → 正文区块只有 1 份、目录是「目录」;
3. 以 `initialLanguage="en"` 打开 → 点中文 → 同样断言。
验收:在未修复的基线上这条测试是**红**的(进度记录贴失败输出),修复后是绿的。如果现有测试台(`react-client-lifecycle-test-support`)跑不了整页,说明原因并换可行的方案,不得退回只测组件。
### T3 · 记录
- `docs/BUG_HISTORY.md` 的 BUG-1126 补齐修复、验证、防复发,状态改为 resolved(待部署、真机待产品)。
- `CHANGELOG.md` 加一条:报告阅读页中英切换恢复正常。
- `docs/testing/report-english-edition-20260929.md` 追加一条真机步骤:先中文打开,切 English,再切回中文,每次正文与目录都要跟着变,正文不能出现两份。
- 本单不改 UI 外观,`DESIGN.md` 不用更新。
## 6. 验收口径
- `./node_modules/.bin/tsc --noEmit` 0 错;`npm run lint` 0 error。
- `npm test` 失败清单与基线逐条一致,总数不少于基线加新增条数。
- `next build` 通过,`/` 仍是 Static;首屏 gzip 在 ±2% 内(预期不变)。
- 交付:快进推 `origin/staging`,核对远端 SHA;部署后 `/api/health` 的 `deployment.gitCommit` 等于该提交。
## 7. 让步顺序
时间不够时按这个顺序保:T1 → T2 → T3。T1 和 T2 必须一起交付,不接受只改代码不加回归测试。
## 8. 开工前置命令
```bash
cd /workspace/Jyotisha && git status -sb | head -1
git fetch origin --prune
git worktree add -b codex/report-language-switch-stale-20260930 .worktrees/report-language-switch-stale-20260930 origin/staging
cd .worktrees/report-language-switch-stale-20260930/frontend && npm ci # 各 worktree 需自己装依赖;Node 22 在 /exec-daemon/node
grep -o "BUG-[0-9]\{3,4\}" ../docs/BUG_HISTORY.md | sort -t- -k2 -n | tail -1
```