Files
inventory_analytics/PROJECT_GUIDE.md
T
2026-05-14 12:14:23 +08:00

469 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Inventory Analytics 项目说明
## 1. 项目概览
当前项目围绕 3 条业务链路运行:
- 委外批次库存上传:通过本地网页上传 Excel/CSV 文件,归档原始文件,并逐行写入 Raw PostgreSQL。
- 渠道库存统计同步飞书:从 Analytics PostgreSQL 查询渠道库存、挂单量、销售与商品信息,并同步到飞书多维表格。
- 批次库存统计报表:读取最新批次库存、关联 Analytics 店铺库存与近 30 天销售,生成本地报表并可同步到飞书。
命名说明:
- “渠道库存统计”是框架层命名,当前默认业务目标仍是羽心堂渠道库存-9:30和20:00。
- “批次库存统计”是框架层命名,当前默认业务目标仍是羽心堂批次库存。
- 后续扩展到其他品牌时,优先复用这两条通用链路,而不是继续新增带品牌名的脚本和包名。
项目已经完成一轮框架调整:
- 新实现逐步迁入 `inventory_analytics/` 包。
- 根目录脚本保留兼容入口。
- `scripts/` 目录提供新的标准执行入口。
- 旧的 `inventory_sync/` 仍保留,当前被渠道库存统计链路复用,属于过渡层。
## 2. 当前目录结构
```text
inventory_analytics/
├── .env
├── pyproject.toml
├── PROJECT_GUIDE.md
├── REFACTOR_PLAN.md
├── Dockerfile
├── docker-compose.yaml
├── docker-entrypoint.sh
├── supervisord.conf
├── prefect.yaml
├── prefect_inventory_scheduler.py
├── generate_batch_inventory_report.py
├── generate_yxt_batch_inventory_report.py
├── list_feishu_base_tables.py
├── sync_channel_inventory.py
├── upload_inventory_page.py
├── scripts/
│ ├── generate_batch_inventory_report.py
│ ├── register_prefect_deployments.sh
│ ├── sync_channel_inventory.py
│ └── upload_batch_inventory.py
├── inventory_analytics/
│ ├── __init__.py
│ ├── config.py
│ ├── logging_utils.py
│ ├── paths.py
│ ├── db/
│ │ └── __init__.py
│ ├── feishu/
│ │ ├── __init__.py
│ │ └── client.py
│ ├── batch_upload/
│ │ ├── __init__.py
│ │ └── web.py
│ ├── channel_inventory_sync/
│ │ ├── __init__.py
│ │ ├── cli.py
│ │ ├── entrypoint.py
│ │ ├── queries.py
│ │ ├── service.py
│ │ └── specs.py
│ └── batch_inventory_report/
│ ├── __init__.py
│ ├── cli.py
│ └── service.py
├── inventory_sync/
│ ├── __init__.py
│ ├── cli.py
│ ├── feishu.py
│ ├── postgres.py
│ ├── service.py
│ ├── settings.py
│ ├── specs.py
│ └── sql.py
├── batch_inventory_data/
├── logs/
└── reports/
```
说明:
- `inventory_analytics/` 是当前主包,后续新增实现优先放这里。
- `scripts/` 是推荐执行入口。
- 根目录兼容入口仍保留,避免旧命令立即失效。
- `inventory_sync/` 当前仍在使用,但属于待进一步收敛的历史模块。
## 3. 模块职责
### 3.1 通用基础层
| 文件 | 说明 |
| --- | --- |
| `inventory_analytics/config.py` | 统一加载 `.env`、读取数据库和飞书配置 |
| `inventory_analytics/logging_utils.py` | 统一日志初始化与敏感信息脱敏 |
| `inventory_analytics/paths.py` | 统一维护项目根目录、日志目录、报表目录、上传目录 |
### 3.2 上传链路
| 文件 | 说明 |
| --- | --- |
| `scripts/upload_batch_inventory.py` | 推荐入口 |
| `upload_inventory_page.py` | 兼容入口 |
| `inventory_analytics/batch_upload/web.py` | 上传页、文件解析、Raw 写库实现 |
### 3.3 渠道库存统计链路
| 文件 | 说明 |
| --- | --- |
| `scripts/sync_channel_inventory.py` | 推荐入口,默认等价于 `--action all` |
| `sync_channel_inventory.py` | 通用兼容入口 |
| `list_feishu_base_tables.py` | 历史兼容入口 |
| `inventory_analytics/channel_inventory_sync/entrypoint.py` | 新入口日志封装 |
| `inventory_analytics/channel_inventory_sync/cli.py` | 当前复用旧 `inventory_sync.cli` |
| `inventory_sync/` | 当前渠道库存统计实际实现所在模块 |
### 3.4 批次库存统计链路
| 文件 | 说明 |
| --- | --- |
| `scripts/generate_batch_inventory_report.py` | 推荐入口 |
| `generate_batch_inventory_report.py` | 通用兼容入口 |
| `generate_yxt_batch_inventory_report.py` | 历史兼容入口 |
| `inventory_analytics/batch_inventory_report/service.py` | 报表查询、汇总、导出、飞书同步实现 |
## 4. 环境变量
项目主要使用以下配置:
### 4.1 Raw 数据库
```text
RAW_DB_HOST
RAW_DB_PORT
RAW_DB_USER
RAW_DB_PASSWORD
RAW_DB_NAME
```
### 4.2 Analytics 数据库
```text
ANALYTICS_DB_HOST
ANALYTICS_DB_PORT
ANALYTICS_DB_USER
ANALYTICS_DB_PASSWORD
ANALYTICS_DB_NAME
```
### 4.3 飞书配置
```text
FEISHU_APP_ID
FEISHU_APP_SECRET
FEISHU_BASE_URL
FEISHU_APP_TOKEN
```
说明:
- `FEISHU_APP_TOKEN` 可选。
- 当 `FEISHU_BASE_URL` 已包含 `/base/` 或 `/wiki/` 时,可以不额外配置 `FEISHU_APP_TOKEN`。
- 配置优先从项目根目录 `.env` 读取,若缺失则回退到当前 shell 环境变量。
## 5. 执行方式
### 5.1 推荐入口
启动上传页:
```bash
python3 scripts/upload_batch_inventory.py
```
启动后访问:
```text
http://127.0.0.1:8080
```
执行渠道库存统计完整流程:
```bash
python3 scripts/sync_channel_inventory.py
```
这条命令默认等价于:
```bash
python3 scripts/sync_channel_inventory.py --action all
```
按动作拆分执行:
```bash
python3 scripts/sync_channel_inventory.py --action feishu
python3 scripts/sync_channel_inventory.py --action postgres
python3 scripts/sync_channel_inventory.py --action sync-brand
python3 scripts/sync_channel_inventory.py --action all
```
生成批次库存统计报表并同步飞书:
```bash
python3 scripts/generate_batch_inventory_report.py
```
只生成本地报表,不同步飞书:
```bash
python3 scripts/generate_batch_inventory_report.py --skip-feishu-sync
```
自定义输出路径:
```bash
python3 scripts/generate_batch_inventory_report.py --output reports/custom.xlsx
```
### 5.2 兼容入口
以下旧命令或兼容命令仍可继续使用:
```bash
python3 upload_inventory_page.py
python3 sync_channel_inventory.py --action all
python3 list_feishu_base_tables.py --action all
python3 generate_batch_inventory_report.py
python3 generate_yxt_batch_inventory_report.py
```
## 6. 各链路行为说明
### 6.1 委外批次库存上传
支持文件:
- `.xlsx`
- `.xlsm`
- `.xls`
- `.csv`
单文件大小限制:
```text
200 MB
```
上传成功后会执行:
1. 保存原始文件到 `batch_inventory_data/`
2. 解析 Excel 或 CSV
3. 自动确认 `raw_data.wangdian_batch_inventory` 表存在
4. 每一行写入一条 JSONB payload
写入表:
```text
raw_data.wangdian_batch_inventory
```
### 6.2 渠道库存统计同步飞书
当前支持动作:
```text
feishu
postgres
sync-brand
all
```
说明:
- 当前脚本名已经泛化为“渠道库存统计”,但内部动作参数 `sync-brand` 仍来自历史实现,后续可再统一。
- 当前默认同步目标仍是羽心堂渠道库存-9:30和20:00。
渠道库存统计目标和字段映射当前仍维护在:
- `inventory_sync/specs.py`
- `inventory_sync/sql.py`
### 6.3 批次库存统计报表
当前报表链路会:
1. 读取 `raw_data.wangdian_batch_inventory` 中最新批次数据
2. 提取商家编码
3. 查询 Analytics 中对应店铺可发库存、商品信息、近 30 天销售数量
4. 生成合并报表
5. 输出到 `reports/`
6. 可选同步到飞书 `批次库存` 表
说明:
- 当前命名已泛化为“批次库存统计”
- 当前默认业务规则仍针对羽心堂
默认输出文件名格式:
```text
reports/批次库存统计_YYYYMMDD_HHMMSS.xlsx
```
## 7. 字段同步策略
渠道库存统计和批次库存统计在同步飞书时,都采用相同策略:
1. 先读取当前飞书表字段
2. 判断当前字段结构是否与期望配置一致
3. 如果一致:只删除旧记录,再写入新记录
4. 如果不一致:删除受管字段并按配置重新创建,再写入新记录
## 8. 日志说明
日志统一采用结构化事件格式:
```text
YYYY-MM-DD HH:MM:SS LEVEL logger_name 事件=中文事件描述 中文字段=字段值
```
主要日志文件:
```text
logs/upload_inventory_page.log
logs/sync_channel_inventory.log
logs/generate_batch_inventory_report.log
```
说明:
- 上传页日志主要输出到 stdout,并写入 `upload_inventory_page.log`
- 渠道库存统计日志主要输出到 stderr,并写入 `sync_channel_inventory.log`
- 批次库存统计日志输出到 stdout,并写入 `generate_batch_inventory_report.log`
## 9. 推荐验证方式
验证渠道库存统计入口:
```bash
python3 scripts/sync_channel_inventory.py --action feishu
```
验证上传页:
```bash
python3 scripts/upload_batch_inventory.py
```
验证批次库存统计本地导出:
```bash
python3 scripts/generate_batch_inventory_report.py --skip-feishu-sync
```
编译校验:
```bash
PYTHONPYCACHEPREFIX=/tmp/inventory_analytics_pycache python3 -m compileall inventory_analytics scripts generate_batch_inventory_report.py generate_yxt_batch_inventory_report.py sync_channel_inventory.py list_feishu_base_tables.py upload_inventory_page.py prefect_inventory_scheduler.py
```
## 10. Docker 与 Prefect 部署
项目已补齐以下部署文件:
```text
Dockerfile
docker-compose.yaml
docker-entrypoint.sh
supervisord.conf
prefect.yaml
prefect_inventory_scheduler.py
```
### 10.1 调度目标
当前通过 Prefect 定义了 2 个 deployment,每个 deployment 用一条 cron 覆盖每天 `09:15` 和 `19:15`(`Asia/Shanghai`):
- 渠道库存统计并写入飞书
- 批次库存统计报表并写入飞书
### 10.2 依赖前提
需要先准备:
- 可访问的 Prefect API
- 已创建的 Prefect work pool:`inventory-analytics-pool`
- 项目根目录 `.env`
如果 Prefect API 跑在宿主机本地,容器默认使用:
```text
http://host.docker.internal:4200/api
```
### 10.3 容器内按名称注册 deployment
```bash
sh scripts/register_prefect_deployments.sh
```
脚本会进入 Docker 容器内,按 deployment 名称分别注册:
```bash
docker compose exec -T prefect-inventory-worker prefect --no-prompt deploy --name channel-inventory-sync-0915-1915
docker compose exec -T prefect-inventory-worker prefect --no-prompt deploy --name batch-inventory-report-0915-1915
```
### 10.4 启动 Docker worker
```bash
docker compose up -d --build
```
如果调整了 Python 依赖或 Prefect 版本,需要重新构建镜像后再注册 deployment:
```bash
docker compose build --no-cache prefect-inventory-worker
docker compose up -d prefect-inventory-worker
sh scripts/register_prefect_deployments.sh
```
这会启动一个容器,容器内通过 `supervisord` 常驻运行:
```text
prefect worker start --pool "inventory-analytics-pool" --type process
```
### 10.5 手工触发 Prefect flow
立即执行渠道库存统计:
```bash
python3 prefect_inventory_scheduler.py --run-channel-inventory-sync
```
立即执行批次库存统计:
```bash
python3 prefect_inventory_scheduler.py --run-batch-inventory-report
```
### 10.6 本地 serve 模式
```bash
python3 prefect_inventory_scheduler.py --serve-channel-inventory-sync
python3 prefect_inventory_scheduler.py --serve-batch-inventory-report
```
### 10.7 调度入口说明
Prefect 调度脚本不会走 shell 子进程,而是直接调用当前项目入口逻辑:
- 渠道库存统计等价于 `python3 scripts/sync_channel_inventory.py --action all`
- 批次库存统计等价于 `python3 scripts/generate_batch_inventory_report.py`
## 11. 维护建议
- 新增功能优先落在 `inventory_analytics/` 包内,不再继续向根目录增加重脚本。
- 新命令优先使用 `scripts/` 目录中的入口。
- 渠道库存统计后续应继续把 `inventory_sync/` 中的实现迁入 `inventory_analytics/channel_inventory_sync/` 与 `inventory_analytics/feishu/`。
- 公共配置、日志、路径处理统一走 `config.py`、`logging_utils.py`、`paths.py`。
- 涉及渠道库存统计 SQL 和字段映射时,当前仍优先修改 `inventory_sync/sql.py` 与 `inventory_sync/specs.py`。