Class: ApprovalEngine::ApprovalExposure

Inherits:
Object
  • Object
show all
Defined in:
lib/approval_engine/approval_exposure.rb

Overview

The anti-corruption layer. Collects the explicitly whitelisted attributes a host model is willing to expose to the dynamic rules engine, and produces a flat, string-keyed payload from them.

The rules engine only ever sees what was declared here — never the raw model — so a SaaS admin’s JSON Logic can never reach into unsafe internals.

exposes_for_approval do
  attribute :amount, type: :decimal
  attribute :department, type: :string, source: ->(invoice) { invoice.department.name }
  attribute :is_high_risk, type: :boolean, source: :requires_manual_audit?
end

Defined Under Namespace

Classes: Attribute

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeApprovalExposure

Returns a new instance of ApprovalExposure.



32
33
34
# File 'lib/approval_engine/approval_exposure.rb', line 32

def initialize
  @attributes = {}
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



30
31
32
# File 'lib/approval_engine/approval_exposure.rb', line 30

def attributes
  @attributes
end

Instance Method Details

#attribute(name, type: :string, source: nil) ⇒ Object



43
44
45
# File 'lib/approval_engine/approval_exposure.rb', line 43

def attribute(name, type: :string, source: nil)
  @attributes[name.to_s] = Attribute.new(name: name, type: type, source: source)
end

#initialize_dup(other) ⇒ Object

Keep dup’d exposures independent so per-class definitions never leak into one another (class_attribute inheritance relies on this).



38
39
40
41
# File 'lib/approval_engine/approval_exposure.rb', line 38

def initialize_dup(other)
  super
  @attributes = other.attributes.dup
end

#serialize(record) ⇒ Object

The flat payload handed to the JSON Logic evaluator.



48
49
50
# File 'lib/approval_engine/approval_exposure.rb', line 48

def serialize(record)
  @attributes.transform_values { |attr| coerce(attr.value_for(record), attr.type) }
end