# 天工·商品标签 (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)。