Planning: parent design.md becomes the single authoritative contract (constraint model with 6 kinds, handle manifest, coordinate/unit layering, preview sequencing, storage layout and lazy migration, area config snapshot, API contract). Work is split into four independently verifiable child tasks with per-step gates and rollback points. Test infra: pin vitest 4.1.11, add test:client:unit for client pure logic, extend prettier globs to root *.ts so vitest.config.ts is checked. Add .gitignore: the repo had none, so inputs/, outputs/, workbench-data/ and the client build output were untracked rather than ignored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.6 KiB
4.6 KiB
实施计划
对应父任务 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 依赖 2;6 依赖 5 与 direct-edit-documents。第 2 步交付后客户端子任务即可并行开工。