From 6383e7ab049fcdde2f578ac81e8d74e811964113 Mon Sep 17 00:00:00 2001 From: This2sho Date: Tue, 9 Apr 2024 01:19:39 +0900 Subject: [PATCH 01/19] =?UTF-8?q?refactor:=20=EB=A3=A8=ED=8A=B8=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 34 ++++++++++++++++++++++++++++++++-- settings.gradle | 2 ++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 089da741..c8e99b20 100644 --- a/build.gradle +++ b/build.gradle @@ -26,10 +26,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation group: 'org.hibernate.orm', name: 'hibernate-spatial', version: '6.3.1.Final' - compileOnly 'org.projectlombok:lombok' + runtimeOnly 'com.h2database:h2' runtimeOnly 'com.mysql:mysql-connector-j' - annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' @@ -49,6 +49,36 @@ dependencies { // flyway 추가 implementation 'org.flywaydb:flyway-mysql' implementation 'org.flywaydb:flyway-core' + + // lombok + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} + +subprojects { + group = 'com.parkingcomestrue' + version = '0.0.1-SNAPSHOT' + sourceCompatibility = '17' + + apply plugin: 'java' + + apply plugin: 'java-library' + apply plugin: 'org.springframework.boot' + + apply plugin: 'io.spring.dependency-management' + + + configurations { + compileOnly { + extendsFrom annotationProcessor + } + } + + + dependencies { + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + } } tasks.named('test') { diff --git a/settings.gradle b/settings.gradle index 8cb3c6ea..1cfafbbc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,3 @@ rootProject.name = 'parking' +include 'domain' + From 72ff933c027302d9754b00ccdadfa196abcfcf7c Mon Sep 17 00:00:00 2001 From: This2sho Date: Tue, 9 Apr 2024 01:22:12 +0900 Subject: [PATCH 02/19] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=EB=AA=A8=EB=93=88=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domain/.gitignore | 42 ++ domain/build.gradle | 20 + .../parking/domain/AuditingEntity.java | 21 + .../parking/domain/favorite/Favorite.java | 48 +++ .../repository/FavoriteRepository.java | 17 + .../parking/domain/member/Member.java | 74 ++++ .../parking/domain/member/Password.java | 41 ++ .../member/repository/MemberRepository.java | 22 + .../domain/parking/BaseInformation.java | 54 +++ .../parking/domain/parking/Day.java | 20 + .../parking/domain/parking/DayParking.java | 30 ++ .../parking/domain/parking/Fee.java | 58 +++ .../parking/domain/parking/FeePolicy.java | 81 ++++ .../domain/parking/FreeOperatingTime.java | 73 ++++ .../parking/domain/parking/Location.java | 68 +++ .../parking/domain/parking/OperatingTime.java | 66 +++ .../parking/domain/parking/OperationType.java | 23 + .../parking/domain/parking/Parking.java | 155 +++++++ .../domain/parking/ParkingFeeCalculator.java | 71 ++++ .../parking/domain/parking/ParkingType.java | 31 ++ .../parking/domain/parking/PayType.java | 25 ++ .../parking/domain/parking/PayTypes.java | 46 ++ .../domain/parking/SearchingCondition.java | 25 ++ .../parking/domain/parking/Space.java | 44 ++ .../parking/domain/parking/TimeInfo.java | 62 +++ .../parking/domain/parking/TimeUnit.java | 50 +++ .../parking/dto/ParkingQueryCondition.java | 23 + .../parking/repository/ParkingRepository.java | 45 ++ .../service/ParkingFilteringService.java | 37 ++ .../parking/domain/review/Content.java | 34 ++ .../parking/domain/review/Review.java | 61 +++ .../review/repository/ReviewRepository.java | 27 ++ .../review/service/ReviewDomainService.java | 43 ++ .../domain/searchcondition/FeeType.java | 20 + .../parking/domain/searchcondition/Hours.java | 27 ++ .../domain/searchcondition/Priority.java | 22 + .../searchcondition/SearchCondition.java | 78 ++++ .../SearchConditionAvailable.java | 8 + .../repository/SearchConditionRepository.java | 19 + .../parking/domain/session/MemberSession.java | 31 ++ .../repository/MemberSessionRepository.java | 11 + .../infra/config/JpaAuditingConfig.java | 10 + .../infra/converter/ContentConverter.java | 12 + .../infra/converter/EnumListConverter.java | 32 ++ .../infra/converter/FeeTypeConverter.java | 12 + .../converter/OperationTypeConverter.java | 12 + .../infra/converter/ParkingTypeConverter.java | 12 + .../infra/converter/PayTypeConverter.java | 12 + .../parking/support/Association.java | 26 ++ .../support/exception/ClientException.java | 19 + .../support/exception/DomainException.java | 16 + .../exception/ExceptionInformation.java | 34 ++ .../util/cipher/EncryptionException.java | 8 + .../parking/util/cipher/SHA256.java | 28 ++ domain/src/main/resources/application.yml | 8 + .../mysql/V1.0.0__initial_schema.sql | 94 +++++ .../mysql/V2.0.0__add_point_parking_table.sql | 2 + .../V3.0.0__drop_column_parking_table.sql | 3 + .../V4.0.0__drop_column_member_table.sql | 2 + .../parkingcomestrue/TestConfiguration.java | 8 + .../repository/FavoriteRepositoryTest.java | 50 +++ .../parking/domain/member/MemberTest.java | 64 +++ .../domain/parking/BaseInformationTest.java | 15 + .../parking/domain/parking/DayTest.java | 52 +++ .../parking/domain/parking/FeePolicyTest.java | 85 ++++ .../parking/domain/parking/FeeTest.java | 35 ++ .../domain/parking/FreeOperatingTimeTest.java | 194 +++++++++ .../parking/domain/parking/LocationTest.java | 38 ++ .../parking/ParkingFeeCalculatorTest.java | 394 ++++++++++++++++++ .../parking/domain/parking/ParkingTest.java | 188 +++++++++ .../parking/domain/parking/PayTypesTest.java | 65 +++ .../parking/domain/parking/TimeInfoTest.java | 164 ++++++++ .../parking/domain/parking/TimeUnitTest.java | 36 ++ .../service/ParkingFilteringServiceTest.java | 162 +++++++ .../parking/domain/review/ContentTest.java | 41 ++ .../service/ReviewDomainServiceTest.java | 87 ++++ .../domain/searchcondition/HoursTest.java | 25 ++ .../MemberSessionRepositoryTest.java | 45 ++ .../converter/EnumListConverterTest.java | 30 ++ domain/src/test/resources/application.yml | 3 + .../repository/BasicMemberRepository.java | 58 +++ .../repository/BasicParkingRepository.java | 88 ++++ .../java/repository/BasicRepository.java | 16 + .../repository/BasicReviewRepository.java | 42 ++ .../repository/FakeFavoriteRepository.java | 26 ++ .../FakeSearchConditionRepository.java | 18 + 86 files changed, 4124 insertions(+) create mode 100644 domain/.gitignore create mode 100644 domain/build.gradle create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/AuditingEntity.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/Favorite.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepository.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/member/Password.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/BaseInformation.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Day.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/DayParking.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Fee.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FeePolicy.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTime.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperatingTime.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperationType.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Parking.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculator.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingType.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayType.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayTypes.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/SearchingCondition.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Space.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeInfo.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeUnit.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/dto/ParkingQueryCondition.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringService.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/FeeType.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Priority.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchCondition.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchConditionAvailable.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/session/MemberSession.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepository.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/infra/config/JpaAuditingConfig.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ContentConverter.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/infra/converter/EnumListConverter.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/infra/converter/FeeTypeConverter.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/infra/converter/OperationTypeConverter.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ParkingTypeConverter.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/infra/converter/PayTypeConverter.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/support/Association.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/support/exception/ExceptionInformation.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/util/cipher/EncryptionException.java create mode 100644 domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java create mode 100644 domain/src/main/resources/application.yml create mode 100644 domain/src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql create mode 100644 domain/src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql create mode 100644 domain/src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql create mode 100644 domain/src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql create mode 100644 domain/src/test/java/com/parkingcomestrue/TestConfiguration.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepositoryTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/BaseInformationTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/DayTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeePolicyTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeeTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTimeTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/LocationTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculatorTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/PayTypesTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeInfoTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeUnitTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringServiceTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepositoryTest.java create mode 100644 domain/src/test/java/com/parkingcomestrue/parking/infra/converter/EnumListConverterTest.java create mode 100644 domain/src/test/resources/application.yml create mode 100644 domain/src/testFixtures/java/repository/BasicMemberRepository.java create mode 100644 domain/src/testFixtures/java/repository/BasicParkingRepository.java create mode 100644 domain/src/testFixtures/java/repository/BasicRepository.java create mode 100644 domain/src/testFixtures/java/repository/BasicReviewRepository.java create mode 100644 domain/src/testFixtures/java/repository/FakeFavoriteRepository.java create mode 100644 domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java diff --git a/domain/.gitignore b/domain/.gitignore new file mode 100644 index 00000000..b63da455 --- /dev/null +++ b/domain/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/domain/build.gradle b/domain/build.gradle new file mode 100644 index 00000000..a00082db --- /dev/null +++ b/domain/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'java-library' + id 'java-test-fixtures' + id 'maven-publish' +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' + + + implementation group: 'org.hibernate.orm', name: 'hibernate-spatial', version: '6.3.1.Final' + + testFixturesImplementation 'org.springframework.boot:spring-boot-starter-data-jpa' + testFixturesImplementation group: 'org.hibernate.orm', name: 'hibernate-spatial', version: '6.3.1.Final' + + // flyway 추가 + implementation 'org.flywaydb:flyway-mysql' + implementation 'org.flywaydb:flyway-core' +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/AuditingEntity.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/AuditingEntity.java new file mode 100644 index 00000000..d1450458 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/AuditingEntity.java @@ -0,0 +1,21 @@ +package com.parkingcomestrue.parking.domain; + +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import java.time.LocalDateTime; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public abstract class AuditingEntity { + + @CreatedDate + private LocalDateTime createdAt; + + @LastModifiedDate + private LocalDateTime updatedAt; +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/Favorite.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/Favorite.java new file mode 100644 index 00000000..68010a05 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/Favorite.java @@ -0,0 +1,48 @@ +package com.parkingcomestrue.parking.domain.favorite; + +import com.parkingcomestrue.parking.domain.AuditingEntity; +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.support.Association; +import jakarta.persistence.AttributeOverride; +import jakarta.persistence.Column; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "favorite", + uniqueConstraints = { + @UniqueConstraint( + columnNames = {"memberId", "parkingId"} + ) + } +) +@Entity +public class Favorite extends AuditingEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Embedded + @AttributeOverride(name = "id", column = @Column(name = "member_id")) + private Association memberId; + + @Embedded + @AttributeOverride(name = "id", column = @Column(name = "parking_id")) + private Association parkingId; + + public Favorite(Association memberId, Association parkingId) { + this.memberId = memberId; + this.parkingId = parkingId; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepository.java new file mode 100644 index 00000000..91ddb421 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepository.java @@ -0,0 +1,17 @@ +package com.parkingcomestrue.parking.domain.favorite.repository; + +import com.parkingcomestrue.parking.domain.favorite.Favorite; +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.support.Association; +import java.util.List; +import org.springframework.data.repository.Repository; + +public interface FavoriteRepository extends Repository { + + Favorite save(Favorite favorite); + + void deleteByMemberIdAndParkingId(Association memberId, Association parkingId); + + List findByMemberId(Association memberId); +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java new file mode 100644 index 00000000..c968800c --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java @@ -0,0 +1,74 @@ +package com.parkingcomestrue.parking.domain.member; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import jakarta.persistence.Column; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.util.Objects; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +//@SQLRestriction(value = "deleted = false") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Member { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(unique = true) + private String email; + + private String nickname; + + @Embedded + private Password password; + + private Boolean deleted = Boolean.FALSE; + + public Member(String email, String nickname, Password password) { + this.email = email; + this.nickname = nickname; + this.password = password; + } + + public boolean checkPassword(String password) { + return this.password.isMatch(password); + } + + public void delete() { + deleted = Boolean.TRUE; + } + + public void changePassword(String previousPassword, String newPassword) { + if (checkPassword(previousPassword)) { + this.password = new Password(newPassword); + return; + } + throw new DomainException(ExceptionInformation.INVALID_PASSWORD); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Member member = (Member) o; + return Objects.equals(getId(), member.getId()); + } + + @Override + public int hashCode() { + return Objects.hash(getId()); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Password.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Password.java new file mode 100644 index 00000000..97ce3fc5 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Password.java @@ -0,0 +1,41 @@ +package com.parkingcomestrue.parking.domain.member; + +import com.parkingcomestrue.parking.util.cipher.SHA256; +import jakarta.persistence.Embeddable; +import java.util.Objects; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Embeddable +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Password { + + private String password; + + public Password(String password) { + this.password = SHA256.encrypt(password); + } + + public boolean isMatch(String password) { + return this.password.equals(SHA256.encrypt(password)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Password that = (Password) o; + return Objects.equals(password, that.password); + } + + @Override + public int hashCode() { + return Objects.hash(password); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java new file mode 100644 index 00000000..d9b14eb5 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java @@ -0,0 +1,22 @@ +package com.parkingcomestrue.parking.domain.member.repository; + +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.Optional; +import org.springframework.data.repository.Repository; + +public interface MemberRepository extends Repository { + + boolean existsByEmail(String email); + + Optional findById(Long id); + + Optional findByEmail(String email); + + void save(Member member); + + default Member getById(Long id) { + return findById(id).orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_MEMBER)); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/BaseInformation.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/BaseInformation.java new file mode 100644 index 00000000..3e18f5b4 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/BaseInformation.java @@ -0,0 +1,54 @@ +package com.parkingcomestrue.parking.domain.parking; + +import static jakarta.persistence.EnumType.STRING; + +import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; +import jakarta.persistence.Enumerated; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@Embeddable +public class BaseInformation { + + private String name; + private String tel; + private String address; + + @Embedded + private PayTypes payTypes; + + @Enumerated(STRING) + private ParkingType parkingType; + + @Enumerated(STRING) + private OperationType operationType; + + public BaseInformation(String name, String tel, String address, PayTypes payTypes, ParkingType parkingType, + OperationType operationType) { + this.name = name; + this.tel = tel; + this.address = address; + this.payTypes = payTypes; + this.parkingType = parkingType; + this.operationType = operationType; + } + + public boolean containsOperationType(List operationTypes) { + return operationTypes.stream() + .anyMatch(operationType -> this.operationType == operationType); + } + + public boolean containsParkingType(List parkingTypes) { + return parkingTypes.stream() + .anyMatch(parkingType -> this.parkingType == parkingType); + } + + public boolean containsPayType(List memberPayTypes) { + return this.payTypes.contains(memberPayTypes); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Day.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Day.java new file mode 100644 index 00000000..caa2db5b --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Day.java @@ -0,0 +1,20 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.time.DayOfWeek; + +public enum Day { + + WEEKDAY, + SATURDAY, + HOLIDAY; + + public static Day from(DayOfWeek dayOfWeek) { + if (dayOfWeek == DayOfWeek.SATURDAY) { + return SATURDAY; + } + if (dayOfWeek == DayOfWeek.SUNDAY) { + return HOLIDAY; + } + return WEEKDAY; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/DayParking.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/DayParking.java new file mode 100644 index 00000000..f1f617b6 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/DayParking.java @@ -0,0 +1,30 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.time.LocalTime; +import lombok.Getter; + +@Getter +public class DayParking { + + private final Day day; + private final LocalTime beginTime; + private final LocalTime endTime; + + public DayParking(Day day, LocalTime beginTime, LocalTime endTime) { + this.day = day; + this.beginTime = beginTime; + this.endTime = endTime; + } + + public boolean isWeekDay() { + return day == Day.WEEKDAY; + } + + public boolean isSaturday() { + return day == Day.SATURDAY; + } + + public boolean isHoliday() { + return day == Day.HOLIDAY; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Fee.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Fee.java new file mode 100644 index 00000000..359f6288 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Fee.java @@ -0,0 +1,58 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Embeddable +public class Fee { + + public static final Fee ZERO = new Fee(0); + public static final Fee NO_INFO = new Fee(-1); + + private Integer fee; + + private Fee(Integer fee) { + this.fee = fee; + } + + public static Fee from(Integer fee) { + return new Fee(fee); + } + + public static Fee from(String fee) { + try { + return new Fee(Integer.parseInt(fee)); + } catch (NumberFormatException | NullPointerException e) { + return NO_INFO; + } + } + + public Fee multiply(int time) { + return new Fee(fee * time); + } + + public Fee plus(Fee fee) { + return new Fee(this.fee + fee.fee); + } + + public static Fee min(Fee fee, Fee otherFee) { + if (fee.fee < otherFee.fee) { + return fee; + } + return otherFee; + } + + public boolean isFree() { + return fee == 0; + } + + public boolean isValidFee() { + return !NO_INFO.equals(this); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FeePolicy.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FeePolicy.java new file mode 100644 index 00000000..57a2e1f4 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FeePolicy.java @@ -0,0 +1,81 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.AttributeOverride; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@Embeddable +public class FeePolicy { + + @AttributeOverride(name = "fee", column = @Column(name = "base_fee")) + @Embedded + private Fee baseFee; + + @AttributeOverride(name = "fee", column = @Column(name = "extra_fee")) + @Embedded + private Fee extraFee; + + @AttributeOverride(name = "timeUnit", column = @Column(name = "base_time_unit")) + @Embedded + private TimeUnit baseTimeUnit; + + @AttributeOverride(name = "timeUnit", column = @Column(name = "extra_time_unit")) + @Embedded + private TimeUnit extraTimUnit; + + @AttributeOverride(name = "fee", column = @Column(name = "day_maximum_fee")) + @Embedded + private Fee dayMaximumFee; + + public FeePolicy(Fee baseFee, Fee extraFee, TimeUnit baseTimeUnit, TimeUnit extraTimUnit, Fee dayMaximumFee) { + this.baseFee = baseFee; + this.extraFee = extraFee; + this.baseTimeUnit = baseTimeUnit; + this.extraTimUnit = extraTimUnit; + this.dayMaximumFee = dayMaximumFee; + } + + public Fee calculateFee(int minutes) { + if (supportBase()) { + return calculateFeeWithBase(minutes); + } + return calculateFeeWithoutBase(minutes); + } + + public boolean supportBase() { + return baseFee.isValidFee() && baseTimeUnit.isValidTimeUnit(); + } + + public boolean supportExtra() { + return extraFee.isValidFee() && extraTimUnit.isValidTimeUnit(); + } + + private Fee calculateFeeWithBase(int minutes) { + if (minutes == 0) { + return Fee.ZERO; + } + if (baseTimeUnit.isEqualOrGreaterThan(minutes)) { + return baseFee; + } + minutes = minutes - baseTimeUnit.getTimeUnit(); + int time = extraTimUnit.calculateQuotient(minutes); + return Fee.min(extraFee.multiply(time).plus(baseFee), dayMaximumFee); + } + + private Fee calculateFeeWithoutBase(int minutes) { + if (minutes == 0) { + return Fee.ZERO; + } + if (supportExtra()) { + int time = extraTimUnit.calculateQuotient(minutes); + return Fee.min(extraFee.multiply(time), dayMaximumFee); + } + return Fee.NO_INFO; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTime.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTime.java new file mode 100644 index 00000000..c9c339e6 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTime.java @@ -0,0 +1,73 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.AttributeOverride; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; +import java.time.LocalTime; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Embeddable +public class FreeOperatingTime { + + public static final FreeOperatingTime ALWAYS_PAY = new FreeOperatingTime(TimeInfo.CLOSED, TimeInfo.CLOSED, + TimeInfo.CLOSED); + public static final FreeOperatingTime ALWAYS_FREE = new FreeOperatingTime(TimeInfo.ALL_DAY, TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY); + + @AttributeOverride(name = "beginTime", column = @Column(name = "weekday_free_begin_time")) + @AttributeOverride(name = "endTime", column = @Column(name = "weekday_free_end_time")) + @Embedded + private TimeInfo weekday; + + @AttributeOverride(name = "beginTime", column = @Column(name = "saturday_free_begin_time")) + @AttributeOverride(name = "endTime", column = @Column(name = "saturday_free_end_time")) + @Embedded + private TimeInfo saturday; + + @AttributeOverride(name = "beginTime", column = @Column(name = "holiday_free_begin_time")) + @AttributeOverride(name = "endTime", column = @Column(name = "holiday_free_end_time")) + @Embedded + private TimeInfo holiday; + + public FreeOperatingTime(TimeInfo weekday, TimeInfo saturday, TimeInfo holiday) { + this.weekday = weekday; + this.saturday = saturday; + this.holiday = holiday; + } + + public int calculateNonFreeUsageMinutes(DayParking dayParking) { + TimeInfo today = getTodayTimeInfo(dayParking); + if (isFreeDay(today)) { + return 0; + } + LocalTime beginTime = dayParking.getBeginTime(); + LocalTime endTime = dayParking.getEndTime(); + int parkingMinutes = calculateMinutes(endTime) - calculateMinutes(beginTime); + int overlapMinutes = today.calculateOverlapMinutes(beginTime, endTime); + return parkingMinutes - overlapMinutes; + } + + private TimeInfo getTodayTimeInfo(DayParking dayParking) { + if (dayParking.isWeekDay()) { + return weekday; + } + if (dayParking.isSaturday()) { + return saturday; + } + return holiday; + } + + private boolean isFreeDay(TimeInfo today) { + return today.equals(TimeInfo.ALL_DAY); + } + + private int calculateMinutes(LocalTime localTime) { + if (localTime.equals(LocalTime.MAX)) { + return localTime.getHour() * 60 + localTime.getMinute() + 1; + } + return localTime.getHour() * 60 + localTime.getMinute(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java new file mode 100644 index 00000000..02d0ae60 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java @@ -0,0 +1,68 @@ +package com.parkingcomestrue.parking.domain.parking; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.PrecisionModel; + +@Getter +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Embeddable +public class Location { + + private static final GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); + private static final Location NO_PROVIDE = new Location(geometryFactory.createPoint(new Coordinate(-1.0, -1.0))); + + private static final Double MAX_LONGITUDE = 180.0; + private static final Double MIN_LONGITUDE = -180.0; + + private static final Double MAX_LATITUDE = 90.0; + private static final Double MIN_LATITUDE = -90.0; + + private Point point; + + private Location(Point point) { + this.point = point; + } + + public static Location of(Double longitude, Double latitude) { + try { + verifyLocation(longitude, latitude); + Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); + return new Location(point); + } catch (NullPointerException e) { + return NO_PROVIDE; + } + } + + private static void verifyLocation(Double longitude, Double latitude) { + if (longitude > MAX_LONGITUDE || longitude < MIN_LONGITUDE || latitude > MAX_LATITUDE + || latitude < MIN_LATITUDE) { + throw new DomainException(ExceptionInformation.INVALID_LOCATION); + } + } + + public static Location of(String longitude, String latitude) { + try { + return Location.of(Double.parseDouble(longitude), Double.parseDouble(latitude)); + } catch (NumberFormatException | NullPointerException e) { + return NO_PROVIDE; + } + } + + public double getLongitude() { + return point.getX(); + } + + public double getLatitude() { + return point.getY(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperatingTime.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperatingTime.java new file mode 100644 index 00000000..aeb43bf3 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperatingTime.java @@ -0,0 +1,66 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.AttributeOverride; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; +import java.time.LocalTime; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@Embeddable +public class OperatingTime { + + public static final OperatingTime ALWAYS_OPEN = new OperatingTime(TimeInfo.ALL_DAY, TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY); + + @AttributeOverride(name = "beginTime", column = @Column(name = "weekday_begin_time")) + @AttributeOverride(name = "endTime", column = @Column(name = "weekday_end_time")) + @Embedded + private TimeInfo weekday; + + @AttributeOverride(name = "beginTime", column = @Column(name = "saturday_begin_time")) + @AttributeOverride(name = "endTime", column = @Column(name = "saturday_end_time")) + @Embedded + private TimeInfo saturday; + + @AttributeOverride(name = "beginTime", column = @Column(name = "holiday_begin_time")) + @AttributeOverride(name = "endTime", column = @Column(name = "holiday_end_time")) + @Embedded + private TimeInfo holiday; + + public OperatingTime(TimeInfo weekday, + TimeInfo saturday, + TimeInfo holiday) { + this.weekday = weekday; + this.saturday = saturday; + this.holiday = holiday; + } + + public LocalTime getWeekdayBeginTime() { + return weekday.getBeginTime(); + } + + public LocalTime getWeekdayEndTime() { + return weekday.getEndTime(); + } + + public LocalTime getSaturdayBeginTime() { + return saturday.getBeginTime(); + } + + public LocalTime getSaturdayEndTime() { + return saturday.getEndTime(); + } + + public LocalTime getHolidayBeginTime() { + return holiday.getBeginTime(); + } + + public LocalTime getHolidayEndTime() { + return holiday.getEndTime(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperationType.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperationType.java new file mode 100644 index 00000000..8d293d55 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperationType.java @@ -0,0 +1,23 @@ +package com.parkingcomestrue.parking.domain.parking; + +import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import lombok.Getter; + +@Getter +public enum OperationType implements SearchConditionAvailable { + + PUBLIC("공영"), + PRIVATE("민영"), + NO_INFO("정보 없음"); + + private final String description; + + OperationType(String description) { + this.description = description; + } + + @Override + public OperationType getDefault() { + return NO_INFO; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Parking.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Parking.java new file mode 100644 index 00000000..bdac4c9c --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Parking.java @@ -0,0 +1,155 @@ +package com.parkingcomestrue.parking.domain.parking; + +import com.parkingcomestrue.parking.domain.AuditingEntity; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Parking extends AuditingEntity { + + private static final int MINUTE_UNIT = 60; + + private static final int AVERAGE_WALKING_SPEED = 5; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Embedded + private BaseInformation baseInformation; + + @Embedded + private Location location; + + @Embedded + private Space space; + + @Embedded + private FreeOperatingTime freeOperatingTime; + + @Embedded + private OperatingTime operatingTime; + + @Embedded + private FeePolicy feePolicy; + + @Builder + private Parking(Long id, BaseInformation baseInformation, Location location, Space space, + FreeOperatingTime freeOperatingTime, OperatingTime operatingTime, FeePolicy feePolicy) { + this.id = id; + this.baseInformation = baseInformation; + this.location = location; + this.space = space; + this.freeOperatingTime = freeOperatingTime; + this.operatingTime = operatingTime; + this.feePolicy = feePolicy; + } + + public Parking(BaseInformation baseInformation, Location location, Space space, + FreeOperatingTime freeOperatingTime, OperatingTime operatingTime, FeePolicy feePolicy) { + this.baseInformation = baseInformation; + this.location = location; + this.space = space; + this.freeOperatingTime = freeOperatingTime; + this.operatingTime = operatingTime; + this.feePolicy = feePolicy; + } + + public int calculatePayOfChargeMinutes(DayParking dayParking) { + return freeOperatingTime.calculateNonFreeUsageMinutes(dayParking); + } + + public Fee calculateParkingFee(int payOfChargeMinutes) { + return feePolicy.calculateFee(payOfChargeMinutes); + } + + public boolean supportCalculateParkingFee() { + return feePolicy.supportBase() && feePolicy.supportExtra(); + } + + public void update(Parking updated) { + this.space = updated.space; + this.freeOperatingTime = updated.freeOperatingTime; + this.operatingTime = updated.operatingTime; + this.feePolicy = updated.feePolicy; + } + + public void update(Location location) { + this.location = location; + } + + public boolean containsOperationType(List operationTypes) { + return baseInformation.containsOperationType(operationTypes); + } + + public boolean containsParkingType(List parkingTypes) { + return baseInformation.containsParkingType(parkingTypes); + } + + public boolean containsPayType(List memberPayTypes) { + return baseInformation.containsPayType(memberPayTypes); + } + + public int calculateWalkingTime(Location destination) { + double distance = calculateDistanceToDestination(destination); + double averageWalkingTime = distance / AVERAGE_WALKING_SPEED; + return (int) Math.ceil(averageWalkingTime); + } + + private double calculateDistanceToDestination(Location destination) { + double parkingLongitude = this.location.getLongitude(); + double parkingLatitude = this.location.getLatitude(); + + double radius = 6371; // 지구 반지름(km) + double toRadian = Math.PI / 180; + + double deltaLatitude = Math.abs(parkingLatitude - destination.getLatitude()) * toRadian; + double deltaLongitude = Math.abs(parkingLongitude - destination.getLongitude()) * toRadian; + + double sinDeltaLat = Math.sin(deltaLatitude / 2); + double sinDeltaLng = Math.sin(deltaLongitude / 2); + double squareRoot = Math.sqrt( + sinDeltaLat * sinDeltaLat + + Math.cos(parkingLatitude * toRadian) * Math.cos(destination.getLatitude() * toRadian) + * sinDeltaLng + * sinDeltaLng); + + return 2 * radius * Math.asin(squareRoot); + } + + public int calculateUpdatedDiff(LocalDateTime now) { + Duration diff = Duration.between(now, getUpdatedAt()); + Long diffMinute = diff.getSeconds() / MINUTE_UNIT; + return diffMinute.intValue(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Parking parking = (Parking) o; + return Objects.equals(id, parking.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculator.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculator.java new file mode 100644 index 00000000..5f4bb421 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculator.java @@ -0,0 +1,71 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class ParkingFeeCalculator { + + public Fee calculateParkingFee(Parking parking, LocalDateTime beginTime, LocalDateTime endTime) { + if (!parking.supportCalculateParkingFee()) { + return Fee.NO_INFO; + } + + List dayParkingDates = separateDate(beginTime, endTime); + List payOfChargeMinutesPerDay = dayParkingDates.stream() + .map(parking::calculatePayOfChargeMinutes) + .toList(); + + return payOfChargeMinutesPerDay.stream() + .filter(minutes -> minutes > 0) + .map(parking::calculateParkingFee) + .reduce(Fee::plus) + .orElse(Fee.ZERO); + } + + private List separateDate(LocalDateTime beginTime, LocalDateTime endTime) { + if (isSameDate(beginTime, endTime)) { + return List.of( + new DayParking(Day.from(beginTime.getDayOfWeek()), beginTime.toLocalTime(), endTime.toLocalTime())); + } + + List dayParkingDates = new ArrayList<>(); + dayParkingDates.add(makeFirstDayParking(beginTime)); + beginTime = beginTime.plusDays(1); + while (!isSameDate(beginTime, endTime)) { + dayParkingDates.add(new DayParking(Day.from(beginTime.getDayOfWeek()), LocalTime.MIN, LocalTime.MAX)); + beginTime = beginTime.plusDays(1); + } + dayParkingDates.add(makeLastDayParking(endTime)); + return dayParkingDates; + } + + private boolean isSameDate(LocalDateTime beginTime, LocalDateTime endTime) { + return isSameYear(beginTime, endTime) && + isSameMonth(beginTime, endTime) && + isSameDayOfMonth(beginTime, endTime); + } + + private boolean isSameYear(LocalDateTime beginTime, LocalDateTime endTime) { + return beginTime.getYear() == endTime.getYear(); + } + + private boolean isSameMonth(LocalDateTime beginTime, LocalDateTime endTime) { + return beginTime.getMonth().equals(endTime.getMonth()); + } + + private boolean isSameDayOfMonth(LocalDateTime beginTime, LocalDateTime endTime) { + return beginTime.getDayOfMonth() == endTime.getDayOfMonth(); + } + + private DayParking makeFirstDayParking(LocalDateTime beginTime) { + return new DayParking(Day.from(beginTime.getDayOfWeek()), beginTime.toLocalTime(), LocalTime.MAX); + } + + private DayParking makeLastDayParking(LocalDateTime endTime) { + return new DayParking(Day.from(endTime.getDayOfWeek()), LocalTime.MIN, endTime.toLocalTime()); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingType.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingType.java new file mode 100644 index 00000000..e04e2e9f --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingType.java @@ -0,0 +1,31 @@ +package com.parkingcomestrue.parking.domain.parking; + +import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import java.util.Arrays; +import lombok.Getter; + +@Getter +public enum ParkingType implements SearchConditionAvailable { + OFF_STREET("노외"), + ON_STREET("노상"), + MECHANICAL("기계"), + NO_INFO("정보 없음"); + + private final String description; + + ParkingType(String description) { + this.description = description; + } + + @Override + public ParkingType getDefault() { + return NO_INFO; + } + + public static ParkingType find(String description) { + return Arrays.stream(values()) + .filter(e -> description.startsWith(e.getDescription())) + .findAny() + .orElse(NO_INFO); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayType.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayType.java new file mode 100644 index 00000000..63de4874 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayType.java @@ -0,0 +1,25 @@ +package com.parkingcomestrue.parking.domain.parking; + +import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import lombok.Getter; + +@Getter +public enum PayType implements SearchConditionAvailable { + + CASH("현금"), + CARD("카드"), + BANK_TRANSFER("계좌"), + NO_INFO("정보 없음"); + + private final String description; + + PayType(String description) { + this.description = description; + } + + @Override + public PayType getDefault() { + return NO_INFO; + } +} + diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayTypes.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayTypes.java new file mode 100644 index 00000000..59903a69 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayTypes.java @@ -0,0 +1,46 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.Embeddable; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode +@Embeddable +public class PayTypes { + + public static final PayTypes DEFAULT = new PayTypes(PayType.NO_INFO.getDescription()); + private static final String DELIMITER = ", "; + + private String description; + + private PayTypes(String description) { + this.description = description; + } + + public static PayTypes from(Collection payTypes) { + if (payTypes.contains(PayType.NO_INFO)) { + return DEFAULT; + } + + return new PayTypes(payTypes.stream() + .map(PayType::getDescription) + .sorted() + .collect(Collectors.joining(DELIMITER)) + ); + } + + public boolean contains(List memberPayTypes) { + if (this.description.equals(DEFAULT.description)) { + return true; + } + return memberPayTypes.stream() + .anyMatch(payType -> this.description.contains(payType.getDescription())); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/SearchingCondition.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/SearchingCondition.java new file mode 100644 index 00000000..10791935 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/SearchingCondition.java @@ -0,0 +1,25 @@ +package com.parkingcomestrue.parking.domain.parking; + +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import java.util.List; +import lombok.Getter; + +@Getter +public class SearchingCondition { + + private final List operationTypes; + private final List parkingTypes; + private final List payTypes; + private final FeeType feeType; + private final Integer hours; + + public SearchingCondition(List operationTypes, List parkingTypes, + List payTypes, + FeeType feeType, Integer hours) { + this.operationTypes = operationTypes; + this.parkingTypes = parkingTypes; + this.payTypes = payTypes; + this.feeType = feeType; + this.hours = hours; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Space.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Space.java new file mode 100644 index 00000000..66cba855 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Space.java @@ -0,0 +1,44 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Embeddable +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Space { + + private static final Integer NO_PROVIDE = -1; + + private Integer capacity; + private Integer currentParking; + + private Space(Integer capacity, Integer currentParking) { + this.capacity = capacity; + this.currentParking = currentParking; + } + + public static Space of(String capacity, String currentParking) { + return new Space(parseInt(capacity), parseInt(currentParking)); + } + + private static Integer parseInt(String number) { + try { + return Integer.parseInt(number); + } catch (NumberFormatException e) { + return NO_PROVIDE; + } + } + + public static Space of(Integer capacity, Integer currentParking) { + if (capacity < 0) { + capacity = NO_PROVIDE; + } + if (currentParking < 0) { + currentParking = NO_PROVIDE; + } + return new Space(capacity, currentParking); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeInfo.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeInfo.java new file mode 100644 index 00000000..29dbb00a --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeInfo.java @@ -0,0 +1,62 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.Embeddable; +import java.time.LocalTime; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Embeddable +public class TimeInfo { + + public static final TimeInfo CLOSED = new TimeInfo(LocalTime.MIN, LocalTime.MIN); + public static final TimeInfo ALL_DAY = new TimeInfo(LocalTime.MIN, LocalTime.MAX); + + private LocalTime beginTime; + private LocalTime endTime; + + public TimeInfo(LocalTime beginTime, LocalTime endTime) { + this.beginTime = beginTime; + this.endTime = endTime; + } + + public int calculateOverlapMinutes(LocalTime beginTime, LocalTime endTime) { + if (this.endTime.isBefore(this.beginTime)) { + TimeInfo today = new TimeInfo(this.beginTime, LocalTime.MAX); + TimeInfo tomorrow = new TimeInfo(LocalTime.MIN, this.endTime); + return today.calculateOverlapMinutes(beginTime, endTime) + tomorrow.calculateOverlapMinutes(beginTime, + endTime); + } + LocalTime overlapBeginTime = decideOverlapBeginTime(beginTime); + LocalTime overlapEndTime = decideOverlapEndTime(endTime); + int overlapMinutes = calculateBetweenMinutes(overlapBeginTime, overlapEndTime); + return Math.max(0, overlapMinutes); + } + + private LocalTime decideOverlapBeginTime(LocalTime beginTime) { + if (beginTime.isAfter(this.beginTime)) { + return beginTime; + } + return this.beginTime; + } + + private LocalTime decideOverlapEndTime(LocalTime endTime) { + if (endTime.isBefore(this.endTime)) { + return endTime; + } + return this.endTime; + } + + private int calculateBetweenMinutes(LocalTime beginTime, LocalTime endTime) { + return calculateMinutes(endTime) - calculateMinutes(beginTime); + } + + private int calculateMinutes(LocalTime localTime) { + if (localTime.equals(LocalTime.MAX)) { + return localTime.getHour() * 60 + localTime.getMinute() + 1; + } + return localTime.getHour() * 60 + localTime.getMinute(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeUnit.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeUnit.java new file mode 100644 index 00000000..e6ac836e --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeUnit.java @@ -0,0 +1,50 @@ +package com.parkingcomestrue.parking.domain.parking; + +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Embeddable +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class TimeUnit { + + private static final TimeUnit NO_INFO = new TimeUnit(-1); + + private int timeUnit; + + private TimeUnit(int timeUnit) { + this.timeUnit = timeUnit; + } + + public static TimeUnit from(int timeUnit) { + if (timeUnit == 0) { + return NO_INFO; + } + return new TimeUnit(timeUnit); + } + + public static TimeUnit from(String timeUnit) { + try { + return TimeUnit.from(Integer.parseInt(timeUnit)); + } catch (NumberFormatException | NullPointerException e) { + return NO_INFO; + } + } + + public boolean isEqualOrGreaterThan(int other) { + return timeUnit >= other; + } + + public int calculateQuotient(int minutes) { + if (minutes <= 0) { + return 0; + } + return (minutes - 1) / timeUnit + 1; + } + + public boolean isValidTimeUnit() { + return !NO_INFO.equals(this); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/dto/ParkingQueryCondition.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/dto/ParkingQueryCondition.java new file mode 100644 index 00000000..a87d147e --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/dto/ParkingQueryCondition.java @@ -0,0 +1,23 @@ +package com.parkingcomestrue.parking.domain.parking.dto; + +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import lombok.Getter; + +@Getter +public class ParkingQueryCondition { + + private final OperationType operationType; + private final ParkingType parkingType; + private final Boolean cardEnabled; + private final PayTypes payTypes; + + public ParkingQueryCondition(OperationType operationType, ParkingType parkingType, Boolean cardEnabled, + PayTypes payTypes) { + this.operationType = operationType; + this.parkingType = parkingType; + this.cardEnabled = cardEnabled; + this.payTypes = payTypes; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java new file mode 100644 index 00000000..f9fb9fe0 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java @@ -0,0 +1,45 @@ +package com.parkingcomestrue.parking.domain.parking.repository; + +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import org.locationtech.jts.geom.Point; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.query.Param; + +public interface ParkingRepository extends Repository { + + default Parking getById(Long id) { + return findById(id).orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_PARKING)); + } + + Optional findById(Long id); + + @Query(""" + SELECT p + FROM Parking p + WHERE ST_Contains(ST_Buffer(:point, :radius), p.location.point) + """ + ) + List findAroundParkingLots(@Param("point") Point point, @Param("radius") int radius); + + @Query(""" + SELECT p + FROM Parking p + WHERE ST_Contains(ST_Buffer(:point, :radius), p.location.point) + ORDER BY ST_DISTANCE_SPHERE(:point, p.location.point) + """ + ) + List findAroundParkingLotsOrderByDistance( + @Param("point") Point point, + @Param("radius") int radius + ); + + Set findAllByBaseInformationNameIn(Set parkingNames); + + void saveAll(Iterable parkingLots); +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringService.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringService.java new file mode 100644 index 00000000..b2dae979 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringService.java @@ -0,0 +1,37 @@ +package com.parkingcomestrue.parking.domain.parking.service; + +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingFeeCalculator; +import com.parkingcomestrue.parking.domain.parking.SearchingCondition; +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import java.time.LocalDateTime; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@RequiredArgsConstructor +@Component +public class ParkingFilteringService { + + private final ParkingFeeCalculator parkingFeeCalculator; + + public List filterByCondition(List parkingLots, SearchingCondition searchingCondition, + LocalDateTime now) { + return parkingLots.stream() + .filter(parking -> checkFeeTypeIsPaid(searchingCondition) || checkFeeTypeAndFeeFree(searchingCondition, + now, parking)) + .filter(parking -> parking.containsOperationType(searchingCondition.getOperationTypes())) + .filter(parking -> parking.containsParkingType(searchingCondition.getParkingTypes())) + .filter(parking -> parking.containsPayType(searchingCondition.getPayTypes())) + .toList(); + } + + private boolean checkFeeTypeIsPaid(SearchingCondition searchingCondition) { + return searchingCondition.getFeeType() == FeeType.PAID; + } + + private boolean checkFeeTypeAndFeeFree(SearchingCondition searchingCondition, LocalDateTime now, Parking parking) { + return searchingCondition.getFeeType() == FeeType.FREE && parkingFeeCalculator.calculateParkingFee(parking, now, + now.plusHours(searchingCondition.getHours())).isFree(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java new file mode 100644 index 00000000..876855f0 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java @@ -0,0 +1,34 @@ +package com.parkingcomestrue.parking.domain.review; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.Arrays; +import lombok.Getter; + +@Getter +public enum Content { + + LOTS_OF_PARKING_SPOTS("주차 자리가 많아요"), + GOOD_CONDITION("깔끔하고 관리가 잘 되어 있어요"), + GOOD_CONSIDERATE_SPOT("주차 배려석이 잘 되어 있어요"), + LOTS_OF_CHARGING_SPOTS("전기차 충전석이 많아요"), + LARGE_PARKING_SPACE("주차석이 널널해서 주차가 편해요"), + CLOSE_TO_MAIN_LOAD("큰 길과 가까워요"), + GOOD_ACCESSIBILITY("접근성이 좋아요"), + EASY_TO_PAY("결제가 편리해요"), + FRIENDLY_STAFF("직원이 친절해요"), + LOW_PRICE("가격이 저렴해요"); + + private final String description; + + Content(String description) { + this.description = description; + } + + public static Content find(String description) { + return Arrays.stream(values()) + .filter(content -> content.getDescription().startsWith(description)) + .findAny() + .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_CONTENT)); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java new file mode 100644 index 00000000..3f3a1c2a --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java @@ -0,0 +1,61 @@ +package com.parkingcomestrue.parking.domain.review; + +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.infra.converter.ContentConverter; +import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import jakarta.persistence.AttributeOverride; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.time.LocalDateTime; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class Review { + + private static final int MAX_CONTENTS_SIZE = 3; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Embedded + @AttributeOverride(name = "id", column = @Column(name = "parking_id")) + private Association parkingId; + + @Embedded + @AttributeOverride(name = "id", column = @Column(name = "reviewer_id")) + private Association reviewerId; + + @Convert(converter = ContentConverter.class) + private List contents; + + @Column(updatable = false) + private LocalDateTime createdAt; + + public Review(Association parkingId, Association reviewerId, List contents) { + validate(contents); + this.parkingId = parkingId; + this.reviewerId = reviewerId; + this.contents = contents; + this.createdAt = LocalDateTime.now(); + } + + private static void validate(List contents) { + if (contents == null || contents.isEmpty() || contents.size() > MAX_CONTENTS_SIZE) { + throw new DomainException(ExceptionInformation.INVALID_CONTENTS_SIZE); + } + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java new file mode 100644 index 00000000..f31e4042 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java @@ -0,0 +1,27 @@ +package com.parkingcomestrue.parking.domain.review.repository; + +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.review.Review; +import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.List; +import java.util.Optional; +import org.springframework.data.repository.Repository; + +public interface ReviewRepository extends Repository { + + Optional findById(Long id); + + default Review getById(Long id) { + return findById(id) + .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_REVIEW)); + } + + List findAllByParkingId(Association parkingId); + + void save(Review review); + + boolean existsByParkingIdAndReviewerId(Association parkingId, Association reviewerId); +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java new file mode 100644 index 00000000..f682eabc --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java @@ -0,0 +1,43 @@ +package com.parkingcomestrue.parking.domain.review.service; + +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.review.Content; +import com.parkingcomestrue.parking.domain.review.Review; +import com.parkingcomestrue.parking.domain.review.repository.ReviewRepository; +import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@RequiredArgsConstructor +@Component +public class ReviewDomainService { + + private final ReviewRepository reviewRepository; + + public void validateDuplicateReview(Association parkingId, Association reviewerId) { + if (reviewRepository.existsByParkingIdAndReviewerId(parkingId, reviewerId)) { + throw new DomainException(ExceptionInformation.DUPLICATE_REVIEW); + } + } + + public Map collectByContent(List reviews) { + return reviews.stream() + .map(Review::getContents) + .flatMap(Collection::stream) + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); + } + + public int calculateTotalReviews(Map counts) { + return counts.values().stream() + .mapToInt(Long::intValue) + .sum(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/FeeType.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/FeeType.java new file mode 100644 index 00000000..c4f83355 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/FeeType.java @@ -0,0 +1,20 @@ +package com.parkingcomestrue.parking.domain.searchcondition; + +import lombok.Getter; + +@Getter +public enum FeeType implements SearchConditionAvailable { + + FREE("무료"), PAID("유료"), NO_INFO("정보 없음"); + + private final String description; + + FeeType(String description) { + this.description = description; + } + + @Override + public FeeType getDefault() { + return NO_INFO; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java new file mode 100644 index 00000000..99b6c09e --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java @@ -0,0 +1,27 @@ +package com.parkingcomestrue.parking.domain.searchcondition; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Embeddable +public class Hours { + + private int hours; + + private Hours(int hours) { + this.hours = hours; + } + + public static Hours from(int hours) { + if ((hours >= 1 && hours <= 12) || hours == 24) { + return new Hours(hours); + } + throw new DomainException(ExceptionInformation.INVALID_HOURS); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Priority.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Priority.java new file mode 100644 index 00000000..0e86037e --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Priority.java @@ -0,0 +1,22 @@ +package com.parkingcomestrue.parking.domain.searchcondition; + +import lombok.Getter; + +@Getter +public enum Priority implements SearchConditionAvailable { + + DISTANCE("가까운순"), + PRICE("가격순"), + RECOMMENDATION("추천순"); + + private final String description; + + Priority(String description) { + this.description = description; + } + + @Override + public Priority getDefault() { + return RECOMMENDATION; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchCondition.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchCondition.java new file mode 100644 index 00000000..803a39d0 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchCondition.java @@ -0,0 +1,78 @@ +package com.parkingcomestrue.parking.domain.searchcondition; + +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayType; +import com.parkingcomestrue.parking.infra.converter.FeeTypeConverter; +import com.parkingcomestrue.parking.infra.converter.OperationTypeConverter; +import com.parkingcomestrue.parking.infra.converter.ParkingTypeConverter; +import com.parkingcomestrue.parking.infra.converter.PayTypeConverter; +import com.parkingcomestrue.parking.support.Association; +import jakarta.persistence.AttributeOverride; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class SearchCondition { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Embedded + @AttributeOverride(name = "id", column = @Column(name = "member_id")) + private Association memberId; + + @Convert(converter = OperationTypeConverter.class) + private List operationTypes; + + @Convert(converter = ParkingTypeConverter.class) + private List parkingTypes; + + @Convert(converter = FeeTypeConverter.class) + private List feeTypes; + + @Convert(converter = PayTypeConverter.class) + private List payTypes; + + @Enumerated(EnumType.STRING) + private Priority priority; + + @Embedded + private Hours hours; + + public SearchCondition(Association memberId, List operationTypes, + List parkingTypes, + List feeTypes, List payTypes, Priority priority, Hours hours) { + this.memberId = memberId; + this.operationTypes = operationTypes; + this.parkingTypes = parkingTypes; + this.feeTypes = feeTypes; + this.payTypes = payTypes; + this.priority = priority; + this.hours = hours; + } + + public void update(SearchCondition updated) { + this.operationTypes = updated.operationTypes; + this.parkingTypes = updated.parkingTypes; + this.feeTypes = updated.feeTypes; + this.payTypes = updated.payTypes; + this.priority = updated.priority; + this.hours = updated.hours; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchConditionAvailable.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchConditionAvailable.java new file mode 100644 index 00000000..bcc4f131 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchConditionAvailable.java @@ -0,0 +1,8 @@ +package com.parkingcomestrue.parking.domain.searchcondition; + +public interface SearchConditionAvailable { + + String getDescription(); + + E getDefault(); +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java new file mode 100644 index 00000000..e97dfffd --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java @@ -0,0 +1,19 @@ +package com.parkingcomestrue.parking.domain.searchcondition.repository; + +import com.parkingcomestrue.parking.domain.searchcondition.SearchCondition; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.Optional; +import org.springframework.data.repository.Repository; + +public interface SearchConditionRepository extends Repository { + + Optional findByMemberId(Long memberId); + + default SearchCondition getByMemberId(Long memberId) { + return findByMemberId(memberId) + .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_SEARCH_CONDITION)); + } + + void save(SearchCondition searchCondition); +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/session/MemberSession.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/session/MemberSession.java new file mode 100644 index 00000000..73ef6058 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/session/MemberSession.java @@ -0,0 +1,31 @@ +package com.parkingcomestrue.parking.domain.session; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class MemberSession { + + @Id + private String sessionId; + private Long memberId; + private LocalDateTime createdAt; + private LocalDateTime expiredAt; + + public MemberSession(String sessionId, Long memberId, LocalDateTime createdAt, LocalDateTime expiredAt) { + this.sessionId = sessionId; + this.memberId = memberId; + this.createdAt = createdAt; + this.expiredAt = expiredAt; + } + + public void updateExpiredAt(LocalDateTime newExpiredAt) { + expiredAt = newExpiredAt; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepository.java new file mode 100644 index 00000000..fc37f7dd --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepository.java @@ -0,0 +1,11 @@ +package com.parkingcomestrue.parking.domain.session.repository; + +import com.parkingcomestrue.parking.domain.session.MemberSession; +import java.time.LocalDateTime; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberSessionRepository extends JpaRepository { + + Optional findBySessionIdAndExpiredAtIsGreaterThanEqual(String sessionId, LocalDateTime expiredAt); +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/config/JpaAuditingConfig.java b/domain/src/main/java/com/parkingcomestrue/parking/infra/config/JpaAuditingConfig.java new file mode 100644 index 00000000..33f22e2a --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/infra/config/JpaAuditingConfig.java @@ -0,0 +1,10 @@ +package com.parkingcomestrue.parking.infra.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@Configuration +@EnableJpaAuditing +public class JpaAuditingConfig { + +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ContentConverter.java b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ContentConverter.java new file mode 100644 index 00000000..1591041e --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ContentConverter.java @@ -0,0 +1,12 @@ +package com.parkingcomestrue.parking.infra.converter; + +import com.parkingcomestrue.parking.domain.review.Content; +import jakarta.persistence.Converter; + +@Converter +public class ContentConverter extends EnumListConverter { + + protected ContentConverter() { + super(Content.class); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/EnumListConverter.java b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/EnumListConverter.java new file mode 100644 index 00000000..e83f2ecf --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/EnumListConverter.java @@ -0,0 +1,32 @@ +package com.parkingcomestrue.parking.infra.converter; + +import jakarta.persistence.AttributeConverter; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public abstract class EnumListConverter> implements AttributeConverter, String> { + + private static final String DELIMITER = ", "; + + private final Class enumClass; + + protected EnumListConverter(Class enumClass) { + this.enumClass = enumClass; + } + + @Override + public String convertToDatabaseColumn(List attribute) { + return attribute.stream() + .map(Enum::name) + .sorted() + .collect(Collectors.joining(DELIMITER)); + } + + @Override + public List convertToEntityAttribute(String dbData) { + return Arrays.stream(dbData.split(DELIMITER)) + .map(name -> Enum.valueOf(enumClass, name)) + .toList(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/FeeTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/FeeTypeConverter.java new file mode 100644 index 00000000..63779cd7 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/FeeTypeConverter.java @@ -0,0 +1,12 @@ +package com.parkingcomestrue.parking.infra.converter; + +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import jakarta.persistence.Converter; + +@Converter +public class FeeTypeConverter extends EnumListConverter { + + public FeeTypeConverter() { + super(FeeType.class); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/OperationTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/OperationTypeConverter.java new file mode 100644 index 00000000..5d5c96cd --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/OperationTypeConverter.java @@ -0,0 +1,12 @@ +package com.parkingcomestrue.parking.infra.converter; + +import com.parkingcomestrue.parking.domain.parking.OperationType; +import jakarta.persistence.Converter; + +@Converter +public class OperationTypeConverter extends EnumListConverter { + + public OperationTypeConverter() { + super(OperationType.class); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ParkingTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ParkingTypeConverter.java new file mode 100644 index 00000000..ad62a0ac --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ParkingTypeConverter.java @@ -0,0 +1,12 @@ +package com.parkingcomestrue.parking.infra.converter; + +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import jakarta.persistence.Converter; + +@Converter +public class ParkingTypeConverter extends EnumListConverter { + + public ParkingTypeConverter() { + super(ParkingType.class); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/PayTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/PayTypeConverter.java new file mode 100644 index 00000000..8c1e70ea --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/PayTypeConverter.java @@ -0,0 +1,12 @@ +package com.parkingcomestrue.parking.infra.converter; + +import com.parkingcomestrue.parking.domain.parking.PayType; +import jakarta.persistence.Converter; + +@Converter +public class PayTypeConverter extends EnumListConverter { + + public PayTypeConverter() { + super(PayType.class); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/Association.java b/domain/src/main/java/com/parkingcomestrue/parking/support/Association.java new file mode 100644 index 00000000..2fb8d3a2 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/support/Association.java @@ -0,0 +1,26 @@ +package com.parkingcomestrue.parking.support; + +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.Assert; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode(of = {"id"}) +@Embeddable +public class Association { + + private Long id; + + private Association(Long id) { + this.id = id; + } + + public static Association from(Long id) { + Assert.notNull(id, "Id는 null이 될 수 없습니다."); + return new Association<>(id); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java new file mode 100644 index 00000000..e07d1fdb --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java @@ -0,0 +1,19 @@ +package com.parkingcomestrue.parking.support.exception; + +import lombok.Getter; + +@Getter +public class ClientException extends RuntimeException { + + private final ExceptionInformation exceptionInformation; + + public ClientException(ExceptionInformation exceptionInformation) { + super(); + this.exceptionInformation = exceptionInformation; + } + + @Override + public String getMessage() { + return exceptionInformation.getMessage(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java new file mode 100644 index 00000000..ab62458b --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java @@ -0,0 +1,16 @@ +package com.parkingcomestrue.parking.support.exception; + +public class DomainException extends RuntimeException { + + private final ExceptionInformation exceptionInformation; + + public DomainException(ExceptionInformation exceptionInformation) { + super(); + this.exceptionInformation = exceptionInformation; + } + + @Override + public String getMessage() { + return exceptionInformation.getMessage(); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ExceptionInformation.java b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ExceptionInformation.java new file mode 100644 index 00000000..d5ad23aa --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ExceptionInformation.java @@ -0,0 +1,34 @@ +package com.parkingcomestrue.parking.support.exception; + +import lombok.Getter; + +@Getter +public enum ExceptionInformation { + DUPLICATE_MAIL("중복된 이메일이라 회원가입이 불가능합니다."), + INVALID_EMAIL("회원가입되지 않은 이메일입니다."), + INVALID_MEMBER("존재하지 않는 회원입니다."), + INVALID_PASSWORD("비밀번호가 틀립니다."), + UNAUTHORIZED("존재하지 않는 sessionId 입니다."), + + INVALID_PARKING("존재하지 않는 주차장입니다."), + INVALID_CONTENT("존재하지 않는 리뷰 내용입니다."), + INVALID_REVIEW("존재하지 않는 리뷰입니다."), + DUPLICATE_REVIEW("유저가 해당 주차장에 대해 이미 리뷰를 작성하였습니다."), + INVALID_CONTENTS_SIZE("리뷰 내용은 1개에서 3개까지 선택가능합니다."), + INVALID_HOURS("이용 시간은 1~12, 24 시간까지만 선택할 수 있습니다."), + INVALID_SEARCH_CONDITION("해당 회원의 검색 조건이 존재하지 않습니다."), + + ENCRYPT_EXCEPTION("암호화에 실패했습니다."), + + INVALID_CONNECT("주차장 API 연결 중 예외 발생"), + COORDINATE_EXCEPTION("좌표 변환 중 예외 발생"), + INVALID_AUTH_CODE("존재하지 않는 인증코드 입니다."), + INVALID_DESCRIPTION("해당하는 내용의 검색 조건이 존재하지 않습니다."), + INVALID_LOCATION("경도 또는 위도가 올바르지 않습니다."); + + private final String message; + + ExceptionInformation(String message) { + this.message = message; + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/EncryptionException.java b/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/EncryptionException.java new file mode 100644 index 00000000..491691f4 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/EncryptionException.java @@ -0,0 +1,8 @@ +package com.parkingcomestrue.parking.util.cipher; + +public class EncryptionException extends RuntimeException { + + public EncryptionException(String message) { + super(message); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java b/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java new file mode 100644 index 00000000..c9afdd3c --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java @@ -0,0 +1,28 @@ +package com.parkingcomestrue.parking.util.cipher; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.security.MessageDigest; + +public class SHA256 { + + private final static String ALG_NAME = "SHA-256"; + + public static String encrypt(String plainText) { + try { + MessageDigest md = MessageDigest.getInstance(ALG_NAME); + md.update(plainText.getBytes()); + return bytesToHex(md.digest()); + } catch (Exception e) { + throw new DomainException(ExceptionInformation.ENCRYPT_EXCEPTION); + } + } + + private static String bytesToHex(byte[] bytes) { + StringBuilder builder = new StringBuilder(); + for (byte b : bytes) { + builder.append(String.format("%02x", b)); + } + return builder.toString(); + } +} diff --git a/domain/src/main/resources/application.yml b/domain/src/main/resources/application.yml new file mode 100644 index 00000000..60437cf6 --- /dev/null +++ b/domain/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + flyway: + enabled: true + url: ${DB_URL} + user: ${DB_USERNAME} + password: ${DB_PASSWORD} + baseline-on-migrate: true + locations: classpath:db.migration.mysql diff --git a/domain/src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql b/domain/src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql new file mode 100644 index 00000000..870e0876 --- /dev/null +++ b/domain/src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql @@ -0,0 +1,94 @@ +-- favorite 테이블 생성 +CREATE TABLE favorite +( + id BIGINT NOT NULL AUTO_INCREMENT, + created_at TIMESTAMP, + updated_at TIMESTAMP, + member_id BIGINT, + parking_id BIGINT, + PRIMARY KEY (id), + UNIQUE (member_id, parking_id) +); + +-- member 테이블 생성 +CREATE TABLE member +( + id BIGINT NOT NULL AUTO_INCREMENT, + deleted BOOLEAN, + email VARCHAR(255) UNIQUE, + name VARCHAR(255), + nickname VARCHAR(255), + password VARCHAR(255), + PRIMARY KEY (id) +); + +-- member_session 테이블 생성 +CREATE TABLE member_session +( + session_id VARCHAR(255) NOT NULL, + created_at TIMESTAMP, + expired_at TIMESTAMP, + member_id BIGINT, + PRIMARY KEY (session_id) +); + +-- parking 테이블 생성 +CREATE TABLE parking +( + id BIGINT NOT NULL AUTO_INCREMENT, + created_at TIMESTAMP, + updated_at TIMESTAMP, + base_fee INTEGER, + base_time_unit INTEGER, + capacity INTEGER, + current_parking INTEGER, + day_maximum_fee INTEGER, + extra_fee INTEGER, + extra_time_unit INTEGER, + holiday_begin_time TIME, + holiday_end_time TIME, + holiday_free_begin_time TIME, + holiday_free_end_time TIME, + latitude FLOAT NOT NULL, + longitude FLOAT NOT NULL, + saturday_begin_time TIME, + saturday_end_time TIME, + saturday_free_begin_time TIME, + saturday_free_end_time TIME, + weekday_begin_time TIME, + weekday_end_time TIME, + weekday_free_begin_time TIME, + weekday_free_end_time TIME, + address VARCHAR(255), + description VARCHAR(255), + name VARCHAR(255), + operation_type ENUM ('PUBLIC', 'PRIVATE', 'NO_INFO'), + parking_type ENUM ('OFF_STREET', 'ON_STREET', 'MECHANICAL', 'NO_INFO'), + tel VARCHAR(255), + PRIMARY KEY (id) +); + +-- review 테이블 생성 +CREATE TABLE review +( + id BIGINT NOT NULL AUTO_INCREMENT, + created_at TIMESTAMP, + parking_id BIGINT, + reviewer_id BIGINT, + contents VARCHAR(255), + PRIMARY KEY (id) +); + +-- search_condition 테이블 생성 +CREATE TABLE search_condition +( + id BIGINT NOT NULL AUTO_INCREMENT, + hours INTEGER NOT NULL, + member_id BIGINT, + fee_types VARCHAR(255), + operation_types VARCHAR(255), + parking_types VARCHAR(255), + pay_types VARCHAR(255), + priority ENUM ('DISTANCE', 'PRICE', 'RECOMMENDATION'), + PRIMARY KEY (id) +); diff --git a/domain/src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql b/domain/src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql new file mode 100644 index 00000000..a4779e0d --- /dev/null +++ b/domain/src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql @@ -0,0 +1,2 @@ +ALTER TABLE parking + ADD COLUMN point GEOMETRY; diff --git a/domain/src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql b/domain/src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql new file mode 100644 index 00000000..36a97815 --- /dev/null +++ b/domain/src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql @@ -0,0 +1,3 @@ +ALTER TABLE parking + DROP COLUMN latitude, + DROP COLUMN longitude; diff --git a/domain/src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql b/domain/src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql new file mode 100644 index 00000000..1bb9c3f3 --- /dev/null +++ b/domain/src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql @@ -0,0 +1,2 @@ +ALTER TABLE member + DROP COLUMN name; diff --git a/domain/src/test/java/com/parkingcomestrue/TestConfiguration.java b/domain/src/test/java/com/parkingcomestrue/TestConfiguration.java new file mode 100644 index 00000000..5ad74c17 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/TestConfiguration.java @@ -0,0 +1,8 @@ +package com.parkingcomestrue; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +class TestConfiguration { + +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepositoryTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepositoryTest.java new file mode 100644 index 00000000..fccb6ccd --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepositoryTest.java @@ -0,0 +1,50 @@ +package com.parkingcomestrue.parking.domain.favorite.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.parkingcomestrue.parking.domain.favorite.Favorite; +import com.parkingcomestrue.parking.support.Association; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class FavoriteRepositoryTest { + + @Autowired + private FavoriteRepository favoriteRepository; + + @Test + void 멤버의_즐겨찾기_주차장을_삭제한다() { + Long memberId = 1L; + Long parkingId = 1L; + Favorite favorite = new Favorite(Association.from(memberId), Association.from(parkingId)); + favoriteRepository.save(favorite); + + favoriteRepository.deleteByMemberIdAndParkingId(Association.from(memberId), Association.from(parkingId)); + assertThat(favoriteRepository.findByMemberId(Association.from(memberId))).isEmpty(); + } + + @Test + void 멤버의_즐겨찾기_주차장을_조회한다() { + // given + Long memberId = 1L; + Long memberId2 = 2L; + + Long parkingId = 1L; + Long parkingId2 = 2L; + Long parkingId3 = 3L; + Long parkingId4 = 4L; + + // when + favoriteRepository.save(new Favorite(Association.from(memberId), Association.from(parkingId))); + favoriteRepository.save(new Favorite(Association.from(memberId), Association.from(parkingId2))); + favoriteRepository.save(new Favorite(Association.from(memberId), Association.from(parkingId3))); + + favoriteRepository.save(new Favorite(Association.from(memberId2), Association.from(parkingId3))); + favoriteRepository.save(new Favorite(Association.from(memberId2), Association.from(parkingId4))); + + // then + assertThat(favoriteRepository.findByMemberId(Association.from(memberId))).hasSize(3); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java new file mode 100644 index 00000000..9e73de44 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java @@ -0,0 +1,64 @@ +package com.parkingcomestrue.parking.domain.member; + +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_PASSWORD; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class MemberTest { + + @Test + void 비밀번호가_일치하면_true_를_반환한다() { + // given + String plainPassword = "password"; + Password password = new Password(plainPassword); + Member member = new Member("email@google.com", "nickname", password); + + // when, then + Assertions.assertThat(member.checkPassword(plainPassword)).isTrue(); + } + + @Test + void 비밀번호가_일치하지_않으면_false_를_반환한다() { + // given + String plainPassword = "password"; + Password password = new Password(plainPassword); + Member member = new Member("email@google.com", "nickname", password); + String wrongPlainPassword = "wrongPassword"; + + // when, then + Assertions.assertThat(member.checkPassword(wrongPlainPassword)).isFalse(); + } + + @Test + void 비밀번호를_바꾼다() { + // given + String previousPassword = "password"; + Password password = new Password(previousPassword); + Member member = new Member("email@google.com", "nickname", password); + String newPassword = "newPassword"; + + // when + member.changePassword(previousPassword, newPassword); + + // then + Assertions.assertThat(member.checkPassword(newPassword)).isTrue(); + } + + @Test + void 비밀번호를_바꿀_때_이전의_비밀번호가_일치하지_않으면_예외를_던진다() { + // given + String previousPassword = "password"; + Password password = new Password(previousPassword); + Member member = new Member("email@google.com", "nickname", password); + String newPassword = "newPassword"; + + String wrongPreviousPassword = "wrongPassword"; + + // when, then + Assertions.assertThatThrownBy(() -> member.changePassword(wrongPreviousPassword, newPassword)) + .isInstanceOf(DomainException.class) + .hasMessage(INVALID_PASSWORD.getMessage()); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/BaseInformationTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/BaseInformationTest.java new file mode 100644 index 00000000..a95d8fef --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/BaseInformationTest.java @@ -0,0 +1,15 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class BaseInformationTest { + + @Test + void 결제_방식_포함_여부를_확인한다() { + PayTypes defaultPayTypes = PayTypes.from(List.of(PayType.NO_INFO)); + + Assertions.assertThat(defaultPayTypes.contains(List.of(PayType.CARD))).isTrue(); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/DayTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/DayTest.java new file mode 100644 index 00000000..7aac391b --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/DayTest.java @@ -0,0 +1,52 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.time.DayOfWeek; +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class DayTest { + + @ParameterizedTest + @MethodSource("getDayOfWeek") + void 요일을_주중_토요일_공휴일로_나눈다(DayOfWeek dayOfWeek, Day expected) { + // given, when, then + Assertions.assertThat(Day.from(dayOfWeek)) + .isSameAs(expected); + } + + static Stream getDayOfWeek() { + return Stream.of( + Arguments.of( + DayOfWeek.MONDAY, + Day.WEEKDAY + ), + Arguments.of( + DayOfWeek.TUESDAY, + Day.WEEKDAY + ), + Arguments.of( + DayOfWeek.WEDNESDAY, + Day.WEEKDAY + ), + Arguments.of( + DayOfWeek.THURSDAY, + Day.WEEKDAY + ), + Arguments.of( + DayOfWeek.FRIDAY, + Day.WEEKDAY + ), + Arguments.of( + DayOfWeek.SATURDAY, + Day.SATURDAY + ), + Arguments.of( + DayOfWeek.SUNDAY, + Day.HOLIDAY + ) + ); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeePolicyTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeePolicyTest.java new file mode 100644 index 00000000..bb789e24 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeePolicyTest.java @@ -0,0 +1,85 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class FeePolicyTest { + + @ParameterizedTest + @MethodSource("getFee") + void 주어진_시간의_요금을_계산한다(FeePolicy feePolicy, int minutes, Fee expected) { + // given, when + Fee actual = feePolicy.calculateFee(minutes); + + // then + Assertions.assertThat(actual).isEqualTo(expected); + } + + static Stream getFee() { + return Stream.of( + Arguments.of( + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(15), + TimeUnit.from(15), + Fee.from(10000)), + 60, + Fee.from(8000) + ), + Arguments.of( + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(15), + TimeUnit.from(15), + Fee.from(10000)), + 2000, + Fee.from(10000) + ), + Arguments.of( + new FeePolicy( + Fee.from(0), + Fee.from(2000), + TimeUnit.from(15), + TimeUnit.from(15), + Fee.from(10000)), + 46, + Fee.from(6000) + ), + Arguments.of( + new FeePolicy( + Fee.from(1000), + Fee.from(2000), + TimeUnit.from(15), + TimeUnit.from(15), + Fee.from(10000)), + 46, + Fee.from(7000) + ), + Arguments.of( + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(55000)), + 180, + Fee.from(22000) + ), + Arguments.of( + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(55000)), + 0, + Fee.from(0) + ) + ); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeeTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeeTest.java new file mode 100644 index 00000000..8e686059 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeeTest.java @@ -0,0 +1,35 @@ +package com.parkingcomestrue.parking.domain.parking; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class FeeTest { + + @Test + void 단위_요금에_시간을_곱한다() { + // given + Fee fee = Fee.from(500); + int time = 10; + Fee expected = Fee.from(5000); + + // when + Fee actual = fee.multiply(time); + + // then + Assertions.assertThat(actual).isEqualTo(expected); + } + + @Test + void 요금끼리_더한다() { + // given + Fee fee = Fee.from(500); + Fee otherFee = Fee.from(500); + Fee expected = Fee.from(1000); + + // when + Fee actual = fee.plus(otherFee); + + // then + Assertions.assertThat(actual).isEqualTo(expected); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTimeTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTimeTest.java new file mode 100644 index 00000000..6b258404 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTimeTest.java @@ -0,0 +1,194 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.time.LocalTime; +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class FreeOperatingTimeTest { + + @ParameterizedTest + @MethodSource("getFreeOperatingTime") + void 돈을_지불_해야_할_시간을_계산한다(FreeOperatingTime freeOperatingTime, DayParking dayParking, int expected) { + // given, when, then + Assertions.assertThat(freeOperatingTime.calculateNonFreeUsageMinutes(dayParking)) + .isEqualTo(expected); + } + + static Stream getFreeOperatingTime() { + return Stream.of( + /* + 주중 무료 시간 : 00:00 ~ 24:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 주중 + 주차 시간 : 00:00 ~ 24:00 + 주차 시간(분) : 1440분 + 무료 시간(분) : 1440분 + 유료 시간(분) : 0분 + */ + Arguments.of( + FreeOperatingTime.ALWAYS_FREE, + new DayParking(Day.WEEKDAY, LocalTime.MIN, LocalTime.MAX), + 0 + ), + /* + 주중 무료 시간 : 09:00 ~ 13:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 주중 + 주차 시간 : 00:00 ~ 24:00 + 주차 시간(분) : 1440분 + 무료 시간(분) : 240분 + 유료 시간(분) : 1200분 + */ + Arguments.of( + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), LocalTime.of(13, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new DayParking(Day.WEEKDAY, LocalTime.MIN, LocalTime.MAX), + 1200 + ), + /* + 주중 무료 시간 : 09:00 ~ 13:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 주중 + 주차 시간 : 09:00 ~ 13:00 + 주차 시간(분) : 240분 + 무료 시간(분) : 240분 + 유료 시간(분) : 0분 + */ + Arguments.of( + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), LocalTime.of(13, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new DayParking(Day.WEEKDAY, LocalTime.of(9, 0), LocalTime.of(13, 0)), + 0 + ), + /* + 주중 무료 시간 : 09:00 ~ 13:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 주중 + 주차 시간 : 08:00 ~ 12:00 + 주차 시간(분) : 240분 + 무료 시간(분) : 180분 + 유료 시간(분) : 60분 + */ + Arguments.of( + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), LocalTime.of(13, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new DayParking(Day.WEEKDAY, LocalTime.of(8, 0), LocalTime.of(12, 0)), + 60 + ), + /* + 주중 무료 시간 : 09:00 ~ 13:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 주중 + 주차 시간 : 10:20 ~ 12:50 + 주차 시간(분) : 150분 + 무료 시간(분) : 150분 + 유료 시간(분) : 0분 + */ + Arguments.of( + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), LocalTime.of(13, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new DayParking(Day.WEEKDAY, LocalTime.of(10, 20), LocalTime.of(12, 50)), + 0 + ), + /* + 주중 무료 시간 : 09:00 ~ 13:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 주중 + 주차 시간 : 13:20 ~ 14:45 + 주차 시간(분) : 85분 + 무료 시간(분) : 0분 + 유료 시간(분) : 85분 + */ + Arguments.of( + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), LocalTime.of(13, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new DayParking(Day.WEEKDAY, LocalTime.of(13, 20), LocalTime.of(14, 45)), + 85 + ), + /* + 주중 무료 시간 : 09:00 ~ 13:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 주중 + 주차 시간 : 11:20 ~ 19:00 + 주차 시간(분) : 460분 + 무료 시간(분) : 100분 + 유료 시간(분) : 360분 + */ + Arguments.of( + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), LocalTime.of(13, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new DayParking(Day.WEEKDAY, LocalTime.of(11, 20), LocalTime.of(19, 0)), + 360 + ), + /* + 주중 무료 시간 : 09:00 ~ 13:00 + 토요일 무료 시간 : 00:00 ~ 24:00 + 공휴일 무료 시간 : 00:00 ~ 24:00 + + 주차 요일 : 토요일 + 주차 시간 : 11:20 ~ 19:00 + 주차 시간(분) : 460분 + 무료 시간(분) : 460분 + 유료 시간(분) : 0분 + */ + Arguments.of( + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), LocalTime.of(13, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new DayParking(Day.SATURDAY, LocalTime.of(11, 20), LocalTime.of(19, 0)), + 0 + ) + ); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/LocationTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/LocationTest.java new file mode 100644 index 00000000..bc8e57cd --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/LocationTest.java @@ -0,0 +1,38 @@ +package com.parkingcomestrue.parking.domain.parking; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class LocationTest { + + @Test + void 위도와_경도를_통해_Point객체를_가진_Location객체를_생성한다() { + double latitude = 37.4809626; + double longitude = 127.1216765; + + Location location = Location.of(longitude, latitude); + + assertAll( + () -> assertThat(location.getLongitude()).isEqualTo(longitude), + () -> assertThat(location.getLatitude()).isEqualTo(latitude) + ); + } + + @CsvSource({"0.1, -", " , 0.2", "nil, nil"}) + @ParameterizedTest + void 이상한_값이_들어오면_특정_음수_좌표를_반환한다(String longitude, String latitude) { + //given, when + Location actual = Location.of(longitude, latitude); + Location expected = Location.of("-1.0", "-1.0"); + + //then + assertThat(actual).isEqualTo(expected); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculatorTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculatorTest.java new file mode 100644 index 00000000..494ed2ab --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculatorTest.java @@ -0,0 +1,394 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ParkingFeeCalculatorTest { + + private final ParkingFeeCalculator parkingFeeCalculator = new ParkingFeeCalculator(); + + @ParameterizedTest + @MethodSource("getParkingFeeCalculator") + void 주차요금을_계산한다(Parking parking, LocalDateTime beginTime, LocalDateTime endTime, Fee expected) { + // given, when + Fee actual = parkingFeeCalculator.calculateParkingFee(parking, beginTime, endTime); + + // then + Assertions.assertThat(actual).isEqualTo(expected); + } + + static Stream getParkingFeeCalculator() { + return Stream.of( + /* + 주차장 정보 + [무료 운영 정보] + 주중 : 09:00 ~ 12:00 무료 + 토요일 : 00:00 ~ 24:00 무료 + 일요일 : 00:00 ~ 24:00 무료 + + [요금 정보] + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 요금 : 50000원 + + 주차 정보 + 주차 시작 시각 : 2024/2/16/금/09:00 + 주차 종료 시각 : 2024/2/16/금/21:00 + + 계산 주차 금액 + 1. 2/16 유료 주차 시간 : 2024/2/16/12:00 ~ 2024/2/16/21:00 (540분) + 1. 2/16 주차 금액 : 2000원 + 68000원 = 70000원 -> 하루 최대 요금 적용 -> 50000원 + + 주차 금액 합 : 50000원 + */ + Arguments.of( + new Parking( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), + LocalTime.of(12, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000) + ) + ), + LocalDateTime.of(2024, 2, 16, 9, 0), + LocalDateTime.of(2024, 2, 16, 21, 0), + Fee.from(50000) + ), + /* + 주차장 정보 + [무료 운영 정보] + 주중 : 09:00 ~ 12:00 무료 + 토요일 : 00:00 ~ 24:00 무료 + 일요일 : 00:00 ~ 24:00 무료 + + [요금 정보] + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 요금 : 50000원 + + 주차 정보 + 주차 시작 시각 : 2024/2/16/금/09:00 + 주차 종료 시각 : 2024/2/16/금/13:16 + + 계산 주차 금액 + 1. 2/16 유료 주차 시간 : 2024/2/16/12:00 ~ 2024/2/16/13:16 (76분) + 1. 2/16 주차 금액 : 2000원 + 8000원 = 10000원 + + 주차 금액 합 : 10000원 + */ + Arguments.of( + new Parking( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), + LocalTime.of(12, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000) + ) + ), + LocalDateTime.of(2024, 2, 16, 9, 0), + LocalDateTime.of(2024, 2, 16, 13, 16), + Fee.from(10000) + ), + /* + 주차장 정보 + [무료 운영 정보] + 주중 : 09:00 ~ 12:00 무료 + 토요일 : 00:00 ~ 24:00 무료 + 일요일 : 00:00 ~ 24:00 무료 + + [요금 정보] + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 요금 : 50000원 + + 주차 정보 + 주차 시작 시각 : 2024/2/16/금/10:00 + 주차 종료 시각 : 2024/2/16/금/12:01 + + 계산 주차 금액 + 1. 2/16 유료 주차 시간 : 2024/2/16/12:00 ~ 2024/2/16/12:01 (1분) + 1. 2/16 주차 금액 : 2000원 (기본 요금) + + 주차 금액 합 : 2000원 + */ + Arguments.of( + new Parking( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), + LocalTime.of(12, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000) + ) + ), + LocalDateTime.of(2024, 2, 16, 10, 0), + LocalDateTime.of(2024, 2, 16, 12, 1), + Fee.from(2000) + ), + /* + 주차장 정보 + [무료 운영 정보] + 주중 : 09:00 ~ 12:00 무료 + 토요일 : 00:00 ~ 24:00 무료 + 일요일 : 00:00 ~ 24:00 무료 + + [요금 정보] + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 요금 : 50000원 + + 주차 정보 + 주차 시작 시각 : 2024/2/16/금/21:00 + 주차 종료 시각 : 2024/2/17/토/09:00 + + 계산 주차 금액 + 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) + 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 + + 2. 2/17 유료 주차 시간 : 없음 + 2. 2/17 주차 금액 : 0원 + + 주차 금액 합 : 22000원 + */ + Arguments.of( + new Parking( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), + LocalTime.of(12, 0) + ), + TimeInfo.ALL_DAY, + TimeInfo.ALL_DAY + ), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000) + ) + ), + LocalDateTime.of(2024, 2, 16, 21, 0), + LocalDateTime.of(2024, 2, 17, 9, 0), + Fee.from(22000) + ), + /* + 주차장 정보 + [무료 운영 정보] + 주중 : 09:00 ~ 12:00 무료 + 토요일 : 06:00 ~ 24:00 무료 + 일요일 : 00:00 ~ 24:00 무료 + + [요금 정보] + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 요금 : 50000원 + + 주차 정보 + 주차 시작 시각 : 2024/2/16/금/21:00 + 주차 종료 시각 : 2024/2/17/토/09:00 + + 계산 주차 금액 + 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) + 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 + + 2. 2/17 유료 주차 시간 : 2024/2/17/00:00 ~ 2024/2/17/06:00 (360분) + 2. 2/17 주차 금액 : 2000원 + 44000원 = 46000원 + + 주차 금액 합 : 68000원 + */ + Arguments.of( + new Parking( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), + LocalTime.of(12, 0) + ), + new TimeInfo( + LocalTime.of(6, 0), + LocalTime.MAX + ), + TimeInfo.ALL_DAY + ), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000) + ) + ), + LocalDateTime.of(2024, 2, 16, 21, 0), + LocalDateTime.of(2024, 2, 17, 9, 0), + Fee.from(68000) + ), + /* + 주차장 정보 + [무료 운영 정보] + 주중 : 09:00 ~ 12:00 무료 + 토요일 : 00:00 ~ 24:00 무료 + 일요일 : 04:00 ~ 24:00 무료 + + [요금 정보] + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 요금 : 50000원 + + 주차 정보 + 주차 시작 시각 : 2024/2/16/금/21:00 + 주차 종료 시각 : 2024/2/18/일/09:00 + + 계산 주차 금액 + 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) + 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 + + 2. 2/17 유료 주차 시간 : 없음 + 2. 2/17 주차 금액 : 0원 + + 3. 2/18 유료 주차 시간 : 2024/2/18/00:00 ~ 2024/2/18/04:00 (240분) + 3. 2/18 주차 금액 : 2000원 + 28000원 = 30000원 + + 주차 금액 합 : 22000원 + 0원 + 30000원 = 52000원 + */ + Arguments.of( + new Parking( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), + LocalTime.of(12, 0) + ), + TimeInfo.ALL_DAY, + new TimeInfo( + LocalTime.of(4, 0), + LocalTime.MAX + ) + ), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000) + ) + ), + LocalDateTime.of(2024, 2, 16, 21, 0), + LocalDateTime.of(2024, 2, 18, 9, 0), + Fee.from(52000) + ), + /* + 주차장 정보 + [무료 운영 정보] + 주중 : 09:00 ~ 12:00 무료 + 토요일 : 00:00 ~ 24:00 무료 + 일요일 : 04:00 ~ 24:00 무료 + + [요금 정보] + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 요금 : 50000원 + + 주차 정보 + 주차 시작 시각 : 2024/2/16/금/21:00 + 주차 종료 시각 : 2024/2/18/월/05:00 + + 계산 주차 금액 + 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) + 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 + + 2. 2/17 유료 주차 시간 : 없음 + 2. 2/17 주차 금액 : 0원 + + 3. 2/18 유료 주차 시간 : 2024/2/18/00:00 ~ 2024/2/18/04:00 (240분) + 3. 2/18 주차 금액 : 2000원 + 28000원 = 30000원 + + 4. 2/19 유료 주차 시간 : 2024/2/19/00:00 ~ 2024/2/19/05:01 (301분) + 4. 2/19 주차 금액 : 2000원 + 38000원 = 40000원 + 주차 금액 합 : 22000원 + 0원 + 30000원 + 40000원 = 92000원 + */ + Arguments.of( + new Parking( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime( + new TimeInfo( + LocalTime.of(9, 0), + LocalTime.of(12, 0) + ), + TimeInfo.ALL_DAY, + new TimeInfo( + LocalTime.of(4, 0), + LocalTime.MAX + ) + ), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000) + ) + ), + LocalDateTime.of(2024, 2, 16, 21, 0), + LocalDateTime.of(2024, 2, 19, 5, 1), + Fee.from(92000) + ) + ); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingTest.java new file mode 100644 index 00000000..292a02cb --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingTest.java @@ -0,0 +1,188 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ParkingTest { + + @Test + void 목적지와_68미터_떨어진_주차장_도보_예상시간_계산() { + // given (parking 과 destination 거리 68m) + int expectedTime = (int) Math.ceil(0.068 / 5); + Parking parking = Parking.builder() + .location(Location.of(127.1215865, 37.4811181)) + .build(); + Location destination = Location.of(127.1213647, 37.4817298); + + // when + int walkingTime = parking.calculateWalkingTime(destination); + + // then + Assertions.assertThat(walkingTime).isEqualTo(expectedTime); + } + + @Test + void 목적지와_333미터_떨어진_주차장_도보_예상시간_계산() { + // given (parking 과 destination 거리 68m) + int expectedTime = (int) Math.ceil(0.333 / 5); + Parking parking = Parking.builder() + .location(Location.of(127.1215865, 37.4811181)) + .build(); + Location destination = Location.of(127.1186224, 37.479259); + + // when + int walkingTime = parking.calculateWalkingTime(destination); + + // then + Assertions.assertThat(walkingTime).isEqualTo(expectedTime); + } + + @ParameterizedTest + @MethodSource("getParking") + void 주어진_주차장_정보에_따라_하루_요금_계산을_한다(Parking parking, int payOfChargeMinutes, Fee expected) { + // given, when + Fee actual = parking.calculateParkingFee(payOfChargeMinutes); + + // then + Assertions.assertThat(actual).isEqualTo(expected); + } + + static Stream getParking() { + return Stream.of( + /* + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 주차 요금 : 50000원 + + 주차 시간 : 100분 + 주차 금액 : 2000원 + 10000원 = 12000원 + */ + Arguments.of( + new Parking + ( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime(), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000)) + ), + 100, + Fee.from(12000) + ), + /* + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 주차 요금 : 50000원 + + 주차 시간 : 30분 + 주차 금액 : 2000원 + */ + Arguments.of( + new Parking + ( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime(), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000)) + ), + 30, + Fee.from(2000) + ), + /* + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 주차 요금 : 50000원 + + 주차 시간 : 31분 + 주차 금액 : 2000 + 2000원 = 4000원 + */ + Arguments.of( + new Parking + ( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime(), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000)) + ), + 31, + Fee.from(4000) + ), + /* + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 주차 요금 : 50000원 + + 주차 시간 : 480분 + 주차 금액 : 2000 + 60000원 = 62000원 -> 하루 최대 요금 50000원 적용 + */ + Arguments.of( + new Parking + ( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime(), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000)) + ), + 480, + Fee.from(50000) + ), + /* + 기본 주차 요금 정책 : 30분당 2000원 + 추가 주차 요금 정책 : 15분당 2000원 + 하루 최대 주차 요금 : 50000원 + + 주차 시간 : 374분 + 주차 금액 : 2000 + 46000원 = 48000원 + */ + Arguments.of( + new Parking + ( + new BaseInformation(), + new Location(), + new Space(), + new FreeOperatingTime(), + new OperatingTime(), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000)) + ), + 374, + Fee.from(48000) + ) + ); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/PayTypesTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/PayTypesTest.java new file mode 100644 index 00000000..a1792d3a --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/PayTypesTest.java @@ -0,0 +1,65 @@ +package com.parkingcomestrue.parking.domain.parking; + +import static com.parkingcomestrue.parking.domain.parking.PayType.BANK_TRANSFER; +import static com.parkingcomestrue.parking.domain.parking.PayType.CARD; +import static com.parkingcomestrue.parking.domain.parking.PayType.CASH; +import static com.parkingcomestrue.parking.domain.parking.PayType.NO_INFO; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class PayTypesTest { + + @ParameterizedTest + @MethodSource("parametersProvider") + void 열거형으로_결제방식을_생성한다(Collection payTypes, String expected) { + //given, when + PayTypes actual = PayTypes.from(payTypes); + + //then + assertThat(actual.getDescription()).isEqualTo(expected); + } + + @Test + void 결제방식_포함_시_true() { + //given, when + PayTypes actual = PayTypes.from(List.of(CARD, CASH)); + + //then + assertThat(actual.contains(List.of(CARD))).isTrue(); + } + + @Test + void 결제방식_미포함_시_false() { + //given, when + PayTypes actual = PayTypes.from(List.of(CARD, CASH)); + + //then + assertThat(actual.contains(List.of(BANK_TRANSFER))).isFalse(); + } + + static Stream parametersProvider() { + final String DELIMITER = ", "; + return Stream.of( + arguments(Set.of(CARD), CARD.getDescription()), + arguments(Set.of(CARD, CASH), CARD.getDescription() + DELIMITER + CASH.getDescription()), + arguments(Set.of(CARD, CASH, BANK_TRANSFER), + BANK_TRANSFER.getDescription() + DELIMITER + CARD.getDescription() + DELIMITER + + CASH.getDescription()), + arguments(Set.of(CARD, CASH, BANK_TRANSFER, NO_INFO), NO_INFO.getDescription()) + ); + } +} + + diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeInfoTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeInfoTest.java new file mode 100644 index 00000000..23f5e08d --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeInfoTest.java @@ -0,0 +1,164 @@ +package com.parkingcomestrue.parking.domain.parking; + +import java.time.LocalTime; +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class TimeInfoTest { + + @ParameterizedTest + @MethodSource("getTimeInfos") + void 겹치는_시간이_몇_분인지_계산한다(TimeInfo timeInfo, LocalTime beginTime, LocalTime endTime, int expected) { + // given, when, then + Assertions.assertThat(timeInfo.calculateOverlapMinutes(beginTime, endTime)) + .isEqualTo(expected); + } + + static Stream getTimeInfos() { + return Stream.of( + /* + 무료 운영 시간 : 00:00 ~ 24:00 + 주차 시간 : 00:00 ~ 24:00 + 겹침 시간 : 00:00 ~ 24:00 -> 1440분 + */ + Arguments.of( + new TimeInfo(LocalTime.MIN, LocalTime.MAX), + LocalTime.MIN, + LocalTime.MAX, + 1440), + /* + 무료 운영 시간 : 00:00 ~ 24:00 + 주차 시간 : 01:30 ~ 22:11 + 겹침 시간 : 01:30 ~ 22:11 -> 1241분 + */ + Arguments.of( + new TimeInfo(LocalTime.MIN, LocalTime.MAX), + LocalTime.of(1, 30), + LocalTime.of(22, 11), + 1241), + /* + 무료 운영 시간 : 09:00 ~ 21:00 + 주차 시간 : 08:00 ~ 09:00 + 겹침 시간 : 겹치지 않는다 -> 0분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), + LocalTime.of(8, 0), + LocalTime.of(9, 0), + 0), + /* + 무료 운영 시간 : 09:00 ~ 21:00 + 주차 시간 : 08:00 ~ 09:30 + 겹침 시간 : 09:00 ~ 09:30 -> 30분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), + LocalTime.of(8, 0), + LocalTime.of(9, 30), + 30), + /* + 무료 운영 시간 : 09:00 ~ 21:00 + 주차 시간 : 08:00 ~ 21:00 + 겹침 시간 : 09:00 ~ 21:00 -> 720분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), + LocalTime.of(8, 0), + LocalTime.of(21, 0), + 720), + /* + 무료 운영 시간 : 09:00 ~ 21:00 + 주차 시간 : 08:00 ~ 22:40 + 겹침 시간 : 00:00 ~ 24:00 -> 1440분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), + LocalTime.of(8, 0), + LocalTime.of(22, 40), + 720), + /* + 무료 운영 시간 : 09:00 ~ 21:00 + 주차 시간 : 10:00 ~ 17:20 + 겹침 시간 : 10:00 ~ 17:20 -> 440분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), + LocalTime.of(10, 0), + LocalTime.of(17, 20), + 440), + /* + 무료 운영 시간 : 09:00 ~ 21:00 + 주차 시간 : 10:00 ~ 21:00 + 겹침 시간 : 10:00 ~ 21:00 -> 660분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), + LocalTime.of(10, 0), + LocalTime.of(21, 0), + 660), + /* + 무료 운영 시간 : 09:00 ~ 21:00 + 주차 시간 : 21:00 ~ 23:00 + 겹침 시간 : 겹치지 않는다 -> 0분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), + LocalTime.of(21, 0), + LocalTime.of(23, 0), + 0), + /* + 무료 운영 시간 : 21:00 ~ 09:00 + 주차 시간 : 21:00 ~ 24:00 + 겹침 시간 : 21:00 ~ 24:00 -> 180분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), + LocalTime.of(21, 0), + LocalTime.MAX, + 180), + /* + 무료 운영 시간 : 21:00 ~ 09:00 + 주차 시간 : 09:00 ~ 21:00 + 겹침 시간 : 겹치지 않는다 -> 0분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), + LocalTime.of(9, 0), + LocalTime.of(21, 0), + 0), + /* + 무료 운영 시간 : 21:00 ~ 09:00 + 주차 시간 : 09:00 ~ 21:01 + 겹침 시간 : 21:00 ~ 21:01 -> 1분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), + LocalTime.of(9, 0), + LocalTime.of(21, 1), + 1), + /* + 무료 운영 시간 : 21:00 ~ 09:00 + 주차 시간 : 08:59 ~ 21:00 + 겹침 시간 : 08:59 ~ 09:00 -> 1분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), + LocalTime.of(8, 59), + LocalTime.of(21, 0), + 1), + /* + 무료 운영 시간 : 21:00 ~ 09:00 + 주차 시간 : 08:59 ~ 21:01 + 겹침 시간 : 08:59 ~ 09:00 + 21:00 ~ 21:01 -> 2분 + */ + Arguments.of( + new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), + LocalTime.of(8, 59), + LocalTime.of(21, 1), + 2) + ); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeUnitTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeUnitTest.java new file mode 100644 index 00000000..0458e8ba --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeUnitTest.java @@ -0,0 +1,36 @@ +package com.parkingcomestrue.parking.domain.parking; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class TimeUnitTest { + + @Test + void 시간_단위의_대소_비교한다() { + // given + TimeUnit timeUnit = TimeUnit.from(100); + int otherTimeUnit = 1000; + boolean expected = false; + + // when + boolean actual = timeUnit.isEqualOrGreaterThan(otherTimeUnit); + + // then + Assertions.assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @CsvSource(value = {"10:60:6", "10:59:6"}, delimiter = ':') + void 시간을_단위_시간으로_나눈_몫을_구한다(int timeUnit, int time, int expected) { + // given + TimeUnit unit = TimeUnit.from(timeUnit); + + // when + int actual = unit.calculateQuotient(time); + + // then + Assertions.assertThat(actual).isEqualTo(expected); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringServiceTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringServiceTest.java new file mode 100644 index 00000000..cffb5014 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringServiceTest.java @@ -0,0 +1,162 @@ +package com.parkingcomestrue.parking.domain.parking.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.parkingcomestrue.parking.domain.parking.BaseInformation; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.FeePolicy; +import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingFeeCalculator; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.parking.domain.parking.SearchingCondition; +import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import java.time.LocalDateTime; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class ParkingFilteringServiceTest { + + private final ParkingFilteringService parkingFilteringService = new ParkingFilteringService( + new ParkingFeeCalculator()); + + @Test + void 조회조건에_따라_주차장을_필터링한다1() { + // given + ParkingType parkingTypeCondition = ParkingType.MECHANICAL; + OperationType operationTypeCondition = OperationType.PUBLIC; + PayType wantPayType = PayType.CASH; + + Parking wantParking = Parking.builder() + .baseInformation(new BaseInformation("name", "tell", "address", + PayTypes.from(List.of(wantPayType)), + parkingTypeCondition, + operationTypeCondition)) + .build(); + + Parking notWantParking1 = Parking.builder() + .baseInformation(new BaseInformation("name", "tell", "address", + PayTypes.DEFAULT, + parkingTypeCondition, + OperationType.NO_INFO)) + .build(); + + Parking notWantParking2 = Parking.builder() + .baseInformation(new BaseInformation("name", "tell", "address", + PayTypes.DEFAULT, + ParkingType.OFF_STREET, + operationTypeCondition)) + .build(); + + // when + SearchingCondition searchingCondition = new SearchingCondition( + List.of(operationTypeCondition), + List.of(parkingTypeCondition), + List.of(wantPayType), + FeeType.PAID, 3); + + List filterList = parkingFilteringService.filterByCondition( + List.of(wantParking, notWantParking1, notWantParking2), + searchingCondition, + LocalDateTime.now() + ); + + // then + assertThat(filterList).hasSize(1); + } + + @Test + void 조회조건에_따라_주차장을_필터링한다2() { + // given + ParkingType wantParkingTypeCondition = ParkingType.ON_STREET; + OperationType wantOperationTypeCondition = OperationType.PUBLIC; + PayType wantPayType = PayType.CARD; + + Parking wantParking = Parking.builder() + .baseInformation(new BaseInformation("name", "tel", "address", + PayTypes.from(List.of(wantPayType)), + wantParkingTypeCondition, + wantOperationTypeCondition)) + .build(); + + Parking notWantParking1 = Parking.builder() + .baseInformation(new BaseInformation("name", "tel", "address", + PayTypes.DEFAULT, + ParkingType.MECHANICAL, + wantOperationTypeCondition)) + .build(); + + Parking notWantParking2 = Parking.builder() + .baseInformation(new BaseInformation("name", "tel", "address", + PayTypes.DEFAULT, + ParkingType.NO_INFO, + wantOperationTypeCondition)) + .build(); + + // when + SearchingCondition searchingCondition = new SearchingCondition( + List.of(wantOperationTypeCondition), + List.of(wantParkingTypeCondition), + List.of(wantPayType), + FeeType.PAID, 3); + + List result = parkingFilteringService.filterByCondition( + List.of(wantParking, notWantParking1, notWantParking2), + searchingCondition, + LocalDateTime.now() + ); + + // then + assertThat(result).hasSize(1); + } + + @Test + void 조회조건이_무료일_때_예상요금이_0인_주차장만_조회된다() { + // given - 하루종일 무료 주차장 2개, 유료 주차장 1개 + FeePolicy freeFeePolicy = new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(10), TimeUnit.from(10), Fee.ZERO); + + OperationType operationType = OperationType.PUBLIC; + ParkingType parkingType = ParkingType.MECHANICAL; + BaseInformation baseInformation = new BaseInformation("name", "tel", "address", + PayTypes.from(List.of(PayType.CARD)), + parkingType, + operationType + ); + Parking freeParking1 = Parking.builder() + .baseInformation(baseInformation) + .freeOperatingTime(FreeOperatingTime.ALWAYS_FREE) + .feePolicy(freeFeePolicy) + .build(); + + Parking freeParking2 = Parking.builder() + .baseInformation(baseInformation) + .freeOperatingTime(FreeOperatingTime.ALWAYS_FREE) + .feePolicy(freeFeePolicy) + .build(); + + FeePolicy paidFeePolicy = new FeePolicy(Fee.from(100), Fee.from(200), TimeUnit.from(1), TimeUnit.from(12), + Fee.from(1000)); + Parking paidParking = Parking.builder() + .baseInformation(baseInformation) + .freeOperatingTime(FreeOperatingTime.ALWAYS_PAY) + .feePolicy(paidFeePolicy) + .build(); + + // when - 검색조건이 Free 인 filterCondition 으로 주차장 필터링 + SearchingCondition searchingCondition = new SearchingCondition(List.of(operationType), List.of(parkingType), + List.of(PayType.CARD), FeeType.FREE, 3); + List filteredParkings = parkingFilteringService.filterByCondition( + List.of(freeParking1, freeParking2, paidParking), + searchingCondition, + LocalDateTime.now() + ); + + // then + Assertions.assertThat(filteredParkings).hasSize(2); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java new file mode 100644 index 00000000..887ac490 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java @@ -0,0 +1,41 @@ +package com.parkingcomestrue.parking.domain.review; + +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_CONTENT; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ContentTest { + + @ParameterizedTest + @MethodSource("parametersProvider") + void 설명에_Content를_반환한다(String description, Content expected) { + //given, when + Content actual = Content.find(description); + + //then + assertThat(actual).isEqualTo(expected); + } + + static Stream parametersProvider() { + return Stream.of( + arguments("결제가 편리해요", Content.EASY_TO_PAY), + arguments("직원", Content.FRIENDLY_STAFF) + ); + } + + @Test + void 설명에_맞는_Content가_없으면_예외처리한다() { + //given, when, then + assertThatThrownBy(() -> Content.find("없는 설명")) + .isInstanceOf(DomainException.class) + .hasMessage(INVALID_CONTENT.getMessage()); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java new file mode 100644 index 00000000..99700879 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java @@ -0,0 +1,87 @@ +package com.parkingcomestrue.parking.domain.review.service; + +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.DUPLICATE_REVIEW; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.review.Content; +import com.parkingcomestrue.parking.domain.review.Review; +import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.parking.support.exception.DomainException; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import repository.BasicReviewRepository; + +class ReviewDomainServiceTest { + + private final BasicReviewRepository reviewRepository = new BasicReviewRepository(); + private final ReviewDomainService reviewDomainService = new ReviewDomainService(reviewRepository); + + @Test + void 같은_주차장에_리뷰를_작성하면_예외가_발생한다() { + //given + Association parkingId = Association.from(1L); + Association reviewerId = Association.from(1L); + reviewRepository.save(new Review(parkingId, reviewerId, List.of(Content.LOW_PRICE))); + + //when, then + assertThatThrownBy(() -> reviewDomainService.validateDuplicateReview(parkingId, reviewerId)) + .isInstanceOf(DomainException.class) + .hasMessage(DUPLICATE_REVIEW.getMessage()); + } + + @Test + void 리뷰를_내용별로_집계한다() { + //given + List reviews = List.of( + new Review(Association.from(1L), Association.from(1L), + List.of(Content.LOW_PRICE) + ), + new Review(Association.from(1L), Association.from(2L), + List.of(Content.LOW_PRICE, Content.EASY_TO_PAY) + ), + new Review(Association.from(1L), Association.from(3L), + List.of(Content.LOW_PRICE, Content.EASY_TO_PAY, Content.GOOD_ACCESSIBILITY) + ) + ); + //when + Map actual = reviewDomainService.collectByContent(reviews); + + //then + assertSoftly(soft -> { + soft.assertThat(actual.get(Content.LOW_PRICE)).isEqualTo(3L); + soft.assertThat(actual.get(Content.EASY_TO_PAY)).isEqualTo(2L); + soft.assertThat(actual.get(Content.GOOD_ACCESSIBILITY)).isEqualTo(1L); + }); + } + + @Test + void 전체_리뷰수를_구한다() { + //given + List contents1 = List.of(Content.LOW_PRICE); + List contents2 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY); + List contents3 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY, Content.GOOD_ACCESSIBILITY); + List reviews = List.of( + new Review(Association.from(1L), Association.from(1L), + contents1 + ), + new Review(Association.from(1L), Association.from(2L), + contents2 + ), + new Review(Association.from(1L), Association.from(3L), + contents3 + ) + ); + Map counts = reviewDomainService.collectByContent(reviews); + + //when + int actual = reviewDomainService.calculateTotalReviews(counts); + + //then + assertThat(actual).isEqualTo(contents1.size() + contents2.size() + contents3.size()); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java new file mode 100644 index 00000000..98f973a7 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java @@ -0,0 +1,25 @@ +package com.parkingcomestrue.parking.domain.searchcondition; + +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_HOURS; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import com.parkingcomestrue.parking.support.exception.DomainException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class HoursTest { + + @CsvSource({"1, false", "12, false", "24, false", "0, true", "13, true"}) + @ParameterizedTest + void 이용_시간은_1시간에서_12시간_사이_또는_24시간만_선택_가능하다(int hours, boolean hasException) { + //given, when, then + if (hasException) { + Assertions.assertThatThrownBy(() -> Hours.from(hours)) + .isInstanceOf(DomainException.class) + .hasMessage(INVALID_HOURS.getMessage()); + return; + } + assertDoesNotThrow(() -> Hours.from(hours)); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepositoryTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepositoryTest.java new file mode 100644 index 00000000..0f811176 --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepositoryTest.java @@ -0,0 +1,45 @@ +package com.parkingcomestrue.parking.domain.session.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.parkingcomestrue.parking.domain.session.MemberSession; +import java.time.LocalDateTime; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +class MemberSessionRepositoryTest { + + @Autowired + private MemberSessionRepository memberSessionRepository; + + @Test + void 현재_시간이_세션_만료_시간보다_늦지_않으면_세션이_조회된다() { + // given + MemberSession memberSession = new MemberSession(UUID.randomUUID().toString(), 1L, LocalDateTime.now(), + LocalDateTime.now()); + memberSessionRepository.save(memberSession); + + // when, then + assertThat(memberSessionRepository.findBySessionIdAndExpiredAtIsGreaterThanEqual(memberSession.getSessionId(), + LocalDateTime.now().minusDays(1))) + .isPresent(); + } + + @Test + void 현재_시간이_세션_만료_시간보다_늦으면_빈_옵셔널을_반환한다() { + // given + MemberSession memberSession = new MemberSession(UUID.randomUUID().toString(), 1L, LocalDateTime.now(), + LocalDateTime.now().minusDays(1)); + memberSessionRepository.save(memberSession); + + // when, then + assertThat(memberSessionRepository.findBySessionIdAndExpiredAtIsGreaterThanEqual(memberSession.getSessionId(), + LocalDateTime.now())) + .isEmpty(); + } +} diff --git a/domain/src/test/java/com/parkingcomestrue/parking/infra/converter/EnumListConverterTest.java b/domain/src/test/java/com/parkingcomestrue/parking/infra/converter/EnumListConverterTest.java new file mode 100644 index 00000000..2c99f28e --- /dev/null +++ b/domain/src/test/java/com/parkingcomestrue/parking/infra/converter/EnumListConverterTest.java @@ -0,0 +1,30 @@ +package com.parkingcomestrue.parking.infra.converter; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class EnumListConverterTest { + + @DisplayName("DB에 Enum을 List형식으로 저장할 때, Enum의 값 이름과 " + '"' + ", " + '"' + " 구분자를 이용해서 저장된다.") + @Test + void convertTest() { + //given + FeeTypeConverter feeTypeConverter = new FeeTypeConverter(); + List expectedFeeType = List.of(FeeType.FREE, FeeType.PAID); + String expectedDatabaseColumn = expectedFeeType.stream().map(FeeType::name) + .collect(Collectors.joining(", ")); + + //when + String actualDatabaseField = feeTypeConverter.convertToDatabaseColumn(expectedFeeType); + List actualFeeTypes = feeTypeConverter.convertToEntityAttribute(actualDatabaseField); + + //then + assertThat(actualDatabaseField).isEqualTo(expectedDatabaseColumn); + assertThat(actualFeeTypes).isEqualTo(expectedFeeType); + } +} diff --git a/domain/src/test/resources/application.yml b/domain/src/test/resources/application.yml new file mode 100644 index 00000000..7fa6b598 --- /dev/null +++ b/domain/src/test/resources/application.yml @@ -0,0 +1,3 @@ +spring: + flyway: + enabled: false diff --git a/domain/src/testFixtures/java/repository/BasicMemberRepository.java b/domain/src/testFixtures/java/repository/BasicMemberRepository.java new file mode 100644 index 00000000..4075cb4b --- /dev/null +++ b/domain/src/testFixtures/java/repository/BasicMemberRepository.java @@ -0,0 +1,58 @@ +package repository; + +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.member.Password; +import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class BasicMemberRepository implements MemberRepository, BasicRepository { + + private static Long id = 1L; + private final Map store = new HashMap<>(); + + @Override + public boolean existsByEmail(String email) { + return store.values() + .stream() + .anyMatch(member -> member.getEmail().equals(email)); + } + + @Override + public Optional findById(Long id) { + return Optional.of(store.get(id)); + } + + @Override + public Optional findByEmail(String email) { + return store.values() + .stream() + .filter(member -> member.getEmail().equals(email)) + .findAny(); + } + + @Override + public void save(Member member) { + setId(member, id); + store.put(id++, member); + } + + public List saveAndGet(int size) { + LinkedList result = new LinkedList<>(); + for (int i = 0; i < size; i++) { + Member member = new Member( + "testEmail" + i + "@email.com", + "nickname" + i, + new Password("password1234") + ); + result.add(member); + } + for (Member member : result) { + save(member); + } + return result; + } +} diff --git a/domain/src/testFixtures/java/repository/BasicParkingRepository.java b/domain/src/testFixtures/java/repository/BasicParkingRepository.java new file mode 100644 index 00000000..42d84a55 --- /dev/null +++ b/domain/src/testFixtures/java/repository/BasicParkingRepository.java @@ -0,0 +1,88 @@ +package repository; + +import com.parkingcomestrue.parking.domain.parking.BaseInformation; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.FeePolicy; +import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.OperatingTime; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.parking.domain.parking.Space; +import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import com.parkingcomestrue.parking.domain.parking.repository.ParkingRepository; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.locationtech.jts.geom.Point; + +public class BasicParkingRepository implements ParkingRepository, BasicRepository { + + private static Long id = 1L; + private final Map store = new HashMap<>(); + + @Override + public Optional findById(Long id) { + return Optional.of(store.get(id)); + } + + @Override + public List findAroundParkingLots(Point point, int radius) { + return Collections.EMPTY_LIST; + } + + @Override + public List findAroundParkingLotsOrderByDistance(Point point, int radius) { + return Collections.EMPTY_LIST; + } + + @Override + public Set findAllByBaseInformationNameIn(Set names) { + return store.values() + .stream() + .filter(parking -> names.contains(parking.getBaseInformation().getName())) + .collect(Collectors.toSet()); + } + + @Override + public void saveAll(Iterable parkingLots) { + for (Parking parkingLot : parkingLots) { + save(parkingLot); + } + } + + public void save(Parking parkingLot) { + setId(parkingLot, id); + store.put(id++, parkingLot); + } + + public List saveAndGet(int size) { + LinkedList result = new LinkedList<>(); + for (int i = 0; i < size; i++) { + Parking parking = new Parking( + new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, PayTypes.DEFAULT, + ParkingType.NO_INFO, + OperationType.PUBLIC), + Location.of("33.333" + i, "44.444" + i), + Space.of(-1, -1), + FreeOperatingTime.ALWAYS_FREE, + OperatingTime.ALWAYS_OPEN, + new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(0), TimeUnit.from(0), Fee.ZERO) + ); + result.add(parking); + } + saveAll(result); + return result; + } + + public int count() { + return store.size(); + } +} diff --git a/domain/src/testFixtures/java/repository/BasicRepository.java b/domain/src/testFixtures/java/repository/BasicRepository.java new file mode 100644 index 00000000..6e99a9a7 --- /dev/null +++ b/domain/src/testFixtures/java/repository/BasicRepository.java @@ -0,0 +1,16 @@ +package repository; + +import java.lang.reflect.Field; + +public interface BasicRepository { + + default void setId(T entity, ID id) { + try { + Field field = entity.getClass().getDeclaredField("id"); + field.setAccessible(true); + field.set(entity, id); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/domain/src/testFixtures/java/repository/BasicReviewRepository.java b/domain/src/testFixtures/java/repository/BasicReviewRepository.java new file mode 100644 index 00000000..a471b734 --- /dev/null +++ b/domain/src/testFixtures/java/repository/BasicReviewRepository.java @@ -0,0 +1,42 @@ +package repository; + +import com.parkingcomestrue.parking.domain.review.Review; +import com.parkingcomestrue.parking.domain.review.repository.ReviewRepository; +import com.parkingcomestrue.parking.support.Association; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class BasicReviewRepository implements ReviewRepository, BasicRepository { + + private static Long id = 1L; + private final Map store = new HashMap<>(); + + @Override + public Optional findById(Long id) { + return Optional.of(store.get(id)); + } + + @Override + public List findAllByParkingId(Association parkingId) { + return store.values().stream() + .filter(review -> review.getParkingId().equals(parkingId)) + .toList(); + } + + @Override + public void save(Review review) { + setId(review, id); + store.put(id++, review); + } + + @Override + public boolean existsByParkingIdAndReviewerId(Association parkingId, Association reviewerId) { + return store.values().stream() + .anyMatch( + review -> review.getParkingId().equals(parkingId) && + review.getReviewerId().equals(reviewerId) + ); + } +} diff --git a/domain/src/testFixtures/java/repository/FakeFavoriteRepository.java b/domain/src/testFixtures/java/repository/FakeFavoriteRepository.java new file mode 100644 index 00000000..88bda8a8 --- /dev/null +++ b/domain/src/testFixtures/java/repository/FakeFavoriteRepository.java @@ -0,0 +1,26 @@ +package repository; + +import com.parkingcomestrue.parking.domain.favorite.Favorite; +import com.parkingcomestrue.parking.domain.favorite.repository.FavoriteRepository; +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.support.Association; +import java.util.List; + +public class FakeFavoriteRepository implements FavoriteRepository { + + @Override + public Favorite save(Favorite favorite) { + return null; + } + + @Override + public void deleteByMemberIdAndParkingId(Association memberId, Association parkingId) { + + } + + @Override + public List findByMemberId(Association memberId) { + return null; + } +} diff --git a/domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java b/domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java new file mode 100644 index 00000000..c73ca343 --- /dev/null +++ b/domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java @@ -0,0 +1,18 @@ +package repository; + +import com.parkingcomestrue.parking.domain.searchcondition.SearchCondition; +import com.parkingcomestrue.parking.domain.searchcondition.repository.SearchConditionRepository; +import java.util.Optional; + +public class FakeSearchConditionRepository implements SearchConditionRepository { + + @Override + public Optional findByMemberId(Long memberId) { + return Optional.empty(); + } + + @Override + public void save(SearchCondition searchCondition) { + + } +} From f471dfd371a555c03d78228a341b657965276432 Mon Sep 17 00:00:00 2001 From: This2sho Date: Wed, 10 Apr 2024 23:54:41 +0900 Subject: [PATCH 03/19] =?UTF-8?q?refactor:=20api=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app-api/.gitignore | 42 ++++ app-api/Dockerfile | 5 + app-api/build.gradle | 23 +++ .../com/parkingcomestrue/ApiApplication.java | 21 ++ .../api/auth/authcode/AuthCodeController.java | 35 ++++ .../api/favorite/FavoriteController.java | 40 ++++ .../parking/api/member/MemberController.java | 57 ++++++ .../api/parking/ParkingController.java | 47 +++++ .../parking/api/review/ReviewController.java | 32 +++ .../SearchConditionController.java | 38 ++++ .../application/SearchConditionMapper.java | 39 ++++ .../parking/application/auth/AuthService.java | 101 ++++++++++ .../auth/authcode/AuthCodeCategory.java | 24 +++ .../auth/authcode/AuthCodeEventListener.java | 44 +++++ .../auth/authcode/AuthCodePlatform.java | 25 +++ .../auth/authcode/AuthCodeValidator.java | 21 ++ .../authcode/InValidAuthCodeException.java | 11 ++ .../auth/authcode/MailPlatformValidator.java | 17 ++ .../auth/authcode/PlatformValidator.java | 6 + .../dto/AuthCodeCertificateRequest.java | 23 +++ .../authcode/dto/AuthCodeCreateEvent.java | 19 ++ .../auth/authcode/dto/AuthCodeRequest.java | 19 ++ .../auth/authcode/dto/AuthCodeResponse.java | 13 ++ .../infrastructure/AuthCodeSender.java | 6 + .../infrastructure/MailAuthCodeSender.java | 23 +++ .../auth/authcode/util/AuthCodeGenerator.java | 6 + .../authcode/util/AuthCodeKeyConverter.java | 17 ++ .../util/NumberAuthCodeGenerator.java | 20 ++ .../application/favorite/FavoriteService.java | 43 +++++ .../favorite/dto/FavoriteCreateRequest.java | 15 ++ .../favorite/dto/FavoriteDeleteRequest.java | 15 ++ .../application/member/MemberService.java | 80 ++++++++ .../member/dto/MemberInfoResponse.java | 18 ++ .../member/dto/MemberLoginRequest.java | 17 ++ .../member/dto/MemberSignupRequest.java | 21 ++ .../member/dto/PasswordChangeRequest.java | 17 ++ .../application/parking/ParkingService.java | 182 ++++++++++++++++++ .../dto/ParkingDetailInfoResponse.java | 97 ++++++++++ .../parking/dto/ParkingLotsResponse.java | 44 +++++ .../parking/dto/ParkingQueryRequest.java | 17 ++ .../dto/ParkingSearchConditionRequest.java | 25 +++ .../application/review/ReviewService.java | 47 +++++ .../review/dto/ReviewCountResponse.java | 5 + .../review/dto/ReviewCreateRequest.java | 13 ++ .../review/dto/ReviewInfoResponse.java | 7 + .../SearchConditionService.java | 71 +++++++ .../dto/SearchConditionDto.java | 25 +++ .../parking/config/RedisConfig.java | 35 ++++ .../parking/config/SwaggerConfig.java | 32 +++ .../parking/config/WebMvcConfig.java | 65 +++++++ .../AuthArgumentResolver.java | 38 ++++ .../config/argumentresolver/MemberAuth.java | 13 ++ .../parking/ParkingQuery.java | 11 ++ .../parking/ParkingQueryArgumentResolver.java | 28 +++ .../parking/ParkingSearchCondition.java | 11 ++ ...arkingSearchConditionArgumentResolver.java | 78 ++++++++ .../config/interceptor/AuthInterceptor.java | 29 +++ .../GlobalExceptionHandler.java | 55 ++++++ .../dto/ExceptionResponse.java | 5 + .../src/main/resources/application-prod.yml | 14 ++ app-api/src/main/resources/application.yml | 29 +++ .../parkingcomestrue/ApiApplicationTests.java | 13 ++ .../SearchConditionMapperTest.java | 106 ++++++++++ .../application/auth/AuthServiceTest.java | 148 ++++++++++++++ .../application/config/TestConfig.java | 21 ++ .../application/container/ContainerTest.java | 73 +++++++ .../container/MySQLDataCleaner.java | 34 ++++ .../container/RedisDataCleaner.java | 18 ++ .../application/member/MemberServiceTest.java | 89 +++++++++ .../parking/ParkingServiceTest.java | 90 +++++++++ .../application/review/ReviewServiceTest.java | 98 ++++++++++ app-api/src/test/resources/application.yml | 43 +++++ 72 files changed, 2709 insertions(+) create mode 100644 app-api/.gitignore create mode 100644 app-api/Dockerfile create mode 100644 app-api/build.gradle create mode 100644 app-api/src/main/java/com/parkingcomestrue/ApiApplication.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/api/auth/authcode/AuthCodeController.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/api/favorite/FavoriteController.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/api/member/MemberController.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/api/parking/ParkingController.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/api/review/ReviewController.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/api/searchcondition/SearchConditionController.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeCategory.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeEventListener.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodePlatform.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeValidator.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/InValidAuthCodeException.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/MailPlatformValidator.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/PlatformValidator.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCertificateRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCreateEvent.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeResponse.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/AuthCodeSender.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/MailAuthCodeSender.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeGenerator.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeKeyConverter.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/NumberAuthCodeGenerator.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteCreateRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteDeleteRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberInfoResponse.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberLoginRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberSignupRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/PasswordChangeRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingDetailInfoResponse.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingLotsResponse.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingQueryRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingSearchConditionRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCountResponse.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewInfoResponse.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/dto/SearchConditionDto.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/RedisConfig.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/SwaggerConfig.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/WebMvcConfig.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/MemberAuth.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQuery.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchCondition.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/dto/ExceptionResponse.java create mode 100644 app-api/src/main/resources/application-prod.yml create mode 100644 app-api/src/main/resources/application.yml create mode 100644 app-api/src/test/java/com/parkingcomestrue/ApiApplicationTests.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/config/TestConfig.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/container/ContainerTest.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/container/MySQLDataCleaner.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/container/RedisDataCleaner.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java create mode 100644 app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java create mode 100644 app-api/src/test/resources/application.yml diff --git a/app-api/.gitignore b/app-api/.gitignore new file mode 100644 index 00000000..b63da455 --- /dev/null +++ b/app-api/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/app-api/Dockerfile b/app-api/Dockerfile new file mode 100644 index 00000000..90cb346d --- /dev/null +++ b/app-api/Dockerfile @@ -0,0 +1,5 @@ +FROM amazoncorretto:17-alpine + +COPY build/libs/app-api-0.0.1-SNAPSHOT.jar app.jar + +CMD ["java", "-jar", "app.jar"] diff --git a/app-api/build.gradle b/app-api/build.gradle new file mode 100644 index 00000000..f20cea52 --- /dev/null +++ b/app-api/build.gradle @@ -0,0 +1,23 @@ +dependencies { + implementation project(':domain') + + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' + + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' + implementation group: 'org.hibernate.orm', name: 'hibernate-spatial', version: '6.3.1.Final' + + // 메일 + implementation 'org.springframework.boot:spring-boot-starter-mail' + + // redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + + // testcontainer + testImplementation "org.testcontainers:testcontainers:1.19.6" + testImplementation "org.testcontainers:junit-jupiter:1.19.6" + testImplementation "com.redis:testcontainers-redis:2.2.0" + testImplementation "org.testcontainers:mysql:1.19.6" + + testImplementation(testFixtures(project(":domain"))) +} diff --git a/app-api/src/main/java/com/parkingcomestrue/ApiApplication.java b/app-api/src/main/java/com/parkingcomestrue/ApiApplication.java new file mode 100644 index 00000000..07d7198c --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/ApiApplication.java @@ -0,0 +1,21 @@ +package com.parkingcomestrue; + +import jakarta.annotation.PostConstruct; +import java.util.TimeZone; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableScheduling +@SpringBootApplication +public class ApiApplication { + + @PostConstruct + public void started() { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); + } + + public static void main(String[] args) { + SpringApplication.run(ApiApplication.class, args); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/api/auth/authcode/AuthCodeController.java b/app-api/src/main/java/com/parkingcomestrue/parking/api/auth/authcode/AuthCodeController.java new file mode 100644 index 00000000..dba87144 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/api/auth/authcode/AuthCodeController.java @@ -0,0 +1,35 @@ +package com.parkingcomestrue.parking.api.auth.authcode; + +import com.parkingcomestrue.parking.application.auth.AuthService; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeRequest; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "인증코드 컨트롤러") +@RestController +@RequiredArgsConstructor +public class AuthCodeController { + + private final AuthService authService; + + @PostMapping("/authcode") + public ResponseEntity createAuthCode(@RequestBody AuthCodeRequest authCodeRequest) { + String authCode = authService.createAuthCode(authCodeRequest); + return ResponseEntity.status(HttpStatus.CREATED).body(new AuthCodeResponse(authCode)); + } + + @DeleteMapping("/authcode") + public ResponseEntity certificateAuthCode( + @RequestBody AuthCodeCertificateRequest authCodeCertificateRequest) { + authService.certificateAuthCode(authCodeCertificateRequest); + return ResponseEntity.status(HttpStatus.OK).build(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/api/favorite/FavoriteController.java b/app-api/src/main/java/com/parkingcomestrue/parking/api/favorite/FavoriteController.java new file mode 100644 index 00000000..073e798d --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/api/favorite/FavoriteController.java @@ -0,0 +1,40 @@ +package com.parkingcomestrue.parking.api.favorite; + +import com.parkingcomestrue.parking.application.favorite.FavoriteService; +import com.parkingcomestrue.parking.application.favorite.dto.FavoriteCreateRequest; +import com.parkingcomestrue.parking.application.favorite.dto.FavoriteDeleteRequest; +import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "즐겨찾기 컨트롤러") +@RequiredArgsConstructor +@RestController +public class FavoriteController { + + private final FavoriteService favoriteService; + + @Operation(summary = "즐겨찾기 등록", description = "즐겨찾기 등록") + @PostMapping("/favorites") + public ResponseEntity create(@RequestBody FavoriteCreateRequest favoriteCreateRequest, + @Parameter(hidden = true) @MemberAuth Long memberId) { + favoriteService.createFavorite(favoriteCreateRequest, memberId); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + @Operation(summary = "즐겨찾기 해제", description = "즐겨찾기 해제") + @DeleteMapping("/favorites") + public ResponseEntity delete(@RequestBody FavoriteDeleteRequest favoriteDeleteRequest, + @Parameter(hidden = true) @MemberAuth Long memberId) { + favoriteService.deleteFavorite(favoriteDeleteRequest, memberId); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/api/member/MemberController.java b/app-api/src/main/java/com/parkingcomestrue/parking/api/member/MemberController.java new file mode 100644 index 00000000..c74b6c90 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/api/member/MemberController.java @@ -0,0 +1,57 @@ +package com.parkingcomestrue.parking.api.member; + +import com.parkingcomestrue.parking.application.auth.AuthService; +import com.parkingcomestrue.parking.application.member.MemberService; +import com.parkingcomestrue.parking.application.member.dto.MemberLoginRequest; +import com.parkingcomestrue.parking.application.member.dto.MemberSignupRequest; +import com.parkingcomestrue.parking.application.member.dto.PasswordChangeRequest; +import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "멤버 컨트롤러") +@RequiredArgsConstructor +@RestController +public class MemberController { + + private static final String JSESSIONID = "JSESSIONID"; + + private final MemberService memberService; + private final AuthService authService; + + @Operation(summary = "회원가입", description = "회원가입") + @PostMapping("/signup") + public ResponseEntity signup(@RequestBody MemberSignupRequest request) { + memberService.signup(request); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + @Operation(summary = "로그인", description = "로그인") + @PostMapping("/signin") + public ResponseEntity signIn(HttpServletResponse httpServletResponse, + @RequestBody MemberLoginRequest request) { + Long memberId = memberService.login(request); + String sessionId = authService.createSession(memberId); + httpServletResponse.addCookie(new Cookie(JSESSIONID, sessionId)); + + return ResponseEntity.status(HttpStatus.OK).build(); + } + + @Operation(summary = "비밀번호 변경", description = "비밀번호 변경") + @PatchMapping("/member/password") + public ResponseEntity changePassword(@Parameter(hidden = true) @MemberAuth Long memberId, + @RequestBody PasswordChangeRequest request) { + memberService.changePassword(memberId, request); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/api/parking/ParkingController.java b/app-api/src/main/java/com/parkingcomestrue/parking/api/parking/ParkingController.java new file mode 100644 index 00000000..fbbdef4b --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/api/parking/ParkingController.java @@ -0,0 +1,47 @@ +package com.parkingcomestrue.parking.api.parking; + +import com.parkingcomestrue.parking.application.parking.ParkingService; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingQueryRequest; +import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest; +import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth; +import com.parkingcomestrue.parking.config.argumentresolver.parking.ParkingQuery; +import com.parkingcomestrue.parking.config.argumentresolver.parking.ParkingSearchCondition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "주차장 컨트롤러") +@RequiredArgsConstructor +@RestController +public class ParkingController { + + private final ParkingService parkingService; + + @Operation(summary = "주차장 상세조회", description = "주차장 상세조회") + @GetMapping("/parkings/{parkingId}") + public ResponseEntity findParking(@PathVariable Long parkingId) { + ParkingDetailInfoResponse parkingDetailInfoResponse = parkingService.findParking(parkingId); + return ResponseEntity.status(HttpStatus.OK).body(parkingDetailInfoResponse); + + } + + @Operation(summary = "주차장 반경 조회", description = "주차장 반경 조회") + @GetMapping("/parkings") + public ResponseEntity find( + @ParkingQuery ParkingQueryRequest parkingQueryRequest, + @ParkingSearchCondition ParkingSearchConditionRequest parkingSearchConditionRequest, + @Parameter(hidden = true) @MemberAuth(nullable = true) Long parkingMemberId + ) { + ParkingLotsResponse parkingLots = parkingService.findParkingLots(parkingQueryRequest, + parkingSearchConditionRequest, parkingMemberId); + return ResponseEntity.ok(parkingLots); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/api/review/ReviewController.java b/app-api/src/main/java/com/parkingcomestrue/parking/api/review/ReviewController.java new file mode 100644 index 00000000..15519927 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/api/review/ReviewController.java @@ -0,0 +1,32 @@ +package com.parkingcomestrue.parking.api.review; + +import com.parkingcomestrue.parking.application.review.ReviewService; +import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; +import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "리뷰 컨트롤러") +@RequiredArgsConstructor +@RestController +public class ReviewController { + + private final ReviewService reviewService; + + @Operation(summary = "리뷰 등록", description = "리뷰 등록") + @PostMapping("/parkings/{parkingId}/reviews") + public ResponseEntity createReview(@PathVariable Long parkingId, + @Parameter(hidden = true) @MemberAuth Long memberId, + @ModelAttribute ReviewCreateRequest request) { + Long reviewId = reviewService.createReview(parkingId, memberId, request); + return ResponseEntity.status(HttpStatus.CREATED).body(reviewId); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/api/searchcondition/SearchConditionController.java b/app-api/src/main/java/com/parkingcomestrue/parking/api/searchcondition/SearchConditionController.java new file mode 100644 index 00000000..c2d231e0 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/api/searchcondition/SearchConditionController.java @@ -0,0 +1,38 @@ +package com.parkingcomestrue.parking.api.searchcondition; + +import com.parkingcomestrue.parking.application.searchcondition.SearchConditionService; +import com.parkingcomestrue.parking.application.searchcondition.dto.SearchConditionDto; +import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "조회 조건 컨트롤러") +@RestController +public class SearchConditionController { + + private final SearchConditionService searchConditionService; + + public SearchConditionController(SearchConditionService searchConditionService) { + this.searchConditionService = searchConditionService; + } + + @Operation(summary = "조회 조건 조회", description = "조회 조건 조회") + @GetMapping("/search-condition") + public ResponseEntity loadSearchCondition(@Parameter(hidden = true) @MemberAuth Long memberId) { + return ResponseEntity.ok(searchConditionService.findSearchCondition(memberId)); + } + + @Operation(summary = "조회 조건 수정", description = "조회 조건 수정") + @PutMapping("/search-condition") + public ResponseEntity updateSearchCondition(@Parameter(hidden = true) @MemberAuth Long memberId, + SearchConditionDto request) { + searchConditionService.updateSearchCondition(memberId, request); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java new file mode 100644 index 00000000..4f623964 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java @@ -0,0 +1,39 @@ +package com.parkingcomestrue.parking.application; + +import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.Arrays; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class SearchConditionMapper { + + public & SearchConditionAvailable> List toEnums(Class searchConditionAvailableClass, + List descriptions) { + return descriptions.stream() + .map(description -> toEnum(searchConditionAvailableClass, description)) + .toList(); + } + + public & SearchConditionAvailable> E toEnum(Class searchConditionAvailableClass, + String description) { + E[] conditions = searchConditionAvailableClass.getEnumConstants(); + + return Arrays.stream(conditions) + .filter(condition -> description.startsWith(condition.getDescription())) + .findAny() + .orElseThrow(() -> new ClientException(ExceptionInformation.INVALID_DESCRIPTION)); + } + + public & SearchConditionAvailable> List getValues( + Class searchConditionAvailableClass) { + E[] conditions = searchConditionAvailableClass.getEnumConstants(); + + return Arrays.stream(conditions) + .filter(condition -> condition != condition.getDefault()) + .map(SearchConditionAvailable::getDescription) + .toList(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java new file mode 100644 index 00000000..72112817 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java @@ -0,0 +1,101 @@ +package com.parkingcomestrue.parking.application.auth; + +import com.parkingcomestrue.parking.application.auth.authcode.AuthCodeCategory; +import com.parkingcomestrue.parking.application.auth.authcode.AuthCodePlatform; +import com.parkingcomestrue.parking.application.auth.authcode.AuthCodeValidator; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeRequest; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCreateEvent; +import com.parkingcomestrue.parking.application.auth.authcode.util.AuthCodeGenerator; +import com.parkingcomestrue.parking.application.auth.authcode.util.AuthCodeKeyConverter; +import com.parkingcomestrue.parking.domain.session.MemberSession; +import com.parkingcomestrue.parking.domain.session.repository.MemberSessionRepository; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.time.LocalDateTime; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +public class AuthService { + + private static final Long DURATION_MINUTE = 30L; + + private final MemberSessionRepository memberSessionRepository; + private final AuthCodeGenerator authCodeGenerator; + private final AuthCodeValidator authCodeValidator; + private final ApplicationEventPublisher applicationEventPublisher; + private final RedisTemplate redisTemplate; + + @Transactional + public String createSession(Long memberId) { + LocalDateTime current = LocalDateTime.now(); + String uuid = UUID.randomUUID().toString(); + + MemberSession memberSession = new MemberSession(uuid, memberId, current, current.plusMinutes(DURATION_MINUTE)); + memberSessionRepository.save(memberSession); + return memberSession.getSessionId(); + } + + @Transactional(readOnly = true) + public MemberSession findSession(String sessionId) { + return memberSessionRepository.findBySessionIdAndExpiredAtIsGreaterThanEqual(sessionId, + LocalDateTime.now()) + .orElseThrow(() -> new ClientException(ExceptionInformation.UNAUTHORIZED)); + } + + @Transactional + public void updateSessionExpiredAt(MemberSession session) { + session.updateExpiredAt(LocalDateTime.now().plusMinutes(DURATION_MINUTE)); + memberSessionRepository.save(session); + } + + @Transactional + public String createAuthCode(AuthCodeRequest authCodeRequest) { + String destination = authCodeRequest.getDestination(); + AuthCodePlatform authCodePlatform = AuthCodePlatform.find(authCodeRequest.getAuthPlatform()); + AuthCodeCategory authCodeCategory = AuthCodeCategory.find(authCodeRequest.getAuthCodeCategory()); + + authCodeValidator.validate(authCodePlatform, destination); + String randomAuthCode = authCodeGenerator.generateAuthCode(); + String authCodeKey = AuthCodeKeyConverter.convert(randomAuthCode, destination, authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName()); + redisTemplate.opsForValue().set(authCodeKey, randomAuthCode, 300L, TimeUnit.SECONDS); + + publishAuthCodeCreateEvent(destination, authCodePlatform, authCodeCategory, randomAuthCode); + return randomAuthCode; + } + + private void publishAuthCodeCreateEvent(String destination, AuthCodePlatform authCodePlatform, + AuthCodeCategory authCodeCategory, String randomAuthCode) { + applicationEventPublisher.publishEvent( + new AuthCodeCreateEvent( + destination, + randomAuthCode, + authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName() + ) + ); + } + + @Transactional + public void certificateAuthCode(AuthCodeCertificateRequest authCodeCertificateRequest) { + String authCode = authCodeCertificateRequest.getAuthCode(); + String destination = authCodeCertificateRequest.getDestination(); + AuthCodePlatform authCodePlatform = AuthCodePlatform.find(authCodeCertificateRequest.getAuthCodePlatform()); + AuthCodeCategory authCodeCategory = AuthCodeCategory.find(authCodeCertificateRequest.getAuthCodeCategory()); + + String authCodeKey = AuthCodeKeyConverter.convert(authCode, destination, authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName()); + String findResult = redisTemplate.opsForValue().getAndDelete(authCodeKey); + if (findResult == null) { + throw new ClientException(ExceptionInformation.INVALID_AUTH_CODE); + } + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeCategory.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeCategory.java new file mode 100644 index 00000000..379456b6 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeCategory.java @@ -0,0 +1,24 @@ +package com.parkingcomestrue.parking.application.auth.authcode; + +import java.util.Arrays; +import lombok.Getter; + +@Getter +public enum AuthCodeCategory { + + SIGN_UP("signUp"), + FIND_PASSWORD("findPassword"); + + private final String categoryName; + + AuthCodeCategory(String categoryName) { + this.categoryName = categoryName; + } + + public static AuthCodeCategory find(String authCodeCategory) { + return Arrays.stream(AuthCodeCategory.values()) + .filter(category -> category.categoryName.equals(authCodeCategory)) + .findAny() + .orElseThrow(() -> new InValidAuthCodeException("존재하지 않는 인증 코드 발급 행위입니다.")); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeEventListener.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeEventListener.java new file mode 100644 index 00000000..1129465e --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeEventListener.java @@ -0,0 +1,44 @@ +package com.parkingcomestrue.parking.application.auth.authcode; + + +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCreateEvent; +import com.parkingcomestrue.parking.application.auth.authcode.infrastructure.AuthCodeSender; +import com.parkingcomestrue.parking.application.auth.authcode.util.AuthCodeKeyConverter; +import java.time.Instant; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalEventListener; + +@RequiredArgsConstructor +@Component +public class AuthCodeEventListener { + + @Value("${authcode.expired-time}") + private Integer authCodeExpired; + + private final AuthCodeSender authCodeSender; + private final TaskScheduler taskScheduler; + private final RedisTemplate redisTemplate; + + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + public void sendAuthCode(AuthCodeCreateEvent authCodeCreateEvent) { + String destination = authCodeCreateEvent.getDestination(); + String authCode = authCodeCreateEvent.getAuthCode(); + authCodeSender.send(destination, authCode); + } + + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + public void scheduledAuthCodeRemove(AuthCodeCreateEvent authCodeCreateEvent) { + String authCode = authCodeCreateEvent.getAuthCode(); + String destination = authCodeCreateEvent.getDestination(); + String authCodePlatform = authCodeCreateEvent.getAuthCodePlatform(); + String authCodeCategory = authCodeCreateEvent.getAuthCodeCategory(); + + String authCodeKey = AuthCodeKeyConverter.convert(authCode, destination, authCodePlatform, authCodeCategory); + taskScheduler.schedule(() -> redisTemplate.delete(authCodeKey), Instant.now().plusSeconds(authCodeExpired)); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodePlatform.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodePlatform.java new file mode 100644 index 00000000..65e7aa9d --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodePlatform.java @@ -0,0 +1,25 @@ +package com.parkingcomestrue.parking.application.auth.authcode; + +import java.util.Arrays; + +public enum AuthCodePlatform { + + MAIL("mail"); + + private final String platform; + + AuthCodePlatform(String platform) { + this.platform = platform; + } + + public static AuthCodePlatform find(String authType) { + return Arrays.stream(AuthCodePlatform.values()) + .filter(authCodeType -> authCodeType.platform.equals(authType)) + .findAny() + .orElseThrow(() -> new InValidAuthCodeException("존재하지 않는 인증 코드 전송 플랫폼입니다.")); + } + + public String getPlatform() { + return platform; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeValidator.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeValidator.java new file mode 100644 index 00000000..b570305d --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/AuthCodeValidator.java @@ -0,0 +1,21 @@ +package com.parkingcomestrue.parking.application.auth.authcode; + +import java.util.EnumMap; +import org.springframework.stereotype.Component; + +@Component +public class AuthCodeValidator { + + private final EnumMap validators = new EnumMap<>(AuthCodePlatform.class); + + public AuthCodeValidator() { + validators.put(AuthCodePlatform.MAIL, new MailPlatformValidator()); + } + + public void validate(AuthCodePlatform authCodePlatform, String destination) { + PlatformValidator platformValidator = validators.get(authCodePlatform); + if (platformValidator.isInvalidForm(destination)) { + throw new InValidAuthCodeException("인증 코드 플랫폼과 수신지 형식이 일치하지 않습니다."); + } + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/InValidAuthCodeException.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/InValidAuthCodeException.java new file mode 100644 index 00000000..7bc88881 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/InValidAuthCodeException.java @@ -0,0 +1,11 @@ +package com.parkingcomestrue.parking.application.auth.authcode; + +public class InValidAuthCodeException extends RuntimeException { + + private final String message; + + public InValidAuthCodeException(String message) { + super(message); + this.message = message; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/MailPlatformValidator.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/MailPlatformValidator.java new file mode 100644 index 00000000..695a0b47 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/MailPlatformValidator.java @@ -0,0 +1,17 @@ +package com.parkingcomestrue.parking.application.auth.authcode; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class MailPlatformValidator implements PlatformValidator { + + private static final String EMAIL_PATTERN = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"; + + private static final Pattern PATTERN = Pattern.compile(EMAIL_PATTERN); + + @Override + public boolean isInvalidForm(String destination) { + Matcher matcher = PATTERN.matcher(destination); + return !matcher.matches(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/PlatformValidator.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/PlatformValidator.java new file mode 100644 index 00000000..d33eaac9 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/PlatformValidator.java @@ -0,0 +1,6 @@ +package com.parkingcomestrue.parking.application.auth.authcode; + +public interface PlatformValidator { + + boolean isInvalidForm(String destination); +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCertificateRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCertificateRequest.java new file mode 100644 index 00000000..ea2d85ff --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCertificateRequest.java @@ -0,0 +1,23 @@ +package com.parkingcomestrue.parking.application.auth.authcode.dto; + + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class AuthCodeCertificateRequest { + + private String destination; + private String authCodePlatform; + private String authCodeCategory; + private String authCode; + + public AuthCodeCertificateRequest(String destination, String authCodePlatform, String authCodeCategory, + String authCode) { + this.destination = destination; + this.authCodePlatform = authCodePlatform; + this.authCodeCategory = authCodeCategory; + this.authCode = authCode; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCreateEvent.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCreateEvent.java new file mode 100644 index 00000000..eba65049 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeCreateEvent.java @@ -0,0 +1,19 @@ +package com.parkingcomestrue.parking.application.auth.authcode.dto; + +import lombok.Getter; + +@Getter +public class AuthCodeCreateEvent { + + private final String destination; + private final String authCode; + private final String authCodePlatform; + private final String authCodeCategory; + + public AuthCodeCreateEvent(String destination, String authCode, String authCodePlatform, String authCodeCategory) { + this.destination = destination; + this.authCode = authCode; + this.authCodePlatform = authCodePlatform; + this.authCodeCategory = authCodeCategory; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeRequest.java new file mode 100644 index 00000000..0b49d45a --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeRequest.java @@ -0,0 +1,19 @@ +package com.parkingcomestrue.parking.application.auth.authcode.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class AuthCodeRequest { + + private String destination; + private String authPlatform; + private String authCodeCategory; + + public AuthCodeRequest(String destination, String authPlatform, String authCodeCategory) { + this.destination = destination; + this.authPlatform = authPlatform; + this.authCodeCategory = authCodeCategory; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeResponse.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeResponse.java new file mode 100644 index 00000000..c030750e --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/dto/AuthCodeResponse.java @@ -0,0 +1,13 @@ +package com.parkingcomestrue.parking.application.auth.authcode.dto; + +import lombok.Getter; + +@Getter +public class AuthCodeResponse { + + private String authCode; + + public AuthCodeResponse(String authCode) { + this.authCode = authCode; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/AuthCodeSender.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/AuthCodeSender.java new file mode 100644 index 00000000..e51d045b --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/AuthCodeSender.java @@ -0,0 +1,6 @@ +package com.parkingcomestrue.parking.application.auth.authcode.infrastructure; + +public interface AuthCodeSender { + + void send(String destination, String authCode); +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/MailAuthCodeSender.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/MailAuthCodeSender.java new file mode 100644 index 00000000..051bee8a --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/infrastructure/MailAuthCodeSender.java @@ -0,0 +1,23 @@ +package com.parkingcomestrue.parking.application.auth.authcode.infrastructure; + +import lombok.RequiredArgsConstructor; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Component; + +@RequiredArgsConstructor +@Component +public class MailAuthCodeSender implements AuthCodeSender { + + private final JavaMailSender mailSender; + + @Override + public void send(String destination, String authCode) { + SimpleMailMessage mailMessage = new SimpleMailMessage(); + + mailMessage.setTo(destination); + mailMessage.setSubject("인증 코드"); + mailMessage.setText(authCode); + mailSender.send(mailMessage); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeGenerator.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeGenerator.java new file mode 100644 index 00000000..0bfa0711 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeGenerator.java @@ -0,0 +1,6 @@ +package com.parkingcomestrue.parking.application.auth.authcode.util; + +public interface AuthCodeGenerator { + + String generateAuthCode(); +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeKeyConverter.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeKeyConverter.java new file mode 100644 index 00000000..0b8a9743 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/AuthCodeKeyConverter.java @@ -0,0 +1,17 @@ + +package com.parkingcomestrue.parking.application.auth.authcode.util; + +import java.util.StringJoiner; + +public class AuthCodeKeyConverter { + + public static String convert(String randomAuthCode, String destination, String authCodePlatform, + String authCodeCategory) { + StringJoiner stringJoiner = new StringJoiner(":"); + return stringJoiner + .add(randomAuthCode) + .add(destination) + .add(authCodePlatform) + .add(authCodeCategory).toString(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/NumberAuthCodeGenerator.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/NumberAuthCodeGenerator.java new file mode 100644 index 00000000..56ae56de --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/authcode/util/NumberAuthCodeGenerator.java @@ -0,0 +1,20 @@ +package com.parkingcomestrue.parking.application.auth.authcode.util; + +import java.util.Random; +import org.springframework.stereotype.Component; + +@Component +public class NumberAuthCodeGenerator implements AuthCodeGenerator { + + private static final int MAX_LENGTH = 6; + private static final Random random = new Random(); + + @Override + public String generateAuthCode() { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < MAX_LENGTH; i++) { + stringBuilder.append(random.nextInt(9)); + } + return stringBuilder.toString(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java new file mode 100644 index 00000000..e4c3a4a9 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java @@ -0,0 +1,43 @@ +package com.parkingcomestrue.parking.application.favorite; + +import com.parkingcomestrue.parking.application.favorite.dto.FavoriteCreateRequest; +import com.parkingcomestrue.parking.application.favorite.dto.FavoriteDeleteRequest; +import com.parkingcomestrue.parking.domain.favorite.Favorite; +import com.parkingcomestrue.parking.domain.favorite.repository.FavoriteRepository; +import com.parkingcomestrue.parking.support.Association; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@RequiredArgsConstructor +@Transactional +@Service +public class FavoriteService { + + private final FavoriteRepository favoriteRepository; + + public void createFavorite(FavoriteCreateRequest favoriteCreateRequest, Long memberId) { + Long parkingId = favoriteCreateRequest.getParkingId(); + + Favorite favorite = new Favorite(Association.from(memberId), Association.from(parkingId)); + saveFavorite(favorite); + } + + private void saveFavorite(Favorite favorite) { + try { + favoriteRepository.save(favorite); + } catch (DataIntegrityViolationException e) { + log.warn("memberId: {}, parkingId: {} request duplicate favorite create", favorite.getMemberId(), + favorite.getParkingId()); + } + } + + public void deleteFavorite(FavoriteDeleteRequest favoriteDeleteRequest, Long memberId) { + Long parkingId = favoriteDeleteRequest.getParkingId(); + + favoriteRepository.deleteByMemberIdAndParkingId(Association.from(memberId), Association.from(parkingId)); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteCreateRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteCreateRequest.java new file mode 100644 index 00000000..1b89faf9 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteCreateRequest.java @@ -0,0 +1,15 @@ +package com.parkingcomestrue.parking.application.favorite.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class FavoriteCreateRequest { + + private Long parkingId; + + public FavoriteCreateRequest(Long parkingId) { + this.parkingId = parkingId; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteDeleteRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteDeleteRequest.java new file mode 100644 index 00000000..22936742 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/dto/FavoriteDeleteRequest.java @@ -0,0 +1,15 @@ +package com.parkingcomestrue.parking.application.favorite.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class FavoriteDeleteRequest { + + private Long parkingId; + + public FavoriteDeleteRequest(Long parkingId) { + this.parkingId = parkingId; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java new file mode 100644 index 00000000..6a674655 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java @@ -0,0 +1,80 @@ +package com.parkingcomestrue.parking.application.member; + +import com.parkingcomestrue.parking.application.member.dto.MemberInfoResponse; +import com.parkingcomestrue.parking.application.member.dto.MemberLoginRequest; +import com.parkingcomestrue.parking.application.member.dto.MemberSignupRequest; +import com.parkingcomestrue.parking.application.member.dto.PasswordChangeRequest; +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; +import com.parkingcomestrue.parking.domain.member.Password; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class MemberService { + + private final MemberRepository memberRepository; + + public MemberService(MemberRepository memberRepository) { + this.memberRepository = memberRepository; + } + + @Transactional + public Long signup(MemberSignupRequest dto) { + Member member = new Member( + dto.getEmail(), + dto.getNickname(), + new Password(dto.getPassword())); + + validateDuplicatedEmail(member); + memberRepository.save(member); + return member.getId(); + } + + private void validateDuplicatedEmail(Member member) { + if (memberRepository.existsByEmail(member.getEmail())) { + throw new ClientException(ExceptionInformation.DUPLICATE_MAIL); + } + } + + @Transactional(readOnly = true) + public Long login(MemberLoginRequest dto) { + Member member = findMemberByEmail(dto.getEmail()); + validatePassword(member, dto.getPassword()); + return member.getId(); + } + + private Member findMemberByEmail(String email) { + return memberRepository.findByEmail(email) + .orElseThrow(() -> new ClientException(ExceptionInformation.INVALID_EMAIL)); + } + + private void validatePassword(Member member, String password) { + if (!member.checkPassword(password)) { + throw new ClientException(ExceptionInformation.INVALID_PASSWORD); + } + } + + @Transactional + public void deleteMember(Long memberId) { + Member member = memberRepository.getById(memberId); + member.delete(); + } + + @Transactional(readOnly = true) + public MemberInfoResponse findMemberInfo(Long memberId) { + Member member = memberRepository.getById(memberId); + + return new MemberInfoResponse(member.getNickname(), member.getEmail()); + } + + @Transactional + public void changePassword(Long memberId, PasswordChangeRequest dto) { + Member member = memberRepository.getById(memberId); + String previousPassword = dto.getPreviousPassword(); + String newPassword = dto.getNewPassword(); + member.changePassword(previousPassword, newPassword); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberInfoResponse.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberInfoResponse.java new file mode 100644 index 00000000..01f29c39 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberInfoResponse.java @@ -0,0 +1,18 @@ +package com.parkingcomestrue.parking.application.member.dto; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class MemberInfoResponse { + + private String name; + private String email; + + public MemberInfoResponse(String name, String email) { + this.name = name; + this.email = email; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberLoginRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberLoginRequest.java new file mode 100644 index 00000000..f218b066 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberLoginRequest.java @@ -0,0 +1,17 @@ +package com.parkingcomestrue.parking.application.member.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class MemberLoginRequest { + + private String email; + private String password; + + public MemberLoginRequest(String email, String password) { + this.email = email; + this.password = password; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberSignupRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberSignupRequest.java new file mode 100644 index 00000000..66fbb7c9 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/MemberSignupRequest.java @@ -0,0 +1,21 @@ +package com.parkingcomestrue.parking.application.member.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class MemberSignupRequest { + + private String name; + private String email; + private String password; + private String nickname; + + public MemberSignupRequest(String name, String email, String password, String nickname) { + this.name = name; + this.email = email; + this.password = password; + this.nickname = nickname; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/PasswordChangeRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/PasswordChangeRequest.java new file mode 100644 index 00000000..0f3f72ab --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/dto/PasswordChangeRequest.java @@ -0,0 +1,17 @@ +package com.parkingcomestrue.parking.application.member.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class PasswordChangeRequest { + + private String previousPassword; + private String newPassword; + + public PasswordChangeRequest(String previousPassword, String newPassword) { + this.previousPassword = previousPassword; + this.newPassword = newPassword; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java new file mode 100644 index 00000000..cd945e87 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java @@ -0,0 +1,182 @@ +package com.parkingcomestrue.parking.application.parking; + +import com.parkingcomestrue.parking.application.SearchConditionMapper; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.FeeInfo; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.HolidayOperatingTime; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.SaturdayOperatingTime; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.WeekdayOperatingTime; +import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse.ParkingResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingQueryRequest; +import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest; +import com.parkingcomestrue.parking.application.review.ReviewService; +import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; +import com.parkingcomestrue.parking.domain.favorite.Favorite; +import com.parkingcomestrue.parking.domain.favorite.repository.FavoriteRepository; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingFeeCalculator; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayType; +import com.parkingcomestrue.parking.domain.parking.SearchingCondition; +import com.parkingcomestrue.parking.domain.parking.repository.ParkingRepository; +import com.parkingcomestrue.parking.domain.parking.service.ParkingFilteringService; +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.parking.support.Association; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +public class ParkingService { + + private static final String DISTANCE_ORDER_CONDITION = "가까운 순"; + + private final ParkingRepository parkingRepository; + private final ParkingFilteringService parkingFilteringService; + private final FavoriteRepository favoriteRepository; + private final SearchConditionMapper searchConditionMapper; + private final ParkingFeeCalculator parkingFeeCalculator; + private final ReviewService reviewService; + + @Transactional(readOnly = true) + public ParkingLotsResponse findParkingLots(ParkingQueryRequest parkingQueryRequest, + ParkingSearchConditionRequest parkingSearchConditionRequest, + Long memberId) { + LocalDateTime now = LocalDateTime.now(); + Location destination = Location.of(parkingQueryRequest.getLongitude(), parkingQueryRequest.getLatitude()); + + // 반경 주차장 조회 + List favorites = findMemberFavorites(memberId); + List parkingLots = findParkingLotsByOrderCondition(parkingSearchConditionRequest.getPriority(), + parkingQueryRequest, destination); + + // 조회조건 기반 필터링 + SearchingCondition searchingCondition = toSearchingCondition(parkingSearchConditionRequest); + List filteredParkingLots = parkingFilteringService.filterByCondition(parkingLots, searchingCondition, + now); + + // 응답 dto 변환 + List parkingResponses = collectParkingInfo(filteredParkingLots, + parkingSearchConditionRequest.getHours(), destination, favorites, now); + + return new ParkingLotsResponse(parkingResponses); + } + + private List findMemberFavorites(Long memberId) { + if (memberId == null) { + return Collections.emptyList(); + } + return favoriteRepository.findByMemberId(Association.from(memberId)); + } + + private List findParkingLotsByOrderCondition(String priority, ParkingQueryRequest parkingQueryRequest, + Location middleLocation) { + if (priority.equals(DISTANCE_ORDER_CONDITION)) { + return parkingRepository.findAroundParkingLotsOrderByDistance(middleLocation.getPoint(), + parkingQueryRequest.getRadius()); + } + return parkingRepository.findAroundParkingLots(middleLocation.getPoint(), parkingQueryRequest.getRadius()); + } + + private SearchingCondition toSearchingCondition(ParkingSearchConditionRequest request) { + List parkingTypes = searchConditionMapper.toEnums(ParkingType.class, request.getParkingTypes()); + List operationTypes = searchConditionMapper.toEnums(OperationType.class, + request.getOperationTypes()); + List payTypes = searchConditionMapper.toEnums(PayType.class, request.getPayTypes()); + FeeType feeType = searchConditionMapper.toEnum(FeeType.class, request.getFeeType()); + + return new SearchingCondition(operationTypes, parkingTypes, payTypes, feeType, request.getHours()); + } + + private List collectParkingInfo(List parkingLots, int hours, + Location destination, List memberFavorites, + LocalDateTime now) { + Set favoriteParkingIds = extractFavoriteParkingIds(memberFavorites); + return calculateParkingInfo(parkingLots, destination, hours, favoriteParkingIds, now); + } + + private List calculateParkingInfo(List parkingLots, Location destination, int hours, + Set favoriteParkingIds, LocalDateTime now) { + return parkingLots.stream() + .map(parking -> toParkingResponse( + parking, + parkingFeeCalculator.calculateParkingFee(parking, now, now.plusHours(hours)), + parking.calculateWalkingTime(destination), + favoriteParkingIds.contains(parking.getId()) + ) + ).toList(); + } + + private Set extractFavoriteParkingIds(List memberFavorites) { + return memberFavorites.stream() + .map(Favorite::getParkingId) + .map(Association::getId) + .collect(Collectors.toSet()); + } + + private ParkingResponse toParkingResponse(Parking parking, Fee fee, int walkingTime, boolean isFavorite) { + return new ParkingResponse( + parking.getId(), + parking.getBaseInformation().getName(), + fee.getFee(), + walkingTime, + parking.getBaseInformation().getParkingType().getDescription(), + isFavorite, + parking.getLocation().getLatitude(), + parking.getLocation().getLongitude() + ); + } + + @Transactional + public void saveAll(List parkingLots) { + parkingRepository.saveAll(parkingLots); + } + + @Transactional(readOnly = true) + public ParkingDetailInfoResponse findParking(Long parkingId) { + LocalDateTime now = LocalDateTime.now(); + Parking parking = parkingRepository.getById(parkingId); + ReviewInfoResponse reviews = reviewService.readReviews(parkingId); + int diffMinute = parking.calculateUpdatedDiff(now); + + return toParkingResponse(reviews, parking, diffMinute); + } + + private ParkingDetailInfoResponse toParkingResponse(ReviewInfoResponse reviews, Parking parking, int diffMinute) { + return new ParkingDetailInfoResponse( + parking.getBaseInformation().getName(), + parking.getBaseInformation().getParkingType().getDescription(), + parking.getLocation().getLatitude(), + parking.getLocation().getLongitude(), + new FeeInfo( + parking.getFeePolicy().getBaseFee().getFee(), + parking.getFeePolicy().getBaseTimeUnit().getTimeUnit() + ), + parking.getSpace().getCurrentParking(), + parking.getSpace().getCapacity(), + diffMinute, + parking.getBaseInformation().getTel(), + parking.getBaseInformation().getPayTypes().getDescription(), + new WeekdayOperatingTime( + parking.getOperatingTime().getWeekdayBeginTime(), + parking.getOperatingTime().getWeekdayEndTime()), + new SaturdayOperatingTime( + parking.getOperatingTime().getSaturdayBeginTime(), + parking.getOperatingTime().getSaturdayEndTime()), + new HolidayOperatingTime( + parking.getOperatingTime().getHolidayBeginTime(), + parking.getOperatingTime().getHolidayEndTime()), + reviews + ); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingDetailInfoResponse.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingDetailInfoResponse.java new file mode 100644 index 00000000..29dc9517 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingDetailInfoResponse.java @@ -0,0 +1,97 @@ +package com.parkingcomestrue.parking.application.parking.dto; + +import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; +import java.time.LocalTime; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ParkingDetailInfoResponse { + + private String parkingName; + private String parkingType; + private Double latitude; + private Double longitude; + private FeeInfo feeInfo; + private Integer currentParkingCount; + private Integer capacity; + private Integer lastUpdated; + private String tel; + private String paymentType; + private WeekdayOperatingTime weekdayOperatingTime; + private SaturdayOperatingTime saturdayOperatingTime; + private HolidayOperatingTime holidayOperatingTime; + private ReviewInfoResponse reviewInfo; + + public ParkingDetailInfoResponse(String parkingName, String parkingType, Double latitude, Double longitude, + FeeInfo feeInfo, + Integer currentParkingCount, Integer capacity, Integer lastUpdated, String tel, + String paymentType, WeekdayOperatingTime weekdayOperatingTime, + SaturdayOperatingTime saturdayOperatingTime, + HolidayOperatingTime holidayOperatingTime, ReviewInfoResponse reviewInfo) { + this.parkingName = parkingName; + this.parkingType = parkingType; + this.latitude = latitude; + this.longitude = longitude; + this.feeInfo = feeInfo; + this.currentParkingCount = currentParkingCount; + this.capacity = capacity; + this.lastUpdated = lastUpdated; + this.tel = tel; + this.paymentType = paymentType; + this.weekdayOperatingTime = weekdayOperatingTime; + this.saturdayOperatingTime = saturdayOperatingTime; + this.holidayOperatingTime = holidayOperatingTime; + this.reviewInfo = reviewInfo; + } + + @Getter + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class FeeInfo { + private Integer fee; + private Integer time; + + public FeeInfo(Integer fee, Integer time) { + this.fee = fee; + this.time = time; + } + } + + @Getter + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class WeekdayOperatingTime { + private LocalTime beginTime; + private LocalTime endTime; + + public WeekdayOperatingTime(LocalTime beginTime, LocalTime endTime) { + this.beginTime = beginTime; + this.endTime = endTime; + } + } + + @Getter + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class SaturdayOperatingTime { + private LocalTime beginTime; + private LocalTime endTime; + + public SaturdayOperatingTime(LocalTime beginTime, LocalTime endTime) { + this.beginTime = beginTime; + this.endTime = endTime; + } + } + + @Getter + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class HolidayOperatingTime { + private LocalTime beginTime; + private LocalTime endTime; + + public HolidayOperatingTime(LocalTime beginTime, LocalTime endTime) { + this.beginTime = beginTime; + this.endTime = endTime; + } + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingLotsResponse.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingLotsResponse.java new file mode 100644 index 00000000..5996b478 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingLotsResponse.java @@ -0,0 +1,44 @@ +package com.parkingcomestrue.parking.application.parking.dto; + +import java.util.List; +import lombok.Getter; + +@Getter +public class ParkingLotsResponse { + + private List parkingLots; + + private ParkingLotsResponse() { + } + + public ParkingLotsResponse(List parkingLots) { + this.parkingLots = parkingLots; + } + + @Getter + public static class ParkingResponse { + private Long parkingId; + private String parkingName; + private Integer estimatedFee; + private Integer estimatedWalkingTime; + private String parkingType; + private Boolean isFavorite; + private Double latitude; + private Double longitude; + + private ParkingResponse() { + } + + public ParkingResponse(Long parkingId, String parkingName, Integer estimatedFee, Integer estimatedWalkingTime, + String parkingType, Boolean isFavorite, Double latitude, Double longitude) { + this.parkingId = parkingId; + this.parkingName = parkingName; + this.estimatedFee = estimatedFee; + this.estimatedWalkingTime = estimatedWalkingTime; + this.parkingType = parkingType; + this.isFavorite = isFavorite; + this.latitude = latitude; + this.longitude = longitude; + } + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingQueryRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingQueryRequest.java new file mode 100644 index 00000000..f5f322b0 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingQueryRequest.java @@ -0,0 +1,17 @@ +package com.parkingcomestrue.parking.application.parking.dto; + +import lombok.Getter; + +@Getter +public class ParkingQueryRequest { + + private final Double longitude; + private final Double latitude; + private final Integer radius; + + public ParkingQueryRequest(Double longitude, Double latitude, Integer radius) { + this.longitude = longitude; + this.latitude = latitude; + this.radius = radius; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingSearchConditionRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingSearchConditionRequest.java new file mode 100644 index 00000000..e710426b --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/dto/ParkingSearchConditionRequest.java @@ -0,0 +1,25 @@ +package com.parkingcomestrue.parking.application.parking.dto; + +import java.util.List; +import lombok.Getter; + +@Getter +public class ParkingSearchConditionRequest { + + private final List operationTypes; + private final List parkingTypes; + private final String feeType; + private final List payTypes; + private final Integer hours; + private final String priority; + + public ParkingSearchConditionRequest(List operationTypes, List parkingTypes, String feeType, + List payTypes, int hours, String priority) { + this.operationTypes = operationTypes; + this.parkingTypes = parkingTypes; + this.feeType = feeType; + this.payTypes = payTypes; + this.hours = hours; + this.priority = priority; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java new file mode 100644 index 00000000..72409d00 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java @@ -0,0 +1,47 @@ +package com.parkingcomestrue.parking.application.review; + +import com.parkingcomestrue.parking.application.review.dto.ReviewCountResponse; +import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; +import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; +import com.parkingcomestrue.parking.domain.review.Content; +import com.parkingcomestrue.parking.domain.review.Review; +import com.parkingcomestrue.parking.domain.review.repository.ReviewRepository; +import com.parkingcomestrue.parking.domain.review.service.ReviewDomainService; +import com.parkingcomestrue.parking.support.Association; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ReviewService { + + private final ReviewRepository reviewRepository; + private final ReviewDomainService reviewDomainService; + + @Transactional + public Long createReview(Long parkingId, Long reviewerId, ReviewCreateRequest request) { + reviewDomainService.validateDuplicateReview(Association.from(parkingId), Association.from(reviewerId)); + + Review review = new Review(Association.from(parkingId), Association.from(reviewerId), request.toContents()); + reviewRepository.save(review); + return review.getId(); + } + + public ReviewInfoResponse readReviews(Long parkingId) { + List reviews = reviewRepository.findAllByParkingId(Association.from(parkingId)); + Map counts = reviewDomainService.collectByContent(reviews); + return new ReviewInfoResponse(reviewDomainService.calculateTotalReviews(counts), orderByCounts(counts)); + } + + private List orderByCounts(Map counts) { + return counts.keySet().stream() + .map(content -> new ReviewCountResponse(content.getDescription(), counts.get(content).intValue())) + .sorted(Comparator.comparing(ReviewCountResponse::count).reversed()) + .toList(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCountResponse.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCountResponse.java new file mode 100644 index 00000000..255b15f2 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCountResponse.java @@ -0,0 +1,5 @@ +package com.parkingcomestrue.parking.application.review.dto; + +public record ReviewCountResponse(String content, int count) { + +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java new file mode 100644 index 00000000..da687561 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java @@ -0,0 +1,13 @@ +package com.parkingcomestrue.parking.application.review.dto; + +import com.parkingcomestrue.parking.domain.review.Content; +import java.util.List; + +public record ReviewCreateRequest(List contents) { + + public List toContents() { + return contents.stream() + .map(Content::find) + .toList(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewInfoResponse.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewInfoResponse.java new file mode 100644 index 00000000..3f69b913 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewInfoResponse.java @@ -0,0 +1,7 @@ +package com.parkingcomestrue.parking.application.review.dto; + +import java.util.List; + +public record ReviewInfoResponse(int totalReviewCount, List reviews) { + +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java new file mode 100644 index 00000000..fc5e493d --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java @@ -0,0 +1,71 @@ +package com.parkingcomestrue.parking.application.searchcondition; + +import com.parkingcomestrue.parking.application.SearchConditionMapper; +import com.parkingcomestrue.parking.application.searchcondition.dto.SearchConditionDto; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayType; +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.parking.domain.searchcondition.Hours; +import com.parkingcomestrue.parking.domain.searchcondition.Priority; +import com.parkingcomestrue.parking.domain.searchcondition.SearchCondition; +import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.parking.domain.searchcondition.repository.SearchConditionRepository; +import com.parkingcomestrue.parking.support.Association; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class SearchConditionService { + + private final SearchConditionRepository searchConditionRepository; + private final SearchConditionMapper searchConditionMapper; + + public SearchConditionDto findSearchCondition(Long memberId) { + SearchCondition searchCondition = searchConditionRepository.getByMemberId(memberId); + return toSearchConditionDto(searchCondition); + } + + private SearchConditionDto toSearchConditionDto(SearchCondition searchCondition) { + return new SearchConditionDto( + toDescriptions(searchCondition.getOperationTypes()), + toDescriptions(searchCondition.getParkingTypes()), + toDescriptions(searchCondition.getFeeTypes()), + toDescriptions(searchCondition.getPayTypes()), + searchCondition.getPriority().getDescription(), + searchCondition.getHours().getHours() + ); + } + + private List toDescriptions(List enums) { + return enums.stream() + .map(SearchConditionAvailable::getDescription) + .toList(); + } + + @Transactional + public void updateSearchCondition(Long memberId, SearchConditionDto searchConditionDto) { + SearchCondition newSearchCondition = createSearchCondition(memberId, searchConditionDto); + + searchConditionRepository.findByMemberId(memberId).ifPresentOrElse( + existingSearchCondition -> existingSearchCondition.update(newSearchCondition), + () -> searchConditionRepository.save(newSearchCondition) + ); + } + + private SearchCondition createSearchCondition(Long memberId, SearchConditionDto searchConditionDto) { + return new SearchCondition( + Association.from(memberId), + searchConditionMapper.toEnums(OperationType.class, searchConditionDto.getOperationType()), + searchConditionMapper.toEnums(ParkingType.class, searchConditionDto.getParkingType()), + searchConditionMapper.toEnums(FeeType.class, searchConditionDto.getFeeType()), + searchConditionMapper.toEnums(PayType.class, searchConditionDto.getPayType()), + searchConditionMapper.toEnum(Priority.class, searchConditionDto.getPriority()), + Hours.from(searchConditionDto.getHours()) + ); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/dto/SearchConditionDto.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/dto/SearchConditionDto.java new file mode 100644 index 00000000..cb991b0c --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/dto/SearchConditionDto.java @@ -0,0 +1,25 @@ +package com.parkingcomestrue.parking.application.searchcondition.dto; + +import java.util.List; +import lombok.Getter; + +@Getter +public class SearchConditionDto { + + private List operationType; + private List parkingType; + private List feeType; + private List payType; + private String priority; + private Integer hours; + + public SearchConditionDto(List operationType, List parkingType, List feeType, + List payType, String priority, Integer hours) { + this.operationType = operationType; + this.parkingType = parkingType; + this.feeType = feeType; + this.payType = payType; + this.priority = priority; + this.hours = hours; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/RedisConfig.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/RedisConfig.java new file mode 100644 index 00000000..f4ef7089 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/RedisConfig.java @@ -0,0 +1,35 @@ +package com.parkingcomestrue.parking.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + @Value("${spring.data.redis.host}") + private String host; + + @Value("${spring.data.redis.port}") + private Integer port; + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(host, port); + } + + @Primary + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory()); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + return redisTemplate; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/SwaggerConfig.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/SwaggerConfig.java new file mode 100644 index 00000000..3a1c838c --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/SwaggerConfig.java @@ -0,0 +1,32 @@ +package com.parkingcomestrue.parking.config; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.security.SecurityScheme.In; +import io.swagger.v3.oas.models.security.SecurityScheme.Type; +import io.swagger.v3.oas.models.servers.Server; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@OpenAPIDefinition( + info = @Info(title = "주차의 상상은 현실이 된다 aka 주상현", description = "주차의 상상은 현실이 된다 aka 주상현 API 명세서")) +@Configuration +public class SwaggerConfig { + + private static final String JSESSIONID = "JSESSIONID"; + + @Bean + public OpenAPI openAPI() { + SecurityScheme auth = new SecurityScheme() + .type(Type.APIKEY).in(In.COOKIE).name(JSESSIONID); + SecurityRequirement securityRequirement = new SecurityRequirement().addList(JSESSIONID); + + return new OpenAPI().addServersItem(new Server().url("/")) + .components(new Components().addSecuritySchemes("JSESSIONID", auth)) + .addSecurityItem(securityRequirement); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/WebMvcConfig.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/WebMvcConfig.java new file mode 100644 index 00000000..cb8f0f84 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/WebMvcConfig.java @@ -0,0 +1,65 @@ +package com.parkingcomestrue.parking.config; + +import com.parkingcomestrue.parking.config.argumentresolver.AuthArgumentResolver; +import com.parkingcomestrue.parking.config.argumentresolver.parking.ParkingQueryArgumentResolver; +import com.parkingcomestrue.parking.config.argumentresolver.parking.ParkingSearchConditionArgumentResolver; +import com.parkingcomestrue.parking.config.interceptor.AuthInterceptor; +import io.swagger.v3.oas.models.PathItem; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@RequiredArgsConstructor +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + private final AuthInterceptor authInterceptor; + private final AuthArgumentResolver authArgumentResolver; + private final ParkingQueryArgumentResolver parkingQueryArgumentResolver; + private final ParkingSearchConditionArgumentResolver parkingSearchConditionArgumentResolver; + + @Value("${cors.allowedOrigins}") + private String[] allowedOrigins; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(authInterceptor) + .addPathPatterns("/**") + .excludePathPatterns(List.of( + "/v3/api-docs/**", + "/swagger-resources/**", + "/swagger-ui/**", + "/signup", + "/signin", + "/parkings/**" + )); + } + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(authArgumentResolver); + resolvers.add(parkingQueryArgumentResolver); + resolvers.add(parkingSearchConditionArgumentResolver); + } + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins(allowedOrigins) + .allowedMethods( + PathItem.HttpMethod.OPTIONS.name(), + PathItem.HttpMethod.GET.name(), + PathItem.HttpMethod.POST.name(), + PathItem.HttpMethod.PUT.name(), + PathItem.HttpMethod.DELETE.name(), + PathItem.HttpMethod.PATCH.name() + ) + .allowCredentials(true) + .exposedHeaders("*"); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java new file mode 100644 index 00000000..58833ab1 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java @@ -0,0 +1,38 @@ +package com.parkingcomestrue.parking.config.argumentresolver; + +import com.parkingcomestrue.parking.application.auth.AuthService; +import com.parkingcomestrue.parking.domain.session.MemberSession; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@RequiredArgsConstructor +@Component +public class AuthArgumentResolver implements HandlerMethodArgumentResolver { + + + private static final String JSESSIONID = "JSESSIONID"; + + private final AuthService authService; + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(MemberAuth.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + MemberAuth memberAuth = parameter.getParameterAnnotation(MemberAuth.class); + String sessionId = webRequest.getHeader(JSESSIONID); + if (memberAuth.nullable() && sessionId == null) { + return null; + } + MemberSession session = authService.findSession(sessionId); + return session.getMemberId(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/MemberAuth.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/MemberAuth.java new file mode 100644 index 00000000..6f4ea2bf --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/MemberAuth.java @@ -0,0 +1,13 @@ +package com.parkingcomestrue.parking.config.argumentresolver; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface MemberAuth { + + boolean nullable() default false; +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQuery.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQuery.java new file mode 100644 index 00000000..ad3d7bcc --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQuery.java @@ -0,0 +1,11 @@ +package com.parkingcomestrue.parking.config.argumentresolver.parking; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface ParkingQuery { +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java new file mode 100644 index 00000000..a3f3dc24 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java @@ -0,0 +1,28 @@ +package com.parkingcomestrue.parking.config.argumentresolver.parking; + +import com.parkingcomestrue.parking.application.parking.dto.ParkingQueryRequest; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +public class ParkingQueryArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(ParkingQuery.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + return new ParkingQueryRequest( + Double.valueOf(webRequest.getParameter("longitude")), + Double.valueOf(webRequest.getParameter("latitude")), + Integer.parseInt(webRequest.getParameter("radius")) + ); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchCondition.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchCondition.java new file mode 100644 index 00000000..347f710d --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchCondition.java @@ -0,0 +1,11 @@ +package com.parkingcomestrue.parking.config.argumentresolver.parking; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface ParkingSearchCondition { +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java new file mode 100644 index 00000000..19851bbe --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java @@ -0,0 +1,78 @@ +package com.parkingcomestrue.parking.config.argumentresolver.parking; + +import com.parkingcomestrue.parking.application.SearchConditionMapper; +import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayType; +import java.util.Arrays; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@RequiredArgsConstructor +@Component +public class ParkingSearchConditionArgumentResolver implements HandlerMethodArgumentResolver { + + private static final int BASE_HOURS = 1; + private static final String NOT_FREE = "유료"; + private static final String RECOMMEND_ORDER_CONDITION = "추천 순"; + + private final SearchConditionMapper searchConditionMapper; + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(ParkingSearchCondition.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + + String[] operationTypes = webRequest.getParameterValues("operationTypes"); + String[] parkingTypes = webRequest.getParameterValues("parkingTypes"); + String feeType = webRequest.getParameter("feeTypes"); + String[] payTypes = webRequest.getParameterValues("payTypes"); + String hours = webRequest.getParameter("hours"); + String priority = webRequest.getParameter("priority"); + + if (containsNull(operationTypes, parkingTypes, feeType, payTypes, hours)) { + return defaultRequest(); + } + + return new ParkingSearchConditionRequest( + toList(operationTypes), + toList(parkingTypes), + feeType, + toList(payTypes), + Integer.parseInt(hours), + priority + ); + } + + private boolean containsNull(String[] operationTypes, String[] parkingTypes, String feeType, + String[] payTypes, String hours) { + return operationTypes == null || parkingTypes == null || feeType == null || payTypes == null || hours == null; + } + + private ParkingSearchConditionRequest defaultRequest() { + return new ParkingSearchConditionRequest( + searchConditionMapper.getValues(OperationType.class), + searchConditionMapper.getValues(ParkingType.class), + NOT_FREE, + searchConditionMapper.getValues(PayType.class), + BASE_HOURS, + RECOMMEND_ORDER_CONDITION + ); + } + + private List toList(String[] parameters) { + return Arrays.stream(parameters) + .toList(); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java new file mode 100644 index 00000000..7ab2b150 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java @@ -0,0 +1,29 @@ +package com.parkingcomestrue.parking.config.interceptor; + +import com.parkingcomestrue.parking.application.auth.AuthService; +import com.parkingcomestrue.parking.domain.session.MemberSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@RequiredArgsConstructor +@Component +@Slf4j +public class AuthInterceptor implements HandlerInterceptor { + + private static final String JSESSIONID = "JSESSIONID"; + + private final AuthService authService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + log.info("request: {}", request.getRequestURL()); + String sessionId = request.getHeader(JSESSIONID); + MemberSession session = authService.findSession(sessionId); + authService.updateSessionExpiredAt(session); + return true; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java new file mode 100644 index 00000000..c33b83d4 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java @@ -0,0 +1,55 @@ +package com.parkingcomestrue.parking.controlleradvice; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.UNAUTHORIZED; + +import com.parkingcomestrue.parking.controlleradvice.dto.ExceptionResponse; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.EnumMap; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + private final EnumMap exceptionInfoToHttpStatus = new EnumMap<>( + ExceptionInformation.class); + + public GlobalExceptionHandler() { + exceptionInfoToHttpStatus.put(ExceptionInformation.UNAUTHORIZED, UNAUTHORIZED); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(final Exception e) { + final ExceptionResponse exceptionResponse = new ExceptionResponse("알지 못하는 예외 발생"); + log.error("알지 못하는 예외 발생", e); + + return ResponseEntity.internalServerError() + .body(exceptionResponse); + } + + @ExceptionHandler(DomainException.class) + public ResponseEntity handleServerException(final DomainException e) { + final ExceptionResponse exceptionResponse = new ExceptionResponse(e.getMessage()); + log.error(e.getMessage(), e); + + return ResponseEntity.internalServerError() + .body(exceptionResponse); + } + + @ExceptionHandler(ClientException.class) + public ResponseEntity handleClientException(final ClientException e) { + final ExceptionResponse exceptionResponse = new ExceptionResponse(e.getMessage()); + + final HttpStatus httpStatus = exceptionInfoToHttpStatus.getOrDefault(e.getExceptionInformation(), BAD_REQUEST); + + return ResponseEntity.status(httpStatus) + .body(exceptionResponse); + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/dto/ExceptionResponse.java b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/dto/ExceptionResponse.java new file mode 100644 index 00000000..4f132e31 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/dto/ExceptionResponse.java @@ -0,0 +1,5 @@ +package com.parkingcomestrue.parking.controlleradvice.dto; + +public record ExceptionResponse(String errorMessage) { + +} diff --git a/app-api/src/main/resources/application-prod.yml b/app-api/src/main/resources/application-prod.yml new file mode 100644 index 00000000..494fa049 --- /dev/null +++ b/app-api/src/main/resources/application-prod.yml @@ -0,0 +1,14 @@ +spring: + # JPA + jpa: + hibernate: + ddl-auto: validate + database: mysql + open-in-view: false + + # DB + datasource: + url: ${DB_URL} + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/app-api/src/main/resources/application.yml b/app-api/src/main/resources/application.yml new file mode 100644 index 00000000..b9554ae4 --- /dev/null +++ b/app-api/src/main/resources/application.yml @@ -0,0 +1,29 @@ +spring: + profiles: + active: ${PROFILE:dev} +# MAIL + mail: + host: ${MAIL_HOST:smtp.gmail.com} + port: ${MAIL_PORT:587} + username: ${MAIL_USERNAME:mail@gmail.com} + password: ${MAIL_PASSWORD:password} + properties: + mail: + smtp: + auth: true + timeout: 5000 + starttls: + enable: true +# REDIS + data: + redis: + host: ${REDIS_HOST:localhost} + port: ${REDIS_PORT:6379} + +# AUTH CODE +authcode: + expired-time: 300 + +# Allow origin +cors: + allowedOrigins: ${ORIGIN:http://localhost:3000} diff --git a/app-api/src/test/java/com/parkingcomestrue/ApiApplicationTests.java b/app-api/src/test/java/com/parkingcomestrue/ApiApplicationTests.java new file mode 100644 index 00000000..94d62f51 --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/ApiApplicationTests.java @@ -0,0 +1,13 @@ +package com.parkingcomestrue; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApiApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java new file mode 100644 index 00000000..61f1dd54 --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java @@ -0,0 +1,106 @@ +package com.parkingcomestrue.parking.application; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayType; +import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.parking.domain.searchcondition.Priority; +import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.List; +import java.util.stream.Stream; +import org.junit.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class SearchConditionMapperTest { + + private static final SearchConditionMapper searchConditionMapper = new SearchConditionMapper(); + + @ParameterizedTest + @MethodSource("parametersProvider1") + & SearchConditionAvailable> void enum_class와_설명으로_해당하는_값을_반환한다(Class clazz, + String description, + E expected) { + //given, when + E actual = searchConditionMapper.toEnum(clazz, description); + + //then + assertThat(actual).isEqualTo(expected); + } + + static Stream parametersProvider1() { + return Stream.of( + arguments(OperationType.class, "민영 주차장", OperationType.PRIVATE), + arguments(OperationType.class, "공영", OperationType.PUBLIC), + arguments(ParkingType.class, "노상", ParkingType.ON_STREET), + arguments(ParkingType.class, "노외 주차장", ParkingType.OFF_STREET), + arguments(FeeType.class, "무료", FeeType.FREE), + arguments(FeeType.class, "유료", FeeType.PAID), + arguments(PayType.class, "계좌", PayType.BANK_TRANSFER), + arguments(Priority.class, "가격순", Priority.PRICE) + ); + } + + @Test + void 변환시_해당하는_값이_없으면_클라이언트_예외를_반환한다() { + //given, when, then + assertThatThrownBy(() -> searchConditionMapper.toEnum(PayType.class, "아무거나 입력")) + .isInstanceOf(ClientException.class) + .hasMessage(ExceptionInformation.INVALID_DESCRIPTION.getMessage()); + } + + @ParameterizedTest + @MethodSource("parametersProvider2") + & SearchConditionAvailable> void enum_class와_설명들로_해당하는_값들을_반환한다(Class clazz, + List descriptions, + List expected) { + //given, when + List actual = searchConditionMapper.toEnums(clazz, descriptions); + + //then + assertThat(actual).containsExactlyInAnyOrderElementsOf(expected); + } + + static Stream parametersProvider2() { + return Stream.of( + arguments(OperationType.class, List.of("민영 주차장", "공영 주차장"), + List.of(OperationType.PRIVATE, OperationType.PUBLIC)), + arguments(OperationType.class, List.of("공영"), List.of(OperationType.PUBLIC)), + arguments(ParkingType.class, List.of("노상", "기계"), + List.of(ParkingType.ON_STREET, ParkingType.MECHANICAL)), + arguments(ParkingType.class, List.of("노외 주차장"), List.of(ParkingType.OFF_STREET)), + arguments(FeeType.class, List.of("무료", "유료"), List.of(FeeType.FREE, FeeType.PAID)), + arguments(FeeType.class, List.of("유료"), List.of(FeeType.PAID)), + arguments(PayType.class, List.of("계좌", "현금"), List.of(PayType.BANK_TRANSFER, PayType.CASH)), + arguments(Priority.class, List.of("가격순"), List.of(Priority.PRICE)) + ); + } + + @ParameterizedTest + @MethodSource("parametersProvider3") + & SearchConditionAvailable> void 해당하는_enum_class의_기본_값을_제외한_값들을_가져온다(Class clazz, + List expected) { + //given, when + List actual = searchConditionMapper.getValues(clazz); + + //then + assertThat(actual).containsExactlyInAnyOrderElementsOf(expected); + } + + static Stream parametersProvider3() { + return Stream.of( + arguments(OperationType.class, List.of("공영", "민영")), + arguments(ParkingType.class, List.of("노상", "기계", "노외")), + arguments(FeeType.class, List.of("무료", "유료")), + arguments(PayType.class, List.of("카드", "계좌", "현금")), + arguments(Priority.class, List.of("가까운순", "가격순")) + ); + } +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java new file mode 100644 index 00000000..a6d3d11c --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java @@ -0,0 +1,148 @@ +package com.parkingcomestrue.parking.application.auth; + +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_AUTH_CODE; +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.UNAUTHORIZED; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import com.parkingcomestrue.parking.application.container.ContainerTest; +import com.parkingcomestrue.parking.application.auth.authcode.AuthCodeCategory; +import com.parkingcomestrue.parking.application.auth.authcode.AuthCodePlatform; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest; +import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeRequest; +import com.parkingcomestrue.parking.domain.session.MemberSession; +import com.parkingcomestrue.parking.support.exception.ClientException; +import java.time.LocalDateTime; +import org.junit.jupiter.api.Test; + +class AuthServiceTest extends ContainerTest { + + private static final String AUTH_CODE = "111111"; + + + @Test + void 세션_아이디에_해당하는_세션을_찾는다() { + // given + Long memberId = 1L; + String sessionId = authService.createSession(memberId); + + // when, then + assertThatNoException() + .isThrownBy(() -> authService.findSession(sessionId)); + } + + @Test + void 세션_아이디에_해당하는_세션이_존재하지_않으면_예외를_던진다() { + // given + String wrongSessionId = "아무세션아이디"; + + // when, then + assertThatThrownBy(() -> authService.findSession(wrongSessionId)) + .isInstanceOf(ClientException.class) + .hasMessage(UNAUTHORIZED.getMessage()); + } + + @Test + void 세션_만료시간을_갱신한다() { + // given + Long memberId = 1L; + String sessionId = authService.createSession(memberId); + MemberSession originSession = authService.findSession(sessionId); + LocalDateTime originExpiredAt = originSession.getExpiredAt(); + + // when + authService.updateSessionExpiredAt(originSession); + MemberSession updatedSession = authService.findSession(sessionId); + LocalDateTime updatedExpiredAt = updatedSession.getExpiredAt(); + + // then + assertThat(updatedExpiredAt).isAfter(originExpiredAt); + } + + @Test + void 가장_최근에_발급받은_인증번호는_검증가능하다() { + // given + String authCodeDestination = "destination@gmail.com"; + AuthCodePlatform authCodePlatform = AuthCodePlatform.MAIL; + AuthCodeCategory authCodeCategory = AuthCodeCategory.SIGN_UP; + + String oldAuthCode = authService.createAuthCode( + new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName()) + ); + + String newAuthCode = authService.createAuthCode( + new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName()) + ); + + // when + AuthCodeCertificateRequest authCodeCertificateRequest = new AuthCodeCertificateRequest( + authCodeDestination, + authCodePlatform.getPlatform(), + AuthCodeCategory.SIGN_UP.getCategoryName(), + newAuthCode + ); + + // then + assertDoesNotThrow(() -> authService.certificateAuthCode(authCodeCertificateRequest)); + } + + @Test + void 이미_인증받은_인증번호는_다시_사용할_수_없다() { + // given + String authCodeDestination = "destination@gmail.com"; + AuthCodePlatform authCodePlatform = AuthCodePlatform.MAIL; + AuthCodeCategory authCodeCategory = AuthCodeCategory.SIGN_UP; + + String oldAuthCode = authService.createAuthCode( + new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName()) + ); + + // when + AuthCodeCertificateRequest authCodeCertificateRequest = new AuthCodeCertificateRequest( + authCodeDestination, + authCodePlatform.getPlatform(), + AuthCodeCategory.SIGN_UP.getCategoryName(), + oldAuthCode + ); + authService.certificateAuthCode(authCodeCertificateRequest); + + // then (인증받은 인증코드로 인증 다시 시도) + assertThatThrownBy(() -> authService.certificateAuthCode(authCodeCertificateRequest)) + .isInstanceOf(ClientException.class) + .hasMessage(INVALID_AUTH_CODE.getMessage()); + } + + @Test + void 가장_최근의_인증번호가_아니어도_인증_가능하다() { + // given + String authCodeDestination = "destination@gmail.com"; + AuthCodePlatform authCodePlatform = AuthCodePlatform.MAIL; + AuthCodeCategory authCodeCategory = AuthCodeCategory.SIGN_UP; + + String oldAuthCode = authService.createAuthCode( + new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName()) + ); + + String newAuthCode = authService.createAuthCode( + new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), + authCodeCategory.getCategoryName()) + ); + + // when + AuthCodeCertificateRequest authCodeCertificateRequest = new AuthCodeCertificateRequest( + authCodeDestination, + authCodePlatform.getPlatform(), + AuthCodeCategory.SIGN_UP.getCategoryName(), + oldAuthCode + ); + + // then (예전 인증코드(oldAuthCode)로 인증 시도) + assertDoesNotThrow(() -> authService.certificateAuthCode(authCodeCertificateRequest)); + } +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/config/TestConfig.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/config/TestConfig.java new file mode 100644 index 00000000..03c79662 --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/config/TestConfig.java @@ -0,0 +1,21 @@ +package com.parkingcomestrue.parking.application.config; + +import com.parkingcomestrue.parking.application.auth.authcode.infrastructure.AuthCodeSender; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +@TestConfiguration +public class TestConfig { + + @Bean + @Primary + public AuthCodeSender fakeAuthCodeSender() { + return new AuthCodeSender() { + @Override + public void send(String destination, String authCode) { + + } + }; + } +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/container/ContainerTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/container/ContainerTest.java new file mode 100644 index 00000000..e310ea9d --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/container/ContainerTest.java @@ -0,0 +1,73 @@ +package com.parkingcomestrue.parking.application.container; + +import com.parkingcomestrue.parking.application.auth.AuthService; +import com.parkingcomestrue.parking.application.config.TestConfig; +import com.parkingcomestrue.parking.application.parking.ParkingService; +import com.parkingcomestrue.parking.application.review.ReviewService; +import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; +import com.redis.testcontainers.RedisContainer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; + +@SpringBootTest +@Import({TestConfig.class}) +@ActiveProfiles("test") +public abstract class ContainerTest { + + private static final RedisContainer REDIS_CONTAINER; + private static RedisTemplate redisTemplate; + + static { + REDIS_CONTAINER = new RedisContainer(RedisContainer.DEFAULT_IMAGE_NAME.withTag(RedisContainer.DEFAULT_TAG)) + .withExposedPorts(6379); + REDIS_CONTAINER.start(); + } + + @DynamicPropertySource + static void postgresqlProperties(DynamicPropertyRegistry registry) { + registry.add("spring.data.redis.host", REDIS_CONTAINER::getHost); + registry.add("spring.data.redis.port", REDIS_CONTAINER::getRedisPort); + } + + @Autowired + private MySQLDataCleaner mySQLDataCleaner; + + @Autowired + protected ParkingService parkingService; + + @Autowired + protected ReviewService reviewService; + + @Autowired + protected MemberRepository memberRepository; + + @Autowired + protected AuthService authService; + + @BeforeAll + static void setUpBeforeClass() { + String redisHost = REDIS_CONTAINER.getHost(); + int redisPort = REDIS_CONTAINER.getRedisPort(); + LettuceConnectionFactory redisConnectionFactory = new LettuceConnectionFactory(redisHost, redisPort); + redisConnectionFactory.afterPropertiesSet(); + + redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + } + + @AfterEach + void teardown() { + RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); + connection.serverCommands().flushAll(); + mySQLDataCleaner.delete(); + } +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/container/MySQLDataCleaner.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/container/MySQLDataCleaner.java new file mode 100644 index 00000000..b358ef7e --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/container/MySQLDataCleaner.java @@ -0,0 +1,34 @@ +package com.parkingcomestrue.parking.application.container; + +import jakarta.persistence.EntityManager; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.testcontainers.shaded.com.google.common.base.CaseFormat; + +@Component +public class MySQLDataCleaner { + + @Autowired + private EntityManager entityManager; + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Transactional + public void delete() { + List tableNames = entityManager.getMetamodel().getEntities().stream() + .map(table -> CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, table.getName())) + .toList(); + + setForeignKeyEnabled(false); + tableNames.forEach(table -> jdbcTemplate.execute("TRUNCATE table " + table)); + setForeignKeyEnabled(true); + } + + private void setForeignKeyEnabled(boolean enabled) { + entityManager.createNativeQuery("SET foreign_key_checks = " + enabled).executeUpdate(); + } +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/container/RedisDataCleaner.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/container/RedisDataCleaner.java new file mode 100644 index 00000000..10f82d01 --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/container/RedisDataCleaner.java @@ -0,0 +1,18 @@ +package com.parkingcomestrue.parking.application.container; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +@Component +@Profile("test") +public class RedisDataCleaner { + + @Autowired + private RedisTemplate redisTemplate; + + public void delete() { + redisTemplate.getConnectionFactory().getConnection().serverCommands().flushAll(); + } +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java new file mode 100644 index 00000000..ebdbca4f --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java @@ -0,0 +1,89 @@ +package com.parkingcomestrue.parking.application.member; + +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_MEMBER; +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_PASSWORD; +import static org.assertj.core.api.Assertions.assertThat; + +import com.parkingcomestrue.parking.application.member.dto.MemberLoginRequest; +import com.parkingcomestrue.parking.application.member.dto.MemberSignupRequest; +import com.parkingcomestrue.parking.application.member.dto.PasswordChangeRequest; +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.DomainException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@SpringBootTest +class MemberServiceTest { + + @Autowired + private MemberService memberService; + + @Autowired + private MemberRepository memberRepository; + + @Test + void 회원탈퇴() { + Long memberId = memberService.signup(new MemberSignupRequest("name", "email", "nickname", "password")); + memberService.deleteMember(memberId); + + Member member = memberRepository.getById(memberId); + assertThat(member.getDeleted()).isTrue(); + } + + @Test + void 비밀번호를_바꾸면_바꾼_비밀번호로_로그인이_가능하다() { + // given + String email = "email@google.com"; + String previousPassword = "password"; + MemberSignupRequest memberSignupRequest = new MemberSignupRequest("name", email, previousPassword, "nickname"); + Long memberId = memberService.signup(memberSignupRequest); + + String newPassword = "newPassword"; + + // when + memberService.changePassword(memberId, new PasswordChangeRequest(previousPassword, newPassword)); + + // then + Assertions.assertThatNoException() + .isThrownBy(() -> memberService.login(new MemberLoginRequest(email, newPassword))); + } + + @Test + void 비밀번호를_바꾸면_이전의_비밀번호로_로그인이_불가능하다() { + // given + String email = "email@google.com"; + String previousPassword = "password"; + MemberSignupRequest memberSignupRequest = new MemberSignupRequest("name", email, previousPassword, "nickname"); + Long memberId = memberService.signup(memberSignupRequest); + + String newPassword = "newPassword"; + + // when + memberService.changePassword(memberId, new PasswordChangeRequest(previousPassword, newPassword)); + + // then + Assertions.assertThatThrownBy(() -> memberService.login(new MemberLoginRequest(email, previousPassword))) + .isInstanceOf(ClientException.class) + .hasMessage(INVALID_PASSWORD.getMessage()); + } + + @Test + void 비밀번호를_바꿀_때_해당_회원이_존재하지_않으면_예외를_던진다() { + // given + String previousPassword = "password"; + String newPassword = "newPassword"; + Long wrongMemberId = 12312541L; + + // when, then + Assertions.assertThatThrownBy(() -> memberService.changePassword(wrongMemberId, + new PasswordChangeRequest(previousPassword, newPassword))) + .isInstanceOf(DomainException.class) + .hasMessage(INVALID_MEMBER.getMessage()); + } +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java new file mode 100644 index 00000000..93841ee1 --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java @@ -0,0 +1,90 @@ +package com.parkingcomestrue.parking.application.parking; + +import static org.junit.jupiter.api.Assertions.assertAll; + +import com.parkingcomestrue.parking.application.container.ContainerTest; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; +import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.member.Password; +import com.parkingcomestrue.parking.domain.parking.BaseInformation; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.FeePolicy; +import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.OperatingTime; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.parking.domain.parking.Space; +import com.parkingcomestrue.parking.domain.parking.TimeInfo; +import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import com.parkingcomestrue.parking.domain.review.Content; +import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.time.LocalTime; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class ParkingServiceTest extends ContainerTest { + + @Test + void 조회하려는_주차장이_없으면_예외() { + //given + Assertions.assertThatThrownBy(() -> parkingService.findParking(1L)) + .isInstanceOf(DomainException.class) + .hasMessage(ExceptionInformation.INVALID_PARKING.getMessage()); + } + + @Test + void 주차장_상세조회() { + //given + String parkingName = "호이주차장"; + Parking parking = makeParking(parkingName); + List parkings = List.of(parking); + parkingService.saveAll(parkings); + + Member member = new Member( "email", "하디", new Password("qwer1234")); + memberRepository.save(member); + + ReviewCreateRequest reviewCreateRequest = new ReviewCreateRequest( + List.of(Content.LARGE_PARKING_SPACE.getDescription(), Content.EASY_TO_PAY.getDescription())); + reviewService.createReview(parking.getId(), member.getId(), reviewCreateRequest); + + // when, then + ParkingDetailInfoResponse parkingDetailInfoResponse = parkingService.findParking(parking.getId()); + assertAll( + () -> Assertions.assertThat(parkingDetailInfoResponse.getReviewInfo().reviews()).hasSize(2), + () -> Assertions.assertThat(parkingDetailInfoResponse.getParkingName()).isEqualTo(parkingName) + ); + } + + private Parking makeParking(String parkingName) { + return new Parking + ( + new BaseInformation(parkingName, "010", "부산", PayTypes.DEFAULT, ParkingType.MECHANICAL, + OperationType.PRIVATE), + Location.of(30d, 30d), + Space.of(100, 30), + new FreeOperatingTime( + new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), + new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), + new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)) + ), + new OperatingTime( + new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), + new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), + new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)) + ), + new FeePolicy( + Fee.from(2000), + Fee.from(2000), + TimeUnit.from(30), + TimeUnit.from(15), + Fee.from(50000)) + ); + } + +} diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java new file mode 100644 index 00000000..5fc14888 --- /dev/null +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java @@ -0,0 +1,98 @@ +package com.parkingcomestrue.parking.application.review; + +import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.DUPLICATE_REVIEW; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; +import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; +import com.parkingcomestrue.parking.domain.member.Member; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.review.Content; +import com.parkingcomestrue.parking.domain.review.Review; +import com.parkingcomestrue.parking.domain.review.service.ReviewDomainService; +import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.parking.support.exception.DomainException; +import java.util.List; +import org.junit.jupiter.api.Test; +import repository.BasicMemberRepository; +import repository.BasicParkingRepository; +import repository.BasicReviewRepository; + +class ReviewServiceTest { + + private final BasicParkingRepository parkingRepository = new BasicParkingRepository(); + private final BasicMemberRepository memberRepository = new BasicMemberRepository(); + private final BasicReviewRepository reviewRepository = new BasicReviewRepository(); + private final ReviewService reviewService = new ReviewService( + reviewRepository, + new ReviewDomainService(reviewRepository) + ); + + @Test + void 리뷰를_작성한다() { + //given + Parking parking = parkingRepository.saveAndGet(1).get(0); + Member reviewer = memberRepository.saveAndGet(1).get(0); + ReviewCreateRequest request = new ReviewCreateRequest(List.of("주차 자리가 많아요", "결제가 편리해요")); + + //when + Long reviewId = reviewService.createReview(parking.getId(), reviewer.getId(), request); + + //then + assertThat(reviewId).isNotNull(); + } + + @Test + void 리뷰를_이미_작성했으면_예외가_발생한다() { + //given + Parking parking = parkingRepository.saveAndGet(1).get(0); + Member reviewer = memberRepository.saveAndGet(1).get(0); + ReviewCreateRequest request = new ReviewCreateRequest(List.of("주차 자리가 많아요", "결제가 편리해요")); + reviewService.createReview(parking.getId(), reviewer.getId(), request); + + //when, then + assertThatThrownBy(() -> reviewService.createReview(parking.getId(), reviewer.getId(), request)) + .isInstanceOf(DomainException.class) + .hasMessage(DUPLICATE_REVIEW.getMessage()); + } + + @Test + void 주차장에_대한_리뷰를_내용이_많은순으로_가져온다() { + //given + Parking parking = parkingRepository.saveAndGet(1).get(0); + Association parkingId = Association.from(parking.getId()); + List reviewers = memberRepository.saveAndGet(3); + + List contents1 = List.of(Content.LOW_PRICE); + List contents2 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY); + List contents3 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY, Content.GOOD_ACCESSIBILITY); + reviewRepository.save( + new Review(parkingId, Association.from(reviewers.get(0).getId()), contents1) + ); + reviewRepository.save( + new Review(parkingId, Association.from(reviewers.get(1).getId()), contents2) + ); + reviewRepository.save( + new Review(parkingId, Association.from(reviewers.get(2).getId()), contents3) + ); + + //when + ReviewInfoResponse reviewInfoResponse = reviewService.readReviews(parkingId.getId()); + + //then + assertSoftly( + soft -> { + soft.assertThat(reviewInfoResponse.totalReviewCount()) + .isEqualTo(contents1.size() + contents2.size() + contents3.size()); + soft.assertThat(reviewInfoResponse.reviews().get(0).content()) + .isEqualTo(Content.LOW_PRICE.getDescription()); + soft.assertThat(reviewInfoResponse.reviews().get(1).content()) + .isEqualTo(Content.EASY_TO_PAY.getDescription()); + soft.assertThat(reviewInfoResponse.reviews().get(2).content()) + .isEqualTo(Content.GOOD_ACCESSIBILITY.getDescription()); + } + ); + } +} diff --git a/app-api/src/test/resources/application.yml b/app-api/src/test/resources/application.yml new file mode 100644 index 00000000..dfcd4b4d --- /dev/null +++ b/app-api/src/test/resources/application.yml @@ -0,0 +1,43 @@ +spring: + flyway: + enabled: false + jpa: + hibernate: + ddl-auto: create + show-sql: true + properties: + hibernate: + format_sql: true + mail: + host: smtp.gmail.com + port: 587 + username: test@gmail.com + password: test + properties: + mail: + smtp: + auth: true + timeout: 5000 + starttls: + enable: true + data: + redis: + host: localhost + port: 6379 + datasource: + driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver + url: jdbc:tc:mysql:8://test + username: root + password: test + +kakao: + key: test + +seoul-public-parking-key: test +pusan-public-parking-key: test + +authcode: + expired-time: 60 + +cors: + allowedOrigins: http://localhost:3000 From 68682b77f7bb018bf0fe205ea6a557dd433a4d44 Mon Sep 17 00:00:00 2001 From: This2sho Date: Wed, 10 Apr 2024 23:54:56 +0900 Subject: [PATCH 04/19] =?UTF-8?q?refactor:=20scheduler=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app-scheduler/.gitignore | 42 +++++ app-scheduler/Dockerfile | 5 + app-scheduler/build.gradle | 8 + .../SchedulerApplication.java | 21 +++ .../config/ParkingApiErrorHandler.java | 20 +++ .../external/config/RestTemplateConfig.java | 36 +++++ .../coordinate/CoordinateApiService.java | 62 ++++++++ .../coordinate/CoordinateErrorHandler.java | 23 +++ .../coordinate/dto/CoordinateResponse.java | 45 ++++++ .../parkingapi/ParkingApiService.java | 13 ++ .../pusan/PusanPublicParkingAdapter.java | 110 +++++++++++++ .../pusan/PusanPublicParkingApiService.java | 63 ++++++++ .../pusan/PusanPublicParkingResponse.java | 98 ++++++++++++ .../seoul/SeoulPublicParkingAdapter.java | 144 ++++++++++++++++++ .../seoul/SeoulPublicParkingApiService.java | 72 +++++++++ .../seoul/SeoulPublicParkingResponse.java | 60 ++++++++ .../scheduler/ParkingUpdateScheduler.java | 105 +++++++++++++ .../src/main/resources/application-prod.yml | 14 ++ .../src/main/resources/application.yml | 8 + .../coordinate/CoordinateApiServiceTest.java | 46 ++++++ .../scheduler/ParkingUpdateSchedulerTest.java | 105 +++++++++++++ .../fake/ExceptionParkingApiService.java | 20 +++ .../fake/FakeCoordinateApiService.java | 16 ++ .../NotOfferCurrentParkingApiService.java | 55 +++++++ .../fake/OfferCurrentParkingApiService.java | 55 +++++++ 25 files changed, 1246 insertions(+) create mode 100644 app-scheduler/.gitignore create mode 100644 app-scheduler/Dockerfile create mode 100644 app-scheduler/build.gradle create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/SchedulerApplication.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/config/ParkingApiErrorHandler.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/config/RestTemplateConfig.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/dto/CoordinateResponse.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingResponse.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java create mode 100644 app-scheduler/src/main/resources/application-prod.yml create mode 100644 app-scheduler/src/main/resources/application.yml create mode 100644 app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java create mode 100644 app-scheduler/src/test/java/com/parkingcomestrue/external/scheduler/ParkingUpdateSchedulerTest.java create mode 100644 app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java create mode 100644 app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java create mode 100644 app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java create mode 100644 app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java diff --git a/app-scheduler/.gitignore b/app-scheduler/.gitignore new file mode 100644 index 00000000..b63da455 --- /dev/null +++ b/app-scheduler/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/app-scheduler/Dockerfile b/app-scheduler/Dockerfile new file mode 100644 index 00000000..9cb96438 --- /dev/null +++ b/app-scheduler/Dockerfile @@ -0,0 +1,5 @@ +FROM amazoncorretto:17-alpine + +COPY build/libs/app-scheduler-0.0.1-SNAPSHOT.jar app.jar + +CMD ["java", "-jar", "app.jar"] diff --git a/app-scheduler/build.gradle b/app-scheduler/build.gradle new file mode 100644 index 00000000..cdd7d6ee --- /dev/null +++ b/app-scheduler/build.gradle @@ -0,0 +1,8 @@ +dependencies { + implementation project(':domain') + + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' + + testImplementation(testFixtures(project(":domain"))) +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/SchedulerApplication.java b/app-scheduler/src/main/java/com/parkingcomestrue/SchedulerApplication.java new file mode 100644 index 00000000..dc27d71e --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/SchedulerApplication.java @@ -0,0 +1,21 @@ +package com.parkingcomestrue; + +import jakarta.annotation.PostConstruct; +import java.util.TimeZone; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableScheduling +@SpringBootApplication +public class SchedulerApplication { + + @PostConstruct + public void started() { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); + } + + public static void main(String[] args) { + SpringApplication.run(SchedulerApplication.class, args); + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/config/ParkingApiErrorHandler.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/config/ParkingApiErrorHandler.java new file mode 100644 index 00000000..51b09734 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/config/ParkingApiErrorHandler.java @@ -0,0 +1,20 @@ +package com.parkingcomestrue.external.config; + +import java.io.IOException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.web.client.ResponseErrorHandler; + +@Slf4j +public class ParkingApiErrorHandler implements ResponseErrorHandler { + + @Override + public boolean hasError(ClientHttpResponse response) throws IOException { + return response.getStatusCode().isError(); + } + + @Override + public void handleError(ClientHttpResponse response) throws IOException { + log.warn("fail while request by ParkingAPI {}", response.getStatusCode()); + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/config/RestTemplateConfig.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/config/RestTemplateConfig.java new file mode 100644 index 00000000..d9d50635 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/config/RestTemplateConfig.java @@ -0,0 +1,36 @@ +package com.parkingcomestrue.external.config; + +import com.parkingcomestrue.external.coordinate.CoordinateErrorHandler; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + + private static final String AUTH_HEADER = "Authorization"; + + @Bean + @Qualifier("coordinateRestTemplate") + public RestTemplate coordinateRestTemplate(RestTemplateBuilder restTemplateBuilder, + @Value("${kakao.key}") String kakaoUrl) { + return restTemplateBuilder + .errorHandler(new CoordinateErrorHandler()) + .defaultHeader(AUTH_HEADER, kakaoUrl) + .build(); + } + + @Bean + @Qualifier("parkingApiRestTemplate") + public RestTemplate parkingApiRestTemplate(RestTemplateBuilder restTemplateBuilder) { + return restTemplateBuilder + .errorHandler(new ParkingApiErrorHandler()) + .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) + .build(); + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java new file mode 100644 index 00000000..af6bd639 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java @@ -0,0 +1,62 @@ +package com.parkingcomestrue.external.coordinate; + +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.external.coordinate.dto.CoordinateResponse; +import com.parkingcomestrue.external.coordinate.dto.CoordinateResponse.ExactLocation; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +@Component +public class CoordinateApiService { + + private static final String KAKAO_URL = "https://dapi.kakao.com/v2/local/search/address.json"; + + private final RestTemplate restTemplate; + + @Autowired + public CoordinateApiService(@Qualifier("coordinateRestTemplate") RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public Location extractLocationByAddress(String address, Location location) { + UriComponents uriComponents = makeCompleteUri(address); + ResponseEntity result = connect(uriComponents); + + if (isEmptyResultData(result)) { + return location; + } + + ExactLocation exactLocation = getExactLocation(result); + return Location.of(exactLocation.getLongitude(), exactLocation.getLatitude()); + } + + private ExactLocation getExactLocation(ResponseEntity result) { + List exactLocations = result.getBody().getExactLocations(); + return exactLocations.get(0); + } + + private ResponseEntity connect(UriComponents uriComponents) { + return restTemplate.getForEntity( + uriComponents.toString(), + CoordinateResponse.class + ); + } + + private UriComponents makeCompleteUri(String address) { + return UriComponentsBuilder + .fromHttpUrl(KAKAO_URL) + .queryParam("query", address) + .build(); + } + + private boolean isEmptyResultData(ResponseEntity result) { + Integer matchingDataCount = result.getBody().getMeta().getTotalCount(); + return matchingDataCount == 0; + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java new file mode 100644 index 00000000..68f75477 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java @@ -0,0 +1,23 @@ +package com.parkingcomestrue.external.coordinate; + +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.io.IOException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.web.client.ResponseErrorHandler; + +@Slf4j +public class CoordinateErrorHandler implements ResponseErrorHandler { + + @Override + public boolean hasError(ClientHttpResponse response) throws IOException { + return response.getStatusCode().isError(); + } + + @Override + public void handleError(ClientHttpResponse response) throws IOException { + log.warn("fail while extracting coordinate by address code: {}", response.getStatusCode()); + throw new ClientException(ExceptionInformation.COORDINATE_EXCEPTION); + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/dto/CoordinateResponse.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/dto/CoordinateResponse.java new file mode 100644 index 00000000..b91f2831 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/dto/CoordinateResponse.java @@ -0,0 +1,45 @@ +package com.parkingcomestrue.external.coordinate.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class CoordinateResponse { + + @JsonProperty("documents") + private List exactLocations; + + @JsonProperty("meta") + private Meta meta; + + public CoordinateResponse(List exactLocations, Meta meta) { + this.exactLocations = exactLocations; + this.meta = meta; + } + + @NoArgsConstructor + @Getter + public static class ExactLocation { + + @JsonProperty("x") + private Double longitude; + + @JsonProperty("y") + private Double latitude; + } + + @Getter + @NoArgsConstructor + public static class Meta { + + @JsonProperty("total_count") + private Integer totalCount; + + public Meta(Integer totalCount) { + this.totalCount = totalCount; + } + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java new file mode 100644 index 00000000..941075c9 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java @@ -0,0 +1,13 @@ +package com.parkingcomestrue.external.parkingapi; + +import com.parkingcomestrue.parking.domain.parking.Parking; +import java.util.List; + +public interface ParkingApiService { + + default boolean offerCurrentParking() { + return false; + } + + List read() throws Exception; +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java new file mode 100644 index 00000000..eb47d32e --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java @@ -0,0 +1,110 @@ +package com.parkingcomestrue.external.parkingapi.pusan; + +import com.parkingcomestrue.parking.domain.parking.BaseInformation; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.FeePolicy; +import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.OperatingTime; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.parking.domain.parking.Space; +import com.parkingcomestrue.parking.domain.parking.TimeInfo; +import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import java.time.DateTimeException; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class PusanPublicParkingAdapter { + + private static final String EMPTY = "-"; + private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); + private static final String HOURS_24 = "24:00"; + + public List convert(PusanPublicParkingResponse response) { + return response.getGetParkingInfoDetails().getBody().getItems().getItem() + .stream().map(this::toParking) + .toList(); + } + + private Parking toParking(final PusanPublicParkingResponse.ParkingInfo.Item response) { + return new Parking( + getBaseInformation(response), + getLocation(response), + getSpace(response), + getFreeOperatingTime(response), + getOperatingTime(response), + getFeePolicy(response) + ); + } + + private BaseInformation getBaseInformation(final PusanPublicParkingResponse.ParkingInfo.Item response) { + return new BaseInformation( + response.getParkingName(), + response.getTelephoneNumber(), + filterAddress(response), + PayTypes.DEFAULT, + ParkingType.find(response.getParkingTypeNM()), + OperationType.PUBLIC + ); + } + + private String filterAddress(PusanPublicParkingResponse.ParkingInfo.Item response) { + if (response.getOldAddress().equals(EMPTY)) { + return response.getNewAddress(); + } + return response.getOldAddress(); + } + + private Location getLocation(final PusanPublicParkingResponse.ParkingInfo.Item response) { + return Location.of(response.getLongitude(), response.getLatitude()); + } + + private Space getSpace(final PusanPublicParkingResponse.ParkingInfo.Item response) { + return Space.of(response.getCapacity(), response.getCurParking()); + } + + private OperatingTime getOperatingTime(final PusanPublicParkingResponse.ParkingInfo.Item response) { + return new OperatingTime( + new TimeInfo(parsingOperationTime(response.getWeekdayBeginTime()), + parsingOperationTime(response.getWeekdayEndTime())), + new TimeInfo(parsingOperationTime(response.getWeekendBeginTime()), + parsingOperationTime(response.getWeekendEndTime())), + new TimeInfo(parsingOperationTime(response.getHolidayBeginTime()), + parsingOperationTime(response.getHolidayEndTime())) + ); + } + + private LocalTime parsingOperationTime(String time) { + if (time.equals(HOURS_24)) { + return LocalTime.MAX; + } + try { + return LocalTime.parse(time, TIME_FORMATTER); + } catch (DateTimeException e) { + return null; + } + } + + private FeePolicy getFeePolicy(final PusanPublicParkingResponse.ParkingInfo.Item response) { + return new FeePolicy( + Fee.from(response.getRates()), + Fee.from(response.getAddRates()), + TimeUnit.from(response.getTimeRate()), + TimeUnit.from(response.getAddTimeRate()), + Fee.from(response.getDayMaximum()) + ); + } + + private FreeOperatingTime getFreeOperatingTime(final PusanPublicParkingResponse.ParkingInfo.Item response) { + if (response.getRates().equals("0") && response.getAddRates().equals("0")) { + return FreeOperatingTime.ALWAYS_FREE; + } + return FreeOperatingTime.ALWAYS_PAY; + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java new file mode 100644 index 00000000..487c8672 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java @@ -0,0 +1,63 @@ +package com.parkingcomestrue.external.parkingapi.pusan; + +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.external.parkingapi.ParkingApiService; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.List; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +@Component +public class PusanPublicParkingApiService implements ParkingApiService { + + private static final String URL = "http://apis.data.go.kr/6260000/BusanPblcPrkngInfoService/getPblcPrkngInfo"; + private static final String RESULT_TYPE = "json"; + private static final int SIZE = 1000; + + @Value("${pusan-public-parking-key}") + private String API_KEY; + + private final PusanPublicParkingAdapter adapter; + private final RestTemplate restTemplate; + + public PusanPublicParkingApiService(PusanPublicParkingAdapter adapter, + @Qualifier("parkingApiRestTemplate") RestTemplate restTemplate) { + this.adapter = adapter; + this.restTemplate = restTemplate; + } + + @Override + public List read() throws Exception { + PusanPublicParkingResponse response = call(1, SIZE); + return adapter.convert(response); + } + + private PusanPublicParkingResponse call(int startIndex, int size) { + URI uri = makeUri(startIndex, size); + ResponseEntity response = restTemplate.getForEntity(uri, + PusanPublicParkingResponse.class); + return response.getBody(); + } + + private URI makeUri(int startIndex, int size) { + return UriComponentsBuilder + .fromHttpUrl(URL) + .queryParam("ServiceKey", API_KEY) + .queryParam("pageNo", startIndex) + .queryParam("numOfRows", size) + .queryParam("resultType", RESULT_TYPE) + .encode(StandardCharsets.UTF_8) + .build() + .toUri(); + } + + @Override + public boolean offerCurrentParking() { + return true; + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java new file mode 100644 index 00000000..f6294d3f --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java @@ -0,0 +1,98 @@ +package com.parkingcomestrue.external.parkingapi.pusan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import lombok.Getter; + +@Getter +public class PusanPublicParkingResponse { + + @JsonProperty("getPblcPrkngInfo") + private ParkingInfo getParkingInfoDetails; + + @Getter + public static class ParkingInfo { + private Body body; + + @Getter + public static class Body { + private Items items; + } + + @Getter + public static class Items { + private List item; + } + + @Getter + public static class Item { + + @JsonProperty("pkNam") + private String parkingName; + + @JsonProperty("pkFm") + private String parkingTypeNM; + + @JsonProperty("tponNum") + private String telephoneNumber; + + + @JsonProperty("doroAddr") + private String newAddress; + + @JsonProperty("jibunAddr") + private String oldAddress; + + @JsonProperty("xCdnt") + private String latitude; + + @JsonProperty("yCdnt") + private String longitude; + + + @JsonProperty("pkCnt") + private String capacity; + + @JsonProperty("currava") + private String curParking; + + + @JsonProperty("svcSrtTe") + private String weekdayBeginTime; + + @JsonProperty("svcEndTe") + private String weekdayEndTime; + + @JsonProperty("satSrtTe") + private String weekendBeginTime; + + @JsonProperty("satEndTe") + private String weekendEndTime; + + @JsonProperty("hldSrtTe") + private String holidayBeginTime; + + @JsonProperty("hldEndTe") + private String holidayEndTime; + + + @JsonProperty("feeInfo") + private String payNM; + + @JsonProperty("tenMin") + private String rates; + + @JsonProperty("pkBascTime") + private String timeRate; + + @JsonProperty("feeAdd") + private String addRates; + + @JsonProperty("pkAddTime") + private String addTimeRate; + + @JsonProperty("ftDay") + private String dayMaximum; + } + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java new file mode 100644 index 00000000..050f7653 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java @@ -0,0 +1,144 @@ +package com.parkingcomestrue.external.parkingapi.seoul; + +import com.parkingcomestrue.parking.domain.parking.BaseInformation; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.FeePolicy; +import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.OperatingTime; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.parking.domain.parking.Space; +import com.parkingcomestrue.parking.domain.parking.TimeInfo; +import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import java.time.DateTimeException; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; + +@Component +public class SeoulPublicParkingAdapter { + + private static final Set TIMED_PARKING_RULES = Set.of("1", "3", "5"); + private static final String STREET_PARKING_TYPE = "노상 주차장"; + private static final String FREE = "무료"; + private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmm"); + private static final String HOURS_24 = "2400"; + + public List convert(SeoulPublicParkingResponse response) { + List rows = response.getParkingInfo().getRows(); + List seoulCityParkingLots = calculateCapacity(filterByOperation(rows)); + + return seoulCityParkingLots.stream() + .map(this::toParking) + .toList(); + } + + private List filterByOperation(final List rows) { + return rows.stream() + .filter(result -> TIMED_PARKING_RULES.contains(result.getOperationRule())) + .toList(); + } + + private List calculateCapacity(final List results) { + final Map> collect = results.stream() + .collect(Collectors.groupingBy(a -> a.getParkingCode())); + + return collect.values().stream().map(parkingLots -> { + final SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking parking = parkingLots.get(0); + if (parking.getParkingTypeNM().equals(STREET_PARKING_TYPE)) { + parking.setCapacity(parkingLots.size()); + return parking; + } + return parking; + }).toList(); + } + + private Parking toParking(final SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking response) { + return new Parking( + getBaseInformation(response), + getLocation(response), + getSpace(response), + getFreeOperatingTime(response), + getOperatingTime(response), + getFeePolicy(response) + ); + } + + private BaseInformation getBaseInformation(final SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking response) { + return new BaseInformation( + response.getParkingName(), + response.getTel(), + response.getAddr(), + PayTypes.DEFAULT, + ParkingType.find(response.getParkingTypeNM()), + OperationType.PUBLIC + ); + } + + private Location getLocation(final SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking response) { + return Location.of(response.getLng(), response.getLat()); + } + + private Space getSpace(final SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking response) { + return Space.of( + response.getCapacity(), + response.getCurParking() + ); + } + + private FreeOperatingTime getFreeOperatingTime(SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking response) { + if (response.getPayNM().equals(FREE)) { + return FreeOperatingTime.ALWAYS_FREE; + } + return new FreeOperatingTime( + TimeInfo.CLOSED, + response.getSaturdayPayNM().equals(FREE) ? TimeInfo.ALL_DAY : TimeInfo.CLOSED, + response.getHolidayPayNM().equals(FREE) ? TimeInfo.ALL_DAY : TimeInfo.CLOSED + ); + } + + private OperatingTime getOperatingTime(final SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking response) { + return new OperatingTime( + new TimeInfo( + parsingOperationTime(response.getWeekdayBeginTime()), + parsingOperationTime(response.getWeekdayEndTime()) + ), + new TimeInfo( + parsingOperationTime(response.getWeekendBeginTime()), + parsingOperationTime(response.getWeekendEndTime()) + ), + new TimeInfo( + parsingOperationTime(response.getHolidayBeginTime()), + parsingOperationTime(response.getHolidayEndTime()) + ) + ); + } + + private LocalTime parsingOperationTime(String time) { + if (time.equals(HOURS_24)) { + return LocalTime.MAX; + } + try { + return LocalTime.parse(time, TIME_FORMATTER); + } catch (DateTimeException e) { + return null; + } + } + + private FeePolicy getFeePolicy(final SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking response) { + return new FeePolicy( + Fee.from(response.getRates()), + Fee.from(response.getAddRates()), + TimeUnit.from(response.getTimeRate()), + TimeUnit.from(response.getAddTimeRate()), + Fee.from(response.getDayMaximum()) + ); + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java new file mode 100644 index 00000000..4809512a --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java @@ -0,0 +1,72 @@ +package com.parkingcomestrue.external.parkingapi.seoul; + +import com.parkingcomestrue.external.parkingapi.ParkingApiService; +import com.parkingcomestrue.parking.domain.parking.Parking; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +@Component +public class SeoulPublicParkingApiService implements ParkingApiService { + + private static final String URL = "http://openapi.seoul.go.kr:8088"; + private static final String API_NAME = "GetParkingInfo"; + private static final String RESULT_TYPE = "json"; + private static final int SIZE = 1000; + + @Value("${seoul-public-parking-key}") + private String API_KEY; + + private final SeoulPublicParkingAdapter adapter; + private final RestTemplate restTemplate; + + public SeoulPublicParkingApiService(SeoulPublicParkingAdapter adapter, + @Qualifier("parkingApiRestTemplate") RestTemplate restTemplate) { + this.adapter = adapter; + this.restTemplate = restTemplate; + } + + @Override + public List read() throws Exception { + List response = call(); + return response.stream() + .map(adapter::convert) + .flatMap(Collection::stream) + .toList(); + } + + private List call() { + List result = new LinkedList<>(); + for (int i = 0; i < 2 * SIZE; i += SIZE) { + URI uri = makeUri(String.valueOf(i), String.valueOf(i + SIZE - 1)); + + ResponseEntity response = restTemplate.getForEntity(uri, + SeoulPublicParkingResponse.class); + result.add(response.getBody()); + } + return Collections.unmodifiableList(result); + } + + private URI makeUri(String startIndex, String endIndex) { + return UriComponentsBuilder + .fromHttpUrl(URL) + .pathSegment(API_KEY, RESULT_TYPE, API_NAME, startIndex, endIndex) + .encode(StandardCharsets.UTF_8) + .build() + .toUri(); + } + + @Override + public boolean offerCurrentParking() { + return true; + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingResponse.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingResponse.java new file mode 100644 index 00000000..3516e21f --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingResponse.java @@ -0,0 +1,60 @@ +package com.parkingcomestrue.external.parkingapi.seoul; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import java.util.List; +import lombok.Getter; + +@Getter +public class SeoulPublicParkingResponse { + + @JsonProperty("GetParkingInfo") + private ParkingInfo parkingInfo; + + @Getter + public static class ParkingInfo { + + @JsonProperty("row") + private List rows; + + @Getter + @JsonNaming(value = PropertyNamingStrategies.UpperSnakeCaseStrategy.class) + public static class SeoulCityParking { + + private String parkingCode; + private String parkingName; + private String parkingTypeNM; + private String operationRule; + private String tel; + + private String addr; + private String lat; + private String lng; + + private Integer queStatus; + private Integer capacity; + private Integer curParking; + + private String payNM; + private String saturdayPayNM; + private String holidayPayNM; + private Integer rates; + private Integer timeRate; + private Integer addRates; + private Integer addTimeRate; + private Integer dayMaximum; + + private String weekdayBeginTime; + private String weekdayEndTime; + private String weekendBeginTime; + private String weekendEndTime; + private String holidayBeginTime; + private String holidayEndTime; + + public void setCapacity(int capacity) { + this.capacity = capacity; + } + } + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java new file mode 100644 index 00000000..802bc6b9 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java @@ -0,0 +1,105 @@ +package com.parkingcomestrue.external.scheduler; + +import com.parkingcomestrue.external.coordinate.CoordinateApiService; +import com.parkingcomestrue.external.parkingapi.ParkingApiService; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.repository.ParkingRepository; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class ParkingUpdateScheduler { + + private final List parkingApiServices; + private final CoordinateApiService coordinateApiService; + private final ParkingRepository parkingRepository; + + @Scheduled(cron = "0 */30 * * * *") + public void autoUpdateOfferCurrentParking() { + Map parkingLots = readBy(ParkingApiService::offerCurrentParking); + Map saved = findAllByName(parkingLots.keySet()); + updateSavedParkingLots(parkingLots, saved); + saveNewParkingLots(parkingLots, saved); + } + + private Map readBy(Predicate currentParkingAvailable) { + return parkingApiServices.stream() + .filter(currentParkingAvailable) + .map(this::read) + .flatMap(Collection::stream) + .collect(toParkingMap()); + } + + private List read(ParkingApiService parkingApiService) { + try { + return parkingApiService.read(); + } catch (Exception e) { + log.warn("Error while converting {} to Parking {}", parkingApiService.getClass(), e.getMessage()); + return Collections.emptyList(); + } + } + + private Collector> toParkingMap() { + return Collectors.toMap( + parking -> parking.getBaseInformation().getName(), + Function.identity(), + (existing, replacement) -> existing + ); + } + + private Map findAllByName(Set names) { + return parkingRepository.findAllByBaseInformationNameIn(names) + .stream() + .collect(toParkingMap()); + } + + private void updateSavedParkingLots(Map parkingLots, Map saved) { + for (String parkingName : saved.keySet()) { + Parking origin = saved.get(parkingName); + Parking updated = parkingLots.get(parkingName); + origin.update(updated); + } + } + + private void saveNewParkingLots(Map parkingLots, Map saved) { + List newParkingLots = parkingLots.keySet() + .stream() + .filter(parkingName -> !saved.containsKey(parkingName)) + .map(parkingLots::get) + .toList(); + updateLocation(newParkingLots); + parkingRepository.saveAll(newParkingLots); + } + + private void updateLocation(List newParkingLots) { + for (Parking parking : newParkingLots) { + Location locationByAddress = coordinateApiService.extractLocationByAddress( + parking.getBaseInformation().getAddress(), + parking.getLocation()); + parking.update(locationByAddress); + } + } + + @Scheduled(fixedRate = 30, timeUnit = TimeUnit.DAYS) + public void autoUpdateNotOfferCurrentParking() { + Map parkingLots = readBy(parkingApiService -> !parkingApiService.offerCurrentParking()); + Map saved = findAllByName(parkingLots.keySet()); + updateSavedParkingLots(parkingLots, saved); + saveNewParkingLots(parkingLots, saved); + } +} diff --git a/app-scheduler/src/main/resources/application-prod.yml b/app-scheduler/src/main/resources/application-prod.yml new file mode 100644 index 00000000..494fa049 --- /dev/null +++ b/app-scheduler/src/main/resources/application-prod.yml @@ -0,0 +1,14 @@ +spring: + # JPA + jpa: + hibernate: + ddl-auto: validate + database: mysql + open-in-view: false + + # DB + datasource: + url: ${DB_URL} + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/app-scheduler/src/main/resources/application.yml b/app-scheduler/src/main/resources/application.yml new file mode 100644 index 00000000..ce5779e4 --- /dev/null +++ b/app-scheduler/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + profiles: + active: ${PROFILE:dev} +# API KEY +kakao: + key: ${KAKAO_API_KEY:kakao} +seoul-public-parking-key: ${SEOUL_API_KEY:seoul} +pusan-public-parking-key: ${PUSAN_API_KEY:pusan} diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java b/app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java new file mode 100644 index 00000000..9eb42929 --- /dev/null +++ b/app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java @@ -0,0 +1,46 @@ +package com.parkingcomestrue.external.coordinate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +import com.parkingcomestrue.external.coordinate.dto.CoordinateResponse; +import com.parkingcomestrue.parking.domain.parking.Location; +import java.util.Collections; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +@ExtendWith(MockitoExtension.class) +class CoordinateApiServiceTest { + + @Mock + private RestTemplate restTemplate; + + @InjectMocks + private CoordinateApiService coordinateApiService; + + @Test + void 주소_변환_요청_결과개수가_0이면_기존의_위도_경도를_반환한다() { + CoordinateResponse emptyResponse = new CoordinateResponse(Collections.emptyList(), new CoordinateResponse.Meta(0)); + + when(restTemplate.getForEntity(anyString(), any())) + .thenReturn(new ResponseEntity<>(emptyResponse, HttpStatus.OK)); + + double expectedLongitude = 67; + double expectedLatitude = 10; + + Location result = coordinateApiService.extractLocationByAddress("address", Location.of(67.0, 10.0)); + assertAll( + () -> assertThat(result.getLatitude()).isEqualTo(expectedLatitude), + () -> assertThat(result.getLongitude()).isEqualTo(expectedLongitude) + ); + } +} diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/external/scheduler/ParkingUpdateSchedulerTest.java b/app-scheduler/src/test/java/com/parkingcomestrue/external/scheduler/ParkingUpdateSchedulerTest.java new file mode 100644 index 00000000..ba9a9ff1 --- /dev/null +++ b/app-scheduler/src/test/java/com/parkingcomestrue/external/scheduler/ParkingUpdateSchedulerTest.java @@ -0,0 +1,105 @@ +package com.parkingcomestrue.external.scheduler; + + +import com.parkingcomestrue.external.coordinate.CoordinateApiService; +import com.parkingcomestrue.fake.ExceptionParkingApiService; +import com.parkingcomestrue.fake.FakeCoordinateApiService; +import com.parkingcomestrue.fake.NotOfferCurrentParkingApiService; +import com.parkingcomestrue.fake.OfferCurrentParkingApiService; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import repository.BasicParkingRepository; + +class ParkingUpdateSchedulerTest { + + private final BasicParkingRepository parkingRepository = new BasicParkingRepository(); + private final CoordinateApiService coordinateService = new FakeCoordinateApiService(); + + @DisplayName("실시간 주차 대수를 제공하는 API에서 주차장이 0~4까지 저장되어 있는 상태에서 0~9까지 주차장을 읽어와 업데이트한다.") + @Test + void autoUpdateOfferCurrentParking() { + //given + OfferCurrentParkingApiService offerCurrentParkingApiService = new OfferCurrentParkingApiService(5); + parkingRepository.saveAll(offerCurrentParkingApiService.read()); + int readSize = 10; + offerCurrentParkingApiService.setReadSize(readSize); + + ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( + List.of(offerCurrentParkingApiService), + coordinateService, + parkingRepository + ); + + //when + scheduler.autoUpdateOfferCurrentParking(); + + //then + Assertions.assertThat(parkingRepository.count()).isEqualTo(readSize); + } + + @DisplayName("실시간 주차 대수를 제공하지 않는 API에서 주차장이 0~4까지 저장되어 있는 상태에서 0~9까지 주차장을 읽어와 업데이트한다.") + @Test + void autoUpdateNotOfferCurrentParking() { + //given + NotOfferCurrentParkingApiService notOfferCurrentParkingApiService = new NotOfferCurrentParkingApiService( + 5); + parkingRepository.saveAll(notOfferCurrentParkingApiService.read()); + int readSize = 10; + notOfferCurrentParkingApiService.setReadSize(readSize); + + ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( + List.of(notOfferCurrentParkingApiService), + coordinateService, + parkingRepository + ); + + //when + scheduler.autoUpdateNotOfferCurrentParking(); + + //then + Assertions.assertThat(parkingRepository.count()).isEqualTo(readSize); + } + + @DisplayName("실시간 주차 대수를 제공하는 API와 제공하지 않는 API는 영향을 안준다.") + @Test + void notAffectBetweenOfferAndNotOfferCurrentParking() { + //given + OfferCurrentParkingApiService offerCurrentParkingApiService = new OfferCurrentParkingApiService(5); + NotOfferCurrentParkingApiService notOfferCurrentParkingApiService = new NotOfferCurrentParkingApiService( + 5); + parkingRepository.saveAll(offerCurrentParkingApiService.read()); + int readSize = 10; + notOfferCurrentParkingApiService.setReadSize(readSize); + + ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( + List.of(offerCurrentParkingApiService, notOfferCurrentParkingApiService), + coordinateService, + parkingRepository + ); + + //when + scheduler.autoUpdateOfferCurrentParking(); + + //then + Assertions.assertThat(parkingRepository.count()).isEqualTo(5); + } + + @DisplayName("특정 API에서 예외 발생시, 해당 API는 log를 남기고 무시한다.") + @Test + void autoUpdateWithExceptionApi() { + //given + ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( + List.of(new OfferCurrentParkingApiService(5), new ExceptionParkingApiService()), + coordinateService, + parkingRepository + ); + + //when + scheduler.autoUpdateOfferCurrentParking(); + + //then + Assertions.assertThat(parkingRepository.count()).isEqualTo(5); + } +} diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java new file mode 100644 index 00000000..f1fdf51f --- /dev/null +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java @@ -0,0 +1,20 @@ +package com.parkingcomestrue.fake; + +import com.parkingcomestrue.external.parkingapi.ParkingApiService; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import java.util.List; + +public class ExceptionParkingApiService implements ParkingApiService { + + @Override + public boolean offerCurrentParking() { + return true; + } + + @Override + public List read() { + throw new ClientException(ExceptionInformation.INVALID_CONNECT); + } +} diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java new file mode 100644 index 00000000..c9e4afe7 --- /dev/null +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java @@ -0,0 +1,16 @@ +package com.parkingcomestrue.fake; + +import com.parkingcomestrue.external.coordinate.CoordinateApiService; +import com.parkingcomestrue.parking.domain.parking.Location; + +public class FakeCoordinateApiService extends CoordinateApiService { + + public FakeCoordinateApiService() { + super(null); + } + + @Override + public Location extractLocationByAddress(String address, Location location) { + return Location.of(10.0, 10.0); + } +} diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java new file mode 100644 index 00000000..3abc324c --- /dev/null +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java @@ -0,0 +1,55 @@ +package com.parkingcomestrue.fake; + +import com.parkingcomestrue.external.parkingapi.ParkingApiService; +import com.parkingcomestrue.parking.domain.parking.BaseInformation; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.FeePolicy; +import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.OperatingTime; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.parking.domain.parking.Space; +import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import java.util.LinkedList; +import java.util.List; + +public class NotOfferCurrentParkingApiService implements ParkingApiService { + + private int readSize; + + public NotOfferCurrentParkingApiService(int readSize) { + this.readSize = readSize; + } + + @Override + public boolean offerCurrentParking() { + return false; + } + + @Override + public List read() { + LinkedList result = new LinkedList<>(); + for (int i = 0; i < readSize; i++) { + Parking parking = new Parking( + new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, PayTypes.DEFAULT, + ParkingType.NO_INFO, + OperationType.PUBLIC), + Location.of("33.333" + i, "44.444" + i), + Space.of(-1, -1), + FreeOperatingTime.ALWAYS_FREE, + OperatingTime.ALWAYS_OPEN, + new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(0), TimeUnit.from(0), Fee.ZERO) + ); + result.add(parking); + } + + return result; + } + + public void setReadSize(int readSize) { + this.readSize = readSize; + } +} diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java new file mode 100644 index 00000000..61ea2cc4 --- /dev/null +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java @@ -0,0 +1,55 @@ +package com.parkingcomestrue.fake; + +import com.parkingcomestrue.external.parkingapi.ParkingApiService; +import com.parkingcomestrue.parking.domain.parking.BaseInformation; +import com.parkingcomestrue.parking.domain.parking.Fee; +import com.parkingcomestrue.parking.domain.parking.FeePolicy; +import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.parking.domain.parking.OperatingTime; +import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.parking.domain.parking.Space; +import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import java.util.LinkedList; +import java.util.List; + +public class OfferCurrentParkingApiService implements ParkingApiService { + + private int readSize; + + public OfferCurrentParkingApiService(int readSize) { + this.readSize = readSize; + } + + @Override + public boolean offerCurrentParking() { + return true; + } + + @Override + public List read() { + LinkedList result = new LinkedList<>(); + for (int i = 0; i < readSize; i++) { + Parking parking = new Parking( + new BaseInformation("offer parking" + i, "02-000" + i, "서울시 어딘가 " + i, PayTypes.DEFAULT, + ParkingType.NO_INFO, + OperationType.PUBLIC), + Location.of("11.111" + i, "22.222" + i), + Space.of(100, 10), + FreeOperatingTime.ALWAYS_FREE, + OperatingTime.ALWAYS_OPEN, + new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(0), TimeUnit.from(0), Fee.ZERO) + ); + result.add(parking); + } + + return result; + } + + public void setReadSize(int readSize) { + this.readSize = readSize; + } +} From 65dbd3fd73800330bd0c3166e78f8628923072bf Mon Sep 17 00:00:00 2001 From: This2sho Date: Wed, 10 Apr 2024 23:56:56 +0900 Subject: [PATCH 05/19] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 5 - .../example/parking/ParkingApplication.java | 23 - .../api/favorite/FavoriteController.java | 40 -- .../parking/api/member/MemberController.java | 57 --- .../api/parking/ParkingController.java | 47 --- .../parking/api/review/ReviewController.java | 32 -- .../SearchConditionController.java | 38 -- .../application/SearchConditionMapper.java | 39 -- .../application/favorite/FavoriteService.java | 43 -- .../favorite/dto/FavoriteCreateRequest.java | 15 - .../favorite/dto/FavoriteDeleteRequest.java | 15 - .../application/member/MemberService.java | 80 ---- .../member/dto/MemberInfoResponse.java | 18 - .../member/dto/MemberLoginRequest.java | 17 - .../member/dto/MemberSignupRequest.java | 21 - .../member/dto/PasswordChangeRequest.java | 17 - .../parking/ParkingFilteringService.java | 37 -- .../application/parking/ParkingService.java | 186 --------- .../dto/ParkingDetailInfoResponse.java | 97 ----- .../parking/dto/ParkingLotsResponse.java | 44 -- .../parking/dto/ParkingQueryRequest.java | 17 - .../dto/ParkingSearchConditionRequest.java | 25 -- .../application/review/ReviewService.java | 47 --- .../review/dto/ReviewCountResponse.java | 5 - .../review/dto/ReviewCreateRequest.java | 13 - .../review/dto/ReviewInfoResponse.java | 7 - .../SearchConditionService.java | 71 ---- .../dto/SearchConditionDto.java | 25 -- .../com/example/parking/auth/AuthService.java | 101 ----- .../auth/authcode/AuthCodeCategory.java | 24 -- .../auth/authcode/AuthCodePlatform.java | 25 -- .../authcode/InValidAuthCodeException.java | 11 - .../auth/authcode/api/AuthCodeController.java | 35 -- .../application/AuthCodeEventListener.java | 44 -- .../application/AuthCodeValidator.java | 23 - .../application/MailPlatformValidator.java | 17 - .../application/PlatformValidator.java | 6 - .../dto/AuthCodeCertificateRequest.java | 23 - .../application/dto/AuthCodeRequest.java | 19 - .../application/dto/AuthCodeResponse.java | 13 - .../authcode/event/AuthCodeCreateEvent.java | 19 - .../infrastructure/AuthCodeSender.java | 6 - .../infrastructure/MailAuthCodeSender.java | 23 - .../authcode/util/AuthCodeKeyConverter.java | 16 - .../parking/auth/session/MemberSession.java | 31 -- .../auth/session/MemberSessionRepository.java | 10 - .../parking/config/ApiRestTemplateConfig.java | 22 - .../config/ParkingApiErrorHandler.java | 20 - .../parking/config/RestTemplateConfig.java | 25 -- .../example/parking/config/SwaggerConfig.java | 32 -- .../example/parking/config/WebMvcConfig.java | 65 --- .../AuthArgumentResolver.java | 38 -- .../config/argumentresolver/MemberAuth.java | 13 - .../parking/ParkingQuery.java | 11 - .../parking/ParkingQueryArgumentResolver.java | 28 -- .../parking/ParkingSearchCondition.java | 11 - ...arkingSearchConditionArgumentResolver.java | 78 ---- .../config/interceptor/AuthInterceptor.java | 29 -- .../parking/domain/AuditingEntity.java | 21 - .../parking/domain/favorite/Favorite.java | 48 --- .../domain/favorite/FavoriteRepository.java | 16 - .../example/parking/domain/member/Member.java | 70 ---- .../parking/domain/member/MemberId.java | 17 - .../domain/member/MemberRepository.java | 21 - .../parking/domain/member/Password.java | 38 -- .../domain/parking/BaseInformation.java | 54 --- .../example/parking/domain/parking/Day.java | 20 - .../parking/domain/parking/DayParking.java | 31 -- .../example/parking/domain/parking/Fee.java | 58 --- .../parking/domain/parking/FeePolicy.java | 81 ---- .../domain/parking/FreeOperatingTime.java | 74 ---- .../parking/domain/parking/Location.java | 68 --- .../parking/domain/parking/OperatingTime.java | 66 --- .../parking/domain/parking/OperationType.java | 23 - .../parking/domain/parking/Parking.java | 155 ------- .../domain/parking/ParkingFeeCalculator.java | 71 ---- .../parking/domain/parking/ParkingType.java | 31 -- .../parking/domain/parking/PayType.java | 25 -- .../parking/domain/parking/PayTypes.java | 46 -- .../domain/parking/SearchingCondition.java | 25 -- .../example/parking/domain/parking/Space.java | 44 -- .../parking/domain/parking/TimeInfo.java | 62 --- .../parking/domain/parking/TimeUnit.java | 50 --- .../parking/dto/ParkingQueryCondition.java | 23 - .../parking/repository/ParkingRepository.java | 45 -- .../parking/domain/review/Content.java | 34 -- .../example/parking/domain/review/Review.java | 61 --- .../domain/review/ReviewRepository.java | 26 -- .../review/service/ReviewDomainService.java | 43 -- .../domain/searchcondition/FeeType.java | 20 - .../parking/domain/searchcondition/Hours.java | 27 -- .../domain/searchcondition/Priority.java | 22 - .../searchcondition/SearchCondition.java | 78 ---- .../SearchConditionAvailable.java | 8 - .../SearchConditionRepository.java | 18 - .../parking/external/config/RedisConfig.java | 35 -- .../coordinate/CoordinateErrorHandler.java | 23 - .../coordinate/CoordinateService.java | 62 --- .../coordinate/dto/CoordinateResponse.java | 45 -- .../parkingapi/ParkingApiService.java | 13 - .../pusan/PusanPublicParkingAdapter.java | 112 ----- .../pusan/PusanPublicParkingApiService.java | 63 --- .../pusan/PusanPublicParkingResponse.java | 98 ----- .../seoul/SeoulPublicParkingAdapter.java | 145 ------- .../seoul/SeoulPublicParkingApiService.java | 72 ---- .../seoul/SeoulPublicParkingResponse.java | 60 --- .../scheduler/ParkingUpdateScheduler.java | 104 ----- .../infra/converter/ContentConverter.java | 12 - .../infra/converter/EnumListConverter.java | 32 -- .../infra/converter/FeeTypeConverter.java | 12 - .../converter/OperationTypeConverter.java | 12 - .../infra/converter/ParkingTypeConverter.java | 12 - .../infra/converter/PayTypeConverter.java | 12 - .../example/parking/support/Association.java | 26 -- .../GlobalExceptionHandler.java | 55 --- .../dto/ExceptionResponse.java | 5 - .../support/exception/ClientException.java | 19 - .../support/exception/DomainException.java | 16 - .../exception/ExceptionInformation.java | 34 -- .../util/authcode/AuthCodeGenerator.java | 6 - .../authcode/NumberAuthCodeGenerator.java | 20 - .../util/cipher/EncryptionException.java | 8 - .../example/parking/util/cipher/SHA256.java | 28 -- src/main/resources/application-dev.yml | 11 - src/main/resources/application-prod.yml | 22 - src/main/resources/application.yml | 35 -- .../mysql/V1.0.0__initial_schema.sql | 88 ---- .../mysql/V2.0.0__add_point_parking_table.sql | 2 - .../V3.0.0__drop_column_parking_table.sql | 3 - .../V4.0.0__drop_column_member_table.sql | 2 - .../parking/ParkingApplicationTests.java | 13 - .../application/CoordinateServiceTest.java | 48 --- .../application/member/MemberServiceTest.java | 89 ---- .../parking/ParkingFilteringServiceTest.java | 163 -------- .../parking/ParkingServiceTest.java | 90 ---- .../application/review/ReviewServiceTest.java | 98 ----- .../example/parking/auth/AuthServiceTest.java | 148 ------- .../auth/MemberSessionRepositoryTest.java | 46 -- .../example/parking/config/TestConfig.java | 21 - .../parking/container/ContainerTest.java | 73 ---- .../parking/container/MySQLDataCleaner.java | 34 -- .../parking/container/RedisDataCleaner.java | 18 - .../favorite/FavoriteRepositoryTest.java | 49 --- .../parking/domain/member/MemberTest.java | 64 --- .../domain/parking/BaseInformationTest.java | 15 - .../parking/domain/parking/DayTest.java | 53 --- .../parking/domain/parking/FeePolicyTest.java | 86 ---- .../parking/domain/parking/FeeTest.java | 35 -- .../domain/parking/FreeOperatingTimeTest.java | 195 --------- .../parking/domain/parking/LocationTest.java | 38 -- .../parking/ParkingFeeCalculatorTest.java | 395 ------------------ .../parking/domain/parking/ParkingTest.java | 188 --------- .../parking/domain/parking/PayTypesTest.java | 65 --- .../parking/domain/parking/TimeInfoTest.java | 165 -------- .../parking/domain/parking/TimeUnitTest.java | 36 -- .../parking/domain/review/ContentTest.java | 41 -- .../service/ReviewDomainServiceTest.java | 87 ---- .../EnumListConverterTest.java | 30 -- .../domain/searchcondition/HoursTest.java | 25 -- .../SearchConditionMapperTest.java | 104 ----- .../scheduler/ParkingUpdateSchedulerTest.java | 107 ----- .../parking/fake/BasicMemberRepository.java | 58 --- .../parking/fake/BasicParkingRepository.java | 88 ---- .../example/parking/fake/BasicRepository.java | 16 - .../parking/fake/BasicReviewRepository.java | 42 -- .../fake/ExceptionParkingApiService.java | 20 - .../parking/fake/FakeCoordinateService.java | 16 - .../parking/fake/FakeFavoriteRepository.java | 26 -- .../parking/fake/FakeParkingService.java | 31 -- .../parking/fake/FakeReviewService.java | 12 - .../fake/FakeSearchConditionRepository.java | 17 - .../NotOfferCurrentParkingApiService.java | 55 --- .../fake/OfferCurrentParkingApiService.java | 55 --- src/test/resources/application.yml | 43 -- 174 files changed, 7921 deletions(-) delete mode 100644 Dockerfile delete mode 100644 src/main/java/com/example/parking/ParkingApplication.java delete mode 100644 src/main/java/com/example/parking/api/favorite/FavoriteController.java delete mode 100644 src/main/java/com/example/parking/api/member/MemberController.java delete mode 100644 src/main/java/com/example/parking/api/parking/ParkingController.java delete mode 100644 src/main/java/com/example/parking/api/review/ReviewController.java delete mode 100644 src/main/java/com/example/parking/api/searchcondition/SearchConditionController.java delete mode 100644 src/main/java/com/example/parking/application/SearchConditionMapper.java delete mode 100644 src/main/java/com/example/parking/application/favorite/FavoriteService.java delete mode 100644 src/main/java/com/example/parking/application/favorite/dto/FavoriteCreateRequest.java delete mode 100644 src/main/java/com/example/parking/application/favorite/dto/FavoriteDeleteRequest.java delete mode 100644 src/main/java/com/example/parking/application/member/MemberService.java delete mode 100644 src/main/java/com/example/parking/application/member/dto/MemberInfoResponse.java delete mode 100644 src/main/java/com/example/parking/application/member/dto/MemberLoginRequest.java delete mode 100644 src/main/java/com/example/parking/application/member/dto/MemberSignupRequest.java delete mode 100644 src/main/java/com/example/parking/application/member/dto/PasswordChangeRequest.java delete mode 100644 src/main/java/com/example/parking/application/parking/ParkingFilteringService.java delete mode 100644 src/main/java/com/example/parking/application/parking/ParkingService.java delete mode 100644 src/main/java/com/example/parking/application/parking/dto/ParkingDetailInfoResponse.java delete mode 100644 src/main/java/com/example/parking/application/parking/dto/ParkingLotsResponse.java delete mode 100644 src/main/java/com/example/parking/application/parking/dto/ParkingQueryRequest.java delete mode 100644 src/main/java/com/example/parking/application/parking/dto/ParkingSearchConditionRequest.java delete mode 100644 src/main/java/com/example/parking/application/review/ReviewService.java delete mode 100644 src/main/java/com/example/parking/application/review/dto/ReviewCountResponse.java delete mode 100644 src/main/java/com/example/parking/application/review/dto/ReviewCreateRequest.java delete mode 100644 src/main/java/com/example/parking/application/review/dto/ReviewInfoResponse.java delete mode 100644 src/main/java/com/example/parking/application/searchcondition/SearchConditionService.java delete mode 100644 src/main/java/com/example/parking/application/searchcondition/dto/SearchConditionDto.java delete mode 100644 src/main/java/com/example/parking/auth/AuthService.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/AuthCodeCategory.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/AuthCodePlatform.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/InValidAuthCodeException.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/api/AuthCodeController.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/application/AuthCodeEventListener.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/application/AuthCodeValidator.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/application/MailPlatformValidator.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/application/PlatformValidator.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeCertificateRequest.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeRequest.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeResponse.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/event/AuthCodeCreateEvent.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/infrastructure/AuthCodeSender.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/infrastructure/MailAuthCodeSender.java delete mode 100644 src/main/java/com/example/parking/auth/authcode/util/AuthCodeKeyConverter.java delete mode 100644 src/main/java/com/example/parking/auth/session/MemberSession.java delete mode 100644 src/main/java/com/example/parking/auth/session/MemberSessionRepository.java delete mode 100644 src/main/java/com/example/parking/config/ApiRestTemplateConfig.java delete mode 100644 src/main/java/com/example/parking/config/ParkingApiErrorHandler.java delete mode 100644 src/main/java/com/example/parking/config/RestTemplateConfig.java delete mode 100644 src/main/java/com/example/parking/config/SwaggerConfig.java delete mode 100644 src/main/java/com/example/parking/config/WebMvcConfig.java delete mode 100644 src/main/java/com/example/parking/config/argumentresolver/AuthArgumentResolver.java delete mode 100644 src/main/java/com/example/parking/config/argumentresolver/MemberAuth.java delete mode 100644 src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQuery.java delete mode 100644 src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java delete mode 100644 src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchCondition.java delete mode 100644 src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java delete mode 100644 src/main/java/com/example/parking/config/interceptor/AuthInterceptor.java delete mode 100644 src/main/java/com/example/parking/domain/AuditingEntity.java delete mode 100644 src/main/java/com/example/parking/domain/favorite/Favorite.java delete mode 100644 src/main/java/com/example/parking/domain/favorite/FavoriteRepository.java delete mode 100644 src/main/java/com/example/parking/domain/member/Member.java delete mode 100644 src/main/java/com/example/parking/domain/member/MemberId.java delete mode 100644 src/main/java/com/example/parking/domain/member/MemberRepository.java delete mode 100644 src/main/java/com/example/parking/domain/member/Password.java delete mode 100644 src/main/java/com/example/parking/domain/parking/BaseInformation.java delete mode 100644 src/main/java/com/example/parking/domain/parking/Day.java delete mode 100644 src/main/java/com/example/parking/domain/parking/DayParking.java delete mode 100644 src/main/java/com/example/parking/domain/parking/Fee.java delete mode 100644 src/main/java/com/example/parking/domain/parking/FeePolicy.java delete mode 100644 src/main/java/com/example/parking/domain/parking/FreeOperatingTime.java delete mode 100644 src/main/java/com/example/parking/domain/parking/Location.java delete mode 100644 src/main/java/com/example/parking/domain/parking/OperatingTime.java delete mode 100644 src/main/java/com/example/parking/domain/parking/OperationType.java delete mode 100644 src/main/java/com/example/parking/domain/parking/Parking.java delete mode 100644 src/main/java/com/example/parking/domain/parking/ParkingFeeCalculator.java delete mode 100644 src/main/java/com/example/parking/domain/parking/ParkingType.java delete mode 100644 src/main/java/com/example/parking/domain/parking/PayType.java delete mode 100644 src/main/java/com/example/parking/domain/parking/PayTypes.java delete mode 100644 src/main/java/com/example/parking/domain/parking/SearchingCondition.java delete mode 100644 src/main/java/com/example/parking/domain/parking/Space.java delete mode 100644 src/main/java/com/example/parking/domain/parking/TimeInfo.java delete mode 100644 src/main/java/com/example/parking/domain/parking/TimeUnit.java delete mode 100644 src/main/java/com/example/parking/domain/parking/dto/ParkingQueryCondition.java delete mode 100644 src/main/java/com/example/parking/domain/parking/repository/ParkingRepository.java delete mode 100644 src/main/java/com/example/parking/domain/review/Content.java delete mode 100644 src/main/java/com/example/parking/domain/review/Review.java delete mode 100644 src/main/java/com/example/parking/domain/review/ReviewRepository.java delete mode 100644 src/main/java/com/example/parking/domain/review/service/ReviewDomainService.java delete mode 100644 src/main/java/com/example/parking/domain/searchcondition/FeeType.java delete mode 100644 src/main/java/com/example/parking/domain/searchcondition/Hours.java delete mode 100644 src/main/java/com/example/parking/domain/searchcondition/Priority.java delete mode 100644 src/main/java/com/example/parking/domain/searchcondition/SearchCondition.java delete mode 100644 src/main/java/com/example/parking/domain/searchcondition/SearchConditionAvailable.java delete mode 100644 src/main/java/com/example/parking/domain/searchcondition/SearchConditionRepository.java delete mode 100644 src/main/java/com/example/parking/external/config/RedisConfig.java delete mode 100644 src/main/java/com/example/parking/external/coordinate/CoordinateErrorHandler.java delete mode 100644 src/main/java/com/example/parking/external/coordinate/CoordinateService.java delete mode 100644 src/main/java/com/example/parking/external/coordinate/dto/CoordinateResponse.java delete mode 100644 src/main/java/com/example/parking/external/parkingapi/ParkingApiService.java delete mode 100644 src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingAdapter.java delete mode 100644 src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingApiService.java delete mode 100644 src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingResponse.java delete mode 100644 src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingAdapter.java delete mode 100644 src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingApiService.java delete mode 100644 src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingResponse.java delete mode 100644 src/main/java/com/example/parking/external/scheduler/ParkingUpdateScheduler.java delete mode 100644 src/main/java/com/example/parking/infra/converter/ContentConverter.java delete mode 100644 src/main/java/com/example/parking/infra/converter/EnumListConverter.java delete mode 100644 src/main/java/com/example/parking/infra/converter/FeeTypeConverter.java delete mode 100644 src/main/java/com/example/parking/infra/converter/OperationTypeConverter.java delete mode 100644 src/main/java/com/example/parking/infra/converter/ParkingTypeConverter.java delete mode 100644 src/main/java/com/example/parking/infra/converter/PayTypeConverter.java delete mode 100644 src/main/java/com/example/parking/support/Association.java delete mode 100644 src/main/java/com/example/parking/support/controlleradvice/GlobalExceptionHandler.java delete mode 100644 src/main/java/com/example/parking/support/controlleradvice/dto/ExceptionResponse.java delete mode 100644 src/main/java/com/example/parking/support/exception/ClientException.java delete mode 100644 src/main/java/com/example/parking/support/exception/DomainException.java delete mode 100644 src/main/java/com/example/parking/support/exception/ExceptionInformation.java delete mode 100644 src/main/java/com/example/parking/util/authcode/AuthCodeGenerator.java delete mode 100644 src/main/java/com/example/parking/util/authcode/NumberAuthCodeGenerator.java delete mode 100644 src/main/java/com/example/parking/util/cipher/EncryptionException.java delete mode 100644 src/main/java/com/example/parking/util/cipher/SHA256.java delete mode 100644 src/main/resources/application-dev.yml delete mode 100644 src/main/resources/application-prod.yml delete mode 100644 src/main/resources/application.yml delete mode 100644 src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql delete mode 100644 src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql delete mode 100644 src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql delete mode 100644 src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql delete mode 100644 src/test/java/com/example/parking/ParkingApplicationTests.java delete mode 100644 src/test/java/com/example/parking/application/CoordinateServiceTest.java delete mode 100644 src/test/java/com/example/parking/application/member/MemberServiceTest.java delete mode 100644 src/test/java/com/example/parking/application/parking/ParkingFilteringServiceTest.java delete mode 100644 src/test/java/com/example/parking/application/parking/ParkingServiceTest.java delete mode 100644 src/test/java/com/example/parking/application/review/ReviewServiceTest.java delete mode 100644 src/test/java/com/example/parking/auth/AuthServiceTest.java delete mode 100644 src/test/java/com/example/parking/auth/MemberSessionRepositoryTest.java delete mode 100644 src/test/java/com/example/parking/config/TestConfig.java delete mode 100644 src/test/java/com/example/parking/container/ContainerTest.java delete mode 100644 src/test/java/com/example/parking/container/MySQLDataCleaner.java delete mode 100644 src/test/java/com/example/parking/container/RedisDataCleaner.java delete mode 100644 src/test/java/com/example/parking/domain/favorite/FavoriteRepositoryTest.java delete mode 100644 src/test/java/com/example/parking/domain/member/MemberTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/BaseInformationTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/DayTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/FeePolicyTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/FeeTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/FreeOperatingTimeTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/LocationTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/ParkingFeeCalculatorTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/ParkingTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/PayTypesTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/TimeInfoTest.java delete mode 100644 src/test/java/com/example/parking/domain/parking/TimeUnitTest.java delete mode 100644 src/test/java/com/example/parking/domain/review/ContentTest.java delete mode 100644 src/test/java/com/example/parking/domain/review/service/ReviewDomainServiceTest.java delete mode 100644 src/test/java/com/example/parking/domain/searchcondition/EnumListConverterTest.java delete mode 100644 src/test/java/com/example/parking/domain/searchcondition/HoursTest.java delete mode 100644 src/test/java/com/example/parking/domain/searchcondition/SearchConditionMapperTest.java delete mode 100644 src/test/java/com/example/parking/external/scheduler/ParkingUpdateSchedulerTest.java delete mode 100644 src/test/java/com/example/parking/fake/BasicMemberRepository.java delete mode 100644 src/test/java/com/example/parking/fake/BasicParkingRepository.java delete mode 100644 src/test/java/com/example/parking/fake/BasicRepository.java delete mode 100644 src/test/java/com/example/parking/fake/BasicReviewRepository.java delete mode 100644 src/test/java/com/example/parking/fake/ExceptionParkingApiService.java delete mode 100644 src/test/java/com/example/parking/fake/FakeCoordinateService.java delete mode 100644 src/test/java/com/example/parking/fake/FakeFavoriteRepository.java delete mode 100644 src/test/java/com/example/parking/fake/FakeParkingService.java delete mode 100644 src/test/java/com/example/parking/fake/FakeReviewService.java delete mode 100644 src/test/java/com/example/parking/fake/FakeSearchConditionRepository.java delete mode 100644 src/test/java/com/example/parking/fake/NotOfferCurrentParkingApiService.java delete mode 100644 src/test/java/com/example/parking/fake/OfferCurrentParkingApiService.java delete mode 100644 src/test/resources/application.yml diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index de65fcf8..00000000 --- a/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM amazoncorretto:17-alpine - -COPY build/libs/parking-0.0.1-SNAPSHOT.jar app.jar - -CMD ["java", "-jar", "app.jar"] diff --git a/src/main/java/com/example/parking/ParkingApplication.java b/src/main/java/com/example/parking/ParkingApplication.java deleted file mode 100644 index 7e894bec..00000000 --- a/src/main/java/com/example/parking/ParkingApplication.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.parking; - -import jakarta.annotation.PostConstruct; -import java.util.TimeZone; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.scheduling.annotation.EnableScheduling; - -@EnableJpaAuditing -@EnableScheduling -@SpringBootApplication -public class ParkingApplication { - - @PostConstruct - public void started() { - TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); - } - - public static void main(String[] args) { - SpringApplication.run(ParkingApplication.class, args); - } -} diff --git a/src/main/java/com/example/parking/api/favorite/FavoriteController.java b/src/main/java/com/example/parking/api/favorite/FavoriteController.java deleted file mode 100644 index 9566cee1..00000000 --- a/src/main/java/com/example/parking/api/favorite/FavoriteController.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.example.parking.api.favorite; - -import com.example.parking.application.favorite.FavoriteService; -import com.example.parking.application.favorite.dto.FavoriteCreateRequest; -import com.example.parking.application.favorite.dto.FavoriteDeleteRequest; -import com.example.parking.config.argumentresolver.MemberAuth; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -@Tag(name = "즐겨찾기 컨트롤러") -@RequiredArgsConstructor -@RestController -public class FavoriteController { - - private final FavoriteService favoriteService; - - @Operation(summary = "즐겨찾기 등록", description = "즐겨찾기 등록") - @PostMapping("/favorites") - public ResponseEntity create(@RequestBody FavoriteCreateRequest favoriteCreateRequest, - @Parameter(hidden = true) @MemberAuth Long memberId) { - favoriteService.createFavorite(favoriteCreateRequest, memberId); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } - - @Operation(summary = "즐겨찾기 해제", description = "즐겨찾기 해제") - @DeleteMapping("/favorites") - public ResponseEntity delete(@RequestBody FavoriteDeleteRequest favoriteDeleteRequest, - @Parameter(hidden = true) @MemberAuth Long memberId) { - favoriteService.deleteFavorite(favoriteDeleteRequest, memberId); - return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); - } -} diff --git a/src/main/java/com/example/parking/api/member/MemberController.java b/src/main/java/com/example/parking/api/member/MemberController.java deleted file mode 100644 index 463a64ea..00000000 --- a/src/main/java/com/example/parking/api/member/MemberController.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.example.parking.api.member; - -import com.example.parking.application.member.MemberService; -import com.example.parking.application.member.dto.MemberLoginRequest; -import com.example.parking.application.member.dto.MemberSignupRequest; -import com.example.parking.application.member.dto.PasswordChangeRequest; -import com.example.parking.auth.AuthService; -import com.example.parking.config.argumentresolver.MemberAuth; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.servlet.http.Cookie; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -@Tag(name = "멤버 컨트롤러") -@RequiredArgsConstructor -@RestController -public class MemberController { - - private static final String JSESSIONID = "JSESSIONID"; - - private final MemberService memberService; - private final AuthService authService; - - @Operation(summary = "회원가입", description = "회원가입") - @PostMapping("/signup") - public ResponseEntity signup(@RequestBody MemberSignupRequest request) { - memberService.signup(request); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } - - @Operation(summary = "로그인", description = "로그인") - @PostMapping("/signin") - public ResponseEntity signIn(HttpServletResponse httpServletResponse, - @RequestBody MemberLoginRequest request) { - Long memberId = memberService.login(request); - String sessionId = authService.createSession(memberId); - httpServletResponse.addCookie(new Cookie(JSESSIONID, sessionId)); - - return ResponseEntity.status(HttpStatus.OK).build(); - } - - @Operation(summary = "비밀번호 변경", description = "비밀번호 변경") - @PatchMapping("/member/password") - public ResponseEntity changePassword(@Parameter(hidden = true) @MemberAuth Long memberId, - @RequestBody PasswordChangeRequest request) { - memberService.changePassword(memberId, request); - return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); - } -} diff --git a/src/main/java/com/example/parking/api/parking/ParkingController.java b/src/main/java/com/example/parking/api/parking/ParkingController.java deleted file mode 100644 index 00bfe8f4..00000000 --- a/src/main/java/com/example/parking/api/parking/ParkingController.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.example.parking.api.parking; - -import com.example.parking.application.parking.ParkingService; -import com.example.parking.application.parking.dto.ParkingDetailInfoResponse; -import com.example.parking.application.parking.dto.ParkingLotsResponse; -import com.example.parking.application.parking.dto.ParkingQueryRequest; -import com.example.parking.application.parking.dto.ParkingSearchConditionRequest; -import com.example.parking.config.argumentresolver.MemberAuth; -import com.example.parking.config.argumentresolver.parking.ParkingQuery; -import com.example.parking.config.argumentresolver.parking.ParkingSearchCondition; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; - -@Tag(name = "주차장 컨트롤러") -@RequiredArgsConstructor -@RestController -public class ParkingController { - - private final ParkingService parkingService; - - @Operation(summary = "주차장 상세조회", description = "주차장 상세조회") - @GetMapping("/parkings/{parkingId}") - public ResponseEntity findParking(@PathVariable Long parkingId) { - ParkingDetailInfoResponse parkingDetailInfoResponse = parkingService.findParking(parkingId); - return ResponseEntity.status(HttpStatus.OK).body(parkingDetailInfoResponse); - - } - - @Operation(summary = "주차장 반경 조회", description = "주차장 반경 조회") - @GetMapping("/parkings") - public ResponseEntity find( - @ParkingQuery ParkingQueryRequest parkingQueryRequest, - @ParkingSearchCondition ParkingSearchConditionRequest parkingSearchConditionRequest, - @Parameter(hidden = true) @MemberAuth(nullable = true) Long parkingMemberId - ) { - ParkingLotsResponse parkingLots = parkingService.findParkingLots(parkingQueryRequest, - parkingSearchConditionRequest, parkingMemberId); - return ResponseEntity.ok(parkingLots); - } -} diff --git a/src/main/java/com/example/parking/api/review/ReviewController.java b/src/main/java/com/example/parking/api/review/ReviewController.java deleted file mode 100644 index 5c6edb33..00000000 --- a/src/main/java/com/example/parking/api/review/ReviewController.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.parking.api.review; - -import com.example.parking.application.review.ReviewService; -import com.example.parking.application.review.dto.ReviewCreateRequest; -import com.example.parking.config.argumentresolver.MemberAuth; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RestController; - -@Tag(name = "리뷰 컨트롤러") -@RequiredArgsConstructor -@RestController -public class ReviewController { - - private final ReviewService reviewService; - - @Operation(summary = "리뷰 등록", description = "리뷰 등록") - @PostMapping("/parkings/{parkingId}/reviews") - public ResponseEntity createReview(@PathVariable Long parkingId, - @Parameter(hidden = true) @MemberAuth Long memberId, - @ModelAttribute ReviewCreateRequest request) { - Long reviewId = reviewService.createReview(parkingId, memberId, request); - return ResponseEntity.status(HttpStatus.CREATED).body(reviewId); - } -} diff --git a/src/main/java/com/example/parking/api/searchcondition/SearchConditionController.java b/src/main/java/com/example/parking/api/searchcondition/SearchConditionController.java deleted file mode 100644 index 37ed11b7..00000000 --- a/src/main/java/com/example/parking/api/searchcondition/SearchConditionController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example.parking.api.searchcondition; - -import com.example.parking.application.searchcondition.SearchConditionService; -import com.example.parking.application.searchcondition.dto.SearchConditionDto; -import com.example.parking.config.argumentresolver.MemberAuth; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RestController; - -@Tag(name = "조회 조건 컨트롤러") -@RestController -public class SearchConditionController { - - private final SearchConditionService searchConditionService; - - public SearchConditionController(SearchConditionService searchConditionService) { - this.searchConditionService = searchConditionService; - } - - @Operation(summary = "조회 조건 조회", description = "조회 조건 조회") - @GetMapping("/search-condition") - public ResponseEntity loadSearchCondition(@Parameter(hidden = true) @MemberAuth Long memberId) { - return ResponseEntity.ok(searchConditionService.findSearchCondition(memberId)); - } - - @Operation(summary = "조회 조건 수정", description = "조회 조건 수정") - @PutMapping("/search-condition") - public ResponseEntity updateSearchCondition(@Parameter(hidden = true) @MemberAuth Long memberId, - SearchConditionDto request) { - searchConditionService.updateSearchCondition(memberId, request); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } -} diff --git a/src/main/java/com/example/parking/application/SearchConditionMapper.java b/src/main/java/com/example/parking/application/SearchConditionMapper.java deleted file mode 100644 index 82c700d5..00000000 --- a/src/main/java/com/example/parking/application/SearchConditionMapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.example.parking.application; - -import com.example.parking.domain.searchcondition.SearchConditionAvailable; -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.Arrays; -import java.util.List; -import org.springframework.stereotype.Component; - -@Component -public class SearchConditionMapper { - - public & SearchConditionAvailable> List toEnums(Class searchConditionAvailableClass, - List descriptions) { - return descriptions.stream() - .map(description -> toEnum(searchConditionAvailableClass, description)) - .toList(); - } - - public & SearchConditionAvailable> E toEnum(Class searchConditionAvailableClass, - String description) { - E[] conditions = searchConditionAvailableClass.getEnumConstants(); - - return Arrays.stream(conditions) - .filter(condition -> description.startsWith(condition.getDescription())) - .findAny() - .orElseThrow(() -> new ClientException(ExceptionInformation.INVALID_DESCRIPTION)); - } - - public & SearchConditionAvailable> List getValues( - Class searchConditionAvailableClass) { - E[] conditions = searchConditionAvailableClass.getEnumConstants(); - - return Arrays.stream(conditions) - .filter(condition -> condition != condition.getDefault()) - .map(SearchConditionAvailable::getDescription) - .toList(); - } -} diff --git a/src/main/java/com/example/parking/application/favorite/FavoriteService.java b/src/main/java/com/example/parking/application/favorite/FavoriteService.java deleted file mode 100644 index 5dff0b87..00000000 --- a/src/main/java/com/example/parking/application/favorite/FavoriteService.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.parking.application.favorite; - -import com.example.parking.application.favorite.dto.FavoriteCreateRequest; -import com.example.parking.application.favorite.dto.FavoriteDeleteRequest; -import com.example.parking.domain.favorite.Favorite; -import com.example.parking.domain.favorite.FavoriteRepository; -import com.example.parking.support.Association; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Slf4j -@RequiredArgsConstructor -@Transactional -@Service -public class FavoriteService { - - private final FavoriteRepository favoriteRepository; - - public void createFavorite(FavoriteCreateRequest favoriteCreateRequest, Long memberId) { - Long parkingId = favoriteCreateRequest.getParkingId(); - - Favorite favorite = new Favorite(Association.from(memberId), Association.from(parkingId)); - saveFavorite(favorite); - } - - private void saveFavorite(Favorite favorite) { - try { - favoriteRepository.save(favorite); - } catch (DataIntegrityViolationException e) { - log.warn("memberId: {}, parkingId: {} request duplicate favorite create", favorite.getMemberId(), - favorite.getParkingId()); - } - } - - public void deleteFavorite(FavoriteDeleteRequest favoriteDeleteRequest, Long memberId) { - Long parkingId = favoriteDeleteRequest.getParkingId(); - - favoriteRepository.deleteByMemberIdAndParkingId(Association.from(memberId), Association.from(parkingId)); - } -} diff --git a/src/main/java/com/example/parking/application/favorite/dto/FavoriteCreateRequest.java b/src/main/java/com/example/parking/application/favorite/dto/FavoriteCreateRequest.java deleted file mode 100644 index 11d349c0..00000000 --- a/src/main/java/com/example/parking/application/favorite/dto/FavoriteCreateRequest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.parking.application.favorite.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class FavoriteCreateRequest { - - private Long parkingId; - - public FavoriteCreateRequest(Long parkingId) { - this.parkingId = parkingId; - } -} diff --git a/src/main/java/com/example/parking/application/favorite/dto/FavoriteDeleteRequest.java b/src/main/java/com/example/parking/application/favorite/dto/FavoriteDeleteRequest.java deleted file mode 100644 index c76fadcc..00000000 --- a/src/main/java/com/example/parking/application/favorite/dto/FavoriteDeleteRequest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.parking.application.favorite.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class FavoriteDeleteRequest { - - private Long parkingId; - - public FavoriteDeleteRequest(Long parkingId) { - this.parkingId = parkingId; - } -} diff --git a/src/main/java/com/example/parking/application/member/MemberService.java b/src/main/java/com/example/parking/application/member/MemberService.java deleted file mode 100644 index d87dfa2e..00000000 --- a/src/main/java/com/example/parking/application/member/MemberService.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.example.parking.application.member; - -import com.example.parking.application.member.dto.MemberInfoResponse; -import com.example.parking.application.member.dto.MemberLoginRequest; -import com.example.parking.application.member.dto.MemberSignupRequest; -import com.example.parking.application.member.dto.PasswordChangeRequest; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.member.MemberRepository; -import com.example.parking.domain.member.Password; -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.ExceptionInformation; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class MemberService { - - private final MemberRepository memberRepository; - - public MemberService(MemberRepository memberRepository) { - this.memberRepository = memberRepository; - } - - @Transactional - public Long signup(MemberSignupRequest dto) { - Member member = new Member( - dto.getEmail(), - dto.getNickname(), - new Password(dto.getPassword())); - - validateDuplicatedEmail(member); - memberRepository.save(member); - return member.getId(); - } - - private void validateDuplicatedEmail(Member member) { - if (memberRepository.existsByEmail(member.getEmail())) { - throw new ClientException(ExceptionInformation.DUPLICATE_MAIL); - } - } - - @Transactional(readOnly = true) - public Long login(MemberLoginRequest dto) { - Member member = findMemberByEmail(dto.getEmail()); - validatePassword(member, dto.getPassword()); - return member.getId(); - } - - private Member findMemberByEmail(String email) { - return memberRepository.findByEmail(email) - .orElseThrow(() -> new ClientException(ExceptionInformation.INVALID_EMAIL)); - } - - private void validatePassword(Member member, String password) { - if (!member.checkPassword(password)) { - throw new ClientException(ExceptionInformation.INVALID_PASSWORD); - } - } - - @Transactional - public void deleteMember(Long memberId) { - Member member = memberRepository.getById(memberId); - member.delete(); - } - - @Transactional(readOnly = true) - public MemberInfoResponse findMemberInfo(Long memberId) { - Member member = memberRepository.getById(memberId); - - return new MemberInfoResponse(member.getNickname(), member.getEmail()); - } - - @Transactional - public void changePassword(Long memberId, PasswordChangeRequest dto) { - Member member = memberRepository.getById(memberId); - String previousPassword = dto.getPreviousPassword(); - String newPassword = dto.getNewPassword(); - member.changePassword(previousPassword, newPassword); - } -} diff --git a/src/main/java/com/example/parking/application/member/dto/MemberInfoResponse.java b/src/main/java/com/example/parking/application/member/dto/MemberInfoResponse.java deleted file mode 100644 index b6734fcc..00000000 --- a/src/main/java/com/example/parking/application/member/dto/MemberInfoResponse.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.parking.application.member.dto; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class MemberInfoResponse { - - private String name; - private String email; - - public MemberInfoResponse(String name, String email) { - this.name = name; - this.email = email; - } -} diff --git a/src/main/java/com/example/parking/application/member/dto/MemberLoginRequest.java b/src/main/java/com/example/parking/application/member/dto/MemberLoginRequest.java deleted file mode 100644 index b94367f4..00000000 --- a/src/main/java/com/example/parking/application/member/dto/MemberLoginRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.parking.application.member.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class MemberLoginRequest { - - private String email; - private String password; - - public MemberLoginRequest(String email, String password) { - this.email = email; - this.password = password; - } -} diff --git a/src/main/java/com/example/parking/application/member/dto/MemberSignupRequest.java b/src/main/java/com/example/parking/application/member/dto/MemberSignupRequest.java deleted file mode 100644 index f7276320..00000000 --- a/src/main/java/com/example/parking/application/member/dto/MemberSignupRequest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.example.parking.application.member.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class MemberSignupRequest { - - private String name; - private String email; - private String password; - private String nickname; - - public MemberSignupRequest(String name, String email, String password, String nickname) { - this.name = name; - this.email = email; - this.password = password; - this.nickname = nickname; - } -} diff --git a/src/main/java/com/example/parking/application/member/dto/PasswordChangeRequest.java b/src/main/java/com/example/parking/application/member/dto/PasswordChangeRequest.java deleted file mode 100644 index 9d04c1ec..00000000 --- a/src/main/java/com/example/parking/application/member/dto/PasswordChangeRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.parking.application.member.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class PasswordChangeRequest { - - private String previousPassword; - private String newPassword; - - public PasswordChangeRequest(String previousPassword, String newPassword) { - this.previousPassword = previousPassword; - this.newPassword = newPassword; - } -} diff --git a/src/main/java/com/example/parking/application/parking/ParkingFilteringService.java b/src/main/java/com/example/parking/application/parking/ParkingFilteringService.java deleted file mode 100644 index a4dae272..00000000 --- a/src/main/java/com/example/parking/application/parking/ParkingFilteringService.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.example.parking.application.parking; - -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingFeeCalculator; -import com.example.parking.domain.parking.SearchingCondition; -import com.example.parking.domain.searchcondition.FeeType; -import java.time.LocalDateTime; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - -@RequiredArgsConstructor -@Component -public class ParkingFilteringService { - - private final ParkingFeeCalculator parkingFeeCalculator; - - public List filterByCondition(List parkingLots, SearchingCondition searchingCondition, - LocalDateTime now) { - return parkingLots.stream() - .filter(parking -> checkFeeTypeIsPaid(searchingCondition) || checkFeeTypeAndFeeFree(searchingCondition, - now, parking)) - .filter(parking -> parking.containsOperationType(searchingCondition.getOperationTypes())) - .filter(parking -> parking.containsParkingType(searchingCondition.getParkingTypes())) - .filter(parking -> parking.containsPayType(searchingCondition.getPayTypes())) - .toList(); - } - - private boolean checkFeeTypeIsPaid(SearchingCondition searchingCondition) { - return searchingCondition.getFeeType() == FeeType.PAID; - } - - private boolean checkFeeTypeAndFeeFree(SearchingCondition searchingCondition, LocalDateTime now, Parking parking) { - return searchingCondition.getFeeType() == FeeType.FREE && parkingFeeCalculator.calculateParkingFee(parking, now, - now.plusHours(searchingCondition.getHours())).isFree(); - } -} diff --git a/src/main/java/com/example/parking/application/parking/ParkingService.java b/src/main/java/com/example/parking/application/parking/ParkingService.java deleted file mode 100644 index d0dffef5..00000000 --- a/src/main/java/com/example/parking/application/parking/ParkingService.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.example.parking.application.parking; - -import com.example.parking.application.SearchConditionMapper; -import com.example.parking.application.parking.dto.ParkingDetailInfoResponse; -import com.example.parking.application.parking.dto.ParkingDetailInfoResponse.FeeInfo; -import com.example.parking.application.parking.dto.ParkingDetailInfoResponse.HolidayOperatingTime; -import com.example.parking.application.parking.dto.ParkingDetailInfoResponse.SaturdayOperatingTime; -import com.example.parking.application.parking.dto.ParkingDetailInfoResponse.WeekdayOperatingTime; -import com.example.parking.application.parking.dto.ParkingLotsResponse; -import com.example.parking.application.parking.dto.ParkingLotsResponse.ParkingResponse; -import com.example.parking.application.parking.dto.ParkingQueryRequest; -import com.example.parking.application.parking.dto.ParkingSearchConditionRequest; -import com.example.parking.application.review.ReviewService; -import com.example.parking.application.review.dto.ReviewInfoResponse; -import com.example.parking.domain.favorite.Favorite; -import com.example.parking.domain.favorite.FavoriteRepository; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingFeeCalculator; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayType; -import com.example.parking.domain.parking.SearchingCondition; -import com.example.parking.domain.parking.repository.ParkingRepository; -import com.example.parking.domain.searchcondition.FeeType; -import com.example.parking.support.Association; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@RequiredArgsConstructor -@Service -public class ParkingService { - - private static final String DISTANCE_ORDER_CONDITION = "가까운 순"; - - private final ParkingRepository parkingRepository; - private final ParkingFilteringService parkingFilteringService; - private final FavoriteRepository favoriteRepository; - private final SearchConditionMapper searchConditionMapper; - private final ParkingFeeCalculator parkingFeeCalculator; - private final ReviewService reviewService; - - @Transactional(readOnly = true) - public ParkingLotsResponse findParkingLots(ParkingQueryRequest parkingQueryRequest, - ParkingSearchConditionRequest parkingSearchConditionRequest, - Long memberId) { - LocalDateTime now = LocalDateTime.now(); - Location destination = Location.of(parkingQueryRequest.getLongitude(), parkingQueryRequest.getLatitude()); - - // 반경 주차장 조회 - List favorites = findMemberFavorites(memberId); - List parkingLots = findParkingLotsByOrderCondition(parkingSearchConditionRequest.getPriority(), - parkingQueryRequest, destination); - - // 조회조건 기반 필터링 - SearchingCondition searchingCondition = toSearchingCondition(parkingSearchConditionRequest); - List filteredParkingLots = parkingFilteringService.filterByCondition(parkingLots, searchingCondition, - now); - - // 응답 dto 변환 - List parkingResponses = collectParkingInfo(filteredParkingLots, - parkingSearchConditionRequest.getHours(), destination, favorites, now); - - return new ParkingLotsResponse(parkingResponses); - } - - private List findMemberFavorites(Long memberId) { - if (memberId == null) { - return Collections.emptyList(); - } - return favoriteRepository.findByMemberId(Association.from(memberId)); - } - - private List findParkingLotsByOrderCondition(String priority, ParkingQueryRequest parkingQueryRequest, - Location middleLocation) { - if (priority.equals(DISTANCE_ORDER_CONDITION)) { - return parkingRepository.findAroundParkingLotsOrderByDistance(middleLocation.getPoint(), - parkingQueryRequest.getRadius()); - } - return parkingRepository.findAroundParkingLots(middleLocation.getPoint(), parkingQueryRequest.getRadius()); - } - - private SearchingCondition toSearchingCondition(ParkingSearchConditionRequest request) { - List parkingTypes = searchConditionMapper.toEnums(ParkingType.class, request.getParkingTypes()); - List operationTypes = searchConditionMapper.toEnums(OperationType.class, - request.getOperationTypes()); - List payTypes = searchConditionMapper.toEnums(PayType.class, request.getPayTypes()); - FeeType feeType = searchConditionMapper.toEnum(FeeType.class, request.getFeeType()); - - return new SearchingCondition(operationTypes, parkingTypes, payTypes, feeType, request.getHours()); - } - - private List collectParkingInfo(List parkingLots, int hours, - Location destination, List memberFavorites, - LocalDateTime now) { - Set favoriteParkingIds = extractFavoriteParkingIds(memberFavorites); - return calculateParkingInfo(parkingLots, destination, hours, favoriteParkingIds, now); - } - - private List calculateParkingInfo(List parkingLots, Location destination, int hours, - Set favoriteParkingIds, LocalDateTime now) { - return parkingLots.stream() - .map(parking -> toParkingResponse( - parking, - parkingFeeCalculator.calculateParkingFee(parking, now, now.plusHours(hours)), - parking.calculateWalkingTime(destination), - favoriteParkingIds.contains(parking.getId()) - ) - ).toList(); - } - - private Set extractFavoriteParkingIds(List memberFavorites) { - return memberFavorites.stream() - .map(Favorite::getParkingId) - .map(Association::getId) - .collect(Collectors.toSet()); - } - - private ParkingResponse toParkingResponse(Parking parking, Fee fee, int walkingTime, boolean isFavorite) { - return new ParkingResponse( - parking.getId(), - parking.getBaseInformation().getName(), - fee.getFee(), - walkingTime, - parking.getBaseInformation().getParkingType().getDescription(), - isFavorite, - parking.getLocation().getLatitude(), - parking.getLocation().getLongitude() - ); - } - - @Transactional - public void saveAll(List parkingLots) { - parkingRepository.saveAll(parkingLots); - } - - @Transactional(readOnly = true) - public Set getParkingLots(Set parkingNames) { - return parkingRepository.findAllByBaseInformationNameIn(parkingNames); - } - - @Transactional(readOnly = true) - public ParkingDetailInfoResponse findParking(Long parkingId) { - LocalDateTime now = LocalDateTime.now(); - Parking parking = parkingRepository.getById(parkingId); - ReviewInfoResponse reviews = reviewService.readReviews(parkingId); - int diffMinute = parking.calculateUpdatedDiff(now); - - return toParkingResponse(reviews, parking, diffMinute); - } - - private ParkingDetailInfoResponse toParkingResponse(ReviewInfoResponse reviews, Parking parking, int diffMinute) { - return new ParkingDetailInfoResponse( - parking.getBaseInformation().getName(), - parking.getBaseInformation().getParkingType().getDescription(), - parking.getLocation().getLatitude(), - parking.getLocation().getLongitude(), - new FeeInfo( - parking.getFeePolicy().getBaseFee().getFee(), - parking.getFeePolicy().getBaseTimeUnit().getTimeUnit() - ), - parking.getSpace().getCurrentParking(), - parking.getSpace().getCapacity(), - diffMinute, - parking.getBaseInformation().getTel(), - parking.getBaseInformation().getPayTypes().getDescription(), - new WeekdayOperatingTime( - parking.getOperatingTime().getWeekdayBeginTime(), - parking.getOperatingTime().getWeekdayEndTime()), - new SaturdayOperatingTime( - parking.getOperatingTime().getSaturdayBeginTime(), - parking.getOperatingTime().getSaturdayEndTime()), - new HolidayOperatingTime( - parking.getOperatingTime().getHolidayBeginTime(), - parking.getOperatingTime().getHolidayEndTime()), - reviews - ); - } -} diff --git a/src/main/java/com/example/parking/application/parking/dto/ParkingDetailInfoResponse.java b/src/main/java/com/example/parking/application/parking/dto/ParkingDetailInfoResponse.java deleted file mode 100644 index 7f46f805..00000000 --- a/src/main/java/com/example/parking/application/parking/dto/ParkingDetailInfoResponse.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.example.parking.application.parking.dto; - -import com.example.parking.application.review.dto.ReviewInfoResponse; -import java.time.LocalTime; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ParkingDetailInfoResponse { - - private String parkingName; - private String parkingType; - private Double latitude; - private Double longitude; - private FeeInfo feeInfo; - private Integer currentParkingCount; - private Integer capacity; - private Integer lastUpdated; - private String tel; - private String paymentType; - private WeekdayOperatingTime weekdayOperatingTime; - private SaturdayOperatingTime saturdayOperatingTime; - private HolidayOperatingTime holidayOperatingTime; - private ReviewInfoResponse reviewInfo; - - public ParkingDetailInfoResponse(String parkingName, String parkingType, Double latitude, Double longitude, - FeeInfo feeInfo, - Integer currentParkingCount, Integer capacity, Integer lastUpdated, String tel, - String paymentType, WeekdayOperatingTime weekdayOperatingTime, - SaturdayOperatingTime saturdayOperatingTime, - HolidayOperatingTime holidayOperatingTime, ReviewInfoResponse reviewInfo) { - this.parkingName = parkingName; - this.parkingType = parkingType; - this.latitude = latitude; - this.longitude = longitude; - this.feeInfo = feeInfo; - this.currentParkingCount = currentParkingCount; - this.capacity = capacity; - this.lastUpdated = lastUpdated; - this.tel = tel; - this.paymentType = paymentType; - this.weekdayOperatingTime = weekdayOperatingTime; - this.saturdayOperatingTime = saturdayOperatingTime; - this.holidayOperatingTime = holidayOperatingTime; - this.reviewInfo = reviewInfo; - } - - @Getter - @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class FeeInfo { - private Integer fee; - private Integer time; - - public FeeInfo(Integer fee, Integer time) { - this.fee = fee; - this.time = time; - } - } - - @Getter - @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class WeekdayOperatingTime { - private LocalTime beginTime; - private LocalTime endTime; - - public WeekdayOperatingTime(LocalTime beginTime, LocalTime endTime) { - this.beginTime = beginTime; - this.endTime = endTime; - } - } - - @Getter - @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class SaturdayOperatingTime { - private LocalTime beginTime; - private LocalTime endTime; - - public SaturdayOperatingTime(LocalTime beginTime, LocalTime endTime) { - this.beginTime = beginTime; - this.endTime = endTime; - } - } - - @Getter - @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class HolidayOperatingTime { - private LocalTime beginTime; - private LocalTime endTime; - - public HolidayOperatingTime(LocalTime beginTime, LocalTime endTime) { - this.beginTime = beginTime; - this.endTime = endTime; - } - } -} diff --git a/src/main/java/com/example/parking/application/parking/dto/ParkingLotsResponse.java b/src/main/java/com/example/parking/application/parking/dto/ParkingLotsResponse.java deleted file mode 100644 index aa4f05cd..00000000 --- a/src/main/java/com/example/parking/application/parking/dto/ParkingLotsResponse.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.example.parking.application.parking.dto; - -import java.util.List; -import lombok.Getter; - -@Getter -public class ParkingLotsResponse { - - private List parkingLots; - - private ParkingLotsResponse() { - } - - public ParkingLotsResponse(List parkingLots) { - this.parkingLots = parkingLots; - } - - @Getter - public static class ParkingResponse { - private Long parkingId; - private String parkingName; - private Integer estimatedFee; - private Integer estimatedWalkingTime; - private String parkingType; - private Boolean isFavorite; - private Double latitude; - private Double longitude; - - private ParkingResponse() { - } - - public ParkingResponse(Long parkingId, String parkingName, Integer estimatedFee, Integer estimatedWalkingTime, - String parkingType, Boolean isFavorite, Double latitude, Double longitude) { - this.parkingId = parkingId; - this.parkingName = parkingName; - this.estimatedFee = estimatedFee; - this.estimatedWalkingTime = estimatedWalkingTime; - this.parkingType = parkingType; - this.isFavorite = isFavorite; - this.latitude = latitude; - this.longitude = longitude; - } - } -} diff --git a/src/main/java/com/example/parking/application/parking/dto/ParkingQueryRequest.java b/src/main/java/com/example/parking/application/parking/dto/ParkingQueryRequest.java deleted file mode 100644 index e0590f4d..00000000 --- a/src/main/java/com/example/parking/application/parking/dto/ParkingQueryRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.parking.application.parking.dto; - -import lombok.Getter; - -@Getter -public class ParkingQueryRequest { - - private final Double longitude; - private final Double latitude; - private final Integer radius; - - public ParkingQueryRequest(Double longitude, Double latitude, Integer radius) { - this.longitude = longitude; - this.latitude = latitude; - this.radius = radius; - } -} diff --git a/src/main/java/com/example/parking/application/parking/dto/ParkingSearchConditionRequest.java b/src/main/java/com/example/parking/application/parking/dto/ParkingSearchConditionRequest.java deleted file mode 100644 index 8ff8ccb3..00000000 --- a/src/main/java/com/example/parking/application/parking/dto/ParkingSearchConditionRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.parking.application.parking.dto; - -import java.util.List; -import lombok.Getter; - -@Getter -public class ParkingSearchConditionRequest { - - private final List operationTypes; - private final List parkingTypes; - private final String feeType; - private final List payTypes; - private final Integer hours; - private final String priority; - - public ParkingSearchConditionRequest(List operationTypes, List parkingTypes, String feeType, - List payTypes, int hours, String priority) { - this.operationTypes = operationTypes; - this.parkingTypes = parkingTypes; - this.feeType = feeType; - this.payTypes = payTypes; - this.hours = hours; - this.priority = priority; - } -} diff --git a/src/main/java/com/example/parking/application/review/ReviewService.java b/src/main/java/com/example/parking/application/review/ReviewService.java deleted file mode 100644 index 5e965f25..00000000 --- a/src/main/java/com/example/parking/application/review/ReviewService.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.example.parking.application.review; - -import com.example.parking.application.review.dto.ReviewCountResponse; -import com.example.parking.application.review.dto.ReviewCreateRequest; -import com.example.parking.application.review.dto.ReviewInfoResponse; -import com.example.parking.support.Association; -import com.example.parking.domain.review.Content; -import com.example.parking.domain.review.Review; -import com.example.parking.domain.review.ReviewRepository; -import com.example.parking.domain.review.service.ReviewDomainService; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@RequiredArgsConstructor -@Transactional(readOnly = true) -@Service -public class ReviewService { - - private final ReviewRepository reviewRepository; - private final ReviewDomainService reviewDomainService; - - @Transactional - public Long createReview(Long parkingId, Long reviewerId, ReviewCreateRequest request) { - reviewDomainService.validateDuplicateReview(Association.from(parkingId), Association.from(reviewerId)); - - Review review = new Review(Association.from(parkingId), Association.from(reviewerId), request.toContents()); - reviewRepository.save(review); - return review.getId(); - } - - public ReviewInfoResponse readReviews(Long parkingId) { - List reviews = reviewRepository.findAllByParkingId(Association.from(parkingId)); - Map counts = reviewDomainService.collectByContent(reviews); - return new ReviewInfoResponse(reviewDomainService.calculateTotalReviews(counts), orderByCounts(counts)); - } - - private List orderByCounts(Map counts) { - return counts.keySet().stream() - .map(content -> new ReviewCountResponse(content.getDescription(), counts.get(content).intValue())) - .sorted(Comparator.comparing(ReviewCountResponse::count).reversed()) - .toList(); - } -} diff --git a/src/main/java/com/example/parking/application/review/dto/ReviewCountResponse.java b/src/main/java/com/example/parking/application/review/dto/ReviewCountResponse.java deleted file mode 100644 index 19acd3b3..00000000 --- a/src/main/java/com/example/parking/application/review/dto/ReviewCountResponse.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.parking.application.review.dto; - -public record ReviewCountResponse(String content, int count) { - -} diff --git a/src/main/java/com/example/parking/application/review/dto/ReviewCreateRequest.java b/src/main/java/com/example/parking/application/review/dto/ReviewCreateRequest.java deleted file mode 100644 index 689a22f9..00000000 --- a/src/main/java/com/example/parking/application/review/dto/ReviewCreateRequest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.parking.application.review.dto; - -import com.example.parking.domain.review.Content; -import java.util.List; - -public record ReviewCreateRequest(List contents) { - - public List toContents() { - return contents.stream() - .map(Content::find) - .toList(); - } -} diff --git a/src/main/java/com/example/parking/application/review/dto/ReviewInfoResponse.java b/src/main/java/com/example/parking/application/review/dto/ReviewInfoResponse.java deleted file mode 100644 index fe4ed110..00000000 --- a/src/main/java/com/example/parking/application/review/dto/ReviewInfoResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.parking.application.review.dto; - -import java.util.List; - -public record ReviewInfoResponse(int totalReviewCount, List reviews) { - -} diff --git a/src/main/java/com/example/parking/application/searchcondition/SearchConditionService.java b/src/main/java/com/example/parking/application/searchcondition/SearchConditionService.java deleted file mode 100644 index 5649eb99..00000000 --- a/src/main/java/com/example/parking/application/searchcondition/SearchConditionService.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.example.parking.application.searchcondition; - -import com.example.parking.application.SearchConditionMapper; -import com.example.parking.application.searchcondition.dto.SearchConditionDto; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayType; -import com.example.parking.domain.searchcondition.FeeType; -import com.example.parking.domain.searchcondition.Hours; -import com.example.parking.domain.searchcondition.Priority; -import com.example.parking.domain.searchcondition.SearchCondition; -import com.example.parking.domain.searchcondition.SearchConditionAvailable; -import com.example.parking.domain.searchcondition.SearchConditionRepository; -import com.example.parking.support.Association; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@RequiredArgsConstructor -@Transactional(readOnly = true) -@Service -public class SearchConditionService { - - private final SearchConditionRepository searchConditionRepository; - private final SearchConditionMapper searchConditionMapper; - - public SearchConditionDto findSearchCondition(Long memberId) { - SearchCondition searchCondition = searchConditionRepository.getByMemberId(memberId); - return toSearchConditionDto(searchCondition); - } - - private SearchConditionDto toSearchConditionDto(SearchCondition searchCondition) { - return new SearchConditionDto( - toDescriptions(searchCondition.getOperationTypes()), - toDescriptions(searchCondition.getParkingTypes()), - toDescriptions(searchCondition.getFeeTypes()), - toDescriptions(searchCondition.getPayTypes()), - searchCondition.getPriority().getDescription(), - searchCondition.getHours().getHours() - ); - } - - private List toDescriptions(List enums) { - return enums.stream() - .map(SearchConditionAvailable::getDescription) - .toList(); - } - - @Transactional - public void updateSearchCondition(Long memberId, SearchConditionDto searchConditionDto) { - SearchCondition newSearchCondition = createSearchCondition(memberId, searchConditionDto); - - searchConditionRepository.findByMemberId(memberId).ifPresentOrElse( - existingSearchCondition -> existingSearchCondition.update(newSearchCondition), - () -> searchConditionRepository.save(newSearchCondition) - ); - } - - private SearchCondition createSearchCondition(Long memberId, SearchConditionDto searchConditionDto) { - return new SearchCondition( - Association.from(memberId), - searchConditionMapper.toEnums(OperationType.class, searchConditionDto.getOperationType()), - searchConditionMapper.toEnums(ParkingType.class, searchConditionDto.getParkingType()), - searchConditionMapper.toEnums(FeeType.class, searchConditionDto.getFeeType()), - searchConditionMapper.toEnums(PayType.class, searchConditionDto.getPayType()), - searchConditionMapper.toEnum(Priority.class, searchConditionDto.getPriority()), - Hours.from(searchConditionDto.getHours()) - ); - } -} diff --git a/src/main/java/com/example/parking/application/searchcondition/dto/SearchConditionDto.java b/src/main/java/com/example/parking/application/searchcondition/dto/SearchConditionDto.java deleted file mode 100644 index 6cda8ad8..00000000 --- a/src/main/java/com/example/parking/application/searchcondition/dto/SearchConditionDto.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.parking.application.searchcondition.dto; - -import java.util.List; -import lombok.Getter; - -@Getter -public class SearchConditionDto { - - private List operationType; - private List parkingType; - private List feeType; - private List payType; - private String priority; - private Integer hours; - - public SearchConditionDto(List operationType, List parkingType, List feeType, - List payType, String priority, Integer hours) { - this.operationType = operationType; - this.parkingType = parkingType; - this.feeType = feeType; - this.payType = payType; - this.priority = priority; - this.hours = hours; - } -} diff --git a/src/main/java/com/example/parking/auth/AuthService.java b/src/main/java/com/example/parking/auth/AuthService.java deleted file mode 100644 index 4c487c65..00000000 --- a/src/main/java/com/example/parking/auth/AuthService.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.example.parking.auth; - -import com.example.parking.auth.authcode.AuthCodeCategory; -import com.example.parking.auth.authcode.AuthCodePlatform; -import com.example.parking.auth.authcode.application.AuthCodeValidator; -import com.example.parking.auth.authcode.application.dto.AuthCodeCertificateRequest; -import com.example.parking.auth.authcode.application.dto.AuthCodeRequest; -import com.example.parking.auth.authcode.event.AuthCodeCreateEvent; -import com.example.parking.auth.authcode.util.AuthCodeKeyConverter; -import com.example.parking.auth.session.MemberSession; -import com.example.parking.auth.session.MemberSessionRepository; -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.ExceptionInformation; -import com.example.parking.util.authcode.AuthCodeGenerator; -import java.time.LocalDateTime; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import lombok.RequiredArgsConstructor; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@RequiredArgsConstructor -@Service -public class AuthService { - - private static final Long DURATION_MINUTE = 30L; - - private final MemberSessionRepository memberSessionRepository; - private final AuthCodeGenerator authCodeGenerator; - private final AuthCodeValidator authCodeValidator; - private final ApplicationEventPublisher applicationEventPublisher; - private final RedisTemplate redisTemplate; - - @Transactional - public String createSession(Long memberId) { - LocalDateTime current = LocalDateTime.now(); - String uuid = UUID.randomUUID().toString(); - - MemberSession memberSession = new MemberSession(uuid, memberId, current, current.plusMinutes(DURATION_MINUTE)); - memberSessionRepository.save(memberSession); - return memberSession.getSessionId(); - } - - @Transactional(readOnly = true) - public MemberSession findSession(String sessionId) { - return memberSessionRepository.findBySessionIdAndExpiredAtIsGreaterThanEqual(sessionId, - LocalDateTime.now()) - .orElseThrow(() -> new ClientException(ExceptionInformation.UNAUTHORIZED)); - } - - @Transactional - public void updateSessionExpiredAt(MemberSession session) { - session.updateExpiredAt(LocalDateTime.now().plusMinutes(DURATION_MINUTE)); - memberSessionRepository.save(session); - } - - @Transactional - public String createAuthCode(AuthCodeRequest authCodeRequest) { - String destination = authCodeRequest.getDestination(); - AuthCodePlatform authCodePlatform = AuthCodePlatform.find(authCodeRequest.getAuthPlatform()); - AuthCodeCategory authCodeCategory = AuthCodeCategory.find(authCodeRequest.getAuthCodeCategory()); - - authCodeValidator.validate(authCodePlatform, destination); - String randomAuthCode = authCodeGenerator.generateAuthCode(); - String authCodeKey = AuthCodeKeyConverter.convert(randomAuthCode, destination, authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName()); - redisTemplate.opsForValue().set(authCodeKey, randomAuthCode, 300L, TimeUnit.SECONDS); - - publishAuthCodeCreateEvent(destination, authCodePlatform, authCodeCategory, randomAuthCode); - return randomAuthCode; - } - - private void publishAuthCodeCreateEvent(String destination, AuthCodePlatform authCodePlatform, - AuthCodeCategory authCodeCategory, String randomAuthCode) { - applicationEventPublisher.publishEvent( - new AuthCodeCreateEvent( - destination, - randomAuthCode, - authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName() - ) - ); - } - - @Transactional - public void certificateAuthCode(AuthCodeCertificateRequest authCodeCertificateRequest) { - String authCode = authCodeCertificateRequest.getAuthCode(); - String destination = authCodeCertificateRequest.getDestination(); - AuthCodePlatform authCodePlatform = AuthCodePlatform.find(authCodeCertificateRequest.getAuthCodePlatform()); - AuthCodeCategory authCodeCategory = AuthCodeCategory.find(authCodeCertificateRequest.getAuthCodeCategory()); - - String authCodeKey = AuthCodeKeyConverter.convert(authCode, destination, authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName()); - String findResult = redisTemplate.opsForValue().getAndDelete(authCodeKey); - if (findResult == null) { - throw new ClientException(ExceptionInformation.INVALID_AUTH_CODE); - } - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/AuthCodeCategory.java b/src/main/java/com/example/parking/auth/authcode/AuthCodeCategory.java deleted file mode 100644 index d3e2efc8..00000000 --- a/src/main/java/com/example/parking/auth/authcode/AuthCodeCategory.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.example.parking.auth.authcode; - -import java.util.Arrays; -import lombok.Getter; - -@Getter -public enum AuthCodeCategory { - - SIGN_UP("signUp"), - FIND_PASSWORD("findPassword"); - - private final String categoryName; - - AuthCodeCategory(String categoryName) { - this.categoryName = categoryName; - } - - public static AuthCodeCategory find(String authCodeCategory) { - return Arrays.stream(AuthCodeCategory.values()) - .filter(category -> category.categoryName.equals(authCodeCategory)) - .findAny() - .orElseThrow(() -> new InValidAuthCodeException("존재하지 않는 인증 코드 발급 행위입니다.")); - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/AuthCodePlatform.java b/src/main/java/com/example/parking/auth/authcode/AuthCodePlatform.java deleted file mode 100644 index 823685b8..00000000 --- a/src/main/java/com/example/parking/auth/authcode/AuthCodePlatform.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.parking.auth.authcode; - -import java.util.Arrays; - -public enum AuthCodePlatform { - - MAIL("mail"); - - private final String platform; - - AuthCodePlatform(String platform) { - this.platform = platform; - } - - public static AuthCodePlatform find(String authType) { - return Arrays.stream(AuthCodePlatform.values()) - .filter(authCodeType -> authCodeType.platform.equals(authType)) - .findAny() - .orElseThrow(() -> new InValidAuthCodeException("존재하지 않는 인증 코드 전송 플랫폼입니다.")); - } - - public String getPlatform() { - return platform; - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/InValidAuthCodeException.java b/src/main/java/com/example/parking/auth/authcode/InValidAuthCodeException.java deleted file mode 100644 index 72f5a2e7..00000000 --- a/src/main/java/com/example/parking/auth/authcode/InValidAuthCodeException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.parking.auth.authcode; - -public class InValidAuthCodeException extends RuntimeException { - - private final String message; - - public InValidAuthCodeException(String message) { - super(message); - this.message = message; - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/api/AuthCodeController.java b/src/main/java/com/example/parking/auth/authcode/api/AuthCodeController.java deleted file mode 100644 index f106a7c9..00000000 --- a/src/main/java/com/example/parking/auth/authcode/api/AuthCodeController.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.example.parking.auth.authcode.api; - -import com.example.parking.auth.AuthService; -import com.example.parking.auth.authcode.application.dto.AuthCodeCertificateRequest; -import com.example.parking.auth.authcode.application.dto.AuthCodeRequest; -import com.example.parking.auth.authcode.application.dto.AuthCodeResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -@Tag(name = "인증코드 컨트롤러") -@RestController -@RequiredArgsConstructor -public class AuthCodeController { - - private final AuthService authService; - - @PostMapping("/authcode") - public ResponseEntity createAuthCode(@RequestBody AuthCodeRequest authCodeRequest) { - String authCode = authService.createAuthCode(authCodeRequest); - return ResponseEntity.status(HttpStatus.CREATED).body(new AuthCodeResponse(authCode)); - } - - @DeleteMapping("/authcode") - public ResponseEntity certificateAuthCode( - @RequestBody AuthCodeCertificateRequest authCodeCertificateRequest) { - authService.certificateAuthCode(authCodeCertificateRequest); - return ResponseEntity.status(HttpStatus.OK).build(); - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/application/AuthCodeEventListener.java b/src/main/java/com/example/parking/auth/authcode/application/AuthCodeEventListener.java deleted file mode 100644 index 4c8021b1..00000000 --- a/src/main/java/com/example/parking/auth/authcode/application/AuthCodeEventListener.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.example.parking.auth.authcode.application; - - -import com.example.parking.auth.authcode.event.AuthCodeCreateEvent; -import com.example.parking.auth.authcode.infrastructure.AuthCodeSender; -import com.example.parking.auth.authcode.util.AuthCodeKeyConverter; -import java.time.Instant; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.stereotype.Component; -import org.springframework.transaction.event.TransactionPhase; -import org.springframework.transaction.event.TransactionalEventListener; - -@RequiredArgsConstructor -@Component -public class AuthCodeEventListener { - - @Value("${authcode.expired-time}") - private Integer authCodeExpired; - - private final AuthCodeSender authCodeSender; - private final TaskScheduler taskScheduler; - private final RedisTemplate redisTemplate; - - @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) - public void sendAuthCode(AuthCodeCreateEvent authCodeCreateEvent) { - String destination = authCodeCreateEvent.getDestination(); - String authCode = authCodeCreateEvent.getAuthCode(); - authCodeSender.send(destination, authCode); - } - - @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) - public void scheduledAuthCodeRemove(AuthCodeCreateEvent authCodeCreateEvent) { - String authCode = authCodeCreateEvent.getAuthCode(); - String destination = authCodeCreateEvent.getDestination(); - String authCodePlatform = authCodeCreateEvent.getAuthCodePlatform(); - String authCodeCategory = authCodeCreateEvent.getAuthCodeCategory(); - - String authCodeKey = AuthCodeKeyConverter.convert(authCode, destination, authCodePlatform, authCodeCategory); - taskScheduler.schedule(() -> redisTemplate.delete(authCodeKey), Instant.now().plusSeconds(authCodeExpired)); - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/application/AuthCodeValidator.java b/src/main/java/com/example/parking/auth/authcode/application/AuthCodeValidator.java deleted file mode 100644 index 2ea904e7..00000000 --- a/src/main/java/com/example/parking/auth/authcode/application/AuthCodeValidator.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.parking.auth.authcode.application; - -import com.example.parking.auth.authcode.AuthCodePlatform; -import com.example.parking.auth.authcode.InValidAuthCodeException; -import java.util.EnumMap; -import org.springframework.stereotype.Component; - -@Component -public class AuthCodeValidator { - - private final EnumMap validators = new EnumMap<>(AuthCodePlatform.class); - - public AuthCodeValidator() { - validators.put(AuthCodePlatform.MAIL, new MailPlatformValidator()); - } - - public void validate(AuthCodePlatform authCodePlatform, String destination) { - PlatformValidator platformValidator = validators.get(authCodePlatform); - if (platformValidator.isInvalidForm(destination)) { - throw new InValidAuthCodeException("인증 코드 플랫폼과 수신지 형식이 일치하지 않습니다."); - } - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/application/MailPlatformValidator.java b/src/main/java/com/example/parking/auth/authcode/application/MailPlatformValidator.java deleted file mode 100644 index e023ec4b..00000000 --- a/src/main/java/com/example/parking/auth/authcode/application/MailPlatformValidator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.parking.auth.authcode.application; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class MailPlatformValidator implements PlatformValidator { - - private static final String EMAIL_PATTERN = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"; - - private static final Pattern PATTERN = Pattern.compile(EMAIL_PATTERN); - - @Override - public boolean isInvalidForm(String destination) { - Matcher matcher = PATTERN.matcher(destination); - return !matcher.matches(); - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/application/PlatformValidator.java b/src/main/java/com/example/parking/auth/authcode/application/PlatformValidator.java deleted file mode 100644 index 2c72f19b..00000000 --- a/src/main/java/com/example/parking/auth/authcode/application/PlatformValidator.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.parking.auth.authcode.application; - -public interface PlatformValidator { - - boolean isInvalidForm(String destination); -} diff --git a/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeCertificateRequest.java b/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeCertificateRequest.java deleted file mode 100644 index ff689c76..00000000 --- a/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeCertificateRequest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.parking.auth.authcode.application.dto; - - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class AuthCodeCertificateRequest { - - private String destination; - private String authCodePlatform; - private String authCodeCategory; - private String authCode; - - public AuthCodeCertificateRequest(String destination, String authCodePlatform, String authCodeCategory, - String authCode) { - this.destination = destination; - this.authCodePlatform = authCodePlatform; - this.authCodeCategory = authCodeCategory; - this.authCode = authCode; - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeRequest.java b/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeRequest.java deleted file mode 100644 index eddcd68f..00000000 --- a/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeRequest.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.parking.auth.authcode.application.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class AuthCodeRequest { - - private String destination; - private String authPlatform; - private String authCodeCategory; - - public AuthCodeRequest(String destination, String authPlatform, String authCodeCategory) { - this.destination = destination; - this.authPlatform = authPlatform; - this.authCodeCategory = authCodeCategory; - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeResponse.java b/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeResponse.java deleted file mode 100644 index 4c44603d..00000000 --- a/src/main/java/com/example/parking/auth/authcode/application/dto/AuthCodeResponse.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.parking.auth.authcode.application.dto; - -import lombok.Getter; - -@Getter -public class AuthCodeResponse { - - private String authCode; - - public AuthCodeResponse(String authCode) { - this.authCode = authCode; - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/event/AuthCodeCreateEvent.java b/src/main/java/com/example/parking/auth/authcode/event/AuthCodeCreateEvent.java deleted file mode 100644 index 2aad93fb..00000000 --- a/src/main/java/com/example/parking/auth/authcode/event/AuthCodeCreateEvent.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.parking.auth.authcode.event; - -import lombok.Getter; - -@Getter -public class AuthCodeCreateEvent { - - private final String destination; - private final String authCode; - private final String authCodePlatform; - private final String authCodeCategory; - - public AuthCodeCreateEvent(String destination, String authCode, String authCodePlatform, String authCodeCategory) { - this.destination = destination; - this.authCode = authCode; - this.authCodePlatform = authCodePlatform; - this.authCodeCategory = authCodeCategory; - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/infrastructure/AuthCodeSender.java b/src/main/java/com/example/parking/auth/authcode/infrastructure/AuthCodeSender.java deleted file mode 100644 index 4e69d603..00000000 --- a/src/main/java/com/example/parking/auth/authcode/infrastructure/AuthCodeSender.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.parking.auth.authcode.infrastructure; - -public interface AuthCodeSender { - - void send(String destination, String authCode); -} diff --git a/src/main/java/com/example/parking/auth/authcode/infrastructure/MailAuthCodeSender.java b/src/main/java/com/example/parking/auth/authcode/infrastructure/MailAuthCodeSender.java deleted file mode 100644 index 69af06af..00000000 --- a/src/main/java/com/example/parking/auth/authcode/infrastructure/MailAuthCodeSender.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.parking.auth.authcode.infrastructure; - -import lombok.RequiredArgsConstructor; -import org.springframework.mail.SimpleMailMessage; -import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.stereotype.Component; - -@RequiredArgsConstructor -@Component -public class MailAuthCodeSender implements AuthCodeSender { - - private final JavaMailSender mailSender; - - @Override - public void send(String destination, String authCode) { - SimpleMailMessage mailMessage = new SimpleMailMessage(); - - mailMessage.setTo(destination); - mailMessage.setSubject("인증 코드"); - mailMessage.setText(authCode); - mailSender.send(mailMessage); - } -} diff --git a/src/main/java/com/example/parking/auth/authcode/util/AuthCodeKeyConverter.java b/src/main/java/com/example/parking/auth/authcode/util/AuthCodeKeyConverter.java deleted file mode 100644 index 86dc10d8..00000000 --- a/src/main/java/com/example/parking/auth/authcode/util/AuthCodeKeyConverter.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.parking.auth.authcode.util; - -import java.util.StringJoiner; - -public class AuthCodeKeyConverter { - - public static String convert(String randomAuthCode, String destination, String authCodePlatform, - String authCodeCategory) { - StringJoiner stringJoiner = new StringJoiner(":"); - return stringJoiner - .add(randomAuthCode) - .add(destination) - .add(authCodePlatform) - .add(authCodeCategory).toString(); - } -} diff --git a/src/main/java/com/example/parking/auth/session/MemberSession.java b/src/main/java/com/example/parking/auth/session/MemberSession.java deleted file mode 100644 index 50711966..00000000 --- a/src/main/java/com/example/parking/auth/session/MemberSession.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.parking.auth.session; - -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import java.time.LocalDateTime; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class MemberSession { - - @Id - private String sessionId; - private Long memberId; - private LocalDateTime createdAt; - private LocalDateTime expiredAt; - - public MemberSession(String sessionId, Long memberId, LocalDateTime createdAt, LocalDateTime expiredAt) { - this.sessionId = sessionId; - this.memberId = memberId; - this.createdAt = createdAt; - this.expiredAt = expiredAt; - } - - public void updateExpiredAt(LocalDateTime newExpiredAt) { - expiredAt = newExpiredAt; - } -} diff --git a/src/main/java/com/example/parking/auth/session/MemberSessionRepository.java b/src/main/java/com/example/parking/auth/session/MemberSessionRepository.java deleted file mode 100644 index 547186ae..00000000 --- a/src/main/java/com/example/parking/auth/session/MemberSessionRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.parking.auth.session; - -import java.time.LocalDateTime; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface MemberSessionRepository extends JpaRepository { - - Optional findBySessionIdAndExpiredAtIsGreaterThanEqual(String sessionId, LocalDateTime expiredAt); -} diff --git a/src/main/java/com/example/parking/config/ApiRestTemplateConfig.java b/src/main/java/com/example/parking/config/ApiRestTemplateConfig.java deleted file mode 100644 index 9759b232..00000000 --- a/src/main/java/com/example/parking/config/ApiRestTemplateConfig.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.example.parking.config; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.web.client.RestTemplate; - -@Configuration -public class ApiRestTemplateConfig { - - @Bean - @Qualifier("parkingApiRestTemplate") - public RestTemplate parkingApiRestTemplate(RestTemplateBuilder restTemplateBuilder) { - return restTemplateBuilder - .errorHandler(new ParkingApiErrorHandler()) - .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .build(); - } -} diff --git a/src/main/java/com/example/parking/config/ParkingApiErrorHandler.java b/src/main/java/com/example/parking/config/ParkingApiErrorHandler.java deleted file mode 100644 index 58840087..00000000 --- a/src/main/java/com/example/parking/config/ParkingApiErrorHandler.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.parking.config; - -import java.io.IOException; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.ResponseErrorHandler; - -@Slf4j -public class ParkingApiErrorHandler implements ResponseErrorHandler { - - @Override - public boolean hasError(ClientHttpResponse response) throws IOException { - return response.getStatusCode().isError(); - } - - @Override - public void handleError(ClientHttpResponse response) throws IOException { - log.warn("fail while request by ParkingAPI {}", response.getStatusCode()); - } -} diff --git a/src/main/java/com/example/parking/config/RestTemplateConfig.java b/src/main/java/com/example/parking/config/RestTemplateConfig.java deleted file mode 100644 index 80abb3b7..00000000 --- a/src/main/java/com/example/parking/config/RestTemplateConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.parking.config; - -import com.example.parking.external.coordinate.CoordinateErrorHandler; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; - -@Configuration -public class RestTemplateConfig { - - private static final String AUTH_HEADER = "Authorization"; - - @Bean - @Qualifier("coordinateRestTemplate") - public RestTemplate coordinateRestTemplate(RestTemplateBuilder restTemplateBuilder, - @Value("${kakao.key}") String kakaoUrl) { - return restTemplateBuilder - .errorHandler(new CoordinateErrorHandler()) - .defaultHeader(AUTH_HEADER, kakaoUrl) - .build(); - } -} diff --git a/src/main/java/com/example/parking/config/SwaggerConfig.java b/src/main/java/com/example/parking/config/SwaggerConfig.java deleted file mode 100644 index a3a5230a..00000000 --- a/src/main/java/com/example/parking/config/SwaggerConfig.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.parking.config; - -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.info.Info; -import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.security.SecurityRequirement; -import io.swagger.v3.oas.models.security.SecurityScheme; -import io.swagger.v3.oas.models.security.SecurityScheme.In; -import io.swagger.v3.oas.models.security.SecurityScheme.Type; -import io.swagger.v3.oas.models.servers.Server; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@OpenAPIDefinition( - info = @Info(title = "주차의 상상은 현실이 된다 aka 주상현", description = "주차의 상상은 현실이 된다 aka 주상현 API 명세서")) -@Configuration -public class SwaggerConfig { - - private static final String JSESSIONID = "JSESSIONID"; - - @Bean - public OpenAPI openAPI() { - SecurityScheme auth = new SecurityScheme() - .type(Type.APIKEY).in(In.COOKIE).name(JSESSIONID); - SecurityRequirement securityRequirement = new SecurityRequirement().addList(JSESSIONID); - - return new OpenAPI().addServersItem(new Server().url("/")) - .components(new Components().addSecuritySchemes("JSESSIONID", auth)) - .addSecurityItem(securityRequirement); - } -} diff --git a/src/main/java/com/example/parking/config/WebMvcConfig.java b/src/main/java/com/example/parking/config/WebMvcConfig.java deleted file mode 100644 index 628c0431..00000000 --- a/src/main/java/com/example/parking/config/WebMvcConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.example.parking.config; - -import com.example.parking.config.argumentresolver.AuthArgumentResolver; -import com.example.parking.config.argumentresolver.parking.ParkingQueryArgumentResolver; -import com.example.parking.config.argumentresolver.parking.ParkingSearchConditionArgumentResolver; -import com.example.parking.config.interceptor.AuthInterceptor; -import io.swagger.v3.oas.models.PathItem; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@RequiredArgsConstructor -@Configuration -public class WebMvcConfig implements WebMvcConfigurer { - - private final AuthInterceptor authInterceptor; - private final AuthArgumentResolver authArgumentResolver; - private final ParkingQueryArgumentResolver parkingQueryArgumentResolver; - private final ParkingSearchConditionArgumentResolver parkingSearchConditionArgumentResolver; - - @Value("${cors.allowedOrigins}") - private String[] allowedOrigins; - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(authInterceptor) - .addPathPatterns("/**") - .excludePathPatterns(List.of( - "/v3/api-docs/**", - "/swagger-resources/**", - "/swagger-ui/**", - "/signup", - "/signin", - "/parkings/**" - )); - } - - @Override - public void addArgumentResolvers(List resolvers) { - resolvers.add(authArgumentResolver); - resolvers.add(parkingQueryArgumentResolver); - resolvers.add(parkingSearchConditionArgumentResolver); - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**") - .allowedOrigins(allowedOrigins) - .allowedMethods( - PathItem.HttpMethod.OPTIONS.name(), - PathItem.HttpMethod.GET.name(), - PathItem.HttpMethod.POST.name(), - PathItem.HttpMethod.PUT.name(), - PathItem.HttpMethod.DELETE.name(), - PathItem.HttpMethod.PATCH.name() - ) - .allowCredentials(true) - .exposedHeaders("*"); - } -} diff --git a/src/main/java/com/example/parking/config/argumentresolver/AuthArgumentResolver.java b/src/main/java/com/example/parking/config/argumentresolver/AuthArgumentResolver.java deleted file mode 100644 index 8a4ae81f..00000000 --- a/src/main/java/com/example/parking/config/argumentresolver/AuthArgumentResolver.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example.parking.config.argumentresolver; - -import com.example.parking.auth.AuthService; -import com.example.parking.auth.session.MemberSession; -import lombok.RequiredArgsConstructor; -import org.springframework.core.MethodParameter; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.ModelAndViewContainer; - -@RequiredArgsConstructor -@Component -public class AuthArgumentResolver implements HandlerMethodArgumentResolver { - - - private static final String JSESSIONID = "JSESSIONID"; - - private final AuthService authService; - - @Override - public boolean supportsParameter(MethodParameter parameter) { - return parameter.hasParameterAnnotation(MemberAuth.class); - } - - @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { - MemberAuth memberAuth = parameter.getParameterAnnotation(MemberAuth.class); - String sessionId = webRequest.getHeader(JSESSIONID); - if (memberAuth.nullable() && sessionId == null) { - return null; - } - MemberSession session = authService.findSession(sessionId); - return session.getMemberId(); - } -} diff --git a/src/main/java/com/example/parking/config/argumentresolver/MemberAuth.java b/src/main/java/com/example/parking/config/argumentresolver/MemberAuth.java deleted file mode 100644 index 4fdcee5a..00000000 --- a/src/main/java/com/example/parking/config/argumentresolver/MemberAuth.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.parking.config.argumentresolver; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.RUNTIME) -public @interface MemberAuth { - - boolean nullable() default false; -} diff --git a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQuery.java b/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQuery.java deleted file mode 100644 index e328d4e7..00000000 --- a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQuery.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.parking.config.argumentresolver.parking; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.RUNTIME) -public @interface ParkingQuery { -} diff --git a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java b/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java deleted file mode 100644 index 082db669..00000000 --- a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingQueryArgumentResolver.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.parking.config.argumentresolver.parking; - -import com.example.parking.application.parking.dto.ParkingQueryRequest; -import org.springframework.core.MethodParameter; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.ModelAndViewContainer; - -@Component -public class ParkingQueryArgumentResolver implements HandlerMethodArgumentResolver { - - @Override - public boolean supportsParameter(MethodParameter parameter) { - return parameter.hasParameterAnnotation(ParkingQuery.class); - } - - @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { - return new ParkingQueryRequest( - Double.valueOf(webRequest.getParameter("longitude")), - Double.valueOf(webRequest.getParameter("latitude")), - Integer.parseInt(webRequest.getParameter("radius")) - ); - } -} diff --git a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchCondition.java b/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchCondition.java deleted file mode 100644 index 275cf05e..00000000 --- a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchCondition.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.parking.config.argumentresolver.parking; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.RUNTIME) -public @interface ParkingSearchCondition { -} diff --git a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java b/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java deleted file mode 100644 index 4514e6bb..00000000 --- a/src/main/java/com/example/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.example.parking.config.argumentresolver.parking; - -import com.example.parking.application.SearchConditionMapper; -import com.example.parking.application.parking.dto.ParkingSearchConditionRequest; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayType; -import java.util.Arrays; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.core.MethodParameter; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.ModelAndViewContainer; - -@RequiredArgsConstructor -@Component -public class ParkingSearchConditionArgumentResolver implements HandlerMethodArgumentResolver { - - private static final int BASE_HOURS = 1; - private static final String NOT_FREE = "유료"; - private static final String RECOMMEND_ORDER_CONDITION = "추천 순"; - - private final SearchConditionMapper searchConditionMapper; - - @Override - public boolean supportsParameter(MethodParameter parameter) { - return parameter.hasParameterAnnotation(ParkingSearchCondition.class); - } - - @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { - - String[] operationTypes = webRequest.getParameterValues("operationTypes"); - String[] parkingTypes = webRequest.getParameterValues("parkingTypes"); - String feeType = webRequest.getParameter("feeTypes"); - String[] payTypes = webRequest.getParameterValues("payTypes"); - String hours = webRequest.getParameter("hours"); - String priority = webRequest.getParameter("priority"); - - if (containsNull(operationTypes, parkingTypes, feeType, payTypes, hours)) { - return defaultRequest(); - } - - return new ParkingSearchConditionRequest( - toList(operationTypes), - toList(parkingTypes), - feeType, - toList(payTypes), - Integer.parseInt(hours), - priority - ); - } - - private boolean containsNull(String[] operationTypes, String[] parkingTypes, String feeType, - String[] payTypes, String hours) { - return operationTypes == null || parkingTypes == null || feeType == null || payTypes == null || hours == null; - } - - private ParkingSearchConditionRequest defaultRequest() { - return new ParkingSearchConditionRequest( - searchConditionMapper.getValues(OperationType.class), - searchConditionMapper.getValues(ParkingType.class), - NOT_FREE, - searchConditionMapper.getValues(PayType.class), - BASE_HOURS, - RECOMMEND_ORDER_CONDITION - ); - } - - private List toList(String[] parameters) { - return Arrays.stream(parameters) - .toList(); - } -} diff --git a/src/main/java/com/example/parking/config/interceptor/AuthInterceptor.java b/src/main/java/com/example/parking/config/interceptor/AuthInterceptor.java deleted file mode 100644 index 71f09d76..00000000 --- a/src/main/java/com/example/parking/config/interceptor/AuthInterceptor.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.parking.config.interceptor; - -import com.example.parking.auth.AuthService; -import com.example.parking.auth.session.MemberSession; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@RequiredArgsConstructor -@Component -@Slf4j -public class AuthInterceptor implements HandlerInterceptor { - - private static final String JSESSIONID = "JSESSIONID"; - - private final AuthService authService; - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - log.info("request: {}", request.getRequestURL()); - String sessionId = request.getHeader(JSESSIONID); - MemberSession session = authService.findSession(sessionId); - authService.updateSessionExpiredAt(session); - return true; - } -} diff --git a/src/main/java/com/example/parking/domain/AuditingEntity.java b/src/main/java/com/example/parking/domain/AuditingEntity.java deleted file mode 100644 index 8f1bf061..00000000 --- a/src/main/java/com/example/parking/domain/AuditingEntity.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.example.parking.domain; - -import jakarta.persistence.EntityListeners; -import jakarta.persistence.MappedSuperclass; -import java.time.LocalDateTime; -import lombok.Getter; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - -@Getter -@MappedSuperclass -@EntityListeners(AuditingEntityListener.class) -public abstract class AuditingEntity { - - @CreatedDate - private LocalDateTime createdAt; - - @LastModifiedDate - private LocalDateTime updatedAt; -} diff --git a/src/main/java/com/example/parking/domain/favorite/Favorite.java b/src/main/java/com/example/parking/domain/favorite/Favorite.java deleted file mode 100644 index 69dd9a60..00000000 --- a/src/main/java/com/example/parking/domain/favorite/Favorite.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.example.parking.domain.favorite; - -import com.example.parking.domain.AuditingEntity; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.support.Association; -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; -import jakarta.persistence.Embedded; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "favorite", - uniqueConstraints = { - @UniqueConstraint( - columnNames = {"memberId", "parkingId"} - ) - } -) -@Entity -public class Favorite extends AuditingEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "member_id")) - private Association memberId; - - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "parking_id")) - private Association parkingId; - - public Favorite(Association memberId, Association parkingId) { - this.memberId = memberId; - this.parkingId = parkingId; - } -} diff --git a/src/main/java/com/example/parking/domain/favorite/FavoriteRepository.java b/src/main/java/com/example/parking/domain/favorite/FavoriteRepository.java deleted file mode 100644 index 81aa3862..00000000 --- a/src/main/java/com/example/parking/domain/favorite/FavoriteRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.parking.domain.favorite; - -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.support.Association; -import java.util.List; -import org.springframework.data.repository.Repository; - -public interface FavoriteRepository extends Repository { - - Favorite save(Favorite favorite); - - void deleteByMemberIdAndParkingId(Association memberId, Association parkingId); - - List findByMemberId(Association memberId); -} diff --git a/src/main/java/com/example/parking/domain/member/Member.java b/src/main/java/com/example/parking/domain/member/Member.java deleted file mode 100644 index 8a495975..00000000 --- a/src/main/java/com/example/parking/domain/member/Member.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.example.parking.domain.member; - -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.Objects; - -@Getter -@Entity -//@SQLRestriction(value = "deleted = false") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Member { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(unique = true) - private String email; - - private String nickname; - - @Embedded - private Password password; - - private Boolean deleted = Boolean.FALSE; - - public Member(String email, String nickname, Password password) { - this.email = email; - this.nickname = nickname; - this.password = password; - } - - public boolean checkPassword(String password) { - return this.password.isMatch(password); - } - - public void delete() { - deleted = Boolean.TRUE; - } - - public void changePassword(String previousPassword, String newPassword) { - if (checkPassword(previousPassword)) { - this.password = new Password(newPassword); - return; - } - throw new DomainException(ExceptionInformation.INVALID_PASSWORD); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Member member = (Member) o; - return Objects.equals(getId(), member.getId()); - } - - @Override - public int hashCode() { - return Objects.hash(getId()); - } -} diff --git a/src/main/java/com/example/parking/domain/member/MemberId.java b/src/main/java/com/example/parking/domain/member/MemberId.java deleted file mode 100644 index d3ac6b0b..00000000 --- a/src/main/java/com/example/parking/domain/member/MemberId.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.parking.domain.member; - -import jakarta.persistence.Embeddable; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Embeddable -@NoArgsConstructor -@Getter -public class MemberId { - - private Long memberId; - - public MemberId(Long memberId) { - this.memberId = memberId; - } -} diff --git a/src/main/java/com/example/parking/domain/member/MemberRepository.java b/src/main/java/com/example/parking/domain/member/MemberRepository.java deleted file mode 100644 index 0b515618..00000000 --- a/src/main/java/com/example/parking/domain/member/MemberRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.example.parking.domain.member; - -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.Optional; -import org.springframework.data.repository.Repository; - -public interface MemberRepository extends Repository { - - boolean existsByEmail(String email); - - Optional findById(Long id); - - Optional findByEmail(String email); - - void save(Member member); - - default Member getById(Long id) { - return findById(id).orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_MEMBER)); - } -} diff --git a/src/main/java/com/example/parking/domain/member/Password.java b/src/main/java/com/example/parking/domain/member/Password.java deleted file mode 100644 index f7bc6b27..00000000 --- a/src/main/java/com/example/parking/domain/member/Password.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example.parking.domain.member; - -import com.example.parking.util.cipher.SHA256; -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.Objects; - -@Embeddable -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Password { - - private String password; - - public Password(String password) { - this.password = SHA256.encrypt(password); - } - - public boolean isMatch(String password) { - return this.password.equals(SHA256.encrypt(password)); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Password that = (Password) o; - return Objects.equals(password, that.password); - } - - @Override - public int hashCode() { - return Objects.hash(password); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/BaseInformation.java b/src/main/java/com/example/parking/domain/parking/BaseInformation.java deleted file mode 100644 index 8287650d..00000000 --- a/src/main/java/com/example/parking/domain/parking/BaseInformation.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.example.parking.domain.parking; - -import static jakarta.persistence.EnumType.STRING; - -import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; -import jakarta.persistence.Enumerated; -import java.util.List; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter -@Embeddable -public class BaseInformation { - - private String name; - private String tel; - private String address; - - @Embedded - private PayTypes payTypes; - - @Enumerated(STRING) - private ParkingType parkingType; - - @Enumerated(STRING) - private OperationType operationType; - - public BaseInformation(String name, String tel, String address, PayTypes payTypes, ParkingType parkingType, - OperationType operationType) { - this.name = name; - this.tel = tel; - this.address = address; - this.payTypes = payTypes; - this.parkingType = parkingType; - this.operationType = operationType; - } - - public boolean containsOperationType(List operationTypes) { - return operationTypes.stream() - .anyMatch(operationType -> this.operationType == operationType); - } - - public boolean containsParkingType(List parkingTypes) { - return parkingTypes.stream() - .anyMatch(parkingType -> this.parkingType == parkingType); - } - - public boolean containsPayType(List memberPayTypes) { - return this.payTypes.contains(memberPayTypes); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/Day.java b/src/main/java/com/example/parking/domain/parking/Day.java deleted file mode 100644 index c752d22d..00000000 --- a/src/main/java/com/example/parking/domain/parking/Day.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.parking.domain.parking; - -import java.time.DayOfWeek; - -public enum Day { - - WEEKDAY, - SATURDAY, - HOLIDAY; - - public static Day from(DayOfWeek dayOfWeek) { - if (dayOfWeek == DayOfWeek.SATURDAY) { - return SATURDAY; - } - if (dayOfWeek == DayOfWeek.SUNDAY) { - return HOLIDAY; - } - return WEEKDAY; - } -} diff --git a/src/main/java/com/example/parking/domain/parking/DayParking.java b/src/main/java/com/example/parking/domain/parking/DayParking.java deleted file mode 100644 index 67334b83..00000000 --- a/src/main/java/com/example/parking/domain/parking/DayParking.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.parking.domain.parking; - -import lombok.Getter; - -import java.time.LocalTime; - -@Getter -public class DayParking { - - private Day day; - private LocalTime beginTime; - private LocalTime endTime; - - public DayParking(Day day, LocalTime beginTime, LocalTime endTime) { - this.day = day; - this.beginTime = beginTime; - this.endTime = endTime; - } - - public boolean isWeekDay() { - return day == Day.WEEKDAY; - } - - public boolean isSaturday() { - return day == Day.SATURDAY; - } - - public boolean isHoliday() { - return day == Day.HOLIDAY; - } -} diff --git a/src/main/java/com/example/parking/domain/parking/Fee.java b/src/main/java/com/example/parking/domain/parking/Fee.java deleted file mode 100644 index 2845b1cd..00000000 --- a/src/main/java/com/example/parking/domain/parking/Fee.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@EqualsAndHashCode -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Embeddable -public class Fee { - - public static final Fee ZERO = new Fee(0); - public static final Fee NO_INFO = new Fee(-1); - - private Integer fee; - - private Fee(Integer fee) { - this.fee = fee; - } - - public static Fee from(Integer fee) { - return new Fee(fee); - } - - public static Fee from(String fee) { - try { - return new Fee(Integer.parseInt(fee)); - } catch (NumberFormatException | NullPointerException e) { - return NO_INFO; - } - } - - public Fee multiply(int time) { - return new Fee(fee * time); - } - - public Fee plus(Fee fee) { - return new Fee(this.fee + fee.fee); - } - - public static Fee min(Fee fee, Fee otherFee) { - if (fee.fee < otherFee.fee) { - return fee; - } - return otherFee; - } - - public boolean isFree() { - return fee == 0; - } - - public boolean isValidFee() { - return !NO_INFO.equals(this); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/FeePolicy.java b/src/main/java/com/example/parking/domain/parking/FeePolicy.java deleted file mode 100644 index d208597d..00000000 --- a/src/main/java/com/example/parking/domain/parking/FeePolicy.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter -@Embeddable -public class FeePolicy { - - @AttributeOverride(name = "fee", column = @Column(name = "base_fee")) - @Embedded - private Fee baseFee; - - @AttributeOverride(name = "fee", column = @Column(name = "extra_fee")) - @Embedded - private Fee extraFee; - - @AttributeOverride(name = "timeUnit", column = @Column(name = "base_time_unit")) - @Embedded - private TimeUnit baseTimeUnit; - - @AttributeOverride(name = "timeUnit", column = @Column(name = "extra_time_unit")) - @Embedded - private TimeUnit extraTimUnit; - - @AttributeOverride(name = "fee", column = @Column(name = "day_maximum_fee")) - @Embedded - private Fee dayMaximumFee; - - public FeePolicy(Fee baseFee, Fee extraFee, TimeUnit baseTimeUnit, TimeUnit extraTimUnit, Fee dayMaximumFee) { - this.baseFee = baseFee; - this.extraFee = extraFee; - this.baseTimeUnit = baseTimeUnit; - this.extraTimUnit = extraTimUnit; - this.dayMaximumFee = dayMaximumFee; - } - - public Fee calculateFee(int minutes) { - if (supportBase()) { - return calculateFeeWithBase(minutes); - } - return calculateFeeWithoutBase(minutes); - } - - public boolean supportBase() { - return baseFee.isValidFee() && baseTimeUnit.isValidTimeUnit(); - } - - public boolean supportExtra() { - return extraFee.isValidFee() && extraTimUnit.isValidTimeUnit(); - } - - private Fee calculateFeeWithBase(int minutes) { - if (minutes == 0) { - return Fee.ZERO; - } - if (baseTimeUnit.isEqualOrGreaterThan(minutes)) { - return baseFee; - } - minutes = minutes - baseTimeUnit.getTimeUnit(); - int time = extraTimUnit.calculateQuotient(minutes); - return Fee.min(extraFee.multiply(time).plus(baseFee), dayMaximumFee); - } - - private Fee calculateFeeWithoutBase(int minutes) { - if (minutes == 0) { - return Fee.ZERO; - } - if (supportExtra()) { - int time = extraTimUnit.calculateQuotient(minutes); - return Fee.min(extraFee.multiply(time), dayMaximumFee); - } - return Fee.NO_INFO; - } -} diff --git a/src/main/java/com/example/parking/domain/parking/FreeOperatingTime.java b/src/main/java/com/example/parking/domain/parking/FreeOperatingTime.java deleted file mode 100644 index 0f21f270..00000000 --- a/src/main/java/com/example/parking/domain/parking/FreeOperatingTime.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -import java.time.LocalTime; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Embeddable -public class FreeOperatingTime { - - public static final FreeOperatingTime ALWAYS_PAY = new FreeOperatingTime(TimeInfo.CLOSED, TimeInfo.CLOSED, - TimeInfo.CLOSED); - public static final FreeOperatingTime ALWAYS_FREE = new FreeOperatingTime(TimeInfo.ALL_DAY, TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY); - - @AttributeOverride(name = "beginTime", column = @Column(name = "weekday_free_begin_time")) - @AttributeOverride(name = "endTime", column = @Column(name = "weekday_free_end_time")) - @Embedded - private TimeInfo weekday; - - @AttributeOverride(name = "beginTime", column = @Column(name = "saturday_free_begin_time")) - @AttributeOverride(name = "endTime", column = @Column(name = "saturday_free_end_time")) - @Embedded - private TimeInfo saturday; - - @AttributeOverride(name = "beginTime", column = @Column(name = "holiday_free_begin_time")) - @AttributeOverride(name = "endTime", column = @Column(name = "holiday_free_end_time")) - @Embedded - private TimeInfo holiday; - - public FreeOperatingTime(TimeInfo weekday, TimeInfo saturday, TimeInfo holiday) { - this.weekday = weekday; - this.saturday = saturday; - this.holiday = holiday; - } - - public int calculateNonFreeUsageMinutes(DayParking dayParking) { - TimeInfo today = getTodayTimeInfo(dayParking); - if (isFreeDay(today)) { - return 0; - } - LocalTime beginTime = dayParking.getBeginTime(); - LocalTime endTime = dayParking.getEndTime(); - int parkingMinutes = calculateMinutes(endTime) - calculateMinutes(beginTime); - int overlapMinutes = today.calculateOverlapMinutes(beginTime, endTime); - return parkingMinutes - overlapMinutes; - } - - private TimeInfo getTodayTimeInfo(DayParking dayParking) { - if (dayParking.isWeekDay()) { - return weekday; - } - if (dayParking.isSaturday()) { - return saturday; - } - return holiday; - } - - private boolean isFreeDay(TimeInfo today) { - return today.equals(TimeInfo.ALL_DAY); - } - - private int calculateMinutes(LocalTime localTime) { - if (localTime.equals(LocalTime.MAX)) { - return localTime.getHour() * 60 + localTime.getMinute() + 1; - } - return localTime.getHour() * 60 + localTime.getMinute(); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/Location.java b/src/main/java/com/example/parking/domain/parking/Location.java deleted file mode 100644 index 18732ddc..00000000 --- a/src/main/java/com/example/parking/domain/parking/Location.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.example.parking.domain.parking; - -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.GeometryFactory; -import org.locationtech.jts.geom.Point; -import org.locationtech.jts.geom.PrecisionModel; - -@Getter -@EqualsAndHashCode -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Embeddable -public class Location { - - private static final GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); - private static final Location NO_PROVIDE = new Location(geometryFactory.createPoint(new Coordinate(-1.0, -1.0))); - - private static final Double MAX_LONGITUDE = 180.0; - private static final Double MIN_LONGITUDE = -180.0; - - private static final Double MAX_LATITUDE = 90.0; - private static final Double MIN_LATITUDE = -90.0; - - private Point point; - - private Location(Point point) { - this.point = point; - } - - public static Location of(Double longitude, Double latitude) { - try { - verifyLocation(longitude, latitude); - Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); - return new Location(point); - } catch (NullPointerException e) { - return NO_PROVIDE; - } - } - - private static void verifyLocation(Double longitude, Double latitude) { - if (longitude > MAX_LONGITUDE || longitude < MIN_LONGITUDE || latitude > MAX_LATITUDE - || latitude < MIN_LATITUDE) { - throw new DomainException(ExceptionInformation.INVALID_LOCATION); - } - } - - public static Location of(String longitude, String latitude) { - try { - return Location.of(Double.parseDouble(longitude), Double.parseDouble(latitude)); - } catch (NumberFormatException | NullPointerException e) { - return NO_PROVIDE; - } - } - - public double getLongitude() { - return point.getX(); - } - - public double getLatitude() { - return point.getY(); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/OperatingTime.java b/src/main/java/com/example/parking/domain/parking/OperatingTime.java deleted file mode 100644 index ff8a9a32..00000000 --- a/src/main/java/com/example/parking/domain/parking/OperatingTime.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; -import java.time.LocalTime; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter -@Embeddable -public class OperatingTime { - - public static final OperatingTime ALWAYS_OPEN = new OperatingTime(TimeInfo.ALL_DAY, TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY); - - @AttributeOverride(name = "beginTime", column = @Column(name = "weekday_begin_time")) - @AttributeOverride(name = "endTime", column = @Column(name = "weekday_end_time")) - @Embedded - private TimeInfo weekday; - - @AttributeOverride(name = "beginTime", column = @Column(name = "saturday_begin_time")) - @AttributeOverride(name = "endTime", column = @Column(name = "saturday_end_time")) - @Embedded - private TimeInfo saturday; - - @AttributeOverride(name = "beginTime", column = @Column(name = "holiday_begin_time")) - @AttributeOverride(name = "endTime", column = @Column(name = "holiday_end_time")) - @Embedded - private TimeInfo holiday; - - public OperatingTime(TimeInfo weekday, - TimeInfo saturday, - TimeInfo holiday) { - this.weekday = weekday; - this.saturday = saturday; - this.holiday = holiday; - } - - public LocalTime getWeekdayBeginTime() { - return weekday.getBeginTime(); - } - - public LocalTime getWeekdayEndTime() { - return weekday.getEndTime(); - } - - public LocalTime getSaturdayBeginTime() { - return saturday.getBeginTime(); - } - - public LocalTime getSaturdayEndTime() { - return saturday.getEndTime(); - } - - public LocalTime getHolidayBeginTime() { - return holiday.getBeginTime(); - } - - public LocalTime getHolidayEndTime() { - return holiday.getEndTime(); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/OperationType.java b/src/main/java/com/example/parking/domain/parking/OperationType.java deleted file mode 100644 index 23eab9c7..00000000 --- a/src/main/java/com/example/parking/domain/parking/OperationType.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.parking.domain.parking; - -import com.example.parking.domain.searchcondition.SearchConditionAvailable; -import lombok.Getter; - -@Getter -public enum OperationType implements SearchConditionAvailable { - - PUBLIC("공영"), - PRIVATE("민영"), - NO_INFO("정보 없음"); - - private final String description; - - OperationType(String description) { - this.description = description; - } - - @Override - public OperationType getDefault() { - return NO_INFO; - } -} diff --git a/src/main/java/com/example/parking/domain/parking/Parking.java b/src/main/java/com/example/parking/domain/parking/Parking.java deleted file mode 100644 index 2c2101c4..00000000 --- a/src/main/java/com/example/parking/domain/parking/Parking.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.example.parking.domain.parking; - -import com.example.parking.domain.AuditingEntity; -import jakarta.persistence.Embedded; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Parking extends AuditingEntity { - - private static final int MINUTE_UNIT = 60; - - private static final int AVERAGE_WALKING_SPEED = 5; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Embedded - private BaseInformation baseInformation; - - @Embedded - private Location location; - - @Embedded - private Space space; - - @Embedded - private FreeOperatingTime freeOperatingTime; - - @Embedded - private OperatingTime operatingTime; - - @Embedded - private FeePolicy feePolicy; - - @Builder - private Parking(Long id, BaseInformation baseInformation, Location location, Space space, - FreeOperatingTime freeOperatingTime, OperatingTime operatingTime, FeePolicy feePolicy) { - this.id = id; - this.baseInformation = baseInformation; - this.location = location; - this.space = space; - this.freeOperatingTime = freeOperatingTime; - this.operatingTime = operatingTime; - this.feePolicy = feePolicy; - } - - public Parking(BaseInformation baseInformation, Location location, Space space, - FreeOperatingTime freeOperatingTime, OperatingTime operatingTime, FeePolicy feePolicy) { - this.baseInformation = baseInformation; - this.location = location; - this.space = space; - this.freeOperatingTime = freeOperatingTime; - this.operatingTime = operatingTime; - this.feePolicy = feePolicy; - } - - public int calculatePayOfChargeMinutes(DayParking dayParking) { - return freeOperatingTime.calculateNonFreeUsageMinutes(dayParking); - } - - public Fee calculateParkingFee(int payOfChargeMinutes) { - return feePolicy.calculateFee(payOfChargeMinutes); - } - - public boolean supportCalculateParkingFee() { - return feePolicy.supportBase() && feePolicy.supportExtra(); - } - - public void update(Parking updated) { - this.space = updated.space; - this.freeOperatingTime = updated.freeOperatingTime; - this.operatingTime = updated.operatingTime; - this.feePolicy = updated.feePolicy; - } - - public void update(Location location) { - this.location = location; - } - - public boolean containsOperationType(List operationTypes) { - return baseInformation.containsOperationType(operationTypes); - } - - public boolean containsParkingType(List parkingTypes) { - return baseInformation.containsParkingType(parkingTypes); - } - - public boolean containsPayType(List memberPayTypes) { - return baseInformation.containsPayType(memberPayTypes); - } - - public int calculateWalkingTime(Location destination) { - double distance = calculateDistanceToDestination(destination); - double averageWalkingTime = distance / AVERAGE_WALKING_SPEED; - return (int) Math.ceil(averageWalkingTime); - } - - private double calculateDistanceToDestination(Location destination) { - double parkingLongitude = this.location.getLongitude(); - double parkingLatitude = this.location.getLatitude(); - - double radius = 6371; // 지구 반지름(km) - double toRadian = Math.PI / 180; - - double deltaLatitude = Math.abs(parkingLatitude - destination.getLatitude()) * toRadian; - double deltaLongitude = Math.abs(parkingLongitude - destination.getLongitude()) * toRadian; - - double sinDeltaLat = Math.sin(deltaLatitude / 2); - double sinDeltaLng = Math.sin(deltaLongitude / 2); - double squareRoot = Math.sqrt( - sinDeltaLat * sinDeltaLat + - Math.cos(parkingLatitude * toRadian) * Math.cos(destination.getLatitude() * toRadian) - * sinDeltaLng - * sinDeltaLng); - - return 2 * radius * Math.asin(squareRoot); - } - - public int calculateUpdatedDiff(LocalDateTime now) { - Duration diff = Duration.between(now, getUpdatedAt()); - Long diffMinute = diff.getSeconds() / MINUTE_UNIT; - return diffMinute.intValue(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Parking parking = (Parking) o; - return Objects.equals(id, parking.id); - } - - @Override - public int hashCode() { - return Objects.hash(id); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/ParkingFeeCalculator.java b/src/main/java/com/example/parking/domain/parking/ParkingFeeCalculator.java deleted file mode 100644 index 4c974cef..00000000 --- a/src/main/java/com/example/parking/domain/parking/ParkingFeeCalculator.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.example.parking.domain.parking; - -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.ArrayList; -import java.util.List; -import org.springframework.stereotype.Component; - -@Component -public class ParkingFeeCalculator { - - public Fee calculateParkingFee(Parking parking, LocalDateTime beginTime, LocalDateTime endTime) { - if (!parking.supportCalculateParkingFee()) { - return Fee.NO_INFO; - } - - List dayParkingDates = separateDate(beginTime, endTime); - List payOfChargeMinutesPerDay = dayParkingDates.stream() - .map(parking::calculatePayOfChargeMinutes) - .toList(); - - return payOfChargeMinutesPerDay.stream() - .filter(minutes -> minutes > 0) - .map(parking::calculateParkingFee) - .reduce(Fee::plus) - .orElse(Fee.ZERO); - } - - private List separateDate(LocalDateTime beginTime, LocalDateTime endTime) { - if (isSameDate(beginTime, endTime)) { - return List.of( - new DayParking(Day.from(beginTime.getDayOfWeek()), beginTime.toLocalTime(), endTime.toLocalTime())); - } - - List dayParkingDates = new ArrayList<>(); - dayParkingDates.add(makeFirstDayParking(beginTime)); - beginTime = beginTime.plusDays(1); - while (!isSameDate(beginTime, endTime)) { - dayParkingDates.add(new DayParking(Day.from(beginTime.getDayOfWeek()), LocalTime.MIN, LocalTime.MAX)); - beginTime = beginTime.plusDays(1); - } - dayParkingDates.add(makeLastDayParking(endTime)); - return dayParkingDates; - } - - private boolean isSameDate(LocalDateTime beginTime, LocalDateTime endTime) { - return isSameYear(beginTime, endTime) && - isSameMonth(beginTime, endTime) && - isSameDayOfMonth(beginTime, endTime); - } - - private boolean isSameYear(LocalDateTime beginTime, LocalDateTime endTime) { - return beginTime.getYear() == endTime.getYear(); - } - - private boolean isSameMonth(LocalDateTime beginTime, LocalDateTime endTime) { - return beginTime.getMonth().equals(endTime.getMonth()); - } - - private boolean isSameDayOfMonth(LocalDateTime beginTime, LocalDateTime endTime) { - return beginTime.getDayOfMonth() == endTime.getDayOfMonth(); - } - - private DayParking makeFirstDayParking(LocalDateTime beginTime) { - return new DayParking(Day.from(beginTime.getDayOfWeek()), beginTime.toLocalTime(), LocalTime.MAX); - } - - private DayParking makeLastDayParking(LocalDateTime endTime) { - return new DayParking(Day.from(endTime.getDayOfWeek()), LocalTime.MIN, endTime.toLocalTime()); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/ParkingType.java b/src/main/java/com/example/parking/domain/parking/ParkingType.java deleted file mode 100644 index 5c7c39f3..00000000 --- a/src/main/java/com/example/parking/domain/parking/ParkingType.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.parking.domain.parking; - -import com.example.parking.domain.searchcondition.SearchConditionAvailable; -import java.util.Arrays; -import lombok.Getter; - -@Getter -public enum ParkingType implements SearchConditionAvailable { - OFF_STREET("노외"), - ON_STREET("노상"), - MECHANICAL("기계"), - NO_INFO("정보 없음"); - - private final String description; - - ParkingType(String description) { - this.description = description; - } - - @Override - public ParkingType getDefault() { - return NO_INFO; - } - - public static ParkingType find(String description) { - return Arrays.stream(values()) - .filter(e -> description.startsWith(e.getDescription())) - .findAny() - .orElse(NO_INFO); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/PayType.java b/src/main/java/com/example/parking/domain/parking/PayType.java deleted file mode 100644 index 11e9f793..00000000 --- a/src/main/java/com/example/parking/domain/parking/PayType.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.parking.domain.parking; - -import com.example.parking.domain.searchcondition.SearchConditionAvailable; -import lombok.Getter; - -@Getter -public enum PayType implements SearchConditionAvailable { - - CASH("현금"), - CARD("카드"), - BANK_TRANSFER("계좌"), - NO_INFO("정보 없음"); - - private final String description; - - PayType(String description) { - this.description = description; - } - - @Override - public PayType getDefault() { - return NO_INFO; - } -} - diff --git a/src/main/java/com/example/parking/domain/parking/PayTypes.java b/src/main/java/com/example/parking/domain/parking/PayTypes.java deleted file mode 100644 index 83e64a3f..00000000 --- a/src/main/java/com/example/parking/domain/parking/PayTypes.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.Embeddable; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode -@Embeddable -public class PayTypes { - - public static final PayTypes DEFAULT = new PayTypes(PayType.NO_INFO.getDescription()); - private static final String DELIMITER = ", "; - - private String description; - - private PayTypes(String description) { - this.description = description; - } - - public static PayTypes from(Collection payTypes) { - if (payTypes.contains(PayType.NO_INFO)) { - return DEFAULT; - } - - return new PayTypes(payTypes.stream() - .map(PayType::getDescription) - .sorted() - .collect(Collectors.joining(DELIMITER)) - ); - } - - public boolean contains(List memberPayTypes) { - if (this.description.equals(DEFAULT.description)) { - return true; - } - return memberPayTypes.stream() - .anyMatch(payType -> this.description.contains(payType.getDescription())); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/SearchingCondition.java b/src/main/java/com/example/parking/domain/parking/SearchingCondition.java deleted file mode 100644 index 820ddb7a..00000000 --- a/src/main/java/com/example/parking/domain/parking/SearchingCondition.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.parking.domain.parking; - -import com.example.parking.domain.searchcondition.FeeType; -import java.util.List; -import lombok.Getter; - -@Getter -public class SearchingCondition { - - private final List operationTypes; - private final List parkingTypes; - private final List payTypes; - private final FeeType feeType; - private final Integer hours; - - public SearchingCondition(List operationTypes, List parkingTypes, - List payTypes, - FeeType feeType, Integer hours) { - this.operationTypes = operationTypes; - this.parkingTypes = parkingTypes; - this.payTypes = payTypes; - this.feeType = feeType; - this.hours = hours; - } -} diff --git a/src/main/java/com/example/parking/domain/parking/Space.java b/src/main/java/com/example/parking/domain/parking/Space.java deleted file mode 100644 index addbc039..00000000 --- a/src/main/java/com/example/parking/domain/parking/Space.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Embeddable -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Space { - - private static final Integer NO_PROVIDE = -1; - - private Integer capacity; - private Integer currentParking; - - private Space(Integer capacity, Integer currentParking) { - this.capacity = capacity; - this.currentParking = currentParking; - } - - public static Space of(String capacity, String currentParking) { - return new Space(parseInt(capacity), parseInt(currentParking)); - } - - private static Integer parseInt(String number) { - try { - return Integer.parseInt(number); - } catch (NumberFormatException e) { - return NO_PROVIDE; - } - } - - public static Space of(Integer capacity, Integer currentParking) { - if (capacity < 0) { - capacity = NO_PROVIDE; - } - if (currentParking < 0) { - currentParking = NO_PROVIDE; - } - return new Space(capacity, currentParking); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/TimeInfo.java b/src/main/java/com/example/parking/domain/parking/TimeInfo.java deleted file mode 100644 index 3934fd96..00000000 --- a/src/main/java/com/example/parking/domain/parking/TimeInfo.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.Embeddable; -import java.time.LocalTime; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Embeddable -public class TimeInfo { - - public static final TimeInfo CLOSED = new TimeInfo(LocalTime.MIN, LocalTime.MIN); - public static final TimeInfo ALL_DAY = new TimeInfo(LocalTime.MIN, LocalTime.MAX); - - private LocalTime beginTime; - private LocalTime endTime; - - public TimeInfo(LocalTime beginTime, LocalTime endTime) { - this.beginTime = beginTime; - this.endTime = endTime; - } - - public int calculateOverlapMinutes(LocalTime beginTime, LocalTime endTime) { - if (this.endTime.isBefore(this.beginTime)) { - TimeInfo today = new TimeInfo(this.beginTime, LocalTime.MAX); - TimeInfo tomorrow = new TimeInfo(LocalTime.MIN, this.endTime); - return today.calculateOverlapMinutes(beginTime, endTime) + tomorrow.calculateOverlapMinutes(beginTime, - endTime); - } - LocalTime overlapBeginTime = decideOverlapBeginTime(beginTime); - LocalTime overlapEndTime = decideOverlapEndTime(endTime); - int overlapMinutes = calculateBetweenMinutes(overlapBeginTime, overlapEndTime); - return Math.max(0, overlapMinutes); - } - - private LocalTime decideOverlapBeginTime(LocalTime beginTime) { - if (beginTime.isAfter(this.beginTime)) { - return beginTime; - } - return this.beginTime; - } - - private LocalTime decideOverlapEndTime(LocalTime endTime) { - if (endTime.isBefore(this.endTime)) { - return endTime; - } - return this.endTime; - } - - private int calculateBetweenMinutes(LocalTime beginTime, LocalTime endTime) { - return calculateMinutes(endTime) - calculateMinutes(beginTime); - } - - private int calculateMinutes(LocalTime localTime) { - if (localTime.equals(LocalTime.MAX)) { - return localTime.getHour() * 60 + localTime.getMinute() + 1; - } - return localTime.getHour() * 60 + localTime.getMinute(); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/TimeUnit.java b/src/main/java/com/example/parking/domain/parking/TimeUnit.java deleted file mode 100644 index f98814b9..00000000 --- a/src/main/java/com/example/parking/domain/parking/TimeUnit.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.example.parking.domain.parking; - -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Embeddable -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter -public class TimeUnit { - - private static final TimeUnit NO_INFO = new TimeUnit(-1); - - private int timeUnit; - - private TimeUnit(int timeUnit) { - this.timeUnit = timeUnit; - } - - public static TimeUnit from(int timeUnit) { - if (timeUnit == 0) { - return NO_INFO; - } - return new TimeUnit(timeUnit); - } - - public static TimeUnit from(String timeUnit) { - try { - return TimeUnit.from(Integer.parseInt(timeUnit)); - } catch (NumberFormatException | NullPointerException e) { - return NO_INFO; - } - } - - public boolean isEqualOrGreaterThan(int other) { - return timeUnit >= other; - } - - public int calculateQuotient(int minutes) { - if (minutes <= 0) { - return 0; - } - return (minutes - 1) / timeUnit + 1; - } - - public boolean isValidTimeUnit() { - return !NO_INFO.equals(this); - } -} diff --git a/src/main/java/com/example/parking/domain/parking/dto/ParkingQueryCondition.java b/src/main/java/com/example/parking/domain/parking/dto/ParkingQueryCondition.java deleted file mode 100644 index 3e40c896..00000000 --- a/src/main/java/com/example/parking/domain/parking/dto/ParkingQueryCondition.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.parking.domain.parking.dto; - -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayTypes; -import lombok.Getter; - -@Getter -public class ParkingQueryCondition { - - private OperationType operationType; - private ParkingType parkingType; - private Boolean cardEnabled; - private PayTypes payTypes; - - public ParkingQueryCondition(OperationType operationType, ParkingType parkingType, Boolean cardEnabled, - PayTypes payTypes) { - this.operationType = operationType; - this.parkingType = parkingType; - this.cardEnabled = cardEnabled; - this.payTypes = payTypes; - } -} diff --git a/src/main/java/com/example/parking/domain/parking/repository/ParkingRepository.java b/src/main/java/com/example/parking/domain/parking/repository/ParkingRepository.java deleted file mode 100644 index d7a79aba..00000000 --- a/src/main/java/com/example/parking/domain/parking/repository/ParkingRepository.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.example.parking.domain.parking.repository; - -import com.example.parking.domain.parking.Parking; -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import org.locationtech.jts.geom.Point; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.Param; - -public interface ParkingRepository extends Repository { - - default Parking getById(Long id) { - return findById(id).orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_PARKING)); - } - - Optional findById(Long id); - - @Query(""" - SELECT p - FROM Parking p - WHERE ST_Contains(ST_Buffer(:point, :radius), p.location.point) - """ - ) - List findAroundParkingLots(@Param("point") Point point, @Param("radius") int radius); - - @Query(""" - SELECT p - FROM Parking p - WHERE ST_Contains(ST_Buffer(:point, :radius), p.location.point) - ORDER BY ST_DISTANCE_SPHERE(:point, p.location.point) - """ - ) - List findAroundParkingLotsOrderByDistance( - @Param("point") Point point, - @Param("radius") int radius - ); - - Set findAllByBaseInformationNameIn(Set parkingNames); - - void saveAll(Iterable parkingLots); -} diff --git a/src/main/java/com/example/parking/domain/review/Content.java b/src/main/java/com/example/parking/domain/review/Content.java deleted file mode 100644 index 83dc5290..00000000 --- a/src/main/java/com/example/parking/domain/review/Content.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.example.parking.domain.review; - -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.Arrays; -import lombok.Getter; - -@Getter -public enum Content { - - LOTS_OF_PARKING_SPOTS("주차 자리가 많아요"), - GOOD_CONDITION("깔끔하고 관리가 잘 되어 있어요"), - GOOD_CONSIDERATE_SPOT("주차 배려석이 잘 되어 있어요"), - LOTS_OF_CHARGING_SPOTS("전기차 충전석이 많아요"), - LARGE_PARKING_SPACE("주차석이 널널해서 주차가 편해요"), - CLOSE_TO_MAIN_LOAD("큰 길과 가까워요"), - GOOD_ACCESSIBILITY("접근성이 좋아요"), - EASY_TO_PAY("결제가 편리해요"), - FRIENDLY_STAFF("직원이 친절해요"), - LOW_PRICE("가격이 저렴해요"); - - private final String description; - - Content(String description) { - this.description = description; - } - - public static Content find(String description) { - return Arrays.stream(values()) - .filter(content -> content.getDescription().startsWith(description)) - .findAny() - .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_CONTENT)); - } -} diff --git a/src/main/java/com/example/parking/domain/review/Review.java b/src/main/java/com/example/parking/domain/review/Review.java deleted file mode 100644 index 451f559a..00000000 --- a/src/main/java/com/example/parking/domain/review/Review.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.example.parking.domain.review; - -import com.example.parking.infra.converter.ContentConverter; -import com.example.parking.support.Association; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; -import jakarta.persistence.Convert; -import jakarta.persistence.Embedded; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import java.time.LocalDateTime; -import java.util.List; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -public class Review { - - private static final int MAX_CONTENTS_SIZE = 3; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "parking_id")) - private Association parkingId; - - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "reviewer_id")) - private Association reviewerId; - - @Convert(converter = ContentConverter.class) - private List contents; - - @Column(updatable = false) - private LocalDateTime createdAt; - - public Review(Association parkingId, Association reviewerId, List contents) { - validate(contents); - this.parkingId = parkingId; - this.reviewerId = reviewerId; - this.contents = contents; - this.createdAt = LocalDateTime.now(); - } - - private static void validate(List contents) { - if (contents == null || contents.isEmpty() || contents.size() > MAX_CONTENTS_SIZE) { - throw new DomainException(ExceptionInformation.INVALID_CONTENTS_SIZE); - } - } -} diff --git a/src/main/java/com/example/parking/domain/review/ReviewRepository.java b/src/main/java/com/example/parking/domain/review/ReviewRepository.java deleted file mode 100644 index 5b35b444..00000000 --- a/src/main/java/com/example/parking/domain/review/ReviewRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.parking.domain.review; - -import com.example.parking.support.Association; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.List; -import java.util.Optional; -import org.springframework.data.repository.Repository; - -public interface ReviewRepository extends Repository { - - Optional findById(Long id); - - default Review getById(Long id) { - return findById(id) - .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_REVIEW)); - } - - List findAllByParkingId(Association parkingId); - - void save(Review review); - - boolean existsByParkingIdAndReviewerId(Association parkingId, Association reviewerId); -} diff --git a/src/main/java/com/example/parking/domain/review/service/ReviewDomainService.java b/src/main/java/com/example/parking/domain/review/service/ReviewDomainService.java deleted file mode 100644 index 2e2672a3..00000000 --- a/src/main/java/com/example/parking/domain/review/service/ReviewDomainService.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.parking.domain.review.service; - -import com.example.parking.support.Association; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.review.Content; -import com.example.parking.domain.review.Review; -import com.example.parking.domain.review.ReviewRepository; -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - -@RequiredArgsConstructor -@Component -public class ReviewDomainService { - - private final ReviewRepository reviewRepository; - - public void validateDuplicateReview(Association parkingId, Association reviewerId) { - if (reviewRepository.existsByParkingIdAndReviewerId(parkingId, reviewerId)) { - throw new DomainException(ExceptionInformation.DUPLICATE_REVIEW); - } - } - - public Map collectByContent(List reviews) { - return reviews.stream() - .map(Review::getContents) - .flatMap(Collection::stream) - .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); - } - - public int calculateTotalReviews(Map counts) { - return counts.values().stream() - .mapToInt(Long::intValue) - .sum(); - } -} diff --git a/src/main/java/com/example/parking/domain/searchcondition/FeeType.java b/src/main/java/com/example/parking/domain/searchcondition/FeeType.java deleted file mode 100644 index 75176b27..00000000 --- a/src/main/java/com/example/parking/domain/searchcondition/FeeType.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import lombok.Getter; - -@Getter -public enum FeeType implements SearchConditionAvailable { - - FREE("무료"), PAID("유료"), NO_INFO("정보 없음"); - - private final String description; - - FeeType(String description) { - this.description = description; - } - - @Override - public FeeType getDefault() { - return NO_INFO; - } -} diff --git a/src/main/java/com/example/parking/domain/searchcondition/Hours.java b/src/main/java/com/example/parking/domain/searchcondition/Hours.java deleted file mode 100644 index 9f001d70..00000000 --- a/src/main/java/com/example/parking/domain/searchcondition/Hours.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Embeddable -public class Hours { - - private int hours; - - private Hours(int hours) { - this.hours = hours; - } - - public static Hours from(int hours) { - if ((hours >= 1 && hours <= 12) || hours == 24) { - return new Hours(hours); - } - throw new DomainException(ExceptionInformation.INVALID_HOURS); - } -} diff --git a/src/main/java/com/example/parking/domain/searchcondition/Priority.java b/src/main/java/com/example/parking/domain/searchcondition/Priority.java deleted file mode 100644 index 256bf6d5..00000000 --- a/src/main/java/com/example/parking/domain/searchcondition/Priority.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import lombok.Getter; - -@Getter -public enum Priority implements SearchConditionAvailable { - - DISTANCE("가까운순"), - PRICE("가격순"), - RECOMMENDATION("추천순"); - - private final String description; - - Priority(String description) { - this.description = description; - } - - @Override - public Priority getDefault() { - return RECOMMENDATION; - } -} diff --git a/src/main/java/com/example/parking/domain/searchcondition/SearchCondition.java b/src/main/java/com/example/parking/domain/searchcondition/SearchCondition.java deleted file mode 100644 index 9b55c910..00000000 --- a/src/main/java/com/example/parking/domain/searchcondition/SearchCondition.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayType; -import com.example.parking.infra.converter.FeeTypeConverter; -import com.example.parking.infra.converter.OperationTypeConverter; -import com.example.parking.infra.converter.ParkingTypeConverter; -import com.example.parking.infra.converter.PayTypeConverter; -import com.example.parking.support.Association; -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; -import jakarta.persistence.Convert; -import jakarta.persistence.Embedded; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import java.util.List; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Entity -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class SearchCondition { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "member_id")) - private Association memberId; - - @Convert(converter = OperationTypeConverter.class) - private List operationTypes; - - @Convert(converter = ParkingTypeConverter.class) - private List parkingTypes; - - @Convert(converter = FeeTypeConverter.class) - private List feeTypes; - - @Convert(converter = PayTypeConverter.class) - private List payTypes; - - @Enumerated(EnumType.STRING) - private Priority priority; - - @Embedded - private Hours hours; - - public SearchCondition(Association memberId, List operationTypes, - List parkingTypes, - List feeTypes, List payTypes, Priority priority, Hours hours) { - this.memberId = memberId; - this.operationTypes = operationTypes; - this.parkingTypes = parkingTypes; - this.feeTypes = feeTypes; - this.payTypes = payTypes; - this.priority = priority; - this.hours = hours; - } - - public void update(SearchCondition updated) { - this.operationTypes = updated.operationTypes; - this.parkingTypes = updated.parkingTypes; - this.feeTypes = updated.feeTypes; - this.payTypes = updated.payTypes; - this.priority = updated.priority; - this.hours = updated.hours; - } -} diff --git a/src/main/java/com/example/parking/domain/searchcondition/SearchConditionAvailable.java b/src/main/java/com/example/parking/domain/searchcondition/SearchConditionAvailable.java deleted file mode 100644 index affea042..00000000 --- a/src/main/java/com/example/parking/domain/searchcondition/SearchConditionAvailable.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.example.parking.domain.searchcondition; - -public interface SearchConditionAvailable { - - String getDescription(); - - E getDefault(); -} diff --git a/src/main/java/com/example/parking/domain/searchcondition/SearchConditionRepository.java b/src/main/java/com/example/parking/domain/searchcondition/SearchConditionRepository.java deleted file mode 100644 index 5d3f3aac..00000000 --- a/src/main/java/com/example/parking/domain/searchcondition/SearchConditionRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.Optional; -import org.springframework.data.repository.Repository; - -public interface SearchConditionRepository extends Repository { - - Optional findByMemberId(Long memberId); - - default SearchCondition getByMemberId(Long memberId) { - return findByMemberId(memberId) - .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_SEARCH_CONDITION)); - } - - void save(SearchCondition searchCondition); -} diff --git a/src/main/java/com/example/parking/external/config/RedisConfig.java b/src/main/java/com/example/parking/external/config/RedisConfig.java deleted file mode 100644 index 40fe88b3..00000000 --- a/src/main/java/com/example/parking/external/config/RedisConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.example.parking.external.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.serializer.StringRedisSerializer; - -@Configuration -public class RedisConfig { - - @Value("${spring.data.redis.host}") - private String host; - - @Value("${spring.data.redis.port}") - private Integer port; - - @Bean - public RedisConnectionFactory redisConnectionFactory() { - return new LettuceConnectionFactory(host, port); - } - - @Primary - @Bean - public RedisTemplate redisTemplate() { - RedisTemplate redisTemplate = new RedisTemplate<>(); - redisTemplate.setConnectionFactory(redisConnectionFactory()); - redisTemplate.setKeySerializer(new StringRedisSerializer()); - redisTemplate.setValueSerializer(new StringRedisSerializer()); - return redisTemplate; - } -} diff --git a/src/main/java/com/example/parking/external/coordinate/CoordinateErrorHandler.java b/src/main/java/com/example/parking/external/coordinate/CoordinateErrorHandler.java deleted file mode 100644 index 56806996..00000000 --- a/src/main/java/com/example/parking/external/coordinate/CoordinateErrorHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.parking.external.coordinate; - -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.ExceptionInformation; -import java.io.IOException; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.ResponseErrorHandler; - -@Slf4j -public class CoordinateErrorHandler implements ResponseErrorHandler { - - @Override - public boolean hasError(ClientHttpResponse response) throws IOException { - return response.getStatusCode().isError(); - } - - @Override - public void handleError(ClientHttpResponse response) throws IOException { - log.warn("fail while extracting coordinate by address code: {}", response.getStatusCode()); - throw new ClientException(ExceptionInformation.COORDINATE_EXCEPTION); - } -} diff --git a/src/main/java/com/example/parking/external/coordinate/CoordinateService.java b/src/main/java/com/example/parking/external/coordinate/CoordinateService.java deleted file mode 100644 index ca6abd81..00000000 --- a/src/main/java/com/example/parking/external/coordinate/CoordinateService.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.example.parking.external.coordinate; - -import com.example.parking.external.coordinate.dto.CoordinateResponse; -import com.example.parking.external.coordinate.dto.CoordinateResponse.ExactLocation; -import com.example.parking.domain.parking.Location; -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -@Component -public class CoordinateService { - - private static final String KAKAO_URL = "https://dapi.kakao.com/v2/local/search/address.json"; - - private final RestTemplate restTemplate; - - @Autowired - public CoordinateService(@Qualifier("coordinateRestTemplate") RestTemplate restTemplate) { - this.restTemplate = restTemplate; - } - - public Location extractLocationByAddress(String address, Location location) { - UriComponents uriComponents = makeCompleteUri(address); - ResponseEntity result = connect(uriComponents); - - if (isEmptyResultData(result)) { - return location; - } - - ExactLocation exactLocation = getExactLocation(result); - return Location.of(exactLocation.getLongitude(), exactLocation.getLatitude()); - } - - private ExactLocation getExactLocation(ResponseEntity result) { - List exactLocations = result.getBody().getExactLocations(); - return exactLocations.get(0); - } - - private ResponseEntity connect(UriComponents uriComponents) { - return restTemplate.getForEntity( - uriComponents.toString(), - CoordinateResponse.class - ); - } - - private UriComponents makeCompleteUri(String address) { - return UriComponentsBuilder - .fromHttpUrl(KAKAO_URL) - .queryParam("query", address) - .build(); - } - - private boolean isEmptyResultData(ResponseEntity result) { - Integer matchingDataCount = result.getBody().getMeta().getTotalCount(); - return matchingDataCount == 0; - } -} diff --git a/src/main/java/com/example/parking/external/coordinate/dto/CoordinateResponse.java b/src/main/java/com/example/parking/external/coordinate/dto/CoordinateResponse.java deleted file mode 100644 index 9de28a14..00000000 --- a/src/main/java/com/example/parking/external/coordinate/dto/CoordinateResponse.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.example.parking.external.coordinate.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class CoordinateResponse { - - @JsonProperty("documents") - private List exactLocations; - - @JsonProperty("meta") - private Meta meta; - - public CoordinateResponse(List exactLocations, Meta meta) { - this.exactLocations = exactLocations; - this.meta = meta; - } - - @NoArgsConstructor - @Getter - public static class ExactLocation { - - @JsonProperty("x") - private Double longitude; - - @JsonProperty("y") - private Double latitude; - } - - @Getter - @NoArgsConstructor - public static class Meta { - - @JsonProperty("total_count") - private Integer totalCount; - - public Meta(Integer totalCount) { - this.totalCount = totalCount; - } - } -} diff --git a/src/main/java/com/example/parking/external/parkingapi/ParkingApiService.java b/src/main/java/com/example/parking/external/parkingapi/ParkingApiService.java deleted file mode 100644 index e7f4989a..00000000 --- a/src/main/java/com/example/parking/external/parkingapi/ParkingApiService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.parking.external.parkingapi; - -import com.example.parking.domain.parking.Parking; -import java.util.List; - -public interface ParkingApiService { - - default boolean offerCurrentParking() { - return false; - } - - List read() throws Exception; -} diff --git a/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingAdapter.java b/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingAdapter.java deleted file mode 100644 index 732696b1..00000000 --- a/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingAdapter.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.example.parking.external.parkingapi.pusan; - -import static com.example.parking.external.parkingapi.pusan.PusanPublicParkingResponse.ParkingInfo.*; - -import com.example.parking.domain.parking.BaseInformation; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.FeePolicy; -import com.example.parking.domain.parking.FreeOperatingTime; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.OperatingTime; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayTypes; -import com.example.parking.domain.parking.Space; -import com.example.parking.domain.parking.TimeInfo; -import com.example.parking.domain.parking.TimeUnit; -import java.time.DateTimeException; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import org.springframework.stereotype.Component; - -@Component -public class PusanPublicParkingAdapter { - - private static final String EMPTY = "-"; - private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); - private static final String HOURS_24 = "24:00"; - - public List convert(PusanPublicParkingResponse response) { - return response.getGetParkingInfoDetails().getBody().getItems().getItem() - .stream().map(this::toParking) - .toList(); - } - - private Parking toParking(final Item response) { - return new Parking( - getBaseInformation(response), - getLocation(response), - getSpace(response), - getFreeOperatingTime(response), - getOperatingTime(response), - getFeePolicy(response) - ); - } - - private BaseInformation getBaseInformation(final Item response) { - return new BaseInformation( - response.getParkingName(), - response.getTelephoneNumber(), - filterAddress(response), - PayTypes.DEFAULT, - ParkingType.find(response.getParkingTypeNM()), - OperationType.PUBLIC - ); - } - - private String filterAddress(Item response) { - if (response.getOldAddress().equals(EMPTY)) { - return response.getNewAddress(); - } - return response.getOldAddress(); - } - - private Location getLocation(final Item response) { - return Location.of(response.getLongitude(), response.getLatitude()); - } - - private Space getSpace(final Item response) { - return Space.of(response.getCapacity(), response.getCurParking()); - } - - private OperatingTime getOperatingTime(final Item response) { - return new OperatingTime( - new TimeInfo(parsingOperationTime(response.getWeekdayBeginTime()), - parsingOperationTime(response.getWeekdayEndTime())), - new TimeInfo(parsingOperationTime(response.getWeekendBeginTime()), - parsingOperationTime(response.getWeekendEndTime())), - new TimeInfo(parsingOperationTime(response.getHolidayBeginTime()), - parsingOperationTime(response.getHolidayEndTime())) - ); - } - - private LocalTime parsingOperationTime(String time) { - if (time.equals(HOURS_24)) { - return LocalTime.MAX; - } - try { - return LocalTime.parse(time, TIME_FORMATTER); - } catch (DateTimeException e) { - return null; - } - } - - private FeePolicy getFeePolicy(final Item response) { - return new FeePolicy( - Fee.from(response.getRates()), - Fee.from(response.getAddRates()), - TimeUnit.from(response.getTimeRate()), - TimeUnit.from(response.getAddTimeRate()), - Fee.from(response.getDayMaximum()) - ); - } - - private FreeOperatingTime getFreeOperatingTime(final Item response) { - if (response.getRates().equals("0") && response.getAddRates().equals("0")) { - return FreeOperatingTime.ALWAYS_FREE; - } - return FreeOperatingTime.ALWAYS_PAY; - } -} diff --git a/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingApiService.java b/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingApiService.java deleted file mode 100644 index 099d8b6b..00000000 --- a/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingApiService.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.example.parking.external.parkingapi.pusan; - -import com.example.parking.domain.parking.Parking; -import com.example.parking.external.parkingapi.ParkingApiService; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.List; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.UriComponentsBuilder; - -@Component -public class PusanPublicParkingApiService implements ParkingApiService { - - private static final String URL = "http://apis.data.go.kr/6260000/BusanPblcPrkngInfoService/getPblcPrkngInfo"; - private static final String RESULT_TYPE = "json"; - private static final int SIZE = 1000; - - @Value("${pusan-public-parking-key}") - private String API_KEY; - - private final PusanPublicParkingAdapter adapter; - private final RestTemplate restTemplate; - - public PusanPublicParkingApiService(PusanPublicParkingAdapter adapter, - @Qualifier("parkingApiRestTemplate") RestTemplate restTemplate) { - this.adapter = adapter; - this.restTemplate = restTemplate; - } - - @Override - public List read() throws Exception { - PusanPublicParkingResponse response = call(1, SIZE); - return adapter.convert(response); - } - - private PusanPublicParkingResponse call(int startIndex, int size) { - URI uri = makeUri(startIndex, size); - ResponseEntity response = restTemplate.getForEntity(uri, - PusanPublicParkingResponse.class); - return response.getBody(); - } - - private URI makeUri(int startIndex, int size) { - return UriComponentsBuilder - .fromHttpUrl(URL) - .queryParam("ServiceKey", API_KEY) - .queryParam("pageNo", startIndex) - .queryParam("numOfRows", size) - .queryParam("resultType", RESULT_TYPE) - .encode(StandardCharsets.UTF_8) - .build() - .toUri(); - } - - @Override - public boolean offerCurrentParking() { - return true; - } -} diff --git a/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingResponse.java b/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingResponse.java deleted file mode 100644 index 392053f5..00000000 --- a/src/main/java/com/example/parking/external/parkingapi/pusan/PusanPublicParkingResponse.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.example.parking.external.parkingapi.pusan; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import lombok.Getter; - -@Getter -public class PusanPublicParkingResponse { - - @JsonProperty("getPblcPrkngInfo") - private ParkingInfo getParkingInfoDetails; - - @Getter - public static class ParkingInfo { - private Body body; - - @Getter - public static class Body { - private Items items; - } - - @Getter - public static class Items { - private List item; - } - - @Getter - public static class Item { - - @JsonProperty("pkNam") - private String parkingName; - - @JsonProperty("pkFm") - private String parkingTypeNM; - - @JsonProperty("tponNum") - private String telephoneNumber; - - - @JsonProperty("doroAddr") - private String newAddress; - - @JsonProperty("jibunAddr") - private String oldAddress; - - @JsonProperty("xCdnt") - private String latitude; - - @JsonProperty("yCdnt") - private String longitude; - - - @JsonProperty("pkCnt") - private String capacity; - - @JsonProperty("currava") - private String curParking; - - - @JsonProperty("svcSrtTe") - private String weekdayBeginTime; - - @JsonProperty("svcEndTe") - private String weekdayEndTime; - - @JsonProperty("satSrtTe") - private String weekendBeginTime; - - @JsonProperty("satEndTe") - private String weekendEndTime; - - @JsonProperty("hldSrtTe") - private String holidayBeginTime; - - @JsonProperty("hldEndTe") - private String holidayEndTime; - - - @JsonProperty("feeInfo") - private String payNM; - - @JsonProperty("tenMin") - private String rates; - - @JsonProperty("pkBascTime") - private String timeRate; - - @JsonProperty("feeAdd") - private String addRates; - - @JsonProperty("pkAddTime") - private String addTimeRate; - - @JsonProperty("ftDay") - private String dayMaximum; - } - } -} diff --git a/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingAdapter.java b/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingAdapter.java deleted file mode 100644 index 640f663c..00000000 --- a/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingAdapter.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.example.parking.external.parkingapi.seoul; - -import com.example.parking.domain.parking.BaseInformation; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.FeePolicy; -import com.example.parking.domain.parking.FreeOperatingTime; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.OperatingTime; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayTypes; -import com.example.parking.domain.parking.Space; -import com.example.parking.domain.parking.TimeInfo; -import com.example.parking.domain.parking.TimeUnit; -import com.example.parking.external.parkingapi.seoul.SeoulPublicParkingResponse.ParkingInfo.SeoulCityParking; -import java.time.DateTimeException; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import org.springframework.stereotype.Component; - -@Component -public class SeoulPublicParkingAdapter { - - private static final Set TIMED_PARKING_RULES = Set.of("1", "3", "5"); - private static final String STREET_PARKING_TYPE = "노상 주차장"; - private static final String FREE = "무료"; - private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmm"); - private static final String HOURS_24 = "2400"; - - public List convert(SeoulPublicParkingResponse response) { - List rows = response.getParkingInfo().getRows(); - List seoulCityParkingLots = calculateCapacity(filterByOperation(rows)); - - return seoulCityParkingLots.stream() - .map(this::toParking) - .toList(); - } - - private List filterByOperation(final List rows) { - return rows.stream() - .filter(result -> TIMED_PARKING_RULES.contains(result.getOperationRule())) - .toList(); - } - - private List calculateCapacity(final List results) { - final Map> collect = results.stream() - .collect(Collectors.groupingBy(a -> a.getParkingCode())); - - return collect.values().stream().map(parkingLots -> { - final SeoulCityParking parking = parkingLots.get(0); - if (parking.getParkingTypeNM().equals(STREET_PARKING_TYPE)) { - parking.setCapacity(parkingLots.size()); - return parking; - } - return parking; - }).toList(); - } - - private Parking toParking(final SeoulCityParking response) { - return new Parking( - getBaseInformation(response), - getLocation(response), - getSpace(response), - getFreeOperatingTime(response), - getOperatingTime(response), - getFeePolicy(response) - ); - } - - private BaseInformation getBaseInformation(final SeoulCityParking response) { - return new BaseInformation( - response.getParkingName(), - response.getTel(), - response.getAddr(), - PayTypes.DEFAULT, - ParkingType.find(response.getParkingTypeNM()), - OperationType.PUBLIC - ); - } - - private Location getLocation(final SeoulCityParking response) { - return Location.of(response.getLng(), response.getLat()); - } - - private Space getSpace(final SeoulCityParking response) { - return Space.of( - response.getCapacity(), - response.getCurParking() - ); - } - - private FreeOperatingTime getFreeOperatingTime(SeoulCityParking response) { - if (response.getPayNM().equals(FREE)) { - return FreeOperatingTime.ALWAYS_FREE; - } - return new FreeOperatingTime( - TimeInfo.CLOSED, - response.getSaturdayPayNM().equals(FREE) ? TimeInfo.ALL_DAY : TimeInfo.CLOSED, - response.getHolidayPayNM().equals(FREE) ? TimeInfo.ALL_DAY : TimeInfo.CLOSED - ); - } - - private OperatingTime getOperatingTime(final SeoulCityParking response) { - return new OperatingTime( - new TimeInfo( - parsingOperationTime(response.getWeekdayBeginTime()), - parsingOperationTime(response.getWeekdayEndTime()) - ), - new TimeInfo( - parsingOperationTime(response.getWeekendBeginTime()), - parsingOperationTime(response.getWeekendEndTime()) - ), - new TimeInfo( - parsingOperationTime(response.getHolidayBeginTime()), - parsingOperationTime(response.getHolidayEndTime()) - ) - ); - } - - private LocalTime parsingOperationTime(String time) { - if (time.equals(HOURS_24)) { - return LocalTime.MAX; - } - try { - return LocalTime.parse(time, TIME_FORMATTER); - } catch (DateTimeException e) { - return null; - } - } - - private FeePolicy getFeePolicy(final SeoulCityParking response) { - return new FeePolicy( - Fee.from(response.getRates()), - Fee.from(response.getAddRates()), - TimeUnit.from(response.getTimeRate()), - TimeUnit.from(response.getAddTimeRate()), - Fee.from(response.getDayMaximum()) - ); - } -} diff --git a/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingApiService.java b/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingApiService.java deleted file mode 100644 index 1e2a4bb3..00000000 --- a/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingApiService.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.example.parking.external.parkingapi.seoul; - -import com.example.parking.domain.parking.Parking; -import com.example.parking.external.parkingapi.ParkingApiService; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.UriComponentsBuilder; - -@Component -public class SeoulPublicParkingApiService implements ParkingApiService { - - private static final String URL = "http://openapi.seoul.go.kr:8088"; - private static final String API_NAME = "GetParkingInfo"; - private static final String RESULT_TYPE = "json"; - private static final int SIZE = 1000; - - @Value("${seoul-public-parking-key}") - private String API_KEY; - - private final SeoulPublicParkingAdapter adapter; - private final RestTemplate restTemplate; - - public SeoulPublicParkingApiService(SeoulPublicParkingAdapter adapter, - @Qualifier("parkingApiRestTemplate") RestTemplate restTemplate) { - this.adapter = adapter; - this.restTemplate = restTemplate; - } - - @Override - public List read() throws Exception { - List response = call(); - return response.stream() - .map(adapter::convert) - .flatMap(Collection::stream) - .toList(); - } - - private List call() { - List result = new LinkedList<>(); - for (int i = 0; i < 2 * SIZE; i += SIZE) { - URI uri = makeUri(String.valueOf(i), String.valueOf(i + SIZE - 1)); - - ResponseEntity response = restTemplate.getForEntity(uri, - SeoulPublicParkingResponse.class); - result.add(response.getBody()); - } - return Collections.unmodifiableList(result); - } - - private URI makeUri(String startIndex, String endIndex) { - return UriComponentsBuilder - .fromHttpUrl(URL) - .pathSegment(API_KEY, RESULT_TYPE, API_NAME, startIndex, endIndex) - .encode(StandardCharsets.UTF_8) - .build() - .toUri(); - } - - @Override - public boolean offerCurrentParking() { - return true; - } -} diff --git a/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingResponse.java b/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingResponse.java deleted file mode 100644 index f51555b4..00000000 --- a/src/main/java/com/example/parking/external/parkingapi/seoul/SeoulPublicParkingResponse.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.example.parking.external.parkingapi.seoul; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import java.util.List; -import lombok.Getter; - -@Getter -public class SeoulPublicParkingResponse { - - @JsonProperty("GetParkingInfo") - private ParkingInfo parkingInfo; - - @Getter - public static class ParkingInfo { - - @JsonProperty("row") - private List rows; - - @Getter - @JsonNaming(value = PropertyNamingStrategies.UpperSnakeCaseStrategy.class) - public static class SeoulCityParking { - - private String parkingCode; - private String parkingName; - private String parkingTypeNM; - private String operationRule; - private String tel; - - private String addr; - private String lat; - private String lng; - - private Integer queStatus; - private Integer capacity; - private Integer curParking; - - private String payNM; - private String saturdayPayNM; - private String holidayPayNM; - private Integer rates; - private Integer timeRate; - private Integer addRates; - private Integer addTimeRate; - private Integer dayMaximum; - - private String weekdayBeginTime; - private String weekdayEndTime; - private String weekendBeginTime; - private String weekendEndTime; - private String holidayBeginTime; - private String holidayEndTime; - - public void setCapacity(int capacity) { - this.capacity = capacity; - } - } - } -} diff --git a/src/main/java/com/example/parking/external/scheduler/ParkingUpdateScheduler.java b/src/main/java/com/example/parking/external/scheduler/ParkingUpdateScheduler.java deleted file mode 100644 index 3de2c057..00000000 --- a/src/main/java/com/example/parking/external/scheduler/ParkingUpdateScheduler.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.example.parking.external.scheduler; - -import com.example.parking.application.parking.ParkingService; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.Parking; -import com.example.parking.external.coordinate.CoordinateService; -import com.example.parking.external.parkingapi.ParkingApiService; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -@Slf4j -@RequiredArgsConstructor -@Component -public class ParkingUpdateScheduler { - - private final List parkingApiServices; - private final CoordinateService coordinateService; - private final ParkingService parkingService; - - @Scheduled(cron = "0 */30 * * * *") - public void autoUpdateOfferCurrentParking() { - Map parkingLots = readBy(ParkingApiService::offerCurrentParking); - Map saved = findAllByName(parkingLots.keySet()); - updateSavedParkingLots(parkingLots, saved); - saveNewParkingLots(parkingLots, saved); - } - - private Map readBy(Predicate currentParkingAvailable) { - return parkingApiServices.stream() - .filter(currentParkingAvailable) - .map(this::read) - .flatMap(Collection::stream) - .collect(toParkingMap()); - } - - private List read(ParkingApiService parkingApiService) { - try { - return parkingApiService.read(); - } catch (Exception e) { - log.warn("Error while converting {} to Parking {}", parkingApiService.getClass(), e.getMessage()); - return Collections.emptyList(); - } - } - - private Collector> toParkingMap() { - return Collectors.toMap( - parking -> parking.getBaseInformation().getName(), - Function.identity(), - (existing, replacement) -> existing - ); - } - - private Map findAllByName(Set names) { - return parkingService.getParkingLots(names) - .stream() - .collect(toParkingMap()); - } - - private void updateSavedParkingLots(Map parkingLots, Map saved) { - for (String parkingName : saved.keySet()) { - Parking origin = saved.get(parkingName); - Parking updated = parkingLots.get(parkingName); - origin.update(updated); - } - } - - private void saveNewParkingLots(Map parkingLots, Map saved) { - List newParkingLots = parkingLots.keySet() - .stream() - .filter(parkingName -> !saved.containsKey(parkingName)) - .map(parkingLots::get) - .toList(); - updateLocation(newParkingLots); - parkingService.saveAll(newParkingLots); - } - - private void updateLocation(List newParkingLots) { - for (Parking parking : newParkingLots) { - Location locationByAddress = coordinateService.extractLocationByAddress(parking.getBaseInformation().getAddress(), - parking.getLocation()); - parking.update(locationByAddress); - } - } - - @Scheduled(fixedRate = 30, timeUnit = TimeUnit.DAYS) - public void autoUpdateNotOfferCurrentParking() { - Map parkingLots = readBy(parkingApiService -> !parkingApiService.offerCurrentParking()); - Map saved = findAllByName(parkingLots.keySet()); - updateSavedParkingLots(parkingLots, saved); - saveNewParkingLots(parkingLots, saved); - } -} diff --git a/src/main/java/com/example/parking/infra/converter/ContentConverter.java b/src/main/java/com/example/parking/infra/converter/ContentConverter.java deleted file mode 100644 index 742bff3c..00000000 --- a/src/main/java/com/example/parking/infra/converter/ContentConverter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.parking.infra.converter; - -import com.example.parking.domain.review.Content; -import jakarta.persistence.Converter; - -@Converter -public class ContentConverter extends EnumListConverter { - - protected ContentConverter() { - super(Content.class); - } -} diff --git a/src/main/java/com/example/parking/infra/converter/EnumListConverter.java b/src/main/java/com/example/parking/infra/converter/EnumListConverter.java deleted file mode 100644 index 1e5b91e6..00000000 --- a/src/main/java/com/example/parking/infra/converter/EnumListConverter.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.parking.infra.converter; - -import jakarta.persistence.AttributeConverter; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public abstract class EnumListConverter> implements AttributeConverter, String> { - - private static final String DELIMITER = ", "; - - private final Class enumClass; - - protected EnumListConverter(Class enumClass) { - this.enumClass = enumClass; - } - - @Override - public String convertToDatabaseColumn(List attribute) { - return attribute.stream() - .map(Enum::name) - .sorted() - .collect(Collectors.joining(DELIMITER)); - } - - @Override - public List convertToEntityAttribute(String dbData) { - return Arrays.stream(dbData.split(DELIMITER)) - .map(name -> Enum.valueOf(enumClass, name)) - .toList(); - } -} diff --git a/src/main/java/com/example/parking/infra/converter/FeeTypeConverter.java b/src/main/java/com/example/parking/infra/converter/FeeTypeConverter.java deleted file mode 100644 index 26292af6..00000000 --- a/src/main/java/com/example/parking/infra/converter/FeeTypeConverter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.parking.infra.converter; - -import com.example.parking.domain.searchcondition.FeeType; -import jakarta.persistence.Converter; - -@Converter -public class FeeTypeConverter extends EnumListConverter { - - public FeeTypeConverter() { - super(FeeType.class); - } -} diff --git a/src/main/java/com/example/parking/infra/converter/OperationTypeConverter.java b/src/main/java/com/example/parking/infra/converter/OperationTypeConverter.java deleted file mode 100644 index 452ace9c..00000000 --- a/src/main/java/com/example/parking/infra/converter/OperationTypeConverter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.parking.infra.converter; - -import com.example.parking.domain.parking.OperationType; -import jakarta.persistence.Converter; - -@Converter -public class OperationTypeConverter extends EnumListConverter { - - public OperationTypeConverter() { - super(OperationType.class); - } -} diff --git a/src/main/java/com/example/parking/infra/converter/ParkingTypeConverter.java b/src/main/java/com/example/parking/infra/converter/ParkingTypeConverter.java deleted file mode 100644 index 733a1f0f..00000000 --- a/src/main/java/com/example/parking/infra/converter/ParkingTypeConverter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.parking.infra.converter; - -import com.example.parking.domain.parking.ParkingType; -import jakarta.persistence.Converter; - -@Converter -public class ParkingTypeConverter extends EnumListConverter { - - public ParkingTypeConverter() { - super(ParkingType.class); - } -} diff --git a/src/main/java/com/example/parking/infra/converter/PayTypeConverter.java b/src/main/java/com/example/parking/infra/converter/PayTypeConverter.java deleted file mode 100644 index e4c683ae..00000000 --- a/src/main/java/com/example/parking/infra/converter/PayTypeConverter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.parking.infra.converter; - -import com.example.parking.domain.parking.PayType; -import jakarta.persistence.Converter; - -@Converter -public class PayTypeConverter extends EnumListConverter { - - public PayTypeConverter() { - super(PayType.class); - } -} diff --git a/src/main/java/com/example/parking/support/Association.java b/src/main/java/com/example/parking/support/Association.java deleted file mode 100644 index cbc52d8b..00000000 --- a/src/main/java/com/example/parking/support/Association.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.parking.support; - -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.springframework.util.Assert; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode(of = {"id"}) -@Embeddable -public class Association { - - private Long id; - - private Association(Long id) { - this.id = id; - } - - public static Association from(Long id) { - Assert.notNull(id, "Id는 null이 될 수 없습니다."); - return new Association<>(id); - } -} diff --git a/src/main/java/com/example/parking/support/controlleradvice/GlobalExceptionHandler.java b/src/main/java/com/example/parking/support/controlleradvice/GlobalExceptionHandler.java deleted file mode 100644 index f144b70a..00000000 --- a/src/main/java/com/example/parking/support/controlleradvice/GlobalExceptionHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.example.parking.support.controlleradvice; - -import static org.springframework.http.HttpStatus.BAD_REQUEST; -import static org.springframework.http.HttpStatus.UNAUTHORIZED; - -import com.example.parking.support.controlleradvice.dto.ExceptionResponse; -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.ExceptionInformation; -import com.example.parking.support.exception.DomainException; -import java.util.EnumMap; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -@Slf4j -@RestControllerAdvice -public class GlobalExceptionHandler { - - private final EnumMap exceptionInfoToHttpStatus = new EnumMap<>( - ExceptionInformation.class); - - public GlobalExceptionHandler() { - exceptionInfoToHttpStatus.put(ExceptionInformation.UNAUTHORIZED, UNAUTHORIZED); - } - - @ExceptionHandler(Exception.class) - public ResponseEntity handleException(final Exception e) { - final ExceptionResponse exceptionResponse = new ExceptionResponse("알지 못하는 예외 발생"); - log.error("알지 못하는 예외 발생", e); - - return ResponseEntity.internalServerError() - .body(exceptionResponse); - } - - @ExceptionHandler(DomainException.class) - public ResponseEntity handleServerException(final DomainException e) { - final ExceptionResponse exceptionResponse = new ExceptionResponse(e.getMessage()); - log.error(e.getMessage(), e); - - return ResponseEntity.internalServerError() - .body(exceptionResponse); - } - - @ExceptionHandler(ClientException.class) - public ResponseEntity handleClientException(final ClientException e) { - final ExceptionResponse exceptionResponse = new ExceptionResponse(e.getMessage()); - - final HttpStatus httpStatus = exceptionInfoToHttpStatus.getOrDefault(e.getExceptionInformation(), BAD_REQUEST); - - return ResponseEntity.status(httpStatus) - .body(exceptionResponse); - } -} diff --git a/src/main/java/com/example/parking/support/controlleradvice/dto/ExceptionResponse.java b/src/main/java/com/example/parking/support/controlleradvice/dto/ExceptionResponse.java deleted file mode 100644 index 7ee9cf6a..00000000 --- a/src/main/java/com/example/parking/support/controlleradvice/dto/ExceptionResponse.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.parking.support.controlleradvice.dto; - -public record ExceptionResponse(String errorMessage) { - -} diff --git a/src/main/java/com/example/parking/support/exception/ClientException.java b/src/main/java/com/example/parking/support/exception/ClientException.java deleted file mode 100644 index 74d4d1bd..00000000 --- a/src/main/java/com/example/parking/support/exception/ClientException.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.parking.support.exception; - -import lombok.Getter; - -@Getter -public class ClientException extends RuntimeException{ - - private final ExceptionInformation exceptionInformation; - - public ClientException(ExceptionInformation exceptionInformation) { - super(); - this.exceptionInformation = exceptionInformation; - } - - @Override - public String getMessage() { - return exceptionInformation.getMessage(); - } -} diff --git a/src/main/java/com/example/parking/support/exception/DomainException.java b/src/main/java/com/example/parking/support/exception/DomainException.java deleted file mode 100644 index 77e1b2ec..00000000 --- a/src/main/java/com/example/parking/support/exception/DomainException.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.parking.support.exception; - -public class DomainException extends RuntimeException{ - - private final ExceptionInformation exceptionInformation; - - public DomainException(ExceptionInformation exceptionInformation) { - super(); - this.exceptionInformation = exceptionInformation; - } - - @Override - public String getMessage() { - return exceptionInformation.getMessage(); - } -} diff --git a/src/main/java/com/example/parking/support/exception/ExceptionInformation.java b/src/main/java/com/example/parking/support/exception/ExceptionInformation.java deleted file mode 100644 index 2917ca9b..00000000 --- a/src/main/java/com/example/parking/support/exception/ExceptionInformation.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.example.parking.support.exception; - -import lombok.Getter; - -@Getter -public enum ExceptionInformation { - DUPLICATE_MAIL("중복된 이메일이라 회원가입이 불가능합니다."), - INVALID_EMAIL("회원가입되지 않은 이메일입니다."), - INVALID_MEMBER("존재하지 않는 회원입니다."), - INVALID_PASSWORD("비밀번호가 틀립니다."), - UNAUTHORIZED("존재하지 않는 sessionId 입니다."), - - INVALID_PARKING("존재하지 않는 주차장입니다."), - INVALID_CONTENT("존재하지 않는 리뷰 내용입니다."), - INVALID_REVIEW("존재하지 않는 리뷰입니다."), - DUPLICATE_REVIEW("유저가 해당 주차장에 대해 이미 리뷰를 작성하였습니다."), - INVALID_CONTENTS_SIZE("리뷰 내용은 1개에서 3개까지 선택가능합니다."), - INVALID_HOURS("이용 시간은 1~12, 24 시간까지만 선택할 수 있습니다."), - INVALID_SEARCH_CONDITION("해당 회원의 검색 조건이 존재하지 않습니다."), - - ENCRYPT_EXCEPTION("암호화에 실패했습니다."), - - INVALID_CONNECT("주차장 API 연결 중 예외 발생"), - COORDINATE_EXCEPTION("좌표 변환 중 예외 발생"), - INVALID_AUTH_CODE("존재하지 않는 인증코드 입니다."), - INVALID_DESCRIPTION("해당하는 내용의 검색 조건이 존재하지 않습니다."), - INVALID_LOCATION("경도 또는 위도가 올바르지 않습니다."); - - private final String message; - - ExceptionInformation(String message) { - this.message = message; - } -} diff --git a/src/main/java/com/example/parking/util/authcode/AuthCodeGenerator.java b/src/main/java/com/example/parking/util/authcode/AuthCodeGenerator.java deleted file mode 100644 index d505a434..00000000 --- a/src/main/java/com/example/parking/util/authcode/AuthCodeGenerator.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.parking.util.authcode; - -public interface AuthCodeGenerator { - - String generateAuthCode(); -} diff --git a/src/main/java/com/example/parking/util/authcode/NumberAuthCodeGenerator.java b/src/main/java/com/example/parking/util/authcode/NumberAuthCodeGenerator.java deleted file mode 100644 index 0a26bc9e..00000000 --- a/src/main/java/com/example/parking/util/authcode/NumberAuthCodeGenerator.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.parking.util.authcode; - -import java.util.Random; -import org.springframework.stereotype.Component; - -@Component -public class NumberAuthCodeGenerator implements AuthCodeGenerator { - - private static final int MAX_LENGTH = 6; - private static final Random random = new Random(); - - @Override - public String generateAuthCode() { - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < MAX_LENGTH; i++) { - stringBuilder.append(random.nextInt(9)); - } - return stringBuilder.toString(); - } -} diff --git a/src/main/java/com/example/parking/util/cipher/EncryptionException.java b/src/main/java/com/example/parking/util/cipher/EncryptionException.java deleted file mode 100644 index fa1e644a..00000000 --- a/src/main/java/com/example/parking/util/cipher/EncryptionException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.example.parking.util.cipher; - -public class EncryptionException extends RuntimeException { - - public EncryptionException(String message) { - super(message); - } -} diff --git a/src/main/java/com/example/parking/util/cipher/SHA256.java b/src/main/java/com/example/parking/util/cipher/SHA256.java deleted file mode 100644 index 616d6b52..00000000 --- a/src/main/java/com/example/parking/util/cipher/SHA256.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.parking.util.cipher; - -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.security.MessageDigest; - -public class SHA256 { - - private final static String ALG_NAME = "SHA-256"; - - public static String encrypt(String plainText) { - try { - MessageDigest md = MessageDigest.getInstance(ALG_NAME); - md.update(plainText.getBytes()); - return bytesToHex(md.digest()); - } catch (Exception e) { - throw new DomainException(ExceptionInformation.ENCRYPT_EXCEPTION); - } - } - - private static String bytesToHex(byte[] bytes) { - StringBuilder builder = new StringBuilder(); - for (byte b : bytes) { - builder.append(String.format("%02x", b)); - } - return builder.toString(); - } -} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml deleted file mode 100644 index 22c29aa9..00000000 --- a/src/main/resources/application-dev.yml +++ /dev/null @@ -1,11 +0,0 @@ -spring: - # JPA - jpa: - hibernate: - ddl-auto: create - show-sql: true - properties: - hibernate: - format_sql: true - flyway: - enabled: false diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml deleted file mode 100644 index c7a26256..00000000 --- a/src/main/resources/application-prod.yml +++ /dev/null @@ -1,22 +0,0 @@ -spring: - # JPA - jpa: - hibernate: - ddl-auto: validate - database: mysql - open-in-view: false - - # DB - datasource: - url: ${DB_URL} - username: ${DB_USERNAME} - password: ${DB_PASSWORD} - driver-class-name: com.mysql.cj.jdbc.Driver - # flyway - flyway: - enabled: true - url: ${DB_URL} - user: ${DB_USERNAME} - password: ${DB_PASSWORD} - baseline-on-migrate: true - locations: classpath:db/migration/mysql diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index ec3a02f9..00000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,35 +0,0 @@ -spring: - profiles: - active: ${PROFILE:dev} -# MAIL - mail: - host: ${MAIL_HOST:smtp.gmail.com} - port: ${MAIL_PORT:587} - username: ${MAIL_USERNAME:mail@gmail.com} - password: ${MAIL_PASSWORD:password} - properties: - mail: - smtp: - auth: true - timeout: 5000 - starttls: - enable: true -# REDIS - data: - redis: - host: ${REDIS_HOST:localhost} - port: ${REDIS_PORT:6379} - -# AUTH CODE -authcode: - expired-time: 300 - -# API KEY -kakao: - key: ${KAKAO_API_KEY:kakao} -seoul-public-parking-key: ${SEOUL_API_KEY:seoul} -pusan-public-parking-key: ${PUSAN_API_KEY:pusan} - -# Allow origin -cors: - allowedOrigins: ${ORIGIN:http://localhost:3000} diff --git a/src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql b/src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql deleted file mode 100644 index dd6ec735..00000000 --- a/src/main/resources/db/migration/mysql/V1.0.0__initial_schema.sql +++ /dev/null @@ -1,88 +0,0 @@ --- favorite 테이블 생성 -CREATE TABLE favorite ( - id BIGINT NOT NULL AUTO_INCREMENT, - created_at TIMESTAMP, - updated_at TIMESTAMP, - member_id BIGINT, - parking_id BIGINT, - PRIMARY KEY (id), - UNIQUE (member_id, parking_id) -); - --- member 테이블 생성 -CREATE TABLE member ( - id BIGINT NOT NULL AUTO_INCREMENT, - deleted BOOLEAN, - email VARCHAR(255) UNIQUE, - name VARCHAR(255), - nickname VARCHAR(255), - password VARCHAR(255), - PRIMARY KEY (id) -); - --- member_session 테이블 생성 -CREATE TABLE member_session ( - session_id VARCHAR(255) NOT NULL, - created_at TIMESTAMP, - expired_at TIMESTAMP, - member_id BIGINT, - PRIMARY KEY (session_id) -); - --- parking 테이블 생성 -CREATE TABLE parking ( - id BIGINT NOT NULL AUTO_INCREMENT, - created_at TIMESTAMP, - updated_at TIMESTAMP, - base_fee INTEGER, - base_time_unit INTEGER, - capacity INTEGER, - current_parking INTEGER, - day_maximum_fee INTEGER, - extra_fee INTEGER, - extra_time_unit INTEGER, - holiday_begin_time TIME, - holiday_end_time TIME, - holiday_free_begin_time TIME, - holiday_free_end_time TIME, - latitude FLOAT NOT NULL, - longitude FLOAT NOT NULL, - saturday_begin_time TIME, - saturday_end_time TIME, - saturday_free_begin_time TIME, - saturday_free_end_time TIME, - weekday_begin_time TIME, - weekday_end_time TIME, - weekday_free_begin_time TIME, - weekday_free_end_time TIME, - address VARCHAR(255), - description VARCHAR(255), - name VARCHAR(255), - operation_type ENUM ('PUBLIC', 'PRIVATE', 'NO_INFO'), - parking_type ENUM ('OFF_STREET', 'ON_STREET', 'MECHANICAL', 'NO_INFO'), - tel VARCHAR(255), - PRIMARY KEY (id) -); - --- review 테이블 생성 -CREATE TABLE review ( - id BIGINT NOT NULL AUTO_INCREMENT, - created_at TIMESTAMP, - parking_id BIGINT, - reviewer_id BIGINT, - contents VARCHAR(255), - PRIMARY KEY (id) -); - --- search_condition 테이블 생성 -CREATE TABLE search_condition ( - id BIGINT NOT NULL AUTO_INCREMENT, - hours INTEGER NOT NULL, - member_id BIGINT, - fee_types VARCHAR(255), - operation_types VARCHAR(255), - parking_types VARCHAR(255), - pay_types VARCHAR(255), - priority ENUM ('DISTANCE', 'PRICE', 'RECOMMENDATION'), - PRIMARY KEY (id) -); diff --git a/src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql b/src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql deleted file mode 100644 index a4779e0d..00000000 --- a/src/main/resources/db/migration/mysql/V2.0.0__add_point_parking_table.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE parking - ADD COLUMN point GEOMETRY; diff --git a/src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql b/src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql deleted file mode 100644 index 36a97815..00000000 --- a/src/main/resources/db/migration/mysql/V3.0.0__drop_column_parking_table.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE parking - DROP COLUMN latitude, - DROP COLUMN longitude; diff --git a/src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql b/src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql deleted file mode 100644 index 1bb9c3f3..00000000 --- a/src/main/resources/db/migration/mysql/V4.0.0__drop_column_member_table.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE member - DROP COLUMN name; diff --git a/src/test/java/com/example/parking/ParkingApplicationTests.java b/src/test/java/com/example/parking/ParkingApplicationTests.java deleted file mode 100644 index db6c30db..00000000 --- a/src/test/java/com/example/parking/ParkingApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.parking; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class ParkingApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/com/example/parking/application/CoordinateServiceTest.java b/src/test/java/com/example/parking/application/CoordinateServiceTest.java deleted file mode 100644 index a6c33536..00000000 --- a/src/test/java/com/example/parking/application/CoordinateServiceTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.example.parking.application; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -import com.example.parking.external.coordinate.CoordinateService; -import com.example.parking.external.coordinate.dto.CoordinateResponse; -import com.example.parking.external.coordinate.dto.CoordinateResponse.Meta; -import com.example.parking.domain.parking.Location; -import java.util.Collections; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestTemplate; - -@ExtendWith(MockitoExtension.class) -class CoordinateServiceTest { - - @Mock - private RestTemplate restTemplate; - - @InjectMocks - private CoordinateService coordinateService; - - @Test - void 주소_변환_요청_결과개수가_0이면_기존의_위도_경도를_반환한다() { - CoordinateResponse emptyResponse = new CoordinateResponse(Collections.emptyList(), new Meta(0)); - - when(restTemplate.getForEntity(anyString(), any())) - .thenReturn(new ResponseEntity<>(emptyResponse, HttpStatus.OK)); - - double expectedLongitude = 67; - double expectedLatitude = 10; - - Location result = coordinateService.extractLocationByAddress("address", Location.of(67.0, 10.0)); - assertAll( - () -> assertThat(result.getLatitude()).isEqualTo(expectedLatitude), - () -> assertThat(result.getLongitude()).isEqualTo(expectedLongitude) - ); - } -} diff --git a/src/test/java/com/example/parking/application/member/MemberServiceTest.java b/src/test/java/com/example/parking/application/member/MemberServiceTest.java deleted file mode 100644 index f4e19a83..00000000 --- a/src/test/java/com/example/parking/application/member/MemberServiceTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.example.parking.application.member; - -import static com.example.parking.support.exception.ExceptionInformation.INVALID_MEMBER; -import static com.example.parking.support.exception.ExceptionInformation.INVALID_PASSWORD; -import static org.assertj.core.api.Assertions.assertThat; - -import com.example.parking.application.member.dto.MemberLoginRequest; -import com.example.parking.application.member.dto.MemberSignupRequest; -import com.example.parking.application.member.dto.PasswordChangeRequest; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.member.MemberRepository; -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.DomainException; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -@SpringBootTest -class MemberServiceTest { - - @Autowired - private MemberService memberService; - - @Autowired - private MemberRepository memberRepository; - - @Test - void 회원탈퇴() { - Long memberId = memberService.signup(new MemberSignupRequest("name", "email", "nickname", "password")); - memberService.deleteMember(memberId); - - Member member = memberRepository.getById(memberId); - assertThat(member.getDeleted()).isTrue(); - } - - @Test - void 비밀번호를_바꾸면_바꾼_비밀번호로_로그인이_가능하다() { - // given - String email = "email@google.com"; - String previousPassword = "password"; - MemberSignupRequest memberSignupRequest = new MemberSignupRequest("name", email, previousPassword, "nickname"); - Long memberId = memberService.signup(memberSignupRequest); - - String newPassword = "newPassword"; - - // when - memberService.changePassword(memberId, new PasswordChangeRequest(previousPassword, newPassword)); - - // then - Assertions.assertThatNoException() - .isThrownBy(() -> memberService.login(new MemberLoginRequest(email, newPassword))); - } - - @Test - void 비밀번호를_바꾸면_이전의_비밀번호로_로그인이_불가능하다() { - // given - String email = "email@google.com"; - String previousPassword = "password"; - MemberSignupRequest memberSignupRequest = new MemberSignupRequest("name", email, previousPassword, "nickname"); - Long memberId = memberService.signup(memberSignupRequest); - - String newPassword = "newPassword"; - - // when - memberService.changePassword(memberId, new PasswordChangeRequest(previousPassword, newPassword)); - - // then - Assertions.assertThatThrownBy(() -> memberService.login(new MemberLoginRequest(email, previousPassword))) - .isInstanceOf(ClientException.class) - .hasMessage(INVALID_PASSWORD.getMessage()); - } - - @Test - void 비밀번호를_바꿀_때_해당_회원이_존재하지_않으면_예외를_던진다() { - // given - String previousPassword = "password"; - String newPassword = "newPassword"; - Long wrongMemberId = 12312541L; - - // when, then - Assertions.assertThatThrownBy(() -> memberService.changePassword(wrongMemberId, - new PasswordChangeRequest(previousPassword, newPassword))) - .isInstanceOf(DomainException.class) - .hasMessage(INVALID_MEMBER.getMessage()); - } -} diff --git a/src/test/java/com/example/parking/application/parking/ParkingFilteringServiceTest.java b/src/test/java/com/example/parking/application/parking/ParkingFilteringServiceTest.java deleted file mode 100644 index 36b74bcd..00000000 --- a/src/test/java/com/example/parking/application/parking/ParkingFilteringServiceTest.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.example.parking.application.parking; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.example.parking.domain.parking.BaseInformation; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.FeePolicy; -import com.example.parking.domain.parking.FreeOperatingTime; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingFeeCalculator; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayType; -import com.example.parking.domain.parking.PayTypes; -import com.example.parking.domain.parking.SearchingCondition; -import com.example.parking.domain.parking.TimeUnit; -import com.example.parking.domain.searchcondition.FeeType; -import java.time.LocalDateTime; -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class ParkingFilteringServiceTest { - - private final ParkingFilteringService parkingFilteringService = new ParkingFilteringService( - new ParkingFeeCalculator()); - - @Test - void 조회조건에_따라_주차장을_필터링한다1() { - // given - ParkingType parkingTypeCondition = ParkingType.MECHANICAL; - OperationType operationTypeCondition = OperationType.PUBLIC; - PayType wantPayType = PayType.CASH; - - Parking wantParking = Parking.builder() - .baseInformation(new BaseInformation("name", "tell", "address", - PayTypes.from(List.of(wantPayType)), - parkingTypeCondition, - operationTypeCondition)) - .build(); - - Parking notWantParking1 = Parking.builder() - .baseInformation(new BaseInformation("name", "tell", "address", - PayTypes.DEFAULT, - parkingTypeCondition, - OperationType.NO_INFO)) - .build(); - - Parking notWantParking2 = Parking.builder() - .baseInformation(new BaseInformation("name", "tell", "address", - PayTypes.DEFAULT, - ParkingType.OFF_STREET, - operationTypeCondition)) - .build(); - - // when - SearchingCondition searchingCondition = new SearchingCondition( - List.of(operationTypeCondition), - List.of(parkingTypeCondition), - List.of(wantPayType), - FeeType.PAID, 3); - - List filterList = parkingFilteringService.filterByCondition( - List.of(wantParking, notWantParking1, notWantParking2), - searchingCondition, - LocalDateTime.now() - ); - - // then - assertThat(filterList).hasSize(1); - } - - @Test - void 조회조건에_따라_주차장을_필터링한다2() { - // given - ParkingType wantParkingTypeCondition = ParkingType.ON_STREET; - OperationType wantOperationTypeCondition = OperationType.PUBLIC; - PayType wantPayType = PayType.CARD; - - Parking wantParking = Parking.builder() - .baseInformation(new BaseInformation("name", "tel", "address", - PayTypes.from(List.of(wantPayType)), - wantParkingTypeCondition, - wantOperationTypeCondition)) - .build(); - - Parking notWantParking1 = Parking.builder() - .baseInformation(new BaseInformation("name", "tel", "address", - PayTypes.DEFAULT, - ParkingType.MECHANICAL, - wantOperationTypeCondition)) - .build(); - - Parking notWantParking2 = Parking.builder() - .baseInformation(new BaseInformation("name", "tel", "address", - PayTypes.DEFAULT, - ParkingType.NO_INFO, - wantOperationTypeCondition)) - .build(); - - // when - SearchingCondition searchingCondition = new SearchingCondition( - List.of(wantOperationTypeCondition), - List.of(wantParkingTypeCondition), - List.of(wantPayType), - FeeType.PAID, 3); - - List result = parkingFilteringService.filterByCondition( - List.of(wantParking, notWantParking1, notWantParking2), - searchingCondition, - LocalDateTime.now() - ); - - // then - assertThat(result).hasSize(1); - } - - @Test - void 조회조건이_무료일_때_예상요금이_0인_주차장만_조회된다() { - // given - 하루종일 무료 주차장 2개, 유료 주차장 1개 - FeePolicy freeFeePolicy = new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(10), TimeUnit.from(10), Fee.ZERO); - - OperationType operationType = OperationType.PUBLIC; - ParkingType parkingType = ParkingType.MECHANICAL; - BaseInformation baseInformation = new BaseInformation("name", "tel", "address", - PayTypes.from(List.of(PayType.CARD)), - parkingType, - operationType - ); - Parking freeParking1 = Parking.builder() - .baseInformation(baseInformation) - .freeOperatingTime(FreeOperatingTime.ALWAYS_FREE) - .feePolicy(freeFeePolicy) - .build(); - - Parking freeParking2 = Parking.builder() - .baseInformation(baseInformation) - .freeOperatingTime(FreeOperatingTime.ALWAYS_FREE) - .feePolicy(freeFeePolicy) - .build(); - - FeePolicy paidFeePolicy = new FeePolicy(Fee.from(100), Fee.from(200), TimeUnit.from(1), TimeUnit.from(12), - Fee.from(1000)); - Parking paidParking = Parking.builder() - .baseInformation(baseInformation) - .freeOperatingTime(FreeOperatingTime.ALWAYS_PAY) - .feePolicy(paidFeePolicy) - .build(); - - // when - 검색조건이 Free 인 filterCondition 으로 주차장 필터링 - SearchingCondition searchingCondition = new SearchingCondition(List.of(operationType), List.of(parkingType), - List.of(PayType.CARD), FeeType.FREE, 3); - List filteredParkings = parkingFilteringService.filterByCondition( - List.of(freeParking1, freeParking2, paidParking), - searchingCondition, - LocalDateTime.now() - ); - - // then - Assertions.assertThat(filteredParkings).hasSize(2); - - } -} diff --git a/src/test/java/com/example/parking/application/parking/ParkingServiceTest.java b/src/test/java/com/example/parking/application/parking/ParkingServiceTest.java deleted file mode 100644 index 1379c902..00000000 --- a/src/test/java/com/example/parking/application/parking/ParkingServiceTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.example.parking.application.parking; - -import static org.junit.jupiter.api.Assertions.assertAll; - -import com.example.parking.application.parking.dto.ParkingDetailInfoResponse; -import com.example.parking.application.review.dto.ReviewCreateRequest; -import com.example.parking.container.ContainerTest; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.member.Password; -import com.example.parking.domain.parking.BaseInformation; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.FeePolicy; -import com.example.parking.domain.parking.FreeOperatingTime; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.OperatingTime; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayTypes; -import com.example.parking.domain.parking.Space; -import com.example.parking.domain.parking.TimeInfo; -import com.example.parking.domain.parking.TimeUnit; -import com.example.parking.domain.review.Content; -import com.example.parking.support.exception.DomainException; -import com.example.parking.support.exception.ExceptionInformation; -import java.time.LocalTime; -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class ParkingServiceTest extends ContainerTest { - - @Test - void 조회하려는_주차장이_없으면_예외() { - //given - Assertions.assertThatThrownBy(() -> parkingService.findParking(1L)) - .isInstanceOf(DomainException.class) - .hasMessage(ExceptionInformation.INVALID_PARKING.getMessage()); - } - - @Test - void 주차장_상세조회() { - //given - String parkingName = "호이주차장"; - Parking parking = makeParking(parkingName); - List parkings = List.of(parking); - parkingService.saveAll(parkings); - - Member member = new Member( "email", "하디", new Password("qwer1234")); - memberRepository.save(member); - - ReviewCreateRequest reviewCreateRequest = new ReviewCreateRequest( - List.of(Content.LARGE_PARKING_SPACE.getDescription(), Content.EASY_TO_PAY.getDescription())); - reviewService.createReview(parking.getId(), member.getId(), reviewCreateRequest); - - // when, then - ParkingDetailInfoResponse parkingDetailInfoResponse = parkingService.findParking(parking.getId()); - assertAll( - () -> Assertions.assertThat(parkingDetailInfoResponse.getReviewInfo().reviews()).hasSize(2), - () -> Assertions.assertThat(parkingDetailInfoResponse.getParkingName()).isEqualTo(parkingName) - ); - } - - private Parking makeParking(String parkingName) { - return new Parking - ( - new BaseInformation(parkingName, "010", "부산", PayTypes.DEFAULT, ParkingType.MECHANICAL, - OperationType.PRIVATE), - Location.of(30d, 30d), - Space.of(100, 30), - new FreeOperatingTime( - new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), - new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), - new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)) - ), - new OperatingTime( - new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), - new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)), - new TimeInfo(LocalTime.of(10, 30), LocalTime.of(20, 30)) - ), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000)) - ); - } - -} diff --git a/src/test/java/com/example/parking/application/review/ReviewServiceTest.java b/src/test/java/com/example/parking/application/review/ReviewServiceTest.java deleted file mode 100644 index 2d5f6ad2..00000000 --- a/src/test/java/com/example/parking/application/review/ReviewServiceTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.example.parking.application.review; - -import static com.example.parking.support.exception.ExceptionInformation.DUPLICATE_REVIEW; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.example.parking.application.review.dto.ReviewCreateRequest; -import com.example.parking.application.review.dto.ReviewInfoResponse; -import com.example.parking.support.Association; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.review.Content; -import com.example.parking.domain.review.Review; -import com.example.parking.domain.review.service.ReviewDomainService; -import com.example.parking.fake.BasicMemberRepository; -import com.example.parking.fake.BasicParkingRepository; -import com.example.parking.fake.BasicReviewRepository; -import com.example.parking.support.exception.DomainException; -import java.util.List; -import org.junit.jupiter.api.Test; - -class ReviewServiceTest { - - private final BasicParkingRepository parkingRepository = new BasicParkingRepository(); - private final BasicMemberRepository memberRepository = new BasicMemberRepository(); - private final BasicReviewRepository reviewRepository = new BasicReviewRepository(); - private final ReviewService reviewService = new ReviewService( - reviewRepository, - new ReviewDomainService(reviewRepository) - ); - - @Test - void 리뷰를_작성한다() { - //given - Parking parking = parkingRepository.saveAndGet(1).get(0); - Member reviewer = memberRepository.saveAndGet(1).get(0); - ReviewCreateRequest request = new ReviewCreateRequest(List.of("주차 자리가 많아요", "결제가 편리해요")); - - //when - Long reviewId = reviewService.createReview(parking.getId(), reviewer.getId(), request); - - //then - assertThat(reviewId).isNotNull(); - } - - @Test - void 리뷰를_이미_작성했으면_예외가_발생한다() { - //given - Parking parking = parkingRepository.saveAndGet(1).get(0); - Member reviewer = memberRepository.saveAndGet(1).get(0); - ReviewCreateRequest request = new ReviewCreateRequest(List.of("주차 자리가 많아요", "결제가 편리해요")); - reviewService.createReview(parking.getId(), reviewer.getId(), request); - - //when, then - assertThatThrownBy(() -> reviewService.createReview(parking.getId(), reviewer.getId(), request)) - .isInstanceOf(DomainException.class) - .hasMessage(DUPLICATE_REVIEW.getMessage()); - } - - @Test - void 주차장에_대한_리뷰를_내용이_많은순으로_가져온다() { - //given - Parking parking = parkingRepository.saveAndGet(1).get(0); - Association parkingId = Association.from(parking.getId()); - List reviewers = memberRepository.saveAndGet(3); - - List contents1 = List.of(Content.LOW_PRICE); - List contents2 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY); - List contents3 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY, Content.GOOD_ACCESSIBILITY); - reviewRepository.save( - new Review(parkingId, Association.from(reviewers.get(0).getId()), contents1) - ); - reviewRepository.save( - new Review(parkingId, Association.from(reviewers.get(1).getId()), contents2) - ); - reviewRepository.save( - new Review(parkingId, Association.from(reviewers.get(2).getId()), contents3) - ); - - //when - ReviewInfoResponse reviewInfoResponse = reviewService.readReviews(parkingId.getId()); - - //then - assertSoftly( - soft -> { - soft.assertThat(reviewInfoResponse.totalReviewCount()) - .isEqualTo(contents1.size() + contents2.size() + contents3.size()); - soft.assertThat(reviewInfoResponse.reviews().get(0).content()) - .isEqualTo(Content.LOW_PRICE.getDescription()); - soft.assertThat(reviewInfoResponse.reviews().get(1).content()) - .isEqualTo(Content.EASY_TO_PAY.getDescription()); - soft.assertThat(reviewInfoResponse.reviews().get(2).content()) - .isEqualTo(Content.GOOD_ACCESSIBILITY.getDescription()); - } - ); - } -} diff --git a/src/test/java/com/example/parking/auth/AuthServiceTest.java b/src/test/java/com/example/parking/auth/AuthServiceTest.java deleted file mode 100644 index 23992a21..00000000 --- a/src/test/java/com/example/parking/auth/AuthServiceTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.example.parking.auth; - -import static com.example.parking.support.exception.ExceptionInformation.INVALID_AUTH_CODE; -import static com.example.parking.support.exception.ExceptionInformation.UNAUTHORIZED; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatNoException; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -import com.example.parking.auth.authcode.AuthCodeCategory; -import com.example.parking.auth.authcode.AuthCodePlatform; -import com.example.parking.auth.authcode.application.dto.AuthCodeCertificateRequest; -import com.example.parking.auth.authcode.application.dto.AuthCodeRequest; -import com.example.parking.auth.session.MemberSession; -import com.example.parking.container.ContainerTest; -import com.example.parking.support.exception.ClientException; -import java.time.LocalDateTime; -import org.junit.jupiter.api.Test; - -class AuthServiceTest extends ContainerTest { - - private static final String AUTH_CODE = "111111"; - - - @Test - void 세션_아이디에_해당하는_세션을_찾는다() { - // given - Long memberId = 1L; - String sessionId = authService.createSession(memberId); - - // when, then - assertThatNoException() - .isThrownBy(() -> authService.findSession(sessionId)); - } - - @Test - void 세션_아이디에_해당하는_세션이_존재하지_않으면_예외를_던진다() { - // given - String wrongSessionId = "아무세션아이디"; - - // when, then - assertThatThrownBy(() -> authService.findSession(wrongSessionId)) - .isInstanceOf(ClientException.class) - .hasMessage(UNAUTHORIZED.getMessage()); - } - - @Test - void 세션_만료시간을_갱신한다() { - // given - Long memberId = 1L; - String sessionId = authService.createSession(memberId); - MemberSession originSession = authService.findSession(sessionId); - LocalDateTime originExpiredAt = originSession.getExpiredAt(); - - // when - authService.updateSessionExpiredAt(originSession); - MemberSession updatedSession = authService.findSession(sessionId); - LocalDateTime updatedExpiredAt = updatedSession.getExpiredAt(); - - // then - assertThat(updatedExpiredAt).isAfter(originExpiredAt); - } - - @Test - void 가장_최근에_발급받은_인증번호는_검증가능하다() { - // given - String authCodeDestination = "destination@gmail.com"; - AuthCodePlatform authCodePlatform = AuthCodePlatform.MAIL; - AuthCodeCategory authCodeCategory = AuthCodeCategory.SIGN_UP; - - String oldAuthCode = authService.createAuthCode( - new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName()) - ); - - String newAuthCode = authService.createAuthCode( - new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName()) - ); - - // when - AuthCodeCertificateRequest authCodeCertificateRequest = new AuthCodeCertificateRequest( - authCodeDestination, - authCodePlatform.getPlatform(), - AuthCodeCategory.SIGN_UP.getCategoryName(), - newAuthCode - ); - - // then - assertDoesNotThrow(() -> authService.certificateAuthCode(authCodeCertificateRequest)); - } - - @Test - void 이미_인증받은_인증번호는_다시_사용할_수_없다() { - // given - String authCodeDestination = "destination@gmail.com"; - AuthCodePlatform authCodePlatform = AuthCodePlatform.MAIL; - AuthCodeCategory authCodeCategory = AuthCodeCategory.SIGN_UP; - - String oldAuthCode = authService.createAuthCode( - new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName()) - ); - - // when - AuthCodeCertificateRequest authCodeCertificateRequest = new AuthCodeCertificateRequest( - authCodeDestination, - authCodePlatform.getPlatform(), - AuthCodeCategory.SIGN_UP.getCategoryName(), - oldAuthCode - ); - authService.certificateAuthCode(authCodeCertificateRequest); - - // then (인증받은 인증코드로 인증 다시 시도) - assertThatThrownBy(() -> authService.certificateAuthCode(authCodeCertificateRequest)) - .isInstanceOf(ClientException.class) - .hasMessage(INVALID_AUTH_CODE.getMessage()); - } - - @Test - void 가장_최근의_인증번호가_아니어도_인증_가능하다() { - // given - String authCodeDestination = "destination@gmail.com"; - AuthCodePlatform authCodePlatform = AuthCodePlatform.MAIL; - AuthCodeCategory authCodeCategory = AuthCodeCategory.SIGN_UP; - - String oldAuthCode = authService.createAuthCode( - new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName()) - ); - - String newAuthCode = authService.createAuthCode( - new AuthCodeRequest(authCodeDestination, authCodePlatform.getPlatform(), - authCodeCategory.getCategoryName()) - ); - - // when - AuthCodeCertificateRequest authCodeCertificateRequest = new AuthCodeCertificateRequest( - authCodeDestination, - authCodePlatform.getPlatform(), - AuthCodeCategory.SIGN_UP.getCategoryName(), - oldAuthCode - ); - - // then (예전 인증코드(oldAuthCode)로 인증 시도) - assertDoesNotThrow(() -> authService.certificateAuthCode(authCodeCertificateRequest)); - } -} diff --git a/src/test/java/com/example/parking/auth/MemberSessionRepositoryTest.java b/src/test/java/com/example/parking/auth/MemberSessionRepositoryTest.java deleted file mode 100644 index cbc66091..00000000 --- a/src/test/java/com/example/parking/auth/MemberSessionRepositoryTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.example.parking.auth; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.example.parking.auth.session.MemberSession; -import com.example.parking.auth.session.MemberSessionRepository; -import java.time.LocalDateTime; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -@DataJpaTest -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -class MemberSessionRepositoryTest { - - @Autowired - private MemberSessionRepository memberSessionRepository; - - @Test - void 현재_시간이_세션_만료_시간보다_늦지_않으면_세션이_조회된다() { - // given - MemberSession memberSession = new MemberSession(UUID.randomUUID().toString(), 1L, LocalDateTime.now(), - LocalDateTime.now()); - memberSessionRepository.save(memberSession); - - // when, then - assertThat(memberSessionRepository.findBySessionIdAndExpiredAtIsGreaterThanEqual(memberSession.getSessionId(), - LocalDateTime.now().minusDays(1))) - .isPresent(); - } - - @Test - void 현재_시간이_세션_만료_시간보다_늦으면_빈_옵셔널을_반환한다() { - // given - MemberSession memberSession = new MemberSession(UUID.randomUUID().toString(), 1L, LocalDateTime.now(), - LocalDateTime.now().minusDays(1)); - memberSessionRepository.save(memberSession); - - // when, then - assertThat(memberSessionRepository.findBySessionIdAndExpiredAtIsGreaterThanEqual(memberSession.getSessionId(), - LocalDateTime.now())) - .isEmpty(); - } -} diff --git a/src/test/java/com/example/parking/config/TestConfig.java b/src/test/java/com/example/parking/config/TestConfig.java deleted file mode 100644 index dfd75c64..00000000 --- a/src/test/java/com/example/parking/config/TestConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.example.parking.config; - -import com.example.parking.auth.authcode.infrastructure.AuthCodeSender; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; - -@TestConfiguration -public class TestConfig { - - @Bean - @Primary - public AuthCodeSender fakeAuthCodeSender() { - return new AuthCodeSender() { - @Override - public void send(String destination, String authCode) { - - } - }; - } -} diff --git a/src/test/java/com/example/parking/container/ContainerTest.java b/src/test/java/com/example/parking/container/ContainerTest.java deleted file mode 100644 index 636188db..00000000 --- a/src/test/java/com/example/parking/container/ContainerTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.example.parking.container; - -import com.example.parking.application.parking.ParkingService; -import com.example.parking.application.review.ReviewService; -import com.example.parking.auth.AuthService; -import com.example.parking.config.TestConfig; -import com.example.parking.domain.member.MemberRepository; -import com.redis.testcontainers.RedisContainer; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; - -@SpringBootTest -@Import({TestConfig.class}) -@ActiveProfiles("test") -public abstract class ContainerTest { - - private static final RedisContainer REDIS_CONTAINER; - private static RedisTemplate redisTemplate; - - static { - REDIS_CONTAINER = new RedisContainer(RedisContainer.DEFAULT_IMAGE_NAME.withTag(RedisContainer.DEFAULT_TAG)) - .withExposedPorts(6379); - REDIS_CONTAINER.start(); - } - - @DynamicPropertySource - static void postgresqlProperties(DynamicPropertyRegistry registry) { - registry.add("spring.data.redis.host", REDIS_CONTAINER::getHost); - registry.add("spring.data.redis.port", REDIS_CONTAINER::getRedisPort); - } - - @Autowired - private MySQLDataCleaner mySQLDataCleaner; - - @Autowired - protected ParkingService parkingService; - - @Autowired - protected ReviewService reviewService; - - @Autowired - protected MemberRepository memberRepository; - - @Autowired - protected AuthService authService; - - @BeforeAll - static void setUpBeforeClass() { - String redisHost = REDIS_CONTAINER.getHost(); - int redisPort = REDIS_CONTAINER.getRedisPort(); - LettuceConnectionFactory redisConnectionFactory = new LettuceConnectionFactory(redisHost, redisPort); - redisConnectionFactory.afterPropertiesSet(); - - redisTemplate = new RedisTemplate<>(); - redisTemplate.setConnectionFactory(redisConnectionFactory); - } - - @AfterEach - void teardown() { - RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); - connection.serverCommands().flushAll(); - mySQLDataCleaner.delete(); - } -} diff --git a/src/test/java/com/example/parking/container/MySQLDataCleaner.java b/src/test/java/com/example/parking/container/MySQLDataCleaner.java deleted file mode 100644 index 38893521..00000000 --- a/src/test/java/com/example/parking/container/MySQLDataCleaner.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.example.parking.container; - -import jakarta.persistence.EntityManager; -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; -import org.testcontainers.shaded.com.google.common.base.CaseFormat; - -@Component -public class MySQLDataCleaner { - - @Autowired - private EntityManager entityManager; - - @Autowired - private JdbcTemplate jdbcTemplate; - - @Transactional - public void delete() { - List tableNames = entityManager.getMetamodel().getEntities().stream() - .map(table -> CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, table.getName())) - .toList(); - - setForeignKeyEnabled(false); - tableNames.forEach(table -> jdbcTemplate.execute("TRUNCATE table " + table)); - setForeignKeyEnabled(true); - } - - private void setForeignKeyEnabled(boolean enabled) { - entityManager.createNativeQuery("SET foreign_key_checks = " + enabled).executeUpdate(); - } -} diff --git a/src/test/java/com/example/parking/container/RedisDataCleaner.java b/src/test/java/com/example/parking/container/RedisDataCleaner.java deleted file mode 100644 index e4707ee9..00000000 --- a/src/test/java/com/example/parking/container/RedisDataCleaner.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.parking.container; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Profile; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Component; - -@Component -@Profile("test") -public class RedisDataCleaner { - - @Autowired - private RedisTemplate redisTemplate; - - public void delete() { - redisTemplate.getConnectionFactory().getConnection().serverCommands().flushAll(); - } -} diff --git a/src/test/java/com/example/parking/domain/favorite/FavoriteRepositoryTest.java b/src/test/java/com/example/parking/domain/favorite/FavoriteRepositoryTest.java deleted file mode 100644 index ed6e7292..00000000 --- a/src/test/java/com/example/parking/domain/favorite/FavoriteRepositoryTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.example.parking.domain.favorite; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.example.parking.support.Association; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -@DataJpaTest -class FavoriteRepositoryTest { - - @Autowired - private FavoriteRepository favoriteRepository; - - @Test - void 멤버의_즐겨찾기_주차장을_삭제한다() { - Long memberId = 1L; - Long parkingId = 1L; - Favorite favorite = new Favorite(Association.from(memberId), Association.from(parkingId)); - favoriteRepository.save(favorite); - - favoriteRepository.deleteByMemberIdAndParkingId(Association.from(memberId), Association.from(parkingId)); - assertThat(favoriteRepository.findByMemberId(Association.from(memberId))).isEmpty(); - } - - @Test - void 멤버의_즐겨찾기_주차장을_조회한다() { - // given - Long memberId = 1L; - Long memberId2 = 2L; - - Long parkingId = 1L; - Long parkingId2 = 2L; - Long parkingId3 = 3L; - Long parkingId4 = 4L; - - // when - favoriteRepository.save(new Favorite(Association.from(memberId), Association.from(parkingId))); - favoriteRepository.save(new Favorite(Association.from(memberId), Association.from(parkingId2))); - favoriteRepository.save(new Favorite(Association.from(memberId), Association.from(parkingId3))); - - favoriteRepository.save(new Favorite(Association.from(memberId2), Association.from(parkingId3))); - favoriteRepository.save(new Favorite(Association.from(memberId2), Association.from(parkingId4))); - - // then - assertThat(favoriteRepository.findByMemberId(Association.from(memberId))).hasSize(3); - } -} diff --git a/src/test/java/com/example/parking/domain/member/MemberTest.java b/src/test/java/com/example/parking/domain/member/MemberTest.java deleted file mode 100644 index ce8807cb..00000000 --- a/src/test/java/com/example/parking/domain/member/MemberTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.example.parking.domain.member; - -import static com.example.parking.support.exception.ExceptionInformation.INVALID_PASSWORD; - -import com.example.parking.support.exception.DomainException; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class MemberTest { - - @Test - void 비밀번호가_일치하면_true_를_반환한다() { - // given - String plainPassword = "password"; - Password password = new Password(plainPassword); - Member member = new Member("email@google.com", "nickname", password); - - // when, then - Assertions.assertThat(member.checkPassword(plainPassword)).isTrue(); - } - - @Test - void 비밀번호가_일치하지_않으면_false_를_반환한다() { - // given - String plainPassword = "password"; - Password password = new Password(plainPassword); - Member member = new Member("email@google.com", "nickname", password); - String wrongPlainPassword = "wrongPassword"; - - // when, then - Assertions.assertThat(member.checkPassword(wrongPlainPassword)).isFalse(); - } - - @Test - void 비밀번호를_바꾼다() { - // given - String previousPassword = "password"; - Password password = new Password(previousPassword); - Member member = new Member("email@google.com", "nickname", password); - String newPassword = "newPassword"; - - // when - member.changePassword(previousPassword, newPassword); - - // then - Assertions.assertThat(member.checkPassword(newPassword)).isTrue(); - } - - @Test - void 비밀번호를_바꿀_때_이전의_비밀번호가_일치하지_않으면_예외를_던진다() { - // given - String previousPassword = "password"; - Password password = new Password(previousPassword); - Member member = new Member("email@google.com", "nickname", password); - String newPassword = "newPassword"; - - String wrongPreviousPassword = "wrongPassword"; - - // when, then - Assertions.assertThatThrownBy(() -> member.changePassword(wrongPreviousPassword, newPassword)) - .isInstanceOf(DomainException.class) - .hasMessage(INVALID_PASSWORD.getMessage()); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/BaseInformationTest.java b/src/test/java/com/example/parking/domain/parking/BaseInformationTest.java deleted file mode 100644 index ef2bddb1..00000000 --- a/src/test/java/com/example/parking/domain/parking/BaseInformationTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.parking.domain.parking; - -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class BaseInformationTest { - - @Test - void 결제_방식_포함_여부를_확인한다() { - PayTypes defaultPayTypes = PayTypes.from(List.of(PayType.NO_INFO)); - - Assertions.assertThat(defaultPayTypes.contains(List.of(PayType.CARD))).isTrue(); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/DayTest.java b/src/test/java/com/example/parking/domain/parking/DayTest.java deleted file mode 100644 index 427e636a..00000000 --- a/src/test/java/com/example/parking/domain/parking/DayTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.example.parking.domain.parking; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.time.DayOfWeek; -import java.util.stream.Stream; - -class DayTest { - - @ParameterizedTest - @MethodSource("getDayOfWeek") - void 요일을_주중_토요일_공휴일로_나눈다(DayOfWeek dayOfWeek, Day expected) { - // given, when, then - Assertions.assertThat(Day.from(dayOfWeek)) - .isSameAs(expected); - } - - static Stream getDayOfWeek() { - return Stream.of( - Arguments.of( - DayOfWeek.MONDAY, - Day.WEEKDAY - ), - Arguments.of( - DayOfWeek.TUESDAY, - Day.WEEKDAY - ), - Arguments.of( - DayOfWeek.WEDNESDAY, - Day.WEEKDAY - ), - Arguments.of( - DayOfWeek.THURSDAY, - Day.WEEKDAY - ), - Arguments.of( - DayOfWeek.FRIDAY, - Day.WEEKDAY - ), - Arguments.of( - DayOfWeek.SATURDAY, - Day.SATURDAY - ), - Arguments.of( - DayOfWeek.SUNDAY, - Day.HOLIDAY - ) - ); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/FeePolicyTest.java b/src/test/java/com/example/parking/domain/parking/FeePolicyTest.java deleted file mode 100644 index 398cb0fc..00000000 --- a/src/test/java/com/example/parking/domain/parking/FeePolicyTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.example.parking.domain.parking; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -class FeePolicyTest { - - @ParameterizedTest - @MethodSource("getFee") - void 주어진_시간의_요금을_계산한다(FeePolicy feePolicy, int minutes, Fee expected) { - // given, when - Fee actual = feePolicy.calculateFee(minutes); - - // then - Assertions.assertThat(actual).isEqualTo(expected); - } - - static Stream getFee() { - return Stream.of( - Arguments.of( - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(15), - TimeUnit.from(15), - Fee.from(10000)), - 60, - Fee.from(8000) - ), - Arguments.of( - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(15), - TimeUnit.from(15), - Fee.from(10000)), - 2000, - Fee.from(10000) - ), - Arguments.of( - new FeePolicy( - Fee.from(0), - Fee.from(2000), - TimeUnit.from(15), - TimeUnit.from(15), - Fee.from(10000)), - 46, - Fee.from(6000) - ), - Arguments.of( - new FeePolicy( - Fee.from(1000), - Fee.from(2000), - TimeUnit.from(15), - TimeUnit.from(15), - Fee.from(10000)), - 46, - Fee.from(7000) - ), - Arguments.of( - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(55000)), - 180, - Fee.from(22000) - ), - Arguments.of( - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(55000)), - 0, - Fee.from(0) - ) - ); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/FeeTest.java b/src/test/java/com/example/parking/domain/parking/FeeTest.java deleted file mode 100644 index c287dd76..00000000 --- a/src/test/java/com/example/parking/domain/parking/FeeTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.example.parking.domain.parking; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class FeeTest { - - @Test - void 단위_요금에_시간을_곱한다() { - // given - Fee fee = Fee.from(500); - int time = 10; - Fee expected = Fee.from(5000); - - // when - Fee actual = fee.multiply(time); - - // then - Assertions.assertThat(actual).isEqualTo(expected); - } - - @Test - void 요금끼리_더한다() { - // given - Fee fee = Fee.from(500); - Fee otherFee = Fee.from(500); - Fee expected = Fee.from(1000); - - // when - Fee actual = fee.plus(otherFee); - - // then - Assertions.assertThat(actual).isEqualTo(expected); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/FreeOperatingTimeTest.java b/src/test/java/com/example/parking/domain/parking/FreeOperatingTimeTest.java deleted file mode 100644 index 6cf7cd3e..00000000 --- a/src/test/java/com/example/parking/domain/parking/FreeOperatingTimeTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.example.parking.domain.parking; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.time.LocalTime; -import java.util.stream.Stream; - -class FreeOperatingTimeTest { - - @ParameterizedTest - @MethodSource("getFreeOperatingTime") - void 돈을_지불_해야_할_시간을_계산한다(FreeOperatingTime freeOperatingTime, DayParking dayParking, int expected) { - // given, when, then - Assertions.assertThat(freeOperatingTime.calculateNonFreeUsageMinutes(dayParking)) - .isEqualTo(expected); - } - - static Stream getFreeOperatingTime() { - return Stream.of( - /* - 주중 무료 시간 : 00:00 ~ 24:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 주중 - 주차 시간 : 00:00 ~ 24:00 - 주차 시간(분) : 1440분 - 무료 시간(분) : 1440분 - 유료 시간(분) : 0분 - */ - Arguments.of( - FreeOperatingTime.ALWAYS_FREE, - new DayParking(Day.WEEKDAY, LocalTime.MIN, LocalTime.MAX), - 0 - ), - /* - 주중 무료 시간 : 09:00 ~ 13:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 주중 - 주차 시간 : 00:00 ~ 24:00 - 주차 시간(분) : 1440분 - 무료 시간(분) : 240분 - 유료 시간(분) : 1200분 - */ - Arguments.of( - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9, 0), LocalTime.of(13, 0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new DayParking(Day.WEEKDAY, LocalTime.MIN, LocalTime.MAX), - 1200 - ), - /* - 주중 무료 시간 : 09:00 ~ 13:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 주중 - 주차 시간 : 09:00 ~ 13:00 - 주차 시간(분) : 240분 - 무료 시간(분) : 240분 - 유료 시간(분) : 0분 - */ - Arguments.of( - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9, 0), LocalTime.of(13, 0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new DayParking(Day.WEEKDAY, LocalTime.of(9, 0), LocalTime.of(13, 0)), - 0 - ), - /* - 주중 무료 시간 : 09:00 ~ 13:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 주중 - 주차 시간 : 08:00 ~ 12:00 - 주차 시간(분) : 240분 - 무료 시간(분) : 180분 - 유료 시간(분) : 60분 - */ - Arguments.of( - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9, 0), LocalTime.of(13, 0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new DayParking(Day.WEEKDAY, LocalTime.of(8, 0), LocalTime.of(12, 0)), - 60 - ), - /* - 주중 무료 시간 : 09:00 ~ 13:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 주중 - 주차 시간 : 10:20 ~ 12:50 - 주차 시간(분) : 150분 - 무료 시간(분) : 150분 - 유료 시간(분) : 0분 - */ - Arguments.of( - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9, 0), LocalTime.of(13, 0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new DayParking(Day.WEEKDAY, LocalTime.of(10, 20), LocalTime.of(12, 50)), - 0 - ), - /* - 주중 무료 시간 : 09:00 ~ 13:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 주중 - 주차 시간 : 13:20 ~ 14:45 - 주차 시간(분) : 85분 - 무료 시간(분) : 0분 - 유료 시간(분) : 85분 - */ - Arguments.of( - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9, 0), LocalTime.of(13, 0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new DayParking(Day.WEEKDAY, LocalTime.of(13, 20), LocalTime.of(14, 45)), - 85 - ), - /* - 주중 무료 시간 : 09:00 ~ 13:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 주중 - 주차 시간 : 11:20 ~ 19:00 - 주차 시간(분) : 460분 - 무료 시간(분) : 100분 - 유료 시간(분) : 360분 - */ - Arguments.of( - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9, 0), LocalTime.of(13, 0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new DayParking(Day.WEEKDAY, LocalTime.of(11, 20), LocalTime.of(19, 0)), - 360 - ), - /* - 주중 무료 시간 : 09:00 ~ 13:00 - 토요일 무료 시간 : 00:00 ~ 24:00 - 공휴일 무료 시간 : 00:00 ~ 24:00 - - 주차 요일 : 토요일 - 주차 시간 : 11:20 ~ 19:00 - 주차 시간(분) : 460분 - 무료 시간(분) : 460분 - 유료 시간(분) : 0분 - */ - Arguments.of( - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9, 0), LocalTime.of(13, 0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new DayParking(Day.SATURDAY, LocalTime.of(11, 20), LocalTime.of(19, 0)), - 0 - ) - ); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/LocationTest.java b/src/test/java/com/example/parking/domain/parking/LocationTest.java deleted file mode 100644 index 11811709..00000000 --- a/src/test/java/com/example/parking/domain/parking/LocationTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example.parking.domain.parking; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; - -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -class LocationTest { - - @Test - void 위도와_경도를_통해_Point객체를_가진_Location객체를_생성한다() { - double latitude = 37.4809626; - double longitude = 127.1216765; - - Location location = Location.of(longitude, latitude); - - assertAll( - () -> assertThat(location.getLongitude()).isEqualTo(longitude), - () -> assertThat(location.getLatitude()).isEqualTo(latitude) - ); - } - - @CsvSource({"0.1, -", " , 0.2", "nil, nil"}) - @ParameterizedTest - void 이상한_값이_들어오면_특정_음수_좌표를_반환한다(String longitude, String latitude) { - //given, when - Location actual = Location.of(longitude, latitude); - Location expected = Location.of("-1.0", "-1.0"); - - //then - assertThat(actual).isEqualTo(expected); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/ParkingFeeCalculatorTest.java b/src/test/java/com/example/parking/domain/parking/ParkingFeeCalculatorTest.java deleted file mode 100644 index b0850b79..00000000 --- a/src/test/java/com/example/parking/domain/parking/ParkingFeeCalculatorTest.java +++ /dev/null @@ -1,395 +0,0 @@ -package com.example.parking.domain.parking; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.stream.Stream; - -class ParkingFeeCalculatorTest { - - private final ParkingFeeCalculator parkingFeeCalculator = new ParkingFeeCalculator(); - - @ParameterizedTest - @MethodSource("getParkingFeeCalculator") - void 주차요금을_계산한다(Parking parking, LocalDateTime beginTime, LocalDateTime endTime, Fee expected) { - // given, when - Fee actual = parkingFeeCalculator.calculateParkingFee(parking, beginTime, endTime); - - // then - Assertions.assertThat(actual).isEqualTo(expected); - } - - static Stream getParkingFeeCalculator() { - return Stream.of( - /* - 주차장 정보 - [무료 운영 정보] - 주중 : 09:00 ~ 12:00 무료 - 토요일 : 00:00 ~ 24:00 무료 - 일요일 : 00:00 ~ 24:00 무료 - - [요금 정보] - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 요금 : 50000원 - - 주차 정보 - 주차 시작 시각 : 2024/2/16/금/09:00 - 주차 종료 시각 : 2024/2/16/금/21:00 - - 계산 주차 금액 - 1. 2/16 유료 주차 시간 : 2024/2/16/12:00 ~ 2024/2/16/21:00 (540분) - 1. 2/16 주차 금액 : 2000원 + 68000원 = 70000원 -> 하루 최대 요금 적용 -> 50000원 - - 주차 금액 합 : 50000원 - */ - Arguments.of( - new Parking( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9,0), - LocalTime.of(12,0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000) - ) - ), - LocalDateTime.of(2024, 2, 16, 9, 0), - LocalDateTime.of(2024, 2, 16, 21, 0), - Fee.from(50000) - ), - /* - 주차장 정보 - [무료 운영 정보] - 주중 : 09:00 ~ 12:00 무료 - 토요일 : 00:00 ~ 24:00 무료 - 일요일 : 00:00 ~ 24:00 무료 - - [요금 정보] - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 요금 : 50000원 - - 주차 정보 - 주차 시작 시각 : 2024/2/16/금/09:00 - 주차 종료 시각 : 2024/2/16/금/13:16 - - 계산 주차 금액 - 1. 2/16 유료 주차 시간 : 2024/2/16/12:00 ~ 2024/2/16/13:16 (76분) - 1. 2/16 주차 금액 : 2000원 + 8000원 = 10000원 - - 주차 금액 합 : 10000원 - */ - Arguments.of( - new Parking( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9,0), - LocalTime.of(12,0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000) - ) - ), - LocalDateTime.of(2024, 2, 16, 9, 0), - LocalDateTime.of(2024, 2, 16, 13, 16), - Fee.from(10000) - ), - /* - 주차장 정보 - [무료 운영 정보] - 주중 : 09:00 ~ 12:00 무료 - 토요일 : 00:00 ~ 24:00 무료 - 일요일 : 00:00 ~ 24:00 무료 - - [요금 정보] - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 요금 : 50000원 - - 주차 정보 - 주차 시작 시각 : 2024/2/16/금/10:00 - 주차 종료 시각 : 2024/2/16/금/12:01 - - 계산 주차 금액 - 1. 2/16 유료 주차 시간 : 2024/2/16/12:00 ~ 2024/2/16/12:01 (1분) - 1. 2/16 주차 금액 : 2000원 (기본 요금) - - 주차 금액 합 : 2000원 - */ - Arguments.of( - new Parking( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9,0), - LocalTime.of(12,0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000) - ) - ), - LocalDateTime.of(2024, 2, 16, 10, 0), - LocalDateTime.of(2024, 2, 16, 12, 1), - Fee.from(2000) - ), - /* - 주차장 정보 - [무료 운영 정보] - 주중 : 09:00 ~ 12:00 무료 - 토요일 : 00:00 ~ 24:00 무료 - 일요일 : 00:00 ~ 24:00 무료 - - [요금 정보] - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 요금 : 50000원 - - 주차 정보 - 주차 시작 시각 : 2024/2/16/금/21:00 - 주차 종료 시각 : 2024/2/17/토/09:00 - - 계산 주차 금액 - 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) - 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 - - 2. 2/17 유료 주차 시간 : 없음 - 2. 2/17 주차 금액 : 0원 - - 주차 금액 합 : 22000원 - */ - Arguments.of( - new Parking( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9,0), - LocalTime.of(12,0) - ), - TimeInfo.ALL_DAY, - TimeInfo.ALL_DAY - ), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000) - ) - ), - LocalDateTime.of(2024, 2, 16, 21, 0), - LocalDateTime.of(2024, 2, 17, 9, 0), - Fee.from(22000) - ), - /* - 주차장 정보 - [무료 운영 정보] - 주중 : 09:00 ~ 12:00 무료 - 토요일 : 06:00 ~ 24:00 무료 - 일요일 : 00:00 ~ 24:00 무료 - - [요금 정보] - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 요금 : 50000원 - - 주차 정보 - 주차 시작 시각 : 2024/2/16/금/21:00 - 주차 종료 시각 : 2024/2/17/토/09:00 - - 계산 주차 금액 - 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) - 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 - - 2. 2/17 유료 주차 시간 : 2024/2/17/00:00 ~ 2024/2/17/06:00 (360분) - 2. 2/17 주차 금액 : 2000원 + 44000원 = 46000원 - - 주차 금액 합 : 68000원 - */ - Arguments.of( - new Parking( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9,0), - LocalTime.of(12,0) - ), - new TimeInfo( - LocalTime.of(6,0), - LocalTime.MAX - ), - TimeInfo.ALL_DAY - ), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000) - ) - ), - LocalDateTime.of(2024, 2, 16, 21, 0), - LocalDateTime.of(2024, 2, 17, 9, 0), - Fee.from(68000) - ), - /* - 주차장 정보 - [무료 운영 정보] - 주중 : 09:00 ~ 12:00 무료 - 토요일 : 00:00 ~ 24:00 무료 - 일요일 : 04:00 ~ 24:00 무료 - - [요금 정보] - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 요금 : 50000원 - - 주차 정보 - 주차 시작 시각 : 2024/2/16/금/21:00 - 주차 종료 시각 : 2024/2/18/일/09:00 - - 계산 주차 금액 - 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) - 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 - - 2. 2/17 유료 주차 시간 : 없음 - 2. 2/17 주차 금액 : 0원 - - 3. 2/18 유료 주차 시간 : 2024/2/18/00:00 ~ 2024/2/18/04:00 (240분) - 3. 2/18 주차 금액 : 2000원 + 28000원 = 30000원 - - 주차 금액 합 : 22000원 + 0원 + 30000원 = 52000원 - */ - Arguments.of( - new Parking( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9,0), - LocalTime.of(12,0) - ), - TimeInfo.ALL_DAY, - new TimeInfo( - LocalTime.of(4,0), - LocalTime.MAX - ) - ), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000) - ) - ), - LocalDateTime.of(2024, 2, 16, 21, 0), - LocalDateTime.of(2024, 2, 18, 9, 0), - Fee.from(52000) - ), - /* - 주차장 정보 - [무료 운영 정보] - 주중 : 09:00 ~ 12:00 무료 - 토요일 : 00:00 ~ 24:00 무료 - 일요일 : 04:00 ~ 24:00 무료 - - [요금 정보] - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 요금 : 50000원 - - 주차 정보 - 주차 시작 시각 : 2024/2/16/금/21:00 - 주차 종료 시각 : 2024/2/18/월/05:00 - - 계산 주차 금액 - 1. 2/16 유료 주차 시간 : 2024/2/16/21:00 ~ 2024/2/16/24:00 (180분) - 1. 2/16 주차 금액 : 2000원 + 20000원 = 22000원 - - 2. 2/17 유료 주차 시간 : 없음 - 2. 2/17 주차 금액 : 0원 - - 3. 2/18 유료 주차 시간 : 2024/2/18/00:00 ~ 2024/2/18/04:00 (240분) - 3. 2/18 주차 금액 : 2000원 + 28000원 = 30000원 - - 4. 2/19 유료 주차 시간 : 2024/2/19/00:00 ~ 2024/2/19/05:01 (301분) - 4. 2/19 주차 금액 : 2000원 + 38000원 = 40000원 - 주차 금액 합 : 22000원 + 0원 + 30000원 + 40000원 = 92000원 - */ - Arguments.of( - new Parking( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime( - new TimeInfo( - LocalTime.of(9,0), - LocalTime.of(12,0) - ), - TimeInfo.ALL_DAY, - new TimeInfo( - LocalTime.of(4,0), - LocalTime.MAX - ) - ), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000) - ) - ), - LocalDateTime.of(2024, 2, 16, 21, 0), - LocalDateTime.of(2024, 2, 19, 5, 1), - Fee.from(92000) - ) - ); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/ParkingTest.java b/src/test/java/com/example/parking/domain/parking/ParkingTest.java deleted file mode 100644 index 4b33b123..00000000 --- a/src/test/java/com/example/parking/domain/parking/ParkingTest.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.example.parking.domain.parking; - -import java.util.stream.Stream; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class ParkingTest { - - @Test - void 목적지와_68미터_떨어진_주차장_도보_예상시간_계산() { - // given (parking 과 destination 거리 68m) - int expectedTime = (int) Math.ceil(0.068 / 5); - Parking parking = Parking.builder() - .location(Location.of(127.1215865, 37.4811181)) - .build(); - Location destination = Location.of(127.1213647, 37.4817298); - - // when - int walkingTime = parking.calculateWalkingTime(destination); - - // then - Assertions.assertThat(walkingTime).isEqualTo(expectedTime); - } - - @Test - void 목적지와_333미터_떨어진_주차장_도보_예상시간_계산() { - // given (parking 과 destination 거리 68m) - int expectedTime = (int) Math.ceil(0.333 / 5); - Parking parking = Parking.builder() - .location(Location.of(127.1215865, 37.4811181)) - .build(); - Location destination = Location.of(127.1186224, 37.479259); - - // when - int walkingTime = parking.calculateWalkingTime(destination); - - // then - Assertions.assertThat(walkingTime).isEqualTo(expectedTime); - } - - @ParameterizedTest - @MethodSource("getParking") - void 주어진_주차장_정보에_따라_하루_요금_계산을_한다(Parking parking, int payOfChargeMinutes, Fee expected) { - // given, when - Fee actual = parking.calculateParkingFee(payOfChargeMinutes); - - // then - Assertions.assertThat(actual).isEqualTo(expected); - } - - static Stream getParking() { - return Stream.of( - /* - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 주차 요금 : 50000원 - - 주차 시간 : 100분 - 주차 금액 : 2000원 + 10000원 = 12000원 - */ - Arguments.of( - new Parking - ( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime(), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000)) - ), - 100, - Fee.from(12000) - ), - /* - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 주차 요금 : 50000원 - - 주차 시간 : 30분 - 주차 금액 : 2000원 - */ - Arguments.of( - new Parking - ( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime(), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000)) - ), - 30, - Fee.from(2000) - ), - /* - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 주차 요금 : 50000원 - - 주차 시간 : 31분 - 주차 금액 : 2000 + 2000원 = 4000원 - */ - Arguments.of( - new Parking - ( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime(), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000)) - ), - 31, - Fee.from(4000) - ), - /* - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 주차 요금 : 50000원 - - 주차 시간 : 480분 - 주차 금액 : 2000 + 60000원 = 62000원 -> 하루 최대 요금 50000원 적용 - */ - Arguments.of( - new Parking - ( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime(), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000)) - ), - 480, - Fee.from(50000) - ), - /* - 기본 주차 요금 정책 : 30분당 2000원 - 추가 주차 요금 정책 : 15분당 2000원 - 하루 최대 주차 요금 : 50000원 - - 주차 시간 : 374분 - 주차 금액 : 2000 + 46000원 = 48000원 - */ - Arguments.of( - new Parking - ( - new BaseInformation(), - new Location(), - new Space(), - new FreeOperatingTime(), - new OperatingTime(), - new FeePolicy( - Fee.from(2000), - Fee.from(2000), - TimeUnit.from(30), - TimeUnit.from(15), - Fee.from(50000)) - ), - 374, - Fee.from(48000) - ) - ); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/PayTypesTest.java b/src/test/java/com/example/parking/domain/parking/PayTypesTest.java deleted file mode 100644 index d668fa87..00000000 --- a/src/test/java/com/example/parking/domain/parking/PayTypesTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.example.parking.domain.parking; - -import static com.example.parking.domain.parking.PayType.BANK_TRANSFER; -import static com.example.parking.domain.parking.PayType.CARD; -import static com.example.parking.domain.parking.PayType.CASH; -import static com.example.parking.domain.parking.PayType.NO_INFO; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.params.provider.Arguments.arguments; - -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.stream.Stream; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -class PayTypesTest { - - @ParameterizedTest - @MethodSource("parametersProvider") - void 열거형으로_결제방식을_생성한다(Collection payTypes, String expected) { - //given, when - PayTypes actual = PayTypes.from(payTypes); - - //then - assertThat(actual.getDescription()).isEqualTo(expected); - } - - @Test - void 결제방식_포함_시_true() { - //given, when - PayTypes actual = PayTypes.from(List.of(CARD, CASH)); - - //then - assertThat(actual.contains(List.of(CARD))).isTrue(); - } - - @Test - void 결제방식_미포함_시_false() { - //given, when - PayTypes actual = PayTypes.from(List.of(CARD, CASH)); - - //then - assertThat(actual.contains(List.of(BANK_TRANSFER))).isFalse(); - } - - static Stream parametersProvider() { - final String DELIMITER = ", "; - return Stream.of( - arguments(Set.of(CARD), CARD.getDescription()), - arguments(Set.of(CARD, CASH), CARD.getDescription() + DELIMITER + CASH.getDescription()), - arguments(Set.of(CARD, CASH, BANK_TRANSFER), - BANK_TRANSFER.getDescription() + DELIMITER + CARD.getDescription() + DELIMITER - + CASH.getDescription()), - arguments(Set.of(CARD, CASH, BANK_TRANSFER, NO_INFO), NO_INFO.getDescription()) - ); - } -} - - diff --git a/src/test/java/com/example/parking/domain/parking/TimeInfoTest.java b/src/test/java/com/example/parking/domain/parking/TimeInfoTest.java deleted file mode 100644 index 1bddde9e..00000000 --- a/src/test/java/com/example/parking/domain/parking/TimeInfoTest.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.example.parking.domain.parking; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.time.LocalTime; -import java.util.stream.Stream; - -class TimeInfoTest { - - @ParameterizedTest - @MethodSource("getTimeInfos") - void 겹치는_시간이_몇_분인지_계산한다(TimeInfo timeInfo, LocalTime beginTime, LocalTime endTime, int expected) { - // given, when, then - Assertions.assertThat(timeInfo.calculateOverlapMinutes(beginTime, endTime)) - .isEqualTo(expected); - } - - static Stream getTimeInfos() { - return Stream.of( - /* - 무료 운영 시간 : 00:00 ~ 24:00 - 주차 시간 : 00:00 ~ 24:00 - 겹침 시간 : 00:00 ~ 24:00 -> 1440분 - */ - Arguments.of( - new TimeInfo(LocalTime.MIN, LocalTime.MAX), - LocalTime.MIN, - LocalTime.MAX, - 1440), - /* - 무료 운영 시간 : 00:00 ~ 24:00 - 주차 시간 : 01:30 ~ 22:11 - 겹침 시간 : 01:30 ~ 22:11 -> 1241분 - */ - Arguments.of( - new TimeInfo(LocalTime.MIN, LocalTime.MAX), - LocalTime.of(1, 30), - LocalTime.of(22, 11), - 1241), - /* - 무료 운영 시간 : 09:00 ~ 21:00 - 주차 시간 : 08:00 ~ 09:00 - 겹침 시간 : 겹치지 않는다 -> 0분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), - LocalTime.of(8, 0), - LocalTime.of(9, 0), - 0), - /* - 무료 운영 시간 : 09:00 ~ 21:00 - 주차 시간 : 08:00 ~ 09:30 - 겹침 시간 : 09:00 ~ 09:30 -> 30분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), - LocalTime.of(8, 0), - LocalTime.of(9, 30), - 30), - /* - 무료 운영 시간 : 09:00 ~ 21:00 - 주차 시간 : 08:00 ~ 21:00 - 겹침 시간 : 09:00 ~ 21:00 -> 720분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), - LocalTime.of(8, 0), - LocalTime.of(21, 0), - 720), - /* - 무료 운영 시간 : 09:00 ~ 21:00 - 주차 시간 : 08:00 ~ 22:40 - 겹침 시간 : 00:00 ~ 24:00 -> 1440분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), - LocalTime.of(8, 0), - LocalTime.of(22, 40), - 720), - /* - 무료 운영 시간 : 09:00 ~ 21:00 - 주차 시간 : 10:00 ~ 17:20 - 겹침 시간 : 10:00 ~ 17:20 -> 440분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), - LocalTime.of(10, 0), - LocalTime.of(17, 20), - 440), - /* - 무료 운영 시간 : 09:00 ~ 21:00 - 주차 시간 : 10:00 ~ 21:00 - 겹침 시간 : 10:00 ~ 21:00 -> 660분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), - LocalTime.of(10, 0), - LocalTime.of(21, 0), - 660), - /* - 무료 운영 시간 : 09:00 ~ 21:00 - 주차 시간 : 21:00 ~ 23:00 - 겹침 시간 : 겹치지 않는다 -> 0분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(9, 0), LocalTime.of(21, 0)), - LocalTime.of(21, 0), - LocalTime.of(23, 0), - 0), - /* - 무료 운영 시간 : 21:00 ~ 09:00 - 주차 시간 : 21:00 ~ 24:00 - 겹침 시간 : 21:00 ~ 24:00 -> 180분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), - LocalTime.of(21, 0), - LocalTime.MAX, - 180), - /* - 무료 운영 시간 : 21:00 ~ 09:00 - 주차 시간 : 09:00 ~ 21:00 - 겹침 시간 : 겹치지 않는다 -> 0분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), - LocalTime.of(9, 0), - LocalTime.of(21, 0), - 0), - /* - 무료 운영 시간 : 21:00 ~ 09:00 - 주차 시간 : 09:00 ~ 21:01 - 겹침 시간 : 21:00 ~ 21:01 -> 1분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), - LocalTime.of(9, 0), - LocalTime.of(21, 1), - 1), - /* - 무료 운영 시간 : 21:00 ~ 09:00 - 주차 시간 : 08:59 ~ 21:00 - 겹침 시간 : 08:59 ~ 09:00 -> 1분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), - LocalTime.of(8, 59), - LocalTime.of(21, 0), - 1), - /* - 무료 운영 시간 : 21:00 ~ 09:00 - 주차 시간 : 08:59 ~ 21:01 - 겹침 시간 : 08:59 ~ 09:00 + 21:00 ~ 21:01 -> 2분 - */ - Arguments.of( - new TimeInfo(LocalTime.of(21, 0), LocalTime.of(9, 0)), - LocalTime.of(8, 59), - LocalTime.of(21, 1), - 2) - ); - } -} diff --git a/src/test/java/com/example/parking/domain/parking/TimeUnitTest.java b/src/test/java/com/example/parking/domain/parking/TimeUnitTest.java deleted file mode 100644 index f32c64f1..00000000 --- a/src/test/java/com/example/parking/domain/parking/TimeUnitTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.example.parking.domain.parking; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; - -class TimeUnitTest { - - @Test - void 시간_단위의_대소_비교한다() { - // given - TimeUnit timeUnit = TimeUnit.from(100); - int otherTimeUnit = 1000; - boolean expected = false; - - // when - boolean actual = timeUnit.isEqualOrGreaterThan(otherTimeUnit); - - // then - Assertions.assertThat(actual).isEqualTo(expected); - } - - @ParameterizedTest - @CsvSource(value = {"10:60:6", "10:59:6"}, delimiter = ':') - void 시간을_단위_시간으로_나눈_몫을_구한다(int timeUnit, int time, int expected) { - // given - TimeUnit unit = TimeUnit.from(timeUnit); - - // when - int actual = unit.calculateQuotient(time); - - // then - Assertions.assertThat(actual).isEqualTo(expected); - } -} diff --git a/src/test/java/com/example/parking/domain/review/ContentTest.java b/src/test/java/com/example/parking/domain/review/ContentTest.java deleted file mode 100644 index dc6f3859..00000000 --- a/src/test/java/com/example/parking/domain/review/ContentTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.example.parking.domain.review; - -import static com.example.parking.support.exception.ExceptionInformation.INVALID_CONTENT; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.params.provider.Arguments.arguments; - -import com.example.parking.support.exception.DomainException; -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class ContentTest { - - @ParameterizedTest - @MethodSource("parametersProvider") - void 설명에_Content를_반환한다(String description, Content expected) { - //given, when - Content actual = Content.find(description); - - //then - assertThat(actual).isEqualTo(expected); - } - - static Stream parametersProvider() { - return Stream.of( - arguments("결제가 편리해요", Content.EASY_TO_PAY), - arguments("직원", Content.FRIENDLY_STAFF) - ); - } - - @Test - void 설명에_맞는_Content가_없으면_예외처리한다() { - //given, when, then - assertThatThrownBy(() -> Content.find("없는 설명")) - .isInstanceOf(DomainException.class) - .hasMessage(INVALID_CONTENT.getMessage()); - } -} diff --git a/src/test/java/com/example/parking/domain/review/service/ReviewDomainServiceTest.java b/src/test/java/com/example/parking/domain/review/service/ReviewDomainServiceTest.java deleted file mode 100644 index a28c9530..00000000 --- a/src/test/java/com/example/parking/domain/review/service/ReviewDomainServiceTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.example.parking.domain.review.service; - -import static com.example.parking.support.exception.ExceptionInformation.DUPLICATE_REVIEW; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.example.parking.support.Association; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.review.Content; -import com.example.parking.domain.review.Review; -import com.example.parking.fake.BasicReviewRepository; -import com.example.parking.support.exception.DomainException; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.Test; - -class ReviewDomainServiceTest { - - private final BasicReviewRepository reviewRepository = new BasicReviewRepository(); - private final ReviewDomainService reviewDomainService = new ReviewDomainService(reviewRepository); - - @Test - void 같은_주차장에_리뷰를_작성하면_예외가_발생한다() { - //given - Association parkingId = Association.from(1L); - Association reviewerId = Association.from(1L); - reviewRepository.save(new Review(parkingId, reviewerId, List.of(Content.LOW_PRICE))); - - //when, then - assertThatThrownBy(() -> reviewDomainService.validateDuplicateReview(parkingId, reviewerId)) - .isInstanceOf(DomainException.class) - .hasMessage(DUPLICATE_REVIEW.getMessage()); - } - - @Test - void 리뷰를_내용별로_집계한다() { - //given - List reviews = List.of( - new Review(Association.from(1L), Association.from(1L), - List.of(Content.LOW_PRICE) - ), - new Review(Association.from(1L), Association.from(2L), - List.of(Content.LOW_PRICE, Content.EASY_TO_PAY) - ), - new Review(Association.from(1L), Association.from(3L), - List.of(Content.LOW_PRICE, Content.EASY_TO_PAY, Content.GOOD_ACCESSIBILITY) - ) - ); - //when - Map actual = reviewDomainService.collectByContent(reviews); - - //then - assertSoftly(soft -> { - soft.assertThat(actual.get(Content.LOW_PRICE)).isEqualTo(3L); - soft.assertThat(actual.get(Content.EASY_TO_PAY)).isEqualTo(2L); - soft.assertThat(actual.get(Content.GOOD_ACCESSIBILITY)).isEqualTo(1L); - }); - } - - @Test - void 전체_리뷰수를_구한다() { - //given - List contents1 = List.of(Content.LOW_PRICE); - List contents2 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY); - List contents3 = List.of(Content.LOW_PRICE, Content.EASY_TO_PAY, Content.GOOD_ACCESSIBILITY); - List reviews = List.of( - new Review(Association.from(1L), Association.from(1L), - contents1 - ), - new Review(Association.from(1L), Association.from(2L), - contents2 - ), - new Review(Association.from(1L), Association.from(3L), - contents3 - ) - ); - Map counts = reviewDomainService.collectByContent(reviews); - - //when - int actual = reviewDomainService.calculateTotalReviews(counts); - - //then - assertThat(actual).isEqualTo(contents1.size() + contents2.size() + contents3.size()); - } -} diff --git a/src/test/java/com/example/parking/domain/searchcondition/EnumListConverterTest.java b/src/test/java/com/example/parking/domain/searchcondition/EnumListConverterTest.java deleted file mode 100644 index a8b8081f..00000000 --- a/src/test/java/com/example/parking/domain/searchcondition/EnumListConverterTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.example.parking.infra.converter.FeeTypeConverter; -import java.util.List; -import java.util.stream.Collectors; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class EnumListConverterTest { - - @DisplayName("DB에 Enum을 List형식으로 저장할 때, Enum의 값 이름과 " + '"' + ", " + '"'+ " 구분자를 이용해서 저장된다.") - @Test - void convertTest() { - //given - FeeTypeConverter feeTypeConverter = new FeeTypeConverter(); - List expectedFeeType = List.of(FeeType.FREE, FeeType.PAID); - String expectedDatabaseColumn = expectedFeeType.stream().map(FeeType::name) - .collect(Collectors.joining(", ")); - - //when - String actualDatabaseField = feeTypeConverter.convertToDatabaseColumn(expectedFeeType); - List actualFeeTypes = feeTypeConverter.convertToEntityAttribute(actualDatabaseField); - - //then - assertThat(actualDatabaseField).isEqualTo(expectedDatabaseColumn); - assertThat(actualFeeTypes).isEqualTo(expectedFeeType); - } -} diff --git a/src/test/java/com/example/parking/domain/searchcondition/HoursTest.java b/src/test/java/com/example/parking/domain/searchcondition/HoursTest.java deleted file mode 100644 index 9aa777cc..00000000 --- a/src/test/java/com/example/parking/domain/searchcondition/HoursTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import static com.example.parking.support.exception.ExceptionInformation.INVALID_HOURS; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -import com.example.parking.support.exception.DomainException; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; - -class HoursTest { - - @CsvSource({"1, false", "12, false", "24, false", "0, true", "13, true"}) - @ParameterizedTest - void 이용_시간은_1시간에서_12시간_사이_또는_24시간만_선택_가능하다(int hours, boolean hasException) { - //given, when, then - if (hasException) { - Assertions.assertThatThrownBy(() -> Hours.from(hours)) - .isInstanceOf(DomainException.class) - .hasMessage(INVALID_HOURS.getMessage()); - return; - } - assertDoesNotThrow(() -> Hours.from(hours)); - } -} diff --git a/src/test/java/com/example/parking/domain/searchcondition/SearchConditionMapperTest.java b/src/test/java/com/example/parking/domain/searchcondition/SearchConditionMapperTest.java deleted file mode 100644 index 948796ae..00000000 --- a/src/test/java/com/example/parking/domain/searchcondition/SearchConditionMapperTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.example.parking.domain.searchcondition; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.params.provider.Arguments.arguments; - -import com.example.parking.application.SearchConditionMapper; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayType; -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.List; -import java.util.stream.Stream; -import org.junit.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class SearchConditionMapperTest { - - private static final SearchConditionMapper searchConditionMapper = new SearchConditionMapper(); - - @ParameterizedTest - @MethodSource("parametersProvider1") - & SearchConditionAvailable> void enum_class와_설명으로_해당하는_값을_반환한다(Class clazz, - String description, - E expected) { - //given, when - E actual = searchConditionMapper.toEnum(clazz, description); - - //then - assertThat(actual).isEqualTo(expected); - } - - static Stream parametersProvider1() { - return Stream.of( - arguments(OperationType.class, "민영 주차장", OperationType.PRIVATE), - arguments(OperationType.class, "공영", OperationType.PUBLIC), - arguments(ParkingType.class, "노상", ParkingType.ON_STREET), - arguments(ParkingType.class, "노외 주차장", ParkingType.OFF_STREET), - arguments(FeeType.class, "무료", FeeType.FREE), - arguments(FeeType.class, "유료", FeeType.PAID), - arguments(PayType.class, "계좌", PayType.BANK_TRANSFER), - arguments(Priority.class, "가격순", Priority.PRICE) - ); - } - - @Test - void 변환시_해당하는_값이_없으면_클라이언트_예외를_반환한다() { - //given, when, then - assertThatThrownBy(() -> searchConditionMapper.toEnum(PayType.class, "아무거나 입력")) - .isInstanceOf(ClientException.class) - .hasMessage(ExceptionInformation.INVALID_DESCRIPTION.getMessage()); - } - - @ParameterizedTest - @MethodSource("parametersProvider2") - & SearchConditionAvailable> void enum_class와_설명들로_해당하는_값들을_반환한다(Class clazz, - List descriptions, - List expected) { - //given, when - List actual = searchConditionMapper.toEnums(clazz, descriptions); - - //then - assertThat(actual).containsExactlyInAnyOrderElementsOf(expected); - } - - static Stream parametersProvider2() { - return Stream.of( - arguments(OperationType.class, List.of("민영 주차장", "공영 주차장"), - List.of(OperationType.PRIVATE, OperationType.PUBLIC)), - arguments(OperationType.class, List.of("공영"), List.of(OperationType.PUBLIC)), - arguments(ParkingType.class, List.of("노상", "기계"), - List.of(ParkingType.ON_STREET, ParkingType.MECHANICAL)), - arguments(ParkingType.class, List.of("노외 주차장"), List.of(ParkingType.OFF_STREET)), - arguments(FeeType.class, List.of("무료", "유료"), List.of(FeeType.FREE, FeeType.PAID)), - arguments(FeeType.class, List.of("유료"), List.of(FeeType.PAID)), - arguments(PayType.class, List.of("계좌", "현금"), List.of(PayType.BANK_TRANSFER, PayType.CASH)), - arguments(Priority.class, List.of("가격순"), List.of(Priority.PRICE)) - ); - } - - @ParameterizedTest - @MethodSource("parametersProvider3") - & SearchConditionAvailable> void 해당하는_enum_class의_기본_값을_제외한_값들을_가져온다(Class clazz, - List expected) { - //given, when - List actual = searchConditionMapper.getValues(clazz); - - //then - assertThat(actual).containsExactlyInAnyOrderElementsOf(expected); - } - - static Stream parametersProvider3() { - return Stream.of( - arguments(OperationType.class, List.of("공영", "민영")), - arguments(ParkingType.class, List.of("노상", "기계", "노외")), - arguments(FeeType.class, List.of("무료", "유료")), - arguments(PayType.class, List.of("카드", "계좌", "현금")), - arguments(Priority.class, List.of("가까운순", "가격순")) - ); - } -} diff --git a/src/test/java/com/example/parking/external/scheduler/ParkingUpdateSchedulerTest.java b/src/test/java/com/example/parking/external/scheduler/ParkingUpdateSchedulerTest.java deleted file mode 100644 index 4f540769..00000000 --- a/src/test/java/com/example/parking/external/scheduler/ParkingUpdateSchedulerTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.example.parking.external.scheduler; - -import com.example.parking.external.coordinate.CoordinateService; -import com.example.parking.fake.BasicParkingRepository; -import com.example.parking.fake.ExceptionParkingApiService; -import com.example.parking.fake.FakeCoordinateService; -import com.example.parking.fake.FakeParkingService; -import com.example.parking.fake.NotOfferCurrentParkingApiService; -import com.example.parking.fake.OfferCurrentParkingApiService; -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class ParkingUpdateSchedulerTest { - - private final FakeParkingService parkingService = new FakeParkingService( - new BasicParkingRepository() - ); - private final CoordinateService coordinateService = new FakeCoordinateService(); - - @DisplayName("실시간 주차 대수를 제공하는 API에서 주차장이 0~4까지 저장되어 있는 상태에서 0~9까지 주차장을 읽어와 업데이트한다.") - @Test - void autoUpdateOfferCurrentParking() { - //given - OfferCurrentParkingApiService offerCurrentParkingApiService = new OfferCurrentParkingApiService(5); - parkingService.saveAll(offerCurrentParkingApiService.read()); - int readSize = 10; - offerCurrentParkingApiService.setReadSize(readSize); - - ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( - List.of(offerCurrentParkingApiService), - coordinateService, - parkingService - ); - - //when - scheduler.autoUpdateOfferCurrentParking(); - - //then - Assertions.assertThat(parkingService.count()).isEqualTo(readSize); - } - - @DisplayName("실시간 주차 대수를 제공하지 않는 API에서 주차장이 0~4까지 저장되어 있는 상태에서 0~9까지 주차장을 읽어와 업데이트한다.") - @Test - void autoUpdateNotOfferCurrentParking() { - //given - NotOfferCurrentParkingApiService notOfferCurrentParkingApiService = new NotOfferCurrentParkingApiService( - 5); - parkingService.saveAll(notOfferCurrentParkingApiService.read()); - int readSize = 10; - notOfferCurrentParkingApiService.setReadSize(readSize); - - ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( - List.of(notOfferCurrentParkingApiService), - coordinateService, - parkingService - ); - - //when - scheduler.autoUpdateNotOfferCurrentParking(); - - //then - Assertions.assertThat(parkingService.count()).isEqualTo(readSize); - } - - @DisplayName("실시간 주차 대수를 제공하는 API와 제공하지 않는 API는 영향을 안준다.") - @Test - void notAffectBetweenOfferAndNotOfferCurrentParking() { - //given - OfferCurrentParkingApiService offerCurrentParkingApiService = new OfferCurrentParkingApiService(5); - NotOfferCurrentParkingApiService notOfferCurrentParkingApiService = new NotOfferCurrentParkingApiService( - 5); - parkingService.saveAll(offerCurrentParkingApiService.read()); - int readSize = 10; - notOfferCurrentParkingApiService.setReadSize(readSize); - - ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( - List.of(offerCurrentParkingApiService, notOfferCurrentParkingApiService), - coordinateService, - parkingService - ); - - //when - scheduler.autoUpdateOfferCurrentParking(); - - //then - Assertions.assertThat(parkingService.count()).isEqualTo(5); - } - - @DisplayName("특정 API에서 예외 발생시, 해당 API는 log를 남기고 무시한다.") - @Test - void autoUpdateWithExceptionApi() { - //given - ParkingUpdateScheduler scheduler = new ParkingUpdateScheduler( - List.of(new OfferCurrentParkingApiService(5), new ExceptionParkingApiService()), - coordinateService, - parkingService - ); - - //when - scheduler.autoUpdateOfferCurrentParking(); - - //then - Assertions.assertThat(parkingService.count()).isEqualTo(5); - } -} diff --git a/src/test/java/com/example/parking/fake/BasicMemberRepository.java b/src/test/java/com/example/parking/fake/BasicMemberRepository.java deleted file mode 100644 index b3e35ca5..00000000 --- a/src/test/java/com/example/parking/fake/BasicMemberRepository.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.member.Member; -import com.example.parking.domain.member.MemberRepository; -import com.example.parking.domain.member.Password; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public class BasicMemberRepository implements MemberRepository, BasicRepository { - - private static Long id = 1L; - private final Map store = new HashMap<>(); - - @Override - public boolean existsByEmail(String email) { - return store.values() - .stream() - .anyMatch(member -> member.getEmail().equals(email)); - } - - @Override - public Optional findById(Long id) { - return Optional.of(store.get(id)); - } - - @Override - public Optional findByEmail(String email) { - return store.values() - .stream() - .filter(member -> member.getEmail().equals(email)) - .findAny(); - } - - @Override - public void save(Member member) { - setId(member, id); - store.put(id++, member); - } - - public List saveAndGet(int size) { - LinkedList result = new LinkedList<>(); - for (int i = 0; i < size; i++) { - Member member = new Member( - "testEmail" + i + "@email.com", - "nickname" + i, - new Password("password1234") - ); - result.add(member); - } - for (Member member : result) { - save(member); - } - return result; - } -} diff --git a/src/test/java/com/example/parking/fake/BasicParkingRepository.java b/src/test/java/com/example/parking/fake/BasicParkingRepository.java deleted file mode 100644 index eb44f02a..00000000 --- a/src/test/java/com/example/parking/fake/BasicParkingRepository.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.parking.BaseInformation; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.FeePolicy; -import com.example.parking.domain.parking.FreeOperatingTime; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.OperatingTime; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayTypes; -import com.example.parking.domain.parking.Space; -import com.example.parking.domain.parking.TimeUnit; -import com.example.parking.domain.parking.repository.ParkingRepository; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import org.locationtech.jts.geom.Point; - -public class BasicParkingRepository implements ParkingRepository, BasicRepository { - - private static Long id = 1L; - private final Map store = new HashMap<>(); - - @Override - public Optional findById(Long id) { - return Optional.of(store.get(id)); - } - - @Override - public List findAroundParkingLots(Point point, int radius) { - return Collections.EMPTY_LIST; - } - - @Override - public List findAroundParkingLotsOrderByDistance(Point point, int radius) { - return Collections.EMPTY_LIST; - } - - @Override - public Set findAllByBaseInformationNameIn(Set names) { - return store.values() - .stream() - .filter(parking -> names.contains(parking.getBaseInformation().getName())) - .collect(Collectors.toSet()); - } - - @Override - public void saveAll(Iterable parkingLots) { - for (Parking parkingLot : parkingLots) { - save(parkingLot); - } - } - - public void save(Parking parkingLot) { - setId(parkingLot, id); - store.put(id++, parkingLot); - } - - public List saveAndGet(int size) { - LinkedList result = new LinkedList<>(); - for (int i = 0; i < size; i++) { - Parking parking = new Parking( - new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, PayTypes.DEFAULT, - ParkingType.NO_INFO, - OperationType.PUBLIC), - Location.of("33.333" + i, "44.444" + i), - Space.of(-1, -1), - FreeOperatingTime.ALWAYS_FREE, - OperatingTime.ALWAYS_OPEN, - new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(0), TimeUnit.from(0), Fee.ZERO) - ); - result.add(parking); - } - saveAll(result); - return result; - } - - public int count() { - return store.size(); - } -} diff --git a/src/test/java/com/example/parking/fake/BasicRepository.java b/src/test/java/com/example/parking/fake/BasicRepository.java deleted file mode 100644 index 60c21899..00000000 --- a/src/test/java/com/example/parking/fake/BasicRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.parking.fake; - -import java.lang.reflect.Field; - -public interface BasicRepository { - - default void setId(T entity, ID id) { - try { - Field field = entity.getClass().getDeclaredField("id"); - field.setAccessible(true); - field.set(entity, id); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/test/java/com/example/parking/fake/BasicReviewRepository.java b/src/test/java/com/example/parking/fake/BasicReviewRepository.java deleted file mode 100644 index 1f499e87..00000000 --- a/src/test/java/com/example/parking/fake/BasicReviewRepository.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.support.Association; -import com.example.parking.domain.review.Review; -import com.example.parking.domain.review.ReviewRepository; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public class BasicReviewRepository implements ReviewRepository, BasicRepository { - - private static Long id = 1L; - private final Map store = new HashMap<>(); - - @Override - public Optional findById(Long id) { - return Optional.of(store.get(id)); - } - - @Override - public List findAllByParkingId(Association parkingId) { - return store.values().stream() - .filter(review -> review.getParkingId().equals(parkingId)) - .toList(); - } - - @Override - public void save(Review review) { - setId(review, id); - store.put(id++, review); - } - - @Override - public boolean existsByParkingIdAndReviewerId(Association parkingId, Association reviewerId) { - return store.values().stream() - .anyMatch( - review -> review.getParkingId().equals(parkingId) && - review.getReviewerId().equals(reviewerId) - ); - } -} diff --git a/src/test/java/com/example/parking/fake/ExceptionParkingApiService.java b/src/test/java/com/example/parking/fake/ExceptionParkingApiService.java deleted file mode 100644 index 65ba6733..00000000 --- a/src/test/java/com/example/parking/fake/ExceptionParkingApiService.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.parking.Parking; -import com.example.parking.external.parkingapi.ParkingApiService; -import com.example.parking.support.exception.ClientException; -import com.example.parking.support.exception.ExceptionInformation; -import java.util.List; - -public class ExceptionParkingApiService implements ParkingApiService { - - @Override - public boolean offerCurrentParking() { - return true; - } - - @Override - public List read() { - throw new ClientException(ExceptionInformation.INVALID_CONNECT); - } -} diff --git a/src/test/java/com/example/parking/fake/FakeCoordinateService.java b/src/test/java/com/example/parking/fake/FakeCoordinateService.java deleted file mode 100644 index 2a455a3c..00000000 --- a/src/test/java/com/example/parking/fake/FakeCoordinateService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.parking.Location; -import com.example.parking.external.coordinate.CoordinateService; - -public class FakeCoordinateService extends CoordinateService { - - public FakeCoordinateService() { - super(null); - } - - @Override - public Location extractLocationByAddress(String address, Location location) { - return Location.of(10.0, 10.0); - } -} diff --git a/src/test/java/com/example/parking/fake/FakeFavoriteRepository.java b/src/test/java/com/example/parking/fake/FakeFavoriteRepository.java deleted file mode 100644 index 263edab0..00000000 --- a/src/test/java/com/example/parking/fake/FakeFavoriteRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.favorite.Favorite; -import com.example.parking.domain.favorite.FavoriteRepository; -import com.example.parking.domain.member.Member; -import com.example.parking.domain.parking.Parking; -import com.example.parking.support.Association; -import java.util.List; - -public class FakeFavoriteRepository implements FavoriteRepository { - - @Override - public Favorite save(Favorite favorite) { - return null; - } - - @Override - public void deleteByMemberIdAndParkingId(Association memberId, Association parkingId) { - - } - - @Override - public List findByMemberId(Association memberId) { - return null; - } -} diff --git a/src/test/java/com/example/parking/fake/FakeParkingService.java b/src/test/java/com/example/parking/fake/FakeParkingService.java deleted file mode 100644 index 10eea1fe..00000000 --- a/src/test/java/com/example/parking/fake/FakeParkingService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.application.SearchConditionMapper; -import com.example.parking.application.parking.ParkingFilteringService; -import com.example.parking.application.parking.ParkingService; -import com.example.parking.application.review.ReviewService; -import com.example.parking.domain.parking.ParkingFeeCalculator; -import com.example.parking.domain.review.service.ReviewDomainService; - -public class FakeParkingService extends ParkingService { - - private final BasicParkingRepository repository; - - public FakeParkingService(BasicParkingRepository repository) { - super( - repository, - new ParkingFilteringService(new ParkingFeeCalculator()), - new FakeFavoriteRepository(), - new SearchConditionMapper(), - new ParkingFeeCalculator(), - new ReviewService( - new BasicReviewRepository(), - new ReviewDomainService(new BasicReviewRepository()) - )); - this.repository = repository; - } - - public int count() { - return repository.count(); - } -} diff --git a/src/test/java/com/example/parking/fake/FakeReviewService.java b/src/test/java/com/example/parking/fake/FakeReviewService.java deleted file mode 100644 index e7c5923c..00000000 --- a/src/test/java/com/example/parking/fake/FakeReviewService.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.application.review.ReviewService; -import com.example.parking.domain.review.ReviewRepository; -import com.example.parking.domain.review.service.ReviewDomainService; - -public class FakeReviewService extends ReviewService { - public FakeReviewService(ReviewRepository reviewRepository, - ReviewDomainService reviewDomainService) { - super(reviewRepository, reviewDomainService); - } -} diff --git a/src/test/java/com/example/parking/fake/FakeSearchConditionRepository.java b/src/test/java/com/example/parking/fake/FakeSearchConditionRepository.java deleted file mode 100644 index df13129e..00000000 --- a/src/test/java/com/example/parking/fake/FakeSearchConditionRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.searchcondition.SearchCondition; -import com.example.parking.domain.searchcondition.SearchConditionRepository; -import java.util.Optional; - -public class FakeSearchConditionRepository implements SearchConditionRepository { - @Override - public Optional findByMemberId(Long memberId) { - return Optional.empty(); - } - - @Override - public void save(SearchCondition searchCondition) { - - } -} diff --git a/src/test/java/com/example/parking/fake/NotOfferCurrentParkingApiService.java b/src/test/java/com/example/parking/fake/NotOfferCurrentParkingApiService.java deleted file mode 100644 index 491ec2b8..00000000 --- a/src/test/java/com/example/parking/fake/NotOfferCurrentParkingApiService.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.parking.BaseInformation; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.FeePolicy; -import com.example.parking.domain.parking.FreeOperatingTime; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.OperatingTime; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayTypes; -import com.example.parking.domain.parking.Space; -import com.example.parking.domain.parking.TimeUnit; -import com.example.parking.external.parkingapi.ParkingApiService; -import java.util.LinkedList; -import java.util.List; - -public class NotOfferCurrentParkingApiService implements ParkingApiService { - - private int readSize; - - public NotOfferCurrentParkingApiService(int readSize) { - this.readSize = readSize; - } - - @Override - public boolean offerCurrentParking() { - return false; - } - - @Override - public List read() { - LinkedList result = new LinkedList<>(); - for (int i = 0; i < readSize; i++) { - Parking parking = new Parking( - new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, PayTypes.DEFAULT, - ParkingType.NO_INFO, - OperationType.PUBLIC), - Location.of("33.333" + i, "44.444" + i), - Space.of(-1, -1), - FreeOperatingTime.ALWAYS_FREE, - OperatingTime.ALWAYS_OPEN, - new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(0), TimeUnit.from(0), Fee.ZERO) - ); - result.add(parking); - } - - return result; - } - - public void setReadSize(int readSize) { - this.readSize = readSize; - } -} diff --git a/src/test/java/com/example/parking/fake/OfferCurrentParkingApiService.java b/src/test/java/com/example/parking/fake/OfferCurrentParkingApiService.java deleted file mode 100644 index 44d0c895..00000000 --- a/src/test/java/com/example/parking/fake/OfferCurrentParkingApiService.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.example.parking.fake; - -import com.example.parking.domain.parking.BaseInformation; -import com.example.parking.domain.parking.Fee; -import com.example.parking.domain.parking.FeePolicy; -import com.example.parking.domain.parking.FreeOperatingTime; -import com.example.parking.domain.parking.Location; -import com.example.parking.domain.parking.OperatingTime; -import com.example.parking.domain.parking.OperationType; -import com.example.parking.domain.parking.Parking; -import com.example.parking.domain.parking.ParkingType; -import com.example.parking.domain.parking.PayTypes; -import com.example.parking.domain.parking.Space; -import com.example.parking.domain.parking.TimeUnit; -import com.example.parking.external.parkingapi.ParkingApiService; -import java.util.LinkedList; -import java.util.List; - -public class OfferCurrentParkingApiService implements ParkingApiService { - - private int readSize; - - public OfferCurrentParkingApiService(int readSize) { - this.readSize = readSize; - } - - @Override - public boolean offerCurrentParking() { - return true; - } - - @Override - public List read() { - LinkedList result = new LinkedList<>(); - for (int i = 0; i < readSize; i++) { - Parking parking = new Parking( - new BaseInformation("offer parking" + i, "02-000" + i, "서울시 어딘가 " + i, PayTypes.DEFAULT, - ParkingType.NO_INFO, - OperationType.PUBLIC), - Location.of("11.111" + i, "22.222" + i), - Space.of(100, 10), - FreeOperatingTime.ALWAYS_FREE, - OperatingTime.ALWAYS_OPEN, - new FeePolicy(Fee.ZERO, Fee.ZERO, TimeUnit.from(0), TimeUnit.from(0), Fee.ZERO) - ); - result.add(parking); - } - - return result; - } - - public void setReadSize(int readSize) { - this.readSize = readSize; - } -} diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml deleted file mode 100644 index dfcd4b4d..00000000 --- a/src/test/resources/application.yml +++ /dev/null @@ -1,43 +0,0 @@ -spring: - flyway: - enabled: false - jpa: - hibernate: - ddl-auto: create - show-sql: true - properties: - hibernate: - format_sql: true - mail: - host: smtp.gmail.com - port: 587 - username: test@gmail.com - password: test - properties: - mail: - smtp: - auth: true - timeout: 5000 - starttls: - enable: true - data: - redis: - host: localhost - port: 6379 - datasource: - driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver - url: jdbc:tc:mysql:8://test - username: root - password: test - -kakao: - key: test - -seoul-public-parking-key: test -pusan-public-parking-key: test - -authcode: - expired-time: 60 - -cors: - allowedOrigins: http://localhost:3000 From a4700d00484972ab8001699f993fc9d14cd30ca3 Mon Sep 17 00:00:00 2001 From: This2sho Date: Wed, 10 Apr 2024 23:58:15 +0900 Subject: [PATCH 06/19] =?UTF-8?q?refactor:=20=EB=A3=A8=ED=8A=B8=20gradle?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 87 +++++++++++++++++-------------------------------- settings.gradle | 3 +- 2 files changed, 31 insertions(+), 59 deletions(-) diff --git a/build.gradle b/build.gradle index c8e99b20..8fe34251 100644 --- a/build.gradle +++ b/build.gradle @@ -4,83 +4,54 @@ plugins { id 'io.spring.dependency-management' version '1.1.4' } -group = 'com.example' -version = '0.0.1-SNAPSHOT' - -java { - sourceCompatibility = '17' -} - -configurations { - compileOnly { - extendsFrom annotationProcessor - } -} - repositories { mavenCentral() } -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation group: 'org.hibernate.orm', name: 'hibernate-spatial', version: '6.3.1.Final' - - - runtimeOnly 'com.h2database:h2' - runtimeOnly 'com.mysql:mysql-connector-j' - - testImplementation 'org.springframework.boot:spring-boot-starter-test' - - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' - - // 메일 - implementation 'org.springframework.boot:spring-boot-starter-mail' - - // redis - implementation("org.springframework.boot:spring-boot-starter-data-redis") - - // testcontainer - testImplementation "org.testcontainers:testcontainers:1.19.6" - testImplementation "org.testcontainers:junit-jupiter:1.19.6" - testImplementation "com.redis:testcontainers-redis:2.2.0" - testImplementation "org.testcontainers:mysql:1.19.6" - - // flyway 추가 - implementation 'org.flywaydb:flyway-mysql' - implementation 'org.flywaydb:flyway-core' - - // lombok - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' -} +bootJar.enabled = false subprojects { + repositories { + mavenCentral() + } + group = 'com.parkingcomestrue' version = '0.0.1-SNAPSHOT' - sourceCompatibility = '17' apply plugin: 'java' - apply plugin: 'java-library' apply plugin: 'org.springframework.boot' - apply plugin: 'io.spring.dependency-management' - configurations { - compileOnly { - extendsFrom annotationProcessor - } - } - - dependencies { compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' + + runtimeOnly 'com.h2database:h2' + runtimeOnly 'com.mysql:mysql-connector-j' + + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' } + + test { + useJUnitPlatform() + } +} + +project(':domain') { + bootJar { enabled = false } + jar { enabled = true } } -tasks.named('test') { - useJUnitPlatform() +project(':app-api') { + bootJar { enabled = true } } + +project(':app-scheduler') { + bootJar { enabled = true } +} + + diff --git a/settings.gradle b/settings.gradle index 1cfafbbc..28f6a7d6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,4 @@ rootProject.name = 'parking' include 'domain' - +include 'app-api' +include 'app-scheduler' From 281f2076254bf56629bebc142e8c647d5c2a8d29 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 11 Apr 2024 01:04:04 +0900 Subject: [PATCH 07/19] =?UTF-8?q?refactor:=20CI=20=EB=A9=80=ED=8B=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=82=AC=ED=95=AD=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 52 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a0656ea..37f6288a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,19 +33,63 @@ jobs: - name: Gradle 명령 실행을 위한 권한을 부여합니다 run: chmod +x gradlew - - name: 테스트 수행 - run: ./gradlew test -i + - name: 변경된 모듈을 체크한다. + id: check_changes + run: | + if git diff --name-only origin/main...HEAD | grep -q "^domain/"; then + echo "domain 모듈이 변경되었습니다." + echo "::set-output name=changes::domain_changed" + elif git diff --name-only origin/main...HEAD | grep -q "^app-api/"; then + echo "api 모듈이 변경되었습니다." + echo "::set-output name=changes::api_changed" + elif git diff --name-only origin/main...HEAD | grep -q "^app-scheduler/"; then + echo "scheduler 모듈이 변경되었습니다." + echo "::set-output name=changes::scheduler_changed" + else + echo "모듈에 변경사항이 없습니다." + fi + + - name: 변경된 모듈을 테스트한다. + run: | + case "${{ steps.check_changes.outputs.changes }}" in + domain_changed) + echo "도메인 모듈 및 하위 모듈을 테스트합니다." + ./gradlew :domain:test -i + ./gradlew :app-api:test -i + ./gradlew :app-scheduler:test -i + ;; + api_changed) + echo "api 모듈을 테스트합니다." + ./gradlew :app-api:test -i + ;; + scheduler_changed) + echo "scheduler 모듈을 테스트합니다." + ./gradlew :app-scheduler:test -i + ;; + *) + echo "모듈에 변경 사항이 없습니다." + ;; + esac - name: 테스트 결과를 PR에 코멘트로 등록합니다 uses: EnricoMi/publish-unit-test-result-action@v2 if: github.event_name == 'pull_request' with: - files: '**/build/test-results/test/TEST-*.xml' + files: | + **/domain/build/test-results/test/TEST-*.xml, + **/app-api/build/test-results/test/TEST-*.xml, + **/app-scheduler/build/test-results/test/TEST-*.xml + + + - name: 테스트 실패 시, 실패한 코드 라인에 Check 코멘트를 등록합니다 uses: mikepenz/action-junit-report@v3 with: - report_paths: '**/build/test-results/test/TEST-*.xml' + report_paths: | + **/domain/build/test-results/test/TEST-*.xml, + **/app-api/build/test-results/test/TEST-*.xml, + **/app-scheduler/build/test-results/test/TEST-*.xml token: ${{ github.token }} - name: build 실패 시 Slack으로 알립니다 From 11dee5752fdfd593d613e7c84100130c0e439619 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 11 Apr 2024 02:02:39 +0900 Subject: [PATCH 08/19] =?UTF-8?q?refactor:=20CD=20=EB=A9=80=ED=8B=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=82=AC=ED=95=AD=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ".github/workflows/\bdeploy.yml" | 57 +++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git "a/.github/workflows/\bdeploy.yml" "b/.github/workflows/\bdeploy.yml" index 55f2b99a..36f2d30a 100644 --- "a/.github/workflows/\bdeploy.yml" +++ "b/.github/workflows/\bdeploy.yml" @@ -32,8 +32,42 @@ jobs: - name: Gradle 명령 실행을 위한 권한을 부여합니다 run: chmod +x gradlew - - name: Gradle build를 수행합니다 - run: ./gradlew build + - name: 변경된 모듈을 체크한다. + id: check_changes + run: | + if git diff --name-only origin/main...HEAD | grep -q "^domain/"; then + echo "domain 모듈이 변경되었습니다." + echo "::set-output name=changes::domain_changed" + elif git diff --name-only origin/main...HEAD | grep -q "^app-api/"; then + echo "api 모듈이 변경되었습니다." + echo "::set-output name=changes::api_changed" + elif git diff --name-only origin/main...HEAD | grep -q "^app-scheduler/"; then + echo "scheduler 모듈이 변경되었습니다." + echo "::set-output name=changes::scheduler_changed" + else + echo "모듈에 변경사항이 없습니다." + fi + + - name: 변경된 모듈을 build한다. + run: | + case "${{ steps.check_changes.outputs.changes }}" in + domain_changed) + echo "도메인을 의존하는 모듈을 빌드합니다." + ./gradlew :app-api:build + ./gradlew :app-scheduler:build + ;; + api_changed) + echo "api 모듈을 빌드합니다." + ./gradlew :app-api:build + ;; + scheduler_changed) + echo "scheduler 모듈을 빌드합니다." + ./gradlew :app-scheduler:build + ;; + *) + echo "모듈에 변경 사항이 없습니다." + ;; + esac - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 @@ -46,11 +80,26 @@ jobs: - name: 도커 이미지 build 후 push uses: docker/build-push-action@v2 + if: | + steps.check_changes.outputs.changes == 'domain_changed' || + steps.check_changes.outputs.changes == 'api_changed' with: context: . - file: Dockerfile + file: app-api/Dockerfile push: true - tags: ${{ secrets.DOCKERHUB_USERNAME }}/pct-backend:${{ github.sha }} + tags: ${{ secrets.DOCKERHUB_USERNAME }}/pct-api:${{ github.sha }} + platforms: linux/amd64 + + - name: 도커 이미지 build 후 push + uses: docker/build-push-action@v2 + if: | + steps.check_changes.outputs.changes == 'domain_changed' || + steps.check_changes.outputs.changes == 'scheduler_changed' + with: + context: . + file: app-scheduler/Dockerfile + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/pct-scheduler:${{ github.sha }} platforms: linux/amd64 deploy-to-ec2: From b9929d27c5e0197f1b7aa5aa27603463422981fe Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 11 Apr 2024 02:23:24 +0900 Subject: [PATCH 09/19] =?UTF-8?q?fix:=20=EA=B9=83=ED=97=99=20=EC=95=A1?= =?UTF-8?q?=EC=85=98=EC=97=90=EC=84=9C=20=EC=9D=B4=EC=A0=84=20=EC=BB=A4?= =?UTF-8?q?=EB=B0=8B=EB=8F=84=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ".github/workflows/\bdeploy.yml" | 7 +++++-- .github/workflows/ci.yml | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git "a/.github/workflows/\bdeploy.yml" "b/.github/workflows/\bdeploy.yml" index 36f2d30a..c7503e88 100644 --- "a/.github/workflows/\bdeploy.yml" +++ "b/.github/workflows/\bdeploy.yml" @@ -14,8 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - name: 리포지토리를 가져옵니다 + uses: actions/checkout@v2 + with: + fetch-depth: 2 - name: JDK 17을 설치합니다 uses: actions/setup-java@v4 @@ -35,6 +37,7 @@ jobs: - name: 변경된 모듈을 체크한다. id: check_changes run: | + git fetch origin main if git diff --name-only origin/main...HEAD | grep -q "^domain/"; then echo "domain 모듈이 변경되었습니다." echo "::set-output name=changes::domain_changed" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37f6288a..b7e35cee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,9 @@ jobs: steps: - name: 리포지토리를 가져옵니다 - uses: actions/checkout@v4 + uses: actions/checkout@v2 + with: + fetch-depth: 2 - name: JDK 17을 설치합니다 uses: actions/setup-java@v4 @@ -36,6 +38,7 @@ jobs: - name: 변경된 모듈을 체크한다. id: check_changes run: | + git fetch origin main if git diff --name-only origin/main...HEAD | grep -q "^domain/"; then echo "domain 모듈이 변경되었습니다." echo "::set-output name=changes::domain_changed" From 086b975d5f9100dbef4c105376a8bc448eb8dd3f Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 11 Apr 2024 03:23:32 +0900 Subject: [PATCH 10/19] =?UTF-8?q?feat:=20gradle=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B2=B0=EA=B3=BC=20=EB=AA=A8=EC=95=84=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20task=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/build.gradle b/build.gradle index 8fe34251..6941796b 100644 --- a/build.gradle +++ b/build.gradle @@ -54,4 +54,20 @@ project(':app-scheduler') { bootJar { enabled = true } } +task collectTestResults(type: Copy) { + description = 'Collects test results from all subprojects' + + def resultDirs = [ + 'domain': "$projectDir/domain/build/test-results/test", + 'app-api': "$projectDir/app-api/build/test-results/test", + 'app-scheduler': "$projectDir/app-scheduler/build/test-results/test" + ] + + from resultDirs.collect { _, dir -> + fileTree(dir) { + include '**/TEST-*.xml' + } + } + into "build/allTestResults" +} From 336a4b2553ab2239089f3b3c6ea465018236fcde Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 11 Apr 2024 03:24:03 +0900 Subject: [PATCH 11/19] =?UTF-8?q?refactor:=20domain=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EC=8B=9C=20gradle=20=EB=B3=91=EB=A0=AC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=ED=96=89=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ".github/workflows/\bdeploy.yml" | 5 ++--- .github/workflows/ci.yml | 19 +++++-------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git "a/.github/workflows/\bdeploy.yml" "b/.github/workflows/\bdeploy.yml" index c7503e88..dba1fd28 100644 --- "a/.github/workflows/\bdeploy.yml" +++ "b/.github/workflows/\bdeploy.yml" @@ -55,9 +55,8 @@ jobs: run: | case "${{ steps.check_changes.outputs.changes }}" in domain_changed) - echo "도메인을 의존하는 모듈을 빌드합니다." - ./gradlew :app-api:build - ./gradlew :app-scheduler:build + echo "전체 모듈을 빌드합니다." + ./gradlew build --parallel ;; api_changed) echo "api 모듈을 빌드합니다." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7e35cee..d1ebc7ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,9 +57,7 @@ jobs: case "${{ steps.check_changes.outputs.changes }}" in domain_changed) echo "도메인 모듈 및 하위 모듈을 테스트합니다." - ./gradlew :domain:test -i - ./gradlew :app-api:test -i - ./gradlew :app-scheduler:test -i + ./gradlew test --parallel ;; api_changed) echo "api 모듈을 테스트합니다." @@ -73,26 +71,19 @@ jobs: echo "모듈에 변경 사항이 없습니다." ;; esac + echo "테스트 결과를 하나의 디렉토리에 복사합니다." + ./gradlew collectTestResults - name: 테스트 결과를 PR에 코멘트로 등록합니다 uses: EnricoMi/publish-unit-test-result-action@v2 if: github.event_name == 'pull_request' with: - files: | - **/domain/build/test-results/test/TEST-*.xml, - **/app-api/build/test-results/test/TEST-*.xml, - **/app-scheduler/build/test-results/test/TEST-*.xml - - - + files: '**/build/allTestResults/TEST-*.xml' - name: 테스트 실패 시, 실패한 코드 라인에 Check 코멘트를 등록합니다 uses: mikepenz/action-junit-report@v3 with: - report_paths: | - **/domain/build/test-results/test/TEST-*.xml, - **/app-api/build/test-results/test/TEST-*.xml, - **/app-scheduler/build/test-results/test/TEST-*.xml + report_paths: '**/build/allTestResults/TEST-*.xml' token: ${{ github.token }} - name: build 실패 시 Slack으로 알립니다 From b98101c0f3decb589bf59647da763f48202b4a93 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 11 Apr 2024 03:37:39 +0900 Subject: [PATCH 12/19] =?UTF-8?q?fix:=20=EA=B9=83=ED=97=99=20=EC=95=A1?= =?UTF-8?q?=EC=85=98=20=EA=B3=84=EC=86=8D=20=EB=8F=84=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1ebc7ad..2ad6db97 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: Backend CI on: push: branches: [ main ] - pull_request: + pull_request_target: branches: [ main ] permissions: From 1501092d3fee1081610b5ef33c922ccaa7f8eee5 Mon Sep 17 00:00:00 2001 From: This2sho Date: Fri, 12 Apr 2024 02:30:35 +0900 Subject: [PATCH 13/19] =?UTF-8?q?fix:=20=EA=B0=92=20=EB=B0=94=EA=BB=B4?= =?UTF-8?q?=EC=9E=88=EB=8A=94=EA=B1=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../parkingapi/pusan/PusanPublicParkingResponse.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java index f6294d3f..c79d2130 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingResponse.java @@ -43,13 +43,12 @@ public static class Item { @JsonProperty("jibunAddr") private String oldAddress; - @JsonProperty("xCdnt") + @JsonProperty("yCdnt") private String latitude; - @JsonProperty("yCdnt") + @JsonProperty("xCdnt") private String longitude; - @JsonProperty("pkCnt") private String capacity; From 4bbad4d6e703cec72e5368d9806e7b4d95735f3f Mon Sep 17 00:00:00 2001 From: This2sho Date: Fri, 12 Apr 2024 02:35:00 +0900 Subject: [PATCH 14/19] =?UTF-8?q?refactor:=20Exception=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/SearchConditionMapper.java | 6 ++--- .../parking/application/auth/AuthService.java | 8 +++---- .../exception/ClientException.java | 6 ++--- .../exception/ClientExceptionInformation.java | 22 +++++++++++++++++++ .../application/member/MemberService.java | 16 +++++--------- .../GlobalExceptionHandler.java | 10 ++++----- .../SearchConditionMapperTest.java | 7 +++--- .../application/auth/AuthServiceTest.java | 6 ++--- .../application/member/MemberServiceTest.java | 7 +++--- .../parking/ParkingServiceTest.java | 5 +++-- .../application/review/ReviewServiceTest.java | 2 +- .../coordinate/CoordinateErrorHandler.java | 6 ++--- .../exception/SchedulerException.java | 16 ++++++++++++++ .../SchedulerExceptionInformation.java | 16 ++++++++++++++ .../fake/ExceptionParkingApiService.java | 6 ++--- .../parking/domain/member/Member.java | 16 +++++++++----- .../member/repository/MemberRepository.java | 4 ++-- .../parking/domain/parking/Location.java | 4 ++-- .../parking/repository/ParkingRepository.java | 4 ++-- .../parking/domain/review/Content.java | 4 ++-- .../parking/domain/review/Review.java | 4 ++-- .../review/repository/ReviewRepository.java | 4 ++-- .../review/service/ReviewDomainService.java | 4 ++-- .../parking/domain/searchcondition/Hours.java | 4 ++-- .../repository/SearchConditionRepository.java | 4 ++-- .../support/exception/DomainException.java | 4 ++-- ...n.java => DomainExceptionInformation.java} | 12 +++------- .../parking/util/cipher/SHA256.java | 4 ++-- .../parking/domain/member/MemberTest.java | 2 +- .../parking/domain/review/ContentTest.java | 2 +- .../service/ReviewDomainServiceTest.java | 2 +- .../domain/searchcondition/HoursTest.java | 2 +- 32 files changed, 133 insertions(+), 86 deletions(-) rename {domain/src/main/java/com/parkingcomestrue/parking/support => app-api/src/main/java/com/parkingcomestrue/parking/application}/exception/ClientException.java (57%) create mode 100644 app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientExceptionInformation.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerException.java create mode 100644 app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerExceptionInformation.java rename domain/src/main/java/com/parkingcomestrue/parking/support/exception/{ExceptionInformation.java => DomainExceptionInformation.java} (62%) diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java index 4f623964..b26dba64 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java @@ -1,8 +1,8 @@ package com.parkingcomestrue.parking.application; import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; -import com.parkingcomestrue.parking.support.exception.ClientException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.application.exception.ClientException; +import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; import java.util.Arrays; import java.util.List; import org.springframework.stereotype.Component; @@ -24,7 +24,7 @@ public & SearchConditionAvailable> E toEnum(Class searchCo return Arrays.stream(conditions) .filter(condition -> description.startsWith(condition.getDescription())) .findAny() - .orElseThrow(() -> new ClientException(ExceptionInformation.INVALID_DESCRIPTION)); + .orElseThrow(() -> new ClientException(ClientExceptionInformation.INVALID_DESCRIPTION)); } public & SearchConditionAvailable> List getValues( diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java index 72112817..c2f097e2 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java @@ -10,8 +10,8 @@ import com.parkingcomestrue.parking.application.auth.authcode.util.AuthCodeKeyConverter; import com.parkingcomestrue.parking.domain.session.MemberSession; import com.parkingcomestrue.parking.domain.session.repository.MemberSessionRepository; -import com.parkingcomestrue.parking.support.exception.ClientException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.application.exception.ClientException; +import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; import java.time.LocalDateTime; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -47,7 +47,7 @@ public String createSession(Long memberId) { public MemberSession findSession(String sessionId) { return memberSessionRepository.findBySessionIdAndExpiredAtIsGreaterThanEqual(sessionId, LocalDateTime.now()) - .orElseThrow(() -> new ClientException(ExceptionInformation.UNAUTHORIZED)); + .orElseThrow(() -> new ClientException(ClientExceptionInformation.UNAUTHORIZED)); } @Transactional @@ -95,7 +95,7 @@ public void certificateAuthCode(AuthCodeCertificateRequest authCodeCertificateRe authCodeCategory.getCategoryName()); String findResult = redisTemplate.opsForValue().getAndDelete(authCodeKey); if (findResult == null) { - throw new ClientException(ExceptionInformation.INVALID_AUTH_CODE); + throw new ClientException(ClientExceptionInformation.INVALID_AUTH_CODE); } } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientException.java similarity index 57% rename from domain/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java rename to app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientException.java index e07d1fdb..1b2589ec 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientException.java @@ -1,13 +1,13 @@ -package com.parkingcomestrue.parking.support.exception; +package com.parkingcomestrue.parking.application.exception; import lombok.Getter; @Getter public class ClientException extends RuntimeException { - private final ExceptionInformation exceptionInformation; + private final ClientExceptionInformation exceptionInformation; - public ClientException(ExceptionInformation exceptionInformation) { + public ClientException(ClientExceptionInformation exceptionInformation) { super(); this.exceptionInformation = exceptionInformation; } diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientExceptionInformation.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientExceptionInformation.java new file mode 100644 index 00000000..3baa1737 --- /dev/null +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientExceptionInformation.java @@ -0,0 +1,22 @@ +package com.parkingcomestrue.parking.application.exception; + +import lombok.Getter; + +@Getter +public enum ClientExceptionInformation { + + DUPLICATE_MAIL("중복된 이메일이라 회원가입이 불가능합니다."), + INVALID_EMAIL("회원가입되지 않은 이메일입니다."), + UNAUTHORIZED("존재하지 않는 sessionId 입니다."), + + INVALID_AUTH_CODE("존재하지 않는 인증코드 입니다."), + + INVALID_DESCRIPTION("해당하는 내용의 검색 조건이 존재하지 않습니다."); + + + private final String message; + + ClientExceptionInformation(String message) { + this.message = message; + } +} diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java index 6a674655..fca9f8ee 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java @@ -7,8 +7,8 @@ import com.parkingcomestrue.parking.domain.member.Member; import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; import com.parkingcomestrue.parking.domain.member.Password; -import com.parkingcomestrue.parking.support.exception.ClientException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.application.exception.ClientException; +import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,26 +35,20 @@ public Long signup(MemberSignupRequest dto) { private void validateDuplicatedEmail(Member member) { if (memberRepository.existsByEmail(member.getEmail())) { - throw new ClientException(ExceptionInformation.DUPLICATE_MAIL); + throw new ClientException(ClientExceptionInformation.DUPLICATE_MAIL); } } @Transactional(readOnly = true) public Long login(MemberLoginRequest dto) { Member member = findMemberByEmail(dto.getEmail()); - validatePassword(member, dto.getPassword()); + member.validatePassword(dto.getPassword()); return member.getId(); } private Member findMemberByEmail(String email) { return memberRepository.findByEmail(email) - .orElseThrow(() -> new ClientException(ExceptionInformation.INVALID_EMAIL)); - } - - private void validatePassword(Member member, String password) { - if (!member.checkPassword(password)) { - throw new ClientException(ExceptionInformation.INVALID_PASSWORD); - } + .orElseThrow(() -> new ClientException(ClientExceptionInformation.INVALID_EMAIL)); } @Transactional diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java index c33b83d4..4b7d31e9 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java @@ -4,9 +4,9 @@ import static org.springframework.http.HttpStatus.UNAUTHORIZED; import com.parkingcomestrue.parking.controlleradvice.dto.ExceptionResponse; -import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.application.exception.ClientException; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; import java.util.EnumMap; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -18,11 +18,11 @@ @RestControllerAdvice public class GlobalExceptionHandler { - private final EnumMap exceptionInfoToHttpStatus = new EnumMap<>( - ExceptionInformation.class); + private final EnumMap exceptionInfoToHttpStatus = new EnumMap<>( + ClientExceptionInformation.class); public GlobalExceptionHandler() { - exceptionInfoToHttpStatus.put(ExceptionInformation.UNAUTHORIZED, UNAUTHORIZED); + exceptionInfoToHttpStatus.put(ClientExceptionInformation.UNAUTHORIZED, UNAUTHORIZED); } @ExceptionHandler(Exception.class) diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java index 61f1dd54..72fa20b4 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java @@ -4,14 +4,15 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.params.provider.Arguments.arguments; +import com.parkingcomestrue.parking.application.exception.ClientException; +import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; import com.parkingcomestrue.parking.domain.parking.OperationType; import com.parkingcomestrue.parking.domain.parking.ParkingType; import com.parkingcomestrue.parking.domain.parking.PayType; import com.parkingcomestrue.parking.domain.searchcondition.FeeType; import com.parkingcomestrue.parking.domain.searchcondition.Priority; import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; -import com.parkingcomestrue.parking.support.exception.ClientException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; + import java.util.List; import java.util.stream.Stream; import org.junit.Test; @@ -53,7 +54,7 @@ static Stream parametersProvider1() { //given, when, then assertThatThrownBy(() -> searchConditionMapper.toEnum(PayType.class, "아무거나 입력")) .isInstanceOf(ClientException.class) - .hasMessage(ExceptionInformation.INVALID_DESCRIPTION.getMessage()); + .hasMessage(ClientExceptionInformation.INVALID_DESCRIPTION.getMessage()); } @ParameterizedTest diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java index a6d3d11c..8b3c086b 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.application.auth; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_AUTH_CODE; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.UNAUTHORIZED; +import static com.parkingcomestrue.parking.application.exception.ClientExceptionInformation.INVALID_AUTH_CODE; +import static com.parkingcomestrue.parking.application.exception.ClientExceptionInformation.UNAUTHORIZED; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -13,7 +13,7 @@ import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest; import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeRequest; import com.parkingcomestrue.parking.domain.session.MemberSession; -import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.application.exception.ClientException; import java.time.LocalDateTime; import org.junit.jupiter.api.Test; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java index ebdbca4f..13f844e1 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.application.member; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_MEMBER; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_PASSWORD; +import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_MEMBER; +import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_PASSWORD; import static org.assertj.core.api.Assertions.assertThat; import com.parkingcomestrue.parking.application.member.dto.MemberLoginRequest; @@ -9,7 +9,6 @@ import com.parkingcomestrue.parking.application.member.dto.PasswordChangeRequest; import com.parkingcomestrue.parking.domain.member.Member; import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; -import com.parkingcomestrue.parking.support.exception.ClientException; import com.parkingcomestrue.parking.support.exception.DomainException; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -69,7 +68,7 @@ class MemberServiceTest { // then Assertions.assertThatThrownBy(() -> memberService.login(new MemberLoginRequest(email, previousPassword))) - .isInstanceOf(ClientException.class) + .isInstanceOf(DomainException.class) .hasMessage(INVALID_PASSWORD.getMessage()); } diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java index 93841ee1..d97748ac 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java @@ -22,7 +22,8 @@ import com.parkingcomestrue.parking.domain.parking.TimeUnit; import com.parkingcomestrue.parking.domain.review.Content; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.time.LocalTime; import java.util.List; import org.assertj.core.api.Assertions; @@ -35,7 +36,7 @@ class ParkingServiceTest extends ContainerTest { //given Assertions.assertThatThrownBy(() -> parkingService.findParking(1L)) .isInstanceOf(DomainException.class) - .hasMessage(ExceptionInformation.INVALID_PARKING.getMessage()); + .hasMessage(DomainExceptionInformation.INVALID_PARKING.getMessage()); } @Test diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java index 5fc14888..4fecb50b 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.parking.application.review; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.DUPLICATE_REVIEW; +import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.DUPLICATE_REVIEW; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java index 68f75477..ac082502 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.external.coordinate; -import com.parkingcomestrue.parking.support.exception.ClientException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.external.exception.SchedulerException; +import com.parkingcomestrue.external.exception.SchedulerExceptionInformation; import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.client.ClientHttpResponse; @@ -18,6 +18,6 @@ public boolean hasError(ClientHttpResponse response) throws IOException { @Override public void handleError(ClientHttpResponse response) throws IOException { log.warn("fail while extracting coordinate by address code: {}", response.getStatusCode()); - throw new ClientException(ExceptionInformation.COORDINATE_EXCEPTION); + throw new SchedulerException(SchedulerExceptionInformation.COORDINATE_EXCEPTION); } } diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerException.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerException.java new file mode 100644 index 00000000..bb56aeb9 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerException.java @@ -0,0 +1,16 @@ +package com.parkingcomestrue.external.exception; + +public class SchedulerException extends RuntimeException { + + private final SchedulerExceptionInformation exceptionInformation; + + public SchedulerException(SchedulerExceptionInformation exceptionInformation) { + super(); + this.exceptionInformation = exceptionInformation; + } + + @Override + public String getMessage() { + return exceptionInformation.getMessage(); + } +} diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerExceptionInformation.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerExceptionInformation.java new file mode 100644 index 00000000..934f76c5 --- /dev/null +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerExceptionInformation.java @@ -0,0 +1,16 @@ +package com.parkingcomestrue.external.exception; + +import lombok.Getter; + +@Getter +public enum SchedulerExceptionInformation { + + INVALID_CONNECT("주차장 API 연결 중 예외 발생"), + COORDINATE_EXCEPTION("좌표 변환 중 예외 발생"); + + private final String message; + + SchedulerExceptionInformation(String message) { + this.message = message; + } +} diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java index f1fdf51f..9940c888 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java @@ -1,9 +1,9 @@ package com.parkingcomestrue.fake; +import com.parkingcomestrue.external.exception.SchedulerException; +import com.parkingcomestrue.external.exception.SchedulerExceptionInformation; import com.parkingcomestrue.external.parkingapi.ParkingApiService; import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.support.exception.ClientException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; import java.util.List; public class ExceptionParkingApiService implements ParkingApiService { @@ -15,6 +15,6 @@ public boolean offerCurrentParking() { @Override public List read() { - throw new ClientException(ExceptionInformation.INVALID_CONNECT); + throw new SchedulerException(SchedulerExceptionInformation.INVALID_CONNECT); } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java index c968800c..2956084a 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.domain.member; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; @@ -39,6 +39,13 @@ public Member(String email, String nickname, Password password) { this.password = password; } + public void validatePassword(String password) { + if (checkPassword(password)) { + return; + } + throw new DomainException(DomainExceptionInformation.INVALID_PASSWORD); + } + public boolean checkPassword(String password) { return this.password.isMatch(password); } @@ -48,11 +55,8 @@ public void delete() { } public void changePassword(String previousPassword, String newPassword) { - if (checkPassword(previousPassword)) { - this.password = new Password(newPassword); - return; - } - throw new DomainException(ExceptionInformation.INVALID_PASSWORD); + validatePassword(previousPassword); + this.password = new Password(newPassword); } @Override diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java index d9b14eb5..02b808f0 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java @@ -2,7 +2,7 @@ import com.parkingcomestrue.parking.domain.member.Member; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.util.Optional; import org.springframework.data.repository.Repository; @@ -17,6 +17,6 @@ public interface MemberRepository extends Repository { void save(Member member); default Member getById(Long id) { - return findById(id).orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_MEMBER)); + return findById(id).orElseThrow(() -> new DomainException(DomainExceptionInformation.INVALID_MEMBER)); } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java index 02d0ae60..5b01f945 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.domain.parking; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import jakarta.persistence.Embeddable; import lombok.AccessLevel; import lombok.EqualsAndHashCode; @@ -46,7 +46,7 @@ public static Location of(Double longitude, Double latitude) { private static void verifyLocation(Double longitude, Double latitude) { if (longitude > MAX_LONGITUDE || longitude < MIN_LONGITUDE || latitude > MAX_LATITUDE || latitude < MIN_LATITUDE) { - throw new DomainException(ExceptionInformation.INVALID_LOCATION); + throw new DomainException(DomainExceptionInformation.INVALID_LOCATION); } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java index f9fb9fe0..106d7375 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java @@ -2,7 +2,7 @@ import com.parkingcomestrue.parking.domain.parking.Parking; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.util.List; import java.util.Optional; import java.util.Set; @@ -14,7 +14,7 @@ public interface ParkingRepository extends Repository { default Parking getById(Long id) { - return findById(id).orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_PARKING)); + return findById(id).orElseThrow(() -> new DomainException(DomainExceptionInformation.INVALID_PARKING)); } Optional findById(Long id); diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java index 876855f0..362747ae 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.domain.review; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.util.Arrays; import lombok.Getter; @@ -29,6 +29,6 @@ public static Content find(String description) { return Arrays.stream(values()) .filter(content -> content.getDescription().startsWith(description)) .findAny() - .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_CONTENT)); + .orElseThrow(() -> new DomainException(DomainExceptionInformation.INVALID_CONTENT)); } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java index 3f3a1c2a..887d7e50 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java @@ -5,7 +5,7 @@ import com.parkingcomestrue.parking.infra.converter.ContentConverter; import com.parkingcomestrue.parking.support.Association; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Convert; @@ -55,7 +55,7 @@ public Review(Association parkingId, Association reviewerId, Li private static void validate(List contents) { if (contents == null || contents.isEmpty() || contents.size() > MAX_CONTENTS_SIZE) { - throw new DomainException(ExceptionInformation.INVALID_CONTENTS_SIZE); + throw new DomainException(DomainExceptionInformation.INVALID_CONTENTS_SIZE); } } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java index f31e4042..ede4a953 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java @@ -5,7 +5,7 @@ import com.parkingcomestrue.parking.domain.review.Review; import com.parkingcomestrue.parking.support.Association; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.util.List; import java.util.Optional; import org.springframework.data.repository.Repository; @@ -16,7 +16,7 @@ public interface ReviewRepository extends Repository { default Review getById(Long id) { return findById(id) - .orElseThrow(() -> new DomainException(ExceptionInformation.INVALID_REVIEW)); + .orElseThrow(() -> new DomainException(DomainExceptionInformation.INVALID_REVIEW)); } List findAllByParkingId(Association parkingId); diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java index f682eabc..12d80cbd 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java @@ -7,7 +7,7 @@ import com.parkingcomestrue.parking.domain.review.repository.ReviewRepository; import com.parkingcomestrue.parking.support.Association; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.util.Collection; import java.util.List; import java.util.Map; @@ -24,7 +24,7 @@ public class ReviewDomainService { public void validateDuplicateReview(Association parkingId, Association reviewerId) { if (reviewRepository.existsByParkingIdAndReviewerId(parkingId, reviewerId)) { - throw new DomainException(ExceptionInformation.DUPLICATE_REVIEW); + throw new DomainException(DomainExceptionInformation.DUPLICATE_REVIEW); } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java index 99b6c09e..58be704d 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.domain.searchcondition; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import jakarta.persistence.Embeddable; import lombok.AccessLevel; import lombok.Getter; @@ -22,6 +22,6 @@ public static Hours from(int hours) { if ((hours >= 1 && hours <= 12) || hours == 24) { return new Hours(hours); } - throw new DomainException(ExceptionInformation.INVALID_HOURS); + throw new DomainException(DomainExceptionInformation.INVALID_HOURS); } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java index e97dfffd..d5125afc 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java @@ -2,7 +2,7 @@ import com.parkingcomestrue.parking.domain.searchcondition.SearchCondition; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.util.Optional; import org.springframework.data.repository.Repository; @@ -12,7 +12,7 @@ public interface SearchConditionRepository extends Repository new DomainException(ExceptionInformation.INVALID_SEARCH_CONDITION)); + .orElseThrow(() -> new DomainException(DomainExceptionInformation.INVALID_SEARCH_CONDITION)); } void save(SearchCondition searchCondition); diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java index ab62458b..2d3b76c0 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java @@ -2,9 +2,9 @@ public class DomainException extends RuntimeException { - private final ExceptionInformation exceptionInformation; + private final DomainExceptionInformation exceptionInformation; - public DomainException(ExceptionInformation exceptionInformation) { + public DomainException(DomainExceptionInformation exceptionInformation) { super(); this.exceptionInformation = exceptionInformation; } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ExceptionInformation.java b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainExceptionInformation.java similarity index 62% rename from domain/src/main/java/com/parkingcomestrue/parking/support/exception/ExceptionInformation.java rename to domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainExceptionInformation.java index d5ad23aa..992db4e7 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/ExceptionInformation.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainExceptionInformation.java @@ -3,12 +3,10 @@ import lombok.Getter; @Getter -public enum ExceptionInformation { - DUPLICATE_MAIL("중복된 이메일이라 회원가입이 불가능합니다."), - INVALID_EMAIL("회원가입되지 않은 이메일입니다."), +public enum DomainExceptionInformation { + INVALID_MEMBER("존재하지 않는 회원입니다."), INVALID_PASSWORD("비밀번호가 틀립니다."), - UNAUTHORIZED("존재하지 않는 sessionId 입니다."), INVALID_PARKING("존재하지 않는 주차장입니다."), INVALID_CONTENT("존재하지 않는 리뷰 내용입니다."), @@ -20,15 +18,11 @@ public enum ExceptionInformation { ENCRYPT_EXCEPTION("암호화에 실패했습니다."), - INVALID_CONNECT("주차장 API 연결 중 예외 발생"), - COORDINATE_EXCEPTION("좌표 변환 중 예외 발생"), - INVALID_AUTH_CODE("존재하지 않는 인증코드 입니다."), - INVALID_DESCRIPTION("해당하는 내용의 검색 조건이 존재하지 않습니다."), INVALID_LOCATION("경도 또는 위도가 올바르지 않습니다."); private final String message; - ExceptionInformation(String message) { + DomainExceptionInformation(String message) { this.message = message; } } diff --git a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java b/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java index c9afdd3c..526146a1 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java +++ b/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.util.cipher; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.ExceptionInformation; +import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.security.MessageDigest; public class SHA256 { @@ -14,7 +14,7 @@ public static String encrypt(String plainText) { md.update(plainText.getBytes()); return bytesToHex(md.digest()); } catch (Exception e) { - throw new DomainException(ExceptionInformation.ENCRYPT_EXCEPTION); + throw new DomainException(DomainExceptionInformation.ENCRYPT_EXCEPTION); } } diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java index 9e73de44..6812cead 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.parking.domain.member; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_PASSWORD; +import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_PASSWORD; import com.parkingcomestrue.parking.support.exception.DomainException; import org.assertj.core.api.Assertions; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java index 887ac490..0f5eea80 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.parking.domain.review; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_CONTENT; +import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_CONTENT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.params.provider.Arguments.arguments; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java index 99700879..081bd371 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.parking.domain.review.service; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.DUPLICATE_REVIEW; +import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.DUPLICATE_REVIEW; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java b/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java index 98f973a7..3623283a 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java +++ b/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.parking.domain.searchcondition; -import static com.parkingcomestrue.parking.support.exception.ExceptionInformation.INVALID_HOURS; +import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_HOURS; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import com.parkingcomestrue.parking.support.exception.DomainException; From 0aeac739bc1a955721796f33084dd872ade7d58d Mon Sep 17 00:00:00 2001 From: This2sho Date: Fri, 12 Apr 2024 03:17:05 +0900 Subject: [PATCH 15/19] =?UTF-8?q?fix:=20CI=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EB=8F=8C=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ad6db97..d1ebc7ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: Backend CI on: push: branches: [ main ] - pull_request_target: + pull_request: branches: [ main ] permissions: From 01cc85b36f2f2ad1c245ca359b11f4dfe62d14b5 Mon Sep 17 00:00:00 2001 From: This2sho Date: Fri, 12 Apr 2024 17:45:07 +0900 Subject: [PATCH 16/19] =?UTF-8?q?refactor:=20exception=20support=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../parking/application/SearchConditionMapper.java | 4 ++-- .../parking/application/auth/AuthService.java | 4 ++-- .../parking/application/member/MemberService.java | 4 ++-- .../parking/controlleradvice/GlobalExceptionHandler.java | 4 ++-- .../{application => support}/exception/ClientException.java | 2 +- .../exception/ClientExceptionInformation.java | 2 +- .../parking/application/SearchConditionMapperTest.java | 4 ++-- .../parking/application/auth/AuthServiceTest.java | 6 +++--- .../parking/application/parking/ParkingServiceTest.java | 1 - .../external/coordinate/CoordinateErrorHandler.java | 4 ++-- .../{ => support}/exception/SchedulerException.java | 2 +- .../exception/SchedulerExceptionInformation.java | 2 +- .../parkingcomestrue/fake/ExceptionParkingApiService.java | 4 ++-- 13 files changed, 21 insertions(+), 22 deletions(-) rename app-api/src/main/java/com/parkingcomestrue/parking/{application => support}/exception/ClientException.java (87%) rename app-api/src/main/java/com/parkingcomestrue/parking/{application => support}/exception/ClientExceptionInformation.java (90%) rename app-scheduler/src/main/java/com/parkingcomestrue/external/{ => support}/exception/SchedulerException.java (87%) rename app-scheduler/src/main/java/com/parkingcomestrue/external/{ => support}/exception/SchedulerExceptionInformation.java (85%) diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java index b26dba64..95f7114a 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java @@ -1,8 +1,8 @@ package com.parkingcomestrue.parking.application; import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; -import com.parkingcomestrue.parking.application.exception.ClientException; -import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import java.util.Arrays; import java.util.List; import org.springframework.stereotype.Component; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java index c2f097e2..6359401a 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java @@ -10,8 +10,8 @@ import com.parkingcomestrue.parking.application.auth.authcode.util.AuthCodeKeyConverter; import com.parkingcomestrue.parking.domain.session.MemberSession; import com.parkingcomestrue.parking.domain.session.repository.MemberSessionRepository; -import com.parkingcomestrue.parking.application.exception.ClientException; -import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import java.time.LocalDateTime; import java.util.UUID; import java.util.concurrent.TimeUnit; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java index fca9f8ee..a86d5a92 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java @@ -7,8 +7,8 @@ import com.parkingcomestrue.parking.domain.member.Member; import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; import com.parkingcomestrue.parking.domain.member.Password; -import com.parkingcomestrue.parking.application.exception.ClientException; -import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java index 4b7d31e9..d922eb53 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java @@ -4,9 +4,9 @@ import static org.springframework.http.HttpStatus.UNAUTHORIZED; import com.parkingcomestrue.parking.controlleradvice.dto.ExceptionResponse; -import com.parkingcomestrue.parking.application.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ClientException; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; +import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import java.util.EnumMap; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientException.java b/app-api/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java similarity index 87% rename from app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientException.java rename to app-api/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java index 1b2589ec..afbcbb7b 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientException.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/support/exception/ClientException.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.application.exception; +package com.parkingcomestrue.parking.support.exception; import lombok.Getter; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientExceptionInformation.java b/app-api/src/main/java/com/parkingcomestrue/parking/support/exception/ClientExceptionInformation.java similarity index 90% rename from app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientExceptionInformation.java rename to app-api/src/main/java/com/parkingcomestrue/parking/support/exception/ClientExceptionInformation.java index 3baa1737..d70d7b78 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/exception/ClientExceptionInformation.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/support/exception/ClientExceptionInformation.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.application.exception; +package com.parkingcomestrue.parking.support.exception; import lombok.Getter; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java index 72fa20b4..9724891c 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java @@ -4,8 +4,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.params.provider.Arguments.arguments; -import com.parkingcomestrue.parking.application.exception.ClientException; -import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; +import com.parkingcomestrue.parking.support.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import com.parkingcomestrue.parking.domain.parking.OperationType; import com.parkingcomestrue.parking.domain.parking.ParkingType; import com.parkingcomestrue.parking.domain.parking.PayType; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java index 8b3c086b..9e82f6a9 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.application.auth; -import static com.parkingcomestrue.parking.application.exception.ClientExceptionInformation.INVALID_AUTH_CODE; -import static com.parkingcomestrue.parking.application.exception.ClientExceptionInformation.UNAUTHORIZED; +import static com.parkingcomestrue.parking.support.exception.ClientExceptionInformation.INVALID_AUTH_CODE; +import static com.parkingcomestrue.parking.support.exception.ClientExceptionInformation.UNAUTHORIZED; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -13,7 +13,7 @@ import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest; import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeRequest; import com.parkingcomestrue.parking.domain.session.MemberSession; -import com.parkingcomestrue.parking.application.exception.ClientException; +import com.parkingcomestrue.parking.support.exception.ClientException; import java.time.LocalDateTime; import org.junit.jupiter.api.Test; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java index d97748ac..26ffe0a2 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java @@ -22,7 +22,6 @@ import com.parkingcomestrue.parking.domain.parking.TimeUnit; import com.parkingcomestrue.parking.domain.review.Content; import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.application.exception.ClientExceptionInformation; import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; import java.time.LocalTime; import java.util.List; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java index ac082502..83114fac 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateErrorHandler.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.external.coordinate; -import com.parkingcomestrue.external.exception.SchedulerException; -import com.parkingcomestrue.external.exception.SchedulerExceptionInformation; +import com.parkingcomestrue.external.support.exception.SchedulerException; +import com.parkingcomestrue.external.support.exception.SchedulerExceptionInformation; import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.client.ClientHttpResponse; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerException.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/support/exception/SchedulerException.java similarity index 87% rename from app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerException.java rename to app-scheduler/src/main/java/com/parkingcomestrue/external/support/exception/SchedulerException.java index bb56aeb9..f4100a48 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerException.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/support/exception/SchedulerException.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.external.exception; +package com.parkingcomestrue.external.support.exception; public class SchedulerException extends RuntimeException { diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerExceptionInformation.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/support/exception/SchedulerExceptionInformation.java similarity index 85% rename from app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerExceptionInformation.java rename to app-scheduler/src/main/java/com/parkingcomestrue/external/support/exception/SchedulerExceptionInformation.java index 934f76c5..f9ddf95f 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/exception/SchedulerExceptionInformation.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/support/exception/SchedulerExceptionInformation.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.external.exception; +package com.parkingcomestrue.external.support.exception; import lombok.Getter; diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java index 9940c888..708685ae 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.fake; -import com.parkingcomestrue.external.exception.SchedulerException; -import com.parkingcomestrue.external.exception.SchedulerExceptionInformation; +import com.parkingcomestrue.external.support.exception.SchedulerException; +import com.parkingcomestrue.external.support.exception.SchedulerExceptionInformation; import com.parkingcomestrue.external.parkingapi.ParkingApiService; import com.parkingcomestrue.parking.domain.parking.Parking; import java.util.List; From cc8609221cd9c904d5b3b3f89e1355018c91c08d Mon Sep 17 00:00:00 2001 From: This2sho Date: Fri, 12 Apr 2024 17:48:33 +0900 Subject: [PATCH 17/19] =?UTF-8?q?refactor:=20TestConfig,=20ContainerTest?= =?UTF-8?q?=20=EC=83=81=EC=9C=84=20=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../parking/application/{container => }/ContainerTest.java | 4 ++-- .../parking/application/{config => }/TestConfig.java | 2 +- .../parking/application/auth/AuthServiceTest.java | 5 +---- .../parking/application/parking/ParkingServiceTest.java | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) rename app-api/src/test/java/com/parkingcomestrue/parking/application/{container => }/ContainerTest.java (95%) rename app-api/src/test/java/com/parkingcomestrue/parking/application/{config => }/TestConfig.java (90%) diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/container/ContainerTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/ContainerTest.java similarity index 95% rename from app-api/src/test/java/com/parkingcomestrue/parking/application/container/ContainerTest.java rename to app-api/src/test/java/com/parkingcomestrue/parking/application/ContainerTest.java index e310ea9d..232fdaf5 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/container/ContainerTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/ContainerTest.java @@ -1,7 +1,7 @@ -package com.parkingcomestrue.parking.application.container; +package com.parkingcomestrue.parking.application; import com.parkingcomestrue.parking.application.auth.AuthService; -import com.parkingcomestrue.parking.application.config.TestConfig; +import com.parkingcomestrue.parking.application.container.MySQLDataCleaner; import com.parkingcomestrue.parking.application.parking.ParkingService; import com.parkingcomestrue.parking.application.review.ReviewService; import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/config/TestConfig.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/TestConfig.java similarity index 90% rename from app-api/src/test/java/com/parkingcomestrue/parking/application/config/TestConfig.java rename to app-api/src/test/java/com/parkingcomestrue/parking/application/TestConfig.java index 03c79662..2df3f36c 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/config/TestConfig.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/TestConfig.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.application.config; +package com.parkingcomestrue.parking.application; import com.parkingcomestrue.parking.application.auth.authcode.infrastructure.AuthCodeSender; import org.springframework.boot.test.context.TestConfiguration; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java index 9e82f6a9..90623e67 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java @@ -7,7 +7,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import com.parkingcomestrue.parking.application.container.ContainerTest; +import com.parkingcomestrue.parking.application.ContainerTest; import com.parkingcomestrue.parking.application.auth.authcode.AuthCodeCategory; import com.parkingcomestrue.parking.application.auth.authcode.AuthCodePlatform; import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest; @@ -19,9 +19,6 @@ class AuthServiceTest extends ContainerTest { - private static final String AUTH_CODE = "111111"; - - @Test void 세션_아이디에_해당하는_세션을_찾는다() { // given diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java index 26ffe0a2..01cd1aea 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java @@ -2,7 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; -import com.parkingcomestrue.parking.application.container.ContainerTest; +import com.parkingcomestrue.parking.application.ContainerTest; import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; import com.parkingcomestrue.parking.domain.member.Member; From 03d259df27d5dba19a89614005f26055ad98383b Mon Sep 17 00:00:00 2001 From: This2sho Date: Sat, 13 Apr 2024 03:37:50 +0900 Subject: [PATCH 18/19] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EB=AA=85=20common?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/SearchConditionMapper.java | 2 +- .../parking/application/auth/AuthService.java | 4 +-- .../application/favorite/FavoriteService.java | 6 ++-- .../application/member/MemberService.java | 6 ++-- .../application/parking/ParkingService.java | 28 +++++++-------- .../application/review/ReviewService.java | 10 +++--- .../review/dto/ReviewCreateRequest.java | 2 +- .../SearchConditionService.java | 20 +++++------ .../AuthArgumentResolver.java | 2 +- ...arkingSearchConditionArgumentResolver.java | 6 ++-- .../config/interceptor/AuthInterceptor.java | 2 +- .../GlobalExceptionHandler.java | 2 +- .../parking/application/ContainerTest.java | 2 +- .../SearchConditionMapperTest.java | 12 +++---- .../application/auth/AuthServiceTest.java | 2 +- .../application/member/MemberServiceTest.java | 10 +++--- .../parking/ParkingServiceTest.java | 36 +++++++++---------- .../application/review/ReviewServiceTest.java | 16 ++++----- .../coordinate/CoordinateApiService.java | 2 +- .../parkingapi/ParkingApiService.java | 2 +- .../pusan/PusanPublicParkingAdapter.java | 26 +++++++------- .../pusan/PusanPublicParkingApiService.java | 2 +- .../seoul/SeoulPublicParkingAdapter.java | 26 +++++++------- .../seoul/SeoulPublicParkingApiService.java | 2 +- .../scheduler/ParkingUpdateScheduler.java | 6 ++-- .../coordinate/CoordinateApiServiceTest.java | 2 +- .../fake/ExceptionParkingApiService.java | 2 +- .../fake/FakeCoordinateApiService.java | 2 +- .../NotOfferCurrentParkingApiService.java | 24 ++++++------- .../fake/OfferCurrentParkingApiService.java | 24 ++++++------- .../domain/AuditingEntity.java | 2 +- .../domain/favorite/Favorite.java | 10 +++--- .../repository/FavoriteRepository.java | 10 +++--- .../domain/member/Member.java | 6 ++-- .../domain/member/Password.java | 4 +-- .../member/repository/MemberRepository.java | 8 ++--- .../domain/parking/BaseInformation.java | 2 +- .../domain/parking/Day.java | 2 +- .../domain/parking/DayParking.java | 2 +- .../domain/parking/Fee.java | 2 +- .../domain/parking/FeePolicy.java | 2 +- .../domain/parking/FreeOperatingTime.java | 2 +- .../domain/parking/Location.java | 6 ++-- .../domain/parking/OperatingTime.java | 2 +- .../domain/parking/OperationType.java | 4 +-- .../domain/parking/Parking.java | 4 +-- .../domain/parking/ParkingFeeCalculator.java | 2 +- .../domain/parking/ParkingType.java | 4 +-- .../domain/parking/PayType.java | 4 +-- .../domain/parking/PayTypes.java | 2 +- .../domain/parking/SearchingCondition.java | 4 +-- .../domain/parking/Space.java | 2 +- .../domain/parking/TimeInfo.java | 2 +- .../domain/parking/TimeUnit.java | 2 +- .../parking/dto/ParkingQueryCondition.java | 8 ++--- .../parking/repository/ParkingRepository.java | 8 ++--- .../service/ParkingFilteringService.java | 10 +++--- .../domain/review/Content.java | 6 ++-- .../domain/review/Review.java | 16 ++++----- .../review/repository/ReviewRepository.java | 14 ++++---- .../review/service/ReviewDomainService.java | 18 +++++----- .../domain/searchcondition/FeeType.java | 2 +- .../domain/searchcondition/Hours.java | 6 ++-- .../domain/searchcondition/Priority.java | 2 +- .../searchcondition/SearchCondition.java | 20 +++++------ .../SearchConditionAvailable.java | 2 +- .../repository/SearchConditionRepository.java | 8 ++--- .../domain/session/MemberSession.java | 2 +- .../repository/MemberSessionRepository.java | 4 +-- .../infra/config/JpaAuditingConfig.java | 2 +- .../infra/converter/ContentConverter.java | 4 +-- .../infra/converter/EnumListConverter.java | 2 +- .../infra/converter/FeeTypeConverter.java | 4 +-- .../converter/OperationTypeConverter.java | 4 +-- .../infra/converter/ParkingTypeConverter.java | 4 +-- .../infra/converter/PayTypeConverter.java | 4 +-- .../support/Association.java | 2 +- .../support/exception/DomainException.java | 2 +- .../exception/DomainExceptionInformation.java | 2 +- .../util/cipher/EncryptionException.java | 2 +- .../util/cipher/SHA256.java | 6 ++-- .../repository/FavoriteRepositoryTest.java | 7 ++-- .../domain/member/MemberTest.java | 8 +++-- .../domain/parking/BaseInformationTest.java | 4 ++- .../domain/parking/DayTest.java | 3 +- .../domain/parking/FeePolicyTest.java | 5 ++- .../domain/parking/FeeTest.java | 3 +- .../domain/parking/FreeOperatingTimeTest.java | 6 +++- .../domain/parking/LocationTest.java | 3 +- .../parking/ParkingFeeCalculatorTest.java | 15 ++++++-- .../domain/parking/ParkingTest.java | 13 +++++-- .../domain/parking/PayTypesTest.java | 12 ++++--- .../domain/parking/TimeInfoTest.java | 3 +- .../domain/parking/TimeUnitTest.java | 3 +- .../service/ParkingFilteringServiceTest.java | 29 +++++++-------- .../domain/review/ContentTest.java | 7 ++-- .../service/ReviewDomainServiceTest.java | 17 ++++----- .../domain/searchcondition/HoursTest.java | 7 ++-- .../MemberSessionRepositoryTest.java | 5 +-- .../converter/EnumListConverterTest.java | 5 +-- .../repository/BasicMemberRepository.java | 6 ++-- .../repository/BasicParkingRepository.java | 26 +++++++------- .../repository/BasicReviewRepository.java | 6 ++-- .../repository/FakeFavoriteRepository.java | 10 +++--- .../FakeSearchConditionRepository.java | 4 +-- 105 files changed, 397 insertions(+), 352 deletions(-) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/AuditingEntity.java (92%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/favorite/Favorite.java (81%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/favorite/repository/FavoriteRepository.java (54%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/member/Member.java (90%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/member/Password.java (89%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/member/repository/MemberRepository.java (63%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/BaseInformation.java (96%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/Day.java (86%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/DayParking.java (91%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/Fee.java (95%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/FeePolicy.java (97%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/FreeOperatingTime.java (98%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/Location.java (91%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/OperatingTime.java (97%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/OperationType.java (73%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/Parking.java (97%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/ParkingFeeCalculator.java (98%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/ParkingType.java (82%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/PayType.java (73%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/PayTypes.java (95%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/SearchingCondition.java (85%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/Space.java (95%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/TimeInfo.java (97%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/TimeUnit.java (95%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/dto/ParkingQueryCondition.java (69%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/repository/ParkingRepository.java (82%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/parking/service/ParkingFilteringService.java (81%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/review/Content.java (84%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/review/Review.java (78%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/review/repository/ReviewRepository.java (57%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/review/service/ReviewDomainService.java (65%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/searchcondition/FeeType.java (85%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/searchcondition/Hours.java (71%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/searchcondition/Priority.java (86%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/searchcondition/SearchCondition.java (76%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/searchcondition/SearchConditionAvailable.java (68%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/searchcondition/repository/SearchConditionRepository.java (62%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/session/MemberSession.java (93%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/domain/session/repository/MemberSessionRepository.java (71%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/infra/config/JpaAuditingConfig.java (80%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/infra/converter/ContentConverter.java (62%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/infra/converter/EnumListConverter.java (94%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/infra/converter/FeeTypeConverter.java (60%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/infra/converter/OperationTypeConverter.java (63%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/infra/converter/ParkingTypeConverter.java (63%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/infra/converter/PayTypeConverter.java (62%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/support/Association.java (92%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/support/exception/DomainException.java (87%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/support/exception/DomainExceptionInformation.java (94%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/util/cipher/EncryptionException.java (74%) rename domain/src/main/java/com/parkingcomestrue/{parking => common}/util/cipher/SHA256.java (77%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/favorite/repository/FavoriteRepositoryTest.java (86%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/member/MemberTest.java (85%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/BaseInformationTest.java (68%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/DayTest.java (93%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/FeePolicyTest.java (93%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/FeeTest.java (87%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/FreeOperatingTimeTest.java (96%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/LocationTest.java (91%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/ParkingFeeCalculatorTest.java (96%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/ParkingTest.java (93%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/PayTypesTest.java (81%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/TimeInfoTest.java (98%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/TimeUnitTest.java (89%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/parking/service/ParkingFilteringServiceTest.java (85%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/review/ContentTest.java (81%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/review/service/ReviewDomainServiceTest.java (84%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/searchcondition/HoursTest.java (72%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/domain/session/repository/MemberSessionRepositoryTest.java (88%) rename domain/src/test/java/com/parkingcomestrue/{parking => common}/infra/converter/EnumListConverterTest.java (85%) diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java index 95f7114a..0b9f6208 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/SearchConditionMapper.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.parking.application; -import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.common.domain.searchcondition.SearchConditionAvailable; import com.parkingcomestrue.parking.support.exception.ClientException; import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import java.util.Arrays; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java index 6359401a..94e6f5a7 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/auth/AuthService.java @@ -8,8 +8,8 @@ import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCreateEvent; import com.parkingcomestrue.parking.application.auth.authcode.util.AuthCodeGenerator; import com.parkingcomestrue.parking.application.auth.authcode.util.AuthCodeKeyConverter; -import com.parkingcomestrue.parking.domain.session.MemberSession; -import com.parkingcomestrue.parking.domain.session.repository.MemberSessionRepository; +import com.parkingcomestrue.common.domain.session.MemberSession; +import com.parkingcomestrue.common.domain.session.repository.MemberSessionRepository; import com.parkingcomestrue.parking.support.exception.ClientException; import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import java.time.LocalDateTime; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java index e4c3a4a9..b8205282 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/favorite/FavoriteService.java @@ -2,9 +2,9 @@ import com.parkingcomestrue.parking.application.favorite.dto.FavoriteCreateRequest; import com.parkingcomestrue.parking.application.favorite.dto.FavoriteDeleteRequest; -import com.parkingcomestrue.parking.domain.favorite.Favorite; -import com.parkingcomestrue.parking.domain.favorite.repository.FavoriteRepository; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.favorite.Favorite; +import com.parkingcomestrue.common.domain.favorite.repository.FavoriteRepository; +import com.parkingcomestrue.common.support.Association; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DataIntegrityViolationException; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java index a86d5a92..b5bee195 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/member/MemberService.java @@ -4,9 +4,9 @@ import com.parkingcomestrue.parking.application.member.dto.MemberLoginRequest; import com.parkingcomestrue.parking.application.member.dto.MemberSignupRequest; import com.parkingcomestrue.parking.application.member.dto.PasswordChangeRequest; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; -import com.parkingcomestrue.parking.domain.member.Password; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.member.repository.MemberRepository; +import com.parkingcomestrue.common.domain.member.Password; import com.parkingcomestrue.parking.support.exception.ClientException; import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import org.springframework.stereotype.Service; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java index cd945e87..a3d30a03 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java @@ -12,20 +12,20 @@ import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest; import com.parkingcomestrue.parking.application.review.ReviewService; import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; -import com.parkingcomestrue.parking.domain.favorite.Favorite; -import com.parkingcomestrue.parking.domain.favorite.repository.FavoriteRepository; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingFeeCalculator; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayType; -import com.parkingcomestrue.parking.domain.parking.SearchingCondition; -import com.parkingcomestrue.parking.domain.parking.repository.ParkingRepository; -import com.parkingcomestrue.parking.domain.parking.service.ParkingFilteringService; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.favorite.Favorite; +import com.parkingcomestrue.common.domain.favorite.repository.FavoriteRepository; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingFeeCalculator; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.domain.parking.SearchingCondition; +import com.parkingcomestrue.common.domain.parking.repository.ParkingRepository; +import com.parkingcomestrue.common.domain.parking.service.ParkingFilteringService; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.support.Association; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java index 72409d00..3f5040fa 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/ReviewService.java @@ -3,11 +3,11 @@ import com.parkingcomestrue.parking.application.review.dto.ReviewCountResponse; import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; -import com.parkingcomestrue.parking.domain.review.Content; -import com.parkingcomestrue.parking.domain.review.Review; -import com.parkingcomestrue.parking.domain.review.repository.ReviewRepository; -import com.parkingcomestrue.parking.domain.review.service.ReviewDomainService; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.review.Content; +import com.parkingcomestrue.common.domain.review.Review; +import com.parkingcomestrue.common.domain.review.repository.ReviewRepository; +import com.parkingcomestrue.common.domain.review.service.ReviewDomainService; +import com.parkingcomestrue.common.support.Association; import java.util.Comparator; import java.util.List; import java.util.Map; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java index da687561..c14deb08 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/review/dto/ReviewCreateRequest.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.parking.application.review.dto; -import com.parkingcomestrue.parking.domain.review.Content; +import com.parkingcomestrue.common.domain.review.Content; import java.util.List; public record ReviewCreateRequest(List contents) { diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java index fc5e493d..e4869e04 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/searchcondition/SearchConditionService.java @@ -2,16 +2,16 @@ import com.parkingcomestrue.parking.application.SearchConditionMapper; import com.parkingcomestrue.parking.application.searchcondition.dto.SearchConditionDto; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayType; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; -import com.parkingcomestrue.parking.domain.searchcondition.Hours; -import com.parkingcomestrue.parking.domain.searchcondition.Priority; -import com.parkingcomestrue.parking.domain.searchcondition.SearchCondition; -import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; -import com.parkingcomestrue.parking.domain.searchcondition.repository.SearchConditionRepository; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.searchcondition.Hours; +import com.parkingcomestrue.common.domain.searchcondition.Priority; +import com.parkingcomestrue.common.domain.searchcondition.SearchCondition; +import com.parkingcomestrue.common.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.common.domain.searchcondition.repository.SearchConditionRepository; +import com.parkingcomestrue.common.support.Association; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java index 58833ab1..fa28a409 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/AuthArgumentResolver.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.config.argumentresolver; import com.parkingcomestrue.parking.application.auth.AuthService; -import com.parkingcomestrue.parking.domain.session.MemberSession; +import com.parkingcomestrue.common.domain.session.MemberSession; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java index 19851bbe..a4698554 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java @@ -2,9 +2,9 @@ import com.parkingcomestrue.parking.application.SearchConditionMapper; import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayType; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayType; import java.util.Arrays; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java index 7ab2b150..848879ce 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/interceptor/AuthInterceptor.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.parking.config.interceptor; import com.parkingcomestrue.parking.application.auth.AuthService; -import com.parkingcomestrue.parking.domain.session.MemberSession; +import com.parkingcomestrue.common.domain.session.MemberSession; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java index d922eb53..6d1a67d9 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/controlleradvice/GlobalExceptionHandler.java @@ -5,7 +5,7 @@ import com.parkingcomestrue.parking.controlleradvice.dto.ExceptionResponse; import com.parkingcomestrue.parking.support.exception.ClientException; -import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainException; import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; import java.util.EnumMap; import lombok.extern.slf4j.Slf4j; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/ContainerTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/ContainerTest.java index 232fdaf5..040715e3 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/ContainerTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/ContainerTest.java @@ -4,7 +4,7 @@ import com.parkingcomestrue.parking.application.container.MySQLDataCleaner; import com.parkingcomestrue.parking.application.parking.ParkingService; import com.parkingcomestrue.parking.application.review.ReviewService; -import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; +import com.parkingcomestrue.common.domain.member.repository.MemberRepository; import com.redis.testcontainers.RedisContainer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java index 9724891c..d3c93612 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/SearchConditionMapperTest.java @@ -6,12 +6,12 @@ import com.parkingcomestrue.parking.support.exception.ClientException; import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayType; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; -import com.parkingcomestrue.parking.domain.searchcondition.Priority; -import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.searchcondition.Priority; +import com.parkingcomestrue.common.domain.searchcondition.SearchConditionAvailable; import java.util.List; import java.util.stream.Stream; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java index 90623e67..cd4ed735 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/auth/AuthServiceTest.java @@ -12,7 +12,7 @@ import com.parkingcomestrue.parking.application.auth.authcode.AuthCodePlatform; import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest; import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeRequest; -import com.parkingcomestrue.parking.domain.session.MemberSession; +import com.parkingcomestrue.common.domain.session.MemberSession; import com.parkingcomestrue.parking.support.exception.ClientException; import java.time.LocalDateTime; import org.junit.jupiter.api.Test; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java index 13f844e1..53635f62 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/member/MemberServiceTest.java @@ -1,15 +1,15 @@ package com.parkingcomestrue.parking.application.member; -import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_MEMBER; -import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_PASSWORD; +import static com.parkingcomestrue.common.support.exception.DomainExceptionInformation.INVALID_MEMBER; +import static com.parkingcomestrue.common.support.exception.DomainExceptionInformation.INVALID_PASSWORD; import static org.assertj.core.api.Assertions.assertThat; import com.parkingcomestrue.parking.application.member.dto.MemberLoginRequest; import com.parkingcomestrue.parking.application.member.dto.MemberSignupRequest; import com.parkingcomestrue.parking.application.member.dto.PasswordChangeRequest; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; -import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.member.repository.MemberRepository; +import com.parkingcomestrue.common.support.exception.DomainException; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java index 01cd1aea..b5e56930 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java @@ -5,24 +5,24 @@ import com.parkingcomestrue.parking.application.ContainerTest; import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.member.Password; -import com.parkingcomestrue.parking.domain.parking.BaseInformation; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.FeePolicy; -import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.OperatingTime; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; -import com.parkingcomestrue.parking.domain.parking.Space; -import com.parkingcomestrue.parking.domain.parking.TimeInfo; -import com.parkingcomestrue.parking.domain.parking.TimeUnit; -import com.parkingcomestrue.parking.domain.review.Content; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.member.Password; +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeInfo; +import com.parkingcomestrue.common.domain.parking.TimeUnit; +import com.parkingcomestrue.common.domain.review.Content; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import java.time.LocalTime; import java.util.List; import org.assertj.core.api.Assertions; diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java index 4fecb50b..1d981c06 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/review/ReviewServiceTest.java @@ -1,19 +1,19 @@ package com.parkingcomestrue.parking.application.review; -import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.DUPLICATE_REVIEW; +import static com.parkingcomestrue.common.support.exception.DomainExceptionInformation.DUPLICATE_REVIEW; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.review.Content; -import com.parkingcomestrue.parking.domain.review.Review; -import com.parkingcomestrue.parking.domain.review.service.ReviewDomainService; -import com.parkingcomestrue.parking.support.Association; -import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.review.Content; +import com.parkingcomestrue.common.domain.review.Review; +import com.parkingcomestrue.common.domain.review.service.ReviewDomainService; +import com.parkingcomestrue.common.support.Association; +import com.parkingcomestrue.common.support.exception.DomainException; import java.util.List; import org.junit.jupiter.api.Test; import repository.BasicMemberRepository; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java index af6bd639..d1d8d3b3 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/coordinate/CoordinateApiService.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.external.coordinate; -import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.Location; import com.parkingcomestrue.external.coordinate.dto.CoordinateResponse; import com.parkingcomestrue.external.coordinate.dto.CoordinateResponse.ExactLocation; import java.util.List; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java index 941075c9..877d6a69 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/ParkingApiService.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.external.parkingapi; -import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.Parking; import java.util.List; public interface ParkingApiService { diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java index eb47d32e..387c8b32 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java @@ -1,18 +1,18 @@ package com.parkingcomestrue.external.parkingapi.pusan; -import com.parkingcomestrue.parking.domain.parking.BaseInformation; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.FeePolicy; -import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.OperatingTime; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; -import com.parkingcomestrue.parking.domain.parking.Space; -import com.parkingcomestrue.parking.domain.parking.TimeInfo; -import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeInfo; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import java.time.DateTimeException; import java.time.LocalTime; import java.time.format.DateTimeFormatter; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java index 487c8672..3685b99c 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingApiService.java @@ -1,6 +1,6 @@ package com.parkingcomestrue.external.parkingapi.pusan; -import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.Parking; import com.parkingcomestrue.external.parkingapi.ParkingApiService; import java.net.URI; import java.nio.charset.StandardCharsets; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java index 050f7653..a0918d7b 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java @@ -1,18 +1,18 @@ package com.parkingcomestrue.external.parkingapi.seoul; -import com.parkingcomestrue.parking.domain.parking.BaseInformation; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.FeePolicy; -import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.OperatingTime; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; -import com.parkingcomestrue.parking.domain.parking.Space; -import com.parkingcomestrue.parking.domain.parking.TimeInfo; -import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeInfo; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import java.time.DateTimeException; import java.time.LocalTime; import java.time.format.DateTimeFormatter; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java index 4809512a..c009bc94 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingApiService.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.external.parkingapi.seoul; import com.parkingcomestrue.external.parkingapi.ParkingApiService; -import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.Parking; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Collection; diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java index 802bc6b9..3473afb4 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/scheduler/ParkingUpdateScheduler.java @@ -2,9 +2,9 @@ import com.parkingcomestrue.external.coordinate.CoordinateApiService; import com.parkingcomestrue.external.parkingapi.ParkingApiService; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.repository.ParkingRepository; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.repository.ParkingRepository; import java.util.Collection; import java.util.Collections; import java.util.List; diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java b/app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java index 9eb42929..e1cb42a9 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/external/coordinate/CoordinateApiServiceTest.java @@ -7,7 +7,7 @@ import static org.mockito.Mockito.when; import com.parkingcomestrue.external.coordinate.dto.CoordinateResponse; -import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.Location; import java.util.Collections; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java index 708685ae..0a801903 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/ExceptionParkingApiService.java @@ -3,7 +3,7 @@ import com.parkingcomestrue.external.support.exception.SchedulerException; import com.parkingcomestrue.external.support.exception.SchedulerExceptionInformation; import com.parkingcomestrue.external.parkingapi.ParkingApiService; -import com.parkingcomestrue.parking.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.Parking; import java.util.List; public class ExceptionParkingApiService implements ParkingApiService { diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java index c9e4afe7..567ecf57 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/FakeCoordinateApiService.java @@ -1,7 +1,7 @@ package com.parkingcomestrue.fake; import com.parkingcomestrue.external.coordinate.CoordinateApiService; -import com.parkingcomestrue.parking.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.Location; public class FakeCoordinateApiService extends CoordinateApiService { diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java index 3abc324c..96aaa5e7 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java @@ -1,18 +1,18 @@ package com.parkingcomestrue.fake; import com.parkingcomestrue.external.parkingapi.ParkingApiService; -import com.parkingcomestrue.parking.domain.parking.BaseInformation; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.FeePolicy; -import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.OperatingTime; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; -import com.parkingcomestrue.parking.domain.parking.Space; -import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import java.util.LinkedList; import java.util.List; diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java index 61ea2cc4..2df132e5 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java @@ -1,18 +1,18 @@ package com.parkingcomestrue.fake; import com.parkingcomestrue.external.parkingapi.ParkingApiService; -import com.parkingcomestrue.parking.domain.parking.BaseInformation; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.FeePolicy; -import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.OperatingTime; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; -import com.parkingcomestrue.parking.domain.parking.Space; -import com.parkingcomestrue.parking.domain.parking.TimeUnit; +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import java.util.LinkedList; import java.util.List; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/AuditingEntity.java b/domain/src/main/java/com/parkingcomestrue/common/domain/AuditingEntity.java similarity index 92% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/AuditingEntity.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/AuditingEntity.java index d1450458..fb3139fe 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/AuditingEntity.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/AuditingEntity.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain; +package com.parkingcomestrue.common.domain; import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/Favorite.java b/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/Favorite.java similarity index 81% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/Favorite.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/favorite/Favorite.java index 68010a05..2c760ee1 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/Favorite.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/Favorite.java @@ -1,9 +1,9 @@ -package com.parkingcomestrue.parking.domain.favorite; +package com.parkingcomestrue.common.domain.favorite; -import com.parkingcomestrue.parking.domain.AuditingEntity; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.AuditingEntity; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.support.Association; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Embedded; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepository.java b/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/repository/FavoriteRepository.java similarity index 54% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepository.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/favorite/repository/FavoriteRepository.java index 91ddb421..64613649 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/repository/FavoriteRepository.java @@ -1,9 +1,9 @@ -package com.parkingcomestrue.parking.domain.favorite.repository; +package com.parkingcomestrue.common.domain.favorite.repository; -import com.parkingcomestrue.parking.domain.favorite.Favorite; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.favorite.Favorite; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.support.Association; import java.util.List; import org.springframework.data.repository.Repository; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java b/domain/src/main/java/com/parkingcomestrue/common/domain/member/Member.java similarity index 90% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/member/Member.java index 2956084a..3df995c7 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Member.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/member/Member.java @@ -1,7 +1,7 @@ -package com.parkingcomestrue.parking.domain.member; +package com.parkingcomestrue.common.domain.member; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Password.java b/domain/src/main/java/com/parkingcomestrue/common/domain/member/Password.java similarity index 89% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/member/Password.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/member/Password.java index 97ce3fc5..5befdae1 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/Password.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/member/Password.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.domain.member; +package com.parkingcomestrue.common.domain.member; -import com.parkingcomestrue.parking.util.cipher.SHA256; +import com.parkingcomestrue.common.util.cipher.SHA256; import jakarta.persistence.Embeddable; import java.util.Objects; import lombok.AccessLevel; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java b/domain/src/main/java/com/parkingcomestrue/common/domain/member/repository/MemberRepository.java similarity index 63% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/member/repository/MemberRepository.java index 02b808f0..a4848907 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/member/repository/MemberRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/member/repository/MemberRepository.java @@ -1,8 +1,8 @@ -package com.parkingcomestrue.parking.domain.member.repository; +package com.parkingcomestrue.common.domain.member.repository; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.domain.member.Member; import java.util.Optional; import org.springframework.data.repository.Repository; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/BaseInformation.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/BaseInformation.java similarity index 96% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/BaseInformation.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/BaseInformation.java index 3e18f5b4..73f24df6 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/BaseInformation.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/BaseInformation.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import static jakarta.persistence.EnumType.STRING; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Day.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Day.java similarity index 86% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Day.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/Day.java index caa2db5b..4cf87d51 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Day.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Day.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import java.time.DayOfWeek; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/DayParking.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/DayParking.java similarity index 91% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/DayParking.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/DayParking.java index f1f617b6..4eef5b49 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/DayParking.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/DayParking.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import java.time.LocalTime; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Fee.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Fee.java similarity index 95% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Fee.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/Fee.java index 359f6288..275ffd5a 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Fee.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Fee.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.Embeddable; import lombok.AccessLevel; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FeePolicy.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FeePolicy.java similarity index 97% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FeePolicy.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/FeePolicy.java index 57a2e1f4..8cb08d36 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FeePolicy.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FeePolicy.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTime.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FreeOperatingTime.java similarity index 98% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTime.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/FreeOperatingTime.java index c9c339e6..46d742dd 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTime.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FreeOperatingTime.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Location.java similarity index 91% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/Location.java index 5b01f945..0f512a6b 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Location.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Location.java @@ -1,7 +1,7 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import jakarta.persistence.Embeddable; import lombok.AccessLevel; import lombok.EqualsAndHashCode; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperatingTime.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/OperatingTime.java similarity index 97% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperatingTime.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/OperatingTime.java index aeb43bf3..65cdde82 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperatingTime.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/OperatingTime.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperationType.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/OperationType.java similarity index 73% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperationType.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/OperationType.java index 8d293d55..f51b760d 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/OperationType.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/OperationType.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; -import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.common.domain.searchcondition.SearchConditionAvailable; import lombok.Getter; @Getter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Parking.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Parking.java similarity index 97% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Parking.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/Parking.java index bdac4c9c..0f135a38 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Parking.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Parking.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; -import com.parkingcomestrue.parking.domain.AuditingEntity; +import com.parkingcomestrue.common.domain.AuditingEntity; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculator.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/ParkingFeeCalculator.java similarity index 98% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculator.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/ParkingFeeCalculator.java index 5f4bb421..fbf8c8d2 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculator.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/ParkingFeeCalculator.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import java.time.LocalDateTime; import java.time.LocalTime; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingType.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/ParkingType.java similarity index 82% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingType.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/ParkingType.java index e04e2e9f..4e3a6ce1 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/ParkingType.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/ParkingType.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; -import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.common.domain.searchcondition.SearchConditionAvailable; import java.util.Arrays; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayType.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayType.java similarity index 73% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayType.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayType.java index 63de4874..60310ade 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayType.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayType.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; -import com.parkingcomestrue.parking.domain.searchcondition.SearchConditionAvailable; +import com.parkingcomestrue.common.domain.searchcondition.SearchConditionAvailable; import lombok.Getter; @Getter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayTypes.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayTypes.java similarity index 95% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayTypes.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayTypes.java index 59903a69..9089cdb7 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/PayTypes.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayTypes.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.Embeddable; import java.util.Collection; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/SearchingCondition.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/SearchingCondition.java similarity index 85% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/SearchingCondition.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/SearchingCondition.java index 10791935..ccc6988b 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/SearchingCondition.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/SearchingCondition.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; import java.util.List; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Space.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Space.java similarity index 95% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Space.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/Space.java index 66cba855..bb987b5d 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/Space.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Space.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.Embeddable; import lombok.AccessLevel; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeInfo.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/TimeInfo.java similarity index 97% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeInfo.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/TimeInfo.java index 29dbb00a..f5347050 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeInfo.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/TimeInfo.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.Embeddable; import java.time.LocalTime; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeUnit.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/TimeUnit.java similarity index 95% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeUnit.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/TimeUnit.java index e6ac836e..d407befb 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/TimeUnit.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/TimeUnit.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import jakarta.persistence.Embeddable; import lombok.AccessLevel; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/dto/ParkingQueryCondition.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/dto/ParkingQueryCondition.java similarity index 69% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/dto/ParkingQueryCondition.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/dto/ParkingQueryCondition.java index a87d147e..fd8ae260 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/dto/ParkingQueryCondition.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/dto/ParkingQueryCondition.java @@ -1,8 +1,8 @@ -package com.parkingcomestrue.parking.domain.parking.dto; +package com.parkingcomestrue.common.domain.parking.dto; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayTypes; import lombok.Getter; @Getter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/repository/ParkingRepository.java similarity index 82% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/repository/ParkingRepository.java index 106d7375..47372665 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/repository/ParkingRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/repository/ParkingRepository.java @@ -1,8 +1,8 @@ -package com.parkingcomestrue.parking.domain.parking.repository; +package com.parkingcomestrue.common.domain.parking.repository; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import java.util.List; import java.util.Optional; import java.util.Set; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringService.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringService.java similarity index 81% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringService.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringService.java index b2dae979..be207a3b 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringService.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringService.java @@ -1,9 +1,9 @@ -package com.parkingcomestrue.parking.domain.parking.service; +package com.parkingcomestrue.common.domain.parking.service; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingFeeCalculator; -import com.parkingcomestrue.parking.domain.parking.SearchingCondition; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingFeeCalculator; +import com.parkingcomestrue.common.domain.parking.SearchingCondition; import java.time.LocalDateTime; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java b/domain/src/main/java/com/parkingcomestrue/common/domain/review/Content.java similarity index 84% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/review/Content.java index 362747ae..1ab1b314 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Content.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/review/Content.java @@ -1,7 +1,7 @@ -package com.parkingcomestrue.parking.domain.review; +package com.parkingcomestrue.common.domain.review; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import java.util.Arrays; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java b/domain/src/main/java/com/parkingcomestrue/common/domain/review/Review.java similarity index 78% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/review/Review.java index 887d7e50..7f959b74 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/Review.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/review/Review.java @@ -1,11 +1,11 @@ -package com.parkingcomestrue.parking.domain.review; - -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.infra.converter.ContentConverter; -import com.parkingcomestrue.parking.support.Association; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +package com.parkingcomestrue.common.domain.review; + +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.infra.converter.ContentConverter; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.support.Association; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Convert; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java b/domain/src/main/java/com/parkingcomestrue/common/domain/review/repository/ReviewRepository.java similarity index 57% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/review/repository/ReviewRepository.java index ede4a953..3b367444 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/repository/ReviewRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/review/repository/ReviewRepository.java @@ -1,11 +1,11 @@ -package com.parkingcomestrue.parking.domain.review.repository; +package com.parkingcomestrue.common.domain.review.repository; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.review.Review; -import com.parkingcomestrue.parking.support.Association; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.review.Review; +import com.parkingcomestrue.common.support.Association; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import java.util.List; import java.util.Optional; import org.springframework.data.repository.Repository; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java b/domain/src/main/java/com/parkingcomestrue/common/domain/review/service/ReviewDomainService.java similarity index 65% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/review/service/ReviewDomainService.java index 12d80cbd..b11304f4 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainService.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/review/service/ReviewDomainService.java @@ -1,13 +1,13 @@ -package com.parkingcomestrue.parking.domain.review.service; +package com.parkingcomestrue.common.domain.review.service; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.review.Content; -import com.parkingcomestrue.parking.domain.review.Review; -import com.parkingcomestrue.parking.domain.review.repository.ReviewRepository; -import com.parkingcomestrue.parking.support.Association; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.review.repository.ReviewRepository; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.review.Content; +import com.parkingcomestrue.common.domain.review.Review; +import com.parkingcomestrue.common.support.Association; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import java.util.Collection; import java.util.List; import java.util.Map; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/FeeType.java b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/FeeType.java similarity index 85% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/FeeType.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/FeeType.java index c4f83355..9cc403ec 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/FeeType.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/FeeType.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.searchcondition; +package com.parkingcomestrue.common.domain.searchcondition; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/Hours.java similarity index 71% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/Hours.java index 58be704d..8fc7a223 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Hours.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/Hours.java @@ -1,7 +1,7 @@ -package com.parkingcomestrue.parking.domain.searchcondition; +package com.parkingcomestrue.common.domain.searchcondition; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import jakarta.persistence.Embeddable; import lombok.AccessLevel; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Priority.java b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/Priority.java similarity index 86% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Priority.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/Priority.java index 0e86037e..c4a027a1 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/Priority.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/Priority.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.searchcondition; +package com.parkingcomestrue.common.domain.searchcondition; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchCondition.java b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchCondition.java similarity index 76% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchCondition.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchCondition.java index 803a39d0..043f1781 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchCondition.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchCondition.java @@ -1,14 +1,14 @@ -package com.parkingcomestrue.parking.domain.searchcondition; +package com.parkingcomestrue.common.domain.searchcondition; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayType; -import com.parkingcomestrue.parking.infra.converter.FeeTypeConverter; -import com.parkingcomestrue.parking.infra.converter.OperationTypeConverter; -import com.parkingcomestrue.parking.infra.converter.ParkingTypeConverter; -import com.parkingcomestrue.parking.infra.converter.PayTypeConverter; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.infra.converter.FeeTypeConverter; +import com.parkingcomestrue.common.infra.converter.OperationTypeConverter; +import com.parkingcomestrue.common.infra.converter.ParkingTypeConverter; +import com.parkingcomestrue.common.infra.converter.PayTypeConverter; +import com.parkingcomestrue.common.support.Association; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Convert; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchConditionAvailable.java b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchConditionAvailable.java similarity index 68% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchConditionAvailable.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchConditionAvailable.java index bcc4f131..5ff6095d 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/SearchConditionAvailable.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchConditionAvailable.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.searchcondition; +package com.parkingcomestrue.common.domain.searchcondition; public interface SearchConditionAvailable { diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/repository/SearchConditionRepository.java similarity index 62% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/repository/SearchConditionRepository.java index d5125afc..2e1a9c89 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/searchcondition/repository/SearchConditionRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/repository/SearchConditionRepository.java @@ -1,8 +1,8 @@ -package com.parkingcomestrue.parking.domain.searchcondition.repository; +package com.parkingcomestrue.common.domain.searchcondition.repository; -import com.parkingcomestrue.parking.domain.searchcondition.SearchCondition; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.domain.searchcondition.SearchCondition; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import java.util.Optional; import org.springframework.data.repository.Repository; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/session/MemberSession.java b/domain/src/main/java/com/parkingcomestrue/common/domain/session/MemberSession.java similarity index 93% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/session/MemberSession.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/session/MemberSession.java index 73ef6058..7b1248b2 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/session/MemberSession.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/session/MemberSession.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.domain.session; +package com.parkingcomestrue.common.domain.session; import jakarta.persistence.Entity; import jakarta.persistence.Id; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepository.java b/domain/src/main/java/com/parkingcomestrue/common/domain/session/repository/MemberSessionRepository.java similarity index 71% rename from domain/src/main/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepository.java rename to domain/src/main/java/com/parkingcomestrue/common/domain/session/repository/MemberSessionRepository.java index fc37f7dd..5fedcbbd 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/session/repository/MemberSessionRepository.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.domain.session.repository; +package com.parkingcomestrue.common.domain.session.repository; -import com.parkingcomestrue.parking.domain.session.MemberSession; +import com.parkingcomestrue.common.domain.session.MemberSession; import java.time.LocalDateTime; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/config/JpaAuditingConfig.java b/domain/src/main/java/com/parkingcomestrue/common/infra/config/JpaAuditingConfig.java similarity index 80% rename from domain/src/main/java/com/parkingcomestrue/parking/infra/config/JpaAuditingConfig.java rename to domain/src/main/java/com/parkingcomestrue/common/infra/config/JpaAuditingConfig.java index 33f22e2a..a87e4826 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/infra/config/JpaAuditingConfig.java +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/config/JpaAuditingConfig.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.infra.config; +package com.parkingcomestrue.common.infra.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ContentConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/ContentConverter.java similarity index 62% rename from domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ContentConverter.java rename to domain/src/main/java/com/parkingcomestrue/common/infra/converter/ContentConverter.java index 1591041e..5f5344c7 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ContentConverter.java +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/ContentConverter.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.infra.converter; +package com.parkingcomestrue.common.infra.converter; -import com.parkingcomestrue.parking.domain.review.Content; +import com.parkingcomestrue.common.domain.review.Content; import jakarta.persistence.Converter; @Converter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/EnumListConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/EnumListConverter.java similarity index 94% rename from domain/src/main/java/com/parkingcomestrue/parking/infra/converter/EnumListConverter.java rename to domain/src/main/java/com/parkingcomestrue/common/infra/converter/EnumListConverter.java index e83f2ecf..41aaba43 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/EnumListConverter.java +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/EnumListConverter.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.infra.converter; +package com.parkingcomestrue.common.infra.converter; import jakarta.persistence.AttributeConverter; import java.util.Arrays; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/FeeTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/FeeTypeConverter.java similarity index 60% rename from domain/src/main/java/com/parkingcomestrue/parking/infra/converter/FeeTypeConverter.java rename to domain/src/main/java/com/parkingcomestrue/common/infra/converter/FeeTypeConverter.java index 63779cd7..e8e6ca89 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/FeeTypeConverter.java +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/FeeTypeConverter.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.infra.converter; +package com.parkingcomestrue.common.infra.converter; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; import jakarta.persistence.Converter; @Converter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/OperationTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/OperationTypeConverter.java similarity index 63% rename from domain/src/main/java/com/parkingcomestrue/parking/infra/converter/OperationTypeConverter.java rename to domain/src/main/java/com/parkingcomestrue/common/infra/converter/OperationTypeConverter.java index 5d5c96cd..330edf91 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/OperationTypeConverter.java +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/OperationTypeConverter.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.infra.converter; +package com.parkingcomestrue.common.infra.converter; -import com.parkingcomestrue.parking.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.OperationType; import jakarta.persistence.Converter; @Converter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ParkingTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/ParkingTypeConverter.java similarity index 63% rename from domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ParkingTypeConverter.java rename to domain/src/main/java/com/parkingcomestrue/common/infra/converter/ParkingTypeConverter.java index ad62a0ac..35b5f741 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/ParkingTypeConverter.java +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/ParkingTypeConverter.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.infra.converter; +package com.parkingcomestrue.common.infra.converter; -import com.parkingcomestrue.parking.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.ParkingType; import jakarta.persistence.Converter; @Converter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/PayTypeConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/PayTypeConverter.java similarity index 62% rename from domain/src/main/java/com/parkingcomestrue/parking/infra/converter/PayTypeConverter.java rename to domain/src/main/java/com/parkingcomestrue/common/infra/converter/PayTypeConverter.java index 8c1e70ea..24950000 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/infra/converter/PayTypeConverter.java +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/PayTypeConverter.java @@ -1,6 +1,6 @@ -package com.parkingcomestrue.parking.infra.converter; +package com.parkingcomestrue.common.infra.converter; -import com.parkingcomestrue.parking.domain.parking.PayType; +import com.parkingcomestrue.common.domain.parking.PayType; import jakarta.persistence.Converter; @Converter diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/Association.java b/domain/src/main/java/com/parkingcomestrue/common/support/Association.java similarity index 92% rename from domain/src/main/java/com/parkingcomestrue/parking/support/Association.java rename to domain/src/main/java/com/parkingcomestrue/common/support/Association.java index 2fb8d3a2..2d80978a 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/support/Association.java +++ b/domain/src/main/java/com/parkingcomestrue/common/support/Association.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.support; +package com.parkingcomestrue.common.support; import jakarta.persistence.Embeddable; import lombok.AccessLevel; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java b/domain/src/main/java/com/parkingcomestrue/common/support/exception/DomainException.java similarity index 87% rename from domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java rename to domain/src/main/java/com/parkingcomestrue/common/support/exception/DomainException.java index 2d3b76c0..da5f7af9 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainException.java +++ b/domain/src/main/java/com/parkingcomestrue/common/support/exception/DomainException.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.support.exception; +package com.parkingcomestrue.common.support.exception; public class DomainException extends RuntimeException { diff --git a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainExceptionInformation.java b/domain/src/main/java/com/parkingcomestrue/common/support/exception/DomainExceptionInformation.java similarity index 94% rename from domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainExceptionInformation.java rename to domain/src/main/java/com/parkingcomestrue/common/support/exception/DomainExceptionInformation.java index 992db4e7..ce37f420 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/support/exception/DomainExceptionInformation.java +++ b/domain/src/main/java/com/parkingcomestrue/common/support/exception/DomainExceptionInformation.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.support.exception; +package com.parkingcomestrue.common.support.exception; import lombok.Getter; diff --git a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/EncryptionException.java b/domain/src/main/java/com/parkingcomestrue/common/util/cipher/EncryptionException.java similarity index 74% rename from domain/src/main/java/com/parkingcomestrue/parking/util/cipher/EncryptionException.java rename to domain/src/main/java/com/parkingcomestrue/common/util/cipher/EncryptionException.java index 491691f4..74b4d5f2 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/EncryptionException.java +++ b/domain/src/main/java/com/parkingcomestrue/common/util/cipher/EncryptionException.java @@ -1,4 +1,4 @@ -package com.parkingcomestrue.parking.util.cipher; +package com.parkingcomestrue.common.util.cipher; public class EncryptionException extends RuntimeException { diff --git a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java b/domain/src/main/java/com/parkingcomestrue/common/util/cipher/SHA256.java similarity index 77% rename from domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java rename to domain/src/main/java/com/parkingcomestrue/common/util/cipher/SHA256.java index 526146a1..d12928f1 100644 --- a/domain/src/main/java/com/parkingcomestrue/parking/util/cipher/SHA256.java +++ b/domain/src/main/java/com/parkingcomestrue/common/util/cipher/SHA256.java @@ -1,7 +1,7 @@ -package com.parkingcomestrue.parking.util.cipher; +package com.parkingcomestrue.common.util.cipher; -import com.parkingcomestrue.parking.support.exception.DomainException; -import com.parkingcomestrue.parking.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.common.support.exception.DomainException; +import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; import java.security.MessageDigest; public class SHA256 { diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepositoryTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/favorite/repository/FavoriteRepositoryTest.java similarity index 86% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepositoryTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/favorite/repository/FavoriteRepositoryTest.java index fccb6ccd..c9068814 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/favorite/repository/FavoriteRepositoryTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/favorite/repository/FavoriteRepositoryTest.java @@ -1,9 +1,10 @@ -package com.parkingcomestrue.parking.domain.favorite.repository; +package com.parkingcomestrue.common.domain.favorite.repository; import static org.assertj.core.api.Assertions.assertThat; -import com.parkingcomestrue.parking.domain.favorite.Favorite; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.favorite.Favorite; +import com.parkingcomestrue.common.domain.favorite.repository.FavoriteRepository; +import com.parkingcomestrue.common.support.Association; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/member/MemberTest.java similarity index 85% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/member/MemberTest.java index 6812cead..2dbec5f7 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/member/MemberTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/member/MemberTest.java @@ -1,8 +1,10 @@ -package com.parkingcomestrue.parking.domain.member; +package com.parkingcomestrue.common.domain.member; -import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_PASSWORD; +import static com.parkingcomestrue.common.support.exception.DomainExceptionInformation.INVALID_PASSWORD; -import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.member.Password; +import com.parkingcomestrue.common.support.exception.DomainException; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/BaseInformationTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/BaseInformationTest.java similarity index 68% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/BaseInformationTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/BaseInformationTest.java index a95d8fef..ac00ab36 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/BaseInformationTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/BaseInformationTest.java @@ -1,5 +1,7 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; +import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.domain.parking.PayTypes; import java.util.List; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/DayTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/DayTest.java similarity index 93% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/DayTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/DayTest.java index 7aac391b..1e5243f0 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/DayTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/DayTest.java @@ -1,5 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; +import com.parkingcomestrue.common.domain.parking.Day; import java.time.DayOfWeek; import java.util.stream.Stream; import org.assertj.core.api.Assertions; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeePolicyTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/FeePolicyTest.java similarity index 93% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeePolicyTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/FeePolicyTest.java index bb789e24..0cd738a5 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeePolicyTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/FeePolicyTest.java @@ -1,5 +1,8 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import java.util.stream.Stream; import org.assertj.core.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeeTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/FeeTest.java similarity index 87% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeeTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/FeeTest.java index 8e686059..d209a2d0 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FeeTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/FeeTest.java @@ -1,5 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; +import com.parkingcomestrue.common.domain.parking.Fee; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTimeTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/FreeOperatingTimeTest.java similarity index 96% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTimeTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/FreeOperatingTimeTest.java index 6b258404..6d34ed68 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/FreeOperatingTimeTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/FreeOperatingTimeTest.java @@ -1,5 +1,9 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; +import com.parkingcomestrue.common.domain.parking.Day; +import com.parkingcomestrue.common.domain.parking.DayParking; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.TimeInfo; import java.time.LocalTime; import java.util.stream.Stream; import org.assertj.core.api.Assertions; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/LocationTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/LocationTest.java similarity index 91% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/LocationTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/LocationTest.java index bc8e57cd..0bd85672 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/LocationTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/LocationTest.java @@ -1,8 +1,9 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import com.parkingcomestrue.common.domain.parking.Location; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculatorTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/ParkingFeeCalculatorTest.java similarity index 96% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculatorTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/ParkingFeeCalculatorTest.java index 494ed2ab..d0cd9544 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingFeeCalculatorTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/ParkingFeeCalculatorTest.java @@ -1,5 +1,16 @@ -package com.parkingcomestrue.parking.domain.parking; - +package com.parkingcomestrue.common.domain.parking; + +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingFeeCalculator; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeInfo; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.stream.Stream; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/ParkingTest.java similarity index 93% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/ParkingTest.java index 292a02cb..4e86762d 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/ParkingTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/ParkingTest.java @@ -1,5 +1,14 @@ -package com.parkingcomestrue.parking.domain.parking; - +package com.parkingcomestrue.common.domain.parking; + +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import java.util.stream.Stream; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/PayTypesTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/PayTypesTest.java similarity index 81% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/PayTypesTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/PayTypesTest.java index a1792d3a..a7522149 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/PayTypesTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/PayTypesTest.java @@ -1,12 +1,14 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; -import static com.parkingcomestrue.parking.domain.parking.PayType.BANK_TRANSFER; -import static com.parkingcomestrue.parking.domain.parking.PayType.CARD; -import static com.parkingcomestrue.parking.domain.parking.PayType.CASH; -import static com.parkingcomestrue.parking.domain.parking.PayType.NO_INFO; +import static com.parkingcomestrue.common.domain.parking.PayType.BANK_TRANSFER; +import static com.parkingcomestrue.common.domain.parking.PayType.CARD; +import static com.parkingcomestrue.common.domain.parking.PayType.CASH; +import static com.parkingcomestrue.common.domain.parking.PayType.NO_INFO; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.params.provider.Arguments.arguments; +import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.domain.parking.PayTypes; import java.util.Collection; import java.util.List; import java.util.Set; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeInfoTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/TimeInfoTest.java similarity index 98% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeInfoTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/TimeInfoTest.java index 23f5e08d..ffaefbe0 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeInfoTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/TimeInfoTest.java @@ -1,5 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; +import com.parkingcomestrue.common.domain.parking.TimeInfo; import java.time.LocalTime; import java.util.stream.Stream; import org.assertj.core.api.Assertions; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeUnitTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/TimeUnitTest.java similarity index 89% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeUnitTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/TimeUnitTest.java index 0458e8ba..f6a22cfa 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/TimeUnitTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/TimeUnitTest.java @@ -1,5 +1,6 @@ -package com.parkingcomestrue.parking.domain.parking; +package com.parkingcomestrue.common.domain.parking; +import com.parkingcomestrue.common.domain.parking.TimeUnit; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringServiceTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringServiceTest.java similarity index 85% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringServiceTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringServiceTest.java index cffb5014..91857ef5 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/parking/service/ParkingFilteringServiceTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringServiceTest.java @@ -1,20 +1,21 @@ -package com.parkingcomestrue.parking.domain.parking.service; +package com.parkingcomestrue.common.domain.parking.service; import static org.assertj.core.api.Assertions.assertThat; -import com.parkingcomestrue.parking.domain.parking.BaseInformation; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.FeePolicy; -import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingFeeCalculator; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; -import com.parkingcomestrue.parking.domain.parking.SearchingCondition; -import com.parkingcomestrue.parking.domain.parking.TimeUnit; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingFeeCalculator; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.SearchingCondition; +import com.parkingcomestrue.common.domain.parking.TimeUnit; +import com.parkingcomestrue.common.domain.parking.service.ParkingFilteringService; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; import java.time.LocalDateTime; import java.util.List; import org.assertj.core.api.Assertions; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/review/ContentTest.java similarity index 81% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/review/ContentTest.java index 0f5eea80..974fae28 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/ContentTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/review/ContentTest.java @@ -1,11 +1,12 @@ -package com.parkingcomestrue.parking.domain.review; +package com.parkingcomestrue.common.domain.review; -import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_CONTENT; +import static com.parkingcomestrue.common.support.exception.DomainExceptionInformation.INVALID_CONTENT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.params.provider.Arguments.arguments; -import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.common.domain.review.Content; +import com.parkingcomestrue.common.support.exception.DomainException; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/review/service/ReviewDomainServiceTest.java similarity index 84% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/review/service/ReviewDomainServiceTest.java index 081bd371..6dcb9369 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/review/service/ReviewDomainServiceTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/review/service/ReviewDomainServiceTest.java @@ -1,16 +1,17 @@ -package com.parkingcomestrue.parking.domain.review.service; +package com.parkingcomestrue.common.domain.review.service; -import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.DUPLICATE_REVIEW; +import static com.parkingcomestrue.common.support.exception.DomainExceptionInformation.DUPLICATE_REVIEW; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.review.Content; -import com.parkingcomestrue.parking.domain.review.Review; -import com.parkingcomestrue.parking.support.Association; -import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.review.Content; +import com.parkingcomestrue.common.domain.review.Review; +import com.parkingcomestrue.common.domain.review.service.ReviewDomainService; +import com.parkingcomestrue.common.support.Association; +import com.parkingcomestrue.common.support.exception.DomainException; import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/searchcondition/HoursTest.java similarity index 72% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/searchcondition/HoursTest.java index 3623283a..2544a5d1 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/searchcondition/HoursTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/searchcondition/HoursTest.java @@ -1,9 +1,10 @@ -package com.parkingcomestrue.parking.domain.searchcondition; +package com.parkingcomestrue.common.domain.searchcondition; -import static com.parkingcomestrue.parking.support.exception.DomainExceptionInformation.INVALID_HOURS; +import static com.parkingcomestrue.common.support.exception.DomainExceptionInformation.INVALID_HOURS; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import com.parkingcomestrue.parking.support.exception.DomainException; +import com.parkingcomestrue.common.domain.searchcondition.Hours; +import com.parkingcomestrue.common.support.exception.DomainException; import org.assertj.core.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepositoryTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/session/repository/MemberSessionRepositoryTest.java similarity index 88% rename from domain/src/test/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepositoryTest.java rename to domain/src/test/java/com/parkingcomestrue/common/domain/session/repository/MemberSessionRepositoryTest.java index 0f811176..0f05710d 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/domain/session/repository/MemberSessionRepositoryTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/session/repository/MemberSessionRepositoryTest.java @@ -1,8 +1,9 @@ -package com.parkingcomestrue.parking.domain.session.repository; +package com.parkingcomestrue.common.domain.session.repository; import static org.assertj.core.api.Assertions.assertThat; -import com.parkingcomestrue.parking.domain.session.MemberSession; +import com.parkingcomestrue.common.domain.session.MemberSession; +import com.parkingcomestrue.common.domain.session.repository.MemberSessionRepository; import java.time.LocalDateTime; import java.util.UUID; import org.junit.jupiter.api.Test; diff --git a/domain/src/test/java/com/parkingcomestrue/parking/infra/converter/EnumListConverterTest.java b/domain/src/test/java/com/parkingcomestrue/common/infra/converter/EnumListConverterTest.java similarity index 85% rename from domain/src/test/java/com/parkingcomestrue/parking/infra/converter/EnumListConverterTest.java rename to domain/src/test/java/com/parkingcomestrue/common/infra/converter/EnumListConverterTest.java index 2c99f28e..58f5ec86 100644 --- a/domain/src/test/java/com/parkingcomestrue/parking/infra/converter/EnumListConverterTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/infra/converter/EnumListConverterTest.java @@ -1,8 +1,9 @@ -package com.parkingcomestrue.parking.infra.converter; +package com.parkingcomestrue.common.infra.converter; import static org.assertj.core.api.Assertions.assertThat; -import com.parkingcomestrue.parking.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.domain.searchcondition.FeeType; +import com.parkingcomestrue.common.infra.converter.FeeTypeConverter; import java.util.List; import java.util.stream.Collectors; import org.junit.jupiter.api.DisplayName; diff --git a/domain/src/testFixtures/java/repository/BasicMemberRepository.java b/domain/src/testFixtures/java/repository/BasicMemberRepository.java index 4075cb4b..ec75a8f9 100644 --- a/domain/src/testFixtures/java/repository/BasicMemberRepository.java +++ b/domain/src/testFixtures/java/repository/BasicMemberRepository.java @@ -1,8 +1,8 @@ package repository; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.member.Password; -import com.parkingcomestrue.parking.domain.member.repository.MemberRepository; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.member.Password; +import com.parkingcomestrue.common.domain.member.repository.MemberRepository; import java.util.HashMap; import java.util.LinkedList; import java.util.List; diff --git a/domain/src/testFixtures/java/repository/BasicParkingRepository.java b/domain/src/testFixtures/java/repository/BasicParkingRepository.java index 42d84a55..f4b0dd52 100644 --- a/domain/src/testFixtures/java/repository/BasicParkingRepository.java +++ b/domain/src/testFixtures/java/repository/BasicParkingRepository.java @@ -1,18 +1,18 @@ package repository; -import com.parkingcomestrue.parking.domain.parking.BaseInformation; -import com.parkingcomestrue.parking.domain.parking.Fee; -import com.parkingcomestrue.parking.domain.parking.FeePolicy; -import com.parkingcomestrue.parking.domain.parking.FreeOperatingTime; -import com.parkingcomestrue.parking.domain.parking.Location; -import com.parkingcomestrue.parking.domain.parking.OperatingTime; -import com.parkingcomestrue.parking.domain.parking.OperationType; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.domain.parking.ParkingType; -import com.parkingcomestrue.parking.domain.parking.PayTypes; -import com.parkingcomestrue.parking.domain.parking.Space; -import com.parkingcomestrue.parking.domain.parking.TimeUnit; -import com.parkingcomestrue.parking.domain.parking.repository.ParkingRepository; +import com.parkingcomestrue.common.domain.parking.BaseInformation; +import com.parkingcomestrue.common.domain.parking.Fee; +import com.parkingcomestrue.common.domain.parking.FeePolicy; +import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; +import com.parkingcomestrue.common.domain.parking.Location; +import com.parkingcomestrue.common.domain.parking.OperatingTime; +import com.parkingcomestrue.common.domain.parking.OperationType; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.domain.parking.ParkingType; +import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.Space; +import com.parkingcomestrue.common.domain.parking.TimeUnit; +import com.parkingcomestrue.common.domain.parking.repository.ParkingRepository; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; diff --git a/domain/src/testFixtures/java/repository/BasicReviewRepository.java b/domain/src/testFixtures/java/repository/BasicReviewRepository.java index a471b734..a16ac3d4 100644 --- a/domain/src/testFixtures/java/repository/BasicReviewRepository.java +++ b/domain/src/testFixtures/java/repository/BasicReviewRepository.java @@ -1,8 +1,8 @@ package repository; -import com.parkingcomestrue.parking.domain.review.Review; -import com.parkingcomestrue.parking.domain.review.repository.ReviewRepository; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.review.Review; +import com.parkingcomestrue.common.domain.review.repository.ReviewRepository; +import com.parkingcomestrue.common.support.Association; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/domain/src/testFixtures/java/repository/FakeFavoriteRepository.java b/domain/src/testFixtures/java/repository/FakeFavoriteRepository.java index 88bda8a8..f35aee23 100644 --- a/domain/src/testFixtures/java/repository/FakeFavoriteRepository.java +++ b/domain/src/testFixtures/java/repository/FakeFavoriteRepository.java @@ -1,10 +1,10 @@ package repository; -import com.parkingcomestrue.parking.domain.favorite.Favorite; -import com.parkingcomestrue.parking.domain.favorite.repository.FavoriteRepository; -import com.parkingcomestrue.parking.domain.member.Member; -import com.parkingcomestrue.parking.domain.parking.Parking; -import com.parkingcomestrue.parking.support.Association; +import com.parkingcomestrue.common.domain.favorite.Favorite; +import com.parkingcomestrue.common.domain.favorite.repository.FavoriteRepository; +import com.parkingcomestrue.common.domain.member.Member; +import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.support.Association; import java.util.List; public class FakeFavoriteRepository implements FavoriteRepository { diff --git a/domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java b/domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java index c73ca343..49ba4552 100644 --- a/domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java +++ b/domain/src/testFixtures/java/repository/FakeSearchConditionRepository.java @@ -1,7 +1,7 @@ package repository; -import com.parkingcomestrue.parking.domain.searchcondition.SearchCondition; -import com.parkingcomestrue.parking.domain.searchcondition.repository.SearchConditionRepository; +import com.parkingcomestrue.common.domain.searchcondition.SearchCondition; +import com.parkingcomestrue.common.domain.searchcondition.repository.SearchConditionRepository; import java.util.Optional; public class FakeSearchConditionRepository implements SearchConditionRepository { From 4a2d3da010ebba9409c05913b9644b6cb1e3ebb6 Mon Sep 17 00:00:00 2001 From: This2sho Date: Sat, 13 Apr 2024 05:06:23 +0900 Subject: [PATCH 19/19] =?UTF-8?q?refactor:=20CD=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ".github/workflows/\bdeploy.yml" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/.github/workflows/\bdeploy.yml" "b/.github/workflows/\bdeploy.yml" index dba1fd28..4be313b1 100644 --- "a/.github/workflows/\bdeploy.yml" +++ "b/.github/workflows/\bdeploy.yml" @@ -89,7 +89,7 @@ jobs: context: . file: app-api/Dockerfile push: true - tags: ${{ secrets.DOCKERHUB_USERNAME }}/pct-api:${{ github.sha }} + tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.API_IMAGE }}:${{ github.sha }} platforms: linux/amd64 - name: 도커 이미지 build 후 push @@ -101,7 +101,7 @@ jobs: context: . file: app-scheduler/Dockerfile push: true - tags: ${{ secrets.DOCKERHUB_USERNAME }}/pct-scheduler:${{ github.sha }} + tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.SCHEDULER_IMAGE }}:${{ github.sha }} platforms: linux/amd64 deploy-to-ec2: