diff --git a/src/schema.gql b/src/schema.gql index 454ff74..534b5a9 100644 --- a/src/schema.gql +++ b/src/schema.gql @@ -46,3 +46,18 @@ type Query { course(id: String!): Course teams: [Team!] } + +type Mutation { + createTeam(team: CreateTeamInput!): Team! + updateTeam(team: UpdateTeamInput!): Team! +} + +input CreateTeamInput { + tgLink: String! + courseId: String! +} + +input UpdateTeamInput { + id: String! + tgLink: String! +} diff --git a/src/teams/models/team.input-type.ts b/src/teams/models/team.input-type.ts new file mode 100644 index 0000000..a403dc4 --- /dev/null +++ b/src/teams/models/team.input-type.ts @@ -0,0 +1,21 @@ +import { Field, InputType } from '@nestjs/graphql'; + +import { ICreateTeam, IUpdateTeam } from './team.interface'; + +@InputType() +export class CreateTeamInput implements ICreateTeam { + @Field() + public tgLink: string; + + @Field() + public courseId: string; +} + +@InputType() +export class UpdateTeamInput implements IUpdateTeam { + @Field() + public id: string; + + @Field() + public tgLink: string; +} diff --git a/src/teams/models/team.interface.ts b/src/teams/models/team.interface.ts index 18a153b..c68fb07 100644 --- a/src/teams/models/team.interface.ts +++ b/src/teams/models/team.interface.ts @@ -6,3 +6,7 @@ export interface ITeam { tgLink: string; memberIds: string[]; } + +export type ICreateTeam = Pick; + +export type IUpdateTeam = Pick; diff --git a/src/teams/resolvers/teams.resolver.ts b/src/teams/resolvers/teams.resolver.ts index 944abeb..3c53017 100644 --- a/src/teams/resolvers/teams.resolver.ts +++ b/src/teams/resolvers/teams.resolver.ts @@ -3,8 +3,10 @@ import { CoursesService } from 'src/courses/services/courses.service'; import { User } from 'src/users/models/user.object-type'; import { UsersService } from 'src/users/services/users.service'; -import { Parent, Query, ResolveField, Resolver } from '@nestjs/graphql'; +import { Args, Mutation, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql'; +import { CreateTeamInput, UpdateTeamInput } from '../models/team.input-type'; +import { ICreateTeam, IUpdateTeam } from '../models/team.interface'; import { Team } from '../models/team.object-type'; import { TeamsService } from '../services/teams.service'; @@ -34,4 +36,18 @@ export class TeamsResolver { return this.usersService.findByIds(memberIds); } + + @Mutation(() => Team, { name: 'createTeam' }) + public async createTeam( + @Args({ name: 'team', type: () => CreateTeamInput }) team: ICreateTeam, + ): Promise { + return this.teamsService.createTeam(team); + } + + @Mutation(() => Team, { name: 'updateTeam' }) + public async updateTeam( + @Args({ name: 'team', type: () => UpdateTeamInput }) team: IUpdateTeam, + ): Promise { + return this.teamsService.updateTeam(team); + } } diff --git a/src/teams/services/teams.service.ts b/src/teams/services/teams.service.ts index da1068e..d8fa53f 100644 --- a/src/teams/services/teams.service.ts +++ b/src/teams/services/teams.service.ts @@ -4,6 +4,8 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { TeamEntity } from '../models/team.entity'; +import { ICreateTeam, IUpdateTeam } from '../models/team.interface'; +import { getNextTeamNumber } from '../utils/get-next-team-number.util'; @Injectable() export class TeamsService { @@ -19,6 +21,26 @@ export class TeamsService { } public findByIds(ids: string[]): Promise { - return this.teamsRepository.findByIds(ids, { loadRelationIds: true }); + return this.teamsRepository.findByIds(ids, { loadRelationIds: true, order: { number: 'ASC' } }); + } + + public async createTeam(props: ICreateTeam): Promise { + const teams: TeamEntity[] = await this.teamsRepository.find({ courseId: props.courseId }); + const nextNumber: number = getNextTeamNumber(teams); + const password: string = Math.random().toString(36).substr(2, 8); + + const team: TeamEntity = this.teamsRepository.create({ + ...props, + password, + number: nextNumber, + }); + + return this.teamsRepository.save(team); + } + + public async updateTeam(props: IUpdateTeam): Promise { + await this.teamsRepository.update(props.id, { tgLink: props.tgLink }); + + return this.teamsRepository.findOne(props.id); } } diff --git a/src/teams/utils/get-next-team-number.util.ts b/src/teams/utils/get-next-team-number.util.ts new file mode 100644 index 0000000..80ba033 --- /dev/null +++ b/src/teams/utils/get-next-team-number.util.ts @@ -0,0 +1,24 @@ +import { ITeam } from '../models/team.interface'; + +export const getNextTeamNumber: (arr: ITeam[]) => number = (arr: ITeam[]): number => { + let missedNumber: number; + let lastNumber: number; + + const positiveNumbers: number[] = arr.map(item => item.number).sort(); + + if (!positiveNumbers.length) { + return 1; + } + + positiveNumbers.some((element, index) => { + if (element !== index + 1) { + missedNumber = index + 1; + } + + lastNumber = index + 1; + + return missedNumber; + }); + + return missedNumber ?? lastNumber + 1; +};