Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: team repository #661

Merged
merged 3 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
@@ -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<T> {
getAll(selectedValues?: SelectedValues<T>): Promise<T[]>;
findAll(selectedValues?: SelectedValues<T>): Promise<T[]>;

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

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

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

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

update(id: string, item: T);
update(id: string, item: T): Promise<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(): Promise<void>;

commitTransaction(): Promise<void>;

abortTransaction(): Promise<void>;

endSession(): Promise<void>;
}
90 changes: 73 additions & 17 deletions backend/src/libs/repositories/mongo/mongo-generic.repository.ts
Original file line number Diff line number Diff line change
@@ -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<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?: PopulateType): 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?: PopulateType): 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?: PopulateType
): 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);
}

update(id: string, item: T) {
return this._repository.findByIdAndUpdate(id, item);
update(id: string, item: T): Promise<T> {
return this._repository.findByIdAndUpdate(id, item).exec();
}

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
13 changes: 10 additions & 3 deletions backend/src/modules/schedules/services/create.schedules.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading