# API规则

> **入口**: [_index.md](_index.md)

---

## 1. 路由规范

### 1.1 路由格式

```
/api/{版本}/{模块}/{资源}/{动作}

示例:
/api/v1/products                    # 商品列表
/api/v1/products/:id                # 商品详情
/api/v1/products/:id/publish        # 商品刊登
/api/v1/orders                      # 订单列表
/api/v1/orders/:id/fulfill          # 订单履约
```

### 1.2 HTTP方法映射

| 方法 | 用途 | 示例 |
|------|------|------|
| GET | 查询 | `GET /api/v1/products` |
| POST | 创建 | `POST /api/v1/products` |
| PUT | 全量更新 | `PUT /api/v1/products/:id` |
| PATCH | 部分更新 | `PATCH /api/v1/products/:id` |
| DELETE | 删除 | `DELETE /api/v1/products/:id` |

---

## 2. 权限校验

### 2.1 中间件使用

```typescript
// ✅ 正确：路由层使用 authorize() 中间件
router.get('/api/v1/products', authorize('product:read'), ProductController.list);
router.post('/api/v1/products', authorize('product:create'), ProductController.create);
router.put('/api/v1/products/:id', authorize('product:update'), ProductController.update);

// ❌ 错误：Controller 中硬编码角色
async create(ctx: Context) {
  if (ctx.state.user.role === 'ADMIN') { // 禁止
    // ...
  }
}
```

### 2.2 权限格式

```
{模块}:{动作}

示例:
product:read      # 查看商品
product:create    # 创建商品
product:update    # 更新商品
product:delete    # 删除商品
order:fulfill     # 订单履约
finance:approve   # 财务审批
```

### 2.3 数据隔离

非 ADMIN 用户查询必须根据 `parentId` 层级过滤：

```typescript
// ✅ 正确：Service层处理数据隔离
async listProducts(ctx: Context) {
  const { tenantId, role, parentId } = ctx.state.user;
  
  const query = db('cf_product').where('tenant_id', tenantId);
  
  if (role !== 'ADMIN') {
    query.where('parent_id', parentId);
  }
  
  return query;
}
```

---

## 3. 响应格式

### 3.1 成功响应

```typescript
// 单条数据
{
  "success": true,
  "data": { ... }
}

// 列表数据
{
  "success": true,
  "data": [...],
  "pagination": {
    "total": 100,
    "page": 1,
    "pageSize": 20
  }
}
```

### 3.2 错误响应

```typescript
{
  "success": false,
  "error": {
    "code": "PRODUCT_NOT_FOUND",
    "message": "商品不存在",
    "details": {}
  }
}
```

### 3.3 错误码规范

| 前缀 | 类别 | 示例 |
|------|------|------|
| `VAL_` | 参数校验 | `VAL_INVALID_PARAM` |
| `AUTH_` | 认证授权 | `AUTH_UNAUTHORIZED` |
| `BIZ_` | 业务逻辑 | `BIZ_PRODUCT_NOT_FOUND` |
| `SYS_` | 系统错误 | `SYS_DATABASE_ERROR` |

---

## 4. 请求参数

### 4.1 分页参数

```typescript
// 请求
GET /api/v1/products?page=1&pageSize=20

// 响应
{
  "data": [...],
  "pagination": {
    "total": 100,
    "page": 1,
    "pageSize": 20,
    "totalPages": 5
  }
}
```

### 4.2 排序参数

```typescript
// 请求
GET /api/v1/products?sortBy=created_at&sortOrder=desc

// 默认排序
sortBy: 'created_at'
sortOrder: 'desc'
```

### 4.3 过滤参数

```typescript
// 请求
GET /api/v1/products?platform=SHOPIFY&status=ACTIVE

// 多值过滤
GET /api/v1/products?platform=SHOPIFY,AMAZON
```

---

## 5. 追踪字段

所有API请求必须携带五元组：

```typescript
// 请求头
{
  'X-Tenant-Id': 'xxx',
  'X-Shop-Id': 'xxx',
  'X-Task-Id': 'xxx',      // 可选
  'X-Trace-Id': 'xxx',
  'X-Business-Type': 'TOC'
}

// 或请求体
{
  "tenantId": "xxx",
  "shopId": "xxx",
  "taskId": "xxx",
  "traceId": "xxx",
  "businessType": "TOC"
}
```

---

## 6. 速率限制

| 端点类型 | 限制 | 窗口 |
|---------|------|------|
| 查询接口 | 100次 | 1分钟 |
| 写入接口 | 30次 | 1分钟 |
| 批量接口 | 10次 | 1分钟 |

---

*最后更新: 2026-03-22*
