From 03d4f38fb0b7150384438c31b1cb483a8d590e44 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Wed, 4 Mar 2026 06:18:10 +0300 Subject: [PATCH] feat: add get me --- src/core/app.module.ts | 2 ++ src/modules/users/dto/index.ts | 1 + .../users/dto/rs/get-me.response.dto.ts | 21 +++++++++++++ src/modules/users/dto/rs/index.ts | 1 + src/modules/users/users.controller.ts | 27 +++++++++++++++++ src/modules/users/users.grpc.ts | 22 ++++++++++++++ src/modules/users/users.module.ts | 30 +++++++++++++++++++ yarn.lock | 6 ++-- 8 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/modules/users/dto/index.ts create mode 100644 src/modules/users/dto/rs/get-me.response.dto.ts create mode 100644 src/modules/users/dto/rs/index.ts create mode 100644 src/modules/users/users.controller.ts create mode 100644 src/modules/users/users.grpc.ts create mode 100644 src/modules/users/users.module.ts diff --git a/src/core/app.module.ts b/src/core/app.module.ts index 22b09be..29cfabe 100644 --- a/src/core/app.module.ts +++ b/src/core/app.module.ts @@ -4,6 +4,7 @@ import { PassportModule } from '@teacinema/passport' import { AccountModule } from '../modules/account/account.module' import { AuthModule } from '../modules/auth/auth.module' +import { UsersModule } from '../modules/users/users.module' import { AppController } from './app.controller' import { AppService } from './app.service' @@ -14,6 +15,7 @@ import { getPassportConfig } from './config' ConfigModule.forRoot({ isGlobal: true }), AuthModule, AccountModule, + UsersModule, PassportModule.registerAsync({ useFactory: getPassportConfig, inject: [ConfigService] diff --git a/src/modules/users/dto/index.ts b/src/modules/users/dto/index.ts new file mode 100644 index 0000000..e7b548e --- /dev/null +++ b/src/modules/users/dto/index.ts @@ -0,0 +1 @@ +export * from './rs' diff --git a/src/modules/users/dto/rs/get-me.response.dto.ts b/src/modules/users/dto/rs/get-me.response.dto.ts new file mode 100644 index 0000000..0d45976 --- /dev/null +++ b/src/modules/users/dto/rs/get-me.response.dto.ts @@ -0,0 +1,21 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class GetMeResponseDto { + @ApiProperty({ example: '123' }) + public id: string + + @ApiProperty({ example: 'Ivan' }) + public name: string + + @ApiProperty({ example: 'mail@mail.ru' }) + public email: string + + @ApiProperty({ example: '+79999999999' }) + public phone: string + + @ApiProperty({ + example: + 'https://t4.ftcdn.net/jpg/11/66/06/77/360_F_1166067709_2SooAuPWXp20XkGev7oOT7nuK1VThCsN.jpg' + }) + public avatar: string +} diff --git a/src/modules/users/dto/rs/index.ts b/src/modules/users/dto/rs/index.ts new file mode 100644 index 0000000..8792b32 --- /dev/null +++ b/src/modules/users/dto/rs/index.ts @@ -0,0 +1 @@ +export * from './get-me.response.dto' diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts new file mode 100644 index 0000000..1bb6529 --- /dev/null +++ b/src/modules/users/users.controller.ts @@ -0,0 +1,27 @@ +import { Controller, Get, HttpCode, HttpStatus } from '@nestjs/common' +import { ApiBearerAuth, ApiOkResponse, ApiOperation } from '@nestjs/swagger' +import { lastValueFrom } from 'rxjs' + +import { CurrentUser, Protected } from '../../shared/decorators' + +import { GetMeResponseDto } from './dto' +import { UsersClientGrpc } from './users.grpc' + +@Controller('users') +export class UsersController { + constructor(private readonly client: UsersClientGrpc) {} + + @ApiOperation({ + summary: 'Get Me', + description: 'Get current user' + }) + @ApiBearerAuth() + @ApiOkResponse({ type: GetMeResponseDto }) + @Protected() + @Get('me') + @HttpCode(HttpStatus.OK) + public async getMe(@CurrentUser() userId: string) { + const { user } = await lastValueFrom(this.client.getMe({ id: userId })) + return user + } +} diff --git a/src/modules/users/users.grpc.ts b/src/modules/users/users.grpc.ts new file mode 100644 index 0000000..e5f9989 --- /dev/null +++ b/src/modules/users/users.grpc.ts @@ -0,0 +1,22 @@ +import { Inject, Injectable, OnModuleInit } from '@nestjs/common' +import type { ClientGrpc } from '@nestjs/microservices' +import { + GetMeRequest, + UsersServiceClient +} from '@teacinema/contracts/gen/users' + +@Injectable() +export class UsersClientGrpc implements OnModuleInit { + private usersService: UsersServiceClient + + constructor(@Inject('USERS_PACKAGE') private readonly client: ClientGrpc) {} + + onModuleInit() { + this.usersService = + this.client.getService('UsersService') + } + + public getMe(request: GetMeRequest) { + return this.usersService.getMe(request) + } +} diff --git a/src/modules/users/users.module.ts b/src/modules/users/users.module.ts new file mode 100644 index 0000000..482b4c4 --- /dev/null +++ b/src/modules/users/users.module.ts @@ -0,0 +1,30 @@ +import { Module } from '@nestjs/common' +import { ConfigService } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { PROTO_PATHS } from '@teacinema/contracts' + +import { UsersController } from './users.controller' +import { UsersClientGrpc } from './users.grpc' + +@Module({ + imports: [ + ClientsModule.registerAsync([ + { + name: 'USERS_PACKAGE', + useFactory: (configService: ConfigService) => ({ + transport: Transport.GRPC, + options: { + package: 'users.v1', + protoPath: PROTO_PATHS.USERS, + url: configService.getOrThrow('USERS_GRPC_URL') + } + }), + inject: [ConfigService] + } + ]) + ], + controllers: [UsersController], + providers: [UsersClientGrpc], + exports: [UsersClientGrpc] +}) +export class UsersModule {} diff --git a/yarn.lock b/yarn.lock index 52b5d01..ea961c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1221,9 +1221,9 @@ integrity sha512-q3DURJbSk3k8MNWFIYaSM4LEcBgPbWa+HJmBz/nzYT4kuYitJVSXxpZ97kr0Ea+81AZwAU3JhQKlkK0SBWUi0A== "@teacinema/contracts@^1.0.0": - version "1.0.9" - resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.9/contracts-1.0.9.tgz#14b136d0c08552147b0de637a7af6d340d538527" - integrity sha512-9BwWvXaDKgRcef6+1ep9vUDWBdOndqheeTX5mXK5OOvLXbLOlzYoqAUoT0ZwaRwOCD+Je/LDrqcdti6eoss71Q== + version "1.1.2" + resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.1.2/contracts-1.1.2.tgz#74e5ce7c95515983fd299332ef095a882dbe6665" + integrity sha512-LL9UqmjIX0C9kHVtyoAoNUrp0zk1u/JzNTfnU+gqTXHJhejHOSa3blVtQBO4cjTt+yYDaN89fjm5fRbL/V0dDw== dependencies: "@nestjs/microservices" "^11.1.12" protoc "33.4.0"