Skip to content

Commit

Permalink
Implement get global leaderboard endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Alputer committed Jan 27, 2024
1 parent 4735f41 commit 71c7af4
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 7 deletions.
38 changes: 33 additions & 5 deletions src/controllers/leaderboard.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Controller, Get, Req, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiResponse, ApiTags } from '@nestjs/swagger';
import {
Controller,
Get,
Req,
UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { AuthGuard } from '../services/guards';
import { IAuthorizedRequest } from '../interfaces';
import { LeaderboardService } from '../services';
Expand All @@ -13,7 +18,28 @@ export class LeaderboardController {
@UseGuards(AuthGuard)
@ApiResponse({
status: 200,
description: 'Leaderboard of user\'s group returned successfullys is returned successfully.',
description: 'Global leaderboard is returned successfully.',
})
@ApiResponse({
status: 401,
description: 'You are not authenticated.',
})
@ApiResponse({
status: 500,
description: 'Internal server error, contact with backend team.',
})
@Get('/global')
public async getGlobalLeaderboard(
@Req() req: IAuthorizedRequest,
): Promise<number> {
const user = req.user;
return await this.leaderboardService.getGlobalLeaderboard();
}

@UseGuards(AuthGuard)
@ApiResponse({
status: 200,
description: "Leaderboard of user's group is returned successfully.",
})
@ApiResponse({
status: 401,
Expand All @@ -28,9 +54,11 @@ export class LeaderboardController {
@Req() req: IAuthorizedRequest,
): Promise<number> {
const user = req.user;
return await this.leaderboardService.getTournamentLeaderboard(user.username);
return await this.leaderboardService.getTournamentLeaderboard(
user.username,
);
}

@UseGuards(AuthGuard)
@ApiResponse({
status: 200,
Expand Down
3 changes: 3 additions & 0 deletions src/entities/user.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class User {
currGroupId: string;
claimedReward: boolean;
joinedTournamentAt: string;
dummyPartitionKey: string;

public static async newInstanceFromDTO(data: RegisterDto) {
const result = new User();
Expand All @@ -25,6 +26,7 @@ export class User {
result.levelAndUsername = `0000001#${data.username}`;
result.claimedReward = true;
result.joinedTournamentAt = '';
result.dummyPartitionKey = '_';

return result;
}
Expand All @@ -40,6 +42,7 @@ export class User {
result.currGroupId = data.currGroupId.S;
result.claimedReward = data.claimedReward.BOOL;
result.joinedTournamentAt = data.joinedTournamentAt.S;
result.dummyPartitionKey = data.dummyPartitionKey.S;

return result;
}
Expand Down
11 changes: 9 additions & 2 deletions src/repositories/tournamentGroup.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,15 @@ export class TournamentGroupRepository {
ProjectionExpression: 'id, availableGroupId, availableGroupItemCount', // Replace with actual attribute names
Limit: 1,
});
const result = await this.client.send(queryCommand);
return result;
try {
const result = await this.client.send(queryCommand);
return result;
} catch (error) {
console.error('Error finding available group:', error);
throw new InternalServerErrorException(
'Internal Server Error in findAvailableGroup transaction',
);
}
}

public async getGroupMembersByGroupId(
Expand Down
33 changes: 33 additions & 0 deletions src/repositories/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
DynamoDBClient,
GetItemCommand,
PutItemCommand,
QueryCommand,
TransactWriteItemsCommand,
UpdateItemCommand,
} from '@aws-sdk/client-dynamodb';
Expand Down Expand Up @@ -134,6 +135,29 @@ export class UserRepository {
}
}

public async getGlobalLeaderboard(): Promise<any> {
const queryCommand = new QueryCommand({
TableName: 'Users',
IndexName: 'LevelGSI',
KeyConditionExpression: 'dummyPartitionKey = :dpk',
ExpressionAttributeValues: {
':dpk': { S: '_' },
},
Limit: 1000,
ScanIndexForward: false,
});

try {
const response = await this.client.send(queryCommand);
return response.Items;
} catch (error) {
console.error('Error in get global leaderboard request:', error);
throw new InternalServerErrorException(
'Internal Server Error in getGlobalLeaderboard query',
);
}
}

public async completeLevel(user: User): Promise<void> {
const updateCommand = new UpdateItemCommand({
TableName: this.tableName,
Expand Down Expand Up @@ -219,6 +243,15 @@ export class UserRepository {
':claimedRewardVal': { BOOL: true },
},
});

try {
await this.client.send(updateCommand);
} catch (error) {
console.error('Error updating user during claim reward request:', error);
throw new InternalServerErrorException(
'Internal Server Error in claimReward query',
);
}
}

public getTableName(): string {
Expand Down
6 changes: 6 additions & 0 deletions src/services/leaderboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export class LeaderboardService {
public readonly userRepository: UserRepository,
) {}

public async getGlobalLeaderboard() {
const users = await this.userRepository.getGlobalLeaderboard();

return users;
}

public async getTournamentLeaderboard(username: string) {
const user = await this.userRepository.findUserByUsername(username);

Expand Down

0 comments on commit 71c7af4

Please sign in to comment.