Files
shanxia2.0/openspec/changes/transport-plan-management/specs/pl-api-json/spec.md
T
2026-06-21 09:19:07 +08:00

60 lines
3.3 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.
# PL API JSON 命名(运输计划模块)
本能力补充 `openspec/changes/zkxw-engineering-standards/specs/api-conventions/spec.md` 中「JSON 字段命名」要求,**专用于** `app/api/pl/**` 与 `web-admin/src/api/pl/**`、`web-admin/src/views/pl/**`。
## ADDED Requirements
### Requirement: 运输计划 API JSON 字段 camelCase 对齐
运输计划模块(路由前缀 `/api/transport/**`)的请求体、响应体及 Query 参数中,凡前端 TypeScript 使用 camelCase 的多词字段,后端 Pydantic Schema SHALL 通过 `Field(..., alias="camelCase")` 声明 JSON 别名,并设置 `model_config = {"populate_by_name": True}`(或 `ConfigDict(populate_by_name=True)`)。
路由层访问请求体 SHALL 使用 **Python snake_case 属性名**(如 `payload.carrier_name`),SHALL NOT 使用 `payload.carrierName`。
读接口(`response_model=...Read`)SHALL 为 ORM 列对应的 snake_case 字段配置 alias,使 FastAPI 默认 `response_model_by_alias=True` 输出 camelCase,与 `web-admin/src/api/pl/index.ts` 类型定义一致。
#### Scenario: 承运商新增
- **WHEN** 前端 `POST /api/transport/carrier` 请求体为 `{ "carrierName": "某某物流", "contactName": "张三", "status": "1" }`
- **THEN** `CarrierCreate` SHALL 校验通过(HTTP 非 422)
- **AND** 路由 SHALL 通过 `payload.carrier_name` 写入 `pl_carrier.carrier_name`
#### Scenario: 计划新增含产品明细
- **WHEN** 前端 `POST /api/transport/plan/` 请求体含 `belongsCompany`、`planType`、`planDate` 及 `products[].productId`
- **THEN** `PlanCreate` / `PlanProductCreate` SHALL 校验通过
- **AND** 响应 `PlanRead` / `PlanProductRead` 的 JSON 键 SHALL 为 `planNo`、`createTime` 等 camelCase
#### Scenario: 运输安排
- **WHEN** 前端 `POST /api/transport/order/arrange/{planId}` 请求体为 `{ "vehicleId": "...", "driverId": "...", "freightType": "by_weight" }`
- **THEN** `TransportArrange` SHALL 校验通过
- **AND** 路由 SHALL 使用 `payload.vehicle_id`、`payload.driver_id` 访问字段
#### Scenario: 列表分页 Query
- **WHEN** 前端 GET 列表接口 Query 为 `page=1&pageSize=20&planType=direct`
- **THEN** 路由参数 SHALL 通过 `Query(..., alias="pageSize")` 或 Schema alias 正确解析
- **AND** SHALL NOT 静默忽略 `pageSize` 导致始终使用默认每页 20 条
#### Scenario: 仅 snake_case 无 alias 视为缺陷
- **WHEN** `app/schemas/pl/**` 中 Write/Read Schema 的多词字段仅有 `snake_case` 属性名、无 `alias`
- **THEN** 属于本变更范围内的规范违反;前端发送 camelCase 时将返回 **422 Unprocessable Entity**
- **AND** 修复 SHALL 为后端补 alias,SHALL NOT 要求 web-admin 改为 snake_case
### Requirement: 运输计划 Schema 变更门禁
修改 `app/schemas/pl/**` 或新增 PL 写接口时,提交前 SHALL 运行 `python backend/scripts/check_pl_json_aliases.py`;脚本失败 SHALL 阻塞合并。
Schema 覆盖范围 SHALL 至少包括:
| 路径 | 说明 |
|------|------|
| `app/schemas/pl/__init__.py` | 承运商、车辆、司机 |
| `app/schemas/pl/plan.py` | 计划与产品明细 |
| `app/schemas/pl/transport.py` | 运输、安排、审批 |
| `app/schemas/pl/freight.py` | 运费结算 |
| `app/schemas/pl/inventory.py` | 库存、证件提醒 |
参考实现:`app/schemas/db/weighing.py`(地磅模块 alias 模式)。