From 0dd219c7b903329d9db2fb5b9fb570f2fd6e1a39 Mon Sep 17 00:00:00 2001 From: fern-api <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 18:13:52 +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 | 4 +- lib/schematic.rb | 24 +- lib/schematic/accounts/client.rb | 44 +++ .../types/count_account_members_params.rb | 15 + .../types/count_account_members_request.rb | 14 + .../types/count_account_members_response.rb | 12 + lib/schematic/client.rb | 2 +- lib/schematic/integrationsapi/client.rb | 102 ++++++- .../types/assume_stripe_installed_response.rb | 12 + .../types/install_integration_response.rb | 12 + .../types/install_stripe_response.rb | 12 + ...se.rb => load_sample_data_set_response.rb} | 2 +- .../types/create_plan_group_request_body.rb | 1 + .../types/update_plan_group_request_body.rb | 1 + .../types/account_member_response_data.rb | 2 + .../types/billing_credit_grant_reason.rb | 1 + .../billing_credit_grant_response_data.rb | 3 + .../types/billing_credit_ledger_authority.rb | 13 + lib/schematic/types/billing_credit_view.rb | 1 + ...billing_plan_credit_grant_response_data.rb | 1 + lib/schematic/types/billing_provider_type.rb | 1 + ...ange_subscription_internal_request_body.rb | 1 + .../types/change_subscription_request_body.rb | 1 + .../types/checkout_data_response_data.rb | 1 + lib/schematic/types/checkout_field_input.rb | 14 + .../types/checkout_field_response_data.rb | 18 ++ lib/schematic/types/checkout_field_value.rb | 10 + .../types/checkout_field_with_value.rb | 15 + .../company_credit_balance_response_data.rb | 2 + .../types/company_plan_credit_grant_view.rb | 1 + .../types/component_hydrate_response_data.rb | 1 + .../types/component_preview_response_data.rb | 1 + ..._billing_plan_credit_grant_request_body.rb | 1 + .../types/credit_company_grant_view.rb | 3 + .../credit_event_ledger_response_data.rb | 1 + lib/schematic/types/credit_usage_reason.rb | 15 + .../types/event_detail_response_data.rb | 1 + lib/schematic/types/event_response_data.rb | 1 + .../types/install_integration_request_body.rb | 14 + lib/schematic/types/integration_config.rb | 1 + .../types/integration_install_config.rb | 18 ++ .../integration_install_response_data.rb | 11 + lib/schematic/types/integration_type.rb | 1 + lib/schematic/types/manage_plan_request.rb | 1 + .../types/metronome_integration_config.rb | 7 + lib/schematic/types/migration_error_code.rb | 1 + lib/schematic/types/plan_credit_grant_view.rb | 1 + .../types/plan_group_detail_response_data.rb | 1 + ..._billing_plan_credit_grant_request_body.rb | 1 + lib/schematic/version.rb | 2 +- reference.md | 283 +++++++++++++++++- 52 files changed, 683 insertions(+), 29 deletions(-) create mode 100644 lib/schematic/accounts/types/count_account_members_params.rb create mode 100644 lib/schematic/accounts/types/count_account_members_request.rb create mode 100644 lib/schematic/accounts/types/count_account_members_response.rb create mode 100644 lib/schematic/integrationsapi/types/assume_stripe_installed_response.rb create mode 100644 lib/schematic/integrationsapi/types/install_integration_response.rb create mode 100644 lib/schematic/integrationsapi/types/install_stripe_response.rb rename lib/schematic/integrationsapi/types/{load_sample_data_set_v_2_response.rb => load_sample_data_set_response.rb} (83%) create mode 100644 lib/schematic/types/billing_credit_ledger_authority.rb create mode 100644 lib/schematic/types/checkout_field_input.rb create mode 100644 lib/schematic/types/checkout_field_response_data.rb create mode 100644 lib/schematic/types/checkout_field_value.rb create mode 100644 lib/schematic/types/checkout_field_with_value.rb create mode 100644 lib/schematic/types/credit_usage_reason.rb create mode 100644 lib/schematic/types/install_integration_request_body.rb create mode 100644 lib/schematic/types/integration_install_config.rb create mode 100644 lib/schematic/types/integration_install_response_data.rb create mode 100644 lib/schematic/types/metronome_integration_config.rb diff --git a/.fern/metadata.json b/.fern/metadata.json index 198b5f7..9629b5f 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -13,6 +13,6 @@ "webrick": ">= 1.0" } }, - "originGitCommit": "a3057c10aa6a1daa708dc714c89ce943f67a722a", - "sdkVersion": "1.4.3" + "originGitCommit": "ad1cc528e658e3693935b819c9d22eed02d49017", + "sdkVersion": "1.4.4" } \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index febdc8c..e23c00e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - schematichq (1.4.3) + schematichq (1.4.4) wasmtime (>= 19.0) websocket (>= 1.2) @@ -18,7 +18,7 @@ GEM rexml hashdiff (1.2.1) io-console (0.8.2) - json (2.19.7) + json (2.19.8) language_server-protocol (3.17.0.5) lint_roller (1.1.0) method_source (1.1.0) diff --git a/lib/schematic.rb b/lib/schematic.rb index 7229600..656119c 100644 --- a/lib/schematic.rb +++ b/lib/schematic.rb @@ -41,6 +41,9 @@ require_relative "schematic/types/account_member_response_data" require_relative "schematic/accounts/types/list_account_members_response" require_relative "schematic/accounts/types/get_account_member_response" +require_relative "schematic/accounts/types/count_account_members_params" +require_relative "schematic/types/count_response" +require_relative "schematic/accounts/types/count_account_members_response" require_relative "schematic/accounts/types/list_api_keys_params" require_relative "schematic/types/integration_state" require_relative "schematic/types/integration_type" @@ -57,7 +60,6 @@ require_relative "schematic/types/delete_response" require_relative "schematic/accounts/types/delete_api_key_response" require_relative "schematic/accounts/types/count_api_keys_params" -require_relative "schematic/types/count_response" require_relative "schematic/accounts/types/count_api_keys_response" require_relative "schematic/types/actor_type" require_relative "schematic/accounts/types/list_audit_logs_params" @@ -203,12 +205,14 @@ require_relative "schematic/credits/types/count_billing_plan_credit_grants_response" require_relative "schematic/types/credit_event_type" require_relative "schematic/credits/types/list_credit_event_ledger_params" +require_relative "schematic/types/credit_usage_reason" require_relative "schematic/types/credit_event_ledger_response_data" require_relative "schematic/credits/types/list_credit_event_ledger_response" require_relative "schematic/credits/types/count_credit_event_ledger_params" require_relative "schematic/credits/types/count_credit_event_ledger_response" require_relative "schematic/types/checkout_subscription" require_relative "schematic/checkout/types/checkout_internal_response" +require_relative "schematic/types/billing_credit_ledger_authority" require_relative "schematic/types/credit_currency_price" require_relative "schematic/types/billing_credit_view" require_relative "schematic/types/billing_linked_resource_response_data" @@ -217,6 +221,7 @@ require_relative "schematic/types/billing_subscription_discount_view" require_relative "schematic/types/billing_subscription_view" require_relative "schematic/types/charge_type" +require_relative "schematic/types/checkout_field_with_value" require_relative "schematic/types/metric_period" require_relative "schematic/types/metric_period_month_reset" require_relative "schematic/types/company_event_period_metrics_response_data" @@ -536,6 +541,7 @@ require_relative "schematic/integrationsapi/types/list_integrations_params" require_relative "schematic/types/clerk_integration_config" require_relative "schematic/types/integration_capabilities" +require_relative "schematic/types/metronome_integration_config" require_relative "schematic/types/orb_integration_config" require_relative "schematic/types/stripe_integration_config" require_relative "schematic/types/work_os_integration_config" @@ -544,11 +550,19 @@ require_relative "schematic/integrationsapi/types/list_integrations_response" require_relative "schematic/types/integration_webhook_url_response_data" require_relative "schematic/integrationsapi/types/get_integration_webhook_url_response" +require_relative "schematic/types/company_matching_criteria" +require_relative "schematic/types/integration_install_config" +require_relative "schematic/types/integration_response_data" +require_relative "schematic/types/integration_install_response_data" +require_relative "schematic/integrationsapi/types/install_integration_response" require_relative "schematic/integrationsapi/types/start_data_import_response" require_relative "schematic/types/integrations_data_set_response_data" -require_relative "schematic/integrationsapi/types/load_sample_data_set_v_2_response" +require_relative "schematic/integrationsapi/types/load_sample_data_set_response" +require_relative "schematic/integrationsapi/types/assume_stripe_installed_response" +require_relative "schematic/integrationsapi/types/install_stripe_response" require_relative "schematic/integrationsapi/types/uninstall_integration_response" require_relative "schematic/plangroups/types/get_plan_group_params" +require_relative "schematic/types/checkout_field_response_data" require_relative "schematic/types/checkout_settings_response_data" require_relative "schematic/types/component_settings_response_data" require_relative "schematic/types/custom_plan_view_config_response_data" @@ -620,6 +634,7 @@ require_relative "schematic/types/billing_subscription_discount" require_relative "schematic/types/capture_raw_event" require_relative "schematic/types/capture_raw_event_batch" +require_relative "schematic/types/checkout_field_value" require_relative "schematic/types/update_add_on_request_body" require_relative "schematic/types/update_auto_topup_override_request_body" require_relative "schematic/types/update_credit_bundle_request_body" @@ -627,7 +642,7 @@ require_relative "schematic/types/change_subscription_internal_request_body" require_relative "schematic/types/change_subscription_request_body" require_relative "schematic/types/check_flag_request_body" -require_relative "schematic/types/company_matching_criteria" +require_relative "schematic/types/checkout_field_input" require_relative "schematic/types/company_membership_response_data" require_relative "schematic/types/component_hydrate_response_data" require_relative "schematic/types/condition_group_response_data" @@ -671,7 +686,7 @@ require_relative "schematic/types/flag_view" require_relative "schematic/types/feature_view" require_relative "schematic/types/feature_usage_legacy_response_data" -require_relative "schematic/types/integration_response_data" +require_relative "schematic/types/install_integration_request_body" require_relative "schematic/types/invoice_request_body" require_relative "schematic/types/keys_request_body" require_relative "schematic/types/plan_selection" @@ -728,6 +743,7 @@ require_relative "schematic/client" require_relative "schematic/accounts/client" require_relative "schematic/accounts/types/list_account_members_request" +require_relative "schematic/accounts/types/count_account_members_request" require_relative "schematic/accounts/types/list_api_keys_request" require_relative "schematic/accounts/types/create_api_key_request_body" require_relative "schematic/accounts/types/update_api_key_request_body" diff --git a/lib/schematic/accounts/client.rb b/lib/schematic/accounts/client.rb index cfa0448..23ff762 100644 --- a/lib/schematic/accounts/client.rb +++ b/lib/schematic/accounts/client.rb @@ -86,6 +86,50 @@ def get_account_member(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, nil] :ids + # @option params [String, nil] :q + # @option params [Integer, nil] :limit + # @option params [Integer, nil] :offset + # + # @return [Schematic::Accounts::Types::CountAccountMembersResponse] + def count_account_members(request_options: {}, **params) + params = Schematic::Internal::Types::Utils.normalize_keys(params) + query_param_names = %i[ids q limit offset] + query_params = {} + query_params["ids"] = params[:ids] if params.key?(:ids) + query_params["q"] = params[:q] if params.key?(:q) + query_params["limit"] = params[:limit] if params.key?(:limit) + query_params["offset"] = params[:offset] if params.key?(:offset) + params.except(*query_param_names) + + request = Schematic::Internal::JSON::Request.new( + base_url: request_options[:base_url], + method: "GET", + path: "account-members/count", + query: query_params, + 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::Accounts::Types::CountAccountMembersResponse.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/accounts/types/count_account_members_params.rb b/lib/schematic/accounts/types/count_account_members_params.rb new file mode 100644 index 0000000..902bf6a --- /dev/null +++ b/lib/schematic/accounts/types/count_account_members_params.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Schematic + module Accounts + module Types + # Input parameters + class CountAccountMembersParams < Internal::Types::Model + field :ids, -> { Internal::Types::Array[String] }, optional: true, nullable: false + field :limit, -> { Integer }, optional: true, nullable: false + field :offset, -> { Integer }, optional: true, nullable: false + field :q, -> { String }, optional: true, nullable: false + end + end + end +end diff --git a/lib/schematic/accounts/types/count_account_members_request.rb b/lib/schematic/accounts/types/count_account_members_request.rb new file mode 100644 index 0000000..096388d --- /dev/null +++ b/lib/schematic/accounts/types/count_account_members_request.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Schematic + module Accounts + module Types + class CountAccountMembersRequest < Internal::Types::Model + field :ids, -> { String }, optional: true, nullable: false + field :q, -> { String }, optional: true, nullable: false + field :limit, -> { Integer }, optional: true, nullable: false + field :offset, -> { Integer }, optional: true, nullable: false + end + end + end +end diff --git a/lib/schematic/accounts/types/count_account_members_response.rb b/lib/schematic/accounts/types/count_account_members_response.rb new file mode 100644 index 0000000..605e9ce --- /dev/null +++ b/lib/schematic/accounts/types/count_account_members_response.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Schematic + module Accounts + module Types + class CountAccountMembersResponse < Internal::Types::Model + field :data, -> { Schematic::Types::CountResponse }, optional: false, nullable: false + field :params, -> { Schematic::Accounts::Types::CountAccountMembersParams }, optional: false, nullable: false + end + end + end +end diff --git a/lib/schematic/client.rb b/lib/schematic/client.rb index 1bd2ab8..94f280f 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.3", + "User-Agent" => "schematichq/1.4.4", "X-Fern-Language" => "Ruby", "X-Schematic-Api-Key" => api_key.to_s } diff --git a/lib/schematic/integrationsapi/client.rb b/lib/schematic/integrationsapi/client.rb index bd26243..15eddd8 100644 --- a/lib/schematic/integrationsapi/client.rb +++ b/lib/schematic/integrationsapi/client.rb @@ -124,6 +124,38 @@ def get_integration_webhook_url(request_options: {}, **params) end end + # @param request_options [Hash] + # @param params [Schematic::Types::InstallIntegrationRequestBody] + # @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 + # + # @return [Schematic::Integrationsapi::Types::InstallIntegrationResponse] + def install_integration(request_options: {}, **params) + params = Schematic::Internal::Types::Utils.normalize_keys(params) + request = Schematic::Internal::JSON::Request.new( + base_url: request_options[:base_url], + method: "POST", + path: "integrations/install", + body: Schematic::Types::InstallIntegrationRequestBody.new(params).to_h, + 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::Integrationsapi::Types::InstallIntegrationResponse.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::Integrationsapi::Types::StartDataImportRequestBody] # @option request_options [String] :base_url @@ -164,8 +196,8 @@ def start_data_import(request_options: {}, **params) # @option request_options [Hash{String => Object}] :additional_body_parameters # @option request_options [Integer] :timeout_in_seconds # - # @return [Schematic::Integrationsapi::Types::LoadSampleDataSetV2Response] - def load_sample_data_set_v_2(request_options: {}, **params) + # @return [Schematic::Integrationsapi::Types::LoadSampleDataSetResponse] + def load_sample_data_set(request_options: {}, **params) Schematic::Internal::Types::Utils.normalize_keys(params) request = Schematic::Internal::JSON::Request.new( base_url: request_options[:base_url], @@ -180,7 +212,71 @@ def load_sample_data_set_v_2(request_options: {}, **params) end code = response.code.to_i if code.between?(200, 299) - Schematic::Integrationsapi::Types::LoadSampleDataSetV2Response.load(response.body) + Schematic::Integrationsapi::Types::LoadSampleDataSetResponse.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::Types::InstallIntegrationRequestBody] + # @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 + # + # @return [Schematic::Integrationsapi::Types::AssumeStripeInstalledResponse] + def assume_stripe_installed(request_options: {}, **params) + params = Schematic::Internal::Types::Utils.normalize_keys(params) + request = Schematic::Internal::JSON::Request.new( + base_url: request_options[:base_url], + method: "POST", + path: "integrations/stripe/v2/assume-installed", + body: Schematic::Types::InstallIntegrationRequestBody.new(params).to_h, + 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::Integrationsapi::Types::AssumeStripeInstalledResponse.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::Types::InstallIntegrationRequestBody] + # @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 + # + # @return [Schematic::Integrationsapi::Types::InstallStripeResponse] + def install_stripe(request_options: {}, **params) + params = Schematic::Internal::Types::Utils.normalize_keys(params) + request = Schematic::Internal::JSON::Request.new( + base_url: request_options[:base_url], + method: "POST", + path: "integrations/stripe/v2/install", + body: Schematic::Types::InstallIntegrationRequestBody.new(params).to_h, + 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::Integrationsapi::Types::InstallStripeResponse.load(response.body) else error_class = Schematic::Errors::ResponseError.subclass_for_code(code) raise error_class.new(response.body, code: code) diff --git a/lib/schematic/integrationsapi/types/assume_stripe_installed_response.rb b/lib/schematic/integrationsapi/types/assume_stripe_installed_response.rb new file mode 100644 index 0000000..f71df8a --- /dev/null +++ b/lib/schematic/integrationsapi/types/assume_stripe_installed_response.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Schematic + module Integrationsapi + module Types + class AssumeStripeInstalledResponse < Internal::Types::Model + field :data, -> { Schematic::Types::IntegrationInstallResponseData }, optional: false, nullable: false + field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false + end + end + end +end diff --git a/lib/schematic/integrationsapi/types/install_integration_response.rb b/lib/schematic/integrationsapi/types/install_integration_response.rb new file mode 100644 index 0000000..2b58a14 --- /dev/null +++ b/lib/schematic/integrationsapi/types/install_integration_response.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Schematic + module Integrationsapi + module Types + class InstallIntegrationResponse < Internal::Types::Model + field :data, -> { Schematic::Types::IntegrationInstallResponseData }, optional: false, nullable: false + field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false + end + end + end +end diff --git a/lib/schematic/integrationsapi/types/install_stripe_response.rb b/lib/schematic/integrationsapi/types/install_stripe_response.rb new file mode 100644 index 0000000..38698e0 --- /dev/null +++ b/lib/schematic/integrationsapi/types/install_stripe_response.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Schematic + module Integrationsapi + module Types + class InstallStripeResponse < Internal::Types::Model + field :data, -> { Schematic::Types::IntegrationInstallResponseData }, optional: false, nullable: false + field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false + end + end + end +end diff --git a/lib/schematic/integrationsapi/types/load_sample_data_set_v_2_response.rb b/lib/schematic/integrationsapi/types/load_sample_data_set_response.rb similarity index 83% rename from lib/schematic/integrationsapi/types/load_sample_data_set_v_2_response.rb rename to lib/schematic/integrationsapi/types/load_sample_data_set_response.rb index 8891e48..e673355 100644 --- a/lib/schematic/integrationsapi/types/load_sample_data_set_v_2_response.rb +++ b/lib/schematic/integrationsapi/types/load_sample_data_set_response.rb @@ -3,7 +3,7 @@ module Schematic module Integrationsapi module Types - class LoadSampleDataSetV2Response < Internal::Types::Model + class LoadSampleDataSetResponse < Internal::Types::Model field :data, -> { Schematic::Types::IntegrationsDataSetResponseData }, optional: false, nullable: false field :params, -> { Internal::Types::Hash[String, Object] }, optional: false, nullable: false end diff --git a/lib/schematic/plangroups/types/create_plan_group_request_body.rb b/lib/schematic/plangroups/types/create_plan_group_request_body.rb index 43b62dc..277892d 100644 --- a/lib/schematic/plangroups/types/create_plan_group_request_body.rb +++ b/lib/schematic/plangroups/types/create_plan_group_request_body.rb @@ -9,6 +9,7 @@ class CreatePlanGroupRequestBody < Internal::Types::Model field :checkout_collect_address, -> { Internal::Types::Boolean }, optional: false, nullable: false field :checkout_collect_email, -> { Internal::Types::Boolean }, optional: false, nullable: false field :checkout_collect_phone, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldInput] }, optional: true, nullable: false field :custom_plan_config, -> { Schematic::Types::CustomPlanConfig }, optional: true, nullable: false field :custom_plan_id, -> { String }, optional: true, nullable: false field :enable_tax_collection, -> { Internal::Types::Boolean }, optional: false, nullable: false diff --git a/lib/schematic/plangroups/types/update_plan_group_request_body.rb b/lib/schematic/plangroups/types/update_plan_group_request_body.rb index e5dee17..303b4d8 100644 --- a/lib/schematic/plangroups/types/update_plan_group_request_body.rb +++ b/lib/schematic/plangroups/types/update_plan_group_request_body.rb @@ -10,6 +10,7 @@ class UpdatePlanGroupRequestBody < Internal::Types::Model field :checkout_collect_address, -> { Internal::Types::Boolean }, optional: false, nullable: false field :checkout_collect_email, -> { Internal::Types::Boolean }, optional: false, nullable: false field :checkout_collect_phone, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldInput] }, optional: true, nullable: false field :custom_plan_config, -> { Schematic::Types::CustomPlanConfig }, optional: true, nullable: false field :custom_plan_id, -> { String }, optional: true, nullable: false field :enable_tax_collection, -> { Internal::Types::Boolean }, optional: false, nullable: false diff --git a/lib/schematic/types/account_member_response_data.rb b/lib/schematic/types/account_member_response_data.rb index 9f76714..ce27c06 100644 --- a/lib/schematic/types/account_member_response_data.rb +++ b/lib/schematic/types/account_member_response_data.rb @@ -5,8 +5,10 @@ module Types class AccountMemberResponseData < Internal::Types::Model field :created_at, -> { String }, optional: false, nullable: false field :email, -> { String }, optional: true, nullable: false + field :first_name, -> { String }, optional: true, nullable: false field :id, -> { String }, optional: false, nullable: false field :image_url, -> { String }, optional: true, nullable: false + field :last_name, -> { String }, optional: true, nullable: false field :name, -> { String }, optional: true, nullable: false field :permissions, -> { Internal::Types::Hash[String, Internal::Types::Array[Schematic::Types::AccountMemberPermission]] }, optional: false, nullable: false field :role, -> { Schematic::Types::AccountMemberRole }, optional: true, nullable: false diff --git a/lib/schematic/types/billing_credit_grant_reason.rb b/lib/schematic/types/billing_credit_grant_reason.rb index d785edf..328af11 100644 --- a/lib/schematic/types/billing_credit_grant_reason.rb +++ b/lib/schematic/types/billing_credit_grant_reason.rb @@ -10,6 +10,7 @@ module BillingCreditGrantReason FREE = "free" PLAN = "plan" PURCHASED = "purchased" + ROLLOVER = "rollover" end end end diff --git a/lib/schematic/types/billing_credit_grant_response_data.rb b/lib/schematic/types/billing_credit_grant_response_data.rb index ab8a77f..99621af 100644 --- a/lib/schematic/types/billing_credit_grant_response_data.rb +++ b/lib/schematic/types/billing_credit_grant_response_data.rb @@ -21,6 +21,9 @@ class BillingCreditGrantResponseData < Internal::Types::Model field :quantity_used, -> { Integer }, optional: false, nullable: false field :renewal_enabled, -> { Internal::Types::Boolean }, optional: false, nullable: false field :renewal_period, -> { Schematic::Types::BillingPlanCreditGrantResetCadence }, optional: true, nullable: false + field :reserved, -> { Integer }, optional: true, nullable: false + field :settled, -> { Integer }, optional: true, nullable: false + field :source_grant_id, -> { String }, optional: true, nullable: false field :source_label, -> { String }, optional: false, nullable: false field :transfers, -> { Internal::Types::Array[Schematic::Types::CreditTransferResponseData] }, optional: true, nullable: false field :updated_at, -> { String }, optional: false, nullable: false diff --git a/lib/schematic/types/billing_credit_ledger_authority.rb b/lib/schematic/types/billing_credit_ledger_authority.rb new file mode 100644 index 0000000..c89fbb8 --- /dev/null +++ b/lib/schematic/types/billing_credit_ledger_authority.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Schematic + module Types + module BillingCreditLedgerAuthority + extend Schematic::Internal::Types::Enum + + SCHEMATIC_AUTHORITATIVE = "schematic_authoritative" + EXTERNAL_MIRROR = "external_mirror" + EXTERNAL_RATED = "external_rated" + end + end +end diff --git a/lib/schematic/types/billing_credit_view.rb b/lib/schematic/types/billing_credit_view.rb index 00f2a7a..2f13501 100644 --- a/lib/schematic/types/billing_credit_view.rb +++ b/lib/schematic/types/billing_credit_view.rb @@ -15,6 +15,7 @@ class BillingCreditView < Internal::Types::Model field :environment_id, -> { String }, optional: false, nullable: false field :icon, -> { String }, optional: true, nullable: false field :id, -> { String }, optional: false, nullable: false + field :ledger_authority, -> { Schematic::Types::BillingCreditLedgerAuthority }, optional: false, nullable: false field :name, -> { String }, optional: false, nullable: false field :plural_name, -> { String }, optional: true, nullable: false field :price, -> { Schematic::Types::BillingPriceView }, optional: true, nullable: false diff --git a/lib/schematic/types/billing_plan_credit_grant_response_data.rb b/lib/schematic/types/billing_plan_credit_grant_response_data.rb index 22be983..4c4b7a7 100644 --- a/lib/schematic/types/billing_plan_credit_grant_response_data.rb +++ b/lib/schematic/types/billing_plan_credit_grant_response_data.rb @@ -30,6 +30,7 @@ class BillingPlanCreditGrantResponseData < Internal::Types::Model field :reset_cadence, -> { Schematic::Types::BillingPlanCreditGrantResetCadence }, optional: true, nullable: false field :reset_start, -> { Schematic::Types::BillingPlanCreditGrantResetStart }, optional: true, nullable: false field :reset_type, -> { Schematic::Types::BillingPlanCreditGrantResetType }, optional: true, nullable: false + field :rollover_percentage, -> { Integer }, optional: false, nullable: false field :updated_at, -> { String }, optional: false, nullable: false end end diff --git a/lib/schematic/types/billing_provider_type.rb b/lib/schematic/types/billing_provider_type.rb index 45435b1..962fe28 100644 --- a/lib/schematic/types/billing_provider_type.rb +++ b/lib/schematic/types/billing_provider_type.rb @@ -5,6 +5,7 @@ module Types module BillingProviderType extend Schematic::Internal::Types::Enum + METRONOME = "metronome" ORB = "orb" SCHEMATIC = "schematic" STRIPE = "stripe" diff --git a/lib/schematic/types/change_subscription_internal_request_body.rb b/lib/schematic/types/change_subscription_internal_request_body.rb index 9877ca0..c4754e6 100644 --- a/lib/schematic/types/change_subscription_internal_request_body.rb +++ b/lib/schematic/types/change_subscription_internal_request_body.rb @@ -8,6 +8,7 @@ class ChangeSubscriptionInternalRequestBody < Internal::Types::Model field :company_id, -> { String }, optional: false, nullable: false field :coupon_external_id, -> { String }, optional: true, nullable: false field :credit_bundles, -> { Internal::Types::Array[Schematic::Types::UpdateCreditBundleRequestBody] }, optional: false, nullable: false + field :custom_field_values, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldValue] }, optional: false, nullable: false field :new_plan_id, -> { String }, optional: false, nullable: false field :new_price_id, -> { String }, optional: false, nullable: false field :pay_in_advance, -> { Internal::Types::Array[Schematic::Types::UpdatePayInAdvanceRequestBody] }, optional: false, nullable: false diff --git a/lib/schematic/types/change_subscription_request_body.rb b/lib/schematic/types/change_subscription_request_body.rb index 265d5a2..473a57b 100644 --- a/lib/schematic/types/change_subscription_request_body.rb +++ b/lib/schematic/types/change_subscription_request_body.rb @@ -7,6 +7,7 @@ class ChangeSubscriptionRequestBody < Internal::Types::Model field :auto_topup_overrides, -> { Internal::Types::Array[Schematic::Types::UpdateAutoTopupOverrideRequestBody] }, optional: false, nullable: false field :coupon_external_id, -> { String }, optional: true, nullable: false field :credit_bundles, -> { Internal::Types::Array[Schematic::Types::UpdateCreditBundleRequestBody] }, optional: false, nullable: false + field :custom_field_values, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldValue] }, optional: false, nullable: false field :new_plan_id, -> { String }, optional: false, nullable: false field :new_price_id, -> { String }, optional: false, nullable: false field :pay_in_advance, -> { Internal::Types::Array[Schematic::Types::UpdatePayInAdvanceRequestBody] }, optional: false, nullable: false diff --git a/lib/schematic/types/checkout_data_response_data.rb b/lib/schematic/types/checkout_data_response_data.rb index 715ad1c..a95bec5 100644 --- a/lib/schematic/types/checkout_data_response_data.rb +++ b/lib/schematic/types/checkout_data_response_data.rb @@ -8,6 +8,7 @@ class CheckoutDataResponseData < Internal::Types::Model field :active_usage_based_entitlements, -> { Internal::Types::Array[Schematic::Types::UsageBasedEntitlementResponseData] }, optional: false, nullable: false field :available_credit_bundles, -> { Internal::Types::Array[Schematic::Types::BillingCreditBundleResponseData] }, optional: false, nullable: false field :company, -> { Schematic::Types::CompanyDetailResponseData }, optional: true, nullable: false + field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldWithValue] }, optional: false, nullable: false field :feature_usage, -> { Schematic::Types::FeatureUsageDetailResponseData }, optional: true, nullable: false field :selected_credit_bundles, -> { Internal::Types::Array[Schematic::Types::CreditBundlePurchaseResponseData] }, optional: false, nullable: false field :selected_plan, -> { Schematic::Types::PlanDetailResponseData }, optional: true, nullable: false diff --git a/lib/schematic/types/checkout_field_input.rb b/lib/schematic/types/checkout_field_input.rb new file mode 100644 index 0000000..a7f985c --- /dev/null +++ b/lib/schematic/types/checkout_field_input.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Schematic + module Types + class CheckoutFieldInput < Internal::Types::Model + field :definition_id, -> { String }, optional: true, nullable: false + field :helper_text, -> { String }, optional: true, nullable: false + field :id, -> { String }, optional: true, nullable: false + field :name, -> { String }, optional: false, nullable: false + field :required, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :stripe_metadata_key, -> { String }, optional: false, nullable: false + end + end +end diff --git a/lib/schematic/types/checkout_field_response_data.rb b/lib/schematic/types/checkout_field_response_data.rb new file mode 100644 index 0000000..64bfaf6 --- /dev/null +++ b/lib/schematic/types/checkout_field_response_data.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Schematic + module Types + class CheckoutFieldResponseData < Internal::Types::Model + field :created_at, -> { String }, optional: false, nullable: false + field :definition_id, -> { String }, optional: false, nullable: false + field :helper_text, -> { String }, optional: true, nullable: false + field :id, -> { String }, optional: false, nullable: false + field :name, -> { String }, optional: false, nullable: false + field :position, -> { Integer }, optional: false, nullable: false + field :required, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :stripe_metadata_key, -> { String }, optional: false, nullable: false + field :trait_hierarchy, -> { Internal::Types::Array[String] }, optional: false, nullable: false + field :updated_at, -> { String }, optional: false, nullable: false + end + end +end diff --git a/lib/schematic/types/checkout_field_value.rb b/lib/schematic/types/checkout_field_value.rb new file mode 100644 index 0000000..8da8eaa --- /dev/null +++ b/lib/schematic/types/checkout_field_value.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Schematic + module Types + class CheckoutFieldValue < Internal::Types::Model + field :id, -> { String }, optional: false, nullable: false + field :value, -> { String }, optional: false, nullable: false + end + end +end diff --git a/lib/schematic/types/checkout_field_with_value.rb b/lib/schematic/types/checkout_field_with_value.rb new file mode 100644 index 0000000..66777e8 --- /dev/null +++ b/lib/schematic/types/checkout_field_with_value.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Schematic + module Types + class CheckoutFieldWithValue < Internal::Types::Model + field :definition_id, -> { String }, optional: false, nullable: false + field :helper_text, -> { String }, optional: true, nullable: false + field :id, -> { String }, optional: false, nullable: false + field :name, -> { String }, optional: false, nullable: false + field :required, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :stripe_metadata_key, -> { String }, optional: false, nullable: false + field :value, -> { String }, optional: true, nullable: false + end + end +end diff --git a/lib/schematic/types/company_credit_balance_response_data.rb b/lib/schematic/types/company_credit_balance_response_data.rb index f7fcadb..dbac71c 100644 --- a/lib/schematic/types/company_credit_balance_response_data.rb +++ b/lib/schematic/types/company_credit_balance_response_data.rb @@ -5,6 +5,8 @@ module Types class CompanyCreditBalanceResponseData < Internal::Types::Model field :credit_id, -> { String }, optional: false, nullable: false field :remaining, -> { Integer }, optional: false, nullable: false + field :reserved, -> { Integer }, optional: false, nullable: false + field :settled, -> { Integer }, optional: false, nullable: false field :source, -> { Schematic::Types::BillingProviderType }, optional: false, nullable: false field :total, -> { Integer }, optional: true, nullable: false end diff --git a/lib/schematic/types/company_plan_credit_grant_view.rb b/lib/schematic/types/company_plan_credit_grant_view.rb index 33cf849..5c5b34b 100644 --- a/lib/schematic/types/company_plan_credit_grant_view.rb +++ b/lib/schematic/types/company_plan_credit_grant_view.rb @@ -33,6 +33,7 @@ class CompanyPlanCreditGrantView < Internal::Types::Model field :reset_cadence, -> { Schematic::Types::BillingPlanCreditGrantResetCadence }, optional: true, nullable: false field :reset_start, -> { Schematic::Types::BillingPlanCreditGrantResetStart }, optional: true, nullable: false field :reset_type, -> { Schematic::Types::BillingPlanCreditGrantResetType }, optional: false, nullable: false + field :rollover_percentage, -> { Integer }, optional: false, nullable: false field :singular_name, -> { String }, optional: true, nullable: false field :updated_at, -> { String }, optional: false, nullable: false end diff --git a/lib/schematic/types/component_hydrate_response_data.rb b/lib/schematic/types/component_hydrate_response_data.rb index 9a9dca6..2485411 100644 --- a/lib/schematic/types/component_hydrate_response_data.rb +++ b/lib/schematic/types/component_hydrate_response_data.rb @@ -13,6 +13,7 @@ class ComponentHydrateResponseData < Internal::Types::Model field :component, -> { Schematic::Types::ComponentResponseData }, optional: true, nullable: false field :credit_bundles, -> { Internal::Types::Array[Schematic::Types::BillingCreditBundleView] }, optional: false, nullable: false field :credit_grants, -> { Internal::Types::Array[Schematic::Types::CreditCompanyGrantView] }, optional: false, nullable: false + field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldWithValue] }, optional: false, nullable: false field :default_plan, -> { Schematic::Types::PlanDetailResponseData }, optional: true, nullable: false field :display_settings, -> { Schematic::Types::ComponentDisplaySettings }, optional: false, nullable: false field :feature_usage, -> { Schematic::Types::FeatureUsageDetailResponseData }, optional: true, nullable: false diff --git a/lib/schematic/types/component_preview_response_data.rb b/lib/schematic/types/component_preview_response_data.rb index dc5c424..f03c7b0 100644 --- a/lib/schematic/types/component_preview_response_data.rb +++ b/lib/schematic/types/component_preview_response_data.rb @@ -13,6 +13,7 @@ class ComponentPreviewResponseData < Internal::Types::Model field :component, -> { Schematic::Types::ComponentResponseData }, optional: true, nullable: false field :credit_bundles, -> { Internal::Types::Array[Schematic::Types::BillingCreditBundleView] }, optional: false, nullable: false field :credit_grants, -> { Internal::Types::Array[Schematic::Types::CreditCompanyGrantView] }, optional: false, nullable: false + field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldWithValue] }, optional: false, nullable: false field :default_plan, -> { Schematic::Types::PlanDetailResponseData }, optional: true, nullable: false field :display_settings, -> { Schematic::Types::ComponentDisplaySettings }, optional: false, nullable: false field :feature_usage, -> { Schematic::Types::FeatureUsageDetailResponseData }, optional: true, nullable: false diff --git a/lib/schematic/types/create_billing_plan_credit_grant_request_body.rb b/lib/schematic/types/create_billing_plan_credit_grant_request_body.rb index 2841425..5699cec 100644 --- a/lib/schematic/types/create_billing_plan_credit_grant_request_body.rb +++ b/lib/schematic/types/create_billing_plan_credit_grant_request_body.rb @@ -23,6 +23,7 @@ class CreateBillingPlanCreditGrantRequestBody < Internal::Types::Model field :reset_cadence, -> { Schematic::Types::BillingPlanCreditGrantResetCadence }, optional: false, nullable: false field :reset_start, -> { Schematic::Types::BillingPlanCreditGrantResetStart }, optional: false, nullable: false field :reset_type, -> { Schematic::Types::BillingPlanCreditGrantResetType }, optional: true, nullable: false + field :rollover_percentage, -> { Integer }, optional: true, nullable: false end end end diff --git a/lib/schematic/types/credit_company_grant_view.rb b/lib/schematic/types/credit_company_grant_view.rb index e23e113..9383c94 100644 --- a/lib/schematic/types/credit_company_grant_view.rb +++ b/lib/schematic/types/credit_company_grant_view.rb @@ -28,7 +28,10 @@ class CreditCompanyGrantView < Internal::Types::Model field :quantity_used, -> { Integer }, optional: false, nullable: false field :renewal_enabled, -> { Internal::Types::Boolean }, optional: false, nullable: false field :renewal_period, -> { Schematic::Types::BillingPlanCreditGrantResetCadence }, optional: true, nullable: false + field :reserved, -> { Integer }, optional: true, nullable: false + field :settled, -> { Integer }, optional: true, nullable: false field :singular_name, -> { String }, optional: true, nullable: false + field :source_grant_id, -> { String }, optional: true, nullable: false field :source_label, -> { String }, optional: false, nullable: false field :transfers, -> { Internal::Types::Array[Schematic::Types::CreditTransferView] }, optional: true, nullable: false field :updated_at, -> { String }, optional: false, nullable: false diff --git a/lib/schematic/types/credit_event_ledger_response_data.rb b/lib/schematic/types/credit_event_ledger_response_data.rb index 4e3d210..d8df1bb 100644 --- a/lib/schematic/types/credit_event_ledger_response_data.rb +++ b/lib/schematic/types/credit_event_ledger_response_data.rb @@ -33,6 +33,7 @@ class CreditEventLedgerResponseData < Internal::Types::Model field :source_id, -> { Integer }, optional: false, nullable: false field :to_grant_id, -> { String }, optional: true, nullable: false field :usage_event_id, -> { String }, optional: true, nullable: false + field :usage_reason, -> { Schematic::Types::CreditUsageReason }, optional: true, nullable: false field :zeroed_out_reason, -> { Schematic::Types::BillingCreditGrantZeroedOutReason }, optional: true, nullable: false end end diff --git a/lib/schematic/types/credit_usage_reason.rb b/lib/schematic/types/credit_usage_reason.rb new file mode 100644 index 0000000..7798c68 --- /dev/null +++ b/lib/schematic/types/credit_usage_reason.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Schematic + module Types + module CreditUsageReason + extend Schematic::Internal::Types::Enum + + LEASE_HOLD = "lease_hold" + LEASE_RELEASE = "lease_release" + MANUAL_ADJUSTMENT = "manual_adjustment" + RECONCILIATION = "reconciliation" + TRACK = "track" + end + end +end diff --git a/lib/schematic/types/event_detail_response_data.rb b/lib/schematic/types/event_detail_response_data.rb index b627b65..5301f58 100644 --- a/lib/schematic/types/event_detail_response_data.rb +++ b/lib/schematic/types/event_detail_response_data.rb @@ -17,6 +17,7 @@ class EventDetailResponseData < Internal::Types::Model field :features, -> { Internal::Types::Array[Schematic::Types::PreviewObject] }, optional: false, nullable: false field :id, -> { String }, optional: false, nullable: false field :idempotency_key, -> { String }, optional: true, nullable: false + field :lease_id, -> { String }, optional: true, nullable: false field :loaded_at, -> { String }, optional: true, nullable: false field :processed_at, -> { String }, optional: true, nullable: false field :quantity, -> { Integer }, optional: false, nullable: false diff --git a/lib/schematic/types/event_response_data.rb b/lib/schematic/types/event_response_data.rb index 8bdda1a..8cd0e51 100644 --- a/lib/schematic/types/event_response_data.rb +++ b/lib/schematic/types/event_response_data.rb @@ -14,6 +14,7 @@ class EventResponseData < Internal::Types::Model field :feature_ids, -> { Internal::Types::Array[String] }, optional: false, nullable: false field :id, -> { String }, optional: false, nullable: false field :idempotency_key, -> { String }, optional: true, nullable: false + field :lease_id, -> { String }, optional: true, nullable: false field :loaded_at, -> { String }, optional: true, nullable: false field :processed_at, -> { String }, optional: true, nullable: false field :quantity, -> { Integer }, optional: false, nullable: false diff --git a/lib/schematic/types/install_integration_request_body.rb b/lib/schematic/types/install_integration_request_body.rb new file mode 100644 index 0000000..0806a26 --- /dev/null +++ b/lib/schematic/types/install_integration_request_body.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Schematic + module Types + class InstallIntegrationRequestBody < Internal::Types::Model + field :company_matching_criteria, -> { Schematic::Types::CompanyMatchingCriteria }, optional: true, nullable: false + field :company_matching_field, -> { String }, optional: true, nullable: false + field :config, -> { Internal::Types::Hash[String, Object] }, optional: true, nullable: false + field :is_sandbox, -> { Internal::Types::Boolean }, optional: true, nullable: false + field :live_mode, -> { Internal::Types::Boolean }, optional: true, nullable: false + field :type, -> { Schematic::Types::IntegrationType }, optional: false, nullable: false + end + end +end diff --git a/lib/schematic/types/integration_config.rb b/lib/schematic/types/integration_config.rb index 735dd54..bded1f6 100644 --- a/lib/schematic/types/integration_config.rb +++ b/lib/schematic/types/integration_config.rb @@ -8,6 +8,7 @@ class IntegrationConfig < Internal::Types::Model discriminant :type member -> { Schematic::Types::ClerkIntegrationConfig }, key: "CLERK" + member -> { Schematic::Types::MetronomeIntegrationConfig }, key: "METRONOME" member -> { Schematic::Types::OrbIntegrationConfig }, key: "ORB" member -> { Schematic::Types::StripeIntegrationConfig }, key: "STRIPE" member -> { Schematic::Types::WorkOsIntegrationConfig }, key: "WORKOS" diff --git a/lib/schematic/types/integration_install_config.rb b/lib/schematic/types/integration_install_config.rb new file mode 100644 index 0000000..8aaa0c8 --- /dev/null +++ b/lib/schematic/types/integration_install_config.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Schematic + module Types + class IntegrationInstallConfig < Internal::Types::Model + field :company_matching_criteria, -> { Schematic::Types::CompanyMatchingCriteria }, optional: true, nullable: false + field :company_matching_field, -> { String }, optional: true, nullable: false + field :config, -> { Schematic::Types::IntegrationConfig }, optional: true, nullable: false + field :created_at, -> { String }, optional: false, nullable: false + field :id, -> { String }, optional: false, nullable: false + field :integration_id, -> { String }, optional: false, nullable: false + field :is_app_install, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :is_connect_install, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :live_mode, -> { Internal::Types::Boolean }, optional: false, nullable: false + field :updated_at, -> { String }, optional: false, nullable: false + end + end +end diff --git a/lib/schematic/types/integration_install_response_data.rb b/lib/schematic/types/integration_install_response_data.rb new file mode 100644 index 0000000..6260089 --- /dev/null +++ b/lib/schematic/types/integration_install_response_data.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Schematic + module Types + class IntegrationInstallResponseData < Internal::Types::Model + field :capabilities, -> { Schematic::Types::IntegrationCapabilities }, optional: false, nullable: false + field :config, -> { Schematic::Types::IntegrationInstallConfig }, optional: false, nullable: false + field :integration, -> { Schematic::Types::IntegrationResponseData }, optional: false, nullable: false + end + end +end diff --git a/lib/schematic/types/integration_type.rb b/lib/schematic/types/integration_type.rb index 8da8aa3..ce0afe2 100644 --- a/lib/schematic/types/integration_type.rb +++ b/lib/schematic/types/integration_type.rb @@ -6,6 +6,7 @@ module IntegrationType extend Schematic::Internal::Types::Enum CLERK = "clerk" + METRONOME = "metronome" ORB = "orb" STRIPE = "stripe" UNKNOWN = "unknown" diff --git a/lib/schematic/types/manage_plan_request.rb b/lib/schematic/types/manage_plan_request.rb index f5dc071..3e5a652 100644 --- a/lib/schematic/types/manage_plan_request.rb +++ b/lib/schematic/types/manage_plan_request.rb @@ -11,6 +11,7 @@ class ManagePlanRequest < Internal::Types::Model field :company_id, -> { String }, optional: false, nullable: false field :coupon_external_id, -> { String }, optional: true, nullable: false field :credit_bundles, -> { Internal::Types::Array[Schematic::Types::UpdateCreditBundleRequestBody] }, optional: false, nullable: false + field :custom_field_values, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldValue] }, optional: false, nullable: false field :pay_in_advance_entitlements, -> { Internal::Types::Array[Schematic::Types::UpdatePayInAdvanceRequestBody] }, optional: false, nullable: false field :payment_method_external_id, -> { String }, optional: true, nullable: false field :promo_code, -> { String }, optional: true, nullable: false diff --git a/lib/schematic/types/metronome_integration_config.rb b/lib/schematic/types/metronome_integration_config.rb new file mode 100644 index 0000000..2ce7d00 --- /dev/null +++ b/lib/schematic/types/metronome_integration_config.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Schematic + module Types + class MetronomeIntegrationConfig < Internal::Types::Model; end + end +end diff --git a/lib/schematic/types/migration_error_code.rb b/lib/schematic/types/migration_error_code.rb index 4320571..292ec3c 100644 --- a/lib/schematic/types/migration_error_code.rb +++ b/lib/schematic/types/migration_error_code.rb @@ -9,6 +9,7 @@ module MigrationErrorCode MULTIPLE_SUBSCRIPTIONS = "multiple_subscriptions" NO_PRICE_FOR_INTERVAL = "no_price_for_interval" NOT_ON_ORIGIN_VERSION = "not_on_origin_version" + OPERATION_ITEM_NOT_FOUND = "operation_item_not_found" PERMANENT_CONFIG = "permanent_config" PERMANENT_DECLINE = "permanent_decline" TRANSIENT_DECLINE = "transient_decline" diff --git a/lib/schematic/types/plan_credit_grant_view.rb b/lib/schematic/types/plan_credit_grant_view.rb index 74d979c..cf16e36 100644 --- a/lib/schematic/types/plan_credit_grant_view.rb +++ b/lib/schematic/types/plan_credit_grant_view.rb @@ -30,6 +30,7 @@ class PlanCreditGrantView < Internal::Types::Model field :reset_cadence, -> { Schematic::Types::BillingPlanCreditGrantResetCadence }, optional: true, nullable: false field :reset_start, -> { Schematic::Types::BillingPlanCreditGrantResetStart }, optional: true, nullable: false field :reset_type, -> { Schematic::Types::BillingPlanCreditGrantResetType }, optional: false, nullable: false + field :rollover_percentage, -> { Integer }, optional: false, nullable: false field :singular_name, -> { String }, optional: true, nullable: false field :updated_at, -> { String }, optional: false, nullable: false end diff --git a/lib/schematic/types/plan_group_detail_response_data.rb b/lib/schematic/types/plan_group_detail_response_data.rb index 1a93b73..88f9361 100644 --- a/lib/schematic/types/plan_group_detail_response_data.rb +++ b/lib/schematic/types/plan_group_detail_response_data.rb @@ -6,6 +6,7 @@ class PlanGroupDetailResponseData < Internal::Types::Model field :add_ons, -> { Internal::Types::Array[Schematic::Types::PlanGroupPlanDetailResponseData] }, optional: false, nullable: false field :checkout_settings, -> { Schematic::Types::CheckoutSettingsResponseData }, optional: false, nullable: false field :component_settings, -> { Schematic::Types::ComponentSettingsResponseData }, optional: false, nullable: false + field :custom_checkout_fields, -> { Internal::Types::Array[Schematic::Types::CheckoutFieldResponseData] }, optional: false, nullable: false field :custom_plan_config, -> { Schematic::Types::CustomPlanViewConfigResponseData }, optional: true, nullable: false field :custom_plan_id, -> { String }, optional: true, nullable: false field :default_plan, -> { Schematic::Types::PlanGroupPlanDetailResponseData }, optional: true, nullable: false diff --git a/lib/schematic/types/update_billing_plan_credit_grant_request_body.rb b/lib/schematic/types/update_billing_plan_credit_grant_request_body.rb index b2d75f2..0014c49 100644 --- a/lib/schematic/types/update_billing_plan_credit_grant_request_body.rb +++ b/lib/schematic/types/update_billing_plan_credit_grant_request_body.rb @@ -20,6 +20,7 @@ class UpdateBillingPlanCreditGrantRequestBody < Internal::Types::Model field :reset_cadence, -> { Schematic::Types::BillingPlanCreditGrantResetCadence }, optional: false, nullable: false field :reset_start, -> { Schematic::Types::BillingPlanCreditGrantResetStart }, optional: false, nullable: false field :reset_type, -> { Schematic::Types::BillingPlanCreditGrantResetType }, optional: true, nullable: false + field :rollover_percentage, -> { Integer }, optional: true, nullable: false end end end diff --git a/lib/schematic/version.rb b/lib/schematic/version.rb index 05d0b19..0579c5e 100644 --- a/lib/schematic/version.rb +++ b/lib/schematic/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Schematic - VERSION = "1.4.3" + VERSION = "1.4.4" end diff --git a/reference.md b/reference.md index 1fc6be8..b1ac69a 100644 --- a/reference.md +++ b/reference.md @@ -121,6 +121,83 @@ client.accounts.get_account_member(account_member_id: "account_member_id") + + + + +
client.accounts.count_account_members() -> Schematic::Accounts::Types::CountAccountMembersResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```ruby +client.accounts.count_account_members( + ids: ["ids"], + q: "q", + limit: 1000000, + offset: 1000000 +) +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**ids:** `String` + +
+
+ +
+
+ +**q:** `String` — Search filter + +
+
+ +
+
+ +**limit:** `Integer` — Page limit (default 100) + +
+
+ +
+
+ +**offset:** `Integer` — Page offset (default 0) + +
+
+ +
+
+ +**request_options:** `Schematic::Accounts::RequestOptions` + +
+
+
+
+ +
@@ -1452,7 +1529,7 @@ client.billing.upsert_billing_customer( client.billing.list_customers_with_subscriptions( company_ids: ["company_ids"], name: "name", - provider_type: "orb", + provider_type: "metronome", q: "q", limit: 1000000, offset: 1000000 @@ -1547,7 +1624,7 @@ client.billing.list_customers_with_subscriptions( client.billing.count_customers( company_ids: ["company_ids"], name: "name", - provider_type: "orb", + provider_type: "metronome", q: "q", limit: 1000000, offset: 1000000 @@ -2305,7 +2382,7 @@ client.billing.list_billing_prices( price: 1000000, product_id: "product_id", product_ids: ["product_ids"], - provider_type: "orb", + provider_type: "metronome", q: "q", tiers_mode: "graduated", usage_type: "licensed", @@ -2727,7 +2804,7 @@ client.billing.list_billing_product_prices( price: 1000000, product_id: "product_id", product_ids: ["product_ids"], - provider_type: "orb", + provider_type: "metronome", q: "q", tiers_mode: "graduated", usage_type: "licensed", @@ -3038,7 +3115,7 @@ client.billing.list_billing_products( is_active: true, name: "name", price_usage_type: "licensed", - provider_type: "orb", + provider_type: "metronome", q: "q", recurring_charges_only: true, with_one_time_charges: true, @@ -3196,7 +3273,7 @@ client.billing.count_billing_products( is_active: true, name: "name", price_usage_type: "licensed", - provider_type: "orb", + provider_type: "metronome", q: "q", recurring_charges_only: true, with_one_time_charges: true, @@ -6355,6 +6432,10 @@ client.checkout.internal( bundle_id: "bundle_id", quantity: 1000000 }], + custom_field_values: [{ + id: "id", + value: "value" + }], new_plan_id: "new_plan_id", new_price_id: "new_price_id", pay_in_advance: [{ @@ -6479,6 +6560,10 @@ client.checkout.preview_checkout_internal( bundle_id: "bundle_id", quantity: 1000000 }], + custom_field_values: [{ + id: "id", + value: "value" + }], new_plan_id: "new_plan_id", new_price_id: "new_price_id", pay_in_advance: [{ @@ -6543,6 +6628,10 @@ client.checkout.manage_plan( bundle_id: "bundle_id", quantity: 1000000 }], + custom_field_values: [{ + id: "id", + value: "value" + }], pay_in_advance_entitlements: [{ price_id: "price_id", quantity: 1000000 @@ -6604,6 +6693,10 @@ client.checkout.preview_manage_plan( bundle_id: "bundle_id", quantity: 1000000 }], + custom_field_values: [{ + id: "id", + value: "value" + }], pay_in_advance_entitlements: [{ price_id: "price_id", quantity: 1000000 @@ -10285,7 +10378,7 @@ client.entitlements.list_feature_usage( company_id: "company_id", feature_ids: ["feature_ids"], include_usage_aggregation: true, - managed_by: "orb", + managed_by: "metronome", q: "q", without_negative_entitlements: true, limit: 1000000, @@ -10492,7 +10585,7 @@ client.entitlements.count_feature_usage( company_id: "company_id", feature_ids: ["feature_ids"], include_usage_aggregation: true, - managed_by: "orb", + managed_by: "metronome", q: "q", without_negative_entitlements: true, limit: 1000000, @@ -11599,7 +11692,7 @@ client.entitlements.delete_plan_entitlement(plan_entitlement_id: "plan_entitleme ```ruby client.entitlements.upsert_plan_entitlement_for_billing_product( - billing_provider: "orb", + billing_provider: "metronome", external_resource_id: "external_resource_id", feature_id: "feature_id", plan_id: "plan_id", @@ -13039,7 +13132,7 @@ client.plans.upsert_billing_product_plan( ```ruby client.plans.upsert_plan_for_billing_product( - billing_provider: "orb", + billing_provider: "metronome", description: "description", external_resource_id: "external_resource_id", name: "name", @@ -14898,7 +14991,7 @@ client.features.list_features( boolean_require_event: true, feature_type: ["boolean"], ids: ["ids"], - managed_by: "orb", + managed_by: "metronome", plan_version_id: "plan_version_id", q: "q", without_company_override_for: "without_company_override_for", @@ -15390,7 +15483,7 @@ client.features.delete_feature(feature_id: "feature_id") ```ruby client.features.upsert_feature_for_billing_product( - billing_provider: "orb", + billing_provider: "metronome", description: "description", external_resource_id: "external_resource_id", feature_type: "boolean", @@ -15543,7 +15636,7 @@ client.features.count_features( boolean_require_event: true, feature_type: ["boolean"], ids: ["ids"], - managed_by: "orb", + managed_by: "metronome", plan_version_id: "plan_version_id", q: "q", without_company_override_for: "without_company_override_for", @@ -16825,6 +16918,54 @@ client.integrationsapi.get_integration_webhook_url(type: "type") + + + + +
client.integrationsapi.install_integration(request) -> Schematic::Integrationsapi::Types::InstallIntegrationResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```ruby +client.integrationsapi.install_integration(type: "clerk") +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Schematic::Types::InstallIntegrationRequestBody` + +
+
+ +
+
+ +**request_options:** `Schematic::Integrationsapi::RequestOptions` + +
+
+
+
+ +
@@ -16893,7 +17034,95 @@ client.integrationsapi.start_data_import(integration_id: "integration_id") -
client.integrationsapi.load_sample_data_set_v_2() -> Schematic::Integrationsapi::Types::LoadSampleDataSetV2Response +
client.integrationsapi.load_sample_data_set() -> Schematic::Integrationsapi::Types::LoadSampleDataSetResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```ruby +client.integrationsapi.load_sample_data_set +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `Schematic::Integrationsapi::RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.integrationsapi.assume_stripe_installed(request) -> Schematic::Integrationsapi::Types::AssumeStripeInstalledResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```ruby +client.integrationsapi.assume_stripe_installed(type: "clerk") +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Schematic::Types::InstallIntegrationRequestBody` + +
+
+ +
+
+ +**request_options:** `Schematic::Integrationsapi::RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.integrationsapi.install_stripe(request) -> Schematic::Integrationsapi::Types::InstallStripeResponse
@@ -16906,7 +17135,7 @@ client.integrationsapi.start_data_import(integration_id: "integration_id")
```ruby -client.integrationsapi.load_sample_data_set_v_2 +client.integrationsapi.install_stripe(type: "clerk") ```
@@ -16921,6 +17150,14 @@ client.integrationsapi.load_sample_data_set_v_2
+**request:** `Schematic::Types::InstallIntegrationRequestBody` + +
+
+ +
+
+ **request_options:** `Schematic::Integrationsapi::RequestOptions`
@@ -17123,6 +17360,14 @@ client.plangroups.create_plan_group(
+**custom_checkout_fields:** `Internal::Types::Array[Schematic::Types::CheckoutFieldInput]` + +
+
+ +
+
+ **custom_plan_config:** `Schematic::Types::CustomPlanConfig`
@@ -17453,6 +17698,14 @@ client.plangroups.update_plan_group(
+**custom_checkout_fields:** `Internal::Types::Array[Schematic::Types::CheckoutFieldInput]` + +
+
+ +
+
+ **custom_plan_config:** `Schematic::Types::CustomPlanConfig`
From 180a41785cbb6797af145054878bae21f2fafc5d Mon Sep 17 00:00:00 2001 From: fern-api <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 18:13:55 +0000 Subject: [PATCH 2/2] [fern-replay] Applied customizations Patches with unresolved conflicts (2): - patch-6a2db2b5: handle partial messages properly - patch-46462128: add tests and address nits Run `fern-replay resolve` to apply these customizations. --- .fern/replay.lock | 503 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 501 insertions(+), 2 deletions(-) diff --git a/.fern/replay.lock b/.fern/replay.lock index 3c55877..8be2152 100644 --- a/.fern/replay.lock +++ b/.fern/replay.lock @@ -6,5 +6,504 @@ generations: timestamp: 2026-05-19T19:48:36.665Z cli_version: unknown generator_versions: {} -current_generation: 298b1d0ee88b6637d99742bff32b353cfbd5b32e -patches: [] + - commit_sha: 0dd219c7b903329d9db2fb5b9fb570f2fd6e1a39 + tree_hash: 7a0aadd77d8091d4846b0968fc36d335be98a66d + timestamp: 2026-06-08T18:13:52.357Z + cli_version: unknown + generator_versions: + fernapi/fern-ruby-sdk: 1.1.13 +current_generation: 0dd219c7b903329d9db2fb5b9fb570f2fd6e1a39 +patches: + - id: patch-6a2db2b5 + content_hash: sha256:630a8c3df9ae971e973e4dcb3d71d0d9f28b8da9877b0ff27ff3cca2a1eb924a + original_commit: 6a2db2b584601e13f90302155d37a22e45542fab + original_message: handle partial messages properly + original_author: Christopher Brady + base_generation: e75de47f4e4f08f8e683366dd9b3936bc5c6452f + files: + - lib/schematic/datastream/merge.rb + patch_content: | + diff --git a/lib/schematic/datastream/merge.rb b/lib/schematic/datastream/merge.rb + index 0ab68fe..7f1084d 100644 + --- a/lib/schematic/datastream/merge.rb + +++ b/lib/schematic/datastream/merge.rb + @@ -16,25 +16,42 @@ module Schematic + 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 + + @@ -90,6 +107,60 @@ module Schematic + 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) + + return [true, balances[credit_id.to_s]] if balances.key?(credit_id.to_s) + + + + [false, nil] + + end + end + end + end + 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) + return [true, balances[credit_id.to_s]] if balances.key?(credit_id.to_s) + + [false, nil] + end + end + end + end + status: unresolved + - id: patch-46462128 + content_hash: sha256:94f06e4e687a0908d3f305a4d605d9dc1271db6ed83014a10b86be900187dd83 + original_commit: 46462128cacb25b73fac7770060cf427ff0d9e6d + original_message: add tests and address nits + original_author: Christopher Brady + base_generation: e75de47f4e4f08f8e683366dd9b3936bc5c6452f + files: + - lib/schematic/datastream/merge.rb + patch_content: | + diff --git a/lib/schematic/datastream/merge.rb b/lib/schematic/datastream/merge.rb + index 7f1084d..f4dd4e5 100644 + --- a/lib/schematic/datastream/merge.rb + +++ b/lib/schematic/datastream/merge.rb + @@ -46,7 +46,7 @@ module Schematic + end + end + + - if (updated_balances || metrics_updated) && !entitlements_in_partial + + if (updated_balances&.any? || metrics_updated) && !entitlements_in_partial + result[:entitlements] = sync_entitlements( + result[:entitlements], result[:metrics], updated_balances, metrics_updated + ) + @@ -152,12 +152,12 @@ module Schematic + 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. + + # 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. + 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) + - return [true, balances[credit_id.to_s]] if balances.key?(credit_id.to_s) + + [false, nil] + end + 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&.any? || 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 + + # 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. + 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 + status: unresolved