补记图生输入的OSS直读待讨论项

- api-server 的 image_source 模块头与 platform-tripo 的 upload_image 各留一条 TODO(oss-direct-read):交签名 URL 或对端直读 OSS 能省掉字节中转,但把私有对象与带时效凭据交给第三方,安全口径与可行性待讨论
- 技术方案文档把图生输入口径更新为当前的 source 站内引用 tagged enum,并补同一条待讨论说明
- 讨论清楚之前保持「api-server 自己读、自己传」的现口径,不改行为
This commit is contained in:
2026-09-21 20:02:18 +08:00
parent 14066eea11
commit 2691ca8aca
3 changed files with 11 additions and 1 deletions
@@ -25,11 +25,13 @@ task 尚未完成时 `output` 为空;完成后 `output` 必须是与 task type
## 三个入口的输入
- text-to-model`prompt` 必填,上限 1024 字符;`negative_prompt` 上限 255 字符。空白 prompt 在提交前拒绝。
- image-to-model`input` 是单张参考图引用,序列化为裸字符串并由服务端推断是公开 URL 还是 `file_token`;空白 `input` 在提交前拒绝
- image-to-model`source``Model3dGenerationSource`,即带 `kind` 的站内引用 tagged enum`resource { resourceId }``asset { assetId }`),不接受裸字符串、远程 URL 与 data URL。提交时只按 ID 定点校验归属与记录类型(跨 owner、未登记、类型不符统一 400),worker 执行时再从私有 OSS 读出字节、上传 provider 换回 `file_token` 后提交;provider 生成参数在 `generation`
- multiview-to-model`inputs` 是带 `kind` 的 tagged enum,二选一——`views { front, left, back, right }` 或复用已有结果的 `taskId``views``front` 必填,其余视图至少再提供一张(少于两张视图直接拒绝);左/后/右视图为空白字符串时按未提供处理,不会上传空文件。图片与视图引用都先去掉首尾空白再交给 SDK,`taskId` 走统一的 task id 校验。
三个入口的 `model` 都必填,其余生成参数可选。SDK params 未命名的 `texture_version``delight`,由 image-to-model 和 multiview-to-model 通过 extra 字段透传。
TODO:图生输入当前由 api-server 自己读站内对象的字节再上传换 `file_token`,会多走一次字节中转与一份上行带宽;「让 Tripo 侧直接读站内对象」(交签名 URL,或对端直读 OSS)的**安全口径与可行性待讨论**,讨论前维持现口径。
## 请求与类型
三个生成请求使用官方文档已确认的 enum:模型版本、纹理版本、纹理质量(含 `fast`)、几何质量、纹理对齐、输入方向、导出方向和压缩类型(`geometry`)。文档未将 `style` 列为这三个 endpoint 的请求字段,因此不再保留占位 enum。`model` 在三个请求中都是必填字段(缺失或取值非法时在反序列化阶段即拒绝);除它以外的参数可选,在 Rust 侧为 `Option`TypeScript 绑定对应 `field?: T | null`,调用方既可省略字段也可显式传 `null`。TypeScript 绑定仍按目录生成到 `packages/shared/src/contracts/model3d/`,并由该目录的 `index.ts``packages/shared` 的 barrel 统一再导出;生成命令 `npm run contracts:model3d:generate` 写入的是未格式化的 ts-rs 输出,需再执行 `prettier --write packages/shared/src/contracts/model3d` 后提交。
@@ -8,6 +8,10 @@
//!
//! 预检只按主键定点查引用,不拉取当前用户的工程列表或素材库;跨 owner、已删除与不存在
//! 收敛成同一句 400,避免把别的账号是否存在该 ID 变成可探测信息。
//!
//! TODO(oss-direct-read): 「让 Tripo 侧直接读站内对象」这条替代路径(交签名 URL,或对端直读
//! OSS)能省掉一次字节中转与一份上行带宽,但等于把私有对象和带时效的读取凭据交给第三方,
//! 安全口径与可行性都还没讨论;讨论清楚之前保持「api-server 自己读、自己传」。
use axum::http::StatusCode;
use platform_tripo::{TripoImageInput, TripoProviderClient};
@@ -44,6 +44,10 @@ impl TripoProviderClient {
///
/// 站内图片保存在私有 OSS 上,provider 无法直接读取,所以图片输入统一先上传再提交,
/// 不把带签名的临时地址交给第三方。
///
/// TODO(oss-direct-read): 「让 provider 自己读站内对象」(`PublicUrl` 式的签名地址,或
/// 对端直读 OSS)能省掉这次字节中转,但会把私有对象与带时效的读取凭据交给第三方,安全
/// 口径与可行性需要先讨论;讨论前只保留 `FileToken` 这条现役路径。
pub async fn upload_image(
&self,
bytes: Vec<u8>,