diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/QnAController.java b/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/QnAController.java index 27918114..9a1c7b78 100644 --- a/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/QnAController.java +++ b/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/QnAController.java @@ -100,4 +100,10 @@ public ApiResponse getMyUserInfo(Principal principal) { return ApiResponse.success(SuccessType.GET_MY_USER_INFO_SUCCESS, qnAService.getUserInfo(getUserFromPrincial(principal))); } + @PatchMapping("/home/first") + @ResponseStatus(HttpStatus.OK) + public ApiResponse firstEntry(Principal principal) { + return ApiResponse.success(SuccessType.GET_USER_FIRST_ENTRY_SUCCESS, qnAService.updateUserFirstEntry(getUserFromPrincial(principal))); + } + } diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/dto/response/FirstEntryResponseDto.java b/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/dto/response/FirstEntryResponseDto.java new file mode 100644 index 00000000..21d95062 --- /dev/null +++ b/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/dto/response/FirstEntryResponseDto.java @@ -0,0 +1,22 @@ +package sopt.org.umbba.api.controller.qna.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.user.User; + +@Getter +@Builder +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public class FirstEntryResponseDto { + + private Boolean isFirstEntry; + + public static FirstEntryResponseDto of(boolean isFirstEntry) { + return FirstEntryResponseDto.builder() + .isFirstEntry(isFirstEntry) + .build(); + } +} diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/dto/response/GetInvitationResponseDto.java b/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/dto/response/GetInvitationResponseDto.java index 5c61e0da..29490bf8 100644 --- a/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/dto/response/GetInvitationResponseDto.java +++ b/umbba-api/src/main/java/sopt/org/umbba/api/controller/qna/dto/response/GetInvitationResponseDto.java @@ -10,7 +10,7 @@ @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) public class GetInvitationResponseDto { - private int responseCase; // case를 1,2,3으로 구분 (Client) + private int responseCase; // case를 1,2,3,4으로 구분 (Client) // 예외상황에 따른 필드 private String inviteCode; @@ -19,12 +19,15 @@ public class GetInvitationResponseDto { private Boolean relativeUserActive; + private Boolean isUserFirstAnswer; + // 1. 오늘의 질문을 조회한 일반적인 경우 public static GetInvitationResponseDto of () { return GetInvitationResponseDto.builder() .responseCase(1) .relativeUserActive(true) + .isUserFirstAnswer(true) .build(); } @@ -36,6 +39,7 @@ public static GetInvitationResponseDto of (String inviteCode, String inviteUsern .inviteUsername(inviteUsername) .installUrl(installUrl) .relativeUserActive(true) + .isUserFirstAnswer(true) .build(); } @@ -44,6 +48,16 @@ public static GetInvitationResponseDto of (boolean relativeUserActive) { return GetInvitationResponseDto.builder() .responseCase(3) .relativeUserActive(relativeUserActive) + .isUserFirstAnswer(true) + .build(); + } + + // 4. 아직 첫 질문에 답변하지 않은 경우 + public static GetInvitationResponseDto ofFirst (boolean isUserFirstAnswer) { + return GetInvitationResponseDto.builder() + .responseCase(4) + .relativeUserActive(true) + .isUserFirstAnswer(isUserFirstAnswer) .build(); } } 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 9da16c57..5bdf0e54 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 @@ -66,7 +66,10 @@ public GetInvitationResponseDto getInvitation(Long userId) { log.info("matchUser: {} -> parentchildDao.findMatchUserByUserId()의 결과", matchUser); // 유저의 상태에 따른 분기처리 - if (matchUser.isEmpty()) { + if (!checkFirstAnswerCompleted(userId)) { + return firstTutorialQnA(); + } + else if (matchUser.isEmpty()) { return invitation(userId); } else if (matchUser.get().getUsername() == null) { @@ -78,6 +81,17 @@ else if (matchUser.get().getSocialPlatform().equals(SocialPlatform.WITHDRAW)) { return GetInvitationResponseDto.of(); } + private boolean checkFirstAnswerCompleted(Long userId) { + User user = getUserById(userId); + QnA firstQnA = user.getParentChild().getQnaList().get(0); + + if (user.isMeChild() && firstQnA.isChildAnswer()) { + return true; + } else if (!user.isMeChild() && firstQnA.isParentAnswer()) { + return true; + } + return false; + } @Transactional public void answerTodayQuestion(Long userId, TodayAnswerRequestDto request) { @@ -345,6 +359,8 @@ else if (childList.get(3) != YES || parentList.get(3) != YES) { // 메인페이지 정보 public GetMainViewResponseDto getMainInfo(Long userId) { + // updateUserFirstEntry(userId); + Parentchild parentchild = getParentchild(userId); List qnaList = getQnAListByParentchild(parentchild); @@ -359,6 +375,16 @@ public GetMainViewResponseDto getMainInfo(Long userId) { return GetMainViewResponseDto.of(currentQnA, parentchild.getCount()); } + @Transactional + public FirstEntryResponseDto updateUserFirstEntry(Long userId) { + User user = getUserById(userId); + if (!user.isFirstEntry()) { + return FirstEntryResponseDto.of(false); + } + user.updateIsFirstEntry(); + return FirstEntryResponseDto.of(true); + } + @Transactional public void restartQna(Long userId) { Parentchild parentchild = getParentchild(userId); @@ -436,6 +462,10 @@ private GetInvitationResponseDto withdrawUser() { return GetInvitationResponseDto.of(false); } + private GetInvitationResponseDto firstTutorialQnA() { + return GetInvitationResponseDto.ofFirst(false); + } + /** * 데모데이 테스트용 메서드 diff --git a/umbba-api/src/main/java/sopt/org/umbba/api/service/user/AuthService.java b/umbba-api/src/main/java/sopt/org/umbba/api/service/user/AuthService.java index e72c3164..8a2a4682 100644 --- a/umbba-api/src/main/java/sopt/org/umbba/api/service/user/AuthService.java +++ b/umbba-api/src/main/java/sopt/org/umbba/api/service/user/AuthService.java @@ -56,6 +56,7 @@ public UserLoginResponseDto login(String socialAccessToken, SocialLoginRequestDt .isMeChild(true) .isMatchFinish(false) .fcmToken(request.getFcmToken()) + .isFirstEntry(true) .build(); userRepository.save(user); 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 e68ab841..14760146 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 @@ -28,6 +28,7 @@ public enum SuccessType { GET_MY_USER_INFO_SUCCESS(HttpStatus.OK, "마이페이지 내 정보 조회에 성공했습니다."), TEST_SUCCESS(HttpStatus.OK, "데모데이 테스트용 API 호출에 성공했습니다."), RESTART_QNA_SUCCESS(HttpStatus.OK, "7일 이후 문답이 정상적으로 시작되었습니다."), + GET_USER_FIRST_ENTRY_SUCCESS(HttpStatus.OK, "유저의 첫 진입여부 조회에 성공했습니다."), /** diff --git a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/user/User.java b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/user/User.java index 91db80bf..36334cf0 100644 --- a/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/user/User.java +++ b/umbba-domain/src/main/java/sopt/org/umbba/domain/domain/user/User.java @@ -1,15 +1,32 @@ package sopt.org.umbba.domain.domain.user; -import lombok.*; -import lombok.extern.slf4j.Slf4j; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.ForeignKey; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + import org.hibernate.annotations.SQLDelete; import org.hibernate.annotations.Where; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; import sopt.org.umbba.domain.domain.common.AuditingTimeEntity; import sopt.org.umbba.domain.domain.parentchild.Parentchild; -import javax.persistence.*; -import java.util.List; - @Slf4j @Entity @Table(name = "`User`") @@ -89,6 +106,8 @@ public void updateFcmToken(String fcmToken) { private boolean deleted = Boolean.FALSE; + private boolean isFirstEntry = Boolean.TRUE; + // 로그인 새롭게 할 때마다 해당 필드들 업데이트 public void updateSocialInfo(String socialNickname, String socialProfileImage, String socialAccessToken/*, String socialRefreshToken*/) { this.socialNickname = socialNickname; @@ -103,6 +122,10 @@ public void updateOnboardingInfo(String name, String gender, Integer bornYear) { this.bornYear = bornYear; } + public void updateIsFirstEntry() { + this.isFirstEntry = false; + } + public void deleteSocialInfo() { this.socialPlatform = SocialPlatform.WITHDRAW; this.socialNickname = null;