Skip to content

feat: 큐레이션 데이터 품질 개선 (description, thumbnailUrl 추출)#28

Merged
choihooo merged 4 commits intodevfrom
feat/curation-data-quality
Mar 11, 2026
Merged

feat: 큐레이션 데이터 품질 개선 (description, thumbnailUrl 추출)#28
choihooo merged 4 commits intodevfrom
feat/curation-data-quality

Conversation

@choihooo
Copy link
Copy Markdown
Collaborator

🎯 Summary

이 PR의 목적을 한 줄로 요약해주세요

  • 큐레이션 봇 크롤러가 수집하는 외부 컨텐츠의 데이터 품질을 개선하여 description(요약)과 thumbnailUrl(썸네일) 정보를 추가로 수집 및 저장

🔴 AS-IS

기존 상태 또는 문제점

  • 큐레이션 아이템이 title, url, publishedAt 기본 정보만 수집
  • 웹 대시보드와 봇 스케줄러에 피드 파싱 로직이 중복되어 유지보수 어려움
  • 웹 API의 extractOgImage 함수에 SSRF 보호 체크 누락
  • sanitizeDescription 구현이 두 곳에서 다르게 동작 (HTML 엔티티 처리 불일치)
  • 제어 문자나 유니코드 익스플로잇 등 보안 위험 요소 미제거

🟢 TO-BE

변경 후 상태 또는 개선점

  • RSS 피드에서 description, thumbnailUrl 필드 추출 및 DB 저장
  • feed-parser.ts 공유 유틸리티로 코드 중복 제거
  • SSRF 보호 강화: extractOgImageisSafeUrl 체크 추가 (내부 URL 차단)
  • 보안 로직 개선: 제어 문자/유니코드 익스플로잇 제거, HTML 엔티티 디코딩
  • 테스트 커버리지: 20개의 속성 기반 테스트 추가 (SSRF, XSS, 한글/이모지 처리 등)

💬 참고사항

리뷰어가 알아야 할 내용, 논의 포인트, 주의사항 등

주요 변경사항

  1. 공유 유틸리티 생성: packages/shared/src/utils/feed-parser.ts

    • extractFeedItems(): RSS/Atom/JSON/RDF 포맷 통합 파싱
    • sanitizeDescription(): HTML 태그 제거 + 보안 위험 요소 필터링 + 엔티티 디코딩
    • extractOgImage(): OG 이미지 추출 + SSRF 보호
  2. 보안 강화

    • isSafeUrl()url-validator.ts로 이동하여 봇/웹 공용으로 사용
    • 내부 URL 차단: localhost, 127.0.0.1, 169.254.169.254 (AWS 메타데이터), 10.x, 192.168.x
    • 제어 문자 제거: [\x00-\x08\x0B\x0C\x0E-\x1F\x7F]
    • 유니코드 익스플로잇 제거: [\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]
  3. 데이터베이스 스키마

    • 기존 curation_items 테이블에 description, thumbnailUrl 컬럼 이미 존재
    • 타입: description TEXT, thumbnailUrl VARCHAR(1000)

의존성 추가

  • feedsmith@2.9.0 (업데이트)
  • html-entities@2.6.0 (신규)

테스트

  • ✅ 모든 테스트 통과 (81/81)
  • ✅ 속성 기반 테스트 20개 추가
  • ✅ SSRF 보호 테스트 (내부 URL 차단 확인)
  • ✅ XSS 방지 테스트
  • ✅ 한글/이모지 처리 테스트

주의사항

  • 배포 시 기존 큐레이션 아이템은 description/thumbnailUrl이 null이 됩니다 (데이터 마이그레이션 불필요)
  • OG 이미지 추출은 순차적으로 진행되어 성능에 영향을 줄 수 있음 (향후 병렬 처리 고려)
  • 5초 타임아웃으로 OG 이미지 추출 실패 시 무시하고 진행

🤖 Generated with Claude Code

P1 #8: 큐레이션 봇 크롤러 데이터 품질 개선

주요 변경사항:
- RSS 피드에서 description, thumbnailUrl 필드 추출
- feed-parser 공유 유틸리티 생성 (extractFeedItems, sanitizeDescription, extractOgImage)
- SSRF 보호 강화 (isSafeUrl를 url-validator로 이동)
- HTML 엔티티 디코딩 추가 (html-entities 패키지)
- 제어 문자/유니코드 익스플로잇 제거 로직 개선
- 웹 API와 봇 간 코드 중복 제거

보안 개선:
- extractOgImage 함수에 isSafeUrl SSRF 체크 추가
- sanitizeDescription에 제어 문자/유니코드 익스플로잇 제거 추가
- 내부 URL (localhost, 127.0.0.1, 169.254.169.254 등) 차단

테스트:
- feed-parser.property.test.ts 추가 (20개 테스트 케이스)
- SSRF 보호, XSS 방지, 한글/이모지 처리 등 검증

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@choihooo choihooo requested a review from bbbang105 as a code owner March 11, 2026 00:59
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
study-admin-web Ready Ready Preview, Comment Mar 11, 2026 1:31am

@bbbang105 bbbang105 added ✅ test 테스트 코드 🚀 feat 새로운 기능 추가 / 일부 코드 추가 / 일부 코드 수정 (리팩토링과 구분) / 디자인 요소 수정 labels Mar 11, 2026
choihooo and others added 3 commits March 11, 2026 10:04
- 봇 스케줄러: Promise.allSettled로 OG 이미지 동시 추출
- 웹 API: OG 이미지 병렬 추출 후 DB 삽입 (순차 유지)
- 순차 처리(최대 250초) → 병렬 처리(최대 5초)로 대기 시간 단축
- Promise.allSettled로 개별 실패시 전체 프로세스 보호

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 웹 API: NormalizedFeedItem 타입 import 추가
- filter/map 콜백에 명시적 타입 어노테이션 추가
- Promise.allSettled 결과에 타입 가드 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- shared/utils: utils namespace export 추가 (import { utils } 패턴 지원)
- rss-detect.ts: isSafeUrl re-export 추가
- 타입 안전성 개선: Promise.allSettled result 변수 분리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bbbang105 bbbang105 added ⚡️ perf 성능 개선 작업 🚨 fix 버그 수정 / 에러 해결 labels Mar 11, 2026
@choihooo choihooo merged commit c81c093 into dev Mar 11, 2026
7 checks passed
@choihooo choihooo deleted the feat/curation-data-quality branch March 11, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚀 feat 새로운 기능 추가 / 일부 코드 추가 / 일부 코드 수정 (리팩토링과 구분) / 디자인 요소 수정 🚨 fix 버그 수정 / 에러 해결 ⚡️ perf 성능 개선 작업 ✅ test 테스트 코드

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants