# 2026-06-07 — 推送调度对齐设计文档

## 摘要

修复推送调度 SPA 与后端契约断裂：`target_path` 未持久化、`schedule_runner` 未传递目标路径、`next_run` 恒为空；补全调度类型（push/script）、运行模式（cron/once）、同步模式与脚本调度 UI。

## 动机

- 前端表单有「目标路径」但未提交，DB 无 `target_path` 列，`runNow` 错误默认 `/tmp`
- 设计文档（附录 E.1）要求 source/target + sync_mode 或 script_id，旧版 SPA 仅支持 cron 推送
- 表格「下次运行」无 API 计算，用户无法判断调度是否生效

## 涉及文件

| 层 | 文件 |
|----|------|
| 模型 | `server/domain/models/__init__.py` — `PushSchedule.target_path` |
| 迁移 | `server/infrastructure/database/migrations.py`, `server/api/install.py` |
| Schema | `server/api/schemas.py` — `ScheduleCreate/Update.target_path` |
| API | `server/api/settings.py` — `_schedule_to_dict` + `next_run` |
| Runner | `server/background/schedule_runner.py` — 传 `target_path`、`compute_schedule_next_run` |
| 前端 | `frontend/src/pages/SchedulesPage.vue`, `frontend/src/types/api.ts` |
| 测试 | `tests/test_schedule_next_run.py` |

## 是否需迁移/重启

- **是**：`push_schedules.target_path` 列（启动时 `run_schema_migrations` 自动 ADD）
- **需重启 API** 以加载新代码；前端需 `vite build` 后部署

## 验证方式

```bash
bash scripts/local_verify.sh
python -m pytest tests/test_schedule_next_run.py tests/test_schedule_runner_once.py -q
```

- 新建 cron 推送调度，填写可选目标路径 → 列表显示 target_path、next_run
- `runNow` 留空目标路径 → 走各机 `servers.target_path`（与推送页一致）
- 新建 script 调度 → `schedule_runner` 调 ScriptService

## 行为说明

- **目标路径留空**：与推送页相同，各服务器使用「服务器管理」中的 `target_path`；未配置则 sync 引擎 fallback `/tmp/sync`
- **一次性调度**：`fire_at` 到期后 runner 执行一次并 `enabled=false`；失败时 rollback 恢复 enabled
