swagger: "2.0" info: title: HY User Service API version: "1.0.0" description: | user-service 当前只暴露内部 gRPC + protobuf 接口,没有 HTTP JSON router。 本文件用 OpenAPI 2.0 记录 gRPC 合约,`paths` 使用 gRPC full method 作为文档路径,不代表真实 HTTP endpoint。 host: localhost:13005 basePath: / schemes: - http consumes: - application/grpc+proto produces: - application/grpc+proto tags: - name: auth description: AuthService,登录注册和 token 生命周期。 - name: users description: UserService,用户主状态读取。 - name: user-identity description: UserIdentityService,展示短号解析和变更。 - name: country-admin description: CountryAdminService,国家主数据内部管理 RPC。 - name: region-admin description: RegionAdminService,区域和国家归属内部管理 RPC。 - name: health description: 标准 grpc.health.v1.Health。 responses: GRPCError: description: gRPC status error;稳定业务原因放在 google.rpc.ErrorInfo.reason。 schema: $ref: "#/definitions/GRPCError" paths: /hyapp.user.v1.AuthService/LoginPassword: post: tags: - auth summary: 短号密码登录 operationId: userAuthLoginPassword x-grpc-full-method: /hyapp.user.v1.AuthService/LoginPassword parameters: - name: body in: body required: true schema: $ref: "#/definitions/LoginPasswordRequest" responses: "200": description: 登录成功。 schema: $ref: "#/definitions/AuthResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.AuthService/LoginThirdParty: post: tags: - auth summary: 三方登录或注册 operationId: userAuthLoginThirdParty x-grpc-full-method: /hyapp.user.v1.AuthService/LoginThirdParty parameters: - name: body in: body required: true schema: $ref: "#/definitions/LoginThirdPartyRequest" responses: "200": description: 登录或注册成功。 schema: $ref: "#/definitions/AuthResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.AuthService/SetPassword: post: tags: - auth summary: 首次设置密码 operationId: userAuthSetPassword x-grpc-full-method: /hyapp.user.v1.AuthService/SetPassword parameters: - name: body in: body required: true schema: $ref: "#/definitions/SetPasswordRequest" responses: "200": description: 密码设置完成。 schema: $ref: "#/definitions/SetPasswordResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.AuthService/RefreshToken: post: tags: - auth summary: 刷新 token operationId: userAuthRefreshToken x-grpc-full-method: /hyapp.user.v1.AuthService/RefreshToken parameters: - name: body in: body required: true schema: $ref: "#/definitions/RefreshTokenRequest" responses: "200": description: 刷新成功。 schema: $ref: "#/definitions/RefreshTokenResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.AuthService/Logout: post: tags: - auth summary: 登出并失效 refresh session operationId: userAuthLogout x-grpc-full-method: /hyapp.user.v1.AuthService/Logout parameters: - name: body in: body required: true schema: $ref: "#/definitions/LogoutRequest" responses: "200": description: 登出处理完成。 schema: $ref: "#/definitions/LogoutResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserService/GetUser: post: tags: - users summary: 查询单个用户主状态 operationId: userGetUser x-grpc-full-method: /hyapp.user.v1.UserService/GetUser parameters: - name: body in: body required: true schema: $ref: "#/definitions/GetUserRequest" responses: "200": description: 查询成功。 schema: $ref: "#/definitions/GetUserResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserService/BatchGetUsers: post: tags: - users summary: 批量查询用户主状态 operationId: userBatchGetUsers x-grpc-full-method: /hyapp.user.v1.UserService/BatchGetUsers parameters: - name: body in: body required: true schema: $ref: "#/definitions/BatchGetUsersRequest" responses: "200": description: 查询成功;缺失用户不填充占位对象。 schema: $ref: "#/definitions/BatchGetUsersResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserService/UpdateUserProfile: post: tags: - users summary: 修改用户基础资料 operationId: userUpdateUserProfile x-grpc-full-method: /hyapp.user.v1.UserService/UpdateUserProfile parameters: - name: body in: body required: true schema: $ref: "#/definitions/UpdateUserProfileRequest" responses: "200": description: 修改成功。 schema: $ref: "#/definitions/UpdateUserProfileResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserService/ChangeUserCountry: post: tags: - users summary: 修改用户国家 operationId: userChangeUserCountry description: 国家修改写 `user_country_change_logs`,同一用户按滚动 30 天冷却。 x-grpc-full-method: /hyapp.user.v1.UserService/ChangeUserCountry parameters: - name: body in: body required: true schema: $ref: "#/definitions/ChangeUserCountryRequest" responses: "200": description: 修改成功。 schema: $ref: "#/definitions/ChangeUserCountryResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.CountryAdminService/CreateCountry: post: tags: - country-admin summary: 创建国家主数据 operationId: userCreateCountry x-grpc-full-method: /hyapp.user.v1.CountryAdminService/CreateCountry parameters: - name: body in: body required: true schema: $ref: "#/definitions/CreateCountryRequest" responses: "200": description: 创建成功。 schema: $ref: "#/definitions/CountryResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.CountryAdminService/ListCountries: post: tags: - country-admin summary: 查询国家主数据 operationId: userListCountries x-grpc-full-method: /hyapp.user.v1.CountryAdminService/ListCountries parameters: - name: body in: body required: true schema: $ref: "#/definitions/ListCountriesRequest" responses: "200": description: 查询成功。 schema: $ref: "#/definitions/ListCountriesResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.CountryAdminService/UpdateCountry: post: tags: - country-admin summary: 修改国家展示字段 operationId: userUpdateCountry x-grpc-full-method: /hyapp.user.v1.CountryAdminService/UpdateCountry parameters: - name: body in: body required: true schema: $ref: "#/definitions/UpdateCountryRequest" responses: "200": description: 修改成功。 schema: $ref: "#/definitions/CountryResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.CountryAdminService/DisableCountry: post: tags: - country-admin summary: 停用国家 operationId: userDisableCountry x-grpc-full-method: /hyapp.user.v1.CountryAdminService/DisableCountry parameters: - name: body in: body required: true schema: $ref: "#/definitions/DisableCountryRequest" responses: "200": description: 停用成功。 schema: $ref: "#/definitions/CountryResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.RegionAdminService/CreateRegion: post: tags: - region-admin summary: 创建区域并配置国家列表 operationId: userCreateRegion x-grpc-full-method: /hyapp.user.v1.RegionAdminService/CreateRegion parameters: - name: body in: body required: true schema: $ref: "#/definitions/CreateRegionRequest" responses: "200": description: 创建成功。 schema: $ref: "#/definitions/RegionResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.RegionAdminService/ListRegions: post: tags: - region-admin summary: 查询区域列表 operationId: userListRegions x-grpc-full-method: /hyapp.user.v1.RegionAdminService/ListRegions parameters: - name: body in: body required: true schema: $ref: "#/definitions/ListRegionsRequest" responses: "200": description: 查询成功。 schema: $ref: "#/definitions/ListRegionsResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.RegionAdminService/GetRegion: post: tags: - region-admin summary: 查询单个区域 operationId: userGetRegion x-grpc-full-method: /hyapp.user.v1.RegionAdminService/GetRegion parameters: - name: body in: body required: true schema: $ref: "#/definitions/GetRegionRequest" responses: "200": description: 查询成功。 schema: $ref: "#/definitions/RegionResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.RegionAdminService/UpdateRegion: post: tags: - region-admin summary: 修改区域展示字段 operationId: userUpdateRegion x-grpc-full-method: /hyapp.user.v1.RegionAdminService/UpdateRegion parameters: - name: body in: body required: true schema: $ref: "#/definitions/UpdateRegionRequest" responses: "200": description: 修改成功。 schema: $ref: "#/definitions/RegionResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.RegionAdminService/ReplaceRegionCountries: post: tags: - region-admin summary: 替换区域国家列表 operationId: userReplaceRegionCountries x-grpc-full-method: /hyapp.user.v1.RegionAdminService/ReplaceRegionCountries parameters: - name: body in: body required: true schema: $ref: "#/definitions/ReplaceRegionCountriesRequest" responses: "200": description: 替换成功。 schema: $ref: "#/definitions/RegionResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.RegionAdminService/DisableRegion: post: tags: - region-admin summary: 停用区域 operationId: userDisableRegion x-grpc-full-method: /hyapp.user.v1.RegionAdminService/DisableRegion parameters: - name: body in: body required: true schema: $ref: "#/definitions/DisableRegionRequest" responses: "200": description: 停用成功。 schema: $ref: "#/definitions/RegionResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserIdentityService/GetUserIdentity: post: tags: - user-identity summary: 按 user_id 查询当前展示短号 operationId: userGetUserIdentity x-grpc-full-method: /hyapp.user.v1.UserIdentityService/GetUserIdentity parameters: - name: body in: body required: true schema: $ref: "#/definitions/GetUserIdentityRequest" responses: "200": description: 查询成功。 schema: $ref: "#/definitions/GetUserIdentityResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserIdentityService/ResolveDisplayUserID: post: tags: - user-identity summary: 通过当前展示短号解析用户 operationId: userResolveDisplayUserID x-grpc-full-method: /hyapp.user.v1.UserIdentityService/ResolveDisplayUserID parameters: - name: body in: body required: true schema: $ref: "#/definitions/ResolveDisplayUserIDRequest" responses: "200": description: 解析成功。 schema: $ref: "#/definitions/ResolveDisplayUserIDResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserIdentityService/ChangeDisplayUserID: post: tags: - user-identity summary: 修改默认展示短号 operationId: userChangeDisplayUserID x-grpc-full-method: /hyapp.user.v1.UserIdentityService/ChangeDisplayUserID parameters: - name: body in: body required: true schema: $ref: "#/definitions/ChangeDisplayUserIDRequest" responses: "200": description: 修改成功。 schema: $ref: "#/definitions/ChangeDisplayUserIDResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserIdentityService/ApplyPrettyDisplayUserID: post: tags: - user-identity summary: 申请临时靓号 operationId: userApplyPrettyDisplayUserID x-grpc-full-method: /hyapp.user.v1.UserIdentityService/ApplyPrettyDisplayUserID parameters: - name: body in: body required: true schema: $ref: "#/definitions/ApplyPrettyDisplayUserIDRequest" responses: "200": description: 申请成功。 schema: $ref: "#/definitions/ApplyPrettyDisplayUserIDResponse" default: $ref: "#/responses/GRPCError" /hyapp.user.v1.UserIdentityService/ExpirePrettyDisplayUserID: post: tags: - user-identity summary: 主动触发靓号过期恢复 operationId: userExpirePrettyDisplayUserID x-grpc-full-method: /hyapp.user.v1.UserIdentityService/ExpirePrettyDisplayUserID parameters: - name: body in: body required: true schema: $ref: "#/definitions/ExpirePrettyDisplayUserIDRequest" responses: "200": description: 恢复成功。 schema: $ref: "#/definitions/ExpirePrettyDisplayUserIDResponse" default: $ref: "#/responses/GRPCError" /grpc.health.v1.Health/Check: post: tags: - health summary: 标准 gRPC health check operationId: userHealthCheck x-grpc-full-method: /grpc.health.v1.Health/Check parameters: - name: body in: body required: true schema: $ref: "#/definitions/HealthCheckRequest" responses: "200": description: 返回 SERVING 或 NOT_SERVING;未知 service 返回 gRPC NotFound。 schema: $ref: "#/definitions/HealthCheckResponse" default: $ref: "#/responses/GRPCError" /grpc.health.v1.Health/Watch: post: tags: - health summary: 标准 gRPC health watch operationId: userHealthWatch x-grpc-full-method: /grpc.health.v1.Health/Watch x-server-streaming: true parameters: - name: body in: body required: true schema: $ref: "#/definitions/HealthCheckRequest" responses: "200": description: 服务端流式推送健康状态变化。 schema: $ref: "#/definitions/HealthCheckResponse" default: $ref: "#/responses/GRPCError" definitions: RequestMeta: type: object properties: request_id: type: string caller: type: string gateway_node_id: type: string sent_at_ms: type: integer format: int64 device_id: type: string client_ip: type: string maxLength: 64 user_agent: type: string maxLength: 512 country_by_ip: type: string maxLength: 2 AuthToken: type: object properties: user_id: type: integer format: int64 session_id: type: string access_token: type: string refresh_token: type: string expires_in_sec: type: integer format: int64 token_type: type: string display_user_id: type: string default_display_user_id: type: string display_user_id_kind: type: string display_user_id_expires_at_ms: type: integer format: int64 LoginPasswordRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" display_user_id: type: string password: type: string LoginThirdPartyRequest: type: object description: 三方登录或注册的内部 gRPC 请求;首次注册时资料字段写入 users 主记录。 properties: meta: $ref: "#/definitions/RequestMeta" provider: type: string credential: type: string username: type: string maxLength: 64 gender: type: string maxLength: 32 country: type: string maxLength: 3 pattern: "^[A-Za-z]{2,3}$" description: 国家主数据 country_code,服务端会转大写并要求 active。 invite_code: type: string maxLength: 64 device_id: type: string maxLength: 128 description: 注册和 refresh session 绑定设备;为空时使用 meta.device_id。 device: type: string maxLength: 128 os_version: type: string maxLength: 64 avatar: type: string maxLength: 512 description: 绝对 http/https URL。 birth: type: string description: yyyy-mm-dd。 app_version: type: string maxLength: 64 build_number: type: string maxLength: 64 source: type: string maxLength: 64 install_channel: type: string maxLength: 64 campaign: type: string maxLength: 128 platform: type: string maxLength: 16 enum: - android - ios language: type: string maxLength: 32 description: BCP 47 language tag subset,例如 en-US。 timezone: type: string maxLength: 64 description: IANA timezone name,例如 America/Los_Angeles。 AuthResponse: type: object properties: token: $ref: "#/definitions/AuthToken" is_new_user: type: boolean SetPasswordRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 password: type: string SetPasswordResponse: type: object properties: password_set: type: boolean RefreshTokenRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" refresh_token: type: string RefreshTokenResponse: type: object properties: token: $ref: "#/definitions/AuthToken" LogoutRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" session_id: type: string refresh_token: type: string LogoutResponse: type: object properties: revoked: type: boolean User: type: object properties: user_id: type: integer format: int64 status: type: integer format: int32 enum: - 0 - 1 - 2 - 3 x-enum-names: - USER_STATUS_UNSPECIFIED - USER_STATUS_ACTIVE - USER_STATUS_DISABLED - USER_STATUS_BANNED created_at_ms: type: integer format: int64 updated_at_ms: type: integer format: int64 display_user_id: type: string default_display_user_id: type: string display_user_id_kind: type: string display_user_id_expires_at_ms: type: integer format: int64 username: type: string gender: type: string country: type: string maxLength: 3 pattern: "^[A-Z]{2,3}$" description: 用户选择的国家主数据 country_code。 avatar: type: string birth: type: string description: yyyy-mm-dd。 language: type: string country_id: type: integer format: int64 description: 国家主数据内部 ID;0 表示未命中国家表。 country_name: type: string country_display_name: type: string region_id: type: integer format: int64 description: 国家映射出的区域 ID;0 表示无区域归属。 region_code: type: string region_name: type: string GetUserRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 GetUserResponse: type: object properties: user: $ref: "#/definitions/User" BatchGetUsersRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_ids: type: array items: type: integer format: int64 BatchGetUsersResponse: type: object properties: users: type: object additionalProperties: $ref: "#/definitions/User" UpdateUserProfileRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 username: type: string description: optional;未传表示不修改。 avatar: type: string description: optional;未传表示不修改。 birth: type: string description: optional yyyy-mm-dd;空字符串表示清空生日。 UpdateUserProfileResponse: type: object properties: user: $ref: "#/definitions/User" ChangeUserCountryRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 country: type: string maxLength: 3 pattern: "^[A-Z]{2,3}$" description: 国家主数据 country_code,服务端会归一并要求 active。 ChangeUserCountryResponse: type: object properties: user: $ref: "#/definitions/User" next_change_allowed_at_ms: type: integer format: int64 Country: type: object properties: country_id: type: integer format: int64 country_name: type: string maxLength: 128 country_code: type: string maxLength: 3 pattern: "^[A-Z]{2,3}$" country_display_name: type: string maxLength: 128 status: type: string enum: - active - disabled sort_order: type: integer format: int32 created_at_ms: type: integer format: int64 updated_at_ms: type: integer format: int64 Region: type: object properties: region_id: type: integer format: int64 region_code: type: string pattern: "^[A-Z0-9_]{2,32}$" name: type: string maxLength: 128 status: type: string enum: - active - disabled countries: type: array items: type: string maxLength: 3 pattern: "^[A-Z]{2,3}$" sort_order: type: integer format: int32 created_at_ms: type: integer format: int64 updated_at_ms: type: integer format: int64 CreateCountryRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" country_name: type: string maxLength: 128 country_code: type: string maxLength: 3 pattern: "^[A-Za-z]{2,3}$" country_display_name: type: string maxLength: 128 sort_order: type: integer format: int32 operator_user_id: type: integer format: int64 ListCountriesRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" status: type: string ListCountriesResponse: type: object properties: countries: type: array items: $ref: "#/definitions/Country" UpdateCountryRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" country_id: type: integer format: int64 country_name: type: string maxLength: 128 country_display_name: type: string maxLength: 128 sort_order: type: integer format: int32 operator_user_id: type: integer format: int64 DisableCountryRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" country_id: type: integer format: int64 operator_user_id: type: integer format: int64 CountryResponse: type: object properties: country: $ref: "#/definitions/Country" CreateRegionRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" region_code: type: string pattern: "^[A-Za-z0-9_]{2,32}$" name: type: string maxLength: 128 countries: type: array items: type: string maxLength: 3 pattern: "^[A-Za-z]{2,3}$" sort_order: type: integer format: int32 operator_user_id: type: integer format: int64 ListRegionsRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" status: type: string ListRegionsResponse: type: object properties: regions: type: array items: $ref: "#/definitions/Region" GetRegionRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" region_id: type: integer format: int64 UpdateRegionRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" region_id: type: integer format: int64 region_code: type: string pattern: "^[A-Za-z0-9_]{2,32}$" name: type: string maxLength: 128 sort_order: type: integer format: int32 operator_user_id: type: integer format: int64 ReplaceRegionCountriesRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" region_id: type: integer format: int64 countries: type: array items: type: string maxLength: 3 pattern: "^[A-Za-z]{2,3}$" operator_user_id: type: integer format: int64 DisableRegionRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" region_id: type: integer format: int64 operator_user_id: type: integer format: int64 RegionResponse: type: object properties: region: $ref: "#/definitions/Region" UserIdentity: type: object properties: user_id: type: integer format: int64 display_user_id: type: string status: type: string default_display_user_id: type: string display_user_id_kind: type: string display_user_id_expires_at_ms: type: integer format: int64 GetUserIdentityRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 GetUserIdentityResponse: type: object properties: identity: $ref: "#/definitions/UserIdentity" ResolveDisplayUserIDRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" display_user_id: type: string ResolveDisplayUserIDResponse: type: object properties: identity: $ref: "#/definitions/UserIdentity" ChangeDisplayUserIDRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 new_display_user_id: type: string reason: type: string operator_user_id: type: integer format: int64 ChangeDisplayUserIDResponse: type: object properties: identity: $ref: "#/definitions/UserIdentity" ApplyPrettyDisplayUserIDRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 pretty_display_user_id: type: string lease_duration_ms: type: integer format: int64 payment_receipt_id: type: string ApplyPrettyDisplayUserIDResponse: type: object properties: identity: $ref: "#/definitions/UserIdentity" lease_id: type: string ExpirePrettyDisplayUserIDRequest: type: object properties: meta: $ref: "#/definitions/RequestMeta" user_id: type: integer format: int64 lease_id: type: string ExpirePrettyDisplayUserIDResponse: type: object properties: identity: $ref: "#/definitions/UserIdentity" HealthCheckRequest: type: object properties: service: type: string description: 空字符串或 `user-service`。 HealthCheckResponse: type: object properties: status: type: integer format: int32 enum: - 0 - 1 - 2 - 3 x-enum-names: - UNKNOWN - SERVING - NOT_SERVING - SERVICE_UNKNOWN GRPCError: type: object properties: grpc_code: type: string enum: - InvalidArgument - NotFound - FailedPrecondition - Unauthenticated - PermissionDenied - Unavailable - AlreadyExists - Internal - Aborted reason: type: string enum: - INVALID_ARGUMENT - NOT_FOUND - CONFLICT - UNAUTHORIZED - PERMISSION_DENIED - UNAVAILABLE - INTERNAL_ERROR - AUTH_FAILED - PASSWORD_ALREADY_SET - USER_DISABLED - SESSION_EXPIRED - SESSION_REVOKED - DISPLAY_USER_ID_INVALID - DISPLAY_USER_ID_EXISTS - DISPLAY_USER_ID_COOLDOWN - COUNTRY_CHANGE_COOLDOWN - DISPLAY_USER_ID_NOT_FOUND - DISPLAY_USER_ID_ALLOCATE_FAILED - DISPLAY_USER_ID_PRETTY_NOT_AVAILABLE - DISPLAY_USER_ID_PRETTY_ACTIVE - DISPLAY_USER_ID_LEASE_EXPIRED - DISPLAY_USER_ID_PAYMENT_REQUIRED message: type: string error_info_domain: type: string enum: - hyapp