.vbw-planning/codebase/CONVENTIONS.md
rubocop-rails-omakase gem# frozen_string_literal: true)lib/source_monitor.rb entry pointSourceMonitor::Fetching, Scraping, Health, Security, Dashboard, RealtimeFeedFetcher, ItemScraper, Scheduler, RetentionPruner)Presenter (e.g., BulkResultPresenter, RecentActivityPresenter, TurboStreamPresenter)analytics/ and dashboard/ (e.g., Queries, SourcesIndexMetrics)item_scraper/adapter_resolver.rb, item_scraper/persistence.rb)concerns/ subdirectoriessourcemon_ (configurable via config.models.table_name_prefix)sourcemon_sources, sourcemon_items, sourcemon_fetch_logs, etc.source_id, item_idstarted_at/completed_at pattern for log records!) for operations that raise on failure: soft_delete!, mark_processing!fetch_circuit_open?, auto_paused?, deleted?, success?call method pattern for service objects and scraper adaptersset_* for controller before_actions: set_source, set_import_sessionJob: FetchFeedJob, ScrapeItemJob, ScheduleFetchesJobsource_monitor_queue :fetch class methodSourcesController, ItemsControllerSourceFetchesController, SourceRetriesControllerSourceBulkScrapesController, SourceHealthChecksControllerSourceMonitor.configure { |config| ... } block DSLreset! methods for testingFetchError base with typed subclasses (TimeoutError, ConnectionError, HTTPError, ParsingError)http_status, response, original_errorrescue StandardError wrappers around logging callsRails.logger usage guarded with defined?(Rails) && Rails.respond_to?(:logger) && Rails.loggerStruct.new(..., keyword_init: true) extensively used for result/event objectsResult, ResponseWrapper, EntryProcessingResultItemCreatedEvent, ItemScrapedEvent, FetchCompletedEvent.fm-admin class with Tailwind important selectorwindow.SourceMonitorStimulusasync-submit, confirm-navigation)SourceMonitor::TurboStreams::StreamResponder_row.html.erb, _details.html.erb, _form_fields.html.erbsteps/_upload.html.erb, steps/_preview.html.erbtest/lib/source_monitor/scraping/item_scraper_test.rbcreate_source! factory method in ActiveSupport::TestCasesetup block: SourceMonitor.reset_configuration!before_all for expensive shared setupwith_inline_jobs and with_queue_adapter helpers for job testing# :nocov: markers for untestable/defensive code paths