# RESTful API 全面重构设计

**日期**: 2026-02-26
**状态**: 待实现

## 目标

将后端 HTTP API 改造为完全符合 RESTful 规范，并同步更新前端适配代码。

## 设计原则

1. **资源导向 URL**：使用名词而非动词
2. **HTTP 语义化**：状态通过状态码表达，响应体只包含必要数据
3. **响应格式统一**：成功响应无冗余字段，错误响应使用 RFC 7807
4. **文档同步**：路由变更必须同步更新文档

## URL 重构

### Auth 相关

| 功能 | 当前 URL | 新 URL | HTTP 方法 |
|------|----------|--------|-----------|
| 注册发起 | `/signup/start` | `/verifications` | POST |
| 重发验证码 | `/signup/resend` | `/verifications/resend` | POST |
| 验证码校验 | `/signup/verify` | `/verifications/verify` | POST |
| 登录 | `/login` | `/sessions` | POST |
| 刷新 Token | `/refresh` | `/sessions/refresh` | POST |
| 登出 | `/logout` | `/sessions` | DELETE |
| 按邮箱查用户 | `/users/by-email` | `/users?email=xxx` | GET |

### Profile → Users 统一

| 功能 | 当前 URL | 新 URL | HTTP 方法 |
|------|----------|--------|-----------|
| 获取个人信息 | `/profile/me` | `/users/me` | GET |
| 更新个人信息 | `/profile/me` | `/users/me` | PATCH |
| 按用户名查用户 | `/profile/{username}` | `/users/{username}` | GET |

### Agent Chat

| 功能 | 当前 URL | 新 URL | HTTP 方法 |
|------|----------|--------|-----------|
| 运行对话 | `/agent-chat/run` | `/agent-chats` | POST |

## 响应格式

### 成功响应

| 端点 | 状态码 | 响应体 |
|------|--------|--------|
| `POST /verifications` | 202 | `{email: string}` |
| `POST /verifications/resend` | 204 | 无 |
| `POST /verifications/verify` | 200 | `{access_token, refresh_token, expires_in, token_type, user}` |
| `POST /sessions` | 200 | 同上 |
| `POST /sessions/refresh` | 200 | 同上 |
| `DELETE /sessions` | 204 | 无 |
| `GET /users?email=xxx` | 200 | `{id, email, created_at, email_confirmed_at?}` |
| `GET /users/me` | 200 | `{id, username, avatar_url?, bio?}` |
| `PATCH /users/me` | 200 | 同上 |
| `GET /users/{username}` | 200 | 同上 |
| `POST /agent-chats` | 200 | `{session_id, output, events[]}` |

### 错误响应

保持 RFC 7807 格式（已实现）：

```json
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid verification code",
  "instance": "/api/v1/verifications/verify"
}
```

前端解析优先级：`detail` → `message` → `error` → "请求失败"

## Schema 定义

### 请求 Schema

```python
# verifications
class VerificationCreateRequest(BaseModel):
    username: str = Field(min_length=3, max_length=30)
    email: EmailStr
    password: str = Field(min_length=6)
    redirect_to: str | None = None

class VerificationResendRequest(BaseModel):
    email: EmailStr

class VerificationVerifyRequest(BaseModel):
    email: EmailStr
    token: str = Field(pattern=r"^\d{6}$")

# sessions
class SessionCreateRequest(BaseModel):
    email: EmailStr
    password: str = Field(min_length=6)

class SessionRefreshRequest(BaseModel):
    refresh_token: str = Field(min_length=1)

class SessionDeleteRequest(BaseModel):
    refresh_token: str = Field(min_length=1)

# users
class UserUpdateRequest(BaseModel):
    username: str | None = Field(default=None, min_length=3, max_length=30)
    avatar_url: str | None = None
    bio: str | None = Field(default=None, max_length=200)
```

### 响应 Schema

```python
class VerificationCreateResponse(BaseModel):
    email: EmailStr

class SessionResponse(BaseModel):
    access_token: str
    refresh_token: str
    expires_in: int
    token_type: str
    user: AuthUser

class UserResponse(BaseModel):
    id: str
    username: str
    avatar_url: str | None = None
    bio: str | None = None

class UserByEmailResponse(BaseModel):
    id: str
    email: EmailStr
    created_at: str
    email_confirmed_at: str | None = None
```

## 文件改动清单

### 后端

| 文件 | 改动 |
|------|------|
| `v1/auth/router.py` | URL 重命名，简化响应 |
| `v1/auth/schemas.py` | 重命名/简化模型 |
| `v1/auth/gateway.py` | 适配新 schema |
| `v1/auth/service.py` | 适配新 schema |
| `v1/profile/` → `v1/users/` | 目录重命名 |
| `v1/users/router.py` | URL 更新 |
| `v1/users/schemas.py` | 重命名模型 |
| `v1/agent_chat/router.py` | URL 更新 |
| `v1/router.py` | 更新路由注册 |
| 测试文件 | 同步更新 |

### 前端

| 文件 | 改动 |
|------|------|
| `auth/data/auth_api.dart` | URL 更新 |
| `auth/data/models/auth_response.dart` | 简化 SignupStartResponse，删除 SignupResendResponse |
| `profile/data/profile_api.dart` | 改为 `users/data/users_api.dart` |
| `profile/data/models/profile_response.dart` | 重命名 |
| 相关 cubit/screen | 适配新 API |

### 文档

| 文件 | 改动 |
|------|------|
| `docs/runtime/runtime-route.md` | 新增，记录所有路由 |
| `AGENTS.md` | 添加路由文档同步规则 |

## 风险与缓解

| 风险 | 缓解措施 |
|------|----------|
| 前后端不同步导致功能失效 | 同时修改，一次性提交 |
| 测试覆盖不足 | 先更新测试，确保通过后再改实现 |
| 遗漏某个调用点 | 全局搜索旧 URL 字符串 |

## 验收标准

- [ ] 所有后端测试通过
- [ ] 所有前端测试通过
- [ ] 手动验证注册/登录/登出流程
- [ ] `runtime-route.md` 包含所有端点文档
- [ ] `AGENTS.md` 包含路由同步规则
