Skip to content

Commit 4bc862e

Browse files
authored
Merge pull request #14 from topcoder-platform/pm-1585
fic(PM-1585): Search scorecard modifications
2 parents 07ed4cb + ccefae6 commit 4bc862e

File tree

6 files changed

+276
-118
lines changed

6 files changed

+276
-118
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ lerna-debug.log*
4242
.env.production.local
4343
.env.local
4444

45+
# Prisma score cards
46+
/prisma/Scorecards
47+
4548
# temp directory
4649
.temp
4750
.tmp

src/api/api.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { ChallengeApiService } from 'src/shared/modules/global/challenge.service
1616
import { WebhookController } from './webhook/webhook.controller';
1717
import { WebhookService } from './webhook/webhook.service';
1818
import { GiteaWebhookAuthGuard } from '../shared/guards/gitea-webhook-auth.guard';
19+
import { ScoreCardService } from './scorecard/scorecard.service';
1920

2021
@Module({
2122
imports: [HttpModule, GlobalProvidersModule],
@@ -37,6 +38,7 @@ import { GiteaWebhookAuthGuard } from '../shared/guards/gitea-webhook-auth.guard
3738
ChallengeApiService,
3839
WebhookService,
3940
GiteaWebhookAuthGuard,
41+
ScoreCardService,
4042
],
4143
})
4244
export class ApiModule {}

src/api/scorecard/scorecard.controller.ts

Lines changed: 40 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import {
77
Body,
88
Param,
99
Query,
10-
NotFoundException,
11-
InternalServerErrorException,
10+
UseInterceptors,
1211
} from '@nestjs/common';
1312
import {
1413
ApiTags,
@@ -24,18 +23,20 @@ import { UserRole } from 'src/shared/enums/userRole.enum';
2423
import { Scopes } from 'src/shared/decorators/scopes.decorator';
2524
import { Scope } from 'src/shared/enums/scopes.enum';
2625
import {
26+
ScorecardPaginatedResponseDto,
2727
ScorecardRequestDto,
2828
ScorecardResponseDto,
29-
mapScorecardRequestToDto,
29+
ScorecardWithGroupResponseDto,
3030
} from 'src/dto/scorecard.dto';
3131
import { ChallengeTrack } from 'src/shared/enums/challengeTrack.enum';
32-
import { PrismaService } from '../../shared/modules/global/prisma.service';
32+
import { ScoreCardService } from './scorecard.service';
33+
import { PaginationHeaderInterceptor } from 'src/interceptors/PaginationHeaderInterceptor';
3334

3435
@ApiTags('Scorecard')
3536
@ApiBearerAuth()
3637
@Controller('/scorecards')
3738
export class ScorecardController {
38-
constructor(private readonly prisma: PrismaService) {}
39+
constructor(private readonly scorecardService: ScoreCardService) {}
3940

4041
@Post()
4142
@Roles(UserRole.Admin)
@@ -48,27 +49,13 @@ export class ScorecardController {
4849
@ApiResponse({
4950
status: 201,
5051
description: 'Scorecard added successfully.',
51-
type: ScorecardResponseDto,
52+
type: ScorecardWithGroupResponseDto,
5253
})
5354
@ApiResponse({ status: 403, description: 'Forbidden.' })
5455
async addScorecard(
5556
@Body() body: ScorecardRequestDto,
56-
): Promise<ScorecardResponseDto> {
57-
const data = await this.prisma.scorecard.create({
58-
data: mapScorecardRequestToDto(body),
59-
include: {
60-
scorecardGroups: {
61-
include: {
62-
sections: {
63-
include: {
64-
questions: true,
65-
},
66-
},
67-
},
68-
},
69-
},
70-
});
71-
return data as ScorecardResponseDto;
57+
): Promise<ScorecardWithGroupResponseDto> {
58+
return await this.scorecardService.addScorecard(body);
7259
}
7360

7461
@Put('/:id')
@@ -87,41 +74,15 @@ export class ScorecardController {
8774
@ApiResponse({
8875
status: 200,
8976
description: 'Scorecard updated successfully.',
90-
type: ScorecardResponseDto,
77+
type: ScorecardWithGroupResponseDto,
9178
})
9279
@ApiResponse({ status: 403, description: 'Forbidden.' })
9380
@ApiResponse({ status: 404, description: 'Scorecard not found.' })
9481
async editScorecard(
9582
@Param('id') id: string,
96-
@Body() body: ScorecardRequestDto,
97-
): Promise<ScorecardResponseDto> {
98-
console.log(JSON.stringify(body));
99-
100-
const data = await this.prisma.scorecard
101-
.update({
102-
where: { id },
103-
data: mapScorecardRequestToDto(body),
104-
include: {
105-
scorecardGroups: {
106-
include: {
107-
sections: {
108-
include: {
109-
questions: true,
110-
},
111-
},
112-
},
113-
},
114-
},
115-
})
116-
.catch((error) => {
117-
if (error.code !== 'P2025') {
118-
throw new NotFoundException({ message: `Scorecard not found.` });
119-
}
120-
throw new InternalServerErrorException({
121-
message: `Error: ${error.code}`,
122-
});
123-
});
124-
return data as ScorecardResponseDto;
83+
@Body() body: ScorecardWithGroupResponseDto,
84+
): Promise<ScorecardWithGroupResponseDto> {
85+
return await this.scorecardService.editScorecard(id, body);
12586
}
12687

12788
@Delete(':id')
@@ -139,24 +100,12 @@ export class ScorecardController {
139100
@ApiResponse({
140101
status: 200,
141102
description: 'Scorecard deleted successfully.',
142-
type: ScorecardResponseDto,
103+
type: ScorecardWithGroupResponseDto,
143104
})
144105
@ApiResponse({ status: 403, description: 'Forbidden.' })
145106
@ApiResponse({ status: 404, description: 'Scorecard not found.' })
146107
async deleteScorecard(@Param('id') id: string) {
147-
await this.prisma.scorecard
148-
.delete({
149-
where: { id },
150-
})
151-
.catch((error) => {
152-
if (error.code !== 'P2025') {
153-
throw new NotFoundException({ message: `Scorecard not found.` });
154-
}
155-
throw new InternalServerErrorException({
156-
message: `Error: ${error.code}`,
157-
});
158-
});
159-
return { message: `Scorecard ${id} deleted successfully.` };
108+
return await this.scorecardService.deleteScorecard(id);
160109
}
161110

162111
@Get('/:id')
@@ -173,38 +122,15 @@ export class ScorecardController {
173122
@ApiResponse({
174123
status: 200,
175124
description: 'Scorecard retrieved successfully.',
176-
type: ScorecardResponseDto,
125+
type: ScorecardWithGroupResponseDto,
177126
})
178127
@ApiResponse({ status: 404, description: 'Scorecard not found.' })
179-
async viewScorecard(@Param('id') id: string): Promise<ScorecardResponseDto> {
180-
const data = await this.prisma.scorecard
181-
.findUniqueOrThrow({
182-
where: { id },
183-
include: {
184-
scorecardGroups: {
185-
include: {
186-
sections: {
187-
include: {
188-
questions: true,
189-
},
190-
},
191-
},
192-
},
193-
},
194-
})
195-
.catch((error) => {
196-
if (error.code !== 'P2025') {
197-
throw new NotFoundException({ message: `Scorecard not found.` });
198-
}
199-
throw new InternalServerErrorException({
200-
message: `Error: ${error.code}`,
201-
});
202-
});
203-
return data as ScorecardResponseDto;
128+
async viewScorecard(@Param('id') id: string): Promise<ScorecardWithGroupResponseDto> {
129+
return await this.scorecardService.viewScorecard(id);
204130
}
205131

206132
@Get()
207-
@Roles(UserRole.Admin, UserRole.Copilot)
133+
@Roles(UserRole.Admin)
208134
@Scopes(Scope.ReadScorecard)
209135
@ApiOperation({
210136
summary: 'Search scorecards',
@@ -249,34 +175,31 @@ export class ScorecardController {
249175
description: 'List of matching scorecards',
250176
type: [ScorecardResponseDto],
251177
})
178+
@UseInterceptors(PaginationHeaderInterceptor)
252179
async searchScorecards(
253-
@Query('challengeTrack') challengeTrack?: ChallengeTrack,
254-
@Query('challengeType') challengeType?: string,
180+
@Query('challengeTrack') challengeTrack?: ChallengeTrack | ChallengeTrack[],
181+
@Query('challengeType') challengeType?: string | string[],
255182
@Query('name') name?: string,
256183
@Query('page') page: number = 1,
257184
@Query('perPage') perPage: number = 10,
258-
) {
259-
const skip = (page - 1) * perPage;
260-
const data = await this.prisma.scorecard.findMany({
261-
where: {
262-
...(challengeTrack && { challengeTrack }),
263-
...(challengeType && { challengeType }),
264-
...(name && { name: { contains: name, mode: 'insensitive' } }),
265-
},
266-
include: {
267-
scorecardGroups: {
268-
include: {
269-
sections: {
270-
include: {
271-
questions: true,
272-
},
273-
},
274-
},
275-
},
276-
},
277-
skip,
278-
take: perPage,
185+
): Promise<ScorecardPaginatedResponseDto> {
186+
const challengeTrackArray = Array.isArray(challengeTrack)
187+
? challengeTrack
188+
: challengeTrack
189+
? [challengeTrack]
190+
: [];
191+
const challengeTypeArray = Array.isArray(challengeType)
192+
? challengeType
193+
: challengeType
194+
? [challengeType]
195+
: [];
196+
const result = await this.scorecardService.getScoreCards({
197+
challengeTrack: challengeTrackArray,
198+
challengeType: challengeTypeArray,
199+
name,
200+
page,
201+
perPage,
279202
});
280-
return data as ScorecardResponseDto[];
203+
return result;
281204
}
282205
}

0 commit comments

Comments
 (0)