schematichq 1.4.2 → 1.4.4

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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.fern/metadata.json +2 -2
  3. data/README.md +33 -3
  4. data/WASM_VERSION +1 -1
  5. data/lib/schematic/accounts/client.rb +44 -0
  6. data/lib/schematic/accounts/types/count_account_members_params.rb +15 -0
  7. data/lib/schematic/accounts/types/count_account_members_request.rb +14 -0
  8. data/lib/schematic/accounts/types/count_account_members_response.rb +12 -0
  9. data/lib/schematic/billing/client.rb +32 -0
  10. data/lib/schematic/billing/types/delete_payment_method_by_external_id_response.rb +12 -0
  11. data/lib/schematic/client.rb +1 -1
  12. data/lib/schematic/companies/client.rb +6 -2
  13. data/lib/schematic/companies/types/count_companies_params.rb +1 -0
  14. data/lib/schematic/companies/types/count_companies_request.rb +1 -0
  15. data/lib/schematic/companies/types/list_companies_params.rb +1 -0
  16. data/lib/schematic/companies/types/list_companies_request.rb +1 -0
  17. data/lib/schematic/credits/client.rb +102 -0
  18. data/lib/schematic/credits/types/acquire_credit_lease_request_body.rb +14 -0
  19. data/lib/schematic/credits/types/acquire_credit_lease_response.rb +12 -0
  20. data/lib/schematic/credits/types/extend_credit_lease_request_body.rb +13 -0
  21. data/lib/schematic/credits/types/extend_credit_lease_response.rb +12 -0
  22. data/lib/schematic/credits/types/release_credit_lease_response.rb +12 -0
  23. data/lib/schematic/datastream/merge.rb +71 -0
  24. data/lib/schematic/entitlements/types/create_billing_linked_plan_entitlement_request_body.rb +1 -0
  25. data/lib/schematic/entitlements/types/create_plan_entitlement_request_body.rb +1 -0
  26. data/lib/schematic/entitlements/types/update_plan_entitlement_request_body.rb +1 -0
  27. data/lib/schematic/event_buffer.rb +7 -1
  28. data/lib/schematic/integrationsapi/client.rb +99 -3
  29. data/lib/schematic/integrationsapi/types/assume_stripe_installed_response.rb +12 -0
  30. data/lib/schematic/integrationsapi/types/install_integration_response.rb +12 -0
  31. data/lib/schematic/integrationsapi/types/install_stripe_response.rb +12 -0
  32. data/lib/schematic/integrationsapi/types/{load_sample_data_set_v_2_response.rb → load_sample_data_set_response.rb} +1 -1
  33. data/lib/schematic/logger.rb +1 -1
  34. data/lib/schematic/plangroups/types/create_plan_group_request_body.rb +1 -0
  35. data/lib/schematic/plangroups/types/update_plan_group_request_body.rb +1 -0
  36. data/lib/schematic/planmigrations/client.rb +101 -0
  37. data/lib/schematic/planmigrations/types/create_migration_input.rb +17 -0
  38. data/lib/schematic/planmigrations/types/create_migration_response.rb +12 -0
  39. data/lib/schematic/planmigrations/types/retry_company_migration_response.rb +12 -0
  40. data/lib/schematic/planmigrations/types/retry_migration_request_body.rb +12 -0
  41. data/lib/schematic/planmigrations/types/retry_migration_response.rb +12 -0
  42. data/lib/schematic/plans/client.rb +39 -2
  43. data/lib/schematic/plans/types/count_plans_params.rb +1 -0
  44. data/lib/schematic/plans/types/count_plans_request.rb +1 -0
  45. data/lib/schematic/plans/types/list_plans_params.rb +1 -0
  46. data/lib/schematic/plans/types/list_plans_request.rb +1 -0
  47. data/lib/schematic/plans/types/mark_custom_plan_billing_paid_response.rb +12 -0
  48. data/lib/schematic/schematic_client.rb +46 -13
  49. data/lib/schematic/types/account_member_response_data.rb +2 -0
  50. data/lib/schematic/types/billing_credit_grant_reason.rb +1 -0
  51. data/lib/schematic/types/billing_credit_grant_response_data.rb +3 -0
  52. data/lib/schematic/types/billing_credit_ledger_authority.rb +13 -0
  53. data/lib/schematic/types/billing_credit_view.rb +1 -0
  54. data/lib/schematic/types/billing_plan_credit_grant_response_data.rb +1 -0
  55. data/lib/schematic/types/billing_provider_type.rb +1 -0
  56. data/lib/schematic/types/change_subscription_internal_request_body.rb +1 -0
  57. data/lib/schematic/types/change_subscription_request_body.rb +1 -0
  58. data/lib/schematic/types/checkout_data_response_data.rb +1 -0
  59. data/lib/schematic/types/checkout_field_input.rb +14 -0
  60. data/lib/schematic/types/checkout_field_response_data.rb +18 -0
  61. data/lib/schematic/types/checkout_field_value.rb +10 -0
  62. data/lib/schematic/types/checkout_field_with_value.rb +15 -0
  63. data/lib/schematic/types/checkout_subscription.rb +1 -0
  64. data/lib/schematic/types/company_credit_balance_response_data.rb +2 -0
  65. data/lib/schematic/types/company_plan_credit_grant_view.rb +1 -0
  66. data/lib/schematic/types/company_plan_detail_response_data.rb +2 -1
  67. data/lib/schematic/types/component_hydrate_response_data.rb +1 -0
  68. data/lib/schematic/types/component_preview_response_data.rb +1 -0
  69. data/lib/schematic/types/create_billing_plan_credit_grant_request_body.rb +1 -0
  70. data/lib/schematic/types/create_entitlement_in_bundle_request_body.rb +1 -0
  71. data/lib/schematic/types/credit_company_grant_view.rb +3 -0
  72. data/lib/schematic/types/credit_event_ledger_response_data.rb +1 -0
  73. data/lib/schematic/types/credit_lease_response_data.rb +16 -0
  74. data/lib/schematic/types/credit_usage_reason.rb +15 -0
  75. data/lib/schematic/types/custom_plan_billing_response_data.rb +1 -0
  76. data/lib/schematic/types/event_body_track.rb +1 -0
  77. data/lib/schematic/types/event_detail_response_data.rb +1 -0
  78. data/lib/schematic/types/event_response_data.rb +1 -0
  79. data/lib/schematic/types/feature_view.rb +1 -0
  80. data/lib/schematic/types/install_integration_request_body.rb +14 -0
  81. data/lib/schematic/types/integration_config.rb +2 -0
  82. data/lib/schematic/types/integration_install_config.rb +18 -0
  83. data/lib/schematic/types/integration_install_response_data.rb +11 -0
  84. data/lib/schematic/types/integration_type.rb +2 -0
  85. data/lib/schematic/types/manage_plan_request.rb +1 -0
  86. data/lib/schematic/types/mark_custom_plan_billing_paid_request_body.rb +23 -0
  87. data/lib/schematic/types/metronome_integration_config.rb +7 -0
  88. data/lib/schematic/types/migration_error_code.rb +22 -0
  89. data/lib/schematic/types/plan_credit_grant_view.rb +1 -0
  90. data/lib/schematic/types/plan_detail_response_data.rb +1 -0
  91. data/lib/schematic/types/plan_entitlement_response_data.rb +1 -0
  92. data/lib/schematic/types/plan_group_detail_response_data.rb +1 -0
  93. data/lib/schematic/types/plan_group_plan_detail_response_data.rb +2 -1
  94. data/lib/schematic/types/plan_price_cadence.rb +13 -0
  95. data/lib/schematic/types/plan_version_company_migration_response_data.rb +1 -0
  96. data/lib/schematic/types/plan_version_migration_response_data.rb +1 -0
  97. data/lib/schematic/types/plan_view_public_response_data.rb +2 -1
  98. data/lib/schematic/types/release_credit_lease_request_body.rb +23 -0
  99. data/lib/schematic/types/stripe_integration_config.rb +0 -1
  100. data/lib/schematic/types/update_billing_plan_credit_grant_request_body.rb +1 -0
  101. data/lib/schematic/types/usage_based_entitlement_request_body.rb +1 -0
  102. data/lib/schematic/types/usage_based_entitlement_response_data.rb +1 -0
  103. data/lib/schematic/types/work_os_integration_config.rb +10 -0
  104. data/lib/schematic/version.rb +1 -1
  105. data/lib/schematic/wasm/rulesengine.wasm +0 -0
  106. data/lib/schematic.rb +38 -4
  107. data/reference.md +906 -73
  108. metadata +37 -3
@@ -176,13 +176,19 @@ module Schematic
176
176
  # Transform to capture service payload format (differs from Fern API):
177
177
  # - Field is `type` not `event_type`
178
178
  # - Each event includes `api_key`
179
+ # Optional metadata (idempotency_key, trusted_client_clock, backfill) is
180
+ # only included when the caller set it, so we never send explicit nulls.
179
181
  def event_to_capture_payload(event)
180
- {
182
+ payload = {
181
183
  api_key: @api_key,
182
184
  type: event[:event_type],
183
185
  body: event[:body],
184
186
  sent_at: event[:sent_at] || Time.now.utc.iso8601
185
187
  }
188
+ payload[:idempotency_key] = event[:idempotency_key] unless event[:idempotency_key].nil?
189
+ payload[:trusted_client_clock] = event[:trusted_client_clock] unless event[:trusted_client_clock].nil?
190
+ payload[:backfill] = event[:backfill] unless event[:backfill].nil?
191
+ payload
186
192
  end
187
193
  end
188
194
  end
@@ -124,6 +124,38 @@ module Schematic
124
124
  end
125
125
  end
126
126
 
127
+ # @param request_options [Hash]
128
+ # @param params [Schematic::Types::InstallIntegrationRequestBody]
129
+ # @option request_options [String] :base_url
130
+ # @option request_options [Hash{String => Object}] :additional_headers
131
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
132
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
133
+ # @option request_options [Integer] :timeout_in_seconds
134
+ #
135
+ # @return [Schematic::Integrationsapi::Types::InstallIntegrationResponse]
136
+ def install_integration(request_options: {}, **params)
137
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
138
+ request = Schematic::Internal::JSON::Request.new(
139
+ base_url: request_options[:base_url],
140
+ method: "POST",
141
+ path: "integrations/install",
142
+ body: Schematic::Types::InstallIntegrationRequestBody.new(params).to_h,
143
+ request_options: request_options
144
+ )
145
+ begin
146
+ response = @client.send(request)
147
+ rescue Net::HTTPRequestTimeout
148
+ raise Schematic::Errors::TimeoutError
149
+ end
150
+ code = response.code.to_i
151
+ if code.between?(200, 299)
152
+ Schematic::Integrationsapi::Types::InstallIntegrationResponse.load(response.body)
153
+ else
154
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
155
+ raise error_class.new(response.body, code: code)
156
+ end
157
+ end
158
+
127
159
  # @param request_options [Hash]
128
160
  # @param params [Schematic::Integrationsapi::Types::StartDataImportRequestBody]
129
161
  # @option request_options [String] :base_url
@@ -164,8 +196,8 @@ module Schematic
164
196
  # @option request_options [Hash{String => Object}] :additional_body_parameters
165
197
  # @option request_options [Integer] :timeout_in_seconds
166
198
  #
167
- # @return [Schematic::Integrationsapi::Types::LoadSampleDataSetV2Response]
168
- def load_sample_data_set_v_2(request_options: {}, **params)
199
+ # @return [Schematic::Integrationsapi::Types::LoadSampleDataSetResponse]
200
+ def load_sample_data_set(request_options: {}, **params)
169
201
  Schematic::Internal::Types::Utils.normalize_keys(params)
170
202
  request = Schematic::Internal::JSON::Request.new(
171
203
  base_url: request_options[:base_url],
@@ -180,7 +212,71 @@ module Schematic
180
212
  end
181
213
  code = response.code.to_i
182
214
  if code.between?(200, 299)
183
- Schematic::Integrationsapi::Types::LoadSampleDataSetV2Response.load(response.body)
215
+ Schematic::Integrationsapi::Types::LoadSampleDataSetResponse.load(response.body)
216
+ else
217
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
218
+ raise error_class.new(response.body, code: code)
219
+ end
220
+ end
221
+
222
+ # @param request_options [Hash]
223
+ # @param params [Schematic::Types::InstallIntegrationRequestBody]
224
+ # @option request_options [String] :base_url
225
+ # @option request_options [Hash{String => Object}] :additional_headers
226
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
227
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
228
+ # @option request_options [Integer] :timeout_in_seconds
229
+ #
230
+ # @return [Schematic::Integrationsapi::Types::AssumeStripeInstalledResponse]
231
+ def assume_stripe_installed(request_options: {}, **params)
232
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
233
+ request = Schematic::Internal::JSON::Request.new(
234
+ base_url: request_options[:base_url],
235
+ method: "POST",
236
+ path: "integrations/stripe/v2/assume-installed",
237
+ body: Schematic::Types::InstallIntegrationRequestBody.new(params).to_h,
238
+ request_options: request_options
239
+ )
240
+ begin
241
+ response = @client.send(request)
242
+ rescue Net::HTTPRequestTimeout
243
+ raise Schematic::Errors::TimeoutError
244
+ end
245
+ code = response.code.to_i
246
+ if code.between?(200, 299)
247
+ Schematic::Integrationsapi::Types::AssumeStripeInstalledResponse.load(response.body)
248
+ else
249
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
250
+ raise error_class.new(response.body, code: code)
251
+ end
252
+ end
253
+
254
+ # @param request_options [Hash]
255
+ # @param params [Schematic::Types::InstallIntegrationRequestBody]
256
+ # @option request_options [String] :base_url
257
+ # @option request_options [Hash{String => Object}] :additional_headers
258
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
259
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
260
+ # @option request_options [Integer] :timeout_in_seconds
261
+ #
262
+ # @return [Schematic::Integrationsapi::Types::InstallStripeResponse]
263
+ def install_stripe(request_options: {}, **params)
264
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
265
+ request = Schematic::Internal::JSON::Request.new(
266
+ base_url: request_options[:base_url],
267
+ method: "POST",
268
+ path: "integrations/stripe/v2/install",
269
+ body: Schematic::Types::InstallIntegrationRequestBody.new(params).to_h,
270
+ request_options: request_options
271
+ )
272
+ begin
273
+ response = @client.send(request)
274
+ rescue Net::HTTPRequestTimeout
275
+ raise Schematic::Errors::TimeoutError
276
+ end
277
+ code = response.code.to_i
278
+ if code.between?(200, 299)
279
+ Schematic::Integrationsapi::Types::InstallStripeResponse.load(response.body)
184
280
  else
185
281
  error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
186
282
  raise error_class.new(response.body, code: code)
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Integrationsapi
5
+ module Types
6
+ class AssumeStripeInstalledResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::IntegrationInstallResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Integrationsapi
5
+ module Types
6
+ class InstallIntegrationResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::IntegrationInstallResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Integrationsapi
5
+ module Types
6
+ class InstallStripeResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::IntegrationInstallResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -3,7 +3,7 @@
3
3
  module Schematic
4
4
  module Integrationsapi
5
5
  module Types
6
- class LoadSampleDataSetV2Response < Internal::Types::Model
6
+ class LoadSampleDataSetResponse < Internal::Types::Model
7
7
  field :data, -> { Schematic::Types::IntegrationsDataSetResponseData }, optional: false, nullable: false
8
8
  field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
9
  end
@@ -26,7 +26,7 @@ module Schematic
26
26
 
27
27
  attr_accessor :level
28
28
 
29
- def initialize(level: :info)
29
+ def initialize(level: :warn)
30
30
  @level = level
31
31
  @mutex = Mutex.new
32
32
  @io = $stderr
@@ -9,6 +9,7 @@ module Schematic
9
9
  field :checkout_collect_address, -> { Internal::Types::Boolean }, optional: false, nullable: false
10
10
  field :checkout_collect_email, -> { Internal::Types::Boolean }, optional: false, nullable: false
11
11
  field :checkout_collect_phone, -> { Internal::Types::Boolean }, optional: false, nullable: false
12
+ field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldInput] }, optional: true, nullable: false
12
13
  field :custom_plan_config, -> { Schematic::Types::CustomPlanConfig }, optional: true, nullable: false
13
14
  field :custom_plan_id, -> { String }, optional: true, nullable: false
14
15
  field :enable_tax_collection, -> { Internal::Types::Boolean }, optional: false, nullable: false
@@ -10,6 +10,7 @@ module Schematic
10
10
  field :checkout_collect_address, -> { Internal::Types::Boolean }, optional: false, nullable: false
11
11
  field :checkout_collect_email, -> { Internal::Types::Boolean }, optional: false, nullable: false
12
12
  field :checkout_collect_phone, -> { Internal::Types::Boolean }, optional: false, nullable: false
13
+ field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldInput] }, optional: true, nullable: false
13
14
  field :custom_plan_config, -> { Schematic::Types::CustomPlanConfig }, optional: true, nullable: false
14
15
  field :custom_plan_id, -> { String }, optional: true, nullable: false
15
16
  field :enable_tax_collection, -> { Internal::Types::Boolean }, optional: false, nullable: false
@@ -56,6 +56,38 @@ module Schematic
56
56
  end
57
57
  end
58
58
 
59
+ # @param request_options [Hash]
60
+ # @param params [Hash]
61
+ # @option request_options [String] :base_url
62
+ # @option request_options [Hash{String => Object}] :additional_headers
63
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
64
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
65
+ # @option request_options [Integer] :timeout_in_seconds
66
+ # @option params [String] :plan_version_company_migration_id
67
+ #
68
+ # @return [Schematic::Planmigrations::Types::RetryCompanyMigrationResponse]
69
+ def retry_company_migration(request_options: {}, **params)
70
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
71
+ request = Schematic::Internal::JSON::Request.new(
72
+ base_url: request_options[:base_url],
73
+ method: "POST",
74
+ path: "plan-version-company-migrations/#{URI.encode_uri_component(params[:plan_version_company_migration_id].to_s)}/retry",
75
+ request_options: request_options
76
+ )
77
+ begin
78
+ response = @client.send(request)
79
+ rescue Net::HTTPRequestTimeout
80
+ raise Schematic::Errors::TimeoutError
81
+ end
82
+ code = response.code.to_i
83
+ if code.between?(200, 299)
84
+ Schematic::Planmigrations::Types::RetryCompanyMigrationResponse.load(response.body)
85
+ else
86
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
87
+ raise error_class.new(response.body, code: code)
88
+ end
89
+ end
90
+
59
91
  # @param request_options [Hash]
60
92
  # @param params [Hash]
61
93
  # @option request_options [String] :base_url
@@ -146,6 +178,38 @@ module Schematic
146
178
  end
147
179
  end
148
180
 
181
+ # @param request_options [Hash]
182
+ # @param params [Schematic::Planmigrations::Types::CreateMigrationInput]
183
+ # @option request_options [String] :base_url
184
+ # @option request_options [Hash{String => Object}] :additional_headers
185
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
186
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
187
+ # @option request_options [Integer] :timeout_in_seconds
188
+ #
189
+ # @return [Schematic::Planmigrations::Types::CreateMigrationResponse]
190
+ def create_migration(request_options: {}, **params)
191
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
192
+ request = Schematic::Internal::JSON::Request.new(
193
+ base_url: request_options[:base_url],
194
+ method: "POST",
195
+ path: "plan-version-migrations",
196
+ body: Schematic::Planmigrations::Types::CreateMigrationInput.new(params).to_h,
197
+ request_options: request_options
198
+ )
199
+ begin
200
+ response = @client.send(request)
201
+ rescue Net::HTTPRequestTimeout
202
+ raise Schematic::Errors::TimeoutError
203
+ end
204
+ code = response.code.to_i
205
+ if code.between?(200, 299)
206
+ Schematic::Planmigrations::Types::CreateMigrationResponse.load(response.body)
207
+ else
208
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
209
+ raise error_class.new(response.body, code: code)
210
+ end
211
+ end
212
+
149
213
  # @param request_options [Hash]
150
214
  # @param params [Hash]
151
215
  # @option request_options [String] :base_url
@@ -178,6 +242,43 @@ module Schematic
178
242
  end
179
243
  end
180
244
 
245
+ # @param request_options [Hash]
246
+ # @param params [Schematic::Planmigrations::Types::RetryMigrationRequestBody]
247
+ # @option request_options [String] :base_url
248
+ # @option request_options [Hash{String => Object}] :additional_headers
249
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
250
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
251
+ # @option request_options [Integer] :timeout_in_seconds
252
+ # @option params [String] :plan_version_migration_id
253
+ #
254
+ # @return [Schematic::Planmigrations::Types::RetryMigrationResponse]
255
+ def retry_migration(request_options: {}, **params)
256
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
257
+ request_data = Schematic::Planmigrations::Types::RetryMigrationRequestBody.new(params).to_h
258
+ non_body_param_names = ["plan_version_migration_id"]
259
+ body = request_data.except(*non_body_param_names)
260
+
261
+ request = Schematic::Internal::JSON::Request.new(
262
+ base_url: request_options[:base_url],
263
+ method: "POST",
264
+ path: "plan-version-migrations/#{URI.encode_uri_component(params[:plan_version_migration_id].to_s)}/retry",
265
+ body: body,
266
+ request_options: request_options
267
+ )
268
+ begin
269
+ response = @client.send(request)
270
+ rescue Net::HTTPRequestTimeout
271
+ raise Schematic::Errors::TimeoutError
272
+ end
273
+ code = response.code.to_i
274
+ if code.between?(200, 299)
275
+ Schematic::Planmigrations::Types::RetryMigrationResponse.load(response.body)
276
+ else
277
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
278
+ raise error_class.new(response.body, code: code)
279
+ end
280
+ end
281
+
181
282
  # @param request_options [Hash]
182
283
  # @param params [Hash]
183
284
  # @option request_options [String] :base_url
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Planmigrations
5
+ module Types
6
+ class CreateMigrationInput < Internal::Types::Model
7
+ field :company_ids, -> { Internal::Types::Array[String] }, optional: false, nullable: false
8
+ field :excluded_company_ids, -> { Internal::Types::Array[String] }, optional: false, nullable: false
9
+ field :plan_id, -> { String }, optional: false, nullable: false
10
+ field :plan_version_id_to, -> { String }, optional: false, nullable: false
11
+ field :plan_version_ids_from, -> { Internal::Types::Array[String] }, optional: false, nullable: false
12
+ field :strategy, -> { Schematic::Types::PlanVersionMigrationStrategy }, optional: false, nullable: false
13
+ field :target_plan_type, -> { Schematic::Types::PlanType }, optional: false, nullable: false
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Planmigrations
5
+ module Types
6
+ class CreateMigrationResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::PlanVersionMigrationResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Planmigrations
5
+ module Types
6
+ class RetryCompanyMigrationResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::PlanVersionCompanyMigrationResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Planmigrations
5
+ module Types
6
+ class RetryMigrationRequestBody < Internal::Types::Model
7
+ field :plan_version_migration_id, -> { String }, optional: false, nullable: false
8
+ field :error_codes, -> { Internal::Types::Array[Schematic::Types::MigrationErrorCode] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Planmigrations
5
+ module Types
6
+ class RetryMigrationResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::PlanVersionMigrationResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -95,6 +95,39 @@ module Schematic
95
95
  end
96
96
  end
97
97
 
98
+ # @param request_options [Hash]
99
+ # @param params [Schematic::Types::MarkCustomPlanBillingPaidRequestBody]
100
+ # @option request_options [String] :base_url
101
+ # @option request_options [Hash{String => Object}] :additional_headers
102
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
103
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
104
+ # @option request_options [Integer] :timeout_in_seconds
105
+ # @option params [String] :custom_plan_billing_id
106
+ #
107
+ # @return [Schematic::Plans::Types::MarkCustomPlanBillingPaidResponse]
108
+ def mark_custom_plan_billing_paid(request_options: {}, **params)
109
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
110
+ request = Schematic::Internal::JSON::Request.new(
111
+ base_url: request_options[:base_url],
112
+ method: "PUT",
113
+ path: "custom-plan-billings/#{URI.encode_uri_component(params[:custom_plan_billing_id].to_s)}/mark-paid",
114
+ body: params,
115
+ request_options: request_options
116
+ )
117
+ begin
118
+ response = @client.send(request)
119
+ rescue Net::HTTPRequestTimeout
120
+ raise Schematic::Errors::TimeoutError
121
+ end
122
+ code = response.code.to_i
123
+ if code.between?(200, 299)
124
+ Schematic::Plans::Types::MarkCustomPlanBillingPaidResponse.load(response.body)
125
+ else
126
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
127
+ raise error_class.new(response.body, code: code)
128
+ end
129
+ end
130
+
98
131
  # @param request_options [Hash]
99
132
  # @param params [Schematic::Plans::Types::RetryCustomPlanBillingRequestBody]
100
133
  # @option request_options [String] :base_url
@@ -183,6 +216,7 @@ module Schematic
183
216
  # @option params [Schematic::Types::PlanType, nil] :plan_type
184
217
  # @option params [String, nil] :q
185
218
  # @option params [String, nil] :scoped_to_company_id
219
+ # @option params [Boolean, nil] :with_entitlements
186
220
  # @option params [String, nil] :without_entitlement_for
187
221
  # @option params [Boolean, nil] :without_paid_product_id
188
222
  # @option params [Integer, nil] :limit
@@ -191,7 +225,7 @@ module Schematic
191
225
  # @return [Schematic::Plans::Types::ListPlansResponse]
192
226
  def list_plans(request_options: {}, **params)
193
227
  params = Schematic::Internal::Types::Utils.normalize_keys(params)
194
- query_param_names = %i[company_id company_scoped_only exclude_company_scoped for_fallback_plan for_initial_plan for_trial_expiry_plan has_product_id ids include_draft_versions plan_type q scoped_to_company_id without_entitlement_for without_paid_product_id limit offset]
228
+ query_param_names = %i[company_id company_scoped_only exclude_company_scoped for_fallback_plan for_initial_plan for_trial_expiry_plan has_product_id ids include_draft_versions plan_type q scoped_to_company_id with_entitlements without_entitlement_for without_paid_product_id limit offset]
195
229
  query_params = {}
196
230
  query_params["company_id"] = params[:company_id] if params.key?(:company_id)
197
231
  query_params["company_scoped_only"] = params[:company_scoped_only] if params.key?(:company_scoped_only)
@@ -205,6 +239,7 @@ module Schematic
205
239
  query_params["plan_type"] = params[:plan_type] if params.key?(:plan_type)
206
240
  query_params["q"] = params[:q] if params.key?(:q)
207
241
  query_params["scoped_to_company_id"] = params[:scoped_to_company_id] if params.key?(:scoped_to_company_id)
242
+ query_params["with_entitlements"] = params[:with_entitlements] if params.key?(:with_entitlements)
208
243
  query_params["without_entitlement_for"] = params[:without_entitlement_for] if params.key?(:without_entitlement_for)
209
244
  query_params["without_paid_product_id"] = params[:without_paid_product_id] if params.key?(:without_paid_product_id)
210
245
  query_params["limit"] = params[:limit] if params.key?(:limit)
@@ -540,6 +575,7 @@ module Schematic
540
575
  # @option params [Schematic::Types::PlanType, nil] :plan_type
541
576
  # @option params [String, nil] :q
542
577
  # @option params [String, nil] :scoped_to_company_id
578
+ # @option params [Boolean, nil] :with_entitlements
543
579
  # @option params [String, nil] :without_entitlement_for
544
580
  # @option params [Boolean, nil] :without_paid_product_id
545
581
  # @option params [Integer, nil] :limit
@@ -548,7 +584,7 @@ module Schematic
548
584
  # @return [Schematic::Plans::Types::CountPlansResponse]
549
585
  def count_plans(request_options: {}, **params)
550
586
  params = Schematic::Internal::Types::Utils.normalize_keys(params)
551
- query_param_names = %i[company_id company_scoped_only exclude_company_scoped for_fallback_plan for_initial_plan for_trial_expiry_plan has_product_id ids include_draft_versions plan_type q scoped_to_company_id without_entitlement_for without_paid_product_id limit offset]
587
+ query_param_names = %i[company_id company_scoped_only exclude_company_scoped for_fallback_plan for_initial_plan for_trial_expiry_plan has_product_id ids include_draft_versions plan_type q scoped_to_company_id with_entitlements without_entitlement_for without_paid_product_id limit offset]
552
588
  query_params = {}
553
589
  query_params["company_id"] = params[:company_id] if params.key?(:company_id)
554
590
  query_params["company_scoped_only"] = params[:company_scoped_only] if params.key?(:company_scoped_only)
@@ -562,6 +598,7 @@ module Schematic
562
598
  query_params["plan_type"] = params[:plan_type] if params.key?(:plan_type)
563
599
  query_params["q"] = params[:q] if params.key?(:q)
564
600
  query_params["scoped_to_company_id"] = params[:scoped_to_company_id] if params.key?(:scoped_to_company_id)
601
+ query_params["with_entitlements"] = params[:with_entitlements] if params.key?(:with_entitlements)
565
602
  query_params["without_entitlement_for"] = params[:without_entitlement_for] if params.key?(:without_entitlement_for)
566
603
  query_params["without_paid_product_id"] = params[:without_paid_product_id] if params.key?(:without_paid_product_id)
567
604
  query_params["limit"] = params[:limit] if params.key?(:limit)
@@ -19,6 +19,7 @@ module Schematic
19
19
  field :plan_type, -> { Schematic::Types::PlanType }, optional: true, nullable: false
20
20
  field :q, -> { String }, optional: true, nullable: false
21
21
  field :scoped_to_company_id, -> { String }, optional: true, nullable: false
22
+ field :with_entitlements, -> { Internal::Types::Boolean }, optional: true, nullable: false
22
23
  field :without_entitlement_for, -> { String }, optional: true, nullable: false
23
24
  field :without_paid_product_id, -> { Internal::Types::Boolean }, optional: true, nullable: false
24
25
  end
@@ -16,6 +16,7 @@ module Schematic
16
16
  field :plan_type, -> { Schematic::Types::PlanType }, optional: true, nullable: false
17
17
  field :q, -> { String }, optional: true, nullable: false
18
18
  field :scoped_to_company_id, -> { String }, optional: true, nullable: false
19
+ field :with_entitlements, -> { Internal::Types::Boolean }, optional: true, nullable: false
19
20
  field :without_entitlement_for, -> { String }, optional: true, nullable: false
20
21
  field :without_paid_product_id, -> { Internal::Types::Boolean }, optional: true, nullable: false
21
22
  field :limit, -> { Integer }, optional: true, nullable: false
@@ -19,6 +19,7 @@ module Schematic
19
19
  field :plan_type, -> { Schematic::Types::PlanType }, optional: true, nullable: false
20
20
  field :q, -> { String }, optional: true, nullable: false
21
21
  field :scoped_to_company_id, -> { String }, optional: true, nullable: false
22
+ field :with_entitlements, -> { Internal::Types::Boolean }, optional: true, nullable: false
22
23
  field :without_entitlement_for, -> { String }, optional: true, nullable: false
23
24
  field :without_paid_product_id, -> { Internal::Types::Boolean }, optional: true, nullable: false
24
25
  end
@@ -16,6 +16,7 @@ module Schematic
16
16
  field :plan_type, -> { Schematic::Types::PlanType }, optional: true, nullable: false
17
17
  field :q, -> { String }, optional: true, nullable: false
18
18
  field :scoped_to_company_id, -> { String }, optional: true, nullable: false
19
+ field :with_entitlements, -> { Internal::Types::Boolean }, optional: true, nullable: false
19
20
  field :without_entitlement_for, -> { String }, optional: true, nullable: false
20
21
  field :without_paid_product_id, -> { Internal::Types::Boolean }, optional: true, nullable: false
21
22
  field :limit, -> { Integer }, optional: true, nullable: false
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Plans
5
+ module Types
6
+ class MarkCustomPlanBillingPaidResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::CustomPlanBillingResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -56,6 +56,12 @@ module Schematic
56
56
  DEFAULT_CACHE_MAX_SIZE = 1000
57
57
  DEFAULT_EVENT_BUFFER_PERIOD = 5.0 # seconds (canonical Go value)
58
58
 
59
+ # Optional event metadata accepted via the `options:` keyword on track/identify.
60
+ # identify only honors :idempotency_key; track also honors :sent_at,
61
+ # :trusted_client_clock, and :backfill. Fields are only sent when set.
62
+ TRACK_OPTION_KEYS = %i[idempotency_key sent_at trusted_client_clock backfill].freeze
63
+ IDENTIFY_OPTION_KEYS = %i[idempotency_key].freeze
64
+
59
65
  def initialize(
60
66
  api_key: nil,
61
67
  base_url: nil,
@@ -67,7 +73,7 @@ module Schematic
67
73
  use_data_stream: false,
68
74
  datastream_options: {},
69
75
  logger: nil,
70
- log_level: :info
76
+ log_level: :warn
71
77
  )
72
78
  @api_key = api_key
73
79
  @base_url = base_url || DEFAULT_BASE_URL
@@ -251,26 +257,18 @@ module Schematic
251
257
 
252
258
  # --- Event Submission ---
253
259
 
254
- def identify(body)
260
+ def identify(body, options: nil)
255
261
  return if @offline
256
262
 
257
- @event_buffer.push({
258
- event_type: "identify",
259
- body: body,
260
- sent_at: Time.now.utc.iso8601
261
- })
263
+ @event_buffer.push(build_event("identify", body, options, IDENTIFY_OPTION_KEYS))
262
264
  rescue StandardError => e
263
265
  @logger.error("Error sending identify event: #{e.message}")
264
266
  end
265
267
 
266
- def track(body)
268
+ def track(body, options: nil)
267
269
  return if @offline
268
270
 
269
- @event_buffer.push({
270
- event_type: "track",
271
- body: body,
272
- sent_at: Time.now.utc.iso8601
273
- })
271
+ @event_buffer.push(build_event("track", body, options, TRACK_OPTION_KEYS))
274
272
 
275
273
  # Update company metrics locally if DataStream is active and connected
276
274
  if @datastream_client&.connected? && body[:company]
@@ -495,6 +493,41 @@ module Schematic
495
493
  results
496
494
  end
497
495
 
496
+ # Build the buffered event hash, applying any caller-supplied options.
497
+ # Only keys in allowed_keys are honored, and only when explicitly set, so
498
+ # unset fields never appear on the wire.
499
+ def build_event(event_type, body, options, allowed_keys)
500
+ event = {
501
+ event_type: event_type,
502
+ body: body,
503
+ sent_at: Time.now.utc.iso8601
504
+ }
505
+ return event unless options.is_a?(Hash)
506
+
507
+ allowed_keys.each do |key|
508
+ value = option_value(options, key)
509
+ next if value.nil?
510
+
511
+ event[key] = key == :sent_at ? normalize_sent_at(value) : value
512
+ end
513
+
514
+ event
515
+ end
516
+
517
+ def option_value(options, key)
518
+ return options[key] if options.key?(key)
519
+
520
+ options[key.to_s]
521
+ end
522
+
523
+ def normalize_sent_at(value)
524
+ return value if value.is_a?(String)
525
+ return value.utc.iso8601 if value.respond_to?(:utc)
526
+ return value.iso8601 if value.respond_to?(:iso8601)
527
+
528
+ value
529
+ end
530
+
498
531
  def enqueue_flag_check_event(flag_key, response, company, user)
499
532
  body = {
500
533
  flag_key: flag_key,