schematichq 1.4.2 → 1.4.3

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 (65) 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/billing/client.rb +32 -0
  6. data/lib/schematic/billing/types/delete_payment_method_by_external_id_response.rb +12 -0
  7. data/lib/schematic/client.rb +1 -1
  8. data/lib/schematic/companies/client.rb +6 -2
  9. data/lib/schematic/companies/types/count_companies_params.rb +1 -0
  10. data/lib/schematic/companies/types/count_companies_request.rb +1 -0
  11. data/lib/schematic/companies/types/list_companies_params.rb +1 -0
  12. data/lib/schematic/companies/types/list_companies_request.rb +1 -0
  13. data/lib/schematic/credits/client.rb +102 -0
  14. data/lib/schematic/credits/types/acquire_credit_lease_request_body.rb +14 -0
  15. data/lib/schematic/credits/types/acquire_credit_lease_response.rb +12 -0
  16. data/lib/schematic/credits/types/extend_credit_lease_request_body.rb +13 -0
  17. data/lib/schematic/credits/types/extend_credit_lease_response.rb +12 -0
  18. data/lib/schematic/credits/types/release_credit_lease_response.rb +12 -0
  19. data/lib/schematic/datastream/merge.rb +71 -0
  20. data/lib/schematic/entitlements/types/create_billing_linked_plan_entitlement_request_body.rb +1 -0
  21. data/lib/schematic/entitlements/types/create_plan_entitlement_request_body.rb +1 -0
  22. data/lib/schematic/entitlements/types/update_plan_entitlement_request_body.rb +1 -0
  23. data/lib/schematic/event_buffer.rb +7 -1
  24. data/lib/schematic/logger.rb +1 -1
  25. data/lib/schematic/planmigrations/client.rb +101 -0
  26. data/lib/schematic/planmigrations/types/create_migration_input.rb +17 -0
  27. data/lib/schematic/planmigrations/types/create_migration_response.rb +12 -0
  28. data/lib/schematic/planmigrations/types/retry_company_migration_response.rb +12 -0
  29. data/lib/schematic/planmigrations/types/retry_migration_request_body.rb +12 -0
  30. data/lib/schematic/planmigrations/types/retry_migration_response.rb +12 -0
  31. data/lib/schematic/plans/client.rb +39 -2
  32. data/lib/schematic/plans/types/count_plans_params.rb +1 -0
  33. data/lib/schematic/plans/types/count_plans_request.rb +1 -0
  34. data/lib/schematic/plans/types/list_plans_params.rb +1 -0
  35. data/lib/schematic/plans/types/list_plans_request.rb +1 -0
  36. data/lib/schematic/plans/types/mark_custom_plan_billing_paid_response.rb +12 -0
  37. data/lib/schematic/schematic_client.rb +46 -13
  38. data/lib/schematic/types/checkout_subscription.rb +1 -0
  39. data/lib/schematic/types/company_plan_detail_response_data.rb +2 -1
  40. data/lib/schematic/types/create_entitlement_in_bundle_request_body.rb +1 -0
  41. data/lib/schematic/types/credit_lease_response_data.rb +16 -0
  42. data/lib/schematic/types/custom_plan_billing_response_data.rb +1 -0
  43. data/lib/schematic/types/event_body_track.rb +1 -0
  44. data/lib/schematic/types/feature_view.rb +1 -0
  45. data/lib/schematic/types/integration_config.rb +1 -0
  46. data/lib/schematic/types/integration_type.rb +1 -0
  47. data/lib/schematic/types/mark_custom_plan_billing_paid_request_body.rb +23 -0
  48. data/lib/schematic/types/migration_error_code.rb +21 -0
  49. data/lib/schematic/types/plan_detail_response_data.rb +1 -0
  50. data/lib/schematic/types/plan_entitlement_response_data.rb +1 -0
  51. data/lib/schematic/types/plan_group_plan_detail_response_data.rb +2 -1
  52. data/lib/schematic/types/plan_price_cadence.rb +13 -0
  53. data/lib/schematic/types/plan_version_company_migration_response_data.rb +1 -0
  54. data/lib/schematic/types/plan_version_migration_response_data.rb +1 -0
  55. data/lib/schematic/types/plan_view_public_response_data.rb +2 -1
  56. data/lib/schematic/types/release_credit_lease_request_body.rb +23 -0
  57. data/lib/schematic/types/stripe_integration_config.rb +0 -1
  58. data/lib/schematic/types/usage_based_entitlement_request_body.rb +1 -0
  59. data/lib/schematic/types/usage_based_entitlement_response_data.rb +1 -0
  60. data/lib/schematic/types/work_os_integration_config.rb +10 -0
  61. data/lib/schematic/version.rb +1 -1
  62. data/lib/schematic/wasm/rulesengine.wasm +0 -0
  63. data/lib/schematic.rb +18 -0
  64. data/reference.md +582 -2
  65. metadata +20 -2
@@ -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,
@@ -16,6 +16,7 @@ module Schematic
16
16
  field :expired_at, -> { String }, optional: true, nullable: false
17
17
  field :id, -> { String }, optional: false, nullable: false
18
18
  field :interval, -> { String }, optional: false, nullable: false
19
+ field :invoice_id, -> { String }, optional: true, nullable: false
19
20
  field :invoice_url, -> { String }, optional: true, nullable: false
20
21
  field :metadata, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false
21
22
  field :period_end, -> { Integer }, optional: false, nullable: false
@@ -5,6 +5,7 @@ module Schematic
5
5
  class CompanyPlanDetailResponseData < Internal::Types::Model
6
6
  field :active_version, -> { Schematic::Types::PlanVersionResponseData }, optional: true, nullable: false
7
7
  field :audience_type, -> { String }, optional: true, nullable: false
8
+ field :available_periods, -> { Internal::Types::Array[Schematic::Types::PlanPriceCadence] }, optional: false, nullable: false
8
9
  field :billing_linked_resource, -> { Schematic::Types::BillingLinkedResourceResponseData }, optional: true, nullable: false
9
10
  field :billing_product, -> { Schematic::Types::BillingProductDetailResponseData }, optional: true, nullable: false
10
11
  field :billing_strategy, -> { Schematic::Types::BillingStrategy }, optional: false, nullable: false
@@ -23,7 +24,7 @@ module Schematic
23
24
  field :custom_plan_config, -> { Schematic::Types::CustomPlanConfig }, optional: true, nullable: false
24
25
  field :description, -> { String }, optional: false, nullable: false
25
26
  field :draft_version, -> { Schematic::Types::PlanVersionResponseData }, optional: true, nullable: false
26
- field :entitlements, -> { Internal::Types::Array[Schematic::Types::PlanEntitlementResponseData] }, optional: false, nullable: false
27
+ field :entitlements, -> { Internal::Types::Array[Schematic::Types::PlanEntitlementResponseData] }, optional: true, nullable: false
27
28
  field :features, -> { Internal::Types::Array[Schematic::Types::FeatureInPlanResponseData] }, optional: false, nullable: false
28
29
  field :icon, -> { Schematic::Types::PlanIcon }, optional: false, nullable: false
29
30
  field :id, -> { String }, optional: false, nullable: false
@@ -26,6 +26,7 @@ module Schematic
26
26
  field :quarterly_unit_price_decimal, -> { String }, optional: true, nullable: false
27
27
  field :soft_limit, -> { Integer }, optional: true, nullable: false
28
28
  field :tier_mode, -> { Schematic::Types::BillingTiersMode }, optional: true, nullable: false
29
+ field :usage_quantity, -> { Integer }, optional: true, nullable: false
29
30
  field :value_bool, -> { Internal::Types::Boolean }, optional: true, nullable: false
30
31
  field :value_credit_id, -> { String }, optional: true, nullable: false
31
32
  field :value_numeric, -> { Integer }, optional: true, nullable: false
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Types
5
+ class CreditLeaseResponseData < Internal::Types::Model
6
+ field :company_id, -> { String }, optional: false, nullable: false
7
+ field :created_at, -> { String }, optional: false, nullable: false
8
+ field :credit_type_id, -> { String }, optional: false, nullable: false
9
+ field :expires_at, -> { String }, optional: false, nullable: false
10
+ field :granted_amount, -> { Integer }, optional: false, nullable: false
11
+ field :id, -> { String }, optional: false, nullable: false
12
+ field :released_at, -> { String }, optional: true, nullable: false
13
+ field :updated_at, -> { String }, optional: false, nullable: false
14
+ end
15
+ end
16
+ end
@@ -7,6 +7,7 @@ module Schematic
7
7
  field :company_id, -> { String }, optional: false, nullable: false
8
8
  field :created_at, -> { String }, optional: false, nullable: false
9
9
  field :days_until_due, -> { Integer }, optional: false, nullable: false
10
+ field :external_invoice_id, -> { String }, optional: true, nullable: false
10
11
  field :id, -> { String }, optional: false, nullable: false
11
12
  field :paid_at, -> { String }, optional: true, nullable: false
12
13
  field :plan_id, -> { String }, optional: false, nullable: false
@@ -5,6 +5,7 @@ module Schematic
5
5
  class EventBodyTrack < Internal::Types::Model
6
6
  field :company, -> { Internal::Types::Hash[String, String] }, optional: true, nullable: false
7
7
  field :event, -> { String }, optional: false, nullable: false
8
+ field :lease_id, -> { String }, optional: true, nullable: false
8
9
  field :quantity, -> { Integer }, optional: true, nullable: false
9
10
  field :traits, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false
10
11
  field :user, -> { Internal::Types::Hash[String, String] }, optional: true, nullable: false
@@ -21,6 +21,7 @@ module Schematic
21
21
  field :trait, -> { Schematic::Types::EntityTraitDefinitionResponseData }, optional: true, nullable: false
22
22
  field :trait_id, -> { String }, optional: true, nullable: false
23
23
  field :updated_at, -> { String }, optional: false, nullable: false
24
+ field :usage_limit_trait_id, -> { String }, optional: true, nullable: false
24
25
  end
25
26
  end
26
27
  end
@@ -10,6 +10,7 @@ module Schematic
10
10
  member -> { Schematic::Types::ClerkIntegrationConfig }, key: "CLERK"
11
11
  member -> { Schematic::Types::OrbIntegrationConfig }, key: "ORB"
12
12
  member -> { Schematic::Types::StripeIntegrationConfig }, key: "STRIPE"
13
+ member -> { Schematic::Types::WorkOsIntegrationConfig }, key: "WORKOS"
13
14
  end
14
15
  end
15
16
  end
@@ -9,6 +9,7 @@ module Schematic
9
9
  ORB = "orb"
10
10
  STRIPE = "stripe"
11
11
  UNKNOWN = "unknown"
12
+ WORKOS = "workos"
12
13
  end
13
14
  end
14
15
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Types
5
+ module MarkCustomPlanBillingPaidRequestBody
6
+ # MarkCustomPlanBillingPaidRequestBody is an alias for Hash
7
+
8
+ # @option str [String]
9
+ #
10
+ # @return [untyped]
11
+ def self.load(str)
12
+ ::JSON.parse(str)
13
+ end
14
+
15
+ # @option value [untyped]
16
+ #
17
+ # @return [String]
18
+ def self.dump(value)
19
+ ::JSON.generate(value)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Types
5
+ module MigrationErrorCode
6
+ extend Schematic::Internal::Types::Enum
7
+
8
+ AMBIGUOUS_SUBSCRIPTION_ITEM = "ambiguous_subscription_item"
9
+ MULTIPLE_SUBSCRIPTIONS = "multiple_subscriptions"
10
+ NO_PRICE_FOR_INTERVAL = "no_price_for_interval"
11
+ NOT_ON_ORIGIN_VERSION = "not_on_origin_version"
12
+ PERMANENT_CONFIG = "permanent_config"
13
+ PERMANENT_DECLINE = "permanent_decline"
14
+ TRANSIENT_DECLINE = "transient_decline"
15
+ TRANSIENT_INFRA = "transient_infra"
16
+ TRANSIENT_STRIPE = "transient_stripe"
17
+ UNKNOWN = "unknown"
18
+ WOULD_LEAVE_EMPTY_SUBSCRIPTION = "would_leave_empty_subscription"
19
+ end
20
+ end
21
+ end
@@ -18,6 +18,7 @@ module Schematic
18
18
  field :currency_prices, -> { Internal::Types::Array[Schematic::Types::PlanCurrencyPricesResponseData] }, optional: false, nullable: false
19
19
  field :description, -> { String }, optional: false, nullable: false
20
20
  field :draft_version, -> { Schematic::Types::PlanVersionResponseData }, optional: true, nullable: false
21
+ field :entitlements, -> { Internal::Types::Array[Schematic::Types::PlanEntitlementResponseData] }, optional: true, nullable: false
21
22
  field :features, -> { Internal::Types::Array[Schematic::Types::FeatureInPlanResponseData] }, optional: false, nullable: false
22
23
  field :icon, -> { Schematic::Types::PlanIcon }, optional: false, nullable: false
23
24
  field :id, -> { String }, optional: false, nullable: false
@@ -25,6 +25,7 @@ module Schematic
25
25
  field :soft_limit, -> { Integer }, optional: true, nullable: false
26
26
  field :updated_at, -> { String }, optional: false, nullable: false
27
27
  field :usage_based_product, -> { Schematic::Types::BillingProductResponseData }, optional: true, nullable: false
28
+ field :usage_quantity, -> { Integer }, optional: true, nullable: false
28
29
  field :value_bool, -> { Internal::Types::Boolean }, optional: true, nullable: false
29
30
  field :value_credit, -> { Schematic::Types::BillingCreditResponseData }, optional: true, nullable: false
30
31
  field :value_numeric, -> { Integer }, optional: true, nullable: false
@@ -5,6 +5,7 @@ module Schematic
5
5
  class PlanGroupPlanDetailResponseData < Internal::Types::Model
6
6
  field :active_version, -> { Schematic::Types::PlanVersionResponseData }, optional: true, nullable: false
7
7
  field :audience_type, -> { String }, optional: true, nullable: false
8
+ field :available_periods, -> { Internal::Types::Array[Schematic::Types::PlanPriceCadence] }, optional: false, nullable: false
8
9
  field :billing_linked_resource, -> { Schematic::Types::BillingLinkedResourceResponseData }, optional: true, nullable: false
9
10
  field :billing_product, -> { Schematic::Types::BillingProductDetailResponseData }, optional: true, nullable: false
10
11
  field :billing_strategy, -> { Schematic::Types::BillingStrategy }, optional: false, nullable: false
@@ -20,7 +21,7 @@ module Schematic
20
21
  field :custom_plan_config, -> { Schematic::Types::CustomPlanViewConfigResponseData }, optional: true, nullable: false
21
22
  field :description, -> { String }, optional: false, nullable: false
22
23
  field :draft_version, -> { Schematic::Types::PlanVersionResponseData }, optional: true, nullable: false
23
- field :entitlements, -> { Internal::Types::Array[Schematic::Types::PlanEntitlementResponseData] }, optional: false, nullable: false
24
+ field :entitlements, -> { Internal::Types::Array[Schematic::Types::PlanEntitlementResponseData] }, optional: true, nullable: false
24
25
  field :features, -> { Internal::Types::Array[Schematic::Types::FeatureInPlanResponseData] }, optional: false, nullable: false
25
26
  field :icon, -> { Schematic::Types::PlanIcon }, optional: false, nullable: false
26
27
  field :id, -> { String }, optional: false, nullable: false
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Types
5
+ module PlanPriceCadence
6
+ extend Schematic::Internal::Types::Enum
7
+
8
+ MONTHLY = "monthly"
9
+ QUARTERLY = "quarterly"
10
+ YEARLY = "yearly"
11
+ end
12
+ end
13
+ end
@@ -8,6 +8,7 @@ module Schematic
8
8
  field :completed_at, -> { String }, optional: true, nullable: false
9
9
  field :created_at, -> { String }, optional: false, nullable: false
10
10
  field :error, -> { String }, optional: true, nullable: false
11
+ field :error_code, -> { Schematic::Types::MigrationErrorCode }, optional: true, nullable: false
11
12
  field :id, -> { String }, optional: false, nullable: false
12
13
  field :migration_id, -> { String }, optional: false, nullable: false
13
14
  field :plan_version_id_from, -> { String }, optional: true, nullable: false
@@ -12,6 +12,7 @@ module Schematic
12
12
  field :plan_id, -> { String }, optional: false, nullable: false
13
13
  field :plan_version_id_from, -> { String }, optional: true, nullable: false
14
14
  field :plan_version_id_to, -> { String }, optional: false, nullable: false
15
+ field :plan_version_ids_from, -> { Internal::Types::Array[String] }, optional: false, nullable: false
15
16
  field :skipped_companies, -> { Integer }, optional: false, nullable: false
16
17
  field :started_at, -> { String }, optional: true, nullable: false
17
18
  field :status, -> { Schematic::Types::PlanVersionMigrationStatus }, optional: false, nullable: false