pricing_plans 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/settings.local.json +6 -7
- data/Appraisals +9 -0
- data/CHANGELOG.md +2 -5
- data/README.md +15 -2
- data/docs/01-define-pricing-plans.md +16 -1
- data/docs/04-views.md +2 -1
- data/docs/06-gem-compatibility.md +31 -4
- data/gemfiles/rails_7.2.gemfile +23 -0
- data/gemfiles/rails_8.1.gemfile +23 -0
- data/lib/pricing_plans/configuration.rb +5 -5
- data/lib/pricing_plans/plan.rb +5 -1
- data/lib/pricing_plans/version.rb +1 -1
- data/lib/pricing_plans.rb +2 -0
- metadata +5 -100
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 231aa688b5fb69cffde68df9bbab35af32634d8605930559378e15a841cb6aa0
|
|
4
|
+
data.tar.gz: 2fee172963111d141b39d9ad9335f1b84d3f9b6f46df139e63684103eecb7750
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 99277aae15c2a137b0824a199097420a60613e9c5c20b6569036f11b574186997b303fdfe42d5a2d147a66d0b28a32812e8ca1706903d94c88f6e61a5e09bf27
|
|
7
|
+
data.tar.gz: 12aeee03c7911d19b7b4c04398946150534b0ef66d59aa50211992a52f3000908778e42e7eb51b2acc0bec85e23e51eff5996ae04870f948826485ebf80a1414
|
data/.claude/settings.local.json
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"permissions": {
|
|
3
3
|
"allow": [
|
|
4
|
-
"Bash(mkdir:*)",
|
|
5
|
-
"Bash(bundle install:*)",
|
|
6
|
-
"Bash(bundle exec rake:*)",
|
|
7
|
-
"Bash(bundle update:*)",
|
|
8
|
-
"Bash(bundle exec ruby:*)",
|
|
9
4
|
"Bash(sed:*)",
|
|
10
5
|
"Bash(grep:*)",
|
|
11
|
-
"Bash(ruby:*)",
|
|
12
6
|
"Bash(find:*)",
|
|
13
7
|
"mcp__context7__resolve-library-id",
|
|
14
8
|
"mcp__context7__get-library-docs",
|
|
15
9
|
"WebFetch(domain:github.com)",
|
|
16
|
-
"WebSearch"
|
|
10
|
+
"WebSearch",
|
|
11
|
+
"Bash(bundle exec rake test:*)",
|
|
12
|
+
"Bash(bundle install:*)",
|
|
13
|
+
"Bash(bundle exec appraisal:*)",
|
|
14
|
+
"Bash(ls:*)",
|
|
15
|
+
"Bash(done)"
|
|
17
16
|
],
|
|
18
17
|
"deny": []
|
|
19
18
|
}
|
data/Appraisals
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
## [0.2.1] - 2026-01-15
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
3
|
+
- Added a `metadata` alias to plans, and documented its usage
|
|
7
4
|
|
|
8
5
|
## [0.2.0] - 2025-12-26
|
|
9
6
|
|
data/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# 💵 `pricing_plans` - Define and enforce pricing plan limits in your Rails app (SaaS entitlements)
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/pricing_plans) [](https://github.com/rameerez/pricing_plans/actions)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> [!TIP]
|
|
6
|
+
> **🚀 Ship your next Rails app 10x faster!** I've built **[RailsFast](https://railsfast.com)**, a production-ready Rails boilerplate template that comes with everything you need to launch a software business in days, not weeks.
|
|
7
|
+
|
|
8
|
+
`pricing_plans` allows you to enforce pricing plan limits with one-liners that read like plain English. Avoid scattering and entangling pricing logic everywhere in your Rails SaaS.
|
|
6
9
|
|
|
7
10
|
For example, this is how you define pricing plans and their entitlements:
|
|
8
11
|
```ruby
|
|
@@ -99,6 +102,16 @@ You can also display upgrade alerts to prompt users into upgrading to the next p
|
|
|
99
102
|
|
|
100
103
|

|
|
101
104
|
|
|
105
|
+
You can attach arbitrary plan `metadata` for UI/presentation needs (icons, colors, badges) directly in the initializer:
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
plan :hobby do
|
|
109
|
+
metadata icon: "rocket", color: "bg-red-500"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
plan.metadata[:icon] # => "rocket"
|
|
113
|
+
```
|
|
114
|
+
|
|
102
115
|
You can also grandfather users into old plans (hidden to other users), assign plans manually without requiring a payment (for testing, gifts, or employees), and much more!
|
|
103
116
|
|
|
104
117
|
## 🤓 Read the docs!
|
|
@@ -300,6 +300,7 @@ PricingPlans.configure do |config|
|
|
|
300
300
|
name "Free Plan" # optional, would default to "Free" as inferred from the :free key
|
|
301
301
|
description "A plan to get you started"
|
|
302
302
|
bullets "Basic features", "Community support"
|
|
303
|
+
metadata icon: "rocket", color: "bg-red-500"
|
|
303
304
|
|
|
304
305
|
cta_text "Subscribe"
|
|
305
306
|
# In initializers, prefer a string path/URL or set a global default CTA in config.
|
|
@@ -315,6 +316,18 @@ end
|
|
|
315
316
|
|
|
316
317
|
You can also make a plan `default!`; and you can make a plan `highlighted!` to help you when building a pricing table.
|
|
317
318
|
|
|
319
|
+
### Plan metadata for UI and presentation
|
|
320
|
+
|
|
321
|
+
You can attach arbitrary `metadata` to a plan for presentation needs (for example, per-card icons or colors on a pricing page). This keeps plan UI details co-located in the same DSL rather than scattered elsewhere:
|
|
322
|
+
|
|
323
|
+
```ruby
|
|
324
|
+
plan :hobby do
|
|
325
|
+
metadata icon: "rocket", color: "bg-red-500"
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
plan.metadata[:icon] # => "rocket"
|
|
329
|
+
```
|
|
330
|
+
|
|
318
331
|
### Hide plans from public lists
|
|
319
332
|
|
|
320
333
|
You can mark a plan as `hidden!` to exclude it from public-facing plan lists (`PricingPlans.plans`, `PricingPlans.for_pricing`, `PricingPlans.view_models`). Hidden plans are still accessible internally and can be assigned to users.
|
|
@@ -328,6 +341,8 @@ You can mark a plan as `hidden!` to exclude it from public-facing plan lists (`P
|
|
|
328
341
|
```ruby
|
|
329
342
|
PricingPlans.configure do |config|
|
|
330
343
|
# Hidden default plan for users who haven't subscribed
|
|
344
|
+
# It won't appear on pricing page
|
|
345
|
+
# This is what users are on before they subscribe to any plan
|
|
331
346
|
plan :unsubscribed do
|
|
332
347
|
price 0
|
|
333
348
|
hidden! # Won't appear on pricing page
|
|
@@ -411,4 +426,4 @@ plan :enterprise do
|
|
|
411
426
|
unlimited :products
|
|
412
427
|
allows :api_access, :premium_features
|
|
413
428
|
end
|
|
414
|
-
```
|
|
429
|
+
```
|
data/docs/04-views.md
CHANGED
|
@@ -18,6 +18,7 @@ Each `PricingPlans::Plan` responds to:
|
|
|
18
18
|
- `plan.price_label` → The `price` or `price_string` you've defined for the plan. If `stripe_price` is set and the Stripe gem is available, it auto-fetches the live price from Stripe. You can override or disable this.
|
|
19
19
|
- `plan.cta_text`
|
|
20
20
|
- `plan.cta_url`
|
|
21
|
+
- `plan.metadata` → Optional hash for UI/presentation attributes (icons, colors, badges)
|
|
21
22
|
|
|
22
23
|
### Example: build a pricing page
|
|
23
24
|
|
|
@@ -118,4 +119,4 @@ Tip: you could also use `plan_limit_remaining(:projects)` and `plan_limit_percen
|
|
|
118
119
|
|
|
119
120
|
## Message customization
|
|
120
121
|
|
|
121
|
-
- You can override copy globally via `config.message_builder` in [`pricing_plans.rb`](/docs/01-define-pricing-plans.md), which is used across limit checks and features. Suggested signature: `(context:, **kwargs) -> string` with contexts `:over_limit`, `:grace`, `:feature_denied`, and `:overage_report`.
|
|
122
|
+
- You can override copy globally via `config.message_builder` in [`pricing_plans.rb`](/docs/01-define-pricing-plans.md), which is used across limit checks and features. Suggested signature: `(context:, **kwargs) -> string` with contexts `:over_limit`, `:grace`, `:feature_denied`, and `:overage_report`.
|
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
# Using `pricing_plans` with `pay` and/or `usage_credits`
|
|
2
2
|
|
|
3
|
-
`pricing_plans` is designed to work seamlessly with other complementary popular gems like `pay` (to handle actual subscriptions and payments), and `usage_credits` (to handle credit-like spending and refills)
|
|
3
|
+
`pricing_plans` is designed to work seamlessly with other complementary popular gems like [`pay`](https://github.com/pay-rails/pay) (to handle actual subscriptions and payments), and `usage_credits` (to handle credit-like spending and refills)
|
|
4
4
|
|
|
5
|
-
These gems are related but not overlapping. They're complementary. The boundaries are
|
|
5
|
+
These gems are related but not overlapping. They're complementary. The boundaries are:
|
|
6
|
+
- [`pay`](https://github.com/pay-rails/pay) handles billing
|
|
7
|
+
- [`usage_credits`](https://github.com/rameerez/usage_credits/) handles user credits (metered usage through credits, ledger-like)
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## `pay` gem
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
The integration with the `pay` gem should be seamless and is documented throughout the entire docs; however, to make it explicit:
|
|
12
|
+
|
|
13
|
+
There's nothing to do on your end to make `pricing_plans` work with `pay`!
|
|
14
|
+
|
|
15
|
+
As long as your `pricing_plans` config (`config/initializers/pricing_plans.rb`) contains a plan with the correct `stripe_price` ID, whenever a subscription to that Stripe price ID is found through the `pay` gem, `pricing_plans` will understand the user is subscribed to that plan automatically, and will start enforcing the corresponding limits.
|
|
16
|
+
|
|
17
|
+
The way `pricing_plans` works doesn't require any data migration, or callback setup, or any manual action. You don't need to call `assign_pricing_plan!` at all at any point, unless you're trying to something like overriding a plan, gifting users access to plans without any payment, or things like that.
|
|
18
|
+
|
|
19
|
+
As long as a matching `stripe_price` is found in the `pricing_plans.rb` initializer, the gem will know a user subscribed to that Stripe price ID is under the corresponding plan. Essentially, the gem just looks at the current `pay` subscriptions of your user. If a matching price ID is found in the `pricing_plans` configuration file, it enforces the corresponding limits.
|
|
20
|
+
|
|
21
|
+
> [!TIP]
|
|
22
|
+
> To make your `pricing_plans` gem config work across environments (production, development, etc.) instead of defining price IDs statically like this in the config:
|
|
23
|
+
>
|
|
24
|
+
> ```ruby
|
|
25
|
+
> stripe_price month: "price_123", year: "price_456"
|
|
26
|
+
> ```
|
|
27
|
+
>
|
|
28
|
+
> Try instead defining them dynamically using `Rails.env`, so the corresponding plan for each environment gets loaded automatically. A simple solution would be to define your plans in the credentials file, and then doing something like this in the `pricing_plans` config:
|
|
29
|
+
>
|
|
30
|
+
> ```ruby
|
|
31
|
+
> stripe_price month: Rails.application.credentials.dig(Rails.env.to_sym, :stripe_plans, :plan_name, :monthly), year: Rails.application.credentials.dig(Rails.env.to_sym, :stripe_plans, :plan_name, :yearly)
|
|
32
|
+
> ```
|
|
33
|
+
>
|
|
34
|
+
> You can come up with similar solutions, like adding that config to a plaintext `.yml` file if you don't want to store this info in the credentials file, but this is the overall idea.
|
|
35
|
+
|
|
36
|
+
## `usage_credits` gem
|
|
10
37
|
|
|
11
38
|
In the SaaS world, pricing plans and usage credits are related in so far credits are usually a part of a pricing plan. A plan would give you, say, 100 credits a month along other features, and users would find that information usually documented in the pricing table itself.
|
|
12
39
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "rails", "~> 7.2.3"
|
|
7
|
+
|
|
8
|
+
group :development do
|
|
9
|
+
gem "appraisal"
|
|
10
|
+
gem "irb"
|
|
11
|
+
gem "rubocop", "~> 1.0"
|
|
12
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
13
|
+
gem "rubocop-performance", "~> 1.0"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
group :test do
|
|
17
|
+
gem "minitest", "~> 5.0"
|
|
18
|
+
gem "sqlite3", "~> 2.1"
|
|
19
|
+
gem "ostruct"
|
|
20
|
+
gem "simplecov", require: false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "rails", "~> 8.1.2"
|
|
7
|
+
|
|
8
|
+
group :development do
|
|
9
|
+
gem "appraisal"
|
|
10
|
+
gem "irb"
|
|
11
|
+
gem "rubocop", "~> 1.0"
|
|
12
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
13
|
+
gem "rubocop-performance", "~> 1.0"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
group :test do
|
|
17
|
+
gem "minitest", "~> 5.0"
|
|
18
|
+
gem "sqlite3", "~> 2.1"
|
|
19
|
+
gem "ostruct"
|
|
20
|
+
gem "simplecov", require: false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
gemspec path: "../"
|
|
@@ -12,11 +12,11 @@ module PricingPlans
|
|
|
12
12
|
# Debug mode - set to true to enable debug output
|
|
13
13
|
attr_accessor :debug
|
|
14
14
|
# Global controller ergonomics
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
# Optional global resolver for controller plan owner. Per-controller settings still win.
|
|
16
|
+
# Accepts:
|
|
17
|
+
# - Symbol: a controller helper to call (e.g., :current_organization)
|
|
18
|
+
# - Proc: instance-exec'd in the controller (self is the controller)
|
|
19
|
+
attr_reader :controller_plan_owner_method, :controller_plan_owner_proc
|
|
20
20
|
# When a limit check blocks, controllers can redirect to a global default target.
|
|
21
21
|
# Accepts:
|
|
22
22
|
# - Symbol: a controller helper to call (e.g., :pricing_path)
|
data/lib/pricing_plans/plan.rb
CHANGED
|
@@ -139,6 +139,9 @@ module PricingPlans
|
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
+
alias_method :set_metadata, :set_meta
|
|
143
|
+
alias_method :metadata, :meta
|
|
144
|
+
|
|
142
145
|
# CTA helpers for pricing UI
|
|
143
146
|
def set_cta_text(value)
|
|
144
147
|
@cta_text = value&.to_s
|
|
@@ -169,7 +172,7 @@ module PricingPlans
|
|
|
169
172
|
default = PricingPlans.configuration.default_cta_url
|
|
170
173
|
return default if default
|
|
171
174
|
# New default: if host app defines subscribe_path, prefer that
|
|
172
|
-
if defined?(Rails) && Rails.application.routes.url_helpers.respond_to?(:subscribe_path)
|
|
175
|
+
if defined?(Rails) && Rails.respond_to?(:application) && Rails.application && Rails.application.routes.url_helpers.respond_to?(:subscribe_path)
|
|
173
176
|
return Rails.application.routes.url_helpers.subscribe_path(plan: key, interval: :month)
|
|
174
177
|
end
|
|
175
178
|
nil
|
|
@@ -480,6 +483,7 @@ module PricingPlans
|
|
|
480
483
|
name: name,
|
|
481
484
|
description: description,
|
|
482
485
|
features: bullets, # alias in this gem
|
|
486
|
+
metadata: metadata.dup,
|
|
483
487
|
highlighted: highlighted?,
|
|
484
488
|
default: default?,
|
|
485
489
|
free: free?,
|
data/lib/pricing_plans.rb
CHANGED
|
@@ -135,11 +135,13 @@ module PricingPlans
|
|
|
135
135
|
is_current = plan_owner ? (PlanResolver.effective_plan_for(plan_owner)&.key == plan.key) : false
|
|
136
136
|
is_popular = Registry.highlighted_plan&.key == plan.key
|
|
137
137
|
price_label = plan_price_label_for(plan)
|
|
138
|
+
# Duplicate metadata to avoid mutating plan internals from view-layer code.
|
|
138
139
|
{
|
|
139
140
|
key: plan.key,
|
|
140
141
|
name: plan.name,
|
|
141
142
|
description: plan.description,
|
|
142
143
|
bullets: plan.bullets,
|
|
144
|
+
metadata: plan.metadata.dup,
|
|
143
145
|
price_label: price_label,
|
|
144
146
|
is_current: is_current,
|
|
145
147
|
is_popular: is_popular,
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pricing_plans
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- rameerez
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-01-15 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: activerecord
|
|
@@ -49,104 +49,6 @@ dependencies:
|
|
|
49
49
|
- - "<"
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
51
|
version: '9.0'
|
|
52
|
-
- !ruby/object:Gem::Dependency
|
|
53
|
-
name: bundler
|
|
54
|
-
requirement: !ruby/object:Gem::Requirement
|
|
55
|
-
requirements:
|
|
56
|
-
- - "~>"
|
|
57
|
-
- !ruby/object:Gem::Version
|
|
58
|
-
version: '2.0'
|
|
59
|
-
type: :development
|
|
60
|
-
prerelease: false
|
|
61
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
-
requirements:
|
|
63
|
-
- - "~>"
|
|
64
|
-
- !ruby/object:Gem::Version
|
|
65
|
-
version: '2.0'
|
|
66
|
-
- !ruby/object:Gem::Dependency
|
|
67
|
-
name: rake
|
|
68
|
-
requirement: !ruby/object:Gem::Requirement
|
|
69
|
-
requirements:
|
|
70
|
-
- - "~>"
|
|
71
|
-
- !ruby/object:Gem::Version
|
|
72
|
-
version: '13.0'
|
|
73
|
-
type: :development
|
|
74
|
-
prerelease: false
|
|
75
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
76
|
-
requirements:
|
|
77
|
-
- - "~>"
|
|
78
|
-
- !ruby/object:Gem::Version
|
|
79
|
-
version: '13.0'
|
|
80
|
-
- !ruby/object:Gem::Dependency
|
|
81
|
-
name: minitest
|
|
82
|
-
requirement: !ruby/object:Gem::Requirement
|
|
83
|
-
requirements:
|
|
84
|
-
- - "~>"
|
|
85
|
-
- !ruby/object:Gem::Version
|
|
86
|
-
version: '5.0'
|
|
87
|
-
type: :development
|
|
88
|
-
prerelease: false
|
|
89
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
-
requirements:
|
|
91
|
-
- - "~>"
|
|
92
|
-
- !ruby/object:Gem::Version
|
|
93
|
-
version: '5.0'
|
|
94
|
-
- !ruby/object:Gem::Dependency
|
|
95
|
-
name: sqlite3
|
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
|
97
|
-
requirements:
|
|
98
|
-
- - "~>"
|
|
99
|
-
- !ruby/object:Gem::Version
|
|
100
|
-
version: '2.1'
|
|
101
|
-
type: :development
|
|
102
|
-
prerelease: false
|
|
103
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
104
|
-
requirements:
|
|
105
|
-
- - "~>"
|
|
106
|
-
- !ruby/object:Gem::Version
|
|
107
|
-
version: '2.1'
|
|
108
|
-
- !ruby/object:Gem::Dependency
|
|
109
|
-
name: rubocop
|
|
110
|
-
requirement: !ruby/object:Gem::Requirement
|
|
111
|
-
requirements:
|
|
112
|
-
- - "~>"
|
|
113
|
-
- !ruby/object:Gem::Version
|
|
114
|
-
version: '1.0'
|
|
115
|
-
type: :development
|
|
116
|
-
prerelease: false
|
|
117
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
118
|
-
requirements:
|
|
119
|
-
- - "~>"
|
|
120
|
-
- !ruby/object:Gem::Version
|
|
121
|
-
version: '1.0'
|
|
122
|
-
- !ruby/object:Gem::Dependency
|
|
123
|
-
name: rubocop-minitest
|
|
124
|
-
requirement: !ruby/object:Gem::Requirement
|
|
125
|
-
requirements:
|
|
126
|
-
- - "~>"
|
|
127
|
-
- !ruby/object:Gem::Version
|
|
128
|
-
version: '0.35'
|
|
129
|
-
type: :development
|
|
130
|
-
prerelease: false
|
|
131
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
132
|
-
requirements:
|
|
133
|
-
- - "~>"
|
|
134
|
-
- !ruby/object:Gem::Version
|
|
135
|
-
version: '0.35'
|
|
136
|
-
- !ruby/object:Gem::Dependency
|
|
137
|
-
name: rubocop-performance
|
|
138
|
-
requirement: !ruby/object:Gem::Requirement
|
|
139
|
-
requirements:
|
|
140
|
-
- - "~>"
|
|
141
|
-
- !ruby/object:Gem::Version
|
|
142
|
-
version: '1.0'
|
|
143
|
-
type: :development
|
|
144
|
-
prerelease: false
|
|
145
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
146
|
-
requirements:
|
|
147
|
-
- - "~>"
|
|
148
|
-
- !ruby/object:Gem::Version
|
|
149
|
-
version: '1.0'
|
|
150
52
|
description: Define and enforce pricing plan limits in your Rails SaaS (entitlements,
|
|
151
53
|
quotas, feature gating). pricing_plans acts as your single source of truth for pricing
|
|
152
54
|
plans. Define a pricing catalog with feature gating, persistent caps, per‑period
|
|
@@ -161,6 +63,7 @@ extra_rdoc_files: []
|
|
|
161
63
|
files:
|
|
162
64
|
- ".claude/settings.local.json"
|
|
163
65
|
- ".rubocop.yml"
|
|
66
|
+
- Appraisals
|
|
164
67
|
- CHANGELOG.md
|
|
165
68
|
- CLAUDE.md
|
|
166
69
|
- LICENSE.txt
|
|
@@ -176,6 +79,8 @@ files:
|
|
|
176
79
|
- docs/images/pricing_plans_ruby_rails_gem_usage_alert_upgrade.jpg
|
|
177
80
|
- docs/images/pricing_plans_ruby_rails_gem_usage_meter.jpg
|
|
178
81
|
- docs/images/product_creation_blocked.jpg
|
|
82
|
+
- gemfiles/rails_7.2.gemfile
|
|
83
|
+
- gemfiles/rails_8.1.gemfile
|
|
179
84
|
- lib/generators/pricing_plans/install/install_generator.rb
|
|
180
85
|
- lib/generators/pricing_plans/install/templates/create_pricing_plans_tables.rb.erb
|
|
181
86
|
- lib/generators/pricing_plans/install/templates/initializer.rb
|