From 8487841eae05855059210650ab3ee913538f1afc Mon Sep 17 00:00:00 2001
From: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
Date: Mon, 22 Jun 2026 18:51:25 +0000
Subject: [PATCH 1/2] [fern-generated] Update SDK
Generated by Fern
CLI Version: unknown
Generators:
- fernapi/fern-ruby-sdk: 1.1.13
---
.fern/metadata.json | 4 +-
Gemfile.lock | 2 +-
lib/schematic.rb | 6 +
lib/schematic/billing/client.rb | 96 +++++++++
.../types/delete_billing_coupon_response.rb | 12 ++
.../types/delete_billing_customer_response.rb | 12 ++
.../types/delete_billing_invoice_response.rb | 12 ++
lib/schematic/client.rb | 2 +-
.../types/test_webhook_response_data.rb | 10 +
lib/schematic/version.rb | 2 +-
lib/schematic/webhooks/client.rb | 37 ++++
.../send_test_webhook_action_response.rb | 12 ++
.../types/test_webhook_request_body.rb | 12 ++
reference.md | 203 ++++++++++++++++++
14 files changed, 417 insertions(+), 5 deletions(-)
create mode 100644 lib/schematic/billing/types/delete_billing_coupon_response.rb
create mode 100644 lib/schematic/billing/types/delete_billing_customer_response.rb
create mode 100644 lib/schematic/billing/types/delete_billing_invoice_response.rb
create mode 100644 lib/schematic/types/test_webhook_response_data.rb
create mode 100644 lib/schematic/webhooks/types/send_test_webhook_action_response.rb
create mode 100644 lib/schematic/webhooks/types/test_webhook_request_body.rb
diff --git a/.fern/metadata.json b/.fern/metadata.json
index cb6e7f3..7d3d867 100644
--- a/.fern/metadata.json
+++ b/.fern/metadata.json
@@ -13,6 +13,6 @@
"webrick": ">= 1.0"
}
},
- "originGitCommit": "df83a2723a19055c70199e3b0b78b77e9c394838",
- "sdkVersion": "1.4.5"
+ "originGitCommit": "26286134afce586aa5dbd02bffc9f25da6217032",
+ "sdkVersion": "1.4.6"
}
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
index 6011ae3..0ce66c4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- schematichq (1.4.5)
+ schematichq (1.4.6)
wasmtime (>= 19.0)
websocket (>= 1.2)
diff --git a/lib/schematic.rb b/lib/schematic.rb
index 7970d21..cae6cee 100644
--- a/lib/schematic.rb
+++ b/lib/schematic.rb
@@ -85,6 +85,8 @@
require_relative "schematic/types/billing_coupon_response_data"
require_relative "schematic/billing/types/list_coupons_response"
require_relative "schematic/billing/types/upsert_billing_coupon_response"
+require_relative "schematic/billing/types/delete_billing_coupon_response"
+require_relative "schematic/billing/types/delete_billing_customer_response"
require_relative "schematic/types/billing_customer_response_data"
require_relative "schematic/billing/types/upsert_billing_customer_response"
require_relative "schematic/billing/types/list_customers_with_subscriptions_params"
@@ -98,6 +100,7 @@
require_relative "schematic/types/invoice_response_data"
require_relative "schematic/billing/types/list_invoices_response"
require_relative "schematic/billing/types/upsert_invoice_response"
+require_relative "schematic/billing/types/delete_billing_invoice_response"
require_relative "schematic/billing/types/list_meters_params"
require_relative "schematic/types/billing_meter_response_data"
require_relative "schematic/billing/types/list_meters_response"
@@ -622,6 +625,8 @@
require_relative "schematic/webhooks/types/get_webhook_response"
require_relative "schematic/webhooks/types/update_webhook_response"
require_relative "schematic/webhooks/types/delete_webhook_response"
+require_relative "schematic/types/test_webhook_response_data"
+require_relative "schematic/webhooks/types/send_test_webhook_action_response"
require_relative "schematic/webhooks/types/count_webhooks_params"
require_relative "schematic/webhooks/types/count_webhooks_response"
require_relative "schematic/types/api_error"
@@ -908,5 +913,6 @@
require_relative "schematic/webhooks/types/list_webhooks_request"
require_relative "schematic/webhooks/types/create_webhook_request_body"
require_relative "schematic/webhooks/types/update_webhook_request_body"
+require_relative "schematic/webhooks/types/test_webhook_request_body"
require_relative "schematic/webhooks/types/count_webhooks_request"
require_relative "schematic/environment"
diff --git a/lib/schematic/billing/client.rb b/lib/schematic/billing/client.rb
index 6fab89a..c0da2c7 100644
--- a/lib/schematic/billing/client.rb
+++ b/lib/schematic/billing/client.rb
@@ -86,6 +86,70 @@ def upsert_billing_coupon(request_options: {}, **params)
end
end
+ # @param request_options [Hash]
+ # @param params [Hash]
+ # @option request_options [String] :base_url
+ # @option request_options [Hash{String => Object}] :additional_headers
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
+ # @option request_options [Integer] :timeout_in_seconds
+ # @option params [String] :billing_id
+ #
+ # @return [Schematic::Billing::Types::DeleteBillingCouponResponse]
+ def delete_billing_coupon(request_options: {}, **params)
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
+ request = Schematic::Internal::JSON::Request.new(
+ base_url: request_options[:base_url],
+ method: "DELETE",
+ path: "billing/coupons/#{URI.encode_uri_component(params[:billing_id].to_s)}",
+ request_options: request_options
+ )
+ begin
+ response = @client.send(request)
+ rescue Net::HTTPRequestTimeout
+ raise Schematic::Errors::TimeoutError
+ end
+ code = response.code.to_i
+ if code.between?(200, 299)
+ Schematic::Billing::Types::DeleteBillingCouponResponse.load(response.body)
+ else
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
+ raise error_class.new(response.body, code: code)
+ end
+ end
+
+ # @param request_options [Hash]
+ # @param params [Hash]
+ # @option request_options [String] :base_url
+ # @option request_options [Hash{String => Object}] :additional_headers
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
+ # @option request_options [Integer] :timeout_in_seconds
+ # @option params [String] :billing_id
+ #
+ # @return [Schematic::Billing::Types::DeleteBillingCustomerResponse]
+ def delete_billing_customer(request_options: {}, **params)
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
+ request = Schematic::Internal::JSON::Request.new(
+ base_url: request_options[:base_url],
+ method: "DELETE",
+ path: "billing/customer/#{URI.encode_uri_component(params[:billing_id].to_s)}",
+ request_options: request_options
+ )
+ begin
+ response = @client.send(request)
+ rescue Net::HTTPRequestTimeout
+ raise Schematic::Errors::TimeoutError
+ end
+ code = response.code.to_i
+ if code.between?(200, 299)
+ Schematic::Billing::Types::DeleteBillingCustomerResponse.load(response.body)
+ else
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
+ raise error_class.new(response.body, code: code)
+ end
+ end
+
# @param request_options [Hash]
# @param params [Schematic::Billing::Types::CreateBillingCustomerRequestBody]
# @option request_options [String] :base_url
@@ -292,6 +356,38 @@ def upsert_invoice(request_options: {}, **params)
end
end
+ # @param request_options [Hash]
+ # @param params [Hash]
+ # @option request_options [String] :base_url
+ # @option request_options [Hash{String => Object}] :additional_headers
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
+ # @option request_options [Integer] :timeout_in_seconds
+ # @option params [String] :billing_id
+ #
+ # @return [Schematic::Billing::Types::DeleteBillingInvoiceResponse]
+ def delete_billing_invoice(request_options: {}, **params)
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
+ request = Schematic::Internal::JSON::Request.new(
+ base_url: request_options[:base_url],
+ method: "DELETE",
+ path: "billing/invoices/#{URI.encode_uri_component(params[:billing_id].to_s)}",
+ request_options: request_options
+ )
+ begin
+ response = @client.send(request)
+ rescue Net::HTTPRequestTimeout
+ raise Schematic::Errors::TimeoutError
+ end
+ code = response.code.to_i
+ if code.between?(200, 299)
+ Schematic::Billing::Types::DeleteBillingInvoiceResponse.load(response.body)
+ else
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
+ raise error_class.new(response.body, code: code)
+ end
+ end
+
# @param request_options [Hash]
# @param params [Hash]
# @option request_options [String] :base_url
diff --git a/lib/schematic/billing/types/delete_billing_coupon_response.rb b/lib/schematic/billing/types/delete_billing_coupon_response.rb
new file mode 100644
index 0000000..d7d6dbb
--- /dev/null
+++ b/lib/schematic/billing/types/delete_billing_coupon_response.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Schematic
+ module Billing
+ module Types
+ class DeleteBillingCouponResponse < Internal::Types::Model
+ field :data, -> { Schematic::Types::DeleteResponse }, optional: false, nullable: false
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
+ end
+ end
+ end
+end
diff --git a/lib/schematic/billing/types/delete_billing_customer_response.rb b/lib/schematic/billing/types/delete_billing_customer_response.rb
new file mode 100644
index 0000000..4d8bd80
--- /dev/null
+++ b/lib/schematic/billing/types/delete_billing_customer_response.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Schematic
+ module Billing
+ module Types
+ class DeleteBillingCustomerResponse < Internal::Types::Model
+ field :data, -> { Schematic::Types::DeleteResponse }, optional: false, nullable: false
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
+ end
+ end
+ end
+end
diff --git a/lib/schematic/billing/types/delete_billing_invoice_response.rb b/lib/schematic/billing/types/delete_billing_invoice_response.rb
new file mode 100644
index 0000000..0b7f525
--- /dev/null
+++ b/lib/schematic/billing/types/delete_billing_invoice_response.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Schematic
+ module Billing
+ module Types
+ class DeleteBillingInvoiceResponse < Internal::Types::Model
+ field :data, -> { Schematic::Types::DeleteResponse }, optional: false, nullable: false
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
+ end
+ end
+ end
+end
diff --git a/lib/schematic/client.rb b/lib/schematic/client.rb
index 4613f55..cbf180d 100644
--- a/lib/schematic/client.rb
+++ b/lib/schematic/client.rb
@@ -10,7 +10,7 @@ def initialize(api_key:, base_url: nil)
@raw_client = Schematic::Internal::Http::RawClient.new(
base_url: base_url || Schematic::Environment::DEFAULT,
headers: {
- "User-Agent" => "schematichq/1.4.5",
+ "User-Agent" => "schematichq/1.4.6",
"X-Fern-Language" => "Ruby",
"X-Schematic-Api-Key" => api_key.to_s
}
diff --git a/lib/schematic/types/test_webhook_response_data.rb b/lib/schematic/types/test_webhook_response_data.rb
new file mode 100644
index 0000000..ce5f51d
--- /dev/null
+++ b/lib/schematic/types/test_webhook_response_data.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Schematic
+ module Types
+ class TestWebhookResponseData < Internal::Types::Model
+ field :response_code, -> { Integer }, optional: false, nullable: false
+ field :success, -> { Internal::Types::Boolean }, optional: false, nullable: false
+ end
+ end
+end
diff --git a/lib/schematic/version.rb b/lib/schematic/version.rb
index bdfd52b..b2a5626 100644
--- a/lib/schematic/version.rb
+++ b/lib/schematic/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Schematic
- VERSION = "1.4.5"
+ VERSION = "1.4.6"
end
diff --git a/lib/schematic/webhooks/client.rb b/lib/schematic/webhooks/client.rb
index b77cb68..d712bf4 100644
--- a/lib/schematic/webhooks/client.rb
+++ b/lib/schematic/webhooks/client.rb
@@ -309,6 +309,43 @@ def delete_webhook(request_options: {}, **params)
end
end
+ # @param request_options [Hash]
+ # @param params [Schematic::Webhooks::Types::TestWebhookRequestBody]
+ # @option request_options [String] :base_url
+ # @option request_options [Hash{String => Object}] :additional_headers
+ # @option request_options [Hash{String => Object}] :additional_query_parameters
+ # @option request_options [Hash{String => Object}] :additional_body_parameters
+ # @option request_options [Integer] :timeout_in_seconds
+ # @option params [String] :webhook_id
+ #
+ # @return [Schematic::Webhooks::Types::SendTestWebhookActionResponse]
+ def send_test_webhook_action(request_options: {}, **params)
+ params = Schematic::Internal::Types::Utils.normalize_keys(params)
+ request_data = Schematic::Webhooks::Types::TestWebhookRequestBody.new(params).to_h
+ non_body_param_names = ["webhook_id"]
+ body = request_data.except(*non_body_param_names)
+
+ request = Schematic::Internal::JSON::Request.new(
+ base_url: request_options[:base_url],
+ method: "POST",
+ path: "webhooks/#{URI.encode_uri_component(params[:webhook_id].to_s)}/test",
+ body: body,
+ request_options: request_options
+ )
+ begin
+ response = @client.send(request)
+ rescue Net::HTTPRequestTimeout
+ raise Schematic::Errors::TimeoutError
+ end
+ code = response.code.to_i
+ if code.between?(200, 299)
+ Schematic::Webhooks::Types::SendTestWebhookActionResponse.load(response.body)
+ else
+ error_class = Schematic::Errors::ResponseError.subclass_for_code(code)
+ raise error_class.new(response.body, code: code)
+ end
+ end
+
# @param request_options [Hash]
# @param params [Hash]
# @option request_options [String] :base_url
diff --git a/lib/schematic/webhooks/types/send_test_webhook_action_response.rb b/lib/schematic/webhooks/types/send_test_webhook_action_response.rb
new file mode 100644
index 0000000..a627e13
--- /dev/null
+++ b/lib/schematic/webhooks/types/send_test_webhook_action_response.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Schematic
+ module Webhooks
+ module Types
+ class SendTestWebhookActionResponse < Internal::Types::Model
+ field :data, -> { Schematic::Types::TestWebhookResponseData }, optional: false, nullable: false
+ field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false
+ end
+ end
+ end
+end
diff --git a/lib/schematic/webhooks/types/test_webhook_request_body.rb b/lib/schematic/webhooks/types/test_webhook_request_body.rb
new file mode 100644
index 0000000..613f05b
--- /dev/null
+++ b/lib/schematic/webhooks/types/test_webhook_request_body.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Schematic
+ module Webhooks
+ module Types
+ class TestWebhookRequestBody < Internal::Types::Model
+ field :webhook_id, -> { String }, optional: false, nullable: false
+ field :request_type, -> { Schematic::Types::WebhookRequestType }, optional: false, nullable: false
+ end
+ end
+ end
+end
diff --git a/reference.md b/reference.md
index 468b011..1254b06 100644
--- a/reference.md
+++ b/reference.md
@@ -1446,6 +1446,102 @@ client.billing.upsert_billing_coupon(
+
+
+
+
+client.billing.delete_billing_coupon(billing_id) -> Schematic::Billing::Types::DeleteBillingCouponResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```ruby
+client.billing.delete_billing_coupon(billing_id: "billing_id")
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**billing_id:** `String` — billing_id
+
+
+
+
+
+-
+
+**request_options:** `Schematic::Billing::RequestOptions`
+
+
+
+
+
+
+
+
+
+
+
+client.billing.delete_billing_customer(billing_id) -> Schematic::Billing::Types::DeleteBillingCustomerResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```ruby
+client.billing.delete_billing_customer(billing_id: "billing_id")
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**billing_id:** `String` — billing_id
+
+
+
+
+
+-
+
+**request_options:** `Schematic::Billing::RequestOptions`
+
+
+
+
+
+
+
@@ -1977,6 +2073,54 @@ client.billing.upsert_invoice(
+
+
+
+
+client.billing.delete_billing_invoice(billing_id) -> Schematic::Billing::Types::DeleteBillingInvoiceResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```ruby
+client.billing.delete_billing_invoice(billing_id: "billing_id")
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**billing_id:** `String` — billing_id
+
+
+
+
+
+-
+
+**request_options:** `Schematic::Billing::RequestOptions`
+
+
+
+
+
+
+
@@ -19309,6 +19453,65 @@ client.webhooks.delete_webhook(webhook_id: "webhook_id")
+
+
+
+
+client.webhooks.send_test_webhook_action(webhook_id, request) -> Schematic::Webhooks::Types::SendTestWebhookActionResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```ruby
+client.webhooks.send_test_webhook_action(
+ webhook_id: "webhook_id",
+ request_type: "subscription.trial.ended"
+)
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**webhook_id:** `String` — webhook_id
+
+
+
+
+
+-
+
+**request_type:** `Schematic::Types::WebhookRequestType`
+
+
+
+
+
+-
+
+**request_options:** `Schematic::Webhooks::RequestOptions`
+
+
+
+
+
+
+
From 6ed5e2386e1fd3ffc023815e945841e333de59c4 Mon Sep 17 00:00:00 2001
From: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
Date: Mon, 22 Jun 2026 18:51:27 +0000
Subject: [PATCH 2/2] [fern-replay] Applied customizations
Patches absorbed by generator (1):
- patch-46462128: add tests and address nits
The generator now produces these customizations natively.
---
.fern/replay.lock | 211 ++--------------------------------------------
1 file changed, 8 insertions(+), 203 deletions(-)
diff --git a/.fern/replay.lock b/.fern/replay.lock
index 2fdceff..54a0a96 100644
--- a/.fern/replay.lock
+++ b/.fern/replay.lock
@@ -24,206 +24,11 @@ generations:
cli_version: unknown
generator_versions:
fernapi/fern-ruby-sdk: 1.1.13
-current_generation: 7ff89cac80a7358534185779ed4992b755919d97
-patches:
- - id: patch-46462128
- content_hash: sha256:416a511ede0736c55e936299b78f07a3935feedab63c1270dbb2230687fc6be4
- original_commit: 46462128cacb25b73fac7770060cf427ff0d9e6d
- original_message: add tests and address nits
- original_author: Christopher Brady
- base_generation: 7ff89cac80a7358534185779ed4992b755919d97
- files:
- - lib/schematic/datastream/merge.rb
- patch_content: |
- diff --git a/lib/schematic/datastream/merge.rb b/lib/schematic/datastream/merge.rb
- index f4dd4e5..5c32683 100644
- --- a/lib/schematic/datastream/merge.rb
- +++ b/lib/schematic/datastream/merge.rb
- @@ -46,7 +46,7 @@ module Schematic
- end
- end
-
- - if (updated_balances&.any? || metrics_updated) && !entitlements_in_partial
- + if (updated_balances || metrics_updated) && !entitlements_in_partial
- result[:entitlements] = sync_entitlements(
- result[:entitlements], result[:metrics], updated_balances, metrics_updated
- )
- @@ -152,9 +152,8 @@ module Schematic
- end
- end
-
- - # The partial's credit_balances may be keyed by string or symbol depending
- - # on how the message was parsed, while an entitlement's credit_id is a
- - # string value, so check both key forms.
- + # credit_balances keys may be symbols (deep_copy symbolizes) while an
- + # entitlement's credit_id is always a string, so check both forms.
- def fetch_balance(balances, credit_id)
- return [true, balances[credit_id]] if balances.key?(credit_id)
- return [true, balances[credit_id.to_sym]] if balances.key?(credit_id.to_sym)
- theirs_snapshot:
- lib/schematic/datastream/merge.rb: |
- # frozen_string_literal: true
-
- require "json"
-
- module Schematic
- module DataStream
- module Merge
- module_function
-
- def deep_copy(obj)
- JSON.parse(JSON.generate(obj), symbolize_names: true)
- rescue StandardError
- obj.dup
- end
-
- COMPANY_MAP_FIELDS = %i[credit_balances keys traits].freeze
- COMPANY_ARRAY_FIELDS = %i[billing_product_ids entitlements plan_ids plan_version_ids rules].freeze
-
- # Partials don't carry refreshed entitlements, so when their derived
- # fields change in another part of the company we sync them here to match
- # server behavior (see schematic-python merge.partial_company):
- # - credit_remaining <- credit_balances[credit_id]
- # - usage <- metric value matching (event_name, metric_period, month_reset)
- # Both are skipped when the partial also sends entitlements wholesale.
- def partial_company(existing, partial_data)
- return existing unless partial_data.is_a?(Hash)
-
- result = deep_copy(existing)
- entitlements_in_partial = partial_data.key?(:entitlements) || partial_data.key?("entitlements")
- updated_balances = nil
- metrics_updated = false
-
- partial_data.each do |key, value|
- sym_key = key.to_sym
- if COMPANY_MAP_FIELDS.include?(sym_key)
- result[sym_key] ||= {}
- result[sym_key] = result[sym_key].merge(value) if value.is_a?(Hash)
- updated_balances = (value.is_a?(Hash) ? value : {}) if sym_key == :credit_balances
- elsif COMPANY_ARRAY_FIELDS.include?(sym_key)
- result[sym_key] = value if value.is_a?(Array)
- elsif sym_key == :metrics
- result[sym_key] = upsert_metrics(result[sym_key] || [], value || [])
- metrics_updated = true
- else
- result[sym_key] = value
- end
- end
-
- if (updated_balances || metrics_updated) && !entitlements_in_partial
- result[:entitlements] = sync_entitlements(
- result[:entitlements], result[:metrics], updated_balances, metrics_updated
- )
- end
-
- result
- end
-
- USER_MAP_FIELDS = %i[keys traits].freeze
-
- def partial_user(existing, partial_data)
- return existing unless partial_data.is_a?(Hash)
-
- result = deep_copy(existing)
-
- partial_data.each do |key, value|
- sym_key = key.to_sym
- if USER_MAP_FIELDS.include?(sym_key)
- result[sym_key] ||= {}
- result[sym_key] = result[sym_key].merge(value) if value.is_a?(Hash)
- elsif sym_key == :rules
- result[sym_key] = value if value.is_a?(Array)
- else
- result[sym_key] = value
- end
- end
-
- result
- end
-
- def upsert_metrics(existing, incoming)
- return incoming if existing.nil? || existing.empty?
- return existing if incoming.nil? || incoming.empty?
-
- result = existing.map { |metric| deep_copy(metric) }
-
- incoming.each do |inc_metric|
- match_idx = result.index do |ex|
- metrics_match?(ex, inc_metric)
- end
-
- if match_idx
- result[match_idx] = inc_metric
- else
- result << inc_metric
- end
- end
-
- result
- end
-
- def metrics_match?(left, right)
- get_metric_field(left, :event_subtype) == get_metric_field(right, :event_subtype) &&
- get_metric_field(left, :period) == get_metric_field(right, :period) &&
- get_metric_field(left, :month_reset) == get_metric_field(right, :month_reset)
- end
-
- def get_metric_field(metric, field)
- metric[field] || metric[field.to_s]
- end
-
- # Re-derive entitlement usage / credit_remaining from the merged metrics
- # and the just-updated credit balances. Mirrors schematic-python so that
- # entitlement usage reflects DataStream track events immediately.
- def sync_entitlements(entitlements, metrics, updated_balances, metrics_updated)
- return entitlements unless entitlements.is_a?(Array) && !entitlements.empty?
-
- metrics_lookup = {}
- if metrics_updated && metrics.is_a?(Array)
- metrics.each do |metric|
- next unless metric.is_a?(Hash)
-
- key = [
- get_metric_field(metric, :event_subtype) || "",
- get_metric_field(metric, :period) || "",
- get_metric_field(metric, :month_reset) || ""
- ]
- value = get_metric_field(metric, :value)
- metrics_lookup[key] = value.nil? ? 0 : value
- end
- end
-
- entitlements.map do |ent|
- next ent unless ent.is_a?(Hash)
-
- new_ent = deep_copy(ent)
-
- credit_id = get_metric_field(ent, :credit_id)
- if updated_balances && credit_id
- present, balance = fetch_balance(updated_balances, credit_id)
- new_ent[:credit_remaining] = balance if present
- end
-
- event_name = get_metric_field(ent, :event_name)
- unless metrics_lookup.empty? || event_name.nil?
- period = get_metric_field(ent, :metric_period) || "all_time"
- month_reset = get_metric_field(ent, :month_reset) || "first_of_month"
- matched = metrics_lookup[[event_name, period, month_reset]]
- new_ent[:usage] = matched unless matched.nil?
- end
-
- new_ent
- end
- end
-
- # credit_balances keys may be symbols (deep_copy symbolizes) while an
- # entitlement's credit_id is always a string, so check both forms.
- def fetch_balance(balances, credit_id)
- return [true, balances[credit_id]] if balances.key?(credit_id)
- return [true, balances[credit_id.to_sym]] if balances.key?(credit_id.to_sym)
-
- [false, nil]
- end
- end
- end
- end
+ - commit_sha: 8487841eae05855059210650ab3ee913538f1afc
+ tree_hash: 391a12403ced58b9d8dfaa76de05467a95b1b8f9
+ timestamp: 2026-06-22T18:51:25.550Z
+ cli_version: unknown
+ generator_versions:
+ fernapi/fern-ruby-sdk: 1.1.13
+current_generation: 8487841eae05855059210650ab3ee913538f1afc
+patches: []