diff --git a/src/main/java/com/first/flash/climbing/favorite/application/MemberFavoriteGymService.java b/src/main/java/com/first/flash/climbing/favorite/application/MemberFavoriteGymService.java new file mode 100644 index 00000000..f736b2c7 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/favorite/application/MemberFavoriteGymService.java @@ -0,0 +1,40 @@ +package com.first.flash.climbing.favorite.application; + +import com.first.flash.climbing.favorite.application.dto.MemberFavoriteGymResponseDto; +import com.first.flash.climbing.favorite.domain.MemberFavoriteGym; +import com.first.flash.climbing.favorite.domain.MemberFavoriteGymRepository; +import com.first.flash.climbing.gym.domian.ClimbingGymIdConfirmRequestedEvent; +import com.first.flash.global.event.Events; +import com.first.flash.global.util.AuthUtil; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MemberFavoriteGymService { + + private final MemberFavoriteGymRepository memberFavoriteGymRepository; + + public MemberFavoriteGymResponseDto toggleMemberFavoriteGym(final Long gymId) { + Events.raise(ClimbingGymIdConfirmRequestedEvent.of(gymId)); + UUID memberId = AuthUtil.getId(); + Optional favoriteGym = memberFavoriteGymRepository.findByMemberIdAndGymId(memberId, gymId); + + if (favoriteGym.isPresent()) { + memberFavoriteGymRepository.delete(favoriteGym.get()); + } else { + MemberFavoriteGym memberFavoriteGym = MemberFavoriteGym.createDefault(memberId, gymId); + memberFavoriteGymRepository.save(memberFavoriteGym); + } + return MemberFavoriteGymResponseDto.toDtoByStatus(favoriteGym.isPresent()); + } + + public List findFavoriteGymIdsByMemberId(final UUID memberId) { + return memberFavoriteGymRepository.findByMemberId(memberId).stream() + .map(MemberFavoriteGym::getGymId) + .toList(); + } +} diff --git a/src/main/java/com/first/flash/climbing/favorite/application/dto/MemberFavoriteGymResponseDto.java b/src/main/java/com/first/flash/climbing/favorite/application/dto/MemberFavoriteGymResponseDto.java new file mode 100644 index 00000000..ed1e5529 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/favorite/application/dto/MemberFavoriteGymResponseDto.java @@ -0,0 +1,11 @@ +package com.first.flash.climbing.favorite.application.dto; + +public record MemberFavoriteGymResponseDto(String message) { + + public static MemberFavoriteGymResponseDto toDtoByStatus(final boolean present) { + if (present) { + return new MemberFavoriteGymResponseDto("즐겨찾기에서 제거되었습니다."); + } + return new MemberFavoriteGymResponseDto("즐겨찾기에 추가되었습니다."); + } +} diff --git a/src/main/java/com/first/flash/climbing/favorite/domain/MemberFavoriteGym.java b/src/main/java/com/first/flash/climbing/favorite/domain/MemberFavoriteGym.java new file mode 100644 index 00000000..a0a7e040 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/favorite/domain/MemberFavoriteGym.java @@ -0,0 +1,33 @@ +package com.first.flash.climbing.favorite.domain; + +import com.first.flash.global.domain.BaseEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.util.UUID; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor +@Getter +@ToString +public class MemberFavoriteGym extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private UUID memberId; + private Long gymId; + + protected MemberFavoriteGym(final UUID memberId, final Long gymId) { + this.memberId = memberId; + this.gymId = gymId; + } + + public static MemberFavoriteGym createDefault(final UUID memberId, final Long gymId) { + return new MemberFavoriteGym(memberId, gymId); + } +} diff --git a/src/main/java/com/first/flash/climbing/favorite/domain/MemberFavoriteGymRepository.java b/src/main/java/com/first/flash/climbing/favorite/domain/MemberFavoriteGymRepository.java new file mode 100644 index 00000000..28205336 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/favorite/domain/MemberFavoriteGymRepository.java @@ -0,0 +1,18 @@ +package com.first.flash.climbing.favorite.domain; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface MemberFavoriteGymRepository { + + MemberFavoriteGym save(final MemberFavoriteGym memberFavoriteGym); + + Optional findById(final Long id); + + List findByMemberId(final UUID memberId); + + Optional findByMemberIdAndGymId(final UUID memberId, final Long gymId); + + void delete(final MemberFavoriteGym memberFavoriteGym); +} diff --git a/src/main/java/com/first/flash/climbing/favorite/infrastructure/MemberFavoriteGymJpaRepository.java b/src/main/java/com/first/flash/climbing/favorite/infrastructure/MemberFavoriteGymJpaRepository.java new file mode 100644 index 00000000..de034077 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/favorite/infrastructure/MemberFavoriteGymJpaRepository.java @@ -0,0 +1,20 @@ +package com.first.flash.climbing.favorite.infrastructure; + +import com.first.flash.climbing.favorite.domain.MemberFavoriteGym; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberFavoriteGymJpaRepository extends JpaRepository { + + MemberFavoriteGym save(final MemberFavoriteGym memberFavoriteGym); + + Optional findById(final Long id); + + List findByMemberId(final UUID memberId); + + Optional findByMemberIdAndGymId(final UUID memberId, final Long gymId); + + void delete(final MemberFavoriteGym memberFavoriteGym); +} diff --git a/src/main/java/com/first/flash/climbing/favorite/infrastructure/MemberFavoriteGymRepositoryImpl.java b/src/main/java/com/first/flash/climbing/favorite/infrastructure/MemberFavoriteGymRepositoryImpl.java new file mode 100644 index 00000000..8fbddaf2 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/favorite/infrastructure/MemberFavoriteGymRepositoryImpl.java @@ -0,0 +1,42 @@ +package com.first.flash.climbing.favorite.infrastructure; + +import com.first.flash.climbing.favorite.domain.MemberFavoriteGym; +import com.first.flash.climbing.favorite.domain.MemberFavoriteGymRepository; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class MemberFavoriteGymRepositoryImpl implements MemberFavoriteGymRepository { + + private final MemberFavoriteGymJpaRepository memberFavoriteGymJpaRepository; + + @Override + public MemberFavoriteGym save(final MemberFavoriteGym memberFavoriteGym) { + return memberFavoriteGymJpaRepository.save(memberFavoriteGym); + } + + @Override + public Optional findById(final Long id) { + return memberFavoriteGymJpaRepository.findById(id); + } + + @Override + public List findByMemberId(final UUID memberId) { + return memberFavoriteGymJpaRepository.findByMemberId(memberId); + } + + @Override + public Optional findByMemberIdAndGymId(final UUID memberId, + final Long gymId) { + return memberFavoriteGymJpaRepository.findByMemberIdAndGymId(memberId, gymId); + } + + @Override + public void delete(final MemberFavoriteGym memberFavoriteGym) { + memberFavoriteGymJpaRepository.delete(memberFavoriteGym); + } +} diff --git a/src/main/java/com/first/flash/climbing/favorite/ui/MemberFavoriteGymController.java b/src/main/java/com/first/flash/climbing/favorite/ui/MemberFavoriteGymController.java new file mode 100644 index 00000000..13d5256f --- /dev/null +++ b/src/main/java/com/first/flash/climbing/favorite/ui/MemberFavoriteGymController.java @@ -0,0 +1,38 @@ +package com.first.flash.climbing.favorite.ui; + +import com.first.flash.climbing.favorite.application.MemberFavoriteGymService; +import com.first.flash.climbing.favorite.application.dto.MemberFavoriteGymResponseDto; +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 lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "favorite", description = "즐겨찾기 API") +@RestController +@RequiredArgsConstructor +public class MemberFavoriteGymController { + + private final MemberFavoriteGymService memberFavoriteGymService; + + @Operation(summary = "클라이밍장 즐겨찾기 생성/삭제", description = "클라이밍장 id로 즐겨찾기 토글") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "즐겨찾기 생성 및 삭제", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = MemberFavoriteGymResponseDto.class))), + @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", + content = @Content(mediaType = "application/json")) + }) + @PutMapping("/favorites/{gymId}") + public ResponseEntity toggleMemberFavoriteGym( + @PathVariable final Long gymId) { + return ResponseEntity.status(HttpStatus.OK) + .body(memberFavoriteGymService.toggleMemberFavoriteGym(gymId)); + } +} diff --git a/src/main/java/com/first/flash/climbing/gym/application/ClimbingGymService.java b/src/main/java/com/first/flash/climbing/gym/application/ClimbingGymService.java index 35ef6600..45ea8660 100644 --- a/src/main/java/com/first/flash/climbing/gym/application/ClimbingGymService.java +++ b/src/main/java/com/first/flash/climbing/gym/application/ClimbingGymService.java @@ -1,14 +1,18 @@ package com.first.flash.climbing.gym.application; +import com.first.flash.climbing.favorite.application.MemberFavoriteGymService; import com.first.flash.climbing.gym.application.dto.ClimbingGymCreateRequestDto; import com.first.flash.climbing.gym.application.dto.ClimbingGymCreateResponseDto; import com.first.flash.climbing.gym.application.dto.ClimbingGymDetailResponseDto; -import com.first.flash.climbing.gym.application.dto.ClimbingGymResponseDto; +import com.first.flash.climbing.gym.infrastructure.dto.ClimbingGymResponseDto; import com.first.flash.climbing.gym.domian.ClimbingGym; import com.first.flash.climbing.gym.domian.ClimbingGymRepository; import com.first.flash.climbing.gym.domian.vo.Difficulty; import com.first.flash.climbing.gym.exception.exceptions.ClimbingGymNotFoundException; +import com.first.flash.climbing.gym.infrastructure.dto.SectorInfoResponseDto; +import com.first.flash.global.util.AuthUtil; import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,6 +23,7 @@ public class ClimbingGymService { private final ClimbingGymRepository climbingGymRepository; + private final MemberFavoriteGymService memberFavoriteGymService; @Transactional public ClimbingGymCreateResponseDto save(final ClimbingGymCreateRequestDto createRequestDto) { @@ -32,21 +37,21 @@ public ClimbingGym findClimbingGymById(final Long id) { } public List findAllClimbingGyms() { - return climbingGymRepository.findAll().stream() - .map(ClimbingGymResponseDto::toDto) - .toList(); + UUID memberId = AuthUtil.getId(); + List favoriteGymIds = memberFavoriteGymService.findFavoriteGymIdsByMemberId(memberId); + return climbingGymRepository.findAllWithFavorites(favoriteGymIds); } public ClimbingGymDetailResponseDto findClimbingGymDetail(final Long id) { ClimbingGym climbingGym = findClimbingGymById(id); - List sectorNames = findSectorNamesById(id); + List sectorNames = findSectorNamesById(id); List difficultyNames = getDifficultyNames(climbingGym); return new ClimbingGymDetailResponseDto(climbingGym.getGymName(), climbingGym.getMapImageUrl(), climbingGym.getCalendarImageUrl(), difficultyNames, sectorNames); } - private List findSectorNamesById(final Long id) { + private List findSectorNamesById(final Long id) { return climbingGymRepository.findGymSectorNamesById(id); } diff --git a/src/main/java/com/first/flash/climbing/gym/application/dto/ClimbingGymDetailResponseDto.java b/src/main/java/com/first/flash/climbing/gym/application/dto/ClimbingGymDetailResponseDto.java index f2f1f822..fb9260ef 100644 --- a/src/main/java/com/first/flash/climbing/gym/application/dto/ClimbingGymDetailResponseDto.java +++ b/src/main/java/com/first/flash/climbing/gym/application/dto/ClimbingGymDetailResponseDto.java @@ -1,10 +1,11 @@ package com.first.flash.climbing.gym.application.dto; +import com.first.flash.climbing.gym.infrastructure.dto.SectorInfoResponseDto; import java.util.List; public record ClimbingGymDetailResponseDto(String gymName, String mapImageUrl, String calendarImageUrl, List difficulties, - List sectors) { + List sectors) { } diff --git a/src/main/java/com/first/flash/climbing/gym/application/dto/ClimbingGymResponseDto.java b/src/main/java/com/first/flash/climbing/gym/application/dto/ClimbingGymResponseDto.java deleted file mode 100644 index 5f024d7c..00000000 --- a/src/main/java/com/first/flash/climbing/gym/application/dto/ClimbingGymResponseDto.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.first.flash.climbing.gym.application.dto; - -import com.first.flash.climbing.gym.domian.ClimbingGym; - -public record ClimbingGymResponseDto(Long id, String gymName, String thumbnailUrl) { - - public static ClimbingGymResponseDto toDto(final ClimbingGym gym) { - return new ClimbingGymResponseDto(gym.getId(), gym.getGymName(), gym.getThumbnailUrl()); - } -} diff --git a/src/main/java/com/first/flash/climbing/gym/domian/ClimbingGymRepository.java b/src/main/java/com/first/flash/climbing/gym/domian/ClimbingGymRepository.java index e5e665f0..2367d4ed 100644 --- a/src/main/java/com/first/flash/climbing/gym/domian/ClimbingGymRepository.java +++ b/src/main/java/com/first/flash/climbing/gym/domian/ClimbingGymRepository.java @@ -1,5 +1,7 @@ package com.first.flash.climbing.gym.domian; +import com.first.flash.climbing.gym.infrastructure.dto.ClimbingGymResponseDto; +import com.first.flash.climbing.gym.infrastructure.dto.SectorInfoResponseDto; import java.util.List; import java.util.Optional; @@ -9,7 +11,7 @@ public interface ClimbingGymRepository { Optional findById(final Long id); - List findAll(); + List findAllWithFavorites(final List favoriteGymIds); - List findGymSectorNamesById(final Long id); + List findGymSectorNamesById(final Long id); } diff --git a/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymJpaRepository.java b/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymJpaRepository.java index f5a9a619..49749c71 100644 --- a/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymJpaRepository.java +++ b/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymJpaRepository.java @@ -1,7 +1,6 @@ package com.first.flash.climbing.gym.infrastructure; import com.first.flash.climbing.gym.domian.ClimbingGym; -import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -10,6 +9,4 @@ public interface ClimbingGymJpaRepository extends JpaRepository findById(final Long id); - - List findAll(); } diff --git a/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymQueryDslRepository.java b/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymQueryDslRepository.java index 215c7d32..00f9d5bf 100644 --- a/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymQueryDslRepository.java +++ b/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymQueryDslRepository.java @@ -1,7 +1,12 @@ package com.first.flash.climbing.gym.infrastructure; +import static com.first.flash.climbing.gym.domian.QClimbingGym.climbingGym; import static com.first.flash.climbing.sector.domain.QSector.sector; +import com.first.flash.climbing.gym.infrastructure.dto.ClimbingGymResponseDto; +import com.first.flash.climbing.gym.infrastructure.dto.SectorInfoResponseDto; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; import lombok.RequiredArgsConstructor; @@ -13,12 +18,29 @@ public class ClimbingGymQueryDslRepository { private final JPAQueryFactory jpaQueryFactory; - public List findSortedSectorNamesByGymId(final Long gymId) { - return jpaQueryFactory.select(sector.sectorName.name) + public List findSortedSectorNamesByGymId(final Long gymId) { + return jpaQueryFactory.select( + Projections.constructor(SectorInfoResponseDto.class, sector.sectorName.name, + sector.selectedImageUrl)) .from(sector) .where(sector.gymId.eq(gymId), sector.removalInfo.isExpired.isFalse()) .distinct() .orderBy(sector.sectorName.name.asc()) .fetch(); } + + public List findAllWithFavorites(final List favoriteGymIds) { + return jpaQueryFactory.select( + Projections.constructor(ClimbingGymResponseDto.class, climbingGym.id, + climbingGym.gymName, climbingGym.thumbnailUrl, climbingGym.id.in(favoriteGymIds)) + ) + .from(climbingGym) + .orderBy( + new CaseBuilder() + .when(climbingGym.id.in(favoriteGymIds)).then(1) + .otherwise(0).desc(), + climbingGym.gymName.asc() + ) + .fetch(); + } } diff --git a/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymRepositoryImpl.java b/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymRepositoryImpl.java index ea93b6f0..4946d6f1 100644 --- a/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymRepositoryImpl.java +++ b/src/main/java/com/first/flash/climbing/gym/infrastructure/ClimbingGymRepositoryImpl.java @@ -2,6 +2,8 @@ import com.first.flash.climbing.gym.domian.ClimbingGym; import com.first.flash.climbing.gym.domian.ClimbingGymRepository; +import com.first.flash.climbing.gym.infrastructure.dto.ClimbingGymResponseDto; +import com.first.flash.climbing.gym.infrastructure.dto.SectorInfoResponseDto; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -25,12 +27,12 @@ public Optional findById(final Long id) { } @Override - public List findAll() { - return climbingGymJpaRepository.findAll(); - } + public List findAllWithFavorites(final List favoriteGymIds){ + return climbingGymQueryDslRepository.findAllWithFavorites(favoriteGymIds); + }; @Override - public List findGymSectorNamesById(final Long id) { + public List findGymSectorNamesById(final Long id) { return climbingGymQueryDslRepository.findSortedSectorNamesByGymId(id); } } diff --git a/src/main/java/com/first/flash/climbing/gym/infrastructure/dto/ClimbingGymResponseDto.java b/src/main/java/com/first/flash/climbing/gym/infrastructure/dto/ClimbingGymResponseDto.java new file mode 100644 index 00000000..09c2fbc5 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/gym/infrastructure/dto/ClimbingGymResponseDto.java @@ -0,0 +1,11 @@ +package com.first.flash.climbing.gym.infrastructure.dto; + +import com.first.flash.climbing.gym.domian.ClimbingGym; +import java.util.List; + +public record ClimbingGymResponseDto(Long id, String gymName, String thumbnailUrl, boolean isFavorite) { + + public static Object toDto(final ClimbingGym gym, final List favoriteGymIds) { + return new ClimbingGymResponseDto(gym.getId(), gym.getGymName(), gym.getThumbnailUrl(), favoriteGymIds.contains(gym.getId())); + } +} diff --git a/src/main/java/com/first/flash/climbing/gym/infrastructure/dto/SectorInfoResponseDto.java b/src/main/java/com/first/flash/climbing/gym/infrastructure/dto/SectorInfoResponseDto.java new file mode 100644 index 00000000..16e6cca2 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/gym/infrastructure/dto/SectorInfoResponseDto.java @@ -0,0 +1,5 @@ +package com.first.flash.climbing.gym.infrastructure.dto; + +public record SectorInfoResponseDto(String name, String selectedImageUrl) { + +} diff --git a/src/main/java/com/first/flash/climbing/gym/ui/ClimbingGymController.java b/src/main/java/com/first/flash/climbing/gym/ui/ClimbingGymController.java index 5c4707a8..55e34459 100644 --- a/src/main/java/com/first/flash/climbing/gym/ui/ClimbingGymController.java +++ b/src/main/java/com/first/flash/climbing/gym/ui/ClimbingGymController.java @@ -4,7 +4,7 @@ import com.first.flash.climbing.gym.application.dto.ClimbingGymCreateRequestDto; import com.first.flash.climbing.gym.application.dto.ClimbingGymCreateResponseDto; import com.first.flash.climbing.gym.application.dto.ClimbingGymDetailResponseDto; -import com.first.flash.climbing.gym.application.dto.ClimbingGymResponseDto; +import com.first.flash.climbing.gym.infrastructure.dto.ClimbingGymResponseDto; import com.first.flash.climbing.gym.domian.vo.Difficulty; import com.first.flash.climbing.gym.exception.exceptions.DuplicateDifficultyLevelException; import com.first.flash.climbing.gym.exception.exceptions.DuplicateDifficultyNameException; @@ -27,7 +27,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Tag(name = "gyms", description = "클라이밍장 조회 API") diff --git a/src/main/java/com/first/flash/climbing/problem/application/ProblemEventHandler.java b/src/main/java/com/first/flash/climbing/problem/application/ProblemEventHandler.java index 44c3a089..8b05b54d 100644 --- a/src/main/java/com/first/flash/climbing/problem/application/ProblemEventHandler.java +++ b/src/main/java/com/first/flash/climbing/problem/application/ProblemEventHandler.java @@ -1,6 +1,7 @@ package com.first.flash.climbing.problem.application; import com.first.flash.climbing.problem.domain.ProblemIdConfirmRequestedEvent; +import com.first.flash.climbing.sector.domain.SectorFixedInfoUpdatedEvent; import com.first.flash.climbing.sector.domain.SectorExpiredEvent; import com.first.flash.climbing.sector.domain.SectorInfoUpdatedEvent; import com.first.flash.climbing.sector.domain.SectorRemovalDateUpdatedEvent; @@ -22,7 +23,8 @@ public class ProblemEventHandler { @EventListener @Transactional public void changeRemovalDate(final SectorRemovalDateUpdatedEvent event) { - problemsService.changeRemovalDate(event.getSectorId(), event.getRemovalDate()); + problemsService.changeRemovalDate(event.getSectorId(), event.getRemovalDate(), + event.isExpired()); } @EventListener @@ -40,14 +42,21 @@ public void updateProblemSolutionInfo(final SolutionSavedEvent event) { @EventListener @Transactional public void updateProblemDeletedSolutionInfo(final SolutionDeletedEvent event) { - problemsService.updateProblemDeletedSolutionInfo(event.getProblemId(), event.getPerceivedDifficulty()); + problemsService.updateProblemDeletedSolutionInfo(event.getProblemId(), + event.getPerceivedDifficulty()); } @EventListener @Transactional public void updateQueryProblemInfo(final SectorInfoUpdatedEvent event) { problemsService.updateQueryProblemInfo(event.getId(), event.getSectorName(), - event.getSettingDate()); + event.getSettingDate(), event.isExpired()); + } + + @EventListener + @Transactional + public void updateQueryProblemFixedInfo(final SectorFixedInfoUpdatedEvent event) { + problemsService.updateQueryProblemFixedInfo(event.getSectorIds(), event.getSectorName()); } @EventListener @@ -59,6 +68,7 @@ public void confirmProblemId(final ProblemIdConfirmRequestedEvent event) { @EventListener @Transactional public void updatePerceivedDifficulty(final PerceivedDifficultySetEvent event) { - problemsService.addPerceivedDifficulty(event.getProblemId(), event.getPerceivedDifficulty()); + problemsService.addPerceivedDifficulty(event.getProblemId(), + event.getPerceivedDifficulty()); } } diff --git a/src/main/java/com/first/flash/climbing/problem/application/ProblemsService.java b/src/main/java/com/first/flash/climbing/problem/application/ProblemsService.java index 0685d7ce..d904c4b3 100644 --- a/src/main/java/com/first/flash/climbing/problem/application/ProblemsService.java +++ b/src/main/java/com/first/flash/climbing/problem/application/ProblemsService.java @@ -21,8 +21,8 @@ public class ProblemsService { private final ProblemReadService problemReadService; @Transactional - public void changeRemovalDate(final Long sectorId, final LocalDate removalDate) { - queryProblemRepository.updateRemovalDateBySectorId(sectorId, removalDate); + public void changeRemovalDate(final Long sectorId, final LocalDate removalDate, final boolean isExpired) { + queryProblemRepository.updateRemovalDateBySectorId(sectorId, removalDate, isExpired); } @Transactional @@ -38,7 +38,8 @@ public void updateProblemSolutionInfo(final UUID problemId) { } @Transactional - public void updateProblemDeletedSolutionInfo(final UUID problemId, final Integer perceivedDifficulty) { + public void updateProblemDeletedSolutionInfo(final UUID problemId, + final Integer perceivedDifficulty) { QueryProblem queryProblem = problemReadService.findQueryProblemById(problemId); queryProblem.decrementSolutionCount(); queryProblem.subtractPerceivedDifficulty(perceivedDifficulty); @@ -46,8 +47,8 @@ public void updateProblemDeletedSolutionInfo(final UUID problemId, final Integer @Transactional public void updateQueryProblemInfo(final Long sectorId, final String sectorName, - final LocalDate settingDate) { - queryProblemRepository.updateQueryProblemInfo(sectorId, sectorName, settingDate); + final LocalDate settingDate, final boolean isExpired) { + queryProblemRepository.updateQueryProblemInfo(sectorId, sectorName, settingDate, isExpired); } @Transactional @@ -57,9 +58,14 @@ public void addPerceivedDifficulty(final UUID problemId, final Integer perceived } @Transactional - public ProblemDetailResponseDto setPerceivedDifficulty(final UUID problemId, final Integer perceivedDifficulty) { + public ProblemDetailResponseDto setPerceivedDifficulty(final UUID problemId, + final Integer perceivedDifficulty) { QueryProblem queryProblem = problemReadService.findQueryProblemById(problemId); queryProblem.setPerceivedDifficulty(perceivedDifficulty); return ProblemDetailResponseDto.of(queryProblem); } + + public void updateQueryProblemFixedInfo(final List sectorIds, final String sectorName) { + queryProblemRepository.updateSectorNameBySectorIds(sectorIds, sectorName); + } } diff --git a/src/main/java/com/first/flash/climbing/problem/domain/QueryProblemRepository.java b/src/main/java/com/first/flash/climbing/problem/domain/QueryProblemRepository.java index b0aea189..37bb8c25 100644 --- a/src/main/java/com/first/flash/climbing/problem/domain/QueryProblemRepository.java +++ b/src/main/java/com/first/flash/climbing/problem/domain/QueryProblemRepository.java @@ -17,10 +17,12 @@ List findAll(final ProblemCursor preProblemCursor, final ProblemSo final Long gymId, final List difficulty, final List sector, final Boolean hasSolution, final Boolean isHoney); - void updateRemovalDateBySectorId(final Long sectorId, final LocalDate removalDate); + void updateRemovalDateBySectorId(final Long sectorId, final LocalDate removalDate, final boolean isExpired); void expireProblemsBySectorIds(final List expiredSectorsIds); void updateQueryProblemInfo(final Long sectorId, final String sectorName, - final LocalDate settingDate); + final LocalDate settingDate, final boolean isExpired); + + void updateSectorNameBySectorIds(final List sectorIds, final String sectorName); } diff --git a/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemQueryDslRepository.java b/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemQueryDslRepository.java index 508292e0..351650ef 100644 --- a/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemQueryDslRepository.java +++ b/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemQueryDslRepository.java @@ -23,21 +23,25 @@ public class QueryProblemQueryDslRepository { private final JPAQueryFactory queryFactory; - public List findAll(final ProblemCursor prevProblemCursor, final ProblemSortBy problemSortBy, final int size, + public List findAll(final ProblemCursor prevProblemCursor, + final ProblemSortBy problemSortBy, final int size, final Long gymId, final List difficulty, final List sector, final Boolean hasSolution, final Boolean isHoney) { return queryFactory .selectFrom(queryProblem) - .where(notExpired(), cursorCondition(prevProblemCursor), inGym(gymId), inSectors(sector), + .where(notExpired(), cursorCondition(prevProblemCursor), inGym(gymId), + inSectors(sector), inDifficulties(difficulty), hasSolution(hasSolution), isHoneyCondition(isHoney)) .orderBy(sortItem(problemSortBy), queryProblem.id.desc()) .limit(size) .fetch(); } - public void updateRemovalDateBySectorId(final Long sectorId, final LocalDate removalDate) { + public void updateRemovalDateBySectorId(final Long sectorId, final LocalDate removalDate, + final boolean isExpired) { queryFactory.update(queryProblem) .set(queryProblem.removalDate, removalDate) + .set(queryProblem.isExpired, isExpired) .set(queryProblem.isFakeRemovalDate, false) .where(queryProblem.sectorId.eq(sectorId)) .execute(); @@ -51,10 +55,11 @@ public void expireProblemsBySectorIds(final List expiredSectorsIds) { } public void updateQueryProblemInfo(final Long sectorId, final String sectorName, - final LocalDate settingDate) { + final LocalDate settingDate, final boolean isExpired) { queryFactory.update(queryProblem) .set(queryProblem.sectorName, sectorName) .set(queryProblem.settingDate, settingDate) + .set(queryProblem.isExpired, isExpired) .where(queryProblem.sectorId.eq(sectorId)) .execute(); } @@ -133,4 +138,11 @@ private BooleanExpression hasSolution(final Boolean hasSolution) { } return queryProblem.hasSolution.eq(hasSolution); } + + public void updateSectorNameBySectorIds(final List sectorIds, final String sectorName) { + queryFactory.update(queryProblem) + .set(queryProblem.sectorName, sectorName) + .where(queryProblem.sectorId.in(sectorIds)) + .execute(); + } } diff --git a/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemRepositoryImpl.java b/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemRepositoryImpl.java index b804ae28..c95c3a9a 100644 --- a/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemRepositoryImpl.java +++ b/src/main/java/com/first/flash/climbing/problem/infrastructure/QueryProblemRepositoryImpl.java @@ -29,7 +29,8 @@ public Optional findById(final UUID id) { } @Override - public List findAll(final ProblemCursor prevProblemCursor, final ProblemSortBy problemSortBy, final int size, + public List findAll(final ProblemCursor prevProblemCursor, + final ProblemSortBy problemSortBy, final int size, final Long gymId, final List difficulty, final List sector, final Boolean hasSolution, final Boolean isHoney) { return queryProblemQueryDslRepository.findAll(prevProblemCursor, problemSortBy, size, @@ -37,8 +38,8 @@ public List findAll(final ProblemCursor prevProblemCursor, final P } @Override - public void updateRemovalDateBySectorId(final Long sectorId, final LocalDate removalDate) { - queryProblemQueryDslRepository.updateRemovalDateBySectorId(sectorId, removalDate); + public void updateRemovalDateBySectorId(final Long sectorId, final LocalDate removalDate, final boolean isExpired) { + queryProblemQueryDslRepository.updateRemovalDateBySectorId(sectorId, removalDate, isExpired); } @Override @@ -48,7 +49,13 @@ public void expireProblemsBySectorIds(final List expiredSectorsIds) { @Override public void updateQueryProblemInfo(final Long sectorId, final String sectorName, - final LocalDate settingDate) { - queryProblemQueryDslRepository.updateQueryProblemInfo(sectorId, sectorName, settingDate); + final LocalDate settingDate, final boolean isExpired) { + queryProblemQueryDslRepository.updateQueryProblemInfo(sectorId, sectorName, settingDate, + isExpired); + } + + @Override + public void updateSectorNameBySectorIds(final List sectorIds, final String sectorName) { + queryProblemQueryDslRepository.updateSectorNameBySectorIds(sectorIds, sectorName); } } diff --git a/src/main/java/com/first/flash/climbing/sector/application/SectorService.java b/src/main/java/com/first/flash/climbing/sector/application/SectorService.java index ce7fffc7..63a3106f 100644 --- a/src/main/java/com/first/flash/climbing/sector/application/SectorService.java +++ b/src/main/java/com/first/flash/climbing/sector/application/SectorService.java @@ -1,21 +1,28 @@ package com.first.flash.climbing.sector.application; import com.first.flash.climbing.gym.domian.ClimbingGymIdConfirmRequestedEvent; +import com.first.flash.climbing.sector.application.dto.SectorInfosDetailResponseDto; +import com.first.flash.climbing.sector.domain.SectorFixedInfoUpdatedEvent; +import com.first.flash.climbing.sector.infrastructure.dto.UpdateSectorsDto; import com.first.flash.climbing.sector.application.dto.SectorCreateRequestDto; import com.first.flash.climbing.sector.application.dto.SectorDetailResponseDto; +import com.first.flash.climbing.sector.application.dto.SectorInfoCreateRequestDto; +import com.first.flash.climbing.sector.application.dto.SectorInfoDetailResponseDto; import com.first.flash.climbing.sector.application.dto.SectorUpdateRemovalDateRequestDto; import com.first.flash.climbing.sector.application.dto.SectorUpdateRequestDto; import com.first.flash.climbing.sector.application.dto.SectorsDetailResponseDto; import com.first.flash.climbing.sector.domain.Sector; import com.first.flash.climbing.sector.domain.SectorExpiredEvent; +import com.first.flash.climbing.sector.domain.SectorInfo; +import com.first.flash.climbing.sector.domain.SectorInfoRepository; import com.first.flash.climbing.sector.domain.SectorInfoUpdatedEvent; import com.first.flash.climbing.sector.domain.SectorRemovalDateUpdatedEvent; import com.first.flash.climbing.sector.domain.SectorRepository; +import com.first.flash.climbing.sector.exception.exceptions.SectorInfoNotFoundException; import com.first.flash.climbing.sector.exception.exceptions.SectorNotFoundException; import com.first.flash.global.event.Events; import java.time.LocalDate; import java.util.List; -import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,15 +33,23 @@ public class SectorService { private final SectorRepository sectorRepository; + private final SectorInfoRepository sectorInfoRepository; @Transactional - public SectorDetailResponseDto saveSector(final Long gymId, + public SectorDetailResponseDto saveSector(final Long sectorInfoId, final SectorCreateRequestDto createRequestDto) { + SectorInfo sectorInfo = findSectorInfoById(sectorInfoId); + Sector sector = createSector(sectorInfo, createRequestDto); + return SectorDetailResponseDto.toDto(sectorRepository.save(sector)); + } - Sector sector = createSectorByDto(gymId, createRequestDto); + @Transactional + public SectorInfoDetailResponseDto saveSectorInfo(final Long gymId, + final SectorInfoCreateRequestDto createRequestDto) { + SectorInfo sectorInfo = SectorInfo.createDefault(createRequestDto.name(), + createRequestDto.adminName(), gymId, createRequestDto.selectedImageUrl()); Events.raise(ClimbingGymIdConfirmRequestedEvent.of(gymId)); - - return SectorDetailResponseDto.toDto(sectorRepository.save(sector)); + return SectorInfoDetailResponseDto.toDto(sectorInfoRepository.save(sectorInfo)); } @Transactional @@ -43,7 +58,7 @@ public SectorDetailResponseDto updateSectorRemovalDate(final Long sectorId, Sector sector = findById(sectorId); LocalDate removalDate = sectorUpdateRemovalDateRequestDto.removalDate(); sector.updateRemovalDate(removalDate); - Events.raise(SectorRemovalDateUpdatedEvent.of(sectorId, removalDate)); + Events.raise(SectorRemovalDateUpdatedEvent.of(sectorId, removalDate, sector.isExpired())); return SectorDetailResponseDto.toDto(sector); } @@ -59,14 +74,26 @@ public SectorDetailResponseDto updateSector( final SectorUpdateRequestDto updateRequestDto) { Sector foundSector = findById(sectorId); foundSector.updateSector(updateRequestDto.sectorName(), updateRequestDto.adminSectorName(), - updateRequestDto.settingDate(), - updateRequestDto.removalDate(), updateRequestDto.gymId()); + updateRequestDto.settingDate(), updateRequestDto.removalDate(), + updateRequestDto.selectedImageUrl()); Events.raise(SectorInfoUpdatedEvent.of(foundSector.getId(), updateRequestDto.sectorName(), - updateRequestDto.settingDate())); - Events.raise(ClimbingGymIdConfirmRequestedEvent.of(updateRequestDto.gymId())); + updateRequestDto.settingDate(), foundSector.isExpired())); return SectorDetailResponseDto.toDto(foundSector); } + @Transactional + public SectorInfoDetailResponseDto updateSectorInfo(final Long sectorInfoId, + final SectorInfoCreateRequestDto updateRequestDto) { + SectorInfo sectorInfo = findSectorInfoById(sectorInfoId); + sectorInfo.updateSectorInfo(updateRequestDto.name(), updateRequestDto.adminName(), + updateRequestDto.selectedImageUrl()); + UpdateSectorsDto updateSectorsDto = UpdateSectorsDto.toDto(sectorInfo); + sectorRepository.updateSectors(sectorInfoId, updateSectorsDto); + List sectorIds = sectorRepository.findSectorIdsBySectorInfoId(sectorInfoId); + Events.raise(SectorFixedInfoUpdatedEvent.of(sectorIds, sectorInfo)); + return SectorInfoDetailResponseDto.toDto(sectorInfo); + } + public Sector findById(final Long id) { return sectorRepository.findById(id) .orElseThrow(() -> new SectorNotFoundException(id)); @@ -82,19 +109,26 @@ public SectorsDetailResponseDto findAllSectors() { return new SectorsDetailResponseDto(sectorsResponse); } - private Sector createSectorByDto(final Long gymId, - final SectorCreateRequestDto createRequestDto) { - if (hasNoRemovalDate(createRequestDto)) { - return Sector.createExceptRemovalDate(createRequestDto.name(), - createRequestDto.adminName(), createRequestDto.settingDate(), gymId); - } + public SectorInfosDetailResponseDto findAllSectorInfos() { + List sectorInfosResponse = sectorInfoRepository + .findAll() + .stream() + .map( + SectorInfoDetailResponseDto::toDto) + .toList(); + return new SectorInfosDetailResponseDto(sectorInfosResponse); + } - return Sector.createDefault(createRequestDto.name(), - createRequestDto.adminName(), createRequestDto.settingDate(), - createRequestDto.removalDate(), gymId); + private Sector createSector(final SectorInfo sectorInfo, + final SectorCreateRequestDto createRequestDto) { + return Sector.of(sectorInfo.getSectorName(), createRequestDto.settingDate(), + createRequestDto.removalDate(), sectorInfo.getGymId(), + sectorInfo.getSelectedImageUrl(), sectorInfo.getId()); } - private static boolean hasNoRemovalDate(final SectorCreateRequestDto createRequestDto) { - return Objects.isNull(createRequestDto.removalDate()); + private SectorInfo findSectorInfoById(final Long sectorInfoId) { + return sectorInfoRepository.findById(sectorInfoId) + .orElseThrow( + () -> new SectorInfoNotFoundException(sectorInfoId)); } } diff --git a/src/main/java/com/first/flash/climbing/sector/application/dto/SectorCreateRequestDto.java b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorCreateRequestDto.java index 7472783c..821eece0 100644 --- a/src/main/java/com/first/flash/climbing/sector/application/dto/SectorCreateRequestDto.java +++ b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorCreateRequestDto.java @@ -1,13 +1,10 @@ package com.first.flash.climbing.sector.application.dto; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import java.time.LocalDate; public record SectorCreateRequestDto( - @NotEmpty(message = "섹터 이름은 필수입니다.") String name, - @NotEmpty(message = "섹터 관리 이름은 필수입니다.") String adminName, @NotNull(message = "세팅일 정보는 비어있을 수 없습니다.") LocalDate settingDate, LocalDate removalDate) { -} \ No newline at end of file +} diff --git a/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfoCreateRequestDto.java b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfoCreateRequestDto.java new file mode 100644 index 00000000..2a76ff3c --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfoCreateRequestDto.java @@ -0,0 +1,9 @@ +package com.first.flash.climbing.sector.application.dto; + +import jakarta.validation.constraints.NotEmpty; + +public record SectorInfoCreateRequestDto(@NotEmpty(message = "섹터 이름은 필수입니다.") String name, + @NotEmpty(message = "섹터 관리 이름은 필수입니다.") String adminName, + String selectedImageUrl) { + +} diff --git a/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfoDetailResponseDto.java b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfoDetailResponseDto.java new file mode 100644 index 00000000..efc8f819 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfoDetailResponseDto.java @@ -0,0 +1,13 @@ +package com.first.flash.climbing.sector.application.dto; + +import com.first.flash.climbing.sector.domain.SectorInfo; +import com.first.flash.climbing.sector.domain.vo.SectorName; + +public record SectorInfoDetailResponseDto(Long id, SectorName sectorName, String selectedImageUrl, + Long gymId) { + + public static SectorInfoDetailResponseDto toDto(final SectorInfo sectorInfo) { + return new SectorInfoDetailResponseDto(sectorInfo.getId(), sectorInfo.getSectorName(), + sectorInfo.getSelectedImageUrl(), sectorInfo.getGymId()); + } +} diff --git a/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfosDetailResponseDto.java b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfosDetailResponseDto.java new file mode 100644 index 00000000..ba8cedf2 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorInfosDetailResponseDto.java @@ -0,0 +1,11 @@ +package com.first.flash.climbing.sector.application.dto; + +import java.util.List; + +public record SectorInfosDetailResponseDto(List sectorInfosResponse) { + + public static SectorInfosDetailResponseDto toDto( + final List sectorInfosResponse) { + return new SectorInfosDetailResponseDto(sectorInfosResponse); + } +} diff --git a/src/main/java/com/first/flash/climbing/sector/application/dto/SectorUpdateRequestDto.java b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorUpdateRequestDto.java index ec0a810d..f95265ee 100644 --- a/src/main/java/com/first/flash/climbing/sector/application/dto/SectorUpdateRequestDto.java +++ b/src/main/java/com/first/flash/climbing/sector/application/dto/SectorUpdateRequestDto.java @@ -9,11 +9,6 @@ public record SectorUpdateRequestDto( @NotEmpty(message = "섹터 관리 이름은 필수입니다.") String adminSectorName, @NotNull(message = "세팅일 정보는 비어있을 수 없습니다.") LocalDate settingDate, @NotNull(message = "탈거일 정보는 비어있을 수 없습니다.") LocalDate removalDate, - @NotNull(message = "클라이밍장 ID는 비어있을 수 없습니다.") Long gymId) { + String selectedImageUrl) { - public static SectorUpdateRequestDto of(final String sectorName, final String adminSectorName, - final LocalDate settingDate, final LocalDate removalDate, final Long gymId) { - return new SectorUpdateRequestDto(sectorName, adminSectorName, settingDate, removalDate, - gymId); - } -} \ No newline at end of file +} diff --git a/src/main/java/com/first/flash/climbing/sector/domain/Sector.java b/src/main/java/com/first/flash/climbing/sector/domain/Sector.java index a40ccd64..dd05d812 100644 --- a/src/main/java/com/first/flash/climbing/sector/domain/Sector.java +++ b/src/main/java/com/first/flash/climbing/sector/domain/Sector.java @@ -8,7 +8,9 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import java.time.LocalDate; +import java.util.Objects; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; @@ -17,6 +19,7 @@ @NoArgsConstructor @AllArgsConstructor @Getter +@Builder @ToString public class Sector { @@ -26,27 +29,46 @@ public class Sector { private SectorName sectorName; private LocalDate settingDate; private RemovalInfo removalInfo; + private String selectedImageUrl; private Long gymId; + private Long sectorInfoId; protected Sector(final SectorName sectorName, final LocalDate settingDate, - final RemovalInfo removalInfo, final Long gymId) { + final RemovalInfo removalInfo, final Long gymId, final String selectedImageUrl, + final Long sectorInfoId) { this.sectorName = sectorName; this.settingDate = settingDate; this.removalInfo = removalInfo; + this.selectedImageUrl = selectedImageUrl; this.gymId = gymId; + this.sectorInfoId = sectorInfoId; + } + + public static Sector of(final SectorName sectorName, final LocalDate settingDate, + final LocalDate removalDate, final Long gymId, + final String selectedImageUrl, final Long sectorInfoId) { + if (hasNoRemovalDate(removalDate)) { + return createExceptRemovalDate(sectorName.getName(), sectorName.getAdminName(), + settingDate, gymId, selectedImageUrl, sectorInfoId); + } + + return createDefault(sectorName.getName(), sectorName.getAdminName(), settingDate, + removalDate, gymId, selectedImageUrl, sectorInfoId); } public static Sector createExceptRemovalDate(final String sectorName, - final String adminSectorName, final LocalDate settingDate, final Long gymId) { + final String adminSectorName, final LocalDate settingDate, final Long gymId, + final String selectedImageUrl, final Long sectorInfoId) { return new Sector(SectorName.of(sectorName, adminSectorName), settingDate, - RemovalInfo.createBySettingDate(settingDate), gymId); + RemovalInfo.createBySettingDate(settingDate), gymId, selectedImageUrl, sectorInfoId); } public static Sector createDefault(final String sectorName, final String adminSectorName, - final LocalDate settingDate, final LocalDate removalDate, final Long gymId) { + final LocalDate settingDate, final LocalDate removalDate, final Long gymId, + final String selectedImageUrl, final Long sectorInfoId) { validateRemovalDate(settingDate, removalDate); return new Sector(SectorName.of(sectorName, adminSectorName), settingDate, - RemovalInfo.createDefault(removalDate), gymId); + RemovalInfo.createDefault(removalDate), gymId, selectedImageUrl, sectorInfoId); } public LocalDate getRemovalDate() { @@ -55,16 +77,20 @@ public LocalDate getRemovalDate() { public void updateRemovalDate(final LocalDate removalDate) { validateRemovalDate(settingDate, removalDate); - removalInfo = RemovalInfo.createDefault(removalDate); + removalInfo = RemovalInfo.createByNewRemovalDate(removalDate); } public void updateSector(final String sectorName, final String adminSectorName, - final LocalDate settingDate, final LocalDate removalDate, final Long gymId) { + final LocalDate settingDate, final LocalDate removalDate, final String selectedImageUrl) { validateRemovalDate(settingDate, removalDate); this.sectorName = SectorName.of(sectorName, adminSectorName); this.settingDate = settingDate; - this.removalInfo = RemovalInfo.createDefault(removalDate); - this.gymId = gymId; + this.removalInfo = RemovalInfo.createByNewRemovalDate(removalDate); + this.selectedImageUrl = selectedImageUrl; + } + + public boolean isExpired() { + return removalInfo.getIsExpired(); } private static void validateRemovalDate(final LocalDate settingDate, @@ -73,4 +99,8 @@ private static void validateRemovalDate(final LocalDate settingDate, throw new InvalidRemovalDateException(); } } + + private static boolean hasNoRemovalDate(final LocalDate removalDate) { + return Objects.isNull(removalDate); + } } diff --git a/src/main/java/com/first/flash/climbing/sector/domain/SectorFixedInfoUpdatedEvent.java b/src/main/java/com/first/flash/climbing/sector/domain/SectorFixedInfoUpdatedEvent.java new file mode 100644 index 00000000..9aa6eec8 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/domain/SectorFixedInfoUpdatedEvent.java @@ -0,0 +1,18 @@ +package com.first.flash.climbing.sector.domain; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class SectorFixedInfoUpdatedEvent { + + private List sectorIds; + private String sectorName; + + public static SectorFixedInfoUpdatedEvent of(final List sectorIds, + final SectorInfo sectorInfo) { + return new SectorFixedInfoUpdatedEvent(sectorIds, sectorInfo.getSectorName().getName()); + } +} diff --git a/src/main/java/com/first/flash/climbing/sector/domain/SectorInfo.java b/src/main/java/com/first/flash/climbing/sector/domain/SectorInfo.java new file mode 100644 index 00000000..36da6bd0 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/domain/SectorInfo.java @@ -0,0 +1,44 @@ +package com.first.flash.climbing.sector.domain; + +import com.first.flash.climbing.sector.domain.vo.SectorName; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class SectorInfo { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String selectedImageUrl; + private SectorName sectorName; + private Long gymId; + + protected SectorInfo(final String selectedImageUrl, final SectorName sectorName, + final Long gymId) { + this.selectedImageUrl = selectedImageUrl; + this.sectorName = sectorName; + this.gymId = gymId; + } + + public static SectorInfo createDefault(final String sectorName, final String adminSectorName, + final Long gymId, final String selectedImageUrl) { + return new SectorInfo(selectedImageUrl, SectorName.of(sectorName, adminSectorName), gymId); + } + + public void updateSectorInfo(final String sectorName, final String adminSectorName, + final String selectedImageUrl) { + this.sectorName = SectorName.of(sectorName, adminSectorName); + this.selectedImageUrl = selectedImageUrl; + } +} diff --git a/src/main/java/com/first/flash/climbing/sector/domain/SectorInfoRepository.java b/src/main/java/com/first/flash/climbing/sector/domain/SectorInfoRepository.java new file mode 100644 index 00000000..3f538ff6 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/domain/SectorInfoRepository.java @@ -0,0 +1,13 @@ +package com.first.flash.climbing.sector.domain; + +import java.util.List; +import java.util.Optional; + +public interface SectorInfoRepository { + + SectorInfo save(SectorInfo sectorInfo); + + Optional findById(Long id); + + List findAll(); +} diff --git a/src/main/java/com/first/flash/climbing/sector/domain/SectorInfoUpdatedEvent.java b/src/main/java/com/first/flash/climbing/sector/domain/SectorInfoUpdatedEvent.java index cdcf1dc2..da8f8893 100644 --- a/src/main/java/com/first/flash/climbing/sector/domain/SectorInfoUpdatedEvent.java +++ b/src/main/java/com/first/flash/climbing/sector/domain/SectorInfoUpdatedEvent.java @@ -11,9 +11,10 @@ public class SectorInfoUpdatedEvent { private Long id; private String sectorName; private LocalDate settingDate; + private boolean isExpired; public static SectorInfoUpdatedEvent of(final Long id, final String sectorName, - final LocalDate settingDate) { - return new SectorInfoUpdatedEvent(id, sectorName, settingDate); + final LocalDate settingDate, final boolean isExpired) { + return new SectorInfoUpdatedEvent(id, sectorName, settingDate, isExpired); } } diff --git a/src/main/java/com/first/flash/climbing/sector/domain/SectorRemovalDateUpdatedEvent.java b/src/main/java/com/first/flash/climbing/sector/domain/SectorRemovalDateUpdatedEvent.java index a02bdada..62855233 100644 --- a/src/main/java/com/first/flash/climbing/sector/domain/SectorRemovalDateUpdatedEvent.java +++ b/src/main/java/com/first/flash/climbing/sector/domain/SectorRemovalDateUpdatedEvent.java @@ -11,9 +11,10 @@ public class SectorRemovalDateUpdatedEvent extends Event { private Long sectorId; private LocalDate removalDate; + private boolean isExpired; public static SectorRemovalDateUpdatedEvent of( - final Long sectorId, final LocalDate removalDate) { - return new SectorRemovalDateUpdatedEvent(sectorId, removalDate); + final Long sectorId, final LocalDate removalDate, final boolean isExpired) { + return new SectorRemovalDateUpdatedEvent(sectorId, removalDate, isExpired); } } diff --git a/src/main/java/com/first/flash/climbing/sector/domain/SectorRepository.java b/src/main/java/com/first/flash/climbing/sector/domain/SectorRepository.java index 7b662e4d..80f0821c 100644 --- a/src/main/java/com/first/flash/climbing/sector/domain/SectorRepository.java +++ b/src/main/java/com/first/flash/climbing/sector/domain/SectorRepository.java @@ -1,5 +1,6 @@ package com.first.flash.climbing.sector.domain; +import com.first.flash.climbing.sector.infrastructure.dto.UpdateSectorsDto; import java.util.List; import java.util.Optional; @@ -12,4 +13,8 @@ public interface SectorRepository { List updateExpiredSector(); List findAll(); + + void updateSectors(final Long sectorInfoId, final UpdateSectorsDto updateSectorsDto); + + List findSectorIdsBySectorInfoId(Long sectorInfoId); } diff --git a/src/main/java/com/first/flash/climbing/sector/domain/vo/RemovalInfo.java b/src/main/java/com/first/flash/climbing/sector/domain/vo/RemovalInfo.java index 0e308ab0..aa555463 100644 --- a/src/main/java/com/first/flash/climbing/sector/domain/vo/RemovalInfo.java +++ b/src/main/java/com/first/flash/climbing/sector/domain/vo/RemovalInfo.java @@ -35,4 +35,11 @@ public static RemovalInfo createBySettingDate(final LocalDate settingDate) { public static RemovalInfo createDefault(final LocalDate removalDate) { return new RemovalInfo(removalDate, false, false); } + + public static RemovalInfo createByNewRemovalDate(final LocalDate removalDate) { + if (removalDate.isBefore(LocalDate.now())) { + return new RemovalInfo(removalDate, false, true); + } + return new RemovalInfo(removalDate, false, false); + } } diff --git a/src/main/java/com/first/flash/climbing/sector/exception/SectorExceptionHandler.java b/src/main/java/com/first/flash/climbing/sector/exception/SectorExceptionHandler.java index 5f9041ab..e6de5464 100644 --- a/src/main/java/com/first/flash/climbing/sector/exception/SectorExceptionHandler.java +++ b/src/main/java/com/first/flash/climbing/sector/exception/SectorExceptionHandler.java @@ -1,6 +1,7 @@ package com.first.flash.climbing.sector.exception; import com.first.flash.climbing.sector.exception.exceptions.InvalidRemovalDateException; +import com.first.flash.climbing.sector.exception.exceptions.SectorInfoNotFoundException; import com.first.flash.climbing.sector.exception.exceptions.SectorNotFoundException; import com.first.flash.global.dto.ErrorResponseDto; import org.springframework.http.HttpStatus; @@ -17,6 +18,12 @@ public ResponseEntity handleSectorNotFoundException( return getResponseWithStatus(HttpStatus.NOT_FOUND, exception); } + @ExceptionHandler(SectorInfoNotFoundException.class) + public ResponseEntity handleSectorInfoNotFoundException( + final SectorInfoNotFoundException exception) { + return getResponseWithStatus(HttpStatus.NOT_FOUND, exception); + } + @ExceptionHandler(InvalidRemovalDateException.class) public ResponseEntity handleInvalidRemovalDateException( final InvalidRemovalDateException exception) { diff --git a/src/main/java/com/first/flash/climbing/sector/exception/exceptions/SectorInfoNotFoundException.java b/src/main/java/com/first/flash/climbing/sector/exception/exceptions/SectorInfoNotFoundException.java new file mode 100644 index 00000000..c216cc31 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/exception/exceptions/SectorInfoNotFoundException.java @@ -0,0 +1,8 @@ +package com.first.flash.climbing.sector.exception.exceptions; + +public class SectorInfoNotFoundException extends RuntimeException { + + public SectorInfoNotFoundException(final Long id) { + super(String.format("아이디가 %s인 섹터 정보를 찾을 수 없습니다.", id)); + } +} diff --git a/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorInfoJpaRepository.java b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorInfoJpaRepository.java new file mode 100644 index 00000000..616b8942 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorInfoJpaRepository.java @@ -0,0 +1,15 @@ +package com.first.flash.climbing.sector.infrastructure; + +import com.first.flash.climbing.sector.domain.SectorInfo; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SectorInfoJpaRepository extends JpaRepository { + + SectorInfo save(final SectorInfo sector); + + Optional findById(final Long id); + + List findAll(); +} diff --git a/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorInfoRepositoryImpl.java b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorInfoRepositoryImpl.java new file mode 100644 index 00000000..cf55a1ac --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorInfoRepositoryImpl.java @@ -0,0 +1,30 @@ +package com.first.flash.climbing.sector.infrastructure; + +import com.first.flash.climbing.sector.domain.SectorInfo; +import com.first.flash.climbing.sector.domain.SectorInfoRepository; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class SectorInfoRepositoryImpl implements SectorInfoRepository { + + private final SectorInfoJpaRepository jpaRepository; + + @Override + public SectorInfo save(final SectorInfo sectorInfo) { + return jpaRepository.save(sectorInfo); + } + + @Override + public Optional findById(final Long id) { + return jpaRepository.findById(id); + } + + @Override + public List findAll() { + return jpaRepository.findAll(); + } +} diff --git a/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorQueryDslRepository.java b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorQueryDslRepository.java index 9700beeb..e6acd233 100644 --- a/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorQueryDslRepository.java +++ b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorQueryDslRepository.java @@ -2,6 +2,7 @@ import static com.first.flash.climbing.sector.domain.QSector.sector; +import com.first.flash.climbing.sector.infrastructure.dto.UpdateSectorsDto; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.time.LocalDate; @@ -37,4 +38,21 @@ private BooleanExpression isExpired() { sector.removalInfo.removalDate .before(LocalDate.now())); } + + public void updateSectors(final Long sectorInfoId, + final UpdateSectorsDto updateSectorsDto) { + List sectorIds = findSectorIdsBySectorInfoId(sectorInfoId); + jpaQueryFactory.update(sector) + .set(sector.sectorName.name, updateSectorsDto.name()) + .set(sector.sectorName.adminName, updateSectorsDto.adminName()) + .where(sector.id.in(sectorIds)) + .execute(); + } + + public List findSectorIdsBySectorInfoId(final Long sectorInfoId) { + return jpaQueryFactory.select(sector.id) + .from(sector) + .where(sector.sectorInfoId.eq(sectorInfoId)) + .fetch(); + } } diff --git a/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorRepositoryImpl.java b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorRepositoryImpl.java index 5fc5d5d8..995d8c6c 100644 --- a/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorRepositoryImpl.java +++ b/src/main/java/com/first/flash/climbing/sector/infrastructure/SectorRepositoryImpl.java @@ -2,6 +2,7 @@ import com.first.flash.climbing.sector.domain.Sector; import com.first.flash.climbing.sector.domain.SectorRepository; +import com.first.flash.climbing.sector.infrastructure.dto.UpdateSectorsDto; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -33,4 +34,15 @@ public List updateExpiredSector() { public List findAll() { return sectorJpaRepository.findAll(); } + + @Override + public void updateSectors(final Long sectorInfoId, + final UpdateSectorsDto updateSectorsDto) { + sectorQueryDslRepository.updateSectors(sectorInfoId, updateSectorsDto); + } + + @Override + public List findSectorIdsBySectorInfoId(final Long sectorInfoId) { + return sectorQueryDslRepository.findSectorIdsBySectorInfoId(sectorInfoId); + } } diff --git a/src/main/java/com/first/flash/climbing/sector/infrastructure/dto/UpdateSectorsDto.java b/src/main/java/com/first/flash/climbing/sector/infrastructure/dto/UpdateSectorsDto.java new file mode 100644 index 00000000..9a42f27c --- /dev/null +++ b/src/main/java/com/first/flash/climbing/sector/infrastructure/dto/UpdateSectorsDto.java @@ -0,0 +1,11 @@ +package com.first.flash.climbing.sector.infrastructure.dto; + +import com.first.flash.climbing.sector.domain.SectorInfo; + +public record UpdateSectorsDto(String name, String adminName, String selectedImageUrl) { + + public static UpdateSectorsDto toDto(final SectorInfo sectorInfo) { + return new UpdateSectorsDto(sectorInfo.getSectorName().getName(), + sectorInfo.getSectorName().getAdminName(), sectorInfo.getSelectedImageUrl()); + } +} diff --git a/src/main/java/com/first/flash/climbing/sector/ui/SectorController.java b/src/main/java/com/first/flash/climbing/sector/ui/SectorController.java index 082e11b1..72836fa3 100644 --- a/src/main/java/com/first/flash/climbing/sector/ui/SectorController.java +++ b/src/main/java/com/first/flash/climbing/sector/ui/SectorController.java @@ -3,6 +3,9 @@ import com.first.flash.climbing.sector.application.SectorService; import com.first.flash.climbing.sector.application.dto.SectorCreateRequestDto; import com.first.flash.climbing.sector.application.dto.SectorDetailResponseDto; +import com.first.flash.climbing.sector.application.dto.SectorInfoCreateRequestDto; +import com.first.flash.climbing.sector.application.dto.SectorInfoDetailResponseDto; +import com.first.flash.climbing.sector.application.dto.SectorInfosDetailResponseDto; import com.first.flash.climbing.sector.application.dto.SectorUpdateRemovalDateRequestDto; import com.first.flash.climbing.sector.application.dto.SectorUpdateRequestDto; import com.first.flash.climbing.sector.application.dto.SectorsDetailResponseDto; @@ -44,6 +47,37 @@ public ResponseEntity findAllSectors() { return ResponseEntity.ok(sectorService.findAllSectors()); } + @Operation(summary = "모든 섹터 고정 정보 조회", description = "모든 섹터 정보를 리스트로 반환") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공적으로 섹터를 조회", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SectorInfosDetailResponseDto.class))), + }) + @GetMapping("sectorInfos") + public ResponseEntity findAllSectorInfos() { + return ResponseEntity.ok(sectorService.findAllSectorInfos()); + } + + @Operation(summary = "섹터 고정 정보 생성", description = "특정 클라이밍장의 새로운 섹터 고정 정보 생성") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "성공적으로 섹터를 생성함", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SectorInfoDetailResponseDto.class))), + @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "요청값 누락", value = "{\"name\": \"섹터 이름은 필수입니다.\"}"), + })), + @ApiResponse(responseCode = "404", description = "클라이밍장을 찾을 수 없음", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "클라이밍장 없음", value = "{\"error\": \"아이디가 1인 클라이밍장을 찾을 수 없습니다.\"}") + })) + }) + @PostMapping("admin/gyms/{gymId}/sectorInfos") + public ResponseEntity createSectorInfo( + @PathVariable final Long gymId, + @Valid @RequestBody final SectorInfoCreateRequestDto sectorInfoCreateRequestDto) { + return ResponseEntity.status(HttpStatus.CREATED) + .body(sectorService.saveSectorInfo(gymId, sectorInfoCreateRequestDto)); + } + @Operation(summary = "섹터 갱신(생성)", description = "특정 클라이밍장에 새로운 섹터 생성") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "성공적으로 섹터를 생성함", @@ -58,11 +92,12 @@ public ResponseEntity findAllSectors() { @ExampleObject(name = "클라이밍장 없음", value = "{\"error\": \"아이디가 1인 클라이밍장을 찾을 수 없습니다.\"}") })) }) - @PostMapping("admin/gyms/{gymId}/sectors") - public ResponseEntity createSector(@PathVariable final Long gymId, + @PostMapping("admin/sectorInfos/{sectorInfoId}/sectors") + public ResponseEntity createSector( + @PathVariable final Long sectorInfoId, @Valid @RequestBody final SectorCreateRequestDto sectorCreateRequestDto) { return ResponseEntity.status(HttpStatus.CREATED) - .body(sectorService.saveSector(gymId, sectorCreateRequestDto)); + .body(sectorService.saveSector(sectorInfoId, sectorCreateRequestDto)); } @Operation(summary = "섹터 탈거일 수정", description = "특정 섹터의 탈거일 정보 수정") @@ -100,7 +135,6 @@ public ResponseEntity updateSectorRemovalDate( @ApiResponse(responseCode = "404", description = "리소스를 찾을 수 없음", content = @Content(mediaType = "application/json", examples = { @ExampleObject(name = "섹터 없음", value = "{\"error\": \"아이디가 1인 섹터를 찾을 수 없습니다.\"}"), - @ExampleObject(name = "클라이밍장 없음", value = "{\"error\": \"아이디가 1인 클라이밍장을 찾을 수 없습니다.\"}") })) }) @PutMapping("admin/sectors/{sectorId}") @@ -109,4 +143,24 @@ public ResponseEntity updateSector( @Valid @RequestBody final SectorUpdateRequestDto updateRequestDto) { return ResponseEntity.ok(sectorService.updateSector(sectorId, updateRequestDto)); } + + @Operation(summary = "섹터 전체 수정", description = "특정 섹터의 정보 수정") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공적으로 섹터 정보 수정함", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SectorInfoDetailResponseDto.class))), + @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "요청값 누락", value = "{\"name\": \"섹터 이름은 필수입니다.\"}"), + })), + @ApiResponse(responseCode = "404", description = "리소스를 찾을 수 없음", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "섹터 없음", value = "{\"error\": \"아이디가 1인 섹터 정보를 찾을 수 없습니다.\"}"), + })) + }) + @PutMapping("admin/sectorInfos/{sectorInfoId}") + public ResponseEntity updateSectorInfo( + @PathVariable final Long sectorInfoId, + @Valid @RequestBody final SectorInfoCreateRequestDto updateRequestDto) { + return ResponseEntity.ok(sectorService.updateSectorInfo(sectorInfoId, updateRequestDto)); + } } diff --git a/src/test/java/com/first/flash/climbing/sector/domain/SectorTest.java b/src/test/java/com/first/flash/climbing/sector/domain/SectorTest.java index c4860bf4..b3921d39 100644 --- a/src/test/java/com/first/flash/climbing/sector/domain/SectorTest.java +++ b/src/test/java/com/first/flash/climbing/sector/domain/SectorTest.java @@ -9,6 +9,7 @@ class SectorTest { + private static final String DEFAULT_SECTOR_IMAGE = "example image url"; private static final Long DEFAULT_GYM_ID = 1L; @Test @@ -18,7 +19,7 @@ class SectorTest { // when & then assertThatThrownBy(() -> Sector.createDefault("test", "test", settingDate, - settingDate.minusDays(1), DEFAULT_GYM_ID)) + settingDate.minusDays(1), DEFAULT_GYM_ID, DEFAULT_SECTOR_IMAGE)) .isInstanceOf(InvalidRemovalDateException.class); } @@ -27,7 +28,7 @@ class SectorTest { // given LocalDate settingDate = LocalDate.now(); Sector sector = Sector.createExceptRemovalDate("test", "test", settingDate, - DEFAULT_GYM_ID); + DEFAULT_GYM_ID, DEFAULT_SECTOR_IMAGE); // when sector.updateRemovalDate(settingDate.plusDays(1)); @@ -42,7 +43,7 @@ class SectorTest { // given LocalDate settingDate = LocalDate.now(); Sector sector = Sector.createExceptRemovalDate("test", "test", settingDate, - DEFAULT_GYM_ID); + DEFAULT_GYM_ID, DEFAULT_SECTOR_IMAGE); // when & then assertThatThrownBy(() -> sector.updateRemovalDate(settingDate.minusDays(1))) diff --git a/src/test/java/com/first/flash/climbing/sector/fixture/SectorFixture.java b/src/test/java/com/first/flash/climbing/sector/fixture/SectorFixture.java index bf0fcd80..0cd9fef7 100644 --- a/src/test/java/com/first/flash/climbing/sector/fixture/SectorFixture.java +++ b/src/test/java/com/first/flash/climbing/sector/fixture/SectorFixture.java @@ -6,17 +6,18 @@ public class SectorFixture { + private static final String DEFAULT_SECTOR_IMAGE = "example image url"; private final static Long DEFAULT_PLUS_DAYS = 30L; public static Sector createDefault(final Long gymId, final LocalDate settingDate) { return Sector.createDefault("sector 1", "admin sector 1", - settingDate, settingDate.plusDays(DEFAULT_PLUS_DAYS), gymId); + settingDate, settingDate.plusDays(DEFAULT_PLUS_DAYS), gymId, DEFAULT_SECTOR_IMAGE); } public static Sector createDefaultExceptRemovalDate(final Long gymId, final LocalDate settingDate) { return Sector.createExceptRemovalDate("sector 1", "admin sector 1", - settingDate, gymId); + settingDate, gymId, DEFAULT_SECTOR_IMAGE); } public static SectorCreateRequestDto createDefaultRequestDtoExceptRemovalDate(