# GEO 平台 - 后端服务

基于 Python FastAPI 构建的异步后端服务，提供 RESTful API 供前端调用。

## 环境要求

- Python 3.11+
- PostgreSQL 15
- Redis 7
- Node.js 18+（如需运行 Playwright 浏览器自动化）

## 安装步骤

### 1. 创建虚拟环境

```bash
cd backend
python3 -m venv venv
source venv/bin/activate  # macOS/Linux
# 或
venv\Scripts\activate     # Windows
```

### 2. 安装依赖

```bash
pip install -r requirements.txt
```

### 3. 安装 Playwright 浏览器

```bash
playwright install chromium
```

### 4. 配置环境变量

复制项目根目录的 `.env.example` 为 `.env`，并根据需要修改配置：

```bash
cp ../.env.example ../.env
```

### 5. 初始化数据库

```bash
alembic upgrade head
```

## 运行命令

### 开发模式（热重载）

```bash
uvicorn app.main:app --reload --port 8000
```

### 生产模式

```bash
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
```

启动后访问：
- API 文档（Swagger UI）：http://localhost:8000/docs
- ReDoc 文档：http://localhost:8000/redoc
- 健康检查：http://localhost:8000/health

## API 端点清单

### 认证模块 `/api/v1/auth`

| 方法 | 端点 | 说明 | 认证要求 |
|------|------|------|---------|
| POST | `/register` | 用户注册 | 无需认证 |
| POST | `/login` | 用户登录，返回 JWT Token | 无需认证 |
| GET | `/me` | 获取当前登录用户信息 | Bearer Token |
| POST | `/forgot-password` | 发送密码重置链接 | 无需认证 |
| POST | `/reset-password` | 使用令牌重置密码 | 无需认证 |
| POST | `/verify-email` | 邮箱验证码验证 | 无需认证 |
| POST | `/resend-verification` | 重新发送邮箱验证码 | 无需认证 |
| PUT | `/change-password` | 修改当前用户密码 | Bearer Token |
| PUT | `/profile` | 更新用户资料 | Bearer Token |

### 查询词管理 `/api/v1/queries`

| 方法 | 端点 | 说明 | 认证要求 |
|------|------|------|---------|
| GET | `/` | 获取查询词列表（分页） | Bearer Token |
| POST | `/` | 创建新查询词 | Bearer Token |
| GET | `/{query_id}` | 获取单个查询词详情 | Bearer Token |
| PUT | `/{query_id}` | 更新查询词 | Bearer Token |
| DELETE | `/{query_id}` | 删除查询词 | Bearer Token |
| POST | `/{query_id}/run-now` | 立即执行查询任务 | Bearer Token |

### 引用数据 `/api/v1/citations`

| 方法 | 端点 | 说明 | 认证要求 |
|------|------|------|---------|
| GET | `/` | 获取引用记录列表（支持筛选） | Bearer Token |
| GET | `/stats` | 获取引用统计分析 | Bearer Token |

查询参数说明（`GET /`）：
- `query_id`: 按查询词筛选（UUID）
- `platform`: 按平台名称筛选
- `start_date`: 起始日期（ISO 8601）
- `end_date`: 结束日期（ISO 8601）
- `skip`: 分页偏移量，默认 0
- `limit`: 每页数量，默认 20，最大 100

### 报告导出 `/api/v1/reports`

| 方法 | 端点 | 说明 | 认证要求 |
|------|------|------|---------|
| GET | `/export/csv` | 导出查询词的引用数据为 CSV | Bearer Token |

查询参数：
- `query_id`（必填）: 要导出的查询词 ID
- `format`: 导出格式，目前仅支持 `csv`

### 系统接口

| 方法 | 端点 | 说明 |
|------|------|------|
| GET | `/health` | 服务健康检查 |

## 数据库迁移

本项目使用 Alembic 管理数据库迁移。

```bash
# 执行所有迁移（升级到最新版本）
alembic upgrade head

# 回滚一次迁移
alembic downgrade -1

# 创建新的自动迁移（修改模型后执行）
alembic revision --autogenerate -m "描述本次变更"

# 查看当前版本
alembic current

# 查看迁移历史
alembic history
```

## 项目结构

```
backend/
├── alembic/
│   ├── versions/           # 迁移脚本
│   ├── env.py              # Alembic 环境配置
│   └── script.py.mako      # 迁移脚本模板
├── app/
│   ├── api/                # API 路由层
│   │   ├── auth.py         # 认证接口（注册/登录/密码/资料）
│   │   ├── queries.py      # 查询词 CRUD 与立即执行
│   │   ├── citations.py    # 引用数据查询与统计
│   │   ├── reports.py      # CSV 报告导出
│   │   └── deps.py         # FastAPI 依赖注入（当前用户、数据库会话）
│   ├── middleware/
│   │   ├── rate_limit.py   # 基于内存的限流中间件
│   │   └── logging_middleware.py
│   ├── models/             # SQLAlchemy ORM 模型
│   │   ├── user.py         # 用户模型
│   │   ├── query.py        # 查询词模型
│   │   ├── citation_record.py
│   │   ├── query_task.py   # 查询任务执行记录
│   │   └── subscription.py # 订阅套餐模型
│   ├── schemas/            # Pydantic v2 数据校验模型
│   │   ├── auth.py
│   │   ├── citation.py
│   │   └── query.py
│   ├── services/           # 业务逻辑层
│   │   ├── auth.py         # 认证服务（密码哈希、JWT）
│   │   ├── query.py        # 查询词业务逻辑
│   │   └── citation.py     # 引用数据与报告服务
│   ├── workers/            # 后台任务与引擎
│   │   ├── scheduler.py    # APScheduler 定时调度器
│   │   ├── citation_engine.py
│   │   └── platforms/      # AI 平台适配器
│   │       ├── base.py
│   │       ├── wenxin.py   # 文心一言
│   │       ├── kimi.py     # Kimi
│   │       ├── tongyi.py   # 通义千问
│   │       ├── doubao.py   # 豆包
│   │       ├── qingyan.py  # 清言
│   │       ├── tiangong.py # 天工
│   │       ├── xinghuo.py  # 讯飞星火
│   │       └── search_engine.py
│   ├── config.py           # Pydantic Settings 配置管理
│   ├── database.py         # 异步数据库引擎与 Session
│   └── main.py             # FastAPI 应用入口与生命周期管理
├── requirements.txt
├── Dockerfile
└── README.md
```

## 限流策略

| 接口 | 限制 | 时间窗口 |
|------|------|---------|
| 登录/注册/忘记密码 | 5 次 | 60 秒 |
| 立即查询（run-now） | 10 次 | 3600 秒 |
| 全局接口 | 100 次 | 60 秒 |

## 测试说明

测试文件位于项目根目录的 `tests/` 文件夹中。

```bash
# 安装测试依赖（已包含在 requirements.txt 中）
pip install pytest pytest-asyncio aiosqlite

# 运行所有测试
cd ..  # 切换到项目根目录
pytest

# 运行指定测试文件
pytest tests/test_auth.py
pytest tests/test_queries.py
pytest tests/test_citations.py
pytest tests/test_citation_engine.py
pytest tests/test_scheduler.py
pytest tests/test_business_flow.py

# 显示详细输出
pytest -v

# 显示测试覆盖率（需安装 pytest-cov）
pytest --cov=backend/app --cov-report=html
```

## 主要依赖版本

| 包名 | 版本要求 |
|------|---------|
| fastapi | >=0.109.0 |
| uvicorn | [standard] |
| sqlalchemy | >=2.0 |
| asyncpg | - |
| alembic | - |
| pydantic | >=2.0 |
| pydantic-settings | - |
| python-jose | [cryptography] |
| passlib | [bcrypt] |
| bcrypt | <4.0 |
| redis | - |
| apscheduler | >=3.10 |
| playwright | >=1.40 |
| httpx | - |
| fpdf2 | >=2.7 |
| pytest | >=8.0 |
| pytest-asyncio | >=0.23.0 |
