From 97c1dfb4a674138e1bda27f7afb1af1cc2f63a75 Mon Sep 17 00:00:00 2001 From: Sejeong Kim <64718002+clean2001@users.noreply.github.com> Date: Thu, 12 Sep 2024 20:51:12 +0900 Subject: [PATCH 1/9] =?UTF-8?q?fix/222:=20=EB=A9=A4=EB=B2=84=EA=B0=80=20?= =?UTF-8?q?=ED=83=88=ED=87=B4=ED=96=88=EC=9D=84=20=EB=95=8C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20(#229)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 스페이스 개수 조회 API 작성 * feat: 회고 개수 조회 API 작성 * feat: 특정 스페이스 내 회고 개수 API 작성 * feat: 특정 기간 내에 진행된 회고 개수 스페이스 별로 보는 API * fix: 파일 삭제 * fix: gradle-wrapper.properties 추가 * fix: 탈퇴 멤버 관련 로직 수정 * chore: application-local.yml 수정 * fix: Member 삭제 시간으로 변경 * fix: 잘못된 로직 수정 * test: where 절 추가 * fix: 스페이스에 속한 멤버 조회에서 잘못된 로직 수정 --- .../dto/response/AnswerByPersonGetResponse.java | 6 ++++-- .../dto/response/AnswerByQuestionGetResponse.java | 4 ++-- .../dto/response/PersonAndAnswerGetResponse.java | 2 ++ .../domain/answer/service/AnswerService.java | 9 +++++---- .../layer/domain/auth/service/AuthService.java | 2 +- .../domain/member/service/MemberService.java | 15 +++------------ .../layer/domain/space/service/SpaceService.java | 1 + .../org/layer/domain/member/entity/Member.java | 9 +++++++++ .../org/layer/domain/member/entity/Members.java | 12 ++++++++++-- .../org/layer/domain/space/dto/SpaceMember.java | 6 +++++- .../space/repository/SpaceRepositoryImpl.java | 14 ++++++++++++-- 11 files changed, 54 insertions(+), 26 deletions(-) diff --git a/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByPersonGetResponse.java b/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByPersonGetResponse.java index fc7b3b0d..7887bd5e 100644 --- a/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByPersonGetResponse.java +++ b/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByPersonGetResponse.java @@ -1,13 +1,15 @@ package org.layer.domain.answer.controller.dto.response; -import java.util.List; - import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + @Schema(name = "AnswerByPersonGetResponse", description = "개인별 답변 조회 응답 Dto") public record AnswerByPersonGetResponse( @Schema(description = "답변자", example = "홍길동") String name, + @Schema(description = "탈퇴 여부. 탈퇴시 true", example = "false") + Boolean deleted, @Schema(description = "질문-답변 객체", example = "") List answers ) { diff --git a/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByQuestionGetResponse.java b/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByQuestionGetResponse.java index be6540f8..2df000b9 100644 --- a/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByQuestionGetResponse.java +++ b/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/AnswerByQuestionGetResponse.java @@ -1,9 +1,9 @@ package org.layer.domain.answer.controller.dto.response; -import java.util.List; - import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + @Schema(name = "AnswerByQuestionGetResponse", description = "임시 회고 조회 응답 Dto") public record AnswerByQuestionGetResponse( @Schema(description = "질문 내용", example = "질문 내용입니당") diff --git a/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/PersonAndAnswerGetResponse.java b/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/PersonAndAnswerGetResponse.java index 7de6a59f..81230146 100644 --- a/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/PersonAndAnswerGetResponse.java +++ b/layer-api/src/main/java/org/layer/domain/answer/controller/dto/response/PersonAndAnswerGetResponse.java @@ -6,6 +6,8 @@ public record PersonAndAnswerGetResponse( @Schema(description = "답변자", example = "홍길동") String name, + @Schema(description = "탈퇴 여부. 탈퇴시 true", example = "false") + Boolean deleted, @Schema(description = "답변 내용", example = "답변 내용입니당") String answerContent ) { diff --git a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java index ce44bcd4..4bf46c12 100644 --- a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java +++ b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java @@ -1,7 +1,7 @@ package org.layer.domain.answer.service; import lombok.RequiredArgsConstructor; - +import lombok.extern.slf4j.Slf4j; import org.layer.domain.analyze.entity.Analyze; import org.layer.domain.analyze.enums.AnalyzeType; import org.layer.domain.analyze.repository.AnalyzeRepository; @@ -40,6 +40,7 @@ import static org.layer.common.exception.AnswerExceptionType.NOT_ANSWERED; import static org.layer.common.exception.MemberSpaceRelationExceptionType.NOT_FOUND_MEMBER_SPACE_RELATION; +@Slf4j @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -248,19 +249,19 @@ private List getAnswerByPersonGetResponses(Answers an question.getId(), member.getId()))) .toList(); - return new AnswerByPersonGetResponse(member.getName(), questionAndAnswer); + return new AnswerByPersonGetResponse(member.getName(), member.getDeletedAt() != null, questionAndAnswer); }) .toList(); } private List getAnswerByQuestionGetResponses(Answers answers, Members members, List questions) { + return questions.stream() .map(question -> { List personAndAnswer = answers.getAnswers().stream() .filter(answer -> answer.getQuestionId().equals(question.getId())) - .map(answer -> new PersonAndAnswerGetResponse(members.getName(answer.getMemberId()), - answer.getContent())) + .map(answer -> new PersonAndAnswerGetResponse(members.getName(answer.getMemberId()), members.getDeleted(answer.getMemberId()), answer.getContent())) .toList(); return new AnswerByQuestionGetResponse(question.getContent(), question.getQuestionType().getStyle(), diff --git a/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java b/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java index b482b9fd..d88325d9 100644 --- a/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java +++ b/layer-api/src/main/java/org/layer/domain/auth/service/AuthService.java @@ -93,7 +93,7 @@ public void withdraw(final Long memberId, WithdrawMemberRequest withdrawMemberRe } - // hard delete + // soft delete memberService.withdrawMember(memberId); } diff --git a/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java b/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java index 7369f0b9..64582d95 100644 --- a/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java +++ b/layer-api/src/main/java/org/layer/domain/member/service/MemberService.java @@ -12,14 +12,7 @@ import org.layer.domain.external.google.enums.SheetType; import org.layer.domain.external.google.service.GoogleApiService; import org.layer.domain.jwt.SecurityUtil; -import org.layer.domain.member.controller.dto.CreateFeedbackRequest; -import org.layer.domain.member.controller.dto.GetMemberAnalyzesResponse; -import org.layer.domain.member.controller.dto.GetMemberRecentAnalyzeResponse; -import org.layer.domain.member.controller.dto.GetMemberRecentBadAnalyzeResponse; -import org.layer.domain.member.controller.dto.GetMemberRecentGoodAnalyzeResponse; -import org.layer.domain.member.controller.dto.GetMemberRecentImprovementAnalyzeResponse; -import org.layer.domain.member.controller.dto.UpdateMemberInfoRequest; -import org.layer.domain.member.controller.dto.UpdateMemberInfoResponse; +import org.layer.domain.member.controller.dto.*; import org.layer.domain.member.entity.Member; import org.layer.domain.member.entity.MemberFeedback; import org.layer.domain.member.entity.SocialType; @@ -28,14 +21,12 @@ import org.layer.domain.retrospect.entity.RetrospectStatus; import org.layer.domain.retrospect.repository.RetrospectRepository; import org.layer.domain.space.entity.MemberSpaceRelation; -import org.layer.domain.space.entity.Space; import org.layer.domain.space.repository.MemberSpaceRelationRepository; import org.layer.oauth.dto.service.MemberInfoServiceResponse; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -48,7 +39,7 @@ @RequiredArgsConstructor @Service public class MemberService { -private static final int TWO_MONTHS = 2; + private static final int TWO_MONTHS = 2; private final MemberRepository memberRepository; private final MemberSpaceRelationRepository memberSpaceRelationRepository; @@ -122,7 +113,7 @@ public Member getMemberByMemberId(Long memberId) { @Transactional public void withdrawMember(Long memberId) { Member currentMember = getCurrentMember(); - memberRepository.delete(currentMember); + currentMember.deleteMember(); } @Transactional diff --git a/layer-api/src/main/java/org/layer/domain/space/service/SpaceService.java b/layer-api/src/main/java/org/layer/domain/space/service/SpaceService.java index 1796ed6b..48ea4912 100644 --- a/layer-api/src/main/java/org/layer/domain/space/service/SpaceService.java +++ b/layer-api/src/main/java/org/layer/domain/space/service/SpaceService.java @@ -194,6 +194,7 @@ public List getSpaceMembers(Long memberId, Lo log.info("?"); var SpaceMembers = spaceRepository.findAllSpaceMemberBySpaceIdWithIsLeader(spaceId); return SpaceMembers.stream() + .filter(a -> a.getDeletedAt() == null) .map(SpaceResponse.SpaceMemberResponse::toResponse) .sorted( Comparator.comparing(SpaceResponse.SpaceMemberResponse::isLeader).reversed()) diff --git a/layer-domain/src/main/java/org/layer/domain/member/entity/Member.java b/layer-domain/src/main/java/org/layer/domain/member/entity/Member.java index e9694330..45c6c225 100644 --- a/layer-domain/src/main/java/org/layer/domain/member/entity/Member.java +++ b/layer-domain/src/main/java/org/layer/domain/member/entity/Member.java @@ -8,6 +8,8 @@ import lombok.NoArgsConstructor; import org.layer.domain.common.BaseTimeEntity; +import java.time.LocalDateTime; + @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -36,6 +38,9 @@ public class Member extends BaseTimeEntity { private String profileImageUrl; + private LocalDateTime deletedAt; + + @Builder(access = AccessLevel.PUBLIC) private Member(String name, String email, MemberRole memberRole, SocialType socialType, String socialId) { @@ -53,4 +58,8 @@ public void updateName(String name) { public void updateProfileImageUrl(String profileImageUrl) { this.profileImageUrl = profileImageUrl; } + + public void deleteMember() { + this.deletedAt = LocalDateTime.now(); + } } diff --git a/layer-domain/src/main/java/org/layer/domain/member/entity/Members.java b/layer-domain/src/main/java/org/layer/domain/member/entity/Members.java index 461bcd5c..55316056 100644 --- a/layer-domain/src/main/java/org/layer/domain/member/entity/Members.java +++ b/layer-domain/src/main/java/org/layer/domain/member/entity/Members.java @@ -1,10 +1,10 @@ package org.layer.domain.member.entity; -import java.util.List; - import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.List; + @RequiredArgsConstructor @Getter public class Members { @@ -17,4 +17,12 @@ public String getName(Long memberId) { .findAny() .orElse(null); } + + public Boolean getDeleted(Long memberId) { + return members.stream() + .filter(member -> member.getId().equals(memberId)) + .map(m -> m.getDeletedAt() != null) // 지워졌으면 true, 아니면 false + .findAny() + .orElse(null); + } } diff --git a/layer-domain/src/main/java/org/layer/domain/space/dto/SpaceMember.java b/layer-domain/src/main/java/org/layer/domain/space/dto/SpaceMember.java index 7991fc9f..0132ccdb 100644 --- a/layer-domain/src/main/java/org/layer/domain/space/dto/SpaceMember.java +++ b/layer-domain/src/main/java/org/layer/domain/space/dto/SpaceMember.java @@ -3,6 +3,8 @@ import com.querydsl.core.annotations.QueryProjection; import lombok.Getter; +import java.time.LocalDateTime; + @Getter public class SpaceMember { @@ -12,12 +14,14 @@ public class SpaceMember { private final String name; private final Boolean isLeader; + private final LocalDateTime deletedAt; @QueryProjection - public SpaceMember(Long id, String avatar, String name, Boolean isLeader) { + public SpaceMember(Long id, String avatar, String name, Boolean isLeader, LocalDateTime deletedAt) { this.id = id; this.avatar = avatar; this.name = name; this.isLeader = isLeader; + this.deletedAt = deletedAt; } } diff --git a/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceRepositoryImpl.java b/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceRepositoryImpl.java index c81897f2..7b78e6a0 100644 --- a/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceRepositoryImpl.java +++ b/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceRepositoryImpl.java @@ -51,6 +51,7 @@ public Optional findByIdAndJoinedMemberId(Long spaceId, Lo var foundSpace = getSpaceWithMemberCountQuery(memberId) .where(space.id.eq(spaceId)) + .where(member.deletedAt.isNull()) // 삭제되지 않은 회원만 .fetchOne(); if (foundSpace == null || isSpaceWithMemberCountEmpty(foundSpace)) { @@ -63,7 +64,10 @@ public Optional findByIdAndJoinedMemberId(Long spaceId, Lo @Override public Optional findByIdAndJoinedMemberId(Long spaceId) { - var foundSpace = getSpaceWithMemberCountQuery().where(space.id.eq(spaceId)).fetchOne(); + var foundSpace = getSpaceWithMemberCountQuery() + .where(space.id.eq(spaceId)) + .where(member.deletedAt.isNull()) // 삭제되지 않은 회원만 + .fetchOne(); if (foundSpace == null || isSpaceWithMemberCountEmpty(foundSpace)) { return Optional.empty(); @@ -93,7 +97,8 @@ public List findAllSpaceMemberBySpaceIdWithIsLeader(Long spaceId) { member.id, member.profileImageUrl, member.name, - space.leaderId.eq(member.id) + space.leaderId.eq(member.id), + member.deletedAt ) ) .from(memberSpaceRelation) @@ -102,6 +107,7 @@ public List findAllSpaceMemberBySpaceIdWithIsLeader(Long spaceId) { .leftJoin(space) .on(memberSpaceRelation.space.id.eq(space.id)) .where(memberSpaceRelation.space.id.eq(spaceId).and(member.id.isNotNull())) + .where(member.deletedAt.isNull()) // 삭제되지 않은 회원만 .orderBy(memberSpaceRelation.createdAt.asc()) .fetch(); } @@ -128,6 +134,8 @@ private JPAQuery getSpaceWithMemberCountQuery() { .leftJoin(memberCountRelationTable).on(space.id.eq(memberCountRelationTable.space.id)) .leftJoin(member).on(space.leaderId.eq(member.id)) .leftJoin(form).on(space.formId.eq(form.id)) + .leftJoin(member).on(memberSpaceRelation.memberId.eq(member.id)) // memberId와 member의 id 조인 + .where(member.deletedAt.isNull()) // 삭제되지 않은 회원만 .orderBy(space.createdAt.desc()) .orderBy(form.id.desc()) .limit(1); @@ -157,6 +165,8 @@ private JPAQuery getSpaceWithMemberCountQuery(Long memberI .leftJoin(memberCountRelationTable).on(space.id.eq(memberCountRelationTable.space.id)) .leftJoin(member).on(space.leaderId.eq(member.id)) .leftJoin(form).on(space.formId.eq(form.id)) + .leftJoin(member).on(memberSpaceRelation.memberId.eq(member.id)) // memberId와 member의 id 조인 + .where(member.deletedAt.isNull()) // 삭제되지 않은 회원만 .orderBy(space.createdAt.desc()) .orderBy(form.id.desc()) .limit(1); From 970944aa9cfb107837063298e81383a943b07baf Mon Sep 17 00:00:00 2001 From: Raymond Date: Thu, 12 Sep 2024 21:02:38 +0900 Subject: [PATCH 2/9] =?UTF-8?q?fix:=20nullable=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/layer/domain/actionItem/service/ActionItemService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/layer-api/src/main/java/org/layer/domain/actionItem/service/ActionItemService.java b/layer-api/src/main/java/org/layer/domain/actionItem/service/ActionItemService.java index 8e8821cc..b04150dd 100644 --- a/layer-api/src/main/java/org/layer/domain/actionItem/service/ActionItemService.java +++ b/layer-api/src/main/java/org/layer/domain/actionItem/service/ActionItemService.java @@ -171,7 +171,8 @@ public SpaceActionItemGetResponse getSpaceRecentActionItems(Long memberId, Long // 종료된 것 중 가장 최근에 만들어진 회고 찾기 Optional recentOpt = retrospectList.stream() .filter(r -> r.getRetrospectStatus().equals(DONE)) // 끝난 회고 찾기 - .sorted((a, b) -> b.getDeadline().compareTo(a.getDeadline())) // deadline 내림차순으로 정렬 + .sorted(Comparator.comparing(Retrospect::getDeadline, + Comparator.nullsLast(Comparator.naturalOrder())).reversed()) // deadline 내림차순, null은 아래로 정렬 .findFirst(); if (recentOpt.isPresent()) { From 96229252a605f9f14aac21de874b349b13cf6d6f Mon Sep 17 00:00:00 2001 From: Mingyu Song <100754581+mikekks@users.noreply.github.com> Date: Thu, 12 Sep 2024 21:08:14 +0900 Subject: [PATCH 3/9] =?UTF-8?q?chore:=20=ED=9A=8C=EA=B3=A0=20=EB=8B=B5?= =?UTF-8?q?=EB=B3=80=20=EC=A7=81=ED=9B=84=EC=97=90=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#237)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/answer/service/AnswerService.java | 5 ++-- .../layer/domain/answer/entity/Answers.java | 28 ++++++++++++------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java index 4bf46c12..84518c0e 100644 --- a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java +++ b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java @@ -181,11 +181,10 @@ public AnswerListGetResponse getAnalyzeAnswer(Long spaceId, Long retrospectId, L Team team = new Team(memberSpaceRelationRepository.findAllBySpaceId(spaceId)); team.validateTeamMembership(memberId); - Retrospect retrospect = retrospectRepository.findByIdOrThrow(retrospectId); - retrospect.validateRetrospectStatusDone(); - // answer 뽑기 Answers answers = new Answers(answerRepository.findAllByRetrospectId(retrospectId)); + answers.validateIsWriteDone(memberId, retrospectId); + List questionIds = answers.getAnswers().stream().map(Answer::getQuestionId).toList(); List memberIds = answers.getAnswers().stream().map(Answer::getMemberId).toList(); diff --git a/layer-domain/src/main/java/org/layer/domain/answer/entity/Answers.java b/layer-domain/src/main/java/org/layer/domain/answer/entity/Answers.java index 6507c8fd..1f801ecd 100644 --- a/layer-domain/src/main/java/org/layer/domain/answer/entity/Answers.java +++ b/layer-domain/src/main/java/org/layer/domain/answer/entity/Answers.java @@ -28,7 +28,6 @@ public class Answers { private final List answers; - public String getAnswerToQuestion(Long questionId, Long memberId) { return answers.stream() .filter(answer -> answer.getQuestionId().equals(questionId) && answer.getMemberId().equals(memberId)) @@ -43,12 +42,20 @@ public boolean hasRetrospectAnswer(Long memberId, Long retrospectId) { .anyMatch(answer -> answer.getMemberId().equals(memberId)); } + public void validateIsWriteDone(Long memberId, Long retrospectId) { + WriteStatus writeStatus = getWriteStatus(memberId, retrospectId); + + if (!writeStatus.equals(WriteStatus.DONE)) { + throw new AnswerException(NOT_ANSWERED); + } + } + public WriteStatus getWriteStatus(Long memberId, Long retrospectId) { boolean isDoneWrite = answers.stream() .filter(answer -> answer.getRetrospectId().equals(retrospectId)) .filter(answer -> answer.getMemberId().equals(memberId)) .anyMatch(answer -> answer.getAnswerStatus().equals(AnswerStatus.DONE)); - if(isDoneWrite){ + if (isDoneWrite) { return WriteStatus.DONE; } @@ -56,7 +63,7 @@ public WriteStatus getWriteStatus(Long memberId, Long retrospectId) { .filter(answer -> answer.getRetrospectId().equals(retrospectId)) .filter(answer -> answer.getMemberId().equals(memberId)) .anyMatch(answer -> answer.getAnswerStatus().equals(AnswerStatus.TEMPORARY)); - if(isTemporaryWrite){ + if (isTemporaryWrite) { return WriteStatus.PROCEEDING; } @@ -70,7 +77,7 @@ public long getWriteCount(Long retrospectId) { Set answerMembers = new HashSet<>(); - if(!answersByRetrospectId.containsKey(retrospectId)){ + if (!answersByRetrospectId.containsKey(retrospectId)) { return 0L; } @@ -111,9 +118,10 @@ public void validateAlreadyAnswer(Long memberId, Long retrospectId) { } } - public String getTotalAnswer(Long rangeQuestionId, Long numberQuestionId){ + public String getTotalAnswer(Long rangeQuestionId, Long numberQuestionId) { Map answerConcatMap = answers.stream() - .filter(answer -> !answer.getQuestionId().equals(rangeQuestionId) && !answer.getQuestionId().equals(numberQuestionId)) + .filter(answer -> !answer.getQuestionId().equals(rangeQuestionId) && !answer.getQuestionId() + .equals(numberQuestionId)) .collect(Collectors.groupingBy( Answer::getMemberId, Collectors.mapping(Answer::getContent, Collectors.joining(" ")))); @@ -125,10 +133,11 @@ public String getTotalAnswer(Long rangeQuestionId, Long numberQuestionId){ return String.join("\n&&\n", answerMap.values()); } - public String getIndividualAnswer(Long rangeQuestionId, Long numberQuestionId, Long memberId){ + public String getIndividualAnswer(Long rangeQuestionId, Long numberQuestionId, Long memberId) { Map answerConcatMap = answers.stream() .filter(answer -> answer.getMemberId().equals(memberId)) - .filter(answer -> !answer.getQuestionId().equals(rangeQuestionId) && !answer.getQuestionId().equals(numberQuestionId)) + .filter(answer -> !answer.getQuestionId().equals(rangeQuestionId) && !answer.getQuestionId() + .equals(numberQuestionId)) .collect(Collectors.groupingBy( Answer::getMemberId, Collectors.mapping(Answer::getContent, Collectors.joining(" ")))); @@ -140,7 +149,6 @@ public String getIndividualAnswer(Long rangeQuestionId, Long numberQuestionId, L return String.join("\n&&\n", answerMap.values()); } - public int getGoalCompletionRate(Long questionId) { int sum = 0; @@ -152,7 +160,7 @@ public int getGoalCompletionRate(Long questionId) { } } - if(count == ZERO){ + if (count == ZERO) { throw new AnswerException(NOT_CONTAIN_ANSWERS); } From 9bf30ec1f06c094b02b894414a67cfa7fe4d972e Mon Sep 17 00:00:00 2001 From: Mingyu Song <100754581+mikekks@users.noreply.github.com> Date: Thu, 12 Sep 2024 21:38:54 +0900 Subject: [PATCH 4/9] =?UTF-8?q?fix:=20=ED=9A=8C=EA=B3=A0=20=EB=A7=88?= =?UTF-8?q?=EA=B0=90=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20(#240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../external/ai/service/AIAnalyzeService.java | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java b/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java index 965d2391..96958488 100644 --- a/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java +++ b/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java @@ -67,31 +67,37 @@ public void createAnalyze(Long spaceId, Long retrospectId, List memberIds) String totalAnswer = answers.getTotalAnswer(rangeQuestionId, numberQuestionId); // 분석 요청 - List analyzes = new ArrayList<>(); - - OpenAIResponse aiResponse = openAIService.createAnalyze(totalAnswer); - OpenAIResponse.Content content = aiResponse.parseContent(); - Analyze teamAnalyze = getAnalyzeEntity(retrospectId, answers, rangeQuestionId, numberQuestionId, content, - null, AnalyzeType.TEAM); - analyzes.add(teamAnalyze); - - List individualAnalyzes = memberIds.stream() - .map(memberId -> { - String individualAnswer = answers.getIndividualAnswer(rangeQuestionId, numberQuestionId, memberId); - OpenAIResponse aiIndividualResponse = openAIService.createAnalyze(individualAnswer); - OpenAIResponse.Content individualcontent = aiIndividualResponse.parseContent(); - return getAnalyzeEntity(retrospectId, answers, rangeQuestionId, numberQuestionId, individualcontent, - memberId, AnalyzeType.INDIVIDUAL); - }).toList(); - analyzes.addAll(individualAnalyzes); - - analyzeRepository.saveAll(analyzes); + try{ + List analyzes = new ArrayList<>(); + + OpenAIResponse aiResponse = openAIService.createAnalyze(totalAnswer); + OpenAIResponse.Content content = aiResponse.parseContent(); + + Analyze teamAnalyze = getAnalyzeEntity(retrospectId, answers, rangeQuestionId, numberQuestionId, content, + null, AnalyzeType.TEAM); + analyzes.add(teamAnalyze); + + List individualAnalyzes = memberIds.stream() + .map(memberId -> { + String individualAnswer = answers.getIndividualAnswer(rangeQuestionId, numberQuestionId, memberId); + OpenAIResponse aiIndividualResponse = openAIService.createAnalyze(individualAnswer); + OpenAIResponse.Content individualcontent = aiIndividualResponse.parseContent(); + return getAnalyzeEntity(retrospectId, answers, rangeQuestionId, numberQuestionId, individualcontent, + memberId, AnalyzeType.INDIVIDUAL); + }).toList(); + analyzes.addAll(individualAnalyzes); + + analyzeRepository.saveAll(analyzes); + }catch (Exception e){ + log.info("Not enough Answers"); + } long endTime = System.currentTimeMillis(); // 종료 시간 기록 long duration = endTime - startTime; // 경과 시간 계산 log.info("createAnalyze completed in {} ms", duration); retrospect.updateAnalysisStatus(AnalysisStatus.DONE); + retrospectRepository.save(retrospect); // TODO: 왜 더티체킹이 안될까?? } private Analyze getAnalyzeEntity(Long retrospectId, Answers answers, Long rangeQuestionId, Long numberQuestionId, From ba63e07a63298d8c2a957086609a29c751edfe99 Mon Sep 17 00:00:00 2001 From: Raymond Date: Fri, 13 Sep 2024 00:28:24 +0900 Subject: [PATCH 5/9] =?UTF-8?q?chore:=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- layer-api/src/main/resources/application-prod.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layer-api/src/main/resources/application-prod.yml b/layer-api/src/main/resources/application-prod.yml index 0cc8f953..bb726150 100644 --- a/layer-api/src/main/resources/application-prod.yml +++ b/layer-api/src/main/resources/application-prod.yml @@ -3,8 +3,8 @@ spring: import: optional:file:/config/application-secret.properties datasource: url: ${PROD_DB_URL} - username: ${DEV_DB_NAME} - password: ${DEV_DB_PASSWORD} + username: ${PROD_DB_NAME} + password: ${PROD_DB_PASSWORD} driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: From af5c8253b972a0eb3aa030addf28fb7a384c948b Mon Sep 17 00:00:00 2001 From: mikekks Date: Fri, 13 Sep 2024 00:50:46 +0900 Subject: [PATCH 6/9] =?UTF-8?q?fix:=20ai=20=EB=B6=84=EC=84=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/layer/domain/retrospect/service/RetrospectService.java | 1 + .../java/org/layer/external/ai/service/AIAnalyzeService.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java b/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java index bc9a232e..0bded069 100644 --- a/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java +++ b/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java @@ -186,5 +186,6 @@ public void closeRetrospect(Long spaceId, Long retrospectId, Long memberId) { // 회고 ai 분석 시작 aiAnalyzeService.createAnalyze(spaceId, retrospectId, answers.getWriteMemberIds()); + } } diff --git a/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java b/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java index 96958488..8097ca64 100644 --- a/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java +++ b/layer-external/src/main/java/org/layer/external/ai/service/AIAnalyzeService.java @@ -55,7 +55,6 @@ public void createAnalyze(Long spaceId, Long retrospectId, List memberIds) // 회고 마감 여부 확인 Retrospect retrospect = retrospectRepository.findByIdOrThrow(retrospectId); - retrospect.validateRetrospectStatusDone(); // 답변 조회 Questions questions = new Questions(questionRepository.findAllByRetrospectIdOrderByQuestionOrder(retrospectId)); From 1a7ec97a73eba0667efdf9e654e38b0ee3cce351 Mon Sep 17 00:00:00 2001 From: mikekks Date: Fri, 13 Sep 2024 01:28:34 +0900 Subject: [PATCH 7/9] =?UTF-8?q?hotfix:=20=EB=A7=88=EA=B0=90=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/layer/domain/answer/service/AnswerService.java | 4 ++-- .../org/layer/domain/retrospect/entity/Retrospect.java | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java index 84518c0e..8784cebb 100644 --- a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java +++ b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java @@ -100,8 +100,8 @@ public void create(AnswerListCreateRequest request, Long spaceId, Long retrospec Answers answers = new Answers(answerRepository.findAllByRetrospectId(retrospectId)); - // 마지막 답변일 경우 -> ai 분석 실행 - if (answers.getWriteCount(retrospectId) == team.getTeamMemberCount()){ + // 마지막 답변이고, 마감일이 지정되지 않은 경우 -> ai 분석 실행 + if (answers.getWriteCount(retrospectId) == team.getTeamMemberCount() && !retrospect.hasDeadLine()){ retrospect.updateRetrospectStatus(RetrospectStatus.DONE, time.now()); retrospect.updateAnalysisStatus(AnalysisStatus.PROCEEDING); retrospectRepository.saveAndFlush(retrospect); diff --git a/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java index 2f0bcfe0..14b15d81 100644 --- a/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java +++ b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java @@ -90,7 +90,7 @@ public void updateRetrospect(String title, String introduction, LocalDateTime de public void updateRetrospectStatus(RetrospectStatus retrospectStatus, LocalDateTime now) { isProceedingRetrospect(); - if(this.deadline != null && now.isBefore(this.deadline)){ + if (this.deadline != null && now.isBefore(this.deadline)) { return; } @@ -100,4 +100,12 @@ public void updateRetrospectStatus(RetrospectStatus retrospectStatus, LocalDateT public void updateAnalysisStatus(AnalysisStatus analysisStatus) { this.analysisStatus = analysisStatus; } + + public boolean hasDeadLine() { + if (this.deadline == null) { + return false; + } + + return true; + } } From 3fd6ce04e2e457a3515c8cc6982d96e9f712ca14 Mon Sep 17 00:00:00 2001 From: mikekks Date: Fri, 13 Sep 2024 01:56:42 +0900 Subject: [PATCH 8/9] =?UTF-8?q?hotfix:=20=EB=A7=88=EA=B0=90=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../layer/domain/answer/service/AnswerService.java | 11 +++++++---- .../domain/retrospect/service/RetrospectService.java | 2 +- .../layer/batch/scheduler/RetrospectScheduler.java | 2 +- .../layer/domain/retrospect/entity/Retrospect.java | 6 +----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java index 8784cebb..b171bb2a 100644 --- a/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java +++ b/layer-api/src/main/java/org/layer/domain/answer/service/AnswerService.java @@ -100,11 +100,14 @@ public void create(AnswerListCreateRequest request, Long spaceId, Long retrospec Answers answers = new Answers(answerRepository.findAllByRetrospectId(retrospectId)); - // 마지막 답변이고, 마감일이 지정되지 않은 경우 -> ai 분석 실행 - if (answers.getWriteCount(retrospectId) == team.getTeamMemberCount() && !retrospect.hasDeadLine()){ - retrospect.updateRetrospectStatus(RetrospectStatus.DONE, time.now()); + // 마지막 답변인 경우 -> ai 분석 실행 + if (answers.getWriteCount(retrospectId) == team.getTeamMemberCount()){ retrospect.updateAnalysisStatus(AnalysisStatus.PROCEEDING); - retrospectRepository.saveAndFlush(retrospect); + + if(!retrospect.hasDeadLine()){ + retrospect.updateRetrospectStatus(RetrospectStatus.DONE); + } + retrospectRepository.saveAndFlush(retrospect); aiAnalyzeService.createAnalyze(spaceId, retrospectId, answers.getWriteMemberIds()); } diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java b/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java index 0bded069..d1c6ed1e 100644 --- a/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java +++ b/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java @@ -178,7 +178,7 @@ public void closeRetrospect(Long spaceId, Long retrospectId, Long memberId) { Retrospect retrospect = retrospectRepository.findByIdOrThrow(retrospectId); - retrospect.updateRetrospectStatus(RetrospectStatus.DONE, time.now()); + retrospect.updateRetrospectStatus(RetrospectStatus.DONE); retrospect.updateAnalysisStatus(AnalysisStatus.PROCEEDING); retrospectRepository.saveAndFlush(retrospect); diff --git a/layer-batch/src/main/java/org/layer/batch/scheduler/RetrospectScheduler.java b/layer-batch/src/main/java/org/layer/batch/scheduler/RetrospectScheduler.java index 7145cbe0..9280f083 100644 --- a/layer-batch/src/main/java/org/layer/batch/scheduler/RetrospectScheduler.java +++ b/layer-batch/src/main/java/org/layer/batch/scheduler/RetrospectScheduler.java @@ -43,7 +43,7 @@ public void updateRetrospectStatusToDone() { Map retrospectMap = retrospects.stream() .collect(Collectors.toMap(Retrospect::getId, retrospect -> retrospect)); - retrospects.forEach(retrospect -> retrospect.updateRetrospectStatus(RetrospectStatus.DONE, now)); + retrospects.forEach(retrospect -> retrospect.updateRetrospectStatus(RetrospectStatus.DONE)); retrospectRepository.saveAllAndFlush(retrospects); List retrospectIds = retrospects.stream().map(Retrospect::getId).toList(); diff --git a/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java index 14b15d81..c4cebf1b 100644 --- a/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java +++ b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/Retrospect.java @@ -87,13 +87,9 @@ public void updateRetrospect(String title, String introduction, LocalDateTime de this.deadline = deadline; } - public void updateRetrospectStatus(RetrospectStatus retrospectStatus, LocalDateTime now) { + public void updateRetrospectStatus(RetrospectStatus retrospectStatus) { isProceedingRetrospect(); - if (this.deadline != null && now.isBefore(this.deadline)) { - return; - } - this.retrospectStatus = retrospectStatus; } From e86408ee09db1db9ef12b6662106b87a6c3ebbab Mon Sep 17 00:00:00 2001 From: Mingyu Song <100754581+mikekks@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:59:19 +0900 Subject: [PATCH 9/9] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=20=EB=A7=88?= =?UTF-8?q?=EA=B0=90=EB=90=98=EC=97=88=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#243)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../layer/domain/retrospect/service/RetrospectService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java b/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java index d1c6ed1e..825943f4 100644 --- a/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java +++ b/layer-api/src/main/java/org/layer/domain/retrospect/service/RetrospectService.java @@ -179,6 +179,10 @@ public void closeRetrospect(Long spaceId, Long retrospectId, Long memberId) { Retrospect retrospect = retrospectRepository.findByIdOrThrow(retrospectId); retrospect.updateRetrospectStatus(RetrospectStatus.DONE); + if (retrospect.getAnalysisStatus().equals(AnalysisStatus.DONE)) { // 이미 분석은 완료했지만, 마감되지 않은 경우 + return; + } + retrospect.updateAnalysisStatus(AnalysisStatus.PROCEEDING); retrospectRepository.saveAndFlush(retrospect);