|
- {
- "generatedAt": "2026-09-06T10:36:39.541Z",
- "overall": "PASS",
- "finalRun": true,
- "finalArtifactsVerified": true,
- "featureCount": {
- "total": 119,
- "pass": 119,
- "fail": 0,
- "pending": 0
- },
- "featureKinds": {
- "browser": 112,
- "focused": 7
- },
- "e2eCount": {
- "total": 33,
- "pass": 33,
- "fail": 0,
- "pending": 0
- },
- "validationTotals": [
- {
- "kind": "构建与类型检查",
- "checks": 1,
- "passedChecks": 1,
- "tests": 0,
- "passedTests": 0
- },
- {
- "kind": "后端构建与测试",
- "checks": 1,
- "passedChecks": 1,
- "tests": 373,
- "passedTests": 373
- },
- {
- "kind": "Node 合同与单元",
- "checks": 2,
- "passedChecks": 2,
- "tests": 138,
- "passedTests": 138
- }
- ],
- "cleanupCount": {
- "projects": 167,
- "projectsRemoved": 167,
- "originals": 4,
- "originalsUnchanged": 4,
- "users": 28,
- "usersRemoved": 28,
- "roles": 34,
- "rolesRemoved": 34
- },
- "unknownIds": [],
- "missing": [],
- "malformed": [],
- "features": [
- {
- "id": "project.load",
- "group": "工程入口与顶部命令",
- "name": "按真实项目 ID 打开已存场景",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "async function loadProject",
- "line": 547
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "服务端 content 与版本是真值;不得以模板种子覆盖有效旧工程。",
- "acceptance": "独立新会话打开,真实模型可见、固定版本及对象字段一致。",
- "fix": "新实例部件 sceneId 包含所属根对象身份,不再直接复用来源模型部件 ID;源 interaction/editor 标识保留。旧单实例 ID 保留,旧文档重复 ID 仅按文档顺序迁移后续冲突实例并同步 override。第二完整轮进一步发现 GLB 并发完成顺序会改变根对象顺序;现等待 allSettled 成功后按原文档顺序排列恢复根对象,拆分模板返回数组内部顺序和既有对象均保留,同源两实例不再随网速互换列表位置。新增延迟 30/1/10ms 乱序加载合同,验证序列化仍按文档顺序;最终浏览器验证独立记录。",
- "fixIds": [
- "SCENE-F18"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "successful parallel restores retain document order after delayed GLBs and split-object batches finish out of order",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "project.load",
- "selection.tree"
- ],
- "file": "validation.json",
- "title": "successful parallel restores retain document order after delayed GLBs and split-object batches finish out of order",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.retry",
- "group": "工程入口与顶部命令",
- "name": "项目或挂载加载失败后重新加载",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "mountError",
- "line": 76
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "错误详情自动消退,保留中性失败状态与重试按钮。",
- "acceptance": "注入加载失败;无可写半场景;恢复网络后按钮重试成功。",
- "fix": "前端目录和资源解析同时匹配指定项目、版本、code、id、URI、READY MODEL_FILE;错误引用不回退首文件或本地缓存。仅含 sourceAssetId/assetId 的本项目资源也必须将 ID 纳入缓存/去重键,防止已缓存有效引用掩盖另一个错误ID;失败请求缓存可重试。复制场景保留旧伪 URI 但只读取当前副本资产。",
- "fixIds": [
- "SCENE-F12"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "加载失败重试与加载互斥:不展示可写半场景、恢复网络后模型完整加载",
- "recordedAt": "2026-09-06T10:24:14.518Z",
- "kind": "browser",
- "ids": [
- "project.retry",
- "glb.pending",
- "leave.busy"
- ],
- "file": "evidence/loading-retry.json",
- "title": "加载失败重试与加载互斥:不展示可写半场景、恢复网络后模型完整加载",
- "details": "GET503只留中性失败和重试;延迟受控下载时禁用写入/导出/预览并阻止关闭,释放后真实狐狸加载。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "a failed fixed-version lookup is evicted and the same reference can be retried",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "project.retry"
- ],
- "file": "validation.json",
- "title": "a failed fixed-version lookup is evicted and the same reference can be retried",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.title",
- "group": "工程入口与顶部命令",
- "name": "当前场景名称与项目说明按钮",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "project: () => this.toast",
- "line": 599
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有标题显示服务端名称;说明按钮不是重命名输入框。",
- "acceptance": "长名称完整 title 正确;点击说明反映内容 API 管理。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.new",
- "group": "工程入口与顶部命令",
- "name": "顶部新建独立工程",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "new: () =>",
- "line": 575
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "基线代码重置当前模板;本轮由宿主接真实创建 API,必须保留原项目。",
- "acceptance": "取消/失败不清原工程;成功新 ID;保存重开与列表对应。",
- "fix": "顶部新建委托宿主命名与创建 API,先确认未保存内容。选择放弃也要等创建及导航成功后才清除原 dirty/恢复稿;创建503仍保留原稿。成功后刷新原缓存页,避免再次打开时将已放弃修改冒称已保存。取消、失败不清原场景,成功导航到新项目 ID,并有创建并发守卫。",
- "fixIds": [
- "SCENE-F02"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "新建独立场景:取消、失败、保护原工程以及成功新 ID",
- "recordedAt": "2026-09-06T10:30:58.245Z",
- "kind": "browser",
- "ids": [
- "project.new"
- ],
- "file": "evidence/new-project.json",
- "title": "新建独立场景:取消、失败、保护原工程以及成功新 ID",
- "details": "取消命名、创建503保留原工程、创建成功新ID、保存刷新与原工程内容核对。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.back",
- "group": "工程入口与顶部命令",
- "name": "返回场景制作列表并保留场景标签",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "back: () =>",
- "line": 598
- },
- "implementation": "已有实现已完成验证",
- "boundary": "平台约定返回列表等同切换标签,保留场景缓存和未存稿,不弹关闭确认;真正关闭标签才询问。",
- "acceptance": "未存状态返回列表不写服务器、不丢场景;重新点原标签恢复输入和选择。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.save",
- "group": "工程入口与顶部命令",
- "name": "保存草稿按钮",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async saveProject()",
- "line": 1874
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "只有服务器保存完成才显示成功;本地恢复缓冲不是自动入库。",
- "acceptance": "编辑后真实 PUT,刷新值一致,version 前进一次。",
- "fix": "完整 PUT 回写原有相同 SCENE_MODEL 三元组时沿用场景授权边界;新增或改版依赖仍要求来源模型可见及范围权限,不扩大模型页面访问权。",
- "fixIds": [
- "SCENE-F14"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "recordedAt": "2026-09-06T10:24:27.147Z",
- "kind": "browser",
- "ids": [
- "project.concurrent-save",
- "project.save",
- "project.save-key",
- "recovery.autobuffer",
- "recovery.same-version"
- ],
- "file": "evidence/save-concurrency.json",
- "title": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "details": "延迟真实PUT快照A、重复Ctrl+S不重复请求、期间编辑B仍dirty;再次保存刷新无旧恢复稿误报。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "recordedAt": "2026-09-06T10:25:56.822Z",
- "kind": "browser",
- "ids": [
- "recovery.multi-session",
- "recovery.autobuffer",
- "recovery.discard",
- "project.save"
- ],
- "file": "evidence/scene-multi-session.json",
- "title": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "details": "",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.save-key",
- "group": "工程入口与顶部命令",
- "name": "Ctrl/Meta+S 保存快捷键",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleKeyboard(event)",
- "line": 469
- },
- "implementation": "已有实现已完成验证",
- "boundary": "键盘与按钮走相同保存/权限/忙碌守卫。",
- "acceptance": "实际按键触发一次保存;表单内与非表单焦点分别核查。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "recordedAt": "2026-09-06T10:24:27.147Z",
- "kind": "browser",
- "ids": [
- "project.concurrent-save",
- "project.save",
- "project.save-key",
- "recovery.autobuffer",
- "recovery.same-version"
- ],
- "file": "evidence/save-concurrency.json",
- "title": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "details": "延迟真实PUT快照A、重复Ctrl+S不重复请求、期间编辑B仍dirty;再次保存刷新无旧恢复稿误报。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.save-failure",
- "group": "工程入口与顶部命令",
- "name": "保存失败保留修改和恢复稿",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async saveProject()",
- "line": 1874
- },
- "implementation": "已有实现已完成验证",
- "boundary": "网络失败或业务拒绝不能清 dirty;不弹虚假保存成功。",
- "acceptance": "定向 503 后对象/字段保留,恢复后重试与刷新成功。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "保存失败与封面降级:503 保留草稿,封面上传失败保留旧图,恢复后可重试",
- "recordedAt": "2026-09-06T10:26:33.388Z",
- "kind": "browser",
- "ids": [
- "project.save-failure",
- "cover.failure"
- ],
- "file": "evidence/save-cover-failure.json",
- "title": "保存失败与封面降级:503 保留草稿,封面上传失败保留旧图,恢复后可重试",
- "details": "正文PUT503不清草稿;封面上传503保留旧图但正文可保存;恢复服务后保存刷新。截图异常和409另由聚焦合同验证。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.conflict",
- "group": "工程入口与顶部命令",
- "name": "409 乐观锁冲突保护",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "function describeSaveError",
- "line": 432
- },
- "implementation": "已有实现已完成验证",
- "boundary": "服务器最新版本不覆盖;恢复副本可下载/隔离。",
- "acceptance": "独立副本制造版本冲突;验证失败提示、旧版本不覆盖与本地稿保留。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "recordedAt": "2026-09-06T10:26:49.585Z",
- "kind": "browser",
- "ids": [
- "project.conflict",
- "recovery.autobuffer",
- "recovery.same-version",
- "recovery.stale-version"
- ],
- "file": "evidence/real-recovery-conflict.json",
- "title": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "details": "真实未存输入产生恢复稿,同版本恢复不自动入库;另一版本先保存后409拒绝覆盖,旧稿隔离下载。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "upload conflict propagates without any content PUT",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "project.conflict",
- "cover.failure"
- ],
- "file": "validation.json",
- "title": "upload conflict propagates without any content PUT",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "project.concurrent-save",
- "group": "工程入口与顶部命令",
- "name": "重复保存与保存中继续编辑",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "const saveRevision = this.changeRevision",
- "line": 1887
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "提交快照与后续编辑分开;后续修改不能随早先请求完成清掉。",
- "acceptance": "延迟 PUT、连点保存并继续改值;一次旧提交、新修改仍 dirty。",
- "fix": "开始保存时取消之前安排的恢复稿定时器,避免它覆盖宿主保存快照 nonce;保存中的后续编辑仍单独保留。",
- "fixIds": [
- "SCENE-F08"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "recordedAt": "2026-09-06T10:24:27.147Z",
- "kind": "browser",
- "ids": [
- "project.concurrent-save",
- "project.save",
- "project.save-key",
- "recovery.autobuffer",
- "recovery.same-version"
- ],
- "file": "evidence/save-concurrency.json",
- "title": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "details": "延迟真实PUT快照A、重复Ctrl+S不重复请求、期间编辑B仍dirty;再次保存刷新无旧恢复稿误报。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "json.export",
- "group": "工程文件与资源导入",
- "name": "导出当前场景 JSON",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "exportProject()",
- "line": 578
- },
- "implementation": "已有实现已完成验证",
- "boundary": "导出 edit3dv4.scene、对象/部件覆盖、渲染和稳定资源引用;不冒称自包含 GLB 包。",
- "acceptance": "打开下载 JSON 核对内容、结构和无临时 blob 依赖。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "recordedAt": "2026-09-06T10:31:05.221Z",
- "kind": "browser",
- "ids": [
- "permission.readonly",
- "permission.update",
- "permission.publish",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "json.export"
- ],
- "file": "evidence/readonly.json",
- "title": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "details": "只读按钮/模板/资源禁写、蒙皮浏览、运行预览与快捷键不变更对象,直接PUT拒绝;具体搜索/鼠标覆盖另见视口用例。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "json.import",
- "group": "工程文件与资源导入",
- "name": "导入有效场景工程 JSON",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "importProject(event)",
- "line": 462
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "替换当前编辑文档后仍需保存;不得写入另一个项目身份。",
- "acceptance": "导出后实际文件导入、保存、重开;对象与渲染参数往返一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "json.invalid",
- "group": "工程文件与资源导入",
- "name": "非法 JSON / 错误 schema 拒绝",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "importProject(event)",
- "line": 462
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "解析或结构错误不得清空当前场景。",
- "acceptance": "非法 JSON 与非场景文档各一次,原工程和模型仍可编辑。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "json.missing-resource",
- "group": "工程文件与资源导入",
- "name": "JSON 缺失/错误受控引用拒绝与回滚",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async restoreImportedObject",
- "line": 2016
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "错误资产编码不能回退为另一个模型;恢复失败不半替换。",
- "acceptance": "导入显式不存在编码/版本;原对象保留或明确阻断,零错误发布。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。;前端目录和资源解析同时匹配指定项目、版本、code、id、URI、READY MODEL_FILE;错误引用不回退首文件或本地缓存。仅含 sourceAssetId/assetId 的本项目资源也必须将 ID 纳入缓存/去重键,防止已缓存有效引用掩盖另一个错误ID;失败请求缓存可重试。复制场景保留旧伪 URI 但只读取当前副本资产。",
- "fixIds": [
- "SCENE-F03",
- "SCENE-F12"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "a failed replacement GLB keeps the previous live scene rather than clearing an unsaved draft",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "json.missing-resource"
- ],
- "file": "validation.json",
- "title": "a failed replacement GLB keeps the previous live scene rather than clearing an unsaved draft",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "an explicit missing code cannot fall back to the first READY asset",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "validation.references",
- "json.missing-resource"
- ],
- "file": "validation.json",
- "title": "an explicit missing code cannot fall back to the first READY asset",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "json.rendering",
- "group": "工程文件与资源导入",
- "name": "相机、灯光、雾和环境序列化往返",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "serializeRendering()",
- "line": 857
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "当前默认 UI 不提供全部渲染编辑器;导入/保存仍须保留其文档参数。",
- "acceptance": "合法带渲染参数文档导入、实际画面比对、保存重开字段一致。",
- "fix": "透视按钮实际恢复先前观察位置;导入、加载和历史恢复存在已保存相机时不再被车辆自动聚焦覆盖。",
- "fixIds": [
- "SCENE-F04"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "loading and history restoration preserve an authored camera rather than auto-focusing a vehicle",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "json.rendering",
- "history.undo"
- ],
- "file": "validation.json",
- "title": "loading and history restoration preserve an authored camera rather than auto-focusing a vehicle",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "glb.import",
- "group": "工程文件与资源导入",
- "name": "本地 GLB 上传并加入当前场景",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async importGLB(event)",
- "line": 2122
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "上传到内容服务,消费票据后解析;对象加入不等于工程已保存。",
- "acceptance": "真实选择小 GLB,上传/登记/可见/保存重开均完成。",
- "fix": "恢复显示名、设备和物模型编号使用空值保留规则,不把显式空串补回旧值;新资源序号跳过既有编号,空白编号校验按 trim 处理。",
- "fixIds": [
- "SCENE-F06"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "glb.invalid",
- "group": "工程文件与资源导入",
- "name": "非 GLB / 损坏 GLB / 上传失败处理",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async importGLB(event)",
- "line": 2122
- },
- "implementation": "已有实现已完成验证",
- "boundary": "上传或解析失败不插入占位对象;原场景应保留,提示可重试。",
- "acceptance": "错误格式及损坏文件、上传 503;验证对象数/旧资产/后续成功导入。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "glb.pending",
- "group": "工程文件与资源导入",
- "name": "资源加载/上传期间操作互斥",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "setModelLoading(loading",
- "line": 1411
- },
- "implementation": "已有实现已完成验证",
- "boundary": "加载中的模型不能被半保存、导出或发布;不能离开造成旧请求污染新项目。",
- "acceptance": "延迟下载/上传,操作禁用与待完成状态一致,完成后恢复。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "加载失败重试与加载互斥:不展示可写半场景、恢复网络后模型完整加载",
- "recordedAt": "2026-09-06T10:24:14.518Z",
- "kind": "browser",
- "ids": [
- "project.retry",
- "glb.pending",
- "leave.busy"
- ],
- "file": "evidence/loading-retry.json",
- "title": "加载失败重试与加载互斥:不展示可写半场景、恢复网络后模型完整加载",
- "details": "GET503只留中性失败和重试;延迟受控下载时禁用写入/导出/预览并阻止关闭,释放后真实狐狸加载。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "replacement failure waits for other started loads before restoring the original scene",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.failure",
- "glb.pending"
- ],
- "file": "validation.json",
- "title": "replacement failure waits for other started loads before restoring the original scene",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "an upload finishing after a project switch cannot register into the new session",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "glb.pending",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "an upload finishing after a project switch cannot register into the new session",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "glb.references",
- "group": "工程文件与资源导入",
- "name": "本项目 GLB 稳定资产引用",
- "source": {
- "file": "../../../unreal_tran_web/src/features/scene-legacy/serverAssetStore.ts",
- "symbol": "async put(blob",
- "line": 113
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "自导入使用 content://asset/scene/{projectId}/{assetCode} 和 READY 资产;blob 只供运行。",
- "acceptance": "重新会话受控下载成功,主对象/资产身份一致,无本地缓存依赖。",
- "fix": "前端目录和资源解析同时匹配指定项目、版本、code、id、URI、READY MODEL_FILE;错误引用不回退首文件或本地缓存。仅含 sourceAssetId/assetId 的本项目资源也必须将 ID 纳入缓存/去重键,防止已缓存有效引用掩盖另一个错误ID;失败请求缓存可重试。复制场景保留旧伪 URI 但只读取当前副本资产。;新增 SceneResourceReferenceValidator 检查 objects 和递归 splitParts;自有/固定版本资源的所有显式引用必须指向同一 READY 模型文件,错误引用在发布/提交前阻断,保留受控的内置资源和旧引用兼容。",
- "fixIds": [
- "SCENE-F12",
- "SCENE-F13"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "copied scene keeps its original pseudo URI but reads its own copied asset by stable code",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "glb.references"
- ],
- "file": "validation.json",
- "title": "copied scene keeps its original pseudo URI but reads its own copied asset by stable code",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "panel.left-tabs",
- "group": "左侧目录与资源放置",
- "name": "场景大纲 / 资源库 / 场景模板切换",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "const leftTab =",
- "line": 540
- },
- "implementation": "已有实现已完成验证",
- "boundary": "切面板不写业务文档;筛选状态行为需一致。",
- "acceptance": "三页签均可达,无 DOM 异常或资源目录中断。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "模板搜索与未保存切换确认保留和放弃",
- "recordedAt": "2026-09-06T10:28:42.077Z",
- "kind": "e2e",
- "ids": [
- "panel.left-tabs",
- "search.templates",
- "template.switch-cancel"
- ],
- "file": "evidence/template-confirm.json",
- "title": "模板搜索与未保存切换确认保留和放弃",
- "details": "中文/无匹配/清空搜索;真实取消保留对象,真实确认放弃并切换空白模板后保存。",
- "screenshots": [
- "29-template-confirm-empty.png"
- ]
- }
- ]
- },
- {
- "id": "search.tree",
- "group": "左侧目录与资源放置",
- "name": "对象/部件名称搜索与清空",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "renderTree()",
- "line": 627
- },
- "implementation": "已有实现已完成验证",
- "boundary": "根名与部件名可命中;无匹配状态应清楚,非删除对象。",
- "acceptance": "根名/部件名/无结果/清空分别核对行和真实对象数。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "recordedAt": "2026-09-06T10:29:25.167Z",
- "kind": "e2e",
- "ids": [
- "assets.catalog",
- "assets.model-double-click",
- "assets.model-drop",
- "search.tree",
- "part.source",
- "property.visible"
- ],
- "file": "evidence/published-model-assets.json",
- "title": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "details": "API 已发布目录,狐狸双击和卡车真实拖入;固定来源版本、树根/部件搜索;卡车刚体部件隐藏保存重开,最后恢复可见。基线树没有折叠按钮,不将搜索伪称折叠。",
- "screenshots": [
- "33-fox-placed-visible.png",
- "34-truck-placed-part-restored.png"
- ]
- }
- ]
- },
- {
- "id": "search.assets",
- "group": "左侧目录与资源放置",
- "name": "资源搜索与异步刷新保留筛选",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "applyLeftFilter()",
- "line": 742
- },
- "implementation": "已有实现已完成验证",
- "boundary": "只筛当前目录;异步重绘不复活不匹配卡片。",
- "acceptance": "命中、无结果、清空,目录重绘后过滤仍正确。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "search.templates",
- "group": "左侧目录与资源放置",
- "name": "模板搜索与清空",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "filterLeft(query)",
- "line": 2278
- },
- "implementation": "已有实现已完成验证",
- "boundary": "模板卡片与同一搜索框联动。",
- "acceptance": "中文模板关键字过滤、无结果和清空。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "模板搜索与未保存切换确认保留和放弃",
- "recordedAt": "2026-09-06T10:28:42.077Z",
- "kind": "e2e",
- "ids": [
- "panel.left-tabs",
- "search.templates",
- "template.switch-cancel"
- ],
- "file": "evidence/template-confirm.json",
- "title": "模板搜索与未保存切换确认保留和放弃",
- "details": "中文/无匹配/清空搜索;真实取消保留对象,真实确认放弃并切换空白模板后保存。",
- "screenshots": [
- "29-template-confirm-empty.png"
- ]
- }
- ]
- },
- {
- "id": "assets.catalog",
- "group": "左侧目录与资源放置",
- "name": "真实已发布模型成果目录",
- "source": {
- "file": "../../../unreal_tran_web/src/features/scene-legacy/contentApiClient.ts",
- "symbol": "async listPublishedModels",
- "line": 783
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "目录由 API 预加载,当前默认不以 localStorage 发布清单为真值。",
- "acceptance": "显示发布模型名称/版本,草稿不冒充已发布,空态可操作。",
- "fix": "移除 runtime 旧 content.update 门槛,独立计算新建、更新和发布;无模型页面权限时不加载新模型目录,但既有固定依赖仍可按场景授权读取。",
- "fixIds": [
- "SCENE-F01"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "recordedAt": "2026-09-06T10:29:25.167Z",
- "kind": "e2e",
- "ids": [
- "assets.catalog",
- "assets.model-double-click",
- "assets.model-drop",
- "search.tree",
- "part.source",
- "property.visible"
- ],
- "file": "evidence/published-model-assets.json",
- "title": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "details": "API 已发布目录,狐狸双击和卡车真实拖入;固定来源版本、树根/部件搜索;卡车刚体部件隐藏保存重开,最后恢复可见。基线树没有折叠按钮,不将搜索伪称折叠。",
- "screenshots": [
- "33-fox-placed-visible.png",
- "34-truck-placed-part-restored.png"
- ]
- }
- ]
- },
- {
- "id": "assets.model-double-click",
- "group": "左侧目录与资源放置",
- "name": "双击已发布模型放置",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async placeEditorAsset",
- "line": 1357
- },
- "implementation": "已有实现已完成验证",
- "boundary": "按固定 project/version/assetCode 导入当前实例,继承发布部件和材质。",
- "acceptance": "狐狸和卡车分别双击加入、真实可见、保存重开固定版本。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "recordedAt": "2026-09-06T10:29:25.167Z",
- "kind": "e2e",
- "ids": [
- "assets.catalog",
- "assets.model-double-click",
- "assets.model-drop",
- "search.tree",
- "part.source",
- "property.visible"
- ],
- "file": "evidence/published-model-assets.json",
- "title": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "details": "API 已发布目录,狐狸双击和卡车真实拖入;固定来源版本、树根/部件搜索;卡车刚体部件隐藏保存重开,最后恢复可见。基线树没有折叠按钮,不将搜索伪称折叠。",
- "screenshots": [
- "33-fox-placed-visible.png",
- "34-truck-placed-part-restored.png"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "fresh skinned placement reaches the requested size and floor after authored scale/pose replay",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "assets.model-double-click",
- "assets.model-drop"
- ],
- "file": "validation.json",
- "title": "fresh skinned placement reaches the requested size and floor after authored scale/pose replay",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "assets.model-drop",
- "group": "左侧目录与资源放置",
- "name": "拖入已发布模型放置",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleDrop(event)",
- "line": 461
- },
- "implementation": "已有实现已完成验证",
- "boundary": "拖放实际命中地平面;与双击共用受控资产链路。",
- "acceptance": "真实指针拖放到不同位置,坐标/实例数/固定引用准确。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "recordedAt": "2026-09-06T10:29:25.167Z",
- "kind": "e2e",
- "ids": [
- "assets.catalog",
- "assets.model-double-click",
- "assets.model-drop",
- "search.tree",
- "part.source",
- "property.visible"
- ],
- "file": "evidence/published-model-assets.json",
- "title": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "details": "API 已发布目录,狐狸双击和卡车真实拖入;固定来源版本、树根/部件搜索;卡车刚体部件隐藏保存重开,最后恢复可见。基线树没有折叠按钮,不将搜索伪称折叠。",
- "screenshots": [
- "33-fox-placed-visible.png",
- "34-truck-placed-part-restored.png"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "fresh skinned placement reaches the requested size and floor after authored scale/pose replay",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "assets.model-double-click",
- "assets.model-drop"
- ],
- "file": "validation.json",
- "title": "fresh skinned placement reaches the requested size and floor after authored scale/pose replay",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "assets.basic-double-click",
- "group": "左侧目录与资源放置",
- "name": "双击基础资源放置",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "onRootDblClick",
- "line": 429
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "以当前轨道目标落地;每次生成独立对象身份。",
- "acceptance": "双击生成对象,变换、保存后仍可见。",
- "fix": "恢复显示名、设备和物模型编号使用空值保留规则,不把显式空串补回旧值;新资源序号跳过既有编号,空白编号校验按 trim 处理。",
- "fixIds": [
- "SCENE-F06"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "assets.basic-drop",
- "group": "左侧目录与资源放置",
- "name": "基础资源拖入与拖放提示",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleDrop(event)",
- "line": 461
- },
- "implementation": "已有实现已完成验证",
- "boundary": "MIME 和 text/plain 回退协议一致;离开视口清提示。",
- "acceptance": "真实拖放命中位置与 0.5m 吸附、dragleave/drop 提示复位。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "assets.model-link",
- "group": "左侧目录与资源放置",
- "name": "打开/返回模型编辑器入口",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "open-model-editor",
- "line": 590
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "当前基线只有跳模型列表,来源按钮不得冒称直达正确源项目。",
- "acceptance": "空资源库和选中模型来源两入口,跳转/未保存保护正确。",
- "fix": "模型来源按钮有来源权限时导航正确项目;无来源页面权限回到可访问列表,不将模型列表误称为来源工程编辑。",
- "fixIds": [
- "SCENE-F11"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "model source navigation locates the published owner and falls back without source permission",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "assets.model-link"
- ],
- "file": "validation.json",
- "title": "model source navigation locates the published owner and falls back without source permission",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "asset.diagnostic",
- "group": "左侧目录与资源放置",
- "name": "基础资源:液压诊断工位",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'diagnostic'",
- "line": 123
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.equipment",
- "group": "左侧目录与资源放置",
- "name": "基础资源:维修装备主体",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'equipment'",
- "line": 124
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.workbench",
- "group": "左侧目录与资源放置",
- "name": "基础资源:检修工作台",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'workbench'",
- "line": 125
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.shelf",
- "group": "左侧目录与资源放置",
- "name": "基础资源:器材存放架",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'shelf'",
- "line": 126
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.safety-zone",
- "group": "左侧目录与资源放置",
- "name": "基础资源:安全作业区域",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'safety-zone'",
- "line": 127
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.camera",
- "group": "左侧目录与资源放置",
- "name": "基础资源:视觉采集设备",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'camera'",
- "line": 128
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.worker",
- "group": "左侧目录与资源放置",
- "name": "基础资源:训练人员占位",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'worker'",
- "line": 129
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.light",
- "group": "左侧目录与资源放置",
- "name": "基础资源:区域照明",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'light'",
- "line": 130
- },
- "implementation": "已有实现已完成验证",
- "boundary": "现有程序化场景资源;名称不代表已连接物理设备或真实人员。",
- "acceptance": "实际放置可见,独立编号、位置和保存重开一致;照明应区分灯具外观与光源效果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.vehicle-depot",
- "group": "左侧目录与资源放置",
- "name": "场地资源:真实装备车库",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'vehicle-depot'",
- "line": 121
- },
- "implementation": "已有实现已完成验证",
- "boundary": "整体场地 GLB 与维修车间分开;重复放置按既有规则处理。",
- "acceptance": "资源拖放或双击加载、比例/落地正常、重复放置不产生错误重叠。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "两种整体场地加载、重复放置阻止与显式删除后替换",
- "recordedAt": "2026-09-06T10:29:06.315Z",
- "kind": "e2e",
- "ids": [
- "asset.vehicle-depot",
- "asset.field-terrain",
- "object.delete"
- ],
- "file": "evidence/venue-assets.json",
- "title": "两种整体场地加载、重复放置阻止与显式删除后替换",
- "details": "车库和起伏地形真实加载并分别保存重开;已有整体场地时阻止叠加,显式删除旧场地后才能替换。",
- "screenshots": [
- "31-venue-depot-reopened.png",
- "32-venue-terrain-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "asset.field-terrain",
- "group": "左侧目录与资源放置",
- "name": "场地资源:真实野外地形",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'field-terrain'",
- "line": 122
- },
- "implementation": "已有实现已完成验证",
- "boundary": "真实地形资源和指定落地基准;不能以程序地板代替。",
- "acceptance": "加载后真实起伏地形可见,保存重开资源、地面高度一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "两种整体场地加载、重复放置阻止与显式删除后替换",
- "recordedAt": "2026-09-06T10:29:06.315Z",
- "kind": "e2e",
- "ids": [
- "asset.vehicle-depot",
- "asset.field-terrain",
- "object.delete"
- ],
- "file": "evidence/venue-assets.json",
- "title": "两种整体场地加载、重复放置阻止与显式删除后替换",
- "details": "车库和起伏地形真实加载并分别保存重开;已有整体场地时阻止叠加,显式删除旧场地后才能替换。",
- "screenshots": [
- "31-venue-depot-reopened.png",
- "32-venue-terrain-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "template.depot-1",
- "group": "全部可达场景模板",
- "name": "真实装备车库",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'depot-1'",
- "line": 86
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:真实装备车库",
- "recordedAt": "2026-09-06T10:27:14.151Z",
- "kind": "e2e",
- "ids": [
- "template.depot-1"
- ],
- "file": "evidence/template-depot-1.json",
- "title": "场景模板实际加载、保存重开:真实装备车库",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "20-template-depot-1.png"
- ]
- }
- ]
- },
- {
- "id": "template.terrain-1",
- "group": "全部可达场景模板",
- "name": "真实野外训练场",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'terrain-1'",
- "line": 87
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:真实野外训练场",
- "recordedAt": "2026-09-06T10:27:24.419Z",
- "kind": "e2e",
- "ids": [
- "template.terrain-1"
- ],
- "file": "evidence/template-terrain-1.json",
- "title": "场景模板实际加载、保存重开:真实野外训练场",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "21-template-terrain-1.png"
- ]
- }
- ]
- },
- {
- "id": "template.workshop-1",
- "group": "全部可达场景模板",
- "name": "综合检验车间",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'workshop-1'",
- "line": 88
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:综合检验车间",
- "recordedAt": "2026-09-06T10:27:33.434Z",
- "kind": "e2e",
- "ids": [
- "template.workshop-1"
- ],
- "file": "evidence/template-workshop-1.json",
- "title": "场景模板实际加载、保存重开:综合检验车间",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "22-template-workshop-1.png"
- ]
- }
- ]
- },
- {
- "id": "template.workshop-real",
- "group": "全部可达场景模板",
- "name": "演示维修车间(可拆分)",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'workshop-real'",
- "line": 89
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:演示维修车间(可拆分)",
- "recordedAt": "2026-09-06T10:27:50.202Z",
- "kind": "e2e",
- "ids": [
- "template.workshop-real"
- ],
- "file": "evidence/template-workshop-real.json",
- "title": "场景模板实际加载、保存重开:演示维修车间(可拆分)",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "23-template-workshop-real.png"
- ]
- }
- ]
- },
- {
- "id": "template.workshop-2",
- "group": "全部可达场景模板",
- "name": "总成拆卸车间",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'workshop-2'",
- "line": 90
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:总成拆卸车间",
- "recordedAt": "2026-09-06T10:27:59.059Z",
- "kind": "e2e",
- "ids": [
- "template.workshop-2"
- ],
- "file": "evidence/template-workshop-2.json",
- "title": "场景模板实际加载、保存重开:总成拆卸车间",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "24-template-workshop-2.png"
- ]
- }
- ]
- },
- {
- "id": "template.workshop-3",
- "group": "全部可达场景模板",
- "name": "部件分解车间",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'workshop-3'",
- "line": 91
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:部件分解车间",
- "recordedAt": "2026-09-06T10:28:07.821Z",
- "kind": "e2e",
- "ids": [
- "template.workshop-3"
- ],
- "file": "evidence/template-workshop-3.json",
- "title": "场景模板实际加载、保存重开:部件分解车间",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "25-template-workshop-3.png"
- ]
- }
- ]
- },
- {
- "id": "template.workshop-4",
- "group": "全部可达场景模板",
- "name": "清洗检测车间",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'workshop-4'",
- "line": 92
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:清洗检测车间",
- "recordedAt": "2026-09-06T10:28:16.504Z",
- "kind": "e2e",
- "ids": [
- "template.workshop-4"
- ],
- "file": "evidence/template-workshop-4.json",
- "title": "场景模板实际加载、保存重开:清洗检测车间",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "26-template-workshop-4.png"
- ]
- }
- ]
- },
- {
- "id": "template.workshop-5",
- "group": "全部可达场景模板",
- "name": "复装调试车间",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'workshop-5'",
- "line": 93
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:复装调试车间",
- "recordedAt": "2026-09-06T10:28:25.537Z",
- "kind": "e2e",
- "ids": [
- "template.workshop-5"
- ],
- "file": "evidence/template-workshop-5.json",
- "title": "场景模板实际加载、保存重开:复装调试车间",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "27-template-workshop-5.png"
- ]
- }
- ]
- },
- {
- "id": "template.outdoor-1",
- "group": "全部可达场景模板",
- "name": "室外综合训练场",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "id: 'outdoor-1'",
- "line": 94
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "模板场地与种子布局须有实际执行;切模板不是创建新的业务项目。",
- "acceptance": "独立副本点击模板、确认/取消未存操作、真实画面、保存重开 presetId/环境/对象一致。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "场景模板实际加载、保存重开:室外综合训练场",
- "recordedAt": "2026-09-06T10:28:34.148Z",
- "kind": "e2e",
- "ids": [
- "template.outdoor-1"
- ],
- "file": "evidence/template-outdoor-1.json",
- "title": "场景模板实际加载、保存重开:室外综合训练场",
- "details": "真实模板按钮、选中标签、环境字段、种子对象、PUT 后刷新重开;截图验证对应模板实际画面。",
- "screenshots": [
- "28-template-outdoor-1.png"
- ]
- }
- ]
- },
- {
- "id": "template.switch-cancel",
- "group": "全部可达场景模板",
- "name": "未保存模板切换取消",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async loadPreset",
- "line": 765
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "取消保留原场景、选择与 dirty;请求中不能切换半场景。",
- "acceptance": "有未存修改时取消/确认分别验证,取消零对象和服务端变更。",
- "fix": "模板按钮使用模板种子,不再次读当前项目旧文档;模板/JSON 替换先保存当前运行对象,等待全部加载结束,失败恢复原环境、对象、选择和 dirty;真实确认取消保留原稿。",
- "fixIds": [
- "SCENE-F03"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "模板搜索与未保存切换确认保留和放弃",
- "recordedAt": "2026-09-06T10:28:42.077Z",
- "kind": "e2e",
- "ids": [
- "panel.left-tabs",
- "search.templates",
- "template.switch-cancel"
- ],
- "file": "evidence/template-confirm.json",
- "title": "模板搜索与未保存切换确认保留和放弃",
- "details": "中文/无匹配/清空搜索;真实取消保留对象,真实确认放弃并切换空白模板后保存。",
- "screenshots": [
- "29-template-confirm-empty.png"
- ]
- }
- ]
- },
- {
- "id": "view.orbit",
- "group": "三维视口、选择与变换",
- "name": "鼠标旋转相机",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "new OrbitControls",
- "line": 379
- },
- "implementation": "已有实现已完成验证",
- "boundary": "相机轨道操作不应误选、拖动物体。",
- "acceptance": "实际鼠标拖动,相机变化且对象姿态不变。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "view.pan",
- "group": "三维视口、选择与变换",
- "name": "鼠标平移相机",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "new OrbitControls",
- "line": 379
- },
- "implementation": "已有实现已完成验证",
- "boundary": "轨道目标平移与物体位置分开。",
- "acceptance": "实际右键/约定鼠标平移,目标变化且对象数据不变。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "view.zoom",
- "group": "三维视口、选择与变换",
- "name": "滚轮缩放相机",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "new OrbitControls",
- "line": 379
- },
- "implementation": "已有实现已完成验证",
- "boundary": "改变观察距离,不改对象 scale。",
- "acceptance": "滚轮前后模型可见且对象 scale 不变。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "view.perspective",
- "group": "三维视口、选择与变换",
- "name": "透视按钮",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "data-camera=\"perspective\"",
- "line": 259
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "基线按钮无处理分支;需明确恢复相机视角,不静默无效。",
- "acceptance": "顶视切回透视,实际相机位置与激活样式变化。",
- "fix": "透视按钮实际恢复先前观察位置;导入、加载和历史恢复存在已保存相机时不再被车辆自动聚焦覆盖。",
- "fixIds": [
- "SCENE-F04"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "view.top",
- "group": "三维视口、选择与变换",
- "name": "顶视图按钮",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "setTopView()",
- "line": 585
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "仍为透视相机顶视位置,不冒称正交投影。",
- "acceptance": "实际点击后顶视方向与目标一致。",
- "fix": "透视按钮实际恢复先前观察位置;导入、加载和历史恢复存在已保存相机时不再被车辆自动聚焦覆盖。",
- "fixIds": [
- "SCENE-F04"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "view.focus",
- "group": "三维视口、选择与变换",
- "name": "聚焦选中对象",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "focusSelected()",
- "line": 586
- },
- "implementation": "已有实现已完成验证",
- "boundary": "按对象真实 bounds 调整相机;无选中应提示。",
- "acceptance": "狐狸/卡车/环境分别聚焦可见;无选中提示不异常。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "view.grid",
- "group": "三维视口、选择与变换",
- "name": "网格显隐",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "toggleGrid(button)",
- "line": 1643
- },
- "implementation": "已有实现已完成验证",
- "boundary": "当前视图辅助选项;不默认要求跨重开持久化。",
- "acceptance": "真实网格出现/消失、状态同步、截图封面不含网格。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "copies synchronously without bounds, gizmo, grid or selection glow, then restores before JPEG encoding",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "cover.capture",
- "selection.highlight",
- "view.grid"
- ],
- "file": "validation.json",
- "title": "copies synchronously without bounds, gizmo, grid or selection glow, then restores before JPEG encoding",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "view.enclosure-full",
- "group": "三维视口、选择与变换",
- "name": "车库外壳完整显示",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/garage-enclosure.js",
- "symbol": "createGarageEnclosureControls",
- "line": 377
- },
- "implementation": "已有实现已完成验证",
- "boundary": "完整显示屋顶/墙体/玻璃;仅车库资源存在时出现控制。",
- "acceptance": "实际点击、对象材料和显示恢复,状态与画面一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "view.enclosure-xray",
- "group": "三维视口、选择与变换",
- "name": "车库外壳透明查看",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/garage-enclosure.js",
- "symbol": "createGarageEnclosureControls",
- "line": 377
- },
- "implementation": "已有实现已完成验证",
- "boundary": "车库多种围护材料联动;不等于普通相机透视。",
- "acceptance": "实际外壳透明且内部模型可辨,材质无串改。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "view.enclosure-hidden",
- "group": "三维视口、选择与变换",
- "name": "隐藏车库外壳",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/garage-enclosure.js",
- "symbol": "createGarageEnclosureControls",
- "line": 377
- },
- "implementation": "已有实现已完成验证",
- "boundary": "隐藏围护后保留内部及地面;序列化 enclosureMode 与 dirty 契约须核对。",
- "acceptance": "隐藏/还原、保存重开和只读浏览行为准确。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "selection.viewport",
- "group": "三维视口、选择与变换",
- "name": "点击视口选中根对象/部件",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "selectFromViewport(event)",
- "line": 456
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "只命中真实可选择可见对象;拖相机超过阈值不误选。",
- "acceptance": "真实像素点击目标、树/属性/高亮一致,点击空白清选择。",
- "fix": "新实例部件 sceneId 包含所属根对象身份,不再直接复用来源模型部件 ID;源 interaction/editor 标识保留。旧单实例 ID 保留,旧文档重复 ID 仅按文档顺序迁移后续冲突实例并同步 override。第二完整轮进一步发现 GLB 并发完成顺序会改变根对象顺序;现等待 allSettled 成功后按原文档顺序排列恢复根对象,拆分模板返回数组内部顺序和既有对象均保留,同源两实例不再随网速互换列表位置。新增延迟 30/1/10ms 乱序加载合同,验证序列化仍按文档顺序;最终浏览器验证独立记录。",
- "fixIds": [
- "SCENE-F18"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "selection.tree",
- "group": "三维视口、选择与变换",
- "name": "大纲根对象与部件选中",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "const treeItem =",
- "line": 546
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "大纲显示所有可编辑实例和部件;环境锁定提示不是折叠控件。",
- "acceptance": "树选中与视口高亮/属性联动、筛选后仍可选。",
- "fix": "新实例部件 sceneId 包含所属根对象身份,不再直接复用来源模型部件 ID;源 interaction/editor 标识保留。旧单实例 ID 保留,旧文档重复 ID 仅按文档顺序迁移后续冲突实例并同步 override。第二完整轮进一步发现 GLB 并发完成顺序会改变根对象顺序;现等待 allSettled 成功后按原文档顺序排列恢复根对象,拆分模板返回数组内部顺序和既有对象均保留,同源两实例不再随网速互换列表位置。新增延迟 30/1/10ms 乱序加载合同,验证序列化仍按文档顺序;最终浏览器验证独立记录。",
- "fixIds": [
- "SCENE-F18"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "two published instances have unique tree part IDs and editing the second persists independently after reopen",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "part.transform",
- "selection.tree"
- ],
- "file": "validation.json",
- "title": "two published instances have unique tree part IDs and editing the second persists independently after reopen",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "successful parallel restores retain document order after delayed GLBs and split-object batches finish out of order",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "project.load",
- "selection.tree"
- ],
- "file": "validation.json",
- "title": "successful parallel restores retain document order after delayed GLBs and split-object batches finish out of order",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "selection.hidden",
- "group": "三维视口、选择与变换",
- "name": "隐藏祖先与软删除部件不可误拾取",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-selection.js",
- "symbol": "chooseSceneSelection",
- "line": 41
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "父隐藏/子隐藏/软删除状态不能被射线重新命中。",
- "acceptance": "用重叠模型/部件实测,命中应落可见有效对象。",
- "fix": "射线候选逐级检查父级可见性和软删除;删除根对象先恢复高亮材质再释放几何/材质,避免错误拾取及 GPU 资源残留。",
- "fixIds": [
- "SCENE-F09"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "real Three ray hits on hidden descendants are excluded before selecting a root or part",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "selection.hidden"
- ],
- "file": "validation.json",
- "title": "real Three ray hits on hidden descendants are excluded before selecting a root or part",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "selection.highlight",
- "group": "三维视口、选择与变换",
- "name": "选中高亮与恢复原材质",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "updateSelectionHighlight()",
- "line": 627
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "高亮是暂态,不写入模型/场景材质,不进入封面。",
- "acceptance": "切换对象/清选择/预览/保存截图后材质原值恢复。",
- "fix": "射线候选逐级检查父级可见性和软删除;删除根对象先恢复高亮材质再释放几何/材质,避免错误拾取及 GPU 资源残留。",
- "fixIds": [
- "SCENE-F09"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "selection highlight cleanup restores source materials and releases its own GPU helper",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "selection.highlight",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "selection highlight cleanup restores source materials and releases its own GPU helper",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "copies synchronously without bounds, gizmo, grid or selection glow, then restores before JPEG encoding",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "cover.capture",
- "selection.highlight",
- "view.grid"
- ],
- "file": "validation.json",
- "title": "copies synchronously without bounds, gizmo, grid or selection glow, then restores before JPEG encoding",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "transform.translate",
- "group": "三维视口、选择与变换",
- "name": "移动工具及真实 XYZ 手柄",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "setTransform(mode)",
- "line": 1627
- },
- "implementation": "已有实现已完成验证",
- "boundary": "对象实例位置;部件按发布能力限制。",
- "acceptance": "真实拖动平移手柄,属性联动、撤销重做、保存重开一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "recordedAt": "2026-09-06T10:29:55.869Z",
- "kind": "真实UI手柄+只读几何投影定位",
- "ids": [
- "transform.translate",
- "transform.rotate",
- "transform.scale",
- "transform.keys",
- "transform.snap"
- ],
- "file": "evidence/viewport-transform.json",
- "title": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "details": "",
- "screenshots": [
- "43-real-transform-gizmo"
- ]
- }
- ]
- },
- {
- "id": "transform.rotate",
- "group": "三维视口、选择与变换",
- "name": "旋转工具及真实旋转手柄",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "setTransform(mode)",
- "line": 1627
- },
- "implementation": "已有实现已完成验证",
- "boundary": "UI 度数与保存弧度转换;不能仅用脚本改姿态代替拖动。",
- "acceptance": "实际旋转手柄改变姿态并重开一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "recordedAt": "2026-09-06T10:29:55.869Z",
- "kind": "真实UI手柄+只读几何投影定位",
- "ids": [
- "transform.translate",
- "transform.rotate",
- "transform.scale",
- "transform.keys",
- "transform.snap"
- ],
- "file": "evidence/viewport-transform.json",
- "title": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "details": "",
- "screenshots": [
- "43-real-transform-gizmo"
- ]
- }
- ]
- },
- {
- "id": "transform.scale",
- "group": "三维视口、选择与变换",
- "name": "缩放工具及真实缩放手柄",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "setTransform(mode)",
- "line": 1627
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "归一化模型已有 scale 必须保留,负/零/小值合同明确。",
- "acceptance": "真实缩放与属性数值一致;狐狸不突然放成超大或消失。",
- "fix": "实际手柄跨越枢轴时按既有严格正尺度合同限制,避免产生负或零尺度导致模型翻转或消失;未新增镜像建模功能。",
- "fixIds": [
- "SCENE-F17"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "recordedAt": "2026-09-06T10:29:55.869Z",
- "kind": "真实UI手柄+只读几何投影定位",
- "ids": [
- "transform.translate",
- "transform.rotate",
- "transform.scale",
- "transform.keys",
- "transform.snap"
- ],
- "file": "evidence/viewport-transform.json",
- "title": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "details": "",
- "screenshots": [
- "43-real-transform-gizmo"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "gizmo scaling across its pivot follows the same strictly positive scale contract as inspector edits",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "transform.scale",
- "property.scale"
- ],
- "file": "validation.json",
- "title": "gizmo scaling across its pivot follows the same strictly positive scale contract as inspector edits",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "transform.keys",
- "group": "三维视口、选择与变换",
- "name": "W/E/R 快捷键",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleKeyboard(event)",
- "line": 469
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "键盘焦点在表单时不切工具,失活缓存页不能抢键。",
- "acceptance": "视口按键切工具;名称输入包含 w/e/r 正常;只读不改。",
- "fix": "预览状态同步全部操作禁用,Delete/W/E/R 和表单输入遵守预览/权限;失活缓存页忽略全局快捷键,输入框撤销保持文本语义。",
- "fixIds": [
- "SCENE-F05"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "recordedAt": "2026-09-06T10:29:55.869Z",
- "kind": "真实UI手柄+只读几何投影定位",
- "ids": [
- "transform.translate",
- "transform.rotate",
- "transform.scale",
- "transform.keys",
- "transform.snap"
- ],
- "file": "evidence/viewport-transform.json",
- "title": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "details": "",
- "screenshots": [
- "43-real-transform-gizmo"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.undo",
- "history.redo",
- "transform.keys",
- "lifecycle.cache"
- ],
- "file": "validation.json",
- "title": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "transform.snap",
- "group": "三维视口、选择与变换",
- "name": "吸附 0.5m 与旋转 15° 开关",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "toggleSnap()",
- "line": 581
- },
- "implementation": "已有实现已完成验证",
- "boundary": "开关同时控制拖放/变换吸附;当前视图工具参数与业务值区分。",
- "acceptance": "开/关实际拖动位置、旋转角度,按钮/页脚状态一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "recordedAt": "2026-09-06T10:29:55.869Z",
- "kind": "真实UI手柄+只读几何投影定位",
- "ids": [
- "transform.translate",
- "transform.rotate",
- "transform.scale",
- "transform.keys",
- "transform.snap"
- ],
- "file": "evidence/viewport-transform.json",
- "title": "真实变换手柄移动旋转缩放、吸附与保存重开",
- "details": "",
- "screenshots": [
- "43-real-transform-gizmo"
- ]
- }
- ]
- },
- {
- "id": "property.name",
- "group": "对象属性、部件与底部面板",
- "name": "显示名称",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleInput(event)",
- "line": 437
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "对象/部件 displayName 与项目名称分开。",
- "acceptance": "修改名称,树/对象条/属性同步,保存重开保留。",
- "fix": "恢复显示名、设备和物模型编号使用空值保留规则,不把显式空串补回旧值;新资源序号跳过既有编号,空白编号校验按 trim 处理。",
- "fixIds": [
- "SCENE-F06"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "property.visible",
- "group": "对象属性、部件与底部面板",
- "name": "在场景中可见",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleChange(event)",
- "line": 438
- },
- "implementation": "已有实现已完成验证",
- "boundary": "实例显隐可保存;受保护蒙皮部件不得独立隐藏。",
- "acceptance": "开/关可见性、恢复、保存重开,视口与树状态准确。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "recordedAt": "2026-09-06T10:29:25.167Z",
- "kind": "e2e",
- "ids": [
- "assets.catalog",
- "assets.model-double-click",
- "assets.model-drop",
- "search.tree",
- "part.source",
- "property.visible"
- ],
- "file": "evidence/published-model-assets.json",
- "title": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "details": "API 已发布目录,狐狸双击和卡车真实拖入;固定来源版本、树根/部件搜索;卡车刚体部件隐藏保存重开,最后恢复可见。基线树没有折叠按钮,不将搜索伪称折叠。",
- "screenshots": [
- "33-fox-placed-visible.png",
- "34-truck-placed-part-restored.png"
- ]
- }
- ]
- },
- {
- "id": "property.operable",
- "group": "对象属性、部件与底部面板",
- "name": "可作为实训目标",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleChange(event)",
- "line": 438
- },
- "implementation": "已有实现已完成验证",
- "boundary": "operable/capabilities 进入场景定义;不能扩大平台操作权限。",
- "acceptance": "开/关并保存重开,发布数据的目标能力一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "property.position",
- "group": "对象属性、部件与底部面板",
- "name": "位置 X/Y/Z 数值",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleInput(event)",
- "line": 437
- },
- "implementation": "已有实现已完成验证",
- "boundary": "三个输入回写局部 position;不使用纯展示假字段。",
- "acceptance": "三个轴独立输入与手柄联动、失焦/history/重开准确。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "property.rotation",
- "group": "对象属性、部件与底部面板",
- "name": "旋转 X/Y/Z 数值",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleInput(event)",
- "line": 437
- },
- "implementation": "已有实现已完成验证",
- "boundary": "UI 为角度,文档为弧度。",
- "acceptance": "非整角/负角输入、实际姿态与 JSON/重开一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "property.scale",
- "group": "对象属性、部件与底部面板",
- "name": "缩放 X/Y/Z 数值及有效值",
- "source": {
- "file": "../../../unreal_tran_web/src/features/scene-legacy/modelPlacement.ts",
- "symbol": "parseSceneScale",
- "line": 36
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "支持小数归一化 scale,避免小值格式化成零;非法值不得破坏模型。",
- "acceptance": "小正数、负数/零/清空按合同处理,三轴保存往返正常。",
- "fix": "实际手柄跨越枢轴时按既有严格正尺度合同限制,避免产生负或零尺度导致模型翻转或消失;未新增镜像建模功能。",
- "fixIds": [
- "SCENE-F17"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "gizmo scaling across its pivot follows the same strictly positive scale contract as inspector edits",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "transform.scale",
- "property.scale"
- ],
- "file": "validation.json",
- "title": "gizmo scaling across its pivot follows the same strictly positive scale contract as inspector edits",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "scale input accepts real GLTF normalization factors below 0.05",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "property.scale"
- ],
- "file": "validation.json",
- "title": "scale input accepts real GLTF normalization factors below 0.05",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "property.device-id",
- "group": "对象属性、部件与底部面板",
- "name": "设备编号",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleInput(event)",
- "line": 437
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "根对象绑定字符串;重复/空值由预检与后端核查。",
- "acceptance": "修改后绑定表同步、保存重开,重复值能被阻断。",
- "fix": "恢复显示名、设备和物模型编号使用空值保留规则,不把显式空串补回旧值;新资源序号跳过既有编号,空白编号校验按 trim 处理。",
- "fixIds": [
- "SCENE-F06"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "property.model-id",
- "group": "对象属性、部件与底部面板",
- "name": "物模型编号",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleInput(event)",
- "line": 437
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "与受控 assetCode、来源项目 ID 分开。",
- "acceptance": "修改后只改业务编号,源 GLB 仍加载正确。",
- "fix": "恢复显示名、设备和物模型编号使用空值保留规则,不把显式空串补回旧值;新资源序号跳过既有编号,空白编号校验按 trim 处理。",
- "fixIds": [
- "SCENE-F06"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "property.semantic",
- "group": "对象属性、部件与底部面板",
- "name": "语义类型六个选项",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleChange(event)",
- "line": 438
- },
- "implementation": "已有实现已完成验证",
- "boundary": "实训装备/工位设施/安全区域/采集设备/训练人员/环境设施。",
- "acceptance": "逐项可选且保存重开保留;绑定表显示实际类型。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "part.source",
- "group": "对象属性、部件与底部面板",
- "name": "模型来源与部件权限说明",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "renderInspector()",
- "line": 1520
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "固定模型版本/源节点;蒙皮仅查看高亮,非骨骼独立变换。",
- "acceptance": "狐狸蒙皮与卡车刚性部件说明/禁用态准确。",
- "fix": "模型来源按钮有来源权限时导航正确项目;无来源页面权限回到可访问列表,不将模型列表误称为来源工程编辑。",
- "fixIds": [
- "SCENE-F11"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "recordedAt": "2026-09-06T10:29:25.167Z",
- "kind": "e2e",
- "ids": [
- "assets.catalog",
- "assets.model-double-click",
- "assets.model-drop",
- "search.tree",
- "part.source",
- "property.visible"
- ],
- "file": "evidence/published-model-assets.json",
- "title": "模型成果狐狸卡车双击与真实拖入、树搜索和部件隐藏重开",
- "details": "API 已发布目录,狐狸双击和卡车真实拖入;固定来源版本、树根/部件搜索;卡车刚体部件隐藏保存重开,最后恢复可见。基线树没有折叠按钮,不将搜索伪称折叠。",
- "screenshots": [
- "33-fox-placed-visible.png",
- "34-truck-placed-part-restored.png"
- ]
- }
- ]
- },
- {
- "id": "part.transform",
- "group": "对象属性、部件与底部面板",
- "name": "刚性部件独立变换并保存覆盖",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "captureModelPartOverrides(root)",
- "line": 1123
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "partOverrides 与稳定 interactionId;多个实例互不串改。",
- "acceptance": "两卡车实例改单部件,保存重开另一实例不受影响。",
- "fix": "新实例部件 sceneId 包含所属根对象身份,不再直接复用来源模型部件 ID;源 interaction/editor 标识保留。旧单实例 ID 保留,旧文档重复 ID 仅按文档顺序迁移后续冲突实例并同步 override。第二完整轮进一步发现 GLB 并发完成顺序会改变根对象顺序;现等待 allSettled 成功后按原文档顺序排列恢复根对象,拆分模板返回数组内部顺序和既有对象均保留,同源两实例不再随网速互换列表位置。新增延迟 30/1/10ms 乱序加载合同,验证序列化仍按文档顺序;最终浏览器验证独立记录。",
- "fixIds": [
- "SCENE-F18"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "two published instances have unique tree part IDs and editing the second persists independently after reopen",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "part.transform",
- "selection.tree"
- ],
- "file": "validation.json",
- "title": "two published instances have unique tree part IDs and editing the second persists independently after reopen",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "legacy duplicate instance IDs migrate only later owners in document order despite reversed GLB completion",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "part.transform",
- "publish.fixed-model"
- ],
- "file": "validation.json",
- "title": "legacy duplicate instance IDs migrate only later owners in document order despite reversed GLB completion",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "part.soft-delete",
- "group": "对象属性、部件与底部面板",
- "name": "部件软删除与恢复",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "deleteSelected()",
- "line": 588
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "被允许的部件 sceneDeleted/visible 持久化;可撤销恢复。",
- "acceptance": "实际删除、撤销、保存重开均一致;蒙皮不允许破坏骨架。",
- "fix": "新实例部件 sceneId 包含所属根对象身份,不再直接复用来源模型部件 ID;源 interaction/editor 标识保留。旧单实例 ID 保留,旧文档重复 ID 仅按文档顺序迁移后续冲突实例并同步 override。第二完整轮进一步发现 GLB 并发完成顺序会改变根对象顺序;现等待 allSettled 成功后按原文档顺序排列恢复根对象,拆分模板返回数组内部顺序和既有对象均保留,同源两实例不再随网速互换列表位置。新增延迟 30/1/10ms 乱序加载合同,验证序列化仍按文档顺序;最终浏览器验证独立记录。",
- "fixIds": [
- "SCENE-F18"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "object.delete",
- "group": "对象属性、部件与底部面板",
- "name": "删除根对象按钮 / Delete",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "deleteSelected()",
- "line": 588
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "移除当前场景实例,不删除源模型项目/固定发布版本。",
- "acceptance": "按钮和键盘各验证;源项目不变,撤销和重开正确。",
- "fix": "射线候选逐级检查父级可见性和软删除;删除根对象先恢复高亮材质再释放几何/材质,避免错误拾取及 GPU 资源残留。",
- "fixIds": [
- "SCENE-F09"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "两种整体场地加载、重复放置阻止与显式删除后替换",
- "recordedAt": "2026-09-06T10:29:06.315Z",
- "kind": "e2e",
- "ids": [
- "asset.vehicle-depot",
- "asset.field-terrain",
- "object.delete"
- ],
- "file": "evidence/venue-assets.json",
- "title": "两种整体场地加载、重复放置阻止与显式删除后替换",
- "details": "车库和起伏地形真实加载并分别保存重开;已有整体场地时阻止叠加,显式删除旧场地后才能替换。",
- "screenshots": [
- "31-venue-depot-reopened.png",
- "32-venue-terrain-reopened.png"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "deleting a root disposes its geometry and materials after clearing selection",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "object.delete",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "deleting a root disposes its geometry and materials after clearing selection",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "panel.objects",
- "group": "对象属性、部件与底部面板",
- "name": "底部对象列表与选中",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "renderBottom(mode",
- "line": 1619
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "基线显示前 6 个摘要,完整对象仍在大纲;需明确截断。",
- "acceptance": "大于 6 个对象时列表说明准确,摘要点击选择正确。",
- "fix": "设备绑定显示真实语义与未设置;校验按钮进入当前检查面板并随绑定变更刷新;日志记录本次运行实际操作,错误详情保持瞬时提示;摘要超过六项明确完整列表位置。",
- "fixIds": [
- "SCENE-F10"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "recordedAt": "2026-09-06T10:28:51.941Z",
- "kind": "e2e",
- "ids": [
- "asset.diagnostic",
- "asset.equipment",
- "asset.workbench",
- "asset.shelf",
- "asset.safety-zone",
- "asset.camera",
- "asset.worker",
- "asset.light",
- "assets.basic-double-click",
- "assets.basic-drop",
- "search.assets",
- "panel.objects"
- ],
- "file": "evidence/basic-assets.json",
- "title": "八种基础资源逐项放置、真实拖放、搜索和保存重开",
- "details": "8 种基础资源分别双击放置并分开布置;真实指针拖入第 9 个工作台、吸附检查、唯一编号、保存刷新一致。照明为现有资源外观,不冒称连接真实灯控。",
- "screenshots": [
- "30-eight-basic-assets-reopened.png"
- ]
- }
- ]
- },
- {
- "id": "panel.binding",
- "group": "对象属性、部件与底部面板",
- "name": "设备绑定总表",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "renderBottom(mode",
- "line": 1619
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "基线语义列恒写已绑定;需要真实类型/缺失/冲突反馈。",
- "acceptance": "编辑字段即时同步,空/重复数据不得假标已绑定。",
- "fix": "设备绑定显示真实语义与未设置;校验按钮进入当前检查面板并随绑定变更刷新;日志记录本次运行实际操作,错误详情保持瞬时提示;摘要超过六项明确完整列表位置。",
- "fixIds": [
- "SCENE-F10"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "panel.validation",
- "group": "对象属性、部件与底部面板",
- "name": "底部发布检查面板",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "renderBottom(mode",
- "line": 1619
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "显示当前逐项检查,不等于已发布。",
- "acceptance": "顶部校验/发布失败可定位检查面板,内容随修改更新。",
- "fix": "设备绑定显示真实语义与未设置;校验按钮进入当前检查面板并随绑定变更刷新;日志记录本次运行实际操作,错误详情保持瞬时提示;摘要超过六项明确完整列表位置。",
- "fixIds": [
- "SCENE-F10"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "verify opens live validation and whitespace binding edits immediately invalidate the active tab",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "panel.validation",
- "validation.bindings"
- ],
- "file": "validation.json",
- "title": "verify opens live validation and whitespace binding edits immediately invalidate the active tab",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "panel.logs",
- "group": "对象属性、部件与底部面板",
- "name": "操作日志",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "renderBottom(mode",
- "line": 1619
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "基线为静态示例且误称本地存储;本轮只需真实本次运行日志,不扩展服务端审计。",
- "acceptance": "实际操作产生对应时间/结果;API 模式不显示本地存储为真值。",
- "fix": "设备绑定显示真实语义与未设置;校验按钮进入当前检查面板并随绑定变更刷新;日志记录本次运行实际操作,错误详情保持瞬时提示;摘要超过六项明确完整列表位置。",
- "fixIds": [
- "SCENE-F10"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "activity log reflects actual session events and keeps API error details transient",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "panel.logs"
- ],
- "file": "validation.json",
- "title": "activity log reflects actual session events and keeps API error details transient",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "history.undo",
- "group": "历史与预览",
- "name": "回退按钮 / Ctrl+Z",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async undo()",
- "line": 2417
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "输入连续修改合并成合理历史步;恢复对象/模板/选择。",
- "acceptance": "属性、添加、删除、模板分别撤销,真实画面与文档一致。",
- "fix": "透视按钮实际恢复先前观察位置;导入、加载和历史恢复存在已保存相机时不再被车辆自动聚焦覆盖。;预览状态同步全部操作禁用,Delete/W/E/R 和表单输入遵守预览/权限;失活缓存页忽略全局快捷键,输入框撤销保持文本语义。;文档签名忽略更新时间和对象键顺序;保存后的 undo/redo 根据真实已保存文档判断 dirty;异步恢复失败保留现场并回滚历史索引。",
- "fixIds": [
- "SCENE-F04",
- "SCENE-F05",
- "SCENE-F07"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.undo",
- "history.redo",
- "transform.keys",
- "lifecycle.cache"
- ],
- "file": "validation.json",
- "title": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "loading and history restoration preserve an authored camera rather than auto-focusing a vehicle",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "json.rendering",
- "history.undo"
- ],
- "file": "validation.json",
- "title": "loading and history restoration preserve an authored camera rather than auto-focusing a vehicle",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "save B then undo A stays dirty, and redo B returns to the actual saved baseline",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.undo",
- "history.redo"
- ],
- "file": "validation.json",
- "title": "save B then undo A stays dirty, and redo B returns to the actual saved baseline",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "default history caps at 60 snapshots, stops at either edge and discards redo only after a new branch",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.capacity",
- "history.undo",
- "history.redo"
- ],
- "file": "validation.json",
- "title": "default history caps at 60 snapshots, stops at either edge and discards redo only after a new branch",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "history.redo",
- "group": "历史与预览",
- "name": "前进按钮 / Ctrl+Y / Ctrl+Shift+Z",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async redo()",
- "line": 2437
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "撤销后重做,分叉编辑清 redo。",
- "acceptance": "按钮与两种快捷键各执行;新编辑后旧 redo 不可用。",
- "fix": "预览状态同步全部操作禁用,Delete/W/E/R 和表单输入遵守预览/权限;失活缓存页忽略全局快捷键,输入框撤销保持文本语义。;文档签名忽略更新时间和对象键顺序;保存后的 undo/redo 根据真实已保存文档判断 dirty;异步恢复失败保留现场并回滚历史索引。",
- "fixIds": [
- "SCENE-F05",
- "SCENE-F07"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "recordedAt": "2026-09-06T10:30:32.596Z",
- "kind": "browser",
- "ids": [
- "project.save-key",
- "part.transform",
- "part.soft-delete",
- "history.undo",
- "history.redo",
- "property.name",
- "view.enclosure-full",
- "view.enclosure-xray",
- "view.enclosure-hidden"
- ],
- "file": "evidence/truck-part-history.json",
- "title": "牛奶卡车:刚性部件独立变换、软删除、历史与保存基线一致",
- "details": "实际部件变换和软删除、按钮/键盘历史、保存基线与输入框自身撤销;双实例隔离及车库围护三种模式真实点击、导出和隐藏后保存刷新。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.undo",
- "history.redo",
- "transform.keys",
- "lifecycle.cache"
- ],
- "file": "validation.json",
- "title": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "save B then undo A stays dirty, and redo B returns to the actual saved baseline",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.undo",
- "history.redo"
- ],
- "file": "validation.json",
- "title": "save B then undo A stays dirty, and redo B returns to the actual saved baseline",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "default history caps at 60 snapshots, stops at either edge and discards redo only after a new branch",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.capacity",
- "history.undo",
- "history.redo"
- ],
- "file": "validation.json",
- "title": "default history caps at 60 snapshots, stops at either edge and discards redo only after a new branch",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "history.capacity",
- "group": "历史与预览",
- "name": "60 步历史上限与边界",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "new SceneHistory(60)",
- "line": 180
- },
- "implementation": "已有实现已完成验证",
- "boundary": "历史属于本次编辑会话;不宣称服务端版本历史。",
- "acceptance": "聚焦测试验证 60 步边界、空 undo/redo 与失焦快照。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "default history caps at 60 snapshots, stops at either edge and discards redo only after a new branch",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.capacity",
- "history.undo",
- "history.redo"
- ],
- "file": "validation.json",
- "title": "default history caps at 60 snapshots, stops at either edge and discards redo only after a new branch",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "history.failure",
- "group": "历史与预览",
- "name": "异步历史恢复失败/互斥",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async restoreHistoryState",
- "line": 2328
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "失败不能推进索引或丢当前有效场景;忙碌时写操作需一致。",
- "acceptance": "GLB 恢复失败、并发 undo/redo、保存混入均不半提交。",
- "fix": "文档签名忽略更新时间和对象键顺序;保存后的 undo/redo 根据真实已保存文档判断 dirty;异步恢复失败保留现场并回滚历史索引。",
- "fixIds": [
- "SCENE-F07"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "failed undo restoration retains live objects and keeps the undo target available for retry",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.failure"
- ],
- "file": "validation.json",
- "title": "failed undo restoration retains live objects and keeps the undo target available for retry",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "replacement failure waits for other started loads before restoring the original scene",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.failure",
- "glb.pending"
- ],
- "file": "validation.json",
- "title": "replacement failure waits for other started loads before restoring the original scene",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "preview.enter",
- "group": "历史与预览",
- "name": "进入运行预览",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "togglePreview()",
- "line": 583
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "当前默认预览只展示场景,未接模型 timeline/blueprint 自动执行。",
- "acceptance": "实际进入,辅助选择/手柄状态正常,模型可见。",
- "fix": "预览状态同步全部操作禁用,Delete/W/E/R 和表单输入遵守预览/权限;失活缓存页忽略全局快捷键,输入框撤销保持文本语义。",
- "fixIds": [
- "SCENE-F05"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "recordedAt": "2026-09-06T10:31:05.221Z",
- "kind": "browser",
- "ids": [
- "permission.readonly",
- "permission.update",
- "permission.publish",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "json.export"
- ],
- "file": "evidence/readonly.json",
- "title": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "details": "只读按钮/模板/资源禁写、蒙皮浏览、运行预览与快捷键不变更对象,直接PUT拒绝;具体搜索/鼠标覆盖另见视口用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- },
- {
- "id": "preview.exit",
- "group": "历史与预览",
- "name": "按钮 / Escape 退出预览",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "handleKeyboard(event)",
- "line": 469
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "退出后恢复编辑选择与状态;不得丢未存变换。",
- "acceptance": "两种退出方式均有效,输入焦点与缓存激活行为正确。",
- "fix": "预览状态同步全部操作禁用,Delete/W/E/R 和表单输入遵守预览/权限;失活缓存页忽略全局快捷键,输入框撤销保持文本语义。",
- "fixIds": [
- "SCENE-F05"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "recordedAt": "2026-09-06T10:31:05.221Z",
- "kind": "browser",
- "ids": [
- "permission.readonly",
- "permission.update",
- "permission.publish",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "json.export"
- ],
- "file": "evidence/readonly.json",
- "title": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "details": "只读按钮/模板/资源禁写、蒙皮浏览、运行预览与快捷键不变更对象,直接PUT拒绝;具体搜索/鼠标覆盖另见视口用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "preview locks mutation controls and Delete while Escape restores editing",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "preview.lock",
- "preview.exit"
- ],
- "file": "validation.json",
- "title": "preview locks mutation controls and Delete while Escape restores editing",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "preview.lock",
- "group": "历史与预览",
- "name": "预览中禁止编辑",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "togglePreview()",
- "line": 583
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "显示“场景编辑锁定”必须覆盖属性、删除、模板、导入和快捷键。",
- "acceptance": "尝试所有写入口,预览时文档不改变;退出后正常。",
- "fix": "预览状态同步全部操作禁用,Delete/W/E/R 和表单输入遵守预览/权限;失活缓存页忽略全局快捷键,输入框撤销保持文本语义。",
- "fixIds": [
- "SCENE-F05"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "recordedAt": "2026-09-06T10:31:05.221Z",
- "kind": "browser",
- "ids": [
- "permission.readonly",
- "permission.update",
- "permission.publish",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "json.export"
- ],
- "file": "evidence/readonly.json",
- "title": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "details": "只读按钮/模板/资源禁写、蒙皮浏览、运行预览与快捷键不变更对象,直接PUT拒绝;具体搜索/鼠标覆盖另见视口用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- },
- {
- "status": "PASS",
- "testTitle": "preview locks mutation controls and Delete while Escape restores editing",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "preview.lock",
- "preview.exit"
- ],
- "file": "validation.json",
- "title": "preview locks mutation controls and Delete while Escape restores editing",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "cover.capture",
- "group": "保存封面、发布与依赖",
- "name": "保存时截取当前三维场景封面",
- "source": {
- "file": "../../../unreal_tran_web/src/features/scene-legacy/sceneCoverCapture.ts",
- "symbol": "export async function captureSceneCover",
- "line": 26
- },
- "implementation": "已有实现已完成验证",
- "boundary": "JPEG 最大边 640、当前相机;隐藏手柄/网格/高亮且恢复现场。",
- "acceptance": "截图与服务端图片可辨一致,像素实际有模型,UI 状态不被破坏。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "copies synchronously without bounds, gizmo, grid or selection glow, then restores before JPEG encoding",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "cover.capture",
- "selection.highlight",
- "view.grid"
- ],
- "file": "validation.json",
- "title": "copies synchronously without bounds, gizmo, grid or selection glow, then restores before JPEG encoding",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "cover.atomic",
- "group": "保存封面、发布与依赖",
- "name": "封面资产与文档同次保存",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "saveSceneDocumentWithCover",
- "line": 47
- },
- "implementation": "已有实现已完成验证",
- "boundary": "封面 upload ticket 与 version 同一次 PUT 消费,不另存过期文档。",
- "acceptance": "检查资产/封面字段/当前版本相同,并真实列表加载图片。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "recordedAt": "2026-09-06T10:30:14.385Z",
- "kind": "browser",
- "ids": [
- "project.load",
- "project.title",
- "project.save",
- "selection.tree",
- "property.name",
- "property.visible",
- "property.operable",
- "property.position",
- "property.rotation",
- "property.scale",
- "property.device-id",
- "property.model-id",
- "property.semantic",
- "part.source",
- "panel.binding",
- "cover.capture",
- "cover.atomic"
- ],
- "file": "evidence/fox-properties-cover.json",
- "title": "狐狸:真实细分权限、全部属性、清空绑定、蒙皮保护、相机与封面保存重开",
- "details": "真实字段输入与清空、六个语义选项、蒙皮保护、源模型可见,正文/资产/封面保存和刷新;不把原件旧模板组合当新模板结果。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "scene image ticket, fixed asset replacement, dependencies and coverUri commit in one versioned PUT",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "cover.atomic"
- ],
- "file": "validation.json",
- "title": "scene image ticket, fixed asset replacement, dependencies and coverUri commit in one versioned PUT",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "cover.failure",
- "group": "保存封面、发布与依赖",
- "name": "截图/封面上传失败保留原封面",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "coverFailed",
- "line": 390
- },
- "implementation": "已有实现已完成验证",
- "boundary": "正文可保存时给真实 warning;409 必须阻断且不得覆盖。",
- "acceptance": "截图失败、上传503、PUT409各自核对保留/提示/零错误发布。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "保存失败与封面降级:503 保留草稿,封面上传失败保留旧图,恢复后可重试",
- "recordedAt": "2026-09-06T10:26:33.388Z",
- "kind": "browser",
- "ids": [
- "project.save-failure",
- "cover.failure"
- ],
- "file": "evidence/save-cover-failure.json",
- "title": "保存失败与封面降级:503 保留草稿,封面上传失败保留旧图,恢复后可重试",
- "details": "正文PUT503不清草稿;封面上传503保留旧图但正文可保存;恢复服务后保存刷新。截图异常和409另由聚焦合同验证。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "capture failure saves content with the previous cover and reports a warning result",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "cover.failure"
- ],
- "file": "validation.json",
- "title": "capture failure saves content with the previous cover and reports a warning result",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "upload conflict propagates without any content PUT",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "project.conflict",
- "cover.failure"
- ],
- "file": "validation.json",
- "title": "upload conflict propagates without any content PUT",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "validation.complete",
- "group": "保存封面、发布与依赖",
- "name": "环境、对象用途、模型加载检查",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "verifyScene(showToast",
- "line": 1715
- },
- "implementation": "已有实现已完成验证",
- "boundary": "纯环境允许;模型未完成解析必须阻断。",
- "acceptance": "空地板/纯环境/带模型和加载中分别核对检查结果。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "validation.bindings",
- "group": "保存封面、发布与依赖",
- "name": "设备/物模型编号完整与唯一",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "verifyScene(showToast",
- "line": 1715
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "空白、重复编号按前后端合同处理,不自动替用户分配新业务身份。",
- "acceptance": "空、空格、重复与合法编号;错误项可见,发布被阻断。",
- "fix": "恢复显示名、设备和物模型编号使用空值保留规则,不把显式空串补回旧值;新资源序号跳过既有编号,空白编号校验按 trim 处理。;设备绑定显示真实语义与未设置;校验按钮进入当前检查面板并随绑定变更刷新;日志记录本次运行实际操作,错误详情保持瞬时提示;摘要超过六项明确完整列表位置。",
- "fixIds": [
- "SCENE-F06",
- "SCENE-F10"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "new resource bindings do not reuse a saved serial after earlier objects were deleted",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "validation.bindings"
- ],
- "file": "validation.json",
- "title": "new resource bindings do not reuse a saved serial after earlier objects were deleted",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "verify opens live validation and whitespace binding edits immediately invalidate the active tab",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "panel.validation",
- "validation.bindings"
- ],
- "file": "validation.json",
- "title": "verify opens live validation and whitespace binding edits immediately invalidate the active tab",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "validation.references",
- "group": "保存封面、发布与依赖",
- "name": "受控资源引用完整性",
- "source": {
- "file": "../../../unreal_tran_web/src/features/scene-legacy/serverAssetStore.ts",
- "symbol": "hasReferenceSync",
- "line": 18
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "project/version/assetCode/sourceAssetId 必须指向实际固定资产,不能只测有字段。",
- "acceptance": "不存在编码/错误资产类型/跨项目引用显式拒绝;正确依赖通过。",
- "fix": "前端目录和资源解析同时匹配指定项目、版本、code、id、URI、READY MODEL_FILE;错误引用不回退首文件或本地缓存。仅含 sourceAssetId/assetId 的本项目资源也必须将 ID 纳入缓存/去重键,防止已缓存有效引用掩盖另一个错误ID;失败请求缓存可重试。复制场景保留旧伪 URI 但只读取当前副本资产。;新增 SceneResourceReferenceValidator 检查 objects 和递归 splitParts;自有/固定版本资源的所有显式引用必须指向同一 READY 模型文件,错误引用在发布/提交前阻断,保留受控的内置资源和旧引用兼容。",
- "fixIds": [
- "SCENE-F12",
- "SCENE-F13"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "recordedAt": "2026-09-06T10:26:19.703Z",
- "kind": "browser",
- "ids": [
- "json.export",
- "json.import",
- "json.invalid",
- "json.missing-resource",
- "json.rendering",
- "glb.import",
- "glb.invalid",
- "glb.references",
- "validation.references"
- ],
- "file": "evidence/json-glb-roundtrip.json",
- "title": "工程 JSON 与小 GLB:真实上传、损坏拒绝、引用失败回滚、相机参数往返",
- "details": "真实JSON/GLB文件输入、错误schema/损坏资源/上传503拒绝、错误assetCode回滚、稳定URI及渲染参数保存重开。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "an explicit missing code cannot fall back to the first READY asset",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "validation.references",
- "json.missing-resource"
- ],
- "file": "validation.json",
- "title": "an explicit missing code cannot fall back to the first READY asset",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "publish.saved",
- "group": "保存封面、发布与依赖",
- "name": "发布场景按钮的真实 API 闭环",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async publishScene()",
- "line": 2213
- },
- "implementation": "已有实现已完成验证",
- "boundary": "有编辑权时先保存含封面再发布;两步均成功才显示已发布。",
- "acceptance": "POST 真正发布当前版本,列表状态与下游目录一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "publish.only",
- "group": "保存封面、发布与依赖",
- "name": "只有发布权限时发布已存版本",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "if (this.readOnly)",
- "line": 335
- },
- "implementation": "已有实现已完成验证",
- "boundary": "publish-only 不先 PUT、不上传封面、不要求 update;服务器校验真值。",
- "acceptance": "隔离权限会话发布已存有效版本,零 update/upload 请求。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "仅场景发布权限:浏览器发布已存副本,不发送保存或上传请求",
- "recordedAt": "2026-09-06T10:25:19.519Z",
- "kind": "browser",
- "ids": [
- "permission.publish",
- "publish.only",
- "publish.fixed-model"
- ],
- "file": "evidence/scene-publish-only.json",
- "title": "仅场景发布权限:浏览器发布已存副本,不发送保存或上传请求",
- "details": "",
- "screenshots": []
- }
- ]
- },
- {
- "id": "publish.failure",
- "group": "保存封面、发布与依赖",
- "name": "预检/保存/发布失败阻断",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "async publishScene()",
- "line": 2213
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "保存失败不 POST 发布;发布失败不假标已发布;保持错误恢复能力。",
- "acceptance": "预检错误、PUT409/503、POST失败及重试,版本/状态准确。",
- "fix": "新增 SceneResourceReferenceValidator 检查 objects 和递归 splitParts;自有/固定版本资源的所有显式引用必须指向同一 READY 模型文件,错误引用在发布/提交前阻断,保留受控的内置资源和旧引用兼容。",
- "fixIds": [
- "SCENE-F13"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "publish.concurrent",
- "group": "保存封面、发布与依赖",
- "name": "重复发布与上传/保存队列",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "publishDocument:",
- "line": 509
- },
- "implementation": "已有实现已完成验证",
- "boundary": "整条 POST 完成前仍占 FIFO;重复操作不串版本。",
- "acceptance": "延迟上传/保存/发布并触发竞争,服务端只有完整合法版本。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "role switch waits through validation, save, and the later queued publish after dirty clears",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "publish.concurrent",
- "leave.busy",
- "leave.role-switch"
- ],
- "file": "validation.json",
- "title": "role switch waits through validation, save, and the later queued publish after dirty clears",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "project operation queue serializes upload, save and publish including failures",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "publish.concurrent"
- ],
- "file": "validation.json",
- "title": "project operation queue serializes upload, save and publish including failures",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "publish.fixed-model",
- "group": "保存封面、发布与依赖",
- "name": "固定 SCENE_MODEL 版本与多个实例",
- "source": {
- "file": "../../../unreal_tran_web/src/features/scene-legacy/contentApiClient.ts",
- "symbol": "collectSceneModelDependencies",
- "line": 938
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "去重精确模型版本,不能随模型新发布静默换源版本。",
- "acceptance": "同模型多实例及另模型新版本,场景重开仍使用所存固定版本。",
- "fix": "前端目录和资源解析同时匹配指定项目、版本、code、id、URI、READY MODEL_FILE;错误引用不回退首文件或本地缓存。仅含 sourceAssetId/assetId 的本项目资源也必须将 ID 纳入缓存/去重键,防止已缓存有效引用掩盖另一个错误ID;失败请求缓存可重试。复制场景保留旧伪 URI 但只读取当前副本资产。;新增 SceneResourceReferenceValidator 检查 objects 和递归 splitParts;自有/固定版本资源的所有显式引用必须指向同一 READY 模型文件,错误引用在发布/提交前阻断,保留受控的内置资源和旧引用兼容。;完整 PUT 回写原有相同 SCENE_MODEL 三元组时沿用场景授权边界;新增或改版依赖仍要求来源模型可见及范围权限,不扩大模型页面访问权。;新实例部件 sceneId 包含所属根对象身份,不再直接复用来源模型部件 ID;源 interaction/editor 标识保留。旧单实例 ID 保留,旧文档重复 ID 仅按文档顺序迁移后续冲突实例并同步 override。第二完整轮进一步发现 GLB 并发完成顺序会改变根对象顺序;现等待 allSettled 成功后按原文档顺序排列恢复根对象,拆分模板返回数组内部顺序和既有对象均保留,同源两实例不再随网速互换列表位置。新增延迟 30/1/10ms 乱序加载合同,验证序列化仍按文档顺序;最终浏览器验证独立记录。",
- "fixIds": [
- "SCENE-F12",
- "SCENE-F13",
- "SCENE-F14",
- "SCENE-F18"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "recordedAt": "2026-09-06T10:27:04.782Z",
- "kind": "browser",
- "ids": [
- "validation.complete",
- "validation.bindings",
- "panel.validation",
- "publish.saved",
- "publish.failure",
- "publish.fixed-model",
- "cover.atomic",
- "project.back"
- ],
- "file": "evidence/publish-fixed-version.json",
- "title": "发布:前端绑定校验、保存与发布失败阻断、真实固定版本供训练目录使用",
- "details": "实际校验、绑定阻断、POST503不假发布,重试发布当前固定版本;返回列表保留编辑标签,搜索当前项目并核对真实封面图片加载。下游静态渲染另有独立用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "仅场景发布权限:浏览器发布已存副本,不发送保存或上传请求",
- "recordedAt": "2026-09-06T10:25:19.519Z",
- "kind": "browser",
- "ids": [
- "permission.publish",
- "publish.only",
- "publish.fixed-model"
- ],
- "file": "evidence/scene-publish-only.json",
- "title": "仅场景发布权限:浏览器发布已存副本,不发送保存或上传请求",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "仅场景编辑权限:固定模型可加载和保存,不能发布或访问模型页面",
- "recordedAt": "2026-09-06T10:25:11.741Z",
- "kind": "browser",
- "ids": [
- "permission.update",
- "permission.publish",
- "publish.fixed-model"
- ],
- "file": "evidence/scene-update-only.json",
- "title": "仅场景编辑权限:固定模型可加载和保存,不能发布或访问模型页面",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "legacy duplicate instance IDs migrate only later owners in document order despite reversed GLB completion",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "part.transform",
- "publish.fixed-model"
- ],
- "file": "validation.json",
- "title": "legacy duplicate instance IDs migrate only later owners in document order despite reversed GLB completion",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "fixed model reads the exact version and downloads through its visible scene dependency",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "publish.fixed-model",
- "permission.update"
- ],
- "file": "validation.json",
- "title": "fixed model reads the exact version and downloads through its visible scene dependency",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "fixed model dependencies are recursively collected, exact and de-duplicated",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "publish.fixed-model"
- ],
- "file": "validation.json",
- "title": "fixed model dependencies are recursively collected, exact and de-duplicated",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "publish.downstream",
- "group": "保存封面、发布与依赖",
- "name": "发布场景供训练选择和静态还原",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "场景已发布,训练编排可以引用",
- "line": 2227
- },
- "implementation": "已有实现已完成验证",
- "boundary": "本轮只验证版本/目标/静态可见性;不承诺模型蓝图或原生动画自动执行。",
- "acceptance": "新场景出现在正式训练目录,绑定后狐狸/卡车可见且目标身份一致。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "fox:场景发布后在真实训练编排选择、保存并重开静态模型",
- "recordedAt": "2026-09-06T10:24:43.055Z",
- "kind": "browser",
- "ids": [
- "publish.downstream"
- ],
- "file": "evidence/downstream-fox.json",
- "title": "fox:场景发布后在真实训练编排选择、保存并重开静态模型",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "truck:场景发布后在真实训练编排选择、保存并重开静态模型",
- "recordedAt": "2026-09-06T10:25:01.457Z",
- "kind": "browser",
- "ids": [
- "publish.downstream"
- ],
- "file": "evidence/downstream-truck.json",
- "title": "truck:场景发布后在真实训练编排选择、保存并重开静态模型",
- "details": "",
- "screenshots": []
- }
- ]
- },
- {
- "id": "permission.update",
- "group": "权限、缓存与未保存恢复",
- "name": "场景细分编辑权限",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "this.readOnly =",
- "line": 149
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "只按 content.scene.update;基线残留 content.update 需修,不由角色名推断。",
- "acceptance": "具更新权会话可编辑;无更新权的写入口和接口全部拒绝。",
- "fix": "移除 runtime 旧 content.update 门槛,独立计算新建、更新和发布;无模型页面权限时不加载新模型目录,但既有固定依赖仍可按场景授权读取。;完整 PUT 回写原有相同 SCENE_MODEL 三元组时沿用场景授权边界;新增或改版依赖仍要求来源模型可见及范围权限,不扩大模型页面访问权。",
- "fixIds": [
- "SCENE-F01",
- "SCENE-F14"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "recordedAt": "2026-09-06T10:31:05.221Z",
- "kind": "browser",
- "ids": [
- "permission.readonly",
- "permission.update",
- "permission.publish",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "json.export"
- ],
- "file": "evidence/readonly.json",
- "title": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "details": "只读按钮/模板/资源禁写、蒙皮浏览、运行预览与快捷键不变更对象,直接PUT拒绝;具体搜索/鼠标覆盖另见视口用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "仅场景编辑权限:固定模型可加载和保存,不能发布或访问模型页面",
- "recordedAt": "2026-09-06T10:25:11.741Z",
- "kind": "browser",
- "ids": [
- "permission.update",
- "permission.publish",
- "publish.fixed-model"
- ],
- "file": "evidence/scene-update-only.json",
- "title": "仅场景编辑权限:固定模型可加载和保存,不能发布或访问模型页面",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "scene granular update permission enables editing without the retired shared code",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "permission.update"
- ],
- "file": "validation.json",
- "title": "scene granular update permission enables editing without the retired shared code",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "fixed model reads the exact version and downloads through its visible scene dependency",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "publish.fixed-model",
- "permission.update"
- ],
- "file": "validation.json",
- "title": "fixed model reads the exact version and downloads through its visible scene dependency",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "permission.publish",
- "group": "权限、缓存与未保存恢复",
- "name": "场景细分发布权限",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "this.canPublish =",
- "line": 152
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "页面 content.scene 与 publish 动作分开;更新权不隐含发布。",
- "acceptance": "只更新不能发布;仅发布可发布已存版本;无页面权不可访问。",
- "fix": "移除 runtime 旧 content.update 门槛,独立计算新建、更新和发布;无模型页面权限时不加载新模型目录,但既有固定依赖仍可按场景授权读取。",
- "fixIds": [
- "SCENE-F01"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "recordedAt": "2026-09-06T10:31:05.221Z",
- "kind": "browser",
- "ids": [
- "permission.readonly",
- "permission.update",
- "permission.publish",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "json.export"
- ],
- "file": "evidence/readonly.json",
- "title": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "details": "只读按钮/模板/资源禁写、蒙皮浏览、运行预览与快捷键不变更对象,直接PUT拒绝;具体搜索/鼠标覆盖另见视口用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "无场景页面权限:编辑路由和直接内容接口均拒绝访问",
- "recordedAt": "2026-09-06T10:25:24.402Z",
- "kind": "browser",
- "ids": [
- "permission.publish"
- ],
- "file": "evidence/scene-no-page-permission.json",
- "title": "无场景页面权限:编辑路由和直接内容接口均拒绝访问",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "仅场景发布权限:浏览器发布已存副本,不发送保存或上传请求",
- "recordedAt": "2026-09-06T10:25:19.519Z",
- "kind": "browser",
- "ids": [
- "permission.publish",
- "publish.only",
- "publish.fixed-model"
- ],
- "file": "evidence/scene-publish-only.json",
- "title": "仅场景发布权限:浏览器发布已存副本,不发送保存或上传请求",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "仅场景编辑权限:固定模型可加载和保存,不能发布或访问模型页面",
- "recordedAt": "2026-09-06T10:25:11.741Z",
- "kind": "browser",
- "ids": [
- "permission.update",
- "permission.publish",
- "publish.fixed-model"
- ],
- "file": "evidence/scene-update-only.json",
- "title": "仅场景编辑权限:固定模型可加载和保存,不能发布或访问模型页面",
- "details": "",
- "screenshots": []
- }
- ]
- },
- {
- "id": "permission.readonly",
- "group": "权限、缓存与未保存恢复",
- "name": "只读仍可查看、搜索、选中和预览",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "applyAccessMode()",
- "line": 198
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "禁写不应误禁观察控件;临时视图不保存到服务器。",
- "acceptance": "真实键盘搜索、选择、相机、预览,零内容写请求。",
- "fix": "移除 runtime 旧 content.update 门槛,独立计算新建、更新和发布;无模型页面权限时不加载新模型目录,但既有固定依赖仍可按场景授权读取。",
- "fixIds": [
- "SCENE-F01"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "recordedAt": "2026-09-06T10:31:05.221Z",
- "kind": "browser",
- "ids": [
- "permission.readonly",
- "permission.update",
- "permission.publish",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "json.export"
- ],
- "file": "evidence/readonly.json",
- "title": "只读管理员:可浏览预览与导出,模板/资源/键盘/接口不能改场景",
- "details": "只读按钮/模板/资源禁写、蒙皮浏览、运行预览与快捷键不变更对象,直接PUT拒绝;具体搜索/鼠标覆盖另见视口用例。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "recordedAt": "2026-09-06T10:25:39.438Z",
- "kind": "browser",
- "ids": [
- "leave.role-switch",
- "leave.cancel",
- "leave.save",
- "permission.readonly"
- ],
- "file": "evidence/scene-role-switch.json",
- "title": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "details": "",
- "screenshots": []
- }
- ]
- },
- {
- "id": "recovery.autobuffer",
- "group": "权限、缓存与未保存恢复",
- "name": "800ms 未保存恢复缓冲",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "markDirty(label",
- "line": 654
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "仅写隔离浏览器恢复稿,不伪称自动入库。",
- "acceptance": "实际修改后等待,恢复稿存在但无自动 PUT;手动保存后入库。",
- "fix": "顶部新建委托宿主命名与创建 API,先确认未保存内容。选择放弃也要等创建及导航成功后才清除原 dirty/恢复稿;创建503仍保留原稿。成功后刷新原缓存页,避免再次打开时将已放弃修改冒称已保存。取消、失败不清原场景,成功导航到新项目 ID,并有创建并发守卫。;开始保存时取消之前安排的恢复稿定时器,避免它覆盖宿主保存快照 nonce;保存中的后续编辑仍单独保留。",
- "fixIds": [
- "SCENE-F02",
- "SCENE-F08"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "recordedAt": "2026-09-06T10:26:49.585Z",
- "kind": "browser",
- "ids": [
- "project.conflict",
- "recovery.autobuffer",
- "recovery.same-version",
- "recovery.stale-version"
- ],
- "file": "evidence/real-recovery-conflict.json",
- "title": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "details": "真实未存输入产生恢复稿,同版本恢复不自动入库;另一版本先保存后409拒绝覆盖,旧稿隔离下载。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "recordedAt": "2026-09-06T10:24:27.147Z",
- "kind": "browser",
- "ids": [
- "project.concurrent-save",
- "project.save",
- "project.save-key",
- "recovery.autobuffer",
- "recovery.same-version"
- ],
- "file": "evidence/save-concurrency.json",
- "title": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "details": "延迟真实PUT快照A、重复Ctrl+S不重复请求、期间编辑B仍dirty;再次保存刷新无旧恢复稿误报。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "recordedAt": "2026-09-06T10:25:56.822Z",
- "kind": "browser",
- "ids": [
- "recovery.multi-session",
- "recovery.autobuffer",
- "recovery.discard",
- "project.save"
- ],
- "file": "evidence/scene-multi-session.json",
- "title": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "details": "",
- "screenshots": []
- }
- ]
- },
- {
- "id": "recovery.same-version",
- "group": "权限、缓存与未保存恢复",
- "name": "同版本真实未保存恢复",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "sceneRecoveryMatchesProjectVersion",
- "line": 46
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "先回到视口,须显式保存才入库;相同文档不应产生假恢复。",
- "acceptance": "真实修改后刷新,恢复/保存/再刷新;无注入假 localStorage 代替。",
- "fix": "文档签名忽略更新时间和对象键顺序;保存后的 undo/redo 根据真实已保存文档判断 dirty;异步恢复失败保留现场并回滚历史索引。;开始保存时取消之前安排的恢复稿定时器,避免它覆盖宿主保存快照 nonce;保存中的后续编辑仍单独保留。",
- "fixIds": [
- "SCENE-F07",
- "SCENE-F08"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "recordedAt": "2026-09-06T10:26:49.585Z",
- "kind": "browser",
- "ids": [
- "project.conflict",
- "recovery.autobuffer",
- "recovery.same-version",
- "recovery.stale-version"
- ],
- "file": "evidence/real-recovery-conflict.json",
- "title": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "details": "真实未存输入产生恢复稿,同版本恢复不自动入库;另一版本先保存后409拒绝覆盖,旧稿隔离下载。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "recordedAt": "2026-09-06T10:24:27.147Z",
- "kind": "browser",
- "ids": [
- "project.concurrent-save",
- "project.save",
- "project.save-key",
- "recovery.autobuffer",
- "recovery.same-version"
- ],
- "file": "evidence/save-concurrency.json",
- "title": "延迟保存快照:重复点击只提交一次,期间新编辑保留,旧恢复稿不会误报冲突",
- "details": "延迟真实PUT快照A、重复Ctrl+S不重复请求、期间编辑B仍dirty;再次保存刷新无旧恢复稿误报。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "recovery.stale-version",
- "group": "权限、缓存与未保存恢复",
- "name": "不同版本恢复稿隔离",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "sceneRecoveryMatchesProjectVersion",
- "line": 46
- },
- "implementation": "已有实现已完成验证",
- "boundary": "旧稿不能自动覆盖新服务器版本;下载供人工合并。",
- "acceptance": "另一会话先保存,新会话面对旧稿只能下载/隔离/明确丢弃。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "recordedAt": "2026-09-06T10:26:49.585Z",
- "kind": "browser",
- "ids": [
- "project.conflict",
- "recovery.autobuffer",
- "recovery.same-version",
- "recovery.stale-version"
- ],
- "file": "evidence/real-recovery-conflict.json",
- "title": "同版本恢复与 409:真实未保存草稿重载、服务器新版本保护与隔离下载",
- "details": "真实未存输入产生恢复稿,同版本恢复不自动入库;另一版本先保存后409拒绝覆盖,旧稿隔离下载。",
- "screenshots": []
- }
- ]
- },
- {
- "id": "recovery.discard",
- "group": "权限、缓存与未保存恢复",
- "name": "下载、保留、丢弃恢复稿",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "async function quarantineRecovery",
- "line": 223
- },
- "implementation": "已有实现已完成验证",
- "boundary": "关闭/Escape 不算明确丢弃;他会话新写入稿不得被误删。",
- "acceptance": "按钮逐项核对本地隔离键、下载文件与服务器无意外写入。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "recordedAt": "2026-09-06T10:25:56.822Z",
- "kind": "browser",
- "ids": [
- "recovery.multi-session",
- "recovery.autobuffer",
- "recovery.discard",
- "project.save"
- ],
- "file": "evidence/scene-multi-session.json",
- "title": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "recovery conflict defaults to preserve and only explicit discard may remove it",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "recovery.discard"
- ],
- "file": "validation.json",
- "title": "recovery conflict defaults to preserve and only explicit discard may remove it",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "recovery.multi-session",
- "group": "权限、缓存与未保存恢复",
- "name": "多标签/多会话恢复所有权",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "recoveryStoragePrefix",
- "line": 104
- },
- "implementation": "已有实现已完成验证",
- "boundary": "会话键/nonce/锁避免覆盖别的未存稿;本地缓冲不冒充权限。",
- "acceptance": "两个编辑会话产生不同草稿,保存/丢弃一份不删另一份。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "recordedAt": "2026-09-06T10:25:56.822Z",
- "kind": "browser",
- "ids": [
- "recovery.multi-session",
- "recovery.autobuffer",
- "recovery.discard",
- "project.save"
- ],
- "file": "evidence/scene-multi-session.json",
- "title": "双标签各自修改场景:保存和明确丢弃当前页均保留另一页真实恢复稿",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "per-page recovery keys prevent copied tabs from deleting each other checkpoints",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "recovery.multi-session"
- ],
- "file": "validation.json",
- "title": "per-page recovery keys prevent copied tabs from deleting each other checkpoints",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "leave.cancel",
- "group": "权限、缓存与未保存恢复",
- "name": "关闭场景标签时取消离开",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "async function confirmLeave",
- "line": 704
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "关闭确认保留当前 dirty 与恢复副本;返回列表或切普通标签不应提示。",
- "acceptance": "真实关闭确认的关闭/Escape、继续编辑,数据未丢;不把返回列表当关闭。",
- "fix": "关闭单个或批量场景标签先按目标调用缓存守卫;取消或后续保存失败不提交此前放弃决定,全部确认后才关闭并清理。返回列表仍保留缓存,不扩展为强制关闭。",
- "fixIds": [
- "SCENE-F16"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "recordedAt": "2026-09-06T10:25:39.438Z",
- "kind": "browser",
- "ids": [
- "leave.role-switch",
- "leave.cancel",
- "leave.save",
- "permission.readonly"
- ],
- "file": "evidence/scene-role-switch.json",
- "title": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "closing one selected scene checks its cached guard, leaves unrelated workspaces alone",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.cancel",
- "lifecycle.cache"
- ],
- "file": "validation.json",
- "title": "closing one selected scene checks its cached guard, leaves unrelated workspaces alone",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "cancel or failed save in a later tab never commits earlier draft discard",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.cancel",
- "leave.save",
- "leave.role-switch"
- ],
- "file": "validation.json",
- "title": "cancel or failed save in a later tab never commits earlier draft discard",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "leave.save",
- "group": "权限、缓存与未保存恢复",
- "name": "保存并离开 / 放弃修改",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "async function confirmLeave",
- "line": 704
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "等待保存完成并确认最终 dirty;明确放弃只影响当前工程会话。",
- "acceptance": "保存成功才离开;503/409留原页;放弃按确认执行。",
- "fix": "关闭单个或批量场景标签先按目标调用缓存守卫;取消或后续保存失败不提交此前放弃决定,全部确认后才关闭并清理。返回列表仍保留缓存,不扩展为强制关闭。",
- "fixIds": [
- "SCENE-F16"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "recordedAt": "2026-09-06T10:25:39.438Z",
- "kind": "browser",
- "ids": [
- "leave.role-switch",
- "leave.cancel",
- "leave.save",
- "permission.readonly"
- ],
- "file": "evidence/scene-role-switch.json",
- "title": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "cancel or failed save in a later tab never commits earlier draft discard",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.cancel",
- "leave.save",
- "leave.role-switch"
- ],
- "file": "validation.json",
- "title": "cancel or failed save in a later tab never commits earlier draft discard",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "all successful confirmations commit together and unmounted guards are removed",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.save",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "all successful confirmations commit together and unmounted guards are removed",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "leave.busy",
- "group": "权限、缓存与未保存恢复",
- "name": "加载/上传/发布途中离开",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "const resourcesBusy =",
- "line": 708
- },
- "implementation": "已有实现已完成验证",
- "boundary": "资源未就绪阻止离开;进行中的保存/发布须等待最终结果。",
- "acceptance": "延迟资源与提交各验证取消/等待,旧请求不污染新项目。",
- "fix": "尚未关联本轮修复记录",
- "fixIds": [],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "加载失败重试与加载互斥:不展示可写半场景、恢复网络后模型完整加载",
- "recordedAt": "2026-09-06T10:24:14.518Z",
- "kind": "browser",
- "ids": [
- "project.retry",
- "glb.pending",
- "leave.busy"
- ],
- "file": "evidence/loading-retry.json",
- "title": "加载失败重试与加载互斥:不展示可写半场景、恢复网络后模型完整加载",
- "details": "GET503只留中性失败和重试;延迟受控下载时禁用写入/导出/预览并阻止关闭,释放后真实狐狸加载。",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "role switch waits through validation, save, and the later queued publish after dirty clears",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "publish.concurrent",
- "leave.busy",
- "leave.role-switch"
- ],
- "file": "validation.json",
- "title": "role switch waits through validation, save, and the later queued publish after dirty clears",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "role switch rechecks resource uploads started while the save was finishing",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.busy"
- ],
- "file": "validation.json",
- "title": "role switch rechecks resource uploads started while the save was finishing",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "leave.role-switch",
- "group": "权限、缓存与未保存恢复",
- "name": "角色切换覆盖后台场景未存稿",
- "source": {
- "file": "../../../unreal_tran_web/src/views/content/LegacyScenePageView.vue",
- "symbol": "registerWorkspaceLeaveGuard",
- "line": 2
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "全体守卫确认后才切角色;后一页取消不能抹掉前页 dirty。",
- "acceptance": "含后台场景的切角色确认取消/保存失败/成功后权限重建。",
- "fix": "关闭单个或批量场景标签先按目标调用缓存守卫;取消或后续保存失败不提交此前放弃决定,全部确认后才关闭并清理。返回列表仍保留缓存,不扩展为强制关闭。",
- "fixIds": [
- "SCENE-F16"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "recordedAt": "2026-09-06T10:25:39.438Z",
- "kind": "browser",
- "ids": [
- "leave.role-switch",
- "leave.cancel",
- "leave.save",
- "permission.readonly"
- ],
- "file": "evidence/scene-role-switch.json",
- "title": "后台场景未保存时切换角色:关闭确认保留草稿,保存切换后重建只读权限",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "cancel or failed save in a later tab never commits earlier draft discard",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.cancel",
- "leave.save",
- "leave.role-switch"
- ],
- "file": "validation.json",
- "title": "cancel or failed save in a later tab never commits earlier draft discard",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "role switch waits through validation, save, and the later queued publish after dirty clears",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "publish.concurrent",
- "leave.busy",
- "leave.role-switch"
- ],
- "file": "validation.json",
- "title": "role switch waits through validation, save, and the later queued publish after dirty clears",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "lifecycle.cache",
- "group": "权限、缓存与未保存恢复",
- "name": "标签失活 pause / 激活 resume",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "pause()",
- "line": 523
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "停止后台 RAF、恢复时重算视口;后台实例不能抢当前页键盘。",
- "acceptance": "两场景标签切换、选择和未存值保留、后台无写/快捷键误动作。",
- "fix": "顶部新建委托宿主命名与创建 API,先确认未保存内容。选择放弃也要等创建及导航成功后才清除原 dirty/恢复稿;创建503仍保留原稿。成功后刷新原缓存页,避免再次打开时将已放弃修改冒称已保存。取消、失败不清原场景,成功导航到新项目 ID,并有创建并发守卫。;预览状态同步全部操作禁用,Delete/W/E/R 和表单输入遵守预览/权限;失活缓存页忽略全局快捷键,输入框撤销保持文本语义。;关闭单个或批量场景标签先按目标调用缓存守卫;取消或后续保存失败不提交此前放弃决定,全部确认后才关闭并清理。返回列表仍保留缓存,不扩展为强制关闭。",
- "fixIds": [
- "SCENE-F02",
- "SCENE-F05",
- "SCENE-F16"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "缓存标签暂停键盘、草稿恢复以及关闭取消和保存失败留页",
- "recordedAt": "2026-09-06T10:30:03.089Z",
- "kind": "真实UI缓存/关闭+浏览器模拟503拒绝写入",
- "ids": [
- "lifecycle.cache"
- ],
- "file": "evidence/viewport-cache-close.json",
- "title": "缓存标签暂停键盘、草稿恢复以及关闭取消和保存失败留页",
- "details": "",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "history.undo",
- "history.redo",
- "transform.keys",
- "lifecycle.cache"
- ],
- "file": "validation.json",
- "title": "typing undo/redo stays inside text controls and inactive cached editors ignore global shortcuts",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "closing one selected scene checks its cached guard, leaves unrelated workspaces alone",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.cancel",
- "lifecycle.cache"
- ],
- "file": "validation.json",
- "title": "closing one selected scene checks its cached guard, leaves unrelated workspaces alone",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "lifecycle.destroy",
- "group": "权限、缓存与未保存恢复",
- "name": "关闭释放 WebGL/监听/资源",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "destroy()",
- "line": 421
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "销毁后的异步回调无 DOM 写入,无残留全局事件和资产 URL。",
- "acceptance": "反复打开/关闭、加载中关闭边界,控制台无异常/泄漏事件。",
- "fix": "射线候选逐级检查父级可见性和软删除;删除根对象先恢复高亮材质再释放几何/材质,避免错误拾取及 GPU 资源残留。;关闭单个或批量场景标签先按目标调用缓存守卫;取消或后续保存失败不提交此前放弃决定,全部确认后才关闭并清理。返回列表仍保留缓存,不扩展为强制关闭。",
- "fixIds": [
- "SCENE-F09",
- "SCENE-F16"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "deleting a root disposes its geometry and materials after clearing selection",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "object.delete",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "deleting a root disposes its geometry and materials after clearing selection",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "selection highlight cleanup restores source materials and releases its own GPU helper",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "selection.highlight",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "selection highlight cleanup restores source materials and releases its own GPU helper",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "all successful confirmations commit together and unmounted guards are removed",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "leave.save",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "all successful confirmations commit together and unmounted guards are removed",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- },
- {
- "status": "PASS",
- "testTitle": "an upload finishing after a project switch cannot register into the new session",
- "kind": "unit",
- "runId": "scene-editor-2026-09-06T10:24:04.121Z",
- "ids": [
- "glb.pending",
- "lifecycle.destroy"
- ],
- "file": "validation.json",
- "title": "an upload finishing after a project switch cannot register into the new session",
- "details": "实际执行真实方法/纯函数合同,未冒称浏览器操作",
- "screenshots": []
- }
- ]
- },
- {
- "id": "lifecycle.resize-theme",
- "group": "权限、缓存与未保存恢复",
- "name": "桌面尺寸与明亮/暗黑可读性",
- "source": {
- "file": "../../../unreal_tran_web/src/features/guide-legacy/demo-src/scene-editor.js",
- "symbol": "resize()",
- "line": 414
- },
- "implementation": "本轮修复已完成验证",
- "boundary": "继承正式主题;所有可达控件可读、无截断遮挡。",
- "acceptance": "1920/1440 下工具栏、属性、模板与弹窗截图,主题切换无低对比。",
- "fix": "原型 CSS 全局重置收敛到场景作用域,降低按钮重置优先级;侧栏、输入、模板、属性和摘要使用正式主题变量,修复白字白底;修复 1440 宽时长工具栏/画布撑开网格覆盖属性栏。",
- "fixIds": [
- "SCENE-F15"
- ],
- "verification": "PASS",
- "evidence": [
- {
- "status": "PASS",
- "testTitle": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "recordedAt": "2026-09-06T10:29:44.118Z",
- "kind": "真实UI+只读投影",
- "ids": [
- "view.orbit",
- "view.pan",
- "view.zoom",
- "view.top",
- "view.perspective",
- "view.grid",
- "view.focus",
- "selection.viewport",
- "selection.highlight",
- "preview.enter",
- "preview.exit",
- "preview.lock",
- "lifecycle.resize-theme"
- ],
- "file": "evidence/viewport-camera-theme.json",
- "title": "真实相机操控、视口拾取、预览禁写和两尺寸主题可读性",
- "details": "",
- "screenshots": [
- "40-viewport-dark-1920",
- "41-viewport-light-1440",
- "42-fox-preview-original-material"
- ]
- }
- ]
- }
- ]
- }
|