Validate on Linux Node 22 and PostgreSQL 17: 3894 frontend tests and 64 database tests pass, with no removed test names or new failures. Preserve static Home, bounded gzip, assertion-change records and manual acceptance gaps. Co-Authored-By: Claude Code <noreply@anthropic.com>
9.9 KiB
PROGRESS · 西洋盘避让与移动端点击修复(2026-09-25)
最终整合复验补记
组合快照 final-r4b 已在 Linux Node22.23.2 / PostgreSQL17 验证:前端3894/3894、DB64/64,fail/skip/cancel/todo均0;tsc/lint/build各exit0,lint0error/127既有warning,首页Static。顶层及嵌套旧测试名无删除、新增失败0;完整首屏/入口增量/专属JS gzip分别+0.1612%/−0.4536%/−0.7984%。完整日志与快照hash见 PROGRESS-three-fixes-integration-20260925.md final-r4b节。
下文执行期状态保留作历史。组件几何/字符命中证据不冒充受控登录、整页移动端、真实Tab/读屏或部署验收;这些缺口保留,BUG-1033不提前resolved。
状态与范围
本地实现和组件级验证完成,集成全量/独立复核/登录整页/部署待验收;未提交、未推送。BUG-1033由协调方分配(people预留1031/1032)。
- 工作树:
.worktrees/chart-western-fix-20260925;分支:codex/chart-western-fix-20260925。 - 实际开工基线:
48fe4daf519dab2a5c6bf4b01dd513067de1647b,不是任务书早先的fabe0114。 - 规格校正:任务书所写
frontend/src/lib/western-wheel-layout.ts不存在;实际文件是frontend/src/components/chart-page/western-wheel-layout.ts,协调方已确认。 - 只改Western布局/SVG、测试/golden及文档。无引擎/API/people/报告业务修改,无依赖升级、workflow/main/DNS/stash操作。
- 用户硬门槛:必须用Node22跑全量测试,并和开工时的基线逐条对比,新增失败为0才允许推送;改任何既有断言必须原值/新值/原因三栏。 本单不以定向通过代替此门槛。
决策与实现
D1 固定锚点,行星让位
保留ASC/MC的r162和+9°位置,共用同一坐标函数用于绘制与障碍盒。星座名和宫号亦作固定障碍。行星先保持既有11°松弛,再按距离代价搜索两层半径188/136及邻近角度,要求文字盒不交、完整在viewBox内、显示角仍至少11°、圆心距离大于命中半径+1。保留真实黄经用于刻度与引导线,未更改任何引擎数值。
独立复核发现真实窄宫的宫号互碰,因此最终不再豁免house-house:宫号保留真实宫中角度,默认r84,拥挤才径向尝试108/60/132/36。原golden仍全部r84,其既有半径断言未改。所有真实扫描样本保留,所有标签对均检查。
D2 扫描而非单一幸运样本
- 固定种子20260925、LCG的512张几何压力盘:ASC附近、MC附近、全周均匀随机三类,均匀宫头仅用于几何压力测试,不冒充引擎合同。
- 64张真实Swiss引擎虚构盘:保留原始响应及真实非均匀宫头,纬度±55°,无样本过滤。
MAX_OVERLAPPING_CHART_RATE=0.01,并对固定回归集合额外断言实际重叠盘数为0。- 渲染后读取实际inline字号,检查完整37个标签(11行星+26其他)、全部标签盒、边界;骨架和相位常显合同保留。
D3 按实际盘宽与真实字体验收
| 指标 | 原值 | 最终值 |
|---|---|---|
| 375px页面盘宽 | 忽略左右页边距 | 375−16×2=343px |
| 字号 | 17×343/520=11.21px | 19×343/520=12.53px |
| 透明圆直径 | 44×343/520=29.02px | 68×343/520=44.85px |
| 基线/符号字框 | middle / 约1em估算 | central / 符号2.2em,普通1.4em |
| 点击归属 | 同组圆/线按行星顺序覆盖 | 所有按钮圆先画,所有文字后画;逐字符归属自身 |
真实本地Noto Symbols的文本盒约2.07em高,因此不能只按font-size估高。装饰引导线和刻度pointerEvents=none。可见文字层pointerEvents=bounding-box、点击同一回调,aria-hidden且无tabIndex;原透明圆组保留唯一键盘按钮/aria-pressed/标签,未产生重复Tab项。
D4 原始golden及陈旧文档
原Western fixture从视图键子集改为完整build_tropical_natal_from_request返回对象,测试内mapper转换。另存64份完整原始响应。仅JSON格式化及LF换行,无键值改造。BUG-1025与首页拆分CHANGELOG按历史行为→当前/people跳转更正,不抹掉历史。
失败探索与复核账本
- 初版估算几何扫描过,但Chrome65盘发现462对字框相交、7个中心命中错误。真实字体高度和middle基线导致漏算,后画装饰线也拦点击。修正字框/central/装饰线后65盘均0。
- 高字框暴露512样本中的7个行星-宫号冲突;把实际宫号盒加入障碍后消除,不缩字。
- 曾试
asc + offset*30 + skew*sin(offset*pi/6)任意非均匀宫头,发现大量宫号互碰;这种生成器不是物理盘,未列正式引擎集。没有据此把全部验证换成均匀宫头:另补64张真实引擎完整响应。 - 真实64盘初次Chrome有5对宫号互碰(2盘)。最初新测试临时跳过house-house;独立复核指出任务书要求任意标签,最终撤销例外并实现仅径向宫号避让。同样64盘保留,最终宫号碰撞0。
- 独立复核指出只保护中心仍不够:真实扫描索引8/23/33/53/60可见文字末字符被邻星r34圆吞掉。改为先所有命中圆、后所有文字;逐字符
getExtentOfChar中心elementFromPoint验证纳入可复跑脚本,最终0错误。没有把r34退回22来消红。 git diff --check首次报生成JSON的CRLF空白,统一为LF后复核;不改变raw数据。
既有断言三栏
原有3个Western测试名称、断言表达式和chart-page-view原21项均未删除/替换。即便仅间接改变夹具或盒语义,也按三栏留账:
| 原值 | 新值 | 原因 |
|---|---|---|
| fixture为手工视图数组/键,测试直接读 | 完整引擎raw对象,测试内mapper构造视图 | AGENTS §7.4真实合同;11行星/12宫头真实值保留 |
westernLabelBox默认font17、高约1em |
font19、符号2.2em/普通1.4em | 修正真实字体与343px缩放;盒更大是收紧检查,不是降容差 |
| 单盘两两不交、11°、宫中角度/r84、骨架3圈12线无文字 | 原断言原样保留;追加512压力盘与64真实盘全标签扫描 | 提升覆盖,不删除幸运单盘合同 |
| 本轮新真实扫描草稿暂排除house-house | 最终取消排除,检查全部标签对,阈值≤1%且固定集必须0 | 独立复核纠正范围;宫号径向避让而非豁免失败 |
| 本轮新点击测试最初仅检查圆心 | 追加全部命中圆早于文字、唯一按钮数、装饰线不拦事件;Chrome逐字符hit-test | 独立审查发现可见字末尾被邻圆截获 |
本地验证
运行时:Windows、Node v22.23.2、Python3.11.7;依赖复用已有node_modules目录junction,未安装或升级。Linux全量由协调方独立执行。
| 检查 | 结果 | 边界 |
|---|---|---|
npx tsx --test tests/western-wheel-layout.test.ts tests/chart-page-view.test.tsx |
28/28,fail0 skip0 | 原24项保留,新增4项 |
npx tsc --noEmit |
exit0 | 本地 |
npm run lint |
0 error / 127 warning | 既有无关警告,不顺手修 |
| 512压力盘 | 全标签碰撞0 | 固定种子几何,不是引擎响应 |
| 64真实引擎盘 | 全标签碰撞0 | 不过滤样本,不排除house-house |
| Chrome129盘实际字体 | 碰撞0、宫号碰撞0、圆心与逐字符命中错误0 | 65真实含原golden +64压力;343px盘宽 |
| Chrome实测 | 最小字12.53269px、命中直径44.85382px | 独立组件,不是登录页 |
| LinuxNode22开工基线(协调方回报) | 3863/3863,fail0 skip0;DB61/61,tsc0 | 最终集成仍须名称逐条比较,不能用旧Node20失败豁免 |
| Linux最终全量/build/Static/gzip | 待协调验收 | 未声称通过;不得推送 |
| 登录页面/键盘/点选取消/部署health | 待验 | 见BLOCKED与真人清单 |
额外pre_work_check.py --remote-timeout 8 --command-timeout 45结果fail:test_preflight_fragment_scan_reports_authority_layers_and_risk_buckets在tests/test_preflight_fragment_scan.py:64要求.workbuddy/skills/jyotish-vedic-astrology镜像命中,但独立worktree无该镜像;Python运行、外部适配、远端可见性和其余扫描项通过。未修改Python生产文件或该断言;此失败不豁免前端门禁。
复跑原始响应
仓库根目录运行;输入均为明确虚构的测试数据,不来自真实用户:
import json, random, sys
from pathlib import Path
sys.path.insert(0, 'scripts')
from western_chart_engine import build_tropical_natal_from_request
out = Path('frontend/tests/fixtures')
one = build_tropical_natal_from_request(dict(
year=1990, month=1, day=1, hour=12, minute=0,
lat=39.9042, lon=116.4074, tz=8, house_system='P'))
r = random.Random(20260925)
scan = [build_tropical_natal_from_request(dict(
year=1970+i%45, month=1+i%12, day=1+i%27,
hour=i%24, minute=(i*13)%60,
lat=r.uniform(-55,55), lon=r.uniform(-180,180), tz=0,
house_system='P')) for i in range(64)]
for name, value in [('western-1990-01-01-beijing.json', one),
('western-fictional-scan-20260925.json', scan)]:
(out/name).write_bytes((json.dumps(value, ensure_ascii=False, indent=2)+'\n').encode())
复跑浏览器证据
artifacts/western-browser-check.tsx读取实际组件、globals.css和本地Noto字体,生成HTML,不接网络或用户数据。脚本及artifacts/western-browser-result.json作为复跑证据;生成HTML、Chrome profile、stderr和其他审查临时文件不纳入交付清单。
cd frontend
NODE_PATH="$PWD/node_modules" npx tsx ../artifacts/western-browser-check.tsx
# Chrome路径按本机安装调整,使用新建的专用临时profile,不借用登录profile
chrome --headless --no-first-run --disable-gpu \
--user-data-dir=/tmp/western-check-profile --window-size=375,850 \
--virtual-time-budget=10000 --dump-dom \
file:///absolute/worktree/artifacts/western-browser-check.html
等待字体就绪后#result必须charts129、collisions[]、houseOnlyCollisions[]、hits[]。页面交互、选择/取消及键盘需另按docs/testing/chart-dasha-western-20260924.md在受控登录环境执行。