From e061e0914478960a83bb830ad39e2567f618a5c5 Mon Sep 17 00:00:00 2001 From: Suhwan Jee Date: Sun, 18 Aug 2024 14:22:56 +0900 Subject: [PATCH] =?UTF-8?q?Accessibility=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=EC=9D=84=20JPA=EB=A1=9C=20=EB=B3=80=ED=99=98=20(#366)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app-server/docker-compose.yml | 2 - .../application/build.gradle.kts | 2 + ...tBuildingAccessibilityImagesUseCaseTest.kt | 7 +- ...testPlaceAccessibilityImagesUseCaseTest.kt | 7 +- .../in/AccessibilityApplicationService.kt | 50 ++- .../port/in/AccessibilityImageService.kt | 38 +- ...AdminDeleteBuildingAccessibilityUseCase.kt | 2 +- .../AdminDeletePlaceAccessibilityUseCase.kt | 2 +- .../in/AdminSearchAccessibilitiesUseCase.kt | 2 +- ...atestBuildingAccessibilityImagesUseCase.kt | 20 +- ...InLatestPlaceAccessibilityImagesUseCase.kt | 12 +- ...ngAccessibilityUpvoteApplicationService.kt | 3 +- .../CancelPlaceAccessibilityUpvoteUseCase.kt | 2 +- .../port/in/DeleteAccessibilityAplService.kt | 4 +- .../port/in/DeleteAccessibilityUseCase.kt | 9 +- .../port/in/GetCountForNextRankUseCase.kt | 4 +- .../application/port/in/GetRankUseCase.kt | 4 +- .../in/GivePlaceAccessibilityUpvoteUseCase.kt | 3 +- .../application/port/in/UpdateRanksUseCase.kt | 20 +- .../AccessibilityAllowedRegionRepository.kt | 7 +- ...ilityImageFaceBlurringHistoryRepository.kt | 10 +- .../AccessibilityRankRepository.kt | 30 +- .../BuildingAccessibilityCommentRepository.kt | 5 +- .../BuildingAccessibilityRepository.kt | 35 +- .../BuildingAccessibilityUpvoteRepository.kt | 15 +- .../PlaceAccessibilityCommentRepository.kt | 4 +- .../PlaceAccessibilityRepository.kt | 54 ++- .../PlaceAccessibilityUpvoteRepository.kt | 16 +- .../accessibility/domain/build.gradle.kts | 3 + .../model/AccessibilityAllowedRegion.kt | 19 +- .../domain/model/AccessibilityImage.kt | 3 + .../AccessibilityImageFaceBlurringHistory.kt | 36 +- ...bilityImageListToTextAttributeConverter.kt | 26 ++ .../domain/model/AccessibilityRank.kt | 34 +- .../domain/model/BuildingAccessibility.kt | 77 +++- .../model/BuildingAccessibilityComment.kt | 26 +- .../model/BuildingAccessibilityUpvote.kt | 26 +- ...nceDoorTypeListToTextAttributeConverter.kt | 15 + .../domain/model/PlaceAccessibility.kt | 54 ++- .../domain/model/PlaceAccessibilityComment.kt | 26 +- .../domain/model/PlaceAccessibilityUpvote.kt | 24 +- .../domain/model/AccessibilityScoreTest.kt | 122 ++++-- .../in/controller/AccessibilityRankTest.kt | 13 +- .../in/controller/DeleteAccessibilityTest.kt | 1 + ...veAndCancelPlaceAccessibilityUpvoteTest.kt | 4 +- .../RegisterBuildingAccessibilityTest.kt | 4 +- .../RegisterPlaceAccessibilityTest.kt | 5 +- ...minAccessibilityAllowedRegionController.kt | 4 +- ...ilityImageFaceBlurringHistoryRepository.kt | 67 --- .../AccessibilityRankRepository.kt | 63 --- .../BuildingAccessibilityCommentRepository.kt | 48 --- .../BuildingAccessibilityRepository.kt | 137 ------ .../BuildingAccessibilityUpvoteRepository.kt | 53 --- .../PlaceAccessibilityCommentRepository.kt | 48 --- .../PlaceAccessibilityRepository.kt | 145 ------- .../PlaceAccessibilityUpvoteRepository.kt | 49 --- ...ghtAccessibilityAllowedRegionRepository.kt | 44 -- .../out/persistence/sqldelight/Converters.kt | 300 -------------- .../adapter/in/controller/SearchPlacesTest.kt | 8 +- .../infra/persistence/sqldelight/DB.kt | 42 -- ...0__place_accessibility_floors_nullable.sqm | 12 + .../AccessibilityAllowedRegion.sq | 25 -- .../AccessibilityImageFaceBlurringHistory.sq | 47 --- .../query/accessibility/AccessibilityRank.sq | 51 --- .../accessibility/BuildingAccessibility.sq | 118 ------ .../BuildingAccessibilityComment.sq | 30 -- .../BuildingAccessibilityUpvote.sq | 31 -- .../query/accessibility/PlaceAccessibility.sq | 136 ------ .../PlaceAccessibilityComment.sq | 30 -- .../accessibility/PlaceAccessibilityUpvote.sq | 29 -- .../jpa/IntListToTextAttributeConverter.kt | 14 + .../jpa/ListToTextAttributeConverter.kt | 4 +- .../LocationListToTextAttributeConverter.kt | 16 + .../jpa/StringListToTextAttributeConverter.kt | 14 + .../testing/spring_it/ITDataGenerator.kt | 4 +- .../data_restore/AccessibilityInserter.kt | 390 +++++++++--------- 76 files changed, 903 insertions(+), 1943 deletions(-) create mode 100644 app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageListToTextAttributeConverter.kt create mode 100644 app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/EntranceDoorTypeListToTextAttributeConverter.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityRankRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityCommentRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityUpvoteRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityCommentRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityUpvoteRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/SqlDelightAccessibilityAllowedRegionRepository.kt delete mode 100644 app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/sqldelight/Converters.kt create mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/migration/V30__place_accessibility_floors_nullable.sqm delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityAllowedRegion.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityImageFaceBlurringHistory.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityRank.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibility.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityComment.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityUpvote.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibility.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityComment.sq delete mode 100644 app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityUpvote.sq create mode 100644 app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/IntListToTextAttributeConverter.kt create mode 100644 app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/LocationListToTextAttributeConverter.kt create mode 100644 app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/StringListToTextAttributeConverter.kt diff --git a/app-server/docker-compose.yml b/app-server/docker-compose.yml index 372136b33..8f6ca09f2 100644 --- a/app-server/docker-compose.yml +++ b/app-server/docker-compose.yml @@ -1,5 +1,3 @@ -name: scc - services: postgres: image: postgres:14.5-alpine diff --git a/app-server/subprojects/bounded_context/accessibility/application/build.gradle.kts b/app-server/subprojects/bounded_context/accessibility/application/build.gradle.kts index 4ce460554..4fc480ef1 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/build.gradle.kts +++ b/app-server/subprojects/bounded_context/accessibility/application/build.gradle.kts @@ -9,6 +9,8 @@ dependencies { implementation("org.sejda.webp-imageio:webp-imageio-sejda:0.1.0") implementation("org.bytedeco:javacv-platform:1.5.10") + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + testImplementation("org.mockito.kotlin:mockito-kotlin:5.1.0") integrationTestImplementation(projects.crossCuttingConcern.test.springIt) diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCaseTest.kt b/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCaseTest.kt index 76ce35e0a..d5ac11477 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCaseTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCaseTest.kt @@ -16,6 +16,7 @@ import org.mockito.Mockito import org.mockito.kotlin.any import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest +import org.springframework.data.repository.findByIdOrNull import java.time.Duration @SpringBootTest(classes = [SccSpringITApplication::class]) @@ -39,9 +40,9 @@ class BlurFacesInLatestBuildingAccessibilityImagesUseCaseTest : BlurFacesITBase( mockDetectFacesWithNoFaceImage(MockDetectFacesService.URL_WITHOUT_FACES, imageBytes) Mockito.`when`(imageProcessor.blur(any(), any(), any())).thenReturn(imageBytes) - placeAccessibilityRepository.removeAll() - buildingAccessibilityRepository.removeAll() - accessibilityImageFaceBlurringHistoryRepository.removeAll() + placeAccessibilityRepository.deleteAll() + buildingAccessibilityRepository.deleteAll() + accessibilityImageFaceBlurringHistoryRepository.deleteAll() } @Test diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCaseTest.kt b/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCaseTest.kt index ae60c5a45..b3ebc81d1 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCaseTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/integrationTest/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCaseTest.kt @@ -16,6 +16,7 @@ import org.mockito.Mockito import org.mockito.kotlin.any import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest +import org.springframework.data.repository.findByIdOrNull import java.time.Duration @SpringBootTest(classes = [SccSpringITApplication::class]) @@ -39,9 +40,9 @@ class BlurFacesInLatestPlaceAccessibilityImagesUseCaseTest : BlurFacesITBase() { mockDetectFacesWithNoFaceImage(MockDetectFacesService.URL_WITHOUT_FACES, imageBytes) Mockito.`when`(imageProcessor.blur(any(), any(), any())).thenReturn(imageBytes) - placeAccessibilityRepository.removeAll() - buildingAccessibilityRepository.removeAll() - accessibilityImageFaceBlurringHistoryRepository.removeAll() + placeAccessibilityRepository.deleteAll() + buildingAccessibilityRepository.deleteAll() + accessibilityImageFaceBlurringHistoryRepository.deleteAll() } @Test diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityApplicationService.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityApplicationService.kt index 32d4a2fb6..b769b6ace 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityApplicationService.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityApplicationService.kt @@ -71,10 +71,10 @@ class AccessibilityApplicationService( internal fun doGetAccessibility(placeId: String, userId: String?): GetAccessibilityResult { val place = placeApplicationService.findPlace(placeId) ?: error("Cannot find place with $placeId") - val buildingAccessibility = buildingAccessibilityRepository.findByBuildingId(place.building.id) + val buildingAccessibility = buildingAccessibilityRepository.findFirstByBuildingIdAndDeletedAtIsNull(place.building.id) val buildingAccessibilityComments = buildingAccessibilityCommentRepository.findByBuildingId(place.building.id) val buildingAccessibilityChallengeCrusherGroup = buildingAccessibility?.id?.let { challengeService.getBuildingAccessibilityCrusherGroup(it) } - val placeAccessibility = placeAccessibilityRepository.findByPlaceId(placeId) + val placeAccessibility = placeAccessibilityRepository.findFirstByPlaceIdAndDeletedAtIsNull(placeId) val placeAccessibilityComments = placeAccessibilityCommentRepository.findByPlaceId(placeId) val placeAccessibilityChallengeCrusherGroup = placeAccessibility?.id?.let { challengeService.getPlaceAccessibilityCrusherGroup(it) } val userInfoById = userApplicationService.getUsers( @@ -91,7 +91,7 @@ class AccessibilityApplicationService( buildingAccessibility.id, ) } != null, - totalUpvoteCount = buildingAccessibilityUpvoteRepository.countUpvotes(buildingAccessibility.id), + totalUpvoteCount = buildingAccessibilityUpvoteRepository.countByBuildingAccessibilityId(buildingAccessibility.id), ) } @@ -113,9 +113,7 @@ class AccessibilityApplicationService( ) }, placeAccessibilityChallengeCrusherGroup = placeAccessibilityChallengeCrusherGroup, - hasOtherPlacesToRegisterInSameBuilding = placeAccessibilityRepository.hasAccessibilityNotRegisteredPlaceInBuilding( - place.building.id - ), + hasOtherPlacesToRegisterInSameBuilding = hasOtherPlacesToRegisterInSameBuilding(place.building), isLastPlaceAccessibilityInBuilding = placeAccessibility?.isLastPlaceAccessibilityInBuilding(place.building.id) ?: false, isFavoritePlace = userId?.let { placeFavoriteRepository.findFirstByUserIdAndPlaceIdAndDeletedAtIsNull(it, placeId) } != null, @@ -123,8 +121,18 @@ class AccessibilityApplicationService( ) } + private fun hasOtherPlacesToRegisterInSameBuilding(building: Building): Boolean { + val placesInBuilding = placeApplicationService.findByBuildingId(building.id) + val placeAccessibilityExistingPlaceIds = placeAccessibilityRepository.findByPlaceIdInAndDeletedAtIsNull(placesInBuilding.map { it.id }) + .map { it.placeId } + return placesInBuilding.any { it.id !in placeAccessibilityExistingPlaceIds } + } + private fun PlaceAccessibility.isLastPlaceAccessibilityInBuilding(buildingId: String): Boolean { - return placeAccessibilityRepository.findByBuildingId(buildingId).let { + val placeIds = placeApplicationService.findByBuildingId(buildingId) + .map { it.id } + .toSet() + return placeAccessibilityRepository.findByPlaceIdInAndDeletedAtIsNull(placeIds).let { it.size == 1 && it[0].id == this.id } } @@ -146,8 +154,9 @@ class AccessibilityApplicationService( } val placeIds = places.map { it.id } // 현재 place 당 pa, ba 는 정책상 1개 이므로 단순 associateBy 해준다. - val pas = placeAccessibilityRepository.findByPlaceIds(placeIds).associateBy { it.placeId } - val bas = buildingAccessibilityRepository.findByPlaceIds(placeIds).associateBy { it.buildingId } + val pas = placeAccessibilityRepository.findByPlaceIdInAndDeletedAtIsNull(placeIds).associateBy { it.placeId } + val buildingIds = places.map { it.building.id }.toSet() + val bas = buildingAccessibilityRepository.findByBuildingIdInAndDeletedAtIsNull(buildingIds).associateBy { it.buildingId } return places.map { pas[it.id] to bas[it.building.id] } @@ -210,7 +219,7 @@ class AccessibilityApplicationService( ) } val buildingId = createBuildingAccessibilityParams.buildingId - if (buildingAccessibilityRepository.findByBuildingId(buildingId) != null) { + if (buildingAccessibilityRepository.findFirstByBuildingIdAndDeletedAtIsNull(buildingId) != null) { throw SccDomainException("이미 접근성 정보가 등록된 건물입니다.") } val building = buildingService.getById(buildingId)!! @@ -267,7 +276,7 @@ class AccessibilityApplicationService( createPlaceAccessibilityParams: PlaceAccessibilityRepository.CreateParams, createPlaceAccessibilityCommentParams: PlaceAccessibilityCommentRepository.CreateParams?, ): RegisterPlaceAccessibilityResult { - if (placeAccessibilityRepository.findByPlaceId(createPlaceAccessibilityParams.placeId) != null) { + if (placeAccessibilityRepository.findFirstByPlaceIdAndDeletedAtIsNull(createPlaceAccessibilityParams.placeId) != null) { throw SccDomainException("이미 접근성 정보가 등록된 장소입니다.") } val place = placeApplicationService.findPlace(createPlaceAccessibilityParams.placeId)!! @@ -311,7 +320,7 @@ class AccessibilityApplicationService( placeAccessibility = result, placeAccessibilityComment = placeAccessibilityComment, accessibilityRegisterer = userInfo, - registrationOrder = placeAccessibilityRepository.countAll(), + registrationOrder = placeAccessibilityRepository.countBy(), isLastPlaceAccessibilityInBuilding = result.isLastPlaceAccessibilityInBuilding(buildingId) ?: false, ) } @@ -378,25 +387,26 @@ class AccessibilityApplicationService( if (placeIds.isEmpty()) return emptyList() return transactionManager.doInTransaction { - placeAccessibilityRepository.findByPlaceIds(placeIds).map { it.placeId } + placeAccessibilityRepository.findByPlaceIdInAndDeletedAtIsNull(placeIds).map { it.placeId } } } fun findByUserId(userId: String): Pair, List> { - val placeAccessibilities = placeAccessibilityRepository.findByUserId(userId) + val placeAccessibilities = placeAccessibilityRepository.findByUserIdAndDeletedAtIsNull(userId) if (placeAccessibilities.isEmpty()) return Pair(emptyList(), emptyList()) - val buildingAccessibilities = - buildingAccessibilityRepository.findByPlaceIds(placeAccessibilities.map { it.placeId }) + val buildingIds = placeApplicationService.findAllByIds(placeAccessibilities.map { it.placeId }) + .map { it.building.id } + val buildingAccessibilities = buildingAccessibilityRepository.findByBuildingIdInAndDeletedAtIsNull(buildingIds) return Pair(placeAccessibilities, buildingAccessibilities) } fun countByUserIdAndCreatedAtBetween(userId: String, from: Instant, to: Instant): Int = - placeAccessibilityRepository.countByUserIdAndCreatedAtBetween( + placeAccessibilityRepository.countByUserIdAndCreatedAtBetweenAndDeletedAtIsNull( userId, from, to - ) + buildingAccessibilityRepository.countByUserIdCreatedAtBetween( + ) + buildingAccessibilityRepository.countByUserIdAndCreatedAtBetweenAndDeletedAtIsNull( userId, from, to @@ -407,8 +417,8 @@ class AccessibilityApplicationService( from: Instant, to: Instant ): Pair, List> { - val placeAccessibilities = placeAccessibilityRepository.findByUserIdAndCreatedAtBetween(userId, from, to) - val buildingAccessibilities = buildingAccessibilityRepository.findByUserIdAndCreatedAtBetween(userId, from, to) + val placeAccessibilities = placeAccessibilityRepository.findByUserIdAndCreatedAtBetweenAndDeletedAtIsNull(userId, from, to) + val buildingAccessibilities = buildingAccessibilityRepository.findByUserIdAndCreatedAtBetweenAndDeletedAtIsNull(userId, from, to) return Pair(placeAccessibilities, buildingAccessibilities) } } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityImageService.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityImageService.kt index 2d7162ce0..3e7165eac 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityImageService.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AccessibilityImageService.kt @@ -41,33 +41,36 @@ class AccessibilityImageService( placeAccessibilityId: String? = null ): PlaceAccessibility? { val placeAccessibility = - placeId?.let { placeAccessibilityRepository.findByPlaceId(it) } - ?: placeAccessibilityId?.let { placeAccessibilityRepository.findById(it) } + placeId?.let { placeAccessibilityRepository.findFirstByPlaceIdAndDeletedAtIsNull(it) } + ?: placeAccessibilityId?.let { placeAccessibilityRepository.findById(it).get() }?.takeIf { it.deletedAt == null } ?: return null if (placeAccessibility.images.isEmpty() && placeAccessibility.imageUrls.isNotEmpty()) { val placeAccessibilityImages = placeAccessibility.imageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } - placeAccessibilityRepository.updateImages(placeAccessibility.id, placeAccessibilityImages) + placeAccessibility.updateImages(placeAccessibilityImages) + placeAccessibilityRepository.save(placeAccessibility) } - return placeId?.let { placeAccessibilityRepository.findByPlaceId(it) } ?: placeAccessibilityId?.let { placeAccessibilityRepository.findById(it) } + return placeAccessibility } fun doMigrateBuildingAccessibilityImageUrlsToImagesIfNeeded( buildingId: String? = null, buildingAccessibilityId: String? = null, ): BuildingAccessibility? { - val buildingAccessibility = buildingId?.let { buildingAccessibilityRepository.findByBuildingId(it) } - ?: buildingAccessibilityId?.let { buildingAccessibilityRepository.findById(it) } ?: return null + val buildingAccessibility = buildingId?.let { buildingAccessibilityRepository.findFirstByBuildingIdAndDeletedAtIsNull(it) } + ?: buildingAccessibilityId?.let { buildingAccessibilityRepository.findById(it).get() }?.takeIf { it.deletedAt == null } + ?: return null if (buildingAccessibility.entranceImages.isEmpty() && buildingAccessibility.entranceImageUrls.isNotEmpty()) { val buildingEntranceImages = buildingAccessibility.entranceImageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } - buildingAccessibilityRepository.updateEntranceImages(buildingAccessibility.id, buildingEntranceImages) + buildingAccessibility.updateEntranceImages(buildingEntranceImages) } if (buildingAccessibility.elevatorImages.isEmpty() && buildingAccessibility.elevatorImageUrls.isNotEmpty()) { val buildingElevatorImages = buildingAccessibility.elevatorImageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } - buildingAccessibilityRepository.updateElevatorImages(buildingAccessibility.id, buildingElevatorImages) + buildingAccessibility.updateElevatorImages(buildingElevatorImages) } - return buildingId?.let { buildingAccessibilityRepository.findByBuildingId(it) } ?: buildingAccessibilityId?.let { buildingAccessibilityRepository.findById(it) } + buildingAccessibilityRepository.save(buildingAccessibility) + return buildingAccessibility } fun generateThumbnailsIfNeeded(placeId: String) { @@ -85,8 +88,8 @@ class AccessibilityImageService( private fun getThumbnailGenerationRequiredImages(placeId: String) = transactionManager.doInTransaction { val place = placeApplicationService.findPlace(placeId) ?: return@doInTransaction emptyList() - val placeAccessibility = placeAccessibilityRepository.findByPlaceId(placeId) - val buildingAccessibility = buildingAccessibilityRepository.findByBuildingId(place.building.id) + val placeAccessibility = placeAccessibilityRepository.findFirstByPlaceIdAndDeletedAtIsNull(placeId) + val buildingAccessibility = buildingAccessibilityRepository.findFirstByBuildingIdAndDeletedAtIsNull(place.building.id) val accessibilityImages = listOfNotNull(placeAccessibility?.images, buildingAccessibility?.entranceImages, buildingAccessibility?.elevatorImages).flatten() @@ -96,8 +99,8 @@ class AccessibilityImageService( private fun saveThumbnailUrls(placeId: String, thumbnailUrls: List) { transactionManager.doInTransaction(isolationLevel = TransactionIsolationLevel.REPEATABLE_READ) { val place = placeApplicationService.findPlace(placeId)!! - val placeAccessibility = placeAccessibilityRepository.findByPlaceId(placeId) - val buildingAccessibility = buildingAccessibilityRepository.findByBuildingId(place.building.id) + val placeAccessibility = placeAccessibilityRepository.findFirstByPlaceIdAndDeletedAtIsNull(placeId) + val buildingAccessibility = buildingAccessibilityRepository.findFirstByBuildingIdAndDeletedAtIsNull(place.building.id) if (placeAccessibility != null) { val updatedImages = placeAccessibility.images.map { image -> @@ -105,7 +108,8 @@ class AccessibilityImageService( image } - placeAccessibilityRepository.updateImages(placeAccessibility.id, updatedImages) + placeAccessibility.updateImages(updatedImages) + placeAccessibilityRepository.save(placeAccessibility) } if (buildingAccessibility != null) { @@ -113,13 +117,15 @@ class AccessibilityImageService( findGeneratedThumbnailUrl(image.imageUrl, thumbnailUrls)?.let { image.thumbnailUrl = it } image } - buildingAccessibilityRepository.updateEntranceImages(buildingAccessibility.id, updatedEntranceImages) + buildingAccessibility.updateEntranceImages(updatedEntranceImages) val updatedElevatorImages = buildingAccessibility.elevatorImages.map { image -> findGeneratedThumbnailUrl(image.imageUrl, thumbnailUrls)?.let { image.thumbnailUrl = it } image } - buildingAccessibilityRepository.updateElevatorImages(buildingAccessibility.id, updatedElevatorImages) + buildingAccessibility.updateElevatorImages(updatedElevatorImages) + + buildingAccessibilityRepository.save(buildingAccessibility) } } } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeleteBuildingAccessibilityUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeleteBuildingAccessibilityUseCase.kt index 032fe846a..c4628d8dd 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeleteBuildingAccessibilityUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeleteBuildingAccessibilityUseCase.kt @@ -16,7 +16,7 @@ class AdminDeleteBuildingAccessibilityUseCase( fun handle( buildingAccessibilityId: String, ) : Unit = transactionManager.doInTransaction(TransactionIsolationLevel.SERIALIZABLE) { - val buildingAccessibility = buildingAccessibilityRepository.findById(buildingAccessibilityId) + val buildingAccessibility = buildingAccessibilityRepository.findById(buildingAccessibilityId).get() val building = buildingService.getById(buildingAccessibility.buildingId)!! deleteAccessibilityAplService.deleteBuildingAccessibility(buildingAccessibility, building) } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeletePlaceAccessibilityUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeletePlaceAccessibilityUseCase.kt index b48b83013..7f12842e3 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeletePlaceAccessibilityUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminDeletePlaceAccessibilityUseCase.kt @@ -16,7 +16,7 @@ class AdminDeletePlaceAccessibilityUseCase( fun handle( placeAccessibilityId: String, ) : Unit = transactionManager.doInTransaction(TransactionIsolationLevel.SERIALIZABLE) { - val placeAccessibility = placeAccessibilityRepository.findById(placeAccessibilityId) + val placeAccessibility = placeAccessibilityRepository.findById(placeAccessibilityId).get() val place = placeApplicationService.findPlace(placeAccessibility.placeId)!! deleteAccessibilityAplService.deletePlaceAccessibility(placeAccessibility, place) } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminSearchAccessibilitiesUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminSearchAccessibilitiesUseCase.kt index e5e04db15..2c753feb9 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminSearchAccessibilitiesUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/AdminSearchAccessibilitiesUseCase.kt @@ -56,7 +56,7 @@ class AdminSearchAccessibilitiesUseCase( val placeById = placeApplicationService.findAllByIds(placeAccessibilities.map { it.placeId }) .associateBy { it.id } val buildingAccessibilityByBuildingId = buildingAccessibilityRepository - .findByBuildingIds(placeById.values.map { it.building.id }) + .findByBuildingIdInAndDeletedAtIsNull(placeById.values.map { it.building.id }) .associateBy { it.buildingId } val userById = userAplService.getUsers( userIds = placeAccessibilities.mapNotNull { it.userId } + diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCase.kt index 4162f4df1..0ff6af9dd 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestBuildingAccessibilityImagesUseCase.kt @@ -10,6 +10,7 @@ import club.staircrusher.stdlib.di.annotation.Component import club.staircrusher.stdlib.domain.entity.EntityIdGenerator import club.staircrusher.stdlib.persistence.TransactionManager import kotlinx.coroutines.runBlocking +import org.springframework.data.repository.findByIdOrNull import java.time.Instant import java.util.concurrent.Executors @@ -30,11 +31,11 @@ class BlurFacesInLatestBuildingAccessibilityImagesUseCase( fun handle() { val targetAccessibility: BuildingAccessibility = transactionManager.doInTransaction { - val latestHistory = accessibilityImageFaceBlurringHistoryRepository.findLatestBuildingHistoryOrNull() + val latestHistory = accessibilityImageFaceBlurringHistoryRepository.findFirstByBuildingAccessibilityIdIsNotNullOrderByCreatedAtDesc() val lastBlurredBuildingAccessibility = latestHistory?.let { history -> history.buildingAccessibilityId?.let { buildingAccessibilityRepository.findByIdOrNull(it) } } - buildingAccessibilityRepository.findOneOrNullByCreatedAtGreaterThanAndOrderByCreatedAtAsc( + buildingAccessibilityRepository.findBlurringTargetAccessibility( createdAt = lastBlurredBuildingAccessibility?.createdAt ?: Instant.EPOCH ) } ?: return @@ -44,17 +45,12 @@ class BlurFacesInLatestBuildingAccessibilityImagesUseCase( val elevatorResults = result.elevatorResults val entranceImageUrls = entranceResults.map { it.blurredImageUrl } - buildingAccessibilityRepository.updateEntranceImageUrlsAndImages( - targetAccessibility.id, - entranceImageUrls, - entranceImageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } - ) + targetAccessibility.updateEntranceImages(entranceImageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) }) + val elevatorImageUrls = elevatorResults.map { it.blurredImageUrl } - buildingAccessibilityRepository.updateElevatorImageUrlsAndImages( - targetAccessibility.id, - elevatorImageUrls, - elevatorImageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } - ) + targetAccessibility.updateElevatorImages(elevatorImageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) }) + + buildingAccessibilityRepository.save(targetAccessibility) val originalImageUrls = (entranceResults + elevatorResults).map { it.originalImageUrl } val blurredImageUrls = (entranceResults + elevatorResults).filter { it.isBlurred() }.map { it.blurredImageUrl } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCase.kt index 06df2907a..842891f6d 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BlurFacesInLatestPlaceAccessibilityImagesUseCase.kt @@ -10,6 +10,7 @@ import club.staircrusher.stdlib.di.annotation.Component import club.staircrusher.stdlib.domain.entity.EntityIdGenerator import club.staircrusher.stdlib.persistence.TransactionManager import kotlinx.coroutines.runBlocking +import org.springframework.data.repository.findByIdOrNull import java.time.Instant import java.util.concurrent.Executors @@ -30,11 +31,11 @@ class BlurFacesInLatestPlaceAccessibilityImagesUseCase( fun handle() { val targetAccessibility: PlaceAccessibility = transactionManager.doInTransaction { - val latestHistory = accessibilityImageFaceBlurringHistoryRepository.findLatestPlaceHistoryOrNull() + val latestHistory = accessibilityImageFaceBlurringHistoryRepository.findFirstByPlaceAccessibilityIdIsNotNullOrderByCreatedAtDesc() val lastBlurredPlaceAccessibility = latestHistory?.let { history -> history.placeAccessibilityId?.let { placeAccessibilityRepository.findByIdOrNull(it) } } - placeAccessibilityRepository.findOneOrNullByCreatedAtGreaterThanAndOrderByCreatedAtAsc( + placeAccessibilityRepository.findBlurringTargetAccessibility( createdAt = lastBlurredPlaceAccessibility?.createdAt ?: Instant.EPOCH ) } ?: return @@ -44,11 +45,8 @@ class BlurFacesInLatestPlaceAccessibilityImagesUseCase( val entranceResults = result.entranceResults transactionManager.doInTransaction { val imageUrls = entranceResults.map { it.blurredImageUrl } - placeAccessibilityRepository.updateImageUrlsAndImages( - targetAccessibility.id, - imageUrls, - imageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } - ) + targetAccessibility.updateImages(imageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) }) + placeAccessibilityRepository.save(targetAccessibility) accessibilityImageFaceBlurringHistoryRepository.save( AccessibilityImageFaceBlurringHistory( id = EntityIdGenerator.generateRandom(), diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BuildingAccessibilityUpvoteApplicationService.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BuildingAccessibilityUpvoteApplicationService.kt index 1bb9176c8..ee35288c9 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BuildingAccessibilityUpvoteApplicationService.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/BuildingAccessibilityUpvoteApplicationService.kt @@ -8,6 +8,7 @@ import club.staircrusher.stdlib.di.annotation.Component import club.staircrusher.stdlib.domain.entity.EntityIdGenerator import club.staircrusher.stdlib.persistence.TransactionIsolationLevel import club.staircrusher.stdlib.persistence.TransactionManager +import org.springframework.data.repository.findByIdOrNull import java.time.Clock @Component @@ -30,7 +31,7 @@ class BuildingAccessibilityUpvoteApplicationService( BuildingAccessibilityUpvote( id = EntityIdGenerator.generateRandom(), userId = user.id, - buildingAccessibility = it, + buildingAccessibilityId = it.id, createdAt = clock.instant(), ) ) diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/CancelPlaceAccessibilityUpvoteUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/CancelPlaceAccessibilityUpvoteUseCase.kt index a44689909..0182ee35b 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/CancelPlaceAccessibilityUpvoteUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/CancelPlaceAccessibilityUpvoteUseCase.kt @@ -18,7 +18,7 @@ class CancelPlaceAccessibilityUpvoteUseCase( placeAccessibilityId: String, ) = transactionManager.doInTransaction(TransactionIsolationLevel.REPEATABLE_READ) { val upvote = - placeAccessibilityUpvoteRepository.findUpvote(user.id, placeAccessibilityId) ?: return@doInTransaction + placeAccessibilityUpvoteRepository.findExistingUpvote(user.id, placeAccessibilityId) ?: return@doInTransaction upvote.cancel(clock.instant()) placeAccessibilityUpvoteRepository.save(upvote) } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityAplService.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityAplService.kt index b02066c7c..b937950c3 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityAplService.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityAplService.kt @@ -50,7 +50,7 @@ class DeleteAccessibilityAplService( placeAccessibility: PlaceAccessibility, place: Place, ) { - placeAccessibilityRepository.remove(placeAccessibility.id) + placeAccessibilityRepository.deleteById(placeAccessibility.id) transactionManager.doAfterCommit { runBlocking { domainEventPublisher.publishEvent(PlaceAccessibilityDeletedEvent( @@ -86,7 +86,7 @@ class DeleteAccessibilityAplService( buildingAccessibility: BuildingAccessibility, building: Building, ) { - buildingAccessibilityRepository.remove(buildingAccessibility.id) + buildingAccessibilityRepository.deleteById(buildingAccessibility.id) transactionManager.doAfterCommit { runBlocking { domainEventPublisher.publishEvent(BuildingAccessibilityDeletedEvent( diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityUseCase.kt index b42bf2b86..c9ca55d01 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/DeleteAccessibilityUseCase.kt @@ -20,7 +20,7 @@ class DeleteAccessibilityUseCase( userId: String, placeAccessibilityId: String, ) : Unit = transactionManager.doInTransaction(TransactionIsolationLevel.SERIALIZABLE) { - val placeAccessibility = placeAccessibilityRepository.findById(placeAccessibilityId) + val placeAccessibility = placeAccessibilityRepository.findById(placeAccessibilityId).get() if (!placeAccessibility.isDeletable(userId)) { throw SccDomainException("삭제 가능한 장소 정보가 아닙니다.") } @@ -29,8 +29,11 @@ class DeleteAccessibilityUseCase( deleteAccessibilityAplService.deletePlaceAccessibility(placeAccessibility, place) val building = place.building - if (placeAccessibilityRepository.findByBuildingId(building.id).isEmpty()) { - val buildingAccessibility = buildingAccessibilityRepository.findByBuildingId(building.id) ?: return@doInTransaction + val placeIds = placeApplicationService.findByBuildingId(building.id) + .map { it.id } + .toSet() + if (placeAccessibilityRepository.findByPlaceIdInAndDeletedAtIsNull(placeIds).isEmpty()) { + val buildingAccessibility = buildingAccessibilityRepository.findFirstByBuildingIdAndDeletedAtIsNull(building.id) ?: return@doInTransaction deleteAccessibilityAplService.deleteBuildingAccessibility(buildingAccessibility, building) } } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetCountForNextRankUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetCountForNextRankUseCase.kt index 8ca17729f..34ec8b149 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetCountForNextRankUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetCountForNextRankUseCase.kt @@ -11,8 +11,8 @@ class GetCountForNextRankUseCase( private val transactionManager: TransactionManager, ) { fun handle(userId: String): Int = transactionManager.doInTransaction { - val currentRank = accessibilityRankRepository.findByUserId(userId) ?: throw SccDomainException("잘못된 계정입니다.") - val rank = currentRank.rank ?: accessibilityRankRepository.findByConqueredCount(currentRank.conqueredCount)?.rank!! + val currentRank = accessibilityRankRepository.findFirstByUserId(userId) ?: throw SccDomainException("잘못된 계정입니다.") + val rank = currentRank.rank if (rank == 1L) { 0 diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetRankUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetRankUseCase.kt index 2da24fbc3..aab5bfa7d 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetRankUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GetRankUseCase.kt @@ -18,9 +18,9 @@ class GetRankUseCase( fun handle(userId: String): WithUserInfo { val now = SccClock.instant() val user = userApplicationService.getUser(userId) ?: throw SccDomainException("잘못된 계정입니다.") - val accessibilityRank = accessibilityRankRepository.findByUserId(userId) ?: run { + val accessibilityRank = accessibilityRankRepository.findFirstByUserId(userId) ?: run { // if lastRank can not be found, then the user is the first rank - val lastRank = accessibilityRankRepository.findByConqueredCount(0)?.rank ?: 1 + val lastRank = accessibilityRankRepository.findRankByConqueredCount(0) ?: 1 AccessibilityRank( id = UUID.randomUUID().toString(), userId = user.id, diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GivePlaceAccessibilityUpvoteUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GivePlaceAccessibilityUpvoteUseCase.kt index 1c832e9a1..fc6e46fd1 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GivePlaceAccessibilityUpvoteUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/GivePlaceAccessibilityUpvoteUseCase.kt @@ -8,6 +8,7 @@ import club.staircrusher.stdlib.di.annotation.Component import club.staircrusher.stdlib.domain.entity.EntityIdGenerator import club.staircrusher.stdlib.persistence.TransactionIsolationLevel import club.staircrusher.stdlib.persistence.TransactionManager +import org.springframework.data.repository.findByIdOrNull import java.time.Clock @Component @@ -23,7 +24,7 @@ class GivePlaceAccessibilityUpvoteUseCase( ) = transactionManager.doInTransaction(TransactionIsolationLevel.REPEATABLE_READ) { placeAccessibilityRepository.findByIdOrNull(placeAccessibilityId) ?: throw IllegalArgumentException("PlaceAccessibility of id $placeAccessibilityId does not exist.") - val existingUpvote = placeAccessibilityUpvoteRepository.findUpvote(user.id, placeAccessibilityId) + val existingUpvote = placeAccessibilityUpvoteRepository.findExistingUpvote(user.id, placeAccessibilityId) existingUpvote ?: placeAccessibilityUpvoteRepository.save( PlaceAccessibilityUpvote( id = EntityIdGenerator.generateRandom(), diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/UpdateRanksUseCase.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/UpdateRanksUseCase.kt index 5c96cbed8..49ad5da45 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/UpdateRanksUseCase.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/in/UpdateRanksUseCase.kt @@ -24,12 +24,12 @@ class UpdateRanksUseCase( // update accessibility rank with count first transactionManager.doInTransaction { val users: List = userApplicationService.getAllUsers() - val lastRank = accessibilityRankRepository.findByConqueredCount(0)?.rank ?: 1 + val lastRank = accessibilityRankRepository.findRankByConqueredCount(0) ?: 1 val now = SccClock.instant() val ranks = users.map { - val conqueredCount = placeAccessibilityRepository.countByUserId(it.id) - val accessibilityRank = accessibilityRankRepository.findByUserId(it.id) ?: AccessibilityRank( + val conqueredCount = placeAccessibilityRepository.countByUserIdAndDeletedAtIsNull(it.id) + val accessibilityRank = accessibilityRankRepository.findFirstByUserId(it.id) ?: AccessibilityRank( id = EntityIdGenerator.generateRandom(), userId = it.id, conqueredCount = conqueredCount, @@ -37,11 +37,9 @@ class UpdateRanksUseCase( createdAt = now, updatedAt = now, ) + accessibilityRank.updateConqueredCount(conqueredCount) - accessibilityRankRepository.save(accessibilityRank.copy( - conqueredCount = conqueredCount, - updatedAt = now, - )) + accessibilityRankRepository.save(accessibilityRank) } var previousRank = 0L @@ -53,18 +51,18 @@ class UpdateRanksUseCase( .toSortedMap(compareByDescending { it }) countPerConqueredCount.forEach { (conqueredCount, ranks) -> - val updatedRanks = if (conqueredCount != currentConqueredCount) { + if (conqueredCount != currentConqueredCount) { previousRank = currentRank - ranks.map { it.copy(rank = currentRank, updatedAt = now) } + ranks.forEach { it.updateRank(rank = currentRank) } } else { // If the last conquest count in the previous batch is the same as the conquest // count in the current batch, then they should have the same rank. currentRank += ranks.size - ranks.map { it.copy(rank = previousRank, updatedAt = now) } + ranks.forEach { it.updateRank(rank = previousRank) } } currentRank += ranks.size currentConqueredCount = conqueredCount - accessibilityRankRepository.saveAll(updatedRanks) + accessibilityRankRepository.saveAll(ranks) } } } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityAllowedRegionRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityAllowedRegionRepository.kt index 302f3e2fa..513f96604 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityAllowedRegionRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityAllowedRegionRepository.kt @@ -1,9 +1,6 @@ package club.staircrusher.accessibility.application.port.out.persistence import club.staircrusher.accessibility.domain.model.AccessibilityAllowedRegion -import club.staircrusher.stdlib.domain.repository.EntityRepository +import org.springframework.data.repository.CrudRepository -interface AccessibilityAllowedRegionRepository : EntityRepository { - fun findAll(): List - fun remove(id: String) -} +interface AccessibilityAllowedRegionRepository : CrudRepository diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt index bc6d30da3..c3e9d030b 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt @@ -1,13 +1,11 @@ package club.staircrusher.accessibility.application.port.out.persistence import club.staircrusher.accessibility.domain.model.AccessibilityImageFaceBlurringHistory -import club.staircrusher.stdlib.domain.repository.EntityRepository +import org.springframework.data.repository.CrudRepository -interface AccessibilityImageFaceBlurringHistoryRepository : - EntityRepository { - fun findLatestPlaceHistoryOrNull(): AccessibilityImageFaceBlurringHistory? - fun findLatestBuildingHistoryOrNull(): AccessibilityImageFaceBlurringHistory? +interface AccessibilityImageFaceBlurringHistoryRepository : CrudRepository { + fun findFirstByPlaceAccessibilityIdIsNotNullOrderByCreatedAtDesc(): AccessibilityImageFaceBlurringHistory? + fun findFirstByBuildingAccessibilityIdIsNotNullOrderByCreatedAtDesc(): AccessibilityImageFaceBlurringHistory? fun findByPlaceAccessibilityId(placeAccessibilityId: String): List fun findByBuildingAccessibilityId(buildingAccessibilityId: String): List - fun findAll(): List } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityRankRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityRankRepository.kt index f3a700ccf..4ad402731 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityRankRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/AccessibilityRankRepository.kt @@ -1,13 +1,31 @@ package club.staircrusher.accessibility.application.port.out.persistence import club.staircrusher.accessibility.domain.model.AccessibilityRank -import club.staircrusher.stdlib.domain.repository.EntityRepository +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.CrudRepository -interface AccessibilityRankRepository: EntityRepository { +interface AccessibilityRankRepository: CrudRepository { + @Query(""" + SELECT r + FROM AccessibilityRank r + ORDER BY r.rank ASC + LIMIT :n + """) fun findTopNUsers(n: Int): List - fun findByUserId(userId: String): AccessibilityRank? - fun findByRank(rank: Long): AccessibilityRank? + fun findFirstByUserId(userId: String): AccessibilityRank? + @Query(""" + SELECT r + FROM AccessibilityRank r + WHERE r.rank < :rank + ORDER BY r.rank DESC + LIMIT 1 + """) fun findNextRank(rank: Long): AccessibilityRank? - fun findByConqueredCount(conqueredCount: Int): AccessibilityRank? - fun findAll(): List + @Query(""" + SELECT rank + FROM accessibility_rank r + WHERE conquered_count = :conqueredCount + LIMIT 1 + """, nativeQuery = true) + fun findRankByConqueredCount(conqueredCount: Int): Long? } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityCommentRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityCommentRepository.kt index 1392fc4e3..21439e8c2 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityCommentRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityCommentRepository.kt @@ -1,12 +1,13 @@ package club.staircrusher.accessibility.application.port.out.persistence import club.staircrusher.accessibility.domain.model.BuildingAccessibilityComment -import club.staircrusher.stdlib.domain.repository.EntityRepository +import org.springframework.data.repository.CrudRepository -interface BuildingAccessibilityCommentRepository : EntityRepository { +interface BuildingAccessibilityCommentRepository : CrudRepository { fun findByBuildingId(buildingId: String): List fun removeByBuildingId(buildingId: String) + data class CreateParams( val buildingId: String, val userId: String?, diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityRepository.kt index 733a76f53..711dcb1cf 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityRepository.kt @@ -1,29 +1,28 @@ package club.staircrusher.accessibility.application.port.out.persistence -import club.staircrusher.accessibility.domain.model.AccessibilityImage import club.staircrusher.accessibility.domain.model.BuildingAccessibility import club.staircrusher.accessibility.domain.model.EntranceDoorType import club.staircrusher.accessibility.domain.model.StairHeightLevel import club.staircrusher.accessibility.domain.model.StairInfo -import club.staircrusher.stdlib.domain.repository.EntityRepository -import club.staircrusher.stdlib.geography.EupMyeonDong +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.CrudRepository import java.time.Instant -interface BuildingAccessibilityRepository : EntityRepository { - fun findByBuildingIds(buildingIds: Collection): List - fun findByBuildingId(buildingId: String): BuildingAccessibility? - fun findByPlaceIds(placeIds: Collection): List - fun findByUserIdAndCreatedAtBetween(userId: String, from: Instant, to: Instant): List - fun findByEupMyeonDong(eupMyeonDong: EupMyeonDong): List - fun findOneOrNullByCreatedAtGreaterThanAndOrderByCreatedAtAsc(createdAt: Instant): BuildingAccessibility? - fun findAll(): List - fun countByUserIdCreatedAtBetween(userId: String, from: Instant, to: Instant): Int - fun updateEntranceImages(id: String, entranceImages: List) - fun updateEntranceImageUrlsAndImages(id: String, urls: List, images: List) - fun updateElevatorImages(id: String, elevatorImages: List) - fun updateElevatorImageUrlsAndImages(id: String, urls: List, images: List) - fun countByUserId(userId: String): Int - fun remove(id: String) +interface BuildingAccessibilityRepository : CrudRepository { + fun findByBuildingIdInAndDeletedAtIsNull(buildingIds: Collection): List + fun findFirstByBuildingIdAndDeletedAtIsNull(buildingId: String): BuildingAccessibility? + fun findByUserIdAndCreatedAtBetweenAndDeletedAtIsNull(userId: String, from: Instant, to: Instant): List + @Query(""" + SELECT ba + FROM BuildingAccessibility ba + WHERE + ba.createdAt > :createdAt + AND ba.deletedAt IS NULL + ORDER BY ba.createdAt ASC, ba.id DESC + LIMIT 1 + """) + fun findBlurringTargetAccessibility(createdAt: Instant): BuildingAccessibility? + fun countByUserIdAndCreatedAtBetweenAndDeletedAtIsNull(userId: String, from: Instant, to: Instant): Int data class CreateParams( val buildingId: String, diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityUpvoteRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityUpvoteRepository.kt index b01c68f47..0e55f8468 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityUpvoteRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/BuildingAccessibilityUpvoteRepository.kt @@ -1,9 +1,18 @@ package club.staircrusher.accessibility.application.port.out.persistence import club.staircrusher.accessibility.domain.model.BuildingAccessibilityUpvote -import club.staircrusher.stdlib.domain.repository.EntityRepository +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.CrudRepository -interface BuildingAccessibilityUpvoteRepository : EntityRepository { +interface BuildingAccessibilityUpvoteRepository : CrudRepository { + @Query(""" + SELECT bau + FROM BuildingAccessibilityUpvote bau + WHERE + bau.userId = :userId + AND bau.buildingAccessibilityId = :buildingAccessibilityId + AND bau.deletedAt IS NULL + """) fun findExistingUpvote(userId: String, buildingAccessibilityId: String): BuildingAccessibilityUpvote? - fun countUpvotes(buildingAccessibilityId: String): Int + fun countByBuildingAccessibilityId(buildingAccessibilityId: String): Int } diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityCommentRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityCommentRepository.kt index 68121b742..73f141c76 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityCommentRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityCommentRepository.kt @@ -1,9 +1,9 @@ package club.staircrusher.accessibility.application.port.out.persistence import club.staircrusher.accessibility.domain.model.PlaceAccessibilityComment -import club.staircrusher.stdlib.domain.repository.EntityRepository +import org.springframework.data.repository.CrudRepository -interface PlaceAccessibilityCommentRepository : EntityRepository { +interface PlaceAccessibilityCommentRepository : CrudRepository { fun findByPlaceId(placeId: String): List fun removeByPlaceId(placeId: String) data class CreateParams( diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityRepository.kt index 4c5ad49a4..10d40c675 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityRepository.kt @@ -1,26 +1,47 @@ package club.staircrusher.accessibility.application.port.out.persistence -import club.staircrusher.accessibility.domain.model.AccessibilityImage import club.staircrusher.accessibility.domain.model.EntranceDoorType import club.staircrusher.accessibility.domain.model.PlaceAccessibility import club.staircrusher.accessibility.domain.model.StairHeightLevel import club.staircrusher.accessibility.domain.model.StairInfo -import club.staircrusher.stdlib.domain.repository.EntityRepository -import club.staircrusher.stdlib.geography.EupMyeonDong +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.CrudRepository import java.time.Instant @Suppress("TooManyFunctions") -interface PlaceAccessibilityRepository : EntityRepository { - fun findByPlaceIds(placeIds: Collection): List - fun findByPlaceId(placeId: String): PlaceAccessibility? - fun findByUserId(userId: String): List - fun findByUserIdAndCreatedAtBetween(userId: String, from: Instant, to: Instant): List - fun findByBuildingId(buildingId: String): List - fun findOneOrNullByCreatedAtGreaterThanAndOrderByCreatedAtAsc(createdAt: Instant): PlaceAccessibility? - fun countByEupMyeonDong(eupMyeonDong: EupMyeonDong): Int - fun countByUserId(userId: String): Int - fun countByUserIdAndCreatedAtBetween(userId: String, from: Instant, to: Instant): Int - fun hasAccessibilityNotRegisteredPlaceInBuilding(buildingId: String): Boolean +interface PlaceAccessibilityRepository : CrudRepository { + fun findByPlaceIdInAndDeletedAtIsNull(placeIds: Collection): List + fun findFirstByPlaceIdAndDeletedAtIsNull(placeId: String): PlaceAccessibility? + fun findByUserIdAndDeletedAtIsNull(userId: String): List + fun findByUserIdAndCreatedAtBetweenAndDeletedAtIsNull(userId: String, from: Instant, to: Instant): List + @Query(""" + SELECT pa + FROM PlaceAccessibility pa + WHERE + pa.createdAt > :createdAt + AND pa.deletedAt IS NULL + ORDER BY pa.createdAt ASC, pa.id DESC + LIMIT 1 + """) + fun findBlurringTargetAccessibility(createdAt: Instant): PlaceAccessibility? + fun countByUserIdAndDeletedAtIsNull(userId: String): Int + fun countByUserIdAndCreatedAtBetweenAndDeletedAtIsNull(userId: String, from: Instant, to: Instant): Int + @Query(""" + SELECT pa.* + FROM place_accessibility pa + INNER JOIN place p ON p.id = pa.place_id + WHERE + (:placeNameLike IS NULL OR p.name LIKE :placeNameLike) + AND (:createdAtFrom IS NULL OR pa.created_at >= :createdAtFrom) + AND (:createdAtToExclusive IS NULL OR pa.created_at < :createdAtToExclusive) + AND ( + (pa.created_at = :cursorCreatedAt AND pa.id < :cursorId) + OR (pa.created_at < :cursorCreatedAt) + ) + AND pa.deleted_at IS NULL + ORDER BY pa.created_at DESC, pa.id DESC + LIMIT :limit; + """, nativeQuery = true) fun searchForAdmin( placeName: String?, createdAtFrom: Instant?, @@ -30,10 +51,7 @@ interface PlaceAccessibilityRepository : EntityRepository - fun updateImages(id: String, images: List) - fun updateImageUrlsAndImages(id: String, imageUrls: List, images: List) - fun countAll(): Int - fun remove(id: String) + fun countBy(): Int data class CreateParams( val placeId: String, diff --git a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityUpvoteRepository.kt b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityUpvoteRepository.kt index 1b829efaf..11e94e6f0 100644 --- a/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityUpvoteRepository.kt +++ b/app-server/subprojects/bounded_context/accessibility/application/src/main/kotlin/club/staircrusher/accessibility/application/port/out/persistence/PlaceAccessibilityUpvoteRepository.kt @@ -1,9 +1,17 @@ package club.staircrusher.accessibility.application.port.out.persistence import club.staircrusher.accessibility.domain.model.PlaceAccessibilityUpvote -import club.staircrusher.stdlib.domain.repository.EntityRepository +import org.springframework.data.jpa.repository.Query +import org.springframework.data.repository.CrudRepository -interface PlaceAccessibilityUpvoteRepository : EntityRepository { - fun findUpvote(userId: String, placeAccessibilityId: String): PlaceAccessibilityUpvote? - fun countUpvotes(placeAccessibilityId: String): Int +interface PlaceAccessibilityUpvoteRepository : CrudRepository { + @Query(""" + SELECT pau + FROM PlaceAccessibilityUpvote pau + WHERE + pau.userId = :userId + AND pau.placeAccessibilityId = :placeAccessibilityId + AND pau.deletedAt IS NULL + """) + fun findExistingUpvote(userId: String, placeAccessibilityId: String): PlaceAccessibilityUpvote? } diff --git a/app-server/subprojects/bounded_context/accessibility/domain/build.gradle.kts b/app-server/subprojects/bounded_context/accessibility/domain/build.gradle.kts index cf4b46bf9..1788e68ad 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/build.gradle.kts +++ b/app-server/subprojects/bounded_context/accessibility/domain/build.gradle.kts @@ -1,4 +1,7 @@ dependencies { + val jacksonModuleKotlinVersion: String by project + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + val jUnitJupiterVersion: String by project testImplementation("org.junit.jupiter:junit-jupiter-api:$jUnitJupiterVersion") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jUnitJupiterVersion") diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityAllowedRegion.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityAllowedRegion.kt index 3b40b2f9b..a17603d7e 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityAllowedRegion.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityAllowedRegion.kt @@ -3,11 +3,18 @@ package club.staircrusher.accessibility.domain.model import club.staircrusher.stdlib.clock.SccClock import club.staircrusher.stdlib.domain.entity.EntityIdGenerator import club.staircrusher.stdlib.geography.Location +import club.staircrusher.stdlib.jpa.LocationListToTextAttributeConverter +import jakarta.persistence.Convert +import jakarta.persistence.Entity +import jakarta.persistence.Id import java.time.Instant +@Entity class AccessibilityAllowedRegion( + @Id val id: String, val name: String, + @Convert(converter = LocationListToTextAttributeConverter::class) val boundaryVertices: List, val createdAt: Instant = SccClock.instant(), updatedAt: Instant = createdAt, @@ -26,10 +33,20 @@ class AccessibilityAllowedRegion( private set override fun equals(other: Any?): Boolean { - return other is AccessibilityAllowedRegion && other.id == id + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as AccessibilityAllowedRegion + + return id == other.id } override fun hashCode(): Int { return id.hashCode() } + + override fun toString(): String { + return "AccessibilityAllowedRegion(id='$id', name='$name', boundaryVertices=$boundaryVertices, " + + "createdAt=$createdAt, updatedAt=$updatedAt)" + } } diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImage.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImage.kt index b65db67e4..8ff205068 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImage.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImage.kt @@ -1,5 +1,8 @@ package club.staircrusher.accessibility.domain.model +import jakarta.persistence.Embeddable + +@Embeddable data class AccessibilityImage( val imageUrl: String, var thumbnailUrl: String? = null, diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageFaceBlurringHistory.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageFaceBlurringHistory.kt index 18dfaed4c..8c5315d52 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageFaceBlurringHistory.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageFaceBlurringHistory.kt @@ -1,14 +1,46 @@ package club.staircrusher.accessibility.domain.model +import club.staircrusher.stdlib.jpa.IntListToTextAttributeConverter +import club.staircrusher.stdlib.jpa.StringListToTextAttributeConverter +import jakarta.persistence.Convert +import jakarta.persistence.Entity +import jakarta.persistence.Id import java.time.Instant -data class AccessibilityImageFaceBlurringHistory( +@Entity +class AccessibilityImageFaceBlurringHistory( + @Id val id: String, val placeAccessibilityId: String?, val buildingAccessibilityId: String?, + @Convert(converter = StringListToTextAttributeConverter::class) val originalImageUrls: List, + @Convert(converter = StringListToTextAttributeConverter::class) val blurredImageUrls: List, + @Convert(converter = IntListToTextAttributeConverter::class) val detectedPeopleCounts: List, val createdAt: Instant, val updatedAt: Instant -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as AccessibilityImageFaceBlurringHistory + + return id == other.id + } + + override fun hashCode(): Int { + return id.hashCode() + } + + override fun toString(): String { + return "AccessibilityImageFaceBlurringHistory(id='$id', placeAccessibilityId=$placeAccessibilityId, " + + "buildingAccessibilityId=$buildingAccessibilityId, originalImageUrls=$originalImageUrls, " + + "blurredImageUrls=$blurredImageUrls, detectedPeopleCounts=$detectedPeopleCounts, createdAt=$createdAt, " + + "updatedAt=$updatedAt)" + } + + +} diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageListToTextAttributeConverter.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageListToTextAttributeConverter.kt new file mode 100644 index 000000000..3c048d197 --- /dev/null +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityImageListToTextAttributeConverter.kt @@ -0,0 +1,26 @@ +package club.staircrusher.accessibility.domain.model + +import club.staircrusher.stdlib.jpa.ListToTextAttributeConverter +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.SerializationFeature +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import jakarta.persistence.Converter + +@Converter +object AccessibilityImageListToTextAttributeConverter : ListToTextAttributeConverter() { + override fun convertElementToTextColumn(element: AccessibilityImage): String { + return objectMapper.writeValueAsString(element) + } + + override fun convertElementFromTextColumn(text: String): AccessibilityImage { + return objectMapper.readValue(text) + } + + private val objectMapper = jacksonObjectMapper() + .findAndRegisterModules() + .setSerializationInclusion(JsonInclude.Include.NON_ABSENT) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) +} diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityRank.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityRank.kt index 5c76cabf9..a91fac1ff 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityRank.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityRank.kt @@ -1,12 +1,36 @@ package club.staircrusher.accessibility.domain.model +import club.staircrusher.stdlib.clock.SccClock +import jakarta.persistence.Entity +import jakarta.persistence.Id import java.time.Instant -data class AccessibilityRank( +@Entity +class AccessibilityRank( + @Id val id: String, val userId: String, - val conqueredCount: Int, - val rank: Long, + conqueredCount: Int, + rank: Long, val createdAt: Instant, - val updatedAt: Instant, -) + updatedAt: Instant, +) { + var conqueredCount: Int = conqueredCount + protected set + + var rank: Long = rank + protected set + + var updatedAt: Instant = updatedAt + protected set + + fun updateConqueredCount(conqueredCount: Int) { + this.conqueredCount = conqueredCount + updatedAt = SccClock.instant() + } + + fun updateRank(rank: Long) { + this.rank = rank + updatedAt = SccClock.instant() + } +} diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibility.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibility.kt index d2e2c2342..0491588af 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibility.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibility.kt @@ -1,24 +1,85 @@ package club.staircrusher.accessibility.domain.model +import club.staircrusher.stdlib.jpa.StringListToTextAttributeConverter +import jakarta.persistence.Convert +import jakarta.persistence.Entity +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated +import jakarta.persistence.Id import java.time.Instant -data class BuildingAccessibility( +@Entity +class BuildingAccessibility( + @Id val id: String, val buildingId: String, + @Enumerated(EnumType.STRING) val entranceStairInfo: StairInfo, + @Enumerated(EnumType.STRING) val entranceStairHeightLevel: StairHeightLevel?, - @Deprecated("use images with type instead") - val entranceImageUrls: List, - val entranceImages: List, + entranceImageUrls: List, + entranceImages: List, val hasSlope: Boolean, val hasElevator: Boolean, + @Convert(converter = EntranceDoorTypeListToTextAttributeConverter::class) val entranceDoorTypes: List?, + @Enumerated(EnumType.STRING) val elevatorStairInfo: StairInfo, + @Enumerated(EnumType.STRING) val elevatorStairHeightLevel: StairHeightLevel?, - @Deprecated("use images with type instead") - val elevatorImageUrls: List, - val elevatorImages: List, + elevatorImageUrls: List, + elevatorImages: List, val userId: String?, val createdAt: Instant, val deletedAt: Instant? = null, -) +) { + @Convert(converter = AccessibilityImageListToTextAttributeConverter::class) + var entranceImages: List = entranceImages + protected set + + @Deprecated("use images with type instead") + @Convert(converter = StringListToTextAttributeConverter::class) + var entranceImageUrls: List = entranceImageUrls + protected set + + @Convert(converter = AccessibilityImageListToTextAttributeConverter::class) + var elevatorImages: List = elevatorImages + protected set + + @Deprecated("use images with type instead") + @Convert(converter = StringListToTextAttributeConverter::class) + var elevatorImageUrls: List = elevatorImageUrls + protected set + + fun updateEntranceImages(images: List) { + this.entranceImages = images + this.entranceImageUrls = images.map { it.imageUrl } + } + + fun updateElevatorImages(images: List) { + this.elevatorImages = images + this.elevatorImageUrls = images.map { it.imageUrl } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as BuildingAccessibility + + return id == other.id + } + + override fun hashCode(): Int { + return id.hashCode() + } + + override fun toString(): String { + return "BuildingAccessibility(id='$id', buildingId='$buildingId', entranceStairInfo=$entranceStairInfo, " + + "entranceStairHeightLevel=$entranceStairHeightLevel, entranceImageUrls=$entranceImageUrls, " + + "entranceImages=$entranceImages, hasSlope=$hasSlope, hasElevator=$hasElevator, " + + "entranceDoorTypes=$entranceDoorTypes, elevatorStairInfo=$elevatorStairInfo, " + + "elevatorStairHeightLevel=$elevatorStairHeightLevel, elevatorImageUrls=$elevatorImageUrls, " + + "elevatorImages=$elevatorImages, userId=$userId, createdAt=$createdAt, deletedAt=$deletedAt)" + } +} diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityComment.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityComment.kt index c200c7e1f..d26bcaf17 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityComment.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityComment.kt @@ -1,12 +1,34 @@ package club.staircrusher.accessibility.domain.model +import jakarta.persistence.Entity +import jakarta.persistence.Id import java.time.Instant -data class BuildingAccessibilityComment( +@Entity +class BuildingAccessibilityComment( + @Id val id: String, val buildingId: String, val userId: String?, val comment: String, val createdAt: Instant, val deletedAt: Instant? = null, -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as BuildingAccessibilityComment + + return id == other.id + } + + override fun hashCode(): Int { + return id.hashCode() + } + + override fun toString(): String { + return "BuildingAccessibilityComment(id='$id', buildingId='$buildingId', userId=$userId, comment='$comment', " + + "createdAt=$createdAt, deletedAt=$deletedAt)" + } +} diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityUpvote.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityUpvote.kt index 471bfcc31..b33a95198 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityUpvote.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/BuildingAccessibilityUpvote.kt @@ -1,23 +1,37 @@ package club.staircrusher.accessibility.domain.model +import jakarta.persistence.Entity +import jakarta.persistence.Id import java.time.Instant +@Entity class BuildingAccessibilityUpvote( + @Id val id: String, val userId: String, - val buildingAccessibility: BuildingAccessibility, + val buildingAccessibilityId: String, var createdAt: Instant, var deletedAt: Instant? = null, ) { - override fun hashCode(): Int { - return id.hashCode() + fun cancel(now: Instant) { + deletedAt = now } override fun equals(other: Any?): Boolean { - return other is BuildingAccessibilityUpvote && other.id == id + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as BuildingAccessibilityUpvote + + return id == other.id } - fun cancel(now: Instant) { - deletedAt = now + override fun hashCode(): Int { + return id.hashCode() + } + + override fun toString(): String { + return "BuildingAccessibilityUpvote(id='$id', userId='$userId', " + + "buildingAccessibilityId='$buildingAccessibilityId', createdAt=$createdAt, deletedAt=$deletedAt)" } } diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/EntranceDoorTypeListToTextAttributeConverter.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/EntranceDoorTypeListToTextAttributeConverter.kt new file mode 100644 index 000000000..e69cce420 --- /dev/null +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/EntranceDoorTypeListToTextAttributeConverter.kt @@ -0,0 +1,15 @@ +package club.staircrusher.accessibility.domain.model + +import club.staircrusher.stdlib.jpa.ListToTextAttributeConverter +import jakarta.persistence.Converter + +@Converter +object EntranceDoorTypeListToTextAttributeConverter : ListToTextAttributeConverter() { + override fun convertElementToTextColumn(element: EntranceDoorType): String { + return element.name + } + + override fun convertElementFromTextColumn(text: String): EntranceDoorType { + return EntranceDoorType.valueOf(text) + } +} diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibility.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibility.kt index 56b40e46a..06e76ff98 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibility.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibility.kt @@ -1,30 +1,76 @@ package club.staircrusher.accessibility.domain.model import club.staircrusher.stdlib.clock.SccClock +import club.staircrusher.stdlib.jpa.IntListToTextAttributeConverter +import club.staircrusher.stdlib.jpa.StringListToTextAttributeConverter +import jakarta.persistence.Convert +import jakarta.persistence.Entity +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated +import jakarta.persistence.Id import java.time.Duration import java.time.Instant -data class PlaceAccessibility( +@Entity +class PlaceAccessibility( + @Id val id: String, val placeId: String, + @Convert(converter = IntListToTextAttributeConverter::class) val floors: List?, val isFirstFloor: Boolean, val isStairOnlyOption: Boolean?, + @Enumerated(EnumType.STRING) val stairInfo: StairInfo, + @Enumerated(EnumType.STRING) val stairHeightLevel: StairHeightLevel?, val hasSlope: Boolean, + @Convert(converter = EntranceDoorTypeListToTextAttributeConverter::class) val entranceDoorTypes: List?, - @Deprecated("use images instead") - val imageUrls: List, - val images: List, + imageUrls: List, + images: List, val userId: String?, val createdAt: Instant, val deletedAt: Instant? = null, ) { + @Deprecated("use images instead") + @Convert(converter = StringListToTextAttributeConverter::class) + var imageUrls: List = imageUrls + protected set + + @Convert(converter = AccessibilityImageListToTextAttributeConverter::class) + var images: List = images + protected set + + fun updateImages(images: List) { + this.images = images + this.imageUrls = images.map { it.imageUrl } + } + fun isDeletable(uid: String?): Boolean { return uid != null && uid == userId && SccClock.instant() < createdAt + deletableDuration } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as PlaceAccessibility + + return id == other.id + } + + override fun hashCode(): Int { + return id.hashCode() + } + + override fun toString(): String { + return "PlaceAccessibility(id='$id', placeId='$placeId', floors=$floors, isFirstFloor=$isFirstFloor, " + + "isStairOnlyOption=$isStairOnlyOption, stairInfo=$stairInfo, stairHeightLevel=$stairHeightLevel, " + + "hasSlope=$hasSlope, entranceDoorTypes=$entranceDoorTypes, imageUrls=$imageUrls, images=$images, " + + "userId=$userId, createdAt=$createdAt, deletedAt=$deletedAt)" + } + companion object { val deletableDuration = Duration.ofHours(6) } diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityComment.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityComment.kt index 534703041..c00f498d0 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityComment.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityComment.kt @@ -1,12 +1,34 @@ package club.staircrusher.accessibility.domain.model +import jakarta.persistence.Entity +import jakarta.persistence.Id import java.time.Instant -data class PlaceAccessibilityComment( +@Entity +class PlaceAccessibilityComment( + @Id val id: String, val placeId: String, val userId: String?, val comment: String, val createdAt: Instant, val deletedAt: Instant? = null, -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as PlaceAccessibilityComment + + return id == other.id + } + + override fun hashCode(): Int { + return id.hashCode() + } + + override fun toString(): String { + return "PlaceAccessibilityComment(id='$id', placeId='$placeId', userId=$userId, comment='$comment', " + + "createdAt=$createdAt, deletedAt=$deletedAt)" + } +} diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityUpvote.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityUpvote.kt index 7fe7f37ff..75724ffb5 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityUpvote.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/main/kotlin/club/staircrusher/accessibility/domain/model/PlaceAccessibilityUpvote.kt @@ -1,23 +1,37 @@ package club.staircrusher.accessibility.domain.model +import jakarta.persistence.Entity +import jakarta.persistence.Id import java.time.Instant +@Entity class PlaceAccessibilityUpvote( + @Id val id: String, val userId: String, val placeAccessibilityId: String, var createdAt: Instant, var deletedAt: Instant? = null, ) { - override fun hashCode(): Int { - return id.hashCode() + fun cancel(at: Instant) { + deletedAt = at } override fun equals(other: Any?): Boolean { - return other is PlaceAccessibilityUpvote && other.id == id + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as PlaceAccessibilityUpvote + + return id == other.id } - fun cancel(at: Instant) { - deletedAt = at + override fun hashCode(): Int { + return id.hashCode() + } + + override fun toString(): String { + return "PlaceAccessibilityUpvote(id='$id', userId='$userId', placeAccessibilityId='$placeAccessibilityId', " + + "createdAt=$createdAt, deletedAt=$deletedAt)" } } diff --git a/app-server/subprojects/bounded_context/accessibility/domain/src/unitTest/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityScoreTest.kt b/app-server/subprojects/bounded_context/accessibility/domain/src/unitTest/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityScoreTest.kt index be239c886..2b33e6c25 100644 --- a/app-server/subprojects/bounded_context/accessibility/domain/src/unitTest/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityScoreTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/domain/src/unitTest/kotlin/club/staircrusher/accessibility/domain/model/AccessibilityScoreTest.kt @@ -1,7 +1,7 @@ package club.staircrusher.accessibility.domain.model -import org.junit.jupiter.api.Test import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test import java.time.Instant class AccessibilityScoreTest { @@ -11,57 +11,57 @@ class AccessibilityScoreTest { fun test() { assertEquals( 1.0, AccessibilityScore.get( - mockPa.copy( + createPa( isFirstFloor = true, hasSlope = false, stairInfo = StairInfo.ONE, stairHeightLevel = StairHeightLevel.HALF_THUMB ), - mockBa, + createBa(), ) ) assertEquals( 1.0, AccessibilityScore.get( - mockPa.copy( + createPa( isFirstFloor = true, hasSlope = true, stairInfo = StairInfo.ONE, stairHeightLevel = StairHeightLevel.THUMB ), - mockBa, + createBa(), ) ) assertEquals( 4.0, AccessibilityScore.get( - mockPa.copy( + createPa( isFirstFloor = true, hasSlope = false, stairInfo = StairInfo.TWO_TO_FIVE, stairHeightLevel = StairHeightLevel.HALF_THUMB ), - mockBa, + createBa(), ) ) assertEquals( 3.0, AccessibilityScore.get( - mockPa.copy( + createPa( isFirstFloor = true, hasSlope = true, stairInfo = StairInfo.OVER_SIX, stairHeightLevel = StairHeightLevel.HALF_THUMB ), - mockBa, + createBa(), ) ) assertEquals( 0.5 + 1.0 + 5.0, AccessibilityScore.get( - mockPa.copy( + createPa( isFirstFloor = false, hasSlope = true, stairInfo = StairInfo.ONE, stairHeightLevel = StairHeightLevel.HALF_THUMB ), - mockBa.copy( + createBa( hasElevator = false, entranceStairInfo = StairInfo.ONE, entranceStairHeightLevel = StairHeightLevel.THUMB, @@ -71,13 +71,13 @@ class AccessibilityScoreTest { ) assertEquals( 0.5 + 1.0 + 1.0, AccessibilityScore.get( - mockPa.copy( + createPa( isFirstFloor = false, hasSlope = true, stairInfo = StairInfo.ONE, stairHeightLevel = StairHeightLevel.HALF_THUMB ), - mockBa.copy( + createBa( hasElevator = true, entranceStairInfo = StairInfo.ONE, entranceStairHeightLevel = StairHeightLevel.THUMB, @@ -89,39 +89,71 @@ class AccessibilityScoreTest { ) } - private val mockPa = PlaceAccessibility( - id = "", - placeId = "", - floors = emptyList(), - isFirstFloor = false, - isStairOnlyOption = false, - stairInfo = StairInfo.ONE, - stairHeightLevel = StairHeightLevel.THUMB, - hasSlope = false, - entranceDoorTypes = emptyList(), - imageUrls = emptyList(), - images = emptyList(), - userId = null, - createdAt = Instant.now(), - deletedAt = null + private fun createPa( + id: String = "", + placeId: String = "", + floors: List? = emptyList(), + isFirstFloor: Boolean = false, + isStairOnlyOption: Boolean? = false, + stairInfo: StairInfo = StairInfo.ONE, + stairHeightLevel: StairHeightLevel? = StairHeightLevel.THUMB, + hasSlope: Boolean = false, + entranceDoorTypes: List? = emptyList(), + imageUrls: List = emptyList(), + images: List = emptyList(), + userId: String? = null, + createdAt: Instant = Instant.now(), + deletedAt: Instant? = null + ) = PlaceAccessibility( + id = id, + placeId = placeId, + floors = floors, + isFirstFloor = isFirstFloor, + isStairOnlyOption = isStairOnlyOption, + stairInfo = stairInfo, + stairHeightLevel = stairHeightLevel, + hasSlope = hasSlope, + entranceDoorTypes = entranceDoorTypes, + imageUrls = imageUrls, + images = images, + userId = userId, + createdAt = createdAt, + deletedAt = deletedAt, ) - private val mockBa = BuildingAccessibility( - id = "", - buildingId = "", - entranceStairInfo = StairInfo.ONE, - entranceStairHeightLevel = null, - entranceImageUrls = emptyList(), - entranceImages = emptyList(), - hasSlope = false, - hasElevator = false, - entranceDoorTypes = emptyList(), - elevatorImageUrls = emptyList(), - elevatorImages = emptyList(), - elevatorStairInfo = StairInfo.ONE, - elevatorStairHeightLevel = StairHeightLevel.THUMB, - userId = null, - createdAt = Instant.now(), - deletedAt = null + private fun createBa( + id: String = "", + buildingId: String = "", + entranceStairInfo: StairInfo = StairInfo.ONE, + entranceStairHeightLevel: StairHeightLevel? = null, + entranceImageUrls: List = emptyList(), + entranceImages: List = emptyList(), + hasSlope: Boolean = false, + hasElevator: Boolean = false, + entranceDoorTypes: List? = emptyList(), + elevatorStairInfo: StairInfo = StairInfo.ONE, + elevatorStairHeightLevel: StairHeightLevel? = StairHeightLevel.THUMB, + elevatorImageUrls: List = emptyList(), + elevatorImages: List = emptyList(), + userId: String? = null, + createdAt: Instant = Instant.now(), + deletedAt: Instant? = null, + ) = BuildingAccessibility( + id = id, + buildingId = buildingId, + entranceStairInfo = entranceStairInfo, + entranceStairHeightLevel = entranceStairHeightLevel, + entranceImageUrls = entranceImageUrls, + entranceImages = entranceImages, + hasSlope = hasSlope, + hasElevator = hasElevator, + entranceDoorTypes = entranceDoorTypes, + elevatorStairInfo = elevatorStairInfo, + elevatorStairHeightLevel = elevatorStairHeightLevel, + elevatorImageUrls = elevatorImageUrls, + elevatorImages = elevatorImages, + userId = userId, + createdAt = createdAt, + deletedAt = deletedAt, ) } diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/AccessibilityRankTest.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/AccessibilityRankTest.kt index 950c01ef2..eeeeb7361 100644 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/AccessibilityRankTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/AccessibilityRankTest.kt @@ -8,6 +8,7 @@ import club.staircrusher.accesssibility.infra.adapter.`in`.controller.base.Acces import club.staircrusher.api.spec.dto.GetAccessibilityLeaderboardPost200Response import club.staircrusher.api.spec.dto.GetAccessibilityRankPost200Response import club.staircrusher.api.spec.dto.GetCountForNextRankPost200Response +import club.staircrusher.user.application.port.out.persistence.UserRepository import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach @@ -28,12 +29,16 @@ class AccessibilityRankTest : AccessibilityITBase() { @Autowired private lateinit var buildingAccessibilityUpvoteRepository: BuildingAccessibilityUpvoteRepository + @Autowired + private lateinit var userRepository: UserRepository + @BeforeEach fun setUp() = transactionManager.doInTransaction { - accessibilityRankRepository.removeAll() - placeAccessibilityRepository.removeAll() - buildingAccessibilityUpvoteRepository.removeAll() - buildingAccessibilityRepository.removeAll() +// userRepository.deleteAll() + accessibilityRankRepository.deleteAll() + placeAccessibilityRepository.deleteAll() + buildingAccessibilityUpvoteRepository.deleteAll() + buildingAccessibilityRepository.deleteAll() repeat(10) { val (user, _, _, _) = registerAccessibility() diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/DeleteAccessibilityTest.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/DeleteAccessibilityTest.kt index 624143297..0306404f7 100644 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/DeleteAccessibilityTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/DeleteAccessibilityTest.kt @@ -24,6 +24,7 @@ import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.data.repository.findByIdOrNull import java.time.Duration class DeleteAccessibilityTest : AccessibilityITBase() { diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/GiveAndCancelPlaceAccessibilityUpvoteTest.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/GiveAndCancelPlaceAccessibilityUpvoteTest.kt index 8e342012c..409a08ed7 100644 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/GiveAndCancelPlaceAccessibilityUpvoteTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/GiveAndCancelPlaceAccessibilityUpvoteTest.kt @@ -28,7 +28,7 @@ class GiveAndCancelPlaceAccessibilityUpvoteTest : AccessibilityITBase() { .andExpect { transactionManager.doInTransaction { assertNotNull( - placeAccessibilityUpvoteRepository.findUpvote(user.id, placeAccessibility.id) + placeAccessibilityUpvoteRepository.findExistingUpvote(user.id, placeAccessibility.id) ) } } @@ -41,7 +41,7 @@ class GiveAndCancelPlaceAccessibilityUpvoteTest : AccessibilityITBase() { .andExpect { transactionManager.doInTransaction { assertNull( - placeAccessibilityUpvoteRepository.findUpvote(user.id, placeAccessibility.id) + placeAccessibilityUpvoteRepository.findExistingUpvote(user.id, placeAccessibility.id) ) } } diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterBuildingAccessibilityTest.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterBuildingAccessibilityTest.kt index db24bc4b9..86c1df83c 100644 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterBuildingAccessibilityTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterBuildingAccessibilityTest.kt @@ -28,8 +28,8 @@ class RegisterBuildingAccessibilityTest : AccessibilityITBase() { @BeforeEach fun setUp() = transactionManager.doInTransaction { - buildingAccessibilityUpvoteRepository.removeAll() - buildingAccessibilityRepository.removeAll() + buildingAccessibilityUpvoteRepository.deleteAll() + buildingAccessibilityRepository.deleteAll() } @Test diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterPlaceAccessibilityTest.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterPlaceAccessibilityTest.kt index a887ef719..b04310620 100644 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterPlaceAccessibilityTest.kt +++ b/app-server/subprojects/bounded_context/accessibility/infra/src/integrationTest/kotlin/club/staircrusher/accesssibility/infra/adapter/in/controller/RegisterPlaceAccessibilityTest.kt @@ -14,6 +14,7 @@ import club.staircrusher.api.spec.dto.RegisterPlaceAccessibilityResponseDto import club.staircrusher.api.spec.dto.StairHeightLevel import club.staircrusher.challenge.application.port.out.persistence.ChallengeContributionRepository import club.staircrusher.challenge.application.port.out.persistence.ChallengeParticipationRepository +import club.staircrusher.challenge.application.port.out.persistence.ChallengeRepository import club.staircrusher.challenge.domain.model.Challenge import club.staircrusher.challenge.domain.model.ChallengeActionCondition import club.staircrusher.challenge.domain.model.ChallengeAddressCondition @@ -36,7 +37,7 @@ class RegisterPlaceAccessibilityTest : AccessibilityITBase() { private lateinit var placeAccessibilityRepository: PlaceAccessibilityRepository @Autowired - private lateinit var challengeRepository: BuildingAccessibilityRepository + private lateinit var challengeRepository: ChallengeRepository @Autowired private lateinit var challengeParticipationRepository: ChallengeParticipationRepository @@ -49,7 +50,7 @@ class RegisterPlaceAccessibilityTest : AccessibilityITBase() { @BeforeEach fun setUp() = transactionManager.doInTransaction { - placeAccessibilityRepository.removeAll() + placeAccessibilityRepository.deleteAll() challengeRepository.removeAll() challengeParticipationRepository.removeAll() diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/in/controller/AdminAccessibilityAllowedRegionController.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/in/controller/AdminAccessibilityAllowedRegionController.kt index 59e113056..a470b0fe3 100644 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/in/controller/AdminAccessibilityAllowedRegionController.kt +++ b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/in/controller/AdminAccessibilityAllowedRegionController.kt @@ -30,11 +30,11 @@ class AdminAccessibilityAllowedRegionController( @GetMapping("/admin/accessibilityAllowedRegions/{regionId}") fun getAccessibilityAllowedRegion(@PathVariable regionId: String): AccessibilityAllowedRegionDTO { - return accessibilityAllowedRegionRepository.findById(regionId).toDTO() + return accessibilityAllowedRegionRepository.findById(regionId).get().toDTO() } @DeleteMapping("/admin/accessibilityAllowedRegions/{regionId}") fun deleteAccessibilityAllowedRegion(@PathVariable regionId: String) { - return accessibilityAllowedRegionRepository.remove(regionId) + return accessibilityAllowedRegionRepository.deleteById(regionId) } } diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt deleted file mode 100644 index 643f8337a..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityImageFaceBlurringHistoryRepository.kt +++ /dev/null @@ -1,67 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.AccessibilityImageFaceBlurringHistoryRepository -import club.staircrusher.accessibility.domain.model.AccessibilityImageFaceBlurringHistory -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.clock.SccClock -import club.staircrusher.stdlib.di.annotation.Component -import club.staircrusher.stdlib.time.toOffsetDateTime - -@Suppress("TooManyFunctions") -@Component -class AccessibilityImageFaceBlurringHistoryRepository( - db: DB, -) : AccessibilityImageFaceBlurringHistoryRepository { - private val queries = db.accessibilityImageFaceBlurringHistoryQueries - - override fun findLatestPlaceHistoryOrNull(): AccessibilityImageFaceBlurringHistory? { - return queries.findLatestPlaceHistory().executeAsOneOrNull()?.toDomainModel() - } - - override fun findLatestBuildingHistoryOrNull(): AccessibilityImageFaceBlurringHistory? { - return queries.findLatestBuildingHistory().executeAsOneOrNull()?.toDomainModel() - } - - override fun findByPlaceAccessibilityId(placeAccessibilityId: String): List { - return queries.findByPlaceAccessibility(placeAccessibilityId) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findByBuildingAccessibilityId(buildingAccessibilityId: String): List { - return queries.findByBuildingAccessilbility(buildingAccessibilityId) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun save(entity: AccessibilityImageFaceBlurringHistory): AccessibilityImageFaceBlurringHistory { - queries.save( - entity.toPersistenceModel() - .copy(updated_at = SccClock.instant().toOffsetDateTime()) - ) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): AccessibilityImageFaceBlurringHistory { - return findByIdOrNull(id) - ?: throw IllegalArgumentException("AccessibilityImagesBlurringHistory of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): AccessibilityImageFaceBlurringHistory? { - return queries.findById(id = id).executeAsOneOrNull()?.toDomainModel() - } - - override fun findAll(): List { - return queries.findAll().executeAsList().map { it.toDomainModel() } - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityRankRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityRankRepository.kt deleted file mode 100644 index d849fed5e..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/AccessibilityRankRepository.kt +++ /dev/null @@ -1,63 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.AccessibilityRankRepository -import club.staircrusher.accessibility.domain.model.AccessibilityRank -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.di.annotation.Component - -@Suppress("TooManyFunctions") -@Component -class AccessibilityRankRepository( - val db: DB, -): AccessibilityRankRepository { - private val queries = db.accessibilityRankQueries - - override fun findTopNUsers(n: Int): List { - return queries.findTopNUsers(n.toLong()).executeAsList().map { - it.toDomainModel() - } - } - - override fun findByUserId(userId: String): AccessibilityRank? { - return queries.findByUserId(userId).executeAsOneOrNull()?.toDomainModel() - } - - override fun findByRank(rank: Long): AccessibilityRank? { - return queries.findByRank(rank).executeAsOneOrNull()?.toDomainModel() - } - - override fun findNextRank(rank: Long): AccessibilityRank? { - return queries.findNextRank(rank).executeAsOneOrNull()?.toDomainModel() - } - - override fun findByConqueredCount(conqueredCount: Int): AccessibilityRank? { - return queries.findByConqueredCount(conqueredCount).executeAsOneOrNull()?.toDomainModel() - } - - override fun findAll(): List { - return queries.findAll().executeAsList().map { it.toDomainModel() } - } - - override fun save(entity: AccessibilityRank): AccessibilityRank { - queries.save(entity.toPersistenceModel()) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach { queries.save(it.toPersistenceModel()) } - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): AccessibilityRank { - return queries.findById(id).executeAsOne().toDomainModel() - } - - override fun findByIdOrNull(id: String): AccessibilityRank? { - return queries.findById(id).executeAsOneOrNull()?.toDomainModel() - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityCommentRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityCommentRepository.kt deleted file mode 100644 index f1b07ce29..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityCommentRepository.kt +++ /dev/null @@ -1,48 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.BuildingAccessibilityCommentRepository -import club.staircrusher.accessibility.domain.model.BuildingAccessibilityComment -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.clock.SccClock -import club.staircrusher.stdlib.di.annotation.Component -import club.staircrusher.stdlib.time.toOffsetDateTime - -@Component -class BuildingAccessibilityCommentRepository( - db: DB, -) : BuildingAccessibilityCommentRepository { - private val queries = db.buildingAccessibilityCommentQueries - - override fun save(entity: BuildingAccessibilityComment): BuildingAccessibilityComment { - queries.save(entity.toPersistenceModel()) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): BuildingAccessibilityComment { - return findByIdOrNull(id) ?: throw IllegalArgumentException("BuildingAccessibilityComment of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): BuildingAccessibilityComment? { - return queries.findById(id = id).executeAsOneOrNull()?.toDomainModel() - } - - override fun findByBuildingId(buildingId: String): List { - return queries.findByBuildingId(buildingId = buildingId) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun removeByBuildingId(buildingId: String) { - queries.removeByBuildingId(SccClock.instant().toOffsetDateTime(), buildingId) - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityRepository.kt deleted file mode 100644 index 22effc0e3..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityRepository.kt +++ /dev/null @@ -1,137 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.BuildingAccessibilityRepository -import club.staircrusher.accessibility.domain.model.AccessibilityImage -import club.staircrusher.accessibility.domain.model.BuildingAccessibility -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.clock.SccClock -import club.staircrusher.stdlib.di.annotation.Component -import club.staircrusher.stdlib.geography.EupMyeonDong -import club.staircrusher.stdlib.time.toOffsetDateTime -import java.time.Instant - -@Suppress("TooManyFunctions") -@Component -class BuildingAccessibilityRepository( - db: DB, -) : BuildingAccessibilityRepository { - private val queries = db.buildingAccessibilityQueries - - override fun save(entity: BuildingAccessibility): BuildingAccessibility { - queries.save(entity.toPersistenceModel().copy(updated_at = SccClock.instant().toOffsetDateTime())) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): BuildingAccessibility { - return findByIdOrNull(id) ?: throw IllegalArgumentException("BuildingAccessibility of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): BuildingAccessibility? { - return queries.findById(id = id).executeAsOneOrNull()?.toDomainModel() - } - - override fun findByBuildingIds(buildingIds: Collection): List { - if (buildingIds.isEmpty()) { - return emptyList() - } - return queries.findByBuildingIds(buildingIds = buildingIds) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findByBuildingId(buildingId: String): BuildingAccessibility? { - return queries.findByBuildingId(buildingId = buildingId) - .executeAsOneOrNull() - ?.toDomainModel() - } - - override fun findByPlaceIds(placeIds: Collection): List { - return queries.findByPlaceIds(placeIds = placeIds) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findByUserIdAndCreatedAtBetween(userId: String, from: Instant, to: Instant): List { - return queries.findByUserIdAndCreatedAtBetween( - userId = userId, - from = from.toOffsetDateTime(), - to = to.toOffsetDateTime() - ) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findByEupMyeonDong(eupMyeonDong: EupMyeonDong): List { - return queries.findByEupMyeonDong(eupMyeonDongId = eupMyeonDong.id) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findOneOrNullByCreatedAtGreaterThanAndOrderByCreatedAtAsc(createdAt: Instant): BuildingAccessibility? { - return queries.findByCreatedAtGreaterThanAndOrderByCreatedAtAsc( - createdAt = createdAt.toOffsetDateTime(), limit = 1 - ) - .executeAsOneOrNull() - ?.toDomainModel() - } - - override fun findAll(): List { - return queries.findAll().executeAsList().map { it.toDomainModel() } - } - - override fun updateEntranceImages(id: String, entranceImages: List) { - return queries.updateEntranceImages( - entranceImages = entranceImages, - id = id, - ) - } - - override fun updateEntranceImageUrlsAndImages(id: String, urls: List, images: List) { - return queries.updateEntranceImageUrlsAndImages( - id = id, - entranceImageUrls = urls, - entranceImages = images, - ) - } - - override fun updateElevatorImages(id: String, elevatorImages: List) { - return queries.updateElevatorImages( - elevatorImages = elevatorImages, - id = id, - ) - } - - override fun updateElevatorImageUrlsAndImages(id: String, urls: List, images: List) { - return queries.updateElevatorImageUrlsAndImages( - id = id, - elevatorImageUrls = urls, - elevatorImages = images, - ) - } - - override fun countByUserId(userId: String): Int { - return queries.countByUserId(userId = userId).executeAsOne().toInt() - } - - override fun countByUserIdCreatedAtBetween(userId: String, from: Instant, to: Instant): Int { - return queries.countByUserIdAndCreatedAtBetween( - userId = userId, - from = from.toOffsetDateTime(), - to = to.toOffsetDateTime() - ).executeAsOne().toInt() - } - - override fun remove(id: String) { - queries.remove(SccClock.instant().toOffsetDateTime(), id) - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityUpvoteRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityUpvoteRepository.kt deleted file mode 100644 index 860cade8c..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/BuildingAccessibilityUpvoteRepository.kt +++ /dev/null @@ -1,53 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.BuildingAccessibilityUpvoteRepository -import club.staircrusher.accessibility.domain.model.BuildingAccessibilityUpvote -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.di.annotation.Component - -@Component -class BuildingAccessibilityUpvoteRepository( - db: DB, -) : BuildingAccessibilityUpvoteRepository { - private val queries = db.buildingAccessibilityUpvoteQueries - - override fun save(entity: BuildingAccessibilityUpvote): BuildingAccessibilityUpvote { - queries.save(entity.toPersistenceModel()) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): BuildingAccessibilityUpvote { - return findByIdOrNull(id) - ?: throw IllegalArgumentException("BuildingAccessibilityComment of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): BuildingAccessibilityUpvote? { - return queries.buildingAccessibilityUpvoteFindById(id = id).executeAsOneOrNull()?.toDomainModel() - } - - override fun findExistingUpvote( - userId: String, - buildingAccessibilityId: String - ): BuildingAccessibilityUpvote? { - return queries.findByUserAndBuildingAccessibilityAndNotDeleted( - userId = userId, - buildingAccessibilityId = buildingAccessibilityId, - ).executeAsOneOrNull()?.toDomainModel() - } - - override fun countUpvotes(buildingAccessibilityId: String): Int { - return queries.countUpvotes(buildingAccessibilityId = buildingAccessibilityId) - .executeAsOne() - .toInt() - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityCommentRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityCommentRepository.kt deleted file mode 100644 index 81e2d2748..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityCommentRepository.kt +++ /dev/null @@ -1,48 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.PlaceAccessibilityCommentRepository -import club.staircrusher.accessibility.domain.model.PlaceAccessibilityComment -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.clock.SccClock -import club.staircrusher.stdlib.di.annotation.Component -import club.staircrusher.stdlib.time.toOffsetDateTime - -@Component -class PlaceAccessibilityCommentRepository( - db: DB, -) : PlaceAccessibilityCommentRepository { - private val queries = db.placeAccessibilityCommentQueries - - override fun save(entity: PlaceAccessibilityComment): PlaceAccessibilityComment { - queries.save(entity.toPersistenceModel()) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): PlaceAccessibilityComment { - return findByIdOrNull(id) ?: throw IllegalArgumentException("PlaceAccessibilityComment of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): PlaceAccessibilityComment? { - return queries.findById(id = id).executeAsOneOrNull()?.toDomainModel() - } - - override fun findByPlaceId(placeId: String): List { - return queries.findByPlaceId(placeId = placeId) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun removeByPlaceId(placeId: String) { - queries.removeByPlaceId(SccClock.instant().toOffsetDateTime(), placeId) - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityRepository.kt deleted file mode 100644 index 280909fb2..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityRepository.kt +++ /dev/null @@ -1,145 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.PlaceAccessibilityRepository -import club.staircrusher.accessibility.domain.model.AccessibilityImage -import club.staircrusher.accessibility.domain.model.PlaceAccessibility -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.clock.SccClock -import club.staircrusher.stdlib.di.annotation.Component -import club.staircrusher.stdlib.geography.EupMyeonDong -import club.staircrusher.stdlib.time.toOffsetDateTime -import java.time.Instant - -@Suppress("TooManyFunctions") -@Component -class PlaceAccessibilityRepository( - db: DB, -) : PlaceAccessibilityRepository { - private val queries = db.placeAccessibilityQueries - - override fun save(entity: PlaceAccessibility): PlaceAccessibility { - queries.save(entity.toPersistenceModel().copy(updated_at = SccClock.instant().toOffsetDateTime())) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): PlaceAccessibility { - return findByIdOrNull(id) ?: throw IllegalArgumentException("PlaceAccessibility of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): PlaceAccessibility? { - return queries.findById(id = id).executeAsOneOrNull()?.toDomainModel() - } - - override fun findByPlaceIds(placeIds: Collection): List { - return queries.findByPlaceIds(placeIds = placeIds) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findByPlaceId(placeId: String): PlaceAccessibility? { - return queries.findByPlaceId(placeId = placeId) - .executeAsOneOrNull() - ?.toDomainModel() - } - - override fun findByUserId(userId: String): List { - return queries.findByUserId(userId = userId) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findByUserIdAndCreatedAtBetween(userId: String, from: Instant, to: Instant): List { - return queries.findByUserIdAndCreatedAtBetween( - userId = userId, - from = from.toOffsetDateTime(), - to = to.toOffsetDateTime() - ) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun countByEupMyeonDong(eupMyeonDong: EupMyeonDong): Int { - return queries.countByEupMyeonDong(eupMyeonDongId = eupMyeonDong.id) - .executeAsOne() - .toInt() - } - - override fun countByUserId(userId: String): Int { - return queries.countByUserId(userId = userId).executeAsOne().toInt() - } - - override fun countByUserIdAndCreatedAtBetween(userId: String, from: Instant, to: Instant): Int { - return queries.countByUserIdAndCreatedAtBetween( - userId = userId, - from = from.toOffsetDateTime(), - to = to.toOffsetDateTime() - ).executeAsOne().toInt() - } - - override fun hasAccessibilityNotRegisteredPlaceInBuilding(buildingId: String): Boolean { - return queries.hasAccessibilityNotRegisteredPlaceInBuilding(buildingId = buildingId) - .executeAsOne() - } - - override fun findByBuildingId(buildingId: String): List { - return queries.findByBuildingId(buildingId = buildingId) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun findOneOrNullByCreatedAtGreaterThanAndOrderByCreatedAtAsc(createdAt: Instant): PlaceAccessibility? { - return queries.findByCreatedAtGreaterThanAndOrderByCreatedAtAsc( - createdAt = createdAt.toOffsetDateTime(), limit = 1 - ) - .executeAsOneOrNull() - ?.toDomainModel() - } - - override fun searchForAdmin( - placeName: String?, - createdAtFrom: Instant?, - createdAtToExclusive: Instant?, - cursorCreatedAt: Instant, - cursorId: String, - limit: Int - ): List { - return queries.searchForAdmin( - placeNameLike = placeName?.let { "%$it%" }, - createdAtFrom = (createdAtFrom ?: Instant.EPOCH).toOffsetDateTime(), - createdAtToExclusive = (createdAtToExclusive ?: SccClock.instant()).toOffsetDateTime(), - cursorCreatedAt = cursorCreatedAt.toOffsetDateTime(), - cursorId = cursorId, - limit = limit.toLong(), - ) - .executeAsList() - .map { it.toDomainModel() } - } - - override fun updateImages(id: String, images: List) { - return queries.updateImages(images, id) - } - - override fun updateImageUrlsAndImages(id: String, imageUrls: List, images: List) { - return queries.updateImageUrlsAndImages(id = id, imageUrls = imageUrls, images = images) - } - - override fun countAll(): Int { - return queries.countAll() - .executeAsOne() - .toInt() - } - - override fun remove(id: String) { - queries.remove(SccClock.instant().toOffsetDateTime(), id) - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityUpvoteRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityUpvoteRepository.kt deleted file mode 100644 index 08598cd5a..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/PlaceAccessibilityUpvoteRepository.kt +++ /dev/null @@ -1,49 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.PlaceAccessibilityUpvoteRepository -import club.staircrusher.accessibility.domain.model.PlaceAccessibilityUpvote -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.di.annotation.Component - -@Component -class PlaceAccessibilityUpvoteRepository( - db: DB, -) : PlaceAccessibilityUpvoteRepository { - private val queries = db.placeAccessibilityUpvoteQueries - - override fun save(entity: PlaceAccessibilityUpvote): PlaceAccessibilityUpvote { - queries.save(entity.toPersistenceModel()) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): PlaceAccessibilityUpvote { - return findByIdOrNull(id) - ?: throw IllegalArgumentException("BuildingAccessibilityComment of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): PlaceAccessibilityUpvote? { - return queries.findUpvoteById(id = id) - .executeAsOneOrNull() - ?.toDomainModel() - } - - override fun findUpvote(userId: String, placeAccessibilityId: String): PlaceAccessibilityUpvote? { - return queries.findUpvoteByUserIdAndPlaceAccessilbityIdAndNotDeleted(userId, placeAccessibilityId) - .executeAsOneOrNull() - ?.toDomainModel() - } - - override fun countUpvotes(placeAccessibilityId: String): Int { - return 0 - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/SqlDelightAccessibilityAllowedRegionRepository.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/SqlDelightAccessibilityAllowedRegionRepository.kt deleted file mode 100644 index 0b3f33512..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/SqlDelightAccessibilityAllowedRegionRepository.kt +++ /dev/null @@ -1,44 +0,0 @@ -package club.staircrusher.accessibility.infra.adapter.out.persistence - -import club.staircrusher.accessibility.application.port.out.persistence.AccessibilityAllowedRegionRepository -import club.staircrusher.accessibility.domain.model.AccessibilityAllowedRegion -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toDomainModel -import club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight.toPersistenceModel -import club.staircrusher.infra.persistence.sqldelight.DB -import club.staircrusher.stdlib.di.annotation.Component - -@Component -class SqlDelightAccessibilityAllowedRegionRepository( - db: DB -) : AccessibilityAllowedRegionRepository { - private val queries = db.accessibilityAllowedRegionQueries - - override fun findAll(): List { - return queries.findAll().executeAsList().map { it.toDomainModel() } - } - - override fun remove(id: String) { - queries.remove(id) - } - - override fun save(entity: AccessibilityAllowedRegion): AccessibilityAllowedRegion { - queries.save(entity.toPersistenceModel()) - return entity - } - - override fun saveAll(entities: Collection) { - entities.forEach(::save) - } - - override fun removeAll() { - queries.removeAll() - } - - override fun findById(id: String): AccessibilityAllowedRegion { - return findByIdOrNull(id) ?: throw IllegalArgumentException("AccessibilityAllowedRegion of id $id does not exist.") - } - - override fun findByIdOrNull(id: String): AccessibilityAllowedRegion? { - return queries.findById(id).executeAsOneOrNull()?.toDomainModel() - } -} diff --git a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/sqldelight/Converters.kt b/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/sqldelight/Converters.kt deleted file mode 100644 index 70527199d..000000000 --- a/app-server/subprojects/bounded_context/accessibility/infra/src/main/kotlin/club/staircrusher/accessibility/infra/adapter/out/persistence/sqldelight/Converters.kt +++ /dev/null @@ -1,300 +0,0 @@ -@file:Suppress("TooManyFunctions") - -package club.staircrusher.accessibility.infra.adapter.out.persistence.sqldelight - -import club.staircrusher.accessibility.domain.model.AccessibilityAllowedRegion -import club.staircrusher.accessibility.domain.model.AccessibilityImageFaceBlurringHistory -import club.staircrusher.accessibility.domain.model.AccessibilityRank -import club.staircrusher.accessibility.domain.model.BuildingAccessibility -import club.staircrusher.accessibility.domain.model.BuildingAccessibilityComment -import club.staircrusher.accessibility.domain.model.BuildingAccessibilityUpvote -import club.staircrusher.accessibility.domain.model.PlaceAccessibility -import club.staircrusher.accessibility.domain.model.PlaceAccessibilityComment -import club.staircrusher.accessibility.domain.model.PlaceAccessibilityUpvote -import club.staircrusher.accessibility.domain.model.StairInfo -import club.staircrusher.infra.persistence.sqldelight.migration.Accessibility_allowed_region -import club.staircrusher.infra.persistence.sqldelight.migration.Accessibility_image_face_blurring_history -import club.staircrusher.infra.persistence.sqldelight.migration.Accessibility_rank -import club.staircrusher.infra.persistence.sqldelight.migration.Building_accessibility -import club.staircrusher.infra.persistence.sqldelight.migration.Building_accessibility_comment -import club.staircrusher.infra.persistence.sqldelight.migration.Building_accessibility_upvote -import club.staircrusher.infra.persistence.sqldelight.migration.Place_accessibility -import club.staircrusher.infra.persistence.sqldelight.migration.Place_accessibility_comment -import club.staircrusher.infra.persistence.sqldelight.migration.Place_accessibility_upvote -import club.staircrusher.infra.persistence.sqldelight.query.accessibility.BuildingAccessibilityUpvoteFindById -import club.staircrusher.infra.persistence.sqldelight.query.accessibility.FindByUserAndBuildingAccessibilityAndNotDeleted -import club.staircrusher.infra.persistence.sqldelight.query.accessibility.FindLatestBuildingHistory -import club.staircrusher.infra.persistence.sqldelight.query.accessibility.FindLatestPlaceHistory -import club.staircrusher.stdlib.time.toOffsetDateTime - -fun Building_accessibility.toDomainModel() = BuildingAccessibility( - id = id, - buildingId = building_id, - entranceStairInfo = StairInfo.valueOf(entrance_stair_info), - entranceStairHeightLevel = entrance_stair_height_level, - entranceImageUrls = entrance_image_urls, - entranceImages = entrance_images, - hasSlope = has_slope, - hasElevator = has_elevator, - entranceDoorTypes = entrance_door_types.ifEmpty { null }, - elevatorStairInfo = StairInfo.valueOf(elevator_stair_info), - elevatorStairHeightLevel = elevator_stair_height_level, - elevatorImageUrls = elevator_image_urls, - elevatorImages = elevator_images, - userId = user_id, - createdAt = created_at.toInstant(), - deletedAt = deleted_at?.toInstant(), -) - -fun BuildingAccessibility.toPersistenceModel() = Building_accessibility( - id = id, - building_id = buildingId, - entrance_stair_info = entranceStairInfo.name, - entrance_stair_height_level = entranceStairHeightLevel, - entrance_image_urls = entranceImageUrls, - entrance_images = entranceImages, - has_slope = hasSlope, - has_elevator = hasElevator, - entrance_door_types = entranceDoorTypes ?: emptyList(), - elevator_stair_info = elevatorStairInfo.name, - elevator_stair_height_level = elevatorStairHeightLevel, - elevator_image_urls = elevatorImageUrls, - elevator_images = elevatorImages, - user_id = userId, - created_at = createdAt.toOffsetDateTime(), - updated_at = createdAt.toOffsetDateTime(), - deleted_at = deletedAt?.toOffsetDateTime(), -) - -fun Building_accessibility_comment.toDomainModel() = BuildingAccessibilityComment( - id = id, - buildingId = building_id, - userId = user_id, - comment = comment, - createdAt = created_at.toInstant(), - deletedAt = deleted_at?.toInstant(), -) - -fun BuildingAccessibilityComment.toPersistenceModel() = Building_accessibility_comment( - id = id, - building_id = buildingId, - user_id = userId, - comment = comment, - created_at = createdAt.toOffsetDateTime(), - updated_at = createdAt.toOffsetDateTime(), - deleted_at = deletedAt?.toOffsetDateTime(), -) - -fun BuildingAccessibilityUpvoteFindById.toDomainModel(): BuildingAccessibilityUpvote { - val buildingAccessibility = BuildingAccessibility( - id = id_, - buildingId = building_id, - entranceStairInfo = StairInfo.valueOf(entrance_stair_info), - entranceStairHeightLevel = entrance_stair_height_level, - entranceImageUrls = entrance_image_urls, - entranceImages = entrance_images, - hasSlope = has_slope, - hasElevator = has_elevator, - entranceDoorTypes = entrance_door_types, - elevatorStairInfo = StairInfo.valueOf(elevator_stair_info), - elevatorStairHeightLevel = elevator_stair_height_level, - elevatorImageUrls = elevator_image_urls, - elevatorImages = elevator_images, - userId = user_id_, - createdAt = created_at_.toInstant(), - ) - return BuildingAccessibilityUpvote( - id = id, - userId = user_id, - buildingAccessibility = buildingAccessibility, - createdAt = created_at.toInstant(), - deletedAt = deleted_at?.toInstant(), - ) -} - -fun FindByUserAndBuildingAccessibilityAndNotDeleted.toDomainModel(): BuildingAccessibilityUpvote { - val buildingAccessibility = BuildingAccessibility( - id = id_, - buildingId = building_id, - entranceStairInfo = StairInfo.valueOf(entrance_stair_info), - entranceStairHeightLevel = entrance_stair_height_level, - entranceImageUrls = entrance_image_urls, - entranceImages = entrance_images, - hasSlope = has_slope, - hasElevator = has_elevator, - entranceDoorTypes = entrance_door_types, - elevatorStairInfo = StairInfo.valueOf(elevator_stair_info), - elevatorStairHeightLevel = elevator_stair_height_level, - elevatorImageUrls = elevator_image_urls, - elevatorImages = elevator_images, - userId = user_id_, - createdAt = created_at_.toInstant(), - ) - return BuildingAccessibilityUpvote( - id = id, - userId = user_id, - buildingAccessibility = buildingAccessibility, - createdAt = created_at.toInstant(), - deletedAt = deleted_at?.toInstant(), - ) -} - -fun BuildingAccessibilityUpvote.toPersistenceModel() = Building_accessibility_upvote( - id = id, - user_id = userId, - building_accessibility_id = buildingAccessibility.id, - created_at = createdAt.toOffsetDateTime(), - updated_at = createdAt.toOffsetDateTime(), - deleted_at = deletedAt?.toOffsetDateTime(), -) - -fun Place_accessibility.toDomainModel() = PlaceAccessibility( - id = id, - placeId = place_id, - floors = floors.ifEmpty { null }, - isFirstFloor = is_first_floor, - isStairOnlyOption = is_stair_only_option, - stairInfo = StairInfo.valueOf(stair_info), - stairHeightLevel = stair_height_level, - hasSlope = has_slope, - entranceDoorTypes = entrance_door_types.ifEmpty { null }, - imageUrls = image_urls, - images = images, - userId = user_id, - createdAt = created_at.toInstant(), - deletedAt = deleted_at?.toInstant(), -) - -fun PlaceAccessibility.toPersistenceModel() = Place_accessibility( - id = id, - place_id = placeId, - floors = floors ?: emptyList(), - is_first_floor = isFirstFloor, - is_stair_only_option = isStairOnlyOption, - stair_info = stairInfo.name, - stair_height_level = stairHeightLevel, - has_slope = hasSlope, - entrance_door_types = entranceDoorTypes ?: emptyList(), - image_urls = imageUrls, - images = images, - user_id = userId, - created_at = createdAt.toOffsetDateTime(), - updated_at = createdAt.toOffsetDateTime(), - deleted_at = deletedAt?.toOffsetDateTime(), -) - -fun Place_accessibility_comment.toDomainModel() = PlaceAccessibilityComment( - id = id, - placeId = place_id, - userId = user_id, - comment = comment, - createdAt = created_at.toInstant(), - deletedAt = deleted_at?.toInstant(), -) - -fun PlaceAccessibilityComment.toPersistenceModel() = Place_accessibility_comment( - id = id, - place_id = placeId, - user_id = userId, - comment = comment, - created_at = createdAt.toOffsetDateTime(), - updated_at = createdAt.toOffsetDateTime(), - deleted_at = deletedAt?.toOffsetDateTime(), -) - -fun PlaceAccessibilityUpvote.toPersistenceModel() = Place_accessibility_upvote( - id = id, - user_id = userId, - place_accessibility_id = placeAccessibilityId, - created_at = createdAt.toOffsetDateTime(), - updated_at = createdAt.toOffsetDateTime(), - deleted_at = deletedAt?.toOffsetDateTime(), -) - -fun Place_accessibility_upvote.toDomainModel(): PlaceAccessibilityUpvote { - return PlaceAccessibilityUpvote( - id = id, - userId = user_id, - placeAccessibilityId = place_accessibility_id, - createdAt = created_at.toInstant(), - deletedAt = deleted_at?.toInstant() - ) -} - -fun AccessibilityRank.toPersistenceModel() = Accessibility_rank( - id = id, - user_id = userId, - conquered_count = conqueredCount, - rank = rank, - created_at = createdAt.toOffsetDateTime(), - updated_at = updatedAt.toOffsetDateTime(), -) - -fun Accessibility_rank.toDomainModel() = AccessibilityRank( - id = id, - userId = user_id, - conqueredCount = conquered_count, - rank = rank, - createdAt = created_at.toInstant(), - updatedAt = updated_at.toInstant(), -) - -fun AccessibilityAllowedRegion.toPersistenceModel() = Accessibility_allowed_region( - id = id, - name = name, - boundary_vertices = boundaryVertices, - created_at = createdAt.toOffsetDateTime(), - updated_at = updatedAt.toOffsetDateTime(), -) - -fun Accessibility_allowed_region.toDomainModel() = AccessibilityAllowedRegion( - id = id, - name = name, - boundaryVertices = boundary_vertices, - createdAt = created_at.toInstant(), - updatedAt = updated_at.toInstant(), -) - -fun AccessibilityImageFaceBlurringHistory.toPersistenceModel() = Accessibility_image_face_blurring_history( - id = id, - place_accessibility_id = placeAccessibilityId, - building_accessibility_id = buildingAccessibilityId, - original_image_urls = originalImageUrls, - blurred_image_urls = blurredImageUrls, - detected_people_counts = detectedPeopleCounts, - created_at = createdAt.toOffsetDateTime(), - updated_at = updatedAt.toOffsetDateTime(), -) - -fun FindLatestPlaceHistory.toDomainModel() = AccessibilityImageFaceBlurringHistory( - id = id, - placeAccessibilityId = place_accessibility_id, - buildingAccessibilityId = building_accessibility_id, - originalImageUrls = original_image_urls, - blurredImageUrls = blurred_image_urls, - detectedPeopleCounts = detected_people_counts, - createdAt = created_at.toInstant(), - updatedAt = updated_at.toInstant(), -) - -fun FindLatestBuildingHistory.toDomainModel() = AccessibilityImageFaceBlurringHistory( - id = id, - placeAccessibilityId = place_accessibility_id, - buildingAccessibilityId = building_accessibility_id, - originalImageUrls = original_image_urls, - blurredImageUrls = blurred_image_urls, - detectedPeopleCounts = detected_people_counts, - createdAt = created_at.toInstant(), - updatedAt = updated_at.toInstant(), -) - -fun Accessibility_image_face_blurring_history.toDomainModel() = AccessibilityImageFaceBlurringHistory( - id = id, - placeAccessibilityId = place_accessibility_id, - buildingAccessibilityId = building_accessibility_id, - originalImageUrls = original_image_urls, - blurredImageUrls = blurred_image_urls, - detectedPeopleCounts = detected_people_counts, - createdAt = created_at.toInstant(), - updatedAt = updated_at.toInstant(), -) diff --git a/app-server/subprojects/bounded_context/place_search/infra/src/integrationTest/kotlin/club/staircrusher/place_search/infra/adapter/in/controller/SearchPlacesTest.kt b/app-server/subprojects/bounded_context/place_search/infra/src/integrationTest/kotlin/club/staircrusher/place_search/infra/adapter/in/controller/SearchPlacesTest.kt index 05f0505b8..0c408901e 100644 --- a/app-server/subprojects/bounded_context/place_search/infra/src/integrationTest/kotlin/club/staircrusher/place_search/infra/adapter/in/controller/SearchPlacesTest.kt +++ b/app-server/subprojects/bounded_context/place_search/infra/src/integrationTest/kotlin/club/staircrusher/place_search/infra/adapter/in/controller/SearchPlacesTest.kt @@ -1,16 +1,15 @@ package club.staircrusher.place_search.infra.adapter.`in`.controller import club.staircrusher.api.converter.toDTO +import club.staircrusher.api.spec.dto.PlaceListItem +import club.staircrusher.api.spec.dto.SearchPlaceFilterDto import club.staircrusher.api.spec.dto.SearchPlacesPost200Response import club.staircrusher.api.spec.dto.SearchPlacesPostRequest -import club.staircrusher.api.spec.dto.SearchPlaceFilterDto -import club.staircrusher.api.spec.dto.PlaceListItem import club.staircrusher.place.application.port.out.persistence.PlaceRepository import club.staircrusher.place.application.port.out.web.MapsService import club.staircrusher.place.domain.model.BuildingAddress import club.staircrusher.place_search.infra.adapter.`in`.controller.base.PlaceSearchITBase import club.staircrusher.stdlib.testing.SccRandom -import club.staircrusher.accessibility.application.port.out.persistence.PlaceAccessibilityRepository import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertFalse @@ -25,9 +24,6 @@ class SearchPlacesTest : PlaceSearchITBase() { @Autowired private lateinit var placeRepository: PlaceRepository - @Autowired - private lateinit var placeAccessibilityRepository: PlaceAccessibilityRepository - @SpyBean private lateinit var mapsService: MapsService diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/kotlin/club/staircrusher/infra/persistence/sqldelight/DB.kt b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/kotlin/club/staircrusher/infra/persistence/sqldelight/DB.kt index 47ce08f63..d7af5646b 100644 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/kotlin/club/staircrusher/infra/persistence/sqldelight/DB.kt +++ b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/kotlin/club/staircrusher/infra/persistence/sqldelight/DB.kt @@ -5,19 +5,10 @@ import club.staircrusher.challenge.domain.model.ChallengeCondition import club.staircrusher.challenge.domain.model.ChallengeCrusherGroup import club.staircrusher.domain.server_event.ServerEventPayload import club.staircrusher.domain.server_event.ServerEventType -import club.staircrusher.infra.persistence.sqldelight.column_adapter.AccessibilityImageListStringColumnAdapter -import club.staircrusher.infra.persistence.sqldelight.column_adapter.EntranceDoorTypeListStringColumnAdapter import club.staircrusher.infra.persistence.sqldelight.column_adapter.IntListToTextColumnAdapter import club.staircrusher.infra.persistence.sqldelight.column_adapter.ListToTextColumnAdapter -import club.staircrusher.infra.persistence.sqldelight.column_adapter.LocationListToTextColumnAdapter -import club.staircrusher.infra.persistence.sqldelight.column_adapter.StairHeightLevelStringColumnAdapter -import club.staircrusher.infra.persistence.sqldelight.column_adapter.StringListToTextColumnAdapter -import club.staircrusher.infra.persistence.sqldelight.migration.Accessibility_allowed_region -import club.staircrusher.infra.persistence.sqldelight.migration.Accessibility_image_face_blurring_history -import club.staircrusher.infra.persistence.sqldelight.migration.Building_accessibility import club.staircrusher.infra.persistence.sqldelight.migration.Challenge import club.staircrusher.infra.persistence.sqldelight.migration.External_accessibility -import club.staircrusher.infra.persistence.sqldelight.migration.Place_accessibility import club.staircrusher.infra.persistence.sqldelight.migration.Server_event import club.staircrusher.stdlib.di.annotation.Component import club.staircrusher.stdlib.external_accessibility.ExternalAccessibilityCategory @@ -33,25 +24,6 @@ class DB(dataSource: DataSource) { private val driver = SqlDelightJdbcDriver(dataSource) private val scc = scc( driver = driver, - place_accessibilityAdapter = Place_accessibility.Adapter( - image_urlsAdapter = StringListToTextColumnAdapter, - imagesAdapter = AccessibilityImageListStringColumnAdapter, - floorsAdapter = IntListToTextColumnAdapter, - stair_height_levelAdapter = StairHeightLevelStringColumnAdapter, - entrance_door_typesAdapter = EntranceDoorTypeListStringColumnAdapter, - ), - building_accessibilityAdapter = Building_accessibility.Adapter( - entrance_image_urlsAdapter = StringListToTextColumnAdapter, - elevator_image_urlsAdapter = StringListToTextColumnAdapter, - entrance_stair_height_levelAdapter = StairHeightLevelStringColumnAdapter, - entrance_door_typesAdapter = EntranceDoorTypeListStringColumnAdapter, - elevator_stair_height_levelAdapter = StairHeightLevelStringColumnAdapter, - entrance_imagesAdapter = AccessibilityImageListStringColumnAdapter, - elevator_imagesAdapter = AccessibilityImageListStringColumnAdapter, - ), - accessibility_allowed_regionAdapter = Accessibility_allowed_region.Adapter( - boundary_verticesAdapter = LocationListToTextColumnAdapter, - ), challengeAdapter = Challenge.Adapter( milestonesAdapter = IntListToTextColumnAdapter, crusher_groupAdapter = object : ColumnAdapter { @@ -103,22 +75,8 @@ class DB(dataSource: DataSource) { } } ), - accessibility_image_face_blurring_historyAdapter = Accessibility_image_face_blurring_history.Adapter( - original_image_urlsAdapter = StringListToTextColumnAdapter, - blurred_image_urlsAdapter = StringListToTextColumnAdapter, - detected_people_countsAdapter = IntListToTextColumnAdapter, - ), ) - val accessibilityImageFaceBlurringHistoryQueries = scc.accessibilityImageFaceBlurringHistoryQueries - val buildingAccessibilityQueries = scc.buildingAccessibilityQueries - val buildingAccessibilityCommentQueries = scc.buildingAccessibilityCommentQueries - val buildingAccessibilityUpvoteQueries = scc.buildingAccessibilityUpvoteQueries - val placeAccessibilityQueries = scc.placeAccessibilityQueries - val placeAccessibilityCommentQueries = scc.placeAccessibilityCommentQueries - val placeAccessibilityUpvoteQueries = scc.placeAccessibilityUpvoteQueries - val accessibilityRankQueries = scc.accessibilityRankQueries - val accessibilityAllowedRegionQueries = scc.accessibilityAllowedRegionQueries val challengeQueries = scc.challengeQueries val challengeContributionQueries = scc.challengeContributionQueries val challengeParticipationQueries = scc.challengeParticipationQueries diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/migration/V30__place_accessibility_floors_nullable.sqm b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/migration/V30__place_accessibility_floors_nullable.sqm new file mode 100644 index 000000000..fb77dfc8b --- /dev/null +++ b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/migration/V30__place_accessibility_floors_nullable.sqm @@ -0,0 +1,12 @@ +import kotlin.Int; +import kotlin.collections.List; + +ALTER TABLE place_accessibility + ALTER COLUMN floors DROP NOT NULL, + ALTER COLUMN floors SET DEFAULT NULL, + ALTER COLUMN entrance_door_types DROP NOT NULL, + ALTER COLUMN entrance_door_types SET DEFAULT NULL; + +ALTER TABLE building_accessibility + ALTER COLUMN entrance_door_types DROP NOT NULL, + ALTER COLUMN entrance_door_types SET DEFAULT NULL; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityAllowedRegion.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityAllowedRegion.sq deleted file mode 100644 index 260a42a44..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityAllowedRegion.sq +++ /dev/null @@ -1,25 +0,0 @@ -save: -INSERT INTO accessibility_allowed_region -VALUES :accessibility_allowed_region -ON CONFLICT(id) DO UPDATE SET - id = EXCLUDED.id, - name = EXCLUDED.name, - boundary_vertices = EXCLUDED.boundary_vertices, - created_at = EXCLUDED.created_at, - updated_at = EXCLUDED.updated_at; - -removeAll: -DELETE FROM accessibility_allowed_region; - -remove: -DELETE FROM accessibility_allowed_region -WHERE id = :id; - -findById: -SELECT * -FROM accessibility_allowed_region -WHERE id = :id; - -findAll: -SELECT * -FROM accessibility_allowed_region; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityImageFaceBlurringHistory.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityImageFaceBlurringHistory.sq deleted file mode 100644 index 3e4a6a66e..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityImageFaceBlurringHistory.sq +++ /dev/null @@ -1,47 +0,0 @@ -save: -INSERT INTO accessibility_image_face_blurring_history -VALUES :accessibility_image_face_blurring_history -ON CONFLICT(id) DO UPDATE SET - place_accessibility_id = EXCLUDED.place_accessibility_id, - building_accessibility_id = EXCLUDED.building_accessibility_id, - original_image_urls = EXCLUDED.original_image_urls, - blurred_image_urls = EXCLUDED.blurred_image_urls, - detected_people_counts = EXCLUDED.detected_people_counts, - created_at = EXCLUDED.created_at, - updated_at = EXCLUDED.updated_at; - -removeAll: -DELETE FROM accessibility_image_face_blurring_history; - -findAll: -SELECT * -FROM accessibility_image_face_blurring_history; - -findById: -SELECT h.* -FROM accessibility_image_face_blurring_history h -WHERE h.id = :id; - -findByPlaceAccessibility: -SELECT h.* -FROM accessibility_image_face_blurring_history h -WHERE h.place_accessibility_id = :place_accessibility_id; - -findByBuildingAccessilbility: -SELECT h.* -FROM accessibility_image_face_blurring_history h -WHERE h.building_accessibility_id = :building_accessibility_id; - -findLatestPlaceHistory: -SELECT h.* -FROM accessibility_image_face_blurring_history h -WHERE h.place_accessibility_id IS NOT NULL -ORDER BY h.created_at DESC -LIMIT 1; - -findLatestBuildingHistory: -SELECT * -FROM accessibility_image_face_blurring_history h -WHERE h.building_accessibility_id IS NOT NULL -ORDER BY h.created_at DESC -LIMIT 1; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityRank.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityRank.sq deleted file mode 100644 index ff81d3e15..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/AccessibilityRank.sq +++ /dev/null @@ -1,51 +0,0 @@ -save: -INSERT INTO accessibility_rank -VALUES :accessibility_rank -ON CONFLICT(id) DO UPDATE SET - user_id = EXCLUDED.user_id, - conquered_count = EXCLUDED.conquered_count, - rank = EXCLUDED.rank, - created_at = EXCLUDED.created_at, - updated_at = EXCLUDED.updated_at; - -removeAll: -DELETE FROM accessibility_rank; - -findById: -SELECT * -FROM accessibility_rank -WHERE accessibility_rank.id = :id; - -findByUserId: -SELECT * -FROM accessibility_rank -WHERE accessibility_rank.user_id = :user_id; - -findTopNUsers: -SELECT * -FROM accessibility_rank -ORDER BY accessibility_rank.rank ASC -LIMIT :n; - -findByRank: -SELECT * -FROM accessibility_rank -WHERE accessibility_rank.rank = :rank -LIMIT 1; - -findNextRank: -SELECT * -FROM accessibility_rank -WHERE accessibility_rank.rank < :rank -ORDER BY accessibility_rank.rank DESC -LIMIT 1; - -findAll: -SELECT * -FROM accessibility_rank; - -findByConqueredCount: -SELECT * -FROM accessibility_rank -WHERE accessibility_rank.conquered_count = :conquered_count -LIMIT 1; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibility.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibility.sq deleted file mode 100644 index 184f5dcdd..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibility.sq +++ /dev/null @@ -1,118 +0,0 @@ -save: -INSERT INTO building_accessibility -VALUES :building_accessibility -ON CONFLICT(id) DO UPDATE SET - building_id = EXCLUDED.building_id, - entrance_stair_info = EXCLUDED.entrance_stair_info, - entrance_image_urls = EXCLUDED.entrance_image_urls, - entrance_images = EXCLUDED.entrance_images, - has_slope = EXCLUDED.has_slope, - has_elevator = EXCLUDED.has_elevator, - elevator_stair_info = EXCLUDED.elevator_stair_info, - elevator_image_urls = EXCLUDED.elevator_image_urls, - elevator_images = EXCLUDED.elevator_images, - user_id = EXCLUDED.user_id, - created_at = EXCLUDED.created_at, - deleted_at = NULL; - -removeAll: -DELETE FROM building_accessibility; - -findById: -SELECT * -FROM building_accessibility -WHERE building_accessibility.id = :id - AND deleted_at IS NULL; - -findByBuildingIds: -SELECT * -FROM building_accessibility -WHERE building_id IN :buildingIds - AND deleted_at IS NULL; - -findByBuildingId: -SELECT * -FROM building_accessibility -WHERE building_id = :buildingId - AND deleted_at IS NULL; - -findByPlaceIds: -SELECT building_accessibility.* -FROM building_accessibility - JOIN building ON building.id = building_accessibility.building_id - JOIN place ON place.building_id = building.id -WHERE place.id IN :placeIds - AND building_accessibility.deleted_at IS NULL; - -findByUserIdAndCreatedAtBetween: -SELECT ba.* -FROM building_accessibility ba -WHERE - ba.user_id = :userId - AND ba.created_at >= :from - AND ba.created_at <=:to - AND ba.deleted_at IS NULL; - -findByEupMyeonDong: -SELECT building_accessibility.* -FROM building_accessibility - JOIN building ON building.id = building_accessibility.building_id -WHERE building.eup_myeon_dong_id = :eupMyeonDongId - AND building_accessibility.deleted_at IS NULL; - -findByCreatedAtGreaterThanAndOrderByCreatedAtAsc: -SELECT * -FROM building_accessibility ba -WHERE - ba.created_at > :createdAt - AND ba.deleted_at IS NULL -ORDER BY ba.created_at ASC, ba.id DESC -LIMIT :limit; - -findAll: -SELECT * -FROM building_accessibility; - -updateEntranceImages: -UPDATE building_accessibility -SET entrance_images = :entranceImages -WHERE id = :id; - -updateEntranceImageUrlsAndImages: -UPDATE building_accessibility -SET -entrance_image_urls = :entranceImageUrls, -entrance_images = :entranceImages -WHERE id = :id; - -updateElevatorImages: -UPDATE building_accessibility -SET elevator_images = :elevatorImages -WHERE id = :id; - -updateElevatorImageUrlsAndImages: -UPDATE building_accessibility -SET -elevator_image_urls = :elevatorImageUrls, -elevator_images = :elevatorImages -WHERE id = :id; - -countByUserId: -SELECT COUNT(1) -FROM building_accessibility -WHERE user_id = :userId - AND deleted_at IS NULL; - -countByUserIdAndCreatedAtBetween: -SELECT COUNT(1) -FROM building_accessibility ba -WHERE - ba.user_id = :userId - AND ba.created_at >= :from - AND ba.created_at <=:to - AND ba.deleted_at IS NULL; - -remove: -UPDATE building_accessibility -SET deleted_at = :deletedAt -WHERE id = :id; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityComment.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityComment.sq deleted file mode 100644 index 8c3b620fa..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityComment.sq +++ /dev/null @@ -1,30 +0,0 @@ -save: -INSERT INTO building_accessibility_comment -VALUES :building_accessibility_comment -ON CONFLICT(id) DO UPDATE SET - building_id = EXCLUDED.building_id, - user_id = EXCLUDED.user_id, - comment = EXCLUDED.comment, - created_at = EXCLUDED.created_at, - deleted_at = NULL; - -removeAll: -DELETE FROM building_accessibility_comment; - -findById: -SELECT * -FROM building_accessibility_comment -WHERE building_accessibility_comment.id = :id - AND deleted_at IS NULL; - -findByBuildingId: -SELECT * -FROM building_accessibility_comment -WHERE building_id = :buildingId - AND deleted_at IS NULL; - -removeByBuildingId: -UPDATE building_accessibility_comment -SET deleted_at = :deletedAt -WHERE building_id = :buildingId - AND deleted_at IS NULL; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityUpvote.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityUpvote.sq deleted file mode 100644 index 9a32251eb..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/BuildingAccessibilityUpvote.sq +++ /dev/null @@ -1,31 +0,0 @@ -save: -INSERT INTO building_accessibility_upvote -VALUES :building_accessibility_upvote -ON CONFLICT(id) DO UPDATE SET - user_id = EXCLUDED.user_id, - building_accessibility_id = EXCLUDED.building_accessibility_id, - created_at = EXCLUDED.created_at, - deleted_at = EXCLUDED.deleted_at; - -removeAll: -DELETE FROM building_accessibility_upvote; - -buildingAccessibilityUpvoteFindById: -SELECT * -FROM building_accessibility_upvote - JOIN building_accessibility ON building_accessibility.id = building_accessibility_upvote.building_accessibility_id -WHERE building_accessibility_upvote.id = :id; - -findByUserAndBuildingAccessibilityAndNotDeleted: -SELECT * -FROM building_accessibility_upvote - JOIN building_accessibility ON building_accessibility.id = building_accessibility_upvote.building_accessibility_id -WHERE - building_accessibility_upvote.user_id = :userId - AND building_accessibility_upvote.building_accessibility_id = :buildingAccessibilityId - AND building_accessibility_upvote.deleted_at IS NULL; - -countUpvotes: -SELECT COUNT(1) -FROM building_accessibility_upvote -WHERE building_accessibility_id = :buildingAccessibilityId; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibility.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibility.sq deleted file mode 100644 index 2f8a80477..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibility.sq +++ /dev/null @@ -1,136 +0,0 @@ -save: -INSERT INTO place_accessibility -VALUES :place_accessibility -ON CONFLICT(id) DO UPDATE SET - place_id = EXCLUDED.place_id, - floors = EXCLUDED.floors, - is_first_floor = EXCLUDED.is_first_floor, - is_stair_only_option = EXCLUDED.is_stair_only_option, - stair_info = EXCLUDED.stair_info, - stair_height_level = EXCLUDED.stair_height_level, - has_slope = EXCLUDED.has_slope, - entrance_door_types = EXCLUDED.entrance_door_types, - image_urls = EXCLUDED.image_urls, - images = EXCLUDED.images, - user_id = EXCLUDED.user_id, - created_at = EXCLUDED.created_at, - deleted_at = NULL; - -removeAll: -DELETE FROM place_accessibility; - -findById: -SELECT * -FROM place_accessibility -WHERE place_accessibility.id = :id - AND deleted_at IS NULL; - -findByPlaceIds: -SELECT * -FROM place_accessibility -WHERE place_id IN :placeIds - AND deleted_at IS NULL; - -findByPlaceId: -SELECT * -FROM place_accessibility -WHERE place_id = :placeId - AND deleted_at IS NULL; - -findByUserId: -SELECT * -FROM place_accessibility -WHERE user_id = :userId - AND deleted_at IS NULL; - -findByUserIdAndCreatedAtBetween: -SELECT pa.* -FROM place_accessibility pa -WHERE - pa.user_id = :userId - AND pa.created_at >= :from - AND pa.created_at <=:to - AND pa.deleted_at IS NULL; - -findByCreatedAtGreaterThanAndOrderByCreatedAtAsc: -SELECT pa.* -FROM place_accessibility pa -WHERE - pa.created_at > :createdAt - AND pa.deleted_at IS NULL -ORDER BY pa.created_at ASC, pa.id DESC -LIMIT :limit; - -countByEupMyeonDong: -SELECT COUNT(1) -FROM place_accessibility - JOIN place ON place.id = place_accessibility.place_id -WHERE place.eup_myeon_dong_id = :eupMyeonDongId - AND place_accessibility.deleted_at IS NULL; - -countByUserId: -SELECT COUNT(1) -FROM place_accessibility -WHERE user_id = :userId - AND deleted_at IS NULL; - -hasAccessibilityNotRegisteredPlaceInBuilding: -SELECT count(p.id) > 0 -FROM place p -INNER JOIN building b ON b.id = :buildingId AND b.id = p.building_id -LEFT OUTER JOIN place_accessibility pa ON p.id = pa.place_id -WHERE pa.id IS NULL - AND pa.deleted_at IS NULL; - -findByBuildingId: -SELECT pa.* -FROM place_accessibility pa -INNER JOIN place p ON p.id = pa.place_id -INNER JOIN building b ON b.id = p.building_id -WHERE b.id = :buildingId - AND pa.deleted_at IS NULL; - -searchForAdmin: -SELECT pa.* -FROM place_accessibility pa -INNER JOIN place p ON p.id = pa.place_id -WHERE - (:placeNameLike IS NULL OR p.name LIKE :placeNameLike) - AND (:createdAtFrom IS NULL OR pa.created_at >= :createdAtFrom) - AND (:createdAtToExclusive IS NULL OR pa.created_at < :createdAtToExclusive) - AND ( - (pa.created_at = :cursorCreatedAt AND pa.id < :cursorId) - OR (pa.created_at < :cursorCreatedAt) - ) - AND pa.deleted_at IS NULL -ORDER BY pa.created_at DESC, pa.id DESC -LIMIT :limit; - -updateImages: -UPDATE place_accessibility -SET images = :images -WHERE id = :id; - -updateImageUrlsAndImages: -UPDATE place_accessibility -SET image_urls = :imageUrls, images = :images -WHERE id = :id; - -countAll: -SELECT COUNT(*) -FROM place_accessibility pa -WHERE pa.deleted_at IS NULL; - -countByUserIdAndCreatedAtBetween: -SELECT COUNT(1) -FROM place_accessibility pa -WHERE - pa.user_id = :userId - AND pa.created_at >= :from - AND pa.created_at <=:to - AND pa.deleted_at IS NULL; - -remove: -UPDATE place_accessibility -SET deleted_at = :deletedAt -WHERE id = :id; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityComment.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityComment.sq deleted file mode 100644 index 442dca40a..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityComment.sq +++ /dev/null @@ -1,30 +0,0 @@ -save: -INSERT INTO place_accessibility_comment -VALUES :place_accessibility_comment -ON CONFLICT(id) DO UPDATE SET - place_id = EXCLUDED.place_id, - user_id = EXCLUDED.user_id, - comment = EXCLUDED.comment, - created_at = EXCLUDED.created_at, - deleted_at = NULL; - -removeAll: -DELETE FROM place_accessibility_comment; - -findById: -SELECT * -FROM place_accessibility_comment -WHERE place_accessibility_comment.id = :id - AND deleted_at IS NULL; - -findByPlaceId: -SELECT * -FROM place_accessibility_comment -WHERE place_id = :placeId - AND deleted_at IS NULL; - -removeByPlaceId: -UPDATE place_accessibility_comment -SET deleted_at = :deletedAt -WHERE place_id = :placeId - AND deleted_at IS NULL; diff --git a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityUpvote.sq b/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityUpvote.sq deleted file mode 100644 index 6e7142986..000000000 --- a/app-server/subprojects/cross_cutting_concern/infra/persistence_model/src/main/sqldelight/club/staircrusher/infra/persistence/sqldelight/query/accessibility/PlaceAccessibilityUpvote.sq +++ /dev/null @@ -1,29 +0,0 @@ -save: -INSERT INTO place_accessibility_upvote -VALUES :place_accessibility_upvote -ON CONFLICT(id) DO UPDATE SET - user_id = EXCLUDED.user_id, - place_accessibility_id = EXCLUDED.place_accessibility_id, - created_at = EXCLUDED.created_at, - deleted_at = EXCLUDED.deleted_at; - -removeAll: -DELETE FROM place_accessibility_upvote; - -findUpvoteById: -SELECT * -FROM place_accessibility_upvote -WHERE place_accessibility_upvote.id = :id; - -findUpvoteByUserIdAndPlaceAccessilbityIdAndNotDeleted: -SELECT * -FROM place_accessibility_upvote -WHERE - place_accessibility_upvote.user_id = :userId - AND place_accessibility_upvote.place_accessibility_id = :placeAccessibilityId - AND place_accessibility_upvote.deleted_at IS NULL; - -countUpvotes: -SELECT COUNT(1) -FROM place_accessibility_upvote -WHERE place_accessibility_id = :placeAccessibilityId; diff --git a/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/IntListToTextAttributeConverter.kt b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/IntListToTextAttributeConverter.kt new file mode 100644 index 000000000..7c34261bf --- /dev/null +++ b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/IntListToTextAttributeConverter.kt @@ -0,0 +1,14 @@ +package club.staircrusher.stdlib.jpa + +import jakarta.persistence.Converter + +@Converter +object IntListToTextAttributeConverter : ListToTextAttributeConverter() { + override fun convertElementToTextColumn(element: Int): String { + return element.toString() + } + + override fun convertElementFromTextColumn(text: String): Int { + return text.toInt() + } +} diff --git a/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/ListToTextAttributeConverter.kt b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/ListToTextAttributeConverter.kt index 7702f4801..220065f57 100644 --- a/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/ListToTextAttributeConverter.kt +++ b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/ListToTextAttributeConverter.kt @@ -6,9 +6,9 @@ import com.fasterxml.jackson.module.kotlin.readValue import jakarta.persistence.AttributeConverter abstract class ListToTextAttributeConverter : AttributeConverter, String> { - override fun convertToDatabaseColumn(attribute: List): String { + override fun convertToDatabaseColumn(attribute: List?): String? { // return objectMapper.writeValueAsString(attribute) // FIXME: json으로 바꾸기 - return attribute.joinToString(LEGACY_DELIMITER) { convertElementToTextColumn(it) } + return attribute?.joinToString(LEGACY_DELIMITER) { convertElementToTextColumn(it) } } override fun convertToEntityAttribute(column: String?): List { diff --git a/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/LocationListToTextAttributeConverter.kt b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/LocationListToTextAttributeConverter.kt new file mode 100644 index 000000000..e4f8ae16a --- /dev/null +++ b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/LocationListToTextAttributeConverter.kt @@ -0,0 +1,16 @@ +package club.staircrusher.stdlib.jpa + +import club.staircrusher.stdlib.geography.Location +import jakarta.persistence.Converter + +@Converter +object LocationListToTextAttributeConverter : ListToTextAttributeConverter() { + override fun convertElementToTextColumn(element: Location): String { + return with(element) { "$lng/$lat" } + } + + override fun convertElementFromTextColumn(text: String): Location { + val (lngStr, latStr) = text.split("/") + return Location(lngStr.toDouble(), latStr.toDouble()) + } +} diff --git a/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/StringListToTextAttributeConverter.kt b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/StringListToTextAttributeConverter.kt new file mode 100644 index 000000000..524c6c9cb --- /dev/null +++ b/app-server/subprojects/cross_cutting_concern/stdlib/src/main/kotlin/club/staircrusher/stdlib/jpa/StringListToTextAttributeConverter.kt @@ -0,0 +1,14 @@ +package club.staircrusher.stdlib.jpa + +import jakarta.persistence.Converter + +@Converter +object StringListToTextAttributeConverter : ListToTextAttributeConverter() { + override fun convertElementToTextColumn(element: String): String { + return element + } + + override fun convertElementFromTextColumn(text: String): String { + return text + } +} diff --git a/app-server/subprojects/cross_cutting_concern/test/spring_it/src/main/kotlin/club/staircrusher/testing/spring_it/ITDataGenerator.kt b/app-server/subprojects/cross_cutting_concern/test/spring_it/src/main/kotlin/club/staircrusher/testing/spring_it/ITDataGenerator.kt index fa3b02725..8aee42ad1 100644 --- a/app-server/subprojects/cross_cutting_concern/test/spring_it/src/main/kotlin/club/staircrusher/testing/spring_it/ITDataGenerator.kt +++ b/app-server/subprojects/cross_cutting_concern/test/spring_it/src/main/kotlin/club/staircrusher/testing/spring_it/ITDataGenerator.kt @@ -362,7 +362,7 @@ class ITDataGenerator { user: User? = null, at: Instant = clock.instant(), ): BuildingAccessibility { - return buildingAccessibilityRepository.findByBuildingId(building.id) ?: buildingAccessibilityRepository.save( + return buildingAccessibilityRepository.findFirstByBuildingIdAndDeletedAtIsNull(building.id) ?: buildingAccessibilityRepository.save( BuildingAccessibility( id = EntityIdGenerator.generateRandom(), buildingId = building.id, @@ -441,7 +441,7 @@ class ITDataGenerator { BuildingAccessibilityUpvote( id = EntityIdGenerator.generateRandom(), userId = user.id, - buildingAccessibility = buildingAccessibility, + buildingAccessibilityId = buildingAccessibility.id, createdAt = clock.instant(), ), ) diff --git a/app-server/subprojects/deploying_apps/local_script/src/main/kotlin/club/staircrusher/data_restore/AccessibilityInserter.kt b/app-server/subprojects/deploying_apps/local_script/src/main/kotlin/club/staircrusher/data_restore/AccessibilityInserter.kt index 84d25e5c4..088556ba6 100644 --- a/app-server/subprojects/deploying_apps/local_script/src/main/kotlin/club/staircrusher/data_restore/AccessibilityInserter.kt +++ b/app-server/subprojects/deploying_apps/local_script/src/main/kotlin/club/staircrusher/data_restore/AccessibilityInserter.kt @@ -1,197 +1,197 @@ package club.staircrusher.data_restore -import club.staircrusher.accessibility.domain.model.AccessibilityImage -import club.staircrusher.accessibility.domain.model.BuildingAccessibility -import club.staircrusher.accessibility.domain.model.PlaceAccessibility -import club.staircrusher.accessibility.domain.model.StairInfo -import club.staircrusher.place.application.port.out.web.MapsService -import club.staircrusher.place.domain.model.Building -import club.staircrusher.place.infra.adapter.out.web.KakaoMapsService -import club.staircrusher.place.infra.adapter.out.web.KakaoProperties -import club.staircrusher.readTsvAsLines -import club.staircrusher.stdlib.domain.entity.EntityIdGenerator -import club.staircrusher.toKstString -import club.staircrusher.writeTextAsFile -import kotlinx.coroutines.runBlocking -import java.time.Instant - -val kakaoMapsService = KakaoMapsService( - KakaoProperties("dummy") -) - -fun main() { - writePlaceAccessibilityInsertQueries() - writeBuildingAccessibilityInsertQueries() -} - -private fun writePlaceAccessibilityInsertQueries() { - val places = parseTsvToPlaceList() - writeTextAsFile(places.joinToString("\n") { it.toInsertQuery() }, "insert_place_accessibilities_2023.sql") -} - -private fun parseTsvToPlaceList(): List { - val lines = readTsvAsLines("data_restore/AccessibilityInserter/place_accessibilities.tsv") - // 행 고유번호 빈 column 빈 column 담당자 생성시간 윗 사진과의 등록 시차 이미지 건물장소번호 식별정보 1 장소명 (카카오지도명과 동일하게 입력 도로명 주소 1층여부: 1층=1, 1층 아님 2 계단 수 (눈에 보이는 숫자) 경사로 유무 = 있음 1, 없음 2 - val errorMessages = mutableListOf() - val result = lines.map { line -> - val imageUrls = line[1].split(",") - val images = imageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } - val placeName = line[2] - val address = line[3] - val isFirstFloor = when (val rawIsFirstFloor = line[4]) { - "1" -> true - "2" -> false - else -> throw IllegalArgumentException("Invalid isFirstFloor value: $rawIsFirstFloor") - } - val stairInfo = line[5].parseToStairInfo() - val hasSlope = when (val rawHasSlope = line[6]) { - "1" -> true - "2" -> false - else -> throw IllegalArgumentException("Invalid hasSlope value: $rawHasSlope") - } - val userName = line[9] - val userId = userName.parseToUserId() - - // TODO: 새로운 필드 채우기? - Pair(placeName, PlaceAccessibility( - id = EntityIdGenerator.generateRandom(), - placeId = "", // 지도 api를 대량으로 호출하기 전에 파싱 성공을 확인하기 위해 placeId를 제외한 필드부터 채운다. - floors = null, - isFirstFloor = isFirstFloor, - isStairOnlyOption = null, - stairInfo = stairInfo, - stairHeightLevel = null, - hasSlope = hasSlope, - imageUrls = imageUrls, - images = images, - userId = userId, - createdAt = Instant.now(), - entranceDoorTypes = null, - deletedAt = null, - )) - } - .map { (placeName, placeAccessibility) -> - val placeId: String by lazy { - runBlocking { - kakaoMapsService.findFirstByKeyword(placeName, option = MapsService.SearchByKeywordOption()) - }?.id ?: run { - errorMessages.add("No matching place for $placeName") - "" - } - // TODO: address랑 검색 결과의 주소랑 비교하기? - } - placeAccessibility.copy(placeId = placeId) - } - .filter { it.placeId.isNotBlank() } - .groupBy { it.placeId } - .map { (_, value) -> - value[0].copy(imageUrls = value.flatMap { it.imageUrls }.distinct()) - } - - System.err.println(errorMessages) - - return result -} - -private fun PlaceAccessibility.toInsertQuery(): String { - return "INSERT INTO place_accessibility VALUES (" + - "'$id'," + // id - "'$placeId'," + // place_id - "$isFirstFloor," + // is_first_floor - "'$stairInfo'," + // stair_info - "$hasSlope," + // has_slope - "NULL," + // user_id - "'${createdAt.toKstString()}'," + // created_at - "'${createdAt.toKstString()}'," + // updated_at - "'${imageUrls.joinToString(",,")}'," + // image_urls - "NULL" + // deleted_at - ");" -} - -private fun writeBuildingAccessibilityInsertQueries() { - val buildingAccessibilities = parseTsvToBuildingList() - writeTextAsFile(buildingAccessibilities.joinToString("\n") { it.toInsertQuery() }, "insert_building_accessibilities_2023.sql") -} - -private fun parseTsvToBuildingList(): List { - val lines = readTsvAsLines("data_restore/AccessibilityInserter/building_accessibilities.tsv") - // 행 고유번호 빈 column 빈 column 담당자 생성시간 윗 사진과의 등록 시차 이미지 건물장소번호 식별정보 2 건물 추측한 방법 (ㅇㅇ빌딩, 장소기반 등) 건물 도로명 주소 입구계단수 경사로 유무 = 있음 1, 없음 2 엘리베이터 유무 = 있음 1, 없음 2 엘리베이터까지 계단 개수 - return lines.map { line -> - val imageUrls = line[6].split(",") - val roadAddress = line[10] - val entranceStairInfo = line[11].parseToStairInfo() - val hasSlope = when (val rawHasSlope = line[12]) { - "1" -> true - "2" -> false - else -> throw IllegalArgumentException("Invalid isFirstFloor value: $rawHasSlope") - } - val hasElevator = when (val rawHasElevator = line[13]) { - "1" -> true - "2" -> false - else -> throw IllegalArgumentException("Invalid hasElevator value: $rawHasElevator") - } - val elevatorStairInfo = line[14].parseToStairInfo() - - // TODO: 새로운 필드 채우기? - BuildingAccessibility( - id = EntityIdGenerator.generateRandom(), - buildingId = Building.generateId(roadAddress), - entranceStairInfo = entranceStairInfo, - entranceStairHeightLevel = null, - entranceImageUrls = imageUrls, // TODO: 입구 사진과 엘레베이터 사진으로 나누기 - entranceImages = imageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) }, - hasSlope = hasSlope, - hasElevator = hasElevator, - entranceDoorTypes = emptyList(), - elevatorStairInfo = elevatorStairInfo, - elevatorStairHeightLevel = null, - elevatorImageUrls = emptyList(), - elevatorImages = emptyList(), - userId = null, - createdAt = Instant.now(), - deletedAt = null, - ) - } - .groupBy { it.buildingId } - .map { (_, value) -> - value[0].copy( - entranceImageUrls = value.flatMap { it.entranceImageUrls }.distinct(), - elevatorImageUrls = value.flatMap { it.elevatorImageUrls }.distinct(), - ) - } -} - -private fun BuildingAccessibility.toInsertQuery(): String { - return "INSERT INTO building_accessibility VALUES (" + - "'$id'," + // id - "'$buildingId'," + // building_id - "'$entranceStairInfo'," + // entrance_stair_info - "$hasSlope," + // has_slope - "$hasElevator," + // has_elevator - "'$elevatorStairInfo'," + // elevator_stair_info - "NULL," + // user_id - "'${createdAt.toKstString()}'," + // created_at - "'${createdAt.toKstString()}'," + // updated_at - "'${entranceImageUrls.joinToString(",,")}'," + // entrance_image_urls - "'${elevatorImageUrls.joinToString(",,")}'," + // elevator_image_urls - "NULL" + // deleted_at - ");" -} - -private fun String.parseToStairInfo() = when (this.toInt()) { - 0 -> StairInfo.NONE - 1 -> StairInfo.ONE - in 2..5 -> StairInfo.TWO_TO_FIVE - in 6..Int.MAX_VALUE -> StairInfo.OVER_SIX - else -> throw IllegalArgumentException("Invalid stairInfo value: $this") -} - -private fun String.parseToUserId() = when (this) { - "" -> null - "23봄시즌" -> "6d0385e8-551a-45d4-bfb3-0829e22637ca" - "23봄시즌_강남지부" -> "e81b400b-5814-4e65-823b-8420be623f9e" - "23봄시즌_관악지부" -> "5078c2e3-0ecd-41bb-a114-fbc608b9d04a" - "23봄시즌_성남지부" -> "45345588-2e31-4e69-9e31-23a229b806ec" - "23봄시즌_도봉지부" -> "00d8357c-c936-4311-9517-962c9415387a" - else -> throw IllegalArgumentException("Invalid userName value: $this") -} +//import club.staircrusher.accessibility.domain.model.AccessibilityImage +//import club.staircrusher.accessibility.domain.model.BuildingAccessibility +//import club.staircrusher.accessibility.domain.model.PlaceAccessibility +//import club.staircrusher.accessibility.domain.model.StairInfo +//import club.staircrusher.place.application.port.out.web.MapsService +//import club.staircrusher.place.domain.model.Building +//import club.staircrusher.place.infra.adapter.out.web.KakaoMapsService +//import club.staircrusher.place.infra.adapter.out.web.KakaoProperties +//import club.staircrusher.readTsvAsLines +//import club.staircrusher.stdlib.domain.entity.EntityIdGenerator +//import club.staircrusher.toKstString +//import club.staircrusher.writeTextAsFile +//import kotlinx.coroutines.runBlocking +//import java.time.Instant +// +//val kakaoMapsService = KakaoMapsService( +// KakaoProperties("dummy") +//) +// +//fun main() { +// writePlaceAccessibilityInsertQueries() +// writeBuildingAccessibilityInsertQueries() +//} +// +//private fun writePlaceAccessibilityInsertQueries() { +// val places = parseTsvToPlaceList() +// writeTextAsFile(places.joinToString("\n") { it.toInsertQuery() }, "insert_place_accessibilities_2023.sql") +//} +// +//private fun parseTsvToPlaceList(): List { +// val lines = readTsvAsLines("data_restore/AccessibilityInserter/place_accessibilities.tsv") +// // 행 고유번호 빈 column 빈 column 담당자 생성시간 윗 사진과의 등록 시차 이미지 건물장소번호 식별정보 1 장소명 (카카오지도명과 동일하게 입력 도로명 주소 1층여부: 1층=1, 1층 아님 2 계단 수 (눈에 보이는 숫자) 경사로 유무 = 있음 1, 없음 2 +// val errorMessages = mutableListOf() +// val result = lines.map { line -> +// val imageUrls = line[1].split(",") +// val images = imageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) } +// val placeName = line[2] +// val address = line[3] +// val isFirstFloor = when (val rawIsFirstFloor = line[4]) { +// "1" -> true +// "2" -> false +// else -> throw IllegalArgumentException("Invalid isFirstFloor value: $rawIsFirstFloor") +// } +// val stairInfo = line[5].parseToStairInfo() +// val hasSlope = when (val rawHasSlope = line[6]) { +// "1" -> true +// "2" -> false +// else -> throw IllegalArgumentException("Invalid hasSlope value: $rawHasSlope") +// } +// val userName = line[9] +// val userId = userName.parseToUserId() +// +// // TODO: 새로운 필드 채우기? +// Pair(placeName, PlaceAccessibility( +// id = EntityIdGenerator.generateRandom(), +// placeId = "", // 지도 api를 대량으로 호출하기 전에 파싱 성공을 확인하기 위해 placeId를 제외한 필드부터 채운다. +// floors = null, +// isFirstFloor = isFirstFloor, +// isStairOnlyOption = null, +// stairInfo = stairInfo, +// stairHeightLevel = null, +// hasSlope = hasSlope, +// imageUrls = imageUrls, +// images = images, +// userId = userId, +// createdAt = Instant.now(), +// entranceDoorTypes = null, +// deletedAt = null, +// )) +// } +// .map { (placeName, placeAccessibility) -> +// val placeId: String by lazy { +// runBlocking { +// kakaoMapsService.findFirstByKeyword(placeName, option = MapsService.SearchByKeywordOption()) +// }?.id ?: run { +// errorMessages.add("No matching place for $placeName") +// "" +// } +// // TODO: address랑 검색 결과의 주소랑 비교하기? +// } +// placeAccessibility.copy(placeId = placeId) +// } +// .filter { it.placeId.isNotBlank() } +// .groupBy { it.placeId } +// .map { (_, value) -> +// value[0].copy(imageUrls = value.flatMap { it.imageUrls }.distinct()) +// } +// +// System.err.println(errorMessages) +// +// return result +//} +// +//private fun PlaceAccessibility.toInsertQuery(): String { +// return "INSERT INTO place_accessibility VALUES (" + +// "'$id'," + // id +// "'$placeId'," + // place_id +// "$isFirstFloor," + // is_first_floor +// "'$stairInfo'," + // stair_info +// "$hasSlope," + // has_slope +// "NULL," + // user_id +// "'${createdAt.toKstString()}'," + // created_at +// "'${createdAt.toKstString()}'," + // updated_at +// "'${imageUrls.joinToString(",,")}'," + // image_urls +// "NULL" + // deleted_at +// ");" +//} +// +//private fun writeBuildingAccessibilityInsertQueries() { +// val buildingAccessibilities = parseTsvToBuildingList() +// writeTextAsFile(buildingAccessibilities.joinToString("\n") { it.toInsertQuery() }, "insert_building_accessibilities_2023.sql") +//} +// +//private fun parseTsvToBuildingList(): List { +// val lines = readTsvAsLines("data_restore/AccessibilityInserter/building_accessibilities.tsv") +// // 행 고유번호 빈 column 빈 column 담당자 생성시간 윗 사진과의 등록 시차 이미지 건물장소번호 식별정보 2 건물 추측한 방법 (ㅇㅇ빌딩, 장소기반 등) 건물 도로명 주소 입구계단수 경사로 유무 = 있음 1, 없음 2 엘리베이터 유무 = 있음 1, 없음 2 엘리베이터까지 계단 개수 +// return lines.map { line -> +// val imageUrls = line[6].split(",") +// val roadAddress = line[10] +// val entranceStairInfo = line[11].parseToStairInfo() +// val hasSlope = when (val rawHasSlope = line[12]) { +// "1" -> true +// "2" -> false +// else -> throw IllegalArgumentException("Invalid isFirstFloor value: $rawHasSlope") +// } +// val hasElevator = when (val rawHasElevator = line[13]) { +// "1" -> true +// "2" -> false +// else -> throw IllegalArgumentException("Invalid hasElevator value: $rawHasElevator") +// } +// val elevatorStairInfo = line[14].parseToStairInfo() +// +// // TODO: 새로운 필드 채우기? +// BuildingAccessibility( +// id = EntityIdGenerator.generateRandom(), +// buildingId = Building.generateId(roadAddress), +// entranceStairInfo = entranceStairInfo, +// entranceStairHeightLevel = null, +// entranceImageUrls = imageUrls, // TODO: 입구 사진과 엘레베이터 사진으로 나누기 +// entranceImages = imageUrls.map { AccessibilityImage(imageUrl = it, thumbnailUrl = null) }, +// hasSlope = hasSlope, +// hasElevator = hasElevator, +// entranceDoorTypes = emptyList(), +// elevatorStairInfo = elevatorStairInfo, +// elevatorStairHeightLevel = null, +// elevatorImageUrls = emptyList(), +// elevatorImages = emptyList(), +// userId = null, +// createdAt = Instant.now(), +// deletedAt = null, +// ) +// } +// .groupBy { it.buildingId } +// .map { (_, value) -> +// value[0].copy( +// entranceImageUrls = value.flatMap { it.entranceImageUrls }.distinct(), +// elevatorImageUrls = value.flatMap { it.elevatorImageUrls }.distinct(), +// ) +// } +//} +// +//private fun BuildingAccessibility.toInsertQuery(): String { +// return "INSERT INTO building_accessibility VALUES (" + +// "'$id'," + // id +// "'$buildingId'," + // building_id +// "'$entranceStairInfo'," + // entrance_stair_info +// "$hasSlope," + // has_slope +// "$hasElevator," + // has_elevator +// "'$elevatorStairInfo'," + // elevator_stair_info +// "NULL," + // user_id +// "'${createdAt.toKstString()}'," + // created_at +// "'${createdAt.toKstString()}'," + // updated_at +// "'${entranceImageUrls.joinToString(",,")}'," + // entrance_image_urls +// "'${elevatorImageUrls.joinToString(",,")}'," + // elevator_image_urls +// "NULL" + // deleted_at +// ");" +//} +// +//private fun String.parseToStairInfo() = when (this.toInt()) { +// 0 -> StairInfo.NONE +// 1 -> StairInfo.ONE +// in 2..5 -> StairInfo.TWO_TO_FIVE +// in 6..Int.MAX_VALUE -> StairInfo.OVER_SIX +// else -> throw IllegalArgumentException("Invalid stairInfo value: $this") +//} +// +//private fun String.parseToUserId() = when (this) { +// "" -> null +// "23봄시즌" -> "6d0385e8-551a-45d4-bfb3-0829e22637ca" +// "23봄시즌_강남지부" -> "e81b400b-5814-4e65-823b-8420be623f9e" +// "23봄시즌_관악지부" -> "5078c2e3-0ecd-41bb-a114-fbc608b9d04a" +// "23봄시즌_성남지부" -> "45345588-2e31-4e69-9e31-23a229b806ec" +// "23봄시즌_도봉지부" -> "00d8357c-c936-4311-9517-962c9415387a" +// else -> throw IllegalArgumentException("Invalid userName value: $this") +//}