Class: PricingPlans::LimitChecker
- Inherits:
-
Object
- Object
- PricingPlans::LimitChecker
- Defined in:
- lib/pricing_plans/limit_checker.rb
Class Method Summary collapse
-
.after_limit_action(plan_owner, limit_key) ⇒ Object
Keep short helpers undocumented; public API is plan_limit_* aliases.
- .current_usage_for(plan_owner, limit_key, limit_config = nil) ⇒ Object
- .limit_amount(plan_owner, limit_key) ⇒ Object
- .percent_used(plan_owner, limit_key) ⇒ Object
- .plan_limit_percent_used(plan_owner, limit_key) ⇒ Object
-
.plan_limit_remaining(plan_owner, limit_key) ⇒ Object
English-y aliases used widely across helpers/tests.
- .remaining(plan_owner, limit_key) ⇒ Object
- .should_warn?(plan_owner, limit_key) ⇒ Boolean
- .warning_thresholds(plan_owner, limit_key) ⇒ Object
- .within_limit?(plan_owner, limit_key, by: 1) ⇒ Boolean
Class Method Details
.after_limit_action(plan_owner, limit_key) ⇒ Object
Keep short helpers undocumented; public API is plan_limit_* aliases
48 49 50 51 52 53 54 |
# File 'lib/pricing_plans/limit_checker.rb', line 48 def after_limit_action(plan_owner, limit_key) plan = PlanResolver.effective_plan_for(plan_owner) limit_config = plan&.limit_for(limit_key) return :block_usage unless limit_config limit_config[:after_limit] end |
.current_usage_for(plan_owner, limit_key, limit_config = nil) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/pricing_plans/limit_checker.rb', line 65 def current_usage_for(plan_owner, limit_key, limit_config = nil) limit_config ||= begin plan = PlanResolver.effective_plan_for(plan_owner) plan&.limit_for(limit_key) end return 0 unless limit_config if limit_config[:per] # Per-period allowance - check usage table per_period_usage(plan_owner, limit_key) else # Persistent cap - count live objects persistent_usage(plan_owner, limit_key) end end |
.limit_amount(plan_owner, limit_key) ⇒ Object
56 57 58 59 60 61 62 63 |
# File 'lib/pricing_plans/limit_checker.rb', line 56 def limit_amount(plan_owner, limit_key) plan = PlanResolver.effective_plan_for(plan_owner) limit_config = plan&.limit_for(limit_key) # BREAKING CHANGE: Undefined limits now default to 0 (blocked) instead of :unlimited return 0 unless limit_config limit_config[:to] end |
.percent_used(plan_owner, limit_key) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/pricing_plans/limit_checker.rb', line 34 def percent_used(plan_owner, limit_key) plan = PlanResolver.effective_plan_for(plan_owner) limit_config = plan&.limit_for(limit_key) return 0.0 unless limit_config limit_amount = limit_config[:to] return 0.0 if limit_amount == :unlimited || limit_amount.zero? current_usage = current_usage_for(plan_owner, limit_key, limit_config) [(current_usage.to_f / limit_amount) * 100, 100.0].min end |
.plan_limit_percent_used(plan_owner, limit_key) ⇒ Object
11 12 13 |
# File 'lib/pricing_plans/limit_checker.rb', line 11 def plan_limit_percent_used(plan_owner, limit_key) percent_used(plan_owner, limit_key) end |
.plan_limit_remaining(plan_owner, limit_key) ⇒ Object
English-y aliases used widely across helpers/tests
7 8 9 |
# File 'lib/pricing_plans/limit_checker.rb', line 7 def plan_limit_remaining(plan_owner, limit_key) remaining(plan_owner, limit_key) end |
.remaining(plan_owner, limit_key) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/pricing_plans/limit_checker.rb', line 20 def remaining(plan_owner, limit_key) plan = PlanResolver.effective_plan_for(plan_owner) limit_config = plan&.limit_for(limit_key) # BREAKING CHANGE: Undefined limits now default to 0 (blocked) instead of :unlimited # This is secure-by-default: if a plan doesn't define a limit, access is blocked return 0 unless limit_config limit_amount = limit_config[:to] return :unlimited if limit_amount == :unlimited current_usage = current_usage_for(plan_owner, limit_key, limit_config) [0, limit_amount - current_usage].max end |
.should_warn?(plan_owner, limit_key) ⇒ Boolean
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/pricing_plans/limit_checker.rb', line 90 def should_warn?(plan_owner, limit_key) percent = percent_used(plan_owner, limit_key) thresholds = warning_thresholds(plan_owner, limit_key) # Find the highest threshold that has been crossed crossed_threshold = thresholds.select { |t| percent >= (t * 100) }.max return nil unless crossed_threshold # Check if we've already warned for this threshold state = enforcement_state(plan_owner, limit_key) last_threshold = state&.last_warning_threshold # Return the threshold if this is a new higher threshold, nil otherwise crossed_threshold > (last_threshold || 0) ? crossed_threshold : nil end |
.warning_thresholds(plan_owner, limit_key) ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/pricing_plans/limit_checker.rb', line 82 def warning_thresholds(plan_owner, limit_key) plan = PlanResolver.effective_plan_for(plan_owner) limit_config = plan&.limit_for(limit_key) return [] unless limit_config limit_config[:warn_at] || [] end |
.within_limit?(plan_owner, limit_key, by: 1) ⇒ Boolean
14 15 16 17 18 |
# File 'lib/pricing_plans/limit_checker.rb', line 14 def within_limit?(plan_owner, limit_key, by: 1) remaining_amount = remaining(plan_owner, limit_key) return true if remaining_amount == :unlimited remaining_amount >= by end |