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 Customer
97 TrustLevel.register do |manual:, plan_name:, **|
98 if manual && manual != "Customer"
99 Sentry.capture_message("Unknown TrustLevel: #{manual}")
100 end
101
102 new(plan_name)
103 end
104
105 EXPENSIVE_ROUTE = {
106 "usd_beta_unlimited-v20210223" => 0.9,
107 "cad_beta_unlimited-v20210223" => 1.1
108 }.freeze
109
110 def initialize(plan_name)
111 @max_rate = EXPENSIVE_ROUTE.fetch(plan_name, 0.1)
112 end
113
114 def support_call?(rate, concurrency)
115 rate <= @max_rate && concurrency < 4
116 end
117
118 def send_message?(messages_today)
119 messages_today < 500
120 end
121
122 def credit_card_transaction?(amount, declines)
123 amount <= 100 && declines <= 2
124 end
125
126 def to_s
127 "Customer"
128 end
129 end
130end