Class: UsageCredits::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/usage_credits/configuration.rb

Overview

Configuration for the UsageCredits gem. This is the single source of truth for all settings. This is what turns what’s defined in the initializer DSL into actual objects we can use and operate with.

Constant Summary collapse

VALID_ROUNDING_STRATEGIES =
[:ceil, :floor, :round].freeze
VALID_CURRENCIES =
[:usd, :eur, :gbp, :sgd, :chf].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/usage_credits/configuration.rb', line 43

def initialize
  # Initialize empty data stores
  @operations = {}                  # Credit-consuming operations (e.g., "send_email: 1 credit")
  @credit_packs = {}                # One-time purchases (e.g., "100 credits for $49")
  @credit_subscription_plans = {}   # Recurring plans (e.g., "1000 credits/month for $99")

  # Set sensible defaults
  @default_currency = :usd
  @rounding_strategy = :ceil  # Always round up to ensure we never undercharge
  @credit_formatter = ->(amount) { "#{amount} credits" }  # How to format credit amounts in the UI

  # Grace period for credit expiration after fulfillment period ends.
  # For how long will expiring credits "overlap" the following fulfillment period.
  # This ensures smooth transition between fulfillment periods.
  # For this amount of time, old, already expired credits will be erroneously counted as available in the user's balance.
  # Keep it short enough that users don't notice they have the last period's credits still available, but
  # long enough that there's a smooth transition and users never get zero credits in between fullfillment periods
  # A good setting is to match the frequency of your UsageCredits::FulfillmentJob runs
  @fulfillment_grace_period = 5.minutes # If you run your fulfillment job every 5 minutes, this should be enough

  @allow_negative_balance = false
  @low_balance_threshold = nil
  @low_balance_callback = nil # Called when user hits low_balance_threshold
end

Instance Attribute Details

#allow_negative_balanceObject

Low balance



37
38
39
# File 'lib/usage_credits/configuration.rb', line 37

def allow_negative_balance
  @allow_negative_balance
end

#credit_formatterObject (readonly)

Returns the value of attribute credit_formatter.



29
30
31
# File 'lib/usage_credits/configuration.rb', line 29

def credit_formatter
  @credit_formatter
end

#credit_packsObject (readonly)

Stores all the things users can buy or subscribe to



18
19
20
# File 'lib/usage_credits/configuration.rb', line 18

def credit_packs
  @credit_packs
end

#credit_subscription_plansObject (readonly)

Returns the value of attribute credit_subscription_plans.



19
20
21
# File 'lib/usage_credits/configuration.rb', line 19

def credit_subscription_plans
  @credit_subscription_plans
end

#default_currencyObject

Basic Settings



25
26
27
# File 'lib/usage_credits/configuration.rb', line 25

def default_currency
  @default_currency
end

#fulfillment_grace_periodObject

Returns the value of attribute fulfillment_grace_period.



31
32
33
# File 'lib/usage_credits/configuration.rb', line 31

def fulfillment_grace_period
  @fulfillment_grace_period
end

#low_balance_callbackObject (readonly)

Returns the value of attribute low_balance_callback.



41
42
43
# File 'lib/usage_credits/configuration.rb', line 41

def low_balance_callback
  @low_balance_callback
end

#low_balance_thresholdObject

Returns the value of attribute low_balance_threshold.



39
40
41
# File 'lib/usage_credits/configuration.rb', line 39

def low_balance_threshold
  @low_balance_threshold
end

#operationsObject (readonly)

Stores all the things users can do with credits



15
16
17
# File 'lib/usage_credits/configuration.rb', line 15

def operations
  @operations
end

#rounding_strategyObject

Returns the value of attribute rounding_strategy.



27
28
29
# File 'lib/usage_credits/configuration.rb', line 27

def rounding_strategy
  @rounding_strategy
end

Instance Method Details

#credit_pack(name, &block) ⇒ Object

Define a one-time purchase credit pack

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
90
91
# File 'lib/usage_credits/configuration.rb', line 82

def credit_pack(name, &block)
  raise ArgumentError, "Block is required for credit pack definition" unless block_given?
  raise ArgumentError, "Credit pack name can't be blank" if name.blank?

  name = name.to_sym
  pack = CreditPack.new(name)
  pack.instance_eval(&block)
  pack.validate!
  @credit_packs[name] = pack
end

#find_subscription_plan_by_processor_id(processor_id) ⇒ Object

Find a subscription plan by its processor-specific ID



106
107
108
109
110
# File 'lib/usage_credits/configuration.rb', line 106

def find_subscription_plan_by_processor_id(processor_id)
  @credit_subscription_plans.values.find do |plan|
    plan.processor_plan_ids.values.include?(processor_id)
  end
end

#format_credits(&block) ⇒ Object

Set how credits are displayed in the UI



161
162
163
# File 'lib/usage_credits/configuration.rb', line 161

def format_credits(&block)
  @credit_formatter = block
end

#on_low_balance(&block) ⇒ Object

Set what happens when credits are low

Raises:

  • (ArgumentError)


166
167
168
169
# File 'lib/usage_credits/configuration.rb', line 166

def on_low_balance(&block)
  raise ArgumentError, "Block is required for low balance callback" unless block_given?
  @low_balance_callback = block
end

#operation(name, &block) ⇒ Object

Define a credit-consuming operation

Raises:

  • (ArgumentError)


73
74
75
76
77
78
79
# File 'lib/usage_credits/configuration.rb', line 73

def operation(name, &block)
  raise ArgumentError, "Block is required for operation definition" unless block_given?
  operation = Operation.new(name)
  operation.instance_eval(&block)
  @operations[name.to_sym] = operation
  operation
end

#subscription_plan(name, &block) ⇒ Object

Define a recurring subscription plan

Raises:

  • (ArgumentError)


94
95
96
97
98
99
100
101
102
103
# File 'lib/usage_credits/configuration.rb', line 94

def subscription_plan(name, &block)
  raise ArgumentError, "Block is required for subscription plan definition" unless block_given?
  raise ArgumentError, "Subscription plan name can't be blank" if name.blank?

  name = name.to_sym
  plan = CreditSubscriptionPlan.new(name)
  plan.instance_eval(&block)
  plan.validate!
  @credit_subscription_plans[name] = plan
end

#validate!Object

Ensure configuration is valid



176
177
178
179
180
181
# File 'lib/usage_credits/configuration.rb', line 176

def validate!
  validate_currency!
  validate_threshold!
  validate_rounding_strategy!
  true
end