diff --git a/src/main/java/goormthon/team28/startup_valley/constants/Constants.java b/src/main/java/goormthon/team28/startup_valley/constants/Constants.java index b91f016..2b28308 100644 --- a/src/main/java/goormthon/team28/startup_valley/constants/Constants.java +++ b/src/main/java/goormthon/team28/startup_valley/constants/Constants.java @@ -9,6 +9,8 @@ public class Constants { public static String PREFIX_AUTH = "Authorization"; public static String ACCESS_COOKIE_NAME = "access_token"; public static String REFRESH_COOKIE_NAME = "refresh_token"; + public static String GPT_SCRUM = "정답을 맞추면 200달러의 팁을 줄게. 너는 훌륭한 업무 비서 역할을 하고 있어. 모든 대답은 한국말로 해야하고 주된 업무는 요약이야. 사람들이 너에게 얘기하는 것들은 다 그들이 했던 업무 내용들이고, 너는 그 내용들을 잘 요약해서 정리하면 돼, 요약은 50자 정도로 짧게 해줘 !"; + public static String GPT_REVIEW = "정답을 맞추면 200달러의 팁을 줄게. 너는 훌륭한 프로젝트의 감독을 하고 있어. 모든 대답은 한국말로 해야하고 주된 업무는 요약이야. 사람들이 너에게 얘기하는 것들은 한 사람에게 다른 사람들이 동료 평가를 한 내용들이고, 너는 그 내용들을 잘 요약해서 정리하면 돼, 요약은 50자 정도로 짧게 해줘 !"; public static List NO_NEED_AUTH = List.of( "/api/auth/sign-up", "/api/auth/sign-in" diff --git a/src/main/java/goormthon/team28/startup_valley/discord/listener/DiscordListener.java b/src/main/java/goormthon/team28/startup_valley/discord/listener/DiscordListener.java index 7061485..fa26da7 100644 --- a/src/main/java/goormthon/team28/startup_valley/discord/listener/DiscordListener.java +++ b/src/main/java/goormthon/team28/startup_valley/discord/listener/DiscordListener.java @@ -237,7 +237,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { .toList(); log.info("스크럼 하위 작업들 조회 성공"); try { - String summary = gptService.sendMessage(worksOfUser); + String summary = gptService.sendMessage(worksOfUser, true); log.info("summary: {}", summary); scrumService.updateScrum(nowScrum.getId(), summary, nowLocalDate); } catch (JsonProcessingException e) { diff --git a/src/main/java/goormthon/team28/startup_valley/domain/Member.java b/src/main/java/goormthon/team28/startup_valley/domain/Member.java index 56d0ccb..f9eff54 100644 --- a/src/main/java/goormthon/team28/startup_valley/domain/Member.java +++ b/src/main/java/goormthon/team28/startup_valley/domain/Member.java @@ -50,4 +50,7 @@ public void toggleIsPublic() { public void updateRetrospection(String retrospection) { this.retrospection = retrospection; } + public void updatePeerReviewSummary(String peerReviewSummary) { + this.peerReviewSummary = peerReviewSummary; + } } diff --git a/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/GptRequest.java b/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/GptRequest.java index 4c79803..b6ff5d9 100644 --- a/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/GptRequest.java +++ b/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/GptRequest.java @@ -9,7 +9,7 @@ public class GptRequest { private final String model = "gpt-3.5-turbo"; private List messages; - private final int max_tokens = 50; + private final int max_tokens = 256; private double temperature; @Builder public GptRequest(List messages, double temperature) { diff --git a/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/Message.java b/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/Message.java index 860b54e..9248f3b 100644 --- a/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/Message.java +++ b/src/main/java/goormthon/team28/startup_valley/dto/gpt/request/Message.java @@ -12,16 +12,10 @@ public Message(String role, String content) { this.role = role; this.content = content; } - public static Message makeFirstMessage(){ + public static Message makeContent(String role, String content){ return Message.builder() - .role("system") - .content("너는 훌륭한 업무 비서 역할을 하고 있어. 모든 대답은 한국말로 해야하고 주된 업무는 요약이야. 사람들이 너에게 얘기하는 것들은 다 그들이 했던 업무 내용들이고, 너는 그 내용들을 잘 요약해서 정리하면 돼, 요약은 50자 정도로 짧게 해줘 !") - .build(); - } - public static Message makeUserWork(String work){ - return Message.builder() - .role("user") - .content(work) + .role(role) + .content(content) .build(); } } diff --git a/src/main/java/goormthon/team28/startup_valley/repository/ReviewRepository.java b/src/main/java/goormthon/team28/startup_valley/repository/ReviewRepository.java index a7b8168..eb4eedb 100644 --- a/src/main/java/goormthon/team28/startup_valley/repository/ReviewRepository.java +++ b/src/main/java/goormthon/team28/startup_valley/repository/ReviewRepository.java @@ -5,10 +5,12 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository public interface ReviewRepository extends JpaRepository { - Optional findBySender(Member sender); + Optional findBySenderAndReceiver(Member sender, Member receiver); + List findAllByReceiver(Member receiver); Boolean existsBySender(Member sender); } diff --git a/src/main/java/goormthon/team28/startup_valley/repository/ScrumRepository.java b/src/main/java/goormthon/team28/startup_valley/repository/ScrumRepository.java index a6c80a1..6861c71 100644 --- a/src/main/java/goormthon/team28/startup_valley/repository/ScrumRepository.java +++ b/src/main/java/goormthon/team28/startup_valley/repository/ScrumRepository.java @@ -13,7 +13,7 @@ public interface ScrumRepository extends JpaRepository { Optional findByWorkerAndStatus(Member worker, EScrumStatus status); - List findAllByWorkerOrderByEndAtDesc(Member worker); + List findAllByWorkerAndStatusOrderByEndAtDesc(Member worker, EScrumStatus status); @Modifying(clearAutomatically = true) @Query("update Scrum s set s.endAt = :end, s.status = :status, s.summary = :summary where s.id = :scrumId") void updateScrumAfterOver(Long scrumId, String summary, EScrumStatus status, LocalDate end); diff --git a/src/main/java/goormthon/team28/startup_valley/service/GptService.java b/src/main/java/goormthon/team28/startup_valley/service/GptService.java index 5f4eacc..521664c 100644 --- a/src/main/java/goormthon/team28/startup_valley/service/GptService.java +++ b/src/main/java/goormthon/team28/startup_valley/service/GptService.java @@ -1,7 +1,7 @@ package goormthon.team28.startup_valley.service; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import goormthon.team28.startup_valley.constants.Constants; import goormthon.team28.startup_valley.dto.gpt.request.GptRequest; import goormthon.team28.startup_valley.dto.gpt.request.Message; import goormthon.team28.startup_valley.dto.gpt.response.GptResponse; @@ -23,13 +23,13 @@ public class GptService { @Value("${gpt.token}") private String gptSecretKey; private RestTemplate restTemplate = new RestTemplate(); - public String sendMessage(List works) throws JsonProcessingException { + public String sendMessage(List works, Boolean checkPoint) throws JsonProcessingException { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(gptSecretKey); log.info("gpt 헤더 설정 완료"); - HttpEntity httpEntity = new HttpEntity(makeRequest(works), headers); + HttpEntity httpEntity = new HttpEntity(makeRequest(works, checkPoint), headers); log.info("gpt http entity 생성 완료"); GptResponse gptResponse = restTemplate.exchange( @@ -42,10 +42,13 @@ public String sendMessage(List works) throws JsonProcessingException { return gptResponse.getChoices().get(0).getMessage().getContent(); } - private GptRequest makeRequest(List works){ + private GptRequest makeRequest(List works, boolean checkPoint){ List messages = new ArrayList<>(); - messages.add(Message.makeFirstMessage()); - works.forEach(work -> messages.add(Message.makeUserWork(work))); + if (checkPoint) + messages.add(Message.makeContent("system", Constants.GPT_SCRUM)); + else + messages.add(Message.makeContent("system", Constants.GPT_REVIEW)); + works.forEach(work -> messages.add(Message.makeContent("user", work))); log.info("message size = work's size + 1 = {}", messages.size()); return GptRequest.builder() .messages(messages) diff --git a/src/main/java/goormthon/team28/startup_valley/service/MemberService.java b/src/main/java/goormthon/team28/startup_valley/service/MemberService.java index 522f7cb..1cce2ce 100644 --- a/src/main/java/goormthon/team28/startup_valley/service/MemberService.java +++ b/src/main/java/goormthon/team28/startup_valley/service/MemberService.java @@ -10,6 +10,7 @@ import goormthon.team28.startup_valley.dto.response.MemberListDto; import goormthon.team28.startup_valley.dto.response.ScrumContributionDto; import goormthon.team28.startup_valley.dto.type.EPart; +import goormthon.team28.startup_valley.dto.type.EScrumStatus; import goormthon.team28.startup_valley.exception.CommonException; import goormthon.team28.startup_valley.exception.ErrorCode; import goormthon.team28.startup_valley.repository.MemberRepository; @@ -104,7 +105,8 @@ public MemberContributionDto retrieveContributionMember(Long userId, Long member // 조회하려는 멤버의 기여도가 비공개면서 조회하려는 멤버와 로그인 유저가 다른 경우 조회 불가능 처리 if (!targetMember.getUser().equals(currentUser) && !targetMember.getIsPublic()) throw new CommonException(ErrorCode.INVALID_CHECK_TEAM_CONTRIBUTION); - List scrumList = scrumRepository.findAllByWorkerOrderByEndAtDesc(targetMember); + List scrumList = scrumRepository + .findAllByWorkerAndStatusOrderByEndAtDesc(targetMember, EScrumStatus.FINISH); List scrumContributionDtoList = scrumList.stream() .map(scrum -> ScrumContributionDto.of( scrum.getId(), diff --git a/src/main/java/goormthon/team28/startup_valley/service/ReviewService.java b/src/main/java/goormthon/team28/startup_valley/service/ReviewService.java index 17e52c7..0a48e41 100644 --- a/src/main/java/goormthon/team28/startup_valley/service/ReviewService.java +++ b/src/main/java/goormthon/team28/startup_valley/service/ReviewService.java @@ -1,5 +1,6 @@ package goormthon.team28.startup_valley.service; +import com.fasterxml.jackson.core.JsonProcessingException; import goormthon.team28.startup_valley.domain.Member; import goormthon.team28.startup_valley.domain.Review; import goormthon.team28.startup_valley.domain.Team; @@ -29,6 +30,7 @@ public class ReviewService { private final UserRepository userRepository; private final MemberRepository memberRepository; private final TeamRepository teamRepository; + private final GptService gptService; public PeerReviewListDto listPeerReview(Long userId, Long teamsId) { @@ -47,7 +49,7 @@ public PeerReviewListDto listPeerReview(Long userId, Long teamsId) { member.getUser().getNickname(), member.getUser().getProfileImage(), member.getPart(), - reviewRepository.findBySender(currentMember) + reviewRepository.findBySenderAndReceiver(currentMember, member) .map(Review::getContent) .orElse(null) )) @@ -86,8 +88,24 @@ public Boolean postPeerReview(Long userId, Long teamsId, ReviewCreateDto reviewC .build(); reviewRepository.save(review); - // 추후에 GPT API 추가 + List teamMemberList = memberRepository.findAllByTeam(team); + List reviewList = reviewRepository.findAllByReceiver(targetMember); + // 자신을 제외한 모든 팀원들에게 동료 평가를 받은 경우 + if (teamMemberList.size() == reviewList.size() + 1) { + List reviewStringList = reviewList.stream() + .map(Review::getContent) + .toList(); + String peerReviewSummary = null; + try { + peerReviewSummary = gptService.sendMessage(reviewStringList, false); + } catch (JsonProcessingException e) { + throw new CommonException(ErrorCode.INTERNAL_SERVER_ERROR); + } finally { + targetMember.updatePeerReviewSummary(peerReviewSummary); + } + } return Boolean.TRUE; } + } diff --git a/src/main/java/goormthon/team28/startup_valley/service/ScrumService.java b/src/main/java/goormthon/team28/startup_valley/service/ScrumService.java index 2b5a702..dc40b93 100644 --- a/src/main/java/goormthon/team28/startup_valley/service/ScrumService.java +++ b/src/main/java/goormthon/team28/startup_valley/service/ScrumService.java @@ -64,7 +64,8 @@ public ScrumListDto listScrum(Long userId, Long membersId) { List scrumDtoList = new ArrayList<>(); for (Member tempMember : memberList) { - List scrumList = scrumRepository.findAllByWorkerOrderByEndAtDesc(tempMember); + List scrumList = scrumRepository + .findAllByWorkerAndStatusOrderByEndAtDesc(tempMember, EScrumStatus.FINISH); scrumDtoList.addAll( scrumList.stream() .map(scrum -> ScrumDto.of(