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
@@ -0,0 +1,107 @@
# 商品档案公益 API 系统 — 规划方案 (v1.0 定稿)
> 公益网站/服务:采集全网商品信息,提供商品参数查询 API。**只收集 + 只提供信息,不涉及任何购买行为。**
---
## 1. 已锁定的决策
| # | 决策 | 结论 |
|---|------|------|
| 1 | 品类 | 首批 **食品快消** |
| 2 | 价格 | 只收 **官方标准零售价 (MSRP)**,静态字段,带来源/时间/地区/币种 + 免责说明;**不收实时电商价、不提供购买入口** |
| 3 | 技术栈 | **Go**(对外API/核心服务) + **Python**(采集/ETL/爬虫),经 PostgreSQL + Redis/队列解耦 |
| 4 | 种子数据 | ✅ **先导入 Open Food Facts 食品 dump**,最快拥有真实数据 |
| 5 | 数据许可 | 因采用 OFF → 对外数据库用 **ODbL** 并署名来源;CC0 来源(USDA)可自由混入 |
### 1.1 我先用的默认值(如不同意请指出,否则按此执行)
- **Go Web 框架**`chi` + 标准库 `net/http`(轻量、稳定、易维护)。
- **地域范围**:先用 OFF **全球食品库**起步,后续接 **GS1-China** 补强中国市场数据。
- **数据库迁移工具**Go 侧用 `golang-migrate`(纯 SQL 迁移,两端共享同一套 schema)。
- **部署**:初期 Docker Compose 一键起全套(Postgres/Redis/Go API/Python worker)。
---
## 2. 目标架构(定稿)
```
数据源(OFF dump / OFF API / USDA / GS1)
▼ Python: 采集 adapters → ETL(清洗/归一/去重/质量评分)
┌────▼─────────┐ 图片 ┌──────────┐
│ PostgreSQL │◀───────▶│ S3/MinIO │
│ (商品档案主库)│ └──────────┘
└────▲─────────┘
│ 只读 (+Redis缓存/限流)
▼ Go: 公开 REST API + OpenAPI 文档
各种软件 / 开发者
```
- **解耦契约**:两端通过共享 PostgreSQL schema + 一份《数据契约文档》协作,互不直接调用。
- **Go 端只读主库**(或读副本);**Python 端负责写入**。
---
## 3. 仓库结构(计划,写代码时落地)
```
goods/
├── README.md
├── docker-compose.yml # postgres + redis + minio + api + worker
├── docs/
│ ├── data-contract.md # 两端共享的字段契约
│ └── openapi.yaml # API 契约
├── migrations/ # 共享 SQL 迁移 (golang-migrate)
├── api/ # Go: 对外只读 API
│ ├── cmd/server/main.go
│ ├── internal/{handler,store,model,middleware}/
│ └── go.mod
└── ingestion/ # Python: 采集 + ETL
├── pyproject.toml
├── adapters/{openfoodfacts,usda,gs1}.py
├── etl/{normalize,dedup,quality}.py
└── jobs/{seed_off_dump,scheduler}.py
```
## 4. 数据模型 & API 契约
(沿用 v0.2`product` 主表 + `food` 食品字段 + `msrp` 价格 + 辅助实体;API 以 `GET /products/barcode/{gtin}` 为核心,全只读、无交易端点。详见 v0.2 附件。)
---
## 5. 可执行任务拆分(按里程碑,写代码时逐项落地)
**M0 — 工程地基**
- [ ] 初始化 Go module (`api/`) + Python 项目 (`ingestion/`)
- [ ] `docker-compose.yml`Postgres + Redis + MinIO
- [ ] CIGo: build/vet/testPython: ruff/pytest
- [ ] `docs/data-contract.md` 初版
**M1 — 数据模型**
- [ ] `migrations/`product / food / msrp / brand / manufacturer / category / source / attribute_definition / merge_log
- [ ] JSONB + GIN 索引;gtin 唯一索引
**M2 — 种子数据 (Python)**
- [ ] 下载 OFF 食品 dumpCSV
- [ ] `seed_off_dump`:字段映射 → 入库(含营养/成分/过敏原/图片URL)
- [ ] USDA(CC0) 营养补全(可选)
**M3 — MVP API (Go)**
- [ ] 路由 + handlerbarcode / id / search / nutriments / msrp / brands / categories / sources
- [ ] 统一响应、分页、`fields=` 裁剪、错误处理
- [ ] Redis 缓存 + IP 限流;`/healthz` + OpenAPI 文档
**M4 — 采集管线 (Python)**
- [ ] adapterOFF API(增量更新)+ GS1(条码补全)
- [ ] ETL:清洗/单位归一/去重合并/质量评分/溯源
- [ ] 调度(定时增量更新)
**M5 — 开放与规模化**
- [ ] 搜索引擎(PG 全文 → OpenSearch)、CDN 缓存
- [ ] 免费 API Key(防滥用+统计)、众包纠错后台
- [ ] 开发者文档站 + 开放数据许可声明 + 站点"不提供购买"声明
---
## 6. 下一步
规划已定稿。**你说先不写代码,所以我暂停在这里**。等你说"开始",我就从 **M0 工程地基** 动手,搭好骨架后开 PR 给你看。也可以先只做某个里程碑(比如先 M0+M1 把骨架和数据模型立起来)。