diff --git a/TODO.md b/TODO.md index 2d9e154..085ab7a 100644 --- a/TODO.md +++ b/TODO.md @@ -341,6 +341,17 @@ - [ ] full browser-level validation was not fully reproducible in this environment ## Recent Change Log +- Date: `2026-03-16` +- What changed: + - Relaxed final recommendation merge so Gemini-reviewed non-negative items can still appear, and only a small preview-capable ranked filler set is used when the result list is otherwise too thin. +- Why it changed: + - The stricter `recommended=true only` merge made the visible result set collapse too aggressively in real searches. +- How it was verified: + - `go test ./...` + - `bash scripts/selftest.sh` +- What is still risky or incomplete: + - Filler results can still appear with the fallback reason when Gemini-reviewed positives are scarce, though the amount is now intentionally capped. + - Date: `2026-03-16` - What changed: - Google Video embed URL now uses `youtube-nocookie` with explicit `origin` to reduce player load failures. diff --git a/backend/services/ranker.go b/backend/services/ranker.go index ad893a0..e8fd388 100644 --- a/backend/services/ranker.go +++ b/backend/services/ranker.go @@ -302,6 +302,39 @@ func MergeRecommendations(recommended []AIRecommendation, ranked []SearchResult, seen[item.Link] = true merged = append(merged, item) } + + for _, item := range recommended { + if item.Recommended || item.Link == "" || seen[item.Link] || len(merged) >= limit { + continue + } + if looksNegativeReason(item.Reason) || strings.Contains(item.Reason, GeminiFallbackReason) { + continue + } + seen[item.Link] = true + merged = append(merged, item) + } + + if len(merged) < min(6, limit) { + for _, item := range ranked { + if len(merged) >= min(6, limit) || item.Link == "" || seen[item.Link] { + continue + } + if strings.TrimSpace(item.ThumbnailURL) == "" && strings.TrimSpace(item.PreviewVideoURL) == "" { + continue + } + seen[item.Link] = true + merged = append(merged, AIRecommendation{ + Title: item.Title, + Link: item.Link, + Snippet: item.Snippet, + ThumbnailURL: item.ThumbnailURL, + PreviewVideoURL: item.PreviewVideoURL, + Source: item.Source, + Reason: GeminiFallbackReason, + Recommended: false, + }) + } + } return merged }