Class: Insika::FunnelDeclaration

Inherits:
Object
  • Object
show all
Defined in:
lib/insika/funnel_declaration.rb

Overview

the parsed funnel declaration of ONE agent — the ONLY shape the engine accepts, shared by the fold, the doctor, the Studio and the freeze command. Pure value object: it never touches a store, and the engine never hard-codes a stage name (D1) — stages/primary/advance_on are the forge's vocabulary, carried as data.

parse returns nil on a malformed hash (D8: the fold skips that agent, the doctor explains the exact defect); parse! raises Insika::ValidationError naming the field. attribution_window is carried data, never computed (D4).

Constant Summary collapse

WINDOW_RE =
/\A\d+h\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash) ⇒ FunnelDeclaration

Returns a new instance of FunnelDeclaration.



28
29
30
31
32
33
34
35
36
37
# File 'lib/insika/funnel_declaration.rb', line 28

def initialize(hash)
  raise Insika::ValidationError, "funnel: declaration must be a Hash" unless hash.is_a?(Hash)

  h = hash.transform_keys(&:to_s)
  @stages = stages_of(h)
  @advance_on = advance_on_of(h, @stages)
  @primary = primary_of(h, @stages)
  @attribution_window = window_of(h)
  freeze
end

Instance Attribute Details

#advance_onObject (readonly)

Returns the value of attribute advance_on.



16
17
18
# File 'lib/insika/funnel_declaration.rb', line 16

def advance_on
  @advance_on
end

#attribution_windowObject (readonly)

Returns the value of attribute attribution_window.



16
17
18
# File 'lib/insika/funnel_declaration.rb', line 16

def attribution_window
  @attribution_window
end

#primaryObject (readonly)

Returns the value of attribute primary.



16
17
18
# File 'lib/insika/funnel_declaration.rb', line 16

def primary
  @primary
end

#stagesObject (readonly)

Returns the value of attribute stages.



16
17
18
# File 'lib/insika/funnel_declaration.rb', line 16

def stages
  @stages
end

Class Method Details

.parse(hash) ⇒ Object



18
19
20
21
22
# File 'lib/insika/funnel_declaration.rb', line 18

def self.parse(hash)
  new(hash)
rescue Insika::ValidationError
  nil
end

.parse!(hash) ⇒ Object



24
25
26
# File 'lib/insika/funnel_declaration.rb', line 24

def self.parse!(hash)
  new(hash)
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Value-object equality: two declarations parsed from equal input (symbol or string keys) are the same declaration.



53
54
55
56
57
# File 'lib/insika/funnel_declaration.rb', line 53

def ==(other)
  other.is_a?(FunnelDeclaration) &&
    @stages == other.stages && @advance_on == other.advance_on &&
    @primary == other.primary && @attribution_window == other.attribution_window
end

#first_stageObject

the first declared stage — the funnel's denominator.



46
# File 'lib/insika/funnel_declaration.rb', line 46

def first_stage = @stages.first

#hashObject



60
61
62
# File 'lib/insika/funnel_declaration.rb', line 60

def hash
  [@stages, @advance_on, @primary, @attribution_window].hash
end

#index_of(stage) ⇒ Object

position of a stage in the declared order. -> Integer | nil



40
41
42
43
# File 'lib/insika/funnel_declaration.rb', line 40

def index_of(stage)
  index = @stages.index(stage.to_s)
  index.nil? ? nil : index
end

#window_hoursObject

"72h" -> 72 (Integer). Always valid once parsed.



49
# File 'lib/insika/funnel_declaration.rb', line 49

def window_hours = @attribution_window.to_i