diff --git a/build.gradle b/build.gradle index 3d1c41b..c54d8af 100644 --- a/build.gradle +++ b/build.gradle @@ -39,27 +39,6 @@ subprojects { } dependencies { - // Spring Boot 기본 스타터 패키지 - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // 데이터베이스와 상호작용 (JPA 사용) - implementation 'org.springframework.boot:spring-boot-starter-validation' // 요청 데이터 검증 - implementation 'org.springframework.boot:spring-boot-starter-web' // RESTful API 및 웹 애플리케이션 개발 - implementation 'org.springframework.boot:spring-boot-starter-aop' - - // Querydsl 관련 의존성 (타입 안전한 쿼리 작성) - implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' // Querydsl JPA 지원 - annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' // Querydsl Q클래스 생성 - annotationProcessor 'jakarta.persistence:jakarta.persistence-api' - // 데이터베이스 연결 - runtimeOnly 'org.postgresql:postgresql' // PostgreSQL 드라이버 - - // 지리 데이터 관리 도구 - implementation 'org.locationtech.jts:jts-core:1.20.0' - implementation 'org.hibernate:hibernate-spatial:6.6.4.Final' - - //swagger - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.1' - // 개발 도구 및 반복 코드 감소 compileOnly 'org.projectlombok:lombok' // Lombok으로 반복 코드 제거 (Getter, Setter 등) annotationProcessor 'org.projectlombok:lombok' // Lombok 애노테이션 프로세서 diff --git a/soridam-api/build.gradle b/soridam-api/build.gradle index b0fd44c..e99221d 100644 --- a/soridam-api/build.gradle +++ b/soridam-api/build.gradle @@ -12,4 +12,16 @@ dependencies { implementation project(':soridam-auth') implementation project(':soridam-infra') implementation project(':soridam-global-util') + + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.1' + + //지리 데이터 + implementation 'org.locationtech.jts:jts-core:1.20.0' + + //spring security + implementation 'org.springframework.boot:spring-boot-starter-security' + + // 데이터베이스와 상호작용 (JPA 사용) + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' } \ No newline at end of file diff --git a/soridam-api/src/main/java/sorisoop/soridam/api/noise/application/NoiseService.java b/soridam-api/src/main/java/sorisoop/soridam/api/noise/application/NoiseService.java index 7d1d427..28724ee 100644 --- a/soridam-api/src/main/java/sorisoop/soridam/api/noise/application/NoiseService.java +++ b/soridam-api/src/main/java/sorisoop/soridam/api/noise/application/NoiseService.java @@ -12,6 +12,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import lombok.RequiredArgsConstructor; import sorisoop.soridam.api.noise.presentation.exception.NoiseNotFoundException; import sorisoop.soridam.api.noise.presentation.request.NoiseCreateRequest; import sorisoop.soridam.api.noise.presentation.request.NoiseSearchListRequest; @@ -22,28 +23,24 @@ import sorisoop.soridam.api.noise.presentation.response.NoiseReviewResponse; import sorisoop.soridam.api.noise.presentation.response.NoiseSummaryResponse; import sorisoop.soridam.api.user.application.UserService; -import sorisoop.soridam.globalutil.geometry.GeometryUtils; import sorisoop.soridam.domain.noise.domain.Noise; import sorisoop.soridam.domain.noise.domain.NoiseLevel; +import sorisoop.soridam.domain.noise.domain.NoiseRepository; import sorisoop.soridam.domain.noise.domain.Radius; -import sorisoop.soridam.domain.noise.infrastructure.JpaNoiseRepository; -import sorisoop.soridam.domain.noise.infrastructure.QueryNoiseRepository; import sorisoop.soridam.domain.user.domain.User; - -import lombok.RequiredArgsConstructor; +import sorisoop.soridam.globalutil.geometry.GeometryUtils; @Service @RequiredArgsConstructor public class NoiseService { - private final JpaNoiseRepository jpaNoiseRepository; - private final QueryNoiseRepository queryNoiseRepository; + private final NoiseRepository noiseRepository; private final GeometryUtils geometryUtils; private final UserService userService; @Transactional(readOnly = true) public Optional getDetailNoise(double x, double y) { Point point = createPoint(x, y); - List results = queryNoiseRepository.getNearbyNoises(point); + List results = noiseRepository.getNearbyNoises(point); if (results.isEmpty()) return Optional.empty(); @@ -63,7 +60,7 @@ public Optional getNearbyNoise(NoiseSearchListRequest request List responses = requests.noiseSearchRequests().stream() .map(request -> { Point point = createPoint(request.x(), request.y()); - List results = queryNoiseRepository.findByAvgDecibleAndPoint(point, radius, noiseLevel); + List results = noiseRepository.findByAvgDecibleAndPoint(point, radius, noiseLevel); if (results.isEmpty()) return null; @@ -86,7 +83,7 @@ public Optional getNearbyNoise(NoiseSearchListRequest request @Transactional(readOnly = true) public NoiseSummaryResponse getNoise(String id) { - Noise noise = jpaNoiseRepository.findById(NOISE.getPrefix() + id) + Noise noise = noiseRepository.findById(NOISE.getPrefix() + id) .orElseThrow(NoiseNotFoundException::new); return NoiseSummaryResponse.from(noise); } @@ -104,16 +101,16 @@ public NoisePersistResponse createNoise(NoiseCreateRequest request) { request.review() ); - jpaNoiseRepository.save(noise); + noiseRepository.save(noise); return NoisePersistResponse.from(noise); } @Transactional public void deleteNoise(String id) { - if (!jpaNoiseRepository.existsById(id)) { + if (!noiseRepository.existsById(id)) { throw new NoiseNotFoundException(); } - jpaNoiseRepository.deleteById(id); + noiseRepository.deleteById(id); } private Point createPoint(double x, double y) { diff --git a/soridam-auth/build.gradle b/soridam-auth/build.gradle index 4d6b319..ea85f4e 100644 --- a/soridam-auth/build.gradle +++ b/soridam-auth/build.gradle @@ -9,8 +9,8 @@ jar { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - // OAuth 및 외부 API 호출 - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' // OAuth2 클라이언트 + // OAuth + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' // 도메인 및 공통 모듈 implementation project(':soridam-common') @@ -19,4 +19,7 @@ dependencies { implementation 'io.jsonwebtoken:jjwt-api:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' + + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.1' } diff --git a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/CustomOidcUserService.java b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/CustomOidcUserService.java index 8e9f7d4..0067eeb 100644 --- a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/CustomOidcUserService.java +++ b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/CustomOidcUserService.java @@ -8,20 +8,18 @@ import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import sorisoop.soridam.common.domain.Provider; import sorisoop.soridam.domain.user.domain.User; -import sorisoop.soridam.domain.user.infrastructure.JpaUserRepository; +import sorisoop.soridam.domain.user.domain.UserRepository; @Service @RequiredArgsConstructor public class CustomOidcUserService extends OidcUserService { - private final JpaUserRepository jpaUserRepository; + private final UserRepository userRepository; @Override - @Transactional public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { OidcUser oidcUser = super.loadUser(userRequest); OidcIdToken idToken = oidcUser.getIdToken(); @@ -38,7 +36,7 @@ public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2Authenticatio private User getUserAndUpdateIfNeeded(Provider provider, Map attributes) { String oAuthIdentity = attributes.get("sub").toString(); - return jpaUserRepository.findByOauthIdentityAndProvider(oAuthIdentity, provider) + return userRepository.findByOauthIdentityAndProvider(oAuthIdentity, provider) .map(existingUser -> { updateUserInfo(existingUser, attributes); return existingUser; @@ -46,7 +44,7 @@ private User getUserAndUpdateIfNeeded(Provider provider, Map att .orElseGet(() -> { User newUser = OicdUserFactory.getOAuth2UserInfo(provider, attributes); newUser.updateLastLoginTime(); - return jpaUserRepository.save(newUser); + return userRepository.save(newUser); }); } diff --git a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/OidcService.java b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/OidcService.java index 2080b23..5ecafc8 100644 --- a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/OidcService.java +++ b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/OidcService.java @@ -16,11 +16,11 @@ import sorisoop.soridam.auth.oauth.request.OidcLoginRequest; import sorisoop.soridam.common.domain.Provider; import sorisoop.soridam.domain.user.domain.User; -import sorisoop.soridam.domain.user.infrastructure.JpaUserRepository; +import sorisoop.soridam.domain.user.domain.UserRepository; @RequiredArgsConstructor public abstract class OidcService { - private final JpaUserRepository jpaUserRepository; + private final UserRepository userRepository; protected abstract String getIssuer(); protected abstract String getJwkSetUri(); @@ -74,15 +74,15 @@ private OidcIdToken getOidcIdToken(Jwt jwt) { protected User findOrCreateUser(OidcIdToken idToken) { String identifier = idToken.getSubject(); - return jpaUserRepository.findByOauthIdentityAndProvider(identifier, getProvider()) + return userRepository.findByOauthIdentityAndProvider(identifier, getProvider()) .map(existingUser -> { existingUser.updateLastLoginTime(); - return jpaUserRepository.save(existingUser); + return userRepository.save(existingUser); }) .orElseGet(() -> { User newUser = createNewUser(identifier, new OidcUserInfo(idToken.getClaims())); newUser.updateLastLoginTime(); - return jpaUserRepository.save(newUser); + return userRepository.save(newUser); }); } } diff --git a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/google/GoogleOidcService.java b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/google/GoogleOidcService.java index 05564ae..30c0b79 100644 --- a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/google/GoogleOidcService.java +++ b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/google/GoogleOidcService.java @@ -8,14 +8,14 @@ import sorisoop.soridam.auth.oauth.OidcService; import sorisoop.soridam.common.domain.Provider; import sorisoop.soridam.domain.user.domain.User; -import sorisoop.soridam.domain.user.infrastructure.JpaUserRepository; +import sorisoop.soridam.domain.user.domain.UserRepository; @Service public class GoogleOidcService extends OidcService { private final GoogleOidcProperties properties; - public GoogleOidcService(JpaUserRepository jpaUserRepository, GoogleOidcProperties properties) { - super(jpaUserRepository); + public GoogleOidcService(UserRepository userRepository, GoogleOidcProperties properties) { + super(userRepository); this.properties = properties; } diff --git a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/kakao/KakaoOidcService.java b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/kakao/KakaoOidcService.java index 91011d2..f15180a 100644 --- a/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/kakao/KakaoOidcService.java +++ b/soridam-auth/src/main/java/sorisoop/soridam/auth/oauth/kakao/KakaoOidcService.java @@ -8,14 +8,14 @@ import sorisoop.soridam.auth.oauth.OidcService; import sorisoop.soridam.common.domain.Provider; import sorisoop.soridam.domain.user.domain.User; -import sorisoop.soridam.domain.user.infrastructure.JpaUserRepository; +import sorisoop.soridam.domain.user.domain.UserRepository; @Service public class KakaoOidcService extends OidcService { private final KakaoOidcProperties properties; - public KakaoOidcService(JpaUserRepository jpaUserRepository, KakaoOidcProperties properties) { - super(jpaUserRepository); + public KakaoOidcService(UserRepository userRepository, KakaoOidcProperties properties) { + super(userRepository); this.properties = properties; } diff --git a/soridam-common/build.gradle b/soridam-common/build.gradle index 4b7f5de..c2607e2 100644 --- a/soridam-common/build.gradle +++ b/soridam-common/build.gradle @@ -9,4 +9,18 @@ jar { dependencies { implementation project(':soridam-infra') implementation project(':soridam-global-util') + + // Querydsl 관련 의존성 (타입 안전한 쿼리 작성) + implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' // Querydsl JPA 지원 + annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' // Querydsl Q클래스 생성 + annotationProcessor 'jakarta.persistence:jakarta.persistence-api' + + // 데이터베이스와 상호작용 (JPA 사용) + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + // 요청 데이터 검증 + implementation 'org.springframework.boot:spring-boot-starter-validation' + + // RESTful API + implementation 'org.springframework.boot:spring-boot-starter-web' } \ No newline at end of file diff --git a/soridam-domain/build.gradle b/soridam-domain/build.gradle index e3d0d7e..5cf9743 100644 --- a/soridam-domain/build.gradle +++ b/soridam-domain/build.gradle @@ -10,4 +10,22 @@ dependencies { implementation project(':soridam-global-util') implementation project(':soridam-common') implementation project(':soridam-infra') + + // 지리 데이터 관리 도구 + implementation 'org.locationtech.jts:jts-core:1.20.0' + implementation 'org.hibernate:hibernate-spatial:6.6.4.Final' + + // Querydsl 관련 의존성 (타입 안전한 쿼리 작성) + implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' // Querydsl JPA 지원 + annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' // Querydsl Q클래스 생성 + annotationProcessor 'jakarta.persistence:jakarta.persistence-api' + + // 데이터베이스 연결 + runtimeOnly 'org.postgresql:postgresql' // PostgreSQL 드라이버 + + //spring security + implementation 'org.springframework.boot:spring-boot-starter-security' + + // 데이터베이스와 상호작용 (JPA 사용) + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' } diff --git a/soridam-domain/src/main/java/sorisoop/soridam/domain/noise/domain/NoiseRepository.java b/soridam-domain/src/main/java/sorisoop/soridam/domain/noise/domain/NoiseRepository.java new file mode 100644 index 0000000..c502e8a --- /dev/null +++ b/soridam-domain/src/main/java/sorisoop/soridam/domain/noise/domain/NoiseRepository.java @@ -0,0 +1,20 @@ +package sorisoop.soridam.domain.noise.domain; + +import java.util.List; +import java.util.Optional; + +import org.locationtech.jts.geom.Point; + +public interface NoiseRepository { + List getNearbyNoises(Point point); + + List findByAvgDecibleAndPoint(Point point, Radius radius, NoiseLevel noiseLevel); + + Optional findById(String id); + + Noise save(Noise noise); + + boolean existsById(String id); + + void deleteById(String id); +} diff --git a/soridam-domain/src/main/java/sorisoop/soridam/domain/noise/infrastructure/NoiseRepositoryImpl.java b/soridam-domain/src/main/java/sorisoop/soridam/domain/noise/infrastructure/NoiseRepositoryImpl.java new file mode 100644 index 0000000..d3a3ec8 --- /dev/null +++ b/soridam-domain/src/main/java/sorisoop/soridam/domain/noise/infrastructure/NoiseRepositoryImpl.java @@ -0,0 +1,50 @@ +package sorisoop.soridam.domain.noise.infrastructure; + +import java.util.List; +import java.util.Optional; + +import org.locationtech.jts.geom.Point; +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import sorisoop.soridam.domain.noise.domain.Noise; +import sorisoop.soridam.domain.noise.domain.NoiseLevel; +import sorisoop.soridam.domain.noise.domain.NoiseRepository; +import sorisoop.soridam.domain.noise.domain.Radius; + +@Repository +@RequiredArgsConstructor +public class NoiseRepositoryImpl implements NoiseRepository { + private final JpaNoiseRepository jpaNoiseRepository; + private final QueryNoiseRepository queryNoiseRepository; + + @Override + public List getNearbyNoises(Point point) { + return queryNoiseRepository.getNearbyNoises(point); + } + + @Override + public List findByAvgDecibleAndPoint(Point point, Radius radius, NoiseLevel noiseLevel) { + return queryNoiseRepository.findByAvgDecibleAndPoint(point, radius, noiseLevel); + } + + @Override + public Optional findById(String id) { + return jpaNoiseRepository.findById(id); + } + + @Override + public Noise save(Noise noise) { + return jpaNoiseRepository.save(noise); + } + + @Override + public boolean existsById(String id) { + return jpaNoiseRepository.existsById(id); + } + + @Override + public void deleteById(String id) { + jpaNoiseRepository.deleteById(id); + } +} diff --git a/soridam-domain/src/main/java/sorisoop/soridam/domain/user/domain/UserRepository.java b/soridam-domain/src/main/java/sorisoop/soridam/domain/user/domain/UserRepository.java new file mode 100644 index 0000000..06797cf --- /dev/null +++ b/soridam-domain/src/main/java/sorisoop/soridam/domain/user/domain/UserRepository.java @@ -0,0 +1,13 @@ +package sorisoop.soridam.domain.user.domain; + +import java.util.Optional; + +import sorisoop.soridam.common.domain.Provider; + +public interface UserRepository { + User save(User user); + + Optional findByEmail(String email); + + Optional findByOauthIdentityAndProvider(String oauthIdentifier, Provider provider); +} diff --git a/soridam-domain/src/main/java/sorisoop/soridam/domain/user/infrastructure/UserRepositoryImpl.java b/soridam-domain/src/main/java/sorisoop/soridam/domain/user/infrastructure/UserRepositoryImpl.java new file mode 100644 index 0000000..73a294b --- /dev/null +++ b/soridam-domain/src/main/java/sorisoop/soridam/domain/user/infrastructure/UserRepositoryImpl.java @@ -0,0 +1,31 @@ +package sorisoop.soridam.domain.user.infrastructure; + +import java.util.Optional; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import sorisoop.soridam.common.domain.Provider; +import sorisoop.soridam.domain.user.domain.User; +import sorisoop.soridam.domain.user.domain.UserRepository; + +@Repository +@RequiredArgsConstructor +public class UserRepositoryImpl implements UserRepository { + private final JpaUserRepository jpaUserRepository; + + @Override + public User save(User user) { + return jpaUserRepository.save(user); + } + + @Override + public Optional findByEmail(String email) { + return jpaUserRepository.findByEmail(email); + } + + @Override + public Optional findByOauthIdentityAndProvider(String oauthIdentifier, Provider provider) { + return jpaUserRepository.findByOauthIdentityAndProvider(oauthIdentifier, provider); + } +} diff --git a/soridam-global-util/build.gradle b/soridam-global-util/build.gradle index b97e334..7a75ded 100644 --- a/soridam-global-util/build.gradle +++ b/soridam-global-util/build.gradle @@ -5,3 +5,17 @@ bootJar { jar { enabled = true } + +dependencies { + // 지리 데이터 관리 도구 + implementation 'org.locationtech.jts:jts-core:1.20.0' + + //spring security + implementation 'org.springframework.boot:spring-boot-starter-security' + + // 데이터베이스와 상호작용 (JPA 사용) + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + // RESTful API + implementation 'org.springframework.boot:spring-boot-starter-web' +} \ No newline at end of file diff --git a/soridam-infra/build.gradle b/soridam-infra/build.gradle index 2fafc2e..8f3ce94 100644 --- a/soridam-infra/build.gradle +++ b/soridam-infra/build.gradle @@ -8,4 +8,16 @@ jar { dependencies { implementation 'org.apache.commons:commons-collections4:4.4' + + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.1' + + // Querydsl 관련 의존성 (타입 안전한 쿼리 작성) + implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' + + //spring security + implementation 'org.springframework.boot:spring-boot-starter-security' + + // 데이터베이스와 상호작용 (JPA 사용) + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' } \ No newline at end of file diff --git a/soridam-infra/src/main/java/sorisoop/soridam/infra/config/jpa/JpaConfig.java b/soridam-infra/src/main/java/sorisoop/soridam/infra/config/jpa/JpaConfig.java index f76515d..fea3dce 100644 --- a/soridam-infra/src/main/java/sorisoop/soridam/infra/config/jpa/JpaConfig.java +++ b/soridam-infra/src/main/java/sorisoop/soridam/infra/config/jpa/JpaConfig.java @@ -1,6 +1,5 @@ package sorisoop.soridam.infra.config.jpa; -import org.locationtech.jts.geom.GeometryFactory; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -25,9 +24,4 @@ public JpaConfig(EntityManager entityManager) { public JPAQueryFactory jpaQueryFactory() { return new JPAQueryFactory(entityManager); } - - @Bean - public GeometryFactory geometryFactory() { - return new GeometryFactory(); - } }