Module: ForestAdminAgent::AuditTrail::Recording
- Included in:
- ActionCapture, Capture, Snapshots
- Defined in:
- lib/forest_admin_agent/audit_trail/recording.rb
Overview
Shared by the two capture layers: Capture for the changes Forest writes, ActionCapture for the smart actions it runs. Holds the write protocol's vocabulary and its failure policy.
Constant Summary collapse
- REDACTED =
'[redacted]'.freeze
- PENDING =
A row is inserted before the write and confirmed after it. One left PENDING means the write may or may not have landed — that residue is evidence, and it is the point.
'pending'.freeze
- DONE =
'done'.freeze
- IDENTITY =
{ user_id: :id, user_first_name: :first_name, user_last_name: :last_name, user_email: :email }.freeze
Instance Method Summary collapse
-
#audit_safely ⇒ Object
Everything after the pending insert is best-effort: by then the write has happened, so raising would report a failure for an operation that succeeded (and invite a retry that duplicates it).
-
#correlation_key_for(caller) ⇒ Object
Same id for every change made within one request — set on the caller by the agent (see CallerParser), mirroring the Node agent's caller.requestId.
-
#identity_of(caller) ⇒ Object
Denormalised at write time, so the row says who acted then rather than whoever holds that id today.
- #now ⇒ Object
- #redact(values, redacted_fields) ⇒ Object
Instance Method Details
#audit_safely ⇒ Object
Everything after the pending insert is best-effort: by then the write has happened, so raising would
report a failure for an operation that succeeded (and invite a retry that duplicates it). Losing the
row is the lesser evil, so it is logged and dropped. Only the pending insert itself can refuse an
operation, and only under critical: true — see ForestAdminAgent::AuditTrail.critical?.
49 50 51 52 53 54 |
# File 'lib/forest_admin_agent/audit_trail/recording.rb', line 49 def audit_safely yield rescue StandardError => e AuditTrail.log_failure(e) nil end |
#correlation_key_for(caller) ⇒ Object
Same id for every change made within one request — set on the caller by the agent (see CallerParser), mirroring the Node agent's caller.requestId.
nil when the caller carries none, which is what a write outside any request looks like. Inventing one would group the row into a request of its own, indistinguishable from a genuine single-row request.
29 30 31 |
# File 'lib/forest_admin_agent/audit_trail/recording.rb', line 29 def correlation_key_for(caller) caller.respond_to?(:request_id) ? caller.request_id : nil end |
#identity_of(caller) ⇒ Object
Denormalised at write time, so the row says who acted then rather than whoever holds that id today.
Read defensively: a caller built by another code path need not carry a full identity, and a
NoMethodError here would refuse the write outright under critical: true.
20 21 22 |
# File 'lib/forest_admin_agent/audit_trail/recording.rb', line 20 def identity_of(caller) IDENTITY.transform_values { |reader| caller.respond_to?(reader) ? caller.public_send(reader) : nil } end |
#now ⇒ Object
41 42 43 |
# File 'lib/forest_admin_agent/audit_trail/recording.rb', line 41 def now Time.now.utc.iso8601(3) end |
#redact(values, redacted_fields) ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/forest_admin_agent/audit_trail/recording.rb', line 33 def redact(values, redacted_fields) return values if redacted_fields.empty? values.each_with_object({}) do |(field, value), result| result[field] = redacted_fields.include?(field) ? REDACTED : value end end |