fix:트렌딩 키워드 가져오기 실패 개선 (빈 결과 캐시 방지 + 리프레이밍 폴백)

- 빈 결과를 30분간 캐시하는 문제 수정 (성공 결과만 캐시)
- 건강 키워드가 없을 때 리프레이밍 폴백 추가 (트렌드를 건강 관점으로 재해석)
- 최종 폴백: 원본 인기 키워드 표시
- 프론트엔드 에러/안내 메시지 분리 (오류 vs 건강 키워드 없음)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-19 06:16:13 +09:00
parent 0afe2d7896
commit b00fd45650
3 changed files with 138 additions and 10 deletions

View File

@@ -41,18 +41,60 @@ public function index(Request $request): View|Response
*/
public function fetchTrending(): JsonResponse
{
$keywords = Cache::remember('health_trending', 1800, function () {
$rawKeywords = $this->trendingService->fetchTrendingKeywords(20);
// 1단계: 원본 트렌딩 키워드 수집 (자체 캐시 있음)
$rawKeywords = $this->trendingService->fetchTrendingKeywords(20);
$healthKeywords = $this->geminiService->filterHealthTrending($rawKeywords);
if (empty($rawKeywords)) {
return response()->json([
'success' => false,
'keywords' => [],
'reason' => 'rss_fail',
'message' => 'Google 트렌드 데이터를 가져올 수 없습니다. 잠시 후 다시 시도해주세요.',
]);
}
// Gemini 필터링 결과 반환 (빈 배열이면 빈 배열 — 원본 노출 안 함)
return $healthKeywords;
});
// 2단계: Gemini 필터링 (성공 결과만 캐시)
$cached = Cache::get('health_trending');
if ($cached !== null && ! empty($cached)) {
return response()->json([
'success' => true,
'keywords' => $cached,
]);
}
// 직접 필터링 시도
$healthKeywords = $this->geminiService->filterHealthTrending($rawKeywords);
// 건강 키워드가 없으면 리프레이밍 폴백 시도
if (empty($healthKeywords)) {
$healthKeywords = $this->geminiService->reframeAsHealthTrending($rawKeywords);
}
if (! empty($healthKeywords)) {
Cache::put('health_trending', $healthKeywords, 1800);
return response()->json([
'success' => true,
'keywords' => $healthKeywords,
]);
}
// 최종 폴백: 원본 키워드 상위 5개를 건강 없이 반환
$fallback = collect($rawKeywords)->take(5)->map(fn ($item) => [
'keyword' => $item['keyword'],
'health_angle' => '',
'suggested_topic' => $item['keyword'],
'traffic' => $item['traffic'] ?? '',
'news_title' => $item['news_title'] ?? '',
'pub_date' => $item['pub_date'] ?? null,
'is_raw' => true,
])->values()->toArray();
return response()->json([
'success' => true,
'keywords' => $keywords,
'keywords' => $fallback,
'reason' => 'no_health_match',
'message' => '건강 관련 트렌딩이 없어 인기 키워드를 표시합니다.',
]);
}