import { Injectable } from '@nestjs/common'; import { EntityCondition } from 'src/utils/types/entity-condition.type'; import { IPaginationOptions } from 'src/utils/types/pagination-options'; 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 { UserSchemaClass } from '../entities/user.schema'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { UserMapper } from '../mappers/user.mapper'; @Injectable() export class UsersDocumentRepository implements UserRepository { constructor( @InjectModel(UserSchemaClass.name) private readonly usersModel: Model, ) {} async create(data: User): Promise { const persistenceModel = UserMapper.toPersistence(data); const createdUser = new this.usersModel(persistenceModel); const userObject = await createdUser.save(); return UserMapper.toDomain(userObject); } async findManyWithPagination({ filterOptions, sortOptions, paginationOptions, }: { filterOptions?: FilterUserDto | null; sortOptions?: SortUserDto[] | null; paginationOptions: IPaginationOptions; }): Promise { const where: EntityCondition = {}; if (filterOptions?.roles?.length) { where['role.id'] = { $in: filterOptions.roles.map((role) => role.id), }; } const userObjects = await this.usersModel .find(where) .sort( sortOptions?.reduce( (accumulator, sort) => ({ ...accumulator, [sort.orderBy === 'id' ? '_id' : sort.orderBy]: sort.order.toUpperCase() === 'ASC' ? 1 : -1, }), {}, ), ) .skip((paginationOptions.page - 1) * paginationOptions.limit) .limit(paginationOptions.limit); return userObjects.map((userObject) => UserMapper.toDomain(userObject)); } async findOne(fields: EntityCondition): Promise> { if (fields.id) { const userObject = await this.usersModel.findById(fields.id); return userObject ? UserMapper.toDomain(userObject) : null; } const userObject = await this.usersModel.findOne(fields); return userObject ? UserMapper.toDomain(userObject) : null; } async update(id: User['id'], payload: Partial): Promise { const clonedPayload = { ...payload }; delete clonedPayload.id; const filter = { _id: id }; const userObject = await this.usersModel.findOneAndUpdate( filter, clonedPayload, ); return userObject ? UserMapper.toDomain(userObject) : null; } async softDelete(id: User['id']): Promise { await this.usersModel.deleteOne({ _id: id, }); } }