Merge branch 'crud' into 'main'

findAll

See merge request mobicoop/lab/v3/services/user!2
This commit is contained in:
Gsk54 2022-12-14 14:08:36 +00:00
commit 8f4db60f92
9 changed files with 99 additions and 21 deletions

View File

@ -1,6 +1,7 @@
import { ConsoleLogger, Injectable } from '@nestjs/common'; import { ConsoleLogger, Injectable } from '@nestjs/common';
import { PrismaClientKnownRequestError } from '@prisma/client/runtime'; import { PrismaClientKnownRequestError } from '@prisma/client/runtime';
import { DatabaseException } from '../../exceptions/DatabaseException'; import { DatabaseException } from '../../exceptions/DatabaseException';
import { ICollection } from '../../interfaces/collection.interface';
import { IRepository } from '../../interfaces/repository.interface'; import { IRepository } from '../../interfaces/repository.interface';
import { PrismaService } from './prisma-service'; import { PrismaService } from './prisma-service';
@ -14,24 +15,27 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
constructor(protected readonly _prisma: PrismaService) {} constructor(protected readonly _prisma: PrismaService) {}
findAll(where?: any, include?: any): Promise<T[]> { async findAll(
return this._prisma[this._model].findMany({ where, include }); page = 1,
} perPage = 10,
where?: any,
async findOneById(id: number, include?: any): Promise<T> { include?: any,
try { ): Promise<ICollection<T>> {
const entity = await this._prisma[this._model].findUnique({ const [data, total] = await this._prisma.$transaction([
where: { id }, this._prisma[this._model].findMany({
where,
include,
skip: (page - 1) * perPage,
take: perPage,
}),
this._prisma[this._model].count({
where,
}),
]);
return Promise.resolve({
data,
total,
}); });
return entity;
} catch (e) {
if (e instanceof PrismaClientKnownRequestError) {
throw new DatabaseException(PrismaClientKnownRequestError.name, e.code);
} else {
throw new DatabaseException();
}
}
} }
async findOneByUuid(uuid: string, include?: any): Promise<T> { async findOneByUuid(uuid: string, include?: any): Promise<T> {

View File

@ -0,0 +1,4 @@
export interface ICollection<T> {
data: T[];
total: number;
}

View File

@ -1,5 +1,12 @@
import { ICollection } from './collection.interface';
export interface IRepository<T> { export interface IRepository<T> {
findAll(params?: any, include?: any): Promise<T[]>; findAll(
page: number,
perPage: number,
params?: any,
include?: any,
): Promise<ICollection<T>>;
findOne(where: any, include?: any): Promise<T>; findOne(where: any, include?: any): Promise<T>;
findOneByUuid(uuid: string, include?: any): Promise<T>; findOneByUuid(uuid: string, include?: any): Promise<T>;
create(entity: Partial<T> | any, include?: any): Promise<T>; create(entity: Partial<T> | any, include?: any): Promise<T>;

View File

@ -21,10 +21,14 @@ message User {
string email = 4; string email = 4;
} }
message UserFilter {} message UserFilter {
optional int32 page = 1;
optional int32 perPage = 2;
}
message Users { message Users {
repeated User users = 1; repeated User data = 1;
int32 total = 2;
} }
message Empty {} message Empty {}

View File

@ -8,11 +8,14 @@ import { CreateUserCommand } from '../../commands/create-user.command';
import { DeleteUserCommand } from '../../commands/delete-user.command'; import { DeleteUserCommand } from '../../commands/delete-user.command';
import { UpdateUserCommand } from '../../commands/update-user.command'; import { UpdateUserCommand } from '../../commands/update-user.command';
import { CreateUserRequest } from '../../domain/dto/create-user.request'; import { CreateUserRequest } from '../../domain/dto/create-user.request';
import { FindAllUsersRequest } from '../../domain/dto/find-all-users.request';
import { FindUserByUuidRequest } from '../../domain/dto/find-user-by-uuid.request'; import { FindUserByUuidRequest } from '../../domain/dto/find-user-by-uuid.request';
import { UpdateUserRequest } from '../../domain/dto/update-user.request'; import { UpdateUserRequest } from '../../domain/dto/update-user.request';
import { User } from '../../domain/entities/user'; import { User } from '../../domain/entities/user';
import { FindAllUsersQuery } from '../../queries/find-all-users.query';
import { FindUserByUuidQuery } from '../../queries/find-user-by-uuid.query'; import { FindUserByUuidQuery } from '../../queries/find-user-by-uuid.query';
import { UserPresenter } from './user.presenter'; import { UserPresenter } from './user.presenter';
import { ICollection } from '../../../database/src/interfaces/collection.interface';
@Controller() @Controller()
export class UsersController { export class UsersController {
@ -22,6 +25,19 @@ export class UsersController {
@InjectMapper() private readonly _mapper: Mapper, @InjectMapper() private readonly _mapper: Mapper,
) {} ) {}
@GrpcMethod('UsersService', 'FindAll')
async findAll(data: FindAllUsersRequest): Promise<ICollection<User>> {
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') @GrpcMethod('UsersService', 'FindOneByUuid')
async findOneByUuid(data: FindUserByUuidRequest): Promise<UserPresenter> { async findOneByUuid(data: FindUserByUuidRequest): Promise<UserPresenter> {
const user = await this._queryBus.execute( const user = await this._queryBus.execute(

View File

@ -0,0 +1,11 @@
import { IsInt, IsOptional } from 'class-validator';
export class FindAllUsersRequest {
@IsInt()
@IsOptional()
page?: number;
@IsInt()
@IsOptional()
perPage?: number;
}

View File

@ -0,0 +1,19 @@
import { QueryHandler } from '@nestjs/cqrs';
import { ICollection } from 'src/modules/database/src/interfaces/collection.interface';
import { UsersRepository } from '../../adapters/secondaries/users.repository';
import { FindAllUsersQuery } from '../../queries/find-all-users.query';
import { User } from '../entities/user';
@QueryHandler(FindAllUsersQuery)
export class FindAllUsersUseCase {
constructor(private readonly _usersRepository: UsersRepository) {}
async execute(
findAllUsersQuery: FindAllUsersQuery,
): Promise<ICollection<User>> {
return this._usersRepository.findAll(
findAllUsersQuery.page,
findAllUsersQuery.perPage,
);
}
}

View File

@ -0,0 +1,11 @@
import { FindAllUsersRequest } from '../domain/dto/find-all-users.request';
export class FindAllUsersQuery {
page: number;
perPage: number;
constructor(findAllUsersRequest?: FindAllUsersRequest) {
this.page = findAllUsersRequest?.page ?? 1;
this.perPage = findAllUsersRequest?.perPage ?? 10;
}
}

View File

@ -5,6 +5,7 @@ import { UsersController } from './adapters/primaries/users.controller';
import { UsersRepository } from './adapters/secondaries/users.repository'; import { UsersRepository } from './adapters/secondaries/users.repository';
import { CreateUserUseCase } from './domain/usecases/create-user.usecase'; import { CreateUserUseCase } from './domain/usecases/create-user.usecase';
import { DeleteUserUseCase } from './domain/usecases/delete-user.usecase'; import { DeleteUserUseCase } from './domain/usecases/delete-user.usecase';
import { FindAllUsersUseCase } from './domain/usecases/find-all-users.usecase';
import { FindUserByUuidUseCase } from './domain/usecases/find-user-by-uuid.usecase'; import { FindUserByUuidUseCase } from './domain/usecases/find-user-by-uuid.usecase';
import { UpdateUserUseCase } from './domain/usecases/update-user.usecase'; import { UpdateUserUseCase } from './domain/usecases/update-user.usecase';
import { UserProfile } from './mappers/user.profile'; import { UserProfile } from './mappers/user.profile';
@ -15,6 +16,7 @@ import { UserProfile } from './mappers/user.profile';
providers: [ providers: [
UserProfile, UserProfile,
UsersRepository, UsersRepository,
FindAllUsersUseCase,
FindUserByUuidUseCase, FindUserByUuidUseCase,
CreateUserUseCase, CreateUserUseCase,
UpdateUserUseCase, UpdateUserUseCase,