Browse Source

add DB Dump and const for SE

main
Christoph Marzell 1 month ago
parent
commit
09ee2ec73c
  1. 4
      app/controllers/admin/application_controller.rb
  2. 7
      app/controllers/application_controller.rb
  3. 66
      app/controllers/db_dump_controller.rb
  4. 2
      app/controllers/entries_controller.rb
  5. 2
      app/helpers/db_dump_helper.rb
  6. 6
      app/models/entry.rb
  7. 30
      app/views/db_dump/index.html.erb
  8. 2
      app/views/entries/_form.html.erb
  9. 7
      app/views/entries/index.html.erb
  10. 9
      app/views/layouts/application.html.erb
  11. 3
      config/routes.rb

4
app/controllers/admin/application_controller.rb

@ -12,6 +12,10 @@ module 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.
# def records_per_page

7
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

66
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

2
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 = {}

2
app/helpers/db_dump_helper.rb

@ -0,0 +1,2 @@
module DbDumpHelper
end

6
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

30
app/views/db_dump/index.html.erb

@ -0,0 +1,30 @@
<!-- app/views/db_dump/index.html.erb -->
<div class="container mt-5">
<h2 class="mb-4">📦 Datenbank-Backup & Wiederherstellung</h2>
<!-- Dump erstellen -->
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">🧾 Dump erstellen</h5>
<p class="card-text">Hier kannst du einen aktuellen Dump der Datenbank herunterladen.</p>
<a href="/db_dump/dump" class="btn btn-primary">
Dump jetzt herunterladen
</a>
</div>
</div>
<!-- Dump wiederherstellen -->
<div class="card">
<div class="card-body">
<h5 class="card-title">📤 Dump wiederherstellen</h5>
<p class="card-text">Wähle eine SQL-Dump-Datei, um die Datenbank wiederherzustellen.</p>
<%= form_with url: "/db_dump/restore", method: :post, local: true, html: { multipart: true, class: "needs-validation" } do |form| %>
<div class="mb-3">
<%= form.file_field :dump_file, class: "form-control", required: true %>
</div>
<%= form.submit "Dump einspielen", class: "btn btn-danger" %>
<% end %>
</div>
</div>
</div>

2
app/views/entries/_form.html.erb

@ -57,7 +57,6 @@
value: form.object.distance_km || 0 %>
</div>
<div id="fortbildung-fields" style="<%= form.object.entry_art == "Fortbildung" ? '' : 'display: none;' %>">
<div class="col-12 col-md-4">
<%= 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 %>
</div>
</div>
</div>

7
app/views/entries/index.html.erb

@ -18,6 +18,11 @@
<p><strong><%= year %>:</strong> <%= number_to_currency(sum, unit: "€", separator: ",", delimiter: ".", precision: 2) %></p>
<% end %>
<h5>💭 Selbsterfahrungskosten</h5>
<% @selbsterfahrungskosten_by_year.each do |year, sum| %>
<p><strong><%= year %>:</strong> <%= number_to_currency(sum, unit: "€", separator: ",", delimiter: ".", precision: 2) %></p>
<% end %>
<p><strong>Gesamtzeit:</strong> <%= @total_minutes / 60 %> h <%= @total_minutes % 60 %> min</p>
</div>
@ -73,7 +78,7 @@
<div class="mb-5">
<h4 class="mb-3">📋 Einträge</h4>
<div class="table-responsive">
<table class="table table-striped table-hover" id="entriesTable">
<table class="table table-striped table-hover table-bordered" id="entriesTable">
<thead>
<tr>
<th data-sort-index="0" class="sortable">Datum</th>

9
app/views/layouts/application.html.erb

@ -43,7 +43,7 @@
</script>
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-4">
<div class="container">
<%= link_to "Praktikumsuhr", root_path, class: "navbar-brand" %>
<%= link_to "⏱️ Praktikumsuhr", root_path, class: "navbar-brand" %>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent">
<span class="navbar-toggler-icon"></span>
@ -58,6 +58,13 @@
<li class="nav-item">
<%= link_to "Profil", edit_user_registration_path, class: "nav-link" %>
</li>
<% if current_user&.email =="christoph@marzell.net" %>
<li class="nav-item">
<%= link_to "Database", db_dump_path, class: "nav-link" %>
</li>
<% end %>
<li class="nav-item">
<%= link_to "Abmelden", destroy_user_session_path, method: :delete, data: { turbo: false }, class: "nav-link" %>
</li>

3
config/routes.rb

@ -17,7 +17,10 @@ Rails.application.routes.draw do
}
get '/impressum', to: 'static_pages#impressum'
post "/db_dump/restore", to: "db_dump#restore"
get "/db_dump/dump", to: "db_dump#dump"
get "/db_dump", to: "db_dump#index"
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.

Loading…
Cancel
Save