# CAD 批处理串行执行框架（设计与开发进度）

## 1. 文档目的
本文件用于同步两类信息：
1. 总体批处理设计（长期有效）
2. 当前代码开发进度（持续更新）

---

## 2. 总体设计（已定稿）

### 2.1 目标
- 前端提交批次任务（多模型、多步骤按条目表达）
- 后端按模型扩展名路由到对应 CAD 插件
- 全局严格 FIFO 串行执行（跨软件也串行）
- 插件通过 HTTP 接口执行，结果通过回调闭环
- 单任务失败后按重试策略处理，最终失败不阻塞后续任务

### 2.2 执行策略
- 队列：全局单队列 + 单 worker
- 顺序：严格按提交顺序
- 状态机：`queued -> dispatching -> waiting_callback -> succeeded/failed`
- 失败策略：重试后失败，继续执行后续任务
- 存储策略：首版内存态（重启不恢复）

### 2.3 架构模块
- 模型层：`app/models/cad_batch.py`
- 路由层：`app/core/cad_task_router.py`
- 插件下发层：`app/core/plugin_http_client.py`
- 回调等待层：`app/core/plugin_callback_registry.py`
- 串行执行层：`app/core/serial_batch_executor.py`
- 业务管理层：`app/core/cad_batch_manager.py`
- 插件回调接口：`app/api/v1/plugin_callbacks.py`
- 前端通道（WebSocket）：`app/api/v1/websocket.py`

---

## 3. 公共接口设计

### 3.1 WebSocket 消息
- `submit_batch_tasks`：提交批次
- `get_batch_status`：查询批次
- `get_batch_item_status`：查询条目

### 3.2 WebSocket 推送事件
- `batch_created`
- `batch_item_update`
- `batch_completed`

### 3.3 插件回调 HTTP
- `POST /api/v1/plugin-callbacks/task-result`
- 核心字段：
  - `execution_id`
  - `software_id`
  - `status` (`success|failed`)
  - `error_message`
  - `result`
  - `finished_at`
  - `token/signature`（当前实现为 token 校验）

---

## 4. 配置设计

### 4.1 已支持配置
- `routing.extension_to_software`
- `plugins.{software_id}.base_url`
- `plugins.{software_id}.request_timeout_sec`
- `plugins.{software_id}.callback_timeout_sec`
- `plugins.{software_id}.max_retries`
- `plugins.{software_id}.retry_backoff_sec`
- `plugins.{software_id}.callback_token`
- `plugins.{software_id}.tasks.{task_type}.path`
- `plugins.{software_id}.tasks.{task_type}.body_mode`
- `plugins.{software_id}.tasks.{task_type}.completion_mode`

### 4.2 body_mode 语义
- `file_path`：发送 `filePath + task_params + callback元信息`
- `task_params_only`：发送 `task_params + callback元信息`
- `project_open`：发送 `task_params + callback元信息`
- `creo_close_model`：发送 `{ software_type: "creo", force_close: boolean }`
- `empty`：发送空请求体 `{}`
- `passthrough`：原样透传

### 4.3 completion_mode 语义
- `callback`：下发后进入 `waiting_callback`，等待插件回调判定结果
- `sync`：以接口同步返回结果直接判定成功/失败，不等待回调

---

## 5. 当前开发进度（截至本次更新）

### 5.1 已完成
- [x] 计划文档落盘：`cad-batch-plan.md`
- [x] 批处理核心模型、执行器、管理器已实现
- [x] 插件异步回调机制与幂等处理已实现
- [x] 主应用 `startup/shutdown` 已接入批处理执行器
- [x] WebSocket 提交/查询批次能力已接入
- [x] 插件任务映射已支持按 `software_id + task_type` 路由
- [x] 单元测试已覆盖路由/执行器/回调/API 映射

### 5.2 已集成的 CAD 插件资料

#### Creo (localhost:12345)
- `open_model` -> `/api/model/open` (`file_path`)
- `shrinkwrap_shell` -> `/api/creo/shrinkwrap/shell` (`task_params_only`)
- `shell_analysis` -> `/api/analysis/shell-analysis` (`task_params_only`)
- `close_model` -> `/api/model/close` (`creo_close_model`, `sync`, 已接入)

#### Revit (localhost:9000)
- `open_model` -> `/api/open` (`file_path`)
- `shell_analyze` -> `/api/shell/analyze` (`task_params_only`)
- `shell_execute` -> `/api/shell/execute` (`task_params_only`)
- `close_model` -> `/api/close` (`empty`, `sync`, 已接入)

#### PDMS (localhost:9001)
- `open_project` -> `/api/project/open` (`project_open`)
- `open_mdb` -> `/api/mdb/open` (`project_open`)
- `shrinkwrap_model` -> `/api/model/shrinkwrap` (`task_params_only`)
- `simplify_model` -> `/api/model/simplify` (`task_params_only`)
- `close_project` -> `/api/project/close` (`task_params_only`, 占位)

### 5.3 当前测试状态
- 已通过：`13 passed`
- 覆盖文件：
  - `tests/test_cad_task_router.py`
  - `tests/test_serial_batch_executor.py`
  - `tests/test_plugin_callback_api.py`
  - `tests/test_plugin_http_client_mapping.py`
  - `tests/test_creo_close_model_sync_flow.py`

---

## 6. 待补资料与后续工作

### 6.1 你后续补充后可继续对接
1. 每个 `task_type` 的最终命名标准（是否沿用当前命名）
2. Revit 大任务轮询接口细节（如 `/api/task` 的请求/返回）
3. PDMS `close_project` 是否真实可用（当前仍按占位映射）
4. 回调安全方案最终版（token 还是 signature，签名算法与字段）
5. 各 API 的完整错误码与失败语义（用于统一重试/终止策略）

### 6.2 下一步建议
- 基于真实插件联调一轮 `open -> 处理 -> close`
- 优先确认 PDMS `close_project` 实际行为与容错策略
- 增加端到端集成测试（含回调超时、插件离线、重复回调场景）

---

## 7. 验收标准（当前版本）
- 可提交批次并进入全局串行队列
- 可按扩展名路由并向插件正确下发
- 可通过回调驱动状态闭环
- 单任务失败不会阻塞后续任务
- 可通过 WebSocket 查询批次与条目状态
