.vbw-planning/milestones/07-rails-audit-and-refactoring/03-controller-route-refactoring/02-PLAN.md
Move favicon cooldown clearing logic from SourceFaviconFetchesController into the Source model (C2), following the project convention that business logic lives in models.
app/controllers/source_monitor/source_favicon_fetches_controller.rb:33-36 has clear_favicon_cooldown that directly manipulates metadata hash and calls update_columnapp/models/source_monitor/source.rb already has attribute :metadata, default: -> { {} } (line 35)FaviconFetchJob also checks favicon_last_attempted_at in metadata -- having the clear method on the model centralizes this concernupdate_column -- the model method should preserve this behavior (it's intentional for cooldown clearing)Add tests to test/models/source_monitor/source_test.rb:
favicon_last_attempted_at from metadata when key existsAdd to app/models/source_monitor/source.rb:
def clear_favicon_cooldown!
metadata_without_cooldown = (metadata || {}).except("favicon_last_attempted_at")
update_column(:metadata, metadata_without_cooldown)
end
In app/controllers/source_monitor/source_favicon_fetches_controller.rb:
clear_favicon_cooldown(@source) with @source.clear_favicon_cooldown!clear_favicon_cooldown methodbin/rails test -- all passbin/rubocop -- zero offenses