-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: 보드판 정보 조회 구현 * test: 보드판 정보 테스트 작성 * fix: 미션 인증에서 누락된 유효성 검사 추가 * feat: 보드판 이벤트 enum 정의 * rename: fixture 추가에 따른 이름 수정 * rename: enum 이름 수정 * refactor: dto로 한 겹 감싸기 * feat: 보드쪽 dto 작성 * rename: enum 이름 변경 * refactor: dto 및 enum 변경
- Loading branch information
Showing
19 changed files
with
428 additions
and
51 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
src/main/java/com/nexters/goalpanzi/application/mission/MissionBoardService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.nexters.goalpanzi.application.mission; | ||
|
||
import com.nexters.goalpanzi.application.mission.dto.request.MissionBoardQuery; | ||
import com.nexters.goalpanzi.application.mission.dto.response.MissionBoardResponse; | ||
import com.nexters.goalpanzi.application.mission.dto.response.MissionBoardsResponse; | ||
import com.nexters.goalpanzi.domain.common.BaseEntity; | ||
import com.nexters.goalpanzi.domain.member.Member; | ||
import com.nexters.goalpanzi.domain.mission.Mission; | ||
import com.nexters.goalpanzi.domain.mission.repository.MissionMemberRepository; | ||
import com.nexters.goalpanzi.domain.mission.repository.MissionRepository; | ||
import com.nexters.goalpanzi.exception.ErrorCode; | ||
import com.nexters.goalpanzi.exception.NotFoundException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Comparator; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class MissionBoardService { | ||
|
||
private final MissionRepository missionRepository; | ||
private final MissionMemberRepository missionMemberRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public MissionBoardsResponse getBoard(final MissionBoardQuery query) { | ||
return new MissionBoardsResponse( | ||
missionRepository.findById(query.missionId()) | ||
.map(this::groupByVerificationCount) | ||
.map(this::sortByVerifiedAt) | ||
.map(this::convertToBoardResponse) | ||
.orElseThrow(() -> new NotFoundException(ErrorCode.NOT_FOUND_MISSION, query.missionId()))); | ||
} | ||
|
||
private Map<Integer, List<Member>> groupByVerificationCount(final Mission mission) { | ||
Map<Integer, List<Member>> board = initializeBoard(mission.getBoardCount()); | ||
|
||
missionMemberRepository.findAllByMissionId(mission.getId()) | ||
.forEach(m -> board.get(m.getVerificationCount()).add(m.getMember())); | ||
return board; | ||
} | ||
|
||
private Map<Integer, List<Member>> sortByVerifiedAt(final Map<Integer, List<Member>> groupedMembers) { | ||
return groupedMembers.entrySet().stream() | ||
.peek(entry -> entry.getValue().sort(Comparator.comparing(BaseEntity::getCreatedAt))) | ||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | ||
} | ||
|
||
private List<MissionBoardResponse> convertToBoardResponse(final Map<Integer, List<Member>> groupedAndSortedMembers) { | ||
return groupedAndSortedMembers.entrySet().stream() | ||
.map(entry -> MissionBoardResponse.of(entry.getKey(), entry.getValue())) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private Map<Integer, List<Member>> initializeBoard(final Integer boardCount) { | ||
return IntStream.range(0, boardCount + 1) | ||
.boxed() | ||
.collect(Collectors.toMap(i -> i, i -> new ArrayList<>())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
src/main/java/com/nexters/goalpanzi/application/mission/dto/request/MissionBoardQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.nexters.goalpanzi.application.mission.dto.request; | ||
|
||
public record MissionBoardQuery( | ||
Long missionId | ||
) { | ||
} |
12 changes: 12 additions & 0 deletions
12
...va/com/nexters/goalpanzi/application/mission/dto/response/MissionBoardMemberResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.nexters.goalpanzi.application.mission.dto.response; | ||
|
||
import com.nexters.goalpanzi.domain.member.CharacterType; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
public record MissionBoardMemberResponse( | ||
@Schema(description = "닉네임", requiredMode = Schema.RequiredMode.REQUIRED) | ||
String nickname, | ||
@Schema(description = "캐릭터 타입", requiredMode = Schema.RequiredMode.REQUIRED) | ||
CharacterType characterType | ||
) { | ||
} |
27 changes: 27 additions & 0 deletions
27
...ain/java/com/nexters/goalpanzi/application/mission/dto/response/MissionBoardResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.nexters.goalpanzi.application.mission.dto.response; | ||
|
||
import com.nexters.goalpanzi.domain.member.Member; | ||
import com.nexters.goalpanzi.domain.mission.Reward; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public record MissionBoardResponse( | ||
@Schema(description = "보드칸 번호", type = "integer", format = "int32", requiredMode = Schema.RequiredMode.REQUIRED) | ||
Integer number, | ||
@Schema(description = "보드칸 보상", requiredMode = Schema.RequiredMode.REQUIRED) | ||
Reward reward, | ||
List<MissionBoardMemberResponse> missionBoardMembers | ||
) { | ||
|
||
public static MissionBoardResponse of(final Integer number, final List<Member> members) { | ||
return new MissionBoardResponse( | ||
number, | ||
Reward.of(number), | ||
members.stream(). | ||
map(m -> new MissionBoardMemberResponse(m.getNickname(), m.getCharacterType())) | ||
.collect(Collectors.toList()) | ||
); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...in/java/com/nexters/goalpanzi/application/mission/dto/response/MissionBoardsResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.nexters.goalpanzi.application.mission.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
import java.util.List; | ||
|
||
public record MissionBoardsResponse( | ||
@Schema(description = "미션 보드칸 정보 리스트", requiredMode = Schema.RequiredMode.REQUIRED) | ||
List<MissionBoardResponse> missionBoards | ||
) { | ||
} |
11 changes: 11 additions & 0 deletions
11
.../com/nexters/goalpanzi/application/mission/dto/response/MissionVerificationsResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.nexters.goalpanzi.application.mission.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
import java.util.List; | ||
|
||
public record MissionVerificationsResponse( | ||
@Schema(description = "미션 인증 정보 리스트", requiredMode = Schema.RequiredMode.REQUIRED) | ||
List<MissionVerificationResponse> missionVerifications | ||
) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
src/main/java/com/nexters/goalpanzi/domain/mission/Reward.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.nexters.goalpanzi.domain.mission; | ||
|
||
import lombok.Getter; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
@Getter | ||
public enum Reward { | ||
ORANGE(1), | ||
CANOLA_FLOWER(3), | ||
DOLHARUBANG(6), | ||
HORSE_RIDING(9), | ||
HALLA_MOUNTAIN(13), | ||
WATERFALL(17), | ||
BLACK_PIG(21), | ||
SUNRISE(25), | ||
GREEN_TEA_FIELD(29), | ||
BEACH(31); | ||
|
||
private final int number; | ||
|
||
private static final Map<Integer, Reward> REWARD_MAP = new HashMap<>(); | ||
|
||
static { | ||
for (Reward item : values()) { | ||
REWARD_MAP.put(item.getNumber(), item); | ||
} | ||
} | ||
|
||
Reward(int number) { | ||
this.number = number; | ||
} | ||
|
||
public static Reward of(final int number) { | ||
return REWARD_MAP.get(number); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/main/java/com/nexters/goalpanzi/presentation/mission/MissionBoardController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.nexters.goalpanzi.presentation.mission; | ||
|
||
import com.nexters.goalpanzi.application.mission.MissionBoardService; | ||
import com.nexters.goalpanzi.application.mission.dto.request.MissionBoardQuery; | ||
import com.nexters.goalpanzi.application.mission.dto.response.MissionBoardsResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequiredArgsConstructor | ||
@RequestMapping("/api/missions") | ||
@RestController | ||
public class MissionBoardController implements MissionBoardControllerDocs { | ||
|
||
private final MissionBoardService missionBoardService; | ||
|
||
@GetMapping("/{missionId}/board") | ||
public ResponseEntity<MissionBoardsResponse> getBoard( | ||
@PathVariable(name = "missionId") final Long missionId | ||
) { | ||
MissionBoardsResponse response = missionBoardService.getBoard(new MissionBoardQuery(missionId)); | ||
|
||
return ResponseEntity.ok(response); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/com/nexters/goalpanzi/presentation/mission/MissionBoardControllerDocs.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.nexters.goalpanzi.presentation.mission; | ||
|
||
import com.nexters.goalpanzi.application.mission.dto.response.MissionBoardsResponse; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.media.Content; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
|
||
@Tag( | ||
name = "미션 보드", | ||
description = """ | ||
미션 보드와 관련된 그룹입니다. | ||
미션 보드판 정보을 제공합니다. | ||
""" | ||
) | ||
public interface MissionBoardControllerDocs { | ||
@Operation(summary = "미션 보드판 조회", description = "해당 미션의 보드판 현황을 조회합니다.") | ||
@ApiResponses({ | ||
@ApiResponse(responseCode = "200"), | ||
@ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), | ||
}) | ||
@GetMapping("/{missionId}/board") | ||
ResponseEntity<MissionBoardsResponse> getBoard( | ||
@Schema(description = "미션 아이디", type = "integer", format = "int64", requiredMode = Schema.RequiredMode.REQUIRED) | ||
@PathVariable(name = "missionId") final Long missionId | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.