Skip to content

Commit ce08f33

Browse files
authored
Merge pull request #20 from topcoder-platform/PM-1504_create-edit-scorecard
PM-1504 create edit scorecard
2 parents 74189c7 + 4ab34be commit ce08f33

File tree

5 files changed

+358
-105
lines changed

5 files changed

+358
-105
lines changed

src/api/scorecard/scorecard.controller.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Param,
99
Query,
1010
UseInterceptors,
11+
ValidationPipe,
1112
} from '@nestjs/common';
1213
import {
1314
ApiTags,
@@ -32,6 +33,8 @@ import { ChallengeTrack } from 'src/shared/enums/challengeTrack.enum';
3233
import { ScoreCardService } from './scorecard.service';
3334
import { PaginationHeaderInterceptor } from 'src/interceptors/PaginationHeaderInterceptor';
3435
import { $Enums } from '@prisma/client';
36+
import { User } from 'src/shared/decorators/user.decorator';
37+
import { JwtUser } from 'src/shared/modules/global/jwt.service';
3538

3639
@ApiTags('Scorecard')
3740
@ApiBearerAuth()
@@ -54,9 +57,11 @@ export class ScorecardController {
5457
})
5558
@ApiResponse({ status: 403, description: 'Forbidden.' })
5659
async addScorecard(
57-
@Body() body: ScorecardRequestDto,
60+
@Body(new ValidationPipe({ whitelist: true, transform: true }))
61+
body: ScorecardRequestDto,
62+
@User() user: JwtUser,
5863
): Promise<ScorecardWithGroupResponseDto> {
59-
return await this.scorecardService.addScorecard(body);
64+
return await this.scorecardService.addScorecard(body, user);
6065
}
6166

6267
@Put('/:id')
@@ -81,9 +86,11 @@ export class ScorecardController {
8186
@ApiResponse({ status: 404, description: 'Scorecard not found.' })
8287
async editScorecard(
8388
@Param('id') id: string,
84-
@Body() body: ScorecardWithGroupResponseDto,
89+
@Body(new ValidationPipe({ whitelist: true, transform: true }))
90+
body: ScorecardRequestDto,
91+
@User() user: JwtUser,
8592
): Promise<ScorecardWithGroupResponseDto> {
86-
return await this.scorecardService.editScorecard(id, body);
93+
return await this.scorecardService.editScorecard(id, body, user);
8794
}
8895

8996
@Delete(':id')
@@ -248,7 +255,10 @@ export class ScorecardController {
248255
})
249256
@ApiResponse({ status: 403, description: 'Forbidden.' })
250257
@ApiResponse({ status: 404, description: 'Scorecard not found.' })
251-
async cloneScorecard(@Param('id') id: string): Promise<ScorecardResponseDto> {
252-
return this.scorecardService.cloneScorecard(id);
258+
async cloneScorecard(
259+
@Param('id') id: string,
260+
@User() user: JwtUser,
261+
): Promise<ScorecardResponseDto> {
262+
return this.scorecardService.cloneScorecard(id, user);
253263
}
254264
}

src/api/scorecard/scorecard.service.ts

Lines changed: 100 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ import {
55
} from '@nestjs/common';
66
import { Prisma } from '@prisma/client';
77
import {
8+
mapScorecardRequestForCreate,
89
mapScorecardRequestToDto,
9-
// ScorecardGroupBaseDto,
10+
ScorecardGroupBaseDto,
1011
ScorecardPaginatedResponseDto,
1112
ScorecardQueryDto,
12-
// ScorecardQuestionBaseDto,
13+
ScorecardQuestionBaseDto,
1314
ScorecardRequestDto,
1415
ScorecardResponseDto,
15-
// ScorecardSectionBaseDto,
16+
ScorecardSectionBaseDto,
1617
ScorecardWithGroupResponseDto,
1718
} from 'src/dto/scorecard.dto';
19+
import { JwtUser } from 'src/shared/modules/global/jwt.service';
1820
import { PrismaService } from 'src/shared/modules/global/prisma.service';
1921

2022
@Injectable()
@@ -28,9 +30,16 @@ export class ScoreCardService {
2830
*/
2931
async addScorecard(
3032
body: ScorecardRequestDto,
33+
user: JwtUser,
3134
): Promise<ScorecardWithGroupResponseDto> {
3235
const data = await this.prisma.scorecard.create({
33-
data: mapScorecardRequestToDto(body),
36+
data: {
37+
...(mapScorecardRequestForCreate({
38+
...body,
39+
createdBy: user.isMachine ? 'System' : (user.userId as string),
40+
updatedBy: user.isMachine ? 'System' : (user.userId as string),
41+
}) as any),
42+
},
3443
include: {
3544
scorecardGroups: {
3645
include: {
@@ -44,7 +53,7 @@ export class ScoreCardService {
4453
},
4554
});
4655

47-
return data as ScorecardWithGroupResponseDto;
56+
return data as unknown as ScorecardWithGroupResponseDto;
4857
}
4958

5059
/**
@@ -54,12 +63,17 @@ export class ScoreCardService {
5463
*/
5564
async editScorecard(
5665
id: string,
57-
body: ScorecardWithGroupResponseDto,
66+
body: ScorecardRequestDto,
67+
user: JwtUser,
5868
): Promise<ScorecardWithGroupResponseDto> {
5969
const data = await this.prisma.scorecard
6070
.update({
6171
where: { id },
62-
data: mapScorecardRequestToDto(body),
72+
data: mapScorecardRequestToDto({
73+
...body,
74+
createdBy: user.isMachine ? 'System' : (user.userId as string),
75+
updatedBy: user.isMachine ? 'System' : (user.userId as string),
76+
}) as any,
6377
include: {
6478
scorecardGroups: {
6579
include: {
@@ -81,7 +95,7 @@ export class ScoreCardService {
8195
});
8296
});
8397

84-
return data as ScorecardWithGroupResponseDto;
98+
return data as unknown as ScorecardWithGroupResponseDto;
8599
}
86100

87101
/**
@@ -202,79 +216,87 @@ export class ScoreCardService {
202216
};
203217
}
204218

205-
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/require-await
206-
async cloneScorecard(id: string): Promise<ScorecardResponseDto> {
207-
// const original = await this.prisma.scorecard.findUnique({
208-
// where: { id },
209-
// include: {
210-
// scorecardGroups: {
211-
// include: {
212-
// sections: {
213-
// include: {
214-
// questions: true,
215-
// },
216-
// },
217-
// },
218-
// },
219-
// },
220-
// });
219+
async cloneScorecard(
220+
id: string,
221+
user: { userId?: string; isMachine: boolean },
222+
): Promise<ScorecardResponseDto> {
223+
const original = await this.prisma.scorecard.findUnique({
224+
where: { id },
225+
include: {
226+
scorecardGroups: {
227+
include: {
228+
sections: {
229+
include: {
230+
questions: true,
231+
},
232+
},
233+
},
234+
},
235+
},
236+
});
221237

222-
// if (!original) {
223-
// throw new NotFoundException({ message: `Scorecard not found.` });
224-
// }
238+
if (!original) {
239+
throw new NotFoundException({ message: `Scorecard not found.` });
240+
}
225241

226-
// // Remove id fields from nested objects for cloning
227-
// const cloneGroups = original.scorecardGroups.map(
228-
// (group: ScorecardGroupBaseDto) => ({
229-
// ...group,
230-
// id: undefined,
231-
// createdAt: undefined,
232-
// updatedAt: undefined,
233-
// scorecardId: undefined,
234-
// sections: group.sections.map((section: ScorecardSectionBaseDto) => ({
235-
// ...section,
236-
// id: undefined,
237-
// createdAt: undefined,
238-
// updatedAt: undefined,
239-
// scorecardGroupId: undefined,
240-
// questions: section.questions.map(
241-
// (question: ScorecardQuestionBaseDto) => ({
242-
// ...question,
243-
// id: undefined,
244-
// createdAt: undefined,
245-
// updatedAt: undefined,
246-
// sectionId: undefined,
247-
// scorecardSectionId: undefined,
248-
// }),
249-
// ),
250-
// })),
251-
// }),
252-
// );
242+
const auditFields = {
243+
createdBy: user.isMachine ? 'System' : (user.userId as string),
244+
updatedBy: user.isMachine ? 'System' : (user.userId as string),
245+
createdAt: undefined,
246+
updatedAt: undefined,
247+
};
253248

254-
// const clonedScorecard = await this.prisma.scorecard.create({
255-
// data: {
256-
// ...original,
257-
// id: undefined,
258-
// name: `${original.name} (Clone)`,
259-
// createdAt: undefined,
260-
// updatedAt: undefined,
261-
// scorecardGroups: {
262-
// create: cloneGroups,
263-
// },
264-
// },
265-
// include: {
266-
// scorecardGroups: {
267-
// include: {
268-
// sections: {
269-
// include: {
270-
// questions: true,
271-
// },
272-
// },
273-
// },
274-
// },
275-
// },
276-
// });
277-
const clonedScorecard = {};
249+
// Remove id fields from nested objects for cloning
250+
const cloneGroups = original.scorecardGroups.map(
251+
(group: ScorecardGroupBaseDto) => ({
252+
...group,
253+
id: undefined,
254+
...auditFields,
255+
scorecardId: undefined,
256+
sections: {
257+
create: group.sections.map((section: ScorecardSectionBaseDto) => ({
258+
...section,
259+
id: undefined,
260+
...auditFields,
261+
scorecardGroupId: undefined,
262+
questions: {
263+
create: section.questions.map(
264+
(question: ScorecardQuestionBaseDto) => ({
265+
...question,
266+
id: undefined,
267+
...auditFields,
268+
sectionId: undefined,
269+
scorecardSectionId: undefined,
270+
}),
271+
),
272+
},
273+
})),
274+
},
275+
}),
276+
) as any;
277+
278+
const clonedScorecard = await this.prisma.scorecard.create({
279+
data: {
280+
...original,
281+
id: undefined,
282+
name: `${original.name} (Clone)`,
283+
...auditFields,
284+
scorecardGroups: {
285+
create: cloneGroups,
286+
},
287+
},
288+
include: {
289+
scorecardGroups: {
290+
include: {
291+
sections: {
292+
include: {
293+
questions: true,
294+
},
295+
},
296+
},
297+
},
298+
},
299+
});
278300

279301
return clonedScorecard as ScorecardResponseDto;
280302
}

0 commit comments

Comments
 (0)