Files
goods/docs/data-contract.md
lixu 786b7d3721 feat(M0): 工程地基 - Go API + Python 采集骨架 + CI + 数据契约
- api/: Go(chi) 只读 API 骨架, /healthz + 版本化路由(占位), Dockerfile, 单测
- ingestion/: Python 采集/ETL 包骨架, units 单位归一化(纯函数+测试), adapter 协议
- docker-compose.yml: postgres + redis + minio + api
- .github/workflows/ci.yml: Go build/vet/test + Python ruff/pytest
- docs/data-contract.md(两端共享契约) + docs/disclaimer.md(不提供购买声明)
- migrations/ 占位(M1 起填充)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-06-08 06:18:31 +00:00

1.9 KiB
Raw Permalink Blame History

数据契约 (Data Contract) v0.1

本契约是 Go(API) 与 Python(ingestion) 两端共享的"事实约定",避免两端对字段含义理解不一致。

写入责任:仅 Python (ingestion) 通过 ETL 写入数据库Go (API) 只读。所有写入必须经过单位归一化与字段级溯源。

1. 边界原则

  • 系统只采集与提供客观商品信息;不包含任何购买/交易语义的字段或端点。
  • 价格仅收录官方建议零售价 (MSRP) 的静态快照,必须带 currency/region/source/effective_date

2. 固定枚举

字段 取值
product.status active / merged / deprecated
food_detail.nutrition_basis per_100g / per_100ml / per_serving
unit.dimension mass / volume / energy / count / ratio / length / duration
source.license ODbL / CC0 / proprietary / ...
product_image.kind front / ingredients / nutrition / other

3. 单位规则

  • 数值字段同时保存原始值 + 单位归一化值 + 基准单位canonical)。
  • 质量 → g,体积 → ml,能量 → kJ(同时保留 kcal)。
  • 归一化逻辑由 ingestion/opengoods/units.py 提供(纯函数,含测试),换算因子是唯一事实来源。
  • 营养成分统一折算到品类模板规定的基准(per_100g / per_100ml)。

4. 标识与可空性

  • product.gtin8/12/13/14 位数字,可空(无条码商品),非空时全局唯一。
  • product.quality_score ∈ [0, 1]。
  • 货币用 ISO 4217CNY 等),国家/地区用简短代码(CN 等)。

5. 溯源 (Provenance)

  • 每条数据通过 product_source 记录来源、URL、贡献字段、抓取时间与原始快照。
  • 对外 API 在 sources 中透明返回来源与其许可。

6. 版本

  • 本契约随 schema 演进版本化;任何 schema 变更需同步更新:迁移(SQL) + 本契约 + docs/openapi.yaml