Files
Jyotisha/docs/tasks/TASK-chart-subject-table-fix-20261022.md
T
Jesse_ChenandClaude Opus 5.5 b662bf59fc docs(tasks): chart subject/table fix brief (agent loop, issue #86 round 1)
nowrap and max-content hit every report table and break print; the other-
person save is a drifted copy of the archive page; a click on the dialog
padding closes the editor and drops edits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
2026-10-22 00:34:24 +08:00

5.7 KiB
Raw Blame History

修复单:星盘页就地编辑 / 人名切换 / 报告行星表(issue #86,第 1 次打回,2026-10-22)

  • 被验提交:885bd5665(分支 codex/chart-subject-table-20261021)
  • 需求:issue #86 正文(无单独任务书)
  • 执行方:Grok(Windows + Docker)。在同一分支上继续,只推这个分支;开工前 git merge origin/staging(不 rebase)。
  • BUG 编号:本分支的 BUG-1404 已被 #85 占用(#85 用 1404~1408,#90 将顺延),合入前 Claude 会统一重编;新增记录从开工时 grep -oE "^## BUG-[0-9]+" docs/BUG_HISTORY.md | sort -u | sort -t- -k2 -n | tail -1 的最大号 +1 起(该文件自 400af57e8 起整段重复,必须 sort -u)。

验收结论(Claude,Linux / Node 22)

项 结论
tsc / lint 0 错;0 error(122 warning,同基线)
前端全量 npm test 5103 条,失败 25,名单与 staging 9812f3173 基线逐名一致;新增 7 条
build / 仍 ○ Static;首屏 gzip 644,589(基线 643,357,+0.19%)
全量 pytest 与基线一致(多出的一条 test_active_rectification_api 是子进程 20 秒超时,负载抖动,与本单无关)
范围 没碰数据库、触发器、page.tsx、侧栏;没有删测试或弱化断言
「+ 添加一个人」满 20 人才隐藏(issue 写 5) 判断正确:线上上限是 20(含本人)。已请产品负责人在 issue 里确认

未通过 3 项,见下。

F1 · 所有报告表格都被强制单行(必修,打印退化)

位置:frontend/src/app/globals.css 的 .personal-report-table-wrap th, .personal-report-table-wrap td(white-space: nowrap; word-break: keep-all)与 table { width: max-content },以及 @media print 里同一组规则(width: max-content !important、white-space: nowrap !important,外层 overflow: visible)。

这些规则作用于报告里的每一张 Markdown 表,不只是行星表。瑜伽「作用说明」、主题「建议 / 说明」这类整句的表,屏幕上每格变成一条很长的横滑单行;打印时表格按内容撑宽、外层不裁切,宽表直接跑出 A4 纸。issue 要求「打印 / 导出的样式不能退化」,这里退化了(同类教训:BUG-153 打印测试须覆盖无滚动容器的宽表)。

修法:

  1. 只让短数值 / 名称列不断行。推荐:report-table-reading.ts 识别出行星位置这类数值表(按表头,如含「速度 / Speed / 度数」等),给该表加一个类(例如 personal-report-table-numeric),nowrap 与 max-content 只挂在这个类上;其他表恢复原来的自动换行。
  2. 打印:所有表 width: 100%、单元格可换行;数值表在打印里也允许换行(纸上没有横滑)。
  3. 测试:渲染一份含「行星原始位置」表和一张整句说明表的报告,断言数值表带新类、说明表不带;CSS 合同测试断言 nowrap 只出现在新类的选择器下,打印块里没有 max-content 与 nowrap。

F2 · 「他人」保存逻辑是复制的,已经和档案页分叉(必修)

位置:frontend/src/components/chart-page/chart-birth-editor.tsx 的保存函数,对他人直接 fetch PUT /api/chart-profiles/:id,与 frontend/src/components/people/people-page.tsx 的 saveOther 是两份代码。已经分叉:编辑器保存他人后清了星盘 / 星历缓存,档案页的 saveOther 没清——档案页改完别人,再去星盘页仍是旧盘。(本人一路已经共用 lib/self-profile-save.ts,是对的。)

修法:把「保存他人」抽成 frontend/src/lib/ 下的一个函数(请求、409 reported_birth_time_is_immutable 等错误映射、保存成功后的缓存清理都在里面),编辑器与档案页都调它。档案页因此也补上缓存清理,在 BUG 记录里写明这是顺带修复的旧缺陷。

测试:两处调用同一个函数(源码断言或注入替身);档案页保存他人后 invalidateChartPage / invalidateEphemerisPage 被调用。

F3 · 点编辑框内边距会关掉编辑框、丢失未保存的修改(必修)

位置:同文件 <dialog onClick> 里的 if (event.target === event.currentTarget) onClose();。.chart-birth-dialog 有 padding: var(--space-5),点在内边距上、或在输入框里拖选文字松手落在内边距上,事件目标都是 dialog 本身,于是关闭并丢掉已填内容。

修法(二选一):内容包一层内部容器、内边距挪到容器上,dialog 自身不留可点的内边距;或按点击坐标判断是否落在 dialog 矩形之外才关闭。Esc 关闭保持现状(已正确)。

测试:模拟点击 dialog 内边距(目标是 dialog、坐标在矩形内)不关闭;点击遮罩(坐标在矩形外)关闭。

顺手改(小)

  • 测试文件 frontend/tests/issue-86-chart-subject-table.test.tsx 改名为按内容命名(例如 chart-birth-editor-and-report-table.test.tsx),仓库里没有按 issue 号命名的测试文件。
  • 他人锁定出生时间时,「填报的出生时间保存后不能再改」在表单说明里与锁定提示各出现一次,留一处即可。

交回前必跑

tsc --noEmit、npm run lint、改到的前端测试文件(含 chart-page-view.test.tsx、改名后的本单测试、档案页相关测试、CSS 合同测试)、pytest tests/test_report_chart_blank_columns.py。全量 npm test、build、gzip 由 Claude 验收时跑。

让步顺序

F1、F2、F3 都不可让步。F1 若「按表头识别数值表」不稳,可以退一步:nowrap 只给数字单元格(内容全是数字 / 度数 / 符号的格),整句单元格一律可换行;但打印那一条(width:100%、可换行)不让。