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 credit_card_transaction?(*)
 44			false
 45		end
 46
 47		def to_s
 48			"Tomb"
 49		end
 50	end
 51
 52	class Basement
 53		TrustLevel.register do |manual:, settled_amount:, **|
 54			new if manual == "Basement" || (!manual && settled_amount < 10)
 55		end
 56
 57		def support_call?(rate, concurrency)
 58			rate <= 0.02 && concurrency < 1
 59		end
 60
 61		def send_message?(messages_today)
 62			messages_today < 200
 63		end
 64
 65		def credit_card_transaction?(amount, declines)
 66			amount <= 35 && declines <= 2
 67		end
 68
 69		def to_s
 70			"Basement"
 71		end
 72	end
 73
 74	class Paragon
 75		TrustLevel.register do |manual:, settled_amount:, **|
 76			new if manual == "Paragon" || (!manual && settled_amount > 60)
 77		end
 78
 79		def support_call?(_, concurrency)
 80			concurrency < 10
 81		end
 82
 83		def send_message?(messages_today)
 84			messages_today < 700
 85		end
 86
 87		def credit_card_transaction?(amount, declines)
 88			amount <= 500 && declines <= 3
 89		end
 90
 91		def to_s
 92			"Paragon"
 93		end
 94	end
 95
 96	class Olympias
 97		TrustLevel.register do |manual:, **|
 98			new if manual == "Olympias"
 99		end
100
101		def support_call?(*)
102			true
103		end
104
105		def send_message?(*)
106			true
107		end
108
109		def credit_card_transaction?(*)
110			true
111		end
112
113		def to_s
114			"Olympias"
115		end
116	end
117
118	class Customer
119		TrustLevel.register do |manual:, plan_name:, **|
120			if manual && manual != "Customer"
121				Sentry.capture_message("Unknown TrustLevel: #{manual}")
122			end
123
124			new(plan_name)
125		end
126
127		EXPENSIVE_ROUTE = {
128			"usd_beta_unlimited-v20210223" => 0.9,
129			"cad_beta_unlimited-v20210223" => 1.1
130		}.freeze
131
132		def initialize(plan_name)
133			@max_rate = EXPENSIVE_ROUTE.fetch(plan_name, 0.1)
134		end
135
136		def support_call?(rate, concurrency)
137			rate <= @max_rate && concurrency < 4
138		end
139
140		def send_message?(messages_today)
141			messages_today < 500
142		end
143
144		def credit_card_transaction?(amount, declines)
145			amount <= 100 && declines <= 2
146		end
147
148		def to_s
149			"Customer"
150		end
151	end
152end