5.3 KiB
5.3 KiB
资产对象上传完成确认接口设计
日期:2026-04-21
1. 文档目的
这份文档用于把 M6 中“上传完成后的对象确认接口”冻结到可直接编码的级别。
当前要解决的不是完整资产发布链,而是最小闭环:
- 浏览器先通过
PostObject把文件上传到私有 OSS - 服务端确认对象真实存在
- 服务端把对象元数据写入当前阶段的
asset_object真相存储 - 后续业务绑定与 SpacetimeDB reducer 再基于这条已确认对象继续扩展
2. 当前前提
已落地事实:
POST /api/assets/direct-upload-tickets已能签发浏览器PostObject直传票据。platform-oss已能生成私有读签名 URL。asset_object已在spacetime-module中落下首版表骨架。
当前仍未落地:
- 上传完成确认接口
- 对象 HEAD 校验
asset_object实际写入路径- 业务实体绑定
3. 接口职责
POST /api/assets/objects/confirm 当前阶段只负责三件事:
- 校验请求给出的
bucket + object_key是否合法 - 调 OSS 做一次私有
HEAD Object校验,确认对象真实存在 - 把对象元数据写入当前阶段的
asset_object进程内存储,并返回确认结果
当前阶段明确不做:
- 不做业务实体绑定
- 不做图片尺寸探测
- 不做 hash 计算
- 不做重复对象合并
- 不直接调用 SpacetimeDB reducer
4. 请求体设计
请求路径:
POST /api/assets/objects/confirm
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
bucket |
String |
否 | 当前阶段允许不传;不传时默认回落到服务端 OSS bucket。 |
objectKey |
String |
是 | 正式对象路径真相字段。 |
contentType |
String |
否 | 客户端已知 MIME,可回写到对象元数据。 |
contentLength |
u64 |
否 | 客户端可传期望大小;当前仅用于一致性校验,不作为唯一真相来源。 |
contentHash |
String |
否 | 后续内容摘要预留字段。 |
assetKind |
String |
是 | 业务资产类型,例如 character_visual。 |
accessPolicy |
String |
否 | 默认 private。 |
sourceJobId |
String |
否 | 来源任务 ID。 |
ownerUserId |
String |
否 | 归属用户 ID。 |
profileId |
String |
否 | 归属 profile ID。 |
entityId |
String |
否 | 归属业务实体 ID。 |
补充约束:
bucket当前若传入,必须与服务端已配置 bucket 一致。objectKey必须落在受支持的generated-*前缀下。assetKind当前不能为空。
5. 校验顺序
接口校验顺序固定如下:
- 检查 OSS 配置是否存在
- 校验请求参数基础合法性
- 校验
bucket与服务端配置 bucket 是否一致 - 调用 OSS
HEAD Object - 若客户端传了
contentLength,则与 OSS 返回的真实Content-Length做一致性校验 - 通过后写入
asset_object
6. OSS 校验结果口径
OSS HEAD Object 当前至少回填:
content_lengthcontent_typelast_modified_atetag
当前阶段以 OSS 返回值为准:
content_length真相取 OSScontent_type优先取 OSS,OSS 未返回时再回退请求体content_hash暂不强行等于etag
原因:
etag对 multipart 上传和不同上传模式并不总等价于内容 hash- 当前阶段先留出字段,不把错误假设固化进 schema
7. 写入规则
确认成功后写入 asset_object:
asset_object_id由服务端生成,固定assetobj_前缀bucket与object_key按正式真相写入access_policy当前默认privatecontent_length以 OSS HEAD 为准content_type优先 OSS HEADversion当前固定为1created_at/updated_at在确认时写当前 UTC 时间
当前阶段重复确认同一 bucket + object_key 的行为固定为:
- 若已存在,则返回已存在记录并更新
updated_at - 不生成第二条重复对象记录
8. 响应体设计
成功响应核心字段:
assetObjectIdbucketobjectKeyaccessPolicycontentTypecontentLengthcontentHashassetKindsourceJobIdownerUserIdprofileIdentityIdversioncreatedAtupdatedAt
9. 错误口径
9.1 请求参数错误
返回 400:
objectKey为空objectKey不在受支持前缀下assetKind为空bucket与当前配置 bucket 不一致- 客户端声明的
contentLength与 OSS HEAD 不一致
9.2 OSS 未配置
返回 503
9.3 OSS 对象不存在
返回 404
9.4 OSS 探测失败
返回 502
10. 当前阶段实现边界
当前阶段实现固定为:
platform-oss增加服务端HEAD Objecthelpermodule-assets提供进程内asset_object确认服务api-server接入POST /api/assets/objects/confirm
下一阶段再继续:
- 对接真实 SpacetimeDB reducer
- 业务实体绑定 reducer
- 更细的元数据探测