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>
2.7 KiB
2.7 KiB
约束求解器与编辑 API
父任务:.trellis/tasks/08-26-direct-manipulation-road-editor。需求来源与权威合约在父任务的 prd.md / design.md。
目标
把约束解析从几何生成中抽成纯函数边界,并用它同时支撑草稿预览与正式编译;对外提供预览、保存、revision 与 rebase 的服务端能力。本子任务不含任何 UI。
顺序依赖
前置:direct-edit-documents(需要 v2 文档 schema、documentVersion、活动副本与 area config 快照读取)。
后继:direct-edit-map-editor 与 direct-edit-junction-tools 依赖本任务的 handle manifest 与预览 API。
范围
resolveDirectEditConstraints纯函数:输入基线模型 + v1 覆盖 + v2 约束,输出 editable profiles、junction plans、handle manifest、diagnostics。- 6 个约束 kind 的求解;interval 默认范围推导(避开两端 junction reserve);junction reserve 计算。
junction-approach-width对道路 profile 的优先级,以及两域边界的连续过渡。- 约束重放匹配:精确匹配优先,失败才按
anchorSnapshot找候选,产出 5 态ConstraintStatus。 - 端点:
GET /api/edit-state、POST /api/edit-preview、POST /api/edits、POST /api/revisions、POST /api/revisions/:id/rebase。 previewSeq回显、degraded标记、expectedDocumentVersion前置条件与 409。/api/state、/api/session、/api/import的增量字段。
不做
- 任何客户端改动、手柄渲染或拖拽交互。
- cluster 的高级求解(只保证 cluster 不被当成多个普通路口处理)。
- 多人协作的并发合并策略。
验收标准
- 求解是纯函数:无文件写入、无网络调用,可用单元 fixture 直接驱动。
- 无 v2 约束时编译输出与当前 main 逐字节一致(baseline fixture 比对)。
- 6 个 kind 各有重放 fixture;预览与正式编译对同一约束集给出相同几何。
- 违反最小车道宽 2.4m、左右外缘交叉、路口面自交、connector 越界时返回阻塞性诊断而非静默修复。
boundaryIndex越界转stale;锚点缺失转stale;候选歧义或偏差超阈值转conflicted。- 编译器几何版本不一致时约束全部标
recheck,不自动改值也不自动失效。 POST /api/edit-preview调用前后工作区目录内容与 mtime 不变。expectedDocumentVersion不匹配返回 409 且不写入;原子写入中途失败不留半份文件。- rebase 返回各 status 的计数与逐条明细。
- 既有
/api/overrides、/api/compile、/api/state的字段与行为不变。 npm run format:check、npm run test、npm run test:client、npm run build全绿。