DEV-X-01-005 生态图片全链路简化重构提案
上传、生成、原件存储、预览下载与复用的跨仓梳理及统一文件方案
阅读顺序:完整审计报告 → 本方案 → 实施规格与验收。真实供应商原始结论保留在渠道测试记录。
1. 结论与提案边界
用户已确认的素材存储与画布逻辑:图片和视频的参考输入统一URL;导入立即本地预览,随后自动后台上传进入产品素材库;IndexedDB保存待同步内容;再次打开按本机草稿与云端版本恢复。 本文将这些交互规则纳入目标方案,不再作为可选方向。用户另已确认下述桶分工与原件管理简化。整体仍为Proposed;原件生命周期与Runtime边界已由ADR-0026明确,其他未完成工作不能据此声称实现或上线。
生态图片能力收敛为一个逻辑文件服务、一份不可变原件、一个对外文件标识、产品拥有业务引用。上传和生成产出同一种文件;预览、下载和再次生成消费同一种文件。画布导入不等待上传或IndexedDB;在线后台自动入库,生成仅提高本次依赖优先级并等待其就绪。已有素材直接复用,新素材上传后也用URL。Platform持有生成授权、计费及Operation,Runtime持有任务编排,产品保有素材库和画布权限;文件读取不再要求每次经过完整生成账务和交付链。
单原件目标本身合理。主要复杂度来自文件身份没有统一贯穿输入输出、产品同时运行多种存储路径、每层重复管理文件保留,以及把结果落地推迟到消费时。
本文为用户要求的跨生态重构方案,不代表实现或上线已完成。原件生命周期与Runtime编排职责已按ADR-0026明确,本批只实施Media、Platform和Studio异步图片及视频,旧业务和Drama不动。本批职责调整以新ADR-0026为准,并由实施规格第13节限定合同与验收;其他职责变化仍须相应决策,本文不改写既有Accepted决策。沿用ADR-0024取消开发链旧协议兼容、旧测试数据迁移、备份和联合恢复门禁的范围。已有有效引用、原账和原任务仍须保护;现用new-api客户环境不随重构变更。
本文的生态梳理依据本地代码、现行规格和既有接入记录;供应商Base64输入能力另见真实渠道验证。该验证不等于生态全链路上传、对象存储和部署验收。本地Studio代码与共享原件接入文档不一致;早期审计未取得匹配File Owner的生产方源码,后续已补运行制品和对应分支核对,见PROC-02-017。第2~3节保留早期梳理的范围与缺口,实际部署补充以该记录为准,不能把任一主工作区、规范目标或历史验收记录直接当作全部线上入口的运行状态。
2. 现有生态:实际有多条链
本节保留2026-10-22审计时点的事实和既有规定;新异步链按ADR-0026及第4节职责执行。实际实施与部署范围另见PROC-02-021,不能将本表的历史Runtime保留链当作新目标。
| 参与方 | 上传与输入 | 生成与存储 | 读取、复用和释放 | 判断边界 |
|---|---|---|---|---|
| Studio当前本地代码 | 浏览器Blob经multipart进入产品;另一入口把Blob转data URL再发JSON;登记storageKey | Platform结果按字节读取,再由产品写本地或外部对象存储;Runtime字节写入入口也存在 | 产品媒体路由鉴权后代理/处理;同产品永久文件可直接复用storageKey;变体及签名由产品维护 | 这些路径确实存在;是否已被线上新Writer替换待核 |
| Studio既有共享原件规定(历史审计) | 采用统一原件引用 | Platform manifest → Runtime prepare/adopt/deliver → 产品候选/媒体关联 | Runtime独立保留,产品领域关联退出后走释放outbox | DEV-STUDIO-07-002规定此链,不能据此认定本地代码或全量入口已接通 |
| Drama platform模式 | 产品保存上传意图 → Runtime文件客户端上传到File Owner → 产品落元数据 | Platform原操作 → File Owner原件 → Runtime Artifact/AssetVersion/Delivery → 产品候选、版本、画布 | /media/{id}鉴权 → Runtime续签/读取授权 → 307;上传文件有独立claim路径;产品反查实际引用后释放 | 本地有实际接线;项目、资产、画布权限由产品保留 |
| Drama direct-test历史方案 | 独立测试身份与库,继续使用File Owner | 历史接线为测试适配器直连UUMI/new-api;图片通过original-outputs取得原件 | 目标仍进入原件引用生命周期 | 2026-10-22工作区中前次引用的client.ts路径已不存在,需重新核对当前接线;不把历史例外扩展为生产默认路线 |
| Platform普通图片模式 | 图片参考传Base64、摘要与MIME | 上游URL/Base64 → 完整解码、尺寸/字节检查 → 持久结果 → 字节输出 | 产品再次取得字节;原请求和资金状态约束结果访问 | 该路径与原件描述模式不同 |
| Platform原件模式 | 显式output contract、产品凭据、文件桥和同源配置 | 上游归档后返回摘要型output_refs;Platform保留原任务及结果映射 | 初次manifest访问可能才创建文件映射/claim;读取再续签和发授权 | 暂停新增文件准入会阻断尚未建立映射的已完成结果 |
| Runtime | FileReferenceClient.upload接收整块Uint8Array;输入视频另建任务保留 | 管理Job、Artifact、AssetVersion、Delivery及引用采用 | 读取续签;释放需逐Delivery的产品持久解绑证明 | 既有引用实现有价值,但不应成为每次普通上传/下载的必经业务链 |
| 现行new-api File Owner | 现行契约定义uploads、owned claims、read authorizations等 | 公共模块复用既有TOS,管理正式原件、摘要、文件身份和保留 | 服务端身份及命名空间授权,各消费者独立保留 | 依据现行合同、消费者调用和历史记录;本次缺匹配该版本的生产方源码核对 |
| 独立Media Gateway | 自有参考图Stage会下载来源并写临时存储 | 自有结果spool、transfer/publish与对象登记;配置含临时、主结果、replica三桶 | 自有素材和供应结果读取机制 | 目标供应网关,不是当前共享原件链中的File Owner;不能把两者当成已统一 |
| Commerce原型 | multipart上传本地文件,25 MiB上限 | 图片适配器读取本地参考、调整尺寸和格式、调用模型;输出保存PNG | FileResponse下载,素材ID关联本地路径 | 是原型接入现状,不据此授权恢复正式产品建设或迁移客户 |
| Site | 发布准备脚本处理站点素材,无客户运行时上传 | 独立公开TOS桶、不可变版本目录、响应式WebP/视频 | 静态清单与公开读取 | 属于公开发布资产,不应强行加入用户私有原件的每次鉴权链 |
| Infrastructure | 配置、凭据隔离、入口、对象存储和制品 | 运行和部署归属 | 观测和开关管理 | 不持有产品内容权限,也不成为第二文件数据库Writer |
2.1 用户上传
Studio存在“multipart → 产品 → 本地/S3”和“data URL JSON → 产品 → 本地/S3”两个入口。新共享链的Drama则是“产品待上传记录 → SDK带摘要上传 → File Owner → 产品保存文件与claim”。上传过程、返回身份和读取入口不统一,调用方必须知道自己得到的是storageKey、产品fileId、File Owner file_ref还是Runtime Artifact。
2.2 图片生成与落地
普通链路是“产品/Runtime → Platform → 现用new-api → Provider → URL/Base64 → Platform保存字节 → 产品再次保存”。引用链路是“Provider结果 → File Owner归档 → Platform摘要结果 → 原件绑定 → Runtime采用和送达 → 产品候选”。两条链的成功条件、大小限制和恢复动作不同。
独立MG还有自己的暂存与发布路径,将来切换供应时若继续让产品再落一次文件,会重新形成多份业务原件。供应切换与文件统一应分别验收,但采用相同的目标文件合同。
2.3 预览与原件下载
Studio产品路由区分原件下载与限宽WebP预览;签名上游参考地址另有限制。Drama已引用结果在产品授权后通过Runtime续签,再向File Owner申请读授权。上传文件则直接续签自己的upload claim。首次结果绑定可能还依赖Platform manifest。
原件、预览、供应商参考输入本来是三种用途,现在混入了存储实现及产物交付身份。应统一文件语义,同时保留各用途的权限和转换差异。
2.4 再次生成与跨域复用
Studio已有“站内永久媒体只复用storageKey”的规则,这一方向应保留。但部分平台前端入口直接拒绝参考媒体,不能因为底层Platform支持就视为所有产品入口支持。
Drama图片参考会读回文件、校核摘要并转Base64。现行契约明确这些字节进入产品及Runtime/Platform的私有请求快照。这不等于多写了一份TOS原件,但会扩大数据库、序列化、请求体和恢复成本。视频输入已有file claim路径,可借鉴其稳定引用思想,不照搬全部图片专用协议。
同一账号不代表有权读取其它产品或团队里的全部文件。跨产品复用目前不能视作已经自动开放;目标方案须提供明确的来源授权与目标绑定。
3. 需要解决的问题
| 问题 | 现有证据与影响 | 重构处理 |
|---|---|---|
| 上传允许不等于模型可用 | Studio上传20 MiB;Platform图片参考单张4 MiB、合计8 MiB、最多4张;普通输出单张及整批16 MiB;Runtime上传客户端200 MiB;Commerce25 MiB | 存储限制与模型输入限制分开,统一发布有效能力,选择模型时预检 |
| 原件与加工结果混淆 | Studio normalizeGeneratedImageBytes在目标尺寸不同的分支会rotate/cover resize;Commerce参考缩至1536且转RGB,结果重编码PNG | 原始字节永久保持;裁切、旋转、转码生成有来源关系的派生版本 |
| 文件身份泄露存储实现 | storageKey、路径、file_ref/revision、Artifact、AssetVersion、claim与Delivery混用 | 前端统一file_id;业务asset_id/version保留其业务含义;其余身份留内部 |
| 首次下载承担绑定工作 | Platform初次manifest可能调用original-outputs,新准入关闭时拒绝 | 完成结果时建立文件/业务绑定,下载只做读取授权 |
| 文件读依赖生成链 | 原操作、原账、映射、采用、续签成为多层前置 | 首次交付检查生成授权/费用策略,持久形成文件访问依据;后续读取只走当前文件/业务授权 |
| 多层重复保留与释放 | Platform anchor、Runtime claim、产品领域解绑证明形成链式协调 | File Owner集中管理技术保留;产品管理业务绑定;Runtime不持有文件保留;执行中输入及暂未交付结果由Platform/Media交给Files保护 |
| 原件服务绑定供应地址 | Platform要求生成网关BaseURL等于文件桥BaseURL,历史映射也比对当前地址 | 以稳定服务身份和namespace路由;地址是配置,不参与文件身份 |
| 供应能力与产品传输规则混淆 | 真实供应存在Base64能力,但字段兼容及图参效果不一致 | 产品统一URL;后台入库消除添加等待;单URL与多URL分别核验,不新增渠道传输开关 |
| 缺统一故障状态 | 多处通用unavailable,用户可能长期等待却无法定位保存失败 | 内部区分生成、保存、交付及账务事实;提供可恢复动作和阶段原因 |
| 文档、源码、运行制品不一致 | Studio规范有引用接线,但本地代码主要仍为字节路径;本地new-api分支缺目标文件模块 | 实施起点先固定实际Writer与版本,逐入口出清单,不据单仓测试宣布全生态切换 |
不要仅把上限提高到某个更大常数;那不能解决Base64复制、整块缓冲、重复存储和下载依赖问题。也不应取消摘要、权限、幂等及未知请求保护。
4. 统一目标与职责
Files首先是逻辑模块,复用现有File Owner代码与TOS技术,部署在下节确认的独立媒体实例中,使用其独立数据库和全新桶;不额外拆出专用文件微服务或另建代码仓库。先把接口与生成供应域名解耦;后续部署位置可以独立调整。MG不是新的文件权威,切入时通过同一文件接口登记结果。只统一私有业务文件合同,不合并各租户权限,Site既有公开发布保持独立;旧MG三桶不纳入新链,不直接接管或清理历史对象。
| 归属 | 唯一职责 | 应退出的职责 |
|---|---|---|
| Files / File Owner | 文件身份、不可变字节、验证元数据、物理位置、派生、受限读写、技术保留、清理资格 | 产品采纳、项目权限、模型售价与钱包 |
| Platform | 身份委托、模型能力、计费、Operation、输入/输出file_id快照、首次交付资格 | 保存图片Base64为通用结果、每次下载重新解码/追原账、按供应地址定义文件身份 |
| 供应适配器 | 模型协议、输入转换、结果捕获、按原执行登记文件、原任务恢复 | 产品资产和业务长期文件权限 |
| Runtime | Job/工作流、输入与结果file_id快照、任务依赖及幂等送达 | 普通上传/下载必经的通用资产版本和长期保留链 |
| 产品 | 领域权限、素材与版本、候选/采纳、文件绑定、业务删除 | TOS凭据、本地正式原件写入、重复转存、供应协议编码 |
| Infrastructure | 存储和访问配置、服务发现、流量/容量/运行观测 | 客户领域授权和第二套文件合同 |
Runtime可以继续有Artifact用于追踪任务输出及产品已保存回执;不承担原件AssetVersion、长期claim、续签和释放。业务版本及绑定在产品保留,文件不可变身份和技术保护在Files保留。职责依据ADR-0026,新异步链不再走Runtime文件生命周期。
4.1 桶分工与原件管理简化(已确认)
用户最新确认:复制new-api-new-oceanway服务,数据库直接复制到独立新库,新服务地址为https://media.oceanway.tech,当前OceanWay全部使用新桶,开发业务从新文件开始。 不迁移旧文件、不复制旧桶对象、不为旧素材链接增加兼容或读取回退。此方向取代先前“同一生产实例按令牌区分新旧业务桶”和“优先复用assets桶”的设计。本次仍是方案修订,未复制数据库、创建桶、配置DNS或部署。
| 范围 | 原有顾客业务 | 当前OceanWay业务 |
|---|---|---|
| 服务 | 保持原new-api实例、地址和发布目标 | 独立实例,media.oceanway.tech;复用源码,发布与worker独立 |
| 数据库 | 源库保持原样 | 从源数据库复制到独立新库;初始化仅作用于新库,不承接复制过来的旧业务执行 |
| 对象存储 | 原7桶按原归属保留 | 全部使用新建桶;不复用assets/media/MG旧桶,不搬旧文件 |
| 凭据与队列 | 原凭据、会话、队列继续原业务 | 独立DB、服务、File Bridge、存储凭据和空队列;不复制旧会话或活跃租约 |
| 文件保留 | 原media链既有7天规则保持 | 新上传、生成及临时处理均不继承7天自动删除;素材库与画布共享同一原件 |
新桶按业务文件、辅助临时处理、公开发布三种用途组织:首期必须有新的私有业务桶,原件和可重建预览分前缀;确有临时处理或公开发布需求时再创建对应新桶,不为凑齐旧三桶结构建立必需副本。桶名在实施时登记,不能把尚未创建的名字写成实际资源;新服务凭据不授予旧桶访问权限。
源库复制不等于旧任务继续运行。复制完成后在新库初始化业务数据:旧任务、回调、重试、清理状态、素材/文件引用及旧登录/API授权不得直接进入新业务。保留所需模型、渠道、路由和价格配置;确切清理表与外键顺序在实施前形成清单,只对新库执行。旧客户资金/账本不作为OceanWay新余额,身份及结算边界仍由平台掌握。整个源库及原业务文件不删除。
已核有独立开发producer和数据库,可参考其原件分支实现;它目前共享旧assets桶,不能直接称为满足此次新桶要求。目标新实例应使用自己的部署目录、端口/网络、数据库和新桶配置,不复用旧生产发布脚本的固定容器目标,不覆盖现有开发或客户实例。
正常链为平台→media.oceanway.tech→供应商;生成结果直接写新正式桶,平台、Runtime、画布保存同一文件引用。新服务不为识别原顾客再维护两套桶路由;服务端只接受新业务获准身份,任何入口缺少namespace都不能落回旧桶。复制的渠道配置须核对实际供应入口及凭据配额,不能让新服务又通过旧客户实例转发。共用供应商账户可能仍争用限额,独立实例本身不保证供应资源隔离。
实际云桶和凭据观察仍见PROC-02-016与PROC-02-017,属于切换前事实,不作为新实例沿用旧桶或旧身份的要求。最新实施范围以DEV-X-01-006的7.2~7.4为准。
正式业务桶可用originals/与previews/组织新对象,前缀不是权限边界,也不要求旧对象为统一命名重命名。素材来源、产品、业务版本由元数据表达;进入素材库、画布或再次生成只增加关联,不换桶、搬文件或重复写原件。新写入Owner的授权和环境作用域须独立核对,不能因复用代码就默认继承旧IAM权限。
原件管理收敛为四条规则:上传/生成直接写最终不可变对象键并完成校验;预览可重建且不阻断原件读取;普通读取只核当前业务权限及交付资格并签发地址;业务解绑持久提交后异步释放,物删由Files统一判定。每次操作不重走原件采用、生成账务恢复及多层长期保留登记。单原件表示一份正式业务内容,允许有明确来源的预览和受控缓存,不禁止云存储自身冗余。
开发阶段不需要7天自动删除规则:上传素材、生成结果和辅助临时处理均不新增、不继承该规则,部署模板与应用清理默认值也不得沿用。现有7天规则来自new-api-new-oceanway旧业务,不作为新链的存储要求;本次保留云端原配置,并在方案中要求新链与其匹配范围隔离。后续是否启用临时数据定时清理,按实际需要另行确定,不作为当前开发前置条件。
原件与辅助临时数据分开管理。不能靠数据库hold抵消对象存储生命周期删除,也不能依据规则名称、桶名或延迟用量判定安全。正式原件不按年龄自动过期;明确删除和受控清理仍须检查引用与任务依赖,仅处理已确认可丢弃对象。
CORS按新实例真实浏览器入口与操作配置,不复制旧桶的来源清单;旧桶规则保持原状。不默认放开所有Origin、对象公开读或浏览器删除。私有图片展示、fetch/画布导出、服务端取图分别验收。未配置CORS不等于服务器不能读取URL,也不等于应将私有桶改公开。
5. 最小对象与对外接口草案
5.1 三个主要对象
- File:对外
file_id唯一标识一份不可变内容,附可信MIME、字节数、尺寸、SHA256、就绪状态与来源。编辑产生新file_id;同字节复用可在租户授权范围内部去重,不能用公开摘要猜测别人的文件。 - Binding:某产品、主体/团队、业务对象对文件的有效关联;既说明保留理由,也承载授权上下文。保留记录本身不自动授予下载权限。由产品授权,Files保存技术登记。
- Variant:原件加明确转换规格产生的派生结果,记录parent file、转换版本与实际尺寸/格式;默认预览用派生,默认下载用原件。裁切/转码不覆盖原件。
内部仍可沿用file_ref/revision,不为了改名再建一套身份。对外file_id须固定到原不可变版本。产品asset_id、shot_version等是业务实体,不能与file_id强行合并。
5.2 前端和普通接入方只需五类能力
以下是提案合同,不是已经存在的HTTP路由;上传、云同步、重开恢复状态机及接口形状详见DEV-X-01-006。产品BFF可保持自己的路径,但必须调用同一版本化SDK/合同,不复制DTO与校验规则。Files提供方拥有合同;TS客户端先可作为Runtime仓内无运行时依赖的独立子入口发布,Go消费提供方版本化schema,不恢复旧Contracts中心仓。
| 能力 | 概念调用 | 返回/行为 |
|---|---|---|
| 上传 | files.upload(file, context, idempotencyKey) | 上传标识、状态,完成后file_id和元数据 |
| 查询/恢复 | files.get(file_id) / files.getUpload(upload_id) | 当前状态及同一上传结果,ACK丢失时不盲重传 |
| 预览/下载 | files.content(file_id, variant, disposition) | 产品鉴权后短期地址或受控响应;SDK处理续签 |
| 绑定/移除 | files.bind(file_id, target) / files.unbind(binding_id) | 由服务端核权并幂等登记;前端不操作claim |
| 生成 | generations.submit(metadata, fileRefs) | 本次依赖先上传就绪,提交file_id及版本;返回任务与输出file_id,模型侧统一URL |
外部API可保留常见multipart、URL、Base64输入作为边界适配。新产品内部素材和生成输入统一file_id;新图先通过同一上传链入库,再取得受权URL。外部URL只能经过有域名/IP/重定向/体积保护的导入入口;对象地址、文件标识和哈希均不作为访问凭证。现用new-api公开API的适配不因本提案改变。
6. 五条目标流程
6.0 画布即时显示、后台入库与再次打开
导入先建立稳定节点和local_asset_id,用File/Blob创建object URL本地显示;尺寸解码、哈希、IndexedDB落盘和上传都在后台进行。在线时自动将导入原件保存到产品素材库,再保存画布引用;断网时本机保存,恢复联网后继续。默认自动入库,避免用户只排版未发起生成就一直没有云端副本;添加节点不需要等待这条链完成。
现有卡点:Studio use-canvas-file-actions.tsx先await uploadCanvasImage,再setNodes,上传后还从服务器URL读取尺寸;Drama studio-canvas.tsx的insertFiles逐张await uploadFile后才commit。Studio /create的File/object URL预览可以复用思路,但其内存草稿不等于刷新恢复,画布仍需补持久化和版本保护。
| 用户动作 | 本地行为 | 云端行为 |
|---|---|---|
| 拖入、粘贴、选择文件 | 节点立即出现,Blob预览;异步保存IndexedDB | 自动进入有界后台上传队列,校验后登记素材库 |
| 移动、缩放、连接、复制节点 | 复用内容版本,只改布局/引用 | 保存元数据,不重复上传 |
| 裁切、重绘、蒙版等像素编辑 | 处理过程留本机,确认后产生新内容版本 | 确认版本后台入队;不把每次中间操作都入库 |
| 发起图片/视频生成 | 冻结本次节点及依赖版本 | 所需文件优先上传;只等本次依赖就绪,统一URL派发 |
| 自动同步/明确保存 | 保留完整本机草稿,编辑不中断 | 完成原件、素材登记和对应画布引用后才显示云端已保存 |
| 分享/交付 | 固定所分享快照 | 快照依赖及权限就绪后开放,不能带本机句柄 |
| 本地导出 | 可直接用本机Blob | 不要求先上传再下载 |
20张新图只选2张生成时,20张都可后台入库,但生成只等待2张;其余18张的上传失败不阻塞本次任务。队列有界并发、支持优先级、离线暂停与恢复,后台任务不依赖页面关闭后继续运行。生成所需文件未准备完成不派发收费请求。
同一原件进入素材库和画布共享一个file_id,不重复写对象。上传完成只补充对应local_asset_id/revision映射,不覆盖新编辑;迟到回执不复活已删节点。删除画布节点仅解除本处引用,已入素材库的文件按素材库权限和保留继续存在。
IndexedDB应保存待上传Blob、待同步画布快照、上传身份/回执与file_id映射;可有界缓存缩略图及近期内容。不镜像整个素材库,不长期保存Base64或blob URL字符串。恢复时从实际Blob重新创建URL,云端快照仅存稳定文件引用与内容版本,短期签名地址按当前权限重新取得。
本机与云端保存状态分开:IndexedDB事务提交才算本机已保存,文件上传成功也不等于画布已同步。按账号/产品/画布隔离,配额失败或本机数据被清理时如实显示缺失并允许重试/导出。只有原件就绪、素材库和云端画布引用确认且无待同步/Undo依赖时,本地原件才变为可淘汰缓存;未同步草稿不按固定TTL丢弃。
| 下次打开时的状态 | 恢复方式 |
|---|---|
| 原件和画布均已同步 | 拉取最新云端版本;已授权本机缓存可先显示 |
| 本机有尚未上传的完整草稿 | 同浏览器从IndexedDB恢复节点/Blob,查询原上传后续传;另一设备只有最后云端版本 |
| 原件已上传,素材登记或画布保存未完成 | 找回同一file_id,补登记和元数据同步,不再上传原件 |
| 本机未同步且云端也被其它设备修改 | 比较基线版本,保留本机恢复副本并提示冲突;不静默覆盖任一端 |
| 本机缓存丢失且无云端原件 | 保留可用节点信息并提示重新选择文件,不承诺恢复不存在的字节 |
打开后重新建立账号授权,本机快速展示与云端最新版本拉取并行。无待同步修改时采用云端;有本机修改时按base revision/CAS提交,保存回执未知先查询原命令。旧加载响应不能覆盖打开后新编辑;首期不要求完整实时协同。可见区域缩略图优先,视口外延迟读取,编辑、放大和下载再取原件。
这项前端顺序调整可以先复用现有上传接口落地,后续替换Files实现。需覆盖导入、自动保存、生成、分享、导出、复制/Undo和重开恢复,不能只修改上传函数。
供应输入统一URL,不按渠道适配。浏览器提交file_id及版本,服务端核权、建立执行保护并在派发前签发可用HTTPS地址;原件和派生版本明确分开。URL过期只续签或恢复原任务,不重新上传或另起付费请求。已有单URL与混合测试保留历史事实;多URL同次输入尚未测试,需单独验收。
6.1 上传:先做简单流式入口
达到6.0中的云端提交条件后:产品鉴权并赋予上传上下文 → SDK以multipart/二进制流传到Files → Files在最终不可变对象键写入、验证并返回file_id → 产品绑定素材/对话/画布。普通素材库的明确“上传保存”可以直接启动此链,但不阻塞本地预览出现。
正式文件不要求先Put临时桶再Copy/Put正式桶;文件未就绪时即便对象已写入也不得签发访问。保留持久意图、确定对象键和未知ACK恢复,失败不直接遗失唯一原字节。
第一阶段使用一个流式上传接口,不强制每个小图片都走创建会话、分片、完成三段调用。禁止浏览器先转data URL;避免BFF和SDK层层arrayBuffer。文件未校验完成只显示上传/处理状态,不可用于生成或分享。
实现先持久化upload_id、幂等键、作用域及提交意图;同键不同内容冲突,同键同内容返回同一结果。网络ACK丢失先查询原上传;若服务未完整收取字节,则用同一上传身份重传/继续,不宣称能从缺失字节恢复。Files保留完成判定所需的有界暂存或确定对象键,直到登记完成。
大文件直传TOS和分片是第二种内部传输策略,仅在容量需求明确后实现,SDK屏蔽差异。完成时由Files校核可信对象信息,禁止只信浏览器声明的长度和摘要。没有必要为简化图片链先引入完整大文件上传系统。
6.2 生成:输入引用,输出登记
产品冻结所选素材版本 → 优先完成缺失输入上传与登记 → 验证file_id及对象权限 → 建立执行保护 → Platform冻结模型、参数与输入引用 → 供应协议取得原件或明确派生的受限URL → 单次派发 → 捕获原结果 → Files登记输出 → 产品幂等登记业务绑定 → Runtime记录结果引用并送达。
图片和视频均使用URL,不再为本地新图建立Base64或独立临时执行输入分支。持久任务保存文件身份、内容版本、参数及转换规格;签名URL只在派发前按实际取图窗口准备。上传中暂存仍由同一Files Owner管理,不因此新建长期资产类别或第二服务。异步恢复依靠已登记文件与执行保护,不能只依靠浏览器内存。
输出以供应执行身份加output_index做幂等登记,不依赖产品首个下载请求。已经归档到同一Owner可验证后原位登记;未归档才写入一次正式原件。保存ACK未知查询原登记和确定对象,恢复保存不重新生成。供应商URL失效且无可恢复原字节时如实标记原结果不可恢复,不能自动再收费生成。
内部拆开生成状态、文件就绪、交付绑定与资金状态。已有资金规则决定首次结果何时允许交付;将该决定形成持久交付资格。后续授权下载不要求再次读上游账单或重新完成结算。文件保留不自动开放未获准交付的结果。
6.3 预览和下载:一个入口,两种用途
前端请求file_id → 产品验证当前业务访问权限 → Files签发受限读取 → 浏览器读取TOS。目标普通读取不经过Runtime和Platform原操作恢复,也不写新保留。
预览明确指定已发布的缩略图规格;原件下载保持字节、透明通道、格式及文件名语义。响应支持GET/HEAD、正确Content-Type/Disposition,按实际需求验证Range、跨域与缓存。派生失败不能损坏或阻断原件下载。
签名地址仅作短期传输结果,不进业务库。SDK按有效期或明确过期错误续签;403权限撤销不无限重试。长期业务绑定不需要每次续签其保留身份。服务身份或文件域名变化不改变file_id。
短期地址签发后通常不能凭站内解绑立即撤回,不能把站内404当作旧URL即时失效。需要即时撤销的场景使用受控代理或具备该能力的分发层,并单独定义成本。普通预览与原件默认沿已确认的短期授权策略。
6.4 复用:增加业务关联,不搬文件
结果保存素材、素材放入画布、角色图用于分镜、图片作为下一次生成输入,都直接传file_id。产品根据业务需要增加Binding或引用已有Binding;文件保持同一身份,不先下载再上传。
跨产品复用由用户明确选择来源,服务端核验来源权限、目标写权限及可共享范围,登记目标独立Binding。已有来源可撤销与目标已获得的独立保留语义须公开明确;不能用同一subject_id或哈希自动互通全部私有内容。保留单原件不代表默认开放跨产品素材库。
裁切、抠图、重绘、超分等真实内容修改生成新文件并记录来源;为供应商适配而产生的输入派生同样固定转换版本。不可静默裁切原件以满足模型尺寸,也不可让用户误以为预览图就是下载原件。
6.5 删除:产品解绑,Files判断保留
删除对话/画布节点/候选先持久提交本处解绑与outbox,界面不等待远端物理清理;释放未确认仍显示待处理,不能假报已经物删。删除只移除本业务关联。其它素材库、项目、产品及执行中的引用继续有效。产品不直接unlink或删除TOS对象。
新增关联必须先取得幂等保护,再提交产品绑定和outbox;远端成功本地失败可重放同一命令。解绑在产品事务内写持久事实和outbox,Files按同一binding_id完成释放。产品绑定和删除使用同一版本/锁序,释放后的旧命令不能复活引用,未知送达也不能被当作没有引用。
这些规则收敛为SDK和Files中的通用绑定协议;调用方只使用bind/unbind。独立产品保留直接由其产品绑定负责,Runtime无需为每个已交付结果长期替产品持有并遍历全部Delivery索取解绑证明。执行中输入和未交付结果由Platform/Media按原任务交给Files保护;Runtime只记录依赖和完成状态,不能出现无人保留的窗口。
跨库不承诺单事务:使用保护先于引用、事务outbox及幂等重放,失败时宁可保留孤立保护并暴露诊断,也不能凭TTL清除可能已经生效的业务引用。物理清理资格由Files统一计算;首阶段不启用自动物理GC。以后若实施GC,须在实际删除前再次核对有效/待确认绑定与任务保护,使用代际围栏或同等并发控制。
7. 限制和错误的统一
- 存储限制来自Files:可接收类型、单文件大小、解码像素/内存预算、上传并发与租户容量。网关、代理、BFF有效上限也纳入同一能力检查,避免SDK声称可上传而边缘先拒绝。
- 模型限制来自Platform发布的供应能力:参考数量、单图/合计大小、尺寸、格式、角色。文件可保存不代表每个模型都可使用;前端选模型后显示实际不兼容原因及可执行转换选项。
- 完整字节校验集中在可信接收入库边界,内容转换后再次校验派生;普通跨服务元数据传递不重复全图解码。提供方需要的严格协议与费用规格核对继续保留。
- 输出大小、批次总量和解码内存分别配置,有实际依据后确定数值;不能继续把所有模型的全部输出共用隐式16 MiB总额,也不能改成无限制。
- 错误至少区分上传未完成、格式不支持、模型输入不兼容、权限拒绝、保存失败、原结果缺失与临时读取失败。内部保存阶段与恢复动作可诊断,前端不暴露claim、namespace、原账核对等实现术语。
- 不增加新的供应模型验证门禁取代管理员已确认的启用权。文件和权限正确性验收与模型供应运营启用分别处理。
8. 分仓改造清单与顺序
| 顺序/拟议工作包 | 范围 | 具体改造 | 退出标准 |
|---|---|---|---|
| P0 / WP-FILES-SIMPLE-01 | Docs、各运行Owner | 固定实际Writer/制品/入口矩阵;取得匹配File Owner源码;整理新ADR及PRD/FS;定义file_id和绑定语义 | 不再混用本地HEAD、规范目标和线上状态;唯一合同及职责确定 |
| P0c / 待登记 | new-api、Platform、Infrastructure | 按DEV-X-01-006第7.2~7.4节准备独立实例、数据库副本、新桶及初始化;补全存储入口 | AC31~AC40通过;旧生产不变,新业务无旧文件依赖 |
| P0a / WP-FILES-SIMPLE-09 | Studio、Drama画布 | 本地先插入、Blob预览、IndexedDB草稿、自动后台入库、重开恢复与版本冲突处理;复用现有上传适配器起步 | 断网可添加和编辑;重开可恢复已存草稿;生成只等待所需文件;本机/云端状态准确 |
| P0b / WP-FILES-SIMPLE-10 | MG、Platform协议Owner | 图片/视频统一URL;标准协议、元数据预算、单URL/多URL真实图参核验 | 不新增渠道传输配置;不兼容供给明确报错,无Base64降级重发 |
| P1 / WP-FILES-SIMPLE-02 | File Owner、Infrastructure | 按桶清单实现最终位置直接写入、稳定文件投影、上传查询、读授权、绑定/解绑与派生;服务身份与地址分离 | 上传ACK丢失恢复同一文件;上传/生成停新时已有文件仍可读 |
| P2 / WP-FILES-SIMPLE-03 | new-api供应适配、Platform | 生成输入统一文件引用;供应边界核权并准备URL;生成完成即原件登记;取消产品显式原件协议;首次交付和后续读取分离 | 单次派发;保存失败只恢复保存;新下载不依赖首次adopt |
| P3 / WP-FILES-SIMPLE-04 | Runtime | 产物只记录引用;执行保护交给Platform/Media及Files;送达幂等;文件SDK与编排进程解耦 | 删除Runtime会话不破坏产品已独立绑定文件;无每次读取的Runtime依赖 |
| P4 / WP-FILES-SIMPLE-05 | Studio | 统一附件、对话、素材、Canvas、作品发布与下载入口;替换字节结果转存、data URL上传、路径身份和隐式裁切 | 同一图片跨这些入口保持file_id/原始SHA;有独立公开发布权限 |
| P4 / WP-FILES-SIMPLE-06 | Drama | 上传、候选、角色/形象/分镜、画布、任务输入、读取与解绑用同一合同;direct-test仅替换生成适配器 | 两种执行模式文件语义相同;不把direct-test作为生产计费绕过 |
| P5 / WP-FILES-SIMPLE-07 | MG、Commerce、Site | MG提供File Owner登记适配,退出临时→主→副本串行写入和replica强制配置,保留供应恢复内核;Commerce固定未来AssetService/ExportService对接;Site仅接明确发布的衍生素材 | 不恢复冻结产品开发、不切供应、不动历史对象;新链无副本写入等待和重复原件 |
| P6 / WP-FILES-SIMPLE-08 | 全部活跃消费者、Infrastructure | 统一版本开发验收,关闭已替换新链入口,清理不可达重复代码;开关拆分新上传/新生成/已有读取/清理 | 逐入口与故障矩阵通过;没有新旧Writer共同改同一对象 |
表内WP-FILES-SIMPLE编号为本提案逻辑拆分,尚未注册为正式WP。P0a本地交互与P0b统一协议可以独立推进,不把全生态后端重构作为消除添加等待的前置。
按功能依赖推进,不要求先把Files拆成独立进程。先完成“上传 → 单次生成 → 原件下载 → 再次引用”的Studio/Drama纵向闭环,再扩展发布、批量导出和其它入口。P5中的MG合同接入可先做隔离适配验证,真实供应切换另行授权验收;Commerce保持原型范围,Site既有公开分发继续工作。
“迁移”在本期指代码与配置接线替换,不恢复旧开发数据迁移、双读双写或fallback义务。当前已创建的有效任务和引用仍由原Writer完成,不强行移交在途所有权;对需要退出的开发数据另按明确清单处理,不暗中清库。新链故障停新并修复该统一版本,保持已有读取,不用旧应用读取新引用。
9. 必须验证的用户流程与故障
| 场景 | 验收结果 |
|---|---|
| 断网拖入多张本地图片 | 节点先出现,可编辑和本机保存;断网暂停上传,联网自动续传;不等前一张上传才显示后一张 |
| 画布有多张本地图,仅选择其中一张用于生成 | 仅等待所选输入及必要依赖,其余后台入库;所需输入上传失败不派发模型 |
| 同一图片分别用于图片编辑和视频首帧 | 两者均URL;已有文件复用,新图先上传;多URL输入单独核验,不把blob URL交给服务端 |
| 图片供给不兼容统一协议 | 清晰暴露协议不兼容;不建立渠道特例,不换Base64再次派发未知请求 |
| 本地草稿刷新、上传中替换、删除与Undo | Blob可从本机草稿恢复;迟到响应不覆盖新版本或复活节点;Undo依赖不被提前清理 |
| 上传后刷新、关闭再打开 | 同file_id、同摘要,可预览和下载;无Base64业务快照复制 |
| 文件已上传但画布未同步时重开 | 查询原上传并复用file_id,只补登记和画布保存 |
| 同浏览器重开与另一设备打开 | 前者恢复已持久化本机草稿;后者只能恢复云端版本,不假报完整保存 |
| 双端并发编辑及旧读取响应迟到 | CAS拒绝覆盖,保留本机副本;旧响应不覆盖新编辑 |
| 大画布冷/热缓存打开 | 可见缩略图优先,原件按需读取;过期签名续签不重新上传 |
| 上传成功但响应丢失 | 查询原upload_id找回结果;同键重试不生成第二原件 |
| 20 MiB以内但超过模型输入上限的图片 | 可以按Files能力保存;生成前提示模型具体限制,未发生收费派发 |
| 生成完成但对象保存/登记ACK丢失 | 恢复原登记;模型POST计数不增加,原资金不重复结算 |
| 结果绑定提交丢回执 | 重放同一binding,文件身份和业务目标不变 |
| 下载地址过期 | 有权限时SDK重新获取;无权限时明确拒绝,不重新生成或上传 |
| 同图用于对话、素材、Canvas、Drama业务版本 | 同file_id及原件摘要;每次引用不增加原件Put/Copy |
| 下载原件、裁切导出、缩略图 | 原件SHA和格式不变;派生与来源关系明确;透明通道按操作语义保留 |
| 删对话但素材库或其它任务仍引用 | 本处不可访问,其它有效关联仍可读,进行中输入仍受保护 |
| 最后解绑与迟到送达/新引用竞争 | 持久代际/版本判断拒绝旧命令复活;已授权新引用有保护 |
| 暂停上传/生成或替换Files入口地址 | 已有已授权读取不受新准入影响,file_id不变 |
| 跨主体/团队/产品猜file_id或伪造hash | 读取、生成引用和解绑均拒绝;明确共享流程才建立目标绑定 |
| Provider仅返回短期URL、文件服务暂不可用 | 原结果及时受控暂存,重试保存;无法恢复时如实报告,不重派未知请求 |
| Site公开发布与撤销 | 仅明确发布的派生对外公开;私有原件和服务凭据不外泄;缓存失效范围明确 |
逐阶段观测上传失败率、归档耗时、读取授权请求数、对象Put/Copy、生成POST计数、数据库图片字节量和pending绑定积压。目标是后续引用Put/Copy为0、普通读取无Runtime/账务恢复调用;具体延迟和容量阈值用实际样本测量后设定,不凭空承诺。
10. 依据入口与待核边界
代码路径相对各自仓库;本文只引用结构和行为,不包含凭据、签名URL或私密结果。
| 仓库 | 关键代码/契约入口 |
|---|---|
| Platform | service/platform_media_references.go、platform_image_adapter_openai.go、platform_media_original_outputs.go、platform_media_files.go、docs/openapi/platform-media-file-output-v1.md |
| Runtime | packages/client/src/file-references.ts、packages/server/src/file-reference-client.ts、docs/file-references.md |
| Studio | web/src/services/server-media-storage.ts、web/src/shared/media/storage.ts、service.ts、reference.ts、web/src/lib/server/reference-asset-store.ts、generated-image-normalizer.ts、web/src/services/api/platform-media-tasks.ts |
| Drama | apps/web/lib/server/production/uploaded-files.ts、reference-media.ts、file-reference-lifecycle.ts、apps/web/lib/server/platform/file-references.ts、packages/canvas/src/studio/studio-canvas.tsx(direct-test旧路径以审计待核项为准) |
| MG | internal/image/reference/store.go、internal/assets/transfer.go、internal/platform/objectstore/buckets.go |
| Commerce | server/app.py、server/providers.py、server/image_tools.py |
| Site | docs/media-delivery.md、src/content/site-media.json |
现行要求以共享原件PRD、对象存储架构、公共文件合同及Studio接入为依据。本文新方案与现行合同的差异明确标为提案,未自动替代它们。
实施前尚须补齐:以PROC-02-017已核File Owner运行源码为起点核对目标分支和全部入口;Studio各入口实际Writer及引用接线范围;边缘与TOS真实请求上限和CORS/Range能力;公开发布/跨产品分享的业务范围。它们影响落地细节,不改变先统一文件身份、收敛字节写入、将复杂度集中到Files的方向。
11. 方案取舍与实施风险
| 选择 | 原因 | 代价与处理 |
|---|---|---|
| 本地先显示、自动后台入库 | 添加不等待网络,同时减少长期仅存本机的情况 | 实际仍需上传;队列、同步状态、重开恢复及版本竞态必须完整实现 |
| 图片/视频统一URL | 上传后同一文件贯穿素材库、画布和生成,不构建渠道策略矩阵 | 本地新图首次生成仍可能等待上传;多URL及供给标准兼容须独立验收 |
| IndexedDB保留待同步草稿 | 同浏览器关闭重开可恢复,云端完成前有本机副本 | 浏览器配额和清理可能使本机数据丢失;不能承诺跨设备恢复未上传内容 |
| 复用File Owner代码,独立媒体实例使用新库与新TOS桶 | 新业务与旧客户环境隔离,不另拆文件微服务或新仓库 | 核对克隆初始化、独立凭据与全部入口;每份新原件仍只有一个Writer |
| 结果完成时登记,普通读取只授权 | 下载无需重新进入采用/生成恢复 | 要可靠处理结果保存失败和交付资格;不能提前对未获准结果开放 |
| 产品管理业务绑定,Files管理技术保留 | 减少调用方理解claim/Delivery链的负担 | 按ADR-0026明确职责;产品绑定持久提交,Runtime只接收已保存回执 |
本期不顺带实现完整大文件分片、全局跨租户去重、自动物理GC或跨产品素材自动互通。本机草稿与上传回执恢复属于编辑正确性,不等于被取消的开发备份/联合灾备义务。
12. 文档与交付边界
审计报告回答“当前哪里复杂、证据是什么”;本方案回答“统一成什么、谁负责”;实施规格回答“接口、状态、异常、工作包和验收如何落实”。三份文档共同构成本次完整交付,真实渠道记录保留其原始时点和失败,不因新统一策略改写测试结果。
功能完成必须另有逐仓代码版本、开发联调和用户流程证据;生产供应切换与发布另行记录。本次文档不宣称已经提速、不承诺未经测量的倍数,也不把未验证渠道列为“不支持Base64”。
本批异步图片与视频的制品、独立Media部署和真实云联调证据见PROC-02-021。