{
  "swagger": "2.0",
  "info": {
    "title": "聚玩用户服务",
    "description": "处理用户注册、登录、个人信息管理及关注系统。ID 字段（int64）以 string 传输",
    "version": "1.0"
  },
  "schemes": [
    "http",
    "https"
  ],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/api/v1/admin/verifications": {
      "get": {
        "summary": "管理员获取认证申请列表 (分页)",
        "operationId": "GetVerifications",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GetPendingListResp"
            }
          }
        },
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "required": true,
            "type": "integer",
            "format": "int64",
            "default": "0"
          },
          {
            "name": "limit",
            "in": "query",
            "required": true,
            "type": "integer",
            "format": "int64",
            "default": "20"
          },
          {
            "name": "role",
            "description": " 筛选角色",
            "in": "query",
            "required": false,
            "type": "string"
          },
          {
            "name": "status",
            "description": " 筛选状态，默认 pending",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "tags": [
          "verification_admin"
        ],
        "consumes": [
          "multipart/form-data"
        ]
      }
    },
    "/api/v1/admin/verifications/{id}/approve": {
      "post": {
        "summary": "管理员通过申请",
        "operationId": "ApproveVerification",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/VerificationEmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "body",
            "description": " 管理员：审核操作请求 (只包含 ID 路径参数)",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/VerificationIdReq"
            }
          }
        ],
        "tags": [
          "verification_admin"
        ]
      }
    },
    "/api/v1/admin/verifications/{id}/reject": {
      "post": {
        "summary": "管理员驳回申请",
        "operationId": "RejectVerification",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/VerificationEmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "body",
            "description": " 管理员：驳回请求",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/RejectVerificationReq"
            }
          }
        ],
        "tags": [
          "verification_admin"
        ]
      }
    },
    "/api/v1/auth/login": {
      "post": {
        "summary": "用户登录",
        "operationId": "Login",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/LoginResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/LoginReq"
            }
          }
        ],
        "tags": [
          "auth"
        ]
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "summary": "退出登录",
        "operationId": "Logout",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/LogoutReq"
            }
          }
        ],
        "tags": [
          "auth"
        ]
      }
    },
    "/api/v1/auth/register": {
      "post": {
        "summary": "用户注册",
        "operationId": "Register",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/RegisterResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/RegisterReq"
            }
          }
        ],
        "tags": [
          "auth"
        ]
      }
    },
    "/api/v1/auth/reset-password": {
      "post": {
        "summary": "重置密码",
        "operationId": "ResetPassword",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/ResetPasswordReq"
            }
          }
        ],
        "tags": [
          "auth"
        ]
      }
    },
    "/api/v1/users/me": {
      "get": {
        "summary": "获取当前登录用户信息",
        "operationId": "GetMe",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/User"
            }
          }
        },
        "tags": [
          "user"
        ]
      },
      "put": {
        "summary": "更新个人资料",
        "operationId": "UpdateMe",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/User"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/UpdateUserProfileReq"
            }
          }
        ],
        "tags": [
          "user"
        ]
      }
    },
    "/api/v1/users/me/preferences/notifications": {
      "put": {
        "summary": "更新通知偏好",
        "operationId": "UpdateNotificationSettings",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/UpdateNotifySettingsReq"
            }
          }
        ],
        "tags": [
          "user"
        ]
      }
    },
    "/api/v1/users/me/preferences/theme": {
      "put": {
        "summary": "更新主题偏好",
        "operationId": "UpdateThemeSettings",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/UpdateThemeSettingsReq"
            }
          }
        ],
        "tags": [
          "user"
        ]
      }
    },
    "/api/v1/users/me/switch-role": {
      "post": {
        "summary": "切换当前激活角色",
        "operationId": "SwitchRole",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/SwitchRoleReq"
            }
          }
        ],
        "tags": [
          "user"
        ]
      }
    },
    "/api/v1/users/me/verification": {
      "get": {
        "summary": "获取我的所有认证状态",
        "operationId": "GetMyVerifications",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GetMyVerificationsResp"
            }
          }
        },
        "tags": [
          "verification_user"
        ]
      },
      "post": {
        "summary": "提交或修改角色认证申请 (支持幂等更新)",
        "operationId": "ApplyVerification",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/VerificationEmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "description": " 提交申请请求",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/ApplyVerificationReq"
            }
          }
        ],
        "tags": [
          "verification_user"
        ]
      }
    },
    "/api/v1/users/{id}": {
      "get": {
        "summary": "获取指定用户信息",
        "operationId": "GetUserInfo",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/User"
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "tags": [
          "user"
        ]
      }
    },
    "/api/v1/users/{id}/follow": {
      "delete": {
        "summary": "取消关注用户",
        "operationId": "UnfollowUser",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/UnfollowUserReq"
            }
          }
        ],
        "tags": [
          "user"
        ]
      },
      "post": {
        "summary": "关注用户",
        "operationId": "FollowUser",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/EmptyResp"
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/FollowUserReq"
            }
          }
        ],
        "tags": [
          "user"
        ]
      }
    }
  },
  "definitions": {
    "ApplyVerificationReq": {
      "type": "object",
      "properties": {
        "role": {
          "type": "string",
          "description": " 申请什么角色"
        },
        "materials": {
          "$ref": "#/definitions/MaterialJson",
          "description": " 证明材料键值对 {\"idCardFront\": \"http...\", \"license\": \"http...\"}"
        }
      },
      "title": "ApplyVerificationReq",
      "required": [
        "role",
        "materials"
      ]
    },
    "EmptyResp": {
      "type": "object",
      "title": "EmptyResp"
    },
    "FollowUserReq": {
      "type": "object",
      "title": "FollowUserReq"
    },
    "GetMyVerificationsResp": {
      "type": "object",
      "properties": {
        "list": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/VerificationItem"
          }
        }
      },
      "title": "GetMyVerificationsResp",
      "required": [
        "list"
      ]
    },
    "GetPendingListReq": {
      "type": "object",
      "properties": {
        "offset": {
          "type": "integer",
          "format": "int64",
          "default": "0"
        },
        "limit": {
          "type": "integer",
          "format": "int64",
          "default": "20"
        },
        "role": {
          "type": "string",
          "description": " 筛选角色"
        },
        "status": {
          "type": "string",
          "description": " 筛选状态，默认 pending"
        }
      },
      "title": "GetPendingListReq",
      "required": [
        "offset",
        "limit"
      ]
    },
    "GetPendingListResp": {
      "type": "object",
      "properties": {
        "list": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/VerificationItem"
          }
        },
        "total": {
          "type": "integer",
          "format": "int64"
        }
      },
      "title": "GetPendingListResp",
      "required": [
        "list",
        "total"
      ]
    },
    "GetUserReq": {
      "type": "object",
      "title": "GetUserReq"
    },
    "LoginReq": {
      "type": "object",
      "properties": {
        "phone": {
          "type": "string",
          "description": " 手机号登录"
        },
        "username": {
          "type": "string",
          "description": " 或用户名登录"
        },
        "password": {
          "type": "string"
        },
        "remember": {
          "type": "boolean",
          "format": "boolean"
        }
      },
      "title": "LoginReq",
      "required": [
        "password"
      ]
    },
    "LoginResp": {
      "type": "object",
      "properties": {
        "user": {
          "$ref": "#/definitions/User"
        }
      },
      "title": "LoginResp",
      "required": [
        "user"
      ]
    },
    "LogoutReq": {
      "type": "object",
      "title": "LogoutReq"
    },
    "MaterialJson": {
      "type": "object",
      "properties": {
        "idCardFront": {
          "type": "string",
          "description": " 身份证正面照片URL"
        },
        "idCardBack": {
          "type": "string",
          "description": " 身份证反面照片URL"
        },
        "gameScreenshots": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/string"
          },
          "description": " 游戏截图URL列表"
        },
        "voiceDemo": {
          "type": "string",
          "description": " 语音认证示例URL"
        }
      },
      "title": "MaterialJson",
      "required": [
        "idCardFront",
        "idCardBack"
      ]
    },
    "RegisterReq": {
      "type": "object",
      "properties": {
        "phone": {
          "type": "string"
        },
        "email": {
          "type": "string"
        },
        "username": {
          "type": "string"
        },
        "password": {
          "type": "string"
        },
        "vcode": {
          "type": "string",
          "description": " 验证码"
        }
      },
      "title": "RegisterReq",
      "required": [
        "username",
        "password"
      ]
    },
    "RegisterResp": {
      "type": "object",
      "properties": {
        "user": {
          "$ref": "#/definitions/User"
        }
      },
      "title": "RegisterResp",
      "required": [
        "user"
      ]
    },
    "RejectVerificationReq": {
      "type": "object",
      "properties": {
        "reason": {
          "type": "string",
          "description": " 必填：驳回原因"
        }
      },
      "title": "RejectVerificationReq",
      "required": [
        "reason"
      ]
    },
    "ResetPasswordReq": {
      "type": "object",
      "properties": {
        "phone": {
          "type": "string"
        },
        "email": {
          "type": "string"
        },
        "vcode": {
          "type": "string"
        },
        "newPassword": {
          "type": "string"
        }
      },
      "title": "ResetPasswordReq",
      "required": [
        "vcode",
        "newPassword"
      ]
    },
    "SwitchRoleReq": {
      "type": "object",
      "properties": {
        "role": {
          "type": "string",
          "description": " 目标角色"
        }
      },
      "title": "SwitchRoleReq",
      "required": [
        "role"
      ]
    },
    "UnfollowUserReq": {
      "type": "object",
      "title": "UnfollowUserReq"
    },
    "UpdateNotifySettingsReq": {
      "type": "object",
      "properties": {
        "order": {
          "type": "boolean",
          "format": "boolean"
        },
        "community": {
          "type": "boolean",
          "format": "boolean"
        },
        "system": {
          "type": "boolean",
          "format": "boolean"
        }
      },
      "title": "UpdateNotifySettingsReq"
    },
    "UpdateThemeSettingsReq": {
      "type": "object",
      "properties": {
        "theme": {
          "type": "string",
          "description": " dark, light"
        }
      },
      "title": "UpdateThemeSettingsReq",
      "required": [
        "theme"
      ]
    },
    "UpdateUserProfileReq": {
      "type": "object",
      "properties": {
        "nickname": {
          "type": "string"
        },
        "avatar": {
          "type": "string"
        },
        "bio": {
          "type": "string"
        }
      },
      "title": "UpdateUserProfileReq"
    },
    "User": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "username": {
          "type": "string"
        },
        "nickname": {
          "type": "string"
        },
        "avatar": {
          "type": "string"
        },
        "role": {
          "type": "string",
          "description": " consumer, player, owner, admin"
        },
        "verifiedRoles": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": " e.g. [\"consumer\", \"player\"]"
        },
        "verificationStatus": {
          "type": "object",
          "description": " e.g. {\"player\": \"approved\"}"
        },
        "phone": {
          "type": "string"
        },
        "bio": {
          "type": "string"
        },
        "createdAt": {
          "type": "string",
          "description": " ISO 8601"
        }
      },
      "title": "User",
      "required": [
        "id",
        "username",
        "nickname",
        "avatar",
        "role",
        "verifiedRoles",
        "verificationStatus",
        "createdAt"
      ]
    },
    "VerificationEmptyResp": {
      "type": "object",
      "title": "VerificationEmptyResp"
    },
    "VerificationIdReq": {
      "type": "object",
      "title": "VerificationIdReq"
    },
    "VerificationItem": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64",
          "description": " 认证记录ID (主键，用于管理员操作)"
        },
        "userId": {
          "type": "integer",
          "format": "int64",
          "description": " 申请人ID (外键)"
        },
        "userNickname": {
          "type": "string",
          "description": " 冗余显示，方便前端展示"
        },
        "role": {
          "type": "string",
          "description": " 申请角色: player, owner"
        },
        "status": {
          "type": "string",
          "description": " pending, approved, rejected"
        },
        "materials": {
          "type": "object",
          "description": " 核心字段：对应 DB 的 JSONB"
        },
        "rejectReason": {
          "type": "string",
          "description": " 驳回原因"
        },
        "createdAt": {
          "type": "string",
          "description": " 申请时间"
        },
        "reviewedAt": {
          "type": "string",
          "description": " 审核时间"
        }
      },
      "title": "VerificationItem",
      "required": [
        "id",
        "userId",
        "userNickname",
        "role",
        "status",
        "materials",
        "rejectReason",
        "createdAt",
        "reviewedAt"
      ]
    }
  },
  "securityDefinitions": {
    "apiKey": {
      "type": "apiKey",
      "description": "Enter JWT Bearer token **_only_**",
      "name": "Authorization",
      "in": "header"
    }
  }
}
