source_monitor 0.3.0 → 0.3.2
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-architecture/SKILL.md +233 -0
- data/.claude/skills/sm-architecture/reference/extraction-patterns.md +192 -0
- data/.claude/skills/sm-architecture/reference/module-map.md +194 -0
- data/.claude/skills/sm-configuration-setting/SKILL.md +264 -0
- data/.claude/skills/sm-configuration-setting/reference/settings-catalog.md +248 -0
- data/.claude/skills/sm-configuration-setting/reference/settings-pattern.md +297 -0
- data/.claude/skills/sm-configure/SKILL.md +153 -0
- data/.claude/skills/sm-configure/reference/configuration-reference.md +321 -0
- data/.claude/skills/sm-dashboard-widget/SKILL.md +344 -0
- data/.claude/skills/sm-dashboard-widget/reference/dashboard-patterns.md +304 -0
- data/.claude/skills/sm-domain-model/SKILL.md +188 -0
- data/.claude/skills/sm-domain-model/reference/model-graph.md +114 -0
- data/.claude/skills/sm-domain-model/reference/table-structure.md +348 -0
- data/.claude/skills/sm-engine-migration/SKILL.md +395 -0
- data/.claude/skills/sm-engine-migration/reference/migration-conventions.md +255 -0
- data/.claude/skills/sm-engine-test/SKILL.md +302 -0
- data/.claude/skills/sm-engine-test/reference/test-helpers.md +259 -0
- data/.claude/skills/sm-engine-test/reference/test-patterns.md +411 -0
- data/.claude/skills/sm-event-handler/SKILL.md +265 -0
- data/.claude/skills/sm-event-handler/reference/events-api.md +229 -0
- data/.claude/skills/sm-health-rule/SKILL.md +327 -0
- data/.claude/skills/sm-health-rule/reference/health-system.md +269 -0
- data/.claude/skills/sm-host-setup/SKILL.md +223 -0
- data/.claude/skills/sm-host-setup/reference/initializer-template.md +195 -0
- data/.claude/skills/sm-host-setup/reference/setup-checklist.md +134 -0
- data/.claude/skills/sm-job/SKILL.md +263 -0
- data/.claude/skills/sm-job/reference/job-conventions.md +245 -0
- data/.claude/skills/sm-model-extension/SKILL.md +287 -0
- data/.claude/skills/sm-model-extension/reference/extension-api.md +317 -0
- data/.claude/skills/sm-pipeline-stage/SKILL.md +254 -0
- data/.claude/skills/sm-pipeline-stage/reference/completion-handlers.md +152 -0
- data/.claude/skills/sm-pipeline-stage/reference/entry-processing.md +191 -0
- data/.claude/skills/sm-pipeline-stage/reference/feed-fetcher-architecture.md +198 -0
- data/.claude/skills/sm-scraper-adapter/SKILL.md +284 -0
- data/.claude/skills/sm-scraper-adapter/reference/adapter-contract.md +167 -0
- data/.claude/skills/sm-scraper-adapter/reference/example-adapter.md +274 -0
- data/.vbw-planning/.notification-log.jsonl +102 -0
- data/.vbw-planning/.session-log.jsonl +505 -0
- data/AGENTS.md +20 -57
- data/CHANGELOG.md +19 -0
- data/CLAUDE.md +44 -1
- data/CONTRIBUTING.md +5 -5
- data/Gemfile.lock +20 -21
- data/README.md +18 -5
- data/VERSION +1 -0
- data/docs/deployment.md +1 -1
- data/docs/setup.md +4 -4
- data/lib/source_monitor/setup/skills_installer.rb +94 -0
- data/lib/source_monitor/setup/workflow.rb +17 -2
- data/lib/source_monitor/version.rb +1 -1
- data/lib/tasks/source_monitor_setup.rake +58 -0
- data/source_monitor.gemspec +1 -0
- metadata +39 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sm-configuration-setting
|
|
3
|
+
description: How to add or modify configuration settings in the Source Monitor engine. Use when adding a new config option, modifying defaults, creating a new settings section, or understanding the configuration architecture.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Source Monitor Configuration Settings
|
|
8
|
+
|
|
9
|
+
## Architecture Overview
|
|
10
|
+
|
|
11
|
+
The `SourceMonitor::Configuration` class was refactored from 655 lines into a lean 87-line orchestrator plus 12 extracted settings files. Each settings file follows a consistent pattern.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
lib/source_monitor/configuration.rb # Main class (87 lines)
|
|
15
|
+
lib/source_monitor/configuration/
|
|
16
|
+
authentication_settings.rb # Auth handlers
|
|
17
|
+
events.rb # Callbacks and processors
|
|
18
|
+
fetching_settings.rb # Adaptive interval tuning
|
|
19
|
+
health_settings.rb # Health monitoring thresholds
|
|
20
|
+
http_settings.rb # HTTP client defaults
|
|
21
|
+
model_definition.rb # Concern/validation injection
|
|
22
|
+
models.rb # Model definitions registry
|
|
23
|
+
realtime_settings.rb # ActionCable adapter config
|
|
24
|
+
retention_settings.rb # Item retention policies
|
|
25
|
+
scraper_registry.rb # Scraper adapter registry
|
|
26
|
+
scraping_settings.rb # Scraping concurrency limits
|
|
27
|
+
validation_definition.rb # Validation DSL
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How Configuration Works
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
# In host app initializer
|
|
34
|
+
SourceMonitor.configure do |config|
|
|
35
|
+
config.fetching.min_interval_minutes = 10
|
|
36
|
+
config.http.timeout = 30
|
|
37
|
+
config.retention.strategy = :soft_delete
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Access at runtime
|
|
41
|
+
SourceMonitor.config.fetching.min_interval_minutes # => 10
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The `config` object is a `SourceMonitor::Configuration` instance. Sub-sections are accessed via reader methods that return settings objects.
|
|
45
|
+
|
|
46
|
+
## Adding a Setting to an Existing Section
|
|
47
|
+
|
|
48
|
+
### Step 1: Identify the Settings File
|
|
49
|
+
|
|
50
|
+
| Setting Category | File | Class |
|
|
51
|
+
|-----------------|------|-------|
|
|
52
|
+
| HTTP client | `http_settings.rb` | `HTTPSettings` |
|
|
53
|
+
| Adaptive fetching | `fetching_settings.rb` | `FetchingSettings` |
|
|
54
|
+
| Health monitoring | `health_settings.rb` | `HealthSettings` |
|
|
55
|
+
| Scraping limits | `scraping_settings.rb` | `ScrapingSettings` |
|
|
56
|
+
| Item retention | `retention_settings.rb` | `RetentionSettings` |
|
|
57
|
+
| Realtime/cable | `realtime_settings.rb` | `RealtimeSettings` |
|
|
58
|
+
| Authentication | `authentication_settings.rb` | `AuthenticationSettings` |
|
|
59
|
+
| Events/callbacks | `events.rb` | `Events` |
|
|
60
|
+
| Scraper adapters | `scraper_registry.rb` | `ScraperRegistry` |
|
|
61
|
+
| Model extensions | `models.rb` / `model_definition.rb` | `Models` / `ModelDefinition` |
|
|
62
|
+
|
|
63
|
+
### Step 2: Add the Attribute
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
# lib/source_monitor/configuration/fetching_settings.rb
|
|
67
|
+
class FetchingSettings
|
|
68
|
+
attr_accessor :min_interval_minutes,
|
|
69
|
+
:max_interval_minutes,
|
|
70
|
+
:increase_factor,
|
|
71
|
+
:decrease_factor,
|
|
72
|
+
:failure_increase_factor,
|
|
73
|
+
:jitter_percent,
|
|
74
|
+
:my_new_setting # <-- Add here
|
|
75
|
+
|
|
76
|
+
def reset!
|
|
77
|
+
@min_interval_minutes = 5
|
|
78
|
+
@max_interval_minutes = 24 * 60
|
|
79
|
+
@increase_factor = 1.25
|
|
80
|
+
@decrease_factor = 0.75
|
|
81
|
+
@failure_increase_factor = 1.5
|
|
82
|
+
@jitter_percent = 0.1
|
|
83
|
+
@my_new_setting = "default" # <-- Set default here
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Step 3: Write Tests
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
# test/lib/source_monitor/configuration_test.rb
|
|
92
|
+
test "my_new_setting has correct default" do
|
|
93
|
+
assert_equal "default", SourceMonitor.config.fetching.my_new_setting
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
test "my_new_setting can be overridden" do
|
|
97
|
+
SourceMonitor.configure do |config|
|
|
98
|
+
config.fetching.my_new_setting = "custom"
|
|
99
|
+
end
|
|
100
|
+
assert_equal "custom", SourceMonitor.config.fetching.my_new_setting
|
|
101
|
+
end
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Step 4: Verify Reset
|
|
105
|
+
|
|
106
|
+
Ensure `reset!` restores the default. The test suite calls `SourceMonitor.reset_configuration!` in setup, which recreates the entire Configuration object.
|
|
107
|
+
|
|
108
|
+
## Adding a Setting with Validation
|
|
109
|
+
|
|
110
|
+
For settings that need input normalization or validation, use custom setters:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
class ScrapingSettings
|
|
114
|
+
attr_accessor :max_in_flight_per_source, :max_bulk_batch_size
|
|
115
|
+
|
|
116
|
+
# Custom setter with normalization
|
|
117
|
+
def max_in_flight_per_source=(value)
|
|
118
|
+
@max_in_flight_per_source = normalize_numeric(value)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
private
|
|
122
|
+
|
|
123
|
+
def normalize_numeric(value)
|
|
124
|
+
return nil if value.nil?
|
|
125
|
+
return nil if value == ""
|
|
126
|
+
integer = value.respond_to?(:to_i) ? value.to_i : value
|
|
127
|
+
integer.positive? ? integer : nil
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
For enum-style settings with strict validation:
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
class RetentionSettings
|
|
136
|
+
def strategy=(value)
|
|
137
|
+
normalized = normalize_strategy(value)
|
|
138
|
+
@strategy = normalized unless normalized.nil?
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
def normalize_strategy(value)
|
|
144
|
+
return :destroy if value.nil?
|
|
145
|
+
if value.respond_to?(:to_sym)
|
|
146
|
+
candidate = value.to_sym
|
|
147
|
+
raise ArgumentError, "Invalid retention strategy #{value.inspect}" unless %i[destroy soft_delete].include?(candidate)
|
|
148
|
+
candidate
|
|
149
|
+
else
|
|
150
|
+
raise ArgumentError, "Invalid retention strategy #{value.inspect}"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Creating a New Settings Section
|
|
157
|
+
|
|
158
|
+
### Step 1: Create the Settings Class
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
# lib/source_monitor/configuration/notifications_settings.rb
|
|
162
|
+
# frozen_string_literal: true
|
|
163
|
+
|
|
164
|
+
module SourceMonitor
|
|
165
|
+
class Configuration
|
|
166
|
+
class NotificationsSettings
|
|
167
|
+
attr_accessor :enabled, :channels, :throttle_seconds
|
|
168
|
+
|
|
169
|
+
def initialize
|
|
170
|
+
reset!
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def reset!
|
|
174
|
+
@enabled = true
|
|
175
|
+
@channels = []
|
|
176
|
+
@throttle_seconds = 60
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Step 2: Register in Configuration
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
# lib/source_monitor/configuration.rb
|
|
187
|
+
require "source_monitor/configuration/notifications_settings"
|
|
188
|
+
|
|
189
|
+
class Configuration
|
|
190
|
+
attr_reader :http, :scrapers, :retention, :events, :models,
|
|
191
|
+
:realtime, :fetching, :health, :authentication, :scraping,
|
|
192
|
+
:notifications # <-- Add reader
|
|
193
|
+
|
|
194
|
+
def initialize
|
|
195
|
+
# ... existing initialization ...
|
|
196
|
+
@notifications = NotificationsSettings.new # <-- Initialize
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Step 3: Write Tests
|
|
202
|
+
|
|
203
|
+
```ruby
|
|
204
|
+
test "notifications settings have correct defaults" do
|
|
205
|
+
settings = SourceMonitor.config.notifications
|
|
206
|
+
assert_equal true, settings.enabled
|
|
207
|
+
assert_equal [], settings.channels
|
|
208
|
+
assert_equal 60, settings.throttle_seconds
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
test "notifications settings can be configured" do
|
|
212
|
+
SourceMonitor.configure do |config|
|
|
213
|
+
config.notifications.enabled = false
|
|
214
|
+
config.notifications.channels = [:email, :slack]
|
|
215
|
+
config.notifications.throttle_seconds = 30
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
settings = SourceMonitor.config.notifications
|
|
219
|
+
assert_equal false, settings.enabled
|
|
220
|
+
assert_equal [:email, :slack], settings.channels
|
|
221
|
+
assert_equal 30, settings.throttle_seconds
|
|
222
|
+
end
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Patterns by Section Type
|
|
226
|
+
|
|
227
|
+
### Simple Accessor Pattern (FetchingSettings, HealthSettings)
|
|
228
|
+
|
|
229
|
+
Plain `attr_accessor` with defaults in `reset!`. No validation.
|
|
230
|
+
|
|
231
|
+
### Normalized Setter Pattern (ScrapingSettings)
|
|
232
|
+
|
|
233
|
+
Custom setter that normalizes input (strings to integers, negatives to nil).
|
|
234
|
+
|
|
235
|
+
### Enum Setter Pattern (RetentionSettings, RealtimeSettings)
|
|
236
|
+
|
|
237
|
+
Custom setter that validates against an allowed list and raises `ArgumentError`.
|
|
238
|
+
|
|
239
|
+
### Handler/Callback Pattern (AuthenticationSettings, Events)
|
|
240
|
+
|
|
241
|
+
Registration methods that accept symbols, lambdas, or blocks.
|
|
242
|
+
|
|
243
|
+
### Registry Pattern (ScraperRegistry)
|
|
244
|
+
|
|
245
|
+
Named registration with lookup, unregistration, and enumeration.
|
|
246
|
+
|
|
247
|
+
### Nested Object Pattern (RealtimeSettings::SolidCableOptions)
|
|
248
|
+
|
|
249
|
+
Sub-objects with their own `reset!` and `to_h` methods.
|
|
250
|
+
|
|
251
|
+
## Testing Checklist
|
|
252
|
+
|
|
253
|
+
- [ ] Default value is correct
|
|
254
|
+
- [ ] Value can be overridden via `SourceMonitor.configure`
|
|
255
|
+
- [ ] `reset!` restores the default (tested via `SourceMonitor.reset_configuration!`)
|
|
256
|
+
- [ ] Validation raises `ArgumentError` for invalid values (if applicable)
|
|
257
|
+
- [ ] String/nil normalization works correctly (if applicable)
|
|
258
|
+
- [ ] Test file: `test/lib/source_monitor/configuration_test.rb`
|
|
259
|
+
- [ ] Run: `PARALLEL_WORKERS=1 bin/rails test test/lib/source_monitor/configuration_test.rb`
|
|
260
|
+
|
|
261
|
+
## References
|
|
262
|
+
|
|
263
|
+
- [reference/settings-catalog.md](reference/settings-catalog.md) -- All settings sections with their attributes
|
|
264
|
+
- [reference/settings-pattern.md](reference/settings-pattern.md) -- Step-by-step pattern for adding settings
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# Configuration Settings Catalog
|
|
2
|
+
|
|
3
|
+
All configuration sections with their attributes, defaults, and types.
|
|
4
|
+
|
|
5
|
+
## Top-Level Attributes
|
|
6
|
+
|
|
7
|
+
**File:** `lib/source_monitor/configuration.rb`
|
|
8
|
+
|
|
9
|
+
| Attribute | Type | Default | Description |
|
|
10
|
+
|-----------|------|---------|-------------|
|
|
11
|
+
| `queue_namespace` | String | `"source_monitor"` | Namespace prefix for queue names |
|
|
12
|
+
| `fetch_queue_name` | String | `"source_monitor_fetch"` | Queue name for fetch jobs |
|
|
13
|
+
| `scrape_queue_name` | String | `"source_monitor_scrape"` | Queue name for scrape jobs |
|
|
14
|
+
| `fetch_queue_concurrency` | Integer | `2` | Max concurrent fetch workers |
|
|
15
|
+
| `scrape_queue_concurrency` | Integer | `2` | Max concurrent scrape workers |
|
|
16
|
+
| `recurring_command_job_class` | Class/nil | `nil` | Custom recurring job class |
|
|
17
|
+
| `job_metrics_enabled` | Boolean | `true` | Enable job metrics tracking |
|
|
18
|
+
| `mission_control_enabled` | Boolean | `false` | Enable Mission Control integration |
|
|
19
|
+
| `mission_control_dashboard_path` | String/Proc/nil | `nil` | Path or callable for Mission Control |
|
|
20
|
+
|
|
21
|
+
**Methods:**
|
|
22
|
+
- `queue_name_for(:fetch)` / `queue_name_for(:scrape)` -- Returns prefixed queue name
|
|
23
|
+
- `concurrency_for(:fetch)` / `concurrency_for(:scrape)` -- Returns concurrency limit
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## HTTPSettings
|
|
28
|
+
|
|
29
|
+
**File:** `lib/source_monitor/configuration/http_settings.rb`
|
|
30
|
+
|
|
31
|
+
| Attribute | Type | Default | Description |
|
|
32
|
+
|-----------|------|---------|-------------|
|
|
33
|
+
| `timeout` | Integer | `15` | Total request timeout (seconds) |
|
|
34
|
+
| `open_timeout` | Integer | `5` | Connection open timeout (seconds) |
|
|
35
|
+
| `max_redirects` | Integer | `5` | Max HTTP redirects to follow |
|
|
36
|
+
| `user_agent` | String | `"SourceMonitor/<version>"` | User-Agent header value |
|
|
37
|
+
| `proxy` | String/nil | `nil` | HTTP proxy URL |
|
|
38
|
+
| `headers` | Hash | `{}` | Default HTTP headers |
|
|
39
|
+
| `retry_max` | Integer | `4` | Max retry attempts |
|
|
40
|
+
| `retry_interval` | Float | `0.5` | Base retry interval (seconds) |
|
|
41
|
+
| `retry_interval_randomness` | Float | `0.5` | Retry interval randomness factor |
|
|
42
|
+
| `retry_backoff_factor` | Integer | `2` | Exponential backoff multiplier |
|
|
43
|
+
| `retry_statuses` | Array/nil | `nil` | HTTP statuses to retry on |
|
|
44
|
+
|
|
45
|
+
Has `reset!` method.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## FetchingSettings
|
|
50
|
+
|
|
51
|
+
**File:** `lib/source_monitor/configuration/fetching_settings.rb`
|
|
52
|
+
|
|
53
|
+
| Attribute | Type | Default | Description |
|
|
54
|
+
|-----------|------|---------|-------------|
|
|
55
|
+
| `min_interval_minutes` | Integer | `5` | Minimum fetch interval |
|
|
56
|
+
| `max_interval_minutes` | Integer | `1440` (24h) | Maximum fetch interval |
|
|
57
|
+
| `increase_factor` | Float | `1.25` | Multiplier when content unchanged |
|
|
58
|
+
| `decrease_factor` | Float | `0.75` | Multiplier when content changed |
|
|
59
|
+
| `failure_increase_factor` | Float | `1.5` | Multiplier on fetch failure |
|
|
60
|
+
| `jitter_percent` | Float | `0.1` | Random jitter (10%) |
|
|
61
|
+
|
|
62
|
+
Has `reset!` method. All attributes are plain `attr_accessor`.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## HealthSettings
|
|
67
|
+
|
|
68
|
+
**File:** `lib/source_monitor/configuration/health_settings.rb`
|
|
69
|
+
|
|
70
|
+
| Attribute | Type | Default | Description |
|
|
71
|
+
|-----------|------|---------|-------------|
|
|
72
|
+
| `window_size` | Integer | `20` | Rolling window of fetches for health calc |
|
|
73
|
+
| `healthy_threshold` | Float | `0.8` | Success rate above = healthy |
|
|
74
|
+
| `warning_threshold` | Float | `0.5` | Success rate above = warning |
|
|
75
|
+
| `auto_pause_threshold` | Float | `0.2` | Success rate below = auto-pause |
|
|
76
|
+
| `auto_resume_threshold` | Float | `0.6` | Success rate above = auto-resume |
|
|
77
|
+
| `auto_pause_cooldown_minutes` | Integer | `60` | Cooldown before auto-resume check |
|
|
78
|
+
|
|
79
|
+
Has `reset!` method. All attributes are plain `attr_accessor`.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## ScrapingSettings
|
|
84
|
+
|
|
85
|
+
**File:** `lib/source_monitor/configuration/scraping_settings.rb`
|
|
86
|
+
|
|
87
|
+
| Attribute | Type | Default | Description |
|
|
88
|
+
|-----------|------|---------|-------------|
|
|
89
|
+
| `max_in_flight_per_source` | Integer/nil | `25` | Max concurrent scrape jobs per source |
|
|
90
|
+
| `max_bulk_batch_size` | Integer/nil | `100` | Max items in a bulk scrape batch |
|
|
91
|
+
|
|
92
|
+
Has `reset!` method. Custom setters normalize values:
|
|
93
|
+
- `nil` -> `nil`
|
|
94
|
+
- `""` -> `nil`
|
|
95
|
+
- `0` or negative -> `nil`
|
|
96
|
+
- String -> parsed integer (if positive)
|
|
97
|
+
- Positive integer -> kept as-is
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## RetentionSettings
|
|
102
|
+
|
|
103
|
+
**File:** `lib/source_monitor/configuration/retention_settings.rb`
|
|
104
|
+
|
|
105
|
+
| Attribute | Type | Default | Description |
|
|
106
|
+
|-----------|------|---------|-------------|
|
|
107
|
+
| `items_retention_days` | Integer/nil | `nil` | Days to keep items (nil = forever) |
|
|
108
|
+
| `max_items` | Integer/nil | `nil` | Max items per source (nil = unlimited) |
|
|
109
|
+
| `strategy` | Symbol | `:destroy` | `:destroy` or `:soft_delete` |
|
|
110
|
+
|
|
111
|
+
No `reset!` method (defaults set in `initialize`). The `strategy=` setter validates against allowed values and raises `ArgumentError` for invalid input. Setting `nil` resets to `:destroy`.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## RealtimeSettings
|
|
116
|
+
|
|
117
|
+
**File:** `lib/source_monitor/configuration/realtime_settings.rb`
|
|
118
|
+
|
|
119
|
+
| Attribute | Type | Default | Description |
|
|
120
|
+
|-----------|------|---------|-------------|
|
|
121
|
+
| `adapter` | Symbol | `:solid_cable` | One of `:solid_cable`, `:redis`, `:async` |
|
|
122
|
+
| `redis_url` | String/nil | `nil` | Redis URL (for `:redis` adapter) |
|
|
123
|
+
| `solid_cable` | SolidCableOptions | (nested object) | Solid Cable options |
|
|
124
|
+
|
|
125
|
+
Has `reset!` method. The `adapter=` setter validates against `VALID_ADAPTERS`.
|
|
126
|
+
|
|
127
|
+
**SolidCableOptions:**
|
|
128
|
+
|
|
129
|
+
| Attribute | Type | Default |
|
|
130
|
+
|-----------|------|---------|
|
|
131
|
+
| `polling_interval` | String | `"0.1.seconds"` |
|
|
132
|
+
| `message_retention` | String | `"1.day"` |
|
|
133
|
+
| `autotrim` | Boolean | `true` |
|
|
134
|
+
| `silence_polling` | Boolean | `true` |
|
|
135
|
+
| `use_skip_locked` | Boolean | `true` |
|
|
136
|
+
| `trim_batch_size` | Integer/nil | `nil` |
|
|
137
|
+
| `connects_to` | Hash/nil | `nil` |
|
|
138
|
+
|
|
139
|
+
**Methods:**
|
|
140
|
+
- `action_cable_config` -- Returns hash suitable for ActionCable configuration
|
|
141
|
+
- `solid_cable=(hash)` -- Bulk-assign SolidCable options from a hash
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## AuthenticationSettings
|
|
146
|
+
|
|
147
|
+
**File:** `lib/source_monitor/configuration/authentication_settings.rb`
|
|
148
|
+
|
|
149
|
+
| Attribute | Type | Default | Description |
|
|
150
|
+
|-----------|------|---------|-------------|
|
|
151
|
+
| `authenticate_handler` | Handler/nil | `nil` | Authentication handler |
|
|
152
|
+
| `authorize_handler` | Handler/nil | `nil` | Authorization handler |
|
|
153
|
+
| `current_user_method` | Symbol/nil | `nil` | Method name for current user |
|
|
154
|
+
| `user_signed_in_method` | Symbol/nil | `nil` | Method name for signed-in check |
|
|
155
|
+
|
|
156
|
+
Has `reset!` method.
|
|
157
|
+
|
|
158
|
+
**Methods:**
|
|
159
|
+
- `authenticate_with(handler = nil, &block)` -- Register authentication handler
|
|
160
|
+
- `authorize_with(handler = nil, &block)` -- Register authorization handler
|
|
161
|
+
|
|
162
|
+
Handler types: `:symbol` (method name), `:callable` (lambda/proc/block).
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Events
|
|
167
|
+
|
|
168
|
+
**File:** `lib/source_monitor/configuration/events.rb`
|
|
169
|
+
|
|
170
|
+
| Callback Key | Description |
|
|
171
|
+
|-------------|-------------|
|
|
172
|
+
| `after_item_created` | Fires after a new item is created from a feed entry |
|
|
173
|
+
| `after_item_scraped` | Fires after an item's content is scraped |
|
|
174
|
+
| `after_fetch_completed` | Fires after a feed fetch completes (success or failure) |
|
|
175
|
+
|
|
176
|
+
**Methods:**
|
|
177
|
+
- `after_item_created(handler = nil, &block)` -- Register callback
|
|
178
|
+
- `after_item_scraped(handler = nil, &block)` -- Register callback
|
|
179
|
+
- `after_fetch_completed(handler = nil, &block)` -- Register callback
|
|
180
|
+
- `register_item_processor(processor = nil, &block)` -- Register item processor
|
|
181
|
+
- `callbacks_for(name)` -- Returns array of callbacks (dup'd)
|
|
182
|
+
- `item_processors` -- Returns array of processors (dup'd)
|
|
183
|
+
- `reset!` -- Clears all callbacks and processors
|
|
184
|
+
|
|
185
|
+
All handlers must respond to `#call`. Raises `ArgumentError` otherwise.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## ScraperRegistry
|
|
190
|
+
|
|
191
|
+
**File:** `lib/source_monitor/configuration/scraper_registry.rb`
|
|
192
|
+
|
|
193
|
+
Enumerable registry of scraper adapters.
|
|
194
|
+
|
|
195
|
+
**Methods:**
|
|
196
|
+
- `register(name, adapter)` -- Register adapter class by name
|
|
197
|
+
- `unregister(name)` -- Remove adapter
|
|
198
|
+
- `adapter_for(name)` -- Look up adapter class by name
|
|
199
|
+
- `each` -- Iterate over `{name => adapter}` pairs
|
|
200
|
+
|
|
201
|
+
Names are normalized to lowercase alphanumeric + underscores. Adapter classes must inherit from `SourceMonitor::Scrapers::Base`.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Models
|
|
206
|
+
|
|
207
|
+
**File:** `lib/source_monitor/configuration/models.rb`
|
|
208
|
+
|
|
209
|
+
| Attribute | Type | Default | Description |
|
|
210
|
+
|-----------|------|---------|-------------|
|
|
211
|
+
| `table_name_prefix` | String | `"sourcemon_"` | Database table prefix |
|
|
212
|
+
|
|
213
|
+
**Model Keys:** `source`, `item`, `fetch_log`, `scrape_log`, `health_check_log`, `item_content`, `log_entry`
|
|
214
|
+
|
|
215
|
+
Each key returns a `ModelDefinition` instance.
|
|
216
|
+
|
|
217
|
+
**Methods:**
|
|
218
|
+
- `for(name)` -- Returns `ModelDefinition` by name (raises on unknown)
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## ModelDefinition
|
|
223
|
+
|
|
224
|
+
**File:** `lib/source_monitor/configuration/model_definition.rb`
|
|
225
|
+
|
|
226
|
+
**Methods:**
|
|
227
|
+
- `include_concern(concern = nil, &block)` -- Register a concern module
|
|
228
|
+
- `each_concern` -- Iterate over registered concerns (yields `[signature, resolved_module]`)
|
|
229
|
+
- `validate(handler = nil, **options, &block)` -- Register a custom validation
|
|
230
|
+
- `validations` -- Returns array of `ValidationDefinition` instances
|
|
231
|
+
|
|
232
|
+
Concerns can be: Module instance, String constant name, or anonymous block.
|
|
233
|
+
Validations can be: Symbol method name, String, lambda, or block.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## ValidationDefinition
|
|
238
|
+
|
|
239
|
+
**File:** `lib/source_monitor/configuration/validation_definition.rb`
|
|
240
|
+
|
|
241
|
+
| Attribute | Type | Description |
|
|
242
|
+
|-----------|------|-------------|
|
|
243
|
+
| `handler` | Symbol/Proc | The validation handler |
|
|
244
|
+
| `options` | Hash | Options hash (e.g., `{ if: :active? }`) |
|
|
245
|
+
|
|
246
|
+
**Methods:**
|
|
247
|
+
- `signature` -- Returns deduplication key
|
|
248
|
+
- `symbol?` -- Returns true if handler is a Symbol or String
|