---
description: "代码写完后逐条过一遍。这些是 AI 容易忽略的常见问题"
---

# FastAPI 事后检查清单

代码写完后逐条过一遍。这些是 AI 容易忽略的常见问题。

## 异步陷阱
- [ ] `async def` 路由里有没有阻塞调用？（`time.sleep`、同步 HTTP 请求、同步文件读写 → 会卡死事件循环）
- [ ] 如果不确定是否阻塞，是否改用了普通 `def`？（FastAPI 自动放线程池）
- [ ] 必须在 async 路由里调同步库时，是否用了 `await run_in_threadpool(sync_func, ...)`？
- [ ] CPU 密集型任务（计算、转码）是否交给了 ProcessPoolExecutor 或任务队列，而不是线程池？
- [ ] 线程池默认只有 40 个线程，高并发场景是否够用？

## 依赖注入
- [ ] 数据库级校验（资源是否存在、权限检查）是否放在了 `Depends()` 里，而不是写在 router 函数体内？
- [ ] 多个端点共用的校验逻辑是否抽成了依赖，而不是复制粘贴？
- [ ] 依赖函数是否优先用了 `async def`？（非 async 的依赖也会被扔进线程池）
- [ ] 链式依赖是否利用了 FastAPI 的缓存机制？（同一请求内相同依赖只执行一次）

## 安全与文档
- [ ] 非公开 API 是否隐藏了文档？（生产环境设置 `openapi_url=None`）
- [ ] 有没有在 Pydantic 模型里暴露了不该返回的字段？（如 password_hash）
- [ ] 是否充分利用了 Pydantic 的校验能力？（Field 约束、正则、枚举，而不是在 service 里手写 if）

## 数据库
- [ ] SQLModel/SQLAlchemy 模型的命名是否统一？（小写蛇形、单数形式，如 `post` 不是 `posts`）
- [ ] datetime 字段是否用 `_at` 后缀，date 字段是否用 `_date` 后缀？
- [ ] 数据库迁移文件（Alembic）是否有描述性名称？（如 `2024-08-24_add_post_tags.py`）
- [ ] 复杂查询是否交给了 SQL 而不是在 Python 里循环处理？
- [ ] 嵌套对象的响应是否在 SQL 里用 `json_build_object` 聚合，而不是 Python 里手动拼？

## 响应
- [ ] 所有接口是否都用了 `Response[T]` 泛型包装？
- [ ] `response_model` 是否正确设置？（注意：FastAPI 会用 response_model 再创建一次 Pydantic 对象做校验）
- [ ] 是否设置了合适的 `status_code`？（POST 创建用 201，DELETE 用 204 等）

## 错误处理
- [ ] 是否定义了模块专属异常类？（`raise PostNotFound()` 比 `raise HTTPException(404, "xxx")` 更清晰）
- [ ] Pydantic 里的 `ValueError` 会自动变成 ValidationError 返回给用户，错误信息是否友好？
