docs: 归档天工·商品标签(OpenGoods)规划文档

新增 docs/planning/ 规划文档归档:
- 00-final-plan: 最终规划(决策+架构+M0~M5任务清单)
- 01-detailed-design-v2.0: 分类/单位/数据库/API/治理/采集/部署/众包
- 02-advanced-topics-v3.0: OpenAPI/全表DDL/数据契约/OFF映射/中国合规/测试/安全/图片/SLA/竞品
- history/: v0.1~v1.0 演进记录
更新 README 为项目介绍并链接规划文档。

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
2026-06-08 06:05:29 +00:00
parent 729127661e
commit 54175238ad
8 changed files with 1486 additions and 2 deletions
+115
View File
@@ -0,0 +1,115 @@
# 天工·商品标签 (OpenGoods) — 最终规划 (Final)
> 公益网站/服务:采集全网商品信息,提供商品参数查询 API。
> **核心原则:只采集 + 只提供信息,绝不涉及任何购买/下单/比价导购。**
> 本文档为前几版(v0.1 → v2.0)的最终收敛版,所有关键决策已锁定。详细设计见 v2.0 附件。
---
## 0. 项目标识
- **中文名**:天工·商品标签(呼应《天工开物》)
- **英文名**OpenGoods
- **定位**:开放、中立、可溯源的"商品参数百科 + 开放 API"
---
## 1. 已锁定的全部决策
| 维度 | 决策 |
|------|------|
| 首批品类 | **食品快消** |
| 价格 | 只收 **官方标准零售价 (MSRP)**:静态字段,带 currency/region/source/effective_date + 免责;**不收实时电商价、无购买入口** |
| 技术栈 | **Go**(对外只读 API/核心服务) + **Python**(采集/ETL/爬虫),经 **PostgreSQL + Redis/队列** 解耦 |
| 种子数据 | **Open Food Facts 食品 dump** 先导入,最快有真实数据 |
| 数据许可 | 对外数据库用 **ODbL + 署名**;CC0 来源(USDA)自由混入;每条数据按来源标注许可 |
| 商品分类 | **GS1 GPC 四层标准码 (Segment→Family→Class→Brick)** 为骨架 + **自建中文品类树** 映射 + 保留来源原始分类 |
| 单位管理 | 量纲字典;**原始值 + 归一化值双存**;营养统一折算到 `per_100g/per_100ml`;能量 **双存 kJ+kcal**;用十进制(NUMERIC)防误差 |
| 质量评分 | `0.4*完整度 + 0.3*来源权威 + 0.2*多源一致 + 0.1*新鲜度` |
| 众包 | **一期不做众包,先纯采集**;二期再开放贡献/纠错(带审核与版本化) |
| Go 框架 | `chi` + 标准库 `net/http`(轻量) |
| 迁移工具 | `golang-migrate`(纯 SQL,两端共享 schema |
| 部署 | 初期 Docker Composepostgres+redis+minio+go-api+python-worker)→ 后期 K8s |
| 地域 | 先用 OFF 全球食品库起步,后接 GS1-China 补强中国数据 |
---
## 2. 架构(定稿)
```
数据源: OFF dump / OFF API / USDA(CC0) / GS1-China
▼ Python: 采集 adapters → ETL(清洗/单位归一/分类映射/去重/质量评分)
│ 写入
┌────▼─────────┐ 图片 ┌──────────┐
│ PostgreSQL │◀───────▶│ MinIO/S3 │
│ (商品档案主库)│ └──────────┘
└────▲─────────┘
│ 只读 (+Redis 缓存/限流)
▼ Go: 公开 REST API + OpenAPI 文档
各种软件 / 开发者 (无任何交易端点)
```
两端不直接互调,通过共享 PostgreSQL schema + 《数据契约文档》协作。
---
## 3. 仓库结构(写代码时落地)
```
goods/ (OpenGoods 天工·商品标签)
├── README.md
├── LICENSE # 代码: Apache-2.0/MIT; 数据: ODbL 说明
├── docker-compose.yml
├── docs/{data-contract.md, openapi.yaml, disclaimer.md}
├── migrations/ # golang-migrate 共享 SQL
├── api/ # Go 只读 API (chi)
│ ├── cmd/server/main.go
│ └── internal/{handler,store,model,middleware}/
└── ingestion/ # Python 采集 + ETL
├── adapters/{openfoodfacts,usda,gs1}.py
├── etl/{normalize_units,map_category,dedup,quality}.py
└── jobs/{seed_off_dump,scheduler}.py
```
---
## 4. 最终可执行任务清单(按里程碑)
**M0 — 工程地基**~35d
- [ ] Go module + Python 项目骨架
- [ ] docker-composepostgres+redis+minio
- [ ] CIGo build/vet/testPython ruff/pytest
- [ ] `docs/data-contract.md``docs/disclaimer.md`(不提供购买声明)初版
**M1 — 数据模型 + 分类 + 单位**~46d
- [ ] migrationsproduct / food_detail / product_msrp / product_source / brand / manufacturer / category / category_schema / unit / attribute_definition / merge_log
- [ ] 导入 GS1 GPC 骨架 + 建自建中文品类树 + 映射表
- [ ] 单位字典 + 归一化规则
- [ ] 索引:gtin 唯一、name trigram、JSONB GIN、category ltree
**M2 — 种子数据 (Python)**~58d
- [ ] 下载 OFF 食品 dump → 字段映射(成分/营养/过敏原/图片)
- [ ] 单位归一 + 分类映射入库
- [ ] USDA(CC0) 营养补全(可选)
**M3 — MVP API (Go)**~58d
- [ ] 端点:barcode / id / search / nutriments / msrp / brands / categories / sources / healthz
- [ ] 统一响应信封、分页、`fields=` 裁剪、错误码
- [ ] Redis 缓存 + IP 限流 + OpenAPI 文档
**M4 — 采集管线 (Python)**~812d
- [ ] adapterOFF API 增量 + GS1 条码补全
- [ ] ETL:清洗/归一/去重合并/冲突解决/质量评分/字段级溯源
- [ ] 调度(定时增量更新)
**M5 — 开放与规模化**~1015d
- [ ] 搜索引擎(PG 全文 → OpenSearch)、CDN
- [ ] 免费 API Key(防滥用+统计)
- [ ] 众包贡献后台(提交/审核/版本/信誉)
- [ ] 开发者文档站 + 开放数据许可与免责声明上线
> 关键路径:M0→M1→M2→M3(最快拿到可查询 MVP);M4/M5 后续并行迭代。
---
## 5. 下一步
规划已全部定稿。你之前说"先不写代码",所以我**停在这里待命**。
等你说"开始",我从 **M0 工程地基** 动手,搭好骨架后开 PR 给你看(也可指定先只做某几个里程碑,例如 M0+M1)。