diff --git a/gateway/src/main/java/com/oing/controller/MainViewController.java b/gateway/src/main/java/com/oing/controller/MainViewController.java index fdc86994..742085d1 100644 --- a/gateway/src/main/java/com/oing/controller/MainViewController.java +++ b/gateway/src/main/java/com/oing/controller/MainViewController.java @@ -34,8 +34,6 @@ public class MainViewController implements MainViewApi { @Override public DaytimePageResponse getDaytimePage( - boolean isMissionUnlocked, - boolean isMeUploadedToday, String loginMemberId ) { String familyId = memberBridge.getFamilyIdByMemberId(loginMemberId); @@ -68,6 +66,10 @@ public DaytimePageResponse getDaytimePage( String todayMissionId = missionBridge.getTodayMissionId(); String dailyMissionContent = missionBridge.getContentByMissionId(todayMissionId); + boolean isMissionUnlocked = postController.getMissionAvailableStatus(loginMemberId, loginMemberId, familyId) + .isMissionUnlocked(); + boolean isMeUploadedToday = postController.getSurvivalUploadStatus(loginMemberId, loginMemberId, familyId) + .isMeUploadedToday(); int leftUploadCountUntilMissionUnlock = postController.getRemainingSurvivalPostCount(loginMemberId, loginMemberId, familyId) .leftUploadCountUntilMissionUnlock(); diff --git a/gateway/src/main/java/com/oing/repository/PostRepositoryCustomImpl.java b/gateway/src/main/java/com/oing/repository/PostRepositoryCustomImpl.java index f63a7b26..d68c5b5d 100644 --- a/gateway/src/main/java/com/oing/repository/PostRepositoryCustomImpl.java +++ b/gateway/src/main/java/com/oing/repository/PostRepositoryCustomImpl.java @@ -118,6 +118,27 @@ public boolean existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(String memberId, S } @Override + public boolean isCreatedSurvivalPostByMajority(LocalDate date, String familyId) { + long totalFamilyMembers = queryFactory + .select(member.count()) + .from(member) + .where(member.familyId.eq(familyId) + .and(member.deletedAt.isNull())) + .fetchFirst(); + + long survivalPostCount = queryFactory + .select(post.count()) + .from(post) + .where( + post.familyId.eq(familyId), + post.type.eq(PostType.SURVIVAL), + dateExpr(post.createdAt).eq(date) + ) + .fetchFirst(); + + return survivalPostCount >= totalFamilyMembers / 2; + } + public int calculateRemainingSurvivalPostCount(String familyId) { Long familyMemberCount = queryFactory .select(member.id.count()) diff --git a/gateway/src/main/java/com/oing/restapi/MainViewApi.java b/gateway/src/main/java/com/oing/restapi/MainViewApi.java index 8c969ed2..31c8b669 100644 --- a/gateway/src/main/java/com/oing/restapi/MainViewApi.java +++ b/gateway/src/main/java/com/oing/restapi/MainViewApi.java @@ -10,7 +10,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -27,15 +26,6 @@ public interface MainViewApi { @Operation(summary = "주간의 메인 페이지 조회") @GetMapping("/daytime-page") DaytimePageResponse getDaytimePage( - - @RequestParam(required = false, defaultValue = "true") - @Parameter(description = "(디버그용) 미션 해금 여부 조작 필드", example = "true") - boolean isMissionUnlocked, - - @RequestParam(required = false, defaultValue = "true") - @Parameter(description = "(디버그용) 오늘 나 업로드 여부 조작 필드", example = "true") - boolean isMeUploadedToday, - @Parameter(hidden = true) @LoginMemberId String loginMemberId diff --git a/gateway/src/test/java/com/oing/repository/PostRepositoryCustomTest.java b/gateway/src/test/java/com/oing/repository/PostRepositoryCustomTest.java index 06470c16..6506c52a 100644 --- a/gateway/src/test/java/com/oing/repository/PostRepositoryCustomTest.java +++ b/gateway/src/test/java/com/oing/repository/PostRepositoryCustomTest.java @@ -129,6 +129,31 @@ void setup() { } @Test + void 미션_키_획득한_날짜에_가족의_미션_키_획득_여부를_조회한다() { + // given + String familyId = testMember1.getFamilyId(); + LocalDate today = LocalDate.of(2023, 11, 1); + + // when + boolean exists = postRepositoryCustomImpl.isCreatedSurvivalPostByMajority(today, familyId); + + // then + assertThat(exists).isTrue(); + } + + @Test + void 미션_키_획득하지_못한_날짜에_가족의_미션_키_획득_여부를_조회한다() { + // given + String familyId = testMember1.getFamilyId(); + LocalDate today = LocalDate.of(2024, 4, 1); + + // when + boolean exists = postRepositoryCustomImpl.isCreatedSurvivalPostByMajority(today, familyId); + + // then + assertThat(exists).isFalse(); + } + void 가족_구성원_수가_짝수인_경우_남은_생존게시글_업로드_수를_확인한다() { // given String familyId = testMember1.getFamilyId(); diff --git a/gateway/src/test/java/com/oing/restapi/PostApiTest.java b/gateway/src/test/java/com/oing/restapi/PostApiTest.java index 38751715..0426482e 100644 --- a/gateway/src/test/java/com/oing/restapi/PostApiTest.java +++ b/gateway/src/test/java/com/oing/restapi/PostApiTest.java @@ -184,4 +184,42 @@ void setUp() { .andExpect(status().isOk()) .andExpect(jsonPath("$.leftUploadCountUntilMissionUnlock").value(0)); } + + @Test + void 회원_생존신고_게시글_업로드_여부_조회_테스트() throws Exception { + //given + postRepository.save(new Post(TEST_POST_ID, TEST_MEMBER1_ID, TEST_FAMILY_ID, PostType.SURVIVAL, "img", "img", + "content")); + + //when + ResultActions resultActions = mockMvc.perform( + get("/v1/posts/{memberId}/survival-uploaded", TEST_MEMBER1_ID) + .header("X-AUTH-TOKEN", TEST_MEMBER1_TOKEN) + .contentType(MediaType.APPLICATION_JSON) + ); + + //then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isMeUploadedToday").value(true)); + } + + @Test + void 해당_가족의_미션_키_획득_여부_조회_테스트() throws Exception { + //given + postRepository.save(new Post(TEST_POST_ID, TEST_MEMBER1_ID, TEST_FAMILY_ID, PostType.SURVIVAL, "img", "img", + "content")); + + //when + ResultActions resultActions = mockMvc.perform( + get("/v1/posts/{memberId}/mission-available", TEST_MEMBER1_ID) + .header("X-AUTH-TOKEN", TEST_MEMBER1_TOKEN) + .contentType(MediaType.APPLICATION_JSON) + ); + + //then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isMissionUnlocked").value(true)); + } } diff --git a/post/src/main/java/com/oing/controller/PostController.java b/post/src/main/java/com/oing/controller/PostController.java index 9a3239d9..839e405e 100644 --- a/post/src/main/java/com/oing/controller/PostController.java +++ b/post/src/main/java/com/oing/controller/PostController.java @@ -18,6 +18,7 @@ import org.springframework.stereotype.Controller; import java.time.LocalDate; +import java.time.ZonedDateTime; /** * no5ing-server @@ -91,22 +92,21 @@ public PostResponse getPost(String postId, String loginMemberId) { } @Override - public SurvivalUploadStatusResponse getSurvivalUploadStatus(String memberId, String loginMemberId, boolean valid) { + public SurvivalUploadStatusResponse getSurvivalUploadStatus(String memberId, String loginMemberId, String loginFamilyId) { validateMemberId(loginMemberId, memberId); - // TODO: 추후 valid 파라미터 삭제 - // TODO: 해당 회원이 생존신고 글을 올렸는지 검증 로직 추가 - if (valid) { + + if (postService.existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(memberId, loginFamilyId, PostType.SURVIVAL, LocalDate.now())) { return new SurvivalUploadStatusResponse(true); } return new SurvivalUploadStatusResponse(false); } @Override - public MissionAvailableStatusResponse getMissionAvailableStatus(String memberId, String loginMemberId, boolean valid) { + public MissionAvailableStatusResponse getMissionAvailableStatus(String memberId, String loginMemberId, String loginFamilyId) { validateMemberId(loginMemberId, memberId); - // TODO: 추후 valid 파라미터 삭제 - // TODO: 해당 회원이 미션에 참여 가능한 회원인지 검증 로직 추가 - if (valid) { + LocalDate today = ZonedDateTime.now().toLocalDate(); + + if (postService.isCreatedSurvivalPostByMajority(today, loginFamilyId)) { return new MissionAvailableStatusResponse(true); } return new MissionAvailableStatusResponse(false); diff --git a/post/src/main/java/com/oing/dto/response/MissionAvailableStatusResponse.java b/post/src/main/java/com/oing/dto/response/MissionAvailableStatusResponse.java index 5731366f..cacf126f 100644 --- a/post/src/main/java/com/oing/dto/response/MissionAvailableStatusResponse.java +++ b/post/src/main/java/com/oing/dto/response/MissionAvailableStatusResponse.java @@ -2,9 +2,9 @@ import io.swagger.v3.oas.annotations.media.Schema; -@Schema(description = "회원 미션 참여 가능 여부 응답") +@Schema(description = "가족 미션 참여 가능 (미션 키) 여부 응답") public record MissionAvailableStatusResponse( - @Schema(description = "회원 미션 참여 가능 여부", example = "true") - boolean isAvailable + @Schema(description = "가족 미션 참여 가능 (미션 키) 여부", example = "true") + boolean isMissionUnlocked ) { } diff --git a/post/src/main/java/com/oing/dto/response/SurvivalUploadStatusResponse.java b/post/src/main/java/com/oing/dto/response/SurvivalUploadStatusResponse.java index a53de652..db096fdc 100644 --- a/post/src/main/java/com/oing/dto/response/SurvivalUploadStatusResponse.java +++ b/post/src/main/java/com/oing/dto/response/SurvivalUploadStatusResponse.java @@ -6,6 +6,6 @@ @Schema(description = "회원 생존신고 게시글 업로드 여부 응답") public record SurvivalUploadStatusResponse( @Schema(description = "회원 생존신고 게시글 업로드 여부", example = "true") - boolean isValid + boolean isMeUploadedToday ) { } diff --git a/post/src/main/java/com/oing/repository/PostRepositoryCustom.java b/post/src/main/java/com/oing/repository/PostRepositoryCustom.java index 99717b16..36377133 100644 --- a/post/src/main/java/com/oing/repository/PostRepositoryCustom.java +++ b/post/src/main/java/com/oing/repository/PostRepositoryCustom.java @@ -22,5 +22,6 @@ QueryResults searchPosts(int page, int size, LocalDate date, String member boolean existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(String memberId, String familyId, PostType type, LocalDate postDate); + boolean isCreatedSurvivalPostByMajority(LocalDate date, String familyId); int calculateRemainingSurvivalPostCount(String familyId); } diff --git a/post/src/main/java/com/oing/restapi/PostApi.java b/post/src/main/java/com/oing/restapi/PostApi.java index 9b09e5d7..7ae5e8a0 100644 --- a/post/src/main/java/com/oing/restapi/PostApi.java +++ b/post/src/main/java/com/oing/restapi/PostApi.java @@ -125,9 +125,9 @@ SurvivalUploadStatusResponse getSurvivalUploadStatus( @LoginMemberId String loginMemberId, - @RequestParam - @Parameter(description = "응답 값 조작 필드", example = "true") - boolean valid + @Parameter(hidden = true) + @LoginFamilyId + String loginFamilyId ); @Operation(summary = "회원 미션 참여 가능 여부 응답 조회", description = "회원 미션 참여 가능 여부를 조회합니다.") @@ -141,9 +141,9 @@ MissionAvailableStatusResponse getMissionAvailableStatus( @LoginMemberId String loginMemberId, - @RequestParam - @Parameter(description = "응답 값 조작 필드", example = "true") - boolean valid + @Parameter(hidden = true) + @LoginFamilyId + String loginFamilyId ); @Operation(summary = "미션 키 획득까지 남은 생존신고 업로드 수", description = "미션 키 획득까지 남은 생존신고 업로드 수를 조회합니다.") diff --git a/post/src/main/java/com/oing/service/PostService.java b/post/src/main/java/com/oing/service/PostService.java index 4e892db0..ec21da2b 100644 --- a/post/src/main/java/com/oing/service/PostService.java +++ b/post/src/main/java/com/oing/service/PostService.java @@ -161,6 +161,10 @@ public boolean existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(String memberId, S return postRepository.existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(memberId, familyId, type, postDate); } + public boolean isCreatedSurvivalPostByMajority(LocalDate date, String familyId) { + return postRepository.isCreatedSurvivalPostByMajority(date, familyId); + } + public int calculateRemainingSurvivalPostCount(String familyId) { return postRepository.calculateRemainingSurvivalPostCount(familyId); }