5.4 KiB
5.4 KiB
汇率:数据模型、数据源与更新策略
首期定价只需要
CNY → RUB,但表结构按任意法币对设计。汇率是全局参考数据,不属于平台、门店或工作空间。
1. 口径与使用边界
exchange_rates.rate 始终表示:1 单位 base_currency_code 可兑换多少单位 quote_currency_code。例如 CBR 返回 Nominal=1、Value=12.3343 的 CNY 数据,标准化保存为:
base_currency_code = CNY
quote_currency_code = RUB
rate = 12.3343
这是一种报价参考口径,不等同于卖家实际购汇、物流商结算或提现的成交汇率。因此定价保留三种来源:
| 报价来源 | 读取方式 | 是否写入 exchange_rates |
|---|---|---|
| 系统汇率 | 读取当前有效的正式参考汇率 | 是。首期为 CBR 的 official_reference。 |
| 方案固定汇率 | 读取 pricing_policies.fixed_cny_to_rub_rate |
否,报价快照记录该固定值。 |
| 本次覆盖 | 用户在定价弹窗输入 | 否,报价快照记录覆盖值和原因。 |
无论哪种来源,pricing_quotes 都固化 fx_cny_to_rub、fx_rate_origin、可空的 exchange_rate_id 和完整输入快照。后续系统汇率更新绝不改写已确认报价。
2. 数据库设计
DDL 位于 sql/001_foundation.sql 的 exchange_rates 表:
| 字段 | 含义 |
|---|---|
base_currency_code / quote_currency_code |
币种方向;严禁把 CNY/RUB 与 RUB/CNY 混用。 |
rate |
标准化后的“1 base = rate quote”。使用 NUMERIC,不使用浮点数。 |
kind |
official_reference、market_reference 或 manual。 |
source |
cbr、exchange_rate_api_open、frankfurter、manual。 |
effective_on |
数据源声明的适用日期;不是系统抓取日期。 |
observed_at / fetched_at |
来源观测时间与 Atlas 抓取/录入时间。 |
source_reference / raw_payload |
可追溯的来源链接、批次说明和原始响应。 |
同一个“币种方向 + 口径 + 来源 + 适用日期”只能有一条记录。若来源在同一适用日修订汇率,Worker 应在事务中更新原始记录并保留修订审计,或另行建立修订表;首期 CBR 日汇率正常情况下不需要重复插入。
3. 首选数据源:俄罗斯央行 CBR
首期正式系统汇率使用 CBR 的 CNY 对 RUB 官方参考汇率:
GET https://www.cbr.ru/scripts/XML_daily.asp
GET https://www.cbr.ru/scripts/XML_daily.asp?date_req=dd/mm/yyyy
- 不传
date_req返回最近一个已发布工作日;传日期可补历史数据。 - 解析 XML 中
CharCode=CNY的Nominal与Value;将逗号小数转换为NUMERIC,按Value / Nominal标准化。 - 记录
kind=official_reference、source=cbr、来源 XML URL、响应原文、响应对应的适用日期和抓取时间。 - CBR 在周末与节假日可能返回上一工作日数据,这是正常结果,不创建重复记录也不标记请求失败。
CBR 是 Ozon-RU 定价的首选,因为它直接发布 CNY 对 RUB 的官方口径。它不保证等于卖家实际结算汇率,用户仍可选择固定或本次覆盖汇率。
4. 免费备用与未来扩展
| 服务 | 调用方式 | 适用范围 | 使用规则 |
|---|---|---|---|
| CBR | https://www.cbr.ru/scripts/XML_daily.asp |
首期 CNY→RUB 正式口径 | 主来源。免费、官方、按工作日发布。 |
| ExchangeRate-API Open Access | https://open.er-api.com/v6/latest/CNY |
CNY→多币种可用性备用 | 无 Key、日更、需按其条款归属且有频率限制。只能标记为参考或备用,不能静默覆盖 CBR 正式记录。 |
| Frankfurter | https://api.frankfurter.dev/v2/rate/CNY/RUB |
后续多币种、历史查询和数据源对照 | 无 Key;默认可能混合多个来源。需要时应记录 provider 元数据,不能把混合口径伪装为 CBR 官方口径。 |
不要在前端直接调用上述接口,也不要把第三方响应直接当作报价结果。所有请求只由后端 Worker 发起、校验、标准化、持久化后供报价引擎读取。
5. BullMQ 更新与故障策略
- 定时 Worker 在俄罗斯工作日每 2 小时请求一次 CBR;不依赖未经确认的固定发布时间。
- 以
effective_on去重:没有新适用日期时直接结束;有新日期时插入一条exchange_rates记录。 - 每次任务记录 HTTP 状态、解析结果、原始响应摘要和耗时;禁止记录无关敏感信息。
- CBR 请求失败时保留上一条成功汇率并告警;不得自动以备用来源覆盖正式 CBR 数据。
- 若最近 CBR 有效记录距当前超过 72 小时,报价界面显示“系统汇率可能过期”,但仍允许使用上次值、方案固定值或本次覆盖值。
- 定价服务只读取当前有效的
CNY → RUB + official_reference + cbr最新记录;若不存在则不能输出系统汇率报价,应提示选择固定/覆盖汇率或等待更新任务成功。
6. 实施接口边界
- Worker 内部:
ExchangeRateProvider适配器接口,首期实现CbrProvider;备用提供方独立实现,不影响报价公式。 - 后台管理:查看当前系统汇率、历史记录、来源、抓取时间、异常与人工录入
manual汇率;人工记录不得冒充cbr。 - 定价 API:返回最终汇率、来源、适用日期、抓取时间和是否过期;确认报价时只引用快照,不在请求中重新抓取第三方。