trust_level.rb

  1# frozen_string_literal: true
  2
  3require "delegate"
  4
  5module TrustLevel
  6	def self.for(plan_name:, settled_amount: 0, manual: nil)
  7		@levels.each do |level|
  8			tl = level.call(
  9				plan_name: plan_name,
 10				settled_amount: settled_amount,
 11				manual: manual
 12			)
 13			return manual ? Manual.new(tl) : tl if tl
 14		end
 15
 16		raise "No TrustLevel matched"
 17	end
 18
 19	def self.register(&maybe_mk)
 20		@levels ||= []
 21		@levels << maybe_mk
 22	end
 23
 24	class Manual < SimpleDelegator
 25		def to_s
 26			"Manual(#{super})"
 27		end
 28	end
 29
 30	class Tomb
 31		TrustLevel.register do |manual:, **|
 32			new if manual == "Tomb"
 33		end
 34
 35		def support_call?(*)
 36			false
 37		end
 38
 39		def send_message?(*)
 40			false
 41		end
 42
 43		def to_s
 44			"Tomb"
 45		end
 46	end
 47
 48	class Basement
 49		TrustLevel.register do |manual:, settled_amount:, **|
 50			new if manual == "Basement" || (!manual && settled_amount < 10)
 51		end
 52
 53		def support_call?(rate, concurrency)
 54			rate <= 0.02 && concurrency < 1
 55		end
 56
 57		def send_message?(messages_today)
 58			messages_today < 200
 59		end
 60
 61		def to_s
 62			"Basement"
 63		end
 64	end
 65
 66	class Paragon
 67		TrustLevel.register do |manual:, settled_amount:, **|
 68			new if manual == "Paragon" || (!manual && settled_amount > 60)
 69		end
 70
 71		def support_call?(_, concurrency)
 72			concurrency < 10
 73		end
 74
 75		def send_message?(messages_today)
 76			messages_today < 700
 77		end
 78
 79		def to_s
 80			"Paragon"
 81		end
 82	end
 83
 84	class Customer
 85		TrustLevel.register do |manual:, plan_name:, **|
 86			if manual && manual != "Customer"
 87				Sentry.capture_message("Unknown TrustLevel: #{manual}")
 88			end
 89
 90			new(plan_name)
 91		end
 92
 93		EXPENSIVE_ROUTE = {
 94			"usd_beta_unlimited-v20210223" => 0.9,
 95			"cad_beta_unlimited-v20210223" => 1.1
 96		}.freeze
 97
 98		def initialize(plan_name)
 99			@max_rate = EXPENSIVE_ROUTE.fetch(plan_name, 0.1)
100		end
101
102		def support_call?(rate, concurrency)
103			rate <= @max_rate && concurrency < 4
104		end
105
106		def send_message?(messages_today)
107			messages_today < 500
108		end
109
110		def to_s
111			"Customer"
112		end
113	end
114end