import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { EntityCondition } from 'src/utils/types/entity-condition.type'; import { IPaginationOptions } from 'src/utils/types/pagination-options'; import { FindOptionsWhere, Repository } from 'typeorm'; import { UserEntity } from '../entities/user.entity'; import { NullableType } from '../../../../../utils/types/nullable.type'; import { FilterUserDto, SortUserDto } from '../../../../dto/query-user.dto'; import { User } from '../../../../domain/user'; import { UserRepository } from '../../user.repository'; import { UserMapper } from '../mappers/user.mapper'; @Injectable() export class UsersRelationalRepository implements UserRepository { constructor( @InjectRepository(UserEntity) private readonly usersRepository: Repository, ) {} async create(data: User): Promise { const persistenceModel = UserMapper.toPersistence(data); const newEntity = await this.usersRepository.save( this.usersRepository.create(persistenceModel), ); return UserMapper.toDomain(newEntity); } async findManyWithPagination({ filterOptions, sortOptions, paginationOptions, }: { filterOptions?: FilterUserDto | null; sortOptions?: SortUserDto[] | null; paginationOptions: IPaginationOptions; }): Promise { const where: FindOptionsWhere = {}; if (filterOptions?.roles?.length) { where.role = filterOptions.roles.map((role) => ({ id: role.id, })); } const entities = await this.usersRepository.find({ skip: (paginationOptions.page - 1) * paginationOptions.limit, take: paginationOptions.limit, where: where, order: sortOptions?.reduce( (accumulator, sort) => ({ ...accumulator, [sort.orderBy]: sort.order, }), {}, ), }); return entities.map((user) => UserMapper.toDomain(user)); } async findOne(fields: EntityCondition): Promise> { const entity = await this.usersRepository.findOne({ where: fields as FindOptionsWhere, }); return entity ? UserMapper.toDomain(entity) : null; } async update(id: User['id'], payload: Partial): Promise { const entity = await this.usersRepository.findOne({ where: { id: Number(id) }, }); if (!entity) { throw new Error('User not found'); } const updatedEntity = await this.usersRepository.save( this.usersRepository.create( UserMapper.toPersistence({ ...UserMapper.toDomain(entity), ...payload, }), ), ); return UserMapper.toDomain(updatedEntity); } async softDelete(id: User['id']): Promise { await this.usersRepository.softDelete(id); } }