openapi: 3.0.3
info:
  title: Pixel Game Server API
  description: 像素游戏服务器完整API接口文档 - 包含用户认证、位置广播、聊天系统、管理员后台等功能模块
  version: 1.2.0
  contact:
    name: API Support
    email: support@example.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: http://localhost:3000
    description: 开发环境

tags:
  - name: app
    description: 应用状态相关接口
  - name: auth
    description: 用户认证相关接口
  - name: location-broadcast
    description: 位置广播系统相关接口
  - name: health
    description: 健康检查相关接口
  - name: chat
    description: 聊天系统相关接口
  - name: zulip-accounts
    description: Zulip账号关联管理相关接口
  - name: admin-database
    description: 管理员数据库管理相关接口
  - name: admin-operation-logs
    description: 管理员操作日志相关接口

paths:
  /:
    get:
      tags:
        - app
      summary: 获取应用状态
      description: 返回应用的基本运行状态信息，用于健康检查和监控
      operationId: getAppStatus
      responses:
        '200':
          description: 应用状态获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AppStatusResponse'
              example:
                service: Pixel Game Server
                version: 1.0.0
                status: running
                timestamp: "2025-12-25T08:00:00.000Z"
                uptime: 3600
                environment: development
                storage_mode: database

  /auth/login:
    post:
      tags:
        - auth
      summary: 用户登录
      description: 支持用户名、邮箱或手机号登录
      operationId: login
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginDto'
            example:
              identifier: testuser
              password: password123
      responses:
        '200':
          description: 登录成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
              example:
                success: true
                data:
                  user:
                    id: "1"
                    username: testuser
                    nickname: 测试用户
                    email: test@example.com
                    phone: "+8613800138000"
                    avatar_url: https://example.com/avatar.jpg
                    role: 1
                    created_at: "2025-12-17T10:00:00.000Z"
                  access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                  refresh_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                  is_new_user: false
                  message: 登录成功
                message: 登录成功
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: 用户名或密码错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/register:
    post:
      tags:
        - auth
      summary: 用户注册
      description: 创建新用户账户。如果提供邮箱，需要先调用发送验证码接口获取验证码。发送验证码接口会自动检查邮箱是否已被注册，避免向已存在邮箱发送验证码。
      operationId: register
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterDto'
            example:
              username: newuser
              password: password123
              nickname: 新用户
              email: newuser@example.com
              phone: "+8613800138001"
      responses:
        '201':
          description: 注册成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterResponse'
        '400':
          description: 请求参数错误或验证码错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                validation_error:
                  summary: 参数验证错误
                  value:
                    success: false
                    message: "密码必须包含字母和数字，长度8-128字符"
                    error_code: "REGISTER_FAILED"
                verification_code_error:
                  summary: 验证码错误
                  value:
                    success: false
                    message: "验证码不存在或已过期"
                    error_code: "REGISTER_FAILED"
        '409':
          description: 资源冲突 - 用户名、邮箱或手机号已存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                username_exists:
                  summary: 用户名已存在
                  value:
                    success: false
                    message: "用户名已存在"
                    error_code: "REGISTER_FAILED"
                email_exists:
                  summary: 邮箱已存在
                  value:
                    success: false
                    message: "邮箱已存在"
                    error_code: "REGISTER_FAILED"
                phone_exists:
                  summary: 手机号已存在
                  value:
                    success: false
                    message: "手机号已存在"
                    error_code: "REGISTER_FAILED"

  /auth/github:
    post:
      tags:
        - auth
      summary: GitHub OAuth登录
      description: 使用GitHub账户登录或注册
      operationId: githubOAuth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GitHubOAuthDto'
            example:
              github_id: "12345678"
              username: octocat
              nickname: The Octocat
              email: octocat@github.com
              avatar_url: https://github.com/images/error/octocat_happy.gif
      responses:
        '200':
          description: GitHub登录成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitHubOAuthResponse'
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: GitHub认证失败
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/forgot-password:
    post:
      tags:
        - auth
      summary: 发送密码重置验证码
      description: 向用户邮箱或手机发送密码重置验证码
      operationId: forgotPassword
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ForgotPasswordDto'
            example:
              identifier: test@example.com
      responses:
        '200':
          description: 验证码发送成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForgotPasswordResponse'
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: 用户不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/reset-password:
    post:
      tags:
        - auth
      summary: 重置密码
      description: 使用验证码重置用户密码
      operationId: resetPassword
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResetPasswordDto'
            example:
              identifier: test@example.com
              verification_code: "123456"
              new_password: newpassword123
      responses:
        '200':
          description: 密码重置成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommonResponse'
        '400':
          description: 请求参数错误或验证码无效
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: 用户不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/change-password:
    put:
      tags:
        - auth
      summary: 修改密码
      description: 用户修改自己的密码（需要提供旧密码）
      operationId: changePassword
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangePasswordDto'
            example:
              user_id: "1"
              old_password: oldpassword123
              new_password: newpassword123
      responses:
        '200':
          description: 密码修改成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommonResponse'
        '400':
          description: 请求参数错误或旧密码不正确
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: 用户不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/send-email-verification:
    post:
      tags:
        - auth
      summary: 发送邮箱验证码
      description: 向指定邮箱发送验证码。如果邮箱已被注册，将返回冲突错误。
      operationId: sendEmailVerification
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendEmailVerificationDto'
            example:
              email: test@example.com
      responses:
        '200':
          description: 验证码发送成功（真实发送模式）
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailVerificationResponse'
        '206':
          description: 测试模式：验证码已生成但未真实发送
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestModeEmailVerificationResponse'
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: 邮箱已被注册
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                message: "邮箱已被注册，请使用其他邮箱或直接登录"
                error_code: "SEND_EMAIL_VERIFICATION_FAILED"
        '429':
          description: 发送频率过高
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThrottleErrorResponse'

  /auth/verify-email:
    post:
      tags:
        - auth
      summary: 验证邮箱验证码
      description: 使用验证码验证邮箱
      operationId: verifyEmail
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmailVerificationDto'
            example:
              email: test@example.com
              verification_code: "123456"
      responses:
        '200':
          description: 邮箱验证成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommonResponse'
        '400':
          description: 验证码错误或已过期
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/resend-email-verification:
    post:
      tags:
        - auth
      summary: 重新发送邮箱验证码
      description: 重新向指定邮箱发送验证码
      operationId: resendEmailVerification
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendEmailVerificationDto'
            example:
              email: test@example.com
      responses:
        '200':
          description: 验证码重新发送成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailVerificationResponse'
        '206':
          description: 测试模式：验证码已生成但未真实发送
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestModeEmailVerificationResponse'
        '400':
          description: 邮箱已验证或用户不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: 发送频率过高
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThrottleErrorResponse'

  /auth/verification-code-login:
    post:
      tags:
        - auth
      summary: 验证码登录
      description: 使用邮箱或手机号和验证码进行登录，无需密码
      operationId: verificationCodeLogin
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerificationCodeLoginDto'
            example:
              identifier: test@example.com
              verification_code: "123456"
      responses:
        '200':
          description: 验证码登录成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: 验证码错误或已过期
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationCodeLoginErrorResponse'
        '404':
          description: 用户不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /auth/send-login-verification-code:
    post:
      tags:
        - auth
      summary: 发送登录验证码
      description: 向用户邮箱或手机发送登录验证码。邮件内容使用专门的登录验证码模板，标题为"登录验证码"，内容说明用于登录验证而非密码重置。
      operationId: sendLoginVerificationCode
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendLoginVerificationCodeDto'
            example:
              identifier: test@example.com
      responses:
        '200':
          description: 验证码发送成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailVerificationResponse'
        '206':
          description: 测试模式：验证码已生成但未真实发送
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestModeEmailVerificationResponse'
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: 用户不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendLoginCodeErrorResponse'
        '429':
          description: 发送频率过高
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThrottleErrorResponse'

  /auth/debug-verification-code:
    post:
      tags:
        - auth
      summary: 调试验证码信息
      description: 获取验证码的详细调试信息（仅开发环境）
      operationId: debugVerificationCode
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendEmailVerificationDto'
            example:
              email: test@example.com
      responses:
        '200':
          description: 调试信息获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DebugVerificationCodeResponse'

  /auth/debug-clear-throttle:
    post:
      tags:
        - auth
      summary: 清除限流记录
      description: 清除所有限流记录（仅开发环境使用）
      operationId: clearThrottle
      responses:
        '200':
          description: 限流记录已清除
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommonResponse'

  /auth/refresh-token:
    post:
      tags:
        - auth
      summary: 刷新访问令牌
      description: 使用有效的刷新令牌生成新的访问令牌，实现无感知的令牌续期
      operationId: refreshToken
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshTokenDto'
            example:
              refresh_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
      responses:
        '200':
          description: 令牌刷新成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RefreshTokenResponse'
        '400':
          description: 请求参数错误
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: 刷新令牌无效或已过期
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: 用户不存在或已被禁用
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: 刷新请求过于频繁
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThrottleErrorResponse'

  # ==================== 位置广播系统接口 ====================

  /location-broadcast/sessions:
    post:
      tags:
        - location-broadcast
      summary: 创建新游戏会话
      description: 创建一个新的位置广播会话，支持自定义配置
      operationId: createSession
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSessionDto'
            example:
              sessionId: session_12345
              name: 测试会话
              description: 这是一个测试会话
              maxUsers: 100
              isPublic: true
      responses:
        '201':
          description: 会话创建成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  session:
                    type: object
                  message:
                    type: string
                    example: 会话创建成功
        '400':
          description: 请求参数错误
        '409':
          description: 会话ID已存在
    get:
      tags:
        - location-broadcast
      summary: 查询会话列表
      description: 根据条件查询游戏会话列表，支持分页和过滤
      operationId: querySessions
      security:
        - bearerAuth: []
      parameters:
        - name: status
          in: query
          required: false
          description: 会话状态
          schema:
            type: string
        - name: limit
          in: query
          required: false
          description: 分页大小
          schema:
            type: integer
            default: 20
        - name: offset
          in: query
          required: false
          description: 分页偏移
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: 查询成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  sessions:
                    type: array
                    items:
                      type: object
                  total:
                    type: number
                    example: 10
                  message:
                    type: string
                    example: 查询成功

  /location-broadcast/sessions/{sessionId}:
    get:
      tags:
        - location-broadcast
      summary: 获取会话详情
      description: 获取指定会话的详细信息，包括用户列表和位置信息
      operationId: getSessionDetail
      security:
        - bearerAuth: []
      parameters:
        - name: sessionId
          in: path
          required: true
          description: 会话ID
          schema:
            type: string
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  session:
                    type: object
                  users:
                    type: array
                    items:
                      type: object
                  message:
                    type: string
                    example: 获取成功
        '404':
          description: 会话不存在

  /location-broadcast/positions:
    get:
      tags:
        - location-broadcast
      summary: 查询位置信息
      description: 根据条件查询用户位置信息，支持范围查询和地图过滤
      operationId: queryPositions
      security:
        - bearerAuth: []
      parameters:
        - name: mapId
          in: query
          required: false
          description: 地图ID
          schema:
            type: string
        - name: sessionId
          in: query
          required: false
          description: 会话ID
          schema:
            type: string
        - name: limit
          in: query
          required: false
          description: 分页大小
          schema:
            type: integer
            default: 20
      responses:
        '200':
          description: 查询成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  positions:
                    type: array
                    items:
                      type: object
                  total:
                    type: number
                    example: 5
                  message:
                    type: string
                    example: 查询成功

  /location-broadcast/positions/stats:
    get:
      tags:
        - location-broadcast
      summary: 获取位置统计信息
      description: 获取系统位置数据的统计信息，包括用户分布和活跃度
      operationId: getPositionStats
      security:
        - bearerAuth: []
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  stats:
                    type: object
                  message:
                    type: string
                    example: 获取成功

  /location-broadcast/users/{userId}/data:
    delete:
      tags:
        - location-broadcast
      summary: 清理用户数据
      description: 清理指定用户的位置数据和会话信息
      operationId: cleanupUserData
      security:
        - bearerAuth: []
      parameters:
        - name: userId
          in: path
          required: true
          description: 用户ID
          schema:
            type: string
      responses:
        '200':
          description: 清理成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: 清理成功

  # ==================== 健康检查接口 ====================

  /health:
    get:
      tags:
        - health
      summary: 基础健康检查
      description: 检查位置广播服务的基本可用性
      operationId: healthCheck
      responses:
        '200':
          description: 服务正常
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  timestamp:
                    type: number
                    example: 1641234567890
                  service:
                    type: string
                    example: location-broadcast
                  version:
                    type: string
                    example: 1.0.0
        '503':
          description: 服务不可用

  /health/detailed:
    get:
      tags:
        - health
      summary: 详细健康报告
      description: 获取位置广播系统各组件的详细健康状态
      operationId: detailedHealth
      responses:
        '200':
          description: 健康报告获取成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
                  timestamp:
                    type: number
                    example: 1641234567890
                  service:
                    type: string
                    example: location-broadcast
                  components:
                    type: object
                    properties:
                      redis:
                        type: object
                      database:
                        type: object
                      core_services:
                        type: object
                  metrics:
                    type: object

  /health/ready:
    get:
      tags:
        - health
      summary: 就绪检查
      description: 检查位置广播服务是否准备好接收请求
      operationId: readinessCheck
      responses:
        '200':
          description: 服务已就绪
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ready
                  timestamp:
                    type: number
                    example: 1641234567890
                  checks:
                    type: object

  /health/live:
    get:
      tags:
        - health
      summary: 存活检查
      description: 检查位置广播服务是否仍在运行
      operationId: livenessCheck
      responses:
        '200':
          description: 服务存活
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: alive
                  timestamp:
                    type: number
                    example: 1641234567890
                  uptime:
                    type: number
                    example: 3600000

  /health/metrics:
    get:
      tags:
        - health
      summary: 性能指标
      description: 获取位置广播系统的性能指标和资源使用情况
      operationId: getMetrics
      responses:
        '200':
          description: 指标获取成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  timestamp:
                    type: number
                    example: 1641234567890
                  system:
                    type: object
                  application:
                    type: object
                  performance:
                    type: object

  # ==================== 聊天系统接口 ====================

  /chat/send:
    post:
      tags:
        - chat
      summary: 发送聊天消息
      description: 通过 REST API 发送聊天消息到 Zulip。注意：推荐使用 WebSocket 接口以获得更好的实时性
      operationId: sendMessage
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendChatMessageDto'
      responses:
        '200':
          description: 消息发送成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatMessageResponseDto'
        '400':
          description: 请求参数错误
        '401':
          description: 未授权访问
        '500':
          description: 服务器内部错误

  /chat/history:
    get:
      tags:
        - chat
      summary: 获取聊天历史记录
      description: 获取指定地图或全局的聊天历史记录
      operationId: getChatHistory
      security:
        - bearerAuth: []
      parameters:
        - name: mapId
          in: query
          required: false
          description: 地图ID，不指定则获取全局消息
          schema:
            type: string
            example: whale_port
        - name: limit
          in: query
          required: false
          description: 消息数量限制
          schema:
            type: integer
            example: 50
        - name: offset
          in: query
          required: false
          description: 偏移量（分页用）
          schema:
            type: integer
            example: 0
      responses:
        '200':
          description: 获取聊天历史成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatHistoryResponseDto'
        '401':
          description: 未授权访问
        '500':
          description: 服务器内部错误

  /chat/status:
    get:
      tags:
        - chat
      summary: 获取聊天系统状态
      description: 获取 WebSocket 连接状态、Zulip 集成状态等系统信息
      operationId: getSystemStatus
      responses:
        '200':
          description: 获取系统状态成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemStatusResponseDto'
        '500':
          description: 服务器内部错误

  /chat/websocket/info:
    get:
      tags:
        - chat
      summary: 获取 WebSocket 连接信息
      description: 获取 WebSocket 连接的详细信息，包括连接地址、协议等
      operationId: getWebSocketInfo
      responses:
        '200':
          description: 获取连接信息成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  websocketUrl:
                    type: string
                    example: ws://localhost:3000/game
                    description: WebSocket 连接地址
                  namespace:
                    type: string
                    example: /game
                    description: WebSocket 命名空间
                  supportedEvents:
                    type: array
                    items:
                      type: string
                    example: ['login', 'chat', 'position_update']
                    description: 支持的事件类型
                  authRequired:
                    type: boolean
                    example: true
                    description: 是否需要认证
                  documentation:
                    type: string
                    example: https://docs.example.com/websocket
                    description: 文档链接

  # ==================== Zulip账号关联管理接口 ====================

  /zulip-accounts:
    post:
      tags:
        - zulip-accounts
      summary: 创建Zulip账号关联
      description: 为游戏用户创建与Zulip账号的关联关系
      operationId: createZulipAccount
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateZulipAccountDto'
      responses:
        '201':
          description: 创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZulipAccountResponseDto'
        '400':
          description: 请求参数错误
        '409':
          description: 关联已存在
    get:
      tags:
        - zulip-accounts
      summary: 查询Zulip账号关联列表
      description: 根据条件查询Zulip账号关联列表
      operationId: findManyZulipAccounts
      security:
        - bearerAuth: []
      parameters:
        - name: gameUserId
          in: query
          required: false
          description: 游戏用户ID
          schema:
            type: string
            example: '12345'
        - name: zulipUserId
          in: query
          required: false
          description: Zulip用户ID
          schema:
            type: integer
            example: 67890
        - name: zulipEmail
          in: query
          required: false
          description: Zulip邮箱地址
          schema:
            type: string
            example: user@example.com
        - name: status
          in: query
          required: false
          description: 账号状态
          schema:
            type: string
            enum: [active, inactive, suspended, error]
        - name: includeGameUser
          in: query
          required: false
          description: 是否包含游戏用户信息
          schema:
            type: boolean
            example: false
      responses:
        '200':
          description: 查询成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZulipAccountListResponseDto'

  /zulip-accounts/{id}:
    get:
      tags:
        - zulip-accounts
      summary: 根据ID获取Zulip账号关联
      description: 根据关联记录ID获取详细信息
      operationId: findZulipAccountById
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 关联记录ID
          schema:
            type: string
            example: '1'
        - name: includeGameUser
          in: query
          required: false
          description: 是否包含游戏用户信息
          schema:
            type: boolean
            example: false
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZulipAccountResponseDto'
        '404':
          description: 记录不存在
    put:
      tags:
        - zulip-accounts
      summary: 更新Zulip账号关联
      description: 根据ID更新Zulip账号关联信息
      operationId: updateZulipAccount
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 关联记录ID
          schema:
            type: string
            example: '1'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateZulipAccountDto'
      responses:
        '200':
          description: 更新成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZulipAccountResponseDto'
        '404':
          description: 记录不存在
    delete:
      tags:
        - zulip-accounts
      summary: 删除Zulip账号关联
      description: 根据ID删除Zulip账号关联记录
      operationId: deleteZulipAccount
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 关联记录ID
          schema:
            type: string
            example: '1'
      responses:
        '200':
          description: 删除成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: 删除成功
        '404':
          description: 记录不存在

  /zulip-accounts/game-user/{gameUserId}:
    get:
      tags:
        - zulip-accounts
      summary: 根据游戏用户ID获取Zulip账号关联
      description: 根据游戏用户ID获取关联的Zulip账号信息
      operationId: findZulipAccountByGameUserId
      security:
        - bearerAuth: []
      parameters:
        - name: gameUserId
          in: path
          required: true
          description: 游戏用户ID
          schema:
            type: string
            example: '12345'
        - name: includeGameUser
          in: query
          required: false
          description: 是否包含游戏用户信息
          schema:
            type: boolean
            example: false
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZulipAccountResponseDto'
        '404':
          description: 关联不存在
    put:
      tags:
        - zulip-accounts
      summary: 根据游戏用户ID更新关联
      description: 根据游戏用户ID更新Zulip账号关联信息
      operationId: updateZulipAccountByGameUserId
      security:
        - bearerAuth: []
      parameters:
        - name: gameUserId
          in: path
          required: true
          description: 游戏用户ID
          schema:
            type: string
            example: '12345'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateZulipAccountDto'
      responses:
        '200':
          description: 更新成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZulipAccountResponseDto'
        '404':
          description: 关联不存在
    delete:
      tags:
        - zulip-accounts
      summary: 根据游戏用户ID删除关联
      description: 根据游戏用户ID删除Zulip账号关联记录
      operationId: deleteZulipAccountByGameUserId
      security:
        - bearerAuth: []
      parameters:
        - name: gameUserId
          in: path
          required: true
          description: 游戏用户ID
          schema:
            type: string
            example: '12345'
      responses:
        '200':
          description: 删除成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: 删除成功
        '404':
          description: 关联不存在

  /zulip-accounts/management/statistics:
    get:
      tags:
        - zulip-accounts
      summary: 获取账号状态统计
      description: 获取各种状态的账号数量统计
      operationId: getZulipAccountStatistics
      security:
        - bearerAuth: []
      responses:
        '200':
          description: 获取成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZulipAccountStatsResponseDto'

  /zulip-accounts/management/batch-status:
    put:
      tags:
        - zulip-accounts
      summary: 批量更新账号状态
      description: 批量更新多个账号的状态
      operationId: batchUpdateZulipAccountStatus
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchUpdateStatusDto'
      responses:
        '200':
          description: 更新成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchUpdateResponseDto'

  # ==================== 管理员数据库管理接口 ====================

  /admin/database/users:
    get:
      tags:
        - admin-database
      summary: 获取用户列表
      description: 分页获取用户列表，支持管理员查看所有用户信息
      operationId: getUserList
      security:
        - bearerAuth: []
      parameters:
        - name: limit
          in: query
          required: false
          description: 返回数量（默认20，最大100）
          schema:
            type: integer
            example: 20
        - name: offset
          in: query
          required: false
          description: 偏移量（默认0）
          schema:
            type: integer
            example: 0
      responses:
        '200':
          description: 获取成功
        '401':
          description: 未授权访问
        '403':
          description: 权限不足
    post:
      tags:
        - admin-database
      summary: 创建用户
      description: 创建新用户，需要提供用户名和昵称等基本信息
      operationId: createUser
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminCreateUserDto'
      responses:
        '201':
          description: 创建成功
        '400':
          description: 请求参数错误
        '409':
          description: 用户名或邮箱已存在

  /admin/database/users/{id}:
    get:
      tags:
        - admin-database
      summary: 获取用户详情
      description: 根据用户ID获取详细的用户信息
      operationId: getUserById
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 用户ID
          schema:
            type: string
            example: '1'
      responses:
        '200':
          description: 获取成功
        '404':
          description: 用户不存在
    put:
      tags:
        - admin-database
      summary: 更新用户
      description: 根据用户ID更新用户信息
      operationId: updateUser
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 用户ID
          schema:
            type: string
            example: '1'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminUpdateUserDto'
      responses:
        '200':
          description: 更新成功
        '404':
          description: 用户不存在
    delete:
      tags:
        - admin-database
      summary: 删除用户
      description: 根据用户ID删除用户（软删除）
      operationId: deleteUser
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 用户ID
          schema:
            type: string
            example: '1'
      responses:
        '200':
          description: 删除成功
        '404':
          description: 用户不存在

  /admin/database/users/search:
    get:
      tags:
        - admin-database
      summary: 搜索用户
      description: 根据关键词搜索用户，支持用户名、邮箱、昵称模糊匹配
      operationId: searchUsers
      security:
        - bearerAuth: []
      parameters:
        - name: keyword
          in: query
          required: true
          description: 搜索关键词
          schema:
            type: string
            example: admin
        - name: limit
          in: query
          required: false
          description: 返回数量（默认20，最大50）
          schema:
            type: integer
            example: 20
      responses:
        '200':
          description: 搜索成功

  /admin/database/health:
    get:
      tags:
        - admin-database
      summary: 数据库管理系统健康检查
      description: 检查数据库管理系统的运行状态和连接情况
      operationId: adminDatabaseHealthCheck
      security:
        - bearerAuth: []
      responses:
        '200':
          description: 系统正常

  # ==================== 管理员操作日志接口 ====================

  /admin/operation-logs:
    get:
      tags:
        - admin-operation-logs
      summary: 获取操作日志列表
      description: 分页获取管理员操作日志，支持多种过滤条件
      operationId: getOperationLogs
      security:
        - bearerAuth: []
      parameters:
        - name: limit
          in: query
          required: false
          description: 返回数量（默认50，最大200）
          schema:
            type: integer
            example: 50
        - name: offset
          in: query
          required: false
          description: 偏移量（默认0）
          schema:
            type: integer
            example: 0
        - name: adminUserId
          in: query
          required: false
          description: 管理员用户ID过滤
          schema:
            type: string
            example: '123'
        - name: operationType
          in: query
          required: false
          description: 操作类型过滤
          schema:
            type: string
            example: CREATE
        - name: targetType
          in: query
          required: false
          description: 目标类型过滤
          schema:
            type: string
            example: users
        - name: operationResult
          in: query
          required: false
          description: 操作结果过滤
          schema:
            type: string
            example: SUCCESS
        - name: startDate
          in: query
          required: false
          description: 开始日期（ISO格式）
          schema:
            type: string
            example: '2026-01-01T00:00:00.000Z'
        - name: endDate
          in: query
          required: false
          description: 结束日期（ISO格式）
          schema:
            type: string
            example: '2026-01-08T23:59:59.999Z'
        - name: isSensitive
          in: query
          required: false
          description: 是否敏感操作
          schema:
            type: boolean
            example: true
      responses:
        '200':
          description: 获取成功
        '401':
          description: 未授权访问
        '403':
          description: 权限不足

  /admin/operation-logs/{id}:
    get:
      tags:
        - admin-operation-logs
      summary: 获取操作日志详情
      description: 根据日志ID获取操作日志的详细信息
      operationId: getOperationLogById
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 日志ID
          schema:
            type: string
            example: uuid-123
      responses:
        '200':
          description: 获取成功
        '404':
          description: 日志不存在

  /admin/operation-logs/statistics:
    get:
      tags:
        - admin-operation-logs
      summary: 获取操作统计信息
      description: 获取管理员操作的统计信息，包括操作数量、类型分布等
      operationId: getOperationStatistics
      security:
        - bearerAuth: []
      parameters:
        - name: startDate
          in: query
          required: false
          description: 开始日期（ISO格式）
          schema:
            type: string
            example: '2026-01-01T00:00:00.000Z'
        - name: endDate
          in: query
          required: false
          description: 结束日期（ISO格式）
          schema:
            type: string
            example: '2026-01-08T23:59:59.999Z'
      responses:
        '200':
          description: 获取成功

  /admin/operation-logs/sensitive:
    get:
      tags:
        - admin-operation-logs
      summary: 获取敏感操作日志
      description: 获取标记为敏感的操作日志，用于安全审计
      operationId: getSensitiveOperations
      security:
        - bearerAuth: []
      parameters:
        - name: limit
          in: query
          required: false
          description: 返回数量（默认50，最大200）
          schema:
            type: integer
            example: 50
        - name: offset
          in: query
          required: false
          description: 偏移量（默认0）
          schema:
            type: integer
            example: 0
      responses:
        '200':
          description: 获取成功

  /admin/operation-logs/cleanup:
    delete:
      tags:
        - admin-operation-logs
      summary: 清理过期日志
      description: 清理超过指定天数的操作日志，释放存储空间
      operationId: cleanupExpiredLogs
      security:
        - bearerAuth: []
      parameters:
        - name: daysToKeep
          in: query
          required: false
          description: 保留天数（默认90，最少7，最多365）
          schema:
            type: integer
            example: 90
      responses:
        '200':
          description: 清理成功
        '400':
          description: 参数错误

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    AppStatusResponse:
      type: object
      properties:
        service:
          type: string
          description: 服务名称
          example: Pixel Game Server
        version:
          type: string
          description: 版本号
          example: 1.0.0
        status:
          type: string
          description: 运行状态
          example: running
        timestamp:
          type: string
          format: date-time
          description: 当前时间戳
          example: "2025-12-25T08:00:00.000Z"
        uptime:
          type: integer
          description: 运行时间（秒）
          example: 3600
        environment:
          type: string
          description: 运行环境
          example: development
        storage_mode:
          type: string
          description: 存储模式
          example: database

    LoginDto:
      type: object
      required:
        - identifier
        - password
      properties:
        identifier:
          type: string
          description: 登录标识符，支持用户名、邮箱或手机号
          minLength: 1
          maxLength: 100
          example: testuser
        password:
          type: string
          description: 用户密码
          minLength: 1
          maxLength: 128
          example: password123

    RegisterDto:
      type: object
      required:
        - username
        - password
        - nickname
      properties:
        username:
          type: string
          description: 用户名，只能包含字母、数字和下划线
          minLength: 1
          maxLength: 50
          pattern: '^[a-zA-Z0-9_]+$'
          example: testuser
        password:
          type: string
          description: 密码，必须包含字母和数字，长度8-128字符
          minLength: 8
          maxLength: 128
          pattern: '^(?=.*[a-zA-Z])(?=.*\d)'
          example: password123
        nickname:
          type: string
          description: 用户昵称
          minLength: 1
          maxLength: 50
          example: 测试用户
        email:
          type: string
          format: email
          description: 邮箱地址（可选）
          example: test@example.com
        phone:
          type: string
          description: 手机号码（可选）
          example: "+8613800138000"

    GitHubOAuthDto:
      type: object
      required:
        - github_id
        - username
        - nickname
      properties:
        github_id:
          type: string
          description: GitHub用户ID
          minLength: 1
          maxLength: 100
          example: "12345678"
        username:
          type: string
          description: GitHub用户名
          minLength: 1
          maxLength: 50
          example: octocat
        nickname:
          type: string
          description: GitHub显示名称
          minLength: 1
          maxLength: 50
          example: The Octocat
        email:
          type: string
          format: email
          description: GitHub邮箱地址（可选）
          example: octocat@github.com
        avatar_url:
          type: string
          description: GitHub头像URL（可选）
          example: https://github.com/images/error/octocat_happy.gif

    ForgotPasswordDto:
      type: object
      required:
        - identifier
      properties:
        identifier:
          type: string
          description: 邮箱或手机号
          minLength: 1
          maxLength: 100
          example: test@example.com

    ResetPasswordDto:
      type: object
      required:
        - identifier
        - verification_code
        - new_password
      properties:
        identifier:
          type: string
          description: 邮箱或手机号
          minLength: 1
          maxLength: 100
          example: test@example.com
        verification_code:
          type: string
          description: 6位数字验证码
          pattern: '^\d{6}$'
          example: "123456"
        new_password:
          type: string
          description: 新密码，必须包含字母和数字，长度8-128字符
          minLength: 8
          maxLength: 128
          pattern: '^(?=.*[a-zA-Z])(?=.*\d)'
          example: newpassword123

    ChangePasswordDto:
      type: object
      required:
        - user_id
        - old_password
        - new_password
      properties:
        user_id:
          type: string
          description: 用户ID（实际应用中应从JWT令牌中获取）
          example: "1"
        old_password:
          type: string
          description: 当前密码
          minLength: 1
          maxLength: 128
          example: oldpassword123
        new_password:
          type: string
          description: 新密码，必须包含字母和数字，长度8-128字符
          minLength: 8
          maxLength: 128
          pattern: '^(?=.*[a-zA-Z])(?=.*\d)'
          example: newpassword123

    SendEmailVerificationDto:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          format: email
          description: 邮箱地址
          example: test@example.com

    EmailVerificationDto:
      type: object
      required:
        - email
        - verification_code
      properties:
        email:
          type: string
          format: email
          description: 邮箱地址
          example: test@example.com
        verification_code:
          type: string
          description: 6位数字验证码
          pattern: '^\d{6}$'
          example: "123456"

    VerificationCodeLoginDto:
      type: object
      required:
        - identifier
        - verification_code
      properties:
        identifier:
          type: string
          description: 登录标识符（邮箱或手机号）
          minLength: 1
          maxLength: 100
          example: test@example.com
        verification_code:
          type: string
          description: 6位数字验证码
          pattern: '^\d{6}$'
          example: "123456"

    SendLoginVerificationCodeDto:
      type: object
      required:
        - identifier
      properties:
        identifier:
          type: string
          description: 邮箱或手机号
          minLength: 1
          maxLength: 100
          example: test@example.com

    UserInfo:
      type: object
      properties:
        id:
          type: string
          description: 用户ID
          example: "1"
        username:
          type: string
          description: 用户名
          example: testuser
        nickname:
          type: string
          description: 用户昵称
          example: 测试用户
        email:
          type: string
          format: email
          description: 邮箱地址
          example: test@example.com
        phone:
          type: string
          description: 手机号码
          example: "+8613800138000"
        avatar_url:
          type: string
          description: 头像URL
          example: https://example.com/avatar.jpg
        role:
          type: integer
          description: 用户角色
          example: 1
        created_at:
          type: string
          format: date-time
          description: 创建时间
          example: "2025-12-17T10:00:00.000Z"

    LoginResponseData:
      type: object
      properties:
        user:
          $ref: '#/components/schemas/UserInfo'
        access_token:
          type: string
          description: 访问令牌
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
        refresh_token:
          type: string
          description: 刷新令牌
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
        is_new_user:
          type: boolean
          description: 是否为新用户
          example: false
        message:
          type: string
          description: 响应消息
          example: 登录成功

    LoginResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        data:
          $ref: '#/components/schemas/LoginResponseData'
        message:
          type: string
          description: 响应消息
          example: 登录成功

    RegisterResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        data:
          $ref: '#/components/schemas/LoginResponseData'
        message:
          type: string
          description: 响应消息
          example: 注册成功

    GitHubOAuthResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        data:
          $ref: '#/components/schemas/LoginResponseData'
        message:
          type: string
          description: 响应消息
          example: GitHub登录成功

    ForgotPasswordResponseData:
      type: object
      properties:
        verification_code:
          type: string
          description: 验证码（仅用于演示，实际应用中不应返回）
          example: "123456"

    ForgotPasswordResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        data:
          $ref: '#/components/schemas/ForgotPasswordResponseData'
        message:
          type: string
          description: 响应消息
          example: 验证码已发送，请查收

    CommonResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        message:
          type: string
          description: 响应消息
          example: 操作成功

    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: false
        message:
          type: string
          description: 错误消息
          example: 操作失败
        error_code:
          type: string
          description: 错误代码
          example: OPERATION_FAILED

    EmailVerificationResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        data:
          type: object
          properties:
            sent_to:
              type: string
              description: 发送目标
              example: test@example.com
            expires_in:
              type: integer
              description: 过期时间（秒）
              example: 300
            is_test_mode:
              type: boolean
              description: 是否为测试模式
              example: false
        message:
          type: string
          description: 响应消息
          example: 验证码已发送，请查收邮件

    TestModeEmailVerificationResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: false
        data:
          type: object
          properties:
            verification_code:
              type: string
              description: 验证码（仅测试模式）
              example: "123456"
            sent_to:
              type: string
              description: 发送目标
              example: test@example.com
            expires_in:
              type: integer
              description: 过期时间（秒）
              example: 300
            is_test_mode:
              type: boolean
              description: 是否为测试模式
              example: true
        message:
          type: string
          description: 响应消息
          example: 测试模式：验证码已生成但未真实发送
        error_code:
          type: string
          description: 错误代码
          example: TEST_MODE_ONLY

    VerificationCodeLoginErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: false
        message:
          type: string
          description: 错误消息
          example: 验证码错误或已过期
        error_code:
          type: string
          description: 错误代码
          example: VERIFICATION_CODE_LOGIN_FAILED

    SendLoginCodeErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: false
        message:
          type: string
          description: 错误消息
          example: 用户不存在
        error_code:
          type: string
          description: 错误代码
          example: SEND_LOGIN_CODE_FAILED

    ThrottleErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: false
        message:
          type: string
          description: 错误消息
          example: 请求过于频繁，请稍后再试
        error_code:
          type: string
          description: 错误代码
          example: TOO_MANY_REQUESTS
        throttle_info:
          type: object
          properties:
            limit:
              type: integer
              description: 限制次数
              example: 1
            window_seconds:
              type: integer
              description: 时间窗口（秒）
              example: 60
            current_requests:
              type: integer
              description: 当前请求次数
              example: 1
            reset_time:
              type: string
              format: date-time
              description: 重置时间
              example: "2025-12-25T08:01:00.000Z"

    DebugVerificationCodeResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        data:
          type: object
          properties:
            key:
              type: string
              description: Redis键名
              example: verification_code:email_verification:test@example.com
            exists:
              type: boolean
              description: 是否存在
              example: true
            ttl:
              type: integer
              description: 剩余生存时间（秒）
              example: 290
            rawData:
              type: string
              description: 原始数据
              example: '{"code":"123456","createdAt":1766649341250}'
            parsedData:
              type: object
              description: 解析后的数据
              properties:
                code:
                  type: string
                  example: "123456"
                createdAt:
                  type: integer
                  example: 1766649341250
            currentTime:
              type: integer
              description: 当前时间戳
              example: 1766649341250

    # ==================== 新增的DTO定义 ====================

    RefreshTokenDto:
      type: object
      required:
        - refresh_token
      properties:
        refresh_token:
          type: string
          description: 刷新令牌
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

    RefreshTokenResponse:
      type: object
      properties:
        success:
          type: boolean
          description: 请求是否成功
          example: true
        data:
          type: object
          properties:
            access_token:
              type: string
              description: 新的访问令牌
              example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
            refresh_token:
              type: string
              description: 新的刷新令牌
              example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
            expires_in:
              type: integer
              description: 访问令牌过期时间（秒）
              example: 3600
        message:
          type: string
          description: 响应消息
          example: 令牌刷新成功

    CreateSessionDto:
      type: object
      required:
        - sessionId
        - name
      properties:
        sessionId:
          type: string
          description: 会话ID
          example: session_12345
        name:
          type: string
          description: 会话名称
          example: 测试会话
        description:
          type: string
          description: 会话描述
          example: 这是一个测试会话
        maxUsers:
          type: integer
          description: 最大用户数
          example: 100
        isPublic:
          type: boolean
          description: 是否公开
          example: true

    SendChatMessageDto:
      type: object
      required:
        - content
        - scope
      properties:
        content:
          type: string
          description: 消息内容
          example: 大家好！
        scope:
          type: string
          description: 消息范围
          enum: [local, global]
          example: local
        mapId:
          type: string
          description: 地图ID（local范围时需要）
          example: whale_port

    ChatMessageResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        messageId:
          type: string
          example: msg_12345
        timestamp:
          type: string
          format: date-time
          example: "2026-01-08T10:00:00.000Z"

    ChatHistoryResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        messages:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
                example: 1
              sender:
                type: string
                example: Player_123
              content:
                type: string
                example: 大家好！我刚进入游戏
              scope:
                type: string
                example: local
              mapId:
                type: string
                example: whale_port
              timestamp:
                type: string
                format: date-time
                example: "2026-01-08T10:00:00.000Z"
              streamName:
                type: string
                example: Whale Port
              topicName:
                type: string
                example: Game Chat
        total:
          type: integer
          example: 2
        count:
          type: integer
          example: 2

    SystemStatusResponseDto:
      type: object
      properties:
        websocket:
          type: object
          properties:
            totalConnections:
              type: integer
              example: 25
            authenticatedConnections:
              type: integer
              example: 20
            activeSessions:
              type: integer
              example: 20
            mapPlayerCounts:
              type: object
              properties:
                whale_port:
                  type: integer
                  example: 8
                pumpkin_valley:
                  type: integer
                  example: 6
                novice_village:
                  type: integer
                  example: 6
        zulip:
          type: object
          properties:
            serverConnected:
              type: boolean
              example: true
            serverVersion:
              type: string
              example: "11.4"
            botAccountActive:
              type: boolean
              example: true
            availableStreams:
              type: integer
              example: 12
            gameStreams:
              type: array
              items:
                type: string
              example: ["Whale Port", "Pumpkin Valley", "Novice Village"]
            recentMessageCount:
              type: integer
              example: 156
        uptime:
          type: integer
          example: 3600
        memory:
          type: object
          properties:
            used:
              type: string
              example: "45.2 MB"
            total:
              type: string
              example: "128.0 MB"
            percentage:
              type: number
              example: 35.31

    CreateZulipAccountDto:
      type: object
      required:
        - gameUserId
        - zulipUserId
        - zulipEmail
      properties:
        gameUserId:
          type: string
          description: 游戏用户ID
          example: "12345"
        zulipUserId:
          type: integer
          description: Zulip用户ID
          example: 67890
        zulipEmail:
          type: string
          format: email
          description: Zulip邮箱地址
          example: user@example.com
        zulipFullName:
          type: string
          description: Zulip全名
          example: John Doe
        status:
          type: string
          description: 账号状态
          enum: [active, inactive, suspended, error]
          default: active

    UpdateZulipAccountDto:
      type: object
      properties:
        zulipUserId:
          type: integer
          description: Zulip用户ID
          example: 67890
        zulipEmail:
          type: string
          format: email
          description: Zulip邮箱地址
          example: user@example.com
        zulipFullName:
          type: string
          description: Zulip全名
          example: John Doe
        status:
          type: string
          description: 账号状态
          enum: [active, inactive, suspended, error]

    ZulipAccountResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            id:
              type: string
              example: "1"
            gameUserId:
              type: string
              example: "12345"
            zulipUserId:
              type: integer
              example: 67890
            zulipEmail:
              type: string
              example: user@example.com
            zulipFullName:
              type: string
              example: John Doe
            status:
              type: string
              example: active
            createdAt:
              type: string
              format: date-time
              example: "2026-01-08T10:00:00.000Z"
            updatedAt:
              type: string
              format: date-time
              example: "2026-01-08T10:00:00.000Z"

    ZulipAccountListResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: array
          items:
            $ref: '#/components/schemas/ZulipAccountResponseDto'
        total:
          type: integer
          example: 10
        count:
          type: integer
          example: 10

    ZulipAccountStatsResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            total:
              type: integer
              example: 100
            active:
              type: integer
              example: 85
            inactive:
              type: integer
              example: 10
            suspended:
              type: integer
              example: 3
            error:
              type: integer
              example: 2

    BatchUpdateStatusDto:
      type: object
      required:
        - ids
        - status
      properties:
        ids:
          type: array
          items:
            type: string
          description: 要更新的记录ID列表
          example: ["1", "2", "3"]
        status:
          type: string
          description: 新状态
          enum: [active, inactive, suspended, error]
          example: active

    BatchUpdateResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            updated:
              type: integer
              example: 3
            failed:
              type: integer
              example: 0
        message:
          type: string
          example: 批量更新完成

    AdminCreateUserDto:
      type: object
      required:
        - username
        - nickname
      properties:
        username:
          type: string
          description: 用户名
          example: newuser
        nickname:
          type: string
          description: 用户昵称
          example: 新用户
        email:
          type: string
          format: email
          description: 邮箱地址
          example: newuser@example.com
        phone:
          type: string
          description: 手机号码
          example: "+8613800138000"
        password:
          type: string
          description: 密码
          example: password123
        role:
          type: integer
          description: 用户角色
          example: 1

    AdminUpdateUserDto:
      type: object
      properties:
        username:
          type: string
          description: 用户名
          example: updateduser
        nickname:
          type: string
          description: 用户昵称
          example: 更新用户
        email:
          type: string
          format: email
          description: 邮箱地址
          example: updated@example.com
        phone:
          type: string
          description: 手机号码
          example: "+8613800138001"
        role:
          type: integer
          description: 用户角色
          example: 1
        status:
          type: string
          description: 用户状态
          example: active