import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { Controller, UsePipes } from '@nestjs/common'; import { CommandBus, QueryBus } from '@nestjs/cqrs'; import { GrpcMethod, RpcException } from '@nestjs/microservices'; import { DatabaseException } from '../../../database/src/exceptions/database.exception'; import { CreateUserCommand } from '../../commands/create-user.command'; import { DeleteUserCommand } from '../../commands/delete-user.command'; import { UpdateUserCommand } from '../../commands/update-user.command'; import { CreateUserRequest } from '../../domain/dtos/create-user.request'; import { FindAllUsersRequest } from '../../domain/dtos/find-all-users.request'; import { FindUserByUuidRequest } from '../../domain/dtos/find-user-by-uuid.request'; import { UpdateUserRequest } from '../../domain/dtos/update-user.request'; import { User } from '../../domain/entities/user'; import { FindAllUsersQuery } from '../../queries/find-all-users.query'; import { FindUserByUuidQuery } from '../../queries/find-user-by-uuid.query'; import { UserPresenter } from './user.presenter'; import { ICollection } from '../../../database/src/interfaces/collection.interface'; import { RpcValidationPipe } from '../../../../utils/rpc.validation-pipe'; @UsePipes( new RpcValidationPipe({ whitelist: true, forbidUnknownValues: false, }), ) @Controller() export class UsersController { constructor( private readonly _commandBus: CommandBus, private readonly _queryBus: QueryBus, @InjectMapper() private readonly _mapper: Mapper, ) {} @GrpcMethod('UsersService', 'FindAll') async findAll(data: FindAllUsersRequest): Promise> { const userCollection = await this._queryBus.execute( new FindAllUsersQuery(data), ); return Promise.resolve({ data: userCollection.data.map((user: User) => this._mapper.map(user, User, UserPresenter), ), total: userCollection.total, }); } @GrpcMethod('UsersService', 'FindOneByUuid') async findOneByUuid(data: FindUserByUuidRequest): Promise { try { const user = await this._queryBus.execute(new FindUserByUuidQuery(data)); return this._mapper.map(user, User, UserPresenter); } catch (error) { throw new RpcException({ code: 5, message: 'User not found', }); } } @GrpcMethod('UsersService', 'Create') async createUser(data: CreateUserRequest): Promise { try { const user = await this._commandBus.execute(new CreateUserCommand(data)); return this._mapper.map(user, User, UserPresenter); } catch (e) { if (e instanceof DatabaseException) { if (e.message.includes('Already exists')) { throw new RpcException({ code: 6, message: 'User already exists', }); } } throw new RpcException({}); } } @GrpcMethod('UsersService', 'Update') async updateUser(data: UpdateUserRequest): Promise { try { const user = await this._commandBus.execute(new UpdateUserCommand(data)); return this._mapper.map(user, User, UserPresenter); } catch (e) { if (e instanceof DatabaseException) { if (e.message.includes('not found')) { throw new RpcException({ code: 5, message: 'User not found', }); } } throw new RpcException({}); } } @GrpcMethod('UsersService', 'Delete') async deleteUser(data: FindUserByUuidRequest): Promise { try { await this._commandBus.execute(new DeleteUserCommand(data.uuid)); return Promise.resolve(); } catch (e) { if (e instanceof DatabaseException) { if (e.message.includes('not found')) { throw new RpcException({ code: 5, message: 'User not found', }); } } throw new RpcException({}); } } }