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>
4.7 KiB
4.7 KiB
商品档案公益 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- CI(Go: build/vet/test;Python: 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 食品 dump(CSV)
seed_off_dump:字段映射 → 入库(含营养/成分/过敏原/图片URL)- USDA(CC0) 营养补全(可选)
M3 — MVP API (Go)
- 路由 + handler:barcode / id / search / nutriments / msrp / brands / categories / sources
- 统一响应、分页、
fields=裁剪、错误处理 - Redis 缓存 + IP 限流;
/healthz+ OpenAPI 文档
M4 — 采集管线 (Python)
- adapter:OFF API(增量更新)+ GS1(条码补全)
- ETL:清洗/单位归一/去重合并/质量评分/溯源
- 调度(定时增量更新)
M5 — 开放与规模化
- 搜索引擎(PG 全文 → OpenSearch)、CDN 缓存
- 免费 API Key(防滥用+统计)、众包纠错后台
- 开发者文档站 + 开放数据许可声明 + 站点"不提供购买"声明
6. 下一步
规划已定稿。你说先不写代码,所以我暂停在这里。等你说"开始",我就从 M0 工程地基 动手,搭好骨架后开 PR 给你看。也可以先只做某个里程碑(比如先 M0+M1 把骨架和数据模型立起来)。