# State Machine ## Goal 定义 `biliup-next` 的任务状态机,取代旧系统依赖 flag 文件、日志和目录结构推断状态的方式。 状态机目标: - 让每个任务始终有明确状态 - 支持失败重试和人工介入 - 让 UI 和 API 可以直接消费状态 - 保证步骤顺序和依赖关系清晰 ## State Model 任务状态分为两层: - `task status`:任务整体状态 - `step status`:任务中每一步的执行状态 ## Task Status ### Core Statuses - `created` - `ingested` - `transcribed` - `songs_detected` - `split_done` - `published` - `commented` - `collection_synced` - `completed` ### Failure Statuses - `failed_retryable` - `failed_manual` ### Terminal Statuses - `completed` - `cancelled` - `failed_manual` ## Step Status 每个步骤都独立维护自己的状态。 - `pending` - `running` - `succeeded` - `failed_retryable` - `failed_manual` - `skipped` ## Step Definitions ### ingest 负责: - 接收输入视频 - 基础校验 - 创建任务记录 ### transcribe 负责: - 生成字幕 - 记录字幕产物 ### song_detect 负责: - 识别歌曲列表 - 生成 `songs.json` 和 `songs.txt` ### split 负责: - 根据歌单切割视频 - 生成切片产物 ### publish 负责: - 上传纯享版视频 - 记录 `aid/bvid` ### comment 负责: - 发布评论 - 置顶评论 ### collection_a 负责: - 将完整版视频加入合集 A ### collection_b 负责: - 将纯享版视频加入合集 B ## State Transition Rules ### Task-Level ```text created -> ingested -> transcribed -> songs_detected -> split_done -> published -> commented -> collection_synced -> completed ``` ### Failure Transition 任何步骤失败后: - 若允许自动重试:任务进入 `failed_retryable` - 若必须人工介入:任务进入 `failed_manual` 重试成功后: - 任务回到该步骤成功后的下一个合法状态 ## Dependency Rules - `transcribe` 必须依赖 `ingest` - `song_detect` 必须依赖 `transcribe` - `split` 必须依赖 `song_detect` - `publish` 必须依赖 `split` - `comment` 必须依赖 `publish` - `collection_b` 必须依赖 `publish` - `collection_a` 通常依赖外部完整版 BV,可独立于 `publish` ## Special Case: Collection A 合集 A 的数据来源与主上传链路不同。 因此: - `collection_a` 不应阻塞主任务完成 - `collection_a` 可作为独立步骤存在 - 任务整体完成不必强依赖 `collection_a` 成功 建议: - `completed` 表示主链路完成 - `collection_synced` 表示所有合集同步完成 ## Retry Strategy ### Retryable Errors 适合自动重试: - 网络错误 - 外部 API 临时失败 - 上传频控 - 外部命令短时异常 ### Manual Errors 需要人工介入: - 配置缺失 - 凭证失效 - 文件损坏 - provider 不可用 - 标题无法匹配完整版 BV ## Persistence Requirements 每次状态变更都必须落库: - 任务状态 - 步骤状态 - 开始时间 - 结束时间 - 错误码 - 错误信息 - 重试次数 ## UI Expectations UI 至少需要直接展示: - 当前任务状态 - 当前正在运行的步骤 - 最近失败步骤 - 重试次数 - 是否需要人工介入 ## Non-Goals - 不追求一个任务多个步骤完全并发执行 - 不允许继续依赖 flag 文件作为权威状态来源