core_merchant 0.9.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff6bdd381d58ecdb8153a14ceff12482d22b55b70a738de1e46df9480f3ab472
4
- data.tar.gz: a87c17013865cdbe94f70daf969624f494135955568c0662e86cfe41463a6d88
3
+ metadata.gz: f2a8720cdfe9e44ee389c1f9297dca125be49ee41dd0aa36353480ebe59242f1
4
+ data.tar.gz: 8dc8ed8fd42ef4fca3ecd63b5064a0b5499da237df1fbc19bdb75301054b7646
5
5
  SHA512:
6
- metadata.gz: 044f0541c54678616eff01372b20b54e4a2bfd3f3d087ba276dc749ce06bc550f6bb047ba90bad084d1edb04f1600774cf5dd681fb56b4c91ef0c8530dbcfa38
7
- data.tar.gz: f471e4c215f2d9f36944621e9bb067f9fcde0a6f67d72ee9b6e1cc6a3a2aeb507dd93cdc110bdaf9058be19c7cb700062932609ce9f10437bb5c813c75f0ed82
6
+ metadata.gz: 76f2ff5aa75aeb8f992be5be10d1e5b7630102cf34ddf2bfcdeeafe7ac151253e27ff6dbeea2936b245af3b6965b02dce856354ae2ee7d958844e93f07cc51dd
7
+ data.tar.gz: 7175e21168584ba3b16863933e4ea5afc297fe8fb053f8502766fc8c55b1614168eb0b0c28f9ba89ca4d2e5a82d24c928b5effcbe5633dc18a38dba536d2b188
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- core_merchant (0.8.0)
4
+ core_merchant (0.10.0)
5
5
  activesupport (~> 7.0)
6
6
  rails (~> 7.0)
7
7
 
data/README.md CHANGED
@@ -11,7 +11,7 @@ CoreMerchant is a library for customer, product, and subscription management in
11
11
  - [X] Add SubscriptionPlan model
12
12
  - [X] Add Subscription model
13
13
  - [X] Implement subscription manager and callbacks
14
- - [ ] Add sidekiq jobs for subscription management
14
+ - [X] Implement SubscriptionEvent model for logging
15
15
  - [ ] Add Invoice model
16
16
  - [ ] Add billing and invoicing service
17
17
 
@@ -19,28 +19,35 @@ CoreMerchant is a library for customer, product, and subscription management in
19
19
  - [CoreMerchant](#coremerchant)
20
20
  - [To-dos until 1.0.0 release](#to-dos-until-100-release)
21
21
  - [Table of contents](#table-of-contents)
22
- - [Installation](#installation)
23
- - [Usage](#usage)
24
- - [Initialization](#initialization)
25
- - [Configuration](#configuration)
26
- - [1. Customer class](#1-customer-class)
27
- - [2. Subscription listener class](#2-subscription-listener-class)
28
- - [Subscription management](#subscription-management)
29
- - [Creating a subscription plan](#creating-a-subscription-plan)
30
- - [Creating a subscription](#creating-a-subscription)
31
- - [Cancelling a subscription](#cancelling-a-subscription)
32
- - [Handling subscription events](#handling-subscription-events)
33
- - [Models](#models)
22
+ - [Installation](#installation)
23
+ - [Usage](#usage)
24
+ - [Initialization](#initialization)
25
+ - [Configuration](#configuration)
26
+ - [1. Customer class](#1-customer-class)
27
+ - [2. Subscription listener class](#2-subscription-listener-class)
28
+ - [Subscription management](#subscription-management)
29
+ - [Creating a subscription plan](#creating-a-subscription-plan)
30
+ - [Creating a subscription](#creating-a-subscription)
31
+ - [Cancelling a subscription](#cancelling-a-subscription)
32
+ - [Handling subscription events](#handling-subscription-events)
33
+ - [Subscription History](#subscription-history)
34
+ - [Public API](#public-api)
34
35
  - [SubscriptionManager](#subscriptionmanager)
35
36
  - [SubscriptionPlan](#subscriptionplan)
36
37
  - [Subscription](#subscription)
38
+ - [SubscriptionEvent](#subscriptionevent)
39
+ - [Subclasses](#subclasses)
40
+ - [SubscriptionRenewalEvent](#subscriptionrenewalevent)
41
+ - [SubscriptionStatusChangeEvent](#subscriptionstatuschangeevent)
42
+ - [SubscriptionPlanChangeEvent](#subscriptionplanchangeevent)
43
+ - [SubscriptionCancellationEvent](#subscriptioncancellationevent)
37
44
  - [Contributing](#contributing)
38
45
 
39
46
 
40
- ## Installation
47
+ # Installation
41
48
  Add this line to your application's Gemfile:
42
49
  ```
43
- gem 'core_merchant', '~> 0.1.0'
50
+ gem 'core_merchant', '~> 0.10.0'
44
51
  ```
45
52
  and run `bundle install`.
46
53
 
@@ -49,8 +56,8 @@ Alternatively, you can install the gem manually:
49
56
  $ gem install core_merchant
50
57
  ```
51
58
 
52
- ## Usage
53
- ### Initialization
59
+ # Usage
60
+ ## Initialization
54
61
  Run the generator to create the initializer file and the migrations:
55
62
  ```
56
63
  $ rails generate core_merchant:install
@@ -66,10 +73,10 @@ You can then run the migrations:
66
73
  $ rails db:migrate
67
74
  ```
68
75
 
69
- ### Configuration
76
+ ## Configuration
70
77
  The initializer file `config/initializers/core_merchant.rb` contains the following configuration options:
71
78
 
72
- #### 1. Customer class
79
+ ### 1. Customer class
73
80
  ```ruby
74
81
  config.customer_class = 'User'
75
82
  ```
@@ -84,7 +91,7 @@ class User < ApplicationRecord
84
91
  end
85
92
  ```
86
93
 
87
- #### 2. Subscription listener class
94
+ ### 2. Subscription listener class
88
95
  ```ruby
89
96
  config.subscription_listener_class = 'MySubscriptionListener'
90
97
  ```
@@ -101,15 +108,15 @@ end
101
108
 
102
109
  More about subscription events in the [Handling subscription events](#handling-subscription-events) section.
103
110
 
104
- ### Subscription management
111
+ ## Subscription management
105
112
 
106
- #### Creating a subscription plan
113
+ ### Creating a subscription plan
107
114
  You can create a subscription plan using the `SubscriptionPlan` model:
108
115
  ```ruby
109
116
  CoreMerchant::SubscriptionPlan.create(name_key: 'basic', price_cents: 10_00, duration: '1m')
110
117
  ```
111
118
 
112
- #### Creating a subscription
119
+ ### Creating a subscription
113
120
  You can create a subscription for a customer using the `Subscription` model:
114
121
  ```ruby
115
122
  customer = User.find(1)
@@ -122,13 +129,13 @@ Note that the subscription will not be active until you start it:
122
129
  subscription.start
123
130
  ```
124
131
 
125
- #### Cancelling a subscription
132
+ ### Cancelling a subscription
126
133
  You can cancel a subscription by calling the `cancel` method. You can also specify a reason for the cancellation and whether the cancellation should take effect immediately or at the end of the current billing period:
127
134
  ```ruby
128
135
  subscription.cancel(reason: 'Customer request', at_period_end: false)
129
136
  ```
130
137
 
131
- #### Handling subscription events
138
+ ### Handling subscription events
132
139
  You can handle subscription events by implementing event handlers in the subscription listener class. For example, you can send an email to the customer when a subscription is created:
133
140
  ```ruby
134
141
  class MySubscriptionListener
@@ -173,7 +180,29 @@ Available subscription events:
173
180
  - `on_subscription_renewal_payment_processing(subscription)`
174
181
  - `on_subscription_grace_period_started(subscription, days_remaining:)`
175
182
 
176
- ## Models
183
+ ### Subscription History
184
+ CoreMerchant now keeps a detailed history of subscription events, including creations, renewals, cancellations, status changes, and plan changes. This provides an audit trail and can be useful for debugging, customer support, and analytics.
185
+
186
+ To access a subscription's history:
187
+ ```ruby
188
+ subscription = CoreMerchant::Subscription.find(42)
189
+
190
+ # Get all events
191
+ subscription.subscription_events
192
+
193
+ # Get specific event types
194
+ latest_renewal = subscription.renewal_events.last
195
+ puts "Last renewed at: #{latest_renewal.created_at}"
196
+ puts "Renewal price: #{latest_renewal.price_cents} cents, renewed until: #{latest_renewal.renewed_until}"
197
+
198
+ latest_status_change = subscription.status_change_events.last
199
+ puts "Status changed from #{latest_status_change.from} to #{latest_status_change.to}"
200
+
201
+ latest_plan_change = subscription.plan_change_events.last
202
+ puts "Plan changed from #{latest_plan_change.from_plan.name} to #{latest_plan_change.to_plan.name}"
203
+ ```
204
+
205
+ ## Public API
177
206
  ### SubscriptionManager
178
207
  Access from `CoreMerchant.subscription_manager`. The `SubscriptionManager` class is responsible for managing subscriptions. It is responsible for notifying listeners when subscription events occur and checking for and handling renewals.
179
208
 
@@ -271,6 +300,53 @@ subscription.start
271
300
  subscription.cancel(reason: "Too expensive", at_period_end: true)
272
301
  ```
273
302
 
303
+ ### SubscriptionEvent
304
+ The `SubscriptionEvent` model represents a historical log of events related to a subscription. It provides an audit trail of all significant actions and state changes for a subscription.
305
+
306
+ This class has subclasses for specific event types, such as `SubscriptionRenewalEvent`, `SubscriptionStatusChangeEvent`, and `SubscriptionPlanChangeEvent`. Each subclass has additional fields specific to the event type.
307
+
308
+ **Attributes**:
309
+ - `subscription`: Association to the related Subscription
310
+ - `event_type`: Type of the event (e.g., 'created', 'renewed', 'canceled', 'status_changed', 'plan_changed')
311
+ - `metadata`: JSON field for storing additional event-specific data
312
+
313
+ **Usage**:
314
+ ```ruby
315
+ # Automatically logged when a subscription is created
316
+ subscription = CoreMerchant::Subscription.create(customer: user, subscription_plan: plan)
317
+
318
+ # Logging a custom event
319
+ subscription.log_event('custom_event', key: 'value')
320
+
321
+ # Retrieve the last renewal event
322
+ latest_renewal = subscription.renewal_events.last
323
+ puts "Last renewed at: #{latest_renewal.created_at}"
324
+ puts "Renewal price: #{latest_renewal.price_cents} cents, renewed until: #{latest_renewal.renewed_until}"
325
+
326
+ # Retrieve the last event of any type
327
+ latest_event = subscription.subscription_events.last
328
+ puts "Last event type: #{latest_event.event_type}, metadata: #{latest_event.metadata}"
329
+ ```
330
+
331
+ #### Subclasses
332
+ ##### SubscriptionRenewalEvent
333
+ - `price_cents`: The price of the renewal in cents
334
+ - `renewed_until`: The end date of the renewal
335
+ - `renewed_at`: The date and time of the renewal
336
+
337
+ ##### SubscriptionStatusChangeEvent
338
+ - `from`: The previous status of the subscription
339
+ - `to`: The new status of the subscription
340
+
341
+ ##### SubscriptionPlanChangeEvent
342
+ - `from_plan`: The previous plan of the subscription
343
+ - `to_plan`: The new plan of the subscription
344
+
345
+ ##### SubscriptionCancellationEvent
346
+ - `reason`: The reason for the cancellation
347
+ - `at_period_end`: Whether the cancellation is scheduled for the end of the current period
348
+ - `canceled_at`: The date and time of the cancellation
349
+
274
350
  > [!NOTE]
275
351
  > Other models and features are being developed and will be added in future releases.
276
352
 
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoreMerchant
4
+ module Concerns
5
+ # This concern adds a SubscriptionEvent association including creation and retrieval
6
+ module SubscriptionEventAssociation
7
+ extend ActiveSupport::Concern
8
+
9
+ EVENT_TYPES = %i[renewal status_change plan_change cancellation].freeze
10
+
11
+ included do
12
+ has_many :events, class_name: "SubscriptionEvent", dependent: :destroy
13
+ after_update :create_status_change_event, if: :saved_change_to_status?
14
+
15
+ EVENT_TYPES.each do |event_type|
16
+ scope_name = "#{event_type}_events".to_sym
17
+ class_name = "Subscription#{event_type.to_s.camelize}Event"
18
+
19
+ has_many scope_name, -> { where(event_type: event_type) }, class_name: class_name
20
+
21
+ define_method "create_#{event_type}_event" do |**metadata|
22
+ events.create!(event_type: event_type, metadata: metadata)
23
+ end
24
+ end
25
+
26
+ def create_status_change_event
27
+ status_change_events.create!(from: saved_changes["status"].first, to: status)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "core_merchant/concerns/subscription_state_machine"
4
4
  require "core_merchant/concerns/subscription_notifications"
5
+ require "core_merchant/concerns/subscription_event_association"
6
+ require "core_merchant/subscription_event"
5
7
 
6
8
  module CoreMerchant
7
9
  # Represents a subscription in CoreMerchant.
@@ -52,6 +54,7 @@ module CoreMerchant
52
54
  class Subscription < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
53
55
  include CoreMerchant::Concerns::SubscriptionStateMachine
54
56
  include CoreMerchant::Concerns::SubscriptionNotifications
57
+ include CoreMerchant::Concerns::SubscriptionEventAssociation
55
58
 
56
59
  self.table_name = "core_merchant_subscriptions"
57
60
 
@@ -120,6 +123,7 @@ module CoreMerchant
120
123
  end
121
124
 
122
125
  notify_subscription_manager(:canceled, reason: reason, immediate: !at_period_end)
126
+ cancellation_events.create!(reason: reason, at_period_end: at_period_end)
123
127
  end
124
128
 
125
129
  # Starts a new period for the subscription.
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoreMerchant
4
+ # The `SubscriptionEvent` model represents a historical log of events related to a subscription.
5
+ # It provides an audit trail of all significant actions and state changes for a subscription.
6
+
7
+ # This class has subclasses for specific event types, such as
8
+ # `SubscriptionRenewalEvent`, `SubscriptionStatusChangeEvent`, and `SubscriptionPlanChangeEvent`.
9
+ # Each subclass has additional fields specific to the event type.
10
+
11
+ # **Attributes**:
12
+ # - `subscription`: Association to the related Subscription
13
+ # - `event_type`: Type of the event (e.g., 'created', 'renewed', 'canceled', 'status_changed', 'plan_changed')
14
+ # - `metadata`: JSON field for storing additional event-specific data
15
+
16
+ # **Usage**:
17
+ # ```ruby
18
+ # # Automatically logged when a subscription is created
19
+ # subscription = CoreMerchant::Subscription.create(customer: user, subscription_plan: plan)
20
+
21
+ # # Logging a custom event
22
+ # subscription.log_event('custom_event', key: 'value')
23
+
24
+ # # Retrieve the last renewal event
25
+ # latest_renewal = subscription.renewal_events.last
26
+ # puts "Last renewed at: #{latest_renewal.created_at}"
27
+ # puts "Renewal price: #{latest_renewal.price_cents} cents, renewed until: #{latest_renewal.renewed_until}"
28
+
29
+ # # Retrieve the last event of any type
30
+ # latest_event = subscription.subscription_events.last
31
+ # puts "Last event type: #{latest_event.event_type}, metadata: #{latest_event.metadata}"
32
+ # ```
33
+ class SubscriptionEvent < ActiveRecord::Base
34
+ self.table_name = "core_merchant_subscription_events"
35
+
36
+ belongs_to :subscription, class_name: "CoreMerchant::Subscription"
37
+
38
+ validates :event_type, presence: true
39
+
40
+ def metadata
41
+ value = self[:metadata]
42
+ value.is_a?(Hash) ? value : JSON.parse(value || "{}")
43
+ end
44
+
45
+ def metadata=(value)
46
+ self[:metadata] = value.is_a?(Hash) ? value.to_json : value
47
+ end
48
+ end
49
+
50
+ # Represents a renewal event for a subscription.
51
+ class SubscriptionRenewalEvent < SubscriptionEvent
52
+ def price_cents
53
+ metadata["price_cents"]
54
+ end
55
+
56
+ def price_cents=(value)
57
+ self.metadata = metadata.merge(price_cents: value)
58
+ end
59
+
60
+ def renewed_from
61
+ metadata["renewed_from"].to_date
62
+ end
63
+
64
+ def renewed_from=(value)
65
+ self.metadata = metadata.merge(renewed_from: value)
66
+ end
67
+
68
+ def renewed_until
69
+ metadata["renewed_until"].to_date
70
+ end
71
+
72
+ def renewed_until=(value)
73
+ self.metadata = metadata.merge(renewed_until: value)
74
+ end
75
+ end
76
+
77
+ # Represents a status change event for a subscription.
78
+ class SubscriptionStatusChangeEvent < SubscriptionEvent
79
+ def from
80
+ metadata["from_status"]
81
+ end
82
+
83
+ def from=(value)
84
+ self.metadata = metadata.merge(from_status: value)
85
+ end
86
+
87
+ def to
88
+ metadata["to_status"]
89
+ end
90
+
91
+ def to=(value)
92
+ self.metadata = metadata.merge(to_status: value)
93
+ end
94
+ end
95
+
96
+ # Represents a plan change event for a subscription.
97
+ class SubscriptionPlanChangeEvent < SubscriptionEvent
98
+ def from_plan
99
+ id = metadata["from_plan_id"]
100
+ CoreMerchant::SubscriptionPlan.find(id) if id
101
+ end
102
+
103
+ def from_plan=(value)
104
+ self.metadata = metadata.merge(from_plan_id: value.id)
105
+ end
106
+
107
+ def to_plan
108
+ id = metadata["to_plan_id"]
109
+ CoreMerchant::SubscriptionPlan.find(id) if id
110
+ end
111
+
112
+ def to_plan=(value)
113
+ self.metadata = metadata.merge(to_plan_id: value.id)
114
+ end
115
+ end
116
+
117
+ # Represents a cancellation event for a subscription.
118
+ class SubscriptionCancellationEvent < SubscriptionEvent
119
+ def canceled_at
120
+ created_at
121
+ end
122
+
123
+ def at_period_end?
124
+ metadata["at_period_end"]
125
+ end
126
+
127
+ def at_period_end=(value)
128
+ self.metadata = metadata.merge(at_period_end: value)
129
+ end
130
+
131
+ def reason
132
+ metadata["reason"]
133
+ end
134
+
135
+ def reason=(value)
136
+ self.metadata = metadata.merge(reason: value)
137
+ end
138
+ end
139
+ end
@@ -104,6 +104,11 @@ module CoreMerchant
104
104
  return unless subscription.transition_to_active
105
105
 
106
106
  subscription.start_new_period
107
+ subscription.renewal_events.create!(
108
+ price_cents: subscription.subscription_plan.price_cents,
109
+ renewed_from: subscription.current_period_start, renewed_until: subscription.current_period_end
110
+ )
111
+
107
112
  notify(subscription, :renewed)
108
113
  end
109
114
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CoreMerchant
4
- VERSION = "0.9.0"
4
+ VERSION = "0.10.1"
5
5
  end
@@ -28,6 +28,9 @@ module CoreMerchant
28
28
 
29
29
  migration_template "migrate/create_core_merchant_subscriptions.erb",
30
30
  "db/migrate/create_core_merchant_subscriptions.rb"
31
+
32
+ migration_template "migrate/create_core_merchant_subscription_events.erb",
33
+ "db/migrate/create_core_merchant_subscription_events.rb"
31
34
  end
32
35
 
33
36
  def show_post_install
@@ -36,7 +39,7 @@ module CoreMerchant
36
39
  Next steps:
37
40
  1. Set the customer class in the initializer file (config/initializers/core_merchant.rb) to the class you want to use for customers.
38
41
  2. Create a subscription listener class (should include CoreMerchant::SubscriptionListener) in your app and set this class in the initializer file (config/initializers/core_merchant.rb) to the class you want to use for subscription listeners.
39
- 3. Run `rails db:migrate` to create the subscription and subscription plan tables.
42
+ 3. Run `rails db:migrate` to create the subscription, subscription plan, and subscription event tables.
40
43
  MESSAGE
41
44
  say next_steps, :yellow
42
45
  end
@@ -47,7 +50,7 @@ module CoreMerchant
47
50
 
48
51
  def self.description
49
52
  <<~DESC
50
- Installs CoreMerchant into your application. This generator will create an initializer file, migration files for the subscription and subscription plan tables, and a locale file."
53
+ Installs CoreMerchant into your application. This generator will create an initializer file, migration files for the subscription, subscription plan, and subscription event tables, and a locale file.
51
54
  DESC
52
55
  end
53
56
  end
@@ -7,7 +7,7 @@ CoreMerchant.configure do |config|
7
7
  # include CoreMerchant::CustomerBehavior
8
8
  # ...
9
9
  # end
10
- config.customer_class = "User"
10
+ # config.customer_class = "User"
11
11
 
12
12
  # Set the class that will receive subscription notifications/
13
13
  # This class must include the CoreMerchant::SubscriptionListener module.
@@ -22,5 +22,5 @@ CoreMerchant.configure do |config|
22
22
  #
23
23
  # To test notifications to this class, you can override `on_test_event_received` method
24
24
  # and call `CoreMerchant.subscription_manager.notify_test_event`.
25
- config.subscription_listener_class = "SubscriptionListener"
25
+ # config.subscription_listener_class = "SubscriptionListener"
26
26
  end
@@ -0,0 +1,14 @@
1
+ # Created by: rails generate core_merchant:install
2
+ class CreateCoreMerchantSubscriptionEvents < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
3
+ def change
4
+ create_table :core_merchant_subscription_events do |t|
5
+ t.references :subscription, null: false, foreign_key: { to_table: :core_merchant_subscriptions }
6
+ t.string :event_type, null: false
7
+ t.jsonb :metadata, default: {}, null: false
8
+
9
+ t.timestamps
10
+
11
+ t.index :event_type
12
+ end
13
+ end
14
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: core_merchant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seyithan Teymur
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-24 00:00:00.000000000 Z
11
+ date: 2024-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -144,11 +144,13 @@ files:
144
144
  - Rakefile
145
145
  - core_merchant.gemspec
146
146
  - lib/core_merchant.rb
147
+ - lib/core_merchant/concerns/subscription_event_association.rb
147
148
  - lib/core_merchant/concerns/subscription_manager_notifications.rb
148
149
  - lib/core_merchant/concerns/subscription_notifications.rb
149
150
  - lib/core_merchant/concerns/subscription_state_machine.rb
150
151
  - lib/core_merchant/customer_behavior.rb
151
152
  - lib/core_merchant/subscription.rb
153
+ - lib/core_merchant/subscription_event.rb
152
154
  - lib/core_merchant/subscription_listener.rb
153
155
  - lib/core_merchant/subscription_manager.rb
154
156
  - lib/core_merchant/subscription_plan.rb
@@ -156,6 +158,7 @@ files:
156
158
  - lib/generators/core_merchant/install_generator.rb
157
159
  - lib/generators/core_merchant/templates/core_merchant.en.yml
158
160
  - lib/generators/core_merchant/templates/core_merchant.rb
161
+ - lib/generators/core_merchant/templates/migrate/create_core_merchant_subscription_events.erb
159
162
  - lib/generators/core_merchant/templates/migrate/create_core_merchant_subscription_plans.erb
160
163
  - lib/generators/core_merchant/templates/migrate/create_core_merchant_subscriptions.erb
161
164
  - sig/core_merchant.rbs