Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Comment on lines +15 to 19

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 1) WebClient 사용 지점 및 주입 지점 확인
echo "=== kaKaoWebClient 사용 지점 ==="
rg -nP --type=java -C3 'kaKaoWebClient'

echo ""
echo "=== 상대 경로 URI 사용 지점 ==="
rg -nP --type=java -C2 '\.uri\s*\(\s*"/[^"]*"'

echo ""
echo "=== 절대 URL URI 사용 지점 ==="
rg -nP --type=java -C2 '\.uri\s*\(\s*"https?://[^"]*"'

Repository: D-ingle/backend

Length of output: 1684


🏁 Script executed:

#!/bin/bash
# KaKaoGeocodingService 파일 전체 내용 확인
cat src/main/java/com/example/Dingle/user/service/KaKaoGeocodingService.java

Repository: D-ingle/backend

Length of output: 1621


🏁 Script executed:

#!/bin/bash
# KaKaoWebClientConfig 전체 파일 확인
echo "=== KaKaoWebClientConfig.java ==="
cat src/main/java/com/example/Dingle/global/config/KaKaoWebClientConfig.java

echo ""
echo "=== application properties 파일에서 kakao 설정 확인 ==="
fd --type f -e properties -e yml -e yaml | xargs rg -l 'kakao' 2>/dev/null || echo "No kakao config found"

echo ""
echo "=== kakao 관련 설정값 ==="
fd --type f -e properties -e yml -e yaml -x cat {} \; | rg -C2 'kakao' || echo "No kakao properties found"

Repository: D-ingle/backend

Length of output: 915


baseUrl 제거로 인한 런타임 오류 발생 - 반드시 복구 필요

상대 경로 /v2/local/search/address.json를 사용하는 KaKaoGeocodingService.getGeoPoint()가 이 WebClient를 주입받아 사용하고 있습니다. baseUrl이 없으면 상대 경로를 절대 URL로 변환할 수 없어 런타임에 실패합니다.

baseUrl 파라미터와 .baseUrl(baseUrl) 설정을 복구하고, 해당 설정값을 application.properties 또는 application.yml에 추가해야 합니다:

kakao.base-url=https://dapi.kakao.com
kakao.api-key=your-api-key

또는 yml 형식:

kakao:
  base-url: https://dapi.kakao.com
  api-key: your-api-key
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/example/Dingle/global/config/KaKaoWebClientConfig.java`
around lines 15 - 19, The kaKaoWebClient factory removed the baseUrl causing
relative-path requests in KaKaoGeocodingService.getGeoPoint() to fail at
runtime; restore a baseUrl parameter on the kaKaoWebClient method (e.g., add a
String baseUrl `@Value`("${kakao.base-url}") parameter) and re-enable
.baseUrl(baseUrl) on the WebClient.builder(), and ensure application config
contains kakao.base-url (https://dapi.kakao.com) along with kakao.api-key
entries in application.properties or application.yml so the injected values
resolve.

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -59,51 +52,38 @@ 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
""";
Comment on lines +56 to +67

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find . -name "HomeSafetyRepository.java" -type f 2>/dev/null | head -20

Repository: D-ingle/backend

Length of output: 137


🏁 Script executed:

cat -n ./src/main/java/com/example/Dingle/safety/repository/HomeSafetyRepository.java | sed -n '50,80p'

Repository: D-ingle/backend

Length of output: 1147


🏁 Script executed:

cat -n ./src/main/java/com/example/Dingle/safety/repository/HomeSafetyRepository.java | head -20

Repository: D-ingle/backend

Length of output: 806


🏁 Script executed:

rg "findNearestPoliceDistanceMeter" --type java -A 5 -B 5

Repository: D-ingle/backend

Length of output: 2691


🏁 Script executed:

cat -n ./src/main/java/com/example/Dingle/property/service/openAI/SafetyExplanationService.java | grep -A 30 "findNearestPoliceDistanceMeter" | head -40

Repository: D-ingle/backend

Length of output: 1712


🏁 Script executed:

cat -n ./src/main/java/com/example/Dingle/property/service/openAI/SafetyExplanationService.java | sed -n '1,80p'

Repository: D-ingle/backend

Length of output: 4196


경찰서 최근접 거리 쿼리에서 빈 결과 처리 누락으로 인한 NoResultException 발생 위험

현재 쿼리 구조에서 police_office 테이블이 비어있거나 모든 행의 geom_5179가 NULL인 경우, WHERE 절과 LIMIT 1로 인해 0건의 행이 반환되고, 72번 줄의 getSingleResult()에서 NoResultException이 발생합니다. 현재의 COALESCE는 ST_Distance의 NULL 값만 처리하며, 결과 행 자체가 없는 경우는 처리하지 못합니다.

제안된 수정처럼 COALESCE를 서브쿼리 전체를 감싸도록 변경하여, 0건 결과인 경우도 기본값(999999)으로 반환되도록 해야 합니다:

수정 예시
         String sql = """
         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
+        SELECT COALESCE((
+          SELECT ST_Distance(p.geom_5179, target.g)
+          FROM police_office p, target
+          WHERE p.geom_5179 IS NOT NULL
+          ORDER BY p.geom_5179 <-> target.g
+          LIMIT 1
+        ), 999999)
     """;

police_office 테이블 또는 geom_5179가 전부 NULL인 경우에 대한 테스트 케이스 추가를 권장합니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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
""";
WITH target AS (
SELECT ST_Transform(ST_SetSRID(ST_MakePoint(?1, ?2), 4326), 5179) AS g
)
SELECT COALESCE((
SELECT ST_Distance(p.geom_5179, target.g)
FROM police_office p, target
WHERE p.geom_5179 IS NOT NULL
ORDER BY p.geom_5179 <-> target.g
LIMIT 1
), 999999)
""";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/example/Dingle/safety/repository/HomeSafetyRepository.java`
around lines 56 - 67, The query can return zero rows (empty police_office or all
geom_5179 NULL), causing getSingleResult() in HomeSafetyRepository to throw
NoResultException; change the SQL so the COALESCE wraps the entire subquery
result (e.g. SELECT COALESCE((SELECT ... FROM police_office p, target WHERE
p.geom_5179 IS NOT NULL ORDER BY p.geom_5179 <-> target.g LIMIT 1), 999999) AS
distance) so the call in the repository method (the code that calls
getSingleResult() for the nearest police distance) always returns a numeric
default when no row exists; alternatively adjust the repository method to use
getResultList() and return 999999 when the list is empty.


return ((Number) em.createNativeQuery(sql)
.setParameter(1, lon)
.setParameter(2, lat)
.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)
Expand All @@ -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)
Expand Down