fix: 경기 일정 크론 미업데이트 수정 — 크롤 병렬화 + HTML 파서 재작성#19
Conversation
**원인** 1. 크론 4단계가 순차 실행되어 60s maxDuration 초과 → 스케줄(4단계)만 타임아웃 2. UFC CloudFront CDN API 양쪽 엔드포인트 모두 404 반환 3. HTML 폴백 파서가 `<time datetime>` 을 탐색했으나 실제 구조는 `data-main-card-timestamp` (Unix 초) 사용으로 변경됨 **수정 내용** - cron/crawl: 3단계 병렬 실행 구조로 재작성 - Phase 1: stats/rankings/schedule 크롤 병렬 (의존성 없음) - Phase 2: DB 저장 + Gemini AI 예측 병렬 (Gemini 태스크 내부는 순차) - Phase 3: AI 결과 저장 - 예상 실행 시간 ~65s → ~43s로 단축 - serializeError 헬퍼로 PostgrestError 직렬화 버그 수정 - /rankings 캐시 워밍 누락 추가 - schedule-crawler: fetchFromHtml() 현재 HTML 구조로 완전 재작성 - 날짜: data-main-card-timestamp (Unix 초) 파싱 - 파이터 풀네임: 이미지 파일명에서 추출 (ALLEN_ARNOLD → Arnold Allen) - 파이터 이미지: HTML에서 직접 수집 (enrichFighterImages 불필요) - TBD 파이터 imageUrl 미설정으로 깨진 이미지 표시 방지 - schedule/page.tsx: enrichFighterImages 이중 호출 제거 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 Walkthrough개요UFC 일정 크롤링 및 예측 파이프라인을 재설계합니다. 일정 HTML 파싱 로직을 새로운 선택기 및 속성 기반 데이터 추출로 업데이트하고, 크론 크롤 루트를 순차 실행에서 세 가지 병렬 페이즈로 리팩토링하며, 페이지 컴포넌트에서 이미지 보강 의존성을 제거합니다. 변경 사항일정 크롤링 및 예측 통합
시퀀스 다이어그램sequenceDiagram
participant Handler as Cron Handler
participant P1 as Phase 1 Crawl
participant P2 as Phase 2 Predict
participant P3 as Phase 3 Persist
participant DB as Supabase
Handler->>P1: Start all crawl tasks
P1->>DB: Read existing schedule
P1->>P1: Crawl from UFC HTML
P1-->>Handler: Status
Handler->>P2: Save and generate predictions
P2->>DB: Insert stats, rankings
P2->>P2: Generate opponent predictions
P2->>P2: Generate schedule predictions
P2-->>Handler: Status
Handler->>P3: Conditionally persist results
P3->>DB: Update predictions, schedule
P3-->>Handler: Status
Handler->>Handler: Build final results
Handler->>DB: Revalidate paths
Handler->>Handler: Warm up pages
예상 코드 리뷰 노력🎯 4 (Complex) | ⏱️ ~75분 관련 가능성 있는 PR
시
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR fixes UFC schedule cron updates timing out and restores schedule crawling by parallelizing cron phases and rewriting the HTML fallback parser to match the current ufc.com DOM.
Changes:
- Parallelized cron execution into 3 phases (crawl → DB/AI → DB) and improved error serialization + cache warming.
- Rewrote
fetchFromHtml()to parsedata-main-card-timestamp, extract fighter names from image URLs, and collect fighter image URLs directly. - Removed
enrichFighterImagesusage from the schedule page to avoid redundant enrichment.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/lib/crawl/schedule-crawler.ts | Rewrites HTML fallback parsing and adds image-URL-based fighter name extraction. |
| src/app/api/cron/crawl/route.ts | Parallelizes crawl/save/predict phases, adds error serialization, and warms more pages. |
| src/app/[locale]/schedule/page.tsx | Removes schedule-time image enrichment and returns stored/cached schedule as-is. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * UFC 이미지 파일명 규칙: {LAST}_{FIRST}_{MM-YY}.png 또는 {LAST}_{FIRST}.png | ||
| * 예: ALLEN_ARNOLD_01-24.png → "Arnold Allen" | ||
| */ | ||
| function extractNameFromImageUrl( | ||
| url: string | undefined, | ||
| fallback: string | ||
| ): string { | ||
| if (!url) return fallback; | ||
| const match = url.match(/\/([A-Z]+)_([A-Z]+)(?:_[\d-]+)?\.png/); | ||
| if (!match) return fallback; | ||
| const toTitle = (s: string) => s.charAt(0) + s.slice(1).toLowerCase(); |
| const siteUrl = process.env.NEXT_PUBLIC_SITE_URL; | ||
| if (siteUrl) { | ||
| const pagesToWarm = [ | ||
| "/", | ||
| "/en", |
| if (data?.data) { | ||
| const schedule = data.data as UfcSchedule; | ||
| if (schedule.events?.length > 0) { | ||
| // 이미지 없는 파이터 보완 (크론 실패 또는 구형 데이터 대비) | ||
| const enriched = await enrichFighterImages(schedule.events); | ||
| return { ...schedule, events: enriched }; | ||
| return schedule; | ||
| } |
원인
<time datetime>을 탐색했으나 실제 구조는data-main-card-timestamp(Unix 초) 사용으로 변경됨수정 내용
Summary by CodeRabbit
릴리즈 노트
버그 수정
성능 개선