feat: 方案设计、数据库和接口设计基本完成
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# 对象存储入门:为什么数据库保存 `object_key`
|
||||
|
||||
> 面向 Atlas Seller Kit 的学习文档。本文解释对象存储、`object_key`、来源 URL 与预签名 URL 的不同,以及本项目应如何保存和访问商品素材。
|
||||
|
||||
## 1. 一句话结论
|
||||
|
||||
**对象存储 URL 是“此刻如何访问文件”,`object_key` 是“文件在存储桶中的稳定身份”。**
|
||||
|
||||
Atlas 的数据库以 `storage_provider + bucket + object_key` 标识已转存的文件;不以 URL 作为文件主数据,也不长期保存带授权参数的访问 URL。
|
||||
|
||||
## 2. 用一张商品图片理解三个概念
|
||||
|
||||
同一张商品原图在生产环境可能保存为:
|
||||
|
||||
```text
|
||||
storage_provider: qiniu_kodo
|
||||
bucket: atlas-prod-assets
|
||||
object_key: workspaces/ws_123/products/p_456/original/asset_789.jpg
|
||||
```
|
||||
|
||||
它在不同环境、不同时间可以生成不同 URL:
|
||||
|
||||
```text
|
||||
本地 MinIO URL:
|
||||
http://localhost:9000/atlas-dev-assets/workspaces/ws_123/...
|
||||
|
||||
七牛分发 URL:
|
||||
https://cdn.example.com/workspaces/ws_123/...
|
||||
|
||||
短时私有访问 URL:
|
||||
https://cdn.example.com/workspaces/ws_123/...?
|
||||
e=1780000000&token=temporary-signature
|
||||
```
|
||||
|
||||
这些 URL 可能随环境、域名、CDN、签名和过期时间而变化;稳定不变的是存储桶和 `object_key`。
|
||||
|
||||
| 项目 | 对象存储 URL | `object_key` |
|
||||
|---|---|---|
|
||||
| 含义 | 当前通过网络读取/写入文件的地址 | Bucket 内文件的唯一定位键 |
|
||||
| 示例 | `https://cdn.example.com/a.jpg?token=...` | `workspaces/ws_123/.../a.jpg` |
|
||||
| 稳定性 | 域名、CDN、签名、环境变化时会变化 | 由 Atlas 生成并管理,作为长期主标识 |
|
||||
| 是否自带读取权限 | 可能带有预签名授权 | 不带授权,只是定位信息 |
|
||||
| 是否作为数据库主字段 | 否 | 是 |
|
||||
|
||||
## 3. Atlas 的正确资产记录
|
||||
|
||||
```text
|
||||
media_assets
|
||||
- id
|
||||
- workspace_id
|
||||
- storage_provider # local_minio / qiniu_kodo
|
||||
- bucket
|
||||
- object_key
|
||||
- checksum_sha256
|
||||
- content_type
|
||||
- byte_size
|
||||
- width / height
|
||||
- created_at
|
||||
```
|
||||
|
||||
图片、视频、水印模板和 AI 生成文件都遵循这个规则。SKU 与媒体的关联保存 `media_asset.id`,而不是图片名称、来源 URL 或对象存储 URL。
|
||||
|
||||
## 4. 不同 URL 分别应保存在哪里
|
||||
|
||||
### 4.1 来源 URL:可以保存,但只是采集证据
|
||||
|
||||
采集 1688、淘宝、天猫、Ozon 公开页时得到的图片链接是 `source_url`。它可能过期、防盗链、重定向或失效,因此只应与采集时间、来源页面、解析器版本一起保存在采集证据中。Worker 下载并转存成功后,正式素材身份切换为 `object_key`。
|
||||
|
||||
### 4.2 Atlas 访问 URL:临时生成,不长期保存
|
||||
|
||||
用户预览或下载私有素材时:
|
||||
|
||||
```text
|
||||
浏览器请求素材
|
||||
→ NestJS 验证当前用户是否有该 asset 的权限
|
||||
→ 根据 storage_provider + bucket + object_key 签发短时 GET URL
|
||||
→ 浏览器用该 URL 显示或下载文件
|
||||
```
|
||||
|
||||
短时 URL 会过期,包含签名时还代表临时授权,不能存到商品表、素材表、日志或前端长期缓存。
|
||||
|
||||
### 4.3 平台发布 URL:发布时派生并记录在快照
|
||||
|
||||
Ozon 导入要求图片为 HTTPS 公网可访问 URL。发布适配器可以从 Atlas 的 `object_key` 派生一个让 Ozon 可拉取的受控分发 URL;该 URL 仅用于这次平台请求,并与请求/响应一起保存在发布快照中,不能反过来替代素材的 `object_key`。
|
||||
|
||||
## 5. 上传和转存流程
|
||||
|
||||
### 用户手动上传
|
||||
|
||||
```text
|
||||
前端请求上传
|
||||
→ API 创建 asset ID 和 object_key
|
||||
→ API 签发短时上传 URL
|
||||
→ 浏览器直传 MinIO/Kodo
|
||||
→ API/Worker 校验 MIME、大小、哈希和图片尺寸
|
||||
→ media_assets 状态变为 ready
|
||||
```
|
||||
|
||||
浏览器不保存 MinIO/Kodo 的永久密钥。
|
||||
|
||||
### 浏览器插件采集
|
||||
|
||||
```text
|
||||
插件上报 source_url 和采集证据
|
||||
→ Worker 下载来源文件
|
||||
→ 校验并计算哈希
|
||||
→ 上传 MinIO/Kodo
|
||||
→ 写入 storage_provider + bucket + object_key
|
||||
→ 建立商品/SKU 媒体关联
|
||||
```
|
||||
|
||||
## 6. 为什么不能把 URL 当主数据
|
||||
|
||||
1. 本地 MinIO 切换到生产七牛 Kodo 时,域名与 URL 结构不同;`object_key` 不变,不需要批量改业务数据。
|
||||
2. 更换 CDN、绑定新域名或调整私有访问策略时,不需要重写数据库。
|
||||
3. 预签名 URL 到期后可重新生成;若保存它,只会积累失效链接。
|
||||
4. 私有原图不必永久公开,访问权限可按工作空间、商品和 SKU 动态校验。
|
||||
5. 去重、删除检查、生命周期清理都围绕稳定资产 ID、哈希和 `object_key` 进行。
|
||||
|
||||
## 7. 本项目的边界
|
||||
|
||||
- 本地开发使用 MinIO;共享测试与生产使用七牛 Kodo。
|
||||
- Bucket 默认私有;原图、水印、AI 图和导入文件不长期公开。
|
||||
- `object_key` 本身不是访问凭据,但也不应作为绕过权限校验的下载入口。
|
||||
- 对象删除前必须确认没有有效数据库引用;软删除或保留期结束后再由后台任务物理清理。
|
||||
|
||||
相关文档:[技术栈、异步任务与部署方案](../architecture/technology-and-deployment.md)、[浏览器采集插件需求](../requirements/collector-browser-extension.md)、[商品与 SKU 数据模型](../product/data-model.md)。
|
||||
Reference in New Issue
Block a user