Browse Source

chore(content): remove unreferenced legacy authoring projects

main
leiyun 5 hours ago
parent
commit
e1cc53f816
11 changed files with 3697 additions and 0 deletions
  1. +35
    -0
      reports/bridge-content-cleanup-20260925/README.md
  2. +203
    -0
      reports/bridge-content-cleanup-20260925/deleted-unreferenced.json
  3. +12
    -0
      reports/bridge-content-cleanup-20260925/index.html
  4. +925
    -0
      reports/bridge-content-cleanup-20260925/inventory-before.json
  5. +11
    -0
      reports/bridge-content-cleanup-20260925/list-verification.json
  6. BIN
     
  7. +2363
    -0
      reports/bridge-content-cleanup-20260925/plan.json
  8. BIN
     
  9. BIN
     
  10. +88
    -0
      reports/bridge-content-cleanup-20260925/unreferenced-verification.json
  11. +60
    -0
      tools/bridge-content-cleanup-20260925.mjs

+ 35
- 0
reports/bridge-content-cleanup-20260925/README.md View File

@@ -0,0 +1,35 @@
# 005~008 内容目录清理(第一阶段)

时间:2026-09-25。环境:本地 Web 6180,经 Gateway 6100;root 维护账号。

用户要求模型制作、场景制作、训练编排仅保留 005~008 相关内容。现有删除接口会软删除工程、版本和资产记录,并拒绝删除仍被其他内容或教学任务引用的工程。

## 已完成

- 核对 13 个模型、14 个场景、38 个编排及 12 份作业指导书。
- 清理前备份全部 77 个工程的详情、版本、依赖及资产元数据;未删除资产二进制文件。
- 通过正式内容接口撤回并软删除 28 个无保留业务引用的工程:2 个模型、3 个场景、23 个编排。每次写入使用版本校验,服务端记录审计。
- 剩余列表为 11 个模型、11 个场景、15 个编排。
- 逐项核对保留的 14 个相关工程及 5 个固定教学入口,内容与清理前一致。

## 保留范围

四组制作链:模型 466/468/470/472、场景 467/469/471/473、编排 438/439/440/441。

先前 005 验证链(场景 457、编排 458、任务 116)与 005 相关,亦予保留;原任务 86~89 未改动。

## 待用户选择的范围

另有 23 个非 005~008 工程因直接或间接引用暂未处理。其中 18 个工程直接关联 27 个旧教学任务或 3 份作业指导书,其余 5 个是上述业务的依赖。

已询问用户:将这些工程移出制作列表但保留旧任务/指导书可用,或连同关联旧任务/指导书一起清理。此次授权只指定三个制作列表,尚未扩大到删除教学任务、成绩或指导书。**当前不是全部清理完成。**

## 记录与恢复依据

- `plan.json`:保留项、候选项、全部历史依赖和跨范围引用。
- `deleted-unreferenced.json`:28 个已删工程、执行时间和备份 SHA-256。
- `unreferenced-verification.json`:第一阶段清理后的数量与未变更校验。
- `inventory-before.json`:脱敏的清理前目录清单,不含任务定义、成员或鉴权信息。
- 完整备份仅保存在本机 `E:/work/edit_3d/.codex-tmp/bridge-content-cleanup-20260925/`,包含原工程与全部版本,可供恢复核对;未提交完整业务快照到 Git。

工具 `tools/bridge-content-cleanup-20260925.mjs` 默认只列出固定审计清单;仅显式 `--apply-unreferenced` 执行该清单中无引用项。不会自动删除后来新增的工程。已完成项按执行记录跳过;并发版本变化会停止执行。

+ 203
- 0
reports/bridge-content-cleanup-20260925/deleted-unreferenced.json View File

@@ -0,0 +1,203 @@
{
"startedAt": "2026-09-24T17:56:24.904Z",
"deleted": [
{
"id": "436",
"name": "CL-mode1",
"type": "MODEL",
"deletedAt": "2026-09-24T17:56:25.290Z",
"backupSha256": "0ef507457408becc7de3925b13d6612b2163f968a55cdab3dde1d79e251b3312"
},
{
"id": "155",
"name": "测试",
"type": "MODEL",
"deletedAt": "2026-09-24T17:56:25.675Z",
"backupSha256": "260e2e49b064d45d3c720a1d403043fc0ffa9e7d003529aab83277018e3201df"
},
{
"id": "432",
"name": "HTML服务端编排-mtyissgj",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:26.128Z",
"backupSha256": "9f353ddcb5b90017e82bcd6668038b86d554bea54ebb681b0d88d4000c660703"
},
{
"id": "435",
"name": "HTML服务端编排-mtyjtx1p",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:26.698Z",
"backupSha256": "b757d1c6a3cc3c872145f592e3d944956324c26f21d72875e054ed2c7b002ff0"
},
{
"id": "434",
"name": "HTML闭环验收-mtyjgaok",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:27.238Z",
"backupSha256": "fb4d3f3be7cc3dcf659c5b666c84567683ae3570523aae461a8e1d09f627ae3a"
},
{
"id": "433",
"name": "HTML服务端编排-mtyjd8w5",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:27.760Z",
"backupSha256": "8aadf6d62ea56c8cfba789bb5594bc527fef3b1af4ceadfdc98213c2a4dc82dc"
},
{
"id": "431",
"name": "HTML媒体验收-411-mtygwyxh",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:28.317Z",
"backupSha256": "3a608c7f43e0561502d398004210cc79d5969f9b4ae553c598dabeef4823d449"
},
{
"id": "430",
"name": "HTML闭环验收-mtygust6",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:28.849Z",
"backupSha256": "cacecc001fa781d79f2e59f646237ac5227f41a462afcdc9dc334720396da0bd"
},
{
"id": "429",
"name": "HTML媒体验收-411-mtygrzvz",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:29.395Z",
"backupSha256": "3d5af2f607e13eae1e7a075a71d400a8fb935e01856c3a191467c13feff8761b"
},
{
"id": "428",
"name": "HTML媒体验收-411-mtygq1cj",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:29.929Z",
"backupSha256": "38aedef25fcfcb2a508fb20ba074792cd14d77cb89dfaaa27f1a8499b680dc21"
},
{
"id": "427",
"name": "HTML媒体验收-411-mtygo2oi",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:30.248Z",
"backupSha256": "571c04ffb3170a8f7e2159e80008902fe67c0a2cdc2ea13f575f595a6668c0ca"
},
{
"id": "426",
"name": "HTML媒体验收-411-mtyglbos",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:30.571Z",
"backupSha256": "3a3ca0f282d8e18921dcd3646006aa16af528083b2915095e3479b1c511221d0"
},
{
"id": "425",
"name": "HTML媒体验收-411-mtygj471",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:30.895Z",
"backupSha256": "62f3305b0711f214629819ccb41e9bb3c4ed75b0f44da95301e3c391fa2b7577"
},
{
"id": "423",
"name": "HTML闭环验收-mtyg3srb",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:31.402Z",
"backupSha256": "6beb94f94771ac5f7f97b32135b14cefb40b39655e496d1dc02a1693bba674f0"
},
{
"id": "422",
"name": "HTML闭环验收-mtyg0s9h",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:31.908Z",
"backupSha256": "a0794846d86de6d8f350445e4fdef797782e65fc226afbb0ce9788a813729d00"
},
{
"id": "421",
"name": "HTML闭环验收-mtyfndrj",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:32.462Z",
"backupSha256": "74efc4c6f6aeb6188fb644f0d5b651b08677829f9cffffb5e9b5718edd2b696d"
},
{
"id": "420",
"name": "HTML闭环验收-mtyfllat",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:32.741Z",
"backupSha256": "eab2ad591aaba34c5ec28f9823d8060f864a15792af847ef178cb4b4ae36e492"
},
{
"id": "419",
"name": "动画能力验收训练-20260912",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:33.144Z",
"backupSha256": "352829a984229ce78e84e52f6fd9e03297eadaa2fbf9ee506da331a177da10cb"
},
{
"id": "418",
"name": "动画能力验收场景-20260912",
"type": "SCENE",
"deletedAt": "2026-09-24T17:56:33.625Z",
"backupSha256": "09df00c479996104a18f62051591e503b0bbf9f1e0dbbfd316abd130e6cd989c"
},
{
"id": "415",
"name": "桥梁虚拟仿真-ZDS",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:34.489Z",
"backupSha256": "77589a6b1419b2efaf2cd15787d17e09b4cc74a3f0a296784bd18ab442a0731e"
},
{
"id": "408",
"name": "ZDS-场景1",
"type": "SCENE",
"deletedAt": "2026-09-24T17:56:35.418Z",
"backupSha256": "2c94deb1cd61cf93ab0635bc44a9c058f45abab6b27c61bcedef2379b2598561"
},
{
"id": "409",
"name": "ZDS-虚拟仿真1",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:35.736Z",
"backupSha256": "31b1da5bdd25215cd6d87505a896b4994115ed1061535abed63af7b840b8a57e"
},
{
"id": "162",
"name": "实测训练-牛奶卡车进场检查-已验证-20260905",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:36.310Z",
"backupSha256": "0031c9d609ad9719fccdffb6b551a99045b55682cd57983ee559fbb0fe2b7860"
},
{
"id": "153",
"name": "真实野外山地整机进场点检训练",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:36.783Z",
"backupSha256": "cfe7b34c22aa868c3ef47d6554614b21ea662f8da6c2e82326c119d9ee34c521"
},
{
"id": "132",
"name": "真实装备车库整机进场点检训练",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:37.125Z",
"backupSha256": "5d1638b63d59ec9539736122bdbcbb6e2eb9f857b10ad41d08fbfdd21e6aa39a"
},
{
"id": "131",
"name": "真实装备车库整机进场点检场景",
"type": "SCENE",
"deletedAt": "2026-09-24T17:56:37.653Z",
"backupSha256": "7d3c456f90977391a837748f68b2bbeaa7b964718aa5ac6d30c9f5a81c40d61b"
},
{
"id": "97",
"name": "桥梁架设装备变幅油缸中修训练",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:38.272Z",
"backupSha256": "395fd6ad9aa7ff5234ac1b29e4cb535895c5a0bd1689f0e7e39c8344f6bde884"
},
{
"id": "58",
"name": "支腿液压缸中修训练",
"type": "TRAINING",
"deletedAt": "2026-09-24T17:56:38.636Z",
"backupSha256": "80b14fbebaf9ce9e1b6ca5628372212c68a38807714e841d44a1cb2073abc8b0"
}
],
"completedAt": "2026-09-24T17:56:38.636Z",
"pass": true
}

+ 12
- 0
reports/bridge-content-cleanup-20260925/index.html View File

@@ -0,0 +1,12 @@
<!doctype html><html lang="zh-CN"><meta charset="utf-8"><title>005~008 内容目录清理 · 第一阶段</title>
<style>body{font:16px/1.8 system-ui;color:#16473d;background:#f5f8f7;max-width:1200px;margin:32px auto;padding:0 24px}section{background:white;border:1px solid #d1e1dc;border-radius:12px;padding:24px;margin:20px 0}img{width:100%;border:1px solid #d1e1dc}a{color:#00846d}.pending{background:#fff5e7}table{border-collapse:collapse;width:100%}td,th{border:1px solid #d1e1dc;padding:10px;text-align:left}</style>
<h1>005~008 内容目录清理 · 第一阶段</h1>
<p>2026-09-25 · 本地 6180,经 Gateway 6100 · root 维护账号。</p>
<section><h2>已完成的清理</h2><p>清理前已备份全部工程及版本。通过正式内容接口删除无保留业务引用的 28 项,未删除资产二进制文件。</p>
<table><tr><th>列表</th><th>清理前</th><th>本次删除</th><th>当前剩余</th></tr><tr><td>模型制作</td><td>13</td><td>2</td><td>11</td></tr><tr><td>场景制作</td><td>14</td><td>3</td><td>11</td></tr><tr><td>训练编排</td><td>38</td><td>23</td><td>15</td></tr></table>
<p>005~008 四组制作链、原虚拟仿真任务和旧 005 验证入口均未改变;12 份作业指导书也已核对未变。</p></section>
<section class="pending"><h2>尚未全部完成</h2><p>23 个非 005~008 工程仍有直接或间接引用,其中 18 个工程直接关联 27 个旧教学任务或 3 份指导书。已询问用户:仅将这些内容移出制作列表并保持旧业务可用,或一并清理关联旧业务。尚未扩大删除范围。</p></section>
<section><h2>记录与备份</h2><p><a href="README.md">完整说明与本机备份位置</a> · <a href="plan.json">保留、候选及引用清单</a> · <a href="deleted-unreferenced.json">实际删除记录</a> · <a href="unreferenced-verification.json">数据核对</a> · <a href="list-verification.json">列表与指导书检查</a></p></section>
<section><h2>模型制作</h2><img src="models.png" alt="第一阶段后的模型列表"></section>
<section><h2>场景制作</h2><img src="scenes.png" alt="第一阶段后的场景列表"></section>
<section><h2>训练编排</h2><img src="training-projects.png" alt="第一阶段后的编排列表"></section></html>

+ 925
- 0
reports/bridge-content-cleanup-20260925/inventory-before.json View File

@@ -0,0 +1,925 @@
{
"capturedAt": "2026-09-24T17:53:33.614Z",
"baseUrl": "http://127.0.0.1:6180/api",
"projects": [
{
"id": "472",
"type": "MODEL",
"name": "重型支援桥平衡阀拆拼互换机构模型",
"status": "PUBLISHED",
"version": 7,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-008",
"modelProjectId": "472",
"sceneProjectId": "473",
"trainingProjectId": "441",
"taskId": "89"
}
},
{
"id": "470",
"type": "MODEL",
"name": "重型支援桥前泵换件修复机构模型",
"status": "PUBLISHED",
"version": 7,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-007",
"modelProjectId": "470",
"sceneProjectId": "471",
"trainingProjectId": "440",
"taskId": "88"
}
},
{
"id": "468",
"type": "MODEL",
"name": "重型支援桥液压泵应急替代机构模型",
"status": "PUBLISHED",
"version": 7,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-006",
"modelProjectId": "468",
"sceneProjectId": "469",
"trainingProjectId": "439",
"taskId": "87"
}
},
{
"id": "466",
"type": "MODEL",
"name": "重型支援桥液压泵应急切换机构模型",
"status": "PUBLISHED",
"version": 17,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-005",
"modelProjectId": "466",
"sceneProjectId": "467",
"trainingProjectId": "438",
"taskId": "86"
}
},
{
"id": "416",
"type": "MODEL",
"name": "动画能力验收-组合动作与流向-20260912",
"status": "DRAFT",
"version": 10,
"usageCount": 14
},
{
"id": "407",
"type": "MODEL",
"name": "ZDS-模型1",
"status": "DRAFT",
"version": 36,
"usageCount": 3
},
{
"id": "157",
"type": "MODEL",
"name": "实测模型-狐狸动画-已验证-20260905",
"status": "DRAFT",
"version": 26,
"usageCount": 2
},
{
"id": "156",
"type": "MODEL",
"name": "实测模型-牛奶卡车-已验证-20260905",
"status": "PUBLISHED",
"version": 20,
"usageCount": 2
},
{
"id": "94",
"type": "MODEL",
"name": "桥梁架设装备整机模型",
"status": "DRAFT",
"version": 270,
"usageCount": 4
},
{
"id": "48",
"type": "MODEL",
"name": "UAT 挖掘机装备模型",
"status": "DRAFT",
"version": 556,
"usageCount": 3
},
{
"id": "436",
"type": "MODEL",
"name": "CL-mode1",
"status": "DRAFT",
"version": 36,
"usageCount": 0
},
{
"id": "155",
"type": "MODEL",
"name": "测试",
"status": "DRAFT",
"version": 57,
"usageCount": 0
},
{
"id": "151",
"type": "MODEL",
"name": "野外山地场景与桥梁架设装备",
"status": "PUBLISHED",
"version": 1,
"usageCount": 1
},
{
"id": "473",
"type": "SCENE",
"name": "重型支援桥平衡阀拆拼互换训练场景",
"status": "PUBLISHED",
"version": 9,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-008",
"modelProjectId": "472",
"sceneProjectId": "473",
"trainingProjectId": "441",
"taskId": "89"
}
},
{
"id": "471",
"type": "SCENE",
"name": "重型支援桥前泵换件修复训练场景",
"status": "PUBLISHED",
"version": 9,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-007",
"modelProjectId": "470",
"sceneProjectId": "471",
"trainingProjectId": "440",
"taskId": "88"
}
},
{
"id": "469",
"type": "SCENE",
"name": "重型支援桥液压泵应急替代训练场景",
"status": "PUBLISHED",
"version": 10,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-006",
"modelProjectId": "468",
"sceneProjectId": "469",
"trainingProjectId": "439",
"taskId": "87"
}
},
{
"id": "467",
"type": "SCENE",
"name": "重型支援桥液压泵应急切换训练场景",
"status": "PUBLISHED",
"version": 16,
"usageCount": 1,
"production": {
"taskCode": "TASK-VIRTUAL-005",
"modelProjectId": "466",
"sceneProjectId": "467",
"trainingProjectId": "438",
"taskId": "86"
}
},
{
"id": "160",
"type": "SCENE",
"name": "实测场景-狐狸野外训练区-20260905",
"status": "PUBLISHED",
"version": 13,
"usageCount": 4
},
{
"id": "159",
"type": "SCENE",
"name": "实测场景-牛奶卡车检验区-20260905",
"status": "PUBLISHED",
"version": 7,
"usageCount": 7
},
{
"id": "457",
"type": "SCENE",
"name": "005 液压泵应急切换(编排验证)",
"status": "PUBLISHED",
"version": 20,
"usageCount": 1
},
{
"id": "418",
"type": "SCENE",
"name": "动画能力验收场景-20260912",
"status": "PUBLISHED",
"version": 3,
"usageCount": 12
},
{
"id": "408",
"type": "SCENE",
"name": "ZDS-场景1",
"status": "PUBLISHED",
"version": 8,
"usageCount": 1
},
{
"id": "131",
"type": "SCENE",
"name": "真实装备车库整机进场点检场景",
"status": "DRAFT",
"version": 4,
"usageCount": 1
},
{
"id": "152",
"type": "SCENE",
"name": "真实野外山地桥梁架设训练场",
"status": "PUBLISHED",
"version": 1,
"usageCount": 2
},
{
"id": "49",
"type": "SCENE",
"name": "UAT 综合检验车间",
"status": "DRAFT",
"version": 3,
"usageCount": 2
},
{
"id": "95",
"type": "SCENE",
"name": "桥梁架设装备架桥作业训练场",
"status": "DRAFT",
"version": 1,
"usageCount": 2
},
{
"id": "50",
"type": "SCENE",
"name": "UAT 室外对抗训练场",
"status": "DRAFT",
"version": 5,
"usageCount": 1
},
{
"id": "441",
"type": "TRAINING",
"name": "重型支援桥平衡阀拆拼互换",
"status": "PUBLISHED",
"version": 22,
"usageCount": 0,
"production": {
"taskCode": "TASK-VIRTUAL-008",
"modelProjectId": "472",
"sceneProjectId": "473",
"trainingProjectId": "441",
"taskId": "89"
}
},
{
"id": "440",
"type": "TRAINING",
"name": "重型支援桥前泵换件修复",
"status": "PUBLISHED",
"version": 22,
"usageCount": 0,
"production": {
"taskCode": "TASK-VIRTUAL-007",
"modelProjectId": "470",
"sceneProjectId": "471",
"trainingProjectId": "440",
"taskId": "88"
}
},
{
"id": "439",
"type": "TRAINING",
"name": "重型支援桥液压泵应急替代",
"status": "PUBLISHED",
"version": 26,
"usageCount": 0,
"production": {
"taskCode": "TASK-VIRTUAL-006",
"modelProjectId": "468",
"sceneProjectId": "469",
"trainingProjectId": "439",
"taskId": "87"
}
},
{
"id": "438",
"type": "TRAINING",
"name": "重型支援桥液压泵应急切换",
"status": "PUBLISHED",
"version": 21,
"usageCount": 0,
"production": {
"taskCode": "TASK-VIRTUAL-005",
"modelProjectId": "466",
"sceneProjectId": "467",
"trainingProjectId": "438",
"taskId": "86"
}
},
{
"id": "458",
"type": "TRAINING",
"name": "005 液压泵应急切换(编排验证)",
"status": "DRAFT",
"version": 34,
"usageCount": 0
},
{
"id": "432",
"type": "TRAINING",
"name": "HTML服务端编排-mtyissgj",
"status": "DRAFT",
"version": 4,
"usageCount": 0
},
{
"id": "435",
"type": "TRAINING",
"name": "HTML服务端编排-mtyjtx1p",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "434",
"type": "TRAINING",
"name": "HTML闭环验收-mtyjgaok",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "433",
"type": "TRAINING",
"name": "HTML服务端编排-mtyjd8w5",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "431",
"type": "TRAINING",
"name": "HTML媒体验收-411-mtygwyxh",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "430",
"type": "TRAINING",
"name": "HTML闭环验收-mtygust6",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "429",
"type": "TRAINING",
"name": "HTML媒体验收-411-mtygrzvz",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "428",
"type": "TRAINING",
"name": "HTML媒体验收-411-mtygq1cj",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "427",
"type": "TRAINING",
"name": "HTML媒体验收-411-mtygo2oi",
"status": "DRAFT",
"version": 1,
"usageCount": 0
},
{
"id": "426",
"type": "TRAINING",
"name": "HTML媒体验收-411-mtyglbos",
"status": "DRAFT",
"version": 1,
"usageCount": 0
},
{
"id": "425",
"type": "TRAINING",
"name": "HTML媒体验收-411-mtygj471",
"status": "DRAFT",
"version": 1,
"usageCount": 0
},
{
"id": "423",
"type": "TRAINING",
"name": "HTML闭环验收-mtyg3srb",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "422",
"type": "TRAINING",
"name": "HTML闭环验收-mtyg0s9h",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "421",
"type": "TRAINING",
"name": "HTML闭环验收-mtyfndrj",
"status": "PUBLISHED",
"version": 2,
"usageCount": 0
},
{
"id": "420",
"type": "TRAINING",
"name": "HTML闭环验收-mtyfllat",
"status": "DRAFT",
"version": 1,
"usageCount": 0
},
{
"id": "419",
"type": "TRAINING",
"name": "动画能力验收训练-20260912",
"status": "DRAFT",
"version": 8,
"usageCount": 0
},
{
"id": "415",
"type": "TRAINING",
"name": "桥梁虚拟仿真-ZDS",
"status": "PUBLISHED",
"version": 8,
"usageCount": 0
},
{
"id": "409",
"type": "TRAINING",
"name": "ZDS-虚拟仿真1",
"status": "DRAFT",
"version": 10,
"usageCount": 0
},
{
"id": "410",
"type": "TRAINING",
"name": "APE2E-数字人讲解-狐狸-20260909",
"status": "DRAFT",
"version": 21,
"usageCount": 0
},
{
"id": "411",
"type": "TRAINING",
"name": "APE2E-数字人讲解-牛奶-20260909",
"status": "PUBLISHED",
"version": 10,
"usageCount": 0
},
{
"id": "164",
"type": "TRAINING",
"name": "实测训练-狐狸红蓝协同巡检-20260905",
"status": "PUBLISHED",
"version": 11,
"usageCount": 0
},
{
"id": "163",
"type": "TRAINING",
"name": "实测训练-牛奶卡车实装检查-20260905",
"status": "PUBLISHED",
"version": 7,
"usageCount": 0
},
{
"id": "162",
"type": "TRAINING",
"name": "实测训练-牛奶卡车进场检查-已验证-20260905",
"status": "PUBLISHED",
"version": 6,
"usageCount": 0
},
{
"id": "161",
"type": "TRAINING",
"name": "实测训练-狐狸野外巡检-已验证-20260905",
"status": "PUBLISHED",
"version": 9,
"usageCount": 0
},
{
"id": "154",
"type": "TRAINING",
"name": "真实野外山地整机进场点检对抗训练",
"status": "PUBLISHED",
"version": 1,
"usageCount": 0
},
{
"id": "153",
"type": "TRAINING",
"name": "真实野外山地整机进场点检训练",
"status": "PUBLISHED",
"version": 1,
"usageCount": 0
},
{
"id": "132",
"type": "TRAINING",
"name": "真实装备车库整机进场点检训练",
"status": "DRAFT",
"version": 4,
"usageCount": 0
},
{
"id": "98",
"type": "TRAINING",
"name": "桥梁架设装备变幅系统背靠背排故",
"status": "DRAFT",
"version": 2,
"usageCount": 0
},
{
"id": "97",
"type": "TRAINING",
"name": "桥梁架设装备变幅油缸中修训练",
"status": "PUBLISHED",
"version": 1,
"usageCount": 0
},
{
"id": "58",
"type": "TRAINING",
"name": "支腿液压缸中修训练",
"status": "DRAFT",
"version": 1,
"usageCount": 1
},
{
"id": "53",
"type": "TRAINING",
"name": "UAT 液压系统对抗训练定义",
"status": "PUBLISHED",
"version": 1,
"usageCount": 0
},
{
"id": "52",
"type": "TRAINING",
"name": "UAT 支腿液压缸实装训练定义",
"status": "DRAFT",
"version": 2,
"usageCount": 0
},
{
"id": "51",
"type": "TRAINING",
"name": "UAT 支腿液压缸虚拟训练定义",
"status": "PUBLISHED",
"version": 1,
"usageCount": 0
},
{
"id": "463",
"type": "GUIDE",
"name": "重型支援桥液压泵应急替代训练作业指导书",
"status": "PUBLISHED",
"version": 62,
"usageCount": 0
},
{
"id": "462",
"type": "GUIDE",
"name": "重型支援桥液压泵应急切换训练作业指导书",
"status": "DRAFT",
"version": 48,
"usageCount": 0
},
{
"id": "464",
"type": "GUIDE",
"name": "重型支援桥前泵换件修复训练作业指导书",
"status": "DRAFT",
"version": 37,
"usageCount": 0
},
{
"id": "465",
"type": "GUIDE",
"name": "重型支援桥平衡阀拆拼互换训练作业指导书",
"status": "DRAFT",
"version": 44,
"usageCount": 0
},
{
"id": "417",
"type": "GUIDE",
"name": "动画能力验收指导书-20260912",
"status": "DRAFT",
"version": 55,
"usageCount": 0
},
{
"id": "412",
"type": "GUIDE",
"name": "正式闭环-狐狸与卡车指导书-20260910",
"status": "DRAFT",
"version": 25,
"usageCount": 0
},
{
"id": "461",
"type": "GUIDE",
"name": "装备构造原理标准模板(新建)",
"status": "DRAFT",
"version": 32,
"usageCount": 0
},
{
"id": "9",
"type": "GUIDE",
"name": "支腿液压缸中修作业指导书",
"status": "DRAFT",
"version": 5,
"usageCount": 0
},
{
"id": "414",
"type": "GUIDE",
"name": "正式图片视频资源回归-20260911",
"status": "DRAFT",
"version": 2,
"usageCount": 0
},
{
"id": "413",
"type": "GUIDE",
"name": "正式模板新建回归-20260911",
"status": "DRAFT",
"version": 2,
"usageCount": 0
},
{
"id": "56",
"type": "GUIDE",
"name": "JKHJHL",
"status": "DRAFT",
"version": 1,
"usageCount": 0
},
{
"id": "11",
"type": "GUIDE",
"name": "行走机构润滑保养作业指导书",
"status": "REVIEW",
"version": 0,
"usageCount": 0
}
],
"assignments": [
{
"id": "116",
"code": "BRIDGE-005-AUTHORING-PILOT",
"status": "DRAFT",
"contentProjectId": "458",
"contentVersionId": "560"
},
{
"id": "89",
"code": "TASK-VIRTUAL-008",
"status": "PUBLISHED",
"contentProjectId": "441",
"contentVersionId": "559"
},
{
"id": "88",
"code": "TASK-VIRTUAL-007",
"status": "PUBLISHED",
"contentProjectId": "440",
"contentVersionId": "558"
},
{
"id": "87",
"code": "TASK-VIRTUAL-006",
"status": "PUBLISHED",
"contentProjectId": "439",
"contentVersionId": "567"
},
{
"id": "86",
"code": "TASK-VIRTUAL-005",
"status": "PUBLISHED",
"contentProjectId": "438",
"contentVersionId": "556"
},
{
"id": "85",
"code": "HTML-TIME-MTYK7PCH",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "84",
"code": "HTML-EX-MTYK7PCH",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "83",
"code": "HTML-TIME-MTYJW7UD",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "82",
"code": "HTML-EX-MTYJW7UD",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "80",
"code": "HTML-EX-MTYJTOUG",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "79",
"code": "HTML-EX-MTYJNY4T",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "77",
"code": "HTML-EX-MTYJF2Z6",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "75",
"code": "HTML-EX-MTYJD0RB",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "74",
"code": "HTML-EX-MTYJ38OV",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "72",
"code": "HTML-EX-MTYHWQMI",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "71",
"code": "HTML-EX-MTYHVMZU",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "70",
"code": "HTML-EX-MTYHQWXW",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "69",
"code": "HTML-EX-MTYHNFTH",
"status": "PUBLISHED",
"contentProjectId": "161",
"contentVersionId": "213"
},
{
"id": "53",
"code": "APE2E_DH_PLAYBACK_TRUCK",
"status": "DRAFT",
"contentProjectId": "411",
"contentVersionId": "467"
},
{
"id": "52",
"code": "APE2E_DH_PLAYBACK_FOX",
"status": "DRAFT",
"contentProjectId": "410",
"contentVersionId": "466"
},
{
"id": "51",
"code": "UTE2E-MODES-MTOK5BBA-CONFRONTATION",
"status": "PUBLISHED",
"contentProjectId": "164",
"contentVersionId": "216"
},
{
"id": "50",
"code": "UTE2E-MODES-MTOK5BBA-PHYSICAL",
"status": "PUBLISHED",
"contentProjectId": "163",
"contentVersionId": "215"
},
{
"id": "40",
"code": "TASK-CONFRONTATION-002",
"status": "PUBLISHED",
"contentProjectId": "154",
"contentVersionId": "196"
},
{
"id": "33",
"code": "TASK-CONFRONTATION-BRIDGE-001",
"status": "PUBLISHED",
"contentProjectId": "98",
"contentVersionId": "106"
},
{
"id": "27",
"code": "UAT-EXAM-PHYSICAL-001",
"status": "PUBLISHED",
"contentProjectId": "52",
"contentVersionId": "52"
},
{
"id": "26",
"code": "UAT-TEACH-PHYSICAL-002",
"status": "PUBLISHED",
"contentProjectId": "52",
"contentVersionId": "52"
},
{
"id": "25",
"code": "UAT-TEACH-PHYSICAL-001",
"status": "PUBLISHED",
"contentProjectId": "52",
"contentVersionId": "52"
},
{
"id": "24",
"code": "UAT-EXAM-VIRTUAL-001",
"status": "PUBLISHED",
"contentProjectId": "51",
"contentVersionId": "51"
},
{
"id": "21",
"code": "UAT-EXAM-CONFRONTATION-001",
"status": "PUBLISHED",
"contentProjectId": "53",
"contentVersionId": "53"
},
{
"id": "20",
"code": "UAT-TEACH-CONFRONTATION-002",
"status": "PUBLISHED",
"contentProjectId": "53",
"contentVersionId": "53"
},
{
"id": "19",
"code": "UAT-TEACH-CONFRONTATION-001",
"status": "PUBLISHED",
"contentProjectId": "53",
"contentVersionId": "53"
}
]
}

+ 11
- 0
reports/bridge-content-cleanup-20260925/list-verification.json View File

@@ -0,0 +1,11 @@
{
"pass": true,
"types": [
"MODEL",
"SCENE",
"TRAINING"
],
"retainedProductionEntries": 12,
"unchangedGuides": 12,
"errors": []
}

BIN
View File


+ 2363
- 0
reports/bridge-content-cleanup-20260925/plan.json
File diff suppressed because it is too large
View File


BIN
View File


BIN
View File


+ 88
- 0
reports/bridge-content-cleanup-20260925/unreferenced-verification.json View File

@@ -0,0 +1,88 @@
{
"pass": true,
"checkedAt": "2026-09-24T17:57:11.513Z",
"deleted": 28,
"counts": {
"MODEL": 11,
"SCENE": 11,
"TRAINING": 15
},
"checks": [
{
"id": "472",
"unchanged": true
},
{
"id": "470",
"unchanged": true
},
{
"id": "468",
"unchanged": true
},
{
"id": "466",
"unchanged": true
},
{
"id": "473",
"unchanged": true
},
{
"id": "471",
"unchanged": true
},
{
"id": "469",
"unchanged": true
},
{
"id": "467",
"unchanged": true
},
{
"id": "457",
"unchanged": true
},
{
"id": "441",
"unchanged": true
},
{
"id": "440",
"unchanged": true
},
{
"id": "439",
"unchanged": true
},
{
"id": "438",
"unchanged": true
},
{
"id": "458",
"unchanged": true
},
{
"task": "BRIDGE-005-AUTHORING-PILOT",
"unchanged": true
},
{
"task": "TASK-VIRTUAL-008",
"unchanged": true
},
{
"task": "TASK-VIRTUAL-007",
"unchanged": true
},
{
"task": "TASK-VIRTUAL-006",
"unchanged": true
},
{
"task": "TASK-VIRTUAL-005",
"unchanged": true
}
]
}

+ 60
- 0
tools/bridge-content-cleanup-20260925.mjs View File

@@ -0,0 +1,60 @@
import fs from 'node:fs';
import crypto from 'node:crypto';
import assert from 'node:assert/strict';
import { login, call } from './role-permissions-live.mjs';

// One-time cleanup of the explicitly audited local inventory. New projects are never included.
const dir = 'reports/bridge-content-cleanup-20260925';
const plan = JSON.parse(fs.readFileSync(dir + '/plan.json', 'utf8'));
const protectedIds = new Set([...plan.keep, ...plan.blockers].map(p => p.id));
for (let changed = true; changed;) {
changed = false;
for (const project of plan.all.filter(p => protectedIds.has(p.id))) {
for (const id of project.dependencies) if (!protectedIds.has(id)) { protectedIds.add(id); changed = true; }
}
}
const pending = plan.candidates.filter(p => !protectedIds.has(p.id));
const order = [];
while (pending.length) {
const index = pending.findIndex(p => !pending.some(other => other.id !== p.id && other.dependencies.includes(p.id)));
assert.ok(index >= 0, 'Dependency cycle: stop rather than deleting referenced content');
order.push(...pending.splice(index, 1));
}
console.log(JSON.stringify({ removable: order.map(p => ({ id: p.id, type: p.type, name: p.name })), protectedCount: protectedIds.size }, null, 2));
if (process.argv.includes('--apply-unreferenced')) {
const session = await login('root');
const request = (path, body, method) => call('tran/v1/' + path, session.accessToken, body, method);
const resultPath = dir + '/deleted-unreferenced.json';
const result = fs.existsSync(resultPath) ? JSON.parse(fs.readFileSync(resultPath, 'utf8')) : { startedAt: new Date().toISOString(), deleted: [] };
const save = () => fs.writeFileSync(resultPath, JSON.stringify(result, null, 2));
try {
for (const project of order) {
assert.ok(['MODEL', 'SCENE', 'TRAINING'].includes(project.type));
assert.ok(!protectedIds.has(project.id));
const backup = fs.readFileSync(plan.backupDirectory + '/project-' + project.id + '.json');
assert.equal(crypto.createHash('sha256').update(backup).digest('hex'), project.backupSha256, 'Backup must match audited snapshot');
const response = await request('content/projects/' + project.id);
if (response.status === 404 && result.deleted.some(p => p.id === project.id)) continue;
assert.equal(response.status, 200, 'Read project ' + project.id);
let current = response.data.project;
assert.equal(current.type, project.type);
assert.equal(current.name, project.name);
assert.equal(current.version, project.version, 'Concurrent change to project ' + project.id);
if (current.status === 'PUBLISHED') {
const revoked = await request('content/projects/' + project.id + '/review', {
version: current.version, action: 'REVOKE', comment: '按用户要求清理非005~008的历史内容;已备份并核对无保留工程或教学任务引用。',
});
assert.equal(revoked.status, 200, 'Revoke project ' + project.id + ': ' + revoked.message);
current = revoked.data.project;
}
const deleted = await request('content/projects/' + project.id + '?version=' + current.version, undefined, 'DELETE');
assert.equal(deleted.status, 200, 'Delete project ' + project.id + ': ' + deleted.message);
result.deleted.push({ id: project.id, name: project.name, type: project.type, deletedAt: new Date().toISOString(), backupSha256: project.backupSha256 });
save();
}
result.completedAt = new Date().toISOString(); result.pass = true; save();
console.log('Deleted unreferenced projects:', result.deleted.length);
} catch (error) {
result.pass = false; result.error = error.message; save(); throw error;
}
}

Loading…
Cancel
Save