Class: UsageCredits::Configuration
- Inherits:
-
Object
- Object
- UsageCredits::Configuration
- 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
-
#additional_categories ⇒ Object
Custom transaction categories that extend the default set.
-
#allow_negative_balance ⇒ Object
Low balance =========================================.
-
#credit_formatter ⇒ Object
readonly
Returns the value of attribute credit_formatter.
-
#credit_packs ⇒ Object
readonly
Stores all the things users can buy or subscribe to.
-
#credit_subscription_plans ⇒ Object
readonly
Returns the value of attribute credit_subscription_plans.
-
#default_currency ⇒ Object
Basic Settings =========================================.
-
#fulfillment_grace_period ⇒ Object
Returns the value of attribute fulfillment_grace_period.
-
#low_balance_callback ⇒ Object
readonly
Returns the value of attribute low_balance_callback.
-
#low_balance_threshold ⇒ Object
Returns the value of attribute low_balance_threshold.
-
#min_fulfillment_period ⇒ Object
Minimum allowed fulfillment period for subscription plans.
-
#on_balance_depleted_callback ⇒ Object
readonly
Lifecycle Callbacks =========================================.
-
#on_credit_pack_purchased_callback ⇒ Object
readonly
Lifecycle Callbacks =========================================.
-
#on_credits_added_callback ⇒ Object
readonly
Lifecycle Callbacks =========================================.
-
#on_credits_deducted_callback ⇒ Object
readonly
Lifecycle Callbacks =========================================.
-
#on_insufficient_credits_callback ⇒ Object
readonly
Lifecycle Callbacks =========================================.
-
#on_low_balance_reached_callback ⇒ Object
readonly
Lifecycle Callbacks =========================================.
-
#on_subscription_credits_awarded_callback ⇒ Object
readonly
Lifecycle Callbacks =========================================.
-
#operations ⇒ Object
readonly
Stores all the things users can do with credits.
-
#rounding_strategy ⇒ Object
Returns the value of attribute rounding_strategy.
Instance Method Summary collapse
-
#credit_pack(name, &block) ⇒ Object
Define a one-time purchase credit pack.
-
#find_subscription_plan_by_processor_id(processor_id) ⇒ CreditSubscriptionPlan?
Find a subscription plan by its processor-specific ID Works with both single-price and multi-period plans.
-
#format_credits(&block) ⇒ Object
Set how credits are displayed in the UI.
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
-
#on_balance_depleted(&block) ⇒ Object
Called when balance reaches exactly zero.
-
#on_credit_pack_purchased(&block) ⇒ Object
Called after a credit pack is purchased.
-
#on_credits_added(&block) ⇒ Object
Called after credits are added to a wallet.
-
#on_credits_deducted(&block) ⇒ Object
Called after credits are deducted from a wallet.
-
#on_insufficient_credits(&block) ⇒ Object
Called when an operation fails due to insufficient credits.
-
#on_low_balance(&block) ⇒ Object
BACKWARD COMPATIBILITY: Legacy method that receives owner, not context Existing users' code: config.on_low_balance { |owner| ... }.
-
#on_low_balance_reached(&block) ⇒ Object
Called when balance crosses below the low_balance_threshold Receives CallbackContext with full event data.
-
#on_subscription_credits_awarded(&block) ⇒ Object
Called after subscription credits are awarded.
-
#operation(name, &block) ⇒ Object
Define a credit-consuming operation.
-
#subscription_plan(name, &block) ⇒ Object
Define a recurring subscription plan.
-
#validate! ⇒ Object
Ensure configuration is valid.
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/usage_credits/configuration.rb', line 63 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 fulfillment 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 # Minimum fulfillment period - prevents accidental 1-second refill loops in production @min_fulfillment_period = 1.day # Custom transaction categories (empty by default, apps can extend) @additional_categories = [] @allow_negative_balance = false @low_balance_threshold = nil @low_balance_callback = nil # Called when user hits low_balance_threshold # Lifecycle callbacks (all nil by default) @on_credits_added_callback = nil @on_credits_deducted_callback = nil @on_low_balance_reached_callback = nil @on_balance_depleted_callback = nil @on_insufficient_credits_callback = nil @on_subscription_credits_awarded_callback = nil @on_credit_pack_purchased_callback = nil end |
Instance Attribute Details
#additional_categories ⇒ Object
Custom transaction categories that extend the default set
34 35 36 |
# File 'lib/usage_credits/configuration.rb', line 34 def additional_categories @additional_categories end |
#allow_negative_balance ⇒ Object
=========================================
Low balance
45 46 47 |
# File 'lib/usage_credits/configuration.rb', line 45 def allow_negative_balance @allow_negative_balance end |
#credit_formatter ⇒ Object (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_packs ⇒ Object (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_plans ⇒ Object (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_currency ⇒ Object
=========================================
Basic Settings
25 26 27 |
# File 'lib/usage_credits/configuration.rb', line 25 def default_currency @default_currency end |
#fulfillment_grace_period ⇒ Object
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_callback ⇒ Object (readonly)
Returns the value of attribute low_balance_callback.
49 50 51 |
# File 'lib/usage_credits/configuration.rb', line 49 def low_balance_callback @low_balance_callback end |
#low_balance_threshold ⇒ Object
Returns the value of attribute low_balance_threshold.
47 48 49 |
# File 'lib/usage_credits/configuration.rb', line 47 def low_balance_threshold @low_balance_threshold end |
#min_fulfillment_period ⇒ Object
Minimum allowed fulfillment period for subscription plans. Defaults to 1.day to prevent accidental 1-second refill loops in production. Can be set to shorter periods (e.g., 2.seconds) in development/test for faster iteration.
39 40 41 |
# File 'lib/usage_credits/configuration.rb', line 39 def min_fulfillment_period @min_fulfillment_period end |
#on_balance_depleted_callback ⇒ Object (readonly)
=========================================
Lifecycle Callbacks
55 56 57 |
# File 'lib/usage_credits/configuration.rb', line 55 def on_balance_depleted_callback @on_balance_depleted_callback end |
#on_credit_pack_purchased_callback ⇒ Object (readonly)
=========================================
Lifecycle Callbacks
55 56 57 |
# File 'lib/usage_credits/configuration.rb', line 55 def on_credit_pack_purchased_callback @on_credit_pack_purchased_callback end |
#on_credits_added_callback ⇒ Object (readonly)
=========================================
Lifecycle Callbacks
55 56 57 |
# File 'lib/usage_credits/configuration.rb', line 55 def on_credits_added_callback @on_credits_added_callback end |
#on_credits_deducted_callback ⇒ Object (readonly)
=========================================
Lifecycle Callbacks
55 56 57 |
# File 'lib/usage_credits/configuration.rb', line 55 def on_credits_deducted_callback @on_credits_deducted_callback end |
#on_insufficient_credits_callback ⇒ Object (readonly)
=========================================
Lifecycle Callbacks
55 56 57 |
# File 'lib/usage_credits/configuration.rb', line 55 def on_insufficient_credits_callback @on_insufficient_credits_callback end |
#on_low_balance_reached_callback ⇒ Object (readonly)
=========================================
Lifecycle Callbacks
55 56 57 |
# File 'lib/usage_credits/configuration.rb', line 55 def on_low_balance_reached_callback @on_low_balance_reached_callback end |
#on_subscription_credits_awarded_callback ⇒ Object (readonly)
=========================================
Lifecycle Callbacks
55 56 57 |
# File 'lib/usage_credits/configuration.rb', line 55 def on_subscription_credits_awarded_callback @on_subscription_credits_awarded_callback end |
#operations ⇒ Object (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_strategy ⇒ Object
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
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/usage_credits/configuration.rb', line 117 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) ⇒ CreditSubscriptionPlan?
Find a subscription plan by its processor-specific ID Works with both single-price and multi-period plans
148 149 150 151 152 |
# File 'lib/usage_credits/configuration.rb', line 148 def find_subscription_plan_by_processor_id(processor_id) @credit_subscription_plans.values.find do |plan| plan.matches_processor_id?(processor_id) end end |
#format_credits(&block) ⇒ Object
Set how credits are displayed in the UI
227 228 229 |
# File 'lib/usage_credits/configuration.rb', line 227 def format_credits(&block) @credit_formatter = block end |
#on_balance_depleted(&block) ⇒ Object
Called when balance reaches exactly zero
253 254 255 |
# File 'lib/usage_credits/configuration.rb', line 253 def on_balance_depleted(&block) @on_balance_depleted_callback = block end |
#on_credit_pack_purchased(&block) ⇒ Object
Called after a credit pack is purchased
268 269 270 |
# File 'lib/usage_credits/configuration.rb', line 268 def on_credit_pack_purchased(&block) @on_credit_pack_purchased_callback = block end |
#on_credits_added(&block) ⇒ Object
Called after credits are added to a wallet
237 238 239 |
# File 'lib/usage_credits/configuration.rb', line 237 def on_credits_added(&block) @on_credits_added_callback = block end |
#on_credits_deducted(&block) ⇒ Object
Called after credits are deducted from a wallet
242 243 244 |
# File 'lib/usage_credits/configuration.rb', line 242 def on_credits_deducted(&block) @on_credits_deducted_callback = block end |
#on_insufficient_credits(&block) ⇒ Object
Called when an operation fails due to insufficient credits
258 259 260 |
# File 'lib/usage_credits/configuration.rb', line 258 def on_insufficient_credits(&block) @on_insufficient_credits_callback = block end |
#on_low_balance(&block) ⇒ Object
BACKWARD COMPATIBILITY: Legacy method that receives owner, not context Existing users' code: config.on_low_balance { |owner| ... }
274 275 276 277 278 279 280 |
# File 'lib/usage_credits/configuration.rb', line 274 def on_low_balance(&block) raise ArgumentError, "Block is required for low balance callback" unless block_given? # Store legacy callback as before (for backward compat with direct calls) @low_balance_callback = block # Also create a wrapper for new callback system that extracts owner from context @on_low_balance_reached_callback = ->(ctx) { block.call(ctx.owner) } end |
#on_low_balance_reached(&block) ⇒ Object
Called when balance crosses below the low_balance_threshold Receives CallbackContext with full event data
248 249 250 |
# File 'lib/usage_credits/configuration.rb', line 248 def on_low_balance_reached(&block) @on_low_balance_reached_callback = block end |
#on_subscription_credits_awarded(&block) ⇒ Object
Called after subscription credits are awarded
263 264 265 |
# File 'lib/usage_credits/configuration.rb', line 263 def on_subscription_credits_awarded(&block) @on_subscription_credits_awarded_callback = block end |
#operation(name, &block) ⇒ Object
Define a credit-consuming operation
108 109 110 111 112 113 114 |
# File 'lib/usage_credits/configuration.rb', line 108 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
129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/usage_credits/configuration.rb', line 129 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! # Warn if fulfillment period is shorter than grace period (grace will be auto-capped) warn_if_grace_period_exceeds_fulfillment(plan) @credit_subscription_plans[name] = plan end |
#validate! ⇒ Object
Ensure configuration is valid
287 288 289 290 291 292 |
# File 'lib/usage_credits/configuration.rb', line 287 def validate! validate_currency! validate_threshold! validate_rounding_strategy! true end |