# API 对接检查清单

> 每次新增或修改后端 API 后，逐项检查以下内容，避免前后端对接时出现数据丢失、页面崩溃或静默失败。

## 1. 字段名一致性

- [ ] 后端返回的 JSON 字段名与前端 TypeScript 接口（`services/api/*.ts`）中的属性名完全一致
- [ ] 特别注意 `id` vs `xxxId`、`name` vs `xxxName` 等命名差异
- [ ] 前端 `normalizeXxx` 或过滤函数中检查了哪些字段（如 `!org?.id` 会过滤掉 id 为 undefined 的记录）

## 2. 响应结构一致性

- [ ] 确认 apiClient 响应拦截器是否已解包 `data` 层（本项目已解包，前端拿到的直接是 `data` 内的内容）
- [ ] 列表接口：确认返回 `{ items: [...] }` 还是直接返回数组，与前端解构方式一致
- [ ] 前端代码中没有 `res.data`（apiClient 已解包）或 `res.items`（返回的是裸数组时）的错误用法

## 3. 状态转换 API

- [ ] 所有改变资源状态的 POST 端点（publish、start-xxx、complete 等）返回**完整资源对象**
- [ ] 不要只返回 `{ id, status }` — 前端会用返回值直接替换本地状态

## 4. 空数据行为

- [ ] 列表/概览端点在无数据时返回空结构（`{ items: [], total: 0 }`），不抛异常
- [ ] "查找当前活跃 xxx" 类端点在找不到时返回 `null`，不抛 404
- [ ] 单资源查询（`findById`）找不到时抛 404 是正确的

## 5. 验证方法

```bash
# 1. 获取 token
TOKEN=$(curl -s -X POST http://localhost:3001/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"itadmin","password":"Admin@2024"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['accessToken'])")

# 2. 调用 API 并检查返回字段
curl -s -H "Authorization: Bearer $TOKEN" \
  "http://localhost:3001/api/v1/your-endpoint" \
  | python3 -m json.tool

# 3. 与前端类型定义交叉检查
# 打开 frontend/src/services/api/xxx.ts，找到对应函数的返回类型
# 逐字段比对 JSON 输出和 TypeScript 接口
```

## 6. 常见陷阱

| 陷阱 | 后果 | 预防 |
|------|------|------|
| 后端返回 `organizationId`，前端期望 `id` | 前端 normalize 过滤掉所有数据，UI 为空 | 返回前对齐前端接口 |
| 状态转换只返回 `{ id, status }` | 前端状态被覆盖，name/date 等变 undefined | 返回完整对象 |
| 后端返回 `{ items: [] }`，前端直接 `.filter()` | `TypeError: xxx.filter is not a function` | 前端加 `res.items \|\| res` 防御 |
| apiClient 已解包 data，前端又写 `res.data` | 拿到 undefined | 不要写 `res.data`，直接用 `res` |
| 列表 API 无数据时抛异常 | 前端 loading 永久或显示错误 | 返回空数组，不抛异常 |
