Skip to content

Commit 7731bc0

Browse files
committed
fix: 선택지 수정 벨리데이션 추가
1 parent 405c619 commit 7731bc0

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed

src/game-builder/choice/applications/controllers/choice.controller.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ export class ChoiceController {
6868
@Param('choiceId', ParseIntPipe) choiceId: number,
6969
@Body() body: UpdateChoiceReqDto,
7070
): Promise<UpdateChoiceResDto> {
71-
console.log(body);
7271
return await this.updateChoiceUsecase.execute(gameId, choiceId, body);
7372
}
7473

src/game-builder/choice/applications/usecases/update-choice.usecase.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import { PrismaService } from '@@prisma/prisma.service';
2-
import { Inject, Injectable, NotFoundException } from '@nestjs/common';
3-
import { CreateChoiceReqDto } from '../controllers/dto/create-choice.dto';
2+
import {
3+
ConflictException,
4+
Inject,
5+
Injectable,
6+
NotFoundException,
7+
} from '@nestjs/common';
8+
49
import { IChoiceService } from '../../domain/port/input/choice.service.interface';
510
import { IGameService } from '@@src/game-builder/game/domain/ports/input/game.service.interface';
611
import { UpdateChoiceReqDto } from '../controllers/dto/update-choice.dto';
712
import { IPageService } from '@@src/game-builder/page/domain/ports/input/page.service.interface';
13+
import { toGetAllResMapper } from '@@src/game-builder/game/application/usecases/mapper/to-get-all-res.mapper';
814

915
@Injectable()
1016
export class UpdateChoiceUseCase {
@@ -22,12 +28,42 @@ export class UpdateChoiceUseCase {
2228
) {
2329
const game = await this.gameService.getById(gameId);
2430
if (!game) throw new NotFoundException(`game is null`);
31+
const pages = await this.pageService.getAllByGameId(gameId);
32+
const choices = await this.choiceService.getAllByPageIds(
33+
pages.map((page) => page.id),
34+
);
35+
if (!game) {
36+
throw new NotFoundException('Game not found');
37+
}
38+
39+
const gameTrees = toGetAllResMapper(game, pages, choices);
2540

26-
const parentPage = await this.pageService.getOneById(
27-
createChoiceReqDto.parentPageId,
41+
const parentPage = gameTrees.pages.find(
42+
(page) => page.id === createChoiceReqDto.parentPageId,
2843
);
44+
2945
if (!parentPage) throw new NotFoundException(`parentPage is null`);
30-
parentPage.checkIsEnding();
46+
47+
const pageChoice = await this.choiceService.getAllByToPageId(parentPage.id);
48+
49+
if (pageChoice.length < 1) {
50+
throw new ConflictException(
51+
'부모 페이지가 없으면 선택지를 만들 수 없습니다.',
52+
);
53+
}
54+
55+
if (parentPage.isEnding) {
56+
throw new ConflictException('종료 페이지는 선택지를 만들 수 없습니다.');
57+
}
58+
59+
if (
60+
createChoiceReqDto.childPageId &&
61+
parentPage.fromPageIds.includes(createChoiceReqDto.childPageId)
62+
) {
63+
throw new ConflictException(
64+
'자식 페이지는 부모 페이지가 될 수 없습니다.',
65+
);
66+
}
3167

3268
if (createChoiceReqDto.childPageId) {
3369
const childPage = await this.pageService.getOneById(

src/game-builder/game/application/controllers/dto/get-all-game.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type Page = {
2121
url: string | null;
2222
};
2323
choices: Choice[];
24+
fromPageIds: number[];
2425
};
2526

2627
export class GetAllGameResDto {

src/game-builder/game/application/usecases/mapper/to-get-all-res.mapper.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ export const toGetAllResMapper = (
2525
throw new NotFoundException('Starting page not found');
2626
}
2727

28-
const dfs = (page: PageDomainEntity, depth: number) => {
28+
const dfs = (
29+
page: PageDomainEntity,
30+
depth: number,
31+
fromPageIds: number[],
32+
) => {
2933
if (!page) {
3034
return;
3135
}
@@ -47,12 +51,15 @@ export const toGetAllResMapper = (
4751
},
4852
contents: page.contents,
4953
depth,
54+
fromPageIds,
5055
choices: childChoices,
5156
});
52-
childPages.forEach((childPage) => dfs(childPage, depth + 1));
57+
childPages.forEach((childPage) =>
58+
dfs(childPage, depth + 1, [...fromPageIds, page.id]),
59+
);
5360
};
5461

55-
dfs(startingPage, 1);
62+
dfs(startingPage, 1, []);
5663

5764
// 선택지가 연결되지 않은 페이지
5865
// parentId와 childId가 모두 존재하지 않는 페이지
@@ -77,6 +84,7 @@ export const toGetAllResMapper = (
7784
isEnding: page.isEnding,
7885
depth: -1,
7986
choices: [],
87+
fromPageIds: [],
8088
});
8189
}
8290

0 commit comments

Comments
 (0)