rails_nexus 2.0.0 → 2.0.1
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/app/controllers/rails_nexus/backup_controller.rb +23 -56
- data/app/services/rails_nexus/backup_service.rb +119 -218
- data/app/views/layouts/rails_nexus/application.html.erb +8 -0
- data/app/views/rails_nexus/backup/files.html.erb +30 -16
- data/app/views/rails_nexus/backup/index.html.erb +82 -158
- data/config/routes.rb +1 -2
- data/lib/generators/rails_nexus/install_generator.rb +1 -13
- data/lib/generators/rails_nexus/templates/migration.rb +119 -11
- data/lib/rails_nexus/version.rb +1 -1
- data/lib/tasks/rails_nexus.rake +8 -0
- metadata +1 -14
- data/app/models/rails_nexus/database_stat.rb +0 -128
- data/app/models/rails_nexus/event.rb +0 -101
- data/app/models/rails_nexus/metric.rb +0 -107
- data/app/models/rails_nexus/nginx_metric.rb +0 -112
- data/app/models/rails_nexus/server_metric.rb +0 -168
- data/app/views/rails_nexus/backup/settings.html.erb +0 -158
- data/db/migrate/20240330122311_create_rails_nexus_logged_exceptions.rb +0 -22
- data/lib/generators/rails_nexus/templates/migration_advanced_features.rb +0 -30
- data/lib/generators/rails_nexus/templates/migration_cron_jobs.rb +0 -22
- data/lib/generators/rails_nexus/templates/migration_new_schema.rb +0 -120
- data/lib/generators/rails_nexus/templates/migration_platform_detection.rb +0 -11
- data/lib/generators/rails_nexus/templates/migration_webhook_deliveries.rb +0 -21
- data/lib/generators/rails_nexus/templates/migration_workflow.rb +0 -29
|
@@ -15,197 +15,121 @@
|
|
|
15
15
|
</svg>
|
|
16
16
|
<h1 class="text-2xl font-bold" style="color: var(--rn-text)">Backup Management</h1>
|
|
17
17
|
</div>
|
|
18
|
-
<div class="flex gap-2">
|
|
19
|
-
<a href="<%= backup_settings_path %>" class="rn-btn rn-btn-ghost">Settings</a>
|
|
20
|
-
<a href="<%= backup_files_path %>" class="rn-btn rn-btn-ghost">View All Files</a>
|
|
21
|
-
</div>
|
|
22
18
|
</div>
|
|
23
19
|
|
|
24
20
|
<%# ─── Health Status ───────────────────────────────────────── %>
|
|
25
|
-
|
|
26
|
-
<div class="
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
<
|
|
30
|
-
<span class="text-sm font-semibold" style="color: var(--rn-text)">Backup not configured</span>
|
|
31
|
-
<p class="text-xs mt-1" style="color: var(--rn-text-muted)">Set <code>config.backup_enabled = true</code> and configure paths in your initializer.</p>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
<% else %>
|
|
36
|
-
<div class="rn-card" style="border-left: 3px solid <%= @health[:status] == 'healthy' ? 'var(--rn-success)' : @health[:status] == 'warning' ? 'var(--rn-warning)' : 'var(--rn-danger)' %>">
|
|
37
|
-
<div class="p-4 flex items-center gap-3">
|
|
38
|
-
<span class="w-3 h-3 rounded-full" style="background: <%= @health[:status] == 'healthy' ? 'var(--rn-success)' : @health[:status] == 'warning' ? 'var(--rn-warning)' : 'var(--rn-danger)' %>"></span>
|
|
39
|
-
<div>
|
|
40
|
-
<span class="text-sm font-semibold" style="color: var(--rn-text)"><%= @health[:message] %></span>
|
|
41
|
-
</div>
|
|
21
|
+
<div class="rn-card" style="border-left: 3px solid <%= @health[:status] == 'healthy' ? 'var(--rn-success)' : @health[:status] == 'warning' ? 'var(--rn-warning)' : 'var(--rn-danger)' %>">
|
|
22
|
+
<div class="p-4 flex items-center gap-3">
|
|
23
|
+
<span class="w-3 h-3 rounded-full" style="background: <%= @health[:status] == 'healthy' ? 'var(--rn-success)' : @health[:status] == 'warning' ? 'var(--rn-warning)' : 'var(--rn-danger)' %>"></span>
|
|
24
|
+
<div>
|
|
25
|
+
<span class="text-sm font-semibold" style="color: var(--rn-text)"><%= @health[:message] %></span>
|
|
42
26
|
</div>
|
|
43
27
|
</div>
|
|
44
|
-
|
|
28
|
+
</div>
|
|
45
29
|
|
|
46
30
|
<%# ─── Summary Stats ───────────────────────────────────────── %>
|
|
47
|
-
|
|
48
|
-
<div class="rn-
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
<span class="rn-stat-change"><%= @summary[:last_backup_age_hours] ? "#{@summary[:last_backup_age_hours]}h ago" : "" %></span>
|
|
58
|
-
</div>
|
|
59
|
-
<div class="rn-stat">
|
|
60
|
-
<span class="rn-stat-label">Backup Models</span>
|
|
61
|
-
<span class="rn-stat-value"><%= @summary[:models_count] %></span>
|
|
62
|
-
<span class="rn-stat-change">Configured</span>
|
|
63
|
-
</div>
|
|
64
|
-
<div class="rn-stat">
|
|
65
|
-
<span class="rn-stat-label">Health</span>
|
|
66
|
-
<span class="rn-stat-value" style="color: <%= @summary[:healthy] ? 'var(--rn-success)' : 'var(--rn-danger)' %>">
|
|
67
|
-
<%= @summary[:healthy] ? "✓ Healthy" : "⚠ Issues" %>
|
|
68
|
-
</span>
|
|
69
|
-
<span class="rn-stat-change"><%= @summary[:alerts]&.size || 0 %> alerts</span>
|
|
70
|
-
</div>
|
|
31
|
+
<div class="rn-stats">
|
|
32
|
+
<div class="rn-stat">
|
|
33
|
+
<span class="rn-stat-label">Total Backups</span>
|
|
34
|
+
<span class="rn-stat-value"><%= @summary[:total] %></span>
|
|
35
|
+
<span class="rn-stat-change"><%= @summary[:total_size_human] %> total</span>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="rn-stat">
|
|
38
|
+
<span class="rn-stat-label">Successful</span>
|
|
39
|
+
<span class="rn-stat-value" style="color: var(--rn-success)"><%= @summary[:successful] %></span>
|
|
40
|
+
<span class="rn-stat-change">All time</span>
|
|
71
41
|
</div>
|
|
72
|
-
|
|
42
|
+
<div class="rn-stat">
|
|
43
|
+
<span class="rn-stat-label">Failed</span>
|
|
44
|
+
<span class="rn-stat-value" style="color: var(--rn-danger)"><%= @summary[:failed] %></span>
|
|
45
|
+
<span class="rn-stat-change">All time</span>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="rn-stat">
|
|
48
|
+
<span class="rn-stat-label">Last 7 Days</span>
|
|
49
|
+
<span class="rn-stat-value"><%= @summary[:recent_count] %></span>
|
|
50
|
+
<span class="rn-stat-change"><%= @summary[:recent_success] %> ok, <%= @summary[:recent_failed] %> failed</span>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
73
53
|
|
|
74
|
-
<%# ───
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
54
|
+
<%# ─── Trigger Backup ──────────────────────────────────────── %>
|
|
55
|
+
<div class="rn-card">
|
|
56
|
+
<div class="p-4" style="border-bottom: 1px solid var(--rn-border-light)">
|
|
57
|
+
<h2 class="text-sm font-semibold" style="color: var(--rn-text)">Run Backup</h2>
|
|
58
|
+
<p class="text-xs mt-1" style="color: var(--rn-text-muted)">Trigger a database dump. The record will be saved to the table.</p>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="p-4 flex gap-3">
|
|
61
|
+
<% %w[primary full sync].each do |model| %>
|
|
62
|
+
<%= button_to model.titleize, backup_trigger_path(model: model),
|
|
63
|
+
method: :post,
|
|
64
|
+
class: "rn-btn rn-btn-primary rn-btn-sm",
|
|
65
|
+
data: { turbo_confirm: "Run #{model} backup now?" } %>
|
|
66
|
+
<% end %>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
84
69
|
|
|
85
|
-
<%# ───
|
|
86
|
-
|
|
87
|
-
<div class="rn-
|
|
88
|
-
<div class="
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<h2 class="text-sm font-semibold" style="color: var(--rn-text)">Backup Models</h2>
|
|
94
|
-
</div>
|
|
70
|
+
<%# ─── Recent Backups Table ────────────────────────────────── %>
|
|
71
|
+
<div class="rn-card">
|
|
72
|
+
<div class="p-4" style="border-bottom: 1px solid var(--rn-border-light)">
|
|
73
|
+
<div class="flex items-center gap-2">
|
|
74
|
+
<svg class="w-4 h-4" style="color: var(--rn-primary)" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
75
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
76
|
+
</svg>
|
|
77
|
+
<h2 class="text-sm font-semibold" style="color: var(--rn-text)">Backup History</h2>
|
|
95
78
|
</div>
|
|
79
|
+
<p class="text-xs mt-1" style="color: var(--rn-text-muted)">All backup runs recorded in the database</p>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<% if @records.any? %>
|
|
96
83
|
<div class="rn-table-wrap">
|
|
97
84
|
<table class="rn-table">
|
|
98
85
|
<thead>
|
|
99
86
|
<tr>
|
|
100
87
|
<th>Model</th>
|
|
101
|
-
<th>
|
|
102
|
-
<th>
|
|
103
|
-
<th>
|
|
104
|
-
<th>
|
|
105
|
-
<th
|
|
88
|
+
<th>Status</th>
|
|
89
|
+
<th>Size</th>
|
|
90
|
+
<th>Duration</th>
|
|
91
|
+
<th>Triggered By</th>
|
|
92
|
+
<th>Time</th>
|
|
93
|
+
<th></th>
|
|
106
94
|
</tr>
|
|
107
95
|
</thead>
|
|
108
96
|
<tbody>
|
|
109
|
-
<% @
|
|
97
|
+
<% @records.each do |record| %>
|
|
110
98
|
<tr>
|
|
111
99
|
<td>
|
|
112
|
-
<span class="font-medium" style="color: var(--rn-text)"><%=
|
|
113
|
-
<br><span class="text-xs" style="color: var(--rn-text-muted)"><%= model[:description] %></span>
|
|
100
|
+
<span class="font-medium" style="color: var(--rn-text)"><%= record.model_name %></span>
|
|
114
101
|
</td>
|
|
115
|
-
<td><span class="rn-badge <%= model[:has_mysql] ? 'rn-badge-success' : 'rn-badge-muted' %>">MySQL</span></td>
|
|
116
102
|
<td>
|
|
117
|
-
<span class="rn-badge
|
|
118
|
-
|
|
103
|
+
<span class="rn-badge rn-badge-<%= record.status == 'success' ? 'success' : record.status == 'failed' ? 'danger' : 'warning' %>">
|
|
104
|
+
<%= record.status.capitalize %>
|
|
105
|
+
</span>
|
|
119
106
|
</td>
|
|
120
|
-
<td
|
|
121
|
-
|
|
122
|
-
<td style="text-align: right">
|
|
123
|
-
<%= button_to "Trigger", backup_trigger_path(model: model[:name]),
|
|
124
|
-
method: :post,
|
|
125
|
-
class: "rn-btn rn-btn-primary rn-btn-xs",
|
|
126
|
-
data: { turbo_confirm: "Run #{model[:name]} backup now?" } %>
|
|
107
|
+
<td>
|
|
108
|
+
<span class="text-xs" style="color: var(--rn-text-secondary)"><%= record.file_size ? number_to_human_size(record.file_size) : "—" %></span>
|
|
127
109
|
</td>
|
|
128
|
-
</tr>
|
|
129
|
-
<% end %>
|
|
130
|
-
</tbody>
|
|
131
|
-
</table>
|
|
132
|
-
</div>
|
|
133
|
-
</div>
|
|
134
|
-
<% end %>
|
|
135
|
-
|
|
136
|
-
<%# ─── Recent Backups ──────────────────────────────────────── %>
|
|
137
|
-
<% if @backup_service.backup_files.any? %>
|
|
138
|
-
<div class="rn-card">
|
|
139
|
-
<div class="p-4" style="border-bottom: 1px solid var(--rn-border-light)">
|
|
140
|
-
<div class="flex items-center gap-2">
|
|
141
|
-
<svg class="w-4 h-4" style="color: var(--rn-primary)" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
142
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
143
|
-
</svg>
|
|
144
|
-
<h2 class="text-sm font-semibold" style="color: var(--rn-text)">Recent Backups</h2>
|
|
145
|
-
</div>
|
|
146
|
-
</div>
|
|
147
|
-
<div class="rn-table-wrap">
|
|
148
|
-
<table class="rn-table">
|
|
149
|
-
<thead>
|
|
150
|
-
<tr>
|
|
151
|
-
<th>File</th>
|
|
152
|
-
<th>Size</th>
|
|
153
|
-
<th>Created</th>
|
|
154
|
-
<th>Status</th>
|
|
155
|
-
</tr>
|
|
156
|
-
</thead>
|
|
157
|
-
<tbody>
|
|
158
|
-
<% @backup_service.backup_files.first(10).each do |file| %>
|
|
159
|
-
<tr>
|
|
160
110
|
<td>
|
|
161
|
-
<span class="
|
|
111
|
+
<span class="text-xs" style="color: var(--rn-text-secondary)"><%= record.duration ? "#{record.duration.round(1)}s" : "—" %></span>
|
|
162
112
|
</td>
|
|
163
|
-
<td><span class="text-xs" style="color: var(--rn-text-secondary)"><%= file[:size_human] %></span></td>
|
|
164
|
-
<td><span class="text-xs" style="color: var(--rn-text-muted)"><%= time_ago_in_words(file[:created_at]) %> ago</span></td>
|
|
165
113
|
<td>
|
|
166
|
-
<span class="
|
|
167
|
-
|
|
168
|
-
|
|
114
|
+
<span class="text-xs" style="color: var(--rn-text-muted)"><%= record.triggered_by || "—" %></span>
|
|
115
|
+
</td>
|
|
116
|
+
<td>
|
|
117
|
+
<span class="text-xs" style="color: var(--rn-text-muted)"><%= record.started_at ? time_ago_in_words(record.started_at) + " ago" : "—" %></span>
|
|
118
|
+
</td>
|
|
119
|
+
<td>
|
|
120
|
+
<% if record.error_message.present? %>
|
|
121
|
+
<span class="text-xs" style="color: var(--rn-danger)" title="<%= record.error_message %>">⚠</span>
|
|
122
|
+
<% end %>
|
|
169
123
|
</td>
|
|
170
124
|
</tr>
|
|
171
125
|
<% end %>
|
|
172
126
|
</tbody>
|
|
173
127
|
</table>
|
|
174
128
|
</div>
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
<%# ─── Cron Schedule ───────────────────────────────────────── %>
|
|
179
|
-
<% if @schedule && @schedule[:entries].any? %>
|
|
180
|
-
<div class="rn-card">
|
|
181
|
-
<div class="p-4" style="border-bottom: 1px solid var(--rn-border-light)">
|
|
182
|
-
<div class="flex items-center gap-2">
|
|
183
|
-
<svg class="w-4 h-4" style="color: var(--rn-primary)" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
184
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />
|
|
185
|
-
</svg>
|
|
186
|
-
<h2 class="text-sm font-semibold" style="color: var(--rn-text)">Schedule</h2>
|
|
187
|
-
</div>
|
|
129
|
+
<% else %>
|
|
130
|
+
<div class="p-8 text-center">
|
|
131
|
+
<p class="text-sm" style="color: var(--rn-text-muted)">No backups recorded yet. Run a backup above to get started.</p>
|
|
188
132
|
</div>
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
<thead>
|
|
192
|
-
<tr>
|
|
193
|
-
<th>Frequency</th>
|
|
194
|
-
<th>Time</th>
|
|
195
|
-
<th>Command</th>
|
|
196
|
-
</tr>
|
|
197
|
-
</thead>
|
|
198
|
-
<tbody>
|
|
199
|
-
<% @schedule[:entries].each do |entry| %>
|
|
200
|
-
<tr>
|
|
201
|
-
<td><span class="text-sm" style="color: var(--rn-text)"><%= entry[:frequency] %></span></td>
|
|
202
|
-
<td><span class="text-sm" style="color: var(--rn-text-secondary)"><%= entry[:time] || "All day" %></span></td>
|
|
203
|
-
<td><span class="rn-mono text-xs" style="color: var(--rn-text-muted)"><%= entry[:command] %></span></td>
|
|
204
|
-
</tr>
|
|
205
|
-
<% end %>
|
|
206
|
-
</tbody>
|
|
207
|
-
</table>
|
|
208
|
-
</div>
|
|
209
|
-
</div>
|
|
210
|
-
<% end %>
|
|
133
|
+
<% end %>
|
|
134
|
+
</div>
|
|
211
135
|
</div>
|
data/config/routes.rb
CHANGED
|
@@ -45,9 +45,8 @@ RailsNexus::Engine.routes.draw do
|
|
|
45
45
|
get "backup", to: "backup#index", as: :backup
|
|
46
46
|
get "backup/files", to: "backup#files", as: :backup_files
|
|
47
47
|
post "backup/trigger/:model", to: "backup#trigger", as: :backup_trigger
|
|
48
|
+
delete "backup/:id", to: "backup#destroy", as: :backup_destroy
|
|
48
49
|
get "backup/health", to: "backup#health", as: :backup_health
|
|
49
|
-
get "backup/settings", to: "backup#settings", as: :backup_settings
|
|
50
|
-
patch "backup/settings", to: "backup#update_settings", as: :backup_update_settings
|
|
51
50
|
|
|
52
51
|
# Settings and webhook management
|
|
53
52
|
get "settings", to: "settings#index", as: :settings
|
|
@@ -8,16 +8,6 @@ module RailsNexus
|
|
|
8
8
|
class InstallGenerator < Rails::Generators::Base
|
|
9
9
|
include Rails::Generators::Migration
|
|
10
10
|
|
|
11
|
-
MIGRATIONS = {
|
|
12
|
-
"migration.rb" => "create_rails_nexus_exceptions.rb",
|
|
13
|
-
"migration_advanced_features.rb" => "add_advanced_features_to_rails_nexus_exceptions.rb",
|
|
14
|
-
"migration_platform_detection.rb" => "add_platform_to_rails_nexus_exceptions.rb",
|
|
15
|
-
"migration_workflow.rb" => "add_workflow_to_rails_nexus.rb",
|
|
16
|
-
"migration_cron_jobs.rb" => "create_rails_nexus_cron_jobs.rb",
|
|
17
|
-
"migration_webhook_deliveries.rb" => "create_rails_nexus_webhook_deliveries.rb",
|
|
18
|
-
"migration_new_schema.rb" => "create_rails_nexus_metrics_tables.rb"
|
|
19
|
-
}.freeze
|
|
20
|
-
|
|
21
11
|
source_root File.expand_path("templates", __dir__)
|
|
22
12
|
desc "Install RailsNexus into your Rails application"
|
|
23
13
|
|
|
@@ -26,9 +16,7 @@ module RailsNexus
|
|
|
26
16
|
end
|
|
27
17
|
|
|
28
18
|
def create_migration_files
|
|
29
|
-
|
|
30
|
-
migration_template source, "db/migrate/#{destination}"
|
|
31
|
-
end
|
|
19
|
+
migration_template "migration.rb", "db/migrate/create_rails_nexus_tables.rb"
|
|
32
20
|
end
|
|
33
21
|
|
|
34
22
|
def create_initializer
|
|
@@ -1,18 +1,50 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class
|
|
3
|
+
class CreateRailsNexusTables < ActiveRecord::Migration[<%= "[#{ActiveRecord::Migration.current_version}]" %>]
|
|
4
4
|
def change
|
|
5
|
+
# ─── rails_nexus_exceptions ──────────────────────────────────────
|
|
5
6
|
create_table :rails_nexus_exceptions do |t|
|
|
6
|
-
|
|
7
|
-
t.string
|
|
8
|
-
t.string
|
|
9
|
-
t.
|
|
10
|
-
t.text
|
|
11
|
-
t.text
|
|
12
|
-
t.text
|
|
13
|
-
t.
|
|
14
|
-
t.string
|
|
15
|
-
t.string
|
|
7
|
+
# Core exception data
|
|
8
|
+
t.string :exception_class
|
|
9
|
+
t.string :controller_name
|
|
10
|
+
t.string :action_name
|
|
11
|
+
t.text :message
|
|
12
|
+
t.text :backtrace
|
|
13
|
+
t.text :environment
|
|
14
|
+
t.text :request
|
|
15
|
+
t.string :user_info
|
|
16
|
+
t.string :user_agent
|
|
17
|
+
t.string :remote_ip
|
|
18
|
+
|
|
19
|
+
# Fingerprinting & deduplication
|
|
20
|
+
t.string :fingerprint
|
|
21
|
+
t.integer :occurrence_count, default: 1
|
|
22
|
+
|
|
23
|
+
# Platform detection
|
|
24
|
+
t.string :platform, default: "web"
|
|
25
|
+
t.string :platform_version
|
|
26
|
+
t.string :device_type
|
|
27
|
+
t.string :app_version
|
|
28
|
+
|
|
29
|
+
# Advanced features
|
|
30
|
+
t.text :cause_chain
|
|
31
|
+
t.text :breadcrumbs
|
|
32
|
+
t.text :system_health
|
|
33
|
+
t.text :local_variables
|
|
34
|
+
t.text :instance_variables
|
|
35
|
+
|
|
36
|
+
# User impact tracking
|
|
37
|
+
t.string :user_id
|
|
38
|
+
t.string :user_type
|
|
39
|
+
|
|
40
|
+
# Workflow management
|
|
41
|
+
t.string :priority
|
|
42
|
+
t.string :assigned_to
|
|
43
|
+
t.datetime :assigned_at
|
|
44
|
+
t.datetime :snoozed_until
|
|
45
|
+
t.boolean :muted, default: false
|
|
46
|
+
t.datetime :muted_at
|
|
47
|
+
t.integer :comments_count, default: 0
|
|
16
48
|
|
|
17
49
|
t.timestamps
|
|
18
50
|
end
|
|
@@ -20,5 +52,81 @@ class CreateRailsNexusLoggedExceptions < ActiveRecord::Migration<%= "[#{ActiveRe
|
|
|
20
52
|
add_index :rails_nexus_exceptions, :created_at
|
|
21
53
|
add_index :rails_nexus_exceptions, :exception_class
|
|
22
54
|
add_index :rails_nexus_exceptions, [:controller_name, :action_name]
|
|
55
|
+
add_index :rails_nexus_exceptions, :fingerprint
|
|
56
|
+
add_index :rails_nexus_exceptions, :occurrence_count
|
|
57
|
+
add_index :rails_nexus_exceptions, :platform
|
|
58
|
+
add_index :rails_nexus_exceptions, [:platform, :exception_class]
|
|
59
|
+
add_index :rails_nexus_exceptions, :priority
|
|
60
|
+
add_index :rails_nexus_exceptions, :assigned_to
|
|
61
|
+
add_index :rails_nexus_exceptions, :muted
|
|
62
|
+
add_index :rails_nexus_exceptions, :user_id
|
|
63
|
+
|
|
64
|
+
# ─── rails_nexus_comments ────────────────────────────────────────
|
|
65
|
+
create_table :rails_nexus_comments do |t|
|
|
66
|
+
t.references :logged_exception, null: false, foreign_key: { to_table: :rails_nexus_exceptions }
|
|
67
|
+
t.string :author, null: false
|
|
68
|
+
t.text :body, null: false
|
|
69
|
+
t.string :comment_type, default: "comment"
|
|
70
|
+
|
|
71
|
+
t.timestamps
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
add_index :rails_nexus_comments, [:logged_exception_id, :created_at]
|
|
75
|
+
|
|
76
|
+
# ─── rails_nexus_cron_jobs ───────────────────────────────────────
|
|
77
|
+
create_table :rails_nexus_cron_jobs do |t|
|
|
78
|
+
t.string :name, null: false
|
|
79
|
+
t.string :status, null: false, default: "pending"
|
|
80
|
+
t.text :output
|
|
81
|
+
t.text :error_message
|
|
82
|
+
t.float :duration
|
|
83
|
+
t.string :hostname
|
|
84
|
+
t.json :metadata
|
|
85
|
+
t.datetime :started_at
|
|
86
|
+
t.datetime :finished_at
|
|
87
|
+
|
|
88
|
+
t.timestamps
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
add_index :rails_nexus_cron_jobs, :name
|
|
92
|
+
add_index :rails_nexus_cron_jobs, :status
|
|
93
|
+
add_index :rails_nexus_cron_jobs, :created_at
|
|
94
|
+
add_index :rails_nexus_cron_jobs, :started_at
|
|
95
|
+
|
|
96
|
+
# ─── rails_nexus_webhook_deliveries ──────────────────────────────
|
|
97
|
+
create_table :rails_nexus_webhook_deliveries do |t|
|
|
98
|
+
t.string :url, null: false
|
|
99
|
+
t.string :status, null: false, default: "pending"
|
|
100
|
+
t.integer :response_code
|
|
101
|
+
t.text :request_body
|
|
102
|
+
t.text :response_body
|
|
103
|
+
t.float :duration
|
|
104
|
+
t.text :error_message
|
|
105
|
+
t.string :event_type
|
|
106
|
+
t.json :metadata
|
|
107
|
+
|
|
108
|
+
t.timestamps
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
add_index :rails_nexus_webhook_deliveries, :status
|
|
112
|
+
add_index :rails_nexus_webhook_deliveries, :created_at
|
|
113
|
+
add_index :rails_nexus_webhook_deliveries, :url
|
|
114
|
+
|
|
115
|
+
# ─── rails_nexus_backups ─────────────────────────────────────────
|
|
116
|
+
create_table :rails_nexus_backups do |t|
|
|
117
|
+
t.string :model_name, null: false
|
|
118
|
+
t.string :status, null: false
|
|
119
|
+
t.text :file_path
|
|
120
|
+
t.bigint :file_size
|
|
121
|
+
t.float :duration
|
|
122
|
+
t.text :error_message
|
|
123
|
+
t.string :triggered_by
|
|
124
|
+
t.datetime :started_at, null: false
|
|
125
|
+
t.datetime :completed_at
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
add_index :rails_nexus_backups, [:model_name, :started_at]
|
|
129
|
+
add_index :rails_nexus_backups, :status
|
|
130
|
+
add_index :rails_nexus_backups, :started_at
|
|
23
131
|
end
|
|
24
132
|
end
|
data/lib/rails_nexus/version.rb
CHANGED
data/lib/tasks/rails_nexus.rake
CHANGED
|
@@ -227,4 +227,12 @@ namespace :rails_nexus do
|
|
|
227
227
|
count = RailsNexus::WebhookDelivery.where("created_at < ?", days.days.ago).delete_all
|
|
228
228
|
puts "✓ Deleted #{count} webhook delivery records older than #{days} days"
|
|
229
229
|
end
|
|
230
|
+
|
|
231
|
+
desc "Clean up old backup records and files (default: 30 days)"
|
|
232
|
+
task :backup_cleanup, [:days] => :environment do |_t, args|
|
|
233
|
+
days = (args[:days] || 30).to_i
|
|
234
|
+
service = RailsNexus::BackupService.new
|
|
235
|
+
result = service.cleanup!(retention_days: days)
|
|
236
|
+
puts "✓ Deleted #{result[:deleted]} backup records older than #{days} days"
|
|
237
|
+
end
|
|
230
238
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_nexus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tamiru Hailu
|
|
@@ -142,20 +142,14 @@ files:
|
|
|
142
142
|
- app/models/rails_nexus/base_record.rb
|
|
143
143
|
- app/models/rails_nexus/comment.rb
|
|
144
144
|
- app/models/rails_nexus/cron_job.rb
|
|
145
|
-
- app/models/rails_nexus/database_stat.rb
|
|
146
|
-
- app/models/rails_nexus/event.rb
|
|
147
145
|
- app/models/rails_nexus/logged_exception.rb
|
|
148
146
|
- app/models/rails_nexus/logged_exception_n1.rb
|
|
149
|
-
- app/models/rails_nexus/metric.rb
|
|
150
|
-
- app/models/rails_nexus/nginx_metric.rb
|
|
151
|
-
- app/models/rails_nexus/server_metric.rb
|
|
152
147
|
- app/models/rails_nexus/webhook_delivery.rb
|
|
153
148
|
- app/services/rails_nexus/backup_service.rb
|
|
154
149
|
- app/views/layouts/rails_nexus/application.html.erb
|
|
155
150
|
- app/views/rails_nexus/analytics/index.html.erb
|
|
156
151
|
- app/views/rails_nexus/backup/files.html.erb
|
|
157
152
|
- app/views/rails_nexus/backup/index.html.erb
|
|
158
|
-
- app/views/rails_nexus/backup/settings.html.erb
|
|
159
153
|
- app/views/rails_nexus/cron_jobs/index.html.erb
|
|
160
154
|
- app/views/rails_nexus/database_health/index.html.erb
|
|
161
155
|
- app/views/rails_nexus/logged_exceptions/_comments_list.html.erb
|
|
@@ -181,7 +175,6 @@ files:
|
|
|
181
175
|
- config/initializers/rails_nexus.rb
|
|
182
176
|
- config/locales/en.yml
|
|
183
177
|
- config/routes.rb
|
|
184
|
-
- db/migrate/20240330122311_create_rails_nexus_logged_exceptions.rb
|
|
185
178
|
- lib/generators/rails_nexus/backup_generator.rb
|
|
186
179
|
- lib/generators/rails_nexus/customize_generator.rb
|
|
187
180
|
- lib/generators/rails_nexus/install_generator.rb
|
|
@@ -198,12 +191,6 @@ files:
|
|
|
198
191
|
- lib/generators/rails_nexus/templates/javascript/controllers/rails_nexus_sidebar_controller.js
|
|
199
192
|
- lib/generators/rails_nexus/templates/javascript/controllers/rails_nexus_theme_controller.js
|
|
200
193
|
- lib/generators/rails_nexus/templates/migration.rb
|
|
201
|
-
- lib/generators/rails_nexus/templates/migration_advanced_features.rb
|
|
202
|
-
- lib/generators/rails_nexus/templates/migration_cron_jobs.rb
|
|
203
|
-
- lib/generators/rails_nexus/templates/migration_new_schema.rb
|
|
204
|
-
- lib/generators/rails_nexus/templates/migration_platform_detection.rb
|
|
205
|
-
- lib/generators/rails_nexus/templates/migration_webhook_deliveries.rb
|
|
206
|
-
- lib/generators/rails_nexus/templates/migration_workflow.rb
|
|
207
194
|
- lib/generators/rails_nexus/templates/rails_nexus.rb
|
|
208
195
|
- lib/generators/rails_nexus/templates/views/layouts/rails_nexus/application.html.erb
|
|
209
196
|
- lib/generators/rails_nexus/templates/views/rails_nexus/logged_exceptions/_exceptions.html.erb
|