diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 6da1bcdb..91a23f10 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -8661,4 +8661,20 @@ - 复发自:无 - 修复版本:`cfcd369d` +## BUG-563 | 报告 MD 详情页在无 IntersectionObserver 时同步 setState,staging 门禁 lint 失败 + +- 状态:resolved +- 首次发现:2026-09-06 +- 最近更新:2026-09-06 +- 影响面:`frontend/src/components/personal-report/personal-report-markdown-view.tsx`、Gitea `backend-quality-gate` run 2446 +- 用户现象:staging 未部署本轮报告 MD 页;门禁 `npm run lint` 1 error 后 `publish`/`deploy-staging` 未跑。站点 `/api/health` 的 `deployment.gitCommit` 仍停在此前 SHA。 +- 触发条件:`LazyMarkdownSection` 在 `IntersectionObserver` 未定义时(SSR / 部分测试环境)于 `useEffect` 内同步 `setVisible(true)`。 +- 根因:react-hooks 编译器规则禁止 effect 内同步 setState,以免级联渲染。仓库红线是 lint 0 error。 +- 修复:无观察器时改为 `requestAnimationFrame` 后再 `setVisible`,并在清理函数里 `cancelAnimationFrame`。SSR 首屏仍只渲染 eager 段。 +- 验证:`npm run lint -- src/components/personal-report/personal-report-markdown-view.tsx` 0 error;`frontend/tests/personal-report-markdown-view.test.ts` 仍断言懒加载段不进 SSR 标记。 +- 防复发:报告 MD 视图 effect 不得同步 setState;后续 lint 0 error 才允许合入 staging。 +- 相关记录:BUG-561、BUG-562 +- 复发自:无 +- 修复版本:待本提交 SHA + diff --git a/docs/tasks/PROGRESS-report-longform-gaps2-20260906.md b/docs/tasks/PROGRESS-report-longform-gaps2-20260906.md index d2fa6afa..e8935ad2 100644 --- a/docs/tasks/PROGRESS-report-longform-gaps2-20260906.md +++ b/docs/tasks/PROGRESS-report-longform-gaps2-20260906.md @@ -1,7 +1,7 @@ # PROGRESS · 长报告对齐二轮 gaps2(2026-09-06) 工作树:`.worktrees/report-md-page-20260906`(与 MD 详情页串行) -分支:`codex/report-md-page-20260906`(已 push `origin`,HEAD `8b140479`;实现主体 `cfcd369d`) +分支:`codex/report-md-page-20260906`(已 push `origin`,HEAD `809bdf13`;实现主体 `cfcd369d`) 任务书:`TASK-report-longform-gaps2-20260906.md` ## 任务 0 根因 @@ -36,4 +36,6 @@ # 22 passed ``` +本 worktree 无独立 `.venv`,实测用父仓解释器。实现已随 `809bdf13` 快进到 `origin/staging`;门禁因 MD 页 lint(BUG-563)未部署,与 gaps2 装配无关。 + 未改 `.gitea/workflows/**`,不提升 main。 diff --git a/docs/tasks/PROGRESS-report-md-page-20260906.md b/docs/tasks/PROGRESS-report-md-page-20260906.md index f507e690..c58098e3 100644 --- a/docs/tasks/PROGRESS-report-md-page-20260906.md +++ b/docs/tasks/PROGRESS-report-md-page-20260906.md @@ -2,8 +2,7 @@ 工作树:`.worktrees/report-md-page-20260906` 分支:`codex/report-md-page-20260906` -远端:`origin/codex/report-md-page-20260906` = `8b140479`(实现 `cfcd369d`) -基线:`origin/staging` `e428e9d0` +基线:`origin/staging` 曾为 `e428e9d0`;第一次快进推送后 tip `809bdf13` 任务书:`TASK-report-md-page-20260906.md`(硬依赖 gaps2,已在同一 worktree 完成) 未改 `.gitea/workflows/**`,不提升 main。 @@ -28,7 +27,8 @@ | MD-only 生成 + 计费 | 完成 | `PERSONAL_REPORT_WRITER_ENABLED=false`;附录失败即报告失败 | | 详情页 TOC/懒渲染 | 完成 | `react-markdown` + `remark-gfm` + `skipHtml`;首屏导航+摘要 | | 导出 / 报告中心 | 完成 | 「导出报告(.md)」;一步式等待文案 | -| 端到端 staging | blocked | staging `/api/health` 仍是 `a444c493`,本分支尚未合入/部署 | +| staging 门禁 | 进行中 | `809bdf13` 已快进到 `origin/staging`;run 2446 `validate` 因 lint 1 error 失败,未部署。BUG-563 修 effect 内同步 setState 后再推。 | +| 端到端 staging | blocked | 需门禁绿且 `/api/health` 的 `deployment.gitCommit` 离开 `a444c493`;无登录态/Chrome | ## 计费适配 @@ -45,11 +45,15 @@ ```text pytest gaps2/timing/parity: 22 passed frontend tsc --noEmit: pass -tsx personal-report-* + professional-reference + polling: 137 passed +tsx personal-report-* + professional-reference + polling: 144 passed +markdown-view eslint: 0 error(修 BUG-563 后) ``` ## 推送 - `cfcd369d` feat(report): render longform Markdown as the report and close gaps2 holes - `8b140479` docs: record BUG-561/562 fix SHA -- 未提升 `main`,未合入 `staging` +- `809bdf13` docs(report): record MD-page push SHA and keep markdown view locks +- `809bdf13` 已 `git push origin HEAD:staging`(`e428e9d0..809bdf13`) +- Gitea [backend-quality-gate #1131 / run 2446](https://git.copse.top/root/Jyotisha/actions/runs/2446) `validate` 失败:`Calling setState synchronously within an effect`(BUG-563) +- 未提升 `main` diff --git a/frontend/src/components/personal-report/personal-report-markdown-view.tsx b/frontend/src/components/personal-report/personal-report-markdown-view.tsx index ae9bc87f..b1a620bf 100644 --- a/frontend/src/components/personal-report/personal-report-markdown-view.tsx +++ b/frontend/src/components/personal-report/personal-report-markdown-view.tsx @@ -77,8 +77,8 @@ function LazyMarkdownSection({ useEffect(() => { if (visible) return; if (typeof IntersectionObserver === "undefined") { - setVisible(true); - return; + const frame = requestAnimationFrame(() => setVisible(true)); + return () => cancelAnimationFrame(frame); } if (!ref.current) return; const observer = new IntersectionObserver((entries) => {