22
33import com .blockguard .server .domain .analysis .domain .enums .RiskLevel ;
44import com .blockguard .server .domain .fraud .dao .FraudUrlRepository ;
5+ import com .blockguard .server .domain .fraud .dto .request .FraudPhoneNumberRequest ;
56import com .blockguard .server .domain .fraud .dto .request .FraudUrlRequest ;
6- import com .blockguard .server .domain .fraud .dto .response .FraudUrlResponse ;
7+ import com .blockguard .server .domain .fraud .dto .response .FraudRiskLevelResponse ;
78import com .blockguard .server .global .common .codes .ErrorCode ;
89import com .blockguard .server .global .exception .BusinessExceptionHandler ;
910import com .blockguard .server .infra .google .GoogleSafeBrowsingClient ;
11+ import com .blockguard .server .infra .number .FraudNumberClient ;
1012import lombok .AllArgsConstructor ;
13+ import lombok .extern .slf4j .Slf4j ;
1114import org .springframework .stereotype .Service ;
1215
16+ @ Slf4j
1317@ Service
1418@ AllArgsConstructor
1519public class FraudService {
1620 private final FraudUrlRepository fraudUrlRepository ;
1721 private final GoogleSafeBrowsingClient googleSafeBrowsingService ;
22+ private final FraudNumberClient fraudNumberClient ;
1823
19- public FraudUrlResponse checkFraudUrl (FraudUrlRequest fraudUrlRequest ) {
24+ public FraudRiskLevelResponse checkFraudUrl (FraudUrlRequest fraudUrlRequest ) {
2025 String url = fraudUrlRequest .getUrl ();
2126
2227 if (url == null || url .trim ().isEmpty ()){
@@ -25,21 +30,52 @@ public FraudUrlResponse checkFraudUrl(FraudUrlRequest fraudUrlRequest) {
2530
2631 // 1차: DB 검사
2732 if (fraudUrlRepository .existsByUrl (url )){
28- return FraudUrlResponse .builder ()
33+ return FraudRiskLevelResponse .builder ()
2934 .riskLevel (RiskLevel .Dangers )
3035 .build ();
3136 }
3237
3338 // 2차: Google Safe Browsing API 호출
3439 boolean isSafe = googleSafeBrowsingService .isUrlSafe (url );
3540 if (!isSafe ){
36- return FraudUrlResponse .builder ()
41+ return FraudRiskLevelResponse .builder ()
3742 .riskLevel (RiskLevel .Dangers )
3843 .build ();
3944 }
4045
41- return FraudUrlResponse .builder ()
46+ return FraudRiskLevelResponse .builder ()
4247 .riskLevel (RiskLevel .Safety )
4348 .build ();
4449 }
50+
51+ public FraudRiskLevelResponse checkFraudPhoneNumber (FraudPhoneNumberRequest fraudPhoneNumberRequest ) {
52+ String phoneNumber = fraudPhoneNumberRequest .getPhoneNumber ().replaceAll ("\\ s+" , "" );
53+
54+ // 사기 전화번호 조회 api 호출
55+ String spamCount = fraudNumberClient .checkSpamNumber (phoneNumber ).getSpamCount ();
56+
57+ if (isFraudNumber (spamCount )){
58+ return FraudRiskLevelResponse .builder ()
59+ .riskLevel (RiskLevel .Dangers )
60+ .build ();
61+ }
62+
63+ return FraudRiskLevelResponse .builder ()
64+ .riskLevel (RiskLevel .Safety )
65+ .build ();
66+ }
67+
68+ private Boolean isFraudNumber (String spamCount ) {
69+ try {
70+ // spam count 최대 "1000+" 가 나오는 경우 고려
71+ String numericPart = spamCount .replaceAll ("\\ D+" , "" );
72+ if (numericPart .isEmpty ()){
73+ throw new BusinessExceptionHandler (ErrorCode .FRAUD_NUMBER_SERVER_ERROR );
74+ }
75+ return Integer .parseInt (numericPart ) > 0 ;
76+ } catch (NumberFormatException e ) {
77+ log .error ("Invalid spam count format: {}" , spamCount , e );
78+ throw new BusinessExceptionHandler (ErrorCode .FRAUD_NUMBER_SERVER_ERROR );
79+ }
80+ }
4581}
0 commit comments