From 09ee2ec73ca635a3df3cdaced8ce97a27cb50b36 Mon Sep 17 00:00:00 2001 From: Christoph Marzell Date: Sun, 9 Nov 2025 08:52:58 +0100 Subject: [PATCH] add DB Dump and const for SE --- .../admin/application_controller.rb | 4 ++ app/controllers/application_controller.rb | 7 +- app/controllers/db_dump_controller.rb | 66 +++++++++++++++++++ app/controllers/entries_controller.rb | 2 +- app/helpers/db_dump_helper.rb | 2 + app/models/entry.rb | 6 ++ app/views/db_dump/index.html.erb | 30 +++++++++ app/views/entries/_form.html.erb | 2 - app/views/entries/index.html.erb | 7 +- app/views/layouts/application.html.erb | 9 ++- config/routes.rb | 3 + 11 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 app/controllers/db_dump_controller.rb create mode 100644 app/helpers/db_dump_helper.rb create mode 100644 app/views/db_dump/index.html.erb diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb index 042c9de..a4d5c55 100644 --- a/app/controllers/admin/application_controller.rb +++ b/app/controllers/admin/application_controller.rb @@ -11,6 +11,10 @@ module Admin def authenticate_admin redirect_to root_path, alert: "Kein Zugriff!" unless current_user.email =="christoph@marzell.net" end + + def is_admin? + current_user&.email =="christoph@marzell.net" + end # Override this value to specify the number of elements to display at a time # on index pages. Defaults to 20. diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d834a3a..083c599 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,9 +1,14 @@ class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? - + def authenticate_admin + redirect_to root_path, alert: "Kein Zugriff!" unless current_user.email =="christoph@marzell.net" + end def configure_permitted_parameters devise_parameter_sanitizer.permit(:account_update, keys: [:total_required_hours, :weekly_target_hours, weekly_target_matrix: {}, required_hours_matrix: {}]) end + def is_admin? + current_user&.email =="christoph@marzell.net" + end end diff --git a/app/controllers/db_dump_controller.rb b/app/controllers/db_dump_controller.rb new file mode 100644 index 0000000..972df99 --- /dev/null +++ b/app/controllers/db_dump_controller.rb @@ -0,0 +1,66 @@ +class DbDumpController < ApplicationController + before_action :authenticate_admin # Optional: Schutz davor + + def index + end + + def dump + filename = "dump_#{Time.now.strftime('%Y%m%d_%H%M%S')}.sql" + filepath = Rails.root.join("tmp", filename) + + db_config = ActiveRecord::Base.connection_db_config.configuration_hash + cmd = [ + "pg_dump", + "-U", db_config[:username], + "-h", db_config[:host] || "localhost", + "-p", (db_config[:port] || 5432).to_s, + db_config[:database], + "-f", filepath.to_s + ] + + + + ENV["PGPASSWORD"] = db_config[:password].to_s + + success = system(*cmd) + + ENV["PGPASSWORD"] = nil + + if File.exist?(filepath) + send_file filepath, type: "application/sql", filename: filename + else + render plain: "Dump fehlgeschlagen ❌", status: 500 + end + end + + def restore + uploaded = params[:dump_file] + return render plain: "Keine Datei", status: 400 unless uploaded + + filepath = Rails.root.join("tmp", "upload_restore.sql") + File.binwrite(filepath, uploaded.read) + + db_config = ActiveRecord::Base.connection_db_config.configuration_hash + + cmd = [ + "psql", + "-U", db_config[:username], + "-h", db_config[:host] || "localhost", + "-p", (db_config[:port] || 5432).to_s, + db_config[:database], + "-f", filepath.to_s + ] + + ENV["PGPASSWORD"] = db_config[:password].to_s + + result = system(*cmd) + + ENV["PGPASSWORD"] = nil + if result + render plain: "Restore erfolgreich ✅" + else + render plain: "Restore fehlgeschlagen ❌", status: 500 + end + end + +end diff --git a/app/controllers/entries_controller.rb b/app/controllers/entries_controller.rb index d584962..b18c4a4 100644 --- a/app/controllers/entries_controller.rb +++ b/app/controllers/entries_controller.rb @@ -37,7 +37,7 @@ class EntriesController < ApplicationController end @fortbildungskosten_by_year = Entry.total_fortbildungskosten_by_year(current_user) - + @selbsterfahrungskosten_by_year = Entry.total_selbsterfahrungskosten_by_year(current_user) # Voraussichtliches Ende je Kombination basierend auf weekly_target_matrix @estimated_end_by_typ_art = {} diff --git a/app/helpers/db_dump_helper.rb b/app/helpers/db_dump_helper.rb new file mode 100644 index 0000000..38db233 --- /dev/null +++ b/app/helpers/db_dump_helper.rb @@ -0,0 +1,2 @@ +module DbDumpHelper +end diff --git a/app/models/entry.rb b/app/models/entry.rb index f8bfb6c..419df05 100644 --- a/app/models/entry.rb +++ b/app/models/entry.rb @@ -29,6 +29,12 @@ class Entry < ApplicationRecord .transform_values { |entries| entries.sum { |e| e.kosten.to_f } } end + def self.total_selbsterfahrungskosten_by_year(user) + where(user: user, entry_art: 'Selbsterfahrung') + .group_by { |e| e.date.year } + .transform_values { |entries| entries.sum { |e| e.kosten.to_f } } + end + def jahr date.year end diff --git a/app/views/db_dump/index.html.erb b/app/views/db_dump/index.html.erb new file mode 100644 index 0000000..90b997f --- /dev/null +++ b/app/views/db_dump/index.html.erb @@ -0,0 +1,30 @@ + +
+

📦 Datenbank-Backup & Wiederherstellung

+ + +
+
+
🧾 Dump erstellen
+

Hier kannst du einen aktuellen Dump der Datenbank herunterladen.

+ + Dump jetzt herunterladen + +
+
+ + +
+
+
📤 Dump wiederherstellen
+

Wähle eine SQL-Dump-Datei, um die Datenbank wiederherzustellen.

+ + <%= form_with url: "/db_dump/restore", method: :post, local: true, html: { multipart: true, class: "needs-validation" } do |form| %> +
+ <%= form.file_field :dump_file, class: "form-control", required: true %> +
+ <%= form.submit "Dump einspielen", class: "btn btn-danger" %> + <% end %> +
+
+
diff --git a/app/views/entries/_form.html.erb b/app/views/entries/_form.html.erb index 3bbcf4a..1a39e14 100644 --- a/app/views/entries/_form.html.erb +++ b/app/views/entries/_form.html.erb @@ -57,7 +57,6 @@ value: form.object.distance_km || 0 %> -
">
<%= form.label :beschreibung, 'Beschreibung', class: 'form-label' %> <%= form.text_field :beschreibung, class: 'form-control' %> @@ -67,7 +66,6 @@ <%= form.label :kosten, 'Kosten (z. B. Teilnahmegebühr)', class: 'form-label' %> <%= form.number_field :kosten, class: 'form-control', min: 0, step: 0.01 %>
-
diff --git a/app/views/entries/index.html.erb b/app/views/entries/index.html.erb index b800caf..382f982 100644 --- a/app/views/entries/index.html.erb +++ b/app/views/entries/index.html.erb @@ -18,6 +18,11 @@

<%= year %>: <%= number_to_currency(sum, unit: "€", separator: ",", delimiter: ".", precision: 2) %>

<% end %> +
💭 Selbsterfahrungskosten
+ <% @selbsterfahrungskosten_by_year.each do |year, sum| %> +

<%= year %>: <%= number_to_currency(sum, unit: "€", separator: ",", delimiter: ".", precision: 2) %>

+ <% end %> +

Gesamtzeit: <%= @total_minutes / 60 %> h <%= @total_minutes % 60 %> min

@@ -73,7 +78,7 @@

📋 Einträge

- +
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index e6b4528..eb2e426 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -43,7 +43,7 @@
Datum