rails_pulse 0.1.2 → 0.1.3

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -4
  3. data/app/assets/images/rails_pulse/dashboard.png +0 -0
  4. data/app/assets/images/rails_pulse/request.png +0 -0
  5. data/app/assets/stylesheets/rails_pulse/application.css +28 -5
  6. data/app/assets/stylesheets/rails_pulse/components/badge.css +13 -0
  7. data/app/assets/stylesheets/rails_pulse/components/base.css +12 -2
  8. data/app/assets/stylesheets/rails_pulse/components/collapsible.css +30 -0
  9. data/app/assets/stylesheets/rails_pulse/components/popover.css +0 -1
  10. data/app/assets/stylesheets/rails_pulse/components/row.css +55 -3
  11. data/app/assets/stylesheets/rails_pulse/components/sidebar_menu.css +23 -0
  12. data/app/controllers/concerns/zoom_range_concern.rb +31 -0
  13. data/app/controllers/rails_pulse/application_controller.rb +5 -1
  14. data/app/controllers/rails_pulse/queries_controller.rb +46 -1
  15. data/app/controllers/rails_pulse/requests_controller.rb +14 -1
  16. data/app/controllers/rails_pulse/routes_controller.rb +40 -1
  17. data/app/helpers/rails_pulse/chart_helper.rb +15 -7
  18. data/app/javascript/rails_pulse/application.js +34 -3
  19. data/app/javascript/rails_pulse/controllers/collapsible_controller.js +32 -0
  20. data/app/javascript/rails_pulse/controllers/color_scheme_controller.js +2 -1
  21. data/app/javascript/rails_pulse/controllers/expandable_rows_controller.js +58 -0
  22. data/app/javascript/rails_pulse/controllers/index_controller.js +241 -11
  23. data/app/javascript/rails_pulse/controllers/popover_controller.js +28 -4
  24. data/app/javascript/rails_pulse/controllers/table_sort_controller.js +14 -0
  25. data/app/models/rails_pulse/queries/cards/average_query_times.rb +19 -19
  26. data/app/models/rails_pulse/queries/cards/execution_rate.rb +13 -8
  27. data/app/models/rails_pulse/queries/cards/percentile_query_times.rb +13 -8
  28. data/app/models/rails_pulse/query.rb +46 -0
  29. data/app/models/rails_pulse/routes/cards/average_response_times.rb +17 -19
  30. data/app/models/rails_pulse/routes/cards/error_rate_per_route.rb +13 -8
  31. data/app/models/rails_pulse/routes/cards/percentile_response_times.rb +13 -8
  32. data/app/models/rails_pulse/routes/cards/request_count_totals.rb +13 -8
  33. data/app/services/rails_pulse/analysis/backtrace_analyzer.rb +256 -0
  34. data/app/services/rails_pulse/analysis/base_analyzer.rb +67 -0
  35. data/app/services/rails_pulse/analysis/explain_plan_analyzer.rb +206 -0
  36. data/app/services/rails_pulse/analysis/index_recommendation_engine.rb +326 -0
  37. data/app/services/rails_pulse/analysis/n_plus_one_detector.rb +241 -0
  38. data/app/services/rails_pulse/analysis/query_characteristics_analyzer.rb +146 -0
  39. data/app/services/rails_pulse/analysis/suggestion_generator.rb +217 -0
  40. data/app/services/rails_pulse/query_analysis_service.rb +125 -0
  41. data/app/views/layouts/rails_pulse/_sidebar_menu.html.erb +0 -1
  42. data/app/views/layouts/rails_pulse/application.html.erb +0 -2
  43. data/app/views/rails_pulse/components/_breadcrumbs.html.erb +1 -1
  44. data/app/views/rails_pulse/components/_code_panel.html.erb +17 -3
  45. data/app/views/rails_pulse/components/_empty_state.html.erb +1 -1
  46. data/app/views/rails_pulse/components/_metric_card.html.erb +27 -4
  47. data/app/views/rails_pulse/components/_panel.html.erb +1 -1
  48. data/app/views/rails_pulse/components/_sparkline_stats.html.erb +5 -7
  49. data/app/views/rails_pulse/components/_table_head.html.erb +6 -1
  50. data/app/views/rails_pulse/dashboard/index.html.erb +1 -1
  51. data/app/views/rails_pulse/operations/show.html.erb +17 -15
  52. data/app/views/rails_pulse/queries/_analysis_error.html.erb +15 -0
  53. data/app/views/rails_pulse/queries/_analysis_prompt.html.erb +27 -0
  54. data/app/views/rails_pulse/queries/_analysis_results.html.erb +87 -0
  55. data/app/views/rails_pulse/queries/_analysis_section.html.erb +39 -0
  56. data/app/views/rails_pulse/queries/_show_table.html.erb +1 -1
  57. data/app/views/rails_pulse/queries/_table.html.erb +1 -1
  58. data/app/views/rails_pulse/queries/index.html.erb +48 -51
  59. data/app/views/rails_pulse/queries/show.html.erb +56 -52
  60. data/app/views/rails_pulse/requests/_operations.html.erb +30 -43
  61. data/app/views/rails_pulse/requests/_table.html.erb +3 -1
  62. data/app/views/rails_pulse/requests/index.html.erb +48 -51
  63. data/app/views/rails_pulse/routes/_table.html.erb +1 -1
  64. data/app/views/rails_pulse/routes/index.html.erb +49 -52
  65. data/app/views/rails_pulse/routes/show.html.erb +4 -4
  66. data/config/routes.rb +5 -1
  67. data/db/migrate/20250916031656_add_analysis_to_rails_pulse_queries.rb +13 -0
  68. data/db/rails_pulse_schema.rb +9 -0
  69. data/lib/generators/rails_pulse/convert_to_migrations_generator.rb +65 -0
  70. data/lib/generators/rails_pulse/install_generator.rb +71 -18
  71. data/lib/generators/rails_pulse/templates/migrations/install_rails_pulse_tables.rb +22 -0
  72. data/lib/generators/rails_pulse/templates/migrations/upgrade_rails_pulse_tables.rb +19 -0
  73. data/lib/generators/rails_pulse/upgrade_generator.rb +225 -0
  74. data/lib/rails_pulse/version.rb +1 -1
  75. data/lib/tasks/rails_pulse.rake +27 -8
  76. data/public/rails-pulse-assets/rails-pulse.css +1 -1
  77. data/public/rails-pulse-assets/rails-pulse.css.map +1 -1
  78. data/public/rails-pulse-assets/rails-pulse.js +53 -53
  79. data/public/rails-pulse-assets/rails-pulse.js.map +4 -4
  80. metadata +23 -5
  81. data/app/assets/images/rails_pulse/rails-pulse-logo.png +0 -0
  82. data/app/assets/images/rails_pulse/routes.png +0 -0
  83. data/app/javascript/rails_pulse/controllers/expandable_row_controller.js +0 -67
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_pulse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rails Pulse
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-09-09 00:00:00.000000000 Z
10
+ date: 2025-09-24 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -173,9 +173,7 @@ files:
173
173
  - Rakefile
174
174
  - app/assets/images/rails_pulse/dashboard.png
175
175
  - app/assets/images/rails_pulse/menu.svg
176
- - app/assets/images/rails_pulse/rails-pulse-logo.png
177
176
  - app/assets/images/rails_pulse/request.png
178
- - app/assets/images/rails_pulse/routes.png
179
177
  - app/assets/stylesheets/rails_pulse/application.css
180
178
  - app/assets/stylesheets/rails_pulse/components/alert.css
181
179
  - app/assets/stylesheets/rails_pulse/components/badge.css
@@ -184,6 +182,7 @@ files:
184
182
  - app/assets/stylesheets/rails_pulse/components/button.css
185
183
  - app/assets/stylesheets/rails_pulse/components/card.css
186
184
  - app/assets/stylesheets/rails_pulse/components/chart.css
185
+ - app/assets/stylesheets/rails_pulse/components/collapsible.css
187
186
  - app/assets/stylesheets/rails_pulse/components/csp_safe_positioning.css
188
187
  - app/assets/stylesheets/rails_pulse/components/descriptive_list.css
189
188
  - app/assets/stylesheets/rails_pulse/components/dialog.css
@@ -218,16 +217,18 @@ files:
218
217
  - app/helpers/rails_pulse/status_helper.rb
219
218
  - app/helpers/rails_pulse/table_helper.rb
220
219
  - app/javascript/rails_pulse/application.js
220
+ - app/javascript/rails_pulse/controllers/collapsible_controller.js
221
221
  - app/javascript/rails_pulse/controllers/color_scheme_controller.js
222
222
  - app/javascript/rails_pulse/controllers/context_menu_controller.js
223
223
  - app/javascript/rails_pulse/controllers/dialog_controller.js
224
- - app/javascript/rails_pulse/controllers/expandable_row_controller.js
224
+ - app/javascript/rails_pulse/controllers/expandable_rows_controller.js
225
225
  - app/javascript/rails_pulse/controllers/form_controller.js
226
226
  - app/javascript/rails_pulse/controllers/icon_controller.js
227
227
  - app/javascript/rails_pulse/controllers/index_controller.js
228
228
  - app/javascript/rails_pulse/controllers/menu_controller.js
229
229
  - app/javascript/rails_pulse/controllers/pagination_controller.js
230
230
  - app/javascript/rails_pulse/controllers/popover_controller.js
231
+ - app/javascript/rails_pulse/controllers/table_sort_controller.js
231
232
  - app/javascript/rails_pulse/controllers/timezone_controller.js
232
233
  - app/javascript/rails_pulse/theme.js
233
234
  - app/jobs/rails_pulse/application_job.rb
@@ -258,6 +259,14 @@ files:
258
259
  - app/models/rails_pulse/routes/charts/average_response_times.rb
259
260
  - app/models/rails_pulse/routes/tables/index.rb
260
261
  - app/models/rails_pulse/summary.rb
262
+ - app/services/rails_pulse/analysis/backtrace_analyzer.rb
263
+ - app/services/rails_pulse/analysis/base_analyzer.rb
264
+ - app/services/rails_pulse/analysis/explain_plan_analyzer.rb
265
+ - app/services/rails_pulse/analysis/index_recommendation_engine.rb
266
+ - app/services/rails_pulse/analysis/n_plus_one_detector.rb
267
+ - app/services/rails_pulse/analysis/query_characteristics_analyzer.rb
268
+ - app/services/rails_pulse/analysis/suggestion_generator.rb
269
+ - app/services/rails_pulse/query_analysis_service.rb
261
270
  - app/services/rails_pulse/sql_query_normalizer.rb
262
271
  - app/services/rails_pulse/summary_service.rb
263
272
  - app/views/layouts/rails_pulse/_menu_items.html.erb
@@ -286,6 +295,10 @@ files:
286
295
  - app/views/rails_pulse/operations/_operation_analysis_other.html.erb
287
296
  - app/views/rails_pulse/operations/_operation_analysis_view.html.erb
288
297
  - app/views/rails_pulse/operations/show.html.erb
298
+ - app/views/rails_pulse/queries/_analysis_error.html.erb
299
+ - app/views/rails_pulse/queries/_analysis_prompt.html.erb
300
+ - app/views/rails_pulse/queries/_analysis_results.html.erb
301
+ - app/views/rails_pulse/queries/_analysis_section.html.erb
289
302
  - app/views/rails_pulse/queries/_show_table.html.erb
290
303
  - app/views/rails_pulse/queries/_table.html.erb
291
304
  - app/views/rails_pulse/queries/index.html.erb
@@ -306,10 +319,15 @@ files:
306
319
  - config/initializers/rails_pulse.rb
307
320
  - config/routes.rb
308
321
  - db/migrate/20241222000001_create_rails_pulse_summaries.rb
322
+ - db/migrate/20250916031656_add_analysis_to_rails_pulse_queries.rb
309
323
  - db/rails_pulse_schema.rb
324
+ - lib/generators/rails_pulse/convert_to_migrations_generator.rb
310
325
  - lib/generators/rails_pulse/install_generator.rb
311
326
  - lib/generators/rails_pulse/templates/db/rails_pulse_schema.rb
327
+ - lib/generators/rails_pulse/templates/migrations/install_rails_pulse_tables.rb
328
+ - lib/generators/rails_pulse/templates/migrations/upgrade_rails_pulse_tables.rb
312
329
  - lib/generators/rails_pulse/templates/rails_pulse.rb
330
+ - lib/generators/rails_pulse/upgrade_generator.rb
313
331
  - lib/rails_pulse.rb
314
332
  - lib/rails_pulse/cleanup_service.rb
315
333
  - lib/rails_pulse/configuration.rb
@@ -1,67 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- export default class extends Controller {
4
- static targets = ["trigger", "details", "chevron"]
5
-
6
- connect() {
7
- // Ensure details row is initially hidden
8
- this.detailsTarget.classList.add("hidden")
9
- this.loaded = false
10
- }
11
-
12
- toggle(event) {
13
- event.preventDefault()
14
- event.stopPropagation()
15
-
16
- const isExpanded = !this.detailsTarget.classList.contains("hidden")
17
- console.log('Toggle clicked, currently expanded:', isExpanded)
18
-
19
- console.log('isExpanded', isExpanded)
20
- if (isExpanded) {
21
- console.log('Collapsing...')
22
- this.collapse()
23
- } else {
24
- console.log('Expanding...')
25
- this.expand()
26
- }
27
- }
28
-
29
- expand() {
30
- // Show details row
31
- this.detailsTarget.classList.remove("hidden")
32
-
33
- // Rotate chevron to point down
34
- this.chevronTarget.style.transform = "rotate(90deg)"
35
-
36
- // Add expanded state class to trigger row
37
- this.triggerTarget.classList.add("expanded")
38
-
39
- // Load content lazily on first expansion
40
- if (!this.loaded) {
41
- this.loadOperationDetails()
42
- this.loaded = true
43
- }
44
- }
45
-
46
- loadOperationDetails() {
47
- // Find the turbo frame and set its src to trigger loading
48
- const turboFrame = this.detailsTarget.querySelector('turbo-frame')
49
- if (turboFrame) {
50
- const operationUrl = turboFrame.dataset.operationUrl
51
- if (operationUrl) {
52
- turboFrame.src = operationUrl
53
- }
54
- }
55
- }
56
-
57
- collapse() {
58
- // Hide details row
59
- this.detailsTarget.classList.add("hidden")
60
-
61
- // Rotate chevron back to point right
62
- this.chevronTarget.style.transform = "rotate(0deg)"
63
-
64
- // Remove expanded state class from trigger row
65
- this.triggerTarget.classList.remove("expanded")
66
- }
67
- }