From 903f258206851eee52dcd95f61c1acaf24b186c8 Mon Sep 17 00:00:00 2001 From: ayoubessabiry Date: Mon, 23 Oct 2023 19:07:54 +0100 Subject: [PATCH] ADD: leaderboard --- backend/code/src/app.module.ts | 2 ++ .../src/leaderboard/dto/leaderboard.dto.ts | 8 +++++++ .../src/leaderboard/leaderboard.controller.ts | 22 +++++++++++++++++ .../src/leaderboard/leaderboard.module.ts | 9 +++++++ .../src/leaderboard/leaderboard.service.ts | 24 +++++++++++++++++++ 5 files changed, 65 insertions(+) create mode 100644 backend/code/src/leaderboard/dto/leaderboard.dto.ts create mode 100644 backend/code/src/leaderboard/leaderboard.controller.ts create mode 100644 backend/code/src/leaderboard/leaderboard.module.ts create mode 100644 backend/code/src/leaderboard/leaderboard.service.ts diff --git a/backend/code/src/app.module.ts b/backend/code/src/app.module.ts index 6d88f2e..a141591 100644 --- a/backend/code/src/app.module.ts +++ b/backend/code/src/app.module.ts @@ -11,6 +11,7 @@ import { CloudinaryModule } from './cloudinary/cloudinary.module'; import { MessagesModule } from './messages/messages.module'; import { EventEmitterModule } from '@nestjs/event-emitter'; import { Gateways } from './gateways/gateways.gateway'; +import { LeaderBoardModule } from './leaderboard/leaderboard.module'; @Module({ imports: [ @@ -23,6 +24,7 @@ import { Gateways } from './gateways/gateways.gateway'; CloudinaryModule, MessagesModule, EventEmitterModule.forRoot(), + LeaderBoardModule, ], controllers: [AppController], providers: [PrismaService, Gateways], diff --git a/backend/code/src/leaderboard/dto/leaderboard.dto.ts b/backend/code/src/leaderboard/dto/leaderboard.dto.ts new file mode 100644 index 0000000..b4b648a --- /dev/null +++ b/backend/code/src/leaderboard/dto/leaderboard.dto.ts @@ -0,0 +1,8 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class LeaderboardResponseDto { + @ApiProperty({ example: '60f1a7b0e1b3c2a4e8b4a1a0' }) + userId: string; + @ApiProperty({ example: '3' }) + wins: number; +} diff --git a/backend/code/src/leaderboard/leaderboard.controller.ts b/backend/code/src/leaderboard/leaderboard.controller.ts new file mode 100644 index 0000000..8a3ef9e --- /dev/null +++ b/backend/code/src/leaderboard/leaderboard.controller.ts @@ -0,0 +1,22 @@ +import { Controller, Get, Query, UseGuards, HttpStatus } from '@nestjs/common'; +import { AtGuard } from 'src/auth/guards/at.guard'; +import { LeaderBoardService } from './leaderboard.service'; +import { QueryOffsetDto } from 'src/friends/dto/query-ofsset-dto'; +import { ApiResponse, ApiTags } from '@nestjs/swagger'; +import { LeaderboardResponseDto } from './dto/leaderboard.dto'; + +@ApiTags('leaderboard') +@Controller('leaderboard') +export class LeaderBoardController { + constructor(private readonly leaderBordService: LeaderBoardService) {} + + @Get() + @ApiResponse({ + type: LeaderboardResponseDto, + status: HttpStatus.OK, + }) + @UseGuards(AtGuard) + async getLeaderBoard(@Query() { offset, limit }: QueryOffsetDto) { + return this.leaderBordService.getLeaderBoard(offset, limit); + } +} diff --git a/backend/code/src/leaderboard/leaderboard.module.ts b/backend/code/src/leaderboard/leaderboard.module.ts new file mode 100644 index 0000000..69c7417 --- /dev/null +++ b/backend/code/src/leaderboard/leaderboard.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { LeaderBoardController } from './leaderboard.controller'; +import { LeaderBoardService } from './leaderboard.service'; + +@Module({ + controllers: [LeaderBoardController], + providers: [LeaderBoardService], +}) +export class LeaderBoardModule {} diff --git a/backend/code/src/leaderboard/leaderboard.service.ts b/backend/code/src/leaderboard/leaderboard.service.ts new file mode 100644 index 0000000..aaa2f75 --- /dev/null +++ b/backend/code/src/leaderboard/leaderboard.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from 'src/prisma/prisma.service'; + +@Injectable() +export class LeaderBoardService { + constructor(private prisma: PrismaService) {} + async getLeaderBoard(offset: number, limit: number) { + const leaderboard = await this.prisma.match.groupBy({ + skip: offset, + take: limit, + by: ['winner_id'], + _count: { id: true }, + orderBy: { + _count: { + id: 'desc', + }, + }, + }); + return leaderboard.map((user) => ({ + userId: user.winner_id, + wins: user._count.id, + })); + } +}