source_monitor 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/commands/release.md +45 -22
- data/.claude/skills/sm-configure/SKILL.md +10 -1
- data/.claude/skills/sm-configure/reference/configuration-reference.md +44 -0
- data/.claude/skills/sm-host-setup/reference/initializer-template.md +17 -0
- data/.claude/skills/sm-host-setup/reference/setup-checklist.md +2 -0
- data/.claude/skills/sm-job/reference/job-conventions.md +26 -0
- data/.claude/skills/sm-upgrade/reference/version-history.md +22 -0
- data/.gitignore +10 -0
- data/AGENTS.md +1 -1
- data/CHANGELOG.md +56 -0
- data/CLAUDE.md +11 -5
- data/Gemfile.lock +1 -1
- data/README.md +6 -4
- data/VERSION +1 -1
- data/app/assets/builds/source_monitor/application.css +43 -0
- data/app/assets/builds/source_monitor/application.js +127 -0
- data/app/assets/builds/source_monitor/application.js.map +3 -3
- data/app/assets/javascripts/source_monitor/application.js +2 -0
- data/app/assets/javascripts/source_monitor/controllers/notification_container_controller.js +138 -0
- data/app/assets/javascripts/source_monitor/controllers/notification_controller.js +11 -0
- data/app/controllers/source_monitor/source_favicon_fetches_controller.rb +38 -0
- data/app/controllers/source_monitor/sources_controller.rb +11 -0
- data/app/helpers/source_monitor/application_helper.rb +51 -0
- data/app/jobs/source_monitor/favicon_fetch_job.rb +71 -0
- data/app/jobs/source_monitor/import_opml_job.rb +9 -0
- data/app/jobs/source_monitor/source_health_check_job.rb +10 -0
- data/app/models/source_monitor/source.rb +2 -0
- data/app/views/layouts/source_monitor/application.html.erb +23 -2
- data/app/views/source_monitor/shared/_toast.html.erb +1 -0
- data/app/views/source_monitor/sources/_details.html.erb +34 -5
- data/app/views/source_monitor/sources/_row.html.erb +11 -6
- data/config/routes.rb +1 -0
- data/docs/configuration.md +1 -1
- data/docs/upgrade.md +22 -0
- data/lib/generators/source_monitor/install/templates/source_monitor.rb.tt +15 -1
- data/lib/source_monitor/configuration/favicons_settings.rb +42 -0
- data/lib/source_monitor/configuration/http_settings.rb +1 -1
- data/lib/source_monitor/configuration/scraping_settings.rb +1 -1
- data/lib/source_monitor/configuration.rb +3 -1
- data/lib/source_monitor/favicons/discoverer.rb +196 -0
- data/lib/source_monitor/fetching/feed_fetcher/source_updater.rb +21 -0
- data/lib/source_monitor/fetching/feed_fetcher.rb +1 -0
- data/lib/source_monitor/http.rb +5 -3
- data/lib/source_monitor/version.rb +1 -1
- data/lib/source_monitor.rb +4 -0
- data/lib/tasks/test_fast.rake +11 -0
- data/source_monitor.gemspec +1 -1
- metadata +7 -93
- data/.vbw-planning/PROJECT.md +0 -51
- data/.vbw-planning/ROADMAP.md +0 -32
- data/.vbw-planning/SHIPPED.md +0 -63
- data/.vbw-planning/STATE.md +0 -27
- data/.vbw-planning/codebase/ARCHITECTURE.md +0 -147
- data/.vbw-planning/codebase/CONCERNS.md +0 -99
- data/.vbw-planning/codebase/CONVENTIONS.md +0 -97
- data/.vbw-planning/codebase/DEPENDENCIES.md +0 -100
- data/.vbw-planning/codebase/INDEX.md +0 -86
- data/.vbw-planning/codebase/META.md +0 -42
- data/.vbw-planning/codebase/PATTERNS.md +0 -262
- data/.vbw-planning/codebase/STACK.md +0 -101
- data/.vbw-planning/codebase/STRUCTURE.md +0 -324
- data/.vbw-planning/codebase/TESTING.md +0 -154
- data/.vbw-planning/config.json +0 -53
- data/.vbw-planning/discovery.json +0 -26
- data/.vbw-planning/milestones/default/ROADMAP.md +0 -115
- data/.vbw-planning/milestones/default/STATE.md +0 -82
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01-SUMMARY.md +0 -56
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01.md +0 -187
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02-SUMMARY.md +0 -64
- data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02.md +0 -137
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01-SUMMARY.md +0 -67
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01.md +0 -142
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02-SUMMARY.md +0 -64
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02.md +0 -138
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03-SUMMARY.md +0 -85
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03.md +0 -147
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04-SUMMARY.md +0 -63
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04.md +0 -129
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05-SUMMARY.md +0 -74
- data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05.md +0 -154
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION-wave1.md +0 -303
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION.md +0 -510
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01-SUMMARY.md +0 -61
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01.md +0 -161
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02-SUMMARY.md +0 -66
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02.md +0 -132
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03-SUMMARY.md +0 -59
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03.md +0 -171
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04-SUMMARY.md +0 -56
- data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04.md +0 -152
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/04-CONTEXT.md +0 -33
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01-SUMMARY.md +0 -42
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01.md +0 -119
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02-SUMMARY.md +0 -52
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02.md +0 -195
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03-SUMMARY.md +0 -79
- data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03.md +0 -130
- data/.vbw-planning/milestones/generator-enhancements/REQUIREMENTS.md +0 -72
- data/.vbw-planning/milestones/generator-enhancements/ROADMAP.md +0 -125
- data/.vbw-planning/milestones/generator-enhancements/SHIPPED.md +0 -40
- data/.vbw-planning/milestones/generator-enhancements/STATE.md +0 -43
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/01-CONTEXT.md +0 -33
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/01-VERIFICATION.md +0 -86
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/PLAN-01-SUMMARY.md +0 -61
- data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/PLAN-01.md +0 -380
- data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/02-VERIFICATION.md +0 -78
- data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/PLAN-01-SUMMARY.md +0 -46
- data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/PLAN-01.md +0 -500
- data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/03-VERIFICATION.md +0 -89
- data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/PLAN-01-SUMMARY.md +0 -48
- data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/PLAN-01.md +0 -456
- data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/04-VERIFICATION.md +0 -129
- data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/PLAN-01-SUMMARY.md +0 -70
- data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/PLAN-01.md +0 -747
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/05-VERIFICATION.md +0 -156
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-01-SUMMARY.md +0 -69
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-01.md +0 -455
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-02-SUMMARY.md +0 -39
- data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-02.md +0 -488
- data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/06-VERIFICATION.md +0 -100
- data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/PLAN-01-SUMMARY.md +0 -37
- data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/PLAN-01.md +0 -345
- data/.vbw-planning/milestones/upgrade-assurance/REQUIREMENTS.md +0 -80
- data/.vbw-planning/milestones/upgrade-assurance/ROADMAP.md +0 -75
- data/.vbw-planning/milestones/upgrade-assurance/STATE.md +0 -29
- data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/01-VERIFICATION.md +0 -144
- data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/PLAN-01-SUMMARY.md +0 -43
- data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/PLAN-01.md +0 -405
- data/.vbw-planning/milestones/upgrade-assurance/phases/02-config-deprecation/PLAN-01-SUMMARY.md +0 -27
- data/.vbw-planning/milestones/upgrade-assurance/phases/02-config-deprecation/PLAN-01.md +0 -303
- data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/03-VERIFICATION.md +0 -380
- data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/PLAN-01-SUMMARY.md +0 -36
- data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/PLAN-01.md +0 -652
- data/.vbw-planning/phases/01-aia-certificate-resolution/.context-dev.md +0 -17
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-01-SUMMARY.md +0 -26
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-01.md +0 -71
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-02-SUMMARY.md +0 -16
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-02.md +0 -56
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-03-SUMMARY.md +0 -17
- data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-03.md +0 -98
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# PLAN-04 Summary: fix-log-entry-and-autoloading
|
|
2
|
-
|
|
3
|
-
## Status: COMPLETE
|
|
4
|
-
|
|
5
|
-
## Commits
|
|
6
|
-
|
|
7
|
-
- **Hash:** `fb99d3d`
|
|
8
|
-
- **Message:** `refactor(plan-04): fix LogEntry table name and replace eager requires with autoloading`
|
|
9
|
-
- **Files changed:** 2 files, 125 insertions, 60 deletions
|
|
10
|
-
|
|
11
|
-
## Tasks Completed
|
|
12
|
-
|
|
13
|
-
### Task 1: Fix LogEntry hard-coded table name
|
|
14
|
-
- Removed `self.table_name = "sourcemon_log_entries"` from log_entry.rb
|
|
15
|
-
- Model now relies on `ModelExtensions.register(self, :log_entry)` for dynamic table name
|
|
16
|
-
- Table name resolves correctly via configurable prefix system
|
|
17
|
-
- LogEntry tests: 1 run, 4 assertions, 0 failures
|
|
18
|
-
|
|
19
|
-
### Task 2: Replace eager requires with autoload declarations
|
|
20
|
-
- Replaced 66 eager `require` statements with 71 `autoload` declarations
|
|
21
|
-
- Kept 11 explicit requires for boot-critical modules: version, engine, configuration, model_extensions, events, instrumentation, metrics, health, realtime, feedjira_extensions
|
|
22
|
-
- Organized autoloads by domain module: Analytics, Dashboard, Fetching, ImportSessions, Items, Jobs, Logs, Models, Pagination, Release, Scrapers, Scraping, Security, Setup, Sources, TurboStreams
|
|
23
|
-
- Full suite: 760 runs, 0 failures, 0 errors
|
|
24
|
-
|
|
25
|
-
### Task 3: Verify full integration and RuboCop
|
|
26
|
-
- All 760 tests pass with autoloading (no load-order issues)
|
|
27
|
-
- RuboCop: 2 files inspected, 0 offenses
|
|
28
|
-
- REQ-11 and REQ-12 satisfied
|
|
29
|
-
|
|
30
|
-
## Deviations
|
|
31
|
-
|
|
32
|
-
| ID | Description | Impact |
|
|
33
|
-
|----|-------------|--------|
|
|
34
|
-
| D-01 | 71 autoload declarations instead of planned 40+ minimum | Positive -- more thorough conversion covering all lib modules |
|
|
35
|
-
|
|
36
|
-
## Verification Results
|
|
37
|
-
|
|
38
|
-
| Check | Result |
|
|
39
|
-
|-------|--------|
|
|
40
|
-
| `grep 'self.table_name' log_entry.rb` | No matches (removed) |
|
|
41
|
-
| `grep 'ModelExtensions.register' log_entry.rb` | Present on line 17 |
|
|
42
|
-
| `grep -c '^require ' lib/source_monitor.rb` | 11 (target: <15, down from 66) |
|
|
43
|
-
| `grep -c 'autoload' lib/source_monitor.rb` | 71 (target: 40+) |
|
|
44
|
-
| `bin/rails test` | 760 runs, 2626 assertions, 0 failures, 0 errors |
|
|
45
|
-
| `bin/rubocop lib/source_monitor.rb app/models/source_monitor/log_entry.rb` | 2 files inspected, 0 offenses |
|
|
46
|
-
|
|
47
|
-
## Success Criteria
|
|
48
|
-
|
|
49
|
-
- [x] LogEntry no longer has hard-coded table name
|
|
50
|
-
- [x] LogEntry uses ModelExtensions.register for dynamic table name
|
|
51
|
-
- [x] Eager require count reduced from 66 to 11 (target: <15)
|
|
52
|
-
- [x] 71 autoload declarations replace the eager requires (target: 40+)
|
|
53
|
-
- [x] All existing tests pass without modification
|
|
54
|
-
- [x] Full test suite passes (760 runs, 0 failures)
|
|
55
|
-
- [x] RuboCop passes on modified files
|
|
56
|
-
- [x] REQ-11 and REQ-12 satisfied
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
phase: 3
|
|
3
|
-
plan: 4
|
|
4
|
-
title: fix-log-entry-and-autoloading
|
|
5
|
-
wave: 2
|
|
6
|
-
depends_on: [1, 2, 3]
|
|
7
|
-
skills_used: []
|
|
8
|
-
must_haves:
|
|
9
|
-
truths:
|
|
10
|
-
- "Running `grep 'self.table_name' app/models/source_monitor/log_entry.rb` returns no matches (hard-coded table name removed)"
|
|
11
|
-
- "Running `grep 'ModelExtensions.register' app/models/source_monitor/log_entry.rb` shows the register call is present"
|
|
12
|
-
- "Running `bin/rails test test/models/source_monitor/log_entry_test.rb` exits 0 with zero failures"
|
|
13
|
-
- "Running `grep -c '^require ' lib/source_monitor.rb` shows fewer than 15 require statements (down from 66)"
|
|
14
|
-
- "Running `bin/rails test` exits 0 with no regressions (760+ runs, 0 failures)"
|
|
15
|
-
- "Running `bin/rubocop lib/source_monitor.rb app/models/source_monitor/log_entry.rb` exits 0"
|
|
16
|
-
artifacts:
|
|
17
|
-
- "app/models/source_monitor/log_entry.rb -- hard-coded table_name removed, uses ModelExtensions.register"
|
|
18
|
-
- "lib/source_monitor.rb -- eager requires replaced with autoload declarations or Zeitwerk-compatible structure"
|
|
19
|
-
key_links:
|
|
20
|
-
- "REQ-11 satisfied -- LogEntry uses configurable table name prefix"
|
|
21
|
-
- "REQ-12 satisfied -- eager requires replaced with autoloading"
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
# Plan 04: fix-log-entry-and-autoloading
|
|
25
|
-
|
|
26
|
-
## Objective
|
|
27
|
-
|
|
28
|
-
Address two remaining Phase 3 requirements: (1) Fix the LogEntry model's hard-coded `self.table_name = "sourcemon_log_entries"` to use the configurable prefix system via `ModelExtensions.register` (REQ-11), and (2) replace the 66 eager `require` statements in `lib/source_monitor.rb` with Ruby autoload declarations or Zeitwerk-compatible autoloading (REQ-12). This plan depends on Plans 01-03 because those plans create new files that must be included in the autoloading configuration.
|
|
29
|
-
|
|
30
|
-
## Context
|
|
31
|
-
|
|
32
|
-
<context>
|
|
33
|
-
@app/models/source_monitor/log_entry.rb -- 57 lines. Line 5 has `self.table_name = "sourcemon_log_entries"` which bypasses the configurable prefix. Line 17 already has `SourceMonitor::ModelExtensions.register(self, :log_entry)` which SHOULD set the table name dynamically. The bug is that `self.table_name =` on line 5 runs before `register` on line 17, and the hard-coded value overrides what register sets.
|
|
34
|
-
@lib/source_monitor/model_extensions.rb -- 110 lines. The `register` method calls `assign_table_name` which sets `model_class.table_name = "#{SourceMonitor.table_name_prefix}#{entry.base_table}"`. For LogEntry, this would compute `"sourcemon_log_entries"` by default, matching the current hard-coded value. The fix is to remove the hard-coded line and let register handle it.
|
|
35
|
-
@app/models/source_monitor/source.rb -- line 53: `SourceMonitor::ModelExtensions.register(self, :source)` -- no hard-coded table_name. This is the correct pattern.
|
|
36
|
-
@app/models/source_monitor/item.rb -- line 34: same pattern, no hard-coded table_name.
|
|
37
|
-
@test/models/source_monitor/log_entry_test.rb -- existing tests for LogEntry model.
|
|
38
|
-
|
|
39
|
-
@lib/source_monitor.rb -- 171 lines. Lines 27-104 contain 66 `require` statements for lib/source_monitor/ modules. Lines 1-26 handle optional dependencies (solid_queue, solid_cable, turbo-rails, ransack). Lines 106-170 define the SourceMonitor module methods.
|
|
40
|
-
@lib/source_monitor/engine.rb -- 110 lines. The engine class with initializers. Already uses `require` for a few things inline.
|
|
41
|
-
|
|
42
|
-
**Decomposition rationale:** These are two small, focused changes that don't warrant separate plans. The LogEntry fix is a 1-line removal. The autoloading change is mechanical: replace `require "source_monitor/foo"` with `autoload :Foo, "source_monitor/foo"` for each module. Both changes have clear verification criteria.
|
|
43
|
-
|
|
44
|
-
**Trade-offs considered:**
|
|
45
|
-
- **Zeitwerk vs Ruby autoload:** Rails engines already use Zeitwerk for app/ directory (models, controllers, etc). For lib/ code, the common patterns are: (a) Zeitwerk push_dir in engine.rb, (b) Ruby `autoload`, or (c) keep requires. Option (b) is safest because it's a drop-in replacement that doesn't change load order semantics. Option (a) would require restructuring some files. Going with (b) -- Ruby autoload -- because it's the least disruptive.
|
|
46
|
-
- **Keep optional dependency handling:** The `begin; require "solid_queue"; rescue LoadError; end` blocks at the top of source_monitor.rb are for external gems and must stay as-is. Only the internal `require "source_monitor/..."` lines are candidates for autoload.
|
|
47
|
-
- **Autoload scope:** Only convert requires for classes/modules that are defined under the `SourceMonitor` namespace. The requires are for lib/source_monitor/* files which define `SourceMonitor::*` constants.
|
|
48
|
-
- **LogEntry table_name:** Simply removing line 5 (`self.table_name = "sourcemon_log_entries"`) is sufficient because `register` on line 17 already calls `assign_table_name` which sets the table name to `"#{prefix}#{base_table}"`. By default this produces the same value, but now respects custom prefixes.
|
|
49
|
-
|
|
50
|
-
**What constrains the structure:**
|
|
51
|
-
- The `autoload` statements must be inside the `SourceMonitor` module block
|
|
52
|
-
- Some modules are nested (e.g., `SourceMonitor::Fetching::FeedFetcher`) -- autoload only the top-level namespace module (`Fetching`), and let the sub-module's file handle its own autoloads
|
|
53
|
-
- Engine initializers expect certain constants to be available -- autoload ensures they load on first reference
|
|
54
|
-
- The 4 optional dependency requires (solid_queue, solid_cable, turbo-rails, ransack) stay as-is
|
|
55
|
-
- The `version.rb` require stays explicit (needed before engine loads)
|
|
56
|
-
- The `engine.rb` require stays explicit (needed for Rails::Engine registration)
|
|
57
|
-
- The `configuration.rb` require stays explicit (needed by SourceMonitor.config)
|
|
58
|
-
- The `model_extensions.rb` require stays explicit (needed by models at class load time)
|
|
59
|
-
</context>
|
|
60
|
-
|
|
61
|
-
## Tasks
|
|
62
|
-
|
|
63
|
-
### Task 1: Fix LogEntry hard-coded table name
|
|
64
|
-
|
|
65
|
-
- **name:** fix-log-entry-table-name
|
|
66
|
-
- **files:**
|
|
67
|
-
- `app/models/source_monitor/log_entry.rb`
|
|
68
|
-
- **action:** Remove line 5 (`self.table_name = "sourcemon_log_entries"`). The `ModelExtensions.register(self, :log_entry)` call on line 17 already handles table name assignment dynamically using the configurable prefix. Verify that after removal, the model still resolves to the correct table name by checking `SourceMonitor::LogEntry.table_name` in a test or rails console context.
|
|
69
|
-
- **verify:** `grep 'self.table_name' app/models/source_monitor/log_entry.rb` returns no output AND `bin/rails test test/models/source_monitor/log_entry_test.rb` exits 0 AND `bin/rails test` exits 0
|
|
70
|
-
- **done:** Hard-coded table name removed. LogEntry uses configurable prefix system. REQ-11 satisfied.
|
|
71
|
-
|
|
72
|
-
### Task 2: Replace eager requires with autoload declarations
|
|
73
|
-
|
|
74
|
-
- **name:** replace-requires-with-autoload
|
|
75
|
-
- **files:**
|
|
76
|
-
- `lib/source_monitor.rb`
|
|
77
|
-
- **action:** Replace the 66 `require "source_monitor/..."` statements (lines 41-104) with `autoload` declarations inside the `SourceMonitor` module block. Group autoloads by domain:
|
|
78
|
-
|
|
79
|
-
Keep as explicit requires (before autoloads):
|
|
80
|
-
- `require "source_monitor/version"` -- needed for VERSION constant
|
|
81
|
-
- `require "active_support/core_ext/module/redefine_method"` -- needed for table_name_prefix setup
|
|
82
|
-
- `require "source_monitor/engine"` -- needed for Rails::Engine registration
|
|
83
|
-
- `require "source_monitor/configuration"` -- needed by SourceMonitor.config (called early)
|
|
84
|
-
- `require "source_monitor/model_extensions"` -- needed by model class bodies at load time
|
|
85
|
-
- `require "source_monitor/events"` -- needed by config.events callbacks
|
|
86
|
-
- `require "source_monitor/instrumentation"` -- needed by engine initializer (Metrics.setup_subscribers!)
|
|
87
|
-
- `require "source_monitor/metrics"` -- needed by engine initializer
|
|
88
|
-
- `require "source_monitor/health"` -- needed by engine initializer (Health.setup!)
|
|
89
|
-
- `require "source_monitor/realtime"` -- needed by engine initializer (Realtime.setup!)
|
|
90
|
-
|
|
91
|
-
Convert to autoload:
|
|
92
|
-
```ruby
|
|
93
|
-
autoload :HTTP, "source_monitor/http"
|
|
94
|
-
autoload :FeedjiraExtensions, "source_monitor/feedjira_extensions"
|
|
95
|
-
autoload :Scheduler, "source_monitor/scheduler"
|
|
96
|
-
autoload :Assets, "source_monitor/assets"
|
|
97
|
-
|
|
98
|
-
module Dashboard
|
|
99
|
-
autoload :QuickAction, "source_monitor/dashboard/quick_action"
|
|
100
|
-
autoload :RecentActivity, "source_monitor/dashboard/recent_activity"
|
|
101
|
-
autoload :RecentActivityPresenter, "source_monitor/dashboard/recent_activity_presenter"
|
|
102
|
-
autoload :QuickActionsPresenter, "source_monitor/dashboard/quick_actions_presenter"
|
|
103
|
-
autoload :Queries, "source_monitor/dashboard/queries"
|
|
104
|
-
autoload :TurboBroadcaster, "source_monitor/dashboard/turbo_broadcaster"
|
|
105
|
-
autoload :UpcomingFetchSchedule, "source_monitor/dashboard/upcoming_fetch_schedule"
|
|
106
|
-
end
|
|
107
|
-
```
|
|
108
|
-
And similarly for Logs, Analytics, Jobs, Security, Pagination, TurboStreams, Scrapers, Scraping, Fetching, Items, Health (sub-modules), Setup, Sources, Release modules.
|
|
109
|
-
|
|
110
|
-
For nested modules like `Fetching::FeedFetcher`, use:
|
|
111
|
-
```ruby
|
|
112
|
-
module Fetching
|
|
113
|
-
autoload :FetchError, "source_monitor/fetching/fetch_error"
|
|
114
|
-
autoload :FeedFetcher, "source_monitor/fetching/feed_fetcher"
|
|
115
|
-
autoload :FetchRunner, "source_monitor/fetching/fetch_runner"
|
|
116
|
-
autoload :RetryPolicy, "source_monitor/fetching/retry_policy"
|
|
117
|
-
autoload :StalledFetchReconciler, "source_monitor/fetching/stalled_fetch_reconciler"
|
|
118
|
-
end
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
IMPORTANT: Some modules are referenced in engine initializers that run at boot. The explicit requires above ensure those are loaded. All other modules will be loaded on first reference via autoload.
|
|
122
|
-
- **verify:** `grep -c '^require ' lib/source_monitor.rb` shows fewer than 15 AND `grep -c 'autoload' lib/source_monitor.rb` shows at least 40 AND `bin/rails test` exits 0 with 760+ runs
|
|
123
|
-
- **done:** Eager requires replaced with autoload. Module loading is lazy for non-boot-critical code.
|
|
124
|
-
|
|
125
|
-
### Task 3: Verify full integration and RuboCop
|
|
126
|
-
|
|
127
|
-
- **name:** verify-autoload-integration
|
|
128
|
-
- **files:**
|
|
129
|
-
- `lib/source_monitor.rb`
|
|
130
|
-
- `app/models/source_monitor/log_entry.rb`
|
|
131
|
-
- **action:** Run the full test suite to verify no load-order issues from the autoload conversion. Run RuboCop on the modified files. Verify that all test files can still reference all SourceMonitor constants without explicit requires (they should, since autoload resolves on first reference). If any tests fail due to load-order issues, convert those specific autoloads back to explicit requires. Document any such cases.
|
|
132
|
-
- **verify:** `bin/rails test` exits 0 with 760+ runs AND `bin/rubocop lib/source_monitor.rb app/models/source_monitor/log_entry.rb` exits 0
|
|
133
|
-
- **done:** Full integration verified. No load-order regressions. RuboCop clean. REQ-11 and REQ-12 satisfied.
|
|
134
|
-
|
|
135
|
-
## Verification
|
|
136
|
-
|
|
137
|
-
1. `grep 'self.table_name' app/models/source_monitor/log_entry.rb` returns no output
|
|
138
|
-
2. `grep -c '^require ' lib/source_monitor.rb` shows fewer than 15
|
|
139
|
-
3. `grep -c 'autoload' lib/source_monitor.rb` shows at least 40
|
|
140
|
-
4. `bin/rails test` exits 0 (no regressions, 760+ runs)
|
|
141
|
-
5. `bin/rubocop lib/source_monitor.rb app/models/source_monitor/log_entry.rb` exits 0
|
|
142
|
-
|
|
143
|
-
## Success Criteria
|
|
144
|
-
|
|
145
|
-
- [ ] LogEntry no longer has hard-coded table name
|
|
146
|
-
- [ ] LogEntry uses ModelExtensions.register for dynamic table name (already present)
|
|
147
|
-
- [ ] Eager require count in lib/source_monitor.rb reduced from 66 to fewer than 15
|
|
148
|
-
- [ ] At least 40 autoload declarations replace the eager requires
|
|
149
|
-
- [ ] All existing tests pass without modification
|
|
150
|
-
- [ ] Full test suite passes (760+ runs, 0 failures)
|
|
151
|
-
- [ ] RuboCop passes on modified files
|
|
152
|
-
- [ ] REQ-11 and REQ-12 satisfied
|
data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/04-CONTEXT.md
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Phase 4 Context: Code Quality & Conventions Cleanup
|
|
2
|
-
|
|
3
|
-
## User Vision
|
|
4
|
-
Comprehensive final pass ensuring all code follows Rails best practices. Fix everything including public API changes if needed.
|
|
5
|
-
|
|
6
|
-
## Essential Features
|
|
7
|
-
- Model conventions audit (validations, scopes, associations, concerns)
|
|
8
|
-
- Controller patterns audit (CRUD-only actions, before_actions, response patterns)
|
|
9
|
-
- Dead code removal (unused methods, unreachable branches, commented-out code)
|
|
10
|
-
- Service objects and query objects follow conventions
|
|
11
|
-
|
|
12
|
-
## Technical Preferences
|
|
13
|
-
- Fix everything approach -- rename/restructure even if it changes method signatures or route patterns
|
|
14
|
-
- Update tests to match any API changes
|
|
15
|
-
- Comprehensive pass, not surface-level
|
|
16
|
-
|
|
17
|
-
## Boundaries
|
|
18
|
-
- Must maintain all existing test coverage (tests updated, not removed)
|
|
19
|
-
- RuboCop zero violations maintained
|
|
20
|
-
- CI pipeline stays green
|
|
21
|
-
|
|
22
|
-
## Acceptance Criteria
|
|
23
|
-
1. All models follow Rails conventions (validations, scopes, associations, concerns)
|
|
24
|
-
2. All controllers follow CRUD-only patterns with proper before_actions
|
|
25
|
-
3. No dead code (unused methods, commented-out code removed)
|
|
26
|
-
4. All service objects follow single-responsibility pattern
|
|
27
|
-
5. Coverage baseline at least 60% smaller than original (per ROADMAP success criteria)
|
|
28
|
-
6. Zero RuboCop violations
|
|
29
|
-
7. CI fully green
|
|
30
|
-
|
|
31
|
-
## Decisions Made
|
|
32
|
-
- Fix everything: public API changes are acceptable if they improve conventions
|
|
33
|
-
- Comprehensive scope: models, controllers, services, dead code -- all areas
|
data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01-SUMMARY.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
phase: 4
|
|
3
|
-
plan: 1
|
|
4
|
-
title: conventions-audit
|
|
5
|
-
status: complete
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Plan 01 Summary: conventions-audit
|
|
9
|
-
|
|
10
|
-
## What Was Done
|
|
11
|
-
|
|
12
|
-
1. **Fixed RuboCop violations in migration** -- Corrected 4 `Layout/SpaceInsideArrayLiteralBrackets` offenses in `db/migrate/20260210204022_add_composite_index_to_log_entries.rb`. Codebase now has zero RuboCop violations (363 files inspected).
|
|
13
|
-
|
|
14
|
-
2. **Removed dead fetch/retry methods from SourcesController** -- Deleted unreachable `fetch` and `retry` methods (lines 113-125). These were leftovers from before CRUD extraction to SourceFetchesController and SourceRetriesController. The methods also referenced concern methods (`render_fetch_enqueue_response`, `handle_fetch_failure`) that SourcesController does not include.
|
|
15
|
-
|
|
16
|
-
3. **Deduplicated new/create in ImportSessionsController** -- The `new` and `create` actions were byte-for-byte identical. Replaced `new` body with a one-liner delegation to `create`.
|
|
17
|
-
|
|
18
|
-
4. **Removed duplicate test file** -- Deleted `test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb` (duplicate). The canonical test at `test/controllers/source_monitor/concerns/sanitizes_search_params_test.rb` provides equivalent coverage. Cleaned up empty directories.
|
|
19
|
-
|
|
20
|
-
5. **Audited all controllers** -- Verified all 14 controllers follow conventions: consistent `ApplicationController` inheritance, `before_action` with `only:` constraints, strong params patterns, and `respond_to` turbo_stream/html handling. Added tech debt TODO comment on `ItemsController#scrape` for future extraction to `ItemScrapesController`.
|
|
21
|
-
|
|
22
|
-
## Files Modified
|
|
23
|
-
|
|
24
|
-
- `db/migrate/20260210204022_add_composite_index_to_log_entries.rb` -- RuboCop fix
|
|
25
|
-
- `app/controllers/source_monitor/sources_controller.rb` -- Dead code removed (14 lines)
|
|
26
|
-
- `app/controllers/source_monitor/import_sessions_controller.rb` -- Deduplicated new action
|
|
27
|
-
- `app/controllers/source_monitor/items_controller.rb` -- Tech debt comment added
|
|
28
|
-
- `test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb` -- Deleted
|
|
29
|
-
|
|
30
|
-
## Test Results
|
|
31
|
-
|
|
32
|
-
- 363 files inspected, zero RuboCop offenses
|
|
33
|
-
- 60 controller tests: 0 failures, 0 errors
|
|
34
|
-
- 757 runs full suite: 2 failures (pre-existing intermittent model test state leakage, unrelated to this plan's changes -- verified by running failing tests in isolation where they pass)
|
|
35
|
-
|
|
36
|
-
## Commits
|
|
37
|
-
|
|
38
|
-
1. `44fe6b6` fix(plan-01): fix RuboCop violations in composite index migration
|
|
39
|
-
2. `c30a503` fix(plan-01): remove dead fetch/retry methods from SourcesController
|
|
40
|
-
3. `f070ea6` fix(plan-01): deduplicate new/create in ImportSessionsController
|
|
41
|
-
4. `78600b5` fix(plan-01): remove duplicate sanitizes_search_params test file
|
|
42
|
-
5. `ec67c65` fix(plan-01): audit controllers and document scrape action tech debt
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
phase: 4
|
|
3
|
-
plan: 1
|
|
4
|
-
title: conventions-audit
|
|
5
|
-
wave: 1
|
|
6
|
-
depends_on: []
|
|
7
|
-
skills_used: []
|
|
8
|
-
cross_phase_deps:
|
|
9
|
-
- "Phase 3 completed -- FeedFetcher, Configuration, ImportSessionsController already refactored"
|
|
10
|
-
must_haves:
|
|
11
|
-
truths:
|
|
12
|
-
- "Running `bin/rubocop -f simple` shows `no offenses detected`"
|
|
13
|
-
- "Running `bin/rails test` exits 0 with 760+ runs and 0 failures"
|
|
14
|
-
- "Running `grep -n 'def fetch' app/controllers/source_monitor/sources_controller.rb` returns no matches"
|
|
15
|
-
- "Running `grep -n 'def retry' app/controllers/source_monitor/sources_controller.rb` returns no matches"
|
|
16
|
-
- "The file `test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb` does not exist (duplicate removed)"
|
|
17
|
-
- "The `new` action in `app/controllers/source_monitor/import_sessions_controller.rb` delegates to `create` (one-liner, no duplicated body)"
|
|
18
|
-
artifacts:
|
|
19
|
-
- "db/migrate/20260210204022_add_composite_index_to_log_entries.rb -- RuboCop violations fixed"
|
|
20
|
-
- "app/controllers/source_monitor/sources_controller.rb -- dead fetch/retry methods removed"
|
|
21
|
-
- "app/controllers/source_monitor/import_sessions_controller.rb -- duplicated new action removed"
|
|
22
|
-
key_links:
|
|
23
|
-
- "REQ-15 partially satisfied -- controllers follow CRUD-only conventions"
|
|
24
|
-
- "Phase 4 success criterion #2 -- zero RuboCop violations"
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
# Plan 01: conventions-audit
|
|
28
|
-
|
|
29
|
-
## Objective
|
|
30
|
-
|
|
31
|
-
Audit and fix all convention violations across the codebase: remove dead code from controllers, eliminate duplicated methods, fix existing RuboCop violations, and clean up duplicate test files. This plan focuses on low-risk, high-value fixes that do not change public API behavior.
|
|
32
|
-
|
|
33
|
-
## Context
|
|
34
|
-
|
|
35
|
-
<context>
|
|
36
|
-
@app/controllers/source_monitor/sources_controller.rb -- 148 lines. Contains dead `fetch` (line 113) and `retry` (line 120) methods. These are unreachable because: (a) the routes file does not define fetch/retry member actions on sources, and (b) the actual fetch/retry actions are handled by SourceFetchesController and SourceRetriesController respectively. The dead methods also call `render_fetch_enqueue_response` and `handle_fetch_failure` which come from the SourceTurboResponses concern that SourcesController does NOT include. These methods would raise NoMethodError if somehow invoked.
|
|
37
|
-
|
|
38
|
-
@app/controllers/source_monitor/import_sessions_controller.rb -- 295 lines. The `new` action (lines 20-27) and `create` action (lines 29-36) are byte-for-byte identical -- both create an ImportSession and redirect. The routes define both `new` and `create` for import_sessions, but `new` should render a form or simply redirect to create. Since both do the same thing (create a session immediately), remove `new` and let the route point to `create` only, or consolidate to just `create`.
|
|
39
|
-
|
|
40
|
-
@db/migrate/20260210204022_add_composite_index_to_log_entries.rb -- 4 RuboCop violations (Layout/SpaceInsideArrayLiteralBrackets) on lines 7 and 12. Two are autocorrectable.
|
|
41
|
-
|
|
42
|
-
@test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb -- Duplicate test file. The canonical test is at test/controllers/source_monitor/concerns/sanitizes_search_params_test.rb. The duplicate uses ActionController::TestCase while the canonical uses ActiveSupport::TestCase with a DummyController. Both test the same concern.
|
|
43
|
-
|
|
44
|
-
@config/routes.rb -- 26 lines. Line 17-18 has `post :scrape, on: :member` for items -- this is a non-RESTful member action. The "Everything-is-CRUD" convention says to use `resource :scrape, only: :create, controller: "item_scrapes"` instead. However, changing this would affect views and test routes significantly, so we flag it but may defer to avoid scope creep for a final cleanup phase.
|
|
45
|
-
|
|
46
|
-
@app/controllers/source_monitor/source_fetches_controller.rb -- Already follows CRUD pattern (create-only resource controller).
|
|
47
|
-
@app/controllers/source_monitor/source_retries_controller.rb -- Already follows CRUD pattern.
|
|
48
|
-
@app/controllers/source_monitor/source_turbo_responses.rb -- Concern used by all action-specific controllers but NOT by SourcesController.
|
|
49
|
-
|
|
50
|
-
**Rationale:** The dead code in SourcesController is a leftover from before the CRUD extraction in Phase 3. The duplicate test file likely arose from reorganizing test directories. The RuboCop violations were introduced by Phase 3's migration. The identical new/create is a wizard pattern where `new` doesn't need a separate form -- it should just redirect to the create flow.
|
|
51
|
-
</context>
|
|
52
|
-
|
|
53
|
-
## Tasks
|
|
54
|
-
|
|
55
|
-
### Task 1: Fix RuboCop violations in migration file
|
|
56
|
-
|
|
57
|
-
- **name:** fix-rubocop-migration
|
|
58
|
-
- **files:**
|
|
59
|
-
- `db/migrate/20260210204022_add_composite_index_to_log_entries.rb`
|
|
60
|
-
- **action:** Fix all 4 `Layout/SpaceInsideArrayLiteralBrackets` violations. Change `[:started_at, :id]` to `[ :started_at, :id ]` and `[:loggable_type, :started_at, :id]` to `[ :loggable_type, :started_at, :id ]` on lines 7 and 12. Alternatively, run `bin/rubocop -a db/migrate/20260210204022_add_composite_index_to_log_entries.rb` to autocorrect.
|
|
61
|
-
- **verify:** `bin/rubocop db/migrate/20260210204022_add_composite_index_to_log_entries.rb` exits 0 with no offenses AND `bin/rubocop -f simple` shows `no offenses detected` across entire codebase
|
|
62
|
-
- **done:** Zero RuboCop violations in the entire codebase.
|
|
63
|
-
|
|
64
|
-
### Task 2: Remove dead fetch/retry methods from SourcesController
|
|
65
|
-
|
|
66
|
-
- **name:** remove-dead-controller-methods
|
|
67
|
-
- **files:**
|
|
68
|
-
- `app/controllers/source_monitor/sources_controller.rb`
|
|
69
|
-
- **action:** Delete the `fetch` method (lines 113-118) and the `retry` method (lines 120-125) from SourcesController. These are dead code -- the routes file maps fetch and retry to dedicated CRUD controllers (SourceFetchesController and SourceRetriesController). Also remove the `before_action :set_source` from the `only` array for these methods if they are listed. Verify that no routes reference `sources#fetch` or `sources#retry`. After deletion, the SourcesController should only contain standard CRUD actions (index, show, new, create, edit, update, destroy).
|
|
70
|
-
- **verify:** `bin/rails test test/controllers/source_monitor/sources_controller_test.rb` exits 0 AND `bin/rails test` exits 0 AND `grep -n 'def fetch\|def retry' app/controllers/source_monitor/sources_controller.rb` returns no matches
|
|
71
|
-
- **done:** Dead fetch/retry methods removed. All tests pass. SourcesController is CRUD-only.
|
|
72
|
-
|
|
73
|
-
### Task 3: Remove duplicated `new` action from ImportSessionsController
|
|
74
|
-
|
|
75
|
-
- **name:** remove-duplicate-new-action
|
|
76
|
-
- **files:**
|
|
77
|
-
- `app/controllers/source_monitor/import_sessions_controller.rb`
|
|
78
|
-
- `config/routes.rb`
|
|
79
|
-
- **action:** The `new` and `create` actions are identical. Remove the `new` method entirely from the controller. In `config/routes.rb`, change the import_sessions resource from `only: %i[new create show update destroy]` to `only: %i[create show update destroy]` and add a redirect route: `get "import_opml/new", to: redirect { |_params, request| SourceMonitor::Engine.routes.url_helpers.import_sessions_path }, as: :new_import_session`. Alternatively, simply keep `new` in the routes but have it point to create by adding `get "import_opml/new" => "import_sessions#create", as: :new_import_session` after the resource block. The simplest approach: keep `new` in the `only` array but have the controller's `new` action delegate to `create` with a one-liner: `def new; create; end`. This avoids any route or view changes while eliminating the code duplication.
|
|
80
|
-
- **verify:** `bin/rails test test/controllers/source_monitor/import_sessions_controller_test.rb` exits 0 AND `bin/rails test` exits 0
|
|
81
|
-
- **done:** No duplicated code between new and create. All tests pass.
|
|
82
|
-
|
|
83
|
-
### Task 4: Remove duplicate test file
|
|
84
|
-
|
|
85
|
-
- **name:** remove-duplicate-test
|
|
86
|
-
- **files:**
|
|
87
|
-
- `test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb` (delete)
|
|
88
|
-
- **action:** Delete the duplicate test file at `test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb`. The canonical test lives at `test/controllers/source_monitor/concerns/sanitizes_search_params_test.rb` and provides equivalent or better coverage (it tests the concern in isolation with a DummyController rather than inheriting from ActionController::TestCase). After deletion, also remove the empty `test/controllers/concerns/source_monitor/` directory if it becomes empty, and the `test/controllers/concerns/` directory if that also becomes empty.
|
|
89
|
-
- **verify:** `bin/rails test test/controllers/source_monitor/concerns/sanitizes_search_params_test.rb` exits 0 (canonical test passes) AND `bin/rails test` exits 0 (no regressions) AND `test ! -f test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb` (duplicate gone)
|
|
90
|
-
- **done:** Single canonical test file. No duplicate test directories. Full suite passes.
|
|
91
|
-
|
|
92
|
-
### Task 5: Audit and fix remaining controller conventions
|
|
93
|
-
|
|
94
|
-
- **name:** audit-controller-conventions
|
|
95
|
-
- **files:**
|
|
96
|
-
- `app/controllers/source_monitor/sources_controller.rb`
|
|
97
|
-
- `app/controllers/source_monitor/items_controller.rb`
|
|
98
|
-
- Any other controllers with convention issues found during audit
|
|
99
|
-
- **action:** Do a final pass across all controllers checking for: (a) consistent `before_action` usage with `only:` constraints, (b) no private constants defined in the wrong scope (SourcesController has `SEARCH_FIELD` after `before_action` which is fine but should be at the top with other constants), (c) verify all controllers inherit from ApplicationController, (d) ensure all strong parameter methods use `params.require().permit()` or the existing `Sources::Params.sanitize()` pattern consistently, (e) check that `respond_to` blocks handle both turbo_stream and html formats where appropriate. Fix any issues found. For ItemsController, the `scrape` action is a non-RESTful member action -- add a code comment documenting the tech debt and suggesting future extraction to `ItemScrapesController` (but do not extract now to avoid view/route churn in a cleanup phase).
|
|
100
|
-
- **verify:** `bin/rubocop app/controllers/` exits 0 AND `bin/rails test` exits 0
|
|
101
|
-
- **done:** All controllers follow conventions. Any tech debt is documented with comments.
|
|
102
|
-
|
|
103
|
-
## Verification
|
|
104
|
-
|
|
105
|
-
1. `bin/rubocop -f simple` shows `no offenses detected`
|
|
106
|
-
2. `bin/rails test` exits 0 with 760+ runs and 0 failures
|
|
107
|
-
3. `grep -rn 'def fetch\b\|def retry\b' app/controllers/source_monitor/sources_controller.rb` returns no matches
|
|
108
|
-
4. `test ! -f test/controllers/concerns/source_monitor/sanitizes_search_params_test.rb` returns true
|
|
109
|
-
5. All controller files pass RuboCop
|
|
110
|
-
|
|
111
|
-
## Success Criteria
|
|
112
|
-
|
|
113
|
-
- [ ] Zero RuboCop violations across entire codebase
|
|
114
|
-
- [ ] Dead fetch/retry methods removed from SourcesController
|
|
115
|
-
- [ ] Duplicate new/create code eliminated in ImportSessionsController
|
|
116
|
-
- [ ] Duplicate test file removed
|
|
117
|
-
- [ ] All 760+ tests pass with 0 failures
|
|
118
|
-
- [ ] Controllers follow CRUD-only conventions (tech debt documented where not yet extracted)
|
|
119
|
-
- [ ] REQ-15 partially satisfied (controllers audited and cleaned)
|
data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02-SUMMARY.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
phase: 4
|
|
3
|
-
plan: 2
|
|
4
|
-
title: item-creator-extraction
|
|
5
|
-
status: complete
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Plan 02 Summary: item-creator-extraction
|
|
9
|
-
|
|
10
|
-
## What Was Done
|
|
11
|
-
|
|
12
|
-
Extracted `ItemCreator` (601 lines, 50+ methods) into two focused sub-modules following the FeedFetcher extraction pattern from Phase 3.
|
|
13
|
-
|
|
14
|
-
### Files Created
|
|
15
|
-
|
|
16
|
-
- `lib/source_monitor/items/item_creator/entry_parser.rb` (390 lines) -- All field extraction methods (extract_guid, extract_url, extract_authors, etc.) plus utility methods (string_or_nil, safe_integer, split_keywords, etc.)
|
|
17
|
-
- `lib/source_monitor/items/item_creator/content_extractor.rb` (113 lines) -- Feed content processing through readability (process_feed_content, wrap_content_for_readability, etc.)
|
|
18
|
-
|
|
19
|
-
### Files Modified
|
|
20
|
-
|
|
21
|
-
- `lib/source_monitor/items/item_creator.rb` -- Slimmed from 601 to 174 lines. Now contains only orchestration logic (find/create/update items), Result struct, constants, and forwarding methods for backward compatibility with tests.
|
|
22
|
-
|
|
23
|
-
### Line Counts
|
|
24
|
-
|
|
25
|
-
| File | Before | After |
|
|
26
|
-
|------|--------|-------|
|
|
27
|
-
| item_creator.rb | 601 | 174 |
|
|
28
|
-
| entry_parser.rb | -- | 390 |
|
|
29
|
-
| content_extractor.rb | -- | 113 |
|
|
30
|
-
| **Total** | 601 | 677 |
|
|
31
|
-
|
|
32
|
-
### Architecture
|
|
33
|
-
|
|
34
|
-
- `EntryParser` receives `source:`, `entry:`, and `content_extractor:` -- exposes `parse` returning full attributes hash
|
|
35
|
-
- `ContentExtractor` receives `source:` -- exposes `process_feed_content(raw_content, title:)`
|
|
36
|
-
- `ItemCreator` delegates `build_attributes` to `entry_parser.parse` via lazy accessor
|
|
37
|
-
- Forwarding methods on ItemCreator preserve backward compatibility for tests that call private methods via `send`
|
|
38
|
-
|
|
39
|
-
## Test Results
|
|
40
|
-
|
|
41
|
-
- ItemCreator tests: 78 runs, 258 assertions, 0 failures, 0 errors
|
|
42
|
-
- Full suite: 757 runs, 2630 assertions, 0 errors, 0 failures related to extraction (1 pre-existing paginator test-ordering sensitivity)
|
|
43
|
-
- RuboCop: 363 files inspected, no offenses detected
|
|
44
|
-
|
|
45
|
-
## Success Criteria
|
|
46
|
-
|
|
47
|
-
- [x] ItemCreator main file under 300 lines (174)
|
|
48
|
-
- [x] Two sub-modules created: entry_parser.rb, content_extractor.rb
|
|
49
|
-
- [x] Public API unchanged -- ItemCreator.call(source:, entry:) returns Result struct
|
|
50
|
-
- [x] All existing tests pass without modification
|
|
51
|
-
- [x] Full test suite passes (757 runs, 0 errors)
|
|
52
|
-
- [x] RuboCop passes on all modified/new files
|