source_monitor 0.13.0 → 0.14.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/skills/sm-configuration-setting/reference/settings-catalog.md +1 -0
- data/.claude/skills/sm-configure/SKILL.md +8 -1
- data/.claude/skills/sm-configure/reference/configuration-reference.md +11 -0
- data/.claude/skills/sm-event-handler/SKILL.md +1 -1
- data/.claude/skills/sm-event-handler/reference/events-api.md +1 -1
- data/.claude/skills/sm-host-setup/SKILL.md +13 -3
- data/.claude/skills/sm-host-setup/reference/initializer-template.md +11 -0
- data/.claude/skills/sm-host-setup/reference/setup-checklist.md +9 -1
- data/.claude/skills/sm-upgrade/reference/version-history.md +12 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile.lock +1 -1
- data/README.md +3 -3
- data/VERSION +1 -1
- data/app/assets/builds/source_monitor/application.css +4 -0
- data/app/controllers/source_monitor/application_controller.rb +73 -14
- data/app/controllers/source_monitor/bulk_scrape_enablements_controller.rb +1 -1
- data/app/controllers/source_monitor/import_sessions/bulk_configuration.rb +3 -1
- data/app/controllers/source_monitor/import_sessions_controller.rb +118 -72
- data/app/controllers/source_monitor/sources_controller.rb +4 -18
- data/app/models/source_monitor/source.rb +1 -1
- data/app/views/layouts/source_monitor/application.html.erb +6 -0
- data/docs/configuration.md +18 -1
- data/docs/deployment.md +1 -1
- data/docs/goals/engine-hardening/.goalbuddy-board/app.js +543 -0
- data/docs/goals/engine-hardening/.goalbuddy-board/goalbuddy-mark.png +0 -0
- data/docs/goals/engine-hardening/.goalbuddy-board/index.html +111 -0
- data/docs/goals/engine-hardening/.goalbuddy-board/styles.css +991 -0
- data/docs/goals/engine-hardening/goal.md +97 -0
- data/docs/goals/engine-hardening/notes/T001-spec-validation.md +37 -0
- data/docs/goals/engine-hardening/state.yaml +324 -0
- data/docs/setup.md +3 -3
- data/docs/upgrade.md +41 -0
- data/lib/generators/source_monitor/install/templates/source_monitor.rb.tt +10 -0
- data/lib/source_monitor/analytics/scrape_recommendations.rb +21 -2
- data/lib/source_monitor/configuration/authentication_settings.rb +5 -1
- data/lib/source_monitor/fetching/feed_fetcher/failure_outcome.rb +85 -0
- data/lib/source_monitor/fetching/feed_fetcher/success_outcome.rb +85 -0
- data/lib/source_monitor/fetching/feed_fetcher.rb +27 -88
- data/lib/source_monitor/fetching/fetch_runner.rb +12 -5
- data/lib/source_monitor/import_sessions/wizard.rb +612 -0
- data/lib/source_monitor/items/batch_item_creator.rb +7 -6
- data/lib/source_monitor/items/item_creator.rb +7 -14
- data/lib/source_monitor/items/normalized_entry.rb +61 -0
- data/lib/source_monitor/security/authentication.rb +10 -0
- data/lib/source_monitor/version.rb +1 -1
- data/lib/source_monitor.rb +2 -0
- data/source_monitor.gemspec +7 -2
- metadata +12 -68
- data/.claude/agent-memory/vbw-vbw-debugger/MEMORY.md +0 -15
- data/.claude/agent-memory/vbw-vbw-dev/MEMORY.md +0 -34
- data/.claude/agent-memory/vbw-vbw-lead/MEMORY.md +0 -49
- data/.claude/agents/rails-concern.md +0 -464
- data/.claude/agents/rails-controller.md +0 -424
- data/.claude/agents/rails-hotwire.md +0 -446
- data/.claude/agents/rails-implement.md +0 -374
- data/.claude/agents/rails-job.md +0 -334
- data/.claude/agents/rails-lint.md +0 -294
- data/.claude/agents/rails-mailer.md +0 -371
- data/.claude/agents/rails-migration.md +0 -449
- data/.claude/agents/rails-model.md +0 -420
- data/.claude/agents/rails-policy.md +0 -443
- data/.claude/agents/rails-presenter.md +0 -427
- data/.claude/agents/rails-query.md +0 -412
- data/.claude/agents/rails-review.md +0 -490
- data/.claude/agents/rails-service.md +0 -458
- data/.claude/agents/rails-state-records.md +0 -465
- data/.claude/agents/rails-tdd.md +0 -314
- data/.claude/agents/rails-test.md +0 -441
- data/.claude/agents/rails-view-component.md +0 -418
- data/.claude/commands/rails-audit.md +0 -77
- data/.claude/commands/release.md +0 -366
- data/.claude/hooks/block-secrets.sh +0 -52
- data/.claude/settings.json +0 -85
- data/.claude/skills/action-cable-patterns/SKILL.md +0 -296
- data/.claude/skills/action-mailer-patterns/SKILL.md +0 -295
- data/.claude/skills/active-storage-setup/SKILL.md +0 -311
- data/.claude/skills/api-versioning/SKILL.md +0 -294
- data/.claude/skills/authentication-flow/SKILL.md +0 -335
- data/.claude/skills/authentication-flow/reference/current.md +0 -248
- data/.claude/skills/authentication-flow/reference/passwordless.md +0 -253
- data/.claude/skills/authentication-flow/reference/sessions.md +0 -201
- data/.claude/skills/authorization-pundit/SKILL.md +0 -462
- data/.claude/skills/caching-strategies/SKILL.md +0 -350
- data/.claude/skills/database-migrations/SKILL.md +0 -354
- data/.claude/skills/form-object-patterns/SKILL.md +0 -399
- data/.claude/skills/hotwire-patterns/SKILL.md +0 -247
- data/.claude/skills/hotwire-patterns/reference/stimulus.md +0 -307
- data/.claude/skills/hotwire-patterns/reference/tailwind-integration.md +0 -112
- data/.claude/skills/hotwire-patterns/reference/turbo-frames.md +0 -158
- data/.claude/skills/hotwire-patterns/reference/turbo-streams.md +0 -218
- data/.claude/skills/i18n-patterns/SKILL.md +0 -320
- data/.claude/skills/install/SKILL.md +0 -367
- data/.claude/skills/performance-optimization/SKILL.md +0 -311
- data/.claude/skills/rails-architecture/SKILL.md +0 -259
- data/.claude/skills/rails-architecture/reference/error-handling.md +0 -333
- data/.claude/skills/rails-architecture/reference/event-tracking.md +0 -142
- data/.claude/skills/rails-architecture/reference/layer-interactions.md +0 -417
- data/.claude/skills/rails-architecture/reference/multi-tenancy.md +0 -152
- data/.claude/skills/rails-architecture/reference/query-patterns.md +0 -342
- data/.claude/skills/rails-architecture/reference/service-patterns.md +0 -286
- data/.claude/skills/rails-architecture/reference/state-records.md +0 -250
- data/.claude/skills/rails-architecture/reference/testing-strategy.md +0 -326
- data/.claude/skills/rails-concern/SKILL.md +0 -399
- data/.claude/skills/rails-controller/SKILL.md +0 -336
- data/.claude/skills/rails-model-generator/SKILL.md +0 -321
- data/.claude/skills/rails-model-generator/reference/validations.md +0 -298
- data/.claude/skills/rails-presenter/SKILL.md +0 -274
- data/.claude/skills/rails-query-object/SKILL.md +0 -289
- data/.claude/skills/rails-service-object/SKILL.md +0 -349
- data/.claude/skills/solid-queue-setup/SKILL.md +0 -307
- data/.claude/skills/tdd-cycle/SKILL.md +0 -359
- data/.claude/skills/viewcomponent-patterns/SKILL.md +0 -333
- data/app/controllers/source_monitor/import_sessions/entry_annotation.rb +0 -187
- data/app/controllers/source_monitor/import_sessions/health_check_management.rb +0 -112
- data/app/controllers/source_monitor/import_sessions/opml_parser.rb +0 -130
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/object/blank"
|
|
4
|
+
require "source_monitor/items/item_creator/entry_parser"
|
|
5
|
+
require "source_monitor/items/item_creator/content_extractor"
|
|
6
|
+
|
|
7
|
+
module SourceMonitor
|
|
8
|
+
module Items
|
|
9
|
+
class NormalizedEntry
|
|
10
|
+
def self.call(source:, entry:, content_extractor: nil)
|
|
11
|
+
new(source: source, entry: entry, content_extractor: content_extractor).item_attributes
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(source:, entry:, content_extractor: nil)
|
|
15
|
+
@source = source
|
|
16
|
+
@entry = entry
|
|
17
|
+
@content_extractor = content_extractor || ItemCreator::ContentExtractor.new(source: source)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def attributes
|
|
21
|
+
@attributes ||= parser.parse
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def item_attributes
|
|
25
|
+
attributes.merge(guid: item_guid)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def raw_guid
|
|
29
|
+
attributes[:guid]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def normalized_guid
|
|
33
|
+
raw_guid.present? ? raw_guid.downcase : nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def raw_guid_present?
|
|
37
|
+
normalized_guid.present?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def item_guid
|
|
41
|
+
normalized_guid.presence || content_fingerprint
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def content_fingerprint
|
|
45
|
+
attributes[:content_fingerprint]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
attr_reader :source, :entry, :content_extractor
|
|
51
|
+
|
|
52
|
+
def parser
|
|
53
|
+
@parser ||= ItemCreator::EntryParser.new(
|
|
54
|
+
source: source,
|
|
55
|
+
entry: entry,
|
|
56
|
+
content_extractor: content_extractor
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -31,6 +31,16 @@ module SourceMonitor
|
|
|
31
31
|
config.authenticate_handler.present? || config.authorize_handler.present?
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
# Fail-closed predicate. The engine denies access when the host app has
|
|
35
|
+
# configured no authentication/authorization handler AND has not
|
|
36
|
+
# explicitly opted into open access. Configured handlers always win: when
|
|
37
|
+
# a handler is present the handler decides and this returns false.
|
|
38
|
+
def self.access_denied_by_default?(_controller = nil)
|
|
39
|
+
return false if authentication_configured?
|
|
40
|
+
|
|
41
|
+
!SourceMonitor.config.authentication.open_access
|
|
42
|
+
end
|
|
43
|
+
|
|
34
44
|
def self.authorize_configured?
|
|
35
45
|
SourceMonitor.config.authentication.authorize_handler.present?
|
|
36
46
|
end
|
data/lib/source_monitor.rb
CHANGED
|
@@ -89,6 +89,7 @@ module SourceMonitor
|
|
|
89
89
|
|
|
90
90
|
module ImportSessions
|
|
91
91
|
autoload :EntryNormalizer, "source_monitor/import_sessions/entry_normalizer"
|
|
92
|
+
autoload :Wizard, "source_monitor/import_sessions/wizard"
|
|
92
93
|
autoload :HealthCheckBroadcaster, "source_monitor/import_sessions/health_check_broadcaster"
|
|
93
94
|
autoload :HealthCheckUpdater, "source_monitor/import_sessions/health_check_updater"
|
|
94
95
|
autoload :OPMLImporter, "source_monitor/import_sessions/opml_importer"
|
|
@@ -108,6 +109,7 @@ module SourceMonitor
|
|
|
108
109
|
|
|
109
110
|
module Items
|
|
110
111
|
autoload :ItemCreator, "source_monitor/items/item_creator"
|
|
112
|
+
autoload :NormalizedEntry, "source_monitor/items/normalized_entry"
|
|
111
113
|
autoload :RetentionPruner, "source_monitor/items/retention_pruner"
|
|
112
114
|
autoload :RetentionStrategies, "source_monitor/items/retention_strategies"
|
|
113
115
|
end
|
data/source_monitor.gemspec
CHANGED
|
@@ -23,11 +23,16 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
24
|
tracked_files = `git ls-files -z`.split("\x0")
|
|
25
25
|
tracked_files.reject do |file|
|
|
26
|
-
file.start_with?(".ai/", ".github/", ".vbw-planning/", "coverage/", "node_modules/", "pkg/", "spec/", "test/", "tmp/", "vendor/", "examples/", "bin/")
|
|
26
|
+
file.start_with?(".ai/", ".github/", ".vbw-planning/", "coverage/", "node_modules/", "pkg/", "spec/", "test/", "tmp/", "vendor/", "examples/", "bin/") ||
|
|
27
|
+
# Exclude all .claude internals (agents, hooks, agent-memory, settings,
|
|
28
|
+
# commands) but keep the intended SourceMonitor sm-* skills. Driven from
|
|
29
|
+
# git ls-files (inside Dir.chdir) so packaging is CWD-independent --- a
|
|
30
|
+
# bare Dir[] glob here returned nothing on CI when another test had
|
|
31
|
+
# changed the process working directory.
|
|
32
|
+
(file.start_with?(".claude/") && !file.start_with?(".claude/skills/sm-"))
|
|
27
33
|
end
|
|
28
34
|
end
|
|
29
35
|
spec.files += [ "CHANGELOG.md" ].select { |path| File.exist?(File.join(__dir__, path)) }
|
|
30
|
-
spec.files += Dir[".claude/skills/sm-*/**/*"]
|
|
31
36
|
spec.files.uniq!
|
|
32
37
|
|
|
33
38
|
spec.require_paths = [ "lib" ]
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: source_monitor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- dchuk
|
|
@@ -258,67 +258,6 @@ executables: []
|
|
|
258
258
|
extensions: []
|
|
259
259
|
extra_rdoc_files: []
|
|
260
260
|
files:
|
|
261
|
-
- ".claude/agent-memory/vbw-vbw-debugger/MEMORY.md"
|
|
262
|
-
- ".claude/agent-memory/vbw-vbw-dev/MEMORY.md"
|
|
263
|
-
- ".claude/agent-memory/vbw-vbw-lead/MEMORY.md"
|
|
264
|
-
- ".claude/agents/rails-concern.md"
|
|
265
|
-
- ".claude/agents/rails-controller.md"
|
|
266
|
-
- ".claude/agents/rails-hotwire.md"
|
|
267
|
-
- ".claude/agents/rails-implement.md"
|
|
268
|
-
- ".claude/agents/rails-job.md"
|
|
269
|
-
- ".claude/agents/rails-lint.md"
|
|
270
|
-
- ".claude/agents/rails-mailer.md"
|
|
271
|
-
- ".claude/agents/rails-migration.md"
|
|
272
|
-
- ".claude/agents/rails-model.md"
|
|
273
|
-
- ".claude/agents/rails-policy.md"
|
|
274
|
-
- ".claude/agents/rails-presenter.md"
|
|
275
|
-
- ".claude/agents/rails-query.md"
|
|
276
|
-
- ".claude/agents/rails-review.md"
|
|
277
|
-
- ".claude/agents/rails-service.md"
|
|
278
|
-
- ".claude/agents/rails-state-records.md"
|
|
279
|
-
- ".claude/agents/rails-tdd.md"
|
|
280
|
-
- ".claude/agents/rails-test.md"
|
|
281
|
-
- ".claude/agents/rails-view-component.md"
|
|
282
|
-
- ".claude/commands/rails-audit.md"
|
|
283
|
-
- ".claude/commands/release.md"
|
|
284
|
-
- ".claude/hooks/block-secrets.sh"
|
|
285
|
-
- ".claude/settings.json"
|
|
286
|
-
- ".claude/skills/action-cable-patterns/SKILL.md"
|
|
287
|
-
- ".claude/skills/action-mailer-patterns/SKILL.md"
|
|
288
|
-
- ".claude/skills/active-storage-setup/SKILL.md"
|
|
289
|
-
- ".claude/skills/api-versioning/SKILL.md"
|
|
290
|
-
- ".claude/skills/authentication-flow/SKILL.md"
|
|
291
|
-
- ".claude/skills/authentication-flow/reference/current.md"
|
|
292
|
-
- ".claude/skills/authentication-flow/reference/passwordless.md"
|
|
293
|
-
- ".claude/skills/authentication-flow/reference/sessions.md"
|
|
294
|
-
- ".claude/skills/authorization-pundit/SKILL.md"
|
|
295
|
-
- ".claude/skills/caching-strategies/SKILL.md"
|
|
296
|
-
- ".claude/skills/database-migrations/SKILL.md"
|
|
297
|
-
- ".claude/skills/form-object-patterns/SKILL.md"
|
|
298
|
-
- ".claude/skills/hotwire-patterns/SKILL.md"
|
|
299
|
-
- ".claude/skills/hotwire-patterns/reference/stimulus.md"
|
|
300
|
-
- ".claude/skills/hotwire-patterns/reference/tailwind-integration.md"
|
|
301
|
-
- ".claude/skills/hotwire-patterns/reference/turbo-frames.md"
|
|
302
|
-
- ".claude/skills/hotwire-patterns/reference/turbo-streams.md"
|
|
303
|
-
- ".claude/skills/i18n-patterns/SKILL.md"
|
|
304
|
-
- ".claude/skills/install/SKILL.md"
|
|
305
|
-
- ".claude/skills/performance-optimization/SKILL.md"
|
|
306
|
-
- ".claude/skills/rails-architecture/SKILL.md"
|
|
307
|
-
- ".claude/skills/rails-architecture/reference/error-handling.md"
|
|
308
|
-
- ".claude/skills/rails-architecture/reference/event-tracking.md"
|
|
309
|
-
- ".claude/skills/rails-architecture/reference/layer-interactions.md"
|
|
310
|
-
- ".claude/skills/rails-architecture/reference/multi-tenancy.md"
|
|
311
|
-
- ".claude/skills/rails-architecture/reference/query-patterns.md"
|
|
312
|
-
- ".claude/skills/rails-architecture/reference/service-patterns.md"
|
|
313
|
-
- ".claude/skills/rails-architecture/reference/state-records.md"
|
|
314
|
-
- ".claude/skills/rails-architecture/reference/testing-strategy.md"
|
|
315
|
-
- ".claude/skills/rails-concern/SKILL.md"
|
|
316
|
-
- ".claude/skills/rails-controller/SKILL.md"
|
|
317
|
-
- ".claude/skills/rails-model-generator/SKILL.md"
|
|
318
|
-
- ".claude/skills/rails-model-generator/reference/validations.md"
|
|
319
|
-
- ".claude/skills/rails-presenter/SKILL.md"
|
|
320
|
-
- ".claude/skills/rails-query-object/SKILL.md"
|
|
321
|
-
- ".claude/skills/rails-service-object/SKILL.md"
|
|
322
261
|
- ".claude/skills/sm-architecture/SKILL.md"
|
|
323
262
|
- ".claude/skills/sm-architecture/reference/extraction-patterns.md"
|
|
324
263
|
- ".claude/skills/sm-architecture/reference/module-map.md"
|
|
@@ -358,9 +297,6 @@ files:
|
|
|
358
297
|
- ".claude/skills/sm-upgrade/SKILL.md"
|
|
359
298
|
- ".claude/skills/sm-upgrade/reference/upgrade-workflow.md"
|
|
360
299
|
- ".claude/skills/sm-upgrade/reference/version-history.md"
|
|
361
|
-
- ".claude/skills/solid-queue-setup/SKILL.md"
|
|
362
|
-
- ".claude/skills/tdd-cycle/SKILL.md"
|
|
363
|
-
- ".claude/skills/viewcomponent-patterns/SKILL.md"
|
|
364
300
|
- ".gitignore"
|
|
365
301
|
- ".rubocop.yml"
|
|
366
302
|
- ".ruby-version"
|
|
@@ -408,9 +344,6 @@ files:
|
|
|
408
344
|
- app/controllers/source_monitor/health_controller.rb
|
|
409
345
|
- app/controllers/source_monitor/import_history_dismissals_controller.rb
|
|
410
346
|
- app/controllers/source_monitor/import_sessions/bulk_configuration.rb
|
|
411
|
-
- app/controllers/source_monitor/import_sessions/entry_annotation.rb
|
|
412
|
-
- app/controllers/source_monitor/import_sessions/health_check_management.rb
|
|
413
|
-
- app/controllers/source_monitor/import_sessions/opml_parser.rb
|
|
414
347
|
- app/controllers/source_monitor/import_sessions_controller.rb
|
|
415
348
|
- app/controllers/source_monitor/item_scrapes_controller.rb
|
|
416
349
|
- app/controllers/source_monitor/items_controller.rb
|
|
@@ -545,6 +478,13 @@ files:
|
|
|
545
478
|
- docs/configuration.md
|
|
546
479
|
- docs/deployment.md
|
|
547
480
|
- docs/gh-cli-workflow.md
|
|
481
|
+
- docs/goals/engine-hardening/.goalbuddy-board/app.js
|
|
482
|
+
- docs/goals/engine-hardening/.goalbuddy-board/goalbuddy-mark.png
|
|
483
|
+
- docs/goals/engine-hardening/.goalbuddy-board/index.html
|
|
484
|
+
- docs/goals/engine-hardening/.goalbuddy-board/styles.css
|
|
485
|
+
- docs/goals/engine-hardening/goal.md
|
|
486
|
+
- docs/goals/engine-hardening/notes/T001-spec-validation.md
|
|
487
|
+
- docs/goals/engine-hardening/state.yaml
|
|
548
488
|
- docs/setup-validation-log.md
|
|
549
489
|
- docs/setup.md
|
|
550
490
|
- docs/troubleshooting.md
|
|
@@ -598,7 +538,9 @@ files:
|
|
|
598
538
|
- lib/source_monitor/fetching/feed_fetcher.rb
|
|
599
539
|
- lib/source_monitor/fetching/feed_fetcher/adaptive_interval.rb
|
|
600
540
|
- lib/source_monitor/fetching/feed_fetcher/entry_processor.rb
|
|
541
|
+
- lib/source_monitor/fetching/feed_fetcher/failure_outcome.rb
|
|
601
542
|
- lib/source_monitor/fetching/feed_fetcher/source_updater.rb
|
|
543
|
+
- lib/source_monitor/fetching/feed_fetcher/success_outcome.rb
|
|
602
544
|
- lib/source_monitor/fetching/fetch_error.rb
|
|
603
545
|
- lib/source_monitor/fetching/fetch_runner.rb
|
|
604
546
|
- lib/source_monitor/fetching/retry_orchestrator.rb
|
|
@@ -619,12 +561,14 @@ files:
|
|
|
619
561
|
- lib/source_monitor/import_sessions/health_check_broadcaster.rb
|
|
620
562
|
- lib/source_monitor/import_sessions/health_check_updater.rb
|
|
621
563
|
- lib/source_monitor/import_sessions/opml_importer.rb
|
|
564
|
+
- lib/source_monitor/import_sessions/wizard.rb
|
|
622
565
|
- lib/source_monitor/instrumentation.rb
|
|
623
566
|
- lib/source_monitor/items/batch_item_creator.rb
|
|
624
567
|
- lib/source_monitor/items/item_creator.rb
|
|
625
568
|
- lib/source_monitor/items/item_creator/content_extractor.rb
|
|
626
569
|
- lib/source_monitor/items/item_creator/entry_parser.rb
|
|
627
570
|
- lib/source_monitor/items/item_creator/entry_parser/media_extraction.rb
|
|
571
|
+
- lib/source_monitor/items/normalized_entry.rb
|
|
628
572
|
- lib/source_monitor/items/retention_pruner.rb
|
|
629
573
|
- lib/source_monitor/items/retention_strategies.rb
|
|
630
574
|
- lib/source_monitor/items/retention_strategies/destroy.rb
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# Debugger Memory
|
|
2
|
-
|
|
3
|
-
## Rails Association Cache Pollution Pattern
|
|
4
|
-
- `source.items.new` AND `Item.new(source: source)` both add to the loaded association cache via inverse_of
|
|
5
|
-
- Only `Item.new(source_id: source.id)` truly bypasses inverse_of and avoids cache pollution
|
|
6
|
-
- When unsaved/invalid records are in a loaded has_many cache, `parent.update!` triggers auto-save and fails with `RecordInvalid: Items is invalid`
|
|
7
|
-
- `update_columns` bypasses all callbacks and auto-save, safe to use with polluted caches
|
|
8
|
-
- After `update_columns`, call `reload` so the in-memory object reflects DB state
|
|
9
|
-
|
|
10
|
-
## Test Patterns
|
|
11
|
-
- Use `clean_source_monitor_tables!` in setup for blank-slate DB
|
|
12
|
-
- `create_source!` is the factory helper (in test_helper.rb)
|
|
13
|
-
- WebMock stubs + VCR cassettes for HTTP; `stub_request(:get, url)`
|
|
14
|
-
- Stub class methods with `singleton_class.define_method` pattern
|
|
15
|
-
- Always restore stubs in `ensure` block
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# VBW Dev Agent Memory
|
|
2
|
-
|
|
3
|
-
## Project: source_monitor
|
|
4
|
-
- Rails engine gem for RSS/feed monitoring
|
|
5
|
-
- Ruby 3.4.4, Rails 8.x
|
|
6
|
-
- Test suite: 473 tests via `bin/rails test` (takes ~76 seconds)
|
|
7
|
-
- RuboCop uses `rubocop-rails-omakase` base config
|
|
8
|
-
|
|
9
|
-
## Key Learnings
|
|
10
|
-
|
|
11
|
-
### Shell/Bash in zsh
|
|
12
|
-
- `!` in zsh inline scripts causes `command not found` errors. Use `case` statements instead of `if ! ...` patterns.
|
|
13
|
-
- Use `IFS= read -r` when reading filenames from pipes to handle edge cases.
|
|
14
|
-
|
|
15
|
-
### RuboCop scope vs git scope
|
|
16
|
-
- RuboCop inspects ALL Ruby-like files (Gemfile, Rakefile, .gemspec, .rake, bin/*, config.ru), not just `.rb` files.
|
|
17
|
-
- `git ls-files -- '*.rb'` only matches `.rb` extensions. Plans scoped to `.rb` files may miss RuboCop violations in non-`.rb` Ruby files.
|
|
18
|
-
- `test/tmp/` contains untracked generated Rails app templates. These are NOT git-tracked but RuboCop scans them unless excluded.
|
|
19
|
-
|
|
20
|
-
### File structure
|
|
21
|
-
- `test/lib/tmp/install_generator/` contains test fixtures (1 tracked file: `config/initializers/source_monitor.rb`)
|
|
22
|
-
- `test/tmp/host_app_template_*` directories are generated test artifacts, not git-tracked
|
|
23
|
-
- `.rubocop.yml` is at project root, inherits from `rubocop-rails-omakase`
|
|
24
|
-
|
|
25
|
-
### Frozen string literal pragma
|
|
26
|
-
- Completed in commit `5f02db8` -- 113 files modified
|
|
27
|
-
- Added `test/tmp/**/*` to RuboCop exclude list
|
|
28
|
-
|
|
29
|
-
### RuboCop omakase ruleset details
|
|
30
|
-
- Only 45 cops enabled (out of 775 available)
|
|
31
|
-
- ALL Metrics cops disabled (ClassLength, MethodLength, BlockLength, etc.)
|
|
32
|
-
- After frozen_string_literal fix, codebase had zero remaining violations
|
|
33
|
-
- No `.rubocop.yml` exclusions needed for large files since Metrics cops are off
|
|
34
|
-
- Plan 02 completed with no code changes required
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# Lead Agent Memory -- SourceMonitor
|
|
2
|
-
|
|
3
|
-
## Project Quick Facts
|
|
4
|
-
- Rails 8 engine, Ruby 3.4+, PostgreSQL-only
|
|
5
|
-
- 325 git-tracked Ruby files, 130 test files
|
|
6
|
-
- Coverage baseline: 2328 uncovered lines in config/coverage_baseline.json
|
|
7
|
-
- RuboCop: rubocop-rails-omakase, config at .rubocop.yml
|
|
8
|
-
- CI: .github/workflows/ci.yml (lint, security, test, release-verify, nightly profiling)
|
|
9
|
-
- Large files: FeedFetcher (627), Configuration (655), ImportSessionsController (792)
|
|
10
|
-
|
|
11
|
-
## Phase 1 Findings
|
|
12
|
-
- 98 git-tracked .rb files missing frozen_string_literal (out of 325)
|
|
13
|
-
- Breakdown: app/(5), lib/(24), test/(43 non-dummy), test/dummy/(22), config/(1), db/migrate/(4)
|
|
14
|
-
- test/tmp/ is NOT git-tracked (generated by install_generator tests) -- exclude from changes
|
|
15
|
-
- test/lib/tmp/install_generator/config/initializers/source_monitor.rb IS tracked and already has pragma
|
|
16
|
-
- bin/rubocop wrapper forces --config .rubocop.yml
|
|
17
|
-
- Phase 1 criterion #3 (10% coverage shrink) not addressed by plans 01/02 -- noted for future
|
|
18
|
-
|
|
19
|
-
## Phase 2 Planning Insights
|
|
20
|
-
- Coverage baseline.json has 2117 uncovered lines across 105 files (not 2328 -- that was line count)
|
|
21
|
-
- Top 7 files account for ~743 uncovered lines (35% of total)
|
|
22
|
-
- FeedFetcher: 245 uncovered, 12 existing tests, uses VCR+WebMock
|
|
23
|
-
- ItemCreator: 228 uncovered, 8 existing tests, needs mock entries for Atom/JSON branches
|
|
24
|
-
- Configuration: 94 uncovered, 5 existing tests, ~12 nested settings classes
|
|
25
|
-
- Dashboard::Queries: 66 uncovered, 7 existing tests, uses raw SQL + Cache
|
|
26
|
-
- BulkSourceScraper: 66 uncovered, 6 existing tests, ActiveJob test adapter
|
|
27
|
-
- Broadcaster: 48 uncovered, NO existing test file -- needs creation
|
|
28
|
-
- SourcesIndexMetrics: 34 uncovered, 3 existing tests
|
|
29
|
-
- All 5 Phase 2 plans are Wave 1 (no inter-plan dependencies, no file conflicts)
|
|
30
|
-
- Testing main files will indirectly cover supporting files (retry_policy, fetch_error, state, enqueuer, etc.)
|
|
31
|
-
- Broadcaster tests need Turbo::StreamsChannel stubs -- no full Action Cable required
|
|
32
|
-
- 50% coverage target requires ~1059 lines covered; direct plans target ~630, rest from indirect
|
|
33
|
-
|
|
34
|
-
## Phase 4 Planning Insights
|
|
35
|
-
- 3 plans: conventions-audit (wave 1), item-creator-extraction (wave 1), final-verification (wave 2)
|
|
36
|
-
- SourcesController has dead `fetch`/`retry` methods (leftover from Phase 3 CRUD extraction)
|
|
37
|
-
- ImportSessionsController `new` and `create` are byte-for-byte identical
|
|
38
|
-
- 4 RuboCop violations in db/migrate/20260210204022_add_composite_index_to_log_entries.rb
|
|
39
|
-
- Duplicate test: test/controllers/concerns/ vs test/controllers/source_monitor/concerns/
|
|
40
|
-
- ItemCreator at 601 lines is the last file over 300 lines -- extract to entry_parser + content_extractor
|
|
41
|
-
- Coverage baseline still at 2117 uncovered (not regenerated since Phase 1) -- must regenerate
|
|
42
|
-
- 60% reduction target: at most 847 uncovered lines
|
|
43
|
-
- dashboard/queries.rb (356) and application_helper.rb (346) are near 300 but acceptable as view/query code
|
|
44
|
-
- `bin/update-coverage-baseline` requires `COVERAGE=1 bin/rails test` first
|
|
45
|
-
|
|
46
|
-
## Bash/Shell Notes
|
|
47
|
-
- zsh on macOS -- `!` in shell conditionals causes `command not found` errors
|
|
48
|
-
- Use `case` statements instead of `if ! grep` patterns in zsh
|
|
49
|
-
- git ls-files piped to while loops works reliably for file enumeration
|