.vbw-planning/milestones/polish-and-reliability/phases/02-favicon-support/.context-lead.md
Not available
Not available
No matching requirements found
None
Codebase mapping exists in .vbw-planning/codebase/. Key files:
ARCHITECTURE.mdCONCERNS.mdPATTERNS.mdDEPENDENCIES.mdSTRUCTURE.mdCONVENTIONS.mdTESTING.mdSTACK.mdRead ARCHITECTURE.md, CONCERNS.md, and STRUCTURE.md first to bootstrap codebase understanding.
Researched: 2026-02-20
app/models/source_monitor/source.rbhas_many_attached :images if defined?(ActiveStorage) guard pattern (proven)FeedFetcher#call → perform_fetch → handle_responsehandle_success calls entry_processor.process_feed_entries then source_updater.update_source_for_successActiveStorage::Blob.create_and_upload!(io:, filename:, content_type:) then model.images.attach(blob)SourceMonitor::HTTP.client() provides Faraday with retry (4x), gzip, redirect following (5 max), SSL, custom headersapp/views/source_monitor/sources/_row.html.erb (lines 24-102)<div class="font-medium text-slate-900"> wrapper for namesource_monitor_queue :roleperform(item_id) with model lookup and early returnsdiscard_on ActiveJob::DeserializationError for resilienceSourceMonitor.config.imageshas_one_attached :favicon if defined?(ActiveStorage) + job early returnSourceMonitor::HTTP.client(headers: ...) for all network requestsFaviconsSettings configuration class with: enabled, fetch_timeout (5s), max_download_size (1MB), retry_cooldown_days (7), allowed_content_typeshas_one_attached :favicon (not has_many) with ActiveStorage guardFetchFaviconJob on :fetch queue, triggered from source_updater after successful fetch when favicon blankFavicons::Discoverer module with cascade: /favicon.ico → HTML parsing (Nokogiri, prefer largest) → Google Favicon API