Files

58 lines
5.1 KiB
Markdown
Raw Permalink 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.
# 云端基础模块:数据模型与数据库边界
> 状态:设计稿。数据库为 PostgreSQL;配套可执行 DDL 见 [`sql/001_foundation.sql`](./sql/001_foundation.sql)。本阶段只产出设计和 SQL,不连接、不创建实际数据库。
## 1. 核心边界
```text
账户 User ── Workspace(租户)── Membership
├─ Store ── Store secret / Warehouse / Watermark binding
├─ Watermark template ── versions / uploaded asset
└─ Pricing policy ── Quote / quote options
Platform(全局) ── Platform product category ── Platform commission category mapping
└─ Commission price tiers
Logistics provider(全局) ── Rate card ── Product type × transport method × rate rule
```
- **工作空间即租户**:新账户创建一个工作空间,创建者是 `owner`。用户、工作空间、成员关系分离,以支持未来多人协作和一个用户管理多个工作空间。
- **平台与当前店铺是全局上下文**:店铺属于“工作空间 + 平台”;每个平台最多一个默认店铺。所有门店业务数据均携带 `workspace_id`。
- **两套类目均强绑定平台**:平台商品类目来自 Ozon 等平台的商品分类;平台佣金类目来自该平台的佣金规则树。它们在同一平台内独立维护,并由版本化映射关联;SQL 使用 `platform_id + category_id` 的复合外键阻止跨平台映射,绝不按名称或 ID 猜测。
- **CEL 价表是全局规则数据**:由后台维护版本和生效期;报价只引用确定版本。首期仅 Ozon-rFBS + CEL,香港空运不录入首期规则。
- **报价是快照**:定价方案可以变,CEL/佣金规则可以更新,但已确认 SKU 报价始终保留当时输入、费率、规则版本和费用拆分。
## 2. 关键表的产品映射
| 领域 | 表 | 说明 |
|---|---|---|
| 账户与租户 | `users`、`workspaces`、`workspace_memberships`、`user_sessions` | 手机号密码登录;短信验证/风控字段预留但一期不启用。 |
| 平台与门店 | `platforms`、`currencies`、`platform_currency_support`、`stores`、`store_secrets`、`store_warehouses` | API Key 单独加密保存;密钥过期时间、商品限额无数据时使用 `NULL`,界面显示 `—`。 |
| 水印 | `media_assets`、`watermark_fonts`、`watermark_templates`、`watermark_template_versions`、`store_watermark_bindings` | 店铺绑定一个当前模板;发布任务未来固化模板版本,而不修改原图。 |
| 类目佣金 | `platform_product_categories`、`commission_categories`、`commission_category_rules`、`platform_product_category_commission_mappings` | 平台商品类目和平台佣金类目都强绑定同一平台;佣金按销售价 RUB 阶梯计费,抓取数据以 `competitor_capture` 来源和待审核版本录入。 |
| 跨境物流 | `logistics_providers`、`logistics_rate_cards`、`logistics_product_types`、`logistics_transport_methods`、`logistics_rate_rules` | CEL 产品类型、运输方式、货值/重量/尺寸/抛重规则、费率和版本分开保存。 |
| 定价 | `pricing_policies`、`pricing_policy_transport_methods`、`pricing_quotes`、`pricing_quote_options` | 店铺默认方案、SKU 单次临时选择、所有候选运输方式结果与最终确认结果。 |
## 3. 必须由服务端保证的规则
1. 在每一个请求事务开始后,先验证当前用户的工作空间成员身份,再执行 `SET LOCAL app.workspace_id = '<uuid>'`;PostgreSQL RLS 作为第二道隔离。
2. `store_secrets.secret_ciphertext` 只保存信封加密后的密文、nonce 和密钥版本。不得写日志、返回 API 响应或发往浏览器缓存。
3. 一个工作空间在同一平台只有一个活动默认店铺;切换默认店铺必须在同一事务内完成。
4. 定价引擎枚举“佣金档位 × CEL 产品类型 × 运输方式”,回验最终销售价的 RUB 佣金档和 CNY 商品货值档;不能沿用旧项目的固定 12% / 18% 佣金。
5. `pricing_quotes.product_variant_id` 暂为逻辑外键:商品/SKU DDL 落地时会补为指向 `product_variants` 的真实外键。报价本身可在没有 SKU 的“即时试算”中存在。
## 4. 初始数据与迁移顺序
1. 执行 `001_foundation.sql`。
2. 初始化 `OZON` 平台、`CNY` / `RUB` 币种和平台币种支持关系。
3. 建立 Ozon 平台商品类目和 Ozon 平台佣金类目树,再人工审核并导入同平台映射与阶梯佣金规则。
4. 将已 Review 的 CEL Ozon-rFBS 规则录入一个 `draft` rate card,用真实 CEL 报价复核后发布为 `active`。
5. 商品/SKU 模块落地后,增加 `product_variants` 外键并把 SKU “定价”按钮接到 `pricing_quotes`。
## 5. 仍不在此 DDL 内的内容
- 短信发送、验证码、风控供应商和密码找回流程;
- Ozon API 的实际同步 Worker、密钥轮换 Worker 和对象存储上传;
- 商品/SPU/SKU、媒体处理任务与真正的上架任务表;
- 平台/物流/佣金规则的后台管理 UI 与导入程序。