Module: Hecks::Ports::Persistence::BindingPolicy

Defined in:
lib/hecks/ports/persistence/binding_policy.rb

Overview

Resolves one aggregate's persistence topology. An unmarked binding is authoritative; roles are deliberately opt-in so a second adapter can never silently become a read source.

Class Method Summary collapse

Class Method Details

.ambiguous_binding(domain, aggregate, authoritative) ⇒ Object



40
41
42
43
44
45
# File 'lib/hecks/ports/persistence/binding_policy.rb', line 40

def ambiguous_binding(domain, aggregate, authoritative)
  Runtime::WiringError.new(
    "#{domain}::#{aggregate.hecks_name} has #{authoritative.size} authoritative #{VERB} bindings. " \
    "Declare exactly one adapter without a role."
  )
end

.default_binding(aggregate) ⇒ Object



27
28
29
# File 'lib/hecks/ports/persistence/binding_policy.rb', line 27

def default_binding(aggregate)
  Bluebook::Bind.new(aggregate: aggregate.hecks_name, verb: VERB, adapter: DEFAULT_ADAPTER)
end

.missing_binding(domain, aggregate) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/hecks/ports/persistence/binding_policy.rb', line 31

def missing_binding(domain, aggregate)
  Runtime::WiringError.new(
    "#{domain}::#{aggregate.hecks_name} has no #{VERB} bind. #{domain} declares a " \
    "hecksagon, so its wiring is being decided explicitly and an aggregate " \
    "left out is a forgotten decision. Bind it, or say " \
    "#{aggregate.hecks_name}.#{VERB}(#{DEFAULT_ADAPTER.inspect}) to keep it in memory on purpose."
  )
end

.resolve(registry, domain, aggregate) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/hecks/ports/persistence/binding_policy.rb', line 13

def resolve(registry, domain, aggregate)
  hexagon = registry.hecksagon(domain)
  return default_binding(aggregate) unless hexagon

  bindings = hexagon.binds_for(aggregate.hecks_name, VERB)
  raise missing_binding(domain, aggregate) if bindings.empty?

  authoritative = bindings.select { |bind| bind.role.nil? || bind.role.empty? }
  raise ambiguous_binding(domain, aggregate, authoritative) unless authoritative.size == 1
  raise unsupported_roles(domain, aggregate, bindings - authoritative) unless (bindings - authoritative).empty?

  authoritative.first
end

.unsupported_roles(domain, aggregate, bindings) ⇒ Object



47
48
49
50
51
52
# File 'lib/hecks/ports/persistence/binding_policy.rb', line 47

def unsupported_roles(domain, aggregate, bindings)
  Runtime::WiringError.new(
    "#{domain}::#{aggregate.hecks_name} uses persistence role#{bindings.size == 1 ? '' : 's'} " \
    "#{bindings.map(&:role).map(&:inspect).join(', ')}. Only persisted_by is supported."
  )
end