From 1419e3b25fefb28a522e1b3b680ccc6700cd9bd7 Mon Sep 17 00:00:00 2001 From: Mingyu Song <100754581+mikekks@users.noreply.github.com> Date: Wed, 11 Sep 2024 09:25:47 +0900 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20=EC=B6=94=EC=B2=9C=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=EC=9D=B4=20=EC=A4=91=EB=B3=B5=EC=9D=B8=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0,=20=EA=B7=B8=20=EC=A4=91=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EB=9E=9C=EB=8D=A4=EC=9C=BC=EB=A1=9C=20=ED=95=98=EB=82=98=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(#220)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/form/service/FormService.java | 6 ++++- .../domain/common/random/CustomRandom.java | 7 ++++++ .../domain/common/random/MockRandom.java | 19 ++++++++++++++++ .../domain/common/random/RealRandom.java | 22 +++++++++++++++++++ .../org/layer/domain/form/enums/FormTag.java | 17 +++++++++----- 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 layer-domain/src/main/java/org/layer/domain/common/random/CustomRandom.java create mode 100644 layer-domain/src/main/java/org/layer/domain/common/random/MockRandom.java create mode 100644 layer-domain/src/main/java/org/layer/domain/common/random/RealRandom.java diff --git a/layer-api/src/main/java/org/layer/domain/form/service/FormService.java b/layer-api/src/main/java/org/layer/domain/form/service/FormService.java index b5a53bd9..6a2989bd 100644 --- a/layer-api/src/main/java/org/layer/domain/form/service/FormService.java +++ b/layer-api/src/main/java/org/layer/domain/form/service/FormService.java @@ -1,6 +1,8 @@ package org.layer.domain.form.service; import lombok.RequiredArgsConstructor; + +import org.layer.domain.common.random.CustomRandom; import org.layer.domain.form.controller.dto.request.FormNameUpdateRequest; import org.layer.domain.form.controller.dto.request.RecommendFormQueryDto; import org.layer.domain.form.controller.dto.request.RecommendFormSetRequest; @@ -46,6 +48,8 @@ public class FormService { private final SpaceRepository spaceRepository; private final TemplateMetadataRepository metadataRepository; + private final CustomRandom customRandom; + /** * 회고 폼 질문을 조회한다. * @@ -72,7 +76,7 @@ public FormGetResponse getForm(Long formId, Long memberId) { } public RecommendFormResponseDto getRecommendTemplate(RecommendFormQueryDto queryDto) { - FormTag recommandFormTag = FormTag.getRecommandFormTag(queryDto.purpose()); + FormTag recommandFormTag = FormTag.getRecommandFormTag(queryDto.purpose(), customRandom); Form form = formRepository.findByFormTagAndFormTypeOrThrow(recommandFormTag, FormType.TEMPLATE); TemplateMetadata metadata = metadataRepository.findByFormIdOrThrow(form.getId()); diff --git a/layer-domain/src/main/java/org/layer/domain/common/random/CustomRandom.java b/layer-domain/src/main/java/org/layer/domain/common/random/CustomRandom.java new file mode 100644 index 00000000..c0a1ea07 --- /dev/null +++ b/layer-domain/src/main/java/org/layer/domain/common/random/CustomRandom.java @@ -0,0 +1,7 @@ +package org.layer.domain.common.random; + +public interface CustomRandom { + String generateRandomValue(); + + int nextInt(int index); +} diff --git a/layer-domain/src/main/java/org/layer/domain/common/random/MockRandom.java b/layer-domain/src/main/java/org/layer/domain/common/random/MockRandom.java new file mode 100644 index 00000000..817f963c --- /dev/null +++ b/layer-domain/src/main/java/org/layer/domain/common/random/MockRandom.java @@ -0,0 +1,19 @@ +package org.layer.domain.common.random; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +@Component +@Profile("test") +public class MockRandom implements CustomRandom { + + @Override + public String generateRandomValue() { + return "test-random-value"; + } + + @Override + public int nextInt(int index) { + return 1; + } +} diff --git a/layer-domain/src/main/java/org/layer/domain/common/random/RealRandom.java b/layer-domain/src/main/java/org/layer/domain/common/random/RealRandom.java new file mode 100644 index 00000000..33bb7a77 --- /dev/null +++ b/layer-domain/src/main/java/org/layer/domain/common/random/RealRandom.java @@ -0,0 +1,22 @@ +package org.layer.domain.common.random; + +import java.util.Random; +import java.util.UUID; + +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +@Component +@Profile({"local", "dev", "prod"}) +public class RealRandom implements CustomRandom { + @Override + public String generateRandomValue() { + return UUID.randomUUID().toString().substring(0, 13); + } + + @Override + public int nextInt(int index) { + Random random = new Random(); + return random.nextInt(index); + } +} diff --git a/layer-domain/src/main/java/org/layer/domain/form/enums/FormTag.java b/layer-domain/src/main/java/org/layer/domain/form/enums/FormTag.java index 6847d45c..8d6f6515 100644 --- a/layer-domain/src/main/java/org/layer/domain/form/enums/FormTag.java +++ b/layer-domain/src/main/java/org/layer/domain/form/enums/FormTag.java @@ -1,10 +1,13 @@ package org.layer.domain.form.enums; +import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import org.layer.domain.common.random.CustomRandom; + import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -21,7 +24,7 @@ public enum FormTag { private final String tag; - public static FormTag getRecommandFormTag(List retrospectPurposes) { + public static FormTag getRecommandFormTag(List retrospectPurposes, CustomRandom customRandom) { Map formTagIntegerMap = EnumSet.allOf(FormTag.class).stream() .collect(Collectors.toMap(tag -> tag, tag -> 0)); @@ -33,10 +36,14 @@ public static FormTag getRecommandFormTag(List retrospectPurp formTagIntegerMap.put(PMI, formTagIntegerMap.get(PMI) +purpose.getPmiPont()); }); - return formTagIntegerMap.entrySet() - .stream() - .max(Map.Entry.comparingByValue()) + int maxValue = Collections.max(formTagIntegerMap.values()); + + List maxTags = formTagIntegerMap.entrySet().stream() + .filter(entry -> entry.getValue() == maxValue) .map(Map.Entry::getKey) - .orElse(FormTag.UNTITLED); + .toList(); + + // 최댓값을 가진 것 중 랜덤으로 하나 선택 + return maxTags.get(customRandom.nextInt(maxTags.size())); } } From acc21844693dc6d65b201ea5c0d1a3567b445c45 Mon Sep 17 00:00:00 2001 From: Mingyu Song <100754581+mikekks@users.noreply.github.com> Date: Thu, 12 Sep 2024 01:59:43 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=ED=9A=8C=EA=B3=A0=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=88=98=EC=A0=95=20(#223)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 회고 목록 조회 수정 - 작성 상태 및 분석 상태 추가 * del: service dto 삭제 * fix: dev yml 수정 * chore: 회고 마감 마감일자에 따른 분기처리 * chore: 분석 완료 여부 추가 * chore: 모든 인원이 다 작성한 경우 자동마감 처리하도록 수정 * chore: 회고 목록 조회 수정에 따른 배치 시스템 수정 --- .../domain/answer/service/AnswerService.java | 15 ++++++ .../retrospect/controller/RetrospectApi.java | 2 +- .../controller/RetrospectController.java | 15 +----- .../dto/response/RetrospectGetResponse.java | 51 +++++++++++-------- .../retrospect/service/RetrospectService.java | 32 +++++++----- .../RetrospectCreateServiceRequest.java | 15 ------ .../RetrospectGetServiceResponse.java | 25 --------- .../RetrospectListGetServiceResponse.java | 13 ----- .../src/main/resources/application-dev.yml | 2 +- .../batch/scheduler/RetrospectScheduler.java | 3 +- .../layer/domain/answer/entity/Answers.java | 40 +++++++++++---- .../retrospect/entity/AnalysisStatus.java | 5 ++ .../domain/retrospect/entity/Retrospect.java | 26 ++++++++-- .../domain/retrospect/entity/WriteStatus.java | 5 ++ .../external/ai/service/AIAnalyzeService.java | 3 ++ 15 files changed, 133 insertions(+), 119 deletions(-) delete mode 100644 layer-api/src/main/java/org/layer/domain/retrospect/service/dto/request/RetrospectCreateServiceRequest.java delete mode 100644 layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectGetServiceResponse.java delete mode 100644 layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectListGetServiceResponse.java create mode 100644 layer-domain/src/main/java/org/layer/domain/retrospect/entity/AnalysisStatus.java create mode 100644 layer-domain/src/main/java/org/layer/domain/retrospect/entity/WriteStatus.java 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 f36d4d5f..6f1f8cfb 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 @@ -22,12 +22,15 @@ import org.layer.domain.question.entity.Questions; import org.layer.domain.question.enums.QuestionType; import org.layer.domain.question.repository.QuestionRepository; +import org.layer.domain.retrospect.entity.AnalysisStatus; import org.layer.domain.retrospect.entity.Retrospect; +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.Team; import org.layer.domain.space.exception.MemberSpaceRelationException; import org.layer.domain.space.repository.MemberSpaceRelationRepository; +import org.layer.external.ai.service.AIAnalyzeService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -48,6 +51,8 @@ public class AnswerService { private final MemberRepository memberRepository; private final AnalyzeRepository analyzeRepository; + private final AIAnalyzeService aiAnalyzeService; + private final Time time; @Transactional @@ -91,6 +96,16 @@ public void create(AnswerListCreateRequest request, Long spaceId, Long retrospec Answer answer = new Answer(retrospectId, r.questionId(), memberId, r.answerContent(), answerStatus); answerRepository.save(answer); } + + Answers answers = new Answers(answerRepository.findAllByRetrospectId(retrospectId)); + + // 마지막 답변일 경우 -> ai 분석 실행 + if (answers.getWriteCount(retrospectId) == team.getTeamMemberCount()){ + retrospect.updateRetrospectStatus(RetrospectStatus.DONE, time.now()); + retrospect.updateAnalysisStatus(AnalysisStatus.PROCEEDING); + + aiAnalyzeService.createAnalyze(spaceId, retrospectId, answers.getWriteMemberIds()); + } } @Transactional diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectApi.java b/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectApi.java index c203b251..5e805333 100644 --- a/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectApi.java +++ b/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectApi.java @@ -38,7 +38,7 @@ ResponseEntity updateRetrospect(@PathVariable("spaceI ResponseEntity deleteRetrospect(@PathVariable("spaceId") Long spaceId, @PathVariable("retrospectId") Long retrospectId, @MemberId Long memberId); - @Operation(summary = "회고 마감", description = "특정 팀 스페이스에서 작성했던 회고를 마감하는 기능입니다.
Note: 스페이스 내 모든 인원이 작성해야 가능합니다.") + @Operation(summary = "회고 수동 마감", description = "특정 팀 스페이스에서 작성했던 회고를 마감하는 기능입니다.
Note: 스페이스 내 모든 인원이 작성해야 가능합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "회고 마감 성공", content = @Content(mediaType = "application/json")), diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectController.java b/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectController.java index 9795557b..914bec5d 100644 --- a/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectController.java +++ b/layer-api/src/main/java/org/layer/domain/retrospect/controller/RetrospectController.java @@ -7,16 +7,12 @@ import org.layer.domain.retrospect.controller.dto.request.RetrospectCreateRequest; import org.layer.domain.retrospect.controller.dto.request.RetrospectUpdateRequest; import org.layer.domain.retrospect.controller.dto.response.RetrospectCreateResponse; -import org.layer.domain.retrospect.controller.dto.response.RetrospectGetResponse; import org.layer.domain.retrospect.controller.dto.response.RetrospectListGetResponse; import org.layer.domain.retrospect.service.RetrospectService; -import org.layer.domain.retrospect.service.dto.response.RetrospectListGetServiceResponse; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import java.util.List; - @RestController @RequiredArgsConstructor @RequestMapping("/space/{spaceId}/retrospect") @@ -43,16 +39,7 @@ public ResponseEntity createRetrospect( public ResponseEntity getRetrospects(@PathVariable("spaceId") Long spaceId, @MemberId Long memberId) { - RetrospectListGetServiceResponse serviceResponse = retrospectService.getRetrospects(spaceId, memberId); - - List retrospectGetResponses = serviceResponse.retrospects().stream() - .map(r -> RetrospectGetResponse.of(r.retrospectId(), r.title(), r.introduction(), r.isWrite(), - r.retrospectStatus(), - r.writeCount(), r.totalCount(), r.createdAt(), r.deadline())) - .toList(); - - return ResponseEntity.ok() - .body(RetrospectListGetResponse.of(serviceResponse.layerCount(), retrospectGetResponses)); + return ResponseEntity.ok().body(retrospectService.getRetrospects(spaceId, memberId)); } @Override diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/controller/dto/response/RetrospectGetResponse.java b/layer-api/src/main/java/org/layer/domain/retrospect/controller/dto/response/RetrospectGetResponse.java index 1f08d9e1..1a6feec7 100644 --- a/layer-api/src/main/java/org/layer/domain/retrospect/controller/dto/response/RetrospectGetResponse.java +++ b/layer-api/src/main/java/org/layer/domain/retrospect/controller/dto/response/RetrospectGetResponse.java @@ -1,34 +1,41 @@ package org.layer.domain.retrospect.controller.dto.response; import io.swagger.v3.oas.annotations.media.Schema; + +import org.layer.domain.retrospect.entity.AnalysisStatus; import org.layer.domain.retrospect.entity.RetrospectStatus; +import org.layer.domain.retrospect.entity.WriteStatus; import java.time.LocalDateTime; @Schema(name = "RetrospectGetResponse", description = "특정 회고 조회 Dto") public record RetrospectGetResponse( - @Schema(description = "회고 id", example = "1") - Long retrospectId, - @Schema(description = "회고 이름", example = "중간 발표 이후") - String title, - @Schema(description = "회고 설명", example = "중간 발표 관련해서 KPT 회고를 해봅시다.") - String introduction, - @Schema(description = "회고 작성 여부", example = "false") - boolean isWrite, - @Schema(description = "회고 상태 : PROCEEDING 나 DONE 중에 하나입니다.", example = "PROCEEDING") - RetrospectStatus retrospectStatus, - @Schema(description = "해당 회고 응답 수", example = "4") - long writeCount, - @Schema(description = "전체 인원", example = "10") - long totalCount, - @Schema(description = "회고 생성 일자") - LocalDateTime createdAt, - @Schema(description = "회고 종료 일자") - LocalDateTime deadline + @Schema(description = "회고 id", example = "1") + Long retrospectId, + @Schema(description = "회고 이름", example = "중간 발표 이후") + String title, + @Schema(description = "회고 설명", example = "중간 발표 관련해서 KPT 회고를 해봅시다.") + String introduction, + @Schema(description = "회고 작성 상태", example = "NOT_STARTED") + WriteStatus writeStatus, + @Schema(description = "회고 상태 : PROCEEDING 나 DONE 중에 하나입니다.", example = "PROCEEDING") + RetrospectStatus retrospectStatus, + @Schema(description = "회고 작성 상태", example = "NOT_STARTED") + AnalysisStatus analysisStatus, + @Schema(description = "해당 회고 응답 수", example = "4") + long writeCount, + @Schema(description = "전체 인원", example = "10") + long totalCount, + @Schema(description = "회고 생성 일자") + LocalDateTime createdAt, + @Schema(description = "회고 종료 일자") + LocalDateTime deadline ) { - public static RetrospectGetResponse of(Long retrospectId, String title, String introduction, boolean isWrite, RetrospectStatus retrospectStatus, - long writeCount, long totalCount, LocalDateTime createdAt, LocalDateTime deadline) { + public static RetrospectGetResponse of(Long retrospectId, String title, String introduction, + WriteStatus writeStatus, RetrospectStatus retrospectStatus, AnalysisStatus analysisStatus, + long writeCount, long totalCount, LocalDateTime createdAt, LocalDateTime deadline) { - return new RetrospectGetResponse(retrospectId, title, introduction, isWrite, retrospectStatus, writeCount, totalCount, createdAt, deadline); - } + return new RetrospectGetResponse(retrospectId, title, introduction, writeStatus, retrospectStatus, + analysisStatus, writeCount, totalCount, createdAt, deadline); + } } 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 887f4206..d66d1049 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 @@ -19,11 +19,12 @@ import org.layer.domain.retrospect.controller.dto.request.QuestionCreateRequest; import org.layer.domain.retrospect.controller.dto.request.RetrospectCreateRequest; import org.layer.domain.retrospect.controller.dto.request.RetrospectUpdateRequest; +import org.layer.domain.retrospect.controller.dto.response.RetrospectGetResponse; +import org.layer.domain.retrospect.controller.dto.response.RetrospectListGetResponse; +import org.layer.domain.retrospect.entity.AnalysisStatus; import org.layer.domain.retrospect.entity.Retrospect; import org.layer.domain.retrospect.entity.RetrospectStatus; import org.layer.domain.retrospect.repository.RetrospectRepository; -import org.layer.domain.retrospect.service.dto.response.RetrospectGetServiceResponse; -import org.layer.domain.retrospect.service.dto.response.RetrospectListGetServiceResponse; import org.layer.domain.space.entity.Space; import org.layer.domain.space.entity.Team; import org.layer.domain.space.repository.MemberSpaceRelationRepository; @@ -100,7 +101,7 @@ private Retrospect getRetrospect(RetrospectCreateRequest request, Long spaceId) .build(); } - public RetrospectListGetServiceResponse getRetrospects(Long spaceId, Long memberId) { + public RetrospectListGetResponse getRetrospects(Long spaceId, Long memberId) { // 해당 스페이스 팀원인지 검증 Team team = new Team(memberSpaceRelationRepository.findAllBySpaceId(spaceId)); team.validateTeamMembership(memberId); @@ -109,13 +110,20 @@ public RetrospectListGetServiceResponse getRetrospects(Long spaceId, Long member List retrospectIds = retrospects.stream().map(Retrospect::getId).toList(); Answers answers = new Answers(answerRepository.findAllByRetrospectIdIn(retrospectIds)); - List retrospectDtos = retrospects.stream() - .map(r -> RetrospectGetServiceResponse.of(r.getId(), r.getTitle(), r.getIntroduction(), - answers.hasRetrospectAnswer(memberId, r.getId()), r.getRetrospectStatus(), - answers.getWriteCount(), team.getTeamMemberCount(), r.getCreatedAt(), r.getDeadline())) + List retrospectDtos = retrospects.stream() + .map(r -> { + long writeCount = team.getTeamMemberCount(); + if (r.getRetrospectStatus().equals(RetrospectStatus.DONE)) { + writeCount = answers.getWriteCount(r.getId()); + } + + return RetrospectGetResponse.of(r.getId(), r.getTitle(), r.getIntroduction(), + answers.getWriteStatus(memberId, r.getId()), r.getRetrospectStatus(), r.getAnalysisStatus(), + answers.getWriteCount(r.getId()), writeCount, r.getCreatedAt(), r.getDeadline()); + }) .toList(); - return RetrospectListGetServiceResponse.of(retrospects.size(), retrospectDtos); + return RetrospectListGetResponse.of(retrospects.size(), retrospectDtos); } private List getQuestions(List questions, Long savedRetrospectId, Long formId) { @@ -168,13 +176,13 @@ public void closeRetrospect(Long spaceId, Long retrospectId, Long memberId) { space.isLeaderSpace(memberId); Retrospect retrospect = retrospectRepository.findByIdOrThrow(retrospectId); - retrospect.validateDeadline(time.now()); - Answers answers = new Answers(answerRepository.findAllByRetrospectId(retrospectId)); - - retrospect.updateRetrospectStatus(RetrospectStatus.DONE); + retrospect.updateRetrospectStatus(RetrospectStatus.DONE, time.now()); + retrospect.updateAnalysisStatus(AnalysisStatus.PROCEEDING); retrospectRepository.saveAndFlush(retrospect); + Answers answers = new Answers(answerRepository.findAllByRetrospectId(retrospectId)); + // 회고 ai 분석 시작 aiAnalyzeService.createAnalyze(spaceId, retrospectId, answers.getWriteMemberIds()); } diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/request/RetrospectCreateServiceRequest.java b/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/request/RetrospectCreateServiceRequest.java deleted file mode 100644 index 6e17d37b..00000000 --- a/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/request/RetrospectCreateServiceRequest.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.layer.domain.retrospect.service.dto.request; - -import java.util.List; - -public record RetrospectCreateServiceRequest( - String title, - String introduction, - Long spaceId, - List questions -) { - public static RetrospectCreateServiceRequest of(String title, String introduction, Long spaceId, List questions) { - - return new RetrospectCreateServiceRequest(title, introduction, spaceId, questions); - } -} diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectGetServiceResponse.java b/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectGetServiceResponse.java deleted file mode 100644 index 0e6761e2..00000000 --- a/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectGetServiceResponse.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.layer.domain.retrospect.service.dto.response; - -import org.layer.domain.retrospect.entity.RetrospectStatus; - -import java.time.LocalDateTime; - -public record RetrospectGetServiceResponse( - Long retrospectId, - String title, - String introduction, - boolean isWrite, - RetrospectStatus retrospectStatus, - long writeCount, - long totalCount, - - LocalDateTime createdAt, - - LocalDateTime deadline -) { - public static RetrospectGetServiceResponse of(Long retrospectId, String title, String introduction, boolean isWrite, - RetrospectStatus retrospectStatus, long writeCount, long totalCount, LocalDateTime createdAt, LocalDateTime deadline) { - return new RetrospectGetServiceResponse(retrospectId, title, introduction, isWrite, retrospectStatus, - writeCount, totalCount, createdAt, deadline); - } -} diff --git a/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectListGetServiceResponse.java b/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectListGetServiceResponse.java deleted file mode 100644 index 008e030c..00000000 --- a/layer-api/src/main/java/org/layer/domain/retrospect/service/dto/response/RetrospectListGetServiceResponse.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.layer.domain.retrospect.service.dto.response; - -import java.util.List; - - -public record RetrospectListGetServiceResponse( - int layerCount, - List retrospects -) { - public static RetrospectListGetServiceResponse of(int layerCount, List retrospects){ - return new RetrospectListGetServiceResponse(layerCount, retrospects); - } -} diff --git a/layer-api/src/main/resources/application-dev.yml b/layer-api/src/main/resources/application-dev.yml index f2475acf..82e2714c 100644 --- a/layer-api/src/main/resources/application-dev.yml +++ b/layer-api/src/main/resources/application-dev.yml @@ -1,6 +1,6 @@ spring: config: - import: application-secret.properties + import: optional:file:/config/application-secret.properties datasource: url: ${DEV_DB_URL} username: ${DEV_DB_NAME} 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 1c211f45..7145cbe0 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 @@ -36,7 +36,6 @@ public class RetrospectScheduler { public void updateRetrospectStatusToDone() { log.info("Batch Start : updateRetrospectStatusToDone"); - LocalDateTime now = time.now(); List retrospects = retrospectRepository.findAllByDeadlineBeforeAndRetrospectStatus( @@ -44,7 +43,7 @@ public void updateRetrospectStatusToDone() { Map retrospectMap = retrospects.stream() .collect(Collectors.toMap(Retrospect::getId, retrospect -> retrospect)); - retrospects.forEach(retrospect -> retrospect.updateRetrospectStatus(RetrospectStatus.DONE)); + retrospects.forEach(retrospect -> retrospect.updateRetrospectStatus(RetrospectStatus.DONE, now)); retrospectRepository.saveAllAndFlush(retrospects); List retrospectIds = retrospects.stream().map(Retrospect::getId).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 4b24e56c..53317fbb 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 @@ -5,6 +5,7 @@ import org.layer.domain.answer.enums.AnswerStatus; import org.layer.domain.answer.exception.AnswerException; +import org.layer.domain.retrospect.entity.WriteStatus; import java.util.ArrayList; import java.util.HashSet; @@ -42,17 +43,38 @@ public boolean hasRetrospectAnswer(Long memberId, Long retrospectId) { .anyMatch(answer -> answer.getMemberId().equals(memberId)); } - public long getWriteCount() { - Set set = new HashSet<>(); + 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){ + return WriteStatus.DONE; + } - answers.forEach(answer -> { - // 임시저장된 회고일 경우 제외 - if (answer.getAnswerStatus() != AnswerStatus.TEMPORARY) { - set.add(answer.getMemberId()); - } - }); + boolean isTemporaryWrite = answers.stream() + .filter(answer -> answer.getRetrospectId().equals(retrospectId)) + .filter(answer -> answer.getMemberId().equals(memberId)) + .anyMatch(answer -> answer.getAnswerStatus().equals(AnswerStatus.TEMPORARY)); + if(isTemporaryWrite){ + return WriteStatus.PROCEEDING; + } + + return WriteStatus.NOT_STARTED; + } + + public long getWriteCount(Long retrospectId) { + + Map> answersByRetrospectId = answers.stream() + .collect(Collectors.groupingBy(Answer::getRetrospectId)); + + Set answerMembers = new HashSet<>(); + + answersByRetrospectId.get(retrospectId).stream() + .filter(answer -> answer.getAnswerStatus().equals(AnswerStatus.DONE)) + .forEach(answer -> answerMembers.add(answer.getMemberId())); - return set.size(); + return answerMembers.size(); } public List getWriteMemberIds() { diff --git a/layer-domain/src/main/java/org/layer/domain/retrospect/entity/AnalysisStatus.java b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/AnalysisStatus.java new file mode 100644 index 00000000..6277c57b --- /dev/null +++ b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/AnalysisStatus.java @@ -0,0 +1,5 @@ +package org.layer.domain.retrospect.entity; + +public enum AnalysisStatus { + NOT_STARTED, PROCEEDING, DONE +} 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 49a4d90f..65b281aa 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 @@ -41,15 +41,20 @@ public class Retrospect extends BaseTimeEntity { @Enumerated(EnumType.STRING) private RetrospectStatus retrospectStatus; + @NotNull + @Enumerated(EnumType.STRING) + private AnalysisStatus analysisStatus; + private LocalDateTime deadline; @Builder public Retrospect(Long spaceId, String title, String introduction, RetrospectStatus retrospectStatus, - LocalDateTime deadline) { + AnalysisStatus analysisStatus, LocalDateTime deadline, int capacity) { this.spaceId = spaceId; this.title = title; this.introduction = introduction; this.retrospectStatus = retrospectStatus; + this.analysisStatus = analysisStatus; this.deadline = deadline; } @@ -66,14 +71,14 @@ public void validateDeadline(LocalDateTime currentTime) { } public void validateRetrospectStatusDone() { - if(!this.retrospectStatus.equals(RetrospectStatus.DONE)){ + if (!this.retrospectStatus.equals(RetrospectStatus.DONE)) { throw new RetrospectException(DEADLINE_NOT_PASSED); } } - public void updateRetrospect(String title, String introduction, LocalDateTime deadline, Time time){ + public void updateRetrospect(String title, String introduction, LocalDateTime deadline, Time time) { - if(deadline.isBefore(time.now())){ + if (deadline.isBefore(time.now())) { throw new RetrospectException(INVALID_DEADLINE); } @@ -82,9 +87,20 @@ public void updateRetrospect(String title, String introduction, LocalDateTime de this.deadline = deadline; } - public void updateRetrospectStatus(RetrospectStatus retrospectStatus){ + public void updateRetrospectStatus(RetrospectStatus retrospectStatus, LocalDateTime now) { isProceedingRetrospect(); + if(this.deadline != null && now.isBefore(this.deadline)){ + return; + } + this.retrospectStatus = retrospectStatus; } + + public void updateAnalysisStatus(AnalysisStatus analysisStatus) { + if (this.analysisStatus.equals(AnalysisStatus.NOT_STARTED)) { + this.analysisStatus = analysisStatus; + } + + } } diff --git a/layer-domain/src/main/java/org/layer/domain/retrospect/entity/WriteStatus.java b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/WriteStatus.java new file mode 100644 index 00000000..ef382798 --- /dev/null +++ b/layer-domain/src/main/java/org/layer/domain/retrospect/entity/WriteStatus.java @@ -0,0 +1,5 @@ +package org.layer.domain.retrospect.entity; + +public enum WriteStatus { + NOT_STARTED, PROCEEDING, DONE +} 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 48dd8b0d..965d2391 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 @@ -16,6 +16,7 @@ import org.layer.domain.question.entity.Questions; import org.layer.domain.question.enums.QuestionType; import org.layer.domain.question.repository.QuestionRepository; +import org.layer.domain.retrospect.entity.AnalysisStatus; import org.layer.domain.retrospect.entity.Retrospect; import org.layer.domain.retrospect.repository.RetrospectRepository; import org.layer.domain.space.entity.Team; @@ -89,6 +90,8 @@ public void createAnalyze(Long spaceId, Long retrospectId, List memberIds) long endTime = System.currentTimeMillis(); // 종료 시간 기록 long duration = endTime - startTime; // 경과 시간 계산 log.info("createAnalyze completed in {} ms", duration); + + retrospect.updateAnalysisStatus(AnalysisStatus.DONE); } private Analyze getAnalyzeEntity(Long retrospectId, Answers answers, Long rangeQuestionId, Long numberQuestionId,