Skip to content

[Fix] 뉴스 조회 api 수정#65

Merged
chaeyuuu merged 2 commits intomainfrom
fix/#64/fix-news-api
Aug 13, 2025
Merged

[Fix] 뉴스 조회 api 수정#65
chaeyuuu merged 2 commits intomainfrom
fix/#64/fix-news-api

Conversation

@chaeyuuu
Copy link
Copy Markdown
Contributor

@chaeyuuu chaeyuuu commented Aug 13, 2025

💻 Related Issue

closed #64


🚀 Work Description

  • 뉴스가 카테고리에 중복되어 필터링되는 문제 수정

Summary by CodeRabbit

  • New Features
    • ‘보이스피싱’과 ‘보이스 피싱’ 표기를 모두 인식해 동일 카테고리로 분류, 관련 기사 수집·노출 정확도가 향상되었습니다.
    • 관리자 크롤링 키워드에 두 표기를 모두 포함해 검색 누락 가능성을 줄였으며, 초기 키워드 호출을 공백 표기로 보완해 더 다양한 검색 결과를 확보했습니다.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Aug 13, 2025

Walkthrough

카테고리 매핑에서 “보이스 피싱” 변형을 인식하도록 확장하고, 스케줄러의 크롤링 키워드 리스트에 공백 변형을 추가했으며, 뉴스 저장 스케줄 작업 종료 로그를 추가했습니다. 기타 로직 변화는 없습니다.

Changes

Cohort / File(s) Summary
카테고리 매핑 확장
src/main/java/.../domain/news/domain/enums/Category.java
Category.from(String)에서 "보이스피싱", "보이스 피싱" 모두 VOICE_PHISHING으로 매핑하도록 멀티 라벨 switch 케이스 추가. 기존 스미싱/메신저 피싱 매핑 및 기본값 유지. 경미한 포매팅.
스케줄러 키워드 및 로그
src/main/java/.../domain/news/scheduler/NewsSaveScheduler.java
관리자 크롤링 키워드에 "보이스 피싱" 변형 추가 및 첫 호출 키워드 변경. saveNewsArticles 종료 시 완료 로그 추가. 예외 처리 변경 없음. 경미한 포매팅.

Sequence Diagram(s)

sequenceDiagram
  participant Scheduler as NewsSaveScheduler
  participant Crawler as NewsCrawler
  participant Category as Category.from()

  Scheduler->>Crawler: fetch("보이스 피싱"/"보이스피싱","스미싱","메신저 피싱","몸캠")
  Crawler->>Category: categorize(article.title)
  Category-->>Crawler: VOICE_PHISHING / SMISHING / MESSAGE_VOICE_PHISHING / ETC
  Crawler-->>Scheduler: Articles saved
  Scheduler->>Scheduler: 로그 "뉴스 크롤링 스케줄링 완료"
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~7 minutes

Assessment against linked issues

Objective Addressed Explanation
뉴스 카테고리 수정 (#64)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
완료 로그 추가: "뉴스 크롤링 스케줄링 완료" 출력 (src/main/java/.../domain/news/scheduler/NewsSaveScheduler.java, saveNewsArticles 메서드 말미) 로그 추가는 ‘카테고리 수정’ 범위를 벗어난 운용성 변경으로 보입니다.
관리자 키워드 세트에 "보이스 피싱" 변형 추가 및 첫 호출 키워드 변경 (src/main/java/.../domain/news/scheduler/NewsSaveScheduler.java, crawlingForAdmin/saveNewsArticles) 이 변경은 크롤링 범위/입력 확장으로, 이슈의 카테고리 매핑 수정과 직접적 관련이 불명확합니다.

Suggested labels

🐞 BugFix, 🐼 채유

Poem

토깽이 키보드 탁탁탁, 분류를 쓱 고쳤지
“보이스 피싱”도 “보이스피싱”도, 한 바구니에 쏙—딱이지!
스케줄러는 콧노래, 완료 로그 띡 남기고
당근 같은 키워드, 빠짐없이 바구니로
깡충! 오늘도 뉴스밭 정리 끝 🍀🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#64/fix-news-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@chaeyuuu chaeyuuu merged commit 16d7855 into main Aug 13, 2025
1 check was pending
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (2)
src/main/java/com/blockguard/server/domain/news/domain/enums/Category.java (1)

6-12: 입력 정규화와 null-세이프 처리로 매핑 일관성을 강화하세요

현재는 정확히 일치하는 문자열만 처리합니다. null 입력, 앞뒤/중간의 다양한 공백(스페이스, 탭, NBSP 등) 변형을 고려해 사전 정규화하면 누락과 분기 중복을 줄일 수 있습니다. 공백 제거만으로도 본 변경의 목적을 더 깔끔히 달성할 수 있습니다.

아래처럼 정규화 후 스위치 문을 단일 라벨로 간소화하는 것을 권장합니다.

-    public static Category from(String input) {
-        return switch (input) {
-            case "보이스피싱", "보이스 피싱" -> VOICE_PHISHING;
-            case "스미싱" -> SMISHING;
-            case "메신저 피싱", "메신저피싱" -> MESSAGE_VOICE_PHISHING;
-            default -> ETC;
-        };
-    }
+    public static Category from(String input) {
+        if (input == null) {
+            return ETC;
+        }
+        // 선(先) 정규화: 앞뒤 공백 제거 + 모든 공백(연속 포함) 제거
+        String normalized = input.trim().replaceAll("\\s+", "");
+        return switch (normalized) {
+            case "보이스피싱" -> VOICE_PHISHING;
+            case "스미싱" -> SMISHING;
+            case "메신저피싱" -> MESSAGE_VOICE_PHISHING;
+            default -> ETC;
+        };
+    }

원하시면 하이픈/중점 등 문장부호도 제거하는 정규화(예: replaceAll("[-_·・]", ""))까지 포함하도록 도와드릴 수 있습니다.

src/main/java/com/blockguard/server/domain/news/scheduler/NewsSaveScheduler.java (1)

27-36: 스케줄러도 공통 키워드 루프 사용으로 중복 제거 및 예외 격리

동일 키워드 셋을 반복 호출하지 말고, 관리자용과 동일하게 루프를 사용하면 중복 제거와 예외 격리가 동시에 해결됩니다. 또한 한 키워드 실패가 전체 스케줄을 중단하지 않도록 try-catch를 루프 내부에 유지하세요.

     @Scheduled(cron = "0 0 4 * * *")
-    public void saveNewsArticles() {
+    public void saveNewsArticles() {
         log.info("뉴스 크롤링 스케줄링 시작");
 
-        daumNewsCrawler.fetchNewsFromDaum("보이스 피싱");
-        daumNewsCrawler.fetchNewsFromDaum("스미싱");
-        daumNewsCrawler.fetchNewsFromDaum("메신저 피싱");
-        daumNewsCrawler.fetchNewsFromDaum("몸캠");
+        for (String keyword : KEYWORDS) {
+            try {
+                daumNewsCrawler.fetchNewsFromDaum(keyword);
+            } catch (Exception e) {
+                log.warn("키워드 크롤링 실패: {}", keyword, e);
+            }
+        }
 
         log.info("뉴스 크롤링 스케줄링 완료");
     }

추가로 운영 환경이 KST 기준이라면, 아래처럼 타임존을 명시하는 것도 고려해 주세요:
@Scheduled(cron = "0 0 4 * * *", zone = "Asia/Seoul")

🧹 Nitpick comments (1)
src/main/java/com/blockguard/server/domain/news/scheduler/NewsSaveScheduler.java (1)

19-22: 로그 메시지 언어 일관성 제안

다른 로그는 한글인데, 여기만 영어 메시지입니다. 한글로 맞추면 운영 중 가독성이 좋아집니다.

-                log.warn("Failed to crawl news for keyword: {}", keyword, e);
+                log.warn("키워드 크롤링 실패: {}", keyword, e);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a22e736 and 989debe.

📒 Files selected for processing (2)
  • src/main/java/com/blockguard/server/domain/news/domain/enums/Category.java (1 hunks)
  • src/main/java/com/blockguard/server/domain/news/scheduler/NewsSaveScheduler.java (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/com/blockguard/server/domain/news/scheduler/NewsSaveScheduler.java (3)
src/main/java/com/blockguard/server/infra/crawler/DaumNewsCrawler.java (2)
  • DaumNewsCrawler (24-137)
  • fetchNewsFromDaum (32-116)
src/test/java/com/blockguard/server/infra/crawler/DaumNewsCrawlerTest.java (2)
  • 크롤링_테스트 (12-18)
  • DaumNewsCrawlerTest (7-19)
src/main/java/com/blockguard/server/domain/admin/api/AdminApi.java (1)
  • crawlNewsManually (52-57)
🔇 Additional comments (2)
src/main/java/com/blockguard/server/domain/news/domain/enums/Category.java (1)

8-8: "보이스피싱" ↔ "보이스 피싱" 동시 매핑 추가, 의도에 부합합니다

공백 변형을 동일 카테고리(VOICE_PHISHING)로 매핑해 중복/누락을 줄이는 방향이 타당합니다.

src/main/java/com/blockguard/server/domain/news/scheduler/NewsSaveScheduler.java (1)

35-35: 완료 로그 추가 좋습니다

스케줄 종료 지점을 명확히 남겨 모니터링과 장애 분석에 도움이 됩니다.

Comment on lines +15 to 17
public void crawlingForAdmin() {
String[] keywords = {"보이스 피싱", "보이스피싱", "스미싱", "메신저 피싱", "몸캠"};
for (String keyword : keywords) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

키워드 상수화 및 재사용: 중복 로직/오타 리스크를 줄이세요

관리자 수동 크롤링과 스케줄러에서 동일한 키워드 셋을 반복 선언하지 말고, 클래스 상수로 정의해 단일 소스로 관리하세요. 또한 배열 대신 불변 List 사용을 권장합니다.

아래 변경으로 crawlingForAdmin()에서 상수 재사용이 가능합니다.

-    public void crawlingForAdmin() {
-        String[] keywords = {"보이스 피싱", "보이스피싱", "스미싱", "메신저 피싱", "몸캠"};
-        for (String keyword : keywords) {
+    public void crawlingForAdmin() {
+        for (String keyword : KEYWORDS) {

그리고 클래스 상단에 다음을 추가하세요(선택 코드, 참고용):

// import java.util.List;
private static final List<String> KEYWORDS =
        List.of("보이스 피싱", "보이스피싱", "스미싱", "메신저 피싱", "몸캠");
🤖 Prompt for AI Agents
In
src/main/java/com/blockguard/server/domain/news/scheduler/NewsSaveScheduler.java
around lines 15 to 17, replace the locally declared String[] keywords with a
single immutable class-level constant to avoid duplication and typos: add a
private static final List<String> KEYWORDS = List.of(...); at the top of the
class (ensure java.util.List is imported) and update crawlingForAdmin() to
iterate over KEYWORDS instead of declaring a new array; use List.of to create an
unmodifiable list so other methods (like the admin manual crawler) can reuse the
same constant.

@chaeyuuu chaeyuuu deleted the fix/#64/fix-news-api branch August 18, 2025 06:10
@yeonju73 yeonju73 added 🐞 BugFix Something isn't working 🐼 채유 labels Aug 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞 BugFix Something isn't working 🐼 채유

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fix] 뉴스 조회 카테고리 수정

2 participants