.vbw-planning/milestones/07-rails-audit-and-refactoring/02-model-layer-hardening/01-PLAN.md
Add reusable date range scopes to the Loggable concern so all log models can efficiently filter by date, and add composite indexes to support those queries and common source-scoped log lookups.
@app/models/concerns/source_monitor/loggable.rb -- shared concern for FetchLog, ScrapeLog, HealthCheckLogrecent, successful, failed scopes on started_atsource_id and started_at for each log table, but no composite indexesFiles: app/models/concerns/source_monitor/loggable.rb
Add these scopes inside the included block, after the existing scopes:
scope :since, ->(date) { where(arel_table[:started_at].gteq(date)) }
scope :before, ->(date) { where(arel_table[:started_at].lteq(date)) }
scope :today, -> { since(Time.current.beginning_of_day) }
scope :by_date_range, ->(start_date, end_date) { since(start_date).before(end_date) }
Tests: test/models/concerns/source_monitor/loggable_test.rb (new file)
Acceptance: Scopes return correct records when chained; FetchLog.today returns only today's logs
Files: New migration file
Create migration AddCompositeIndexesToLogTables:
add_index :sourcemon_fetch_logs, [:source_id, :started_at],
name: "index_fetch_logs_on_source_id_and_started_at"
add_index :sourcemon_scrape_logs, [:source_id, :started_at],
name: "index_scrape_logs_on_source_id_and_started_at"
add_index :sourcemon_scrape_logs, [:item_id, :started_at],
name: "index_scrape_logs_on_item_id_and_started_at"
add_index :sourcemon_health_check_logs, [:source_id, :started_at],
name: "index_health_check_logs_on_source_id_and_started_at"
Tests: Assert indexes exist in schema test or migration test
Acceptance: bin/rails db:migrate succeeds; schema.rb shows 4 new composite indexes
Files: test/models/concerns/source_monitor/loggable_test.rb (new file)
Test using FetchLog as the concrete model (all 3 log models share the concern):
test "since scope returns logs on or after date" -- create logs at different times, verify filteringtest "before scope returns logs on or before date" -- same patterntest "today scope returns only today's logs" -- create yesterday + today logstest "by_date_range scope returns logs within range" -- create 3 logs, verify middle one includedtest "date scopes are chainable with existing scopes" -- FetchLog.successful.today returns correct subsetUse create_source! factory + direct FetchLog creation with explicit started_at values.
Acceptance: All 5 tests pass
Files: test/models/concerns/source_monitor/loggable_test.rb (append to same file)
Add test that verifies indexes exist on each table:
test "composite indexes exist on log tables" do
assert ActiveRecord::Base.connection.index_exists?(:sourcemon_fetch_logs, [:source_id, :started_at])
assert ActiveRecord::Base.connection.index_exists?(:sourcemon_scrape_logs, [:source_id, :started_at])
assert ActiveRecord::Base.connection.index_exists?(:sourcemon_scrape_logs, [:item_id, :started_at])
assert ActiveRecord::Base.connection.index_exists?(:sourcemon_health_check_logs, [:source_id, :started_at])
end
Acceptance: Test passes confirming all 4 indexes exist
| Action | Path |
|---|---|
| MODIFY | app/models/concerns/source_monitor/loggable.rb |
| CREATE | db/migrate/YYYYMMDDHHMMSS_add_composite_indexes_to_log_tables.rb |
| CREATE | test/models/concerns/source_monitor/loggable_test.rb |
bin/rails db:migrate
bin/rails test test/models/concerns/source_monitor/loggable_test.rb
bin/rubocop app/models/concerns/source_monitor/loggable.rb