Appearance
ADR-240: 代码重复审计与双源消除 —— canvasToBase64 去重 / applyWindToParticles 空壳处置 / 工作区垃圾清理
状态: ✅ 已实施(2026-08-03 完成;P1 清理 + P2 双源消除 + P3 空壳删除落地,P4 暂缓) 日期: 2026-08-03
编号: 240
关联: ADR-191(core/utils 神桶下沉、零依赖叶纪律——本次为补漏执行)、ADR-017(A2-04 toBlob 异步编码——scene-menu 私有复制实现即其产物,去重不改行为)
来源: 2026-08-03 全仓重复代码审计(646 个 TS 文件 / 15.5 万行):重名函数扫描 + 双源 diff 校验 + 调用面核验。
决策者: Riku(联邦首席架构师 AI)、Jieling(人类侧首席架构师)
创建日期: 2026-08-03
1. 背景:审计发现三类可处置项
按 AGENTS.md「显著重复」标准(相似逻辑 ≥2 文件出现应抽取,UI builder 纯布局除外)全仓盘查:
| 级别 | 位置 | 事实(实测) |
|---|---|---|
| 🔴 P1 | frontend/src/_reach*.cjs ×7、base_export/(7.6M) | 一次性探查脚本 + 误导出目录,全部未跟踪,迟早误提交 |
| 🟠 P2 | menus/scene-menu.ts:39 vs core/image.ts:13 | 私有 canvasToBase64 与 ADR-191 下沉的零依赖叶逐字等价(diff 仅 FileReader 分支 if/else vs 三元风格漂移)——双源隐患:单侧修复即分叉 |
| 🟡 P3 | scene/env/env.ts:108 applyWindToParticles | 与 env-particles.ts:826 真实实现(ps: ParticleSystem)同名空壳(_wind: {x,y,z}),正文为空——实测无任何外部调用,纯误导性占位 |
| 🟢 P4 | menus/model-preset.ts:353 vs menus/preset-list-viewer.ts:156 双 buildPresetListLevel | 同名不同义(无参专用 vs 泛型通用),导出名冲突易误用 |
| ✅ 合法 | env.ts 门面、camera.ts↔camera-state.ts、lipsync-bridge.ts↔perception.ts、core/path.ts↔library/library-path.ts(computeLibraryRef 包装器)、测试 mock 重名 | 均为刻意分层/适配器(注释明示),不合并——保持现状 |
非重复澄清:canUndo/buildLevel/getScene/setter 双份(setCameraControl/setFov/setLipSyncEnabled 等)均为同名不同义或状态层/行为层分层,非逻辑重复,不动。
2. 决策
- P1 清理:删除
_reach*.cjs×7 与base_export/;.gitignore加base_export,防再犯。 - P2 双源消除:
scene-menu.ts删除私有canvasToBase64,改import { canvasToBase64 } from '@/core/image'(ar-camera.ts/thumbnail-capture.ts已如此导入,签名一致,行为不变)。 - P3 空壳删除:删除
env.ts:108的applyWindToParticles空壳——无调用方,且与env-particles.ts真实实现重名构成陷阱(从@/scene/env导入会拿到空壳);真实风力路径在env-particles.ts内部自洽。 - P4 暂缓:
buildPresetListLevel改名(如buildModelPresetLevel)收益低、波及两文件引用,记录为后续可选,本次不执行。
3. 风险与对策
| 级别 | 风险 | 对策 |
|---|---|---|
| 🟡 P2 | scene-menu 改导入后签名/行为不一致 | 两版本函数体已 diff 确认等价;改完跑 scene-menu 相关单测 + tsc --noEmit |
| 🟡 P3 | 空壳删除后若有隐藏调用方(字符串引用/动态导入) | 全仓 grep applyWindToParticles 核验仅 env-particles 内部 + env.ts 定义,无第三方引用;改后 npm run check:consumers -- applyWindToParticles 复核 |
| 🟢 P3 | 清理误删用户进行中的测试文件 | model-preset.pbr.test.ts 等未跟踪测试文件不清理,仅清 _reach*.cjs/base_export/ 明确垃圾 |
4. 实施步骤
- P1:
rm _reach*.cjs+rm -rf base_export+.gitignore追加base_export - P2:
scene-menu.ts顶部加import { canvasToBase64 } from '@/core/image',删除 39-69 行私有实现(两处调用点不动) - P3:
env.ts删除 108-110 行空壳(env-particles.ts真实实现不动) - 验证:
npm run check(tsc)+ scene-menu/env 相关单测 - 同步:
npm run gen:status+npm run gen:docsindex+npm run check:docs - 提交:仅 add 本次认领文件(ADR + scene-menu.ts + env.ts + .gitignore),不碰用户进行中文件