Update seller store experience
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# 商品采集媒体(图片与视频)存储策略
|
||||
|
||||
> 状态:采集阶段的按需物化已落地;正式商品编辑、水印、AI 图片处理和发布尚未接入选择动作。后续任何相关开发必须以本文为准;接口、数据模型和 Worker 改动须先在同一任务中完成相应契约更新。
|
||||
|
||||
## 1. 目标与基本原则
|
||||
|
||||
采集阶段的绝大多数图片和视频最终不会被用户选中、编辑或发布。首期因此采用**按需物化**:先保存可审查的来源候选信息,只有用户实际使用媒体时才下载、校验并写入 Atlas 对象存储。
|
||||
|
||||
1. `source_url` 是来源证据与即时预览地址,不是 Atlas 控制的正式素材,也不是可靠的长期地址。
|
||||
2. `media_asset` 才是经过大小、格式、安全校验并由 Atlas 控制的正式素材;编辑、发布和需要稳定重试的处理链路只能引用它。
|
||||
3. 浏览器可显示来源图片不代表后端或第三方 AI 服务可稳定下载它。来源可能有防盗链、临时 URL、限流、地区限制、图片替换或失效。
|
||||
4. Worker 不携带来源站 Cookie,不能为了下载图片绕过来源站的会话或防盗链机制。
|
||||
5. 首期不做“已选择但未发布素材”的自动生命周期删除。自动清理需要定义引用、编辑中状态、恢复和误删处理,复杂度与风险超过当前收益。
|
||||
|
||||
## 2. 场景决策表
|
||||
|
||||
| 场景 | 是否需要先转存原图 | 原因 |
|
||||
|---|---:|---|
|
||||
| 采集测试页预览 | 否 | 直接显示来源 URL;视频使用 `preload=none`,最快、零存储成本 |
|
||||
| 采集箱暂存 | 否 | 只保存候选 URL、媒体类型、角色、SKU 关联、视频封面与证据 |
|
||||
| 用户选图/视频进入编辑 | 建议是 | 转存选中的媒体,保证后续可用、可重试 |
|
||||
| 加水印 | 不一定 | 可在任务中临时下载来源图→加水印→只保存水印结果;但来源失效后无法重试 |
|
||||
| AI 生图 / AI 改图 | 通常要先转存或至少临时下载 | AI 服务需要实际图片字节,不能可靠地只依赖来源 URL |
|
||||
| 正式发布 | 是 | 必须使用 Atlas 控制的已验证素材,不能依赖第三方 URL |
|
||||
|
||||
## 3. 推荐流程
|
||||
|
||||
```text
|
||||
来源商品页
|
||||
→ 采集候选 source_url、媒体类型、图片角色、SKU/规格关联、排序、视频封面和证据
|
||||
→ 采集箱 / 测试页直接加载 source_url 供人工核对
|
||||
→ 用户选择图片、请求水印/AI 处理或发起发布
|
||||
→ 按需下载 → HTTPS/格式/大小/内容校验 → 创建或复用 media_asset
|
||||
→ 编辑、派生任务和发布仅引用 media_asset
|
||||
```
|
||||
|
||||
### 3.1 采集与即时预览
|
||||
|
||||
- 采集 API 只持久化来源候选信息;不得在采集完成后自动创建“下载全部候选图”的素材任务或 Outbox 事件。
|
||||
- 测试页和后续采集箱详情优先以 `source_url` 作为 `<img>` 或 `<video preload="none">` 预览。跨域媒体通常可以由浏览器显示,但来源拒绝加载时只显示明确的失败状态与“查看来源”链接。
|
||||
- 来源预览不得被误写入 `media_assets`、商品正式媒体关系、发布请求或长期缓存。
|
||||
|
||||
### 3.2 选择图片与正式编辑
|
||||
|
||||
- 用户首次把候选图设为商品主图、SKU 图、详情图,或进入依赖稳定原图的编辑操作时,服务端创建按需转存任务。
|
||||
- 转存完成后,界面和后续操作切换到该 `media_asset` 的短时访问 URL;来源 URL 仍保留为采集证据。
|
||||
- 转存失败或来源图已不可访问时,应提示用户重新采集/重新选择,而不是尝试携带来源 Cookie 或伪造 Referer 绕过限制。
|
||||
|
||||
### 3.3 水印与 AI 图片处理
|
||||
|
||||
- 水印任务可以临时下载来源图并只存储水印派生结果,以节约原图存储;但该模式无法在来源失效后可靠重试。需要稳定重试、再次编辑或保留原图时,应先转存原图。
|
||||
- AI 生图不一定需要来源图;AI 改图、图生图、抠图等需要图片输入的能力,必须获得实际图片字节。实现可选择先物化 `media_asset`,或在单次任务内临时下载后提交给 AI 提供商。
|
||||
- 向 AI 提供商发送来源图片字节或可访问 URL 属于对第三方的数据传输。产品界面、隐私说明和任务审计必须在该能力立项时明确告知;不得默认将所有采集候选图发送给 AI。
|
||||
- 所有水印和 AI 的成功输出都必须保存为 Atlas 控制的 `media_asset`,并记录输入素材/来源、模板或模型版本与任务证据。
|
||||
|
||||
### 3.4 发布
|
||||
|
||||
- 发布前必须验证每张已选图片是当前工作空间内已校验的 `media_asset`。
|
||||
- 禁止将来源站 URL 直接提交给目标销售平台;发布任务只能使用 Atlas 对象存储中的受控素材或由平台要求的上传结果。
|
||||
|
||||
## 4. 首期明确不做的能力
|
||||
|
||||
不实现“已选择但未发布素材在 7~30 天未使用即自动删除”。实现这一策略需要追踪编辑草稿、引用关系、处理中任务、发布快照、恢复窗口和误删申诉;在没有真实成本数据前,首期保留用户已按需转存的素材。
|
||||
|
||||
未来如存储成本成为问题,优先考虑只清理**从未被商品媒体、派生任务或发布快照引用**的素材,并在独立需求、数据模型、Worker 与用户通知方案评审后实施。
|
||||
|
||||
## 5. 已落地的按需物化边界
|
||||
|
||||
`POST /api/extension/materials` 已将图片和视频保存为 `collection_asset_transfers` 的 `pending_selection` 候选,不会创建素材 Worker 的 Outbox 事件。候选记录带 `media_type`,视频可另带 `poster_url`。重复采集会取消旧快照中尚未完成的候选或转存任务,并以新快照候选覆盖它们。
|
||||
|
||||
`POST /api/collection-items/{id}/asset-materializations` 是当前唯一的按需转存入口:请求必须包含当前快照中的一个或多个 `pending_selection` 候选 ID,并携带 `Idempotency-Key`。服务端将所选行标为 `queued`、创建 operation 并写入 `collection.assets.materialize.requested` Outbox 事件;既有 Worker 继续执行安全下载、校验、去重与 `media_asset` 创建。
|
||||
|
||||
`/collection-test/{id}` 对图片候选直接显示 `source_url`,对视频候选使用按需播放的来源 URL;已转存的历史素材则优先显示 Atlas 短时预览 URL。该测试页只核对数据,不能触发转存。
|
||||
|
||||
### 5.1 首期视频格式边界
|
||||
|
||||
- 当前采集器只接受来源商品结构化状态中明确给出的 HTTPS `MP4` / `WebM` 直链;Ozon 读取 `webGallery` / `webVideo`,1688 读取 `gallery.fields.video|videos`,淘宝/天猫读取 `item.videos`。绝不扫描整页 `video` 元素。
|
||||
- `blob:` URL、`m3u8` / HLS、DRM 和无法识别的扩展不进入候选;转存 Worker 再以文件魔数确认 MP4/WebM。MP4/WebM 单文件上限为 200MB、最长下载等待 60 秒;图片保持 20MB 限制。
|
||||
- 首期不做视频转码、封面抽帧、HLS 下载、DRM 处理、视频水印或发布。视频尺寸和时长也暂不解析;`media_asset.content_type` 是后续处理时的媒体判断依据。
|
||||
|
||||
下一阶段必须在正式商品编辑页实现选图后调用上述接口,并补齐来源失效、防盗链、重复点击、跨工作空间访问、AI/水印输入和发布前素材校验的集成测试;不得绕过该接口直接把来源 URL 写入正式商品媒体或发布请求。
|
||||
|
||||
## 6. 待优化 P1:来源站下载限流与退避
|
||||
|
||||
### 6.1 当前风险边界
|
||||
|
||||
按需物化已避免“采集一次下载全部图片”,但当前 Worker 尚未按来源平台或域名限流:单个转存任务内部逐张下载,Worker 总并发为 5;多个商品同时选图、多个 Worker 实例,或用户在测试页一次打开大量候选图片时,都可能在短时间向同一来源 CDN 发出多次请求。
|
||||
|
||||
- 测试页的候选图片预览由用户浏览器直接请求 `source_url`,不经过 Atlas Worker;它不会消耗 Atlas 存储,但多张图片同屏会形成来源站请求突发。
|
||||
- Worker 下载会限制 HTTPS 公网地址、最多 3 次重定向、60 秒超时;图片上限 20MB、视频上限 200MB。这些是安全和资源保护,**不是来源站限流**。
|
||||
- 当前 `429`、`503` 等下载失败会把候选标记为失败;不会读取 `Retry-After` 后延迟重试,因此不容易持续猛撞来源站,但会降低成功率。
|
||||
- 素材仅在下载后按内容 SHA-256 去重;相同的来源 URL 被多个候选选中时,当前仍可能被重复下载。
|
||||
|
||||
### 6.2 正式编辑页接入前必须完成
|
||||
|
||||
1. 建立基于 Redis 的分布式下载限流器,限流键至少覆盖来源平台和规范化域名;初始建议每域名最多 2 个并发、每秒 2~3 个请求、短时突发不超过 4。实际阈值需按来源平台压测和运行数据调整。
|
||||
2. 将 `429`、带 `Retry-After` 的响应和临时 `503` 转为可调度的延迟重试;遵守 `Retry-After`,使用指数退避与抖动,不能立即重试。
|
||||
3. 对归一化后的来源 URL 建立下载任务去重:同一图片仅下载一次,完成后让多个候选关联同一 `media_asset`,而不是依赖下载后的哈希去重。
|
||||
4. 对连续限流或临时不可用的来源建立熔断/降速窗口,并在操作状态中给出可理解的“来源暂时限流,稍后重试”反馈。
|
||||
5. 测试页和正式采集箱详情采用懒加载、分页或虚拟列表,避免首次进入即请求全部来源预览图;来源图加载失败时保留“查看来源”链接,不能尝试携带 Cookie 或伪造 Referer 绕过防盗链。
|
||||
|
||||
在以上能力落地前,不允许将按需转存用于自动批量选图、全量素材预热或无人值守的大规模转存。
|
||||
Reference in New Issue
Block a user