diff --git a/backend/src/infrastructure/database/mongoose.module.ts b/backend/src/infrastructure/database/mongoose.module.ts index 73e2ed80d..ad4223e32 100644 --- a/backend/src/infrastructure/database/mongoose.module.ts +++ b/backend/src/infrastructure/database/mongoose.module.ts @@ -3,8 +3,8 @@ import ResetPassword, { ResetPasswordSchema } from 'src/modules/auth/schemas/res import Board, { BoardSchema } from 'src/modules/boards/schemas/board.schema'; import BoardUser, { BoardUserSchema } from 'src/modules/boards/schemas/board.user.schema'; import Schedules, { SchedulesSchema } from 'src/modules/schedules/schemas/schedules.schema'; -import TeamUser, { TeamUserSchema } from 'src/modules/teams/schemas/team.user.schema'; -import Team, { TeamSchema } from 'src/modules/teams/schemas/teams.schema'; +import TeamUser, { TeamUserSchema } from 'src/modules/teams/entities/team.user.schema'; +import Team, { TeamSchema } from 'src/modules/teams/entities/teams.schema'; import User, { UserSchema } from 'src/modules/users/entities/user.schema'; export const mongooseBoardModule = MongooseModule.forFeature([ diff --git a/backend/src/libs/guards/teamRoles.guard.ts b/backend/src/libs/guards/teamRoles.guard.ts index 8fbb3731c..ab190df02 100644 --- a/backend/src/libs/guards/teamRoles.guard.ts +++ b/backend/src/libs/guards/teamRoles.guard.ts @@ -2,7 +2,7 @@ import { CanActivate, ExecutionContext, ForbiddenException, Injectable } from '@ import { Reflector } from '@nestjs/core'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; -import TeamUser, { TeamUserDocument } from '../../modules/teams/schemas/team.user.schema'; +import TeamUser, { TeamUserDocument } from '../../modules/teams/entities/team.user.schema'; @Injectable() export class TeamUserGuard implements CanActivate { diff --git a/backend/src/libs/models/base.model.ts b/backend/src/libs/models/base.model.ts new file mode 100644 index 000000000..94a6a0616 --- /dev/null +++ b/backend/src/libs/models/base.model.ts @@ -0,0 +1,3 @@ +export default class BaseModel { + _id?: string; +} diff --git a/backend/src/libs/repositories/interfaces/base.repository.interface.ts b/backend/src/libs/repositories/interfaces/base.repository.interface.ts index 6fdca55fb..43ebe19fb 100644 --- a/backend/src/libs/repositories/interfaces/base.repository.interface.ts +++ b/backend/src/libs/repositories/interfaces/base.repository.interface.ts @@ -1,18 +1,38 @@ -import { UpdateQuery } from 'mongoose'; +import { PopulateOptions, UpdateQuery } from 'mongoose'; import { ModelProps, SelectedValues } from '../types'; +export type PopulateType = PopulateOptions | (PopulateOptions | string)[]; + export interface BaseInterfaceRepository { - getAll(selectedValues?: SelectedValues): Promise; + findAll(selectedValues?: SelectedValues): Promise; + + findOneById(id: any, selectedValues?: SelectedValues, populate?: PopulateType): Promise; - get(id: string, selectedValues?: SelectedValues): Promise; + findAllWithQuery( + query: any, + selectedValues?: SelectedValues, + populate?: PopulateType + ): Promise; + + findOneByField(fields: ModelProps): Promise; create(item: T): Promise; - update(id: string, item: T); + update(id: string, item: T): Promise; - getByProp(value: ModelProps): Promise; + deleteMany(field: ModelProps, withSession: boolean): Promise; countDocuments(): Promise; findOneByFieldAndUpdate(value: ModelProps, query: UpdateQuery): Promise; + + findOneAndRemoveByField(fields: ModelProps, withSession: boolean): Promise; + + startTransaction(): Promise; + + commitTransaction(): Promise; + + abortTransaction(): Promise; + + endSession(): Promise; } diff --git a/backend/src/libs/repositories/mongo/mongo-generic.repository.ts b/backend/src/libs/repositories/mongo/mongo-generic.repository.ts index 8d08af18a..26a2f0bcc 100644 --- a/backend/src/libs/repositories/mongo/mongo-generic.repository.ts +++ b/backend/src/libs/repositories/mongo/mongo-generic.repository.ts @@ -1,45 +1,101 @@ -import { Model, UpdateQuery } from 'mongoose'; -import { BaseInterfaceRepository } from '../interfaces/base.repository.interface'; +import { ClientSession, Model, UpdateQuery } from 'mongoose'; +import { BaseInterfaceRepository, PopulateType } from '../interfaces/base.repository.interface'; import { ModelProps, SelectedValues } from '../types'; export class MongoGenericRepository implements BaseInterfaceRepository { - private _repository: Model; - private _populateOnFind: string[]; + protected _repository: Model; + protected _session: ClientSession; - constructor(repository: Model, populateOnFind: string[] = []) { + constructor(repository: Model) { this._repository = repository; - this._populateOnFind = populateOnFind; } - getAll(selectedValues?: SelectedValues): Promise { - return this._repository.find().select(selectedValues).populate(this._populateOnFind).exec(); + countDocuments(): Promise { + return this._repository.countDocuments().lean().exec(); + } + + findAll(selectedValues?: SelectedValues, populate?: PopulateType): Promise { + return this._repository.find().select(selectedValues).populate(populate).exec(); } - get(id: any, selectedValues?: SelectedValues): Promise { + findOneById(id: any, selectedValues?: SelectedValues, populate?: PopulateType): Promise { return this._repository .findById(id) .select(selectedValues) - .populate(this._populateOnFind) + .populate(populate) .exec() as Promise; } - getByProp(value: ModelProps): Promise { + findOneByField(value: ModelProps): Promise { return this._repository.findOne(value).exec(); } + findAllWithQuery( + query: any, + selectedValues?: SelectedValues, + populate?: PopulateType + ): Promise { + return this._repository + .find(query) + .select(selectedValues) + .populate(populate) + .lean({ virtuals: true }) + .exec() as unknown as Promise; + } + create(item: T): Promise { return this._repository.create(item); } - update(id: string, item: T) { - return this._repository.findByIdAndUpdate(id, item); + update(id: string, item: T): Promise { + return this._repository.findByIdAndUpdate(id, item).exec(); } - countDocuments(): Promise { - return this._repository.countDocuments().exec(); + findOneByFieldAndUpdate(value: ModelProps, query: UpdateQuery): Promise { + return this._repository.findOneAndUpdate(value, query, { new: true }).exec(); } - findOneByFieldAndUpdate(value: ModelProps, query: UpdateQuery): Promise { - return this._repository.findOneAndUpdate(value, query).exec(); + findOneAndRemove(id: string, withSession = false): Promise { + return this._repository + .findOneAndRemove( + { + _id: id + }, + { session: withSession ? this._session : undefined } + ) + .exec(); + } + + findOneAndRemoveByField(fields: ModelProps, withSession: boolean): Promise { + return this._repository + .findOneAndRemove(fields, { + session: withSession ? this._session : undefined + }) + .exec(); + } + + async deleteMany(field: ModelProps, withSession = false): Promise { + const { deletedCount } = await this._repository + .deleteMany(field, { session: withSession ? this._session : undefined }) + .exec(); + + return deletedCount; + } + + async startTransaction() { + this._session = await this._repository.db.startSession(); + this._session.startTransaction(); + } + + async commitTransaction() { + await this._session.commitTransaction(); + } + + async abortTransaction() { + await this._session.abortTransaction(); + } + + async endSession() { + await this._session.endSession(); } } diff --git a/backend/src/modules/auth/controller/auth.controller.spec.ts b/backend/src/modules/auth/controller/auth.controller.spec.ts index db290bd61..400aaae52 100644 --- a/backend/src/modules/auth/controller/auth.controller.spec.ts +++ b/backend/src/modules/auth/controller/auth.controller.spec.ts @@ -18,7 +18,13 @@ import { import AuthController from 'src/modules/auth/controller/auth.controller'; import { getBoardApplication, getBoardService } from 'src/modules/boards/boards.providers'; import EmailModule from 'src/modules/mailer/mailer.module'; -import { createTeamService, getTeamApplication, getTeamService } from 'src/modules/teams/providers'; +import { + createTeamService, + getTeamApplication, + getTeamService, + teamRepository, + teamUserRepository +} from 'src/modules/teams/providers'; import { createUserService, getUserApplication, @@ -58,6 +64,8 @@ describe('AuthController', () => { getUserApplication, getUserService, userRepository, + teamRepository, + teamUserRepository, ConfigService, { provide: ConfigService, diff --git a/backend/src/modules/auth/services/validate-user.auth.service.spec.ts b/backend/src/modules/auth/services/validate-user.auth.service.spec.ts index ac9425988..28fd0e28f 100644 --- a/backend/src/modules/auth/services/validate-user.auth.service.spec.ts +++ b/backend/src/modules/auth/services/validate-user.auth.service.spec.ts @@ -7,7 +7,7 @@ import configService from 'src/libs/test-utils/mocks/configService.mock'; import jwtService from 'src/libs/test-utils/mocks/jwtService.mock'; import mockedUser from 'src/libs/test-utils/mocks/user.mock'; import ValidateUserAuthServiceImpl from 'src/modules/auth/services/validate-user.auth.service'; -import { getTeamService } from 'src/modules/teams/providers'; +import { getTeamService, teamRepository, teamUserRepository } from 'src/modules/teams/providers'; import { GetUserService } from 'src/modules/users/interfaces/services/get.user.service.interface'; import { TYPES } from 'src/modules/users/interfaces/types'; import { getUserService, userRepository } from 'src/modules/users/users.providers'; @@ -38,6 +38,8 @@ describe('The AuthenticationService', () => { getUserService, getTeamService, userRepository, + teamRepository, + teamUserRepository, { provide: ConfigService, useValue: configService diff --git a/backend/src/modules/boards/applications/delete.board.application.ts b/backend/src/modules/boards/applications/delete.board.application.ts index a118545b5..fa06c6e54 100644 --- a/backend/src/modules/boards/applications/delete.board.application.ts +++ b/backend/src/modules/boards/applications/delete.board.application.ts @@ -1,13 +1,13 @@ import { Inject, Injectable } from '@nestjs/common'; import { DeleteBoardApplicationInterface } from '../interfaces/applications/delete.board.application.interface'; -import { DeleteBoardService } from '../interfaces/services/delete.board.service.interface'; +import { DeleteBoardServiceInterface } from '../interfaces/services/delete.board.service.interface'; import { TYPES } from '../interfaces/types'; @Injectable() export class DeleteBoardApplication implements DeleteBoardApplicationInterface { constructor( @Inject(TYPES.services.DeleteBoardService) - private deleteBoardService: DeleteBoardService + private deleteBoardService: DeleteBoardServiceInterface ) {} delete(boardId: string, userId: string): Promise { diff --git a/backend/src/modules/boards/controller/boards.controller.spec.ts b/backend/src/modules/boards/controller/boards.controller.spec.ts index 029ca30a9..fdc699075 100644 --- a/backend/src/modules/boards/controller/boards.controller.spec.ts +++ b/backend/src/modules/boards/controller/boards.controller.spec.ts @@ -18,7 +18,13 @@ import { deleteSchedulesService } from 'src/modules/schedules/schedules.providers'; import SocketGateway from 'src/modules/socket/gateway/socket.gateway'; -import { createTeamService, getTeamApplication, getTeamService } from 'src/modules/teams/providers'; +import { + createTeamService, + getTeamApplication, + getTeamService, + teamRepository, + teamUserRepository +} from 'src/modules/teams/providers'; describe('BoardsController', () => { let controller: BoardsController; @@ -42,6 +48,8 @@ describe('BoardsController', () => { createTeamService, createSchedulesService, deleteSchedulesService, + teamRepository, + teamUserRepository, { provide: getModelToken('User'), useValue: {} diff --git a/backend/src/modules/boards/interfaces/findQuery.ts b/backend/src/modules/boards/interfaces/findQuery.ts index df816bb11..8c7352a63 100644 --- a/backend/src/modules/boards/interfaces/findQuery.ts +++ b/backend/src/modules/boards/interfaces/findQuery.ts @@ -1,5 +1,5 @@ import { LeanDocument } from 'mongoose'; -import { TeamDocument } from 'src/modules/teams/schemas/teams.schema'; +import Team from 'src/modules/teams/entities/teams.schema'; export type QueryType = { $and: ( @@ -20,7 +20,7 @@ export type QueryType = { } | { team: { - $in?: LeanDocument[]; + $in?: Team[] | string[]; $ne?: undefined | null; }; _id?: undefined; diff --git a/backend/src/modules/boards/interfaces/services/delete.board.service.interface.ts b/backend/src/modules/boards/interfaces/services/delete.board.service.interface.ts index f4607515f..aaa7880ca 100644 --- a/backend/src/modules/boards/interfaces/services/delete.board.service.interface.ts +++ b/backend/src/modules/boards/interfaces/services/delete.board.service.interface.ts @@ -1,4 +1,4 @@ -export interface DeleteBoardService { +export interface DeleteBoardServiceInterface { delete(boardId: string, userId: string): Promise; deleteBoardsByTeamId(teamId: string): Promise; } diff --git a/backend/src/modules/boards/schemas/board.schema.ts b/backend/src/modules/boards/schemas/board.schema.ts index 6b27beb94..5a456e2e0 100644 --- a/backend/src/modules/boards/schemas/board.schema.ts +++ b/backend/src/modules/boards/schemas/board.schema.ts @@ -1,7 +1,7 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { Document, ObjectId, SchemaTypes } from 'mongoose'; import * as leanVirtualsPlugin from 'mongoose-lean-virtuals'; -import Team from 'src/modules/teams/schemas/teams.schema'; +import Team from 'src/modules/teams/entities/teams.schema'; import User from 'src/modules/users/entities/user.schema'; import { ColumnDocument, ColumnSchema } from './column.schema'; diff --git a/backend/src/modules/boards/services/create.board.service.ts b/backend/src/modules/boards/services/create.board.service.ts index 72bf6b385..35d26c997 100644 --- a/backend/src/modules/boards/services/create.board.service.ts +++ b/backend/src/modules/boards/services/create.board.service.ts @@ -20,7 +20,7 @@ import { CreateSchedulesServiceInterface } from 'src/modules/schedules/interface import * as SchedulesType from 'src/modules/schedules/interfaces/types'; import { GetTeamServiceInterface } from 'src/modules/teams/interfaces/services/get.team.service.interface'; import { TYPES as TeamType } from 'src/modules/teams/interfaces/types'; -import TeamUser, { TeamUserDocument } from 'src/modules/teams/schemas/team.user.schema'; +import TeamUser, { TeamUserDocument } from 'src/modules/teams/entities/team.user.schema'; import { UserDocument } from 'src/modules/users/entities/user.schema'; import BoardDto from '../dto/board.dto'; import BoardUserDto from '../dto/board.user.dto'; diff --git a/backend/src/modules/boards/services/delete.board.service.ts b/backend/src/modules/boards/services/delete.board.service.ts index 3537dfc4b..c738ac7ee 100644 --- a/backend/src/modules/boards/services/delete.board.service.ts +++ b/backend/src/modules/boards/services/delete.board.service.ts @@ -14,16 +14,16 @@ import { DeleteSchedulesServiceInterface } from 'src/modules/schedules/interface import * as Schedules from 'src/modules/schedules/interfaces/types'; import { GetTeamServiceInterface } from 'src/modules/teams/interfaces/services/get.team.service.interface'; import * as Teams from 'src/modules/teams/interfaces/types'; -import { TeamUserDocument } from 'src/modules/teams/schemas/team.user.schema'; +import { TeamUserDocument } from 'src/modules/teams/entities/team.user.schema'; import { UserDocument } from 'src/modules/users/entities/user.schema'; -import { DeleteBoardService } from '../interfaces/services/delete.board.service.interface'; +import { DeleteBoardServiceInterface } from '../interfaces/services/delete.board.service.interface'; import Board, { BoardDocument } from '../schemas/board.schema'; import BoardUser, { BoardUserDocument } from '../schemas/board.user.schema'; import * as Boards from 'src/modules/boards/interfaces/types'; import { GetBoardServiceInterface } from '../interfaces/services/get.board.service.interface'; @Injectable() -export default class DeleteBoardServiceImpl implements DeleteBoardService { +export default class DeleteBoardServiceImpl implements DeleteBoardServiceInterface { constructor( @InjectModel(Board.name) private boardModel: Model, diff --git a/backend/src/modules/boards/services/get.board.service.spec.ts b/backend/src/modules/boards/services/get.board.service.spec.ts index 95a54b95b..b2b01a56f 100644 --- a/backend/src/modules/boards/services/get.board.service.spec.ts +++ b/backend/src/modules/boards/services/get.board.service.spec.ts @@ -6,7 +6,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { Document, LeanDocument } from 'mongoose'; import Board from 'src/modules/boards/schemas/board.schema'; import GetBoardServiceImpl from 'src/modules/boards/services/get.board.service'; -import { getTeamService } from 'src/modules/teams/providers'; +import { getTeamService, teamRepository, teamUserRepository } from 'src/modules/teams/providers'; import { getBoardService } from '../boards.providers'; describe('GetBoardServiceImpl', () => { @@ -17,6 +17,8 @@ describe('GetBoardServiceImpl', () => { providers: [ getTeamService, getBoardService, + teamUserRepository, + teamRepository, { provide: getModelToken('Team'), useValue: {} diff --git a/backend/src/modules/boards/services/update.board.service.ts b/backend/src/modules/boards/services/update.board.service.ts index bfbc6b4f4..24f326350 100644 --- a/backend/src/modules/boards/services/update.board.service.ts +++ b/backend/src/modules/boards/services/update.board.service.ts @@ -18,7 +18,7 @@ import { CommunicationServiceInterface } from 'src/modules/communication/interfa import * as CommunicationsType from 'src/modules/communication/interfaces/types'; import { GetTeamServiceInterface } from 'src/modules/teams/interfaces/services/get.team.service.interface'; import * as Teams from 'src/modules/teams/interfaces/types'; -import { TeamUserDocument } from 'src/modules/teams/schemas/team.user.schema'; +import { TeamUserDocument } from 'src/modules/teams/entities/team.user.schema'; import User, { UserDocument } from 'src/modules/users/entities/user.schema'; import { UpdateBoardDto } from '../dto/update-board.dto'; import { ResponsibleType } from '../interfaces/responsible.interface'; diff --git a/backend/src/modules/schedules/services/create.schedules.service.ts b/backend/src/modules/schedules/services/create.schedules.service.ts index da50bab96..223439363 100644 --- a/backend/src/modules/schedules/services/create.schedules.service.ts +++ b/backend/src/modules/schedules/services/create.schedules.service.ts @@ -64,12 +64,19 @@ export class CreateSchedulesService implements CreateSchedulesServiceInterface { team: String(teamId), owner: String(ownerId), maxUsers: maxUsersPerTeam, - willRunAt: new Date(new Date().getFullYear(), month, day, 10).toISOString() + willRunAt: new Date( + new Date().getUTCMonth() === 11 && month == 0 + ? new Date().getFullYear() + 1 + : new Date().getFullYear(), + month, + day, + 10 + ).toISOString() }); if (!cronJobDoc) throw Error('CronJob not created'); - const job = new CronJob(`0 10 18 10 *`, () => - // const job = new CronJob(`0 10 ${day} ${month} *`, () => + + const job = new CronJob(`0 10 ${day} ${month} *`, () => this.handleComplete(String(ownerId), teamId, cronJobDoc.board.toString()) ); this.schedulerRegistry.addCronJob(String(boardId), job); diff --git a/backend/src/modules/teams/schemas/team.user.schema.ts b/backend/src/modules/teams/entities/team.user.schema.ts similarity index 83% rename from backend/src/modules/teams/schemas/team.user.schema.ts rename to backend/src/modules/teams/entities/team.user.schema.ts index 6f30149ff..88269e032 100644 --- a/backend/src/modules/teams/schemas/team.user.schema.ts +++ b/backend/src/modules/teams/entities/team.user.schema.ts @@ -2,13 +2,14 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { Document, ObjectId, SchemaTypes } from 'mongoose'; import * as leanVirtualsPlugin from 'mongoose-lean-virtuals'; import { TeamRoles } from 'src/libs/enum/team.roles'; +import BaseModel from 'src/libs/models/base.model'; import User from 'src/modules/users/entities/user.schema'; import Team from './teams.schema'; export type TeamUserDocument = TeamUser & Document; @Schema() -export default class TeamUser { +export default class TeamUser extends BaseModel { @Prop({ nullable: false, type: String, @@ -20,13 +21,13 @@ export default class TeamUser { type: Boolean, nullable: false }) - isNewJoiner!: boolean; + isNewJoiner?: boolean; @Prop({ type: SchemaTypes.ObjectId, ref: 'User', nullable: false }) - user!: User | ObjectId; + user!: User | ObjectId | string; @Prop({ type: SchemaTypes.ObjectId, ref: 'Team', nullable: false }) - team!: Team | ObjectId; + team?: Team | ObjectId | string; } export const TeamUserSchema = SchemaFactory.createForClass(TeamUser); diff --git a/backend/src/modules/teams/schemas/teams.schema.ts b/backend/src/modules/teams/entities/teams.schema.ts similarity index 82% rename from backend/src/modules/teams/schemas/teams.schema.ts rename to backend/src/modules/teams/entities/teams.schema.ts index ccf85476f..02abcc9d8 100644 --- a/backend/src/modules/teams/schemas/teams.schema.ts +++ b/backend/src/modules/teams/entities/teams.schema.ts @@ -1,7 +1,9 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { Document } from 'mongoose'; import * as leanVirtualsPlugin from 'mongoose-lean-virtuals'; +import BaseModel from 'src/libs/models/base.model'; import Board from '../../boards/schemas/board.schema'; +import TeamUser from './team.user.schema'; export type TeamDocument = Team & Document; @@ -10,11 +12,13 @@ export type TeamDocument = Team & Document; toJSON: { virtuals: true }, toObject: { virtuals: true } }) -export default class Team { +export default class Team extends BaseModel { @Prop({ nullable: false }) name!: string; boards?: Board[]; + + users?: TeamUser[]; } export const TeamSchema = SchemaFactory.createForClass(Team); diff --git a/backend/src/modules/teams/interfaces/applications/create.team.application.interface.ts b/backend/src/modules/teams/interfaces/applications/create.team.application.interface.ts index 2477c6ead..81915fc58 100644 --- a/backend/src/modules/teams/interfaces/applications/create.team.application.interface.ts +++ b/backend/src/modules/teams/interfaces/applications/create.team.application.interface.ts @@ -1,10 +1,10 @@ import { CreateTeamDto } from '../../dto/crate-team.dto'; import TeamUserDto from '../../dto/team.user.dto'; -import { TeamUserDocument } from '../../schemas/team.user.schema'; -import { TeamDocument } from '../../schemas/teams.schema'; +import TeamUser from '../../entities/team.user.schema'; +import Team from '../../entities/teams.schema'; export interface CreateTeamApplicationInterface { - createTeamUser(teamUser: TeamUserDto): Promise; + createTeamUser(teamUser: TeamUserDto): Promise; - create(teamData: CreateTeamDto): Promise; + create(teamData: CreateTeamDto): Promise; } diff --git a/backend/src/modules/teams/interfaces/applications/get.team.application.interface.ts b/backend/src/modules/teams/interfaces/applications/get.team.application.interface.ts index ad5f4077d..60fef74bc 100644 --- a/backend/src/modules/teams/interfaces/applications/get.team.application.interface.ts +++ b/backend/src/modules/teams/interfaces/applications/get.team.application.interface.ts @@ -1,6 +1,6 @@ import { LeanDocument } from 'mongoose'; import { TeamQueryParams } from 'src/libs/dto/param/team.query.params'; -import { TeamDocument } from '../../schemas/teams.schema'; +import { TeamDocument } from '../../entities/teams.schema'; export interface GetTeamApplicationInterface { countTeams(userId: string): Promise; diff --git a/backend/src/modules/teams/interfaces/applications/update.team.application.interface.ts b/backend/src/modules/teams/interfaces/applications/update.team.application.interface.ts index 4219c06b7..7b6bd6c61 100644 --- a/backend/src/modules/teams/interfaces/applications/update.team.application.interface.ts +++ b/backend/src/modules/teams/interfaces/applications/update.team.application.interface.ts @@ -1,6 +1,6 @@ import { LeanDocument } from 'mongoose'; import TeamUserDto from '../../dto/team.user.dto'; -import { TeamUserDocument } from '../../schemas/team.user.schema'; +import { TeamUserDocument } from '../../entities/team.user.schema'; export interface UpdateTeamApplicationInterface { updateTeamUser(teamData: TeamUserDto): Promise | null>; diff --git a/backend/src/modules/teams/interfaces/services/create.team.service.interface.ts b/backend/src/modules/teams/interfaces/services/create.team.service.interface.ts index 7fd6d84f6..27cdcc268 100644 --- a/backend/src/modules/teams/interfaces/services/create.team.service.interface.ts +++ b/backend/src/modules/teams/interfaces/services/create.team.service.interface.ts @@ -1,12 +1,12 @@ import TeamDto from '../../dto/team.dto'; import TeamUserDto from '../../dto/team.user.dto'; -import { TeamUserDocument } from '../../schemas/team.user.schema'; -import { TeamDocument } from '../../schemas/teams.schema'; +import TeamUser from '../../entities/team.user.schema'; +import Team from '../../entities/teams.schema'; export interface CreateTeamServiceInterface { - create(teamData: TeamDto): Promise; + create(teamData: TeamDto): Promise; - createTeam(name: string): Promise; + createTeam(name: string): Promise; - createTeamUser(teamUser: TeamUserDto): Promise; + createTeamUser(teamUser: TeamUserDto): Promise; } diff --git a/backend/src/modules/teams/interfaces/services/get.team.service.interface.ts b/backend/src/modules/teams/interfaces/services/get.team.service.interface.ts index 78a21155c..961b38ff4 100644 --- a/backend/src/modules/teams/interfaces/services/get.team.service.interface.ts +++ b/backend/src/modules/teams/interfaces/services/get.team.service.interface.ts @@ -1,7 +1,7 @@ import { LeanDocument } from 'mongoose'; import { TeamQueryParams } from 'src/libs/dto/param/team.query.params'; -import { TeamUserDocument } from '../../schemas/team.user.schema'; -import { TeamDocument } from '../../schemas/teams.schema'; +import TeamUser from '../../entities/team.user.schema'; +import Team from '../../entities/teams.schema'; import { UserWithTeams } from '../../../users/interfaces/type-user-with-teams'; export interface GetTeamServiceInterface { @@ -9,18 +9,15 @@ export interface GetTeamServiceInterface { countAllTeams(): Promise; - getTeamsOfUser(userId: string): Promise[]>; + getTeamsOfUser(userId: string): Promise; - getTeam( - teamId: string, - teamQueryParams?: TeamQueryParams - ): Promise | null>; + getTeam(teamId: string, teamQueryParams?: TeamQueryParams): Promise; - getUsersOfTeam(teamId: string): Promise[]>; + getUsersOfTeam(teamId: string): Promise; - getTeamUser(userId: string, teamId: string): Promise | null>; + getTeamUser(userId: string, teamId: string): Promise; - getAllTeams(): Promise[]>; + getAllTeams(): Promise[]>; - getUsersOnlyWithTeams(): Promise[]>; + getUsersOnlyWithTeams(): Promise; } diff --git a/backend/src/modules/teams/interfaces/services/update.team.service.interface.ts b/backend/src/modules/teams/interfaces/services/update.team.service.interface.ts index be73657cd..b6330823b 100644 --- a/backend/src/modules/teams/interfaces/services/update.team.service.interface.ts +++ b/backend/src/modules/teams/interfaces/services/update.team.service.interface.ts @@ -1,6 +1,6 @@ import { LeanDocument } from 'mongoose'; import TeamUserDto from '../../dto/team.user.dto'; -import { TeamUserDocument } from '../../schemas/team.user.schema'; +import { TeamUserDocument } from '../../entities/team.user.schema'; export interface UpdateTeamServiceInterface { updateTeamUser(teamData: TeamUserDto): Promise | null>; diff --git a/backend/src/modules/teams/interfaces/types.ts b/backend/src/modules/teams/interfaces/types.ts index 889d462ca..2325ed919 100644 --- a/backend/src/modules/teams/interfaces/types.ts +++ b/backend/src/modules/teams/interfaces/types.ts @@ -11,5 +11,9 @@ export const TYPES = { UpdateTeamApplication: 'UpdateTeamApplication', DeleteTeamApplication: 'DeleteTeamApplication' // UpdateBoardApplication: 'UpdateBoardApplication', + }, + repositories: { + TeamRepository: 'TeamRepository', + TeamUserRepository: 'TeamUserRepository' } }; diff --git a/backend/src/modules/teams/providers.ts b/backend/src/modules/teams/providers.ts index d2cad2429..e94afbbfb 100644 --- a/backend/src/modules/teams/providers.ts +++ b/backend/src/modules/teams/providers.ts @@ -3,6 +3,8 @@ import { DeleteTeamApplication } from './applications/delete.team.application'; import { GetTeamApplication } from './applications/get.team.application'; import { UpdateTeamApplication } from './applications/update.team.application'; import { TYPES } from './interfaces/types'; +import { TeamUserRepository } from './repositories/team-user.repository'; +import { TeamRepository } from './repositories/team.repository'; import CreateTeamService from './services/create.team.service'; import DeleteTeamService from './services/delete.team.service'; import GetTeamService from './services/get.team.service'; @@ -47,3 +49,13 @@ export const deleteTeamApplication = { provide: TYPES.applications.DeleteTeamApplication, useClass: DeleteTeamApplication }; + +export const teamRepository = { + provide: TYPES.repositories.TeamRepository, + useClass: TeamRepository +}; + +export const teamUserRepository = { + provide: TYPES.repositories.TeamUserRepository, + useClass: TeamUserRepository +}; diff --git a/backend/src/modules/teams/repositories/team-user.repository.interface.ts b/backend/src/modules/teams/repositories/team-user.repository.interface.ts new file mode 100644 index 000000000..83eaa81bf --- /dev/null +++ b/backend/src/modules/teams/repositories/team-user.repository.interface.ts @@ -0,0 +1,12 @@ +import { BaseInterfaceRepository } from 'src/libs/repositories/interfaces/base.repository.interface'; +import { UserWithTeams } from 'src/modules/users/interfaces/type-user-with-teams'; +import TeamUserDto from '../dto/team.user.dto'; +import TeamUser from '../entities/team.user.schema'; + +export interface TeamUserRepositoryInterface extends BaseInterfaceRepository { + countTeamsOfUser(userId: string): Promise; + getAllTeamsOfUser(userId: string): Promise; + getUsersOnlyWithTeams(): Promise; + getUsersOfTeam(teamId: string); + updateTeamUser(teamData: TeamUserDto): Promise; +} diff --git a/backend/src/modules/teams/repositories/team-user.repository.ts b/backend/src/modules/teams/repositories/team-user.repository.ts new file mode 100644 index 000000000..7f76c3923 --- /dev/null +++ b/backend/src/modules/teams/repositories/team-user.repository.ts @@ -0,0 +1,94 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { MongoGenericRepository } from 'src/libs/repositories/mongo/mongo-generic.repository'; +import { UserWithTeams } from 'src/modules/users/interfaces/type-user-with-teams'; +import TeamUserDto from '../dto/team.user.dto'; +import TeamUser, { TeamUserDocument } from '../entities/team.user.schema'; +import { TeamUserRepositoryInterface } from './team-user.repository.interface'; + +@Injectable() +export class TeamUserRepository + extends MongoGenericRepository + implements TeamUserRepositoryInterface +{ + constructor(@InjectModel(TeamUser.name) private model: Model) { + super(model); + } + + countTeamsOfUser(userId: string) { + return this._repository.find({ user: userId }).distinct('team').count().exec(); + } + + updateTeamUser(teamData: TeamUserDto): Promise { + return this.findOneByFieldAndUpdate( + { user: teamData.user, team: teamData.team }, + { $set: { role: teamData.role, isNewJoiner: teamData.isNewJoiner } } + ); + } + + getAllTeamsOfUser(userId: string): Promise { + return this._repository.find({ user: userId }).distinct('team').exec(); + } + + getUsersOfTeam(teamId: string) { + return this.findAllWithQuery({ team: teamId }, undefined, { + path: 'user', + select: '_id firstName lastName email isSAdmin' + }); + } + + getUsersOnlyWithTeams(): Promise { + return this._repository + .aggregate([ + { + $lookup: { + from: 'users', + localField: 'user', + foreignField: '_id', + as: 'user' + } + }, + { + $lookup: { + from: 'teams', + localField: 'team', + foreignField: '_id', + as: 'teams' + } + }, + { + $unwind: { path: '$user' } + }, + { + $unwind: { path: '$teams' } + }, + + { + $group: { + _id: '$user', + teamsName: { $push: '$teams.name' } + } + }, + { + $set: { userWithTeam: '$_id' } + }, + { + $unset: [ + '_id', + 'user.currentHashedRefreshToken', + 'user.isSAdmin', + 'user.joinedAt', + 'user.isDeleted' + ] + }, + { + $project: { + user: '$userWithTeam', + teamsNames: '$teamsName' + } + } + ]) + .exec(); + } +} diff --git a/backend/src/modules/teams/repositories/team.repository.interface.ts b/backend/src/modules/teams/repositories/team.repository.interface.ts new file mode 100644 index 000000000..dad37bdb2 --- /dev/null +++ b/backend/src/modules/teams/repositories/team.repository.interface.ts @@ -0,0 +1,8 @@ +import { BaseInterfaceRepository } from 'src/libs/repositories/interfaces/base.repository.interface'; +import Team from '../entities/teams.schema'; + +export interface TeamRepositoryInterface extends BaseInterfaceRepository { + getTeam(teamId: string): Promise; + getTeamsWithUsers(teamIds: string[]): Promise; + getAllTeams(): Promise; +} diff --git a/backend/src/modules/teams/repositories/team.repository.ts b/backend/src/modules/teams/repositories/team.repository.ts new file mode 100644 index 000000000..f8f8d8cba --- /dev/null +++ b/backend/src/modules/teams/repositories/team.repository.ts @@ -0,0 +1,59 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { MongoGenericRepository } from 'src/libs/repositories/mongo/mongo-generic.repository'; +import Team, { TeamDocument } from '../entities/teams.schema'; +import { TeamRepositoryInterface } from './team.repository.interface'; + +@Injectable() +export class TeamRepository + extends MongoGenericRepository + implements TeamRepositoryInterface +{ + constructor(@InjectModel(Team.name) private model: Model) { + super(model); + } + + getTeam(teamId: string): Promise { + return this.findOneById( + teamId, + { _id: 1, name: 1 }, + { + path: 'users', + select: 'user role isNewJoiner', + populate: { + path: 'user', + select: '_id firstName lastName email joinedAt' + } + } + ); + } + + getTeamsWithUsers(teamIds: string[]): Promise { + return this.findAllWithQuery({ _id: { $in: teamIds } }, { _id: 1, name: 1 }, [ + { + path: 'users', + select: 'user role', + populate: { + path: 'user', + select: '_id firstName lastName email joinedAt' + } + }, + { + path: 'boards', + select: '_id' + } + ]); + } + + getAllTeams(): Promise { + return this.findAllWithQuery(null, null, { + path: 'users', + select: 'user role email', + populate: { + path: 'user', + select: '_id firstName lastName email joinedAt' + } + }); + } +} diff --git a/backend/src/modules/teams/services/create.team.service.ts b/backend/src/modules/teams/services/create.team.service.ts index bbe170ff6..041f30d28 100644 --- a/backend/src/modules/teams/services/create.team.service.ts +++ b/backend/src/modules/teams/services/create.team.service.ts @@ -1,44 +1,48 @@ -import { Injectable } from '@nestjs/common'; -import { InjectModel } from '@nestjs/mongoose'; -import { Model } from 'mongoose'; +import { Inject, Injectable } from '@nestjs/common'; import isEmpty from 'src/libs/utils/isEmpty'; import { CreateTeamDto } from '../dto/crate-team.dto'; import TeamUserDto from '../dto/team.user.dto'; import { CreateTeamServiceInterface } from '../interfaces/services/create.team.service.interface'; -import TeamUser, { TeamUserDocument } from '../schemas/team.user.schema'; -import Team, { TeamDocument } from '../schemas/teams.schema'; +import TeamUser from '../entities/team.user.schema'; +import { TeamRepositoryInterface } from '../repositories/team.repository.interface'; +import { TeamUserRepositoryInterface } from '../repositories/team-user.repository.interface'; +import { TYPES } from '../interfaces/types'; @Injectable() export default class CreateTeamService implements CreateTeamServiceInterface { constructor( - @InjectModel(Team.name) private teamModel: Model, - @InjectModel(TeamUser.name) private teamUserModel: Model + @Inject(TYPES.repositories.TeamRepository) + private readonly teamRepository: TeamRepositoryInterface, + @Inject(TYPES.repositories.TeamUserRepository) + private readonly teamUserRepository: TeamUserRepositoryInterface ) {} - async createTeamUsers(teamUsers: TeamUserDto[], teamId: string) { - await Promise.all( - teamUsers.map((user) => this.teamUserModel.create({ ...user, team: teamId })) + createTeamUsers(teamUsers: TeamUserDto[], teamId: string) { + return Promise.all( + teamUsers.map((user) => this.teamUserRepository.create({ ...user, team: teamId })) ); } createTeamUser(teamUser: TeamUserDto) { - return this.teamUserModel.create({ ...teamUser }); + return this.teamUserRepository.create({ ...teamUser }); } createTeam(name: string) { - return this.teamModel.create({ name }); + return this.teamRepository.create({ name }); } async create(teamData: CreateTeamDto) { const { users, name } = teamData; - const newTeam = await this.teamModel.create({ + const newTeam = await this.teamRepository.create({ name }); + let teamUsers: TeamUser[] = []; + if (!isEmpty(users)) { - await this.createTeamUsers(users, newTeam._id); + teamUsers = await this.createTeamUsers(users, newTeam._id); } - return newTeam.populate('users'); + return { ...newTeam, users: teamUsers }; } } diff --git a/backend/src/modules/teams/services/delete.team.service.ts b/backend/src/modules/teams/services/delete.team.service.ts index 53aa06c2c..abd6b0fb4 100644 --- a/backend/src/modules/teams/services/delete.team.service.ts +++ b/backend/src/modules/teams/services/delete.team.service.ts @@ -1,68 +1,65 @@ import { BadRequestException, Inject, Injectable, NotFoundException } from '@nestjs/common'; -import { InjectModel } from '@nestjs/mongoose'; -import { ClientSession, Model } from 'mongoose'; import { DELETE_FAILED } from 'src/libs/exceptions/messages'; import { DeleteTeamServiceInterface } from '../interfaces/services/delete.team.service.interface'; -import TeamUser, { TeamUserDocument } from '../schemas/team.user.schema'; -import Team, { TeamDocument } from '../schemas/teams.schema'; -import * as Boards from 'src/modules/boards/interfaces/types'; -import { DeleteBoardService } from 'src/modules/boards/interfaces/services/delete.board.service.interface'; +import { TYPES } from '../interfaces/types'; +import { TeamRepositoryInterface } from '../repositories/team.repository.interface'; +import { TeamUserRepositoryInterface } from '../repositories/team-user.repository.interface'; +import * as Boards from '../../boards/interfaces/types'; +import { DeleteBoardServiceInterface } from 'src/modules/boards/interfaces/services/delete.board.service.interface'; @Injectable() export default class DeleteTeamService implements DeleteTeamServiceInterface { constructor( - @InjectModel(Team.name) private teamModel: Model, - @InjectModel(TeamUser.name) private teamUserModel: Model, + @Inject(TYPES.repositories.TeamRepository) + private readonly teamRepository: TeamRepositoryInterface, + @Inject(TYPES.repositories.TeamUserRepository) + private readonly teamUserRepository: TeamUserRepositoryInterface, @Inject(Boards.TYPES.services.DeleteBoardService) - private deleteBoardService: DeleteBoardService + private deleteBoardService: DeleteBoardServiceInterface ) {} async delete(teamId: string): Promise { - const teamSession = await this.teamModel.db.startSession(); - teamSession.startTransaction(); - const teamUserSession = await this.teamUserModel.db.startSession(); - teamUserSession.startTransaction(); + await this.teamRepository.startTransaction(); + await this.teamUserRepository.startTransaction(); try { - await this.deleteTeam(teamId, teamSession); - await this.deleteTeamUsers(teamId, teamUserSession); + await this.deleteTeam(teamId, true); + await this.deleteTeamUsers(teamId, true); await this.deleteBoardService.deleteBoardsByTeamId(teamId); - await teamSession.commitTransaction(); - await teamUserSession.commitTransaction(); + await this.teamRepository.commitTransaction(); + await this.teamUserRepository.commitTransaction(); return true; } catch (e) { - await teamSession.abortTransaction(); - await teamUserSession.abortTransaction(); + await this.teamRepository.abortTransaction(); + await this.teamUserRepository.abortTransaction(); } finally { - await teamSession.endSession(); - await teamUserSession.endSession(); + await this.teamRepository.endSession(); + await this.teamUserRepository.endSession(); } throw new BadRequestException(DELETE_FAILED); } - private async deleteTeam(teamId: string, teamSession: ClientSession) { - const result = await this.teamModel.findOneAndRemove( + private async deleteTeam(teamId: string, withSession: boolean) { + const result = await this.teamRepository.findOneAndRemoveByField( { _id: teamId }, - { session: teamSession } + withSession ); if (!result) throw new NotFoundException(DELETE_FAILED); } - private async deleteTeamUsers(teamId: string, teamUserSession: ClientSession) { - const { deletedCount } = await this.teamUserModel - .deleteMany( - { - team: teamId - }, - { session: teamUserSession } - ) - .exec(); + private async deleteTeamUsers(teamId: string, withSession: boolean) { + const deletedCount = await this.teamUserRepository.deleteMany( + { + team: teamId + }, + withSession + ); if (deletedCount <= 0) throw new Error(DELETE_FAILED); } diff --git a/backend/src/modules/teams/services/get.team.service.ts b/backend/src/modules/teams/services/get.team.service.ts index d0f44b213..bd60752e4 100644 --- a/backend/src/modules/teams/services/get.team.service.ts +++ b/backend/src/modules/teams/services/get.team.service.ts @@ -1,147 +1,56 @@ -import { Injectable } from '@nestjs/common'; -import { InjectModel } from '@nestjs/mongoose'; -import { LeanDocument, Model } from 'mongoose'; +import { Inject, Injectable } from '@nestjs/common'; import { GetTeamServiceInterface } from '../interfaces/services/get.team.service.interface'; -import { UserWithTeams } from '../../users/interfaces/type-user-with-teams'; -import TeamUser, { TeamUserDocument } from '../schemas/team.user.schema'; -import Team, { TeamDocument } from '../schemas/teams.schema'; +import Team from '../entities/teams.schema'; +import { TYPES } from '../interfaces/types'; +import { TeamRepositoryInterface } from '../repositories/team.repository.interface'; +import { TeamUserRepositoryInterface } from '../repositories/team-user.repository.interface'; @Injectable() export default class GetTeamService implements GetTeamServiceInterface { constructor( - @InjectModel(Team.name) private teamModel: Model, - @InjectModel(TeamUser.name) private teamUserModel: Model + @Inject(TYPES.repositories.TeamRepository) + private readonly teamRepository: TeamRepositoryInterface, + @Inject(TYPES.repositories.TeamUserRepository) + private readonly teamUserRepository: TeamUserRepositoryInterface ) {} - async countTeams(userId: string) { - return this.teamUserModel.find({ user: userId }).distinct('team').count(); + countTeams(userId: string) { + return this.teamUserRepository.countTeamsOfUser(userId); } countAllTeams() { - return this.teamModel.countDocuments().exec(); + return this.teamRepository.countDocuments(); } getTeam(teamId: string) { - const teamModel = this.teamModel.findById(teamId); - - return teamModel - .select('_id name') - .populate({ - path: 'users', - select: 'user role isNewJoiner', - populate: { - path: 'user', - select: '_id firstName lastName email joinedAt' - } - }) - .exec(); + return this.teamRepository.getTeam(teamId); } async getTeamsOfUser(userId: string) { - const teamsUser = await this.teamUserModel.find({ user: userId }).distinct('team'); + const teamsUser = await this.teamUserRepository.getAllTeamsOfUser(userId); - const teams: LeanDocument = await this.teamModel - .find({ _id: { $in: teamsUser } }) - .select('_id name') - .populate({ - path: 'users', - select: 'user role', - populate: { - path: 'user', - select: '_id firstName lastName email joinedAt' - } - }) - .populate({ - path: 'boards', - select: '_id' - }) - .lean({ virtuals: true }) - .exec(); + const teams: Team[] = await this.teamRepository.getTeamsWithUsers( + teamsUser.map((teamUser) => teamUser._id) + ); return teams.map((team) => { return { ...team, boardsCount: team.boards?.length ?? 0, boards: undefined }; }); } - async getUsersOnlyWithTeams() { - const teams: LeanDocument[] = await this.teamUserModel.aggregate([ - { - $lookup: { - from: 'users', - localField: 'user', - foreignField: '_id', - as: 'user' - } - }, - { - $lookup: { - from: 'teams', - localField: 'team', - foreignField: '_id', - as: 'teams' - } - }, - { - $unwind: { path: '$user' } - }, - { - $unwind: { path: '$teams' } - }, - - { - $group: { - _id: '$user', - teamsName: { $push: '$teams.name' } - } - }, - { - $set: { userWithTeam: '$_id' } - }, - { - $unset: [ - '_id', - 'userWithTeam.currentHashedRefreshToken', - 'userWithTeam.joinedAt', - 'userWithTeam.isDeleted' - ] - }, - { - $project: { - user: '$userWithTeam', - teamsNames: '$teamsName' - } - } - ]); - - return teams; + getUsersOnlyWithTeams() { + return this.teamUserRepository.getUsersOnlyWithTeams(); } getTeamUser(userId: string, teamId: string) { - return this.teamUserModel.findOne({ user: userId, team: teamId }).lean().exec(); + return this.teamUserRepository.findOneByField({ user: userId, team: teamId }); } getAllTeams() { - return this.teamModel - .find() - .populate({ - path: 'users', - select: 'user role email', - populate: { - path: 'user', - select: '_id firstName lastName email joinedAt' - } - }) - .lean({ virtuals: true }) - .exec(); + return this.teamRepository.getAllTeams(); } getUsersOfTeam(teamId: string) { - return this.teamUserModel - .find({ team: teamId }) - .populate({ - path: 'user', - select: '_id firstName lastName email isSAdmin' - }) - .exec(); + return this.teamUserRepository.getUsersOfTeam(teamId); } } diff --git a/backend/src/modules/teams/services/update.team.service.ts b/backend/src/modules/teams/services/update.team.service.ts index eb2b94f04..ee951d5f3 100644 --- a/backend/src/modules/teams/services/update.team.service.ts +++ b/backend/src/modules/teams/services/update.team.service.ts @@ -1,22 +1,18 @@ -import { Injectable } from '@nestjs/common'; -import { InjectModel } from '@nestjs/mongoose'; -import { LeanDocument, Model } from 'mongoose'; +import { Inject, Injectable } from '@nestjs/common'; import TeamUserDto from '../dto/team.user.dto'; +import TeamUser from '../entities/team.user.schema'; import { UpdateTeamServiceInterface } from '../interfaces/services/update.team.service.interface'; -import TeamUser, { TeamUserDocument } from '../schemas/team.user.schema'; +import { TYPES } from '../interfaces/types'; +import { TeamUserRepositoryInterface } from '../repositories/team-user.repository.interface'; @Injectable() export default class UpdateTeamService implements UpdateTeamServiceInterface { - constructor(@InjectModel(TeamUser.name) private teamUserModel: Model) {} + constructor( + @Inject(TYPES.repositories.TeamUserRepository) + private readonly teamUserRepository: TeamUserRepositoryInterface + ) {} - updateTeamUser(teamData: TeamUserDto): Promise | null> { - return this.teamUserModel - .findOneAndUpdate( - { user: teamData.user, team: teamData.team }, - { $set: { role: teamData.role, isNewJoiner: teamData.isNewJoiner } }, - { new: true } - ) - .lean() - .exec(); + updateTeamUser(teamData: TeamUserDto): Promise { + return this.teamUserRepository.updateTeamUser(teamData); } } diff --git a/backend/src/modules/teams/teams.module.ts b/backend/src/modules/teams/teams.module.ts index fd9598cc3..79f5ee5aa 100644 --- a/backend/src/modules/teams/teams.module.ts +++ b/backend/src/modules/teams/teams.module.ts @@ -12,6 +12,8 @@ import { deleteTeamService, getTeamApplication, getTeamService, + teamRepository, + teamUserRepository, updateTeamApplication, updateTeamService } from './providers'; @@ -26,7 +28,9 @@ import { updateTeamService, updateTeamApplication, deleteTeamApplication, - deleteTeamService + deleteTeamService, + teamUserRepository, + teamRepository ], controllers: [TeamsController], exports: [getTeamApplication, getTeamService, createTeamService, updateTeamService] diff --git a/backend/src/modules/users/entities/user.schema.ts b/backend/src/modules/users/entities/user.schema.ts index cdd3e9803..e33b6e664 100644 --- a/backend/src/modules/users/entities/user.schema.ts +++ b/backend/src/modules/users/entities/user.schema.ts @@ -1,5 +1,6 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import * as mongoose from 'mongoose'; +import BaseModel from 'src/libs/models/base.model'; export type UserDocument = User & mongoose.Document; @@ -8,9 +9,7 @@ export type UserDocument = User & mongoose.Document; virtuals: true } }) -export default class User { - _id?: string; - +export default class User extends BaseModel { @Prop({ nullable: false }) firstName!: string; diff --git a/backend/src/modules/users/repository/user.repository.ts b/backend/src/modules/users/repository/user.repository.ts index 464141cfd..330318de8 100644 --- a/backend/src/modules/users/repository/user.repository.ts +++ b/backend/src/modules/users/repository/user.repository.ts @@ -13,9 +13,8 @@ export class UserRepository constructor(@InjectModel(User.name) private model: Model) { super(model); } - - getById(userId: string) { - return this.get(userId, { + getById(userId: string): Promise { + return this.findOneById(userId, { password: 0, currentHashedRefreshToken: 0 }); diff --git a/backend/src/modules/users/services/get.user.service.ts b/backend/src/modules/users/services/get.user.service.ts index 4d6e70364..0bb8cab79 100644 --- a/backend/src/modules/users/services/get.user.service.ts +++ b/backend/src/modules/users/services/get.user.service.ts @@ -17,7 +17,7 @@ export default class GetUserServiceImpl implements GetUserService { ) {} getByEmail(email: string) { - return this.userRepository.getByProp({ email }); + return this.userRepository.findOneByField({ email }); } getById(_id: string) { @@ -39,7 +39,7 @@ export default class GetUserServiceImpl implements GetUserService { } getAllUsers() { - return this.userRepository.getAll({ password: 0, currentHashedRefreshToken: 0 }); + return this.userRepository.findAll({ password: 0, currentHashedRefreshToken: 0 }); } async getAllUsersWithTeams() { diff --git a/backend/src/modules/users/services/update.user.service.ts b/backend/src/modules/users/services/update.user.service.ts index 13cafed72..e41401adf 100644 --- a/backend/src/modules/users/services/update.user.service.ts +++ b/backend/src/modules/users/services/update.user.service.ts @@ -41,7 +41,7 @@ export default class updateUserServiceImpl implements UpdateUserService { if (!userFromDb) throw new HttpException('USER_FROM_TOKEN_NOT_FOUND', HttpStatus.NOT_FOUND); this.tokenValidator(userFromDb.updatedAt); - const user = await this.userRepository.getByProp({ email: userFromDb.emailAddress }); + const user = await this.userRepository.findOneByField({ email: userFromDb.emailAddress }); if (!user) throw new HttpException('USER_NOT_FOUND', HttpStatus.NOT_FOUND);