Files
social-app/docs/runtime/runtime-route.md
T

13 KiB
Raw Blame History

Runtime API Routes

本文档记录所有 HTTP API 端点。修改路由时必须同步更新此文档。

格式说明

  • Request/Response 使用 JSON 格式
  • 错误响应使用 RFC 7807 application/problem+json
  • 所有端点前缀: /api/v1

Auth

POST /auth/verifications

创建验证码(注册发起)。

Request:

{
  "username": "string (3-30 chars)",
  "email": "string (email)",
  "password": "string (min 6 chars)",
  "redirect_to": "string? (optional)",
  "invite_code": "string? (8 chars, 排除易混淆字符 0/1/I/L/O)"
}

Response: 202 Accepted

{
  "email": "user@example.com"
}

邀请码说明:

  • 可选字段,不填则注册不受影响
  • 格式:8 位字母数字组合,排除易混淆字符 (0, 1, I, L, O)
  • 注册时传入有效邀请码会建立邀请关系并增加邀请码使用次数
  • 无效邀请码(不存在/已禁用/已过期/已达上限)不会阻断注册成功

Errors:

  • 422: 请求参数无效
  • 429: 请求过于频繁

POST /auth/verifications/resend

重发验证码。

Request:

{
  "email": "string (email)"
}

Response: 204 No Content

Errors:

  • 422: 请求参数无效
  • 429: 请求过于频繁

POST /auth/verifications/verify

验证码校验。

Request:

{
  "email": "string (email)",
  "token": "string (6 digits)"
}

Response: 200 OK

{
  "access_token": "string",
  "refresh_token": "string",
  "expires_in": 3600,
  "token_type": "bearer",
  "user": {
    "id": "string",
    "email": "string"
  }
}

Errors:

  • 401: 验证码无效或已过期
  • 422: 请求参数无效
  • 429: 请求过于频繁

POST /auth/sessions

登录(创建会话)。

Request:

{
  "email": "string (email)",
  "password": "string (min 6 chars)"
}

Response: 200 OK

{
  "access_token": "string",
  "refresh_token": "string",
  "expires_in": 3600,
  "token_type": "bearer",
  "user": {
    "id": "string",
    "email": "string"
  }
}

Errors:

  • 401: 邮箱或密码错误
  • 422: 请求参数无效
  • 429: 请求过于频繁

POST /auth/sessions/refresh

刷新 Token。

Request:

{
  "refresh_token": "string"
}

Response: 200 OK

{
  "access_token": "string",
  "refresh_token": "string",
  "expires_in": 3600,
  "token_type": "bearer",
  "user": {
    "id": "string",
    "email": "string"
  }
}

Errors:

  • 401: 无效的 refresh token
  • 422: 请求参数无效

DELETE /auth/sessions

登出(删除会话)。

Request:

{
  "refresh_token": "string"
}

Response: 204 No Content

Errors:

  • 422: 请求参数无效

POST /auth/password-reset

发送密码重置验证码。

Request:

{
  "email": "string (email)",
  "redirect_to": "string? (optional)"
}

Response: 204 No Content

Errors:

  • 422: 请求参数无效
  • 429: 请求过于频繁

POST /auth/password-reset/confirm

验证 recovery 验证码并完成改密。

Request:

{
  "email": "string (email)",
  "token": "string (6 digits)",
  "new_password": "string (min 6 chars)"
}

Response: 204 No Content

Errors:

  • 401: 验证码无效或已过期
  • 422: 请求参数无效
  • 429: 请求过于频繁

GET /auth/users

按邮箱查询用户(需要认证)。

Query Parameters:

  • email: string (required)

Response: 200 OK

{
  "id": "string",
  "email": "string",
  "created_at": "string (ISO 8601)",
  "email_confirmed_at": "string? (ISO 8601)"
}

Errors:

  • 403: 无权限访问
  • 404: 用户不存在
  • 422: 请求参数无效

Schedule Items

POST /schedule-items

创建日历事项(需要认证)。

Request:

{
  "title": "string (1-255 chars, required)",
  "description": "string? (max 2000 chars)",
  "start_at": "string (ISO 8601 datetime, required)",
  "end_at": "string? (ISO 8601 datetime)",
  "timezone": "string? (default: UTC)",
  "metadata": {
    "color": "#FF6B6B",
    "location": "会议室A",
    "notes": "记得带身份证",
    "attachments": [],
    "version": 1
  }
}

Response: 201 Created

{
  "id": "uuid",
  "title": "string",
  "description": "string?",
  "start_at": "string",
  "end_at": "string?",
  "timezone": "string",
  "metadata": {},
  "status": "active",
  "source_type": "manual",
  "created_at": "string",
  "updated_at": "string"
}

Errors:

  • 400: end_at 早于 start_at
  • 401: 未认证
  • 503: 服务不可用

GET /schedule-items

按时间范围查询日历事项列表(需要认证)。

Query Parameters:

  • start_at: ISO 8601 date/datetime(查询范围起始)
  • end_at: ISO 8601 date/datetime(查询范围结束)

Response: 200 OK

[
  {
    "id": "uuid",
    "title": "string",
    "start_at": "string",
    "end_at": "string?",
    "timezone": "string",
    "status": "active"
  }
]

Errors:

  • 400: end_at 早于 start_at
  • 401: 未认证

GET /schedule-items/{id}

获取单个日历事项详情(需要认证)。

Response: 200 OK

Errors:

  • 401: 未认证
  • 404: 事项不存在

PATCH /schedule-items/{id}

更新日历事项(需要认证)。

Request: 支持 title/description/start_at/end_at/timezone/metadata/status 部分更新

Response: 200 OK

Errors:

  • 401: 未认证
  • 404: 事项不存在

DELETE /schedule-items/{id}

删除日历事项(软删除,需要认证)。

Response: 204 No Content

Errors:

  • 401: 未认证
  • 404: 事项不存在

POST /schedule-items/{id}/share

分享日历事项给他人(需要认证)。

通过邮箱邀请其他用户,被邀请人将收到待办消息邀请。

Request:

{
  "email": "string (required, email of user to share with)",
  "permission_view": "boolean (default: true)",
  "permission_edit": "boolean (default: false)",
  "permission_invite": "boolean (default: false)"
}

Permission 位说明:

权限 说明
view 1 查看事项详情
invite 2 邀请其他人订阅此事项
edit 4 修改事项内容、管理订阅

可组合使用,如 view+edit = 5view+invite+edit = 7。

Response: 200 OK

{
  "message": "Invitation sent to user@example.com"
}

Errors:

  • 401: 未认证
  • 403: 非日历所有者无权分享
  • 404: 日历事项不存在或用户不存在

Inbox Messages

Inbox Messages

GET /inbox/messages

获取当前用户的待办消息列表(需要认证)。

Query Parameters:

  • status: string (optional) - 过滤状态:pending/accepted/rejected/dismissed

Response: 200 OK

[
  {
    "id": "uuid",
    "recipient_id": "uuid",
    "sender_id": "uuid?",
    "message_type": "calendar",
    "schedule_item_id": "uuid?",
    "content": "string?",
    "is_read": false,
    "status": "pending",
    "created_at": "2024-01-01T00:00:00Z"
  }
]

Errors:

  • 401: 未认证

POST /inbox/messages/{id}/accept

接受邀请(需要认证)。

接受日历邀请时,会为当前用户创建订阅关系。

Request:

{
  "permission_view": "boolean (default: true)",
  "permission_edit": "boolean (default: false)",
  "permission_invite": "boolean (default: false)"
}

Response: 204 No Content

Errors:

  • 401: 未认证
  • 404: 消息不存在
  • 400: 消息不是待处理状态或不是日历类型邀请

POST /inbox/messages/{id}/dismiss

忽略邀请(需要认证)。

Response: 204 No Content

Errors:

  • 401: 未认证
  • 404: 消息不存在
  • 400: 消息不是待处理状态

Users

GET /users/me

获取当前用户信息(需要认证)。

Response: 200 OK

{
  "id": "string",
  "username": "string",
  "avatar_url": "string?",
  "bio": "string?"
}

Errors:

  • 401: 未认证

PATCH /users/me

更新当前用户信息(需要认证)。

Request:

{
  "username": "string? (3-30 chars)",
  "avatar_url": "string? (URL)",
  "bio": "string? (max 200 chars)"
}

Response: 200 OK

{
  "id": "string",
  "username": "string",
  "avatar_url": "string?",
  "bio": "string?"
}

Errors:

  • 401: 未认证
  • 422: 请求参数无效

POST /users/search

搜索用户(需要认证)。

支持两种查询模式:

  • 用户名查询:模糊匹配,返回最多 20 个结果
  • 邮箱查询:精确匹配,返回 0 或 1 个结果

查询类型自动识别:包含 @ 符号视为邮箱查询。

Request:

{
  "query": "string (1-100 chars)"
}

Response: 200 OK

[
  {
    "id": "string",
    "username": "string",
    "avatar_url": "string?",
    "bio": "string?"
  }
]

Errors:

  • 401: 未认证
  • 503: Auth 服务不可用(仅邮箱查询)
  • 422: 请求参数无效

Friends

POST /friends/requests

发送好友请求(需要认证)。

Request:

{
  "target_user_id": "string (uuid)",
  "content": "string? (max 500 chars)"
}

Response: 201 Created

{
  "id": "uuid",
  "from_user_id": "uuid",
  "to_user_id": "uuid",
  "content": "string?",
  "status": "pending",
  "created_at": "string (ISO 8601)",
  "updated_at": "string (ISO 8601)"
}

Errors:

  • 400: 不能添加自己为好友
  • 401: 未认证
  • 404: 目标用户不存在
  • 409: 已是好友或请求已存在
  • 422: 请求参数无效

GET /friends/requests/inbox

获取收到的好友请求(需要认证)。

Response: 200 OK

[
  {
    "id": "uuid",
    "from_user_id": "uuid",
    "to_user_id": "uuid",
    "content": "string?",
    "status": "pending",
    "created_at": "string (ISO 8601)",
    "updated_at": "string (ISO 8601)"
  }
]

Errors:

  • 401: 未认证

GET /friends/requests/outgoing

获取发出的好友请求(需要认证)。

Response: 200 OK

[
  {
    "id": "uuid",
    "from_user_id": "uuid",
    "to_user_id": "uuid",
    "content": "string?",
    "status": "pending",
    "created_at": "string (ISO 8601)",
    "updated_at": "string (ISO 8601)"
  }
]

Errors:

  • 401: 未认证

POST /friends/requests/{id}/accept

接受好友请求(需要认证)。

Response: 200 OK

{
  "id": "uuid",
  "from_user_id": "uuid",
  "to_user_id": "uuid",
  "content": "string?",
  "status": "accepted",
  "created_at": "string (ISO 8601)",
  "updated_at": "string (ISO 8601)"
}

Errors:

  • 401: 未认证
  • 404: 请求不存在
  • 409: 请求已被处理

POST /friends/requests/{id}/decline

拒绝好友请求(需要认证)。

Response: 200 OK

{
  "id": "uuid",
  "from_user_id": "uuid",
  "to_user_id": "uuid",
  "content": "string?",
  "status": "declined",
  "created_at": "string (ISO 8601)",
  "updated_at": "string (ISO 8601)"
}

Errors:

  • 401: 未认证
  • 404: 请求不存在
  • 409: 请求已被处理

DELETE /friends/requests/{id}

取消发出的好友请求(需要认证)。

Response: 204 No Content

Errors:

  • 401: 未认证
  • 404: 请求不存在

GET /friends

获取好友列表(需要认证)。

Response: 200 OK

[
  {
    "id": "uuid",
    "friend_id": "uuid",
    "username": "string",
    "avatar_url": "string?",
    "bio": "string?",
    "created_at": "string (ISO 8601)"
  }
]

Errors:

  • 401: 未认证

DELETE /friends/{id}

删除好友(需要认证)。

Response: 204 No Content

Errors:

  • 401: 未认证
  • 404: 好友关系不存在

Agent Chat

POST /agent-chats

运行 Agent 对话(需要认证)。

Request:

{
  "message": "string (1-8000 chars)",
  "session_id": "string? (UUID)"
}

Response: 200 OK

{
  "session_id": "string (UUID)",
  "output": "string",
  "events": [
    {
      "type": "string",
      "run_id": "string?",
      "message_id": "string?",
      "delta": "string?",
      "tool_name": "string?",
      "result": "string?",
      "output": "string?",
      "error": "string?"
    }
  ]
}

Errors:

  • 401: 未认证
  • 422: 请求参数无效

Infra

GET /infra/health

检查基础设施健康状态。

Response: 200 OK

{
  "status": "healthy" | "unhealthy",
  "services": {
    "redis": {
      "status": "healthy" | "unhealthy",
      "latency_ms": 0
    }
  }
}

GET /health

检查服务健康状态。

Response: 200 OK

{
  "status": "ok"
}

Error Response Format (RFC 7807)

所有错误响应使用 application/problem+json 格式:

{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "验证码无效或已过期",
  "instance": "/api/v1/auth/verifications/verify"
}

前端应优先读取 detail 字段显示给用户。