Files
atlas-seller-kit/docs/requirements/collector-browser-extension.md
T

384 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 浏览器采集插件:需求与技术方案
> 状态:已确认核心方向,待实施。本文是 Atlas Seller Kit 从来源商品详情页进入采集箱、商品编辑与后续 Ozon 上线的采集入口规范。
>
> 本文取代旧 `ozon-seller-kit` 采集插件的产品定位,但只复用经验证的页面采集思路,不复用旧项目的本地数据库、无鉴权接口、`/trial/:id` 页面、AI 套图或生图流程。
## 1. 目标、范围与非目标
### 1.1 目标
浏览器插件让用户在来源商品详情页一键把商品导入 Atlas。它必须:
1. 采集商品原始文本、参数、媒体、规格轴和真实 SKU 组合;
2. 把记录写入登录用户当前工作空间的**当前默认店铺**;
3. 让用户选择“只进入采集箱”或“导入后直接编辑上架”;
4. 保存来源证据和素材转存任务,确保后续可以修正、重试、审计;
5. 尽可能保留真实多 SKU,不凭名称、图片或笛卡尔积猜测不存在的组合。
首期来源站点与旧采集插件相同:Ozon(`ozon.ru`、`ozon.kz`、`ozon.by`)、1688、淘宝、天猫。
### 1.2 非目标
- 插件内不展示采集详情、商品字段编辑、AI 智能规划、AI 文案、AI 生图、套图生成、图片导出或定价;这些工作均在 Atlas ERP 页面完成。
- 插件不直接调用 Atlas 的正式发布接口,不直接创建 Ozon offer,也不保存 Ozon Seller Cookie。
- 插件不以网页上的规格名称、SKU 图片或“所有颜色 × 所有尺码”的笛卡尔积推测真实 SKU。
- Ozon Seller 网页内部接口仅用于可观察的实验性采集,不能成为生产发布、库存或定价的唯一数据源。
## 2. 用户体验
### 2.1 出现位置与外观
在受支持来源站的**商品详情页**右下角显示一个小型矩形悬浮窗。它应使用 Shadow DOM 隔离来源站 CSS,布局接近参考插件:品牌图标/名称、收起按钮和纵向操作按钮。非商品页或 URL 软导航到非商品页时隐藏。
插件不使用旧版的全高 iframe Side Panel。点击操作时仅显示短暂的加载、成功或失败状态;复杂信息回到 ERP 页面展示。
### 2.2 登录态
| 状态 | 悬浮窗内容 | 行为 |
|---|---|---|
| 未登录或令牌失效 | `登录 Atlas ERP` | 新标签打开 Atlas 登录页。完成授权后,插件自动刷新为已登录状态。 |
| 已登录但没有默认店铺 | `前往 ERP 设置默认店铺` | 打开店铺管理页;不允许导入,避免采集记录落到不确定的店铺。 |
| 已登录且存在当前默认店铺 | `编辑上架`、`采集商品`、`进入 ERP` | 按下面的操作规则执行。 |
首期不在悬浮窗中选择店铺。服务端从插件授权身份解析工作空间,并使用该工作空间的当前默认店铺;默认店铺切换在 ERP 中完成。
推荐采用扩展专用的短期授权码流程:插件打开 Atlas 登录/授权页,登录页完成后向 `chrome-extension://{extension-id}/...` 回传一次性 code,插件交换短期 access token 与可轮换 refresh token。令牌只放 Chrome 扩展专属存储,后台请求统一携带 `Authorization: Bearer`。不得像参考插件一样直接读取 ERP 网页 localStorage 中的长期 Token。
### 2.3 三个操作
| 操作 | 流程 | 成功结果 |
|---|---|---|
| 编辑上架 | 扫描当前页 → 上报采集记录 → 创建/复用商品草稿 → 打开编辑页 | 新标签打开 `/products/{productId}/editor`;素材继续后台转存,编辑页显示状态。 |
| 采集商品 | 扫描当前页 → 上报采集记录 | 停留来源页,提示“已进入采集箱”;用户以后从采集箱编辑。 |
| 进入 ERP | 不扫描、不上报 | 新标签打开 Atlas ERP 首页。 |
“上报成功”定义为:数据库事务已创建或复用采集记录、商品草稿、SKU 草稿和素材转存任务。它不等待所有图片下载完成;各素材的 `pending/downloading/ready/failed` 状态在采集箱和编辑页可见,失败可单独重试。
## 3. 端到端流程与状态
```text
来源商品详情页
→ 插件认证、确认当前默认店铺
→ 平台采集器(原始证据 + 规范化结果)
→ 扩展后台统一上报
→ Atlas API:幂等创建采集记录、SPU 草稿、真实 SKU 草稿、素材任务
→ Redis/BullMQ Worker:下载、校验、去重、转存到 MinIO/Kodo
→ 采集箱
├─ 继续编辑:商品编辑页
└─ 删除/归档/重试
→ 文案、SKU 媒体、定价、AI 生图、发布校验
→ 发布快照 → 官方 Ozon Seller API 导入、轮询、库存设置、上线状态
```
建议的采集状态:
| 状态 | 含义 |
|---|---|
| `collecting` | 插件正在扫描来源页。 |
| `received` | 服务端已接受原始结果并创建事务记录。 |
| `materializing` | 素材下载、转存、哈希去重进行中。 |
| `ready_for_edit` | 至少商品草稿可编辑;单个素材仍可能失败。 |
| `needs_review` | SKU 组合、规格或媒体证据不足,需要人工确认。 |
| `failed` | 采集请求或关键记录创建失败;保留可诊断错误。 |
| `archived` | 用户不再处理的采集记录。 |
同一默认店铺内,以 `source_platform + source_item_key` 进行幂等。重复“采集商品”应返回已有采集记录;重复“编辑上架”打开同一商品草稿。只有用户在 ERP 中明确选择“重新采集并合并/创建副本”时,才允许覆盖或复制。
## 4. 统一采集数据模型
### 4.1 原始与规范化数据分层
采集结果不能直接当作已确认商品数据。至少保留三层:
1. **原始证据**:页面 URL、采集时间、来源页面状态片段/响应片段、字段路径、解析器版本、原始文本和来源素材 URL。
2. **规范化采集结果**:解析出的通用字段、规格轴、SKU 组合、媒体关系和可信度。
3. **商品草稿**:用户或 AI 确认后的 SPU/SKU、属性、媒体和价格;只有草稿能进入发布快照。
每个字段和媒体关系应携带 `source`、`confidence`、`raw_value`、`captured_at`。规格、重量或尺寸口径未知时保留原文并标记 `ambiguous`,不能直接写入实物或包装物流规格。
### 4.2 规范化载荷
```ts
interface CollectedProductPayload {
source: {
platform: 'ozon' | '1688' | 'taobao' | 'tmall';
itemKey: string;
canonicalUrl: string;
collectedAt: string;
parserVersion: string;
};
common: {
title?: CollectedValue;
description?: CollectedValue;
brand?: CollectedValue;
sourcePrice?: MoneyValue;
attributes: CollectedAttribute[];
categories: SourceCategory[];
};
variantAxes: SourceVariantAxis[];
variants: CollectedVariant[];
assets: CollectedAsset[];
evidence: SourceEvidence[];
}
interface CollectedVariant {
sourceVariantKey: string; // 来源稳定 ID;不可只用展示名称
sourceSku?: string;
selections: Array<{ axisKey: string; valueKey: string; valueName: string }>;
displayName: string;
sourcePrice?: MoneyValue;
sourceStock?: number;
physical?: RawMeasurementSet;
package?: RawMeasurementSet;
mediaBindings: VariantMediaBinding[];
confidence: 'verified' | 'partial';
evidenceRefs: string[];
}
```
`variantAxes` 描述颜色、尺码、容量等可选值;`variants` 只描述可售的真实组合。两者不能互相替代。
### 4.3 媒体关系与继承
| 关系 | 条件 | 编辑页/发布时的表现 |
|---|---|---|
| `variant_direct` | 来源明确给出这个 SKU 与素材的稳定关联 | 自动绑定给该 SKU。 |
| `axis_value` | 例如颜色值有稳定图片,SKU 组合明确包含该颜色 | 该素材可作为包含该颜色的 SKU 默认图,保留“来自颜色轴”证据。 |
| `product_candidate` | 主图、详情图或无法可靠关联的素材 | 进入商品候选池;用户可选给任一 SKU。 |
| `inherited_product_default` | SKU 已验证存在但无专属图 | SKU 卡片与发布预览解析父商品默认图;不复制资产、不声称它是来源 SKU 图。 |
这允许“真实多 SKU 但没有 SKU 图”的商品继续进入编辑、定价和发布,同时不制造错误的来源关联。发布快照必须记录最终解析到的媒体 ID 与关系来源。
## 5. 多 SKU 通用规则
1. 创建多个 SKU 的前提是来源提供稳定组合记录、SKU ID、变体 SKU、`propPath` 等可验证证据;单独的“红色”“M 码”选项不够。
2. `source_variant_key` 优先使用来源 SKU ID。不存在来源 ID 时,使用来源提供的属性 ID/值 ID 的有序组合,并记录构造规则与风险;不得只拼本地化展示名称。
3. 同一 `source_variant_key` 重采集应更新其采集记录和候选素材,不应再创建一个 SKU。
4. 只识别出规格轴但没有组合时,创建一个默认 SKU,状态为 `needs_review`;规格轴仍保留给编辑页辅助人工拆分。
5. 不使用笛卡尔积构造 SKU。来源若只返回“颜色选项”和“尺码选项”而没有组合可售表,无法证明每种组合都存在。
6. 来源价格、库存、重量、尺寸只作采集参考。发布前必须由用户确认有效包装规格、定价快照、目标店铺类目和目标语言内容。
## 6. 各平台详细方案
### 6.1 Ozon 公开商品页
#### 目标
按 Ozon 页面公开的真实 `sku` 发现同一前台变体组,并为每个发现的来源 SKU 建立 `CollectedVariant`。这里的来源 `sku` 是 Ozon 前台商品/变体标识,**不是 Atlas 目标店铺的 `offer_id`**;发布后每个 Atlas SKU 仍生成自己的 `offer_id`。
#### 采集步骤
1. 从当前商品页的白名单状态组件读取标题、价格、画廊、视频、参数、类目和当前来源 SKU。
2. 从包含产品变体的页面状态(参考实现中的 `webProductsModal` / `aspects[].variants` 一类组件)提取每一条 `sku`、标题、价格、划线价、封面、规格文本和关联链接。旧采集插件只保留了 `webAspects` 的名称与图片,丢弃了 `sku`,新实现不得如此。
3. 将当前 SKU 和发现到的关联 SKU 放入有界队列;按 `sku` 去重。对每个 SKU 加载该 SKU 的公开详情页面/页面 JSON,补齐图片、视频、描述与可能继续出现的关联 SKU。
4. 队列达到固定上限(建议 100)或无新 SKU 时停止。记录 `discovered_count`、`hydrated_count`、失败项与页面证据。
5. 每个成功补全的来源 SKU 创建一个 `CollectedVariant`;没有专属图片时设置 `inherited_product_default`,不丢弃变体。
#### 完整性边界
“采集完整”只表示当前公开页面明确暴露的同一变体组已经遍历完成,不能承诺获得 Ozon 系统中所有相似商品、其他卖家 offer、未在该组展示的变体,或受地区/库存/实验策略隐藏的内容。来源页面没有稳定 `sku` 的候选项不得创建 SKU。
#### 失败与回退
- 公开变体组不可读:只创建当前页面默认 SKU,并保留“未发现可验证关联 SKU”警告。
- 个别变体详情失败:保留已经发现的 `sourceVariantKey`,状态为 `partial`;用户可在采集箱触发重新补全。
- 页面内容延迟加载:先等待目标组件和有限滚动;不得抓取推荐、关联购买等非当前商品组件。
### 6.2 1688
#### 可复用的旧插件能力
旧项目的 `extensions/collector` 会通过 MAIN world bridge 读取 `window.context`,已能从中取得:
- `skuModel.skuProps`:规格轴和值,部分值带图片;
- `skuMapOriginal`:SKU 级价格、库存和组合信息;
- `pieceWeightScaleInfo`:部分 SKU 的长、宽、高和重量;
- 主图、视频、标题、类目、店铺、参数和来源 `offerId`。
但旧实现把 SKU 信息扁平为“带规格名的 SKU 图片”,其最终 `ScanResult` 和 `/api/materials` 上报均未保留真实 SKU 记录,必须重构。
#### 新解析方案
1. 读取并保存规格轴:每个属性维度的来源属性 ID、名称、值 ID、值名称和图片 URL。
2. 遍历 `skuMapOriginal` 的每个真实组合行。优先取行自身 SKU ID;若没有,读取行中完整的属性 ID/值 ID 组合生成 canonical key。
3. 通过属性 ID/值 ID,而不是文字名称,将组合行映射到规格轴。这样“黑色”在两个维度重复出现也不会错配。
4. 读取该组合行的价格、库存和可用状态;从 `pieceWeightScaleInfo` 以来源 SKU ID 或同一属性组合匹配重量/尺寸,保存原单位和证据路径。
5. 若颜色/样式轴图片明确属于组合中的一个值,创建 `axis_value` 媒体关系;无可靠关系时只放候选池,SKU 继承父商品默认图。
#### 禁止的回退
参考毛子 ERP 的 1688 DOM 逻辑会把“规格选项 × SKU 详情”做笛卡尔积,再用父商品主图填充图片。父图回退本身可用,但笛卡尔积会制造不存在的组合,Atlas 禁止采用。缺少真实组合表时只保留规格轴并创建默认 SKU。
### 6.3 淘宝与天猫
#### 可复用的页面数据
旧插件读取 `__ICE_APP_CONTEXT__`、`__general_skupanel_cache_data` 和 `__ICE_DATA_LOADER__`,目前只能提取规格轴和值图片。毛子 ERP 的实现展示了真实组合应如何解析:
- `skuBase.props`:属性维度和值,包含 `pid`、`vid`、名称和部分图片;
- `skuBase.skus`:每个真实可售组合的 `skuId` 和 `propPath`;
- `skuCore.sku2info[skuId]`:该组合的价格等 SKU 级信息。
`propPath` 中的 `pid:vid` 列表是组合证据。新插件须将它映射回 `skuBase.props`,生成如“颜色=红、尺码=M”的选择集,使用 `skuId` 作为 `sourceVariantKey`。
#### 采集策略
1. 优先读取当前页面已经加载的状态数据,不主动调用签名 MTop 接口。
2. 若状态中同时存在 `skuBase.skus` 与 `skuCore.sku2info`,按真实 `skuId` 创建多 SKU;价格缺失时标记 `partial`,不丢失组合。
3. 若只存在 `skuBase.props`,只保存规格轴和颜色等值图片;创建默认 SKU 并要求人工确认。
4. 颜色值图片可按 `axis_value` 关系继承给包含该颜色的真实组合;尺码、容量等无图片的组合继承父商品默认图。
毛子 ERP 会在某些场景直接携带浏览器登录态调用签名 MTop 详情接口,取得 `skuCore` 与详情描述。该做法可以作为独立的技术可行性研究,但不能成为首期生产依赖:它受签名算法、登录态、风控和来源站规则影响。若未来试验,必须显式开关、最小请求量、记录来源与失败原因,且不能把 Cookie 或签名凭据上传 Atlas。
### 6.4 平台能力与回退矩阵
| 平台 | 真实 SKU 组合证据 | 价格/库存 | SKU 图片策略 | 无组合时 |
|---|---|---|---|---|
| Ozon | 公开变体的 `sku` 与页面关联数据 | 逐 SKU 公开价格;库存通常不作为可信采集字段 | 逐 SKU封面,缺失时继承父图 | 当前页面默认 SKU。 |
| 1688 | `skuMapOriginal` 行与属性 ID/值 ID 组合 | 可采集价格、库存 | 颜色/样式值图片按轴继承;其余父图继承 | 默认 SKU + 规格轴。 |
| 淘宝/天猫 | `skuBase.skus.skuId + propPath` | `skuCore.sku2info` | 颜色轴图片按组合继承;其余父图继承 | 默认 SKU + 规格轴。 |
## 7. Ozon Seller 网页增强采集:观察性实验
### 7.1 目的与边界
毛子 ERP 在公开 Ozon 商品页采集外,还要求浏览器打开已登录的 `seller.ozon.ru`,并通过跨标签消息调用 Seller 网页的内部接口。Atlas 可以在 Ozon 采集插件中实现一个**可选、显式开启、只用于观察结果**的实验模式。
实验模式目标是把公开页面发现的来源 SKU 与 Seller 网页返回的补充数据并排保存,帮助评估是否值得采用;它不得:
- 自动修改 Atlas 商品、价格、包装规格、库存或发布数据;
- 读取、保存、上传或记录 Seller Cookie、`company_id` 以外的会话凭据;
- 替代官方 `Client-Id + Api-Key` Seller API 的正式发布、库存和状态同步;
- 将返回的销量/浏览等数据表述为“当前店铺数据”,除非 Ozon 未来提供可验证的官方契约。
四个接口都属于 `seller.ozon.ru` 网页内部接口,不是公开 Seller API;官方公开文档未给出其稳定契约。接口变动、登录态不足或风控失败必须视为正常实验失败,而非商品采集失败。
### 7.2 参考插件的调用方式
毛子 ERP 的 background/content script 大致如下:
```text
公开 Ozon 商品页发现 source SKU
→ 检查是否有已登录 seller.ozon.ru 标签页
→ 从当前浏览器会话取得 company_id
→ 跨标签发消息给 seller.ozon.ru content script
→ 在 seller.ozon.ru 同源上下文中 fetch 内部接口
headers: x-o3-company-id / x-o3-language
credentials: include
→ 仅把响应数据(不含 Cookie)回传来源页
→ 毛子 ERP 加密后上传自己的后端
```
Atlas 只可借鉴“请求必须在已登录 Ozon 同源标签执行”的技术结构。实验结果进入 `source_evidence` 或独立 `seller_enrichment_observations`,保存原始响应的净化副本、字段清单、接口名、时间、当前来源 SKU、解析版本和错误信息。
### 7.3 四个接口与已观察到的用途
| 接口 | 参考请求形态 | 已观察到的用途 | Atlas 实验记录 |
|---|---|---|---|
| `/api/v1/search-variant-model` | `{ name: sourceSku, limit: 50 }` | 按来源 SKU/名称查找变体模型候选。 | 候选数量、候选 `variant_id`、是否存在精确 SKU。 |
| `/api/v1/search` | `company_id` + SKU filter + `is_copy_allowed: false` | 以来源 SKU 查找内部变体记录,必要时取得 `variant_id`。 | 查询上下文、匹配项、选择理由。 |
| `/api/site/seller-prototype/create-bundle-by-variant-id` | `company_id`、`variant_id`、`source: SOURCE_UI_COPY_MERGED` | 获得复制/创建商品 bundle;代码可见其中包含商品图片、包装长宽高和重量等。 | bundle 的净化原始 JSON、可解析字段、与公开页差异。 |
| `/api/site/seller-analytics/what_to_sell/data/v3` | `company_id`、SKU、`period: monthly`、`stock: any_stock` | 参考插件读取销量/销售额相关字段、品牌、类目、浏览/点击/退款等指标;其他字段会透传到其后端。 | 全量字段名、数值、时间口径、账户差异、是否可重复。 |
前 3 个接口主要用于 SKU/变体定位和复制 bundle;经营指标主要来自第 4 个分析接口。截图中的 rFBS 佣金、跟卖列表和跟卖价在毛子 ERP 中还会通过其自身后端接口补充,不应误认为由这四个 Ozon 接口直接返回。
### 7.4 数据范围尚未确认的事项
`what_to_sell/data/v3` 请求需要 `company_id`,但仅从插件代码无法证明它返回“当前店铺指标”还是“平台/权限范围内的市场洞察”。毛子 ERP 会对公开来源商品的 SKU 发起请求,这说明它可能用于竞品/选品数据;但这不是可依赖的接口契约。
因此实验页面必须标注:`Ozon Seller 网页观察数据,范围与口径未确认,仅供研究`。
验证方法:使用两个不同店铺账户,对同一个不属于任一店铺的公开 SKU 对比响应;再和当前店铺已上架 SKU 的官方 Seller API 数据对比。只有在口径、权限和稳定性得到确认后,才能决定是否建设独立“选品洞察”功能。
### 7.5 Atlas 实验流程与安全控制
1. 用户在插件设置中显式打开“采集 Ozon Seller 网页观察数据(实验)”。默认关闭。
2. 用户自行在浏览器登录 `seller.ozon.ru`;插件只检测标签页和请求可用性,不显示、不导出、不持久化 Cookie。
3. 标准公开页面采集先完成。对每一个发现的 `sourceVariantKey`,后台按低并发、有限数量发起四个观察请求。
4. 回传前清除请求/响应中可能存在的会话字段、用户信息、店铺名称、授权头等无关信息;服务器再次执行结构化白名单与脱敏。
5. 结果写入工作空间隔离的观察记录。采集箱展示“公开页数据 / Seller 网页观察数据”的字段差异,但不会自动覆盖草稿。
6. 请求失败、账号无权、没有 Seller 标签页或内部接口变更时,只记录 `unavailable` 原因;“编辑上架”和“采集商品”仍正常完成。
## 8. Atlas API、任务与存储
### 8.1 插件接口建议
| 接口 | 用途 |
|---|---|
| `GET /api/extension/session` | 返回登录状态、工作空间、当前默认店铺是否可用;不返回敏感门店凭据。 |
| `POST /api/extension/auth/exchange` | 用一次性授权码交换扩展短期令牌。 |
| `POST /api/extension/materials` | 接收 `CollectedProductPayload`;服务端解析当前身份与默认店铺,实施幂等创建。 |
| `GET /api/collection-items/{id}` | 查询采集记录、SKU 发现数、素材转存状态和警告。 |
| `POST /api/collection-items/{id}/retry-assets` | 重新投递失败素材。 |
| `POST /api/collection-items/{id}/seller-enrichment-observations` | 仅实验开关启用时接收已净化的 Ozon Seller 网页观察数据。 |
不得让插件在请求体中随意指定 `workspace_id` 或 `store_id`。服务端从令牌确定工作空间,读取该工作空间的当前默认店铺,并在事务中应用 PostgreSQL RLS。
### 8.2 素材转存
- 插件上报来源 URL、Referer origin、MIME/类型、组别、排序和媒体关系;不把二进制图片塞进常规 JSON。
- Worker 用受控请求下载来源素材,进行 MIME、大小、尺寸、哈希校验,再写入私有 MinIO/Kodo 对象存储。
- 下载受来源防盗链、过期 URL 或风控影响而失败时,保留来源 URL 和错误;用户可重新采集或在编辑页手动上传。
- 同一工作空间内用内容哈希和来源规范化 URL 去重,但同一资产可在多个商品/SKU 媒体关系中复用。
### 8.3 可恢复性
采集记录、素材任务、Ozon Seller 网页实验请求和未来发布任务都应先写 PostgreSQL,再经 outbox 投递 BullMQ。重试必须有幂等键、次数上限、指数退避和可见错误。浏览器关闭、Worker 重启或 Redis 重建都不能造成已创建商品草稿重复或素材关系丢失。
## 9. 旧实现与参考实现的取舍
### 9.1 `ozon-seller-kit/extensions/collector`
可复用:WXT/TypeScript 扩展结构、Shadow DOM 注入、MAIN world bridge、来源素材分组、Ozon/1688/淘宝/天猫的基础页面识别、图片 URL 还原、详情图懒加载和后台代理请求。
不复用:全高 AI Side Panel、AI 规划/生图/导出、无鉴权 `POST /api/materials`、本地服务地址、单商品数据模型,以及把 `variantName` 当作 SKU 关系的做法。
### 9.2 `extension-v1` 与 `extension-v2`
两者的 `ProductJson` 都只有一个商品;`_images.sku[].variantName` 只是图片备注,不能表达真实多 SKU。v1 甚至只取淘宝/天猫第一条规格轴;v2 对 Ozon 仅保存变体名称和图片。它们只能作为页面选择器和素材采集参考。
### 9.3 毛子 ERP 插件
可借鉴:小悬浮窗和登录状态切换、淘宝/天猫 `skuId + propPath + sku2info` 的真实组合解析、Ozon 以公开 `sku` 发现变体并逐一补全详情、按 SKU 去重、无专属图时回退父商品图、Seller 网页内部接口的跨标签同源调用结构。
不复用:读取 ERP localStorage Token、长期保存访问令牌、上传 Cookie、依赖未公开 Seller 网页接口完成核心业务、1688 的规格轴与 SKU 明细笛卡尔积、将未证实的经营指标作为正式店铺事实。
## 10. 实施分期与验收
### 10.1 分期
1. **采集基础**:扩展认证、小浮窗、默认店铺检查、统一载荷、采集箱入库、素材转存、幂等和“编辑上架/采集商品”。
2. **真实多 SKU**:1688 `skuMapOriginal`、淘宝/天猫 `skuId + propPath`、Ozon 公开 `sku` 变体遍历;完善 SKU 媒体继承与采集箱警告。
3. **Ozon Seller 网页观察实验**:四个接口的同源调用、净化存储、字段差异观察页与双店铺验证;不接入正式发布链路。
4. **编辑与发布闭环**:动态属性、AI 文案/媒体、定价快照、发布校验、官方 Ozon Seller API 导入、轮询和库存设置。
### 10.2 验收样本矩阵
每个平台至少准备以下可重复样本并保存允许使用的页面快照:
| 场景 | 断言 |
|---|---|
| 单 SKU 商品 | 创建一个默认 SKU,主图和参数完整。 |
| 单规格轴、多 SKU | 创建来源实际出现的所有 SKU,不重复。 |
| 颜色 × 尺码 | 只创建来源组合表实际列出的组合;不得出现笛卡尔积假组合。 |
| 有颜色图、无尺码图 | 组合继承颜色轴图或父图,关系可追溯。 |
| 无 SKU 图 | 真实 SKU 均存在并继承父商品默认图。 |
| 个别变体详情/素材失败 | 保留发现的 SKU 和错误;可单独重试。 |
| 重复点击采集 | 复用同一采集记录和商品草稿。 |
| 无默认店铺/令牌过期 | 只显示正确的登录或设置引导,不写入数据。 |
| Ozon Seller 实验无权限 | 标准公开采集成功,观察实验单独失败且不阻塞。 |
## 11. 待确认与后续文档
本文件已确认插件入口、默认店铺、多 SKU 基本原则和 Ozon Seller 网页观察实验的边界。实施前仍需补充:
1. `CollectedProductPayload` 的 OpenAPI/JSON Schema 与 PostgreSQL 表、迁移和 RLS 细节;
2. 当前默认店铺的服务端选择、切换和删除规则;
3. 各来源真实页面快照测试集与解析器版本策略;
4. Ozon Seller 网页四接口实验的字段字典、双店铺对照结果、数据保留期和是否继续投入;
5. 采集箱列表、详情、重新采集、合并与归档的页面需求;
6. 正式 Ozon 发布任务的状态机、请求/响应审计与库存策略。
相关文档:[商品编辑页](../product/README.md)、[商品 API 草案](../product/api.md)、[技术与异步任务方案](../architecture/technology-and-deployment.md)、[Ozon Seller API 资料](../integrations/ozon-seller-api/README.md)。