Class: ApprovalEngine::Consensus

Inherits:
Object
  • Object
show all
Defined in:
app/models/approval_engine/consensus.rb

Overview

Value object for a layer’s consensus condition. It parses the declarative ‘approvals_required` spec and computes how many approvals a group of a given size needs:

:any       -> 1
:all       -> everyone in the group
:majority  -> more than half
"60%"      -> that proportion of the group (at least 1)
2          -> an exact count

Relative specs are resolved against the live group, so authors never have to know team sizes — “majority of whoever is on the team” just works, and adapts as members are added or drop out.

Constant Summary collapse

FORMAT =
/\A([1-9][0-9]*%?|any|all|majority)\z/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(spec) ⇒ Consensus

Returns a new instance of Consensus.



22
23
24
# File 'app/models/approval_engine/consensus.rb', line 22

def initialize(spec)
  @spec = spec.to_s
end

Class Method Details

.valid?(spec) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
# File 'app/models/approval_engine/consensus.rb', line 18

def self.valid?(spec)
  FORMAT.match?(spec.to_s)
end

Instance Method Details

#required(group_size) ⇒ Object

How many approvals are needed out of a group of ‘group_size`.



27
28
29
30
31
32
33
34
35
# File 'app/models/approval_engine/consensus.rb', line 27

def required(group_size)
  case @spec
  when "any"      then 1
  when "all"      then group_size
  when "majority" then (group_size / 2) + 1
  when /%\z/      then [ (group_size * @spec.to_i / 100.0).ceil, 1 ].max
  else @spec.to_i
  end
end