ai-chatbot/docs/video-canvas-task-repairs-2026-09-17.md

146 lines
19 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.

# 视频画布任务与交互修复 · 2026-09-17
承接 `23f86dfc` 的全面扫描。用户补充“浏览器刷新一下就好了”,本轮重点修复任务结果与页面状态脱节,同时处理 F02–F07 中已确认的入口问题。本记录是分支修复与本地验收,未部署 48 服务器,也没有把原 231 项清单改成全部通过。
> 前半部分保留 0d17638a 阶段记录;本轮新增修复和验证见文末“后续修复”。
## 修复范围
| 扫描项 | 本轮改动 | 验证及边界 |
|---|---|---|
| F01 任务恢复 | 新增统一生成任务接口、数据库受理记录、请求 ID 去重、原子领取、心跳与结果保存;客户端提交前保存待核对请求,刷新/重开/online/focus/visibilitychange 时查询;去掉虚假进度;旧版无任务 ID 的 pending 明确提示无法恢复 | 主图像/视频生成、配置工具的图像/视频/分析、脚本再生成、批量分镜/视频接入。局部编辑按已有 taskId 恢复查询。真实数据库与浏览器验收见下文。专用图像后期、角度编辑、脚本弹窗资产生成/逐镜提示词仍有同步请求,未宣称全部入口具备同等恢复能力 |
| F02 取消 | 排队任务通过数据库 CAS 取消;已提交供应商的任务返回明确说明,继续保存结果;删除已完成结果写入任务隐藏记录 | 数据库并发及浏览器排队取消通过;没有冒充支持上游中止 |
| F03 模板 | 待执行模板设为 idle;参考样例标记示例;空脚本不再显示硬编码成稿 | 代码检查;未逐个模板做生产生成 |
| F04 脚本 | 脚本入口统一 story-script;空响应/无有效镜头返回失败并保留旧稿 | 结果契约回归通过;脚本资产生成与单镜提示词处理不是此次持久队列接入范围 |
| F05 批量 | 批量分镜和视频实际入队;按有无首帧选择兼容模式,采用模型声明的离散时长/比例/分辨率;完成任务不重复提交,失败/空节点可继续执行 | 模型参数和任务契约通过;没有新增真实付费批量请求 |
| F06 素材弹窗 | 去掉假分页和无效图标,增加搜索、纵向滚动、自适应列、素材名称与明确数量单位 | 实际组件注入 100 个素材,第 100 项能选中、确认回传,搜索返回 1 项;使用当前 Tailwind 编译产物验收 |
| F07 次级控件 | 文本及音频生视频提示词翻译接真实接口并预览后应用;旧脚本编辑聚焦;资源替换接上传;通知显示真实任务;模板筛选使用配置数据;退出接现有登出流程;未实现按钮明确禁用 | 代码与类型检查。未实际退出生产账户,未声称所有停用高级能力已实现 |
任务表复用既有 `0091_add_canvas_capability_tasks.sql`,没有新增数据库迁移。上线前须核对该既有迁移已应用。
## 任务一致性
- 同一请求 ID 重试不会重复执行;同一节点已有活动任务时复用现有任务。
- 同画布任务串行领取,多执行者通过 PostgreSQL 事务锁与状态更新竞争。
- 刷新前画布尚未保存的已受理节点,可从任务快照补回;不会从旧任务复活已保存删除的节点。
- 多图结果使用任务 ID 与序号组成稳定结果节点 ID,轮询不重复追加,重新生成不误用上次附图。
- 旧请求不能覆盖新请求;画布保存落后于新任务时,根据任务时间和保存版本恢复最新结果。
- 连线仅首次恢复时补齐,后续轮询不反复恢复用户已经删除的连线。
- 执行进程心跳超过 120 秒未更新,任务标记待核实;不自动重新提交付费请求。若原执行稍后确实返回,仍允许保存真实结果。
- 浏览器离开与服务端执行进程重启是不同情况:本轮解决前者的主要入口;进程中断后尚未实现供应商任务 ID 的自动续查。
## 验证记录
1. **真实本地 PostgreSQL**:`scripts/qa/video-canvas-task-db.cjs` 建立隔离测试库,加载实际任务表迁移和实际 store。10 次并发相同提交只创建 1 条记录;10 次并发领取仅 1 次成功;跨用户隔离、排队取消、执行中不可取消、串行队列、结果保存、结果隐藏、过期不重投、晚到结果保存全部通过。这是并发数据库调用测试,不是 10 个操作系统进程实测。
2. **真实浏览器任务恢复**:验收页使用实际 React Hook、实际任务 route/worker/store 与本地 PostgreSQL;鉴权使用固定测试用户,NextResponse/after 使用本地适配器,模型返回使用 12 秒测试桩。提交图片后立即刷新,最终出现 2 个结果且只 1 条任务;视频执行时关闭页面,再打开能恢复结果;后续分析排队任务成功取消;移除附图后刷新不复活。画布快照保存使用本地验收服务器,不是生产画布接口。
3. **实际素材组件**:100 项列表可定位选择最后一项,确认回传 `测试素材 100`;搜索同名只剩 1 项且保留选中状态;已有第 100 项再连续点选第 1–10 项,最终只选中 10 项,第 10 项(第 11 次选择)被正确拦截。验收期间先发现旧测试样式缓存,重新编译当前源码样式后验证通过。
4. **自动化**:最终 helpers/route 回归 437 项通过,无跳过,包含本次新增 13 项任务/批量参数测试和既有真实 FFmpeg 检查。不是 437 个生产端到端测试。
5. **静态检查**:TypeScript 无错误;`git diff --check` 通过。新增服务端模块与旧接口共享执行逻辑,图像计费仍走原有计费模块。
没有进行新的付费模型测试,没有重新宣称参考站像素级一致,没有覆盖操作系统休眠、真实断网、多标签冲突、生产 Next.js 进程重启或生产部署后的回归。原扫描中 79 项缺失/停用能力依然需要单独实现与验证,详见原验证矩阵。
## 复现
```sh
# FFmpeg / ffprobe 必须在 PATH 中,避免媒体测试跳过
pnpm exec playwright test --config=playwright.helpers.config.ts
pnpm exec tsc --noEmit --incremental false
# 隔离数据库测试依赖仅装入忽略的 .qa 目录,不改项目依赖
npm install --prefix .qa/video-task-db --no-save embedded-postgres
node scripts/qa/video-canvas-task-db.cjs
```
浏览器验收脚手架位于忽略目录 `.qa/video-durable` 和 `.qa/video-repair`;上述记录保留测试方法和模拟边界,不能代替后续部署验收。
## 后续修复:图片后期与脚本子任务(承接 0d17638a)
本轮把角度编辑(自定义参数及预设)、高清、扩图、抠图、宫格批量放大,以及脚本弹窗的资产生成、单镜/全部提示词合成接入已有持久队列。结果节点在提交时创建,完成后由任务查询更新;脚本任务另外按资产 ID、镜头 ID 回填对应字段。生成期间的修改或删除会保留,新结果继续留在独立节点,并显示冲突说明。脚本弹窗重新打开后显示服务器任务的处理中/失败状态。
高清接口的 AOS 分支可能先返回 HTTP 202 和 taskId。之前视频画布同步调用只寻找 original_url,导致将“已受理”误当失败。本轮先保存上游 taskId,再调用原有 GET 查询;查询中断或达到等待上限时标为“待核实”,保留上游标识,不重新 POST。当前仍不自动恢复服务端进程重启后的上游查询,需后续补全;浏览器刷新不影响在运行的服务端查询。
四个原 API 的执行实现抽取到 `lib/canvas/operations/`,原 URL 的入口继续通过 auth 验证身份;队列使用已校验的任务所有者调用共享执行函数。逐文件比较确认模型、存储、计费执行逻辑与抽取前保持一致。另修正上轮清理共享生图模块时遗漏的 `getCanvasImageTaskForUser` 导入,本轮完整类型检查通过。
本轮验证:
- helpers/route 回归 **447 项通过,无跳过**,其中任务专项 23 项;新增后期参数校验、202 续查只提交一次、断网/502/等待上限待核实、角度响应、空结果拒绝、脚本稳定 ID 回填与修改冲突保护。
- 真实隔离 PostgreSQL:原并发/权限/取消检查通过;新增上游任务标识写入、待核实时保留标识、不自动重投检查通过。
- 本地浏览器:实际 Hook/API/worker/store + PostgreSQL;鉴权、模型和后期服务使用测试桩。高清提交后刷新恢复;脚本资产提交后刷新自动回填;提示词提交后刷新自动回填 imagePrompt/motionPrompt,原对白保留;生成中修改资产的冲突保护单独检查。画布保存仍使用本地验收接口,不是生产画布 API。
- TypeScript 与 diff 空白检查通过;没有新增付费模型调用,没有部署 48 服务器。
仍需继续的项目:视频解析故事入口尚有同步请求,后台进程中断后的上游续查、多标签同时编辑、生产部署回归,以及原矩阵中的高级功能缺口。本轮不据此宣称 231 项全部完成。
## 后续修复:视频故事与上游任务续查(承接 86b66172)
本节更新前面仍标为未完成的“视频解析故事”和“AOS 高清已有任务编号续查”。这两项已完成分支修复与下述本地验证,其他范围不因此自动视为已修复。
### 视频解析故事
- 工具栏“解析故事”在提交时创建故事节点,进入实际持久任务队列;刷新、重新打开画布后通过任务状态恢复结果。故事节点重新运行也走视频解析,修正了原先落入通用脚本生成分支的问题。
- 解析失败或模型返回空镜头时显示错误并保留旧稿,新节点显示 0 镜。移除前后端自动填入的开场剧情、运镜、灯光、音乐等占位内容;缺失字段显示空值。
- 前后端共用镜头规范化逻辑,保留时间 0,不再截断成最多 8 镜;目前上限 120 镜。双击提交由本地提交锁和服务端同节点任务去重保护。
### 高清续查
- AOS 受理后先持久化 taskId、操作类型与源图,再查询结果。执行进程中断后,只恢复服务器已保存且与原请求匹配的高清编号;恢复分支只 GET 原任务,不重新 POST。
- 下一次画布任务查询发现心跳过期后标记 interrupted,再按 30 秒起、最高 5 分钟的间隔接管续查;限任务创建后 24 小时、总领取次数少于 20 次。不依赖后台永久调度器,服务重启后需要画布查询触发恢复。
- 增加领取次数校验:旧执行者的心跳、结果、检查点与失败不能覆盖已被新执行者接管的任务。恢复窗口内对同一节点重复点击运行会复用原任务。
- AOS 明确负数失败状态立即终止查询,修正被吞掉后长期显示 processing 的问题;每次网络查询有超时,整个短轮询按实际经过时间计时。
- 仍未给没有持久化上游编号的其他供应商任务添加自动续查;视频模型及 VIP98K 同步调用在进程中断后的恢复不能据此视为完成。没有任务编号的请求不会自动重投。
### 本轮验证
- helpers/route **454 项通过,无跳过**,其中任务专项 30 项;包含既有真实 FFmpeg 验证。新增检查编号匹配、恢复时限/间隔、GET-only 恢复、执行权失效、终态失败、AOS 短轮询上限、完整镜头及空结果拒绝。
- 真实隔离 PostgreSQL:10 个并发调用争抢续查只有 1 个成功;旧领取次数的结果/错误/检查点不能覆盖新领取;重复提交恢复中的节点不会新增任务。
- **独立进程中断与重启**:实际 worker/store + PostgreSQL,供应商使用本地桩。首次进程在受理、保存编号并开始 GET 后强制退出,第二个独立进程从库恢复并完成。调用记录严格为 `POST → GET → GET`,上游编号一致。这不是生产 Next.js 部署重启测试。
- **浏览器刷新**:实际故事节点组件、Hook、route、worker、store + PostgreSQL;鉴权/供应商/Next after 使用本地适配。故事任务处理中刷新后恢复为 1 个真实桩镜头;另一个空镜头响应变为失败,刷新后仍显示 0 镜与明确错误。画布快照保存仍为本地验收接口。
- TypeScript 无错误、diff 空白检查通过。没有新增付费模型调用,没有部署 48 服务器。
后续仍需完成:其他供应商执行中断恢复、多标签编辑冲突、生产部署回归,以及原矩阵列出的高级功能缺口。本次未声称参考站 231 项全部完成或像素级一致。
## 后续修复:五类视频续查、多页面保存与 3D 加载(承接 69dcf9b7)
本节更新前面仍列为待办的五类视频供应商续查、多页面冲突和部分导演台能力。以下均为分支修复与本地验收;没有部署 48 服务器,没有新增付费生成,也没有声称参考站 231 项全部完成。
### 视频提交与恢复
- 阿里云、VIP98K external task、火山、AtlasCloud、Agnes 五类异步视频适配器接入同一任务生命周期。上游受理后先保存 taskId、原模型和服务商身份,再查询;恢复只 GET 原编号,不重复准备参考素材或 POST 生视频。
- 恢复沿用既有 24 小时窗口、最多 20 次领取、30 秒至 5 分钟退避及执行权校验。由画布任务查询触发,不是脱离画布的永久后台调度器。
- 模型或服务线路发生变化时停止自动查询并保留原编号。未取得编号的网络中断显示待核实,不自动重新提交;VIP98K/火山的持久任务路径禁用不确定 POST 的自动重试。明确的图片超限拒绝仍允许火山压缩后重试。
- 明确失败/取消结束任务;AtlasCloud 的终态错误即使含有 network 字样也不会误当临时网络故障继续等待。没有上游编号的旧任务不能凭空恢复。
- 去掉领取恢复任务时旧的 240 条扫描截断,按恢复窗口和领取次数筛选,避免陈旧记录挡住可恢复任务。
### 多页面保存与草稿
- 遇到保存版本冲突,读取最新服务器内容,对基线、本页与服务器三个版本按节点/连线稳定 ID 和字段合并。不同位置的修改自动保留,同字段、删除与编辑、相互冲突的顺序修改必须显式选择。
- 页面展示冲突位置,可选择冲突处保留本页或服务器版;无冲突的修改继续保留。支持下载当前 JSON 草稿,不再让用户只能刷新丢掉一版修改。
- 浏览器 sessionStorage 按画布保存当前标签页的未保存草稿,隐藏、离开和定时保存前保留;重开当前标签页时与服务器版本合并。修正初始化时旧快照覆盖刚恢复草稿的问题。
- 移除节点序列化时每次重造的 createdAt/updatedAt,避免产生虚假冲突;服务器版本时间至少递增 1 毫秒。
- 远端连续保存导致超过 3 次自动合并重试时,暂停并保留草稿,用户仍可手动重试,不会进入永久阻塞。当前只在保存冲突时拉取其他页面版本,没有新增实时多人协同;sessionStorage 不是跨设备备份,存储满时仍需使用草稿下载。
### 3D 导演台逐项记录
| 原矩阵 ID | 当前实现与修复 | 验收及剩余边界 |
|---|---|---|
| 08-01、08-15 | GLB 30 秒超时、404/解析失败提示、空几何拒绝、重试加载;WebGL 上下文丢失后可重建场景;异常中止视频导出 | 实际浏览器:404→重试显示橙色方块;35 秒响应在 30 秒提示超时,晚到结果不冒充成功;空模型提示无有效几何;模拟 GPU 丢失→重试恢复原对象。未覆盖所有浏览器/显卡 |
| 08-10 | 八个人偶体型比例预设 | 实际浏览器选择幼童、重开保存;回归验证持久化。这是简化人偶比例,不等同参考站八种精细角色资产 |
| 08-14 | 复制对象与 3×3 群众阵列,限制总数 200 | 实际浏览器显示 9 个人偶;回归验证数量、间距、上限。未新增自定义行列阵列编辑器 |
| 08-17、08-18 | 上传 2:1 全景图、20 MiB 上限、20 条背景历史、默认背景、失败/20 秒超时提示及重试 | 实际 TextureLoader 浏览器渲染本地全景测试图、404 错误与切回默认背景;上传调用现有服务,未做生产对象存储上传验收 |
| 09-02、09-14 | 各机位保存独立相机轨迹,切换不串轨 | 浏览器:机位 1 两帧→新机位零帧→机位 1 恢复两帧;序列化回归通过。尚不是对象、相机、灯光同时运行的完整多轨系统 |
| 09-04、09-05 | yaw/pitch 旋转、持续注视所选对象;预览、截图、真实录制和发送的运镜描述共用相机解析 | 浏览器移动对象后注视坐标跟随,手动旋转会退出跟随;方向/距离及解析一致性回归通过。未实现相机位置跟随对象平移或物体动画轨 |
| 09-13 | 编辑机位时自动记录当前时间关键帧 | 浏览器启用后旋转相机更新当前帧;预览播放不自动写帧 |
| 09-19 | 整条轨迹右移 1 米、轨迹与注视方向一起转 90° | 浏览器检查变换后的首帧坐标;回归验证距离不变。不是自由变换轴或铅笔/钢笔路径编辑器 |
| 09-24 | MP4 不支持时回退 WebM VP9/VP8/默认编码,文件名与内容类型一致 | 录制测试覆盖 MP4 与 WebM 回退、切后台/取消/渲染失败清理;本轮未新增真实生产视频上传 |
### 最终本地验证
1. helpers/route **468 项通过,无跳过**,包括真实 FFmpeg 检查。新增模型恢复、合并冲突、独立轨道/跟随/体型/轨迹等回归;不是 468 个生产端到端测试。
2. `scripts/qa/video-canvas-provider-recovery.cjs` 调用实际模型选择与五类供应商适配器,使用合成目录、凭证及 fetch 响应。逐一验证受理后先存编号、查询中断、GET-only 续查、原服务商身份、明确终态失败只查一次、提交网络中断只 POST 一次。脚本禁止访问测试域名以外的网络,没有付费生成。
3. `scripts/qa/video-canvas-task-db.cjs` 的真实隔离 PostgreSQL 检查通过,新增视频编号持久化、重复节点去重、10 个并发调用仅一个接管;保留原高清独立进程中断恢复测试。视频本轮没有另做生产进程重启测试。
4. 两个真实浏览器标签页使用实际持久化 Hook 和冲突组件:不同节点修改自动合并,同节点冲突可选择且保留另一节点修改;恢复预置的 sessionStorage 草稿后可保存。画布 CAS 接口为本地验收服务器,没有写生产项目。
5. 实际导演台组件的 WebGL、独立机位、跟随、自动帧、群众阵列、全景和加载异常验收见上表。浏览器脚手架位于忽略目录 `.qa/video-concurrency`。
6. TypeScript 无错误,Git diff 空白检查通过。复现供应商检查:`node scripts/qa/video-canvas-provider-recovery.cjs`;其余测试命令同前文。
### 仍未完成的范围
原矩阵是历史扫描基线,本节是增量结果,不能据此将原 79 项缺失全部改为已完成。仍缺:TTS/音乐/音色接口,多画布/故事板/Agent 与跨项目资产,部分专用视频后期和智能剪辑,精细角色/手工关节、AI 识图重建、AI 全景、对象多轨、时间轴单位缩放、自由绘制轨迹,以及参考站逐状态像素对照与上线验收。现有服务尚无通用 TTS/音乐实现,不能用仅有入口或普通模型目录代替这些能力。未接通入口继续明确标示状态。