-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
기타 접근성 정보 내려주기 #331
기타 접근성 정보 내려주기 #331
Changes from all commits
d321a2b
b7d787c
40fb324
6ab4d2a
8dd931b
19cfc9d
72b87e3
d532285
4c71c2c
e5cb0be
6c4aa80
0bc571d
61cf52e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dependencies { | ||
implementation(projects.apiSpecification.domainEvent) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package club.staircrusher.external_accessibility.application.port.`in` | ||
|
||
import club.staircrusher.external_accessibility.application.port.out.persistence.ExternalAccessibilityRepository | ||
import club.staircrusher.external_accessibility.domain.model.ExternalAccessibility | ||
import club.staircrusher.stdlib.di.annotation.Component | ||
import club.staircrusher.stdlib.external_accessibility.ExternalAccessibilityCategory | ||
import club.staircrusher.stdlib.geography.Length | ||
import club.staircrusher.stdlib.geography.Location | ||
import club.staircrusher.stdlib.geography.LocationUtils | ||
import club.staircrusher.stdlib.util.string.isSimilarWith | ||
|
||
@Component | ||
class ExternalAccessibilitySearchService( | ||
private val externalAccessibilityRepository: ExternalAccessibilityRepository, | ||
) { | ||
fun searchExternalAccessibilities( | ||
searchText: String?, | ||
currentLocation: Location?, | ||
distanceMetersLimit: Length, | ||
categories: List<ExternalAccessibilityCategory> = emptyList(), | ||
): List<ExternalAccessibility> { | ||
return ( | ||
if (categories.isEmpty()) externalAccessibilityRepository.findAll() | ||
else externalAccessibilityRepository.findByCategoryIn(categories.toSet()) | ||
) | ||
// FIXME: 현재 fullscan 후 필터링 중, 나중에 spatial index 걸어주기 | ||
.filter { | ||
currentLocation ?: return@filter true | ||
val distance = LocationUtils.calculateDistance(currentLocation, it.location) | ||
distance <= distanceMetersLimit | ||
} | ||
.filter { | ||
searchText ?: return@filter true | ||
searchText.isSimilarWith(it.name) | ||
} | ||
Comment on lines
+32
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 별다른 정렬 로직은 없나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 일단은 UX 상에서 없어서 쉽게 가고, 나중에 필요할 시 추가하겠습니다 |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package club.staircrusher.external_accessibility.application.port.`in` | ||
|
||
import club.staircrusher.external_accessibility.application.port.out.persistence.ExternalAccessibilityRepository | ||
import club.staircrusher.external_accessibility.domain.model.ExternalAccessibility | ||
import club.staircrusher.stdlib.di.annotation.Component | ||
|
||
@Component | ||
class ExternalAccessibilityService( | ||
private val externalAccessibilityRepository: ExternalAccessibilityRepository, | ||
) { | ||
fun get( | ||
id: String | ||
): ExternalAccessibility { | ||
return externalAccessibilityRepository.findByIdOrNull(id) | ||
?: throw IllegalArgumentException("External Accessibility with id $id does not exist.") | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package club.staircrusher.external_accessibility.application.port.out.persistence | ||
|
||
import club.staircrusher.external_accessibility.domain.model.ExternalAccessibility | ||
import club.staircrusher.stdlib.domain.repository.EntityRepository | ||
import club.staircrusher.stdlib.external_accessibility.ExternalAccessibilityCategory | ||
|
||
@Suppress("TooManyFunctions") | ||
interface ExternalAccessibilityRepository : EntityRepository<ExternalAccessibility, String> { | ||
fun findAll(): List<ExternalAccessibility> | ||
fun findByCategoryIn(categories: Set<ExternalAccessibilityCategory>): List<ExternalAccessibility> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
plugins { | ||
kotlin("plugin.serialization") | ||
} | ||
|
||
dependencies { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package club.staircrusher.external_accessibility.domain.model | ||
|
||
import club.staircrusher.stdlib.external_accessibility.ExternalAccessibilityCategory | ||
import club.staircrusher.stdlib.geography.Location | ||
import java.time.Instant | ||
|
||
data class ExternalAccessibility( | ||
val id: String, | ||
val name: String, | ||
val location: Location, | ||
val address: String, | ||
val createdAt: Instant, | ||
val updatedAt: Instant, | ||
val category: ExternalAccessibilityCategory, | ||
val toiletDetails: ToiletAccessibilityDetails?, | ||
) | ||
Comment on lines
+7
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 외부 데이터를 연동해올 때 쓸 수 있는 멱등키 같은 게 column으로 들어가 있으면 나중에 여러 데이터 소스에서 여러 번 불러올 때 더 좋을 것 같군요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (소스별 prefix + 소스에서제공하는 id) 를 멱등키로 업데이트 하려고 합니다. 이걸 externalAccessibility.id 로 저장할 예정 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그러면 id가 멱등키로 쓰인다는 주석이 있으면 좋겠습니닷 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package club.staircrusher.external_accessibility.domain.model | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ToiletAccessibilityDetails( | ||
val gender: Boolean? = null, | ||
val accessDesc: String? = null, | ||
val availableDesc: String? = null, | ||
val entranceDesc: String? = null, | ||
val stallDesc: String? = null, | ||
val doorDesc: String? = null, | ||
val washStandDesc: String? = null, | ||
val extra: String? = null, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
plugins { | ||
id("io.spring.dependency-management") | ||
id("org.springframework.boot") | ||
} | ||
|
||
dependencies { | ||
api(projects.apiSpecification.api) | ||
api(projects.apiSpecification.domainEvent) | ||
implementation(projects.crossCuttingConcern.infra.persistenceModel) | ||
implementation("org.springframework.boot:spring-boot-starter-web") | ||
|
||
integrationTestImplementation(projects.crossCuttingConcern.test.springIt) | ||
|
||
val awsSdkVersion: String by project | ||
implementation("software.amazon.awssdk:s3:$awsSdkVersion") | ||
runtimeOnly("software.amazon.awssdk:sts:$awsSdkVersion") // IRSA를 사용하기 위해서 필요함 | ||
|
||
testImplementation(projects.boundedContext.externalAccessibility.application) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package club.staircrusher.external_accessibility.infra.adapter.`in`.controller | ||
|
||
import club.staircrusher.api.converter.toDTO | ||
import club.staircrusher.api.spec.dto.ExternalAccessibility | ||
import club.staircrusher.api.spec.dto.GetExternalAccessibilityPostRequest | ||
import club.staircrusher.api.spec.dto.SearchExternalAccessibilitiesPostRequest | ||
import club.staircrusher.api.spec.dto.SearchExternalAccessibilitiesPost200Response | ||
import club.staircrusher.user.domain.model.User | ||
import club.staircrusher.external_accessibility.infra.adapter.`in`.controller.base.ExternalAccessibilityITBase | ||
import club.staircrusher.external_accessibility.infra.adapter.out.persistence.ExternalAccessibilityRepository | ||
import club.staircrusher.stdlib.geography.Length | ||
import club.staircrusher.stdlib.geography.Location | ||
import org.junit.jupiter.api.Assertions.assertEquals | ||
import org.junit.jupiter.api.Assertions.assertNotNull | ||
import org.junit.jupiter.api.Assertions.assertNull | ||
import org.junit.jupiter.api.Assertions.assertTrue | ||
import org.junit.jupiter.api.BeforeEach | ||
import org.junit.jupiter.api.Test | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import kotlin.random.Random | ||
|
||
class ExternalAccessibilityControllerTest : ExternalAccessibilityITBase() { | ||
|
||
@Autowired | ||
private lateinit var externalAccessibilityRepository: ExternalAccessibilityRepository | ||
|
||
@BeforeEach | ||
fun setUp() { | ||
transactionManager.doInTransaction { | ||
externalAccessibilityRepository.removeAll() | ||
} | ||
} | ||
|
||
@Test | ||
fun 서치_정상_동작() { | ||
val currentLocation = Location(127.5, 37.5) | ||
// 데이터가 없다면 보여주지 않는다. | ||
val response = mvc.sccRequest( | ||
"/searchExternalAccessibilities", | ||
SearchExternalAccessibilitiesPostRequest( | ||
currentLocation = currentLocation.toDTO(), | ||
distanceMetersLimit = 2000, | ||
) | ||
) | ||
.getResult(SearchExternalAccessibilitiesPost200Response::class).items ?: emptyList() | ||
assertTrue(response.isEmpty()) | ||
|
||
// 데이터가 존재한다면 보여준다. | ||
testDataGenerator.createExternalAccessibility(location = currentLocation) | ||
testDataGenerator.createExternalAccessibility(location = currentLocation.plusLat(Length.ofMeters(1000))) | ||
val response2 = mvc.sccRequest( | ||
"/searchExternalAccessibilities", | ||
SearchExternalAccessibilitiesPostRequest( | ||
currentLocation = currentLocation.toDTO(), | ||
distanceMetersLimit = 2000, | ||
) | ||
) | ||
.getResult(SearchExternalAccessibilitiesPost200Response::class).items ?: emptyList() | ||
assertTrue(response2.size == 2) | ||
|
||
// 범위 안의 데이터만 보여준다. | ||
val response3 = mvc.sccRequest( | ||
"/searchExternalAccessibilities", | ||
SearchExternalAccessibilitiesPostRequest( | ||
currentLocation = currentLocation.toDTO(), | ||
distanceMetersLimit = 500, | ||
) | ||
) | ||
.getResult(SearchExternalAccessibilitiesPost200Response::class).items ?: emptyList() | ||
assertEquals(1, response3.size) | ||
} | ||
|
||
@Test | ||
fun 서치_단건_조회() { | ||
val data = testDataGenerator.createExternalAccessibility() | ||
val response = mvc.sccRequest( | ||
"/getExternalAccessibility", | ||
GetExternalAccessibilityPostRequest(externalAccessibilityId = data.id) | ||
) | ||
.getResult(ExternalAccessibility::class) | ||
assertEquals(data.name, response.name) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package club.staircrusher.external_accessibility.infra.adapter.`in`.controller.base | ||
|
||
import club.staircrusher.testing.spring_it.base.SccSpringITBase | ||
import java.time.Clock | ||
import org.springframework.beans.factory.annotation.Autowired | ||
|
||
open class ExternalAccessibilityITBase : SccSpringITBase() { | ||
@Autowired private lateinit var clock: Clock | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
required 필드 안 둬도 되나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4c71c2c