Skip to content

Commit 441645b

Browse files
authored
Merge pull request #80 from Final-Project-Team-Temporary/feature/사용자-이름-추가
Feat:#43 용어 AI 설명 요청 API 구현
2 parents 95f9b54 + b931562 commit 441645b

10 files changed

Lines changed: 102 additions & 19 deletions

File tree

src/main/java/com/example/whiplash/auth/service/AuthService.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public TokenResponseDTO joinUser(UserCreateDTO userCreateDTO) {
5757

5858
String tempToken = jwtTokenProvider.generateTempToken(newUser);
5959

60-
return AuthConverter.toTokenResponseDTO(tempToken, null, UserStatus.PENDING, LoginStatus.NEW_USER);
60+
return AuthConverter.toTokenResponseDTO(tempToken, null, UserStatus.PENDING, LoginStatus.NEW_USER, newUser.getName());
6161
}
6262

6363
@Transactional
@@ -81,7 +81,7 @@ public TokenResponseDTO authenticateByKakao(String code) {
8181

8282
// 회원가입의 경우 임시토큰 생성
8383
String tempToken = jwtTokenProvider.generateTempSocialToken(kakaoUser);
84-
return AuthConverter.toTokenResponseDTO(tempToken, null, UserStatus.PENDING, LoginStatus.NEW_USER);
84+
return AuthConverter.toTokenResponseDTO(tempToken, null, UserStatus.PENDING, LoginStatus.NEW_USER, kakaoUser.getName());
8585
}
8686

8787
@Transactional
@@ -104,7 +104,7 @@ public TokenResponseDTO loginByKakao(User user) {
104104

105105
refreshTokenService.saveRefreshToken(refreshToken);
106106

107-
return AuthConverter.toTokenResponseDTO(accessToken, refreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER);
107+
return AuthConverter.toTokenResponseDTO(accessToken, refreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER, user.getName());
108108
}
109109

110110
@Transactional
@@ -134,7 +134,7 @@ public TokenResponseDTO login(LoginRequestDTO loginRequestDTO) {
134134

135135
refreshTokenService.saveRefreshToken(refreshToken);
136136

137-
return AuthConverter.toTokenResponseDTO(accessToken, refreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER);
137+
return AuthConverter.toTokenResponseDTO(accessToken, refreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER, user.getName());
138138
}
139139

140140
@Transactional
@@ -167,7 +167,7 @@ public TokenResponseDTO refreshToken(String refreshToken) {
167167

168168
refreshTokenService.saveRefreshToken(newRefreshToken);
169169

170-
return AuthConverter.toTokenResponseDTO(newAccessToken, newRefreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER);
170+
return AuthConverter.toTokenResponseDTO(newAccessToken, newRefreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER, user.getName());
171171
}
172172

173173
@Transactional
@@ -193,7 +193,7 @@ public TokenResponseDTO completeRegistration(String userName, ProfileRegisterDTO
193193

194194
refreshTokenService.saveRefreshToken(newRefreshToken);
195195

196-
return AuthConverter.toTokenResponseDTO(newAccessToken, newRefreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER);
196+
return AuthConverter.toTokenResponseDTO(newAccessToken, newRefreshToken, UserStatus.ACTIVE, LoginStatus.EXISTING_USER, tempUser.getName());
197197

198198
}
199199

src/main/java/com/example/whiplash/converter/AuthConverter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66

77
public class AuthConverter {
88

9-
public static TokenResponseDTO toTokenResponseDTO(String accessToken, String refreshToken, UserStatus userStatus, LoginStatus loginStatus) {
9+
public static TokenResponseDTO toTokenResponseDTO(String accessToken, String refreshToken, UserStatus userStatus, LoginStatus loginStatus, String userName) {
1010
return TokenResponseDTO.builder()
1111
.accessToken(accessToken)
1212
.refreshToken(refreshToken)
1313
.userStatus(userStatus)
1414
.loginStatus(loginStatus)
15+
.userName(userName)
1516
.build();
1617
}
1718
}

src/main/java/com/example/whiplash/quiz/client/AiServerClient.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.example.whiplash.quiz.dto.request.QuizCreateReqDto;
44
import com.example.whiplash.quiz.dto.response.QuizResDto;
5+
import com.example.whiplash.term.dto.request.TermExplainReqDto;
6+
import com.example.whiplash.term.dto.response.TermExplainResDto;
57
import lombok.extern.slf4j.Slf4j;
68
import org.springframework.beans.factory.annotation.Value;
79
import org.springframework.http.HttpStatusCode;
@@ -61,4 +63,37 @@ public QuizResDto generateQuiz(String keyword, int count) {
6163
throw new RuntimeException("퀴즈 생성 실패: " + e.getMessage(), e);
6264
}
6365
}
66+
67+
/**
68+
* AI 서버에 용어 설명 요청
69+
*/
70+
public TermExplainResDto getTermExplain(String term) {
71+
log.info("AI 서버 용어 설명 요청 : {}", term);
72+
73+
TermExplainReqDto request = new TermExplainReqDto(term);
74+
75+
try {
76+
TermExplainResDto response = webClient.post()
77+
.uri("/keyword/define") // AI 서버 엔드포인트
78+
.bodyValue(request)
79+
.retrieve()
80+
.onStatus(HttpStatusCode::isError, clientResponse -> {
81+
log.error("AI 서버 에러: status={}", clientResponse.statusCode());
82+
return Mono.error(new RuntimeException("AI 서버 응답 실패"));
83+
})
84+
.bodyToMono(TermExplainResDto.class)
85+
.timeout(Duration.ofSeconds(30))
86+
.block(); // 동기 방식으로 대기
87+
88+
if (response != null) {
89+
log.info("AI 용어 설명 완료 : {}", response.getDefinition());
90+
}
91+
92+
return response;
93+
94+
} catch (Exception e) {
95+
log.error("AI 서버 통신 실패: keyword={}", term, e);
96+
throw new RuntimeException("용어 설명 실패: " + e.getMessage(), e);
97+
}
98+
}
6499
}

src/main/java/com/example/whiplash/term/controller/TermsController.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
@RestController
2121
@RequiredArgsConstructor
2222
@RequestMapping("/api/users/terms")
23-
@Tag(name = "용어 관련 API",description = "용어 저장/조회/삭제 API")
23+
@Tag(name = "용어 관련 API", description = "용어 저장/조회/삭제 API")
2424
public class TermsController {
2525

2626
private final TermService termService;
@@ -55,9 +55,13 @@ public ApiResponse<?> getTerms(@AuthenticationPrincipal UserPrincipal principal)
5555

5656
@GetMapping("/{termsId}")
5757
@Operation(summary = "용어 상세조회", description = "용어에 대한 상세설명을 조회합니다.")
58-
public ApiResponse<?> getTermsById(@PathVariable("termsId") String termsId){
58+
public ApiResponse<?> getTermsById(@PathVariable("termsId") String termsId) {
5959
return null;
6060
}
6161

62-
62+
@GetMapping("/explain")
63+
@Operation(summary = "용어 AI설명 요청", description = "용어에 대한 AI 설명을 요청합니다.")
64+
public ApiResponse<?> getTermsExplain(@RequestParam String term) {
65+
return ApiResponse.onSuccess(termService.getTermExplanation(term));
66+
}
6367
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.example.whiplash.term.dto.request;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
6+
@Data
7+
@AllArgsConstructor
8+
public class TermExplainReqDto {
9+
private String term;
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example.whiplash.term.dto.response;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
6+
@Data
7+
@AllArgsConstructor
8+
public class TermExplainResDto {
9+
private String term;
10+
private String definition;
11+
}

src/main/java/com/example/whiplash/term/service/TermService.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import com.example.whiplash.apiPayload.ErrorStatus;
44
import com.example.whiplash.apiPayload.exception.WhiplashException;
5+
import com.example.whiplash.quiz.client.AiServerClient;
56
import com.example.whiplash.quiz.service.QuizPreGenerationService;
67
import com.example.whiplash.term.dto.request.TermAddDto;
78
import com.example.whiplash.term.dto.response.DictionaryTermListResDto;
9+
import com.example.whiplash.term.dto.response.TermExplainResDto;
810
import com.example.whiplash.term.entity.Terms;
911
import com.example.whiplash.term.entity.UserTerms;
1012
import com.example.whiplash.term.repository.TermsRepository;
@@ -31,6 +33,7 @@ public class TermService {
3133
private final UserTermsRepository userTermsRepository;
3234
private final UserRepository userRepository;
3335
private final QuizPreGenerationService quizPreGenerationService;
36+
private final AiServerClient aiServerClient;
3437

3538
/**
3639
* 용어 사전에 새 용어 추가
@@ -80,6 +83,23 @@ public List<DictionaryTermListResDto> getTerms(Long userId) {
8083
.build()).toList();
8184
}
8285

86+
/**
87+
* 용어 AI 설명요청
88+
*/
89+
public TermExplainResDto getTermExplanation(String term) {
90+
Optional<Terms> findTerm = termsRepository.findByTermName(term);
91+
92+
if(findTerm.isPresent()) {
93+
Terms terms = findTerm.get();
94+
return new TermExplainResDto(terms.getTermName(), terms.getAiExplanation());
95+
}
96+
97+
return aiServerClient.getTermExplain(term);
98+
}
99+
100+
101+
102+
83103
// Terms 조회/생성 로직 분리 (가독성 향상)
84104
private Terms getOrCreateTerm(TermAddDto termAddDto) {
85105
try {

src/main/java/com/example/whiplash/user/service/UserService.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,17 @@ public void createUserKeyword(UserKeywordCreateRequest request, Optional<Long> c
7171
}
7272
}
7373

74-
public InvestorProfileResDto getUserProfile(Optional<Long> currentUserId) {
75-
checkUserIsAuthenticated(currentUserId);
76-
User user = userRepository.findById(currentUserId.get())
77-
.orElseThrow(() -> new WhiplashException(ErrorStatus.USER_NOT_FOUND));
74+
public InvestorProfileResDto getUserProfile(Long userId) {
7875

79-
log.info("user id : {}", user.getId().toString());
76+
User user = userRepository.findById(userId)
77+
.orElseThrow(() -> new WhiplashException(ErrorStatus.USER_NOT_FOUND));
8078

8179
InvestorProfile investorProfile = investorProfileRepository.findByUser(user)
8280
.orElseThrow(() -> new WhiplashException(ErrorStatus.USER_NOT_FOUND));
8381

8482
return InvestorProfileResDto.builder()
8583
.id(investorProfile.getId())
86-
.userId(user.getId())
84+
.userId(userId)
8785
.investmentLevel(investorProfile.getInvestmentLevel())
8886
.riskTolerance(investorProfile.getRiskTolerance())
8987
.investmentGoal(investorProfile.getInvestmentGoal())

src/main/java/com/example/whiplash/user/web/controller/UserController.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.example.whiplash.user.web.controller;
22

33
import com.example.whiplash.apiPayload.ApiResponse;
4+
import com.example.whiplash.config.security.UserPrincipal;
45
import com.example.whiplash.global.util.SecurityContextUtils;
56
import com.example.whiplash.user.domain.User;
67
import com.example.whiplash.user.web.dto.request.ProfileRegisterDTO;
@@ -33,8 +34,10 @@ public ResponseEntity<ApiResponse<?>> profileSetup(@Valid @RequestBody ProfileRe
3334
}
3435

3536
@GetMapping("/profile")
36-
public ApiResponse<?> getProfile() {
37-
Optional<Long> optionalUserId = SecurityContextUtils.getCurrentUserId();
38-
return ApiResponse.onSuccess(userService.getUserProfile(optionalUserId));
37+
public ApiResponse<?> getProfile(@AuthenticationPrincipal UserPrincipal principal) {
38+
39+
Long userId = principal.getUserId();
40+
41+
return ApiResponse.onSuccess(userService.getUserProfile(userId));
3942
}
4043
}

src/main/java/com/example/whiplash/user/web/dto/response/TokenResponseDTO.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ public class TokenResponseDTO {
1414
private String refreshToken;
1515
private UserStatus userStatus;
1616
private LoginStatus loginStatus;
17+
private String userName;
1718
}

0 commit comments

Comments
 (0)