diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/CloserController.java b/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/CloserController.java new file mode 100644 index 00000000..c8ceffa0 --- /dev/null +++ b/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/CloserController.java @@ -0,0 +1,47 @@ +package sopt.org.umbba.api.controller.closer; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; +import sopt.org.umbba.api.config.jwt.JwtProvider; +import sopt.org.umbba.api.controller.closer.dto.request.TodayCloserAnswerRequestDto; +import sopt.org.umbba.api.controller.closer.dto.response.TodayCloserQnAResponseDto; +import sopt.org.umbba.api.service.closer.CloserService; +import sopt.org.umbba.common.exception.SuccessType; +import sopt.org.umbba.common.exception.dto.ApiResponse; + +import javax.validation.Valid; +import java.security.Principal; + +import static sopt.org.umbba.common.exception.SuccessType.ANSWER_TODAY_CLOSER_QUESTION_SUCCESS; +import static sopt.org.umbba.common.exception.SuccessType.PASS_TO_NEXT_CLOSER_QUESTION_SUCCESS; + +@Slf4j +@RestController +@RequestMapping("/closer") +@RequiredArgsConstructor +public class CloserController { + + private final CloserService closerService; + + @GetMapping("/today") + @ResponseStatus(HttpStatus.OK) + public ApiResponse getTodayCloserQnA(Principal principal) { + return ApiResponse.success(SuccessType.GET_TODAY_CLOSER_QNA_SUCCESS, closerService.getTodayCloserQnA(JwtProvider.getUserFromPrincial(principal))); + } + + @PatchMapping("/answer") + @ResponseStatus(HttpStatus.OK) + public ApiResponse answerTodayCloserQnA(Principal principal, @Valid @RequestBody final TodayCloserAnswerRequestDto request) { + closerService.answerTodayCloserQnA(JwtProvider.getUserFromPrincial(principal), request); + return ApiResponse.success(ANSWER_TODAY_CLOSER_QUESTION_SUCCESS); + } + + @PatchMapping("/next") + @ResponseStatus(HttpStatus.OK) + public ApiResponse passToNextCloserQnA(Principal principal) { + closerService.passToNextCloserQnA(JwtProvider.getUserFromPrincial(principal)); + return ApiResponse.success(PASS_TO_NEXT_CLOSER_QUESTION_SUCCESS); + } +} diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/dto/request/TodayCloserAnswerRequestDto.java b/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/dto/request/TodayCloserAnswerRequestDto.java new file mode 100644 index 00000000..c395c87b --- /dev/null +++ b/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/dto/request/TodayCloserAnswerRequestDto.java @@ -0,0 +1,26 @@ +package sopt.org.umbba.api.controller.closer.dto.request; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; + +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public class TodayCloserAnswerRequestDto { + + @Min(value = 1, message = "답변은 1 혹은 2여야 합니다.") + @Max(value = 2, message = "답변은 1 혹은 2여야 합니다.") + int answer; + + public static TodayCloserAnswerRequestDto of (int answer) { + return new TodayCloserAnswerRequestDto(answer); + } +} diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/dto/response/TodayCloserQnAResponseDto.java b/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/dto/response/TodayCloserQnAResponseDto.java new file mode 100644 index 00000000..d22a1751 --- /dev/null +++ b/umbba-api/src/main/java/sopt/org/umbba/api/controller/closer/dto/response/TodayCloserQnAResponseDto.java @@ -0,0 +1,70 @@ +package sopt.org.umbba.api.controller.closer.dto.response; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.Builder; +import lombok.Getter; +import sopt.org.umbba.domain.domain.closer.CloserQnA; +import sopt.org.umbba.domain.domain.closer.CloserQuestion; + +@Getter +@Builder +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public class TodayCloserQnAResponseDto { + + private Long closerQnaId; + + private int responseCase; + + private String balanceQuestion; + private String choiceAnswer1; + private String choiceAnswer2; + + private String myChoice; + private String opponentChoice; + + public static TodayCloserQnAResponseDto of(CloserQnA closerQna, int responseCase, boolean isMeChild) { + + CloserQuestion closerQuestion = closerQna.getCloserQuestion(); + int myAnswer; + int opponentAnswer; + if (isMeChild) { + myAnswer = closerQna.getChildAnswer(); + opponentAnswer = closerQna.getParentAnswer(); + } else { + myAnswer = closerQna.getParentAnswer(); + opponentAnswer = closerQna.getChildAnswer(); + } + + String myChoice; + if (myAnswer == 0) { + myChoice = null; + } else if (myAnswer == 1) { + myChoice = closerQuestion.getChoiceAnswer1(); + } else { + myChoice = closerQuestion.getChoiceAnswer2(); + } + String opponentChoice; + if (opponentAnswer == 0) { + opponentChoice = null; + } else if (opponentAnswer == 1) { + opponentChoice = closerQuestion.getChoiceAnswer1(); + } else { + opponentChoice = closerQuestion.getChoiceAnswer2(); + } + + if (responseCase == 3 && (myAnswer != opponentAnswer)) { + responseCase = 4; + } + + return TodayCloserQnAResponseDto.builder() + .closerQnaId(closerQna.getId()) + .responseCase(responseCase) + .balanceQuestion(closerQuestion.getBalanceQuestion()) + .choiceAnswer1(closerQuestion.getChoiceAnswer1()) + .choiceAnswer2(closerQuestion.getChoiceAnswer2()) + .myChoice(myChoice) + .opponentChoice(opponentChoice) + .build(); + } +} diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/service/closer/CloserService.java b/umbba-api/src/main/java/sopt/org/umbba/api/service/closer/CloserService.java new file mode 100644 index 00000000..f6d40e39 --- /dev/null +++ b/umbba-api/src/main/java/sopt/org/umbba/api/service/closer/CloserService.java @@ -0,0 +1,143 @@ +package sopt.org.umbba.api.service.closer; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import sopt.org.umbba.api.controller.closer.dto.request.TodayCloserAnswerRequestDto; +import sopt.org.umbba.api.controller.closer.dto.response.TodayCloserQnAResponseDto; +import sopt.org.umbba.common.exception.ErrorType; +import sopt.org.umbba.common.exception.model.CustomException; +import sopt.org.umbba.domain.domain.closer.CloserQnA; +import sopt.org.umbba.domain.domain.closer.CloserQuestion; +import sopt.org.umbba.domain.domain.closer.repository.CloserQnARepository; +import sopt.org.umbba.domain.domain.closer.repository.CloserQuestionRepository; +import sopt.org.umbba.domain.domain.parentchild.Parentchild; +import sopt.org.umbba.domain.domain.user.User; +import sopt.org.umbba.domain.domain.user.repository.UserRepository; + +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class CloserService { + + private final UserRepository userRepository; + private final CloserQuestionRepository closerQuestionRepository; + private final CloserQnARepository closerQnARepository; + + public TodayCloserQnAResponseDto getTodayCloserQnA(Long userId) { + User user = getUserById(userId); + Parentchild parentchild = user.getParentChild(); + if (parentchild == null) { + throw new CustomException(ErrorType.USER_HAVE_NO_PARENTCHILD); + } + + if (user.isMeChild()) { + int closerCount = parentchild.getCloserChildCount(); + CloserQnA todayQnA = parentchild.getCloserQnaList().get(closerCount); + + if (!todayQnA.isChildAnswer()) { // Case 1 (내가 답변하지 않은 경우) + return TodayCloserQnAResponseDto.of(todayQnA, 1, true); + } else if (!todayQnA.isParentAnswer()) { // Case 2 (상대가 답변하지 않은 경우) + return TodayCloserQnAResponseDto.of(todayQnA, 2, true); + } else { // Case 3,4 (둘다 답변한 경우) + return TodayCloserQnAResponseDto.of(todayQnA, 3, true); + } + + } else { + int closerCount = parentchild.getCloserParentCount(); + CloserQnA todayQnA = parentchild.getCloserQnaList().get(closerCount); + + if (!todayQnA.isParentAnswer()) { // Case 1 (내가 답변하지 않은 경우) + return TodayCloserQnAResponseDto.of(todayQnA, 1, false); + } else if (!todayQnA.isChildAnswer()) { // Case 2 (상대가 답변하지 않은 경우) + return TodayCloserQnAResponseDto.of(todayQnA, 2, false); + } else { // Case 3,4 (둘다 답변한 경우) + return TodayCloserQnAResponseDto.of(todayQnA, 3, false); + } + } + } + + @Transactional + public void answerTodayCloserQnA(Long userId, TodayCloserAnswerRequestDto request) { + User user = getUserById(userId); + Parentchild parentchild = user.getParentChild(); + if (parentchild == null) { + throw new CustomException(ErrorType.USER_HAVE_NO_PARENTCHILD); + } + + if (user.isMeChild()) { + int closerCount = parentchild.getCloserChildCount(); + CloserQnA todayQnA = parentchild.getCloserQnaList().get(closerCount); + + todayQnA.saveChildAnswer(request.getAnswer()); + } else { + int closerCount = parentchild.getCloserParentCount(); + CloserQnA todayQnA = parentchild.getCloserQnaList().get(closerCount); + + todayQnA.saveParentAnswer(request.getAnswer()); + } + } + + @Transactional + public void passToNextCloserQnA(Long userId) { + User user = getUserById(userId); + Parentchild parentchild = user.getParentChild(); + if (parentchild == null) { + throw new CustomException(ErrorType.USER_HAVE_NO_PARENTCHILD); + } + + if (user.isMeChild()) { + if (parentchild.getCloserChildCount() < parentchild.getCloserParentCount()) { + parentchild.addCloserChildCount(); + } else if (parentchild.getCloserChildCount() == parentchild.getCloserParentCount()) { + parentchild.addCloserChildCount(); + CloserQuestion newCloserQuestion = closerQuestionRepository.findRandomExceptIds(getCloserQuestionIds(parentchild)) + .orElseThrow(() -> new CustomException(ErrorType.NOT_FOUND_CLOSER_QUESTION)); + CloserQnA newCloserQnA = CloserQnA.builder() + .closerQuestion(newCloserQuestion) + .isParentAnswer(false) + .isChildAnswer(false) + .build(); + closerQnARepository.save(newCloserQnA); + parentchild.addCloserQna(newCloserQnA); + } else { + throw new CustomException(ErrorType.INVALID_COUNT_STATUS); + } + } else { + if (parentchild.getCloserParentCount() < parentchild.getCloserChildCount()) { + parentchild.addCloserParentCount(); + } else if (parentchild.getCloserParentCount() == parentchild.getCloserChildCount()) { + parentchild.addCloserParentCount(); + CloserQuestion newCloserQuestion = closerQuestionRepository.findRandomExceptIds(getCloserQuestionIds(parentchild)) + .orElseThrow(() -> new CustomException(ErrorType.NOT_FOUND_CLOSER_QUESTION)); + CloserQnA newCloserQnA = CloserQnA.builder() + .closerQuestion(newCloserQuestion) + .isParentAnswer(false) + .isChildAnswer(false) + .build(); + closerQnARepository.save(newCloserQnA); + parentchild.addCloserQna(newCloserQnA); + } else { + throw new CustomException(ErrorType.INVALID_COUNT_STATUS); + } + } + } + + private static List getCloserQuestionIds(Parentchild parentchild) { + return parentchild.getCloserQnaList().stream() + .map(closerQnA -> closerQnA.getCloserQuestion().getId()) + .collect(Collectors.toList()); + } + + private User getUserById(Long userId) { + + return userRepository.findById(userId).orElseThrow( + () -> new CustomException(ErrorType.INVALID_USER) + ); + } +} \ No newline at end of file diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/service/qna/QnAService.java b/umbba-api/src/main/java/sopt/org/umbba/api/service/qna/QnAService.java index dd75f302..a8c451cf 100644 --- a/umbba-api/src/main/java/sopt/org/umbba/api/service/qna/QnAService.java +++ b/umbba-api/src/main/java/sopt/org/umbba/api/service/qna/QnAService.java @@ -11,6 +11,10 @@ import sopt.org.umbba.api.service.notification.NotificationService; import sopt.org.umbba.common.exception.ErrorType; import sopt.org.umbba.common.exception.model.CustomException; +import sopt.org.umbba.domain.domain.closer.CloserQnA; +import sopt.org.umbba.domain.domain.closer.CloserQuestion; +import sopt.org.umbba.domain.domain.closer.repository.CloserQnARepository; +import sopt.org.umbba.domain.domain.closer.repository.CloserQuestionRepository; import sopt.org.umbba.domain.domain.parentchild.Parentchild; import sopt.org.umbba.domain.domain.parentchild.dao.ParentchildDao; import sopt.org.umbba.domain.domain.qna.*; @@ -49,6 +53,9 @@ public class QnAService { private final ParentchildDao parentchildDao; private final NotificationService notificationService; + private final CloserQuestionRepository closerQuestionRepository; + private final CloserQnARepository closerQnARepository; + public TodayQnAResponseDto getTodayQnA(Long userId) { User myUser = getUserById(userId); @@ -195,7 +202,6 @@ public void filterFirstQuestion(Long userId) { throw new CustomException(ErrorType.USER_HAVE_NO_PARENTCHILD); } - // 첫번째 질문은 MVP 단에서는 고정 QnA newQnA = QnA.builder() .question(questionRepository.findByType(FIX).get(0)) @@ -204,7 +210,6 @@ public void filterFirstQuestion(Long userId) { .build(); qnARepository.save(newQnA); - parentchild.initQna(); parentchild.setQna(newQnA); } @@ -243,6 +248,20 @@ public void filterAllQuestion(Long userId) { for (QnA qnA : forLogging) { log.info(qnA.getQuestion().getParentQuestion()); } + + // 가까워지기 QnA도 추가 + if (parentchild.getCloserQnaList().isEmpty()) { + CloserQuestion firstCloserQuestion = closerQuestionRepository.findRandomExceptIds(new ArrayList<>()) + .orElseThrow(() -> new CustomException(ErrorType.NOT_FOUND_CLOSER_QUESTION)); + + CloserQnA newCloserQnA = CloserQnA.builder() + .closerQuestion(firstCloserQuestion) + .isParentAnswer(false) + .isChildAnswer(false) + .build(); + closerQnARepository.save(newCloserQnA); + parentchild.addCloserQna(newCloserQnA); + } } // 마이페이지 - 부모자식 관계 정보 조회 diff --git a/umbba-common/src/main/java/sopt/org/umbba/common/exception/ErrorType.java b/umbba-common/src/main/java/sopt/org/umbba/common/exception/ErrorType.java index 3a170993..a026cf50 100644 --- a/umbba-common/src/main/java/sopt/org/umbba/common/exception/ErrorType.java +++ b/umbba-common/src/main/java/sopt/org/umbba/common/exception/ErrorType.java @@ -37,6 +37,9 @@ public enum ErrorType { // Album INVALID_BUCKET_PREFIX(HttpStatus.BAD_REQUEST, "유효하지 않은 S3 버킷 디렉토리명입니다."), + // Closer + INVALID_COUNT_STATUS(HttpStatus.BAD_REQUEST, "count 조건으로 인해 다음 가까워지기 질문으로 넘어갈 수 없습니다."), + /** * 401 UNAUTHORIZED */ @@ -64,6 +67,7 @@ public enum ErrorType { PARENTCHILD_HAVE_NO_OPPONENT(HttpStatus.NOT_FOUND, "부모자식 관계에 1명만 참여하고 있습니다."), NOT_FOUND_SECTION(HttpStatus.NOT_FOUND, "해당 아이디와 일치하는 섹션이 없습니다."), NOT_FOUND_ALBUM(HttpStatus.NOT_FOUND, "존재하지 않는 앨범입니다."), + NOT_FOUND_CLOSER_QUESTION(HttpStatus.NOT_FOUND, "일치하는 가까워지기 질문이 없습니다."), /** * About Apple (HttpStatus 고민) diff --git a/umbba-common/src/main/java/sopt/org/umbba/common/exception/SuccessType.java b/umbba-common/src/main/java/sopt/org/umbba/common/exception/SuccessType.java index 25226397..527f74da 100644 --- a/umbba-common/src/main/java/sopt/org/umbba/common/exception/SuccessType.java +++ b/umbba-common/src/main/java/sopt/org/umbba/common/exception/SuccessType.java @@ -33,7 +33,9 @@ public enum SuccessType { IMAGE_S3_DELETE_SUCCESS(HttpStatus.OK, "S3 버킷에서 이미지를 삭제하는 데 성공했습니다."), DELETE_ALBUM_SUCCESS(HttpStatus.OK, "앨범의 기록 삭제에 성공했습니다."), GET_ALBUM_LIST_SUCCESS(HttpStatus.OK, "앨범의 기록 목록 조회에 성공했습니다."), - + GET_TODAY_CLOSER_QNA_SUCCESS(HttpStatus.OK, "오늘의 가까워지기 문답 조회에 성공했습니다."), + ANSWER_TODAY_CLOSER_QUESTION_SUCCESS(HttpStatus.OK, "오늘의 가까워지기 문답에 답변을 완료하였습니다."), + PASS_TO_NEXT_CLOSER_QUESTION_SUCCESS(HttpStatus.OK, "다음 가까워지기 문답으로 넘어가는 데에 성공했습니다."), /** * 201 CREATED diff --git a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/CloserQnA.java b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/CloserQnA.java new file mode 100644 index 00000000..8afb8637 --- /dev/null +++ b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/CloserQnA.java @@ -0,0 +1,57 @@ +package sopt.org.umbba.domain.domain.closer; + +import lombok.*; +import org.hibernate.annotations.SQLDelete; +import org.hibernate.annotations.Where; +import sopt.org.umbba.domain.domain.common.AuditingTimeEntity; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +@SQLDelete(sql = "UPDATE closer_qna SET deleted=true WHERE closer_qna_id=?") +@Where(clause = "deleted=false") +public class CloserQnA extends AuditingTimeEntity { + + @Id + @Column(name = "closer_qna_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne + @JoinColumn(name = "closer_question_id", nullable = false) + private CloserQuestion closerQuestion; + + private int parentAnswer; + + private int childAnswer; + + @Column(nullable = false) + private boolean isParentAnswer; + + @Column(nullable = false) + private boolean isChildAnswer; + + private boolean deleted = Boolean.FALSE; + + public boolean isParentAnswer() { + return isParentAnswer; + } + + public boolean isChildAnswer() { + return isChildAnswer; + } + + public void saveParentAnswer(int answer) { + this.parentAnswer = answer; + this.isParentAnswer = true; + } + + public void saveChildAnswer(int answer) { + this.childAnswer = answer; + this.isChildAnswer = true; + } +} diff --git a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/CloserQuestion.java b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/CloserQuestion.java new file mode 100644 index 00000000..ba8be140 --- /dev/null +++ b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/CloserQuestion.java @@ -0,0 +1,28 @@ +package sopt.org.umbba.domain.domain.closer; + +import lombok.*; +import sopt.org.umbba.domain.domain.common.AuditingTimeEntity; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +public class CloserQuestion extends AuditingTimeEntity { + + @Id + @Column(name = "closer_question_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String balanceQuestion; + + @Column(nullable = false) + private String choiceAnswer1; + + @Column(nullable = false) + private String choiceAnswer2; +} diff --git a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/repository/CloserQnARepository.java b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/repository/CloserQnARepository.java new file mode 100644 index 00000000..570996c6 --- /dev/null +++ b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/repository/CloserQnARepository.java @@ -0,0 +1,7 @@ +package sopt.org.umbba.domain.domain.closer.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import sopt.org.umbba.domain.domain.closer.CloserQnA; + +public interface CloserQnARepository extends JpaRepository { +} diff --git a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/repository/CloserQuestionRepository.java b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/repository/CloserQuestionRepository.java new file mode 100644 index 00000000..af3fab42 --- /dev/null +++ b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/closer/repository/CloserQuestionRepository.java @@ -0,0 +1,39 @@ +package sopt.org.umbba.domain.domain.closer.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import sopt.org.umbba.common.exception.ErrorType; +import sopt.org.umbba.common.exception.model.CustomException; +import sopt.org.umbba.domain.domain.closer.CloserQuestion; + +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.stream.Collectors; + + +public interface CloserQuestionRepository extends JpaRepository { + + default Optional findRandomExceptIds(List ids) { + Random random = new Random(); + List allQuestions = findAll(); + + if (allQuestions.isEmpty()) { + throw new CustomException(ErrorType.NOT_FOUND_CLOSER_QUESTION); + } + if (ids.isEmpty()) { + int randomIndex = random.nextInt(allQuestions.size()); + return Optional.ofNullable(allQuestions.get(randomIndex)); + } + + List filteredQuestions = allQuestions.stream() + .filter(question -> !ids.contains(question.getId())) + .collect(Collectors.toList()); + + if (filteredQuestions.isEmpty()) { + return Optional.empty(); + } + + int randomIndex = random.nextInt(filteredQuestions.size()); + return Optional.of(filteredQuestions.get(randomIndex)); + } +} \ No newline at end of file diff --git a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/parentchild/Parentchild.java b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/parentchild/Parentchild.java index 7a88e0fd..ca6010e5 100644 --- a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/parentchild/Parentchild.java +++ b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/parentchild/Parentchild.java @@ -7,6 +7,7 @@ import sopt.org.umbba.common.exception.ErrorType; import sopt.org.umbba.common.exception.model.CustomException; import sopt.org.umbba.domain.domain.album.Album; +import sopt.org.umbba.domain.domain.closer.CloserQnA; import sopt.org.umbba.domain.domain.common.AuditingTimeEntity; import sopt.org.umbba.domain.domain.qna.OnboardingAnswer; import sopt.org.umbba.domain.domain.qna.QnA; @@ -33,7 +34,7 @@ public class Parentchild extends AuditingTimeEntity { @OneToMany(fetch = FetchType.EAGER) @JoinColumn(name = "parentchild_id") - private List qnaList; + private final List qnaList = new ArrayList<>(); @OneToMany(mappedBy = "parentchild", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) private final List albumList = new ArrayList<>(); @@ -55,6 +56,28 @@ public void addRemindCnt() { this.remindCnt += 1; } + @OneToMany + @JoinColumn(name = "parentchild_id") + private final List closerQnaList = new ArrayList<>(); + + public void addCloserQna(CloserQnA closerQnA) { + closerQnaList.add(closerQnA); + } + + @Column(nullable = false) + private int closerParentCount; + + @Column(nullable = false) + private int closerChildCount; + + public void addCloserParentCount() { + this.closerParentCount += 1; + } + + public void addCloserChildCount() { + this.closerChildCount += 1; + } + @Column(nullable = false) private String inviteCode; @@ -89,10 +112,6 @@ public void changeParentOnboardingAnswerList(List onboardingAn private boolean deleted = Boolean.FALSE; - public void initQna() { - qnaList = new ArrayList<>(); - } - public void setQna(QnA qnA) { if (qnaList.size() >= 7) { throw new CustomException(ErrorType.ALREADY_QNA_LIST_FULL);