From 05c6550bdefe0ef5ac3353d5df76a0643a2b0aee Mon Sep 17 00:00:00 2001 From: HUIJAEKO Date: Tue, 3 Mar 2026 15:33:48 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=95=88=EC=A0=84=20=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=EA=B3=84=EC=82=B0=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/KaKaoWebClientConfig.java | 5 +- .../openAI/SafetyExplanationService.java | 35 ----- .../repository/HomeSafetyRepository.java | 126 +++++++----------- 3 files changed, 53 insertions(+), 113 deletions(-) diff --git a/src/main/java/com/example/Dingle/global/config/KaKaoWebClientConfig.java b/src/main/java/com/example/Dingle/global/config/KaKaoWebClientConfig.java index 508947e..52cb8a1 100644 --- a/src/main/java/com/example/Dingle/global/config/KaKaoWebClientConfig.java +++ b/src/main/java/com/example/Dingle/global/config/KaKaoWebClientConfig.java @@ -10,10 +10,11 @@ @Configuration public class KaKaoWebClientConfig { +// @Value("${kakao.base-url}") String baseUrl @Bean - public WebClient kaKaoWebClient(@Value("${kakao.base-url}") String baseUrl, @Value("${kakao.api-key}") String apiKey) { + public WebClient kaKaoWebClient(@Value("${kakao.api-key}") String apiKey) { return WebClient.builder() - .baseUrl(baseUrl) +// .baseUrl(baseUrl) .defaultHeader(HttpHeaders.AUTHORIZATION, "KakaoAK " + apiKey) .build(); } diff --git a/src/main/java/com/example/Dingle/property/service/openAI/SafetyExplanationService.java b/src/main/java/com/example/Dingle/property/service/openAI/SafetyExplanationService.java index 842565b..04448cb 100644 --- a/src/main/java/com/example/Dingle/property/service/openAI/SafetyExplanationService.java +++ b/src/main/java/com/example/Dingle/property/service/openAI/SafetyExplanationService.java @@ -2,10 +2,8 @@ import com.example.Dingle.global.exception.BusinessException; import com.example.Dingle.global.message.BusinessErrorMessage; -import com.example.Dingle.property.dto.openAI.SafetyEvaluationResult; import com.example.Dingle.property.dto.openAI.SafetyExplanationPrompt; import com.example.Dingle.property.entity.Property; -import com.example.Dingle.property.entity.PropertyDescription; import com.example.Dingle.property.entity.PropertyScore; import com.example.Dingle.property.repository.PropertyDescriptionRepository; import com.example.Dingle.property.repository.PropertyRepository; @@ -102,38 +100,5 @@ public void evaluateAndDescribe(Long propertyId) { .orElseThrow(() -> new BusinessException(BusinessErrorMessage.PROPERTY_SCORE_NOT_FOUND)); score.updateSafetyScore(finalSafetyScore); - - // AI 요약 - SafetyEvaluationResult result = SafetyEvaluationResult.builder() - .safetyScore(finalSafetyScore) - .home(SafetyEvaluationResult.Home.builder() - .crimeScore(crimeScoreHome) - .policeScore(policeScore) - .infraScore(infraScoreHome) - .score(homeSafetyScore) - .build()) - .path(SafetyEvaluationResult.Path.builder() - .crimeCount(crimeCount) - .cctvCount(cctvCount) - .safetyLightCount(lightCount) - .score(pathSafetyScore) - .build()) - .build(); - - String json; - try { - json = objectMapper.writeValueAsString(result); - } catch (Exception e) { - throw new RuntimeException("SafetyEvaluationResult serialization failed", e); - } - - String explanation = openAiClient.generate( - prompt.build(result, json) - ); - - PropertyDescription description = propertyDescriptionRepository.findByPropertyId(propertyId) - .orElseThrow(() -> new BusinessException(BusinessErrorMessage.PROPERTY_EXPLANATION_NOT_EXISTS)); - - description.updateSafetyDescription(explanation); } } diff --git a/src/main/java/com/example/Dingle/safety/repository/HomeSafetyRepository.java b/src/main/java/com/example/Dingle/safety/repository/HomeSafetyRepository.java index 323ada4..027cd65 100644 --- a/src/main/java/com/example/Dingle/safety/repository/HomeSafetyRepository.java +++ b/src/main/java/com/example/Dingle/safety/repository/HomeSafetyRepository.java @@ -12,18 +12,15 @@ public class HomeSafetyRepository { // 범죄주의구역 내부 최대 리스크 레벨 public int findInsideMaxRiskLevel(double lat, double lon) { - String sql = """ - SELECT COALESCE(MAX(c.risk_level), 0) - FROM crime_prone_area c - WHERE ST_Contains( - c.geometry, - ST_Transform( - ST_SetSRID(ST_MakePoint(?1, ?2), 4326), - 5179 - ) - ) - """; + WITH target AS ( + SELECT ST_Transform(ST_SetSRID(ST_MakePoint(?1, ?2), 4326), 5179) AS g + ) + SELECT COALESCE(MAX(c.risk_level), 0) + FROM crime_prone_area c, target + WHERE c.geometry && target.g + AND ST_Contains(c.geometry, target.g) + """; return ((Number) em.createNativeQuery(sql) .setParameter(1, lon) @@ -34,21 +31,17 @@ WHERE ST_Contains( // 범죄주의구역 300m 내 존재 여부 public boolean existsCrimeWithin300m(double lat, double lon) { - String sql = """ - SELECT EXISTS ( - SELECT 1 - FROM crime_prone_area c - WHERE ST_DWithin( - c.geometry, - ST_Transform( - ST_SetSRID(ST_MakePoint(?1, ?2), 4326), - 5179 - ), - 300 - ) - ) - """; + WITH target AS ( + SELECT ST_Transform(ST_SetSRID(ST_MakePoint(?1, ?2), 4326), 5179) AS g + ) + SELECT EXISTS ( + SELECT 1 + FROM crime_prone_area c, target + WHERE c.geometry && ST_Expand(target.g, 300) + AND ST_DWithin(c.geometry, target.g, 300) + ) + """; return (Boolean) em.createNativeQuery(sql) .setParameter(1, lon) @@ -59,25 +52,19 @@ WHERE ST_DWithin( // 경찰서 / 파출소 최소 거리 public int findNearestPoliceDistanceMeter(double lat, double lon) { - String sql = """ - SELECT COALESCE( - MIN( - ST_Distance( - ST_Transform( - ST_SetSRID(ST_MakePoint(p.longitude, p.latitude), 4326), - 5179 - ), - ST_Transform( - ST_SetSRID(ST_MakePoint(?1, ?2), 4326), - 5179 - ) - ) - ), - 999999 - ) - FROM police_office p - """; + WITH target AS ( + SELECT ST_Transform(ST_SetSRID(ST_MakePoint(?1, ?2), 4326), 5179) AS g + ) + SELECT COALESCE( + ST_Distance(p.geom_5179, target.g), + 999999 + ) + FROM police_office p, target + WHERE p.geom_5179 IS NOT NULL + ORDER BY p.geom_5179 <-> target.g + LIMIT 1 + """; return ((Number) em.createNativeQuery(sql) .setParameter(1, lon) @@ -85,25 +72,18 @@ SELECT COALESCE( .getSingleResult()).intValue(); } - // CCTV 50m 내 개수 public int countCctvWithin50m(double lat, double lon) { - String sql = """ - SELECT COUNT(*) - FROM safety s - WHERE s.infra_type = 'CCTV' - AND ST_DWithin( - ST_Transform( - ST_SetSRID(ST_MakePoint(s.longitude, s.latitude), 4326), - 5179 - ), - ST_Transform( - ST_SetSRID(ST_MakePoint(?1, ?2), 4326), - 5179 - ), - 50 - ) - """; + SELECT COUNT(*) + FROM safety s + WHERE s.infra_type = 'CCTV' + AND s.geom_5179 IS NOT NULL + AND ST_DWithin( + s.geom_5179, + ST_Transform(ST_SetSRID(ST_MakePoint(?1, ?2), 4326), 5179), + 50 + ) + """; return ((Number) em.createNativeQuery(sql) .setParameter(1, lon) @@ -113,23 +93,17 @@ AND ST_DWithin( // 보안등 50m 내 개수 public int countSafetyLightWithin50m(double lat, double lon) { - String sql = """ - SELECT COUNT(*) - FROM safety s - WHERE s.infra_type = 'SAFETY_LIGHT' - AND ST_DWithin( - ST_Transform( - ST_SetSRID(ST_MakePoint(s.longitude, s.latitude), 4326), - 5179 - ), - ST_Transform( - ST_SetSRID(ST_MakePoint(?1, ?2), 4326), - 5179 - ), - 50 - ) - """; + SELECT COUNT(*) + FROM safety s + WHERE s.infra_type = 'SAFETY_LIGHT' + AND s.geom_5179 IS NOT NULL + AND ST_DWithin( + s.geom_5179, + ST_Transform(ST_SetSRID(ST_MakePoint(?1, ?2), 4326), 5179), + 50 + ) + """; return ((Number) em.createNativeQuery(sql) .setParameter(1, lon)