Files
road-compiler/.trellis/tasks/archive/2026-08/08-26-direct-edit-solver-api/implement.md

58 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实施计划
对应父任务 `implement.md` 的第 4、5 步。每步一个提交,门禁不过就停。
前置:`direct-edit-documents` 已交付v2 文档 schema、活动副本、area config 快照可读)。
## 1. 求解器骨架与恒等性
- 目标:插入 `resolveDirectEditConstraints` 阶段,且在无 v2 约束时是恒等变换。
- 范围:`src/compile/` 新增纯函数模块;在 `compileGeometry()` 前接入;输出 editable profiles、junction plans、handle manifest、diagnostics 四件套的空实现。
- 验证:`npm run test`,与 `direct-edit-documents` 建立的快照逐字节比对无差异。
- 门禁:无 v2 约束时编译输出与快照完全一致。这条不过不许继续。快照必须是 `direct-edit-documents` 从当前 main 重新生成的那份,不是仓库原有的过期 `test/baseline/*.json`
- 回滚点:恒等变换,可安全单独 revert。
## 2. junction reserve 与 handle manifest
- 目标:先产出"能拖什么、不能拖什么",为客户端解锁并行开发。
- 范围junction reserve 计算6 个 kind 的 handle 生成,含 `position``axisAzimuth``value.min/max``affects``editable``disabledReason`
- 验证:`npm run test` 新增 fixture——reserve 内的道路 handle 一律 `editable: false` 且带原因;`affects` 覆盖道路面、步行带、车道线、标线与 connector`axisAzimuth` 与道路法线/切线方向一致。
- 门禁manifest 字段与父任务 `design.md`「Handle manifest」逐字段一致客户端可据此开工。
- 回滚点:纯新增返回值,无调用方时 revert 无影响。
## 3. 六个 kind 的求解与不变量
- 目标:约束真正改变几何,且违规时给阻塞性诊断。
- 范围:`road-edge-offset``road-sidewalk-width``road-lane-divider``junction-approach-width``junction-cutback``junction-corner-radius`interval 默认范围推导(避开两端 reserve`smoothstep` 过渡;`junction-approach-width` 优先级与两域边界连续。
- 验证:`npm run test` 新增 fixture——每个 kind 一条重放用例;最小车道宽 2.4m、左右外缘不交叉、道路/路口连续、路口面不自交、connector 包含性各一条违规用例返回阻塞诊断。
- 门禁:违规一律诊断,绝不静默修复或钳制到合法值。
- 回滚点:按 kind 分批提交,可单独回退某个 kind。
## 4. 重放匹配与状态机
- 目标OSM 重导入后约束的 5 态分类可靠。
- 范围:精确匹配(`roadId` / `segmentId` / `nodeId`)优先;失败才用 `anchorSnapshot` 的 OSM node、距离与切线找候选编译器版本不一致时全部标 `recheck`
- 验证:`npm run test` 新增 fixture——同一 OSM 全 `exact`;删掉某条道路后相关约束 `stale``boundaryIndex` 越界 `stale`;候选歧义或偏差超阈值 `conflicted`;版本变化全 `recheck` 且值未变。
- 门禁:`pending` / `conflicted` / `stale` 一律不进入求解,不存在静默模糊应用的路径。
- 回滚点匹配模块独立revert 后退回仅精确匹配。
## 5. 只读端点
- 目标:先上无写入风险的两个端点。
- 范围:`GET /api/edit-state``POST /api/edit-preview``previewSeq` 回显、`degraded` 标记;复用现有请求体读取与 `sendJson`
- 验证:`npm run test` 新增 server integration——预览调用前后工作区目录内容与 mtime 不变;`previewSeq` 原样回显;预览与正式编译对同一约束集给出相同几何;超预算时 `degraded: true` 而非报错。
- 门禁:预览零写入,有测试证明。
- 回滚点新增路由revert 后其余端点不受影响。
## 6. 写入端点与并发保护
- 目标保存、revision 与 rebase 落地,并挡住多标签页覆盖。
- 范围:`POST /api/edits`(要求 `expectedDocumentVersion`)、`POST /api/revisions``POST /api/revisions/:id/rebase``/api/state``/api/session``/api/import` 增量字段。
- 验证:`npm run test` 新增 server integration——版本不匹配返回 409 且不写入原子写入中途失败不留半份文件rebase 返回各 status 计数与明细;`/api/import` 成功后返回基线 revision id既有 `/api/overrides``/api/compile``/api/state` 字段与行为不变。
- 门禁409 路径与原子失败路径都有测试覆盖;既有端点无回归。
- 回滚点写入端点独立revert 后回到只读预览。
## 步骤依赖
1 → 2 → 3 硬顺序4 可与 3 并行5 依赖 26 依赖 5 与 `direct-edit-documents`。第 2 步交付后客户端子任务即可并行开工。