# 迷榖车辆运维 OTA（WatchDog）设计规格

**日期：** 2026-07-19
**状态：** 已批准并实现中
**范围：** 在迷榖「车辆运维」中交付完整 OTA 能力；车上协议沿用 WatchDog；管理面由 MiGu.Server 编排。

---

## 1. 背景与目标

### 1.1 参考实现

`E:\Work\FRLD\OTA\ota` 为 Electron OTA 管理工具：版本拉取/管理、多车 M/D/C 同步、自定义文件、配置 JSON 下发、带宽限速与分批。车上依赖 WatchDog（`:9776`）。参考工具缺少任务状态机、可靠进度与正式回滚。

### 1.2 迷榖现状

- 「车辆运维」=`VehicleHubView`：运维总览 / 维护策略 / 车队生命周期。
- OTA 仅为 `OtaPolicy`（enabled / batchSize / rollbackOnFail）只读占位，无包库、下发、进度或审计。

### 1.3 目标

1. 车辆运维顶部仅保留 **运维总览** 与 **OTA**。
2. 删除「维护策略」「车队生命周期」Tab 及维护策略配置页（本期不迁移）。
3. OTA 全面对齐参考工具能力，并补齐平台侧任务进度、失败重试、审计。
4. 车上协议 **沿用 WatchDog**；浏览器不直连车辆。
5. UI 按迷榖运维工作台语言重做，不照搬 Electron 通用后台壳。

### 1.4 非目标（本期）

- 差分/增量包、签名验签、A/B 双分区
- 空闲时段自动升级
- 浏览器直连 WatchDog
- 维护策略配置的任何入口保留或迁移

---

## 2. 架构决策

**选定：方案 A — 平台编排。**


| 组件                 | 职责                           |
| ------------------ | ---------------------------- |
| 前端                 | 仅调用 `/api/ota/`*，展示对照/进度/设置  |
| MiGu.Server OTA 模块 | 包存储、目标版本、任务状态机、分批、限速、延迟探测、审计 |
| 车队名单               | 复用现有投影/车辆列表（IP、名称、状态）        |
| WatchDog `:9776`   | 装包、读版本、回传包、读写 JSON、自定义文件     |


---

## 3. 信息架构

### 3.1 车辆运维 Tab


| Tab  | 内容                 |
| ---- | ------------------ |
| 运维总览 | 保持现有：健康卡片、维护态、车队分配 |
| OTA  | 新工作台               |


- 路由：`/admin/config/vehicle-hub?tab=ota`（监控侧同理）。
- 旧 `?tab=maintenance` / `?tab=fleet` 深链重定向到 `ota`。

### 3.2 OTA 子导航（左侧）

1. **车辆升级** — 版本对照、勾选、分组件/全量同步、延迟检测开关
2. **版本库** — 从车拉取 / 本地上传、设为目标、清理
3. **任务中心** — 进行中/历史、进度、重试、取消
4. **配置同步** — Medulla/Detour/Clumsy JSON 浏览、编辑、多车下发
5. **自定义文件** — 文件 + 车上路径 + 重启策略
6. **设置** — 带宽、并发、备份、延迟检测阈值与门禁策略

### 3.3 与运维总览的边界


| 能力                                   | Tab  |
| ------------------------------------ | ---- |
| 健康、电量、报警、维护态、车队分配、开车上页               | 运维总览 |
| 版本对照、包库、下发、JSON/自定义文件、任务、OTA 设置、延迟检测 | OTA  |


运维总览不强制展示完整 MDC 哈希；若后续加「版本落后」标记，仅作跳转 OTA 的入口。

---

## 4. 后端：存储、API、任务

### 4.1 存储布局

根目录：`MiGu.Server/data/ota/`（可配置）


| 路径               | 用途                      |
| ---------------- | ----------------------- |
| `packages/{id}/` | 一次拉取或上传的 M/D/C 文件树      |
| `target.json`    | 当前目标版本（等价参考 `ota.json`） |
| `jobs/`          | 任务元数据与事件日志              |
| `history/`       | 定时备份（JSON ± exe）        |


- 版本标识：文件 **MD5（Base64，去除 `-`）**，与 WatchDog `getMDCInfo` 对齐。
- 组件映射：内置/可配置 `MDCPath`（Medulla / Detour / Clumsy 的 exe·dll·pdb）。

### 4.2 API


| 方法      | 路径                                    | 作用                       |
| ------- | ------------------------------------- | ------------------------ |
| GET     | `/api/ota/vehicles`                   | 车列表 + 车上 MDC 版本 +（可选）RTT |
| POST    | `/api/ota/packages/pull`              | 从指定车拉取包                  |
| POST    | `/api/ota/packages/upload`            | 管理端上传包                   |
| GET     | `/api/ota/packages`                   | 版本库列表                    |
| POST    | `/api/ota/packages/{id}/activate`     | 设为目标版本                   |
| DELETE  | `/api/ota/packages/{id}`              | 清理（当前目标不可删）              |
| GET     | `/api/ota/target`                     | 当前目标                     |
| POST    | `/api/ota/jobs`                       | 创建下发任务（全量/组件/自定义文件/JSON） |
| GET     | `/api/ota/jobs` · `/jobs/{id}`        | 列表与详情进度                  |
| POST    | `/api/ota/jobs/{id}/retry` · `cancel` | 重试失败项 / 取消未开始            |
| GET/PUT | `/api/ota/settings`                   | 带宽、maxCar、备份、延迟检测        |
| GET/PUT | `/api/ota/config/{carId}/{app}`       | 单车 JSON（medulla          |
| POST    | `/api/ota/config/push`                | JSON 多车下发（走 job）         |
| GET     | `/api/ota/latency`                    | 按需批量 RTT（受设置开关约束）        |


权限：JWT/RBAC；Platform 全量写；Monitor 可读 + 受控执行（`ops.ota.`*）。写操作进入审计。

### 4.3 任务状态机

```
pending → probing(可选) → running → succeeded
                              ↘ failed | partial
                              ↘ cancelled
```

- **分批：** `maxCar`（兼容原 `ota.batchSize` 语义）
- **限速：** 服务端上传流按 `bandwidth` kb/s 节流
- **进度：** 按「车 × 组件」；SSE 或短轮询推到任务中心
- **重试：** 仅重跑失败车辆/组件
- **取消：** 仅 `pending` / 未开始批次；已在传的组件尽量完成并标记
- **延迟门禁：** 任务可带 `requireLatencyCheck`；超阈值按设置跳过或二次确认后仍下发

### 4.4 WatchDog 映射


| 能力   | WatchDog                                                  |
| ---- | --------------------------------------------------------- |
| 读版本  | `GET /getMDCInfo`                                         |
| 拉包   | `GET /getmdcsexe` → 车推到平台接收端（或平台主动拉，实现时选更稳方案）             |
| 下发   | `/updateMedullaExecutable` 等 + `/updateFile/{name}/{op}/` |
| JSON | `get*json` / `update*json`                                |
| 备份   | `gethistoryexe` + 平台 `history/`                           |


参考工具 Express `:8000` 接收能力收进 MiGu（内部端点，仅供 WatchDog 回传）。服务端对 WatchDog 统一超时与有限重试。

---

## 5. UI 设计

**Design Read：** 工业 B2B 运维工作台；延续运维总览玻璃卡片 + 状态色 + JetBrains Mono；密度偏驾驶舱。
**Dial：** Variance 4 / Motion 3 / Density 7。使用 `--mg-`* 与 `--mg-status-`*。

### 5.1 骨架

左子导航 + 右工作区；顶条固定：**当前目标版本摘要**（M/D/C 短哈希 + 名称）+ 进行中任务角标。

### 5.2 车辆升级

- 工具条：搜索、车队筛选、「仅显示不一致」、**网络延迟检测开关**、刷新、同步全部/分组件
- 主表：勾选 | 车名/ID | IP | Medulla | Detour | Clumsy | RTT | 维护态
  - 与目标一致 → 绿；不一致 → 琥珀；不可达 → 灰
  - 延迟检测关：RTT 为「—」；开：数值 + 超阈值着色
- 有勾选时底栏粘性操作条：已选数、预计批次、开始下发（二次确认）

### 5.3 版本库

包列表（时间、来源 IP、体积、是否目标）+ 包内文件树与哈希；操作：拉取、上传、激活、删除。

### 5.4 任务中心

进行中（车×组件进度）+ 历史；详情含错误摘要、重试失败项、取消未开始。

### 5.5 配置同步 / 自定义文件 / 设置

- 配置：选车 → JSON 树 → 编辑 → 多车下发（进任务）
- 自定义文件：文件、车上路径、重启策略（无/M/D/C/WatchDog）、多车 → 任务
- 设置：传输（带宽、maxCar）、延迟检测（默认开关、RTT 阈值、超限策略）、备份、展示名

### 5.6 交互原则

- 下发二次确认，写清目标版本与车辆数
- 延迟开且超阈值：默认排除并提示；设置可改为「仍允许但确认」
- 任务进度可离页后续看（持久化）
- 动效克制：进度与状态点过渡即可

---

## 6. 错误处理与审计


| 场景              | 行为                           |
| --------------- | ---------------------------- |
| WatchDog 不可达/超时 | 该车失败，不阻塞同批其他车；任务可为 `partial` |
| 上传中断/哈希不匹配      | 组件级失败；可按失败项重试                |
| 延迟超阈值           | 依设置跳过或确认后下发                  |
| 无目标版本却同步        | 前端拦截 + API 400               |
| 磁盘满/包损坏         | 拉取/上传失败，不激活残包                |
| 任务取消            | 仅未开始批次                       |


审计覆盖：激活目标、创建/取消/重试任务、改设置、推 JSON/自定义文件（操作者、时间、摘要）。

---

## 7. 前端改动要点（实现指引）

- `VehicleHubView`：Tab 改为 `overview` | `ota`；移除 `VehicleMaintenanceView` / `FleetLifecycleView` 挂载。
- 新增 `views/.../OtaWorkbenchView.vue`（及子页/composables/api）。
- 新增 `src/api/ota.ts` 对接 `/api/ota/`*。
- 路由/深链：`maintenance`/`fleet` → `ota`。
- 删除或停用对维护策略页、FleetLifecycle 只读 OTA 页的导航依赖；`FleetLifecycleConfig.ota` 可迁移到 `/api/ota/settings` 后废弃只读 UI。

---

## 8. 后端改动要点（实现指引）

- 新增 OTA Controller / Service / 存储 / Job runner / WatchDog HttpClient。
- 配置项：OTA 数据根路径、WatchDog 端口（默认 9776）、超时。
- RBAC：`ops.ota.`*；与现有 Ops 审计集成或并行 OTA audit store。
- 包接收端点替代原 Express `:8000` 的 `upload-mdcs`* / `upload-history`*。

---

## 9. 验收标准

1. 车辆运维仅见「运维总览」「OTA」；旧 Tab 深链落到 OTA。
2. 可从车拉取或上传包，激活为目标，在车辆升级页看到绿/琥珀对照。
3. 可分批全量或分组件下发；任务中心可见进度；失败可重试；可取消未开始。
4. 延迟检测开关生效：关不探测；开显示 RTT 并按阈值门禁。
5. 配置 JSON 多车下发、自定义文件同步可用。
6. 设置可持久化（带宽、并发、备份、延迟策略）。
7. 写操作有审计；浏览器不直连 `:9776`。

---

## 10. 已确认决策摘要


| 决策     | 选择                     |
| ------ | ---------------------- |
| 车上协议   | WatchDog               |
| IA     | 运维总览 + OTA；去掉维护策略与生命周期 |
| 维护策略配置 | 本期删除                   |
| 功能范围   | 全面对齐参考工具 + 平台任务/进度/重试  |
| 架构     | MiGu.Server 平台编排       |
| 延迟检测   | OTA 内按钮开关；开才检测         |
