109 lines
7.3 KiB
Markdown
109 lines
7.3 KiB
Markdown
# geMoldInsight 前后端契约(API_CONTRACT)
|
||
|
||
> 文档定位:**前后端契约的唯一归属**——端点总览、统一约定、OpenAPI 类型生成流程。
|
||
> 端点定义、路径、请求/响应 schema 的**最终真相源是根目录 `openapi.json`**(由 FastAPI 自动生成);本文维护人可读的总览与变更规则。当前状态见 [STATUS.md](STATUS.md),架构见 [ARCHITECTURE.md](ARCHITECTURE.md),接口类技术债见 [TECH_DEBT.md](TECH_DEBT.md) D1。
|
||
|
||
---
|
||
|
||
## 1. 总览
|
||
|
||
三种部署形态暴露的 API 面(入口见 [src/entrypoints/](../src/entrypoints/)):
|
||
|
||
| 形态 | API 面 |
|
||
|---|---|
|
||
| unified(推荐) | `/api/*`(moldinsight + inventory)+ `/api/auth/*` + 顶层 `/health` |
|
||
| moldinsight-only | `/api/*`(moldinsight)+ `/api/auth/*` + `/health` |
|
||
| inventory-only | `/api/*`(inventory)+ `/api/auth/*` + `/health` |
|
||
|
||
- moldinsight 路由在 [moldinsight/api/\_\_init\_\_.py](../src/moldinsight/api/__init__.py) 经 `_safe_include` 聚合(子 router 加载失败仅 WARNING 跳过;`debug_router` 仅 `DEBUG=true` 注册)。
|
||
- inventory 路由在 [inventory/api/\_\_init\_\_.py](../src/inventory/api/__init__.py) 按域静态聚合。
|
||
- 认证路由来自 [shared/services/auth_routes.py](../src/shared/services/auth_routes.py),由 [app_factory](../src/shared/app_factory.py) 挂载,三种形态共用。
|
||
|
||
## 2. 统一约定
|
||
|
||
- **鉴权**:JWT Bearer(`Authorization: Bearer <token>`)。登录:`POST /api/auth/login`(表单)/ `POST /api/auth/login/json`(JSON);受保护路由通过 FastAPI 依赖 `get_current_active_user` 注入当前用户([shared/services/auth_service.py](../src/shared/services/auth_service.py))。`SECRET_KEY` 跨进程必须一致。
|
||
- **响应形态**:现状**无统一信封包装**——各端点直接返回业务 JSON;schema 以 `openapi.json` 的 components 为准。新增接口不建议另起信封风格,保持与所在模块一致。
|
||
- **错误**:FastAPI 标准 `HTTPException` 状态码语义;业务校验优先 Pydantic 请求模型自动 422。
|
||
- **业务路由前缀**:全部业务端点在 `/api` 下;顶层仅 `/health`(探活)、`/login`、`/users`(历史遗留入口,前端主链路用 `/api/auth/*`)。
|
||
|
||
## 3. 端点总览(按域分组)
|
||
|
||
> 下表为导航用速览;路径参数、请求/响应字段以 `openapi.json` 为准。
|
||
|
||
### 3.1 认证与用户(shared)
|
||
|
||
| 域 | 端点 | 文件 |
|
||
|---|---|---|
|
||
| 登录 | `/api/auth/login`、`/api/auth/login/json`、`/api/auth/logout` | auth_routes.py |
|
||
| 当前用户 | `/api/auth/me` | auth_routes.py |
|
||
| 用户管理 | `/api/auth/users`、`/api/auth/users/{user_id}`、`/api/auth/users/{user_id}/reset-password` | auth_routes.py |
|
||
| 角色权限 | `/api/auth/roles`、`/api/auth/roles/{role_id}`、`/api/auth/roles/{role_id}/permissions`、`/api/auth/permissions`、`/api/auth/permissions/{permission_id}` | auth_routes.py |
|
||
|
||
### 3.2 moldinsight(模具分析)
|
||
|
||
| 域 | 端点 | 文件 |
|
||
|---|---|---|
|
||
| 上传 | `/api/upload` | upload_router.py |
|
||
| 批量分析 | `/api/batch-upload`、`/api/batch/{batch_id}`(聚合状态以 PG 为准;响应含 `current_step`;他人批次 403、不存在 404) | batch_router.py |
|
||
| 任务状态 | `/api/status/{task_id}`(需登录;仅任务所有者可访问,他人/无主任务 403,不存在 404) | task_router.py |
|
||
| 历史结果 | `/api/history`、`/api/history/{filename}` | history_router.py |
|
||
| CAM | `/api/cam/plan` | cam_router.py |
|
||
| 铝价(模拟数据) | `/api/aluminum-price/current`、`/api/aluminum-price/history` | aluminum_price_routes.py |
|
||
| 健康检查 | `/api/health` | health_router.py |
|
||
| 调试(仅 DEBUG) | `/api/debug/tasks` | debug_router.py |
|
||
| 导出/估算/设计等高级接口 | 见 `openapi.json` 对应路径 | advanced_router.py(技术债 D1:待拆分) |
|
||
|
||
### 3.3 inventory(进销存)
|
||
|
||
| 域 | 端点 | 文件 |
|
||
|---|---|---|
|
||
| 成品 | `/api/products`、`/api/products/{product_id}`、`/api/products/{product_id}/materials`、`/api/products/from-task/{task_id}` | product_routes.py |
|
||
| 物料价格/供应商 | `/api/materials/*` | material_routes.py |
|
||
| 供应商 | `/api/suppliers`、`/api/suppliers/{supplier_id}` | supplier_routes.py |
|
||
| 客户 | `/api/customers`、`/api/customers/{customer_id}` | customer_routes.py |
|
||
| 仓库 | `/api/warehouses` | warehouse_routes.py |
|
||
| 库存 | `/api/inventory`、`/api/inventory/{inventory_id}` | inventory_routes.py |
|
||
| 库存流水 | `/api/stock-movements` | stock_movement_routes.py |
|
||
| 采购订单 | `/api/purchase-orders`、`/api/purchase-orders/{order_id}`、`.../receive`、`.../status` | purchase_order_routes.py |
|
||
| 采购建议 | `/api/purchase-demands/calculate` | purchase_demand_routes.py |
|
||
| 销售订单 | `/api/sales-orders`、`/api/sales-orders/{order_id}`、`.../status`、`.../issue-materials`、`.../consume-materials`、`.../production-plan` | sales_order_routes.py |
|
||
| 财务 | `/api/finance/summary`、`/api/finance/receivables|payables|receipts|payments|transactions`、`/api/finance/partner-statement/{partner_type}` 等 | finance_routes.py |
|
||
| 看板 | `/api/dashboard` | dashboard_routes.py |
|
||
|
||
**moldinsight → inventory 桥接**:`/api/products/from-task/{task_id}` 由分析任务一键创建成品(对应 `STPFile.product_id -> Product.id` 单库桥接,见 [ARCHITECTURE.md](ARCHITECTURE.md) §5.1)。
|
||
|
||
## 4. OpenAPI 与前端类型生成(接口变更三件套)
|
||
|
||
接口变更后**必须依次完成**:
|
||
|
||
1. **改代码**:路由 + Pydantic 请求/响应模型(优先模型,少写 `request.json()` 解析)。
|
||
2. **重导出 `openapi.json`**(在可 import 项目的环境执行,如 conda `gemold`):
|
||
|
||
```bash
|
||
python -c "import sys; sys.path.insert(0, 'src'); from entrypoints.unified import app; import json; print(json.dumps(app.openapi(), ensure_ascii=False, indent=2))" > openapi.json
|
||
```
|
||
|
||
(moldinsight-only 契约视角可把 `entrypoints.unified` 换成 `entrypoints.moldinsight`;对外主契约以 unified 为准。)
|
||
|
||
3. **重新生成前端类型**:
|
||
|
||
```bash
|
||
cd frontend && npm run gen:api # openapi-typescript:../openapi.json -> src/types/api.ts
|
||
```
|
||
|
||
- `frontend/src/types/api.ts` 是**生成物,禁止手改**;前端代码类型引用它。
|
||
- 三步缺一即前后端契约漂移(硬约束,见 [AGENTS.md](../AGENTS.md) §2)。
|
||
- **当前已知滞后**:checked-in `openapi.json`(2026-07-27)落后当前代码(实际 76 paths vs 文件内 70),下次接口变更时按上述流程重导出。
|
||
|
||
## 5. 契约变更规则
|
||
|
||
- 新增接口先定模块归属(moldinsight / inventory / shared auth),再写路由;返回结构、路径、鉴权发生变化时,同步更新本文相应表格。
|
||
- 路由文件过大按职责拆分(现状债务:`advanced_router` 待拆分,见 [TECH_DEBT.md](TECH_DEBT.md) D1)。
|
||
- 破坏性变更(删字段 / 改语义)需在 [STATUS.md](STATUS.md) 日志条目中记录,并确认前端同仓同步修改。
|
||
|
||
## 6. 前端消费约定
|
||
|
||
- 前端为独立工程 [frontend/](../frontend/)(Vue 3 + Vite + TS + Pinia + TDesign),按域组织在 `src/modules/`(moldinsight / inventory / users / login / home)。
|
||
- API 类型唯一来源 `src/types/api.ts`(生成物);组件不手写与后端重复的响应类型。
|
||
- 跨域:开发期走 Vite;部署期为同域反代(见 [DEPLOYMENT.md](DEPLOYMENT.md)),`CORS_ORIGINS` 仅服务于非同域场景。
|