Skip to content

Commit

Permalink
feat: team repository
Browse files Browse the repository at this point in the history
  • Loading branch information
nunocaseiro committed Dec 7, 2022
1 parent ead06d7 commit 038f0a5
Show file tree
Hide file tree
Showing 39 changed files with 438 additions and 247 deletions.
4 changes: 2 additions & 2 deletions backend/src/infrastructure/database/mongoose.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
2 changes: 1 addition & 1 deletion backend/src/libs/guards/teamRoles.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions backend/src/libs/models/base.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default class BaseModel {
_id?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@ import { UpdateQuery } from 'mongoose';
import { ModelProps, SelectedValues } from '../types';

export interface BaseInterfaceRepository<T> {
getAll(selectedValues?: SelectedValues<T>): Promise<T[]>;
findAll(selectedValues?: SelectedValues<T>): Promise<T[]>;

get(id: string, selectedValues?: SelectedValues<T>): Promise<T>;
findOneById(id: any, selectedValues?: SelectedValues<T>, populate?: any): Promise<T>;

findAllWithQuery(query: any, selectedValues?: SelectedValues<T>, populate?: any): Promise<T[]>;

findOneByField(fields: ModelProps<T>): Promise<T>;

create(item: T): Promise<T>;

update(id: string, item: T);

getByProp(value: ModelProps<T>): Promise<T>;
deleteMany(field: ModelProps<T>, withSession: boolean): Promise<number>;

countDocuments(): Promise<number>;

findOneByFieldAndUpdate(value: ModelProps<T>, query: UpdateQuery<T>): Promise<T>;

findOneAndRemoveByField(fields: ModelProps<T>, withSession: boolean): Promise<T>;

startTransaction();

commitTransaction();

abortTransaction();

endSession();
}
83 changes: 69 additions & 14 deletions backend/src/libs/repositories/mongo/mongo-generic.repository.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,47 @@
import { Model, UpdateQuery } from 'mongoose';
import { ClientSession, Model, PopulateOptions, UpdateQuery } from 'mongoose';
import { BaseInterfaceRepository } from '../interfaces/base.repository.interface';
import { ModelProps, SelectedValues } from '../types';

export class MongoGenericRepository<T> implements BaseInterfaceRepository<T> {
private _repository: Model<T>;
private _populateOnFind: string[];
protected _repository: Model<T>;
protected _session: ClientSession;

constructor(repository: Model<T>, populateOnFind: string[] = []) {
constructor(repository: Model<T>) {
this._repository = repository;
this._populateOnFind = populateOnFind;
}

getAll(selectedValues?: SelectedValues<T>): Promise<T[]> {
return this._repository.find().select(selectedValues).populate(this._populateOnFind).exec();
countDocuments(): Promise<number> {
return this._repository.countDocuments().lean().exec();
}

findAll(
selectedValues?: SelectedValues<T>,
populate?: PopulateOptions | (PopulateOptions | string)[]
): Promise<T[]> {
return this._repository.find().select(selectedValues).populate(populate).exec();
}

get(id: any, selectedValues?: SelectedValues<T>): Promise<T> {
findOneById(id: any, selectedValues?: SelectedValues<T>, populate?: any): Promise<T> {
return this._repository
.findById(id)
.select(selectedValues)
.populate(this._populateOnFind)
.populate(populate)
.exec() as Promise<T>;
}

getByProp(value: ModelProps<T>): Promise<T> {
findOneByField(value: ModelProps<T>): Promise<T> {
return this._repository.findOne(value).exec();
}

findAllWithQuery(query: any, selectedValues?: SelectedValues<T>, populate?: any): Promise<T[]> {
return this._repository
.find(query)
.select(selectedValues)
.populate(populate)
.lean({ virtuals: true })
.exec() as unknown as Promise<T[]>;
}

create(item: T): Promise<T> {
return this._repository.create(item);
}
Expand All @@ -35,11 +50,51 @@ export class MongoGenericRepository<T> implements BaseInterfaceRepository<T> {
return this._repository.findByIdAndUpdate(id, item);
}

countDocuments(): Promise<number> {
return this._repository.countDocuments().exec();
findOneByFieldAndUpdate(value: ModelProps<T>, query: UpdateQuery<T>): Promise<T> {
return this._repository.findOneAndUpdate(value, query, { new: true }).exec();
}

findOneByFieldAndUpdate(value: ModelProps<T>, query: UpdateQuery<T>): Promise<T> {
return this._repository.findOneAndUpdate(value, query).exec();
findOneAndRemove(id: string, withSession = false): Promise<T> {
return this._repository
.findOneAndRemove(
{
_id: id
},
{ session: withSession ? this._session : undefined }
)
.exec();
}

findOneAndRemoveByField(fields: ModelProps<T>, withSession: boolean): Promise<T> {
return this._repository
.findOneAndRemove(fields, {
session: withSession ? this._session : undefined
})
.exec();
}

async deleteMany(field: ModelProps<T>, withSession = false): Promise<number> {
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();
}
}
10 changes: 9 additions & 1 deletion backend/src/modules/auth/controller/auth.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -58,6 +64,8 @@ describe('AuthController', () => {
getUserApplication,
getUserService,
userRepository,
teamRepository,
teamUserRepository,
ConfigService,
{
provide: ConfigService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -38,6 +38,8 @@ describe('The AuthenticationService', () => {
getUserService,
getTeamService,
userRepository,
teamRepository,
teamUserRepository,
{
provide: ConfigService,
useValue: configService
Expand Down
Original file line number Diff line number Diff line change
@@ -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<boolean> {
Expand Down
10 changes: 9 additions & 1 deletion backend/src/modules/boards/controller/boards.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -42,6 +48,8 @@ describe('BoardsController', () => {
createTeamService,
createSchedulesService,
deleteSchedulesService,
teamRepository,
teamUserRepository,
{
provide: getModelToken('User'),
useValue: {}
Expand Down
4 changes: 2 additions & 2 deletions backend/src/modules/boards/interfaces/findQuery.ts
Original file line number Diff line number Diff line change
@@ -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: (
Expand All @@ -20,7 +20,7 @@ export type QueryType = {
}
| {
team: {
$in?: LeanDocument<TeamDocument>[];
$in?: Team[] | string[];
$ne?: undefined | null;
};
_id?: undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface DeleteBoardService {
export interface DeleteBoardServiceInterface {
delete(boardId: string, userId: string): Promise<boolean>;
deleteBoardsByTeamId(teamId: string): Promise<boolean>;
}
2 changes: 1 addition & 1 deletion backend/src/modules/boards/schemas/board.schema.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
6 changes: 3 additions & 3 deletions backend/src/modules/boards/services/delete.board.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<BoardDocument>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -17,6 +17,8 @@ describe('GetBoardServiceImpl', () => {
providers: [
getTeamService,
getBoardService,
teamUserRepository,
teamRepository,
{
provide: getModelToken('Team'),
useValue: {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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);
Expand Down
Loading

0 comments on commit 038f0a5

Please sign in to comment.