rails_pulse 0.2.5.pre.9 → 0.2.5.pre.11

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/rails_pulse/components/badge.css +2 -2
  3. data/app/assets/stylesheets/rails_pulse/components/button.css +1 -1
  4. data/app/assets/stylesheets/rails_pulse/components/datepicker.css +0 -2
  5. data/app/assets/stylesheets/rails_pulse/components/flash.css +1 -1
  6. data/app/assets/stylesheets/rails_pulse/components/layouts.css +2 -2
  7. data/app/assets/stylesheets/rails_pulse/components/prose.css +2 -2
  8. data/app/assets/stylesheets/rails_pulse/components/table.css +2 -2
  9. data/app/controllers/concerns/chart_table_concern.rb +1 -2
  10. data/app/controllers/rails_pulse/application_controller.rb +15 -20
  11. data/app/controllers/rails_pulse/job_runs_controller.rb +1 -1
  12. data/app/controllers/rails_pulse/jobs_controller.rb +2 -6
  13. data/app/controllers/rails_pulse/queries_controller.rb +2 -2
  14. data/app/controllers/rails_pulse/requests_controller.rb +1 -1
  15. data/app/controllers/rails_pulse/routes_controller.rb +1 -1
  16. data/app/helpers/rails_pulse/application_helper.rb +2 -44
  17. data/app/jobs/rails_pulse/backfill_summaries_job.rb +1 -1
  18. data/app/jobs/rails_pulse/cleanup_job.rb +4 -4
  19. data/app/jobs/rails_pulse/summary_job.rb +6 -6
  20. data/app/models/concerns/rails_pulse/taggable.rb +2 -2
  21. data/app/services/rails_pulse/analysis/explain_plan_analyzer.rb +1 -1
  22. data/app/services/rails_pulse/summary_service.rb +3 -3
  23. data/app/views/rails_pulse/components/_table_pagination.html.erb +9 -9
  24. data/lib/rails_pulse/cleanup_service.rb +10 -10
  25. data/lib/rails_pulse/configuration.rb +2 -14
  26. data/lib/rails_pulse/engine.rb +0 -7
  27. data/lib/rails_pulse/job_run_collector.rb +9 -5
  28. data/lib/rails_pulse/middleware/asset_server.rb +7 -8
  29. data/lib/rails_pulse/paginator.rb +23 -0
  30. data/lib/rails_pulse/subscribers/operation_subscriber.rb +13 -13
  31. data/lib/rails_pulse/tracker.rb +2 -5
  32. data/lib/rails_pulse/version.rb +1 -1
  33. data/lib/rails_pulse.rb +7 -2
  34. data/public/rails-pulse-assets/rails-pulse.css +1 -1
  35. data/public/rails-pulse-assets/rails-pulse.css.map +1 -1
  36. metadata +22 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0d584256d9cd683cc6f5f10f470a6d13a5eb46adf26040f8d22ce487464543c
4
- data.tar.gz: 30a4f265826ebebd5b5e981046da97231a08c80b6a12fbe48952e9bf0791bd5a
3
+ metadata.gz: ce571d5ae696930e4885ac654389e354ef235f0b071046b95bfbd1089b92015d
4
+ data.tar.gz: 1b77c49cc62356cc0faa30b641cde07998ce6252c6ef155386dbd2ac6dbbeea4
5
5
  SHA512:
6
- metadata.gz: 6ed38e5f1dc9395fcc0a9ee31cc4c07d345326d4f9d7c45a8d9d9c07cb19eef347f6634c049553e45456e85f87610e62d2f98bee8be2c32551358722a9023784
7
- data.tar.gz: 3a6b8003127bedec29b8dcb269d843458489ad805846b2c71296a80ef0a4fae35c6f2bade7e37486a35468c23e967af3fd947d4903430cfbe43a19ad32826671
6
+ metadata.gz: 7f2c84081607cc389a4098c3bd70c1df2a396aa2c569befff183f13d8dceb2b6e884559df26ac49b7c2cd10b79490e9e6d0366eb582450f85fdb02e938e1f75b
7
+ data.tar.gz: 6d096ff11eca6bd80968118bcb041ffb4dbd13ff58bf1108a69dec4eaefef44e229dba5700039b43cb4f55532fc16f25ed6ca4eb96b7d3e2243f2bd038ca3279
@@ -61,11 +61,11 @@
61
61
  .badge--trend rails-pulse-icon { color: var(--badge-color, currentColor); }
62
62
  html[data-color-scheme="dark"] .badge--trend rails-pulse-icon {
63
63
  /* Lighten icon relative to badge text color for contrast */
64
- color: color-mix(in srgb, var(--badge-color) 55%, white 45%);
64
+ opacity: 0.8;
65
65
  }
66
66
 
67
67
  /* Trend amount lightening (dark mode only) */
68
68
  .badge--trend .badge__trend-amount { color: var(--badge-color, currentColor); }
69
69
  html[data-color-scheme="dark"] .badge--trend .badge__trend-amount {
70
- color: color-mix(in srgb, var(--badge-color) 55%, white 45%);
70
+ opacity: 0.8;
71
71
  }
@@ -1,6 +1,6 @@
1
1
  .btn {
2
2
  --btn-background: var(--color-bg);
3
- --hover-color: oklch(from var(--btn-background) calc(l * .95) c h);
3
+ --hover-color: rgba(0, 0, 0, 0.05);
4
4
 
5
5
  align-items: center;
6
6
  background-color: var(--btn-background);
@@ -1,5 +1,3 @@
1
- @import url("https://esm.sh/flatpickr@4.6.13/dist/flatpickr.min.css");
2
-
3
1
  .flatpickr-calendar {
4
2
  --calendar-size: 250px;
5
3
  --container-size: 220px;
@@ -2,7 +2,7 @@
2
2
  align-items: center;
3
3
  animation: appear-then-fade 4s 300ms both;
4
4
  backdrop-filter: var(--blur-sm) var(--contrast-75);
5
- background-color: var(--flash-background, rgb(from var(--color-text) r g b / .65));
5
+ background-color: var(--flash-background, rgba(0, 0, 0, 0.65));
6
6
  border-radius: var(--rounded-full);
7
7
  color: var(--flash-color, var(--color-text-reversed));
8
8
  column-gap: var(--size-2);
@@ -33,7 +33,7 @@
33
33
 
34
34
  #header {
35
35
  align-items: center;
36
- background-color: rgb(from var(--color-border-light) r g b / .5);
36
+ background-color: rgba(0, 0, 0, 0.05);
37
37
  border-block-end-width: var(--border);
38
38
  block-size: var(--size-16);
39
39
  column-gap: var(--size-4);
@@ -43,7 +43,7 @@
43
43
  }
44
44
 
45
45
  #sidebar {
46
- background-color: rgb(from var(--color-border-light) r g b / .5);
46
+ background-color: rgba(0, 0, 0, 0.05);
47
47
  border-inline-end-width: var(--sidebar-border-width, 0);
48
48
  display: flex;
49
49
  flex-direction: column;
@@ -122,12 +122,12 @@
122
122
  }
123
123
 
124
124
  del {
125
- background-color: rgb(from var(--color-negative) r g b / .1);
125
+ background-color: rgba(220, 38, 38, 0.1);
126
126
  color: var(--color-negative);
127
127
  }
128
128
 
129
129
  ins {
130
- background-color: rgb(from var(--color-positive) r g b / .1);
130
+ background-color: rgba(34, 197, 94, 0.1);
131
131
  color: var(--color-positive);
132
132
  }
133
133
 
@@ -17,7 +17,7 @@
17
17
  }
18
18
 
19
19
  tr:hover {
20
- background-color: rgb(from var(--color-border-light) r g b / .5);
20
+ background-color: rgba(0, 0, 0, 0.05);
21
21
  }
22
22
 
23
23
  th {
@@ -45,7 +45,7 @@
45
45
  }
46
46
 
47
47
  tfoot {
48
- background-color: rgb(from var(--color-border-light) r g b / .5);
48
+ background-color: rgba(0, 0, 0, 0.05);
49
49
  border-block-start-width: var(--border);
50
50
  font-weight: var(--font-medium);
51
51
  }
@@ -51,8 +51,7 @@ module ChartTableConcern
51
51
  table_results = build_table_results
52
52
  handle_pagination
53
53
 
54
- # Use pagy_options for version compatibility
55
- @pagy, @table_data = pagy(table_results, **pagy_options(session_pagination_limit))
54
+ @pagination, @table_data = paginate(table_results, limit: session_pagination_limit)
56
55
  end
57
56
 
58
57
  def setup_zoom_range_data
@@ -1,12 +1,5 @@
1
1
  module RailsPulse
2
2
  class ApplicationController < ActionController::Base
3
- # Support both Pagy 8.x (Backend) and Pagy 43+ (Method)
4
- if defined?(Pagy::Method)
5
- include Pagy::Method
6
- else
7
- include Pagy::Backend
8
- end
9
-
10
3
  before_action :authenticate_rails_pulse_user!
11
4
  before_action :set_show_non_tagged_default
12
5
  helper_method :session_global_filters, :session_disabled_tags
@@ -66,6 +59,10 @@ module RailsPulse
66
59
 
67
60
  private
68
61
 
62
+ def logger
63
+ RailsPulse.logger
64
+ end
65
+
69
66
  def authenticate_rails_pulse_user!
70
67
  return unless RailsPulse.configuration.authentication_enabled
71
68
 
@@ -83,15 +80,15 @@ module RailsPulse
83
80
  if respond_to?(method_name, true)
84
81
  send(method_name)
85
82
  else
86
- Rails.logger.error "RailsPulse: Authentication method '#{method_name}' not found"
83
+ logger.error "RailsPulse: Authentication method '#{method_name}' not found"
87
84
  render plain: "Authentication configuration error", status: :internal_server_error
88
85
  end
89
86
  else
90
- Rails.logger.error "RailsPulse: Invalid authentication method type: #{RailsPulse.configuration.authentication_method.class}"
87
+ logger.error "RailsPulse: Invalid authentication method type: #{RailsPulse.configuration.authentication_method.class}"
91
88
  render plain: "Authentication configuration error", status: :internal_server_error
92
89
  end
93
90
  rescue StandardError => e
94
- Rails.logger.warn "RailsPulse authentication failed: #{e.message}"
91
+ logger.warn "RailsPulse authentication failed: #{e.message}"
95
92
  redirect_to RailsPulse.configuration.authentication_redirect_path
96
93
  end
97
94
 
@@ -102,7 +99,7 @@ module RailsPulse
102
99
  expected_password = ENV.fetch("RAILS_PULSE_PASSWORD", nil)
103
100
 
104
101
  if expected_password.nil?
105
- Rails.logger.error "RailsPulse: No authentication method configured and RAILS_PULSE_PASSWORD not set. Access denied."
102
+ logger.error "RailsPulse: No authentication method configured and RAILS_PULSE_PASSWORD not set. Access denied."
106
103
  false
107
104
  else
108
105
  username == expected_username && password == expected_password
@@ -144,7 +141,7 @@ module RailsPulse
144
141
 
145
142
  thresholds[threshold.to_sym]
146
143
  rescue StandardError => e
147
- Rails.logger.warn "Failed to get performance threshold: #{e.message}"
144
+ logger.warn "Failed to get performance threshold: #{e.message}"
148
145
  nil
149
146
  end
150
147
 
@@ -153,14 +150,12 @@ module RailsPulse
153
150
  session[:show_non_tagged] = true if session[:show_non_tagged].nil?
154
151
  end
155
152
 
156
- # Returns Pagy options hash with correct parameter name for current version
157
- # Pagy 8.x uses 'items:', Pagy 43+ uses 'limit:'
158
- def pagy_options(count)
159
- if defined?(Pagy::Method)
160
- { limit: count } # Pagy 43+
161
- else
162
- { items: count } # Pagy 8.x
163
- end
153
+ def paginate(collection, limit:)
154
+ page = [ params[:page].to_i, 1 ].max
155
+ raw = collection.count(:all)
156
+ count = raw.is_a?(Hash) ? raw.size : raw
157
+ records = collection.offset((page - 1) * limit).limit(limit)
158
+ [ RailsPulse::Paginator.new(count: count, page: page, limit: limit), records ]
164
159
  end
165
160
  end
166
161
  end
@@ -7,7 +7,7 @@ module RailsPulse
7
7
 
8
8
  def index
9
9
  @ransack_query = @job.runs.ransack(params[:q])
10
- @pagy, @runs = pagy(@ransack_query.result.order(occurred_at: :desc), **pagy_options(session_pagination_limit))
10
+ @pagination, @runs = paginate(@ransack_query.result.order(occurred_at: :desc), limit: session_pagination_limit)
11
11
  @table_data = @runs
12
12
  end
13
13
 
@@ -20,9 +20,7 @@ module RailsPulse
20
20
  # Apply tag filters from session
21
21
  base_query = apply_tag_filters(@ransack_query.result)
22
22
 
23
- @pagy, @jobs = pagy(base_query.order(runs_count: :desc),
24
- **pagy_options(session_pagination_limit),
25
- overflow: :last_page)
23
+ @pagination, @jobs = paginate(base_query.order(runs_count: :desc), limit: session_pagination_limit)
26
24
  @table_data = @jobs
27
25
  @available_queues = RailsPulse::Job.distinct.pluck(:queue_name).compact.sort
28
26
  end
@@ -56,9 +54,7 @@ module RailsPulse
56
54
  # Apply tag filters from session
57
55
  base_query = apply_tag_filters(@ransack_query.result)
58
56
 
59
- @pagy, @recent_runs = pagy(base_query,
60
- **pagy_options(session_pagination_limit),
61
- overflow: :last_page)
57
+ @pagination, @recent_runs = paginate(base_query, limit: session_pagination_limit)
62
58
  @table_data = @recent_runs
63
59
  end
64
60
 
@@ -32,7 +32,7 @@ module RailsPulse
32
32
  }
33
33
  end
34
34
  rescue => e
35
- Rails.logger.error("[QueryAnalysis] Analysis failed for query #{@query.id}: #{e.message}")
35
+ logger.error("[QueryAnalysis] Analysis failed for query #{@query.id}: #{e.message}")
36
36
 
37
37
  respond_to do |format|
38
38
  format.turbo_stream {
@@ -163,7 +163,7 @@ module RailsPulse
163
163
  table_results = build_table_results
164
164
  handle_pagination
165
165
 
166
- @pagy, @table_data = pagy(table_results, **pagy_options(session_pagination_limit))
166
+ @pagination, @table_data = paginate(table_results, limit: session_pagination_limit)
167
167
  end
168
168
 
169
169
  def handle_pagination
@@ -123,7 +123,7 @@ module RailsPulse
123
123
  table_results = build_table_results
124
124
  handle_pagination
125
125
 
126
- @pagy, @table_data = pagy(table_results, **pagy_options(session_pagination_limit))
126
+ @pagination, @table_data = paginate(table_results, limit: session_pagination_limit)
127
127
  end
128
128
 
129
129
  def handle_pagination
@@ -142,7 +142,7 @@ module RailsPulse
142
142
  table_results = build_table_results
143
143
  handle_pagination
144
144
 
145
- @pagy, @table_data = pagy(table_results, **pagy_options(session_pagination_limit))
145
+ @pagination, @table_data = paginate(table_results, limit: session_pagination_limit)
146
146
  end
147
147
 
148
148
  def handle_pagination
@@ -8,10 +8,6 @@ module RailsPulse
8
8
  include FormHelper
9
9
  include TagsHelper
10
10
 
11
- # Include Pagy frontend helpers for Pagy 8.x compatibility
12
- # Pagy 43+ doesn't need this, but it doesn't hurt to include it
13
- include Pagy::Frontend if defined?(Pagy::Frontend)
14
-
15
11
  # Replacement for lucide_icon helper that works with pre-compiled assets
16
12
  # Outputs a custom element that will be hydrated by Stimulus
17
13
  def rails_pulse_icon(name, options = {})
@@ -69,47 +65,9 @@ module RailsPulse
69
65
  end
70
66
 
71
67
  private :normalize_dimension
72
- # Get items per page from Pagy instance (compatible with Pagy 8.x and 43+)
73
- def pagy_items(pagy)
74
- # Pagy 43+ uses options[:items] or has a limit method
75
- if pagy.respond_to?(:options) && pagy.options.is_a?(Hash)
76
- pagy.options[:items]
77
- # Pagy 8.x uses vars[:items]
78
- elsif pagy.respond_to?(:vars)
79
- pagy.vars[:items]
80
- # Fallback
81
- else
82
- pagy.limit || 10
83
- end
84
- end
85
-
86
- # Get page URL from Pagy instance (compatible with Pagy 8.x and 43+)
87
- def pagy_page_url(pagy, page_number)
88
- # Pagy 43+ has page_url method
89
- if pagy.respond_to?(:page_url)
90
- pagy.page_url(page_number)
91
- # Pagy 8.x requires using pagy_url_for helper
92
- else
93
- pagy_url_for(pagy, page_number)
94
- end
95
- end
96
-
97
- # Get previous page number (compatible with Pagy 8.x and 43+)
98
- def pagy_previous(pagy)
99
- # Pagy 43+ uses 'previous'
100
- if pagy.respond_to?(:previous)
101
- pagy.previous
102
- # Pagy 8.x uses 'prev'
103
- elsif pagy.respond_to?(:prev)
104
- pagy.prev
105
- else
106
- nil
107
- end
108
- end
109
68
 
110
- # Get next page number (compatible with Pagy 8.x and 43+)
111
- def pagy_next(pagy)
112
- pagy.respond_to?(:next) ? pagy.next : nil
69
+ def page_url(page_number)
70
+ url_for(request.query_parameters.merge(page: page_number))
113
71
  end
114
72
 
115
73
  # Make Rails Pulse routes available as rails_pulse in views
@@ -16,7 +16,7 @@ module RailsPulse
16
16
  period_end = Summary.calculate_period_end(period_type, end_date)
17
17
 
18
18
  while current <= period_end
19
- Rails.logger.info "[RailsPulse] Backfilling #{period_type} summary for #{current}"
19
+ RailsPulse.logger.info "Backfilling #{period_type} summary for #{current}"
20
20
 
21
21
  SummaryService.new(period_type, current).perform
22
22
 
@@ -3,16 +3,16 @@ module RailsPulse
3
3
  def perform
4
4
  return unless RailsPulse.configuration.archiving_enabled
5
5
 
6
- Rails.logger.info "[RailsPulse::CleanupJob] Starting scheduled cleanup"
6
+ RailsPulse.logger.info "[CleanupJob] Starting scheduled cleanup"
7
7
 
8
8
  stats = CleanupService.perform
9
9
 
10
- Rails.logger.info "[RailsPulse::CleanupJob] Cleanup completed - #{stats[:total_deleted]} records deleted"
10
+ RailsPulse.logger.info "[CleanupJob] Cleanup completed - #{stats[:total_deleted]} records deleted"
11
11
 
12
12
  stats
13
13
  rescue => e
14
- Rails.logger.error "[RailsPulse::CleanupJob] Cleanup failed: #{e.message}"
15
- Rails.logger.error e.backtrace.join("\n")
14
+ RailsPulse.logger.error "[CleanupJob] Cleanup failed: #{e.message}"
15
+ RailsPulse.logger.error e.backtrace.join("\n")
16
16
  raise
17
17
  end
18
18
  end
@@ -21,30 +21,30 @@ module RailsPulse
21
21
  end
22
22
  end
23
23
  rescue => e
24
- Rails.logger.error "[RailsPulse] Summary job failed: #{e.message}"
25
- Rails.logger.error e.backtrace.join("\n")
24
+ RailsPulse.logger.error "Summary job failed: #{e.message}"
25
+ RailsPulse.logger.error e.backtrace.join("\n")
26
26
  raise
27
27
  end
28
28
 
29
29
  private
30
30
 
31
31
  def process_hourly_summary(hour)
32
- Rails.logger.info "[RailsPulse] Processing hourly summary for #{hour}"
32
+ RailsPulse.logger.info "Processing hourly summary for #{hour}"
33
33
  SummaryService.new("hour", hour).perform
34
34
  end
35
35
 
36
36
  def process_daily_summary(date)
37
- Rails.logger.info "[RailsPulse] Processing daily summary for #{date}"
37
+ RailsPulse.logger.info "Processing daily summary for #{date}"
38
38
  SummaryService.new("day", date).perform
39
39
  end
40
40
 
41
41
  def process_weekly_summary(week_start)
42
- Rails.logger.info "[RailsPulse] Processing weekly summary for week starting #{week_start}"
42
+ RailsPulse.logger.info "Processing weekly summary for week starting #{week_start}"
43
43
  SummaryService.new("week", week_start).perform
44
44
  end
45
45
 
46
46
  def process_monthly_summary(month_start)
47
- Rails.logger.info "[RailsPulse] Processing monthly summary for month starting #{month_start}"
47
+ RailsPulse.logger.info "Processing monthly summary for month starting #{month_start}"
48
48
  SummaryService.new("month", month_start).perform
49
49
  end
50
50
  end
@@ -14,11 +14,11 @@ module RailsPulse
14
14
  # Note: LIKE patterns are sanitized to prevent SQL injection via wildcards
15
15
  scope :with_tag, ->(tag) {
16
16
  sanitized_tag = sanitize_sql_like(tag.to_s, "\\")
17
- where("#{table_name}.tags LIKE ?", "%#{sanitized_tag}%")
17
+ where("#{table_name}.tags LIKE ?", "%\"#{sanitized_tag}\"%")
18
18
  }
19
19
  scope :without_tag, ->(tag) {
20
20
  sanitized_tag = sanitize_sql_like(tag.to_s, "\\")
21
- where.not("#{table_name}.tags LIKE ?", "%#{sanitized_tag}%")
21
+ where.not("#{table_name}.tags LIKE ?", "%\"#{sanitized_tag}\"%")
22
22
  }
23
23
  scope :with_tags, -> { where("#{table_name}.tags IS NOT NULL AND #{table_name}.tags != '[]'") }
24
24
  end
@@ -41,7 +41,7 @@ module RailsPulse
41
41
  end
42
42
  end
43
43
  rescue => e
44
- Rails.logger.warn("[ExplainPlanAnalyzer] EXPLAIN failed for query #{query.id}: #{e.message}")
44
+ RailsPulse.logger.warn("[ExplainPlanAnalyzer] EXPLAIN failed for query #{query.id}: #{e.message}")
45
45
  nil
46
46
  end
47
47
  end
@@ -10,7 +10,7 @@ module RailsPulse
10
10
  end
11
11
 
12
12
  def perform
13
- Rails.logger.info "[RailsPulse] Starting #{period_type} summary for #{start_time}"
13
+ RailsPulse.logger.info "Starting #{period_type} summary for #{start_time}"
14
14
 
15
15
  ActiveRecord::Base.transaction do
16
16
  aggregate_requests # Overall system metrics
@@ -19,9 +19,9 @@ module RailsPulse
19
19
  aggregate_jobs # Per-job metrics
20
20
  end
21
21
 
22
- Rails.logger.info "[RailsPulse] Completed #{period_type} summary"
22
+ RailsPulse.logger.info "Completed #{period_type} summary"
23
23
  rescue => e
24
- Rails.logger.error "[RailsPulse] Summary failed: #{e.message}"
24
+ RailsPulse.logger.error "Summary failed: #{e.message}"
25
25
  raise
26
26
  end
27
27
 
@@ -1,5 +1,5 @@
1
1
  <div class="flex items-center mbs-4">
2
- <div class="text-sm text-subtle show@md">Total of <%= @pagy.count %> record(s).</div>
2
+ <div class="text-sm text-subtle show@md">Total of <%= @pagination.count %> record(s).</div>
3
3
 
4
4
  <div class="flex items-center mis-auto justify-end" style="column-gap: 1rem">
5
5
  <div class="flex items-center gap show@md"
@@ -7,7 +7,7 @@
7
7
  data-rails-pulse--pagination-url-value="<%= rails_pulse.pagination_limit_path %>">
8
8
  <label for="pagination_limit" class="text-sm font-medium">Rows per page</label>
9
9
  <%= select_tag :limit,
10
- options_for_select([[10, 10], [20, 20], [30, 30], [40, 40], [50, 50]], pagy_items(@pagy)),
10
+ options_for_select([[10, 10], [20, 20], [30, 30], [40, 40], [50, 50]], @pagination.limit),
11
11
  {
12
12
  id: "pagination_limit",
13
13
  class: "input",
@@ -21,24 +21,24 @@
21
21
  %>
22
22
  </div>
23
23
 
24
- <div class="text-sm font-medium"><%= "Page #{@pagy.page} of #{@pagy.last}" %></div>
24
+ <div class="text-sm font-medium"><%= "Page #{@pagination.page} of #{@pagination.last}" %></div>
25
25
 
26
26
  <nav class="flex items-center gap shrink-0" style="--btn-padding: .5rem;" aria-label="Pagination">
27
- <% previous_page = pagy_previous(@pagy) %>
28
- <% next_page = pagy_next(@pagy) %>
29
- <%= link_to pagy_page_url(@pagy, 1), class: "btn", aria: { disabled: previous_page.nil? }.compact_blank do %>
27
+ <% prev_page = @pagination.previous %>
28
+ <% next_page = @pagination.next %>
29
+ <%= link_to page_url(1), class: "btn", aria: { disabled: prev_page.nil? }.compact_blank do %>
30
30
  <%= rails_pulse_icon 'chevrons-left', width: '16', height: '16' %>
31
31
  <span class="sr-only">Go to first page</span>
32
32
  <% end %>
33
- <%= link_to pagy_page_url(@pagy, previous_page || @pagy.page), class: "btn", aria: { disabled: previous_page.nil? }.compact_blank do %>
33
+ <%= link_to page_url(prev_page || @pagination.page), class: "btn", aria: { disabled: prev_page.nil? }.compact_blank do %>
34
34
  <%= rails_pulse_icon 'chevron-left', width: '16', height: '16' %>
35
35
  <span class="sr-only">Go to previous page</span>
36
36
  <% end %>
37
- <%= link_to pagy_page_url(@pagy, next_page || @pagy.page), class: "btn", aria: { disabled: next_page.nil? }.compact_blank do %>
37
+ <%= link_to page_url(next_page || @pagination.page), class: "btn", aria: { disabled: next_page.nil? }.compact_blank do %>
38
38
  <%= rails_pulse_icon 'chevron-right', width: '16', height: '16' %>
39
39
  <span class="sr-only">Go to next page</span>
40
40
  <% end %>
41
- <%= link_to pagy_page_url(@pagy, @pagy.last), class: "btn", aria: { disabled: next_page.nil? }.compact_blank do %>
41
+ <%= link_to page_url(@pagination.last), class: "btn", aria: { disabled: next_page.nil? }.compact_blank do %>
42
42
  <%= rails_pulse_icon 'chevrons-right', width: '16', height: '16' %>
43
43
  <span class="sr-only">Go to last page</span>
44
44
  <% end %>
@@ -16,7 +16,7 @@ module RailsPulse
16
16
  def perform
17
17
  return unless cleanup_enabled?
18
18
 
19
- Rails.logger.info "[RailsPulse] Starting data cleanup..."
19
+ RailsPulse.logger.info "Starting data cleanup..."
20
20
 
21
21
  perform_time_based_cleanup
22
22
  perform_count_based_cleanup
@@ -35,7 +35,7 @@ module RailsPulse
35
35
  return unless @config.full_retention_period
36
36
 
37
37
  cutoff_time = @config.full_retention_period.ago
38
- Rails.logger.info "[RailsPulse] Time-based cleanup: removing records older than #{cutoff_time}"
38
+ RailsPulse.logger.info "Time-based cleanup: removing records older than #{cutoff_time}"
39
39
 
40
40
  # Clean up in order that respects foreign key constraints
41
41
  @stats[:time_based][:operations] = cleanup_operations_by_time(cutoff_time)
@@ -49,7 +49,7 @@ module RailsPulse
49
49
  def perform_count_based_cleanup
50
50
  return unless @config.max_table_records&.any?
51
51
 
52
- Rails.logger.info "[RailsPulse] Count-based cleanup: enforcing table record limits"
52
+ RailsPulse.logger.info "Count-based cleanup: enforcing table record limits"
53
53
 
54
54
  # Clean up in order that respects foreign key constraints
55
55
  @stats[:count_based][:operations] = cleanup_operations_by_count
@@ -266,18 +266,18 @@ module RailsPulse
266
266
  total_count_based = @stats[:count_based].values.sum
267
267
  @stats[:total_deleted] = total_time_based + total_count_based
268
268
 
269
- Rails.logger.info "[RailsPulse] Cleanup completed:"
270
- Rails.logger.info " Time-based: #{total_time_based} records deleted"
271
- Rails.logger.info " Count-based: #{total_count_based} records deleted"
272
- Rails.logger.info " Total: #{@stats[:total_deleted]} records deleted"
269
+ RailsPulse.logger.info "Cleanup completed:"
270
+ RailsPulse.logger.info " Time-based: #{total_time_based} records deleted"
271
+ RailsPulse.logger.info " Count-based: #{total_count_based} records deleted"
272
+ RailsPulse.logger.info " Total: #{@stats[:total_deleted]} records deleted"
273
273
 
274
274
  if @stats[:total_deleted] > 0
275
- Rails.logger.info " Breakdown:"
275
+ RailsPulse.logger.info " Breakdown:"
276
276
  @stats[:time_based].each do |table, count|
277
- Rails.logger.info " #{table} (time): #{count}" if count > 0
277
+ RailsPulse.logger.info " #{table} (time): #{count}" if count > 0
278
278
  end
279
279
  @stats[:count_based].each do |table, count|
280
- Rails.logger.info " #{table} (count): #{count}" if count > 0
280
+ RailsPulse.logger.info " #{table} (count): #{count}" if count > 0
281
281
  end
282
282
  end
283
283
  end
@@ -75,8 +75,6 @@ module RailsPulse
75
75
 
76
76
  # Tracking mode settings
77
77
  @async = true
78
-
79
- validate_configuration!
80
78
  end
81
79
 
82
80
  # Get all routes to ignore, including asset patterns if track_assets is false
@@ -104,11 +102,6 @@ module RailsPulse
104
102
  validate_tracking_settings!
105
103
  end
106
104
 
107
- # Revalidate configuration after changes
108
- def revalidate!
109
- validate_configuration!
110
- end
111
-
112
105
  private
113
106
 
114
107
  def validate_thresholds!
@@ -160,15 +153,10 @@ module RailsPulse
160
153
 
161
154
  def validate_authentication_settings!
162
155
  if @authentication_enabled && @authentication_method.nil?
163
- # Use Rails.logger if available, otherwise fall back to puts (for asset precompilation)
164
- if Rails.logger
165
- Rails.logger.warn "RailsPulse: Authentication is enabled but no authentication method is configured. This will deny all access."
166
- else
167
- puts "RailsPulse: Authentication is enabled but no authentication method is configured. This will deny all access."
168
- end
156
+ RailsPulse.logger.warn "Authentication is enabled but no authentication method is configured. This will deny all access."
169
157
  end
170
158
 
171
- if @authentication_method && ![ Proc, Symbol, String, NilClass ].include?(@authentication_method.class)
159
+ if @authentication_method && ![ Proc, Symbol, String ].include?(@authentication_method.class)
172
160
  raise ArgumentError, "authentication_method must be a Proc, Symbol, String, or nil, got #{@authentication_method.class}"
173
161
  end
174
162
  end
@@ -8,7 +8,6 @@ require "rails_pulse/extensions/active_record"
8
8
  require "request_store"
9
9
  require "rack/static"
10
10
  require "ransack"
11
- require "pagy"
12
11
  require "turbo-rails"
13
12
 
14
13
  module RailsPulse
@@ -107,12 +106,6 @@ module RailsPulse
107
106
  # Our custom group_by_date extension works regardless of ActiveRecord.default_timezone
108
107
  end
109
108
 
110
- initializer "rails_pulse.configure_logger", before: :initialize_logger do
111
- RailsPulse.configure do |config|
112
- config.logger ||= Rails.logger
113
- end
114
- end
115
-
116
109
  # CSP helper methods
117
110
  def self.csp_sources
118
111
  {