54175238ad
新增 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>
5.4 KiB
5.4 KiB
天工·商品标签 (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 Compose(postgres+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 — 工程地基(~3–5d)
- Go module + Python 项目骨架
- docker-compose(postgres+redis+minio)
- CI(Go build/vet/test;Python ruff/pytest)
docs/data-contract.md、docs/disclaimer.md(不提供购买声明)初版
M1 — 数据模型 + 分类 + 单位(~4–6d)
- migrations:product / 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)(~5–8d)
- 下载 OFF 食品 dump → 字段映射(成分/营养/过敏原/图片)
- 单位归一 + 分类映射入库
- USDA(CC0) 营养补全(可选)
M3 — MVP API (Go)(~5–8d)
- 端点:barcode / id / search / nutriments / msrp / brands / categories / sources / healthz
- 统一响应信封、分页、
fields=裁剪、错误码 - Redis 缓存 + IP 限流 + OpenAPI 文档
M4 — 采集管线 (Python)(~8–12d)
- adapter:OFF API 增量 + GS1 条码补全
- ETL:清洗/归一/去重合并/冲突解决/质量评分/字段级溯源
- 调度(定时增量更新)
M5 — 开放与规模化(~10–15d)
- 搜索引擎(PG 全文 → OpenSearch)、CDN
- 免费 API Key(防滥用+统计)
- 众包贡献后台(提交/审核/版本/信誉)
- 开发者文档站 + 开放数据许可与免责声明上线
关键路径:M0→M1→M2→M3(最快拿到可查询 MVP);M4/M5 后续并行迭代。
5. 下一步
规划已全部定稿。你之前说"先不写代码",所以我停在这里待命。 等你说"开始",我从 M0 工程地基 动手,搭好骨架后开 PR 给你看(也可指定先只做某几个里程碑,例如 M0+M1)。