# API接口设计

<cite>
**本文档引用的文件**
- [backend/app/main.py](file://backend/app/main.py)
- [backend/app/api/auth.py](file://backend/app/api/auth.py)
- [backend/app/api/queries.py](file://backend/app/api/queries.py)
- [backend/app/api/citations.py](file://backend/app/api/citations.py)
- [backend/app/api/reports.py](file://backend/app/api/reports.py)
- [backend/app/api/deps.py](file://backend/app/api/deps.py)
- [backend/app/schemas/auth.py](file://backend/app/schemas/auth.py)
- [backend/app/schemas/query.py](file://backend/app/schemas/query.py)
- [backend/app/schemas/citation.py](file://backend/app/schemas/citation.py)
- [backend/app/services/auth.py](file://backend/app/services/auth.py)
- [backend/app/services/query.py](file://backend/app/services/query.py)
- [backend/app/services/citation.py](file://backend/app/services/citation.py)
- [backend/app/database.py](file://backend/app/database.py)
- [backend/app/config.py](file://backend/app/config.py)
- [backend/app/models/user.py](file://backend/app/models/user.py)
- [backend/app/models/citation_record.py](file://backend/app/models/citation_record.py)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件为 GEO 平台的 API 接口设计规范文档，面向后端与前端开发者，系统性阐述 RESTful API 设计原则、路由组织结构、版本控制策略、请求/响应数据模型（Pydantic）、错误处理机制、认证与授权、API 文档与测试策略，以及使用示例与最佳实践。

## 项目结构
后端采用 FastAPI 框架，按功能模块划分 API 路由与服务层，数据库使用 SQLAlchemy 异步引擎，配置通过 Pydantic Settings 管理。主要模块如下：
- 应用入口与路由注册：backend/app/main.py
- 认证与用户：backend/app/api/auth.py、backend/app/services/auth.py、backend/app/schemas/auth.py
- 查询词管理：backend/app/api/queries.py、backend/app/services/query.py、backend/app/schemas/query.py
- 引用数据与统计：backend/app/api/citations.py、backend/app/services/citation.py、backend/app/schemas/citation.py
- 报告导出：backend/app/api/reports.py
- 依赖注入与鉴权：backend/app/api/deps.py
- 数据库与模型：backend/app/database.py、backend/app/models/*.py
- 配置：backend/app/config.py

```mermaid
graph TB
A["应用入口<br/>backend/app/main.py"] --> B["认证路由<br/>backend/app/api/auth.py"]
A --> C["查询路由<br/>backend/app/api/queries.py"]
A --> D["引用路由<br/>backend/app/api/citations.py"]
A --> E["报告路由<br/>backend/app/api/reports.py"]
B --> F["认证服务<br/>backend/app/services/auth.py"]
C --> G["查询服务<br/>backend/app/services/query.py"]
D --> H["引用服务<br/>backend/app/services/citation.py"]
F --> I["数据库会话<br/>backend/app/database.py"]
G --> I
H --> I
I --> J["配置<br/>backend/app/config.py"]
I --> K["用户模型<br/>backend/app/models/user.py"]
I --> L["引用记录模型<br/>backend/app/models/citation_record.py"]
```

图表来源
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
- [backend/app/api/citations.py:1-78](file://backend/app/api/citations.py#L1-L78)
- [backend/app/api/reports.py:1-47](file://backend/app/api/reports.py#L1-L47)
- [backend/app/services/auth.py:1-69](file://backend/app/services/auth.py#L1-L69)
- [backend/app/services/query.py:1-130](file://backend/app/services/query.py#L1-L130)
- [backend/app/services/citation.py:1-269](file://backend/app/services/citation.py#L1-L269)
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
- [backend/app/models/user.py:1-41](file://backend/app/models/user.py#L1-L41)
- [backend/app/models/citation_record.py:1-42](file://backend/app/models/citation_record.py#L1-L42)

章节来源
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)

## 核心组件
- 版本控制与路由前缀
  - 应用统一使用 /api/v1 前缀，并按资源划分子路由：
    - /api/v1/auth：认证相关
    - /api/v1/queries：查询词 CRUD
    - /api/v1/citations：引用数据列表、统计、立即执行
    - /api/v1/reports：报告导出
- CORS 配置
  - 允许本地前端 localhost:3000 进行跨域访问，支持所有方法与头
- 健康检查
  - GET /health 返回 {"status":"ok"}

章节来源
- [backend/app/main.py:24-48](file://backend/app/main.py#L24-L48)

## 架构总览
下图展示从客户端到 API、服务层与数据库的调用链路，以及认证中间件如何注入当前用户上下文。

```mermaid
sequenceDiagram
participant Client as "客户端"
participant API as "FastAPI 应用"
participant Router as "API 路由"
participant Deps as "依赖注入/鉴权"
participant Service as "业务服务"
participant DB as "数据库"
Client->>API : "HTTP 请求"
API->>Router : "路由分发"
Router->>Deps : "获取当前用户(鉴权)"
Deps-->>Router : "User 对象"
Router->>Service : "调用业务逻辑"
Service->>DB : "SQLAlchemy 异步查询/写入"
DB-->>Service : "结果集"
Service-->>Router : "领域对象/聚合"
Router-->>Client : "JSON 响应/状态码"
```

图表来源
- [backend/app/main.py:38-42](file://backend/app/main.py#L38-L42)
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/queries.py:15-85](file://backend/app/api/queries.py#L15-L85)
- [backend/app/api/citations.py:25-77](file://backend/app/api/citations.py#L25-L77)
- [backend/app/api/reports.py:16-46](file://backend/app/api/reports.py#L16-L46)
- [backend/app/services/auth.py:37-69](file://backend/app/services/auth.py#L37-L69)
- [backend/app/services/query.py:12-130](file://backend/app/services/query.py#L12-L130)
- [backend/app/services/citation.py:24-269](file://backend/app/services/citation.py#L24-L269)
- [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29)

## 详细组件分析

### 认证与用户管理
- 路由与方法
  - POST /api/v1/auth/register：注册，返回用户信息，状态码 201
  - POST /api/v1/auth/login：登录，返回访问令牌与用户信息，状态码 200；失败 401
  - GET /api/v1/auth/me：获取当前用户信息，需携带 Bearer Token
- 鉴权流程
  - 使用 OAuth2PasswordBearer 指向 /api/v1/auth/login
  - 依赖 get_current_user 校验 JWT 并加载用户
- 数据模型
  - 注册输入：邮箱、密码、姓名（最小长度约束）
  - 登录输入：邮箱、密码
  - 用户输出：id、email、name、plan、max_queries、is_active、created_at
  - 令牌输出：access_token、token_type、user
- 错误处理
  - 注册重复邮箱：400
  - 登录失败：401（带 WWW-Authenticate 头）
  - 鉴权失败：401（凭据无效）

```mermaid
sequenceDiagram
participant Client as "客户端"
participant Auth as "认证路由"
participant Deps as "get_current_user"
participant Svc as "认证服务"
participant DB as "数据库"
Client->>Auth : "POST /api/v1/auth/login"
Auth->>Svc : "authenticate_user(email,password)"
Svc->>DB : "查询用户并校验密码"
DB-->>Svc : "用户对象"
Svc-->>Auth : "用户或None"
Auth-->>Client : "200 OK + {access_token,user}"
Note over Client,Auth : "后续请求携带 Authorization : Bearer <token>"
```

图表来源
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
- [backend/app/services/auth.py:55-69](file://backend/app/services/auth.py#L55-L69)

章节来源
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
- [backend/app/schemas/auth.py:7-34](file://backend/app/schemas/auth.py#L7-L34)
- [backend/app/services/auth.py:37-69](file://backend/app/services/auth.py#L37-L69)

### 查询词管理
- 路由与方法
  - GET /api/v1/queries：分页列出查询词，支持 skip/limit
  - POST /api/v1/queries：创建查询词，状态码 201
  - GET /api/v1/queries/{query_id}：获取单个查询词
  - PUT /api/v1/queries/{query_id}：更新查询词
  - DELETE /api/v1/queries/{query_id}：删除查询词，状态码 204
- 输入/输出模型
  - 创建输入：keyword、target_brand、brand_aliases、platforms、frequency（默认 weekly）
  - 更新输入：可选字段 keyword、target_brand、brand_aliases、platforms、frequency、status
  - 输出：完整查询词详情（含频率、状态、时间戳等）
- 权限与限制
  - 用户最大查询数受用户计划限制，超过抛出 403
  - 所有操作均进行所有权校验（user_id 匹配）
- 错误处理
  - 未找到：404
  - 超出配额：403
  - 参数校验失败：422（Pydantic 自动）

```mermaid
flowchart TD
Start(["创建查询"]) --> CheckCount["检查用户当前查询数"]
CheckCount --> CountOK{"是否小于等于 max_queries?"}
CountOK -- 否 --> Forbidden["返回 403: 超出配额"]
CountOK -- 是 --> CalcNext["根据频率计算 next_query_at"]
CalcNext --> Create["持久化 Query 记录"]
Create --> Return201["返回 201 + QueryResponse"]
```

图表来源
- [backend/app/api/queries.py:26-39](file://backend/app/api/queries.py#L26-L39)
- [backend/app/services/query.py:45-81](file://backend/app/services/query.py#L45-L81)

章节来源
- [backend/app/api/queries.py:15-85](file://backend/app/api/queries.py#L15-L85)
- [backend/app/schemas/query.py:11-94](file://backend/app/schemas/query.py#L11-L94)
- [backend/app/services/query.py:12-130](file://backend/app/services/query.py#L12-L130)

### 引用数据与统计
- 路由与方法
  - GET /api/v1/citations：分页列出引用记录，支持 query_id、platform、日期范围过滤
  - GET /api/v1/citations/stats：统计摘要（总查询、总引用、引用率、平台分布、趋势）
  - POST /api/v1/queries/{query_id}/run-now：立即触发查询任务，状态码 202
- 数据模型
  - 引用记录输出：id、query_id、platform、cited、citation_position、citation_text、competitor_brands、queried_at
  - 统计输出：总览指标、平台维度统计、周粒度趋势
  - 立即执行输出：task_id、status、message
- 安全与权限
  - 列表与统计均进行所有权校验；当提供 query_id 时额外校验查询归属
  - 导出 CSV 亦进行所有权校验
- 错误处理
  - 未找到查询：404
  - 查询非激活或无平台配置：400/404
  - 未授权/无效凭据：401

```mermaid
sequenceDiagram
participant Client as "客户端"
participant Cit as "引用路由"
participant Svc as "引用服务"
participant DB as "数据库"
Client->>Cit : "GET /api/v1/citations/stats?query_id={id}"
Cit->>Svc : "get_citation_stats(user_id, query_id?)"
Svc->>DB : "聚合统计(条件含 user_id 与可选 query_id)"
DB-->>Svc : "统计结果"
Svc-->>Cit : "CitationStatsResponse"
Cit-->>Client : "200 OK"
```

图表来源
- [backend/app/api/citations.py:49-56](file://backend/app/api/citations.py#L49-L56)
- [backend/app/services/citation.py:76-201](file://backend/app/services/citation.py#L76-L201)

章节来源
- [backend/app/api/citations.py:25-77](file://backend/app/api/citations.py#L25-L77)
- [backend/app/schemas/citation.py:7-50](file://backend/app/schemas/citation.py#L7-L50)
- [backend/app/services/citation.py:24-269](file://backend/app/services/citation.py#L24-L269)

### 报告导出
- 路由与方法
  - GET /api/v1/reports/export/csv：导出 CSV 文件流，支持文件名与 Content-Disposition 头
- 错误处理
  - 不支持的格式：400
  - 查询不存在：404
  - 流式响应：StreamingResponse，媒体类型 text/csv

章节来源
- [backend/app/api/reports.py:16-46](file://backend/app/api/reports.py#L16-L46)
- [backend/app/services/citation.py:237-269](file://backend/app/services/citation.py#L237-L269)

### 立即执行查询（独立路由）
- 路由与方法
  - POST /api/v1/queries/{query_id}/run-now：加入查询任务队列，状态码 202
- 行为
  - 校验查询归属与状态，为每个平台创建一个 QueryTask
- 错误处理
  - 查询不存在或非激活：404
  - 无平台配置：400

章节来源
- [backend/app/api/citations.py:59-77](file://backend/app/api/citations.py#L59-L77)
- [backend/app/services/citation.py:204-234](file://backend/app/services/citation.py#L204-L234)

## 依赖分析
- 组件耦合
  - API 层仅依赖依赖注入与服务层，不直接操作数据库
  - 服务层通过异步 Session 访问数据库，避免阻塞
  - 配置集中于 Settings，便于环境隔离
- 关键依赖关系
  - OAuth2PasswordBearer 指向登录端点，确保令牌一致
  - 所有受保护路由均通过 get_current_user 注入 User 上下文
  - 业务服务内部进行所有权校验，保证数据隔离

```mermaid
graph LR
API_Auth["API 认证"] --> Deps["依赖注入"]
API_Queries["API 查询"] --> Deps
API_Citations["API 引用"] --> Deps
API_Reports["API 报告"] --> Deps
Deps --> Svc_Auth["认证服务"]
Deps --> Svc_Query["查询服务"]
Deps --> Svc_Citation["引用服务"]
Svc_Auth --> DB["数据库"]
Svc_Query --> DB
Svc_Citation --> DB
```

图表来源
- [backend/app/api/deps.py:13-43](file://backend/app/api/deps.py#L13-L43)
- [backend/app/services/auth.py:37-69](file://backend/app/services/auth.py#L37-L69)
- [backend/app/services/query.py:12-130](file://backend/app/services/query.py#L12-L130)
- [backend/app/services/citation.py:24-269](file://backend/app/services/citation.py#L24-L269)
- [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29)

## 性能考虑
- 分页与过滤
  - 列表接口支持 skip/limit，建议前端按需请求，避免一次性拉取大量数据
  - 引用列表支持多维过滤（query_id、platform、日期），建议在高频查询场景下配合索引
- 数据库索引
  - 引用记录表对 query_id、queried_at、platform 建有索引，有利于统计与分页
- 异步 I/O
  - 使用 SQLAlchemy 异步引擎与异步 Session，减少阻塞
- 缓存与队列
  - 立即执行查询通过任务队列异步处理，避免长耗时请求阻塞 API

## 故障排查指南
- 401 未授权
  - 检查 Authorization 头是否为 Bearer Token
  - 检查 token 是否过期或签名错误
- 403 禁止访问
  - 用户配额不足或权限不足（如创建查询超限）
- 404 未找到
  - 资源 ID 不存在或不属于当前用户
- 400 参数错误
  - 平台列表为空或包含非法值；导出格式不支持
- 500 服务器错误
  - 检查数据库连接与服务日志

章节来源
- [backend/app/api/auth.py:26-30](file://backend/app/api/auth.py#L26-L30)
- [backend/app/api/queries.py:34-38](file://backend/app/api/queries.py#L34-L38)
- [backend/app/api/citations.py:67-71](file://backend/app/api/citations.py#L67-L71)
- [backend/app/api/reports.py:23-27](file://backend/app/api/reports.py#L23-L27)
- [backend/app/api/deps.py:20-41](file://backend/app/api/deps.py#L20-L41)

## 结论
本规范以 RESTful 设计为核心，结合 FastAPI 的类型安全与自动文档能力，构建了清晰的路由分层、严格的认证授权与完善的错误处理机制。通过 Pydantic 模型与 SQLAlchemy 异步 ORM，实现了高一致性与高性能的数据访问。建议在生产环境中进一步完善速率限制、审计日志与监控告警体系。

## 附录

### RESTful 设计原则与路由组织
- URL 命名规范
  - 使用名词复数形式表示资源集合，如 /queries、/citations
  - 资源标识符使用路径参数，如 /queries/{query_id}
- HTTP 方法使用
  - GET：读取资源列表或单个资源
  - POST：创建资源
  - PUT：更新资源
  - DELETE：删除资源
- 状态码标准
  - 200：成功获取或更新
  - 201：创建成功
  - 202：异步任务已接受
  - 204：删除成功且无内容
  - 400：参数或业务错误
  - 401：未授权
  - 403：禁止访问
  - 404：资源不存在
  - 422：数据校验失败（Pydantic）
  - 500：服务器内部错误

### API 版本控制与路由前缀
- 版本控制策略
  - 采用 URL 前缀 /api/v1 进行版本隔离，便于未来演进
- 路由前缀管理
  - 认证：/api/v1/auth
  - 查询词：/api/v1/queries
  - 引用数据：/api/v1/citations
  - 报告：/api/v1/reports

章节来源
- [backend/app/main.py:38-42](file://backend/app/main.py#L38-L42)

### 请求与响应数据模型（Pydantic）
- 认证
  - 注册输入：邮箱、密码、姓名（最小长度约束）
  - 登录输入：邮箱、密码
  - 用户输出：id、email、name、plan、max_queries、is_active、created_at
  - 令牌输出：access_token、token_type、user
- 查询词
  - 创建输入：keyword、target_brand、brand_aliases、platforms、frequency（默认 weekly）
  - 更新输入：可选字段 keyword、target_brand、brand_aliases、platforms、frequency、status
  - 输出：完整查询词详情（含频率、状态、时间戳等）
- 引用数据
  - 列表项：id、query_id、platform、cited、citation_position、citation_text、competitor_brands、queried_at
  - 统计：总览指标、平台维度统计、周粒度趋势
  - 立即执行：task_id、status、message

章节来源
- [backend/app/schemas/auth.py:7-34](file://backend/app/schemas/auth.py#L7-L34)
- [backend/app/schemas/query.py:11-94](file://backend/app/schemas/query.py#L11-L94)
- [backend/app/schemas/citation.py:7-50](file://backend/app/schemas/citation.py#L7-L50)

### 错误处理机制
- 异常类型分类
  - 业务异常：如配额不足、查询不存在、平台非法
  - 凭据异常：JWT 解析失败、用户不存在
- 错误响应格式
  - 统一为 JSON：{ "detail": "错误描述" }
  - 未授权携带 WWW-Authenticate 头
- HTTP 状态码映射
  - 400：参数/业务错误
  - 401：凭据无效
  - 403：权限不足
  - 404：资源不存在
  - 422：数据校验失败
  - 500：服务器错误

章节来源
- [backend/app/api/auth.py:17-18](file://backend/app/api/auth.py#L17-L18)
- [backend/app/api/queries.py:34-38](file://backend/app/api/queries.py#L34-L38)
- [backend/app/api/citations.py:67-71](file://backend/app/api/citations.py#L67-L71)
- [backend/app/api/reports.py:23-27](file://backend/app/api/reports.py#L23-L27)
- [backend/app/api/deps.py:20-41](file://backend/app/api/deps.py#L20-L41)

### 认证与授权实现
- 认证方式
  - JWT Bearer Token，密钥与过期时间由配置管理
- 授权策略
  - 所有受保护路由通过 get_current_user 注入当前用户
  - 业务层进行所有权校验（user_id 匹配），防止越权访问
- 最佳实践
  - 生产环境更换默认密钥与设置合理过期时间
  - 前端统一在请求头携带 Authorization: Bearer <token>

章节来源
- [backend/app/api/deps.py:13-43](file://backend/app/api/deps.py#L13-L43)
- [backend/app/services/auth.py:24-34](file://backend/app/services/auth.py#L24-L34)
- [backend/app/config.py:9-10](file://backend/app/config.py#L9-L10)

### API 文档生成与测试策略
- 文档生成
  - FastAPI 自动生成 OpenAPI 规范与交互式文档，默认启用
- 测试策略
  - 单元测试：针对服务层函数（如 get_citations、create_query）进行异步测试
  - 集成测试：通过 API 路由层发起请求，验证鉴权、权限与错误码
  - 建议使用 pytest 异步运行器与测试数据库

### API 使用示例与最佳实践
- 示例
  - 登录获取令牌后，在后续请求头中添加 Authorization: Bearer <token>
  - 创建查询时指定 platforms 与 frequency，注意平台集合的有效性
  - 导出报告时仅支持 csv 格式
- 最佳实践
  - 前端分页请求 skip/limit，避免一次性加载过多数据
  - 在高频查询场景下利用过滤参数缩小数据集
  - 对外暴露的路由保持幂等性与明确的状态码语义