Skip to content

fic(PM-1585): Search scorecard modifications #14

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

Merged
merged 5 commits into from
Aug 8, 2025

Conversation

hentrymartin
Copy link
Collaborator

What's in this PR?

  • Search scorecard modifications

Ticket link - https://topcoder.atlassian.net/browse/PM-1585

@@ -37,6 +38,7 @@ import { GiteaWebhookAuthGuard } from '../shared/guards/gitea-webhook-auth.guard
ChallengeApiService,
WebhookService,
GiteaWebhookAuthGuard,
ScoreCardService,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ScoreCardService is added to the providers array, but ensure that it is properly imported at the top of the file. If it's already imported, verify that the import path is correct and matches the file structure.

@hentrymartin hentrymartin requested a review from kkartunov August 7, 2025 06:53
mapScorecardRequestToDto,
} from 'src/dto/scorecard.dto';
import { ChallengeTrack } from 'src/shared/enums/challengeTrack.enum';
import { PrismaService } from '../../shared/modules/global/prisma.service';
import { ScoreCardService } from './scorecard.service';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import statement for ScoreCardService should be consistent with the naming convention used in the rest of the file. Consider using ScorecardService to match the existing naming pattern.


@ApiTags('Scorecard')
@ApiBearerAuth()
@Controller('/scorecards')
export class ScorecardController {
constructor(private readonly prisma: PrismaService) {}
constructor(private readonly prisma: PrismaService, private readonly scorecardService: ScoreCardService) {}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor parameter scorecardService is added but not used in this snippet. Ensure that it is utilized in the class methods or remove it if unnecessary to avoid unused code.

@@ -68,7 +76,7 @@ export class ScorecardController {
},
},
});
return data as ScorecardResponseDto;
return data as ScorecardWithGroupResponseDto;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type has been changed from ScorecardResponseDto to ScorecardWithGroupResponseDto. Ensure that the new type ScorecardWithGroupResponseDto is correctly defined and that all parts of the application using this method are compatible with this change.

@Body() body: ScorecardRequestDto,
): Promise<ScorecardResponseDto> {
@Body() body: ScorecardWithGroupResponseDto,
): Promise<ScorecardWithGroupResponseDto> {
console.log(JSON.stringify(body));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the console.log statement to avoid unnecessary logging in production code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want this. Please always use logged.debug for that purpose.
Later we can enable or disable debug with env variables. You will enable it for your local env...

@@ -121,7 +129,7 @@ export class ScorecardController {
message: `Error: ${error.code}`,
});
});
return data as ScorecardResponseDto;
return data as ScorecardWithGroupResponseDto;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type has been changed from ScorecardResponseDto to ScorecardWithGroupResponseDto. Ensure that this change is consistent with the rest of the codebase and that ScorecardWithGroupResponseDto is the correct type to return here. Verify that all usages of this method are updated accordingly.

@@ -139,7 +147,7 @@ export class ScorecardController {
@ApiResponse({
status: 200,
description: 'Scorecard deleted successfully.',
type: ScorecardResponseDto,
type: ScorecardWithGroupResponseDto,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type for the API response has been changed from ScorecardResponseDto to ScorecardWithGroupResponseDto. Ensure that the new type ScorecardWithGroupResponseDto is correctly defined and that all necessary fields are included for this response type. Verify that this change aligns with the intended modifications for the scorecard search functionality.

@@ -200,11 +208,11 @@ export class ScorecardController {
message: `Error: ${error.code}`,
});
});
return data as ScorecardResponseDto;
return data as ScorecardWithGroupResponseDto;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion

Ensure that ScorecardWithGroupResponseDto is correctly defined and imported in this file. If this type includes additional properties compared to ScorecardResponseDto, verify that these properties are being handled appropriately in the rest of the code.

}

@Get()
@Roles(UserRole.Admin, UserRole.Copilot)
@Roles(UserRole.Admin)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion

Consider the implications of removing the UserRole.Copilot role from the @Roles decorator. Ensure that this change aligns with the intended access control requirements for the search scorecards functionality.

},
skip,
take: perPage,
): Promise<ScorecardPaginatedResponseDto> {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type of the searchScorecards method is specified as Promise<ScorecardPaginatedResponseDto>, but it is not clear from the code if this.scorecardService.getScoreCards returns this type. Ensure that the return type of getScoreCards matches ScorecardPaginatedResponseDto.

skip,
take: perPage,
): Promise<ScorecardPaginatedResponseDto> {
const challengeTrackArray = Array.isArray(challengeTrack)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for converting challengeTrack to an array could be simplified using a ternary operator or utility function to improve readability.

: challengeTrack
? [challengeTrack]
: [];
const challengeTypeArray = Array.isArray(challengeType)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for converting challengeType to an array could be simplified using a ternary operator or utility function to improve readability.

scoreCards: data as ScorecardResponseDto[],
};
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that there is a newline at the end of the file to adhere to POSIX standards and improve compatibility with various tools.


export class ScorecardBaseWithGroupsDto extends ScorecardBaseDto {
scorecardGroups: any[];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider specifying a more specific type for scorecardGroups instead of using any[]. This will improve type safety and make the code easier to understand and maintain.


@ApiProperty({
description: 'The list of score cards',
type: [ScorecardGroupResponseDto],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider specifying the type of elements in the scoreCards array as ScorecardResponseDto[] instead of ScorecardGroupResponseDto[] in the @ApiProperty decorator for clarity and consistency with the property type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one @hentrymartin!

@@ -48,12 +56,12 @@ export class ScorecardController {
@ApiResponse({
status: 201,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are really returning 201 here? Probably change to 200...

Copy link
Collaborator Author

@hentrymartin hentrymartin Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kkartunov This is for adding scorecard, normally for adding we return 201 so this looks like its returning correct, for search api it returns 200.

@Body() body: ScorecardRequestDto,
): Promise<ScorecardResponseDto> {
@Body() body: ScorecardWithGroupResponseDto,
): Promise<ScorecardWithGroupResponseDto> {
console.log(JSON.stringify(body));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want this. Please always use logged.debug for that purpose.
Later we can enable or disable debug with env variables. You will enable it for your local env...

mapScorecardRequestToDto,
} from 'src/dto/scorecard.dto';
import { ChallengeTrack } from 'src/shared/enums/challengeTrack.enum';
import { PrismaService } from '../../shared/modules/global/prisma.service';
import { ScoreCardService } from './scorecard.service';
import { PaginationHeaderInterceptor } from 'src/interceptors/PaginationHeaderInterceptor';

@ApiTags('Scorecard')
@ApiBearerAuth()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OkResponse import has been removed, but it is not clear if it is no longer needed or if it should be replaced with another response type. Please ensure that the removal of this import does not affect the functionality of the code.

mapScorecardRequestToDto,
} from 'src/dto/scorecard.dto';
import { ChallengeTrack } from 'src/shared/enums/challengeTrack.enum';
import { PrismaService } from '../../shared/modules/global/prisma.service';
import { ScoreCardService } from './scorecard.service';
import { PaginationHeaderInterceptor } from 'src/interceptors/PaginationHeaderInterceptor';

@ApiTags('Scorecard')
@ApiBearerAuth()
@Controller('/scorecards')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Response import from 'express' has been removed. If this was used in the code, make sure to replace it with an appropriate alternative or confirm that it is no longer necessary.

});
return data as ScorecardResponseDto;
): Promise<ScorecardWithGroupResponseDto> {
return await this.scorecardService.addScorecard(body);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The await keyword is redundant here since the function already returns a Promise. You can remove await to simplify the code: return this.scorecardService.addScorecard(body);.

@@ -139,24 +102,12 @@ export class ScorecardController {
@ApiResponse({
status: 200,
description: 'Scorecard deleted successfully.',
type: ScorecardResponseDto,
type: ScorecardWithGroupResponseDto,
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The console.log statement has been removed. Ensure that any necessary logging is handled appropriately elsewhere if needed.

@@ -173,38 +124,15 @@ export class ScorecardController {
@ApiResponse({
status: 200,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic for P2025 has been removed. Ensure that the scorecardService.editScorecard method includes appropriate error handling for cases where the scorecard is not found or other errors occur.

});
});
return { message: `Scorecard ${id} deleted successfully.` };
return await this.scorecardService.deleteScorecard(id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic has been removed from this method. Ensure that scorecardService.deleteScorecard(id) properly handles exceptions, especially for cases like Scorecard not found and other potential errors, to maintain the robustness of the application.

});
return data as ScorecardResponseDto;
async viewScorecard(@Param('id') id: string): Promise<ScorecardWithGroupResponseDto> {
return await this.scorecardService.viewScorecard(id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic for findUniqueOrThrow has been removed. Ensure that this.scorecardService.viewScorecard(id) includes appropriate error handling, particularly for cases where the scorecard is not found or other database errors occur.

@@ -0,0 +1,169 @@
import { Injectable, InternalServerErrorException, NotFoundException } from "@nestjs/common";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider importing only the exceptions that are actually used in the code to avoid unnecessary imports.

@@ -0,0 +1,169 @@
import { Injectable, InternalServerErrorException, NotFoundException } from "@nestjs/common";
import { Prisma } from "@prisma/client";
import { mapScorecardRequestToDto, ScorecardPaginatedResponseDto, ScorecardQueryDto, ScorecardRequestDto, ScorecardResponseDto, ScorecardWithGroupResponseDto } from "src/dto/scorecard.dto";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that mapScorecardRequestToDto and ScorecardWithGroupResponseDto are used in the code. If they are not used, consider removing them to keep the imports clean and maintainable.

},
})
.catch((error) => {
if (error.code !== 'P2025') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic seems to be reversed. The condition error.code !== 'P2025' should throw an InternalServerErrorException, while error.code === 'P2025' should throw a NotFoundException. Please verify the logic.

where: { id },
})
.catch((error) => {
if (error.code !== 'P2025') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic seems to be reversed. The condition error.code !== 'P2025' should throw an InternalServerErrorException, while error.code === 'P2025' should throw a NotFoundException. Please verify the logic.

},
})
.catch((error) => {
if (error.code !== 'P2025') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic seems to be reversed. The condition error.code !== 'P2025' should throw an InternalServerErrorException, while error.code === 'P2025' should throw a NotFoundException. Please verify the logic.

ScorecardRequestDto,
ScorecardResponseDto,
mapScorecardRequestToDto,
ScorecardWithGroupResponseDto,
} from 'src/dto/scorecard.dto';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import mapScorecardRequestToDto has been removed, but there is no indication in this diff whether it was used elsewhere in the code. Ensure that this removal does not affect any functionality or cause any errors due to missing imports.


@ApiTags('Scorecard')
@ApiBearerAuth()
@Controller('/scorecards')
export class ScorecardController {
constructor(private readonly prisma: PrismaService) {}
constructor(private readonly scorecardService: ScoreCardService) {}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PrismaService dependency has been removed from the constructor. Ensure that this change does not affect any functionality that relies on PrismaService. If PrismaService is no longer needed, consider removing any related unused imports or code.

@hentrymartin
Copy link
Collaborator Author

@kkartunov I've updated the PR based on the review comment, can you please do another round of review?

Copy link
Contributor

@kkartunov kkartunov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@hentrymartin hentrymartin merged commit 4bc862e into feat/scorecards Aug 8, 2025
1 check passed
@hentrymartin hentrymartin deleted the pm-1585 branch August 8, 2025 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants