diff --git a/Gemfile b/Gemfile index bf70e13..9ec06ca 100644 --- a/Gemfile +++ b/Gemfile @@ -17,6 +17,7 @@ gem "image_processing", "~> 1.12" gem "devise" gem "devise-i18n" +gem "paper_trail" gem "slack-notifier" gem "administrate-field-active_storage" gem "administrate-field-enumerize" diff --git a/Gemfile.lock b/Gemfile.lock index 89105c8..b0edbd3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -175,6 +175,9 @@ GEM mini_portile2 (~> 2.6.1) racc (~> 1.4) orm_adapter (0.5.0) + paper_trail (12.0.0) + activerecord (>= 5.2) + request_store (~> 1.1) parallel (1.20.1) parser (3.0.2.0) ast (~> 2.4.1) @@ -235,6 +238,8 @@ GEM rb-inotify (0.10.1) ffi (~> 1.0) regexp_parser (2.1.1) + request_store (1.5.0) + rack (>= 1.4) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) @@ -354,6 +359,7 @@ DEPENDENCIES image_processing (~> 1.12) listen (~> 3.3) money-rails + paper_trail pg (~> 1.1) pry-byebug puma (~> 5.0) diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb index aed0512..bb63a55 100644 --- a/app/controllers/admin/application_controller.rb +++ b/app/controllers/admin/application_controller.rb @@ -2,5 +2,12 @@ module Admin class ApplicationController < Administrate::ApplicationController before_action :authenticate_admin_user! + before_action :set_paper_trail_whodunnit + + # used by #set_paper_trail_whodunnit + def current_user + # add admin prefix to differentiate from a customer + "admin/#{current_admin_user.id}" + end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d970904..a30d4c6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true class ApplicationController < ActionController::Base + before_action :set_paper_trail_whodunnit before_action :configure_devise_permitted_parameters, if: :devise_controller? protected diff --git a/app/models/balance.rb b/app/models/balance.rb index 7f98371..1020d1e 100644 --- a/app/models/balance.rb +++ b/app/models/balance.rb @@ -22,6 +22,8 @@ # fk_rails_... (user_id => users.id) # class Balance < ApplicationRecord + include Trackable + belongs_to :user belongs_to :currency diff --git a/app/models/concerns/trackable.rb b/app/models/concerns/trackable.rb new file mode 100644 index 0000000..810e161 --- /dev/null +++ b/app/models/concerns/trackable.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +module Trackable + extend ActiveSupport::Concern + + included do + has_paper_trail + end +end diff --git a/app/models/fiat_balance.rb b/app/models/fiat_balance.rb index b64c62a..3f297a2 100644 --- a/app/models/fiat_balance.rb +++ b/app/models/fiat_balance.rb @@ -20,6 +20,8 @@ # fk_rails_... (user_id => users.id) # class FiatBalance < ApplicationRecord + include Trackable + belongs_to :user monetize :amount_cents diff --git a/db/migrate/20210817233439_create_versions.rb b/db/migrate/20210817233439_create_versions.rb new file mode 100644 index 0000000..438cf98 --- /dev/null +++ b/db/migrate/20210817233439_create_versions.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# This migration creates the `versions` table, the only schema PT requires. +# All other migrations PT provides are optional. +class CreateVersions < ActiveRecord::Migration[6.1] + # The largest text column available in all supported RDBMS is + # 1024^3 - 1 bytes, roughly one gibibyte. We specify a size + # so that MySQL will use `longtext` instead of `text`. Otherwise, + # when serializing very large objects, `text` might not be big enough. + TEXT_BYTES = 1_073_741_823 + + def change + create_table(:versions) do |t| + t.string(:item_type, { null: false }) + t.bigint(:item_id, null: false) + t.string(:event, null: false) + t.string(:whodunnit) + t.text(:object, limit: TEXT_BYTES) + + t.datetime(:created_at) + end + add_index(:versions, [:item_type, :item_id]) + end +end diff --git a/db/schema.rb b/db/schema.rb index 89afce2..89ef41a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_08_16_174637) do +ActiveRecord::Schema.define(version: 2021_08_17_233439) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -138,6 +138,16 @@ ActiveRecord::Schema.define(version: 2021_08_16_174637) do t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end + create_table "versions", force: :cascade do |t| + t.string "item_type", null: false + t.bigint "item_id", null: false + t.string "event", null: false + t.string "whodunnit" + t.text "object" + t.datetime "created_at" + t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" + end + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "balances", "currencies" diff --git a/erd.svg b/erd.svg index 28dd21c..25c19e1 100644 --- a/erd.svg +++ b/erd.svg @@ -69,8 +69,8 @@ m_Currency->m_Balance - - + + @@ -79,7 +79,7 @@ - + m_SellCryptoOrder SellCryptoOrder @@ -102,7 +102,7 @@ - + m_StakeOrder StakeOrder @@ -137,8 +137,25 @@ user_id integer (8) ∗ FK + + +m_PaperTrail::Version + +PaperTrail::Version + +event +string ∗ +item_id +integer (8) ∗ +item_type +string ∗ +object +text +whodunnit +string + - + m_User User @@ -188,7 +205,7 @@ - + m_UserDocument UserDocument