.vbw-planning/milestones/ui-fixes-and-smart-scraping/phases/04-smart-scrape-recommendations/04-PLAN-02.md
Add a dashboard widget card that shows the count of sources recommended for scraping (low avg feed word count, scraping not yet enabled). Links to the sources index filtered to show only candidates.
Files:
lib/source_monitor/dashboard/queries/stats_query.rbDescription:
Add scrape_candidates_count to the stats hash returned by StatsQuery#call. Use SourceMonitor::Analytics::ScrapeRecommendations to compute the count.
Add to the returned hash:
scrape_candidates_count: scrape_candidates_count
Add private method:
def scrape_candidates_count
SourceMonitor::Analytics::ScrapeRecommendations.new.candidates_count
end
Tests:
test/lib/source_monitor/dashboard/ (or create if not present) to assert scrape_candidates_count is returnedFiles:
app/views/source_monitor/dashboard/_scrape_recommendations.html.erbDescription:
Create a widget partial that follows the existing dashboard card pattern (bordered card with header + divider + content). Only render content when scrape_candidates_count > 0.
Widget should display:
The filter link should use: source_monitor.sources_path(q: { avg_feed_words_lt: threshold, scraping_enabled_eq: false, active_eq: true })
Use the same Tailwind card pattern as the Quick Actions widget:
<div class="rounded-lg border border-slate-200 bg-white shadow-sm">
<div class="border-b border-slate-200 px-5 py-4">
<h2 class="text-lg font-medium">Scrape Recommendations</h2>
<p class="mt-1 text-xs text-slate-500">Sources with low feed word counts.</p>
</div>
<div class="px-5 py-4">
...count and link...
</div>
</div>
Tests:
Files:
app/controllers/source_monitor/dashboard_controller.rbapp/views/source_monitor/dashboard/index.html.erbDescription:
In the controller, compute and assign @scrape_candidates_count:
@scrape_candidates_count = queries.stats[:scrape_candidates_count]
@scrape_recommendation_threshold = SourceMonitor.config.scraping.scrape_recommendation_threshold
In the view, render the widget in the right sidebar column (after job_metrics, before Quick Actions) only when count > 0:
<%= render "scrape_recommendations",
count: @scrape_candidates_count,
threshold: @scrape_recommendation_threshold if @scrape_candidates_count.to_i > 0 %>
Tests:
test/controllers/source_monitor/dashboard_controller_test.rb -- Add test for:
@scrape_candidates_count is assignedFiles:
app/models/source_monitor/source.rbDescription:
Add scraping_enabled to the ransackable_attributes array so the dashboard widget link can filter by scraping_enabled_eq: false. It's a boolean column already on the sources table.
Tests:
scraping_enabled is in Source.ransackable_attributes