Files
fdesk/docs/superpowers/specs/2026-06-02-public-stock-api-design.md
T
mzl92 35d98c16e9 feat: 新增备货单公共 API 接口(PI 号/VIN 号列表)
- 新增 ApiKeyAuth 中间件(hash_equals 防时序攻击)
- 新增 PublicApiController(piList/vinList 两个只读接口)
- 仅返回已审批通过(approval_status=2)的数据,支持分页和模糊搜索
- LIKE 通配符已转义,异常信息不暴露内部细节
- 附对接文档 docs/public-stock-api.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 17:44:53 +08:00

108 lines
2.5 KiB
Markdown

# Public Stock Order API Design
## Goal
Provide two read-only public APIs for internal systems to query approved stock order PI numbers and VIN numbers, with API Key authentication.
## Data Model
- `stock_orders.approval_status = 2` means approved
- `stock_orders.pi_no` — PI number (string)
- `stock_order_items.vin` — VIN/chassis number (string)
- `stock_order_items.model_snapshot` — car model name (plain string)
- `stock_order_items.order_id` → `stock_orders.id`
## Authentication
New middleware `ApiKeyAuth`:
- Read `Fdesk-Api-Key` header
- Compare against key stored in `.env` (`API_KEY`) or `config/app.php`
- Reject with 401 on mismatch or missing key
- Bypass both `AuthCheck` (JWT) and `BasicData` middleware
## Endpoints
### A. PI Number List
```
GET /common/public/pi/list
Headers: Fdesk-Api-Key: <key>
Query: page, page_size, pi_no (optional filter)
```
Response:
```json
{
"status": "success",
"code": 200,
"data": {
"total": 150,
"per_page": 20,
"current_page": 1,
"data": [
{
"pi_no": "PI20250601001",
"vins": ["LSVAU2A39N2123456", "LSVAU2A39N2123457"],
"model_names": ["Model Y", "Model 3"]
}
]
}
}
```
Logic:
1. Query `stock_orders` where `approval_status = 2` and `pi_no IS NOT NULL` and `pi_no != ''`
2. Optional filter by `pi_no` (LIKE match)
3. Paginate
4. For each order, eager-load `items` → collect `vin` and `model_snapshot`
5. Return aggregated result
### B. VIN Number List
```
GET /common/public/vin/list
Headers: Fdesk-Api-Key: <key>
Query: page, page_size, vin (optional filter)
```
Response:
```json
{
"status": "success",
"code": 200,
"data": {
"total": 500,
"per_page": 20,
"current_page": 1,
"data": [
{
"vin": "LSVAU2A39N2123456",
"model_name": "Model Y"
}
]
}
}
```
Logic:
1. Query `stock_order_items` via `stock_orders` where `approval_status = 2`
2. Optional filter by `vin` (LIKE match)
3. Paginate
4. Return `vin` + `model_snapshot` per item
## File Changes
| Action | File | Description |
|--------|------|-------------|
| New | `app/middleware/ApiKeyAuth.php` | API Key auth middleware |
| New | `app/common/controller/PublicApiController.php` | Two endpoints |
| Modify | `config/route.php` | Add `/common/public/*` route group with ApiKeyAuth |
## Constraints
- Read-only, no write operations
- Only `approval_status = 2` records
- Pagination required (default page_size = 20)
- No JWT / BasicData middleware for these routes