mongoid-auditor 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2aa7ebf81ba4781aef853bf48e5fa096de08e532df7744c0bb2de5084e9b9bfb
4
- data.tar.gz: 75f6100cf88e0490121e6758c08c690685136da4a0c7d96ab1f39055bccef9e7
3
+ metadata.gz: fea6c16c9d652abff899a1669fded9cdc31db182ae1db1c37da335ebc13a054d
4
+ data.tar.gz: bfd1d39c03525e9a76756a433f1d5f0e3966ad05f121cc32e5258a46f3ce6beb
5
5
  SHA512:
6
- metadata.gz: e92739869c96d293ed5a8faa1ec7089546a4a4975e5e645dad1cf3451d1722299a438619e4b3e6617b375f60248a92b77e9b0738b37419b797b634697f906f86
7
- data.tar.gz: ef29f674dd7d5a5a43ff289709f715e8b386131d405311cf0bd33818bcd3c9343dd204a0d87e3a52118341c0050d774656e167ea0b2c2dbccdca37d3252fc108
6
+ metadata.gz: 7757843e9cbed5b925b1d3b5f6669f9b29995994d7e36b3cfd04defca264851a3aea52a831fa5bb898f85481e5765401e5404cb831049b5a389026f00b2a0abc
7
+ data.tar.gz: cb208483c3e2fdd3f2b4c9dc3e6cdfc370a2a8fbad7cb2f3274dc13f34a5fb1229e3e19ebae821319353a409f947ae70861231ce7b2340a2c00f923a9c6372e9
data/CHANGELOG.md CHANGED
@@ -1,4 +1,3 @@
1
- ## [Unreleased]
2
1
 
3
2
  ## [0.1.0] - 2025-12-24
4
3
 
@@ -7,3 +6,16 @@
7
6
  ## [0.1.1] - 2025-12-25
8
7
  ### Fix
9
8
  - Avoided method name collision with Mongoid/ActiveModel by renaming auditor `errors` helper to `audit_errors`.
9
+
10
+ ## [0.1.2] - 2026-03-28
11
+ ### Fix
12
+ - Fixed `NoMethodError` when `configure` is never called
13
+ - Fixed ActiveJob key serialization breaking error audit entries
14
+ - Fixed `queue_name` config option being ignored
15
+ - Fixed event validation rejecting `perform`, `index`, and `show` events
16
+ - Fixed `error_summary` methods loading all records into memory
17
+ - Fixed `fallback_model_type` crash on nil controller name
18
+ - Fixed stale `today_time` memoization on long-lived objects
19
+
20
+ ### Changed
21
+ - Optimized indexes for better query coverage
data/README.md CHANGED
@@ -132,7 +132,7 @@ The `Mongoid::Auditor::AuditLog` model stores audit entries with the following a
132
132
  * `path` — Controller action or job name.
133
133
  * `model_type` — Class of the audited model (e.g., `Product`).
134
134
  * `model_id` — ID of the audited model.
135
- * `event` — `create`, `update`, `destroy`, or `error`.
135
+ * `event` — `create`, `update`, `destroy`, `error`, `perform`, `index`, or `show`.
136
136
  * `dirties` — Before/after attribute snapshots (hash with `attribute: [before_value, after_value]` format).
137
137
  * `sequence` — Incremental sequence number for ordering events within a request.
138
138
  * `error` — Contains class, message and backtrace of the error (when `has_error` is true).
@@ -157,7 +157,7 @@ The `Mongoid::Auditor::RequestContext` model stores context information for requ
157
157
  `RequestContext` allows the auditor to link audit logs to a specific request or background job, making it easier to
158
158
  trace changes and errors back to the original operation.
159
159
 
160
- **NOTE:** The `RequestContext` data is automatically deleted after 24 hours (via TTL index) and also cleaned up when jobs complete to prevent unbounded growth and minimize database usage. This ensures the audit system remains efficient and does not consume unnecessary space.
160
+ > `RequestContext` records auto-expire after 24 hours (TTL index) and are cleaned up on job completion.
161
161
  ---
162
162
 
163
163
  ### Mongoid::Auditor::Current
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support/core_ext/hash/indifferent_access'
4
+
3
5
  module Mongoid
4
6
  module Auditor
5
7
  class Audit
@@ -20,6 +22,7 @@ module Mongoid
20
22
  private
21
23
 
22
24
  def log_error(err, entry)
25
+ entry = entry.is_a?(Hash) ? entry.with_indifferent_access : {}
23
26
  ::Mongoid::Auditor::AuditLog.create!(
24
27
  request_id: entry[:request_id],
25
28
  actor: entry[:actor],
@@ -63,6 +63,8 @@ module Mongoid
63
63
  end
64
64
 
65
65
  def fallback_model_type(controller_name)
66
+ return 'UnresolvedController' if controller_name.nil?
67
+
66
68
  controller_name.split('/').last.singularize.camelize
67
69
  end
68
70
 
@@ -7,7 +7,7 @@ module Mongoid
7
7
 
8
8
  self.skip_audit = true
9
9
 
10
- queue_as :default
10
+ queue_as { ::Mongoid::Auditor.config.queue_name || :default }
11
11
 
12
12
  def perform(state, exception = nil, entry = nil)
13
13
  return unless config.enabled
@@ -26,17 +26,16 @@ module Mongoid
26
26
  field :model_error, type: Hash, default: nil
27
27
 
28
28
  # Indexes for performance
29
- index({ request_id: 1 })
29
+ index({ request_id: 1, sequence: 1 })
30
30
  index({ model_type: 1, model_id: 1 })
31
- index({ model_type: 1, model_id: 1, event: 1 })
31
+ index({ model_type: 1, event: 1, created_at: -1 })
32
32
  index({ actor: 1 })
33
- index({ has_error: 1, created_at: -1 })
33
+ index({ has_error: 1, event: 1, created_at: -1 })
34
34
  index({ created_at: -1 })
35
- index({ request_id: 1, sequence: 1 })
36
35
 
37
36
  # Validations
38
37
  validates :request_id, presence: true
39
- validates :event, presence: true, inclusion: { in: %w[create update destroy error] }
38
+ validates :event, presence: true, inclusion: { in: %w[create update destroy error perform index show] }
40
39
  validates :sequence, presence: true, numericality: { only_integer: true }
41
40
 
42
41
  def model
@@ -50,17 +50,30 @@ module Mongoid
50
50
  audit_errors.where(actor: actor_id)
51
51
  end
52
52
 
53
- # Quick summary: class names and counts
53
+ # Quick summary: class names and counts via MongoDB aggregation
54
54
  def error_summary
55
- audit_errors.group_by { |log| log.error&.dig('class') || 'Unknown' }.transform_values(&:count)
55
+ aggregate_error_summary(audit_errors)
56
56
  end
57
57
 
58
58
  def error_summary_today
59
- errors_today.group_by { |log| log.error&.dig('class') || 'Unknown' }.transform_values(&:count)
59
+ aggregate_error_summary(errors_today)
60
60
  end
61
61
 
62
62
  def error_summary_last(days)
63
- errors_last(days).group_by { |log| log.error&.dig('class') || 'Unknown' }.transform_values(&:count)
63
+ aggregate_error_summary(errors_last(days))
64
+ end
65
+
66
+ private
67
+
68
+ def aggregate_error_summary(scope)
69
+ scope.collection.aggregate(
70
+ scope.pipeline +
71
+ [
72
+ { '$group' => { '_id' => { '$ifNull' => ['$error.class', 'Unknown'] }, 'count' => { '$sum' => 1 } } }
73
+ ]
74
+ ).each_with_object({}) do |doc, result|
75
+ result[doc['_id']] = doc['count']
76
+ end
64
77
  end
65
78
  end
66
79
  end
@@ -46,7 +46,7 @@ module Mongoid
46
46
  end
47
47
 
48
48
  def today_time
49
- @today_time ||= Time.current.all_day
49
+ Time.current.all_day
50
50
  end
51
51
  end
52
52
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Mongoid
4
4
  module Auditor
5
- VERSION = '0.1.1'
5
+ VERSION = '0.1.2'
6
6
  end
7
7
  end
@@ -10,10 +10,11 @@ require 'mongoid/auditor/railtie' if defined?(Rails)
10
10
  module Mongoid
11
11
  module Auditor
12
12
  class << self
13
- attr_accessor :config
13
+ def config
14
+ @config ||= Configuration.new
15
+ end
14
16
 
15
17
  def configure
16
- self.config ||= Configuration.new
17
18
  yield(config)
18
19
  end
19
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-auditor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pralad Mishra
@@ -38,7 +38,7 @@ dependencies:
38
38
  version: '7.0'
39
39
  - - "<"
40
40
  - !ruby/object:Gem::Version
41
- version: 8.1.1
41
+ version: '8.2'
42
42
  type: :runtime
43
43
  prerelease: false
44
44
  version_requirements: !ruby/object:Gem::Requirement
@@ -48,7 +48,7 @@ dependencies:
48
48
  version: '7.0'
49
49
  - - "<"
50
50
  - !ruby/object:Gem::Version
51
- version: 8.1.1
51
+ version: '8.2'
52
52
  description: |2-
53
53
 
54
54
  Provides an easy way to track changes, creations, and errors across your Rails