Class: Hecks::Bluebook::PortOperation

Inherits:
Object
  • Object
show all
Includes:
Behaviour::PortOperation, IR
Defined in:
lib/hecks/bluebook/domain_port.rb

Overview

THE PRIMARY/DRIVING HALF OF HEXAGONAL ARCHITECTURE (Cockburn) — called BY an adapter living outside the bluebook entirely, never by the domain calling out. That is already Hecks.port (persistence, projection, extraction, loading) plus Ports::* : the secondary/ driven half, unchanged by this.

An operation carries no given/ensures/then_set — a port is the anti-corruption boundary that turns an external call into a fact in this domain's own vocabulary, not a second place business rules live. Those stay on whatever command a policy triggers in reaction to the event an operation emits.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Behaviour::PortOperation

#identity_attribute, #references

Methods included from Behaviour::Indexed

#attribute, #command, #index_attributes, #index_by_hecks_name, #query

Methods included from IR

extended, included

Constructor Details

#initialize(name:, attributes: [], emits: [], direction: :inbound, answers: nil, refuses: nil, to: nil) ⇒ PortOperation

TWO DIRECTIONS THROUGH ONE DOOR.

:inbound is what this class has always been — tells, spelled operation before it had a twin: an external fact arriving, turned into this domain's own event. It emits and that is all; there is no channel back to whoever called.

:outbound is asks — the domain wanting something from outside and having to live with either answer. It names BOTH: answers for what the adapter came back with, refuses for what it said instead. Naming only the happy one would put the failure somewhere the model cannot see, which is the whole reason a boundary is worth modelling.



36
37
38
39
40
41
42
43
44
45
# File 'lib/hecks/bluebook/domain_port.rb', line 36

def initialize(name:, attributes: [], emits: [], direction: :inbound, answers: nil, refuses: nil, to: nil)
  @hecks_name = name.to_s
  @attributes = attributes
  @emits      = emits
  @direction  = direction.to_sym
  @answers    = answers
  @refuses    = refuses
  @to         = to
  @attributes_by_name = attributes.to_h { |attribute| [attribute.name, attribute] }
end

Instance Attribute Details

#answersObject (readonly)

Returns the value of attribute answers.



22
23
24
# File 'lib/hecks/bluebook/domain_port.rb', line 22

def answers
  @answers
end

#attributesObject (readonly)

Returns the value of attribute attributes.



22
23
24
# File 'lib/hecks/bluebook/domain_port.rb', line 22

def attributes
  @attributes
end

#directionObject (readonly)

Returns the value of attribute direction.



22
23
24
# File 'lib/hecks/bluebook/domain_port.rb', line 22

def direction
  @direction
end

#emitsObject (readonly)

Returns the value of attribute emits.



22
23
24
# File 'lib/hecks/bluebook/domain_port.rb', line 22

def emits
  @emits
end

#hecks_nameObject (readonly)

Returns the value of attribute hecks_name.



22
23
24
# File 'lib/hecks/bluebook/domain_port.rb', line 22

def hecks_name
  @hecks_name
end

#refusesObject (readonly)

Returns the value of attribute refuses.



22
23
24
# File 'lib/hecks/bluebook/domain_port.rb', line 22

def refuses
  @refuses
end

#toObject (readonly)

Returns the value of attribute to.



22
23
24
# File 'lib/hecks/bluebook/domain_port.rb', line 22

def to
  @to
end

Instance Method Details

#inbound?Boolean

Returns:

  • (Boolean)


48
# File 'lib/hecks/bluebook/domain_port.rb', line 48

def inbound?  = @direction == :inbound

#outbound?Boolean

Returns:

  • (Boolean)


47
# File 'lib/hecks/bluebook/domain_port.rb', line 47

def outbound? = @direction == :outbound

#to_hObject

direction/answers/refuses are deliberately OUTSIDE emits_ir's declared shape and added here only for an outbound operation — an ordinary inbound one (tells, still spelled operation everywhere in the existing corpus) keeps the EXACT prior IR shape, byte for byte. Pizzas' PaymentGateway port is inbound-only and is checked against hecks-parse's own Rust output for byte-identity (parser_parity_spec.rb) — the Rust side has no notion of asks yet, so an unconditional new key here would break that parity for a domain that never asked for the feature. Only a chapter that actually declares asks (this extraction's own QualityControl ledger, not yet in any Rust-parity corpus) pays for it. to — SAME "deliberately outside emits_ir, merged in only when present" treatment as direction/answers/refuses just above, and for the identical reason: an operation still spelled the old way (reference_to inside the block, shadow-parsing only — see reference_to_impl's own comment) or one that simply hasn't migrated yet keeps the EXACT prior IR shape, byte for byte, instead of an unconditional new key breaking parser_parity_spec for every domain that never touched this.



75
76
77
78
79
80
# File 'lib/hecks/bluebook/domain_port.rb', line 75

def to_h
  shape = super
  shape = shape.merge(direction: @direction.to_s, answers: @answers, refuses: @refuses) unless inbound?
  shape = shape.merge(to: @to) if @to
  shape
end