source_monitor 0.3.3 → 0.4.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 +101 -58
- data/.claude/skills/sm-configure/SKILL.md +13 -2
- data/.claude/skills/sm-configure/reference/configuration-reference.md +33 -0
- data/.claude/skills/sm-host-setup/SKILL.md +15 -1
- data/.claude/skills/sm-host-setup/reference/setup-checklist.md +33 -0
- data/.claude/skills/sm-job/SKILL.md +1 -1
- data/.vbw-planning/REQUIREMENTS.md +22 -0
- data/.vbw-planning/ROADMAP.md +125 -0
- data/.vbw-planning/STATE.md +43 -0
- data/.vbw-planning/config.json +3 -1
- data/.vbw-planning/discovery.json +3 -1
- data/.vbw-planning/phases/01-generator-steps/01-CONTEXT.md +33 -0
- data/.vbw-planning/phases/01-generator-steps/01-VERIFICATION.md +86 -0
- data/.vbw-planning/phases/01-generator-steps/PLAN-01-SUMMARY.md +61 -0
- data/.vbw-planning/phases/01-generator-steps/PLAN-01.md +380 -0
- data/.vbw-planning/phases/02-verification/02-VERIFICATION.md +78 -0
- data/.vbw-planning/phases/02-verification/PLAN-01-SUMMARY.md +46 -0
- data/.vbw-planning/phases/02-verification/PLAN-01.md +500 -0
- data/.vbw-planning/phases/03-docs-alignment/03-VERIFICATION.md +89 -0
- data/.vbw-planning/phases/03-docs-alignment/PLAN-01-SUMMARY.md +48 -0
- data/.vbw-planning/phases/03-docs-alignment/PLAN-01.md +456 -0
- data/.vbw-planning/phases/04-dashboard-ux/04-VERIFICATION.md +129 -0
- data/.vbw-planning/phases/04-dashboard-ux/PLAN-01-SUMMARY.md +70 -0
- data/.vbw-planning/phases/04-dashboard-ux/PLAN-01.md +747 -0
- data/.vbw-planning/phases/05-active-storage-images/05-VERIFICATION.md +156 -0
- data/.vbw-planning/phases/05-active-storage-images/PLAN-01-SUMMARY.md +69 -0
- data/.vbw-planning/phases/05-active-storage-images/PLAN-01.md +455 -0
- data/.vbw-planning/phases/05-active-storage-images/PLAN-02-SUMMARY.md +39 -0
- data/.vbw-planning/phases/05-active-storage-images/PLAN-02.md +488 -0
- data/.vbw-planning/phases/06-netflix-feed-fix/06-VERIFICATION.md +100 -0
- data/.vbw-planning/phases/06-netflix-feed-fix/PLAN-01-SUMMARY.md +37 -0
- data/.vbw-planning/phases/06-netflix-feed-fix/PLAN-01.md +345 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile.lock +1 -1
- data/VERSION +1 -1
- data/app/assets/builds/source_monitor/application.css +9 -0
- data/app/helpers/source_monitor/application_helper.rb +38 -0
- data/app/jobs/source_monitor/download_content_images_job.rb +72 -0
- data/app/models/source_monitor/item_content.rb +2 -0
- data/app/views/source_monitor/dashboard/_recent_activity.html.erb +9 -0
- data/app/views/source_monitor/items/_details.html.erb +2 -2
- data/app/views/source_monitor/logs/index.html.erb +9 -0
- data/app/views/source_monitor/sources/_details.html.erb +2 -2
- data/app/views/source_monitor/sources/_row.html.erb +1 -1
- data/docs/setup.md +10 -1
- data/docs/troubleshooting.md +38 -7
- data/lib/generators/source_monitor/install/install_generator.rb +101 -0
- data/lib/source_monitor/configuration/http_settings.rb +7 -1
- data/lib/source_monitor/configuration/images_settings.rb +37 -0
- data/lib/source_monitor/configuration.rb +3 -1
- data/lib/source_monitor/dashboard/queries/recent_activity_query.rb +16 -7
- data/lib/source_monitor/dashboard/recent_activity.rb +1 -0
- data/lib/source_monitor/dashboard/recent_activity_presenter.rb +15 -2
- data/lib/source_monitor/fetching/feed_fetcher/entry_processor.rb +13 -0
- data/lib/source_monitor/http.rb +23 -0
- data/lib/source_monitor/images/content_rewriter.rb +81 -0
- data/lib/source_monitor/images/downloader.rb +82 -0
- data/lib/source_monitor/logs/table_presenter.rb +25 -0
- data/lib/source_monitor/setup/procfile_patcher.rb +31 -0
- data/lib/source_monitor/setup/queue_config_patcher.rb +84 -0
- data/lib/source_monitor/setup/verification/recurring_schedule_verifier.rb +102 -0
- data/lib/source_monitor/setup/verification/runner.rb +1 -1
- data/lib/source_monitor/setup/verification/solid_queue_verifier.rb +1 -1
- data/lib/source_monitor/setup/workflow.rb +10 -0
- data/lib/source_monitor/version.rb +1 -1
- data/lib/source_monitor.rb +8 -0
- metadata +31 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
phase: 4
|
|
3
|
+
tier: standard
|
|
4
|
+
result: PASS
|
|
5
|
+
passed: 23
|
|
6
|
+
failed: 0
|
|
7
|
+
total: 23
|
|
8
|
+
date: 2026-02-12
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Must-Have Checks
|
|
12
|
+
|
|
13
|
+
| # | Truth/Condition | Status | Evidence |
|
|
14
|
+
|---|-----------------|--------|----------|
|
|
15
|
+
| 1 | Run `PARALLEL_WORKERS=1 bin/rails test test/lib/source_monitor/dashboard/recent_activity_presenter_test.rb` exits 0 with 0 failures | PASS | 6 runs, 14 assertions, 0 failures, 0 errors, 0 skips |
|
|
16
|
+
| 2 | Run `PARALLEL_WORKERS=1 bin/rails test test/lib/source_monitor/logs/table_presenter_test.rb` exits 0 with 0 failures | PASS | 1 runs, 51 assertions, 0 failures, 0 errors, 0 skips |
|
|
17
|
+
| 3 | Run `bin/rails test` exits 0 with 874+ runs and 0 failures | PASS | 885 runs, 2957 assertions, 0 failures, 0 errors, 0 skips |
|
|
18
|
+
| 4 | Run `bin/rubocop` exits 0 with 0 offenses | PASS | 381 files inspected, 0 offenses (after auto-fix of Active Storage migration) |
|
|
19
|
+
|
|
20
|
+
## Artifact Checks
|
|
21
|
+
|
|
22
|
+
| Artifact | Exists | Contains | Status |
|
|
23
|
+
|----------|--------|----------|--------|
|
|
24
|
+
| lib/source_monitor/dashboard/recent_activity.rb | YES | source_feed_url | PASS |
|
|
25
|
+
| lib/source_monitor/dashboard/recent_activity_presenter.rb | YES | source_domain | PASS |
|
|
26
|
+
| lib/source_monitor/dashboard/queries/recent_activity_query.rb | YES | feed_url | PASS |
|
|
27
|
+
| lib/source_monitor/logs/table_presenter.rb | YES | url_label | PASS |
|
|
28
|
+
| app/helpers/source_monitor/application_helper.rb | YES | external_link_to | PASS |
|
|
29
|
+
| app/views/source_monitor/dashboard/_recent_activity.html.erb | YES | url_display | PASS |
|
|
30
|
+
| app/views/source_monitor/sources/_row.html.erb | YES | external_link_to | PASS |
|
|
31
|
+
| app/views/source_monitor/sources/_details.html.erb | YES | external_link_to | PASS |
|
|
32
|
+
| app/views/source_monitor/items/_details.html.erb | YES | external_link_to | PASS |
|
|
33
|
+
|
|
34
|
+
## Key Link Checks
|
|
35
|
+
|
|
36
|
+
| From | To | Via | Status |
|
|
37
|
+
|------|----|----|--------|
|
|
38
|
+
| recent_activity_query.rb#fetch_log_sql | REQ-22 | JOIN sources to pull feed_url (line 90), displayed as domain on dashboard | PASS |
|
|
39
|
+
| recent_activity_query.rb#scrape_log_sql | REQ-22 | JOIN items to pull item url (line 108), displayed on dashboard | PASS |
|
|
40
|
+
| application_helper.rb#external_link_to | REQ-23 | All external URLs use this helper for target=_blank + external-link icon (line 217) | PASS |
|
|
41
|
+
| sources/_row.html.erb | REQ-23 | Feed URL in source index row is clickable (line 32) | PASS |
|
|
42
|
+
| sources/_details.html.erb | REQ-23 | Website URL and feed URL on source detail page are clickable (lines 28, 140) | PASS |
|
|
43
|
+
| items/_details.html.erb | REQ-23 | Item URL and canonical URL are clickable (lines 56-57) | PASS |
|
|
44
|
+
|
|
45
|
+
## Convention Compliance
|
|
46
|
+
|
|
47
|
+
| Convention | File | Status | Detail |
|
|
48
|
+
|------------|------|--------|--------|
|
|
49
|
+
| frozen_string_literal | All modified .rb files | PASS | All files have frozen_string_literal pragma |
|
|
50
|
+
| Test coverage | Helper tests | PASS | 7 new tests for external_link_to and domain_from_url |
|
|
51
|
+
| Test coverage | Presenter tests | PASS | 4 new tests for url_display in fetch/scrape events |
|
|
52
|
+
| Test coverage | Table presenter tests | PASS | 6 new assertions for url_label/url_href |
|
|
53
|
+
| RuboCop omakase | All modified files | PASS | 0 offenses after auto-fix |
|
|
54
|
+
| Rails conventions | Helper methods | PASS | external_link_to follows Rails helper patterns, returns html_safe |
|
|
55
|
+
| Rails conventions | Query objects | PASS | SQL JOINs use LEFT JOIN, proper table name quoting |
|
|
56
|
+
| Rails conventions | View partials | PASS | Use helper methods, maintain existing layout structure |
|
|
57
|
+
|
|
58
|
+
## Anti-Pattern Scan
|
|
59
|
+
|
|
60
|
+
| Pattern | Found | Location | Severity |
|
|
61
|
+
|---------|-------|----------|----------|
|
|
62
|
+
| TODO/FIXME/HACK/XXX | YES | app/controllers/source_monitor/items_controller.rb:39 | INFO |
|
|
63
|
+
| Hard-coded strings | NO | N/A | N/A |
|
|
64
|
+
| Missing nil checks | NO | All helpers check for blank URLs | N/A |
|
|
65
|
+
| Unsafe HTML rendering | NO | link_to returns html_safe | N/A |
|
|
66
|
+
| N+1 queries | NO | Query uses JOINs, not lazy loading | N/A |
|
|
67
|
+
|
|
68
|
+
**Note:** The TODO in items_controller.rb is pre-existing (extract ItemScrapesController), not related to Phase 4.
|
|
69
|
+
|
|
70
|
+
## Requirement Mapping
|
|
71
|
+
|
|
72
|
+
| Requirement | Plan Ref | Artifact Evidence | Status |
|
|
73
|
+
|-------------|----------|-------------------|--------|
|
|
74
|
+
| REQ-22: Fetch logs show source URL on dashboard | PLAN-01 Task 2, 3, 4 | recent_activity_query.rb JOINs sources (line 90), presenter extracts domain (line 33), view displays url_display (line 24-30) | PASS |
|
|
75
|
+
| REQ-22: Scrape logs show item URL on dashboard | PLAN-01 Task 2, 3, 4 | recent_activity_query.rb JOINs items (line 108), presenter passes item_url (line 372), view displays url_display (line 24-30) | PASS |
|
|
76
|
+
| REQ-22: Both success and failure show URLs | PLAN-01 Task 2 | Tests verify failure events include url_display (recent_activity_presenter_test.rb line 436-455) | PASS |
|
|
77
|
+
| REQ-22: Logs table shows URL info | PLAN-01 Task 3 | table_presenter.rb url_label method (line 64), logs/index.html.erb displays below subject | PASS |
|
|
78
|
+
| REQ-23: external_link_to helper with target=_blank | PLAN-01 Task 1 | application_helper.rb line 217-224, includes target="_blank", rel="noopener noreferrer" | PASS |
|
|
79
|
+
| REQ-23: Feed URLs clickable in source index | PLAN-01 Task 5 | sources/_row.html.erb line 32 uses external_link_to | PASS |
|
|
80
|
+
| REQ-23: Website/Feed URLs clickable in source detail | PLAN-01 Task 5 | sources/_details.html.erb lines 28, 140 use external_link_to | PASS |
|
|
81
|
+
| REQ-23: Item URLs clickable in item detail | PLAN-01 Task 5 | items/_details.html.erb lines 56-57 use external_link_to | PASS |
|
|
82
|
+
|
|
83
|
+
## Summary
|
|
84
|
+
|
|
85
|
+
**Tier:** standard
|
|
86
|
+
|
|
87
|
+
**Result:** PASS
|
|
88
|
+
|
|
89
|
+
**Passed:** 23/23
|
|
90
|
+
|
|
91
|
+
**Failed:** None
|
|
92
|
+
|
|
93
|
+
### Verification Details
|
|
94
|
+
|
|
95
|
+
Phase 4 (Dashboard UX Improvements) has been fully executed according to PLAN-01 specifications:
|
|
96
|
+
|
|
97
|
+
1. **Helper Layer (Task 1):** `external_link_to` helper added with target="_blank", rel="noopener noreferrer", and external-link SVG icon. `domain_from_url` helper extracts hostnames from URLs. Both handle nil/blank inputs gracefully. 7 comprehensive tests cover all edge cases.
|
|
98
|
+
|
|
99
|
+
2. **Data Layer (Task 2):** `recent_activity_query.rb` now JOINs sources table for fetch logs (pulling feed_url) and items table for scrape logs (pulling item url). Event struct extended with `source_feed_url` field. Presenter extracts domain for fetch events and passes through item URL for scrape events. Both success and failure events include URL info. 4 new tests verify all scenarios.
|
|
100
|
+
|
|
101
|
+
3. **Logs Table (Task 3):** `table_presenter.rb` Row class adds `url_label` (domain for fetches, full URL for scrapes) and `url_href` methods. Health check rows return nil. 6 assertions added to existing comprehensive test.
|
|
102
|
+
|
|
103
|
+
4. **View Layer (Task 4):** Dashboard `_recent_activity.html.erb` displays URL below event description. Logs `index.html.erb` displays URL below subject column. Both use `external_link_to` for clickable links with consistent muted styling.
|
|
104
|
+
|
|
105
|
+
5. **Clickable URLs (Task 5):** All external URLs across source index rows, source detail page (feed URL, website URL), and item detail page (URL, canonical URL) are now clickable with new-tab behavior.
|
|
106
|
+
|
|
107
|
+
### Test Results
|
|
108
|
+
|
|
109
|
+
- Test suite: **885 runs, 2957 assertions, 0 failures**
|
|
110
|
+
- RuboCop: **381 files inspected, 0 offenses**
|
|
111
|
+
- Coverage: All new functionality covered by tests
|
|
112
|
+
|
|
113
|
+
### Requirements Satisfied
|
|
114
|
+
|
|
115
|
+
- **REQ-22:** Fetch logs show source domain; scrape logs show item URL; both success and failure events display URL info; logs table shows URL below subject column
|
|
116
|
+
- **REQ-23:** All external URLs are clickable links opening in new tabs with external-link icon indicator
|
|
117
|
+
|
|
118
|
+
### Commits Verified
|
|
119
|
+
|
|
120
|
+
All 5 commits referenced in PLAN-01-SUMMARY.md are present:
|
|
121
|
+
- 6fde387: Add external_link_to and domain_from_url helpers
|
|
122
|
+
- 527bea1: Add URL info to recent activity query and presenter
|
|
123
|
+
- cd6041e: Add url_label and url_href to logs table presenter
|
|
124
|
+
- 5376b03: Show URL info in dashboard and logs views
|
|
125
|
+
- 51db3c6: Make external URLs clickable across views
|
|
126
|
+
|
|
127
|
+
### Deviations
|
|
128
|
+
|
|
129
|
+
None. All tasks executed as specified in PLAN-01. No requirements gaps, no anti-patterns introduced, full test coverage achieved.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# PLAN-01 Summary: dashboard-url-display-and-clickable-links
|
|
2
|
+
|
|
3
|
+
## Status: COMPLETE
|
|
4
|
+
|
|
5
|
+
## What Was Built
|
|
6
|
+
|
|
7
|
+
### Task 1: Add external_link_to helper and tests
|
|
8
|
+
- Added `external_link_to(label, url, **options)` public helper: renders `<a>` with `target="_blank"`, `rel="noopener noreferrer"`, and external-link SVG icon; returns plain label when URL is blank
|
|
9
|
+
- Added `domain_from_url(url)` public helper: extracts hostname via `URI.parse`, returns nil for blank/invalid URLs
|
|
10
|
+
- Added `external_link_icon` private helper: renders Heroicon external-link SVG with consistent Tailwind styling
|
|
11
|
+
- 7 new tests covering link rendering, nil/blank handling, custom CSS class, domain extraction, and invalid URL
|
|
12
|
+
|
|
13
|
+
### Task 2: Add URL info to recent activity query and presenter
|
|
14
|
+
- Added `:source_feed_url` field to `Dashboard::RecentActivity::Event` struct
|
|
15
|
+
- Updated `fetch_log_sql` to JOIN `sources` table and SELECT `feed_url AS source_feed_url`
|
|
16
|
+
- Updated `scrape_log_sql` to JOIN `items` table and SELECT `items.url AS item_url`
|
|
17
|
+
- Added `NULL AS source_feed_url` to `scrape_log_sql` and `item_sql` for UNION column alignment
|
|
18
|
+
- Updated `build_event` to pass `source_feed_url` from query results
|
|
19
|
+
- Added `url_display` (domain for fetches, full URL for scrapes) and `url_href` keys to presenter view models
|
|
20
|
+
- Added `source_domain` private method for domain extraction
|
|
21
|
+
- 4 new tests: fetch with domain, fetch with nil URL, failure with URL, scrape with item URL
|
|
22
|
+
|
|
23
|
+
### Task 3: Add URL to logs table presenter
|
|
24
|
+
- Added `url_label` public method: returns domain for fetch rows, item URL for scrape rows, nil for health checks
|
|
25
|
+
- Added `url_href` public method: returns full feed_url for fetches, item URL for scrapes, nil for health checks
|
|
26
|
+
- Added `domain_from_feed_url` private helper with URI parsing
|
|
27
|
+
- 6 new assertions for fetch, scrape, and health check row types
|
|
28
|
+
|
|
29
|
+
### Task 4: Update dashboard and logs views with URL display
|
|
30
|
+
- Dashboard `_recent_activity.html.erb`: added URL display line below event description, using `external_link_to` for clickable links
|
|
31
|
+
- Logs `index.html.erb`: added URL display below subject column in table rows, using `external_link_to` for clickable links
|
|
32
|
+
- Both use muted `text-slate-400` styling with `hover:text-blue-500` for visual consistency
|
|
33
|
+
|
|
34
|
+
### Task 5: Make external URLs clickable across views
|
|
35
|
+
- `sources/_row.html.erb`: feed_url in source index row is now a clickable external link
|
|
36
|
+
- `sources/_details.html.erb`: Feed URL header and Website URL in details hash are clickable external links
|
|
37
|
+
- `items/_details.html.erb`: URL and Canonical URL in details hash are clickable external links
|
|
38
|
+
|
|
39
|
+
## Files Modified
|
|
40
|
+
- `app/helpers/source_monitor/application_helper.rb` (external_link_to, domain_from_url, external_link_icon)
|
|
41
|
+
- `lib/source_monitor/dashboard/recent_activity.rb` (source_feed_url field)
|
|
42
|
+
- `lib/source_monitor/dashboard/queries/recent_activity_query.rb` (JOIN sources/items, source_feed_url column)
|
|
43
|
+
- `lib/source_monitor/dashboard/recent_activity_presenter.rb` (url_display, url_href, source_domain)
|
|
44
|
+
- `lib/source_monitor/logs/table_presenter.rb` (url_label, url_href, domain_from_feed_url)
|
|
45
|
+
- `app/views/source_monitor/dashboard/_recent_activity.html.erb` (URL display below description)
|
|
46
|
+
- `app/views/source_monitor/logs/index.html.erb` (URL display below subject)
|
|
47
|
+
- `app/views/source_monitor/sources/_row.html.erb` (clickable feed_url)
|
|
48
|
+
- `app/views/source_monitor/sources/_details.html.erb` (clickable feed URL, website URL)
|
|
49
|
+
- `app/views/source_monitor/items/_details.html.erb` (clickable URL, canonical URL)
|
|
50
|
+
- `test/helpers/source_monitor/application_helper_test.rb` (7 new tests)
|
|
51
|
+
- `test/lib/source_monitor/dashboard/recent_activity_presenter_test.rb` (4 new tests)
|
|
52
|
+
- `test/lib/source_monitor/logs/table_presenter_test.rb` (6 new assertions)
|
|
53
|
+
|
|
54
|
+
## Commits
|
|
55
|
+
- `6fde387` feat(04-dashboard-ux): add external_link_to and domain_from_url helpers
|
|
56
|
+
- `527bea1` feat(04-dashboard-ux): add URL info to recent activity query and presenter
|
|
57
|
+
- `cd6041e` feat(04-dashboard-ux): add url_label and url_href to logs table presenter
|
|
58
|
+
- `5376b03` feat(04-dashboard-ux): show URL info in dashboard and logs views
|
|
59
|
+
- `51db3c6` feat(04-dashboard-ux): make external URLs clickable across views
|
|
60
|
+
|
|
61
|
+
## Requirements Satisfied
|
|
62
|
+
- REQ-22: Fetch log events display source domain; scrape log events display item URL; both success and failure events show URL info; logs table shows URL below subject column
|
|
63
|
+
- REQ-23: All external URLs (feed URLs, website URLs, item URLs, canonical URLs) are clickable links opening in new tabs with external-link icon indicator
|
|
64
|
+
|
|
65
|
+
## Verification Results
|
|
66
|
+
- `bin/rails test`: 885 runs, 2957 assertions, 0 failures, 0 errors
|
|
67
|
+
- `bin/rubocop`: 378 files inspected, 0 offenses
|
|
68
|
+
|
|
69
|
+
## Deviations
|
|
70
|
+
None. All tasks executed as specified in the plan.
|