// Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: // protoc-gen-ts_proto v2.11.4 // protoc v7.34.0 // source: user.proto /* eslint-disable */ import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices"; import { Observable } from "rxjs"; export const protobufPackage = "user"; export enum UserStatus { ACTIVE = 0, BANNED = 1, UNRECOGNIZED = -1, } export enum UserKycStatus { UNVERIFIED = 0, NOT_STARTED = 1, IN_PROGRESS = 2, PENDING_REVIEW = 3, APPROVED = 4, RETRY_REQUIRED = 5, REJECTED = 6, UNRECOGNIZED = -1, } export enum UserSearchBonusType { PROFIT = 0, VOLUME = 1, UNRECOGNIZED = -1, } export enum UserSortBy { CREATED_AT = 0, STATUS = 1, REGISTRATION_TYPE = 2, UNRECOGNIZED = -1, } export enum SortOrder { DESC = 0, ASC = 1, UNRECOGNIZED = -1, } export interface GetUserRequest { id: number; } export interface UserResponse { id: number; uid: number; email?: string | undefined; emailVerified: boolean; phone?: string | undefined; phoneVerified: boolean; telegramId?: string | undefined; telegramUsername?: string | undefined; appleSub?: string | undefined; registrationType: string; status: UserStatus; firstName?: string | undefined; lastName?: string | undefined; avatar?: string | undefined; createdAt: string; updatedAt: string; balances: UserBalance[]; kycStatus: UserKycStatus; kyc: UserKycInfo | undefined; cardFirstName?: string | undefined; cardLastName?: string | undefined; crmCustomerId?: number | undefined; referrerUserId?: number | undefined; refPercent?: number | undefined; referralVolume?: number | undefined; exchangesCount?: number | undefined; exchangeCountLastYear?: number | undefined; totalAmount?: number | undefined; avgCheck?: number | undefined; firstExchangeAt?: string | undefined; lastExchangeAt?: string | undefined; lifePeriod?: number | undefined; lifePeriodYear?: number | undefined; frequency?: number | undefined; ltv?: number | undefined; userSearchUpdatedAt?: string | undefined; bonusType?: UserSearchBonusType | undefined; referrerName?: string | undefined; exchangeCountLastMonth?: number | undefined; totalProfit?: number | undefined; refCode?: string | undefined; advChannelName?: string | undefined; isPartner?: boolean | undefined; attention?: string | undefined; ban?: boolean | undefined; comment?: string | undefined; instagram?: string | undefined; facebook?: string | undefined; facebookUrl?: string | undefined; utmDataJson?: string | undefined; blockInTg?: boolean | undefined; } export interface AdminGetUserForUpdateRequest { userId: number; } export interface AdminUserForUpdateResponse { id: number; uid: number; firstName?: string | undefined; lastName?: string | undefined; email?: string | undefined; phone?: string | undefined; telegramUsername?: string | undefined; telegramId?: string | undefined; whatsapp?: string | undefined; advChannel?: string | undefined; refCode?: string | undefined; referrerUserId?: | number | undefined; /** * Строковый тип для admin-flow, чтобы избежать тихого enum-default при межсервисном проксировании. * Допустимые значения: PROFIT | VOLUME | REFERRAL_BONUS_TYPE_PROFIT | REFERRAL_BONUS_TYPE_VOLUME. */ bonusType?: string | undefined; refPercent?: | number | undefined; /** true, если в рамках AdminUpdateUserProfile был установлен referrer_user_id. */ referrerChanged: boolean; isPartner?: boolean | undefined; attention?: string | undefined; ban?: boolean | undefined; comment?: string | undefined; instagram?: string | undefined; facebook?: string | undefined; facebookUrl?: string | undefined; advChannelId?: number | undefined; } export interface AdminUpdateUserProfileRequest { userId: number; firstName?: string | undefined; lastName?: string | undefined; email?: string | undefined; phone?: string | undefined; telegramUsername?: string | undefined; telegramId?: string | undefined; whatsapp?: string | undefined; advChannel?: string | undefined; refCode?: | string | undefined; /** * Разрешено только если у пользователя еще нет реферера. * Если текущий реферер уже задан, сервис возвращает ошибку REFERRER_ALREADY_SET. */ referrerUserId?: | number | undefined; /** * Строковый тип для admin-flow, чтобы избежать тихого enum-default при межсервисном проксировании. * Допустимые значения: PROFIT | VOLUME | REFERRAL_BONUS_TYPE_PROFIT | REFERRAL_BONUS_TYPE_VOLUME. */ bonusType?: string | undefined; refPercent?: number | undefined; isPartner?: boolean | undefined; attention?: string | undefined; ban?: boolean | undefined; comment?: string | undefined; instagram?: string | undefined; facebook?: string | undefined; facebookUrl?: | string | undefined; /** * true — в этом запросе нужно выполнить изменение referrer_user_id; * false/отсутствует — referrer_user_id игнорируется и не должен вызывать REFERRER_ALREADY_SET. */ referrerChanged?: boolean | undefined; advChannelId?: number | undefined; } export interface AdminCreateUserRequest { firstName?: string | undefined; lastName?: string | undefined; email?: string | undefined; phone?: string | undefined; telegramUsername?: string | undefined; telegramId?: string | undefined; whatsapp?: string | undefined; advChannel?: string | undefined; refCode?: string | undefined; referrerUserId?: | number | undefined; /** * Строковый тип для admin-flow, чтобы избежать тихого enum-default при межсервисном проксировании. * Допустимые значения: PROFIT | VOLUME | REFERRAL_BONUS_TYPE_PROFIT | REFERRAL_BONUS_TYPE_VOLUME. */ bonusType?: string | undefined; refPercent?: number | undefined; isPartner?: boolean | undefined; attention?: string | undefined; ban?: boolean | undefined; comment?: string | undefined; instagram?: string | undefined; facebook?: string | undefined; facebookUrl?: string | undefined; advChannelId?: number | undefined; } export interface AdminFindUserByRefCodeRequest { refCode: string; } export interface AdminReferrerLookupResponse { userId: number; uid: number; firstName?: string | undefined; lastName?: string | undefined; fullName?: string | undefined; telegramUsername?: string | undefined; refCode?: string | undefined; } export interface UpdateUserRequest { userId: number; firstName?: string | undefined; lastName?: string | undefined; avatar?: string | undefined; cardFirstName?: string | undefined; cardLastName?: string | undefined; } export interface UpdateUserStatusRequest { userId: number; status: UserStatus; } export interface ListUsersRequest { page?: number | undefined; limit?: number | undefined; sortBy?: UserSortBy | undefined; order?: SortOrder | undefined; search?: string | undefined; statusValue?: UserStatus | undefined; registrationTypeValue?: string | undefined; sources: string[]; tags: string[]; referrerUserId?: number | undefined; registrationFrom?: string | undefined; registrationTo?: string | undefined; dealFrom?: string | undefined; dealTo?: string | undefined; lastDealFrom?: string | undefined; lastDealTo?: string | undefined; sort?: string | undefined; } export interface ListUsersResponse { items: UserResponse[]; allCount: number; page: number; limit: number; } export interface ListUserSourcesRequest { } export interface UserSourceItem { id: number; name: string; code?: string | undefined; } export interface ListUserSourcesResponse { sources: UserSourceItem[]; } export interface UserSearchExchangeStats { exchangesCount: number; exchangeCountLastYear: number; totalAmount: number; avgCheck: number; firstExchangeAt?: string | undefined; lastExchangeAt?: string | undefined; lifePeriod?: number | undefined; lifePeriodYear?: number | undefined; frequency?: number | undefined; ltv?: number | undefined; } export interface UserSearchReferralStats { referrerUserId?: number | undefined; refPercent?: number | undefined; referralVolume: number; bonusType?: UserSearchBonusType | undefined; } export interface UserSearchStatsUpdate { userId: number; exchangeStats: UserSearchExchangeStats | undefined; referralStats: UserSearchReferralStats | undefined; } export interface UpdateUserSearchStatsRequest { items: UserSearchStatsUpdate[]; } export interface UpdateUserSearchStatsResponse { updatedCount: number; } export interface GetUserFullNamesByIdsRequest { userIds: number[]; } export interface UserFullNameById { userId: number; fullName?: string | undefined; } export interface GetUserFullNamesByIdsResponse { items: UserFullNameById[]; notFoundUserIds: number[]; } export interface ResolveUserForTransferRequest { userId?: number | undefined; email?: string | undefined; phone?: string | undefined; telegramUsername?: string | undefined; uid?: string | undefined; } export interface ResolveUserForTransferResponse { id: number; } export interface GetCrmSessionRequest { forceRefresh: boolean; } export interface GetCrmSessionResponse { sessionId: string; expiresAtUnix: number; } export interface CrmExchangeHttpRequest { method: string; path: string; queryString?: string | undefined; jsonBody?: string | undefined; } export interface CrmExchangeHttpResponse { httpStatus: number; bodyJson: string; } export interface SubmitWalletCrmExchangeOrderRequest { walletUserId: number; inputAmount: number; outputAmount: number; inputCurrency: number; outputCurrency: number; withdrawType: number; receiveBank?: number | undefined; exchangeRateDisplay?: number | undefined; sendCurrencyShort?: string | undefined; receiveCurrencyShort?: string | undefined; } export interface SubmitWalletCrmExchangeOrderResponse { success: boolean; orderId?: number | undefined; message?: string | undefined; } export interface ListWalletExchangeRecentPairsRequest { walletUserId: number; /** По умолчанию 20, максимум обрезается на сервисе. */ limit: number; } export interface WalletExchangeRecentPairItem { sendCurrencyShort: string; receiveCurrencyShort: string; lastInputAmount: number; lastSubmittedAtUnixMs: number; } export interface ListWalletExchangeRecentPairsResponse { pairs: WalletExchangeRecentPairItem[]; } export interface ForwardManagerChatMessageRequest { forwardSecret: string; text: string; isEcho: boolean; walletClientId: string; walletManagerId?: string | undefined; datetime?: string | undefined; content?: string | undefined; messageId?: | string | undefined; /** JSON для reply_to: отсутствие поля — нет ответа; строка "null" — null; иначе JSON-значение. */ replyToJson?: string | undefined; } export interface ForwardManagerChatMessageResponse { ok: boolean; } export interface DeleteManagerChatMessageRequest { messageId: string; } export interface DeleteManagerChatMessageResponse { ok: boolean; message?: string | undefined; } export interface PostArbiWalletChatMessageRequest { walletUserId: number; /** Частичное тело от клиента: text, content, reply_to, datetime (ISO UTC). */ jsonBody: string; mediaFile?: Uint8Array | undefined; mediaFilename?: string | undefined; mediaContentType?: string | undefined; } export interface PostArbiWalletChatMessageResponse { httpStatus: number; bodyJson: string; } export interface ListArbiWalletChatMessagesRequest { walletUserId: number; limit?: number | undefined; offset?: number | undefined; } export interface ListArbiWalletChatMessagesResponse { httpStatus: number; bodyJson: string; } export interface ProxyArbiWalletChatMediaRequest { walletUserId: number; url: string; } export interface ProxyArbiWalletChatMediaResponse { httpStatus: number; body: Uint8Array; contentType: string; } export interface GetSupportChatLastReadRequest { walletUserId: number; } export interface GetSupportChatLastReadResponse { lastReadMessageId: number; } export interface SetSupportChatLastReadRequest { walletUserId: number; lastReadMessageId: number; } export interface SetSupportChatLastReadResponse { ok: boolean; } export interface EnsureTelegramUserRequest { telegramId: string; telegramUsername?: string | undefined; firstName?: string | undefined; lastName?: string | undefined; } export interface CreateMonikaCustomerRequest { telegramId?: string | undefined; whatsapp?: string | undefined; telegramUsername?: string | undefined; username?: string | undefined; firstName?: string | undefined; lastName?: string | undefined; refCode?: string | undefined; advChannel?: string | undefined; utmId?: string | undefined; code?: string | undefined; utmDataJson?: string | undefined; } export interface CreateMonikaCustomerResponse { success: boolean; jwt: string; } export interface FindMonikaCustomerRequest { lookupValue: string; filterBy?: string | undefined; } export interface FindMonikaCustomerResponse { success: boolean; jwt?: string | undefined; } export interface CreateMonikaSessionUtmRequest { utmDataJson?: string | undefined; clientId?: string | undefined; gClientId?: string | undefined; gclid?: string | undefined; } export interface CreateMonikaSessionUtmResponse { success: boolean; jwt: string; } export interface GetMonikaSessionUtmByIdRequest { id: number; } export interface GetMonikaSessionUtmByIdResponse { success: boolean; jwt: string; } export interface ListMonikaSessionUtmsRequest { } export interface ListMonikaSessionUtmsResponse { success: boolean; jwt: string; } export interface PatchMonikaSessionUtmRequest { id: number; utmDataJson?: string | undefined; clientId?: string | undefined; gClientId?: string | undefined; gclid?: string | undefined; } export interface PatchMonikaSessionUtmResponse { success: boolean; jwt: string; } export interface ListMonikaAdvChannelGroupsRequest { } export interface CreateMonikaAdvChannelGroupRequest { name: string; } export interface PatchMonikaAdvChannelGroupRequest { id: number; name?: string | undefined; } export interface DeleteMonikaAdvChannelGroupRequest { id: number; } export interface ListMonikaAdvChannelGroupsResponse { success: boolean; jwt: string; } export interface CreateMonikaAdvChannelGroupResponse { success: boolean; jwt: string; } export interface PatchMonikaAdvChannelGroupResponse { success: boolean; jwt: string; } export interface DeleteMonikaAdvChannelGroupResponse { success: boolean; jwt: string; } export interface ListMonikaAdvChannelsRequest { search?: string | undefined; groupId?: number | undefined; partnerId?: number | undefined; } export interface GetMonikaAdvChannelByIdRequest { id: number; } export interface CreateMonikaAdvChannelRequest { name: string; code: string; groupId?: number | undefined; urlList?: string | undefined; isWebsite?: boolean | undefined; marketingReport?: boolean | undefined; partnerId?: number | undefined; } export interface PatchMonikaAdvChannelRequest { id: number; name?: string | undefined; code?: string | undefined; groupId?: number | undefined; urlList?: string | undefined; isWebsite?: boolean | undefined; marketingReport?: boolean | undefined; partnerId?: number | undefined; } export interface DeleteMonikaAdvChannelRequest { id: number; } export interface ListMonikaAdvChannelsResponse { success: boolean; jwt: string; } export interface GetMonikaAdvChannelByIdResponse { success: boolean; jwt: string; } export interface CreateMonikaAdvChannelResponse { success: boolean; jwt: string; } export interface PatchMonikaAdvChannelResponse { success: boolean; jwt: string; } export interface DeleteMonikaAdvChannelResponse { success: boolean; jwt: string; } export interface ListMonikaTgLinksWithUtmRequest { page?: number | undefined; limit?: number | undefined; } export interface CreateMonikaTgLinkWithUtmRequest { utmQueries: string; } export interface ListMonikaTgLinksWithUtmResponse { success: boolean; jwt: string; } export interface CreateMonikaTgLinkWithUtmResponse { success: boolean; jwt: string; } export interface UpdateLanguageByTelegramIdRequest { telegramId: string; language: string; } export interface TelegramUserLanguageResponse { id: number; language?: string | undefined; } export interface GetReferralLinkByTelegramIdRequest { telegramId: string; } export interface GetReferralLinkByUserIdRequest { userId: number; } export interface GetReferralLinkByTelegramIdResponse { referralLink: string; refCode: string; } export interface GetReferralBalanceByUserIdRequest { userId: number; } export interface ReferralLevels { level1: number; level2: number; level3: number; level4: number; level5: number; } export interface ReferralPartner { level: number; id: number; telegramId?: string | undefined; email?: string | undefined; walletId?: number | undefined; username?: string | undefined; firstName?: string | undefined; lastName?: string | undefined; fullName?: string | undefined; createdAt?: string | undefined; } export interface GetReferralBalanceByUserIdResponse { totalUsdtBalance: string; availableUsdtBalance: string; referralsCount: number; refPercent: number; isMultilevel: boolean; levels: ReferralLevels | undefined; referrals: ReferralPartner[]; } export interface RequestChangeEmailCodeRequest { userId: number; email: string; } export interface VerifyChangeEmailCodeRequest { userId: number; email: string; code: string; } export interface RequestChangePhoneCodeRequest { userId: number; phone: string; } export interface VerifyChangePhoneCodeRequest { userId: number; phone: string; code: string; } export interface ContactChangeMessageResponse { message: string; } export interface BatchGetUserIdsBySearchRequest { search: string; /** Максимум возвращаемых id; сервис может дополнительно ограничить. */ limit: number; } export interface BatchGetUserIdsBySearchResponse { userIds: number[]; /** true, если совпадений больше, чем limit (результат был обрезан). */ tooManyMatches: boolean; totalMatches: number; } export interface BatchGetUserIdsByAdvChannelRequest { advChannel: string; /** Максимум возвращаемых id; сервис может дополнительно ограничить. */ limit: number; } export interface BatchGetUserIdsByAdvChannelResponse { userIds: number[]; /** true, если совпадений больше, чем limit (результат был обрезан). */ tooManyMatches: boolean; totalMatches: number; } export interface SearchUserRequest { /** Строка поиска по полям: telegram_username, email, phone, whatsapp. */ search: string; /** По умолчанию 50, максимум 50. */ limit: number; } export interface SearchUserItem { id: number; uid: number; firstName?: string | undefined; lastName?: string | undefined; email?: string | undefined; phone?: string | undefined; telegramUsername?: string | undefined; whatsapp?: string | undefined; } export interface SearchUserResponse { items: SearchUserItem[]; } export interface PrealoadUserForSearchRequest { userId: number; } export interface PrealoadUserForSearchResponse { item?: SearchUserItem | undefined; } export interface BatchGetUsersByIdsRequest { userIds: number[]; } export interface BatchUserPublicItem { id: number; uid: number; firstName?: string | undefined; lastName?: string | undefined; avatar?: string | undefined; telegramUsername?: string | undefined; status: UserStatus; crmCustomerId?: number | undefined; isPartner?: boolean | undefined; } export interface BatchGetUsersByIdsResponse { items: BatchUserPublicItem[]; } export interface GetFinModelRegistrationStatsRequest { dateFrom: string; dateTo: string; partnerId?: number | undefined; } export interface GetFinModelRegistrationStatsResponse { total: number; hasDeal: number; } export interface UserBalance { asset: string; network: string; available: string; reserved: string; total: string; } export interface UserKycInfo { userId: string; applicantId: string; kycStatus: UserKycStatus; reviewAnswer: string; rejectionLabels: string[]; moderationComment: string; createdAtMs: number; updatedAtMs: number; } export const USER_PACKAGE_NAME = "user"; export interface UserServiceClient { getUser(request: GetUserRequest): Observable; /** CRM admin: получить поля пользователя для формы редактирования. */ adminGetUserForUpdate(request: AdminGetUserForUpdateRequest): Observable; /** CRM admin: создать пользователя и вернуть данные для формы. */ adminCreateUser(request: AdminCreateUserRequest): Observable; /** CRM admin: найти пользователя-реферера по персональному реф. коду. */ adminFindUserByRefCode(request: AdminFindUserByRefCodeRequest): Observable; updateUser(request: UpdateUserRequest): Observable; /** CRM admin: обновить редактируемые поля пользователя. */ adminUpdateUserProfile(request: AdminUpdateUserProfileRequest): Observable; updateUserStatus(request: UpdateUserStatusRequest): Observable; listUsers(request: ListUsersRequest): Observable; listUserSources(request: ListUserSourcesRequest): Observable; updateUserSearchStats(request: UpdateUserSearchStatsRequest): Observable; /** Батч-резолв полных имен пользователей по их id (для enrichment в других сервисах). */ getUserFullNamesByIds(request: GetUserFullNamesByIdsRequest): Observable; /** Ровно одно из полей: user_id, email, phone, telegram_username → id получателя для внутреннего перевода. */ resolveUserForTransfer(request: ResolveUserForTransferRequest): Observable; /** CRM Arbi Exchange: логин сервисным аккаунтом (env), OTP из TOTP-секрета; session_id для X-Session-ID. */ getCrmSession(request: GetCrmSessionRequest): Observable; /** HTTP к CRM Exchange: сессия и X-Session-ID только внутри user-service. */ crmExchangeHttp(request: CrmExchangeHttpRequest): Observable; /** Создание/получение CRM-клиента по wallet_user_id и создание заявки на обмен (два шага к CRM внутри сервиса). */ submitWalletCrmExchangeOrder( request: SubmitWalletCrmExchangeOrderRequest, ): Observable; /** Уникальные валютные пары из последних заявок на обмен (по БД user-service), без дубликатов пар. */ listWalletExchangeRecentPairs( request: ListWalletExchangeRecentPairsRequest, ): Observable; /** Сообщение менеджера клиенту: публикация в Rabbit app.notification → gateway → Socket.IO `notification`. */ forwardManagerChatMessage(request: ForwardManagerChatMessageRequest): Observable; /** Удаление сообщения из Monica CRM: soft-delete по message_id + Socket.IO `notification` с is_deleted. */ deleteManagerChatMessage(request: DeleteManagerChatMessageRequest): Observable; /** Чат AlexAI (chat-analytics): POST /api/v1/arbi-wallet/messages; CRM session только на user-service. */ postArbiWalletChatMessage(request: PostArbiWalletChatMessageRequest): Observable; /** Чат AlexAI (chat-analytics): GET /api/v1/arbi-wallet/messages?wallet_client_id=… — список сообщений пользователя. */ listArbiWalletChatMessages( request: ListArbiWalletChatMessagesRequest, ): Observable; /** Прокси медиа по HTTPS URL (allowlist): CRM session + X-Session-ID только в user-service; тело для отдачи на gateway → FE. */ proxyArbiWalletChatMedia(request: ProxyArbiWalletChatMediaRequest): Observable; /** Локально в user-service: последний прочитанный message_id из chat-analytics (read receipt). */ getSupportChatLastRead(request: GetSupportChatLastReadRequest): Observable; setSupportChatLastRead(request: SetSupportChatLastReadRequest): Observable; /** Telegram bot microservice: upsert user by telegram_id (registration TELEGRAM). */ ensureTelegramUser(request: EnsureTelegramUserRequest): Observable; /** Monika-compatible customer create endpoint payload (local Wallet source of truth). */ createMonikaCustomer(request: CreateMonikaCustomerRequest): Observable; /** Monika-compatible customer lookup by filter_by or customer id. */ findMonikaCustomer(request: FindMonikaCustomerRequest): Observable; /** Monika-compatible UTM session create/get. */ createMonikaSessionUtm(request: CreateMonikaSessionUtmRequest): Observable; getMonikaSessionUtmById(request: GetMonikaSessionUtmByIdRequest): Observable; listMonikaSessionUtms(request: ListMonikaSessionUtmsRequest): Observable; patchMonikaSessionUtm(request: PatchMonikaSessionUtmRequest): Observable; /** Monika-compatible adv channel groups CRUD. */ listMonikaAdvChannelGroups( request: ListMonikaAdvChannelGroupsRequest, ): Observable; createMonikaAdvChannelGroup( request: CreateMonikaAdvChannelGroupRequest, ): Observable; patchMonikaAdvChannelGroup( request: PatchMonikaAdvChannelGroupRequest, ): Observable; deleteMonikaAdvChannelGroup( request: DeleteMonikaAdvChannelGroupRequest, ): Observable; /** Monika-compatible adv channels CRUD. */ listMonikaAdvChannels(request: ListMonikaAdvChannelsRequest): Observable; getMonikaAdvChannelById(request: GetMonikaAdvChannelByIdRequest): Observable; createMonikaAdvChannel(request: CreateMonikaAdvChannelRequest): Observable; patchMonikaAdvChannel(request: PatchMonikaAdvChannelRequest): Observable; deleteMonikaAdvChannel(request: DeleteMonikaAdvChannelRequest): Observable; /** Monika-compatible links for TG bot with UTM. */ listMonikaTgLinksWithUtm(request: ListMonikaTgLinksWithUtmRequest): Observable; createMonikaTgLinkWithUtm(request: CreateMonikaTgLinkWithUtmRequest): Observable; updateLanguageByTelegramId(request: UpdateLanguageByTelegramIdRequest): Observable; /** Реферальная ссылка MONETA по telegram_id → ref_code → https://arbi.exchange/contacts/qr?code=… */ getReferralLinkByTelegramId( request: GetReferralLinkByTelegramIdRequest, ): Observable; /** Реферальная ссылка: TELEGRAM users → CRM by telegram_id; остальные → текущий CRM customer id. */ getReferralLinkByUserId(request: GetReferralLinkByUserIdRequest): Observable; /** Реферальный баланс: TELEGRAM users → CRM by telegram_id; остальные → текущий CRM customer id. */ getReferralBalanceByUserId( request: GetReferralBalanceByUserIdRequest, ): Observable; /** Смена email: отправка кода на новый адрес (RabbitMQ → notification). */ requestChangeEmailCode(request: RequestChangeEmailCodeRequest): Observable; verifyChangeEmailCode(request: VerifyChangeEmailCodeRequest): Observable; /** Смена phone: отправка SMS-кода через Twilio. */ requestChangePhoneCode(request: RequestChangePhoneCodeRequest): Observable; verifyChangePhoneCode(request: VerifyChangePhoneCodeRequest): Observable; /** Батч-поиск пользователей по строке (telegram_username, email, phone, whatsapp): возвращает только id. */ batchGetUserIdsBySearch(request: BatchGetUserIdsBySearchRequest): Observable; /** Батч-поиск пользователей по adv channel (name/code/legacy string): возвращает только id. */ batchGetUserIdsByAdvChannel( request: BatchGetUserIdsByAdvChannelRequest, ): Observable; /** Поиск пользователей по строке (telegram_username, email, phone, whatsapp): возвращает до 50 совпадений. */ searchUser(request: SearchUserRequest): Observable; /** Прелоад выбранного пользователя по id для поиска пользователей: возвращает один элемент. */ prealoadUserForSearch(request: PrealoadUserForSearchRequest): Observable; /** Батч-получение публичных данных пользователей по списку id (для enrichment в других сервисах). */ batchGetUsersByIds(request: BatchGetUsersByIdsRequest): Observable; getFinModelRegistrationStats( request: GetFinModelRegistrationStatsRequest, ): Observable; } export interface UserServiceController { getUser(request: GetUserRequest): Promise | Observable | UserResponse; /** CRM admin: получить поля пользователя для формы редактирования. */ adminGetUserForUpdate( request: AdminGetUserForUpdateRequest, ): Promise | Observable | AdminUserForUpdateResponse; /** CRM admin: создать пользователя и вернуть данные для формы. */ adminCreateUser( request: AdminCreateUserRequest, ): Promise | Observable | AdminUserForUpdateResponse; /** CRM admin: найти пользователя-реферера по персональному реф. коду. */ adminFindUserByRefCode( request: AdminFindUserByRefCodeRequest, ): Promise | Observable | AdminReferrerLookupResponse; updateUser(request: UpdateUserRequest): Promise | Observable | UserResponse; /** CRM admin: обновить редактируемые поля пользователя. */ adminUpdateUserProfile( request: AdminUpdateUserProfileRequest, ): Promise | Observable | AdminUserForUpdateResponse; updateUserStatus(request: UpdateUserStatusRequest): Promise | Observable | UserResponse; listUsers(request: ListUsersRequest): Promise | Observable | ListUsersResponse; listUserSources( request: ListUserSourcesRequest, ): Promise | Observable | ListUserSourcesResponse; updateUserSearchStats( request: UpdateUserSearchStatsRequest, ): Promise | Observable | UpdateUserSearchStatsResponse; /** Батч-резолв полных имен пользователей по их id (для enrichment в других сервисах). */ getUserFullNamesByIds( request: GetUserFullNamesByIdsRequest, ): Promise | Observable | GetUserFullNamesByIdsResponse; /** Ровно одно из полей: user_id, email, phone, telegram_username → id получателя для внутреннего перевода. */ resolveUserForTransfer( request: ResolveUserForTransferRequest, ): | Promise | Observable | ResolveUserForTransferResponse; /** CRM Arbi Exchange: логин сервисным аккаунтом (env), OTP из TOTP-секрета; session_id для X-Session-ID. */ getCrmSession( request: GetCrmSessionRequest, ): Promise | Observable | GetCrmSessionResponse; /** HTTP к CRM Exchange: сессия и X-Session-ID только внутри user-service. */ crmExchangeHttp( request: CrmExchangeHttpRequest, ): Promise | Observable | CrmExchangeHttpResponse; /** Создание/получение CRM-клиента по wallet_user_id и создание заявки на обмен (два шага к CRM внутри сервиса). */ submitWalletCrmExchangeOrder( request: SubmitWalletCrmExchangeOrderRequest, ): | Promise | Observable | SubmitWalletCrmExchangeOrderResponse; /** Уникальные валютные пары из последних заявок на обмен (по БД user-service), без дубликатов пар. */ listWalletExchangeRecentPairs( request: ListWalletExchangeRecentPairsRequest, ): | Promise | Observable | ListWalletExchangeRecentPairsResponse; /** Сообщение менеджера клиенту: публикация в Rabbit app.notification → gateway → Socket.IO `notification`. */ forwardManagerChatMessage( request: ForwardManagerChatMessageRequest, ): | Promise | Observable | ForwardManagerChatMessageResponse; /** Удаление сообщения из Monica CRM: soft-delete по message_id + Socket.IO `notification` с is_deleted. */ deleteManagerChatMessage( request: DeleteManagerChatMessageRequest, ): | Promise | Observable | DeleteManagerChatMessageResponse; /** Чат AlexAI (chat-analytics): POST /api/v1/arbi-wallet/messages; CRM session только на user-service. */ postArbiWalletChatMessage( request: PostArbiWalletChatMessageRequest, ): | Promise | Observable | PostArbiWalletChatMessageResponse; /** Чат AlexAI (chat-analytics): GET /api/v1/arbi-wallet/messages?wallet_client_id=… — список сообщений пользователя. */ listArbiWalletChatMessages( request: ListArbiWalletChatMessagesRequest, ): | Promise | Observable | ListArbiWalletChatMessagesResponse; /** Прокси медиа по HTTPS URL (allowlist): CRM session + X-Session-ID только в user-service; тело для отдачи на gateway → FE. */ proxyArbiWalletChatMedia( request: ProxyArbiWalletChatMediaRequest, ): | Promise | Observable | ProxyArbiWalletChatMediaResponse; /** Локально в user-service: последний прочитанный message_id из chat-analytics (read receipt). */ getSupportChatLastRead( request: GetSupportChatLastReadRequest, ): | Promise | Observable | GetSupportChatLastReadResponse; setSupportChatLastRead( request: SetSupportChatLastReadRequest, ): | Promise | Observable | SetSupportChatLastReadResponse; /** Telegram bot microservice: upsert user by telegram_id (registration TELEGRAM). */ ensureTelegramUser( request: EnsureTelegramUserRequest, ): Promise | Observable | TelegramUserLanguageResponse; /** Monika-compatible customer create endpoint payload (local Wallet source of truth). */ createMonikaCustomer( request: CreateMonikaCustomerRequest, ): Promise | Observable | CreateMonikaCustomerResponse; /** Monika-compatible customer lookup by filter_by or customer id. */ findMonikaCustomer( request: FindMonikaCustomerRequest, ): Promise | Observable | FindMonikaCustomerResponse; /** Monika-compatible UTM session create/get. */ createMonikaSessionUtm( request: CreateMonikaSessionUtmRequest, ): | Promise | Observable | CreateMonikaSessionUtmResponse; getMonikaSessionUtmById( request: GetMonikaSessionUtmByIdRequest, ): | Promise | Observable | GetMonikaSessionUtmByIdResponse; listMonikaSessionUtms( request: ListMonikaSessionUtmsRequest, ): Promise | Observable | ListMonikaSessionUtmsResponse; patchMonikaSessionUtm( request: PatchMonikaSessionUtmRequest, ): Promise | Observable | PatchMonikaSessionUtmResponse; /** Monika-compatible adv channel groups CRUD. */ listMonikaAdvChannelGroups( request: ListMonikaAdvChannelGroupsRequest, ): | Promise | Observable | ListMonikaAdvChannelGroupsResponse; createMonikaAdvChannelGroup( request: CreateMonikaAdvChannelGroupRequest, ): | Promise | Observable | CreateMonikaAdvChannelGroupResponse; patchMonikaAdvChannelGroup( request: PatchMonikaAdvChannelGroupRequest, ): | Promise | Observable | PatchMonikaAdvChannelGroupResponse; deleteMonikaAdvChannelGroup( request: DeleteMonikaAdvChannelGroupRequest, ): | Promise | Observable | DeleteMonikaAdvChannelGroupResponse; /** Monika-compatible adv channels CRUD. */ listMonikaAdvChannels( request: ListMonikaAdvChannelsRequest, ): Promise | Observable | ListMonikaAdvChannelsResponse; getMonikaAdvChannelById( request: GetMonikaAdvChannelByIdRequest, ): | Promise | Observable | GetMonikaAdvChannelByIdResponse; createMonikaAdvChannel( request: CreateMonikaAdvChannelRequest, ): | Promise | Observable | CreateMonikaAdvChannelResponse; patchMonikaAdvChannel( request: PatchMonikaAdvChannelRequest, ): Promise | Observable | PatchMonikaAdvChannelResponse; deleteMonikaAdvChannel( request: DeleteMonikaAdvChannelRequest, ): | Promise | Observable | DeleteMonikaAdvChannelResponse; /** Monika-compatible links for TG bot with UTM. */ listMonikaTgLinksWithUtm( request: ListMonikaTgLinksWithUtmRequest, ): | Promise | Observable | ListMonikaTgLinksWithUtmResponse; createMonikaTgLinkWithUtm( request: CreateMonikaTgLinkWithUtmRequest, ): | Promise | Observable | CreateMonikaTgLinkWithUtmResponse; updateLanguageByTelegramId( request: UpdateLanguageByTelegramIdRequest, ): Promise | Observable | TelegramUserLanguageResponse; /** Реферальная ссылка MONETA по telegram_id → ref_code → https://arbi.exchange/contacts/qr?code=… */ getReferralLinkByTelegramId( request: GetReferralLinkByTelegramIdRequest, ): | Promise | Observable | GetReferralLinkByTelegramIdResponse; /** Реферальная ссылка: TELEGRAM users → CRM by telegram_id; остальные → текущий CRM customer id. */ getReferralLinkByUserId( request: GetReferralLinkByUserIdRequest, ): | Promise | Observable | GetReferralLinkByTelegramIdResponse; /** Реферальный баланс: TELEGRAM users → CRM by telegram_id; остальные → текущий CRM customer id. */ getReferralBalanceByUserId( request: GetReferralBalanceByUserIdRequest, ): | Promise | Observable | GetReferralBalanceByUserIdResponse; /** Смена email: отправка кода на новый адрес (RabbitMQ → notification). */ requestChangeEmailCode( request: RequestChangeEmailCodeRequest, ): Promise | Observable | ContactChangeMessageResponse; verifyChangeEmailCode( request: VerifyChangeEmailCodeRequest, ): Promise | Observable | UserResponse; /** Смена phone: отправка SMS-кода через Twilio. */ requestChangePhoneCode( request: RequestChangePhoneCodeRequest, ): Promise | Observable | ContactChangeMessageResponse; verifyChangePhoneCode( request: VerifyChangePhoneCodeRequest, ): Promise | Observable | UserResponse; /** Батч-поиск пользователей по строке (telegram_username, email, phone, whatsapp): возвращает только id. */ batchGetUserIdsBySearch( request: BatchGetUserIdsBySearchRequest, ): | Promise | Observable | BatchGetUserIdsBySearchResponse; /** Батч-поиск пользователей по adv channel (name/code/legacy string): возвращает только id. */ batchGetUserIdsByAdvChannel( request: BatchGetUserIdsByAdvChannelRequest, ): | Promise | Observable | BatchGetUserIdsByAdvChannelResponse; /** Поиск пользователей по строке (telegram_username, email, phone, whatsapp): возвращает до 50 совпадений. */ searchUser( request: SearchUserRequest, ): Promise | Observable | SearchUserResponse; /** Прелоад выбранного пользователя по id для поиска пользователей: возвращает один элемент. */ prealoadUserForSearch( request: PrealoadUserForSearchRequest, ): Promise | Observable | PrealoadUserForSearchResponse; /** Батч-получение публичных данных пользователей по списку id (для enrichment в других сервисах). */ batchGetUsersByIds( request: BatchGetUsersByIdsRequest, ): Promise | Observable | BatchGetUsersByIdsResponse; getFinModelRegistrationStats( request: GetFinModelRegistrationStatsRequest, ): | Promise | Observable | GetFinModelRegistrationStatsResponse; } export function UserServiceControllerMethods() { return function (constructor: Function) { const grpcMethods: string[] = [ "getUser", "adminGetUserForUpdate", "adminCreateUser", "adminFindUserByRefCode", "updateUser", "adminUpdateUserProfile", "updateUserStatus", "listUsers", "listUserSources", "updateUserSearchStats", "getUserFullNamesByIds", "resolveUserForTransfer", "getCrmSession", "crmExchangeHttp", "submitWalletCrmExchangeOrder", "listWalletExchangeRecentPairs", "forwardManagerChatMessage", "deleteManagerChatMessage", "postArbiWalletChatMessage", "listArbiWalletChatMessages", "proxyArbiWalletChatMedia", "getSupportChatLastRead", "setSupportChatLastRead", "ensureTelegramUser", "createMonikaCustomer", "findMonikaCustomer", "createMonikaSessionUtm", "getMonikaSessionUtmById", "listMonikaSessionUtms", "patchMonikaSessionUtm", "listMonikaAdvChannelGroups", "createMonikaAdvChannelGroup", "patchMonikaAdvChannelGroup", "deleteMonikaAdvChannelGroup", "listMonikaAdvChannels", "getMonikaAdvChannelById", "createMonikaAdvChannel", "patchMonikaAdvChannel", "deleteMonikaAdvChannel", "listMonikaTgLinksWithUtm", "createMonikaTgLinkWithUtm", "updateLanguageByTelegramId", "getReferralLinkByTelegramId", "getReferralLinkByUserId", "getReferralBalanceByUserId", "requestChangeEmailCode", "verifyChangeEmailCode", "requestChangePhoneCode", "verifyChangePhoneCode", "batchGetUserIdsBySearch", "batchGetUserIdsByAdvChannel", "searchUser", "prealoadUserForSearch", "batchGetUsersByIds", "getFinModelRegistrationStats", ]; for (const method of grpcMethods) { const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method); GrpcMethod("UserService", method)(constructor.prototype[method], method, descriptor); } const grpcStreamMethods: string[] = []; for (const method of grpcStreamMethods) { const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method); GrpcStreamMethod("UserService", method)(constructor.prototype[method], method, descriptor); } }; } export const USER_SERVICE_NAME = "UserService";