diff --git a/schema.gql b/schema.gql index bf5c35c9e8362f3861fa70248a75f2db447909e5..eea880cc96d6b0ad7023b4c92dd1de837b94eaf3 100644 --- a/schema.gql +++ b/schema.gql @@ -60,6 +60,25 @@ type BroadcastPlayer { name: String! } +type BroadcastPlayerForChartGame { + player: BroadcastPlayer! + isRight: Boolean! +} + +type BroadcastAnswerForChartGame { + answerID: String! + players: [BroadcastPlayerForChartGame!]! +} + +type BroadcastPlayingGame { + currentTimeSec: Int! + gameCode: String! + startTimeSec: Int! + currentQuestionUUID: String! + gameStatus: GameStatus! + answers: [BroadcastAnswerForChartGame!]! +} + type StartGame { gameCode: String! } @@ -133,4 +152,5 @@ type Subscription { onWaitForJoiningPlayerToGame(gameCode: String!, playerUUID: String!): BroadcastPlayer! onWaitForStartingGame(gameCode: String!, playerUUID: String!): StartGame! onDeletePlayerFromGame(gameCode: String!, playerUUID: String!): BroadcastPlayer! + onPlayingGame(gameCode: String!, playerUUID: String!): BroadcastPlayingGame! } diff --git a/src/app.module.ts b/src/app.module.ts index 3fe967354b0de7aa3c5fb04fcee197a51da278b8..ce83987a15bbbbca35b9a6775bd6a0db98cf063c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -12,6 +12,8 @@ import { GamesModule } from './games/games.module'; import { Game } from './games/models/game.model'; import { PlayersModule } from './players/players.module'; import { Player } from './players/models/player.model'; +import { BroadcastModule } from './broadcast/broadcast.module'; +import { PubSubModule } from './common/modules/pubSub.module'; @Module({ imports: [ @@ -37,6 +39,8 @@ import { Player } from './players/models/player.model'; AnswersModule, GamesModule, PlayersModule, + BroadcastModule, + PubSubModule, ], }) export class AppModule {} diff --git a/src/broadcast/broadcast.module.ts b/src/broadcast/broadcast.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..82b2d7ec08627d3616334b71b82ff426e8009e30 --- /dev/null +++ b/src/broadcast/broadcast.module.ts @@ -0,0 +1,17 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { BroadcastService } from './broadcast.service'; +import { BroadcastRepository } from './broadcast.repository'; +import { QuestionsModule } from '../questions/questions.module'; +import { GamesModule } from '../games/games.module'; +import { QuizzesModule } from '../quizzes/quizzes.module'; + +@Module({ + providers: [BroadcastService, BroadcastRepository], + exports: [BroadcastService], + imports: [ + forwardRef(() => QuestionsModule), + forwardRef(() => GamesModule), + forwardRef(() => QuizzesModule), + ], +}) +export class BroadcastModule {} diff --git a/src/broadcast/broadcast.repository.ts b/src/broadcast/broadcast.repository.ts new file mode 100644 index 0000000000000000000000000000000000000000..ee1ee3c8fd2073b09dfc30602d33d83688f052cd --- /dev/null +++ b/src/broadcast/broadcast.repository.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@nestjs/common'; +import { Game } from '../games/models/game.model'; +import { BroadcastPlayer } from './dto/broadcast-player.type'; +import { GameStatus } from '../games/enums/statuses.enum'; + +@Injectable() +export class BroadcastRepository { + private gameStorage = {}; + + addGame(game: Game): void { + this.gameStorage[game.CODE] = game; + this.gameStorage[game.CODE].answers = []; + } + + addPlayers(players: BroadcastPlayer[], gameCode: string): void { + this.gameStorage[gameCode].players = players; + } + + getGameByCode(code: string) { + return this.gameStorage[code]; + } + + statusUpdate(code: string, status: GameStatus): void { + this.gameStorage[code].status = status; + } + + deleteGame(code: string): void { + if (this.getGameByCode(code)) { + delete this.gameStorage[code]; + } + } +} diff --git a/src/broadcast/broadcast.service.ts b/src/broadcast/broadcast.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..231cc9ca93ad39704b9071a44546958b7f824a21 --- /dev/null +++ b/src/broadcast/broadcast.service.ts @@ -0,0 +1,120 @@ +import { forwardRef, Inject, Injectable } from '@nestjs/common'; +import { Game } from '../games/models/game.model'; +import { BroadcastRepository } from './broadcast.repository'; +import { BroadcastPlayingGame } from './dto/broadcast-playing-game.type'; +import { + GAME_PROCESS_EVENT, + PLAYER_DELETED_EVENT, + TIME_TO_ONE_QUESTION_SEC, +} from '../constants'; +import { GamesService } from '../games/games.service'; +import { Answer } from '../answers/models/answer.model'; +import { Player } from '../players/models/player.model'; +import { BroadcastPlayer } from './dto/broadcast-player.type'; +import { GameStatus } from '../games/enums/statuses.enum'; +import { PUB_SUB } from '../common/modules/pubSub.module'; +import { PubSub } from 'graphql-subscriptions'; +import { DeletePlayerArgs } from '../games/dto/delete-player.args'; +import { BroadcastPlayerForChartGame } from './dto/broadcast-player-chart.type'; +import { BroadcastAnswerForChartGame } from './dto/broadcast-answer.type'; + +@Injectable() +export class BroadcastService { + constructor( + private readonly broadcastRepository: BroadcastRepository, + @Inject(forwardRef(() => GamesService)) + private readonly gamesService: GamesService, + @Inject(PUB_SUB) + private readonly pubSub: PubSub, + ) {} + + addGameToStorage(game: Game) { + this.broadcastRepository.addGame(game); + } + + addAnswer(answer: Answer, player: Player) { + const game = this.broadcastRepository.getGameByCode(player.game.CODE); + const brPlayer = game.players.find((elem) => elem.UUID === player.id); + const brForChartPlayer = new BroadcastPlayerForChartGame(); + brForChartPlayer.player = brPlayer; + brForChartPlayer.isRight = answer.isCorrect; + let brAnswer = game.answers.find((elem) => elem.answerID === answer.id); + if (brAnswer) { + brAnswer.players.push(brForChartPlayer); + } else { + brAnswer = new BroadcastAnswerForChartGame(); + brAnswer.answerID = answer.id; + brAnswer.players = []; + brAnswer.players.push(brForChartPlayer); + game.answers.push(brAnswer); + } + } + + addPlayers(game: Game) { + const brPlayersArray = game.players.map((player) => { + const brPlayer = new BroadcastPlayer(); + brPlayer.gameCode = game.CODE; + brPlayer.name = player.name; + brPlayer.UUID = player.id; + return brPlayer; + }); + this.broadcastRepository.addPlayers(brPlayersArray, game.CODE); + } + + async playGame(game: Game) { + this.broadcastRepository.statusUpdate(game.CODE, game.status); + const gameFromStorage = this.broadcastRepository.getGameByCode(game.CODE); + const brGame = new BroadcastPlayingGame(); + let numberOfQuestion = 0; + brGame.startTimeSec = TIME_TO_ONE_QUESTION_SEC; + brGame.currentTimeSec = TIME_TO_ONE_QUESTION_SEC; + brGame.gameCode = gameFromStorage.CODE; + brGame.gameStatus = gameFromStorage.status; + brGame.answers = gameFromStorage.answers; + brGame.currentQuestionUUID = + gameFromStorage.quiz.questions[numberOfQuestion].id; + + const start = async () => { + this.pubSub.publish(GAME_PROCESS_EVENT, { + onPlayingGame: brGame, + }); + brGame.currentTimeSec--; + if (brGame.currentTimeSec === 0) { + numberOfQuestion++; + if (numberOfQuestion >= gameFromStorage.quiz.questions.length) { + this.gamesService.updateStatusGame( + brGame.gameCode, + GameStatus.FINISHED, + ); + brGame.gameStatus = GameStatus.FINISHED; + return brGame; + } else { + brGame.currentQuestionUUID = + gameFromStorage.quiz.questions[numberOfQuestion].id; + brGame.currentTimeSec = TIME_TO_ONE_QUESTION_SEC; + } + } + setTimeout(start, 1000); + }; + start(); + } + + deletePlayer(deletePlayerData: DeletePlayerArgs) { + const game = this.broadcastRepository.getGameByCode( + deletePlayerData.gameCode, + ); + if (!game) return null; + + const { players } = game; + if (!players) return null; + + const newPlayersArr = players.filter( + (elem) => elem.UUID !== deletePlayerData.playerId, + ); + game.players = newPlayersArr; + } + + deleteGame(code: string): void { + this.broadcastRepository.deleteGame(code); + } +} diff --git a/src/broadcast/dto/broadcast-answer.type.ts b/src/broadcast/dto/broadcast-answer.type.ts new file mode 100644 index 0000000000000000000000000000000000000000..662ad5d63c192a1ea70d53bc331953ffc10d72d9 --- /dev/null +++ b/src/broadcast/dto/broadcast-answer.type.ts @@ -0,0 +1,13 @@ +import { Field, ObjectType } from '@nestjs/graphql'; +import { IsUUID } from 'class-validator'; +import { BroadcastPlayerForChartGame } from './broadcast-player-chart.type'; + +@ObjectType() +export class BroadcastAnswerForChartGame { + @Field((type) => String, { nullable: false }) + @IsUUID('all') + answerID: string; + + @Field((type) => [BroadcastPlayerForChartGame], { nullable: false }) + players: BroadcastPlayerForChartGame[]; +} diff --git a/src/broadcast/dto/broadcast-player-chart.type.ts b/src/broadcast/dto/broadcast-player-chart.type.ts new file mode 100644 index 0000000000000000000000000000000000000000..3a25546edb61485b44bf3303a1678eabf181bed8 --- /dev/null +++ b/src/broadcast/dto/broadcast-player-chart.type.ts @@ -0,0 +1,11 @@ +import { Field, ObjectType } from '@nestjs/graphql'; +import { BroadcastPlayer } from './broadcast-player.type'; + +@ObjectType() +export class BroadcastPlayerForChartGame { + @Field((type) => BroadcastPlayer, { nullable: false }) + player: BroadcastPlayer; + + @Field((type) => Boolean, { nullable: false }) + isRight: boolean; +} diff --git a/src/broadcast/dto/broadcast-player.type.ts b/src/broadcast/dto/broadcast-player.type.ts new file mode 100644 index 0000000000000000000000000000000000000000..cbba16a236040d25fa218b4b9e00e782621e8590 --- /dev/null +++ b/src/broadcast/dto/broadcast-player.type.ts @@ -0,0 +1,17 @@ +import { Field, ObjectType } from '@nestjs/graphql'; +import { IsUUID } from 'class-validator'; + +@ObjectType() +export class BroadcastPlayer { + @Field({ nullable: false }) + @IsUUID('all') + UUID: string; + + @Field({ nullable: false }) + @IsUUID('all') + gameCode: string; + + @Field({ nullable: false }) + @IsUUID('all') + name: string; +} diff --git a/src/broadcast/dto/broadcast-playing-game.type.ts b/src/broadcast/dto/broadcast-playing-game.type.ts new file mode 100644 index 0000000000000000000000000000000000000000..929ccfcd3a91544a91a71f2b73f114293c010e6e --- /dev/null +++ b/src/broadcast/dto/broadcast-playing-game.type.ts @@ -0,0 +1,29 @@ +import { Field, Int, ObjectType } from '@nestjs/graphql'; +import { IsInt, IsUUID } from 'class-validator'; +import { GameStatus } from '../../games/enums/statuses.enum'; +import { BroadcastAnswerForChartGame } from './broadcast-answer.type'; + +@ObjectType() +export class BroadcastPlayingGame { + @Field((type) => Int, { nullable: false }) + @IsInt() + currentTimeSec: number; + + @Field((type) => String, { nullable: false }) + @IsUUID('all') + gameCode: string; + + @Field((type) => Int, { nullable: false }) + @IsInt() + startTimeSec: number; + + @Field((type) => String, { nullable: false }) + @IsUUID('all') + currentQuestionUUID: string; + + @Field((type) => GameStatus, { nullable: false }) + gameStatus: GameStatus; + + @Field((type) => [BroadcastAnswerForChartGame], { nullable: false }) + answers: BroadcastAnswerForChartGame[]; +} diff --git a/src/common/modules/pubSub.module.ts b/src/common/modules/pubSub.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..bcf437385b8748a0a16f8a8bedbc1bdf09226f1e --- /dev/null +++ b/src/common/modules/pubSub.module.ts @@ -0,0 +1,17 @@ +import { Global, Module } from '@nestjs/common'; +import { PubSub } from 'graphql-subscriptions'; + +export const PUB_SUB = 'PUB_SUB'; + +@Global() +@Module({ + providers: [ + { + provide: PUB_SUB, + useClass: PubSub, + useValue: new PubSub(), + }, + ], + exports: [PUB_SUB], +}) +export class PubSubModule {} diff --git a/src/constants.ts b/src/constants.ts index 0a47651dbd0219b100cf74f67c0066a12c7574e7..bfe6ab84b280be5cffd0954c867fb06936a8dfb2 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -14,3 +14,9 @@ export const CREAT_QUESTION_BEFORE_DELETE = 'create new question before delete'; export const NO_QUESTION = 'no such question'; export const MIN_QUESTIONS = 2; export const MIN_ANSWERS = 3; +export const TIME_TO_ONE_QUESTION_SEC = 15; + +export const PLAYER_JOINED_EVENT = 'onWaitForJoiningPlayerToGame'; +export const GAME_STARTED_EVENT = 'onWaitForStartingGame'; +export const PLAYER_DELETED_EVENT = 'onDeletePlayerFromGame'; +export const GAME_PROCESS_EVENT = 'onPlayingGame'; diff --git a/src/games/games.module.ts b/src/games/games.module.ts index f44ccb1d541dd2152224af315a18b1efa9439755..13c1dbc707ac689b47da513a6b2f70834bcc65e3 100644 --- a/src/games/games.module.ts +++ b/src/games/games.module.ts @@ -6,6 +6,7 @@ import { Game } from './models/game.model'; import { QuizzesModule } from '../quizzes/quizzes.module'; import { PlayersModule } from '../players/players.module'; import { AnswersModule } from '../answers/answers.module'; +import { BroadcastModule } from '../broadcast/broadcast.module'; @Module({ providers: [GamesService, GamesResolver], @@ -14,6 +15,8 @@ import { AnswersModule } from '../answers/answers.module'; forwardRef(() => QuizzesModule), forwardRef(() => PlayersModule), forwardRef(() => AnswersModule), + forwardRef(() => BroadcastModule), ], + exports: [GamesService], }) export class GamesModule {} diff --git a/src/games/games.resolver.ts b/src/games/games.resolver.ts index d1a44011e5e73a4856d6554ad371169505be4582..7f69c1df59cdba29235cb9544e3ea8230aed0d1c 100644 --- a/src/games/games.resolver.ts +++ b/src/games/games.resolver.ts @@ -6,35 +6,57 @@ import { Player } from '../players/models/player.model'; import { JoinPlayerInput } from './dto/join-player.input'; import { DeletePlayerArgs } from './dto/delete-player.args'; import { AnswerQuestionArgs } from './dto/answer-question.args'; -import { PubSub } from 'graphql-subscriptions'; -import { BroadcastPlayer } from '../players/dto/broadcast-player.type'; +import { BroadcastPlayer } from '../broadcast/dto/broadcast-player.type'; import { StartGame } from './dto/start-game.type'; import { SubscriptionsArgs } from '../common/dto/subscriptions.args'; +import { BroadcastService } from '../broadcast/broadcast.service'; +import { BroadcastPlayingGame } from '../broadcast/dto/broadcast-playing-game.type'; +import { + GAME_NOT_ACTIVATED, + GAME_PROCESS_EVENT, + GAME_STARTED_EVENT, + NO_PLAYER, + PLAYER_DELETED_EVENT, + PLAYER_JOINED_EVENT, +} from '../constants'; +import { Inject } from '@nestjs/common'; +import { PubSub } from 'graphql-subscriptions'; +import { PUB_SUB } from '../common/modules/pubSub.module'; import { GameStatus } from './enums/statuses.enum'; -const pubSub = new PubSub(); - @Resolver() export class GamesResolver { - constructor(private readonly gamesService: GamesService) {} + constructor( + private readonly gamesService: GamesService, + private readonly broadcastService: BroadcastService, + @Inject(PUB_SUB) + private readonly pubSub: PubSub, + ) {} @Mutation((returns) => Game) async activateGame(@Args('quizId') quizId: string): Promise { - return await this.gamesService.createGame(quizId); + const game = await this.gamesService.createGame(quizId); + this.broadcastService.addGameToStorage(game); + return game; } @Mutation((returns) => StatusModel) async deactivateGameByCode(@Args('code') code: string) { const success = await this.gamesService.deleteGame(code); + if (success) { + this.broadcastService.deleteGame(code); + } return { success }; } @Mutation((returns) => Game) async startGameByCode(@Args('code') code: string): Promise { const game = await this.gamesService.startGameByCode(code); - pubSub.publish('onWaitForStartingGame', { + await this.pubSub.publish(GAME_STARTED_EVENT, { onWaitForStartingGame: { gameCode: game.CODE }, }); + this.broadcastService.addPlayers(game); + this.broadcastService.playGame(game); return game; } @@ -43,10 +65,11 @@ export class GamesResolver { @Args() deletePlayerData: DeletePlayerArgs, ): Promise { const player = await this.gamesService.deletePlayer(deletePlayerData); - pubSub.publish('onDeletePlayerFromGame', { + this.pubSub.publish(PLAYER_DELETED_EVENT, { ...player, ...deletePlayerData, }); + this.broadcastService.deletePlayer(deletePlayerData); return { success: true }; } @@ -55,7 +78,7 @@ export class GamesResolver { @Args('joinPlayerInput') joinPlayerInput: JoinPlayerInput, ): Promise { const player = await this.gamesService.joinPlayer(joinPlayerInput); - pubSub.publish('onWaitForJoiningPlayerToGame', { + this.pubSub.publish(PLAYER_JOINED_EVENT, { ...player, ...joinPlayerInput, }); @@ -66,7 +89,11 @@ export class GamesResolver { async answerQuestionById( @Args() answerQuestionData: AnswerQuestionArgs, ): Promise { - return this.gamesService.answerQuestion(answerQuestionData); + const { answer, player } = await this.gamesService.answerQuestion( + answerQuestionData, + ); + this.broadcastService.addAnswer(answer, player); + return answer.isCorrect; } @Query((returns) => [Game]) @@ -85,45 +112,48 @@ export class GamesResolver { } @Subscription((returns) => BroadcastPlayer, { - name: 'onWaitForJoiningPlayerToGame', - async filter(this: GamesResolver, _, args) { - return ( - (await this.gamesService.validatePlayer(args)) && - (await this.gamesService.validateGameStatus( - GameStatus.WAITING_FOR_PLAYERS, - args.gameCode, - )) - ); // спросить норм ли так + name: PLAYER_JOINED_EVENT, + filter: (payload, args) => { + return payload.gameCode === args.gameCode; }, - async resolve(this: GamesResolver, payload, args) { + async resolve(this: GamesResolver, payload) { const { gameCode, name, id: UUID } = payload; return { gameCode, name, UUID }; }, }) - playerJoined(@Args() subscriptionData: SubscriptionsArgs) { - return pubSub.asyncIterator('onWaitForJoiningPlayerToGame'); + async playerJoined(@Args() subscriptionData: SubscriptionsArgs) { + const isStatusValid = await this.gamesService.validateGameStatus( + GameStatus.WAITING_FOR_PLAYERS, + subscriptionData.gameCode, + ); + const isPlayerValid = await this.gamesService.validatePlayer( + subscriptionData, + ); + if (!isPlayerValid) throw new Error(NO_PLAYER); + else if (!isStatusValid) throw new Error(GAME_NOT_ACTIVATED); + + return this.pubSub.asyncIterator(PLAYER_JOINED_EVENT); } @Subscription((returns) => StartGame, { - name: 'onWaitForStartingGame', - async filter(this: GamesResolver, _, args) { - return await this.gamesService.validatePlayer(args); + name: GAME_STARTED_EVENT, + filter: (payload, args) => { + return payload.onWaitForStartingGame.gameCode === args.gameCode; }, }) async gameStarted(@Args() subscriptionData: SubscriptionsArgs) { - return pubSub.asyncIterator('onWaitForStartingGame'); + const isPlayerValid = await this.gamesService.validatePlayer( + subscriptionData, + ); + if (!isPlayerValid) throw new Error(NO_PLAYER); + + return this.pubSub.asyncIterator(GAME_STARTED_EVENT); } @Subscription((returns) => BroadcastPlayer, { - name: 'onDeletePlayerFromGame', - async filter(this: GamesResolver, _, args) { - return ( - (await this.gamesService.validatePlayer(args)) && - (await this.gamesService.validateGameStatus( - GameStatus.PLAYING, - args.gameCode, - )) - ); // спросить норм ли так + name: PLAYER_DELETED_EVENT, + filter: (payload, args) => { + return payload.gameCode === args.gameCode; }, resolve: (payload) => { const { gameCode, name, playerId: UUID } = payload; @@ -131,6 +161,25 @@ export class GamesResolver { }, }) async playerDeleted(@Args() subscriptionData: SubscriptionsArgs) { - return pubSub.asyncIterator('onDeletePlayerFromGame'); + const isPlayerValid = await this.gamesService.validatePlayer( + subscriptionData, + ); + if (!isPlayerValid) throw new Error(NO_PLAYER); + + return this.pubSub.asyncIterator(PLAYER_DELETED_EVENT); + } + + @Subscription((returns) => BroadcastPlayingGame, { + filter: (payload, args) => { + return payload.onPlayingGame.gameCode === args.gameCode; + }, + }) + async onPlayingGame(@Args() subscriptionData: SubscriptionsArgs) { + const isPlayerValid = await this.gamesService.validatePlayer( + subscriptionData, + ); + if (!isPlayerValid) throw new Error(NO_PLAYER); + + return this.pubSub.asyncIterator(GAME_PROCESS_EVENT); } } diff --git a/src/games/games.service.ts b/src/games/games.service.ts index 793529282a82fd74d1a8ea170c985cc900e6b287..9bf331031f89c1dae286bfef541d223f1c37e8a8 100644 --- a/src/games/games.service.ts +++ b/src/games/games.service.ts @@ -23,6 +23,8 @@ import { SMTHNG_WENT_WRONG, } from '../constants'; import { SubscriptionsArgs } from '../common/dto/subscriptions.args'; +import { BroadcastService } from '../broadcast/broadcast.service'; +import { Answer } from '../answers/models/answer.model'; @Injectable() export class GamesService { @@ -58,7 +60,7 @@ export class GamesService { return await this.gamesRepository.findOne( { CODE: code }, { - relations: ['players'], + relations: ['players', 'quiz'], }, ); } @@ -74,6 +76,10 @@ export class GamesService { return await this.gamesRepository.save(game); } + async updateStatusGame(code: string, status: GameStatus) { + await this.gamesRepository.update({ CODE: code }, { status }); + } + async joinPlayer(data: JoinPlayerInput): Promise { const game = await this.getGameByCode(data.gameCode); if (!game) throw new Error(NO_GAME); @@ -99,7 +105,9 @@ export class GamesService { return player; } - async answerQuestion(data: AnswerQuestionArgs): Promise { + async answerQuestion( + data: AnswerQuestionArgs, + ): Promise<{ player: Player; answer: Answer }> { const player = await this.playerService.getPlayerById(data.playerId); if (!player) throw new Error(NO_PLAYER); else if (player.game.status !== GameStatus.PLAYING) { @@ -122,7 +130,7 @@ export class GamesService { const updated = await this.playerService.updatePlayer(player); if (!updated) throw new Error(SMTHNG_WENT_WRONG); - return answer.isCorrect; + return { player, answer }; } async getGameResult(code: string): Promise { diff --git a/src/players/players.module.ts b/src/players/players.module.ts index 5b025b01122a0f48f5ba5093ba292f3a82a2018a..daf8ae89e831af8713b90c220e005e549d60f0e4 100644 --- a/src/players/players.module.ts +++ b/src/players/players.module.ts @@ -1,11 +1,10 @@ import { Module } from '@nestjs/common'; import { PlayersService } from './players.service'; -import { PlayersResolver } from './players.resolver'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Player } from './models/player.model'; @Module({ - providers: [PlayersService, PlayersResolver], + providers: [PlayersService], imports: [TypeOrmModule.forFeature([Player])], exports: [PlayersService], }) diff --git a/src/players/players.resolver.ts b/src/players/players.resolver.ts deleted file mode 100644 index fbb10f234ad089aff1cb154e3310986420f2267f..0000000000000000000000000000000000000000 --- a/src/players/players.resolver.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Resolver } from '@nestjs/graphql'; - -@Resolver() -export class PlayersResolver {}