Skip to content

Commit 3eaa0f4

Browse files
authored
Merge pull request #33 from prgrms-web-devcourse-final-project/refactor/#30/user-service
[BE/feat] User 도메인 리팩토링
2 parents 6c44869 + 2137c2e commit 3eaa0f4

File tree

6 files changed

+187
-39
lines changed

6 files changed

+187
-39
lines changed

src/main/java/back/kalender/domain/user/controller/UserController.java

Lines changed: 156 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import back.kalender.domain.user.service.UserService;
99
import io.swagger.v3.oas.annotations.Operation;
1010
import io.swagger.v3.oas.annotations.media.Content;
11+
import io.swagger.v3.oas.annotations.media.ExampleObject;
1112
import io.swagger.v3.oas.annotations.media.Schema;
1213
import io.swagger.v3.oas.annotations.responses.ApiResponse;
1314
import io.swagger.v3.oas.annotations.responses.ApiResponses;
@@ -39,8 +40,54 @@ public class UserController {
3940
),
4041
@ApiResponse(
4142
responseCode = "400",
42-
description = "잘못된 요청 (이메일 중복, 유효성 검증 실패 등)",
43-
content = @Content()
43+
description = "잘못된 요청",
44+
content = @Content(
45+
mediaType = "application/json",
46+
examples = {
47+
@ExampleObject(
48+
name = "필수 값 누락",
49+
value = """
50+
{
51+
"error": {
52+
"code": "BAD_REQUEST",
53+
"status": "400",
54+
"message": "잘못된 요청입니다."
55+
}
56+
}
57+
"""
58+
),
59+
@ExampleObject(
60+
name = "이메일 형식 오류",
61+
value = """
62+
{
63+
"error": {
64+
"code": "BAD_REQUEST",
65+
"status": "400",
66+
"message": "잘못된 요청입니다."
67+
}
68+
}
69+
"""
70+
)
71+
}
72+
)
73+
),
74+
@ApiResponse(
75+
responseCode = "409",
76+
description = "중복된 데이터",
77+
content = @Content(
78+
mediaType = "application/json",
79+
examples = @ExampleObject(
80+
value = """
81+
{
82+
"error": {
83+
"code": "DUPLICATE_NICKNAME",
84+
"status": "409",
85+
"message": "이미 사용 중인 닉네임입니다."
86+
}
87+
}
88+
"""
89+
)
90+
)
4491
)
4592
})
4693
@PostMapping
@@ -61,6 +108,7 @@ public ResponseEntity<UserSignupResponse> signup(
61108
return ResponseEntity.ok(dummyData);
62109
}
63110

111+
64112
@Operation(
65113
summary = "내 정보 조회",
66114
description = "로그인한 사용자의 정보를 조회합니다."
@@ -74,7 +122,38 @@ public ResponseEntity<UserSignupResponse> signup(
74122
@ApiResponse(
75123
responseCode = "401",
76124
description = "인증 실패",
77-
content = @Content()
125+
content = @Content(
126+
mediaType = "application/json",
127+
examples = @ExampleObject(
128+
value = """
129+
{
130+
"error": {
131+
"code": "UNAUTHORIZED",
132+
"status": "401",
133+
"message": "로그인이 필요합니다."
134+
}
135+
}
136+
"""
137+
)
138+
)
139+
),
140+
@ApiResponse(
141+
responseCode = "404",
142+
description = "사용자를 찾을 수 없음",
143+
content = @Content(
144+
mediaType = "application/json",
145+
examples = @ExampleObject(
146+
value = """
147+
{
148+
"error": {
149+
"code": "USER_NOT_FOUND",
150+
"status": "404",
151+
"message": "유저를 찾을 수 없습니다."
152+
}
153+
}
154+
"""
155+
)
156+
)
78157
)
79158
})
80159
@GetMapping("/me")
@@ -99,12 +178,38 @@ public ResponseEntity<UserProfileResponse> getMyProfile() {
99178
@ApiResponse(
100179
responseCode = "400",
101180
description = "잘못된 파일",
102-
content = @Content()
181+
content = @Content(
182+
mediaType = "application/json",
183+
examples = @ExampleObject(
184+
value = """
185+
{
186+
"error": {
187+
"code": "BAD_REQUEST",
188+
"status": "400",
189+
"message": "잘못된 요청입니다."
190+
}
191+
}
192+
"""
193+
)
194+
)
103195
),
104196
@ApiResponse(
105197
responseCode = "401",
106198
description = "인증 실패",
107-
content = @Content()
199+
content = @Content(
200+
mediaType = "application/json",
201+
examples = @ExampleObject(
202+
value = """
203+
{
204+
"error": {
205+
"code": "UNAUTHORIZED",
206+
"status": "401",
207+
"message": "로그인이 필요합니다."
208+
}
209+
}
210+
"""
211+
)
212+
)
108213
)
109214
})
110215
@PostMapping(value = "/me/profile-image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@@ -131,12 +236,56 @@ public ResponseEntity<UploadProfileImgResponse> uploadProfileImage(
131236
@ApiResponse(
132237
responseCode = "400",
133238
description = "잘못된 요청",
134-
content = @Content()
239+
content = @Content(
240+
mediaType = "application/json",
241+
examples = @ExampleObject(
242+
value = """
243+
{
244+
"error": {
245+
"code": "BAD_REQUEST",
246+
"status": "400",
247+
"message": "잘못된 요청입니다."
248+
}
249+
}
250+
"""
251+
)
252+
)
135253
),
136254
@ApiResponse(
137255
responseCode = "401",
138256
description = "인증 실패",
139-
content = @Content()
257+
content = @Content(
258+
mediaType = "application/json",
259+
examples = @ExampleObject(
260+
value = """
261+
{
262+
"error": {
263+
"code": "UNAUTHORIZED",
264+
"status": "401",
265+
"message": "로그인이 필요합니다."
266+
}
267+
}
268+
"""
269+
)
270+
)
271+
),
272+
@ApiResponse(
273+
responseCode = "409",
274+
description = "닉네임 중복",
275+
content = @Content(
276+
mediaType = "application/json",
277+
examples = @ExampleObject(
278+
value = """
279+
{
280+
"error": {
281+
"code": "DUPLICATE_NICKNAME",
282+
"status": "409",
283+
"message": "이미 사용 중인 닉네임입니다."
284+
}
285+
}
286+
"""
287+
)
288+
)
140289
)
141290
})
142291
@PatchMapping("/me")

src/main/java/back/kalender/domain/user/dto/response/UserProfileResponse.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package back.kalender.domain.user.dto.response;
22

3+
import back.kalender.domain.user.entity.User;
34
import back.kalender.global.common.Enum.Gender;
45
import io.swagger.v3.oas.annotations.media.Schema;
56

@@ -11,4 +12,15 @@ public record UserProfileResponse(
1112
Integer level,
1213
Integer age,
1314
Gender gender
14-
) {}
15+
) {
16+
public static UserProfileResponse from(User user) {
17+
return new UserProfileResponse(
18+
user.getEmail(),
19+
user.getNickname(),
20+
user.getProfileImage(),
21+
user.getLevel(),
22+
user.getAge(),
23+
user.getGender()
24+
);
25+
}
26+
}

src/main/java/back/kalender/domain/user/dto/response/UserSignupResponse.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package back.kalender.domain.user.dto.response;
22

3+
import back.kalender.domain.user.entity.User;
34
import io.swagger.v3.oas.annotations.media.Schema;
45

56
import java.time.LocalDate;
@@ -12,7 +13,17 @@ public record UserSignupResponse(
1213
String nickname,
1314
LocalDate birthDate,
1415
LocalDateTime createdAt
15-
) {}
16+
) {
17+
public static UserSignupResponse from(User user) {
18+
return new UserSignupResponse(
19+
user.getId(),
20+
user.getEmail(),
21+
user.getNickname(),
22+
user.getBirthDate(),
23+
user.getCreatedAt()
24+
);
25+
}
26+
}
1627

1728

1829

src/main/java/back/kalender/domain/user/entity/User.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package back.kalender.domain.user.entity;
22

3+
import back.kalender.global.common.entity.BaseEntity;
34
import back.kalender.global.common.Enum.Gender;
45
import jakarta.persistence.*;
56
import lombok.*;
@@ -15,11 +16,7 @@
1516
@NoArgsConstructor(access = AccessLevel.PROTECTED)
1617
@AllArgsConstructor
1718
@Builder
18-
public class User {
19-
@Id
20-
@GeneratedValue(strategy = GenerationType.IDENTITY)
21-
@Column(name = "user_id")
22-
private Long id;
19+
public class User extends BaseEntity {
2320

2421
@Column(nullable = false, unique = true)
2522
private String email;
@@ -37,14 +34,6 @@ public class User {
3734

3835
private Integer level;
3936

40-
@CreationTimestamp
41-
@Column(name = "created_at", nullable = false)
42-
private LocalDateTime createdAt;
43-
44-
@UpdateTimestamp
45-
@Column(name = "updated_at")
46-
private LocalDateTime updatedAt;
47-
4837
private LocalDate birthDate;
4938

5039
public void updateNickname(String nickname) {

src/main/java/back/kalender/domain/user/service/UserServiceImpl.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,7 @@ public UserProfileResponse getMyProfile(Long userId) {
2626
User user = userRepository.findById(userId)
2727
.orElseThrow(() -> new ServiceException(ErrorCode.USER_NOT_FOUND));
2828

29-
return new UserProfileResponse(
30-
user.getEmail(),
31-
user.getNickname(),
32-
user.getProfileImage(),
33-
user.getLevel(),
34-
user.getAge(),
35-
user.getGender()
36-
);
29+
return UserProfileResponse.from(user);
3730
}
3831

3932
/**
@@ -76,14 +69,7 @@ public UserProfileResponse updateMyProfile(Long userId, UpdateProfileRequest req
7669
user.updateProfileImage(request.profileImage());
7770
}
7871

79-
return new UserProfileResponse(
80-
user.getEmail(),
81-
user.getNickname(),
82-
user.getProfileImage(),
83-
user.getLevel(),
84-
user.getAge(),
85-
user.getGender()
86-
);
72+
return UserProfileResponse.from(user);
8773
}
8874

8975
/**

src/test/java/back/kalender/domain/user/UserServiceImplTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.mockito.junit.jupiter.MockitoExtension;
1717
import org.springframework.mock.web.MockMultipartFile;
1818

19+
import java.lang.reflect.Field;
1920
import java.time.LocalDate;
2021
import java.util.Optional;
2122

@@ -258,7 +259,7 @@ void updateMyProfile_UserNotFound() {
258259

259260
private void setUserId(User user, Long id) {
260261
try {
261-
java.lang.reflect.Field idField = User.class.getDeclaredField("id");
262+
Field idField = user.getClass().getSuperclass().getDeclaredField("id");
262263
idField.setAccessible(true);
263264
idField.set(user, id);
264265
} catch (Exception e) {

0 commit comments

Comments
 (0)