diff --git a/app/src/test/kotlin/com/maggom/app/event/MarathonEventQueryRepositoryTest.kt b/app/src/test/kotlin/com/maggom/app/event/MarathonEventQueryRepositoryTest.kt index 8c4645f..28d95ba 100644 --- a/app/src/test/kotlin/com/maggom/app/event/MarathonEventQueryRepositoryTest.kt +++ b/app/src/test/kotlin/com/maggom/app/event/MarathonEventQueryRepositoryTest.kt @@ -57,7 +57,7 @@ class MarathonEventQueryRepositoryTest { @DisplayName("OPEN 상태 + 지역 일치 + regEndDate 미래 - 반환") fun open_status_matching_region_future_reg_end_date_returns_event() { // given - save(status = MarathonEventStatus.OPEN, region = "수도권", regEndDate = now.plusDays(7)) + save(status = MarathonEventStatus.OPEN, region = "서울특별시 마포구", regEndDate = now.plusDays(7)) // when val results = repository.findOpenByRegions(listOf("수도권")) @@ -70,7 +70,7 @@ class MarathonEventQueryRepositoryTest { @DisplayName("UPCOMING 상태 + 지역 일치 - 반환") fun upcoming_status_matching_region_returns_event() { // given - save(status = MarathonEventStatus.UPCOMING, region = "수도권", regEndDate = now.plusDays(7)) + save(status = MarathonEventStatus.UPCOMING, region = "경기도 성남시", regEndDate = now.plusDays(7)) // when val results = repository.findOpenByRegions(listOf("수도권")) @@ -83,7 +83,7 @@ class MarathonEventQueryRepositoryTest { @DisplayName("CLOSED 상태 - 제외") fun closed_status_excludes_event() { // given - save(status = MarathonEventStatus.CLOSED, region = "수도권", regEndDate = now.plusDays(7)) + save(status = MarathonEventStatus.CLOSED, region = "서울특별시 강남구", regEndDate = now.plusDays(7)) // when val results = repository.findOpenByRegions(listOf("수도권")) @@ -96,7 +96,7 @@ class MarathonEventQueryRepositoryTest { @DisplayName("지역 불일치 - 제외") fun mismatched_region_excludes_event() { // given - save(status = MarathonEventStatus.OPEN, region = "충청권", regEndDate = now.plusDays(7)) + save(status = MarathonEventStatus.OPEN, region = "충청북도 청주시", regEndDate = now.plusDays(7)) // when val results = repository.findOpenByRegions(listOf("수도권")) @@ -109,7 +109,7 @@ class MarathonEventQueryRepositoryTest { @DisplayName("regEndDate가 과거이면 제외") fun past_reg_end_date_excludes_event() { // given - save(status = MarathonEventStatus.OPEN, region = "수도권", regEndDate = now.minusDays(1)) + save(status = MarathonEventStatus.OPEN, region = "서울특별시 마포구", regEndDate = now.minusDays(1)) // when val results = repository.findOpenByRegions(listOf("수도권")) @@ -122,7 +122,7 @@ class MarathonEventQueryRepositoryTest { @DisplayName("regEndDate가 null이면 포함") fun null_reg_end_date_includes_event() { // given - save(status = MarathonEventStatus.OPEN, region = "수도권", regEndDate = null) + save(status = MarathonEventStatus.OPEN, region = "인천광역시 남동구", regEndDate = null) // when val results = repository.findOpenByRegions(listOf("수도권")) @@ -135,7 +135,7 @@ class MarathonEventQueryRepositoryTest { @DisplayName("여러 지역 중 하나라도 일치하면 반환") fun at_least_one_matching_region_returns_event() { // given - save(status = MarathonEventStatus.OPEN, region = "충청권", regEndDate = now.plusDays(7)) + save(status = MarathonEventStatus.OPEN, region = "충청북도 청주시", regEndDate = now.plusDays(7)) // when val results = repository.findOpenByRegions(listOf("수도권", "충청권")) @@ -148,9 +148,9 @@ class MarathonEventQueryRepositoryTest { @DisplayName("OPEN 이벤트는 regEndDate 오름차순 정렬") fun open_events_sorted_by_reg_end_date_ascending() { // given - save(status = MarathonEventStatus.OPEN, region = "수도권", regEndDate = now.plusDays(10)) - save(status = MarathonEventStatus.OPEN, region = "수도권", regEndDate = now.plusDays(3)) - save(status = MarathonEventStatus.OPEN, region = "수도권", regEndDate = now.plusDays(7)) + save(status = MarathonEventStatus.OPEN, region = "서울특별시 마포구", regEndDate = now.plusDays(10)) + save(status = MarathonEventStatus.OPEN, region = "경기도 성남시", regEndDate = now.plusDays(3)) + save(status = MarathonEventStatus.OPEN, region = "인천광역시 연수구", regEndDate = now.plusDays(7)) // when val results = repository.findOpenByRegions(listOf("수도권")) @@ -165,8 +165,8 @@ class MarathonEventQueryRepositoryTest { @DisplayName("OPEN이 UPCOMING보다 먼저 정렬") fun open_events_sorted_before_upcoming_events() { // given - save(status = MarathonEventStatus.UPCOMING, region = "수도권", regEndDate = now.plusDays(10)) - save(status = MarathonEventStatus.OPEN, region = "수도권", regEndDate = now.plusDays(5)) + save(status = MarathonEventStatus.UPCOMING, region = "서울특별시 송파구", regEndDate = now.plusDays(10)) + save(status = MarathonEventStatus.OPEN, region = "서울특별시 마포구", regEndDate = now.plusDays(5)) // when val results = repository.findOpenByRegions(listOf("수도권")) diff --git a/event/src/main/kotlin/com/maggom/event/adapter/out/persistence/MarathonEventQueryRepository.kt b/event/src/main/kotlin/com/maggom/event/adapter/out/persistence/MarathonEventQueryRepository.kt index 2b10a98..3f4e6f9 100644 --- a/event/src/main/kotlin/com/maggom/event/adapter/out/persistence/MarathonEventQueryRepository.kt +++ b/event/src/main/kotlin/com/maggom/event/adapter/out/persistence/MarathonEventQueryRepository.kt @@ -1,6 +1,8 @@ package com.maggom.event.adapter.out.persistence import com.maggom.event.domain.MarathonEventStatus +import com.maggom.event.domain.RegionGroup +import com.querydsl.core.BooleanBuilder import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQueryFactory import org.springframework.stereotype.Repository @@ -24,11 +26,16 @@ class MarathonEventQueryRepository( .`when`(event.status.eq(MarathonEventStatus.OPEN)).then(event.regEndDate) .otherwise(event.regStartDate) + val prefixes = regions.flatMap { RegionGroup.toPrefixes(it) } + val regionPredicate = prefixes.fold(BooleanBuilder()) { builder, prefix -> + builder.or(event.region.startsWith(prefix)) + } + return queryFactory .selectFrom(event) .where( event.status.`in`(MarathonEventStatus.OPEN, MarathonEventStatus.UPCOMING), - event.region.`in`(regions), + regionPredicate, event.regEndDate.isNull.or(event.regEndDate.gt(now)), ) .orderBy( diff --git a/event/src/main/kotlin/com/maggom/event/domain/RegionGroup.kt b/event/src/main/kotlin/com/maggom/event/domain/RegionGroup.kt new file mode 100644 index 0000000..9bcbaaa --- /dev/null +++ b/event/src/main/kotlin/com/maggom/event/domain/RegionGroup.kt @@ -0,0 +1,15 @@ +package com.maggom.event.domain + +object RegionGroup { + + private val PREFIXES: Map> = mapOf( + "수도권" to listOf("서울", "경기도", "인천"), + "충청권" to listOf("충청북도", "충청남도", "대전", "세종"), + "경상권" to listOf("경상북도", "경상남도", "대구", "부산", "울산"), + "전라권" to listOf("전라북도", "전라남도", "전북특별자치도", "광주"), + "강원권" to listOf("강원도", "강원특별자치도"), + "제주권" to listOf("제주"), + ) + + fun toPrefixes(regionGroup: String): List = PREFIXES[regionGroup] ?: listOf(regionGroup) +}