# 调度定义 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、时区或节点归属不合法 |