Skip to content

Commit

Permalink
[BSVR-97] 특정 경기장 구역 내 블럭 리스트 조회 (#21)
Browse files Browse the repository at this point in the history
* feat(Block): 특정 경기장의 블럭 조회 서비스 구현

* fix: 경기장 구역의 블럭을 조회하도록 예외처리 추가

* feat: 구역내 블록 리스트 조회 컨트롤러 추가

* fix: 코드 디폴트 구현 삭제

* feat(Block): data.sql 업데이트

* fix: data.sql 오타 수정
  • Loading branch information
EunjiShin authored Jul 14, 2024
1 parent 6c5de58 commit a4f4d64
Show file tree
Hide file tree
Showing 21 changed files with 254 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.depromeet.spot.application.block;

import java.util.List;

import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;

import org.depromeet.spot.application.block.dto.response.BlockCodeInfoResponse;
import org.depromeet.spot.usecase.port.in.block.BlockReadUsecase;
import org.depromeet.spot.usecase.port.in.block.BlockReadUsecase.BlockCodeInfo;
import org.springframework.http.HttpStatus;
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.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@RestController
@Tag(name = "블록")
@RequiredArgsConstructor
@RequestMapping("/api/v1")
public class BlockReadController {

private final BlockReadUsecase blockReadUsecase;

@ResponseStatus(HttpStatus.OK)
@GetMapping("/stadiums/{stadiumId}/sections/{sectionId}/blocks")
@Operation(summary = "특정 야구 경기장 특정 구역 내의 블록 리스트를 조회한다.")
public List<BlockCodeInfoResponse> findCodeInfosByStadium(
@PathVariable("stadiumId")
@NotNull
@Positive
@Parameter(name = "stadiumId", description = "야구 경기장 PK", required = true)
final Long stadiumId,
@PathVariable("sectionId")
@NotNull
@Positive
@Parameter(name = "sectionId", description = "구역 PK", required = true)
final Long sectionId) {
List<BlockCodeInfo> infos = blockReadUsecase.findCodeInfosByStadium(stadiumId, sectionId);
return infos.stream().map(BlockCodeInfoResponse::from).toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.depromeet.spot.application.block.dto.response;

import org.depromeet.spot.usecase.port.in.block.BlockReadUsecase.BlockCodeInfo;

public record BlockCodeInfoResponse(Long id, String code) {

public static BlockCodeInfoResponse from(BlockCodeInfo blockCodeInfo) {
return new BlockCodeInfoResponse(blockCodeInfo.getId(), blockCodeInfo.getCode());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.depromeet.spot.common.exception.section;

import org.depromeet.spot.common.exception.ErrorCode;
import org.springframework.http.HttpStatus;

import lombok.Getter;

@Getter
public enum SectionErrorCode implements ErrorCode {
SECTION_NOT_FOUND(HttpStatus.NOT_FOUND, "SE001", "요청 구역이 존재하지 않습니다."),
SECTION_NOT_BELONG_TO_STADIUM(HttpStatus.BAD_REQUEST, "SE002", "요청 경기장의 구역이 아닙니다."),
;

private final HttpStatus status;
private final String code;
private String message;

SectionErrorCode(HttpStatus status, String code, String message) {
this.status = status;
this.code = code;
this.message = message;
}

public SectionErrorCode appended(Object o) {
message = message + " {" + o.toString() + "}";
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.depromeet.spot.common.exception.section;

import org.depromeet.spot.common.exception.BusinessException;

public abstract class SectionException extends BusinessException {

protected SectionException(SectionErrorCode errorCode) {
super(errorCode);
}

public static class SectionNotFoundException extends SectionException {
public SectionNotFoundException() {
super(SectionErrorCode.SECTION_NOT_FOUND);
}
}

public static class SectionNotBelongStadiumException extends SectionException {
public SectionNotBelongStadiumException() {
super(SectionErrorCode.SECTION_NOT_BELONG_TO_STADIUM);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.depromeet.spot.jpa.block.repository;

import java.util.List;

import org.depromeet.spot.jpa.block.entity.BlockEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BlockJpaRepository extends JpaRepository<BlockEntity, Long> {

List<BlockEntity> findAllBySectionId(Long sectionId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.depromeet.spot.jpa.block.repository;

import java.util.List;

import org.depromeet.spot.domain.block.Block;
import org.depromeet.spot.jpa.block.entity.BlockEntity;
import org.depromeet.spot.usecase.port.out.block.BlockRepository;
import org.springframework.stereotype.Repository;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class BlockRepositoryImpl implements BlockRepository {

private final BlockJpaRepository blockJpaRepository;

@Override
public List<Block> findAllBySection(final Long sectionId) {
List<BlockEntity> entities = blockJpaRepository.findAllBySectionId(sectionId);
return entities.stream().map(BlockEntity::toDomain).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
public interface SectionJpaRepository extends JpaRepository<SectionEntity, Long> {

List<SectionEntity> findAllByStadiumId(Long stadiumId);

boolean existsByStadiumIdAndId(Long stadiumId, Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ public Section save(Section section) {
// TODO: test를 위해 추가 -> 구역 생성 티켓 작업할 때 구현 예정
return null;
}

@Override
public boolean existsInStadium(Long stadiumId, Long sectionId) {
return sectionJpaRepository.existsByStadiumIdAndId(stadiumId, sectionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ public Stadium save(Stadium stadium) {
// TODO: test를 위해 추가 -> 구장 저장 API 티켓때 구현 예정
return null;
}

@Override
public boolean existsById(final Long id) {
return stadiumJpaRepository.existsById(id);
}
}
8 changes: 7 additions & 1 deletion infrastructure/jpa/src/main/resources/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ VALUES (1, 1, 1),
INSERT INTO sections (id, stadium_id, name, alias, red, green, blue)
VALUES (1, 1, '오렌지석', '응원석', 255, 255, 255),
(2, 1, '네이비석', '프리미엄석', 100, 100, 100),
(3, 1, '레드석', null, 100, 0, 0);
(3, 1, '레드석', null, 100, 0, 0);

-- Section Blocks
INSERT INTO blocks (id, stadium_id, section_id, code, max_rows)
VALUES (1, 1, 1, "207", 18),
(2, 1, 1, "208", 39),
(3, 1, 2, "108", 10);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.depromeet.spot.usecase.port.in.block;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Getter;

public interface BlockReadUsecase {

List<BlockCodeInfo> findCodeInfosByStadium(Long stadiumId, Long sectionId);

@Getter
@AllArgsConstructor
class BlockCodeInfo {
private final Long id;
private final String code;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public interface SectionReadUsecase {

StadiumSections findAllByStadium(Long stadiumId);

boolean existsInStadium(Long stadiumId, Long sectionId);

@Getter
@AllArgsConstructor
class StadiumSections {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public interface StadiumReadUsecase {

Stadium findById(Long id);

boolean existsById(Long id);

@Getter
@AllArgsConstructor
class StadiumHomeTeamInfo {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.depromeet.spot.usecase.port.out.block;

import java.util.List;

import org.depromeet.spot.domain.block.Block;

public interface BlockRepository {

List<Block> findAllBySection(Long sectionId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public interface SectionRepository {
List<Section> findAllByStadium(Long stadiumId);

Section save(Section section);

boolean existsInStadium(Long stadiumId, Long sectionId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ public interface StadiumRepository {
List<Stadium> findAll();

Stadium save(Stadium stadium);

boolean existsById(Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.depromeet.spot.usecase.service.block;

import java.util.List;

import org.depromeet.spot.common.exception.section.SectionException.SectionNotBelongStadiumException;
import org.depromeet.spot.common.exception.stadium.StadiumException.StadiumNotFoundException;
import org.depromeet.spot.domain.block.Block;
import org.depromeet.spot.usecase.port.in.block.BlockReadUsecase;
import org.depromeet.spot.usecase.port.in.section.SectionReadUsecase;
import org.depromeet.spot.usecase.port.in.stadium.StadiumReadUsecase;
import org.depromeet.spot.usecase.port.out.block.BlockRepository;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class BlockReadService implements BlockReadUsecase {

private final BlockRepository blockRepository;
private final StadiumReadUsecase stadiumReadUsecase;
private final SectionReadUsecase sectionReadUsecase;

@Override
public List<BlockCodeInfo> findCodeInfosByStadium(final Long stadiumId, final Long sectionId) {
if (!stadiumReadUsecase.existsById(stadiumId)) {
throw new StadiumNotFoundException();
}
if (!sectionReadUsecase.existsInStadium(stadiumId, sectionId)) {
throw new SectionNotBelongStadiumException();
}
List<Block> blocks = blockRepository.findAllBySection(sectionId);
return blocks.stream().map(b -> new BlockCodeInfo(b.getId(), b.getCode())).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ public StadiumSections findAllByStadium(final Long stadiumId) {
List<SectionInfo> sectionInfos = sections.stream().map(SectionInfo::from).toList();
return new StadiumSections(stadium.getSeatingChartImage(), sectionInfos);
}

@Override
public boolean existsInStadium(final Long stadiumId, final Long sectionId) {
return sectionRepository.existsInStadium(stadiumId, sectionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,9 @@ public StadiumInfoWithSeatChart findWithSeatChartById(final Long id) {
public Stadium findById(final Long id) {
return stadiumRepository.findById(id);
}

@Override
public boolean existsById(final Long id) {
return stadiumRepository.existsById(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@ public Section save(Section section) {
return section;
}
}

@Override
public boolean existsInStadium(Long stadiumId, Long sectionId) {
return data.stream()
.filter(section -> section.getStadiumId().equals(sectionId))
.anyMatch(section -> section.getId().equals(sectionId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,9 @@ public Stadium save(Stadium stadium) {
return stadium;
}
}

@Override
public boolean existsById(final Long id) {
return data.stream().anyMatch(stadium -> stadium.getId().equals(id));
}
}

0 comments on commit a4f4d64

Please sign in to comment.