diff --git a/server-profile-submodule b/server-profile-submodule index 44e5e61..54e5ed3 160000 --- a/server-profile-submodule +++ b/server-profile-submodule @@ -1 +1 @@ -Subproject commit 44e5e61aba92d866a56869a14716f9bac1869cc1 +Subproject commit 54e5ed3e72447e6b229313fa56114bb6eb179617 diff --git a/src/main/kotlin/com/celuveat/common/adapter/out/aws/CloudFrontProperty.kt b/src/main/kotlin/com/celuveat/common/adapter/out/aws/CloudFrontProperty.kt new file mode 100644 index 0000000..3d5e2c9 --- /dev/null +++ b/src/main/kotlin/com/celuveat/common/adapter/out/aws/CloudFrontProperty.kt @@ -0,0 +1,8 @@ +package com.celuveat.common.adapter.out.aws + +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties(prefix = "aws.cloudfront") +data class CloudFrontProperty( + val domain: String, +) diff --git a/src/main/kotlin/com/celuveat/region/adapter/in/rest/RegionApi.kt b/src/main/kotlin/com/celuveat/region/adapter/in/rest/RegionApi.kt new file mode 100644 index 0000000..984145e --- /dev/null +++ b/src/main/kotlin/com/celuveat/region/adapter/in/rest/RegionApi.kt @@ -0,0 +1,13 @@ +package com.celuveat.region.adapter.`in`.rest + +import com.celuveat.region.adapter.`in`.rest.response.RepresentativeRegionResponse +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.web.bind.annotation.GetMapping + +@Tag(name = "지역 API") +interface RegionApi { + @Operation(summary = "대표 지역 조회") + @GetMapping("/regions/representative") + fun readRepresentativeRegions(): List +} diff --git a/src/main/kotlin/com/celuveat/region/adapter/in/rest/RegionController.kt b/src/main/kotlin/com/celuveat/region/adapter/in/rest/RegionController.kt new file mode 100644 index 0000000..b2dea0d --- /dev/null +++ b/src/main/kotlin/com/celuveat/region/adapter/in/rest/RegionController.kt @@ -0,0 +1,20 @@ +package com.celuveat.region.adapter.`in`.rest + +import com.celuveat.region.adapter.`in`.rest.response.RepresentativeRegionResponse +import com.celuveat.region.application.port.`in`.ReadRepresentativeRegionsUseCase +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RequestMapping("/regions") +@RestController +class RegionController( + private val readRepresentativeRegionsUseCase: ReadRepresentativeRegionsUseCase, +) : RegionApi { + + @GetMapping("/representative") + override fun readRepresentativeRegions(): List { + return readRepresentativeRegionsUseCase.readRepresentativeRegions() + .map { RepresentativeRegionResponse.from(it) } + } +} diff --git a/src/main/kotlin/com/celuveat/region/adapter/in/rest/response/RepresentativeRegionResponse.kt b/src/main/kotlin/com/celuveat/region/adapter/in/rest/response/RepresentativeRegionResponse.kt new file mode 100644 index 0000000..8dfb3e2 --- /dev/null +++ b/src/main/kotlin/com/celuveat/region/adapter/in/rest/response/RepresentativeRegionResponse.kt @@ -0,0 +1,17 @@ +package com.celuveat.region.adapter.`in`.rest.response + +import com.celuveat.region.application.port.`in`.result.RepresentativeRegionResult + +data class RepresentativeRegionResponse( + val name: String, + val imageUrl: String, +) { + companion object { + fun from(result: RepresentativeRegionResult): RepresentativeRegionResponse { + return RepresentativeRegionResponse( + name = result.name, + imageUrl = result.imageUrl, + ) + } + } +} diff --git a/src/main/kotlin/com/celuveat/region/adapter/out/persistence/RegionPersistenceAdapter.kt b/src/main/kotlin/com/celuveat/region/adapter/out/persistence/RegionPersistenceAdapter.kt index 6d81fc4..f1fdc17 100644 --- a/src/main/kotlin/com/celuveat/region/adapter/out/persistence/RegionPersistenceAdapter.kt +++ b/src/main/kotlin/com/celuveat/region/adapter/out/persistence/RegionPersistenceAdapter.kt @@ -3,16 +3,23 @@ package com.celuveat.region.adapter.out.persistence import com.celuveat.common.annotation.Adapter import com.celuveat.region.adapter.out.persistence.entity.RegionJpaRepository import com.celuveat.region.adapter.out.persistence.entity.RegionPersistenceMapper +import com.celuveat.region.adapter.out.static.RegionStaticRepository +import com.celuveat.region.application.port.`in`.result.RepresentativeRegionResult import com.celuveat.region.application.port.out.ReadRegionPort import com.celuveat.region.domain.Region @Adapter class RegionPersistenceAdapter( private val regionJpaRepository: RegionJpaRepository, + private val regionStaticRepository: RegionStaticRepository, private val regionPersistenceMapper: RegionPersistenceMapper, ) : ReadRegionPort { override fun readByName(name: String): List { val regions = regionJpaRepository.readByNameContains(name) return regions.map { regionPersistenceMapper.toDomain(it) } } + + override fun readRepresentativeRegions(): List { + return regionStaticRepository.readRepresentativeRegions() + } } diff --git a/src/main/kotlin/com/celuveat/region/adapter/out/static/RegionStaticRepository.kt b/src/main/kotlin/com/celuveat/region/adapter/out/static/RegionStaticRepository.kt new file mode 100644 index 0000000..1346c61 --- /dev/null +++ b/src/main/kotlin/com/celuveat/region/adapter/out/static/RegionStaticRepository.kt @@ -0,0 +1,24 @@ +package com.celuveat.region.adapter.out.static + +import com.celuveat.common.adapter.out.aws.CloudFrontProperty +import com.celuveat.common.annotation.Adapter +import com.celuveat.region.application.port.`in`.result.RepresentativeRegionResult + +@Adapter +class RegionStaticRepository( + property: CloudFrontProperty, +) { + private val representedRegions: List = listOf( + RepresentativeRegionResult("잠실", "${property.domain}/regions/jamsil.webp"), + RepresentativeRegionResult("성수", "${property.domain}/regions/seongsu.webp"), + RepresentativeRegionResult("홍대", "${property.domain}/regions/hongdae.webp"), + RepresentativeRegionResult("을지로", "${property.domain}/regions/euljiro.webp"), + RepresentativeRegionResult("압구정", "${property.domain}/regions/apgujeong.webp"), + RepresentativeRegionResult("여의도", "${property.domain}/regions/yeouido.webp"), + RepresentativeRegionResult("이태원", "${property.domain}/regions/itaewon.webp"), + ) + + fun readRepresentativeRegions(): List { + return representedRegions + } +} diff --git a/src/main/kotlin/com/celuveat/region/application/RegionQueryService.kt b/src/main/kotlin/com/celuveat/region/application/RegionQueryService.kt new file mode 100644 index 0000000..0ffa475 --- /dev/null +++ b/src/main/kotlin/com/celuveat/region/application/RegionQueryService.kt @@ -0,0 +1,16 @@ +package com.celuveat.region.application + +import com.celuveat.region.application.port.`in`.ReadRepresentativeRegionsUseCase +import com.celuveat.region.application.port.`in`.result.RepresentativeRegionResult +import com.celuveat.region.application.port.out.ReadRegionPort +import org.springframework.stereotype.Service + +@Service +class RegionQueryService( + private val readRegionPort: ReadRegionPort, +) : ReadRepresentativeRegionsUseCase { + + override fun readRepresentativeRegions(): List { + return readRegionPort.readRepresentativeRegions() + } +} diff --git a/src/main/kotlin/com/celuveat/region/application/port/in/ReadRepresentativeRegionsUseCase.kt b/src/main/kotlin/com/celuveat/region/application/port/in/ReadRepresentativeRegionsUseCase.kt new file mode 100644 index 0000000..787bf63 --- /dev/null +++ b/src/main/kotlin/com/celuveat/region/application/port/in/ReadRepresentativeRegionsUseCase.kt @@ -0,0 +1,7 @@ +package com.celuveat.region.application.port.`in` + +import com.celuveat.region.application.port.`in`.result.RepresentativeRegionResult + +interface ReadRepresentativeRegionsUseCase { + fun readRepresentativeRegions(): List +} diff --git a/src/main/kotlin/com/celuveat/region/application/port/in/result/RepresentativeRegionResult.kt b/src/main/kotlin/com/celuveat/region/application/port/in/result/RepresentativeRegionResult.kt new file mode 100644 index 0000000..67a8166 --- /dev/null +++ b/src/main/kotlin/com/celuveat/region/application/port/in/result/RepresentativeRegionResult.kt @@ -0,0 +1,6 @@ +package com.celuveat.region.application.port.`in`.result + +data class RepresentativeRegionResult( + val name: String, + val imageUrl: String, +) diff --git a/src/main/kotlin/com/celuveat/region/application/port/out/ReadRegionPort.kt b/src/main/kotlin/com/celuveat/region/application/port/out/ReadRegionPort.kt index 1bc9dae..56eb497 100644 --- a/src/main/kotlin/com/celuveat/region/application/port/out/ReadRegionPort.kt +++ b/src/main/kotlin/com/celuveat/region/application/port/out/ReadRegionPort.kt @@ -1,7 +1,9 @@ package com.celuveat.region.application.port.out +import com.celuveat.region.application.port.`in`.result.RepresentativeRegionResult import com.celuveat.region.domain.Region interface ReadRegionPort { fun readByName(name: String): List + fun readRepresentativeRegions(): List }