diff --git a/src/main/java/com/planetrush/planetrush/planet/service/PlanetPolicy.java b/src/main/java/com/planetrush/planetrush/planet/service/PlanetPolicy.java new file mode 100644 index 0000000..1a2e135 --- /dev/null +++ b/src/main/java/com/planetrush/planetrush/planet/service/PlanetPolicy.java @@ -0,0 +1,56 @@ +package com.planetrush.planetrush.planet.service; + +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; + +import org.springframework.stereotype.Component; + +import com.planetrush.planetrush.member.domain.Member; +import com.planetrush.planetrush.planet.domain.Planet; +import com.planetrush.planetrush.planet.exception.InvalidStartDateException; +import com.planetrush.planetrush.planet.exception.ResidentAlreadyExistsException; +import com.planetrush.planetrush.planet.exception.ResidentOverflowException; +import com.planetrush.planetrush.planet.repository.ResidentRepository; +import com.planetrush.planetrush.planet.repository.custom.ResidentRepositoryCustom; + +@Component +public final class PlanetPolicy { + + private static final int MAX_RESIDENT_LIMIT = 9; + private static final int MAX_CHALLENGE_START_OFFSET = 14; + + /** + * 가입 가능한 최대 챌린지 수를 초과하는지 검사합니다. + * @param member + * @param residentRepositoryCustom + */ + public static void validateResidentLimit(Member member, ResidentRepositoryCustom residentRepositoryCustom) { + if (residentRepositoryCustom.getReadyAndInProgressResidents(member) >= MAX_RESIDENT_LIMIT) { + throw new ResidentOverflowException("resident count overflow"); + } + } + + /** + * 동일한 행성에 중복 가입을 방지합니다. + * @param member + * @param planet + * @param residentRepository + */ + public static void validateDuplicateResident(Member member, Planet planet, ResidentRepository residentRepository) { + residentRepository.findByMemberIdAndPlanetId(member.getId(), planet.getId()) + .ifPresent(resident -> { + throw new ResidentAlreadyExistsException("resident already exists: " + resident.getId()); + }); + } + + /** + * 2주 이내로 시작하는지 검사합니다. + * @param startDate + */ + public static void validateStartDateWithinTwoWeeks(LocalDate startDate) { + if(ChronoUnit.DAYS.between(LocalDate.now(), startDate) > MAX_CHALLENGE_START_OFFSET) { + throw new InvalidStartDateException("Start date must be within 14 days from today."); + } + } + +} diff --git a/src/main/java/com/planetrush/planetrush/planet/service/PlanetServiceImpl.java b/src/main/java/com/planetrush/planetrush/planet/service/PlanetServiceImpl.java index 4891d6d..b4dac6d 100644 --- a/src/main/java/com/planetrush/planetrush/planet/service/PlanetServiceImpl.java +++ b/src/main/java/com/planetrush/planetrush/planet/service/PlanetServiceImpl.java @@ -1,5 +1,7 @@ package com.planetrush.planetrush.planet.service; +import static com.planetrush.planetrush.planet.service.PlanetPolicy.*; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; @@ -21,11 +23,8 @@ import com.planetrush.planetrush.planet.domain.image.DefaultPlanetImg; import com.planetrush.planetrush.planet.exception.DuplicatedDeleteResidentRequestException; import com.planetrush.planetrush.planet.exception.DuplicatedRegisterResidentRequestException; -import com.planetrush.planetrush.planet.exception.InvalidStartDateException; import com.planetrush.planetrush.planet.exception.PlanetNotFoundException; -import com.planetrush.planetrush.planet.exception.ResidentAlreadyExistsException; import com.planetrush.planetrush.planet.exception.ResidentNotFoundException; -import com.planetrush.planetrush.planet.exception.ResidentOverflowException; import com.planetrush.planetrush.planet.repository.DefaultPlanetImgRepository; import com.planetrush.planetrush.planet.repository.PlanetRepository; import com.planetrush.planetrush.planet.repository.ResidentRepository; @@ -320,13 +319,8 @@ public void registerResident(PlanetSubscriptionDto dto) { log.error("[IDEMPOTENT] 행성 가입 중복 요청 발생, 회원={}, 행성={}", member.getId(), planet.getId()); throw new DuplicatedRegisterResidentRequestException(); } - if(residentRepositoryCustom.getReadyAndInProgressResidents(member) >= 9) { - throw new ResidentOverflowException("resident count overflow"); - } - residentRepository.findByMemberIdAndPlanetId(member.getId(), planet.getId()) - .ifPresent(resident -> { - throw new ResidentAlreadyExistsException("resident already exists: " + resident.getId()); - }); + validateResidentLimit(member, residentRepositoryCustom); + validateDuplicateResident(member, planet, residentRepository); planet.addParticipant(); residentRepository.save(Resident.isNotCreator(member, planet)); } @@ -368,12 +362,8 @@ public void deleteResident(PlanetSubscriptionDto dto) { public void registerPlanet(RegisterPlanetDto dto) { Member member = memberRepository.findById(dto.getMemberId()) .orElseThrow(() -> new MemberNotFoundException("Member not found with ID: " + dto.getMemberId())); - if(ChronoUnit.DAYS.between(LocalDate.now(), dto.getStartDate()) > 14) { - throw new InvalidStartDateException("Start date must be within 14 days from today."); - } - if(residentRepositoryCustom.getReadyAndInProgressResidents(member) >= 9) { - throw new ResidentOverflowException("resident count overflow"); - } + validateStartDateWithinTwoWeeks(dto.getStartDate()); + validateResidentLimit(member, residentRepositoryCustom); Planet planet = planetRepository.save(Planet.builder() .name(dto.getName()) .category(Category.valueOf(dto.getCategory()))