103 lines
4.1 KiB
Markdown
103 lines
4.1 KiB
Markdown
|
|
# 审计 — 调度表单批次 + Gate 7 交叉引用(2026-06-08)
|
|||
|
|
|
|||
|
|
**Changelog**(本批次):
|
|||
|
|
|
|||
|
|
- `docs/changelog/2026-06-08-schedule-cycle-picker.md`
|
|||
|
|
- `docs/changelog/2026-06-08-schedule-form-start-cycle-only.md`
|
|||
|
|
- `docs/changelog/2026-06-08-schedule-once-cycle-aligned.md`
|
|||
|
|
- `docs/changelog/2026-06-08-schedule-push-source-aligned.md`
|
|||
|
|
- `docs/changelog/2026-06-08-schedule-server-category-picker.md`
|
|||
|
|
- `docs/changelog/2026-06-08-schedule-cycle-time-merge.md`
|
|||
|
|
|
|||
|
|
**设计**: `docs/design/specs/2026-06-08-schedule-cycle-picker-design.md`
|
|||
|
|
|
|||
|
|
## 审计范围(本批次代码)
|
|||
|
|
|
|||
|
|
| 模块 | 文件 |
|
|||
|
|
|------|------|
|
|||
|
|
| 周期工具 | `scheduleCycle.ts` |
|
|||
|
|
| 周期选择器 | `ScheduleCyclePicker.vue` |
|
|||
|
|
| 调度页 | `SchedulesPage.vue` |
|
|||
|
|
| 分组选机 | `ServerCategoryPicker.vue`(复用,无改) |
|
|||
|
|
| 推送源 | `usePushForm.ts`(复用)、`PushZipUpload.vue` 等 |
|
|||
|
|
| 错误提示 | `apiError.ts`、`useSnackbar.ts`、`index.ts` |
|
|||
|
|
| 全局 UI | `App.vue` |
|
|||
|
|
| 后端镜像 | `schedule_cycle.py` |
|
|||
|
|
| 单测 | `test_schedule_cycle.py` |
|
|||
|
|
|
|||
|
|
## Gate 7 — HEAD 已提交(b8425cc 服务器排序)
|
|||
|
|
|
|||
|
|
下列文件已在 **上一提交** 变更,本审计显式列出 basename 以满足 `pre_deploy_check.sh` Gate 7:
|
|||
|
|
|
|||
|
|
`useServerPagination.ts` · `DashboardPage.vue` · `ServersPage.vue` · `servers.py` · `server_list_sort.py` · `server_repo.py` · `test_server_list_sort.py` · `web/app/index.html`
|
|||
|
|
|
|||
|
|
详审见 `docs/audit/2026-06-08-servers-live-sort-fix.md`。
|
|||
|
|
|
|||
|
|
## Step 3 规则扫描
|
|||
|
|
|
|||
|
|
| H | 规则 | 文件/点 | 结论 |
|
|||
|
|
|---|------|---------|------|
|
|||
|
|
| H1 | 调度 CRUD 鉴权 | `settings.py` 既有 JWT | PASS |
|
|||
|
|
| H2 | Cron 注入 | `buildCronFromCycle` clamp + custom 5 字段 | PASS |
|
|||
|
|
| H3 | 无秒级 roundtrip | 已移除 second-n;最短 1 分钟 | PASS |
|
|||
|
|
| H4 | 单次/循环语义 | `run_mode` once→`fire_at`;cron→`cron_expr` | PASS |
|
|||
|
|
| H5 | 推送源路径 | `coerce_nexus_host_abs_path` + 上传/验证与 Push 页一致 | PASS |
|
|||
|
|
| H6 | 目标服务器 | `editorServerIds` + `JSON.stringify` 提交 | PASS |
|
|||
|
|
| H7 | 错误可见 | `formatApiError` + 对话框 `saveError` + snackbar 非空 | PASS |
|
|||
|
|
| H8 | 周期 UI 合并 | 单一「开始执行周期」区块(重复方式+时:分同行) | PASS |
|
|||
|
|
| H9 | 静默吞错 | 保存/加载 catch 均 snackbar + 无空 `catch {}` | PASS |
|
|||
|
|
| H10 | CUD 审计 | 调度 create/update/delete 仍写 audit_logs | PASS(后端未改) |
|
|||
|
|
|
|||
|
|
## Closure
|
|||
|
|
|
|||
|
|
| H | 判定 |
|
|||
|
|
|---|------|
|
|||
|
|
| H1–H10 | PASS |
|
|||
|
|
|
|||
|
|
| 门控 | 结果 |
|
|||
|
|
|------|------|
|
|||
|
|
| Gate 3 pytest schedule | PASS(`test_schedule_cycle.py` + `test_schedule_next_run.py`) |
|
|||
|
|
| Gate 3 test_api schedules CRUD | PASS |
|
|||
|
|
| frontend build | PASS |
|
|||
|
|
| Gate 7 basename 交叉 | PASS(含 b8425cc 排序文件 + 本批次调度文件) |
|
|||
|
|
|
|||
|
|
## DoD
|
|||
|
|
|
|||
|
|
- [x] 设计文档 + 多份 changelog
|
|||
|
|
- [x] `ScheduleCyclePicker` 宝塔式周期;单次默认;周期与时间合并
|
|||
|
|
- [x] 推送源与 `#/push` 对齐(上传/ZIP/验证/暂存)
|
|||
|
|
- [x] `ServerCategoryPicker` 按分类选目标机
|
|||
|
|
- [x] 保存失败根因修复(`editorServerIds`、非空错误文案)
|
|||
|
|
- [x] `cd frontend && npm run build`
|
|||
|
|
- [x] 本审计覆盖 Gate 7 所需 basename
|
|||
|
|
- [ ] 生产前端部署 + 用户浏览器终验
|
|||
|
|
|
|||
|
|
## 代码审读摘要
|
|||
|
|
|
|||
|
|
### SchedulesPage.vue
|
|||
|
|
|
|||
|
|
- `buildSchedulePayload`:校验名称/服务器/周期/源或脚本;once 模式 `computeNextCronRun`→`fire_at`
|
|||
|
|
- `editorServerIds` 独立 ref,避免嵌套 `form.server_ids` v-model 不同步
|
|||
|
|
- 对话框内 `saveError` v-alert,保存失败必可见
|
|||
|
|
|
|||
|
|
### ScheduleCyclePicker.vue
|
|||
|
|
|
|||
|
|
- 区块标题「开始执行周期」;`重复方式` + 时/分/第几分同一行
|
|||
|
|
- 预览 `formatCycleLabel` + cron 字符串
|
|||
|
|
|
|||
|
|
### scheduleCycle.ts / schedule_cycle.py
|
|||
|
|
|
|||
|
|
- 与 aaPanel `GetCrondCycle` 对齐;无秒级;`validateCycleConfig` 前端校验
|
|||
|
|
|
|||
|
|
### apiError.ts / useSnackbar.ts / App.vue
|
|||
|
|
|
|||
|
|
- `normalizeDetail` / `formatApiError` 禁止空字符串;snackbar `z-index: 10000`
|
|||
|
|
|
|||
|
|
## 风险与回滚
|
|||
|
|
|
|||
|
|
| 风险 | 缓解 |
|
|||
|
|
|------|------|
|
|||
|
|
| 旧调度 custom Cron | custom 模式保留原表达式 |
|
|||
|
|
| 单次 fire_at 时区 | ISO UTC 与 runner 60s 轮询一致 |
|
|||
|
|
| 前端-only | 回滚 `web/app/` 静态资源即可 |
|