generated from pricelees/issue-pr-template
refactor: region 스키마에서 행정동 컬럼 제거 & API 반영
This commit is contained in:
parent
407d7e9a5e
commit
116dd24e26
@ -46,29 +46,14 @@ class RegionService(
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun findDongBySidoAndSigungu(sidoCode: String, sigunguCode: String): DongListResponse {
|
||||
log.info { "[RegionService.findDongBySidoAndSigungu] 행정동 조회 시작: sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" }
|
||||
val result: List<Pair<String, String>> = regionRepository.findAllDongBySidoAndSigungu(sidoCode, sigunguCode)
|
||||
fun findRegionCode(sidoCode: String, sigunguCode: String): RegionCodeResponse {
|
||||
log.info { "[RegionService.findRegionCode] 지역 코드 조회 시작: sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" }
|
||||
|
||||
if (result.isEmpty()) {
|
||||
log.warn { "[RegionService.findDongBySidoAndSigungu] 행정동 조회 실패: sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" }
|
||||
throw RegionException(RegionErrorCode.DONG_CODE_NOT_FOUND)
|
||||
}
|
||||
|
||||
return DongListResponse(result.map { DongResponse(code = it.first, name = it.second) }).also {
|
||||
log.info { "[RegionService.findDongBySidoAndSigungu] sidoCode=${sidoCode}, sigunguCode=${sigunguCode}인 ${it.dongList.size}개의 행정동 조회 완료" }
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun findRegionCode(sidoCode: String, sigunguCode: String, dongCode: String): RegionCodeResponse {
|
||||
log.info { "[RegionService.findRegionCode] 지역 코드 조회 시작: sidoCode=${sidoCode} / sigunguCode=${sigunguCode} / dongCode=${dongCode}" }
|
||||
|
||||
return regionRepository.findRegionCode(sidoCode, sigunguCode, dongCode)?.let {
|
||||
log.info { "[RegionService.findRegionCode] 지역 코드 조회 완료: code=${it} sidoCode=${sidoCode} / sigunguCode=${sigunguCode} / dongCode=${dongCode}" }
|
||||
return regionRepository.findRegionCode(sidoCode, sigunguCode)?.let {
|
||||
log.info { "[RegionService.findRegionCode] 지역 코드 조회 완료: code=${it} sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" }
|
||||
RegionCodeResponse(it)
|
||||
} ?: run {
|
||||
log.warn { "[RegionService.findRegionCode] 지역 코드 조회 실패: sidoCode=${sidoCode} / sigunguCode=${sigunguCode} / dongCode=${dongCode}" }
|
||||
log.warn { "[RegionService.findRegionCode] 지역 코드 조회 실패: sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" }
|
||||
throw RegionException(RegionErrorCode.REGION_CODE_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ interface RegionAPI {
|
||||
fun findRegionCode(
|
||||
@RequestParam(name = "sidoCode", required = true) sidoCode: String,
|
||||
@RequestParam(name = "sigunguCode", required = true) sigunguCode: String,
|
||||
@RequestParam(name = "dongCode", required = true) dongCode: String,
|
||||
): ResponseEntity<CommonApiResponse<RegionCodeResponse>>
|
||||
|
||||
@Public
|
||||
@ -34,12 +33,4 @@ interface RegionAPI {
|
||||
fun findAllSigunguBySido(
|
||||
@RequestParam(required = true) sidoCode: String
|
||||
): ResponseEntity<CommonApiResponse<SigunguListResponse>>
|
||||
|
||||
@Public
|
||||
@Operation(summary = "모든 행정동 목록 조회")
|
||||
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||
fun findAllDongBySigungu(
|
||||
@RequestParam(name = "sidoCode", required = true) sidoCode: String,
|
||||
@RequestParam(name = "sigunguCode", required = true) sigunguCode: String
|
||||
): ResponseEntity<CommonApiResponse<DongListResponse>>
|
||||
}
|
||||
|
||||
@ -3,16 +3,15 @@ package roomescape.region.infrastructure.persistence
|
||||
import jakarta.persistence.Entity
|
||||
import jakarta.persistence.Id
|
||||
import jakarta.persistence.Table
|
||||
import jakarta.persistence.UniqueConstraint
|
||||
|
||||
@Entity
|
||||
@Table(name = "region")
|
||||
@Table(name = "region", uniqueConstraints = [UniqueConstraint(columnNames = ["sidoCode", "sigunguCode"])])
|
||||
class RegionEntity(
|
||||
@Id
|
||||
val code: String,
|
||||
val sidoCode: String,
|
||||
val sigunguCode: String,
|
||||
val dongCode: String,
|
||||
val sidoName: String,
|
||||
val sigunguName: String,
|
||||
val dongName: String,
|
||||
)
|
||||
|
||||
@ -34,22 +34,6 @@ interface RegionRepository : JpaRepository<RegionEntity, String> {
|
||||
@Param("sidoCode") sidoCode: String
|
||||
): List<Pair<String, String>>
|
||||
|
||||
@Query("""
|
||||
SELECT
|
||||
new kotlin.Pair(r.dongCode, r.dongName)
|
||||
FROM
|
||||
RegionEntity r
|
||||
WHERE
|
||||
r.sidoCode = :sidoCode
|
||||
AND r.sigunguCode = :sigunguCode
|
||||
ORDER BY
|
||||
r.dongName
|
||||
""")
|
||||
fun findAllDongBySidoAndSigungu(
|
||||
@Param("sidoCode") sidoCode: String,
|
||||
@Param("sigunguCode") sigunguCode: String
|
||||
): List<Pair<String, String>>
|
||||
|
||||
@Query("""
|
||||
SELECT
|
||||
r.code
|
||||
@ -58,11 +42,9 @@ interface RegionRepository : JpaRepository<RegionEntity, String> {
|
||||
WHERE
|
||||
r.sidoCode = :sidoCode
|
||||
AND r.sigunguCode = :sigunguCode
|
||||
AND r.dongCode = :dongCode
|
||||
""")
|
||||
fun findRegionCode(
|
||||
@Param("sidoCode") sidoCode: String,
|
||||
@Param("sigunguCode") sigunguCode: String,
|
||||
@Param("dongCode") dongCode: String,
|
||||
): String?
|
||||
}
|
||||
|
||||
@ -18,9 +18,8 @@ class RegionController(
|
||||
override fun findRegionCode(
|
||||
@RequestParam(name = "sidoCode", required = true) sidoCode: String,
|
||||
@RequestParam(name = "sigunguCode", required = true) sigunguCode: String,
|
||||
@RequestParam(name = "dongCode", required = true) dongCode: String,
|
||||
): ResponseEntity<CommonApiResponse<RegionCodeResponse>> {
|
||||
val response = regionService.findRegionCode(sidoCode, sigunguCode, dongCode)
|
||||
val response = regionService.findRegionCode(sidoCode, sigunguCode)
|
||||
|
||||
return ResponseEntity.ok(CommonApiResponse(response))
|
||||
}
|
||||
@ -40,14 +39,4 @@ class RegionController(
|
||||
|
||||
return ResponseEntity.ok(CommonApiResponse(response))
|
||||
}
|
||||
|
||||
@GetMapping("/dong")
|
||||
override fun findAllDongBySigungu(
|
||||
@RequestParam(name = "sidoCode", required = true) sidoCode: String,
|
||||
@RequestParam(name = "sigunguCode", required = true) sigunguCode: String
|
||||
): ResponseEntity<CommonApiResponse<DongListResponse>> {
|
||||
val response = regionService.findDongBySidoAndSigungu(sidoCode, sigunguCode)
|
||||
|
||||
return ResponseEntity.ok(CommonApiResponse(response))
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,10 +2,39 @@ create table if not exists region (
|
||||
code varchar(10) primary key,
|
||||
sido_code varchar(2) not null,
|
||||
sigungu_code varchar(3) not null,
|
||||
dong_code varchar(5) not null ,
|
||||
sido_name varchar(20) not null,
|
||||
sigungu_name varchar(20) not null,
|
||||
dong_name varchar(20) not null
|
||||
|
||||
constraint uk_region__sido_sigungu_code unique (sido_code, sigungu_code)
|
||||
);
|
||||
|
||||
create table if not exists store(
|
||||
id bigint primary key,
|
||||
name varchar(20) not null,
|
||||
address varchar(100) not null,
|
||||
business_reg_num varchar(10) not null,
|
||||
region_code varchar(10) not null,
|
||||
|
||||
created_at timestamp not null,
|
||||
updated_at timestamp not null,
|
||||
|
||||
constraint uk_store__business_reg_num unique (business_reg_num),
|
||||
constraint fk_store__sido_code foreign key (region_code) references region (code)
|
||||
);
|
||||
|
||||
create table if not exists room(
|
||||
id bigint primary key ,
|
||||
name varchar(20) not null,
|
||||
store_id bigint not null,
|
||||
max_capacity smallint not null,
|
||||
status varchar(20) not null,
|
||||
|
||||
created_at timestamp not null,
|
||||
created_by bigint not null,
|
||||
updated_at timestamp not null,
|
||||
updated_by bigint not null,
|
||||
|
||||
constraint fk_room__store_id foreign key (store_id) references store (id)
|
||||
);
|
||||
|
||||
create table if not exists users(
|
||||
|
||||
@ -37,26 +37,14 @@ class RegionApiFailTest(
|
||||
)
|
||||
}
|
||||
|
||||
test("행정동") {
|
||||
every {
|
||||
regionRepository.findAllDongBySidoAndSigungu(any(), any())
|
||||
} returns emptyList()
|
||||
|
||||
runExceptionTest(
|
||||
method = HttpMethod.GET,
|
||||
endpoint = "/regions/dong?sidoCode=11&sigunguCode=110",
|
||||
expectedErrorCode = RegionErrorCode.DONG_CODE_NOT_FOUND,
|
||||
)
|
||||
}
|
||||
|
||||
test("지역 코드") {
|
||||
every {
|
||||
regionRepository.findRegionCode(any(), any(), any())
|
||||
regionRepository.findRegionCode(any(), any())
|
||||
} returns null
|
||||
|
||||
runExceptionTest(
|
||||
method = HttpMethod.GET,
|
||||
endpoint = "/regions/code?sidoCode=11&sigunguCode=110&dongCode=10100",
|
||||
endpoint = "/regions/code?sidoCode=11&sigunguCode=110",
|
||||
expectedErrorCode = RegionErrorCode.REGION_CODE_NOT_FOUND,
|
||||
)
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import roomescape.supports.runTest
|
||||
|
||||
class RegionApiSuccessTest: FunSpecSpringbootTest() {
|
||||
init {
|
||||
context("시/도 -> 시/군/구 -> 행정동 -> 지역 코드 순으로 조회한다.") {
|
||||
context("시/도 -> 시/군/구 -> 지역 코드 순으로 조회한다.") {
|
||||
test("정상 응답") {
|
||||
val sidoCode: String = runTest(
|
||||
on = {
|
||||
@ -33,25 +33,16 @@ class RegionApiSuccessTest: FunSpecSpringbootTest() {
|
||||
}
|
||||
).extract().path("data.sigunguList[0].code")
|
||||
|
||||
val dongCode: String = runTest(
|
||||
on = {
|
||||
get("/regions/dong?sidoCode=$sidoCode&sigunguCode=$sigunguCode")
|
||||
},
|
||||
expect = {
|
||||
statusCode(HttpStatus.OK.value())
|
||||
}
|
||||
).extract().path("data.dongList[0].code")
|
||||
|
||||
val regionCode: String = runTest(
|
||||
on = {
|
||||
get("/regions/code?sidoCode=$sidoCode&sigunguCode=$sigunguCode&dongCode=${dongCode}")
|
||||
get("/regions/code?sidoCode=$sidoCode&sigunguCode=$sigunguCode")
|
||||
},
|
||||
expect = {
|
||||
statusCode(HttpStatus.OK.value())
|
||||
}
|
||||
).extract().path("data.code")
|
||||
|
||||
regionCode shouldBe "$sidoCode$sigunguCode$dongCode"
|
||||
regionCode shouldBe "$sidoCode$sigunguCode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ object UserFixture {
|
||||
email: String = "sample@example.com",
|
||||
password: String = "a".repeat(MIN_PASSWORD_LENGTH),
|
||||
phone: String = "01012345678",
|
||||
regionCode: String = "1111010100",
|
||||
regionCode: String = "1111000000",
|
||||
status: UserStatus = UserStatus.ACTIVE
|
||||
): UserEntity = UserEntity(
|
||||
id = id,
|
||||
@ -69,7 +69,7 @@ object UserFixture {
|
||||
email = "sample@example.com",
|
||||
password = "a".repeat(MIN_PASSWORD_LENGTH),
|
||||
phone = "01012345678",
|
||||
regionCode = "1111010100"
|
||||
regionCode = "1111000000"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user