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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d21af200007a5f9fad7ebc682971bbad191e98c0b5f7cd10b691627651069c7
4
- data.tar.gz: e944d620948b8acdb24d375eed9365982edf50c8ff089a6f4c74821cbb88a4c3
3
+ metadata.gz: beede11cf31a32d41acacecfcf43f24d415952cc1bfc02ae762593885d804030
4
+ data.tar.gz: ca42025157214fcc6b06ce6313ce591ed78d7f9e49f033f6aad432dcef691097
5
5
  SHA512:
6
- metadata.gz: 980692b9e74fbbf6683623e2502bd5ef153d78f5c20245bdb5d3cc26787eaa142f6ac345ba5873acfb29a2fa93a2e0c0beab40717c692e5f3154d731219fad9d
7
- data.tar.gz: 0f16bc4c9d391123750a85530d21a7a4a841cf8962d2cc867912f2935f0627e732cbff5c1c56ed677302704636290f962794066c18d9cb6f4e2d74dc63f3890d
6
+ metadata.gz: f36aa806e79e4dc3c547fd9580b021f616c1b187c659eb7f0784e28983cc5a1bf74f6c32b32edbca0234d0df3372b34aefb6974c0f2e21a059c6bfd56e91682d
7
+ data.tar.gz: e8fb63d038eedf92d7fd992b18cd94931d599abe632640cb44b482eada7161392c8a373e18494b44c5acfbba3909ef1b4b61d3120763538630d68c0ceb9a7105
data/.fern/metadata.json CHANGED
@@ -13,6 +13,6 @@
13
13
  "webrick": ">= 1.0"
14
14
  }
15
15
  },
16
- "originGitCommit": "3dc12b536625ca1efbb649f6c55df7da258c7e05",
17
- "sdkVersion": "1.4.2"
16
+ "originGitCommit": "ad1cc528e658e3693935b819c9d22eed02d49017",
17
+ "sdkVersion": "1.4.4"
18
18
  }
data/README.md CHANGED
@@ -127,7 +127,7 @@ client = Schematic::SchematicClient.new(
127
127
  client.close
128
128
  ```
129
129
 
130
- You can also adjust the log level of the built-in console logger:
130
+ You can also adjust the log level of the built-in console logger via the `log_level` option:
131
131
 
132
132
  ```ruby
133
133
  require "schematichq"
@@ -135,11 +135,11 @@ require "schematichq"
135
135
  api_key = ENV["SCHEMATIC_API_KEY"]
136
136
  client = Schematic::SchematicClient.new(
137
137
  api_key: api_key,
138
- logger: Schematic::ConsoleLogger.new(level: :debug)
138
+ log_level: :debug
139
139
  )
140
140
  ```
141
141
 
142
- If no logger is provided, the client will use a default console logger at the `:info` level that outputs to stderr.
142
+ If no logger is provided, the client will use a default console logger at the `:warn` level that outputs to stderr. The `log_level` option only applies to this built-in logger; when you supply your own `logger`, its level is left untouched.
143
143
 
144
144
  ## Usage Examples
145
145
 
@@ -216,6 +216,36 @@ client.track({
216
216
  })
217
217
  ```
218
218
 
219
+ #### Event options
220
+
221
+ Both `track` and `identify` accept an `options:` keyword for optional event metadata. Only fields you set are sent.
222
+
223
+ ```ruby
224
+ client.track(
225
+ { event: "query-tokens", company: { "id" => "your-company-id" }, quantity: 1500 },
226
+ options: {
227
+ # Dedupe key. Duplicate events with the same key are dropped
228
+ # server-side for 24 hours.
229
+ idempotency_key: "evt_2026_05_21_query_tokens",
230
+ # Timestamp the event occurred (Time or ISO 8601 String). Required
231
+ # when trusted_client_clock is true.
232
+ sent_at: Time.now.utc,
233
+ # Use sent_at as the effective event time instead of server receipt
234
+ # time. Requires a secret API key and sent_at.
235
+ trusted_client_clock: true,
236
+ # Import historical data without affecting billing. Requires a secret
237
+ # API key and trusted_client_clock.
238
+ backfill: false
239
+ }
240
+ )
241
+
242
+ client.identify(
243
+ { keys: { "user_id" => "your-user-id" }, name: "Wile E. Coyote" },
244
+ # identify only supports idempotency_key.
245
+ options: { idempotency_key: "ident_your-user-id" }
246
+ )
247
+ ```
248
+
219
249
  ### Creating and updating companies
220
250
 
221
251
  Although it is faster to create companies and users via identify events, if you need to handle a response, you can use the companies API to upsert companies. Because you use your own identifiers to identify companies, rather than a Schematic company ID, creating and updating companies are both done via the same upsert operation:
data/WASM_VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.3.0
@@ -86,6 +86,50 @@ module Schematic
86
86
  end
87
87
  end
88
88
 
89
+ # @param request_options [Hash]
90
+ # @param params [Hash]
91
+ # @option request_options [String] :base_url
92
+ # @option request_options [Hash{String => Object}] :additional_headers
93
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
94
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
95
+ # @option request_options [Integer] :timeout_in_seconds
96
+ # @option params [String, nil] :ids
97
+ # @option params [String, nil] :q
98
+ # @option params [Integer, nil] :limit
99
+ # @option params [Integer, nil] :offset
100
+ #
101
+ # @return [Schematic::Accounts::Types::CountAccountMembersResponse]
102
+ def count_account_members(request_options: {}, **params)
103
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
104
+ query_param_names = %i[ids q limit offset]
105
+ query_params = {}
106
+ query_params["ids"] = params[:ids] if params.key?(:ids)
107
+ query_params["q"] = params[:q] if params.key?(:q)
108
+ query_params["limit"] = params[:limit] if params.key?(:limit)
109
+ query_params["offset"] = params[:offset] if params.key?(:offset)
110
+ params.except(*query_param_names)
111
+
112
+ request = Schematic::Internal::JSON::Request.new(
113
+ base_url: request_options[:base_url],
114
+ method: "GET",
115
+ path: "account-members/count",
116
+ query: query_params,
117
+ request_options: request_options
118
+ )
119
+ begin
120
+ response = @client.send(request)
121
+ rescue Net::HTTPRequestTimeout
122
+ raise Schematic::Errors::TimeoutError
123
+ end
124
+ code = response.code.to_i
125
+ if code.between?(200, 299)
126
+ Schematic::Accounts::Types::CountAccountMembersResponse.load(response.body)
127
+ else
128
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
129
+ raise error_class.new(response.body, code: code)
130
+ end
131
+ end
132
+
89
133
  # @param request_options [Hash]
90
134
  # @param params [Hash]
91
135
  # @option request_options [String] :base_url
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Accounts
5
+ module Types
6
+ # Input parameters
7
+ class CountAccountMembersParams < Internal::Types::Model
8
+ field :ids, -> { Internal::Types::Array[String] }, optional: true, nullable: false
9
+ field :limit, -> { Integer }, optional: true, nullable: false
10
+ field :offset, -> { Integer }, optional: true, nullable: false
11
+ field :q, -> { String }, optional: true, nullable: false
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Accounts
5
+ module Types
6
+ class CountAccountMembersRequest < Internal::Types::Model
7
+ field :ids, -> { String }, optional: true, nullable: false
8
+ field :q, -> { String }, optional: true, nullable: false
9
+ field :limit, -> { Integer }, optional: true, nullable: false
10
+ field :offset, -> { Integer }, optional: true, nullable: false
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Accounts
5
+ module Types
6
+ class CountAccountMembersResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::CountResponse }, optional: false, nullable: false
8
+ field :params, -> { Schematic::Accounts::Types::CountAccountMembersParams }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -442,6 +442,38 @@ module Schematic
442
442
  end
443
443
  end
444
444
 
445
+ # @param request_options [Hash]
446
+ # @param params [Hash]
447
+ # @option request_options [String] :base_url
448
+ # @option request_options [Hash{String => Object}] :additional_headers
449
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
450
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
451
+ # @option request_options [Integer] :timeout_in_seconds
452
+ # @option params [String] :billing_id
453
+ #
454
+ # @return [Schematic::Billing::Types::DeletePaymentMethodByExternalIdResponse]
455
+ def delete_payment_method_by_external_id(request_options: {}, **params)
456
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
457
+ request = Schematic::Internal::JSON::Request.new(
458
+ base_url: request_options[:base_url],
459
+ method: "DELETE",
460
+ path: "billing/payment-methods/#{URI.encode_uri_component(params[:billing_id].to_s)}",
461
+ request_options: request_options
462
+ )
463
+ begin
464
+ response = @client.send(request)
465
+ rescue Net::HTTPRequestTimeout
466
+ raise Schematic::Errors::TimeoutError
467
+ end
468
+ code = response.code.to_i
469
+ if code.between?(200, 299)
470
+ Schematic::Billing::Types::DeletePaymentMethodByExternalIdResponse.load(response.body)
471
+ else
472
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
473
+ raise error_class.new(response.body, code: code)
474
+ end
475
+ end
476
+
445
477
  # @param request_options [Hash]
446
478
  # @param params [Hash]
447
479
  # @option request_options [String] :base_url
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Billing
5
+ module Types
6
+ class DeletePaymentMethodByExternalIdResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::DeleteResponse }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -10,7 +10,7 @@ module Schematic
10
10
  @raw_client = Schematic::Internal::Http::RawClient.new(
11
11
  base_url: base_url || Schematic::Environment::DEFAULT,
12
12
  headers: {
13
- "User-Agent" => "schematichq/1.4.2",
13
+ "User-Agent" => "schematichq/1.4.4",
14
14
  "X-Fern-Language" => "Ruby",
15
15
  "X-Schematic-Api-Key" => api_key.to_s
16
16
  }
@@ -24,6 +24,7 @@ module Schematic
24
24
  # @option params [String, nil] :plan_id
25
25
  # @option params [String, nil] :plan_ids
26
26
  # @option params [String, nil] :plan_version_id
27
+ # @option params [String, nil] :plan_version_ids
27
28
  # @option params [String, nil] :q
28
29
  # @option params [String, nil] :sort_order_column
29
30
  # @option params [Schematic::Types::SortDirection, nil] :sort_order_direction
@@ -40,7 +41,7 @@ module Schematic
40
41
  # @return [Schematic::Companies::Types::ListCompaniesResponse]
41
42
  def list_companies(request_options: {}, **params)
42
43
  params = Schematic::Internal::Types::Utils.normalize_keys(params)
43
- query_param_names = %i[credit_type_ids has_scheduled_downgrade ids monetized_subscriptions plan_id plan_ids plan_version_id q sort_order_column sort_order_direction subscription_statuses subscription_types with_entitlement_for without_feature_override_for without_plan without_subscription with_subscription limit offset]
44
+ query_param_names = %i[credit_type_ids has_scheduled_downgrade ids monetized_subscriptions plan_id plan_ids plan_version_id plan_version_ids q sort_order_column sort_order_direction subscription_statuses subscription_types with_entitlement_for without_feature_override_for without_plan without_subscription with_subscription limit offset]
44
45
  query_params = {}
45
46
  query_params["credit_type_ids"] = params[:credit_type_ids] if params.key?(:credit_type_ids)
46
47
  query_params["has_scheduled_downgrade"] = params[:has_scheduled_downgrade] if params.key?(:has_scheduled_downgrade)
@@ -49,6 +50,7 @@ module Schematic
49
50
  query_params["plan_id"] = params[:plan_id] if params.key?(:plan_id)
50
51
  query_params["plan_ids"] = params[:plan_ids] if params.key?(:plan_ids)
51
52
  query_params["plan_version_id"] = params[:plan_version_id] if params.key?(:plan_version_id)
53
+ query_params["plan_version_ids"] = params[:plan_version_ids] if params.key?(:plan_version_ids)
52
54
  query_params["q"] = params[:q] if params.key?(:q)
53
55
  query_params["sort_order_column"] = params[:sort_order_column] if params.key?(:sort_order_column)
54
56
  query_params["sort_order_direction"] = params[:sort_order_direction] if params.key?(:sort_order_direction)
@@ -203,6 +205,7 @@ module Schematic
203
205
  # @option params [String, nil] :plan_id
204
206
  # @option params [String, nil] :plan_ids
205
207
  # @option params [String, nil] :plan_version_id
208
+ # @option params [String, nil] :plan_version_ids
206
209
  # @option params [String, nil] :q
207
210
  # @option params [String, nil] :sort_order_column
208
211
  # @option params [Schematic::Types::SortDirection, nil] :sort_order_direction
@@ -219,7 +222,7 @@ module Schematic
219
222
  # @return [Schematic::Companies::Types::CountCompaniesResponse]
220
223
  def count_companies(request_options: {}, **params)
221
224
  params = Schematic::Internal::Types::Utils.normalize_keys(params)
222
- query_param_names = %i[credit_type_ids has_scheduled_downgrade ids monetized_subscriptions plan_id plan_ids plan_version_id q sort_order_column sort_order_direction subscription_statuses subscription_types with_entitlement_for without_feature_override_for without_plan without_subscription with_subscription limit offset]
225
+ query_param_names = %i[credit_type_ids has_scheduled_downgrade ids monetized_subscriptions plan_id plan_ids plan_version_id plan_version_ids q sort_order_column sort_order_direction subscription_statuses subscription_types with_entitlement_for without_feature_override_for without_plan without_subscription with_subscription limit offset]
223
226
  query_params = {}
224
227
  query_params["credit_type_ids"] = params[:credit_type_ids] if params.key?(:credit_type_ids)
225
228
  query_params["has_scheduled_downgrade"] = params[:has_scheduled_downgrade] if params.key?(:has_scheduled_downgrade)
@@ -228,6 +231,7 @@ module Schematic
228
231
  query_params["plan_id"] = params[:plan_id] if params.key?(:plan_id)
229
232
  query_params["plan_ids"] = params[:plan_ids] if params.key?(:plan_ids)
230
233
  query_params["plan_version_id"] = params[:plan_version_id] if params.key?(:plan_version_id)
234
+ query_params["plan_version_ids"] = params[:plan_version_ids] if params.key?(:plan_version_ids)
231
235
  query_params["q"] = params[:q] if params.key?(:q)
232
236
  query_params["sort_order_column"] = params[:sort_order_column] if params.key?(:sort_order_column)
233
237
  query_params["sort_order_direction"] = params[:sort_order_direction] if params.key?(:sort_order_direction)
@@ -14,6 +14,7 @@ module Schematic
14
14
  field :plan_id, -> { String }, optional: true, nullable: false
15
15
  field :plan_ids, -> { Internal::Types::Array[String] }, optional: true, nullable: false
16
16
  field :plan_version_id, -> { String }, optional: true, nullable: false
17
+ field :plan_version_ids, -> { Internal::Types::Array[String] }, optional: true, nullable: false
17
18
  field :q, -> { String }, optional: true, nullable: false
18
19
  field :sort_order_column, -> { String }, optional: true, nullable: false
19
20
  field :sort_order_direction, -> { Schematic::Types::SortDirection }, optional: true, nullable: false
@@ -11,6 +11,7 @@ module Schematic
11
11
  field :plan_id, -> { String }, optional: true, nullable: false
12
12
  field :plan_ids, -> { String }, optional: true, nullable: false
13
13
  field :plan_version_id, -> { String }, optional: true, nullable: false
14
+ field :plan_version_ids, -> { String }, optional: true, nullable: false
14
15
  field :q, -> { String }, optional: true, nullable: false
15
16
  field :sort_order_column, -> { String }, optional: true, nullable: false
16
17
  field :sort_order_direction, -> { Schematic::Types::SortDirection }, optional: true, nullable: false
@@ -14,6 +14,7 @@ module Schematic
14
14
  field :plan_id, -> { String }, optional: true, nullable: false
15
15
  field :plan_ids, -> { Internal::Types::Array[String] }, optional: true, nullable: false
16
16
  field :plan_version_id, -> { String }, optional: true, nullable: false
17
+ field :plan_version_ids, -> { Internal::Types::Array[String] }, optional: true, nullable: false
17
18
  field :q, -> { String }, optional: true, nullable: false
18
19
  field :sort_order_column, -> { String }, optional: true, nullable: false
19
20
  field :sort_order_direction, -> { Schematic::Types::SortDirection }, optional: true, nullable: false
@@ -11,6 +11,7 @@ module Schematic
11
11
  field :plan_id, -> { String }, optional: true, nullable: false
12
12
  field :plan_ids, -> { String }, optional: true, nullable: false
13
13
  field :plan_version_id, -> { String }, optional: true, nullable: false
14
+ field :plan_version_ids, -> { String }, optional: true, nullable: false
14
15
  field :q, -> { String }, optional: true, nullable: false
15
16
  field :sort_order_column, -> { String }, optional: true, nullable: false
16
17
  field :sort_order_direction, -> { Schematic::Types::SortDirection }, optional: true, nullable: false
@@ -747,6 +747,108 @@ module Schematic
747
747
  end
748
748
  end
749
749
 
750
+ # @param request_options [Hash]
751
+ # @param params [Schematic::Credits::Types::AcquireCreditLeaseRequestBody]
752
+ # @option request_options [String] :base_url
753
+ # @option request_options [Hash{String => Object}] :additional_headers
754
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
755
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
756
+ # @option request_options [Integer] :timeout_in_seconds
757
+ #
758
+ # @return [Schematic::Credits::Types::AcquireCreditLeaseResponse]
759
+ def acquire_credit_lease(request_options: {}, **params)
760
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
761
+ request = Schematic::Internal::JSON::Request.new(
762
+ base_url: request_options[:base_url],
763
+ method: "POST",
764
+ path: "billing/credits/lease",
765
+ body: Schematic::Credits::Types::AcquireCreditLeaseRequestBody.new(params).to_h,
766
+ request_options: request_options
767
+ )
768
+ begin
769
+ response = @client.send(request)
770
+ rescue Net::HTTPRequestTimeout
771
+ raise Schematic::Errors::TimeoutError
772
+ end
773
+ code = response.code.to_i
774
+ if code.between?(200, 299)
775
+ Schematic::Credits::Types::AcquireCreditLeaseResponse.load(response.body)
776
+ else
777
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
778
+ raise error_class.new(response.body, code: code)
779
+ end
780
+ end
781
+
782
+ # @param request_options [Hash]
783
+ # @param params [Schematic::Credits::Types::ExtendCreditLeaseRequestBody]
784
+ # @option request_options [String] :base_url
785
+ # @option request_options [Hash{String => Object}] :additional_headers
786
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
787
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
788
+ # @option request_options [Integer] :timeout_in_seconds
789
+ # @option params [String] :lease_id
790
+ #
791
+ # @return [Schematic::Credits::Types::ExtendCreditLeaseResponse]
792
+ def extend_credit_lease(request_options: {}, **params)
793
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
794
+ request_data = Schematic::Credits::Types::ExtendCreditLeaseRequestBody.new(params).to_h
795
+ non_body_param_names = ["lease_id"]
796
+ body = request_data.except(*non_body_param_names)
797
+
798
+ request = Schematic::Internal::JSON::Request.new(
799
+ base_url: request_options[:base_url],
800
+ method: "PUT",
801
+ path: "billing/credits/lease/#{URI.encode_uri_component(params[:lease_id].to_s)}/extend",
802
+ body: body,
803
+ request_options: request_options
804
+ )
805
+ begin
806
+ response = @client.send(request)
807
+ rescue Net::HTTPRequestTimeout
808
+ raise Schematic::Errors::TimeoutError
809
+ end
810
+ code = response.code.to_i
811
+ if code.between?(200, 299)
812
+ Schematic::Credits::Types::ExtendCreditLeaseResponse.load(response.body)
813
+ else
814
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
815
+ raise error_class.new(response.body, code: code)
816
+ end
817
+ end
818
+
819
+ # @param request_options [Hash]
820
+ # @param params [Schematic::Types::ReleaseCreditLeaseRequestBody]
821
+ # @option request_options [String] :base_url
822
+ # @option request_options [Hash{String => Object}] :additional_headers
823
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
824
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
825
+ # @option request_options [Integer] :timeout_in_seconds
826
+ # @option params [String] :lease_id
827
+ #
828
+ # @return [Schematic::Credits::Types::ReleaseCreditLeaseResponse]
829
+ def release_credit_lease(request_options: {}, **params)
830
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
831
+ request = Schematic::Internal::JSON::Request.new(
832
+ base_url: request_options[:base_url],
833
+ method: "PUT",
834
+ path: "billing/credits/lease/#{URI.encode_uri_component(params[:lease_id].to_s)}/release",
835
+ body: params,
836
+ request_options: request_options
837
+ )
838
+ begin
839
+ response = @client.send(request)
840
+ rescue Net::HTTPRequestTimeout
841
+ raise Schematic::Errors::TimeoutError
842
+ end
843
+ code = response.code.to_i
844
+ if code.between?(200, 299)
845
+ Schematic::Credits::Types::ReleaseCreditLeaseResponse.load(response.body)
846
+ else
847
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
848
+ raise error_class.new(response.body, code: code)
849
+ end
850
+ end
851
+
750
852
  # @param request_options [Hash]
751
853
  # @param params [Hash]
752
854
  # @option request_options [String] :base_url
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Credits
5
+ module Types
6
+ class AcquireCreditLeaseRequestBody < Internal::Types::Model
7
+ field :company_id, -> { String }, optional: false, nullable: false
8
+ field :credit_type_id, -> { String }, optional: false, nullable: false
9
+ field :expires_at, -> { String }, optional: true, nullable: false
10
+ field :requested_amount, -> { Integer }, optional: false, nullable: false
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Credits
5
+ module Types
6
+ class AcquireCreditLeaseResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::CreditLeaseResponseData }, 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,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Credits
5
+ module Types
6
+ class ExtendCreditLeaseRequestBody < Internal::Types::Model
7
+ field :lease_id, -> { String }, optional: false, nullable: false
8
+ field :additional_amount, -> { Integer }, optional: false, nullable: false
9
+ field :expires_at, -> { String }, optional: true, nullable: false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Schematic
4
+ module Credits
5
+ module Types
6
+ class ExtendCreditLeaseResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::CreditLeaseResponseData }, 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 Credits
5
+ module Types
6
+ class ReleaseCreditLeaseResponse < Internal::Types::Model
7
+ field :data, -> { Schematic::Types::CreditLeaseResponseData }, optional: false, nullable: false
8
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
9
+ end
10
+ end
11
+ end
12
+ end
@@ -16,25 +16,42 @@ module Schematic
16
16
  COMPANY_MAP_FIELDS = %i[credit_balances keys traits].freeze
17
17
  COMPANY_ARRAY_FIELDS = %i[billing_product_ids entitlements plan_ids plan_version_ids rules].freeze
18
18
 
19
+ # Partials don't carry refreshed entitlements, so when their derived
20
+ # fields change in another part of the company we sync them here to match
21
+ # server behavior (see schematic-python merge.partial_company):
22
+ # - credit_remaining <- credit_balances[credit_id]
23
+ # - usage <- metric value matching (event_name, metric_period, month_reset)
24
+ # Both are skipped when the partial also sends entitlements wholesale.
19
25
  def partial_company(existing, partial_data)
20
26
  return existing unless partial_data.is_a?(Hash)
21
27
 
22
28
  result = deep_copy(existing)
29
+ entitlements_in_partial = partial_data.key?(:entitlements) || partial_data.key?("entitlements")
30
+ updated_balances = nil
31
+ metrics_updated = false
23
32
 
24
33
  partial_data.each do |key, value|
25
34
  sym_key = key.to_sym
26
35
  if COMPANY_MAP_FIELDS.include?(sym_key)
27
36
  result[sym_key] ||= {}
28
37
  result[sym_key] = result[sym_key].merge(value) if value.is_a?(Hash)
38
+ updated_balances = (value.is_a?(Hash) ? value : {}) if sym_key == :credit_balances
29
39
  elsif COMPANY_ARRAY_FIELDS.include?(sym_key)
30
40
  result[sym_key] = value if value.is_a?(Array)
31
41
  elsif sym_key == :metrics
32
42
  result[sym_key] = upsert_metrics(result[sym_key] || [], value || [])
43
+ metrics_updated = true
33
44
  else
34
45
  result[sym_key] = value
35
46
  end
36
47
  end
37
48
 
49
+ if (updated_balances&.any? || metrics_updated) && !entitlements_in_partial
50
+ result[:entitlements] = sync_entitlements(
51
+ result[:entitlements], result[:metrics], updated_balances, metrics_updated
52
+ )
53
+ end
54
+
38
55
  result
39
56
  end
40
57
 
@@ -90,6 +107,60 @@ module Schematic
90
107
  def get_metric_field(metric, field)
91
108
  metric[field] || metric[field.to_s]
92
109
  end
110
+
111
+ # Re-derive entitlement usage / credit_remaining from the merged metrics
112
+ # and the just-updated credit balances. Mirrors schematic-python so that
113
+ # entitlement usage reflects DataStream track events immediately.
114
+ def sync_entitlements(entitlements, metrics, updated_balances, metrics_updated)
115
+ return entitlements unless entitlements.is_a?(Array) && !entitlements.empty?
116
+
117
+ metrics_lookup = {}
118
+ if metrics_updated && metrics.is_a?(Array)
119
+ metrics.each do |metric|
120
+ next unless metric.is_a?(Hash)
121
+
122
+ key = [
123
+ get_metric_field(metric, :event_subtype) || "",
124
+ get_metric_field(metric, :period) || "",
125
+ get_metric_field(metric, :month_reset) || ""
126
+ ]
127
+ value = get_metric_field(metric, :value)
128
+ metrics_lookup[key] = value.nil? ? 0 : value
129
+ end
130
+ end
131
+
132
+ entitlements.map do |ent|
133
+ next ent unless ent.is_a?(Hash)
134
+
135
+ new_ent = deep_copy(ent)
136
+
137
+ credit_id = get_metric_field(ent, :credit_id)
138
+ if updated_balances && credit_id
139
+ present, balance = fetch_balance(updated_balances, credit_id)
140
+ new_ent[:credit_remaining] = balance if present
141
+ end
142
+
143
+ event_name = get_metric_field(ent, :event_name)
144
+ unless metrics_lookup.empty? || event_name.nil?
145
+ period = get_metric_field(ent, :metric_period) || "all_time"
146
+ month_reset = get_metric_field(ent, :month_reset) || "first_of_month"
147
+ matched = metrics_lookup[[event_name, period, month_reset]]
148
+ new_ent[:usage] = matched unless matched.nil?
149
+ end
150
+
151
+ new_ent
152
+ end
153
+ end
154
+
155
+ # The partial's credit_balances may be keyed by string or symbol depending
156
+ # on how the message was parsed, while an entitlement's credit_id is a
157
+ # string value, so check both key forms.
158
+ def fetch_balance(balances, credit_id)
159
+ return [true, balances[credit_id]] if balances.key?(credit_id)
160
+ return [true, balances[credit_id.to_sym]] if balances.key?(credit_id.to_sym)
161
+
162
+ [false, nil]
163
+ end
93
164
  end
94
165
  end
95
166
  end
@@ -29,6 +29,7 @@ module Schematic
29
29
  field :quarterly_unit_price_decimal, -> { String }, optional: true, nullable: false
30
30
  field :soft_limit, -> { Integer }, optional: true, nullable: false
31
31
  field :tier_mode, -> { Schematic::Types::BillingTiersMode }, optional: true, nullable: false
32
+ field :usage_quantity, -> { Integer }, optional: true, nullable: false
32
33
  field :value_bool, -> { Internal::Types::Boolean }, optional: true, nullable: false
33
34
  field :value_credit_id, -> { String }, optional: true, nullable: false
34
35
  field :value_numeric, -> { Integer }, optional: true, nullable: false
@@ -27,6 +27,7 @@ module Schematic
27
27
  field :quarterly_unit_price_decimal, -> { String }, optional: true, nullable: false
28
28
  field :soft_limit, -> { Integer }, optional: true, nullable: false
29
29
  field :tier_mode, -> { Schematic::Types::BillingTiersMode }, optional: true, nullable: false
30
+ field :usage_quantity, -> { Integer }, optional: true, nullable: false
30
31
  field :value_bool, -> { Internal::Types::Boolean }, optional: true, nullable: false
31
32
  field :value_credit_id, -> { String }, optional: true, nullable: false
32
33
  field :value_numeric, -> { Integer }, optional: true, nullable: false
@@ -25,6 +25,7 @@ module Schematic
25
25
  field :quarterly_unit_price_decimal, -> { String }, optional: true, nullable: false
26
26
  field :soft_limit, -> { Integer }, optional: true, nullable: false
27
27
  field :tier_mode, -> { Schematic::Types::BillingTiersMode }, 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_id, -> { String }, optional: true, nullable: false
30
31
  field :value_numeric, -> { Integer }, optional: true, nullable: false