Skip to content

Fix lint errors and correct path #7

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 1 commit into from
Aug 1, 2025
Merged

Conversation

billsedison
Copy link
Collaborator

@billsedison billsedison commented Jul 31, 2025

http://www.topcoder.com/challenge-details/30377549/?type=develop

  • Fix TypeScript Lint Errors
  • Remove /api Prefix from All Endpoints

@billsedison billsedison requested a review from kkartunov July 31, 2025 15:36
@@ -57,7 +57,7 @@ let projectCategoryMap: Record<string, ProjectTypeMap> = {};
let reviewItemCommentTypeMap: Record<string, string> = {};

// Global submission map to store submission information.
let submissionMap: Record<string, Record<string, string>> = {};
const submissionMap: Record<string, Record<string, string>> = {};

Choose a reason for hiding this comment

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

Consider reviewing other variables in the file to ensure consistent use of const where appropriate. Changing let to const is a good practice when the variable is not reassigned, but consistency across similar variables can improve readability and maintainability.

@@ -287,15 +287,15 @@ function processLookupFiles() {
/**
* Read submission data from resource_xxx.json, upload_xxx.json and submission_xxx.json.
*/
async function initSubmissionMap() {
function initSubmissionMap() {

Choose a reason for hiding this comment

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

The function initSubmissionMap was changed from async to a regular function. Ensure that there are no asynchronous operations within this function that require the use of await. If there are, the function should remain async to handle promises correctly.

@@ -313,14 +313,14 @@ async function initSubmissionMap() {
const filePath = path.join(DATA_DIR, f);
console.log(`Reading submission data from ${f}`);
const jsonData = readJson(filePath)['submission'];
for (let d of jsonData) {
for (const d of jsonData) {

Choose a reason for hiding this comment

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

Consider using const for the variable jsonData on line 315 since its value is not reassigned.

@@ -342,12 +342,17 @@ async function initSubmissionMap() {
const filePath = path.join(DATA_DIR, f);
console.log(`Reading upload data from ${f}`);
const jsonData = readJson(filePath)['upload'];
for (let d of jsonData) {
if (d['upload_status_id'] === '1' && d['upload_type_id'] === '1' && d['resource_id']) {
for (const d of jsonData) {

Choose a reason for hiding this comment

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

Consider using const instead of let for d since it is not reassigned within the loop.

// get submission info
uploadCount += 1
uploadCount += 1;

Choose a reason for hiding this comment

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

Ensure consistent use of semicolons throughout the code. A semicolon was added here, so verify other parts of the code for consistency.

@@ -387,16 +392,17 @@ async function initSubmissionMap() {
}
}
}
console.log(`Read resource count: ${resourceCount}, submission resource count: ${validResourceCount}`);
console.log(

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 split into multiple lines. Consider keeping it on a single line for better readability unless it exceeds the maximum line length.

@@ -1050,7 +1056,7 @@ async function migrate() {

// init resource-submission data
console.log('Starting resource/submission import...');
await initSubmissionMap();
initSubmissionMap();

Choose a reason for hiding this comment

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

The await keyword has been removed from the initSubmissionMap() call. If initSubmissionMap() is an asynchronous function and its completion is necessary before proceeding, consider adding await back to ensure the function completes before moving on to the next steps.

code: errorResponse.code
throw new NotFoundException({
message: `Appeal with ID ${appealId} was not found`,
code: errorResponse.code,

Choose a reason for hiding this comment

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

Trailing comma is unnecessary in the object literal. Consider removing it for consistency with the rest of the code style.

code: errorResponse.code
throw new NotFoundException({
message: `Appeal with ID ${appealId} was not found`,
code: errorResponse.code,

Choose a reason for hiding this comment

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

Consider removing the trailing comma after errorResponse.code to adhere to standard JavaScript object syntax.

const { page = 1, perPage = 10 } = paginationDto || {};
const skip = (page - 1) * perPage;


try {
// Build where clause for filtering
const whereClause: any = {};
if (resourceId) whereClause.resourceId = resourceId;
if (challengeId) whereClause.challengeId = challengeId;
if (reviewId) whereClause.appealId = reviewId;

Choose a reason for hiding this comment

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

The condition if (reviewId) whereClause.appealId = reviewId; seems to be setting appealId instead of reviewId. Verify if this is intentional or if it should be whereClause.reviewId = reviewId;.

@@ -326,11 +345,13 @@ export class AppealController {
}),

Choose a reason for hiding this comment

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

The indentation of the closing bracket on line 345 should match the opening bracket on line 326 for better readability.

@@ -326,11 +345,13 @@ export class AppealController {
}),
this.prisma.appealResponse.count({
where: whereClause,
})
}),

Choose a reason for hiding this comment

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

The indentation of the closing bracket on line 348 should match the opening bracket on line 346 for consistency.

@@ -19,16 +19,16 @@ import { PrismaService } from '../../shared/modules/global/prisma.service';

@ApiTags('Contact Requests')
@ApiBearerAuth()
@Controller('/api')
@Controller('/')

Choose a reason for hiding this comment

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

Changing the controller path from /api to / might affect the routing of the application. Ensure that this change is intentional and that all routes are correctly updated to reflect this new path.

@@ -23,7 +23,7 @@ export class GetHealthCheckResponseDto {
}

@ApiTags('Healthcheck')
@Controller('/api')
@Controller('/')

Choose a reason for hiding this comment

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

The change from @Controller('/api') to @Controller('/') alters the base path for the health check endpoint. Ensure that this change aligns with the intended routing structure and does not inadvertently affect other endpoints or the application's routing logic.

@@ -18,7 +23,7 @@ import { PrismaErrorService } from '../../shared/modules/global/prisma-error.ser

@ApiTags('ProjectResult')
@ApiBearerAuth()
@Controller('/api')
@Controller('/')

Choose a reason for hiding this comment

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

The change from @Controller('/api') to @Controller('/') alters the base path for the controller. Ensure that this change is intentional and that all routes are updated accordingly in the application to prevent routing issues.

@@ -65,22 +71,27 @@ export class ProjectResultController {
}),

Choose a reason for hiding this comment

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

Consider aligning the indentation of the this.prisma.challengeResult.count call with the surrounding code for better readability.

@@ -65,22 +71,27 @@ export class ProjectResultController {
}),
this.prisma.challengeResult.count({
where: { challengeId },
})
}),

Choose a reason for hiding this comment

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

Ensure consistent use of trailing commas in multi-line array and object literals for better diff readability and to adhere to common linting rules.

@@ -18,7 +27,7 @@ import { isAdmin, JwtUser } from 'src/shared/modules/global/jwt.service';
import { ReviewApplicationService } from './reviewApplication.service';

@ApiTags('Review Application')
@Controller('/api/review-applications')
@Controller('/review-applications')

Choose a reason for hiding this comment

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

The path change from /api/review-applications to /review-applications might affect existing API consumers. Ensure that this change is intentional and that any necessary updates to documentation or client code are made to reflect this change.

role: dto.role
}
role: dto.role,
},
});
if (existing && existing.length > 0) {
throw new ConflictException('Reviewer has submitted application before.');

Choose a reason for hiding this comment

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

Consider using double quotes for the string in ConflictException to maintain consistency with the other exception messages.

}
}
gte: beginDate,
},

Choose a reason for hiding this comment

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

Trailing comma added here. Ensure this is consistent with the project's linting rules. If the rules require trailing commas, this is correct; otherwise, it should be removed.

@@ -196,43 +207,50 @@ export class ReviewApplicationService {
* @param entityList review application entity list
* @param status application status
*/
private async sendEmails(entityList, status: ReviewApplicationStatus) {
private async sendEmails(
entityList: any[],

Choose a reason for hiding this comment

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

Consider specifying a more precise type for entityList instead of using any[] to improve type safety.

// All review application has same review opportunity and same challenge id.
const challengeId = entityList[0].opportunity.challengeId;
// get member id list
const userIds = entityList.map(e => e.userId);
const userIds: string[] = entityList.map((e: any) => e.userId as string);

Choose a reason for hiding this comment

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

The type assertion as string is used here. Ensure that userId is always a string to avoid runtime errors.

for (let entity of entityList) {
const payload:EventBusSendEmailPayload = new EventBusSendEmailPayload();
for (const entity of entityList) {
const payload: EventBusSendEmailPayload = new EventBusSendEmailPayload();
payload.sendgrid_template_id = sendgridTemplateId;

Choose a reason for hiding this comment

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

Consider checking if userEmailMap.get(entity.userId) returns a valid email before adding it to payload.recipients to avoid sending emails to undefined addresses.


@ApiTags('Review History')
@Controller('/api/review-history')
@Controller('/review-history')

Choose a reason for hiding this comment

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

The change from '/api/review-history' to '/review-history' in the @Controller decorator modifies the endpoint path. Ensure this change is intentional and aligns with the application's routing requirements.

// Check user permission
const authUser: JwtUser = req['user'] as JwtUser;
if (authUser.userId !== userId && !isAdmin(authUser)) {
throw new ForbiddenException('You cannot check this user\'s review history')
throw new ForbiddenException(
"You cannot check this user's review history",

Choose a reason for hiding this comment

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

Consider using single quotes for consistency, as the rest of the code uses single quotes for strings.

@@ -30,7 +30,7 @@ import { JwtUser } from 'src/shared/modules/global/jwt.service';
import { ReviewOpportunityService } from './reviewOpportunity.service';

@ApiTags('Review Opportunity')
@Controller('/api/review-opportunities')
@Controller('/review-opportunities')

Choose a reason for hiding this comment

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

The change in the path from /api/review-opportunities to /review-opportunities might affect the routing if other parts of the application or external clients are expecting the original path. Ensure that this change is intentional and that all necessary updates are made to accommodate this new path.

@@ -108,18 +132,20 @@ export class ReviewOpportunityService {
);
} catch (e) {
// challenge doesn't exist. Return 400
this.logger.error('Can\'t get challenge:', e)
this.logger.error("Can't get challenge:", e);

Choose a reason for hiding this comment

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

Consider using template literals for better readability and consistency with modern JavaScript practices: this.logger.error(\Can't get challenge: ${e}`);`

});
if (existing && existing.length > 0) {
throw new ConflictException('Review opportunity exists for challenge and type');
throw new ConflictException(
'Review opportunity exists for challenge and type',

Choose a reason for hiding this comment

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

Consider using template literals for better readability and consistency with modern JavaScript practices: throw new ConflictException(\Review opportunity exists for challenge and type`);`

@@ -197,23 +223,22 @@ export class ReviewOpportunityService {
* @returns response list
*/
private async assembleList(
entityList,
entityList: any[],

Choose a reason for hiding this comment

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

Consider specifying a more precise type for entityList instead of using any[]. This will improve type safety and maintainability.

): Promise<ReviewOpportunityResponseDto[]> {
// get challenge id and remove duplicated
const challengeIdList = [...new Set(entityList.map((e) => e.challengeId))];
const challengeIdList: string[] = [
...new Set(entityList.map((e: any) => e.challengeId as string)),

Choose a reason for hiding this comment

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

The use of any for the map function parameter e could be replaced with a more specific type to enhance type safety.

challengeIdList as string[],
);
const challengeList =
await this.challengeService.getChallenges(challengeIdList);
// build challenge id -> challenge data map
const challengeMap = new Map();

Choose a reason for hiding this comment

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

Consider specifying the type for challengeMap to improve type safety and readability.

@@ -235,7 +260,7 @@ export class ReviewOpportunityService {
* @returns response dto
*/
private buildResponse(
entity,
entity: any,

Choose a reason for hiding this comment

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

Consider specifying a more precise type instead of any for the entity parameter to improve type safety and maintainability.

@@ -272,7 +297,7 @@ export class ReviewOpportunityService {
applicationDate: e.createdBy,
}));
}

Choose a reason for hiding this comment

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

Unnecessary whitespace change. Consider reverting to maintain consistency with surrounding code.

@@ -39,7 +39,7 @@ import { PrismaErrorService } from '../../shared/modules/global/prisma-error.ser

@ApiTags('Reviews')
@ApiBearerAuth()
@Controller('/api/reviews')
@Controller('/reviews')

Choose a reason for hiding this comment

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

The change in the path from /api/reviews to /reviews may affect existing API clients that rely on the previous endpoint. Ensure that this change is intentional and that any necessary updates to client applications or documentation are made to reflect this new path.

@@ -302,11 +316,11 @@ export class ReviewController {
},
},
});

Choose a reason for hiding this comment

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

Remove unnecessary whitespace at the end of the line.

reviews = scorecards.flatMap((d) => d.reviews);

Choose a reason for hiding this comment

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

Remove unnecessary whitespace at the end of the line.

@@ -322,8 +336,8 @@ export class ReviewController {
where: { challengeId },
});

const submissionIds = challengeResults.map(c => c.submissionId);

const submissionIds = challengeResults.map((c) => c.submissionId);

Choose a reason for hiding this comment

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

Remove the unnecessary space after the opening parenthesis in the arrow function parameter to maintain consistent formatting.

@@ -340,21 +354,21 @@ export class ReviewController {
},

Choose a reason for hiding this comment

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

Unnecessary whitespace change. Consider reverting to maintain consistency with the surrounding code.

@@ -340,21 +354,21 @@ export class ReviewController {
},
},
});

Choose a reason for hiding this comment

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

Unnecessary whitespace change. Consider reverting to maintain consistency with the surrounding code.

@@ -33,16 +33,16 @@ import { PrismaService } from '../../shared/modules/global/prisma.service';

@ApiTags('Scorecard')
@ApiBearerAuth()
@Controller('/api/scorecards')
@Controller('/scorecards')

Choose a reason for hiding this comment

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

The change from /api/scorecards to /scorecards might affect existing API clients expecting the previous path. Ensure that this change is intentional and update any relevant documentation or client code accordingly.

@@ -110,12 +115,10 @@ export class CreateReviewOpportunityDto {
incrementalPayment: number;

Choose a reason for hiding this comment

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

The OmitType function call is missing a closing parenthesis. Ensure that the syntax is correct and all parentheses are properly closed.

// Intercept response to log it
const originalSend = res.send;
res.send = function(body) {
res.send = function (body: any): Response {

Choose a reason for hiding this comment

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

Consider specifying a more precise type for body instead of using any to improve type safety.

return originalSend.call(this, body);

return originalSend.call(this, body) as Response;

Choose a reason for hiding this comment

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

The type assertion as Response might be unnecessary if the originalSend method already returns a Response type. Consider verifying the return type of originalSend to ensure this type assertion is needed.

@@ -124,7 +126,8 @@ async function bootstrap() {
--header 'content-type: application/json' \\
--data '{"client_id":"your-client-id","client_secret":"your-client-secret","audience":"https://m2m.topcoder-dev.com/","grant_type":"client_credentials"}'

`)
`,

Choose a reason for hiding this comment

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

The trailing comma after the template literal might not be necessary here. Ensure that this is intentional and does not affect the functionality.

process.on('unhandledRejection', (reason, promise) => {
logger.error(`Unhandled Promise Rejection at: ${promise}`, reason as string);
process.on('unhandledRejection', (reason) => {
logger.error('Unhandled Promise Rejection', reason as string);

Choose a reason for hiding this comment

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

Consider providing more context in the log message for unhandled promise rejections. Including the promise information might be helpful for debugging.

};

Choose a reason for hiding this comment

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

Ensure there is a newline at the end of the file to comply with POSIX standards and avoid potential issues with version control systems.

],
'm2m-token-project-result': [
Scope.AllProjectResult
Scope.AllScorecard,

Choose a reason for hiding this comment

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

Consider adding a trailing comma after Scope.AllScorecard for consistency with the rest of the array elements.

@@ -90,31 +80,30 @@ export class JwtService implements OnModuleInit {
}

let decodedToken: any;

Choose a reason for hiding this comment

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

Remove the unused variable decodedToken if it is not used elsewhere in the code.

// Verify the token
decodedToken = verify(token, signingKey, verifyOptions);

} catch (error) {
console.error('JWT verification failed:', error);

Choose a reason for hiding this comment

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

Avoid using console.error for logging errors in production code. Consider using a logging library that can be configured for different environments.

@@ -123,12 +112,12 @@ export class JwtService implements OnModuleInit {
// In development, just decode the token without verification
decodedToken = decode(token);
}

Choose a reason for hiding this comment

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

Remove unnecessary whitespace change.

@@ -147,7 +136,7 @@ export class JwtService implements OnModuleInit {
user.userId = decodedToken[key] as string;
}
if (key.endsWith('roles')) {
user.roles = decodedToken[key] as UserRole[]
user.roles = decodedToken[key] as UserRole[];

Choose a reason for hiding this comment

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

Ensure consistent use of semicolons throughout the codebase. The semicolon added here is correct, but verify that similar statements in the file also follow this convention.

if (typeof message === 'object') {
try {
logMessage = JSON.stringify(message);
} catch (e) {
} catch {

Choose a reason for hiding this comment

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

Consider specifying the error variable in the catch block for better error handling and debugging. For example, use catch (error) { instead of just catch {.

? error.meta.target.join(', ')
: typeof error.meta.target === 'string'
? error.meta.target
: JSON.stringify(error.meta.target)

Choose a reason for hiding this comment

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

Consider using JSON.stringify only when error.meta.target is an object, as using it on non-object types might lead to unexpected results. Ensure that error.meta.target is not a primitive type before applying JSON.stringify.

@@ -60,27 +67,33 @@ export class PrismaService extends PrismaClient implements OnModuleInit, OnModul
try {
await this.$connect();
this.logger.log('Prisma connected successfully');

Choose a reason for hiding this comment

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

Remove the unnecessary blank line to maintain code consistency and adhere to linting rules.

@kkartunov kkartunov merged commit 8d33cec into develop Aug 1, 2025
1 check passed
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