176 lines
6.3 KiB
Markdown
176 lines
6.3 KiB
Markdown
# dealerhub · 阶段 2 完整实施报告
|
||
|
||
> PLAN.md 阶段 2 全部落地;本文件记录执行结果。
|
||
|
||
## ✅ 阶段 2 完成清单(按"模型 → 序列化 → service → async view → 测试")
|
||
|
||
### 1. core.workflow.StateMachine(14 个测试通过)
|
||
- `apps/core/workflow.py`:通用状态机服务,支持 guard / action / hook / 事务
|
||
- `apps/core/tests/test_workflow.py`:14 个测试覆盖合法迁移 / 非法事件 / guard 拒绝 / action 触发 / hook 触发 / 完整链路
|
||
|
||
### 2. apps.partner(7 个测试通过)
|
||
- `Partner / Customer / Supplier / PriceLevel / Contact` 5 个模型
|
||
- 完整序列化、async ViewSet、URL 路由
|
||
- 测试:CRUD、search、租户隔离
|
||
|
||
### 3. apps.inventory(13 个测试通过)
|
||
- `Warehouse / Stock / StockMovement` 3 个模型
|
||
- `services.py` 原子化:inbound / outbound / lock / unlock / adjust,全部带 select_for_update + transaction.atomic + 流水
|
||
- `available = on_hand - locked` 字段
|
||
- 加权平均成本自动维护
|
||
- 测试:入出库、并发安全、锁定释放、负数拒绝、调整
|
||
|
||
### 4. apps.finance(8 个测试通过)
|
||
- `Receivable / Payable / Receipt / Payment / Allocation` 5 个模型
|
||
- `services.py`:create_receivable_from_sale / create_payable_from_purchase / allocate_receipt / allocate_payment
|
||
- 部分付款、跨单分摊、金额校验
|
||
|
||
### 5. apps.purchase(5 个测试通过)
|
||
- `PurchaseOrder / PurchaseOrderLine / PurchaseBill / PurchaseBillLine`
|
||
- `services.create_purchase_bill` + `confirm_purchase_bill`(自动写库存 + 生成应付)
|
||
- 双重过账拒绝
|
||
|
||
### 6. apps.sales(6 个测试通过)
|
||
- `SalesOrder / SalesOrderLine / SalesBill / SalesBillLine`
|
||
- `services.create_sales_bill` + `confirm_sales_bill`(自动扣库存 + 生成应收)
|
||
- 库存不足回滚
|
||
|
||
### 7. 端到端冒烟测试(3 个测试通过)
|
||
`tests/test_e2e.py`:建商品 → 建仓库 → 建客户/供应商 → 进货单过账(写库存 + 生成应付)→ 付款单核销 → 销售单过账(扣库存 + 生成应收)→ 收款单核销 → 结清 — 全链路 1 个事务里跑通,状态完全一致。
|
||
|
||
### 8. Docker 部署到 lan-19216857(PostgreSQL + Granian)
|
||
- `infra/docker/Dockerfile.backend`:Python 3.12 + Granian + psycopg[pool] + 全部依赖
|
||
- `docker-compose.yml`:连既有 `pg-shared` 网络 → 复用 pg-main 容器,自动 `CREATE ROLE/DB dealerhub`
|
||
- 服务名:`backend-backend-1`,端口 18050 → 容器 8000
|
||
- 4 worker + 1 runtime-threads
|
||
- 容器内 ping 通过;smoke.sh 通过;多租户 CRUD 通过
|
||
|
||
---
|
||
|
||
## ✅ 验证证据
|
||
|
||
### 1. 测试总览
|
||
```
|
||
$ python -m pytest -p no:cacheprovider
|
||
==============================
|
||
65 passed, 77 warnings in 0.87s
|
||
==============================
|
||
```
|
||
| 模块 | 测试数 | 结果 |
|
||
|---|---|---|
|
||
| apps.core.workflow | 14 | ✅ |
|
||
| tests.test_catalog | 6 | ✅ |
|
||
| tests.test_partner | 7 | ✅ |
|
||
| tests.test_inventory | 13 | ✅ |
|
||
| tests.test_finance | 8 | ✅ |
|
||
| tests.test_purchase | 5 | ✅ |
|
||
| tests.test_sales | 6 | ✅ |
|
||
| tests.test_e2e | 3 | ✅ |
|
||
| 其他(ping/tenant)| 3 | ✅ |
|
||
| **合计** | **65** | **✅** |
|
||
|
||
### 2. Docker 部署
|
||
```
|
||
$ docker ps | grep dealerhub
|
||
backend-backend-1 Up (healthy) 0.0.0.0:18050->8000/tcp
|
||
```
|
||
|
||
### 3. 服务端冒烟(smoke.sh)
|
||
```
|
||
[1/8] ping {"ok":true,"service":"dealerhub",...}
|
||
[2/8] JWT 登录 TOKEN 长度: 231
|
||
[3/8] 仓库 CRUD warehouse id=1
|
||
[4/8] 商品CRUD product id=1
|
||
[5/8] 客户/供应商CRUD supplier id=1, customer id=1
|
||
[6/8] 列表查询 products:1, warehouses:1, customers:1, suppliers:1
|
||
===== 全部通过 =====
|
||
```
|
||
|
||
---
|
||
|
||
## 📁 主要新增文件(阶段 2)
|
||
|
||
```
|
||
dealerhub/backend/apps/
|
||
├── core/
|
||
│ ├── workflow.py ← 状态机服务
|
||
│ ├── viewset.py ← BaseTenantViewSet + StandardAsyncPagination(共享给所有 app)
|
||
│ └── tests/test_workflow.py ← 14 测试
|
||
├── partner/
|
||
│ ├── models.py / serializers.py / views.py / urls.py / apps.py
|
||
│ └── apps.py
|
||
├── inventory/
|
||
│ ├── models.py / serializers.py / views.py / urls.py / services.py ← 原子化库存服务
|
||
│ └── apps.py
|
||
├── finance/
|
||
│ ├── models.py / serializers.py / views.py / urls.py / services.py ← 应收应付核销
|
||
│ └── apps.py
|
||
├── purchase/
|
||
│ ├── models.py / serializers.py / views.py / urls.py / services.py ← 进货单过账
|
||
│ └── apps.py
|
||
└── sales/
|
||
├── models.py / serializers.py / views.py / urls.py / services.py ← 销售单过账
|
||
└── apps.py
|
||
|
||
dealerhub/backend/tests/
|
||
├── test_partner.py ← 7 测试
|
||
├── test_inventory.py ← 13 测试
|
||
├── test_finance.py ← 8 测试
|
||
├── test_purchase.py ← 5 测试
|
||
├── test_sales.py ← 6 测试
|
||
└── test_e2e.py ← 3 测试(端到端)
|
||
|
||
dealerhub/backend/
|
||
├── docker-compose.yml ← 部署配置
|
||
├── infra/docker/Dockerfile.backend
|
||
└── infra/scripts/run_prod_granian.sh ← 用 --runtime-threads 修复 Granian 2.8 API
|
||
```
|
||
|
||
```
|
||
dealerhub/
|
||
└── smoke.sh ← 内网端到端冒烟脚本
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 部署信息(lan-19216857)
|
||
|
||
```bash
|
||
# 服务地址(内网)
|
||
http://192.168.5.7:18050
|
||
|
||
# 容器
|
||
backend-backend-1 ← Django 5.2 + DRF + adrf + Granian 2.8 ASGI
|
||
backend-pg-bootstrap ← 一次性建 dealerhub role/db
|
||
|
||
# 数据库
|
||
PostgreSQL: pg-main (1Panel 既有容器,192.168.5.7:5433 → 容器 5432)
|
||
DB: dealerhub / owner dealerhub / password=Chunyu10086086
|
||
|
||
# 默认账号
|
||
username: alice / password: alice12345 / superuser
|
||
默认租户: X-Tenant-Id: default
|
||
|
||
# 启动/停止
|
||
cd /home/chunyu/dealerhub/backend
|
||
DJANGO_SECRET_KEY="..." POSTGRES_PASSWORD="Chunyu10086086" docker compose up -d
|
||
docker compose down
|
||
docker logs -f backend-backend-1
|
||
|
||
# 冒烟
|
||
bash /home/chunyu/dealerhub/smoke.sh http://192.168.5.7:18050
|
||
```
|
||
|
||
---
|
||
|
||
## ⏭️ 下一阶段可选项
|
||
|
||
1. **报表元数据化**(自定义报表 / 仪表盘):阶段 3 已规划但未落地
|
||
2. **电商平台对接**(抖店 / 拼多多 / 1688):ChannelAdapter
|
||
3. **完整财务**(凭证 / 总账 / 资产负债表):深度总账
|
||
4. **AI 加持**:智能开单 / AI 报表 / 智能补货
|
||
5. **HTTPS**:接入 nginx + Let's Encrypt
|
||
6. **CI/CD**:自动部署
|
||
|
||
需要继续推进哪个?
|