Module: LcpRuby::Auditing::AuditWriter

Defined in:
lib/lcp_ruby/auditing/audit_writer.rb

Constant Summary collapse

EXCLUDED_FIELDS =

Fields always excluded from audit diffs

%w[id created_at updated_at].freeze

Class Method Summary collapse

Class Method Details

.clear_cache!Object

Clear cached field mapping (called from LcpRuby.reset!)



253
254
255
# File 'lib/lcp_ruby/auditing/audit_writer.rb', line 253

def self.clear_cache!
  @field_mapping = nil
end

.compute_all_changes(action, record, options, model_definition) ⇒ Hash

Computes all changes for the given action, applying filters and expansions. Public for custom audit writers that need to recompute changes.

Returns:

  • (Hash)

    field-level diffs



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/lcp_ruby/auditing/audit_writer.rb', line 43

def compute_all_changes(action, record, options, model_definition)
  changes = compute_scalar_changes(action, record)
  changes = filter_fields(changes, options, model_definition)

  # Expand custom_data into cf: prefixed keys
  if options.fetch("expand_custom_fields", true) && changes.key?("custom_data")
    expand_custom_data!(changes)
  end

  # Expand JSON fields into dot-path diffs
  Array(options["expand_json_fields"]).each do |field_name|
    expand_json_field!(changes, field_name) if changes.key?(field_name)
  end

  # Aggregate nested association changes
  if options.fetch("track_associations", true)
    nested_changes = compute_nested_changes(record, model_definition)
    changes.merge!(nested_changes)
  end

  changes
end

.log(action:, record:, options:, model_definition:) ⇒ Object

Main entry point. Computes diffs and writes an audit log record.

Parameters:

  • action (Symbol)

    :create, :update, :destroy, :discard, :undiscard

  • record (ActiveRecord::Base)

    the changed record

  • options (Hash)

    auditing options from model definition

  • model_definition (Metadata::ModelDefinition)

    the model’s metadata



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/lcp_ruby/auditing/audit_writer.rb', line 14

def log(action:, record:, options:, model_definition:)
  # Delegate to custom writer if configured
  custom_writer = LcpRuby.configuration.audit_writer
  if custom_writer
    user = LcpRuby::Current.user
    changes = compute_all_changes(action, record, options, model_definition)
    return custom_writer.log(
      action: action,
      record: record,
      changes: changes,
      user: user,
      metadata: 
    )
  end

  return unless Registry.available?

  changes = compute_all_changes(action, record, options, model_definition)

  # Skip empty updates (no tracked fields changed)
  return if action == :update && changes.empty?

  write_audit_record(action, record, changes, model_definition)
end