baseline: 批次A-D 成果 + membership 半成品(测试红)

This commit is contained in:
agent
2026-09-11 23:11:35 +08:00
commit b3f3095d53
311 changed files with 40540 additions and 0 deletions
+175
View File
@@ -0,0 +1,175 @@
# 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**:自动部署
需要继续推进哪个?