rails_nexus 2.0.3 → 2.0.6
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/assets/javascripts/rails_nexus/controllers.js +21 -1
- data/app/assets/stylesheets/rails_nexus/application.css +295 -29
- data/app/controllers/rails_nexus/backup_controller.rb +6 -2
- data/app/javascript/controllers/rails_nexus_controller.js +2 -0
- data/app/javascript/controllers/rails_nexus_sidebar_controller.js +13 -0
- data/app/models/rails_nexus/backup_config.rb +77 -14
- data/app/services/rails_nexus/backup_service.rb +416 -97
- data/app/views/layouts/rails_nexus/_sidebar_navigation.html.erb +83 -0
- data/app/views/layouts/rails_nexus/application.html.erb +70 -22
- data/app/views/rails_nexus/backup/_form.html.erb +183 -37
- data/app/views/rails_nexus/logged_exceptions/_exceptions.html.erb +16 -15
- data/app/views/rails_nexus/logged_exceptions/index.html.erb +3 -3
- data/db/seeds/backup_configs.rb +139 -0
- data/lib/generators/rails_nexus/templates/migration.rb +23 -3
- data/lib/rails_nexus/version.rb +1 -1
- data/lib/tasks/rails_nexus.rake +10 -0
- metadata +3 -1
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
</div>
|
|
15
15
|
<% else %>
|
|
16
16
|
<%# ─── Table Header Bar ───────────────────────────────────── %>
|
|
17
|
-
<div class="
|
|
18
|
-
<div class="
|
|
17
|
+
<div class="rn-exceptions-toolbar" style="background: var(--rn-bg-secondary); border-bottom: 1px solid var(--rn-border-light)">
|
|
18
|
+
<div class="rn-exceptions-toolbar-summary">
|
|
19
19
|
<span class="text-xs font-medium" style="color: var(--rn-text-secondary)">
|
|
20
|
-
<span class="font-semibold" style="color: var(--rn-text)"><%= number_with_delimiter(@pagy.count) %></span>
|
|
20
|
+
<span class="font-semibold" style="color: var(--rn-text)"><%= number_with_delimiter(@pagy.count) %></span>
|
|
21
|
+
<%= "exception".pluralize(@pagy.count) %>
|
|
21
22
|
<% if filtered? %>
|
|
22
23
|
<span style="color: var(--rn-text-muted)">(filtered)</span>
|
|
23
24
|
<% end %>
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
</div>
|
|
36
37
|
</div>
|
|
37
38
|
|
|
38
|
-
<div class="
|
|
39
|
+
<div class="rn-exceptions-toolbar-actions">
|
|
39
40
|
<%# Keyboard hint %>
|
|
40
41
|
<span class="text-xs flex items-center gap-1" style="color: var(--rn-text-muted)">
|
|
41
42
|
<span class="rn-kbd">?</span> shortcuts
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
<%# ─── Exception Table ────────────────────────────────────── %>
|
|
55
56
|
<div class="rn-table-wrap">
|
|
56
57
|
<table class="rn-table rn-exceptions-table">
|
|
58
|
+
<caption class="sr-only">Logged application exceptions</caption>
|
|
57
59
|
<thead>
|
|
58
60
|
<tr>
|
|
59
61
|
<th class="rn-col-severity"><span class="sr-only">Severity</span></th>
|
|
@@ -79,24 +81,23 @@
|
|
|
79
81
|
<% @exceptions.each_with_index do |exception, index| %>
|
|
80
82
|
<tr id="<%= dom_id(exception) %>"
|
|
81
83
|
class="group"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
tabindex="0"
|
|
85
|
+
aria-label="View <%= exception.exception_class %>: <%= exception.message.presence || 'No message' %>"
|
|
86
|
+
data-action="click->rails_nexus#selectRow keydown.enter->rails_nexus#selectRow keydown.space->rails_nexus#selectRow"
|
|
84
87
|
data-url="<%= logged_exception_path(exception) %>"
|
|
85
88
|
data-index="<%= index %>"
|
|
86
89
|
data-rails_nexus-index-param="<%= index %>">
|
|
87
90
|
|
|
88
91
|
<%# Severity indicator dot %>
|
|
89
|
-
<td>
|
|
90
|
-
<span class="rn-
|
|
91
|
-
style="background: var(--rn-<%= severity_for(exception) %>-light); color: var(--rn-<%= severity_for(exception) %>); width: 0.5rem; height: 0.5rem; min-width: 0; padding: 0; border-radius: 50%">
|
|
92
|
-
</span>
|
|
92
|
+
<td class="rn-col-severity">
|
|
93
|
+
<span class="rn-severity-dot rn-severity-<%= severity_for(exception) %>" aria-hidden="true"></span>
|
|
93
94
|
</td>
|
|
94
95
|
|
|
95
96
|
<%# Exception class with severity badge %>
|
|
96
97
|
<td class="rn-col-exception">
|
|
97
|
-
<span class="rn-
|
|
98
|
+
<span class="rn-exception-name" title="<%= exception.exception_class %>"><%= exception.exception_class %></span>
|
|
98
99
|
<% if exception.respond_to?(:fingerprint) && exception.fingerprint.present? %>
|
|
99
|
-
<span class="rn-row-meta rn-mono" title="Fingerprint"
|
|
100
|
+
<span class="rn-row-meta rn-mono" title="Fingerprint <%= exception.fingerprint %>">#<%= exception.fingerprint.first(10) %></span>
|
|
100
101
|
<% end %>
|
|
101
102
|
</td>
|
|
102
103
|
|
|
@@ -128,7 +129,7 @@
|
|
|
128
129
|
|
|
129
130
|
<%# Occurrence count %>
|
|
130
131
|
<td class="rn-col-count">
|
|
131
|
-
<span class="rn-
|
|
132
|
+
<span class="rn-occurrence-count" title="<%= pluralize(exception_occurrence_count(exception), 'occurrence') %>"><%= number_with_delimiter(exception_occurrence_count(exception)) %></span>
|
|
132
133
|
</td>
|
|
133
134
|
|
|
134
135
|
<%# Workflow indicators %>
|
|
@@ -148,11 +149,11 @@
|
|
|
148
149
|
</td>
|
|
149
150
|
|
|
150
151
|
<%# Time (relative) %>
|
|
151
|
-
<td class="rn-date"><%= pretty_exception_date(exception) %></td>
|
|
152
|
+
<td class="rn-col-time rn-date"><%= pretty_exception_date(exception) %></td>
|
|
152
153
|
|
|
153
154
|
<%# Actions (delete on hover) %>
|
|
154
155
|
<td class="rn-col-actions" style="text-align: right">
|
|
155
|
-
<div class="
|
|
156
|
+
<div class="rn-row-actions">
|
|
156
157
|
<%= link_to logged_exception_path(exception),
|
|
157
158
|
class: "rn-icon-btn",
|
|
158
159
|
style: "color: var(--rn-text-muted)",
|
|
@@ -272,11 +272,11 @@
|
|
|
272
272
|
|
|
273
273
|
<%# ─── Keyboard Shortcuts Dialog ───────────────────────────── %>
|
|
274
274
|
<% if RailsNexus.configuration.keyboard_shortcuts %>
|
|
275
|
-
<div class="rn-shortcuts-overlay" data-rails_nexus-target="shortcutsDialog">
|
|
275
|
+
<div class="rn-shortcuts-overlay" data-rails_nexus-target="shortcutsDialog" role="dialog" aria-modal="true" aria-labelledby="rn-shortcuts-title">
|
|
276
276
|
<div class="rn-shortcuts">
|
|
277
277
|
<div class="flex items-center justify-between mb-4">
|
|
278
|
-
<h3>Keyboard Shortcuts</h3>
|
|
279
|
-
<button type="button" class="rn-icon-btn" data-action="click->rails_nexus#closeShortcuts">
|
|
278
|
+
<h3 id="rn-shortcuts-title">Keyboard Shortcuts</h3>
|
|
279
|
+
<button type="button" class="rn-icon-btn" data-action="click->rails_nexus#closeShortcuts" aria-label="Close keyboard shortcuts">
|
|
280
280
|
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
|
|
281
281
|
</button>
|
|
282
282
|
</div>
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# ════════════════════════════════════════════════════════════════════
|
|
4
|
+
# Backup Config Seed — Migrated from ~/Backup gem models
|
|
5
|
+
#
|
|
6
|
+
# Run with:
|
|
7
|
+
# rails runner db/seeds/backup_configs.rb
|
|
8
|
+
#
|
|
9
|
+
# Or from the engine:
|
|
10
|
+
# rails_nexus:seed_backups rake task
|
|
11
|
+
# ════════════════════════════════════════════════════════════════════
|
|
12
|
+
|
|
13
|
+
configs = [
|
|
14
|
+
{
|
|
15
|
+
name: "tti_daily_backup",
|
|
16
|
+
description: "TTI Daily MySQL Backup — skip sessions, versions, logged_exceptions",
|
|
17
|
+
adapter: "mysql",
|
|
18
|
+
database_name: "tti_erp",
|
|
19
|
+
host: "localhost",
|
|
20
|
+
port: 3306,
|
|
21
|
+
username: "root",
|
|
22
|
+
# password: "36B042D8948C4086F37FA@root", # stored in mysql-config/cnf — set via env or UI
|
|
23
|
+
skip_tables: "tti_erp.logged_exceptions,tti_erp.sessions,tti_erp.versions",
|
|
24
|
+
|
|
25
|
+
storage_path: "~/dumps",
|
|
26
|
+
keep_count: 365,
|
|
27
|
+
|
|
28
|
+
compress: true,
|
|
29
|
+
bzip2_compress: false,
|
|
30
|
+
encrypted: true,
|
|
31
|
+
encryption_password: "12upo12e064a3",
|
|
32
|
+
gpg_enabled: false,
|
|
33
|
+
|
|
34
|
+
rsync_enabled: true,
|
|
35
|
+
rsync_host: "172.16.1.232",
|
|
36
|
+
rsync_port: 22,
|
|
37
|
+
rsync_user: "estudent",
|
|
38
|
+
rsync_path: "tti_backups",
|
|
39
|
+
rsync_mirror: false,
|
|
40
|
+
|
|
41
|
+
s3_enabled: false,
|
|
42
|
+
|
|
43
|
+
archive_enabled: false,
|
|
44
|
+
|
|
45
|
+
notify_command: "bk-send",
|
|
46
|
+
notify_on_success: true,
|
|
47
|
+
notify_on_failure: true,
|
|
48
|
+
email_notify: false,
|
|
49
|
+
|
|
50
|
+
schedule_cron: "0 2 * * *", # daily at 2am
|
|
51
|
+
enabled: true
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
name: "tti_full_backup",
|
|
56
|
+
description: "TTI Full MySQL Backup — all tables, no skip",
|
|
57
|
+
adapter: "mysql",
|
|
58
|
+
database_name: "tti_erp",
|
|
59
|
+
host: "localhost",
|
|
60
|
+
port: 3306,
|
|
61
|
+
username: "root",
|
|
62
|
+
skip_tables: "",
|
|
63
|
+
|
|
64
|
+
storage_path: "~/dumps",
|
|
65
|
+
keep_count: 10,
|
|
66
|
+
|
|
67
|
+
compress: true,
|
|
68
|
+
bzip2_compress: false,
|
|
69
|
+
encrypted: true,
|
|
70
|
+
encryption_password: "12upo12e064a3",
|
|
71
|
+
gpg_enabled: false,
|
|
72
|
+
|
|
73
|
+
rsync_enabled: false,
|
|
74
|
+
|
|
75
|
+
s3_enabled: false,
|
|
76
|
+
|
|
77
|
+
archive_enabled: false,
|
|
78
|
+
|
|
79
|
+
notify_command: "bk-send",
|
|
80
|
+
notify_on_success: true,
|
|
81
|
+
notify_on_failure: true,
|
|
82
|
+
email_notify: false,
|
|
83
|
+
|
|
84
|
+
schedule_cron: "0 0 * * 0", # weekly Sunday at midnight
|
|
85
|
+
enabled: true
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
name: "tti_sync_backup",
|
|
90
|
+
description: "TTI Sync — MySQL dump + RSync push to remote server",
|
|
91
|
+
adapter: "mysql",
|
|
92
|
+
database_name: "tti_erp",
|
|
93
|
+
host: "localhost",
|
|
94
|
+
port: 3306,
|
|
95
|
+
username: "root",
|
|
96
|
+
skip_tables: "tti_erp.logged_exceptions,tti_erp.sessions,tti_erp.versions",
|
|
97
|
+
|
|
98
|
+
storage_path: "~/dumps/sync",
|
|
99
|
+
keep_count: 1,
|
|
100
|
+
|
|
101
|
+
compress: true,
|
|
102
|
+
bzip2_compress: false,
|
|
103
|
+
encrypted: false,
|
|
104
|
+
|
|
105
|
+
rsync_enabled: true,
|
|
106
|
+
rsync_host: "198.199.121.213",
|
|
107
|
+
rsync_port: 22,
|
|
108
|
+
rsync_user: "winner2",
|
|
109
|
+
rsync_path: "dumps/tti",
|
|
110
|
+
rsync_mirror: false,
|
|
111
|
+
|
|
112
|
+
s3_enabled: false,
|
|
113
|
+
|
|
114
|
+
archive_enabled: false,
|
|
115
|
+
|
|
116
|
+
notify_command: "bk-send",
|
|
117
|
+
notify_on_success: true,
|
|
118
|
+
notify_on_failure: true,
|
|
119
|
+
email_notify: false,
|
|
120
|
+
|
|
121
|
+
schedule_cron: "0 3 * * *", # daily at 3am
|
|
122
|
+
enabled: true
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
puts "Seeding #{configs.size} backup configs..."
|
|
127
|
+
|
|
128
|
+
configs.each do |attrs|
|
|
129
|
+
config = RailsNexus::BackupConfig.find_or_initialize_by(name: attrs[:name])
|
|
130
|
+
config.assign_attributes(attrs)
|
|
131
|
+
|
|
132
|
+
if config.save
|
|
133
|
+
puts " ✓ #{config.name} (#{config.adapter}/#{config.database_name})"
|
|
134
|
+
else
|
|
135
|
+
puts " ✗ #{config.name}: #{config.errors.full_messages.join(', ')}"
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
puts "Done. #{RailsNexus::BackupConfig.count} configs total."
|
|
@@ -139,14 +139,17 @@ class CreateRailsNexusTables < ActiveRecord::Migration[<%= "[#{ActiveRecord::Mig
|
|
|
139
139
|
t.integer :port
|
|
140
140
|
t.string :username
|
|
141
141
|
t.string :password
|
|
142
|
-
t.
|
|
142
|
+
t.string :skip_tables
|
|
143
143
|
|
|
144
144
|
t.string :storage_path, null: false
|
|
145
145
|
t.integer :keep_count, default: 30
|
|
146
146
|
|
|
147
147
|
t.boolean :compress, default: true
|
|
148
|
-
t.boolean :
|
|
149
|
-
t.
|
|
148
|
+
t.boolean :bzip2_compress, default: false
|
|
149
|
+
t.boolean :encrypted, default: false
|
|
150
|
+
t.string :encryption_password
|
|
151
|
+
t.boolean :gpg_enabled, default: false
|
|
152
|
+
t.string :gpg_password
|
|
150
153
|
|
|
151
154
|
t.boolean :rsync_enabled, default: false
|
|
152
155
|
t.string :rsync_host
|
|
@@ -155,9 +158,26 @@ class CreateRailsNexusTables < ActiveRecord::Migration[<%= "[#{ActiveRecord::Mig
|
|
|
155
158
|
t.string :rsync_path
|
|
156
159
|
t.boolean :rsync_mirror, default: false
|
|
157
160
|
|
|
161
|
+
# S3 storage
|
|
162
|
+
t.boolean :s3_enabled, default: false
|
|
163
|
+
t.string :s3_access_key
|
|
164
|
+
t.string :s3_secret_key
|
|
165
|
+
t.string :s3_bucket
|
|
166
|
+
t.string :s3_region, default: "us-east-1"
|
|
167
|
+
t.string :s3_prefix
|
|
168
|
+
|
|
169
|
+
# Archives (file/dir backup)
|
|
170
|
+
t.boolean :archive_enabled, default: false
|
|
171
|
+
t.string :archive_paths
|
|
172
|
+
t.string :archive_excludes
|
|
173
|
+
t.boolean :split_chunks, default: false
|
|
174
|
+
|
|
175
|
+
# Notifications
|
|
158
176
|
t.string :notify_command
|
|
159
177
|
t.boolean :notify_on_success, default: true
|
|
160
178
|
t.boolean :notify_on_failure, default: true
|
|
179
|
+
t.boolean :email_notify, default: false
|
|
180
|
+
t.string :email_to
|
|
161
181
|
|
|
162
182
|
t.string :schedule_cron
|
|
163
183
|
t.boolean :enabled, default: true
|
data/lib/rails_nexus/version.rb
CHANGED
data/lib/tasks/rails_nexus.rake
CHANGED
|
@@ -298,4 +298,14 @@ namespace :rails_nexus do
|
|
|
298
298
|
end
|
|
299
299
|
end
|
|
300
300
|
end
|
|
301
|
+
|
|
302
|
+
desc "Seed backup configs from ~/Backup gem models"
|
|
303
|
+
task seed_backups: :environment do
|
|
304
|
+
seed_file = File.join(RailsNexus::Engine.root, "db", "seeds", "backup_configs.rb")
|
|
305
|
+
if File.exist?(seed_file)
|
|
306
|
+
load seed_file
|
|
307
|
+
else
|
|
308
|
+
puts "Seed file not found: #{seed_file}"
|
|
309
|
+
end
|
|
310
|
+
end
|
|
301
311
|
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.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tamiru Hailu
|
|
@@ -148,6 +148,7 @@ files:
|
|
|
148
148
|
- app/models/rails_nexus/webhook_delivery.rb
|
|
149
149
|
- app/services/rails_nexus/backup_runner.rb
|
|
150
150
|
- app/services/rails_nexus/backup_service.rb
|
|
151
|
+
- app/views/layouts/rails_nexus/_sidebar_navigation.html.erb
|
|
151
152
|
- app/views/layouts/rails_nexus/application.html.erb
|
|
152
153
|
- app/views/rails_nexus/analytics/index.html.erb
|
|
153
154
|
- app/views/rails_nexus/backup/_form.html.erb
|
|
@@ -180,6 +181,7 @@ files:
|
|
|
180
181
|
- config/initializers/date_formats.rb
|
|
181
182
|
- config/locales/en.yml
|
|
182
183
|
- config/routes.rb
|
|
184
|
+
- db/seeds/backup_configs.rb
|
|
183
185
|
- lib/generators/rails_nexus/backup_generator.rb
|
|
184
186
|
- lib/generators/rails_nexus/customize_generator.rb
|
|
185
187
|
- lib/generators/rails_nexus/install_generator.rb
|