loggable_activity 0.5.0 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -0
  3. data/CHANGELOG.md +15 -0
  4. data/GETTING-STARTED.md +60 -0
  5. data/README.md +42 -31
  6. data/app/assets/config/loggable_activity_manifest.js +1 -3
  7. data/app/assets/javascripts/loggable_activity/application.js +0 -1
  8. data/app/assets/stylesheets/loggable_activity/activities.scss +25 -0
  9. data/app/assets/stylesheets/loggable_activity/application.scss +2 -6
  10. data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_first_page.html.erb +0 -1
  11. data/app/views/kaminari/pico/_last_page.html.erb +12 -0
  12. data/app/views/layouts/loggable_activity/application.html.slim +20 -0
  13. data/app/views/loggable_activity/activities/_activities.html.slim +28 -0
  14. data/app/views/loggable_activity/activities/index.html.erb +5 -6
  15. data/app/views/loggable_activity/bootstrap/kaminari/_first_page.html.erb +13 -0
  16. data/app/views/loggable_activity/bootstrap/kaminari/_gap.html.erb +8 -0
  17. data/app/views/loggable_activity/bootstrap/kaminari/_next_page.html.erb +13 -0
  18. data/app/views/loggable_activity/bootstrap/kaminari/_page.html.erb +14 -0
  19. data/app/views/loggable_activity/bootstrap/kaminari/_paginator.html.erb +27 -0
  20. data/app/views/loggable_activity/bootstrap/kaminari/_prev_page.html.erb +13 -0
  21. data/config/initializers/kaminari_config.rb +1 -1
  22. data/lib/generators/loggable_activity/install/install_generator.rb +68 -0
  23. data/lib/generators/loggable_activity/install/templates/create_loggable_activities.rb +45 -0
  24. data/lib/generators/loggable_activity/install/templates/loggable_activity.en.yml +32 -0
  25. data/lib/generators/loggable_activity/install/templates/loggable_activity.rb +27 -0
  26. data/lib/generators/loggable_activity/install/templates/loggable_activity.yml +103 -0
  27. data/lib/loggable_activity/activity.rb +4 -3
  28. data/lib/loggable_activity/config_schema.json +2 -20
  29. data/lib/loggable_activity/configuration.rb +0 -15
  30. data/lib/loggable_activity/encryption.rb +33 -12
  31. data/lib/loggable_activity/encryption_key.rb +1 -1
  32. data/lib/loggable_activity/engine.rb +0 -5
  33. data/lib/loggable_activity/error.rb +3 -3
  34. data/lib/loggable_activity/hooks.rb +42 -18
  35. data/lib/loggable_activity/payload.rb +6 -4
  36. data/lib/loggable_activity/services/base_payloads_builder.rb +2 -1
  37. data/lib/loggable_activity/services/custom_payloads_builder.rb +55 -0
  38. data/lib/loggable_activity/services/payloads_builder.rb +3 -3
  39. data/lib/loggable_activity/services/update_payloads_builder.rb +4 -4
  40. data/lib/loggable_activity/version.rb +1 -1
  41. data/lib/loggable_activity.rb +4 -1
  42. data/loggable_activity-0.5.0.gem +0 -0
  43. metadata +34 -127
  44. data/app/views/layouts/loggable_activity/application.html.erb +0 -19
  45. data/app/views/loggable_activity/activities/_activities.html.erb +0 -56
  46. data/app/views/loggable_activity/activities/show.html.erb +0 -2
  47. /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_gap.html.erb +0 -0
  48. /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_next_page.html.erb +0 -0
  49. /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_page.html.erb +0 -0
  50. /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_paginator.html.erb +0 -0
  51. /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_prev_page.html.erb +0 -0
  52. /data/app/views/{kaminari/kaminari-turbo-bootstrap → loggable_activity/bootstrap/kaminari}/_last_page.html.erb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62e1b197ae053af29d55c9b183c358a773f43186691c20c8e124ba7786bde586
4
- data.tar.gz: ae8bd2c8d9a9718c02fc246c2a5a703b6fad9b27823cf357a51020d96b0a5a16
3
+ metadata.gz: e8d0d096b34f0b29dc9d0af6fb1c44e7fb4ba79b85b92e0e6aee4d895e5dcc57
4
+ data.tar.gz: 35ffb9e0e97409e8da7d659a37a37a66e2305f441505c4852af03d9681b8d90d
5
5
  SHA512:
6
- metadata.gz: 7ed08eae394bc830b08d21f68de6b3f77811fde3b73d4278351bc807ee7c9de3369632bb349f16e45dd518e74297064494b1f810bb1b2c3cf1744d34f898adf9
7
- data.tar.gz: 91891b25f6826cd70fcacc3bd3365a14b50e319c6d3af6ceecf72cb8340adb1298a79d28a1d08964087011c9e3766e188fe80193a3d293d087611a543817a7f4
6
+ metadata.gz: f2cae0fe288f7ac429004f9318e833af33d2b629b57041dfa6d2da11e81b6cf10cd282ee0672b5a8aab4a0529ff9637f682979c9b91749559827863b42281c10
7
+ data.tar.gz: 7f068e3bf66ac331a646e909c631d79ef9e455643f13b2ac9a3e574d99e9dfefc046d76885a6f38bba275a5763c8c7f64980076a86cbc4e230dd4d65aaa64d2c
data/.rubocop.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  AllCops:
2
+ NewCops: enable
2
3
  Exclude:
3
4
  - 'db/migrate/20240702092648_create_loggable_activity_tables.rb'
4
5
  Layout/LineLength:
@@ -9,6 +10,8 @@ Layout/LineLength:
9
10
  Metrics/AbcSize:
10
11
  Exclude:
11
12
  - 'lib/loggable_activity/encryption.rb'
13
+ - 'lib/loggable_activity/services/update_payloads_builder.rb'
14
+ - 'lib/generators/loggable_activity/install/templates/create_loggable_activities.rb'
12
15
  Metrics/BlockLength:
13
16
  Exclude:
14
17
  - 'test/dummy/config/environments/development.rb'
@@ -18,6 +21,7 @@ Metrics/ClassLength:
18
21
  Exclude:
19
22
  - 'lib/loggable_activity/services/update_payloads_builder.rb'
20
23
  Metrics/MethodLength:
24
+ Enabled: true
21
25
  Exclude:
22
26
  - 'lib/loggable_activity/services/update_payloads_builder.rb'
23
27
  - 'lib/loggable_activity/services/destroy_payloads_builder.rb'
@@ -27,6 +31,9 @@ Metrics/MethodLength:
27
31
  - 'lib/loggable_activity/activity.rb'
28
32
  - 'lib/loggable_activity/services/payloads_builder.rb'
29
33
  - 'lib/loggable_activity/hooks.rb'
34
+ - 'test/dummy/db/migrate/20240629154538_create_users.rb'
35
+ - 'lib/loggable_activity/services/custom_payloads_builder.rb'
36
+ - 'lib/generators/loggable_activity/install/templates/create_loggable_activities.rb'
30
37
  Metrics/ModuleLength:
31
38
  Exclude:
32
39
  - 'lib/loggable_activity/hooks.rb'
@@ -36,3 +43,6 @@ Style/Documentation:
36
43
  - 'app/models/loggable_activity/application_record.rb'
37
44
  - 'app/mailers/loggable_activity/application_mailer.rb'
38
45
  - 'app/helpers/loggable_activity/application_helper.rb'
46
+ Metrics/CyclomaticComplexity:
47
+ Exclude:
48
+ - 'lib/loggable_activity/hooks.rb'
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [0.5.6] - 2024-07-18
2
+ - Documentation updated
3
+ - Generator updated
4
+
5
+ ## [0.5.5] - 2024-07-16
6
+ - Custom attrs added
7
+ ### Breaking change
8
+ - Configuration.yml changed
9
+
10
+ ## [0.5.4] - 2024-03-21
11
+ - Styling with bootstrap css
12
+
13
+ ## [0.5.2] - 2024-03-21
14
+ - Styling with pico css
15
+ - Public attrs added
1
16
 
2
17
  ## [0.2.0] - 2024-07-03
3
18
  - Keys kan be kept until LoggableActivity::Sanitizer.run is called
@@ -0,0 +1,60 @@
1
+ # Getting started
2
+ This document should you getting started with `LoggableActivity`
3
+
4
+ ## Prerequisite
5
+ 1 A running Rails Application<br/>
6
+ 2 An authorization system where a current user or similar is available.
7
+
8
+ ## Installation
9
+ Add the loggable_activity gem to the Gemfile `gem 'loggable_activity', '~> 0.5.4` and then<br/>
10
+ ```
11
+ $ bundle install
12
+ ```
13
+ Then we have to generate some migrations and execute them<br/>
14
+ ```
15
+ $ bin/rails generate loggable_activity:install
16
+ $ bin/rails db:migrate
17
+ ```
18
+
19
+ ## Add hoks to models
20
+ ```
21
+ class User < ApplicationRecord
22
+ include LoggableActivity::Hooks
23
+ ```
24
+
25
+ ## Configuration
26
+ Update `config/initializers/loggable_activity.rb` documentation is in the file.
27
+
28
+ ## loggable_activity.yaml
29
+ You have to update the configuration file installed inside the `config/loggable_activity.yaml`
30
+ This file defines how data are logged.
31
+
32
+ ## Automatically log show from controllers
33
+ This assumes that there is a current_user. E.g provided by the Devise gem</br>
34
+ Add a this to the application_controller.rb if you want automatically log show
35
+ ```
36
+ class ApplicationController < ActionController::Base
37
+ include LoggableActivity::CurrentUser
38
+ ```
39
+ Otherwise you might create `app/controllers/concerns/current_user.rb` and alter it .
40
+
41
+ ## Manually log show from controllers
42
+ If you want to log the show action you can add this to your controllers show method
43
+ ```
44
+ def show
45
+ @user.log(:show)
46
+ ```
47
+
48
+ ## For developers and contributors
49
+ You can download and play around with a demo app
50
+ - 1 Download the project from [github](https://github.com/LoggableActivity/LoggableActivity)
51
+ - 1 Download the demo application from [github](https://github.com/LoggableActivity/LoggableActivityDemoApp)
52
+ - 2 Update the Gemfile in the demo project so it points to your localhost.
53
+ ```
54
+ Gemfile
55
+
56
+ gem 'loggable_activity', '~> VERSION', path: '/PATH_TO_PROJECT/LoggableActivityEngine/LoggableActivityEngine'
57
+ # gem 'loggable_activity', '~> VERSION'
58
+ ```
59
+ *VERSION is the version number found in the gemfile*<br/>
60
+ *PATH_TO_PROJECT* is where you have stored the project on your local drive
data/README.md CHANGED
@@ -1,31 +1,42 @@
1
- # LoggableActivity
2
- Short description and motivation.
3
-
4
- ## Usage
5
- How to use my plugin.
6
-
7
- ## Installation
8
- Add this line to your application's Gemfile:
9
-
10
- ```ruby
11
- gem "loggable_activity"
12
- ```
13
-
14
- And then execute:
15
- ```bash
16
- $ bundle
17
- ```
18
-
19
- Or install it yourself as:
20
- ```bash
21
- $ gem install loggable_activity
22
- ```
23
-
24
- ## Contributing
25
- Contribution directions go here.
26
-
27
- ## License
28
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
29
-
30
- ##
31
- bin/rails loggable_activity:install:migrations
1
+ # Loggable Activity 🌟
2
+ Super easy to use activity log with views out of the box
3
+ - Just add the gem and mount the engine and you have a cool looking activity log.
4
+ - Easy and simple to customize and configure
5
+ - All data are encrypted, and
6
+
7
+ ### Important!
8
+ This project is under development and not ready for production. There might be breaking changes, so please consult the CHANGELOG.md
9
+ ### What it is not
10
+ - An error logging system
11
+ - A paper trails system with rollback.
12
+ - A backup system
13
+
14
+ ### Applications
15
+ Most organizations needs to keep a log of how users interact with data stored in the DB
16
+ - Finance
17
+ - Healthcare
18
+ - Sales and Support
19
+
20
+ *Super simplified example from the healthcare.*
21
+ - Each patient has a journal, that is updated on a regular basis.
22
+ - Supervisor needs to follow the journal, how was it updated, who read it, did it get deleted.
23
+ - Security personnel needs to know how the journal is handled, who did what when.
24
+ - Patients has the right to know how their journal is handled and that their data will be removed when required.
25
+
26
+ Beside the journal in the db, an activity log is kept so it is possible to track how the journal is used.<br/>
27
+ At some point in time the patients data from the DB and the activity log has to be removed according to GDPR.<br/>
28
+
29
+ ### Getting started
30
+ please read the [GETTING-STARTED.md](https://github.com/LoggableActivity/LoggableActivity/blob/main/GETTING-STARTED.md) guide
31
+
32
+ ### Contribute
33
+ 👉 Join the Slack channel here: [LoggableActivity Slack Workspace](https://join.slack.com/t/loggableactivity/shared_invite/zt-2a3tvgv37-mGwjHJTrBXBH2srXFRRSXQ)
34
+ <br/>
35
+ 👉 Want to play around with an online version: [Show Demo](https://loggableactivity-efe7b931c886.herokuapp.com/)
36
+ <br/>
37
+ We value each contribution and believe in the power of community. Looking forward to seeing you there!
38
+
39
+
40
+ ### Test
41
+ We embrace the philosophy of black-box testing, where we focus on the input and output of the public interface without worrying about internal implementation details.<br/>
42
+ This approach aligns with the principle of testing behavior rather than implementation.
@@ -1,4 +1,2 @@
1
1
  //= link_directory ../stylesheets/loggable_activity .css
2
- //= link application.css
3
- //= link_directory ../javascripts/loggable_activity .js
4
- //= link application.js
2
+
@@ -1,2 +1 @@
1
- //= require bootstrap
2
1
 
@@ -0,0 +1,25 @@
1
+ .activity {
2
+ --bs-alert-bg: transparent;
3
+ --bs-alert-padding-x: 1rem;
4
+ --bs-alert-padding-y: 0.5rem;
5
+ // --bs-alert-margin-bottom: 1rem;
6
+ --bs-alert-color: inherit;
7
+ --bs-alert-border-color: transparent;
8
+ --bs-alert-border: var(--bs-border-width) solid var(--bs-alert-border-color);
9
+ --bs-alert-border-radius: var(--bs-border-radius);
10
+ --bs-alert-link-color: inherit;
11
+ position: relative;
12
+ padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x);
13
+ margin-bottom: var(--bs-alert-margin-bottom);
14
+ color: var(--bs-alert-color);
15
+ background-color: var(--bs-alert-bg);
16
+ border: var(--bs-alert-border);
17
+ // border-radius: 0;
18
+ }
19
+
20
+ .activity-info {
21
+ --bs-alert-color: var(--bs-info-text-emphasis);
22
+ --bs-alert-bg: var(--bs-info-bg-subtle);
23
+ --bs-alert-border-color: var(--bs-info-border-subtle);
24
+ --bs-alert-link-color: var(--bs-info-text-emphasis);
25
+ }
@@ -12,9 +12,5 @@
12
12
  *
13
13
  *= require_tree .
14
14
  *= require_self
15
- */
16
-
17
- @import "bootstrap/functions";
18
- @import "bootstrap/variables";
19
- @import "bootstrap/mixins";
20
- @import "bootstrap";
15
+ *= require loggable_activity/activities
16
+ */
@@ -8,7 +8,6 @@
8
8
  -%>
9
9
  <% unless current_page.first? %>
10
10
  <li class="page-item">
11
- <%# <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :class => 'page-link', :remote => remote %>
12
11
  <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, class: 'page-link', data: { turbo: true } %>
13
12
  </li>
14
13
  <% end %>
@@ -0,0 +1,12 @@
1
+ <%# Link to the "Last" page
2
+ - available local variables
3
+ url: url to the last page
4
+ current_page: a page object for the currently displayed page
5
+ num_pages: total number of pages
6
+ per_page: number of items to fetch per page
7
+ remote: data-remote
8
+ -%>
9
+ <% unless current_page.last? %>
10
+ <%= link_to_unless current_page.last?, raw(t('views.pagination.last')), url, class: 'page-link', data: { turbo: true } %>
11
+ </li>
12
+ <% end %>
@@ -0,0 +1,20 @@
1
+ doctype html
2
+ html
3
+ head
4
+ title Loggable activity
5
+ = csrf_meta_tags
6
+ = csp_meta_tag
7
+ = stylesheet_link_tag "loggable_activity/application", media: "all"
8
+
9
+ link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism.min.css" rel="stylesheet"
10
+ script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"
11
+
12
+ = stylesheet_link_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css',
13
+ integrity: 'sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH',
14
+ crossorigin: 'anonymous'
15
+
16
+ body data-bs-theme="dark"
17
+ = yield
18
+ = javascript_include_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js',
19
+ integrity: 'sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz',
20
+ crossorigin: 'anonymous'
@@ -0,0 +1,28 @@
1
+
2
+ .row
3
+ .col-3
4
+ b.text-secondary = t('loggable_activity.activity.action')
5
+ .col-3
6
+ b.text-secondary = t('loggable_activity.activity.record')
7
+ .col-3
8
+ b.text-secondary = t('loggable_activity.activity.actor')
9
+ .col-3
10
+ b.text-secondary = t('loggable_activity.activity.created_at')
11
+
12
+ - @activities.each do |activity|
13
+ .activity.activity-info[type="button" data-bs-toggle="collapse" data-bs-target="#activity_#{activity.id}" aria-expanded="false" aria-controls="collapseExample"]
14
+ .row
15
+ .col-3
16
+ = activity_action(activity)
17
+ .col-3
18
+ = activity.record_display_name
19
+ .col-3
20
+ = activity.actor_display_name
21
+ .col-3
22
+ = l(activity.created_at, format: :long)
23
+ .collapse id="activity_#{activity.id}"
24
+ pre
25
+ code.language-json
26
+ = format_json_for_display(activity.attrs)
27
+ javascript:
28
+ Prism.highlightAll();
@@ -1,7 +1,6 @@
1
- <h1>Activities</h1>
2
- <%= render partial: "activities", activities: @activities %>
1
+ <div class="container">
2
+ <h1>Activities</h1>
3
+ <%= paginate @activities, views_prefix: "loggable_activity/bootstrap" %>
4
+ <%= render partial: "activities", activities: @activities %>
5
+ </div>
3
6
 
4
- <%= paginate @activities, theme: 'kaminari-turbo-bootstrap' %>
5
-
6
-
7
-
@@ -0,0 +1,13 @@
1
+ <%# Link to the "First" page
2
+ - available local variables
3
+ url: url to the first page
4
+ current_page: a page object for the currently displayed page
5
+ num_pages: total number of pages
6
+ per_page: number of items to fetch per page
7
+ remote: data-remote
8
+ -%>
9
+ <% unless current_page.first? %>
10
+ <li class="page-item">
11
+ <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, class: 'page-link', data: { turbo: true } %>
12
+ </li>
13
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <%# Non-link tag that stands for skipped pages...
2
+ - available local variables
3
+ current_page: a page object for the currently displayed page
4
+ num_pages: total number of pages
5
+ per_page: number of items to fetch per page
6
+ remote: data-remote
7
+ -%>
8
+ <li class="page-item disabled"><a href="#" onclick="return false;" class="page-link"><%= raw(t 'views.pagination.truncate') %></a></li>
@@ -0,0 +1,13 @@
1
+ <%# Link to the "Next" page
2
+ - available local variables
3
+ url: url to the next page
4
+ current_page: a page object for the currently displayed page
5
+ num_pages: total number of pages
6
+ per_page: number of items to fetch per page
7
+ remote: data-remote
8
+ -%>
9
+ <% unless current_page.last? %>
10
+ <li class="page-item">
11
+ <%= link_to_unless current_page.last?, raw(t('views.pagination.next')), url, class: 'page-link', rel: 'next', data: { turbo: true }, remote: remote %>
12
+ </li>
13
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <%# Link showing page number
2
+ - available local variables
3
+ page: a page object for "this" page
4
+ url: url to this page
5
+ current_page: a page object for the currently displayed page
6
+ num_pages: total number of pages
7
+ per_page: number of items to fetch per page
8
+ remote: data-remote
9
+ -%>
10
+ <li class="page-item<%= ' active' if page.current? %>">
11
+ <%#= link_to page, url, opts = {:remote => remote, :class => 'page-link', :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %>
12
+ <%= link_to page, url, class: 'page-link', rel: page.next? ? 'next' : page.prev? ? 'prev' : nil, data: { turbo: true }, remote: remote %>
13
+
14
+ </li>
@@ -0,0 +1,27 @@
1
+ <%# The container tag
2
+ - available local variables
3
+ current_page: a page object for the currently displayed page
4
+ num_pages: total number of pages
5
+ per_page: number of items to fetch per page
6
+ remote: data-remote
7
+ paginator: the paginator that renders the pagination tags inside
8
+ -%>
9
+ <%- pagination_class ||= '' %>
10
+ <%- nav_class ||= '' %>
11
+ <%= paginator.render do -%>
12
+ <nav class="<%= nav_class %>">
13
+ <ul class="pagination <%= pagination_class %>">
14
+ <%= first_page_tag unless current_page.first? %>
15
+ <%= prev_page_tag unless current_page.first? %>
16
+ <% each_page do |page| -%>
17
+ <% if page.left_outer? || page.right_outer? || page.inside_window? -%>
18
+ <%= page_tag page %>
19
+ <% elsif !page.was_truncated? -%>
20
+ <%= gap_tag %>
21
+ <% end -%>
22
+ <% end -%>
23
+ <%= next_page_tag unless current_page.last? %>
24
+ <%= last_page_tag unless current_page.last? %>
25
+ </ul>
26
+ </nav>
27
+ <% end -%>
@@ -0,0 +1,13 @@
1
+ <%# Link to the "Previous" page
2
+ - available local variables
3
+ url: url to the previous page
4
+ current_page: a page object for the currently displayed page
5
+ num_pages: total number of pages
6
+ per_page: number of items to fetch per page
7
+ remote: data-remote
8
+ -%>
9
+ <% unless current_page.first? %>
10
+ <li class="page-item">
11
+ <%= link_to_unless current_page.first?, raw(t('views.pagination.previous')), url, rel: 'prev', class: 'page-link', data: { turbo: true }, remote: remote %>
12
+ </li>
13
+ <% end %>
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Kaminari.configure do |config|
4
- config.default_per_page = 3
4
+ # config.default_per_page = 10
5
5
  # config.max_per_page = nil
6
6
  # config.window = 4
7
7
  # config.outer_window = 0
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This module provides generators for installing and configuring LoggableActivity.
4
+ # It includes generators for creating initializer, migration, and locale files.
5
+ #
6
+ # Example usage:
7
+ # rails generate loggable_activity:install
8
+ #
9
+ # This will:
10
+ # - Create an initializer file in config/initializers/loggable_activity.rb
11
+ # - Create a migration file in db/migrate/
12
+ # - Create a locale file in config/locales/loggable_activity.en.yml
13
+ #
14
+ # After running the generator, remember to:
15
+ # - Add `mount LoggableActivity::Engine => '/loggable_activity'` to your routes.rb file.
16
+ # - Run `rails db:migrate` to create the necessary database tables.
17
+ # - Include `LoggableActivity::Hook` in the models you want to track.
18
+ # - Update the config/loggable_activity.yaml file with the fields you want to track.
19
+ # - Ensure the locale files are properly set up in config/locales/loggable_activity.en.yml.
20
+ module LoggableActivity
21
+ module Generators
22
+ # The InstallGenerator class is responsible for copying the necessary
23
+ # files to set up LoggableActivity in a Rails application.
24
+ class InstallGenerator < Rails::Generators::Base
25
+ source_root File.expand_path('templates', __dir__)
26
+
27
+ desc 'Creates a LoggableActivity initializer in your application.'
28
+ def copy_initializer
29
+ template 'loggable_activity.rb', 'config/initializers/loggable_activity.rb'
30
+ end
31
+
32
+ desc 'Creates a migration file for LoggableActivity in your application.'
33
+ def copy_migration
34
+ template 'create_loggable_activities.rb', "db/migrate/#{migration_number}_create_loggable_activities.rb"
35
+ end
36
+
37
+ desc 'Creates a locale file for LoggableActivity in your application.'
38
+ def copy_locale
39
+ template 'loggable_activity.en.yml', 'config/locales/loggable_activity.en.yml'
40
+ end
41
+
42
+ # Generates a timestamp to use in the migration filename.
43
+ #
44
+ # @return [String] the current UTC time formatted as a timestamp
45
+ def migration_number
46
+ Time.now.utc.strftime('%Y%m%d%H%M%S')
47
+ end
48
+
49
+ puts ''
50
+ puts "\e[1m\e[32m* ----------------------------- LoggableActivity ----------------------------- *\e[0m"
51
+ puts "\e[1m\e[32m* *\e[0m"
52
+ puts "\e[1m\e[32m* LoggableActivity has been successfully installed. *\e[0m"
53
+ puts "\e[1m\e[32m* Add the following to your routes.rb file. *\e[0m"
54
+ puts "\e[1m\e[32m* Mount LoggableActivity::Engine => '/loggable_activity' *\e[0m"
55
+ puts "\e[1m\e[32m* *\e[0m"
56
+ puts "\e[1m\e[32m* $ rails db:migrate to create the tables. *\e[0m"
57
+ puts "\e[1m\e[32m* *\e[0m"
58
+ puts "\e[1m\e[32m* Add include LoggableActivity::Hook to the models you want to track. *\e[0m"
59
+ puts "\e[1m\e[32m* *\e[0m"
60
+ puts "\e[1m\e[32m* Update the config/loggable_activity.yaml file with fields to track. *\e[0m"
61
+ puts "\e[1m\e[32m* *\e[0m"
62
+ puts "\e[1m\e[32m* Locale files are found in config/locale/loggable_activity.en.yaml. *\e[0m"
63
+ puts "\e[1m\e[32m* *\e[0m"
64
+ puts "\e[1m\e[32m* ---------------------------------------------------------------------------- *\e[0m"
65
+ puts ''
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This migration creates the necessary tables for LoggableActivity.
4
+ class CreateLoggableActivities < ActiveRecord::Migration[7.1]
5
+ def change
6
+ create_table :loggable_activity_encryption_keys do |t|
7
+ t.references :record, polymorphic: true, null: true, index: true
8
+ t.string :secret_key
9
+ t.datetime :delete_at
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ create_table :loggable_activity_activities do |t|
15
+ t.string :action
16
+ t.references :actor, polymorphic: true, null: true
17
+ t.string :encrypted_actor_name
18
+ t.references :record, polymorphic: true, null: true
19
+
20
+ t.timestamps
21
+ end
22
+
23
+ create_table :loggable_activity_payloads do |t|
24
+ t.references :activity, null: false, foreign_key: { to_table: 'loggable_activity_activities' }
25
+ t.references :encryption_key, null: false, foreign_key: { to_table: 'loggable_activity_encryption_keys' }
26
+ t.references :record, polymorphic: true, null: true, index: true
27
+ t.string :encrypted_record_name
28
+ t.json :encrypted_attrs
29
+ t.integer :related_to_activity_as, default: 0
30
+ t.boolean :data_owner, default: false
31
+ t.string :route
32
+ t.boolean :current_payload, default: true
33
+ t.json :public_attrs, default: {}
34
+
35
+ t.timestamps
36
+ end
37
+
38
+ create_table :loggable_activity_data_owners do |t|
39
+ t.references :record, polymorphic: true, null: true, index: true
40
+ t.references :encryption_key, null: false, foreign_key: { to_table: 'loggable_activity_encryption_keys' }
41
+
42
+ t.timestamps
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+
2
+ # This file was generated when you installed Loggable Activity and is used for internationalization.
3
+ # When a model 'includes LoggableActivity::Hooks' tags for translations are generated.
4
+ # Example:
5
+ # class User < ApplicationRecord
6
+ # include LoggableActivity::Hooks
7
+ # end
8
+ # This will make the following tags for translations available:
9
+ # - loggable_activity.user.create
10
+ # - loggable_activity.user.show
11
+ # - loggable_activity.user.update
12
+ # - loggable_activity.user.destroy
13
+ # - loggable_activity.user.login
14
+ # - loggable_activity.user.logout
15
+ #
16
+ en:
17
+ loggable_activity:
18
+ activity:
19
+ actor: Actor
20
+ action: Action
21
+ record: Record
22
+ created_at: Created at
23
+ deleted: "*** DELETED ***"
24
+ user:
25
+ update: A user was updated
26
+ create: A user was created
27
+ show: "A user was shown"
28
+ destroy: A user was deleted
29
+ sign_up: A user signed up
30
+ login: A user logged in
31
+ logout: A user logged out
32
+
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This configuration file is for setting up the LoggableActivity gem in your Rails application.
4
+
5
+ # Specify the name of the model that represents the actor performing the activities.
6
+ # This should be a string that matches the class name of the model.
7
+ # Example: If your user model is named "User", set it to 'User'.
8
+ LoggableActivity.actor_model_name = 'User'
9
+
10
+ # Specify the attribute from which to fetch the actor's name.
11
+ # This should be eighter a string representing the attribute name of the actor model
12
+ # or a method that returns the actor's name.
13
+ # Example: If you want to use the user's email as their name, set it to 'email'.
14
+ LoggableActivity.fetch_actor_name_from = 'email'
15
+
16
+ # Specify the path to the configuration file for LoggableActivity.
17
+ # This file should be a YAML file that contains the necessary configuration for logging activities.
18
+ # The path is set relative to the Rails root directory.
19
+ # Example: The default configuration file path is 'config/loggable_activity.yaml'.
20
+ LoggableActivity.config_file_path = Rails.root.join('config/loggable_activity.yaml')
21
+
22
+ # Specify whether the sanitazion should be performed by a task or not
23
+ # If set to 'false' the sanitization is performed immediately.
24
+ # If set to 'true' the data is inaccessible, but can be restored.
25
+ # If set to 'true' you have to permanently delete
26
+ # the data by calling 'LoggableActivity::Sanitizer.run' from a task.
27
+ LoggableActivity.task_for_sanitization = false