refactor: integrate model platform backend

This commit is contained in:
Winnie
2026-07-30 13:43:29 +08:00
parent baee7a60e1
commit 6d6c70cea8
97 changed files with 19724 additions and 2146 deletions
@@ -0,0 +1,122 @@
# 调度定义 API 契约 V1
冻结日期:2026-07-28
状态:`implemented`
## 1. 范围
本契约只覆盖调度定义,不触发任务执行:
- 调度方案增删改查;
- 稳定版本制品列表;
- 节点和连线增删改;
- 五段 Cron 校验与未来时间预览;
- DAG 完整性和有向无环校验。
立即运行、Cron 自动触发、Redis Streams 事件和 Worker 执行属于后续小步。
## 2. 请求上下文
所有接口都要求:
| Header | 含义 |
|---|---|
| `X-User-ID` | 当前用户 |
| `X-Workspace-ID` | 当前 Workspace |
| `X-Request-ID` | 请求追踪 ID;可省略,由服务端生成 |
服务端只返回当前 Workspace 的调度。节点引用的 `versions_id` 必须属于当前
Workspace,且当前用户有权读取。
## 3. HTTP 接口
| 方法 | 路径 | 作用 |
|---|---|---|
| `GET` | `/api/v1/schedule-artifacts` | 查询可加入调度的稳定版本 |
| `POST` | `/api/v1/cron/preview` | 校验 Cron 并预览未来时间 |
| `GET` | `/api/v1/schedules` | 查询调度列表 |
| `POST` | `/api/v1/schedules` | 新建调度 |
| `GET` | `/api/v1/schedules/{schedule_id}` | 查询调度及完整 DAG |
| `PUT/PATCH` | `/api/v1/schedules/{schedule_id}` | 修改调度基本信息 |
| `DELETE` | `/api/v1/schedules/{schedule_id}` | 软删除调度 |
| `POST` | `/api/v1/schedules/{schedule_id}/nodes` | 新建节点 |
| `PUT` | `/api/v1/schedules/{schedule_id}/nodes/{node_id}` | 修改节点 |
| `DELETE` | `/api/v1/schedules/{schedule_id}/nodes/{node_id}` | 删除节点及关联连线 |
| `POST` | `/api/v1/schedules/{schedule_id}/edges` | 新建有向连线 |
| `PUT` | `/api/v1/schedules/{schedule_id}/edges/{edge_id}` | 修改连线条件 |
| `DELETE` | `/api/v1/schedules/{schedule_id}/edges/{edge_id}` | 删除连线 |
| `POST` | `/api/v1/schedules/{schedule_id}/validate` | 校验当前 DAG |
成功响应统一为:
```json
{
"request_id": "01...",
"data": {},
"meta": {}
}
```
## 4. 并发修改契约
新建调度时 `workflow_version=1`。每次修改调度、节点或连线都必须在请求体中
提交当前 `workflow_version`,成功后版本号加一。
版本不一致时返回 `412 Precondition Failed`
```json
{
"detail": {
"code": "WORKFLOW_VERSION_CONFLICT",
"message": "schedule was modified by another request",
"expected": 3,
"current": 4
}
}
```
前端收到 `412` 后必须重新读取调度,不得用旧画布直接覆盖。
## 5. 调度与 Cron 约束
- `trigger_type``manual / cron / api`
- `failure_policy``stop / continue`
- Cron 固定为五段:`minute hour day month weekday`
- 时区使用 IANA 名称,例如 `Asia/Shanghai`
- `cron` 类型必须提供 `cron_expression`,其他类型不得提供;
- 新建的空调度不能直接启用;
- 只有 DAG 校验通过的调度才能设为 `enabled=true`
- `next_run_at` 在数据库和接口中按 UTC 保存和返回。
Cron 预览请求示例:
```json
{
"cron_expression": "*/5 * * * *",
"timezone": "Asia/Shanghai",
"count": 5,
"base_time": "2026-07-28T08:00:00+08:00"
}
```
## 6. 节点与 DAG 约束
- 节点必须引用不可变稳定版本 `versions_id`,不能引用工作副本;
- 同一个调度内 `node_key` 唯一;
- 节点保存超时、重试、位置、参数和环境引用;
- 连线的起点、终点必须属于同一调度;
- 不允许自环、重复连线和有向环;
- 删除节点会同时删除与该节点相连的边;
- 已有运行历史的节点不能物理删除;
- 校验结果返回根节点、叶节点、拓扑顺序和错误列表。
## 7. 典型状态码
| 状态码 | 场景 |
|---|---|
| `201` | 调度、节点或连线创建成功 |
| `404` | 调度、稳定版本、节点或连线不存在/不可见 |
| `409` | 名称冲突、重复连线、DAG 成环或无效 DAG 启用 |
| `412` | `workflow_version` 已过期 |
| `422` | 请求字段、Cron、时区或节点归属不合法 |