DEV-X-01-006 图片链路重构实施规格
统一URL输入、画布即时预览与后台入库、IndexedDB恢复、文件接口及跨仓验收
1. 规格边界与统一规则
2026-10-22执行范围更新:用户要求继续全平台原件改造,Drama本轮暂不修改;已启动的独立Commerce项目纳入实施。历史Drama记录保留追溯,不作为本轮继续修改Drama的授权。Commerce以最新独立仓库的素材库、图片编辑、海报、商品链接改图及视频工作流为边界,不再按冻结原型排除;Site公开发布桶仍独立。
本文是总体方案的实现补充。用户已确认的素材存储与画布规则为:图片和视频参考输入统一使用URL;导入先本地显示,随后自动后台上传并进入产品素材库;IndexedDB保存待同步内容;再次打开时结合本机草稿与云端版本恢复。 本文保留Proposed,表示整体跨仓实施及职责调整尚未完成规范落定;上述已确认交互不再列为待定,也不代表代码已上线。
| 场景 | 传输与持久化规则 | 用户操作时机 |
|---|---|---|
| 已有云端素材用于图片/视频 | 客户端提交file_id及内容版本;服务端核权后取得受限HTTPS URL | 派发前签发,不读回转Base64、不重复上传 |
| 本地新图、新蒙版或确认后的像素编辑 | File/Blob以二进制上传,得到可用file_id后按相同URL链提交 | 平时后台上传;生成时提高本次依赖优先级 |
| 无参考素材的生成 | 无需创建空文件或虚构引用 | 直接走现有授权与派发 |
| 导入画布 | 本地立即预览,IndexedDB保存与后台入库分别异步进行 | 节点出现不等待上述两项完成 |
| 移动、缩放、连线、复制节点 | 只保存布局和引用,复用内容版本 | 不重复上传原件 |
| 预览/下载/复用 | file_id和当前权限;预览派生,下载原件 | 签名地址仅临时使用 |
不新增逐渠道传输开关,不混合URL与Base64输入,不因URL失败改Base64重发。OpenAI/Gemini等协议字段差异保留在协议实现中;同一协议采用统一字段,私有字段不兼容应整改供给。既有公开API边界适配与供应输出Base64解析不因本方案被一并删除。
单URL及历史URL+Base64结果见真实供应验证。同一次图片请求的多URL尚未实测,混合输入通过不能替代多URL验收。 选择统一URL是产品与存储方案的收敛,不是宣称所有供应商已经兼容。
2. 分层与数据归属
| 层 | 持有的身份与状态 | 字节责任 |
|---|---|---|
| 浏览器 | local_asset_id、内容版本、草稿、上传回执映射、同步版本 | File/Blob及有界缓存;不持久化整图Base64或object URL字符串 |
| 产品BFF | 用户/团队权限、素材条目、画布快照、业务绑定与上传意图 | 流式转交字节,不另建正式原件目录 |
| Files / 现有File Owner | 不可变文件身份、上传回执、保护、派生、读取能力 | 唯一正式原件Writer;上传中暂存和恢复复用现有体系 |
| Platform | Operation、授权、计费、模型参数、输入file_id快照 | 不复制Base64到通用请求/结果快照,不接管产品素材库 |
| Runtime | Job、输入/输出引用、任务依赖、幂等送达 | 不持有原件claim、AssetVersion、下载续签或文件释放;依据ADR-0026 |
| 媒体网关 | Attempt、供应协议、执行状态、输入转换规格 | 解析受权URL,捕获结果并交Files登记 |
Files复用现有Owner代码,作为第7.2节独立媒体实例中的逻辑模块,使用该实例的新数据库与新桶,不再额外拆分专用文件服务或新建代码仓库。MG spool只作有界执行缓冲。产品继续拥有项目、素材库及领域权限;统一文件存储不等于把各产品私有内容搬进Platform业务库。
同一导入原件进入素材库并被画布引用,只写一份文件;创建两个业务引用不再复制字节。跨产品复用仍需来源授权与目标写权限,账号相同不自动互通素材库。
3. 最小数据模型
| 对象 | 必要字段(概念) | 不变量 |
|---|---|---|
| LocalAsset | local_asset_id、revision、Blob、MIME、name、本机保存状态、upload_id、file_id映射 | 改变内容产生新revision;恢复时从Blob重新创建object URL |
| CanvasDraft | account/product/canvas作用域、base_cloud_revision、local_revision、synced_revision、节点/连线/引用、待同步意图 | 完整本机草稿与云端提交版本区分;本机身份不可冒充云端file_id |
| File | file_id、不可变内容版本、Owner、SHA256、可信MIME、bytes、尺寸、state、来源 | 同一身份不能换字节;存储路径、签名URL不成为持久身份 |
| Binding | binding_id、file_id、产品/团队/业务target、generation、state | 保留不等于读取授权;创建/解除可幂等恢复 |
| Variant | parent_file_id、transform_version、transform_spec、output_file_id | 原件不覆盖;同转换可在授权范围内复用 |
| GenerationIntent | intent_id、model、输入身份/版本、参数、operation_id | 输入集合冻结;同键换输入拒绝;刷新查询原操作 |
每个内容版本有稳定上传身份,多个节点共用同一次上传;重试、重开浏览器、多标签恢复都不能另造上传意图。file_id可映射现有file_ref/revision,不为改名重写对象。客户端摘要和ID不是授权凭证;不提供跨租户摘要探测。
4. 画布本地优先与再次打开
4.1 导入、编辑和后台入库
- 选择、拖入、粘贴后立即建立节点和local_asset_id,用File/Blob创建object URL;异步读取尺寸。不等上传、哈希、IndexedDB落盘或服务器回读。
- 同时调度本机草稿持久化和后台上传;在线自动入库,断网暂停,恢复联网后继续。小图先采用单次流式上传,不让每个用户都承担会话/分片步骤。
- 上传队列有界并发和退避;选择用于生成的素材优先,其余保持后台队列。禁止逐张await上传后才添加下一节点,也不以固定延迟作为唯一触发方式。
- 文件校验就绪后,产品幂等登记素材库条目及画布引用映射,再保存匹配版本的云端画布。素材库可先显示“同步中”,完成前不能假报云端可用。
- 移动、缩放、连线、复制节点只改元数据。裁切、重绘等确认后的像素变更产生新版本并入队;处理中的每次鼠标移动或笔画不各上传一份,也不为每个中间版本创建素材条目。
上传完成只补充对应local_asset_id/revision的file_id,不能替换后来编辑的图片、布局或连线。删除后的迟到回执不复活节点;尚未派发且无任何消费者的上传可取消。若原件已入素材库,删画布节点不等于删素材库;文件删除仍按各处绑定判断。生成已冻结、Undo仍使用的版本保留其依赖。
4.2 生成、保存和分享
| 动作 | 字节范围与完成条件 |
|---|---|
| 图片/视频生成 | 冻结本次节点、显式参考及必要依赖;优先准备其中缺失文件,只等待这些文件就绪,然后以全部URL派发一次 |
| 自动同步 | 背景完成导入素材入库和画布元数据保存;不因每次移动重复上传已有文件 |
| 明确保存/分享整个画布 | 固定快照,保证其引用全部云端就绪且权限有效,云端接受对应版本后报告完成 |
| 本地导出 | 可直接使用本机Blob,无须先上传再下载 |
| 离开/关闭页面 | 尽力完成本机持久化,显示尚未同步数量;不依赖卸载事件或关闭后继续上传来保证保存 |
例如导入20张、选2张生成:20张都可后台入库,但生成仅等待所选2张,不能被另外18张的失败或队列尾部阻塞。输入准备失败时不创建收费派发;保留可重试意图。等待期间编辑素材不静默更换被冻结输入,取消重提作为新意图处理。
4.3 IndexedDB范围与清理
必须保存尚未上传的Blob、尚未云同步的完整画布快照、内容版本到上传回执/file_id的映射及恢复所需意图。可按容量预算保存缩略图和近期内容缓存;不默认下载整个云端素材库作为本地镜像。object URL只是当前文档句柄,不能把它或Base64字符串当作持久原件。
数据按账号、产品、画布隔离;切换账号不得展示前一主体草稿。恢复前建立当前授权上下文;多标签用版本比较与单任务租约或等效协调,同一上传的服务端幂等仍为最终保护。
本机保存以IndexedDB事务提交为准,不能以入队或内存更新为准。配额不足、私密模式限制、浏览器清理等情况显示真实未保存/缺失状态,保留仍可用内存并提供重试或导出。可申请持久存储,但不承诺浏览器永不清理。没有云端版本且本机Blob已丢失时,保留节点信息并提示重新选择原文件,不能假造恢复成功。
未同步草稿不按固定TTL自动删除。仅当原件就绪、素材库登记和相关云端画布引用确认,且无待同步编辑、生成准备或Undo依赖时,本地原件才转为可淘汰缓存。缓存可按容量/LRU清理,上传回执映射与仍需草稿不能随缓存误删。
4.4 用户下次打开画布
| 已保存状态 | 同一浏览器打开 | 另一设备或本机缓存丢失 |
|---|---|---|
| 原件和画布已云同步 | 可先用已授权本机缓存展示,同时拉取最新云端版本 | 从云端快照与文件恢复 |
| 原件尚未上传,本机草稿完整 | 从IndexedDB恢复节点和Blob,重新创建object URL,恢复后台上传 | 只能看到最后一次云端快照;明确该设备没有未同步素材 |
| 原件已上传,画布元数据未同步 | 查询原upload_id并复用file_id,只补素材登记/画布同步 | 已登记素材可在素材库找回;画布局部改动未上云就不能承诺恢复 |
| 本机有待同步修改,云端被其他设备更新 | 保留本机草稿,与base_cloud_revision比较并提示冲突 | 仍以该设备可取的云端版本为准 |
| 上传或保存回执未知 | 先查询原命令/版本回执,再决定补传或重放 | 服务端仅恢复已收到且有授权的事实 |
恢复顺序:重新认证 → 读取本机快照用于快速展示 → 同时拉取云端最新版本 → 无本机待同步改动时采用最新云端;有改动且云端未越过基线时继续提交;双方都变更时保存本机恢复副本并提示选择/合并。不能用“最后打开的时间”无条件覆盖任一端,首期不要求完整实时协同算法。
云端保存使用base revision/CAS及稳定保存命令。回执未知先查询,避免把自己已提交的版本误判为他人修改。旧异步读取响应不得覆盖用户打开后新编辑的本机版本;旧上传响应同样按内容版本合并。
进入画布优先读取可见区域缩略图和必要元数据,视口外延迟加载;编辑、放大或下载时再取原件。云端长期只存稳定文件引用与内容版本,过期URL按当前权限续签,不重新上传。
5. 统一接口形状
以下是逻辑能力,不是已存在的HTTP路径。Owner维护版本化schema,TS/Go客户端共用合同;不要求前端理解claim或技术暂存目录。
| 能力 | 输入 | 完成与重试 |
|---|---|---|
| files.upload / getUpload | 单次multipart/二进制、作用域、稳定上传身份和幂等键 | 返回同一file_id;ACK未知先查询,缺失字节才补传 |
| files.get/read | file_id、用途、variant、disposition | 核权后受限读取,续签不创建新文件 |
| files.bind/unbind | 文件、业务target、稳定命令和generation | 同命令同结果,旧命令不得作用于新代际 |
| canvas.get/save/getSave | 画布ID、完整快照、base revision、保存命令 | CAS提交、回执可查询;拒绝冲突并保留草稿 |
| generations.submit/get | intent_id、模型参数、输入file_id与版本;查询operation_id | 服务端核权及保护就绪后单次派发;查询不隐式生成 |
{
"intent_id": "client-stable-intent",
"media_type": "image",
"model": "published-image-model",
"inputs": [
{"role": "reference", "file_id": "existing-file", "revision": 1},
{"role": "reference", "file_id": "newly-uploaded-file", "revision": 3}
]
}此例中第二张已通过上传取得file_id,最终两项都是供应商可读HTTPS URL。没有local_part、Base64或blob URL的生成输入分支。服务端不信任客户端Owner/scope/摘要;并发上传允许部分成功复用,不因一个失败而重传全部。
6. 入库、同步与生成状态
上传字节校验、正式文件登记、素材库绑定、画布同步是不同确认点。文件已上传但产品事务失败时,通过持久outbox/幂等命令补登记,不重复Put/Copy;不能只靠页面回调收尾。上传未就绪前的技术暂存由Files管理,不另建面向产品的ExecutionInput资产类型。
完整云端画布只提交可解析的稳定引用;尚有本地文件时保留完整本机草稿与最后已提交云端版本,显示“本机已保存,云端同步中”。元数据自动保存可合并短时间编辑,但不能把包含本机句柄的快照标成已云保存。生成可以只等其依赖就绪,不必等待整个画布快照上云;执行保护须在首次付费派发前建立。
| 维度 | 状态/事件 | 恢复原则 |
|---|---|---|
| 本机保存 | memory_only / writing / saved / failed | 未完成事务不假报;不与云同步共用一个saved布尔值 |
| 上传 | queued / uploading / verified / failed / receipt_unknown | 同身份查询与重试;同键换字节拒绝 |
| 素材登记 | pending / bound / failed | 原文件不重传,重放同一业务登记 |
| 画布同步 | dirty / syncing / synced / conflict / failed | 以具体revision为准,冲突保留本机恢复副本 |
| 执行 | preparing / authorized / submitting / accepted / running / submit_unknown / terminal | 未知只核对原Attempt,不因URL失败换格式/渠道重新生成 |
| 输出与交付 | capturing / saved / save_failed / irrecoverable;pending / bound / detached | 保存失败只恢复原结果,交付按持久命令重放 |
| 资金 | 沿现有Operation状态 | 文件就绪不等于获准交付;不另建钱包或结算机 |
签名有效期覆盖供应端实际取图窗口,排队时不提前签发;派发前再核对授权、保留和地址。上游已接受后地址到期按原任务恢复协议处理,不能另发付费请求。用户取消等待不等于供应商取消、失败或退款。
7. 网关协议边界
| 改造点 | 要求 |
|---|---|
| 入参领域 | 接收受权file_id/版本,经可信解析得到URL;浏览器不决定任意内部读取地址 |
| 统一传输 | 图片和视频均URL,不新增渠道transport配置及Base64降级 |
| OpenAI兼容图片编辑 | 目标基线为/v1/images/edits的images[].image_url填HTTPS地址;reference/mask角色按明确合同验收 |
| Gemini图片 | 既有协议的fileData.fileUri填获准HTTPS地址;实际URI类型、单URL、多URL分别验收 |
| 视频 | 保持首尾帧、参考图/音视频URL输入,核实异步取图与有效期 |
| 输出 | 仍可解码供应返回的Base64或捕获URL原始字节;输入统一URL不代表输出只能URL |
| 体积与内存 | 上传按二进制/像素预算;生成JSON按引用数量/参数预算。核实当前1 MiB Handler及代理上限,不再为整图内联扩容 |
| 恢复与诊断 | 持久保存引用和转换规格,不记录凭据、完整签名地址或图片正文;未知请求不换协议重发 |
统一字段不保证全部现有供给兼容。CookingAI的私有image字符串等保留在实测证据中,不据此增加渠道分支。HTTP 200但未采用某张参考图视为失败;多URL、顺序、角色和实际图像特征须独立核验。未验证、当前不可用、管理员停用分别记录,不自动改生产路由或启停。
7.1 存储角色与最终位置写入
桶分工及逐桶保留/调整以总体方案4.1为准,实际配置证据见云端只读核对。本规格不包含生产配置执行。
- 新链使用统一Files Owner及正式业务桶,新上传和生成结果写最终不可变对象键;记录接收/输出意图后写入,校验与登记成功才ready。未就绪对象不签发读取,也不能仅凭文件在正式桶就开放。
- 不把“临时Put→主桶Put→副本Put→Publish”作为正常链。先查同一上传/原执行输出回执和对象身份,未知ACK不换键重写;已就绪文件业务复用Put/Copy为0。确需临时保存的唯一恢复字节保留到正式写入确认,不进可自动到期的缓存范围。
- MG后续配置和readiness取消replica必填及强制探测;新链保存不等待副本。已有部署保持原配置,直至统一版本和Owner接线验收,不能只把环境变量清空或把三个角色填同一桶来绕过旧代码约束。
- 当前OceanWay新实例仅使用新桶,不读取或复制旧main/replica/assets/media对象;旧实例维持自身业务,不为新链提供文件读取fallback。
- 原件与预览分前缀;预览是有来源的可重建派生,失败不阻断原件下载。正式原件无年龄TTL;开发阶段上传、生成与辅助临时处理均不新增或继承7天自动删除,桶生命周期、部署模板及应用清理默认值保持一致。首期不启用新的自动物理GC;后续临时数据定时清理按实际需要另定,不作为当前开发前置条件。
- 普通读取只核当前业务权限、文件ready和首次交付资格,不重新adopt、创建长期claim或恢复原账;必要内部保留机制由Files处理。用户删除先提交解绑outbox,远端释放异步,不等待物删才更新画布,也不提前宣称释放确认。
- CORS是浏览器路径配置,供应商服务端取URL另验可达性。逐实际Origin验证预览、fetch、canvas导出、HEAD/Range;如采用直传再核PUT及签名头。保持私有访问,不把CORS与文件授权混为一谈。
7.2 独立实例、数据库副本及全新桶(最新确认)
目标地址固定为https://media.oceanway.tech。复制服务代码及数据库,数据库落入独立新库;所有新业务文件使用新建桶,开发阶段不迁移旧数据/文件、不兼容旧素材引用。这里“数据库复制”是初始化方式,不要求仅复制schema;“不迁移旧数据”指不将复制过来的旧客户任务、资金、文件引用作为新业务继续执行或提供读取。本方案不修改源库、原业务或旧桶。
| 资源 | 目标配置与边界 |
|---|---|
| 服务与发布 | 独立应用/worker实例、部署目录、容器和网络;复用已审计源码,新版本独立发布。原网关固定生产发布目标保持,不能用复制后的脚本覆盖旧容器 |
| 数据库 | 源数据库一致性逻辑快照恢复到新库,新DB凭据和应用角色;应用/worker保持关闭直到初始化结束。不能连接源库启动应用或AutoMigrate |
| 数据初始化 | 完整复制后,仅在新库清理/停用旧任务、回调、重试、租约、素材/文件引用、会话/API授权及旧客户业务状态;保留所需模型/渠道/路由/价格配置。先列准确表、依赖顺序及行数再执行,不以删除整个源库实现“从零开始” |
| 账务和调用身份 | 新服务使用独立OceanWay调用身份及Key,File Bridge/签名秘密独立;旧客户余额、订单、账务和会话不生效。Platform仍为新业务唯一客户资金Owner,不因克隆新增一套客户余额 |
| Redis与worker | 独立空Redis/队列及调度域;不恢复旧队列消息,不运行复制过来的旧任务,不向旧回调地址发送请求。克隆实例初始化期间禁止供应调用、回调、支付及清理出站 |
| 存储 | 新建私有业务桶;临时处理/公开发布桶按需新建;不创建必需原件副本。新IAM只允许对应新桶,旧桶不在权限范围;不复制旧生命周期、旧CORS或7天应用到期默认值 |
| 域名与入口 | media.oceanway.tech的DNS、HTTPS证书、反代和回调origin单独配置;真实浏览器CORS按操作最小开放,不让旧域名规则自动生效。域名/证书配置尚未执行 |
| 消费者 | Platform托管模型连接和File Bridge均绑定新origin与新凭据;产品文件SDK及引用同步对齐,Runtime服务不配置Files身份。先独立验收后切新请求;新链无旧服务/旧桶fallback |
| 供应配置 | 从复制库保留所需渠道/模型配置;逐项核对上游地址、必要秘密解密与供应配额。供应密文用受控方式重加密后验证,不直接替换加密秘密导致配置失效;不复制整份生产env或把旧客户Key继续当新业务身份 |
原业务已受理任务由原实例自己处理;新实例不接管、重派或对账这些任务。新开发界面不恢复旧素材记录,文件缺失不触发从旧桶下载复制。此范围不要求旧新数据库持续同步或历史双读双写。
7.3 精确改动清单
身份审计已确认当前有原件直接写正式桶的图片分支,以及旧网关token100/101共用user1的问题。独立实例方向下,不再修改旧网关增加新旧客户分桶绑定,也不把证明旧token专用性作为新部署前置条件;直接为新实例签发独立身份。复用原件分支,补齐视频和全入口覆盖。
| 责任与位置 | 新实例所需改动 | 验收重点 |
|---|---|---|
| Infrastructure:新部署模板、DB初始化脚本、DNS/反代 | 固定media.oceanway.tech;新实例、新数据库副本、新Redis、新桶及独立秘密;初始化清单按7.2执行,启动前验证目标身份 | 旧容器/数据库/桶/凭据不变;新实例无旧库连接和旧桶权限;旧任务不会重跑 |
Platform:platform_model_connections.go、platform_media_gateway.go及托管连接表 | 新图片/视频连接指向media.oceanway.tech,使用新服务Key;不只改env、不沿用旧token100/101。切新请求时同时校验模型绑定、供应能力及价格 | 获准图片和视频都走新实例;新服务故障不改向旧网关或重新生成 |
新网关:middleware/auth.go、service/file_reference.go、service/file_original_output.go | 新业务独立鉴权;File Bridge绑定新principal/source身份。实例正式存储策略由服务器决定,namespace仅承载授权范围;去掉空namespace降级普通旧桶路径 | 旧Key/会话无效;伪造namespace拒绝;所有获准请求只使用新桶 |
新网关:service/async_image.go、model/async_image.go、model/task.go、model/file_original_output.go | 新任务受理时固定producer、backend/bucket、策略版本及输出身份;保存时用快照,复用既有写入意图和幂等机制 | 重启/轮换/配置变化不改变本次新任务的位置;未知写回执查询原对象,不重复生成 |
新网关:relay/async_image.go、image_output_archive.go、image_delivery.go及原生图片入口 | 覆盖同步/异步、OpenAI/Gemini、图片编辑、URL/Base64结果;复用persistOriginalImage及正式存储校验。未支持组合派发前拒绝 | 每份新结果一次正式写入,不先归档旧桶再复制;TargetBucket等客户端字段不得绕过策略 |
新网关:seedance_v2_archive_runtime.go、seedance_v2_archive.go、model/seedance_v2_archive.go及视频受理 | 新视频/末帧归档记录固定新bucket/backend和策略;worker使用对应存储,不依赖旧全局桶 | 视频与末帧单次写新桶,可供素材库和画布复用;不增加旧归档记录兼容分支 |
新网关:service/media_storage.go及到期读取/清理路径 | 正式文件支持明确无年龄到期模式,解除新实例1~30天保留限制;签名URL有效期独立。删除旧桶必填/unused占位及replica强制依赖 | 超过7天仍可续签读取;只配新业务桶也能启动;无自动继承旧清理任务 |
Platform:platform_media_original_outputs.go、platform_image_adapter_openai.go、platform_file_bridge.go、platform_media_pricing.go、platform_media_files.go | 新生成origin与File Bridge统一media.oceanway.tech;补视频文件引用和获准API入口,去掉非必要重复采用/原账恢复依赖 | 新实例同源授权明确;正常读取不重复登记;不要求开发旧producer历史读取兼容 |
| Studio:文件SDK、结果绑定和画布同步 | 配对新File Bridge凭据与producer,使用同一file_id;新画布业务从新文件开始,保持IndexedDB与后台上传体验 | 新上传/生成/下载/复用全链不访问旧桶,不二次转存;新环境不误恢复旧账号/旧producer的本机草稿 |
本次仅写方案,不执行生产或新环境部署。源代码定位以已核制品为依据,实施时对照目标分支并保留他人修改。复制同一代码仍可独立发布,不强制新建代码仓库;旧生产不会因新实例代码升级自动重启。
7.4 从复制到启用的顺序
- 固定源实例/数据库及源码版本,创建独立目标部署目录、DB、空Redis和新桶;新应用/worker不启动,出站保持关闭。桶名、容器名和DB名先记录,不冒充已存在资源。
- 只读导出源数据库一致性快照并恢复到新库;核验目标连接与schema/配置完整性。新库按清单初始化旧业务数据、文件引用、会话与后台执行状态;不复制旧文件,不对源库做清理或迁移。
- 注入新身份、服务/存储凭据及供应配置,完成必要密文转换;配置media.oceanway.tech的DNS、证书、反代与新回调入口。初始只启用健康/元数据验证,未通过身份与资源检查不得启动任务执行。
- 在新实例验证图片/视频、单原件写入、URL读取/续签、素材复用、重开画布及失败恢复;对旧库、旧桶访问失败作明确断言。付费生成与实际切流按具体授权执行。
- 验收后修改Platform托管连接、File Bridge和产品文件入口,切换新业务请求。失败时暂停新业务;不回退旧桶、重派未知任务或让旧生产承担新规则。旧业务实例、数据库和桶始终维持原状。
8. 结果、读取与复用
生成完成即捕获短期URL或解码Base64输出,按原执行+output_index幂等登记原始文件字节。原件保持格式、透明通道及原始信息;缩略图和旋转展示由派生承担。保存回执未知查询原登记,输出不可恢复时如实标记,不重新生成;批次部分失败不能重做已完成输出。
普通下载只核验当前业务权限/交付资格和读授权,不再次采用原件或恢复账务。签名并发续签可合并,权限撤销不无限重试;旧签名URL不承诺立即失效,需即时撤销的场景采用受控读取。私有缓存隔离账号与权限,Site公开资源沿独立发布流程。
同一文件进入素材库、画布、对话或剧集,只新增获准Binding;裁切、重绘等内容变化创建有来源关系的新文件。删除只解除本处绑定,其它引用和执行保护继续有效,首期不新增自动物理GC。
9. 错误与用户动作
| 事实 | 用户提示含义 | 系统动作 |
|---|---|---|
| IndexedDB写入失败 | 尚未保存到本机 | 保留内存,重试/导出;云端状态单独显示 |
| 上传中断/回执未知 | 素材同步尚未完成 | 查询原上传,缺字节才补传;节点继续编辑 |
| 已上传但登记/画布同步失败 | 原件已上传,素材或画布仍待同步 | 重放原登记/保存;不重复上传 |
| 双端同时修改 | 有尚未合并的本机修改 | 保留恢复副本,明确版本冲突 |
| 换设备找不到未同步文件 | 此设备只能读取云端版本 | 说明需回原设备继续同步,保留可恢复信息 |
| 模型输入不兼容 | 素材不符合数量/尺寸/角色或供给协议 | 派发前拒绝,提示可执行修改,不静默裁切 |
| 上游接受未知 | 正在确认原生成结果 | 原Attempt核对,不换URL/Base64重发 |
| 结果保存失败/不可恢复 | 生成与保存状态分开说明 | 恢复原输出;确实不可恢复才终结文件阶段 |
前端不暴露claim、namespace或数据库术语;内部用upload_id、file_id、canvas revision、operation_id、binding_id关联诊断。
10. 分阶段工作包与责任
下列编号是提案逻辑拆分,尚未注册正式WP;详细映射见总体方案。
| 顺序 | 责任范围 | 工作 | 退出标准 |
|---|---|---|---|
| P0 | Docs、各运行Owner | 固定实际Writer/制品;规范文件、素材和画布的归属 | 实际源码可核,职责调整有对应规范 |
| P0c | new-api、Platform、Infrastructure | 按7.2~7.4准备media.oceanway.tech独立实例、数据库副本、新桶及初始化;补全存储入口 | AC31~AC40通过;旧生产不变,新业务无旧文件依赖 |
| P0a | Studio画布 | 即时预览、IndexedDB、后台入库、重开恢复和冲突处理 | Studio离线恢复与各确认点通过;Commerce按第10.1节远端存储,不复用该Blob草稿策略 |
| P0b | MG、Platform协议Owner | 统一URL、标准协议、单/多URL图参验证 | 无渠道传输分支;结果按内容核验,不直接生产切流 |
| P1 | File Owner、Infrastructure | 流式上传、回执查询、稳定引用、受权读取 | 一次原件落地,未知ACK可恢复 |
| P2 | Platform、供应适配 | file_id贯穿Operation;派发前URL准备;结果及时登记 | 输入就绪后单次派发,保存故障不增加模型POST |
| P3 | Runtime / Studio | 产品调用文件SDK,Runtime只编排及可靠送达,执行保护交给Platform/Media与Files | 已有业务绑定不受会话删除破坏 |
| P4 | Studio、Commerce业务层 | 全入口保存、复用、读取和解绑 | 素材库与画布同file_id,业务权限独立 |
| P5 | Site公开发布边界 | 显式发布与公开衍生文件映射 | 私有原件与公开发布桶独立;不隐式发布私有素材 |
| P6 | 活跃消费者 | 统一制品联调、故障与性能对照 | 停新保已有读取,原任务沿原Writer处理 |
按ADR-0024不恢复旧测试数据迁移、双读双写、跨版本回退、开发备份或联合灾备门禁。本机草稿恢复属于编辑可靠性,不是新增跨服务灾备项目。
10.1 Commerce的统一原件接入
Commerce维持独立部署和既有工作流。当前宿主仍为单用户、仅loopback的开发网关;File Owner接线不能代替中央身份与逐用户授权,也不能据此公开网关。
- 素材上传由产品服务登记稳定命令;查询仅接收UUID、SHA-256、字节长度和MIME,命令指纹绑定当前宿主/File Owner作用域。并发、丢失响应和刷新继续使用同一命令,元数据查询恢复后不重传原件。命令冲突、未知状态或回收站中的素材拒绝继续,不以新命令自动兜底。
- 最新用户决定:Commerce不再使用本地媒体存储。 编辑器、品牌、批处理、AI工具不向IndexedDB写入媒体Blob或上传回执。File/Blob只作当前页面的内存预览;成功后设计和任务保存稳定素材ID与同源读取入口。浏览器仍可保存项目/设计元数据;未成功提交的文件不承诺关闭页面后恢复。本轮不自动清除既有浏览器数据,旧媒体表不再读取/写入。
- 素材库进入工具、结果进入编辑器直接复用产品素材ID;结果入口可返回原件元数据,不能先下载再作为新素材登记。切换编辑模式保留URL中的素材ID,刷新恢复相同原件。
- File Owner为必需配置,只使用专用服务身份与可信subject,产品域为commerce。缺配置、部分配置、Owner拒绝或回执不一致均拦截;不得启用本地文件或限时relay兜底。宿主仍单用户loopback,不能据此公开服务。
- 上传素材、图片/海报/商品链接各镜头成品、最终视频和换装raw结果都先获得Owner回执再发布可用状态。结果入同一素材目录,只有稳定原件证明持久化;图片多参考角色按顺序映射为HTTPS URL,视觉文本请求和Seedance同样使用URL。未验证URL映射的视频协议在收费前拒绝。
- 原件grant和签名URL仅在当前调用内使用。预览跳转到当前授权地址,下载有界临时读取并校验长度/SHA/MIME,不向对象服务转发宿主凭据。下载后清理临时字节;无常驻原件缓存。历史项目读取仍可访问移入回收站的原件,新的素材选择/生成拒绝回收站引用。
- 产品SQLite保存素材分类、任务、稳定引用及JSON/SRT文本元数据;不将媒体字节或Base64写进业务库。FFmpeg/Pillow输入、合成帧与输出仅在任务临时目录中处理,正常/异常结束清理,父进程在取消/终止worker后清理其目录。整机硬崩溃可能遗留OS临时文件,宿主清理即可,不得作为正式读取来源。
- 图片/视频上传25MiB,音频15MiB,不能把Owner更低的音频上限留到付费任务之后才发现。File Owner上传契约按真实容器字节识别WAV常见MIME别名、Ogg音频和Matroska;保持旧客户Asset API不变,不将扩展名当内容证据。
- Owner保存失败不能假报完成、落盘兜底或自动重发付费生成。若模型结果仅存在worker内存而Owner不可用或worker在确认前退出,当前候选无法跨进程恢复该结果;供应商结果采用/故障恢复仍须另行闭合。中央用户接线、真实新实例/桶联调、跨域画布导出和生产切换也不以本机测试代验。
11. 验收矩阵
| 编号 | 场景 | 必须观测到的结果 |
|---|---|---|
| AC01 | 断网批量添加20张图 | 节点独立出现可编辑,保存本机;重联网自动排队入库 |
| AC02 | IndexedDB慢写/配额拒绝/切换账号 | 预览不等待落盘,失败不假报,账号隔离 |
| AC03 | 20张只选2张生成 | 2张优先且只等待这2张;其余仍后台入库,不阻塞本次派发 |
| AC04 | 已有图和本地新图用于图片/视频 | 最终均HTTPS URL;已有图不重传,新图只上传一次 |
| AC05 | 裁切、蒙版、移动、复制、Undo | 确认像素编辑新版本,纯布局不重传,Undo依赖仍可恢复 |
| AC06 | 上传中替换/删除/迟到响应/多标签 | 不覆盖新版本或复活节点;同内容版本不重复上传 |
| AC07 | 已存素材再次生成 | 仅传文件身份,权限重新核验,无业务侧Base64编码 |
| AC08 | 导入后自动入库和画布引用 | 同file_id/原件SHA;每次业务复用Put/Copy为0 |
| AC09 | 上传或保存ACK丢失、进程重启 | 先查原命令,再恢复必要步骤;不另造原件或生成 |
| AC10 | 上游超时/断连/502接受未知 | 只核对原Attempt,不换格式/渠道自动重发 |
| AC11 | 超限文件、解码炸弹、MIME冒充、不受权URL | 可信边界有界拒绝,未收费派发,限制可解释 |
| AC12 | 标准单URL和多URL真实编辑 | 每份参考图未写进提示词的特征均有效;顺序/角色正确,200不足以通过 |
| AC13 | 输出URL过期/批次部分保存失败 | 恢复原结果或标明不可恢复,不重生成已完成输出 |
| AC14 | 原件下载/缩略图/裁切导出 | 原件SHA不变,派生有来源,格式和透明通道符合语义 |
| AC15 | 删除与迟到绑定/解绑竞争 | 代际判断拒绝旧命令,仍有有效引用不删除 |
| AC16 | 停新上传/生成、读取权限撤销 | 停新不阻已有获准读取,撤销不无限续签 |
| AC17 | 跨产品复用/分享/Site公开发布 | 来源与目标核权,私有内容不默认公开 |
| AC18 | 供应不兼容标准URL字段 | 明确待整改,不建立渠道传输特例、不伪报支持 |
| AC19 | 已云同步后本机/另一设备重开 | 从最新云端恢复;本机缓存只加速,不覆盖新版本 |
| AC20 | Blob未上传时关闭重开 | 本机成功保存的节点/Blob恢复并续传;另一设备不伪造完整恢复 |
| AC21 | 文件已上传但素材/画布未同步时重开 | 查回执复用file_id,补登记及保存,不重复传原件 |
| AC22 | 双端修改、保存回执未知、加载中继续编辑 | CAS检测冲突并保留本机副本;旧响应不覆盖新编辑 |
| AC23 | 大画布重开、缓存冷/热、签名过期 | 可见区域缩略图优先,原件按需取,过期续签不上传 |
| AC24 | 缓存淘汰/浏览器清理/Undo仍引用 | 未同步数据不按TTL清理;实际缺失不假报恢复,仍需版本不提前释放 |
| AC25 | 新上传/生成结果保存与回执未知 | 正常路径只写正式原件一次;无必经临时/副本Put;未知查原对象,未校验不可读 |
| AC26 | replica未配置/不可用 | 新链启动和保存不依赖副本;已有部署和历史读取未被直接改动 |
| AC27 | 开发阶段无7天自动删除,旧业务隔离 | 新链上传、生成及辅助临时文件不进入旧规则范围,桶配置/部署模板/应用清理不继承7天默认值;new-api-new-oceanway旧业务现有规则本次不改,唯一恢复字节不被缓存TTL误删 |
| AC28 | 原件已ready、预览失败、生成服务停新 | 原件仍可按当前授权读取;不创建新保留或恢复生成账务 |
| AC29 | 实际产品Origin预览/fetch/canvas导出 | 逐路径CORS验证,权限保持私有;服务器取图成功不代验浏览器路径 |
| AC30 | 旧资源边界 | 原业务资源保持原状;新开发链不迁移、不读取、不恢复旧文件,不为旧引用增加兼容 |
| AC31 | 两实例并行 | 旧顾客仍访问原实例;OceanWay图片/视频及File Bridge指向media.oceanway.tech;新请求只写新桶 |
| AC32 | 新任务恢复与目标故障 | 本次新业务任务重启/配置变化仍沿用受理位置;故障不回落旧桶、不重派生成 |
| AC33 | 克隆后身份隔离 | 新库不接受复制过来的旧Key/会话;新服务只接受获准新身份;源库凭据不变 |
| AC34 | namespace与默认存储 | 获准新请求由实例策略进入新桶;缺失header不降级;越权namespace、过期凭据在派发前拒绝 |
| AC35 | 所有获准结果入口 | 同步/异步图片、OpenAI/Gemini、URL/Base64输出、编辑及视频/末帧分别验证;未支持组合派发前拒绝,不以图片async通过代替全入口 |
| AC36 | 对象保留与地址过期 | 时间推进超过7天后OceanWay原件仍可续签读取,旧顾客既有到期行为保持;不存在全局retention覆盖新策略 |
| AC37 | producer和Key轮换 | 所有新调用与文件授权绑定media.oceanway.tech;轮换不改变已接受新任务的位置或重派请求 |
| AC38 | 新视频归档 | 视频、末帧和记录都使用新bucket/backend;新链没有旧历史位置读取fallback |
| AC39 | 数据库复制后首次启动 | 仅恢复到新库;旧任务/回调/清理/队列不运行,旧客户资金与授权不生效;旧库无写入 |
| AC40 | 全新桶与入口 | 新凭据无旧桶权限,新库不提供旧素材;DNS/TLS、回调和消费者入口均匹配media.oceanway.tech,无旧文件复制请求 |
12. 性能验证与完成定义
同设备、网络、文件、模型参数对照,区分冷/热缓存。先做本地与隔离测试,真实供应只在明确额度内验证;历史异构渠道耗时不做速度排名。
| 指标 | 边界 | 目标性质 |
|---|---|---|
| 添加反馈 | 选择到节点出现,另记预览解码完成 | 不等待网络/IndexedDB,实际测量p50/p95后定预算 |
| 本机保存 | 接收Blob至IndexedDB事务完成 | 与可编辑分开,不提前改状态制造提速 |
| 云端同步 | 入队至原件、素材库、画布各自确认 | 分别记录队列等待、上行与登记,不能只报上传完成 |
| 生成准备 | 点击到本次依赖全部就绪并获准派发 | 后台上传可与编辑时间重叠;点击时未完成仍需等待,原始带宽不会凭空增加 |
| 重开画布 | 打开至节点可见、可见图加载、本机恢复、云端核对完成 | 分别测同浏览器/跨设备/冷缓存/冲突,不只测首页占位 |
| 读取与资源 | 授权、TTFB、完整下载、缓存命中、CPU/RSS、DB字节及Put/Copy | 原件不为提速缩小;无重复业务原件或Base64快照 |
覆盖小图、大图、多图、透明PNG、EXIF JPEG及高像素样本。浏览器测试报告样本量与p50/p95,付费小样本只报告逐次结果。节点先显示改善操作等待,后台上传减少后续等待,缩略图改善加载;均须实测,不承诺加速倍数。
完成须具备逐仓版本、测试及用户流程证据、实际协议、未闭合项与有效数据保护说明。文档更新、代码合并、真实供应验证和生产切换分别记录。
13. 异步图片和视频的本批实施边界
依据ADR-0026,Media拥有结果归档,Platform拥有原任务与稳定输出引用,Studio拥有业务素材绑定,Runtime仅编排和送达。本节优先于本文早期将执行中保留、文件后端或生命周期交给Runtime的安排;文件SDK可被产品复用,Runtime服务不持有Files凭据。Drama、旧客户服务和桶、同步图片保持原状。
13.1 完成与恢复
Media将新异步任务的归档策略在派发前冻结;视频任务和必需归档意图共同持久化,并由后台幂等补齐已受理但缺失的保存意图。图片持久保存供应商已返回结果后仅重试归档。结果文件通过大小、MIME、摘要和对象回执校验后才可交付;未知存储结果核验同一对象,禁止重复模型派发、重复计费或另存副本。
13.2 稳定引用与下载续签
完成任务持久保存文件ID、版本、摘要、大小及MIME,不持久保存签名URL或访问grant。Platform API返回图片data[].url、视频content_url及稳定输出元数据;地址是短期签名HTTPS,可无Platform Bearer直接GET。重新查询同一任务只续签同一文件。首次交付和下载授权均须检查当前客户归属及已完成的交付资格;未完成归档、结算或已丢弃结果不能暴露下载地址。
13.3 Studio绑定与Runtime退出
Studio根据Platform原任务的稳定输出回执建立产品自身绑定,Files只登记技术保留,不复制对象。绑定意图先持久化,远端未知结果通过相同命令恢复;普通读取直接按产品已存绑定向Files续签。Runtime接收不含claim、grant、桶位置或签名URL的产品保存回执,Artifact仅记录元数据并幂等送达;新异步输出没有Runtime原件采用、文件版本和保留链。缺少新合同接线时明确失败,禁止静默退回下载再上传。
13.4 必须分别验证
真实异步图片与视频各验证一次生成归档、无Bearer直接下载、续签前后ID和SHA一致、已有素材复用不增加正式原件。覆盖视频归档意图登记中断、存储回执丢失、重启恢复和业务绑定重试。停止Runtime后,API生成归档和已有Studio文件读取仍正常。受控夹具不替代真实供应与云桶证据;独立Media部署验证通过也不等于已切换共享Platform连接。
本批代码、独立部署和真实联调的时点证据见PROC-02-021。该记录不代表共享Platform或Studio已切流,也不替代完整画布浏览器验收。