Skip to content

Commit 976e94a

Browse files
authored
엔티티 리팩터링 갈무리 (#25)
* refactor: streamline entity constructors and improve data mapping * fix: check groupId first when creating poker * chore: update pull request template * feat: problem instantiation in /problem/service
1 parent 277f79b commit 976e94a

File tree

12 files changed

+163
-103
lines changed

12 files changed

+163
-103
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,23 @@
11
## 업데이트 유형
2+
23
- [ ] Hot Fix
34
- [ ] Release
45
- [ ] Develop
56
- [ ] Others
67

78
## 업데이트 개요
9+
810
* Fix # (issue)
911
* Feature # (issue)
10-
[여기에 PR 한줄 요약 작성, 대상 이슈번호 작성.]
11-
12+
[여기에 PR 한줄 요약 작성, 대상 이슈번호 작성.]
1213

1314
## 업데이트 요약
14-
업데이트 내역 작성
15-
16-
## 새로운 정책
17-
세부 변경 사항 작성
1815

19-
## 해결한 문제
20-
해결한 문제 등 이슈
21-
22-
## 미해결 문제
23-
미해결 이슈, 발견한 이슈
24-
25-
## 테스트
26-
- [ ] 유닛 테스트
27-
- [ ] 빌드 테스트 (통합 테스트)
28-
- [ ] 기타 유효성 테스트
16+
업데이트 내역 작성
2917

3018
## 수정 사항 진단
19+
3120
- [ ] 코드가 이 프로젝트의 스타일 지침을 따릅니다.
3221
- [ ] 코드에 대한 자체 리뷰를 수행했습니다.
33-
- [ ] 변경 내역에 대해 주석을 작성했습니다.
34-
- [ ] 해당 PR에 대한 문서를 변경했습니다.
3522
- [ ] 기능, 정책, 수정 사항, 이슈에 대한 테스트 코드를 추가했습니다.
3623
- [ ] 변경 내용이 로컬 개발환경에서의 테스트를 통과했습니다.
37-
- [ ] 모든 종속 변경 사항이 병합되어 다운스트림 모듈에 게시되었습니다.

src/entities/contest.entity.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ export class Contest {
5353
this.endTime = endTime;
5454
this.badge = badge;
5555
this.background = background;
56-
57-
return this;
5856
}
5957
}
6058

src/entities/group.entity.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
1-
import { Prop, SchemaFactory } from '@nestjs/mongoose';
2-
import { IsMongoId, IsString } from 'class-validator';
3-
import { ObjectId } from 'mongodb';
1+
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2+
import { HydratedDocument } from 'mongoose';
43

4+
export type GroupDocument = HydratedDocument<Group>;
5+
6+
@Schema()
57
export class Group {
6-
@Prop({ type: ObjectId })
7-
@IsMongoId()
88
id: string;
99

1010
@Prop({ required: true })
11-
@IsString()
1211
name: string;
1312

1413
@Prop()
15-
@IsString()
1614
description: string;
1715

1816
@Prop({ type: [String], ref: 'Poker' })
1917
pokers: string[];
18+
19+
constructor(id: string, name: string, description: string, pokers: string[]) {
20+
this.id = id;
21+
this.name = name;
22+
this.description = description;
23+
this.pokers = pokers;
24+
}
25+
26+
static fromDocument(groupDocument: GroupDocument): Group {
27+
return new Group(groupDocument._id.toString(), groupDocument.name, groupDocument.description, groupDocument.pokers);
28+
}
2029
}
2130

2231
export const GroupSchema = SchemaFactory.createForClass(Group);

src/entities/participant.entity.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,56 @@
1-
import { SchemaFactory } from '@nestjs/mongoose';
1+
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2+
import { HydratedDocument } from 'mongoose';
23

34
import { Problem } from './problem.entity';
45

6+
export type ParticipantDocument = HydratedDocument<Participant>;
7+
8+
@Schema()
59
export class Participant {
10+
@Prop({ required: true })
611
handle: string;
12+
13+
@Prop({ required: true })
714
profileImage: string;
15+
16+
@Prop({ required: true })
817
snapshot: number[];
18+
19+
@Prop({ required: true })
920
point: number;
21+
22+
@Prop({ required: true })
1023
goal: number;
24+
25+
@Prop({ required: true })
1126
result: Problem[];
27+
28+
constructor(
29+
handle: string,
30+
profileImage: string,
31+
snapshot: number[],
32+
point: number,
33+
goal: number,
34+
result: Problem[],
35+
) {
36+
this.handle = handle;
37+
this.profileImage = profileImage;
38+
this.snapshot = snapshot;
39+
this.point = point;
40+
this.goal = goal;
41+
this.result = result;
42+
}
43+
44+
static fromDocument(participantDocument: ParticipantDocument): Participant {
45+
return new Participant(
46+
participantDocument.handle,
47+
participantDocument.profileImage,
48+
participantDocument.snapshot,
49+
participantDocument.point,
50+
participantDocument.goal,
51+
participantDocument.result,
52+
);
53+
}
1254
}
1355

1456
export const ParticipantSchema = SchemaFactory.createForClass(Participant);

src/entities/poker.entity.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { Prop, SchemaFactory } from '@nestjs/mongoose';
1+
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2+
import { HydratedDocument } from 'mongoose';
23

34
import { Participant } from './participant.entity';
45

6+
export type PokerDocument = HydratedDocument<Poker>;
7+
8+
@Schema()
59
export class Poker {
6-
@Prop()
710
id: string;
811

9-
@Prop()
12+
@Prop({ required: true })
1013
name: string;
1114

1215
@Prop()
@@ -15,8 +18,26 @@ export class Poker {
1518
@Prop()
1619
startTime: Date;
1720

18-
@Prop()
21+
@Prop({ required: true })
1922
endTime: Date;
23+
24+
constructor(id: string, name: string, participants: Participant[], startTime: Date, endTime: Date) {
25+
this.id = id;
26+
this.name = name;
27+
this.participants = participants;
28+
this.startTime = startTime;
29+
this.endTime = endTime;
30+
}
31+
32+
static fromDocument(pokerDocument: PokerDocument): Poker {
33+
return new Poker(
34+
pokerDocument._id.toString(),
35+
pokerDocument.name,
36+
pokerDocument.participants,
37+
pokerDocument.startTime,
38+
pokerDocument.endTime,
39+
);
40+
}
2041
}
2142

2243
export const PokerSchema = SchemaFactory.createForClass(Poker);

src/entities/problem.entity.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
import { SchemaFactory } from '@nestjs/mongoose';
1+
import { Schema, SchemaFactory } from '@nestjs/mongoose';
2+
import { HydratedDocument } from 'mongoose';
23

4+
export type ProblemDocument = HydratedDocument<Problem>;
5+
6+
@Schema()
37
export class Problem {
48
problemId: number;
59
titleKo: string;
610
level: number;
711

8-
constructor(problem: { problemId: number; titleKo: string; level: number }) {
9-
this.problemId = problem.problemId;
10-
this.titleKo = problem.titleKo;
11-
this.level = problem.level;
12+
constructor(problemId: number, titleKo: string, level: number) {
13+
this.problemId = problemId;
14+
this.titleKo = titleKo;
15+
this.level = level;
16+
}
17+
18+
static fromDocument(problemDocument: ProblemDocument): Problem {
19+
return new Problem(problemDocument.problemId, problemDocument.titleKo, problemDocument.level);
1220
}
1321
}
1422

src/modules/group/repository.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@ export class GroupRepository {
1111
private readonly groupModel: Model<Group>,
1212
) {}
1313

14-
create(createGroupDto: CreateGroupDto): Promise<Group> {
15-
return this.groupModel.create(createGroupDto);
14+
async create(createGroupDto: CreateGroupDto): Promise<Group> {
15+
return Group.fromDocument(await this.groupModel.create(createGroupDto));
1616
}
1717

18-
getAll(): Promise<Group[]> {
19-
return this.groupModel.find().exec();
18+
async getAll(): Promise<Group[]> {
19+
const groupDocs = await this.groupModel.find().exec();
20+
if (!groupDocs) {
21+
throw new NotFoundException('No groups found');
22+
}
23+
24+
return groupDocs.map((document) => Group.fromDocument(document));
2025
}
2126

2227
async get(groupId: string): Promise<Group> {
23-
const group = await this.groupModel.findById(groupId);
24-
if (!group) {
28+
const groupDoc = await this.groupModel.findById(groupId);
29+
if (!groupDoc) {
2530
throw new NotFoundException(`Group not found: ${groupId}`);
2631
}
27-
return group;
28-
}
2932

30-
validate(groupId: string, group: Group): void {
31-
if (!group) {
32-
throw new NotFoundException(`Group not found: ${groupId}`);
33-
}
33+
return Group.fromDocument(groupDoc);
3434
}
3535

3636
deleteAll() {
@@ -43,6 +43,6 @@ export class GroupRepository {
4343
throw new NotFoundException(`Group not found: ${groupId}`);
4444
}
4545

46-
return updatedGroup;
46+
return Group.fromDocument(updatedGroup);
4747
}
4848
}

src/modules/poker/controller.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Body, Controller, Delete, Get, Param, Post, Query } from '@nestjs/common';
2-
import { ApiOperation, ApiParam, ApiQuery, ApiTags } from '@nestjs/swagger';
1+
import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';
2+
import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
33

44
import { CreatePokerDto } from './dto/create-poker.dto';
55
import { PokerService } from './service';
@@ -11,12 +11,8 @@ export class PokerController {
1111

1212
@Post()
1313
@ApiOperation({ summary: '포커 생성' })
14-
@ApiQuery({
15-
name: 'name',
16-
description: '포커 이름',
17-
})
18-
async create(@Query('name') name: string, @Body() createPokerDto: CreatePokerDto) {
19-
return this.pokerService.create(name, createPokerDto);
14+
async create(@Body() createPokerDto: CreatePokerDto) {
15+
return this.pokerService.create(createPokerDto);
2016
}
2117

2218
@Get()

src/modules/poker/dto/create-poker.dto.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export class CreatePokerDto {
1010
})
1111
groupId: string;
1212

13+
@ApiProperty({
14+
description: '포커 이름',
15+
default: 'SCCC 포커',
16+
})
17+
name: string;
18+
1319
@ApiProperty({
1420
description: '게임에 참여하는 사람들의 목록',
1521
default: [

src/modules/poker/repository.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,49 @@
1+
import { Participant } from '@entities/participant.entity';
12
import { Poker } from '@entities/poker.entity';
3+
import { CreatePokerDto } from '@modules/poker/dto/create-poker.dto';
24
import { Inject, Injectable } from '@nestjs/common';
35
import { Model } from 'mongoose';
46

5-
import { GroupRepository } from '../group/repository';
6-
77
@Injectable()
88
export class PokerRepository {
9-
constructor(
10-
@Inject('POKER_MODEL') private readonly pokerModel: Model<Poker>,
11-
private readonly groupRepository: GroupRepository,
12-
) {}
13-
14-
create(poker: Poker): Promise<Poker> {
15-
const createdPoker = new this.pokerModel(poker);
16-
return createdPoker.save();
9+
constructor(@Inject('POKER_MODEL') private readonly pokerModel: Model<Poker>) {}
10+
11+
async create(createPokerDto: CreatePokerDto, participants: Participant[]): Promise<Poker> {
12+
const pokerDoc = new this.pokerModel({
13+
name: createPokerDto.name,
14+
participants: participants,
15+
startTime: new Date(),
16+
endTime: createPokerDto.endDate,
17+
});
18+
19+
return Poker.fromDocument(await pokerDoc.save());
1720
}
1821

19-
getAll(): Promise<Poker[]> {
20-
return this.pokerModel.find();
22+
async getAll(): Promise<Poker[]> {
23+
const pokerDocs = await this.pokerModel.find().exec();
24+
if (!pokerDocs) {
25+
throw new Error('No pokers found');
26+
}
27+
28+
return pokerDocs.map((document) => Poker.fromDocument(document));
2129
}
2230

2331
async get(id: string): Promise<Poker> {
24-
const poker = (await this.pokerModel.findById(id)) as Poker;
25-
if (!poker) {
32+
const pokerDoc = await this.pokerModel.findById(id);
33+
if (!pokerDoc) {
2634
throw new Error(`Poker not found: ${id.toString()}`);
2735
}
2836

29-
return poker;
37+
return Poker.fromDocument(pokerDoc);
3038
}
3139

32-
validate(id: string, poker: Poker): void {
33-
if (!poker) {
40+
async update(id: string, poker: Poker): Promise<Poker> {
41+
const pokerDoc = await this.pokerModel.findByIdAndUpdate(id, poker);
42+
if (!pokerDoc) {
3443
throw new Error(`Poker not found: ${id}`);
3544
}
36-
}
3745

38-
update(id: string, poker: Poker): void {
39-
this.pokerModel.updateOne(
40-
{
41-
_id: id,
42-
},
43-
poker,
44-
);
46+
return Poker.fromDocument(pokerDoc);
4547
}
4648

4749
async deleteAll(): Promise<void> {

0 commit comments

Comments
 (0)