# 实施计划 轻量任务,一个提交即可。门禁不过就停。 前置:无。客户端置灰渲染路径已由 `08-26-direct-edit-map-editor` 第 3 步交付并有单测覆盖, 本任务只补服务端输入。 ## 关键决定:置灰只影响手柄,不影响求解 `editable: false` 只改变 handle manifest,**不改变 `solveConstraints()` 的行为**。 落在被置灰 segment 上的既有约束仍然照常应用、照常参与几何编译。 理由:否则本次改动会让升级后的编译静默丢掉用户已保存的编辑——一个 UI 可编辑性的判断 不该回溯否决已持久化的意图。用户想撤销这类编辑,走 undo / 禁用约束的正常路径。 这也让「几何输出逐字节不变」这条验收标准成立,从而使本步骤可安全回滚。 ## 1. 判据与置灰 - 目标:可编辑带短于道路宽度的 segment,其全部 `road-*` 手柄 `editable: false`。 - 位置:`src/compile/direct-edit-solver.js` 的 `makeRoadHandles()`。 该函数已算出 `start` / `end` / `length` / `width`,判据是纯本地计算,不需要新数据。 - 实现要点: - 带长米数 `(end - start) * length`,与 `width`(该 segment 双向宽度之和)比较。 - 复用既有 `baseDisabled` 机制与既有文案「该道路全部位于路口保留区,请进入 JunctionTools 编辑。」, 不新增第二套提示语。 - 保留原 `unavailable` 判断作为兜底,两者取或。 - 被置灰的 segment 仍然产出手柄(位置照旧),只是 `editable: false` 且带 `disabledReason`。 - 不改:`junctionReserves()` 的 0.45 上限、cutback 推导、`solveConstraints()`、junction 手柄。 ## 2. 测试 - 位置:`test/direct-edit-solver.js`。 - 覆盖: - 短路段(带长 < 宽度)的全部 `road-*` 手柄 `editable: false` 且 `disabledReason` 非空。 - 正常路段 `editable: true` 且无 `disabledReason`。 - 判据边界:带长略小于 / 略大于宽度两侧各一例。 - junction 手柄仍 `editable: true`。 - 置灰 segment 上的既有约束仍被求解(`constraintStates` 里 `applied: true`), 证明置灰没有回溯否决已保存编辑。 ## 3. 验证 ```bash npm run test # 含 test/direct-edit-solver.js npm run test:client # 客户端类型 npm run test:client:unit # 客户端纯逻辑 npm run format:check npm run build ``` 几何不变的实测(本任务的核心安全性证明):对 `test/fixtures/fengshu-er-road.osm` 在改动前后各跑一次 `compileGeometry`,比较全部输出图层的 JSON,必须完全一致。 `npm run test` 里的 fixture 基线测试已覆盖这条,若基线有 diff 即为回归。 手测(可选,`directEdit` 开关打开):选中 `test/fixtures` 里那 6 段短路之一, 应看到灰色手柄且 header 显示原因。这是父任务 prd 那条验收标准第一次真正可演示。 ## 4. 门禁 - 几何输出零变化(fixture 基线无 diff)。 - 正常路段行为与当前 main 完全一致。 - 既有约束不因置灰而失效。 ## 回滚点 单文件单函数改动,`git revert` 即可回到当前行为。 客户端不需要任何配合改动,回滚后灰色手柄自然消失,回到「空真」状态。