48 lines
4.4 KiB
Markdown
48 lines
4.4 KiB
Markdown
# 商品域数据模型与迁移
|
||
|
||
> 可执行 PostgreSQL DDL:[`sql/002_product-domain.sql`](./sql/002_product-domain.sql)。必须先执行 [`sql/001_foundation.sql`](./sql/001_foundation.sql)。
|
||
|
||
## 1. 两个不能混用的商品域
|
||
|
||
```text
|
||
工作空间
|
||
├─ 采集箱商品(跨平台 Atlas 草稿)
|
||
│ collection_items → products → product_variants
|
||
│ └→ product_platform_profiles(每个平台一份)
|
||
│ └→ product_variant_platform_listings(每个 SKU 首次导入状态)
|
||
└─ 在线商品(平台 + 门店独有的同步镜像)
|
||
platform_product_sync_runs → platform_listings → platform_listing_sync_snapshots
|
||
```
|
||
|
||
`products` / `product_variants` 只服务采集箱商品,保存来源、采购和跨平台可复用资料。`platform_listings` 则是目标平台、目标门店的实际商品镜像;它不能跨平台或跨门店复用,即使它关联了 Atlas SKU。`product_platform_profiles.market_code` 表示当前平台业务上下文,首期取平台默认 `RU`,不从门店派生。
|
||
|
||
## 2. 关键关系与状态
|
||
|
||
| 表 | 粒度 | 核心约束 |
|
||
|---|---|---|
|
||
| `collection_items` | 工作空间的一条采集箱记录 | 来源平台商品按 `workspace + source_platform + source_item_key` 幂等;手动商品无来源平台。`workspaces.collection_item_limit` 默认 1000,触发器在创建或恢复记录时以工作空间行锁保证不超限。 |
|
||
| `products` / `product_variants` | 采集箱 SPU / SKU | SKU 删除是 Atlas 软删除,不下架任何平台商品。 |
|
||
| `collection_asset_transfers` | 来源素材转存任务 | 来源 URL 先以持久化任务进入 Worker;成功后才创建 `media_assets` 与商品候选素材。失败可单独重试,不能把未下载素材伪装成资产。 |
|
||
| `collection_seller_enrichment_observations` | Ozon Seller 本地观察结果 | 记录浏览器同源调用四个网页内部接口后的净化结果或不可用原因;不保存 Cookie、授权头或完整会话信息。 |
|
||
| `product_platform_profiles` | 采集箱商品 × 目标平台 | 同一采集箱 SPU 在一个平台只有一份配置;A/B 平台的类目、属性、标题、价格和状态独立。 |
|
||
| `product_variant_platform_listings` | 平台配置 × Atlas SKU | 保存 `offer_id`、首次导入状态、Ozon `product_id`、实际提交时的门店和价格。`imported` 后不可再次从采集箱提交。 |
|
||
| `platform_listings` | 平台 × 门店 × Ozon 商品 SKU | 以店铺内 Ozon `product_id` / `offer_id` 唯一;保存 `visible`、库存、审核、错误和最新原始响应。 |
|
||
|
||
采集箱页面按**当前页头平台**汇总 `product_variant_platform_listings`:无成功导入 SKU 为“未上架”,部分成功为“已部分上架”,全部未删除 SKU 成功为“已上架”。这与 `platform_listings.visible` 完全分离:后者只代表 Ozon 当前是否可购买/可见。
|
||
|
||
## 3. 媒体、AI、任务与审计
|
||
|
||
- `product_media_candidates` 是来源图、AI 图和手工上传图的候选池。
|
||
- `product_variant_listing_media` 是当前平台 SKU 最终选图与顺序;Ozon 首期最多 15 张由发布适配器校验,数据库不硬编码该上限,以支持未来平台差异。
|
||
- `media_derivatives` 记录“编辑图片 → 添加水印”生成的派生资产,固化水印模板版本;原图不被覆盖。
|
||
- `product_ai_tasks` 保存 AI 文案、类目、套图和尺寸图任务的输入快照、模型信息、输出和错误;`ai_category_suggestions` 保存可供用户确认的类目候选。
|
||
- `product_publish_jobs` / `product_publish_job_items` 是 BullMQ 之外的持久化发布事实;重试不能仅依赖 Redis/BullMQ 状态。
|
||
- `platform_product_sync_runs` / `platform_listing_sync_snapshots` 为 Ozon 在线商品全量同步保留运行记录和响应审计。
|
||
|
||
## 4. 执行顺序
|
||
|
||
1. 在空库依次执行 `001_foundation.sql`、`002_product-domain.sql`。
|
||
2. 使用 NestJS migration runner 记录迁移版本;生产环境禁止手工在控制台执行。
|
||
3. 每个请求在成员授权后,在同一事务执行 `SET LOCAL app.workspace_id = '<workspace UUID>'`;API/Worker 使用专用非所有者、无 `BYPASSRLS` 的应用角色。两份迁移对业务表均 `FORCE ROW LEVEL SECURITY`,避免所有者静默绕过。
|
||
4. 商品发布、图片处理、AI、Ozon 同步均先落事务表,再投递 BullMQ;Worker 应能据表中的未完成任务恢复。
|