Files
mcn-short-video/project/短视频脚本创作/V1.0/references/接口调用/自动化任务清理规范.md
T
maogeigei c48902f063 09-10 工作台:配置收敛、复盘字段契约修复、原创选题分镜支持、榜单期号区间显示
配置收敛:
- 端口/DB名/产出根/榜单目录单源化到 mcn-work-shop/config.json,代码层统一经 load-config.js 读取
- 新增 get-port.js 供 start.bat 读端口(bat 内嵌 node -e 会被 cmd 截断,读到的是兜底值)
- start.bat 修复失效的 managed node 路径(原写死 22.22.2 已不存在),改为遍历 versions 自动探测

复盘诊断页(真 bug 修复):
- 问题清单严重度全部显示成绿色 + 修改建议不显示:模型输出 {sev:'high',fix} 与前端读取 {severity:'高',suggestion} 字段名与取值均不匹配
- 前端新增 normIssue 归一化,兼容 sev/severity/level 与中英取值,并回补所属维度显示
- 在 submit-review-tasks 与诊断/复盘 prompt 中固化 issues_json 字段契约,从源头防 schema 漂移

分镜提示词:
- 原创选题(video_id 为空)原本无生成入口(分镜按 video_id 查询)
- listStoryboards 支持按 rewrite_id 查询,前端放开入口、切版本重查,并补落库指令(此前入库靠模型自由发挥)

榜单展示:
- 期号改为显示区间「08/31 ~ 09/06」,避免被误读为单日(期号=该周周一)
- 后端新增 collectRanges,从落盘文件读真实 dateStart/dateEnd 随 API 返回(日榜 start=end 不显区间)

其他:
- 清理 dsh 环境废弃后的历史叙述类废话(16 文件约 18 处),文末变更记录区保留
- 新增 docs/工作台UI规范.md(设计 token / 布局 / 8 页面路由 / 12 类组件 / 9 条已知坑)
2026-09-10 18:28:42 +08:00

105 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 自动化任务清理规范(09-03 定稿)
> **用途**:后台自动化任务(一次性任务)积攒过多时,安全清理**过期 / 执行失败**的任务。
> **适用环境**:WorkBuddy 全环境通用(开发机 / 用户环境)——automations 表是 WorkBuddy 宿主自带(`~/.workbuddy/workbuddy.db`),不依赖 MCN 工作台,任何装了本技能的 WorkBuddy 都能执行。
> **红线(用户明确)**:**只能清理「过期」或「错误/失败」的任务**,禁止清理未来任务 / 周期任务 / 运行中任务。
## 一、触发场景
用户表达以下任一意图时,按本文档执行(不需要走创作流程):
- 「后台在执行什么任务?」
- 「没用的任务可以清空吗 / 清一下后台任务 / 把过期任务删掉」
- 「清理自动化任务 / 任务太多了」
执行前先**只读盘点 → 列出清单 → 用户确认 → 再删**,禁止未经确认批量删除。
## 二、判定标准(只清这两类)
自动化任务表 `automations` 存储任务定义,运行记录在 `automation_runs`,运行状态在 `automation_runtime_state`。
| 类别 | 可清理条件(全部满足) | 典型 |
|---|---|---|
| 🟢 **过期历史任务** | `schedule_type='once'`(一次性)且计划时间已过,且**已跑完**(有 run 记录且终态 ACCEPTED、`result_success=1`) | 工作台批量创作/复盘跑完后的任务定义 |
| 🔴 **错误/失败任务** | `schedule_type='once'` 且已终结但**未成功**:run 终态 PENDING_REVIEW / `result_success=0` / runtime_state 有 `last_error`(如 user_cancel 中断) | 被用户取消的导入、出错的复盘 |
| ⚪ **死任务**(可选,需用户点头) | `schedule_type='once'` 且**从未运行**(无 run 记录)且计划时间已过期(如 >24h 前),确认不会被调度器补跑 | 旧版重复任务、被新版取代的任务 |
### 禁止清理(硬性)
| 情形 | 原因 |
|---|---|
| `schedule_type='recurring'`(周期任务) | 未来还会按 rrule 触发 |
| 计划时间在**未来**(`scheduled_at` / `next_run_at` 未到) | 还没执行 |
| `automation_runtime_state.running=1` | 正在执行 |
| run 状态 QUEUED / IN_PROGRESS(排队/进行中) | 尚未终结 |
| `deleted_at` 已非空 | 已删过,无需处理 |
## 三、执行步骤
### 第 1 步:只读盘点(SQL 查询,只读不改)
数据库:`~/.workbuddy/workbuddy.db`(Windows: `C:\Users\<用户名>\.workbuddy\workbuddy.db`;macOS/Linux: `~/.workbuddy/workbuddy.db`)。**只用只读模式打开**(SQLite URI `mode=ro`),任务表可能被宿主进程占用,只读查询不受影响。
```bash
# 审计三表:automations(任务定义)/ automation_runs(运行历史)/ automation_runtime_state(运行状态)
python3 -c "
import sqlite3, os, datetime, json
db = os.path.expanduser('~/.workbuddy/workbuddy.db')
con = sqlite3.connect(f'file:{db}?mode=ro', uri=True)
con.row_factory = sqlite3.Row
cur = con.cursor()
def ts(v):
if v is None: return None
try: return datetime.datetime.fromtimestamp(int(v)/1000).strftime('%m-%d %H:%M')
except: return v
print('=== 1) 真正在跑(running=1,禁止清理)===')
for r in cur.execute('SELECT automation_id, running, last_error FROM automation_runtime_state WHERE running=1').fetchall():
print(dict(r))
print()
print('=== 2) 每个任务:类型/计划时间/是否已跑/是否成功 ===')
rows = cur.execute('''
SELECT a.id, a.name, a.status, a.schedule_type, a.scheduled_at, a.next_run_at, a.last_run_at,
COUNT(r.automation_id) AS run_cnt,
SUM(CASE WHEN r.result_success=1 THEN 1 ELSE 0 END) AS ok_cnt,
MAX(CASE WHEN r.status IN ('QUEUED','IN_PROGRESS') THEN 1 ELSE 0 END) AS active_run
FROM automations a LEFT JOIN automation_runs r ON r.automation_id = a.id
WHERE a.deleted_at IS NULL
GROUP BY a.id ORDER BY a.created_at
''').fetchall()
for r in rows:
d = dict(r)
d['scheduled_at'] = ts(d['scheduled_at']); d['next_run_at'] = ts(d['next_run_at']); d['last_run_at'] = ts(d['last_run_at'])
print(json.dumps(d, ensure_ascii=False))
"
```
### 第 2 步:按判定标准归档
对上面输出逐条归档到三类:**🟢 过期已完成** / **🔴 错误失败** / **⚪ 从未运行的死任务**(这三类之外的:未来任务 / recurring / running / QUEUED / IN_PROGRESS → 一律保留)。
### 第 3 步:列清单给用户确认
用表格呈现:`任务名 | ID | 计划时间 | 归档类别 | 建议动作(删除/保留)`,等用户明确同意后再删。
### 第 4 步:删除(走宿主工具,禁止直改数据库)
删除必须通过 WorkBuddy 宿主自动化工具逐条执行(`automation_update`,mode=delete),**严禁**用 SQL `DELETE` / `UPDATE` 直写 automations 表(宿主可能正持有连接;且工具删除是受支持的软删,会正确置 `deleted_at`)。
> 工具删除幂等安全:对已删除任务重复删会返回 `already deleted or does not exist`(success:true),不会报错。
### 第 5 步:复核
```python
# 只读复核:有效任务应为 0 或仅剩应保留项
SELECT COUNT(*) FROM automations WHERE deleted_at IS NULL;
SELECT COUNT(*) FROM automation_runtime_state WHERE running=1; -- 应为 0
```
## 四、补充事实(实测,便于判断)
- **宿主不会自动清理**:一次性任务跑完(ACCEPTED)后任务定义保留、状态仍 ACTIVE,调度器只扫未来时间,不会再触发——但也不会自动删除 → 需人工/按本规范清理
- **删除不影响任何产物**:已生成的脚本/复盘/会话历史在 `automation_runs`(保留),删任务定义只移除调度入口,不影响历史记录与产出文件
- 工具删除为**软删**(置 `deleted_at`),表行物理保留,逻辑上不可见
- 命名线索:`创作指令`/`复盘指令`/`重写-xxx(videoID)`/`修复-videoID`/`解析视频-xxx` 均为一次性任务;带明确未来重复意图(周报/日报)才会是 recurring