schematichq 1.4.9 → 1.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.fern/metadata.json +2 -2
- data/.fern/replay.lock +350 -2
- data/WASM_VERSION +1 -1
- data/lib/schematic/accounts/client.rb +6 -2
- data/lib/schematic/accounts/types/count_account_members_params.rb +1 -0
- data/lib/schematic/accounts/types/count_account_members_request.rb +1 -0
- data/lib/schematic/accounts/types/list_account_members_params.rb +1 -0
- data/lib/schematic/accounts/types/list_account_members_request.rb +1 -0
- data/lib/schematic/catalogs/client.rb +480 -0
- data/lib/schematic/catalogs/types/create_catalog_request_body.rb +13 -0
- data/lib/schematic/catalogs/types/create_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/delete_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_configuration_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_credit_bundles_in_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_derived_features_response.rb +12 -0
- data/lib/schematic/catalogs/types/get_plans_in_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/list_catalogs_params.rb +15 -0
- data/lib/schematic/catalogs/types/list_catalogs_request.rb +14 -0
- data/lib/schematic/catalogs/types/list_catalogs_response.rb +12 -0
- data/lib/schematic/catalogs/types/update_catalog_configuration_request_body.rb +20 -0
- data/lib/schematic/catalogs/types/update_catalog_request_body.rb +14 -0
- data/lib/schematic/catalogs/types/update_catalog_response.rb +12 -0
- data/lib/schematic/catalogs/types/update_configuration_response.rb +12 -0
- data/lib/schematic/checkout/client.rb +69 -0
- data/lib/schematic/checkout/types/get_company_billing_details_response.rb +12 -0
- data/lib/schematic/checkout/types/update_company_billing_details_request_body.rb +15 -0
- data/lib/schematic/checkout/types/update_company_billing_details_response.rb +12 -0
- data/lib/schematic/client.rb +11 -1
- data/lib/schematic/components/client.rb +37 -0
- data/lib/schematic/components/types/bind_catalog_request_body.rb +12 -0
- data/lib/schematic/components/types/bind_catalog_response.rb +12 -0
- data/lib/schematic/dataexports/client.rb +76 -0
- data/lib/schematic/dataexports/types/create_data_export_request_body.rb +3 -3
- data/lib/schematic/dataexports/types/get_data_export_response.rb +12 -0
- data/lib/schematic/dataexports/types/list_data_exports_params.rb +15 -0
- data/lib/schematic/dataexports/types/list_data_exports_request.rb +14 -0
- data/lib/schematic/dataexports/types/list_data_exports_response.rb +12 -0
- data/lib/schematic/licenses/client.rb +138 -0
- data/lib/schematic/licenses/types/count_licenses_params.rb +16 -0
- data/lib/schematic/licenses/types/count_licenses_request.rb +15 -0
- data/lib/schematic/licenses/types/count_licenses_response.rb +12 -0
- data/lib/schematic/licenses/types/get_single_license_response.rb +12 -0
- data/lib/schematic/licenses/types/list_licenses_params.rb +16 -0
- data/lib/schematic/licenses/types/list_licenses_request.rb +15 -0
- data/lib/schematic/licenses/types/list_licenses_response.rb +12 -0
- data/lib/schematic/planbundle/types/create_custom_plan_bundle_request_body.rb +1 -0
- data/lib/schematic/planmigrations/client.rb +32 -0
- data/lib/schematic/planmigrations/types/preview_migration_request_body.rb +14 -0
- data/lib/schematic/planmigrations/types/preview_migration_response.rb +12 -0
- data/lib/schematic/types/audit_log_export_metadata.rb +13 -0
- data/lib/schematic/types/billing_credit_grant_zeroed_out_reason.rb +1 -0
- data/lib/schematic/types/catalog_config_ordered_bundle.rb +9 -0
- data/lib/schematic/types/catalog_config_ordered_bundle_response_data.rb +9 -0
- data/lib/schematic/types/catalog_config_ordered_entitlement.rb +10 -0
- data/lib/schematic/types/catalog_config_ordered_entitlement_response_data.rb +10 -0
- data/lib/schematic/types/catalog_config_ordered_plan.rb +10 -0
- data/lib/schematic/types/catalog_config_ordered_plan_response_data.rb +10 -0
- data/lib/schematic/types/catalog_configuration_response_data.rb +19 -0
- data/lib/schematic/types/catalog_credit_bundle_i_ds_response_data.rb +9 -0
- data/lib/schematic/types/catalog_derived_feature_response_data.rb +11 -0
- data/lib/schematic/types/catalog_derived_features_response_data.rb +9 -0
- data/lib/schematic/types/catalog_plan_i_ds_response_data.rb +9 -0
- data/lib/schematic/types/catalog_response_data.rb +22 -0
- data/lib/schematic/types/company_billing_address_view.rb +14 -0
- data/lib/schematic/types/company_billing_checkout_settings.rb +11 -0
- data/lib/schematic/types/company_billing_details_response_data.rb +13 -0
- data/lib/schematic/types/company_billing_details_view.rb +13 -0
- data/lib/schematic/types/company_feature_usage_export_metadata.rb +25 -0
- data/lib/schematic/types/company_plan_detail_response_data.rb +1 -0
- data/lib/schematic/types/component_response_data.rb +1 -0
- data/lib/schematic/types/create_entitlement_in_bundle_request_body.rb +1 -0
- data/lib/schematic/types/credits_auto_topup_success.rb +12 -0
- data/lib/schematic/types/credits_credit_purchase_success.rb +14 -0
- data/lib/schematic/types/credits_webhook_company_summary.rb +10 -0
- data/lib/schematic/types/credits_webhook_credit_summary.rb +10 -0
- data/lib/schematic/types/customer_billing_address.rb +14 -0
- data/lib/schematic/types/data_export_metadata.rb +14 -0
- data/lib/schematic/types/data_export_output_file_type.rb +3 -14
- data/lib/schematic/types/data_export_response_data.rb +3 -3
- data/lib/schematic/types/data_export_type.rb +3 -14
- data/lib/schematic/types/feature_detail_response_data.rb +3 -0
- data/lib/schematic/types/feature_entitlement.rb +1 -0
- data/lib/schematic/types/feature_in_plan_response_data.rb +2 -0
- data/lib/schematic/types/feature_response_data.rb +2 -0
- data/lib/schematic/types/feature_type.rb +1 -0
- data/lib/schematic/types/feature_view.rb +2 -0
- data/lib/schematic/types/license_response_data.rb +12 -0
- data/lib/schematic/types/plan_catalog_membership_response_data.rb +10 -0
- data/lib/schematic/types/plan_detail_response_data.rb +1 -0
- data/lib/schematic/types/plan_group_plan_detail_response_data.rb +1 -0
- data/lib/schematic/types/plan_version_migration_preview_company_response_data.rb +14 -0
- data/lib/schematic/types/plan_version_migration_preview_response_data.rb +9 -0
- data/lib/schematic/types/plan_view_public_response_data.rb +1 -0
- data/lib/schematic/types/preview_subscription_discount_response_data.rb +19 -0
- data/lib/schematic/types/preview_subscription_finance_response_data.rb +2 -0
- data/lib/schematic/types/rulesengine_feature_entitlement.rb +1 -0
- data/lib/schematic/types/rulesengine_warning_tier.rb +10 -0
- data/lib/schematic/types/upsert_company_request_body.rb +2 -0
- data/lib/schematic/types/warning_tier.rb +10 -0
- data/lib/schematic/types/webhook_request_type.rb +2 -0
- data/lib/schematic/version.rb +1 -1
- data/lib/schematic/wasm/rulesengine.wasm +0 -0
- data/lib/schematic.rb +105 -39
- data/reference.md +1800 -301
- metadata +68 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a42d012076b989e91c5c9019e981ee2af4e4f5f7115aaa1b304bed519c44a454
|
|
4
|
+
data.tar.gz: dd803e3554e9f425bdd2deb7f8b56b57c16483da2f86437e4f8400dae3ba1962
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 73bac05632b13d3839a98d2fa63b207243e6fa291bb255f9750af3d1658ac56373aedd630ecb3967ec580c2af9b819af176fa60c7a27897e7b6d72a34e1d9509
|
|
7
|
+
data.tar.gz: c014f30d286b1b01b25cafe35426efb6841c4861f6e8de6e362fbe9f2ca366f0680fb2ff2f2ea8994514f7b3f6e652bd167ca8d4a66f2de1906a0c297922fe45
|
data/.fern/metadata.json
CHANGED
data/.fern/replay.lock
CHANGED
|
@@ -36,5 +36,353 @@ generations:
|
|
|
36
36
|
cli_version: unknown
|
|
37
37
|
generator_versions:
|
|
38
38
|
fernapi/fern-ruby-sdk: 1.1.13
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
- commit_sha: dfe70dc9f1f1787aa5b55f6802739898633c35c7
|
|
40
|
+
tree_hash: 114498346f315168be50ca9bf5c9f463bcfe3303
|
|
41
|
+
timestamp: 2026-07-22T19:30:43.525Z
|
|
42
|
+
cli_version: unknown
|
|
43
|
+
generator_versions:
|
|
44
|
+
fernapi/fern-ruby-sdk: 1.1.13
|
|
45
|
+
- commit_sha: 6d4bb962eb2a83ad3a76662f58edbd07cc5fdadf
|
|
46
|
+
tree_hash: 9ec72264899730d464919a3605eb3a6667ba9464
|
|
47
|
+
timestamp: 2026-07-27T18:37:54.168Z
|
|
48
|
+
cli_version: unknown
|
|
49
|
+
generator_versions:
|
|
50
|
+
fernapi/fern-ruby-sdk: 1.1.13
|
|
51
|
+
current_generation: 6d4bb962eb2a83ad3a76662f58edbd07cc5fdadf
|
|
52
|
+
patches:
|
|
53
|
+
- id: patch-5da692c2
|
|
54
|
+
content_hash: sha256:e652287219a0a709e16112ced444e6472c6fa8bdfe888edf868caaf9769a9472
|
|
55
|
+
original_commit: 5da692c20aef08577d900f9a860b5f78a549418e
|
|
56
|
+
original_message: inject host time into datastream wasm rules engine (SCHY-471)
|
|
57
|
+
original_author: Christopher Brady <chris@schematichq.com>
|
|
58
|
+
base_generation: 6d4bb962eb2a83ad3a76662f58edbd07cc5fdadf
|
|
59
|
+
files:
|
|
60
|
+
- test/rules_engine_clock_test.rb
|
|
61
|
+
patch_content: |
|
|
62
|
+
diff --git a/test/rules_engine_clock_test.rb b/test/rules_engine_clock_test.rb
|
|
63
|
+
new file mode 100644
|
|
64
|
+
index 0000000..8711b5e
|
|
65
|
+
--- /dev/null
|
|
66
|
+
+++ b/test/rules_engine_clock_test.rb
|
|
67
|
+
@@ -0,0 +1,75 @@
|
|
68
|
+
+# frozen_string_literal: true
|
|
69
|
+
+
|
|
70
|
+
+require_relative "test_helper"
|
|
71
|
+
+require "minitest/autorun"
|
|
72
|
+
+
|
|
73
|
+
+# Regression for SCHY-471.
|
|
74
|
+
+#
|
|
75
|
+
+# A company-override entitlement rule whose metric condition uses a
|
|
76
|
+
+# calendar/billing metric period drives the engine into the metric-period-reset
|
|
77
|
+
+# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
78
|
+
+# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
79
|
+
+# its default value for a company that is legitimately entitled. The host now
|
|
80
|
+
+# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
81
|
+
+class RulesEngineClockTest < Minitest::Test
|
|
82
|
+
+ def setup
|
|
83
|
+
+ @engine = Schematic::RulesEngine.new
|
|
84
|
+
+ @engine.initialize!
|
|
85
|
+
+ # The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
86
|
+
+ # (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
87
|
+
+ skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
88
|
+
+ end
|
|
89
|
+
+
|
|
90
|
+
+ def flag
|
|
91
|
+
+ {
|
|
92
|
+
+ "id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
93
|
+
+ "environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
94
|
+
+ }
|
|
95
|
+
+ end
|
|
96
|
+
+
|
|
97
|
+
+ # Usage 40 < allocation 100, so the override grants the feature.
|
|
98
|
+
+ def entitled_company
|
|
99
|
+
+ {
|
|
100
|
+
+ "id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
101
|
+
+ "keys" => { "id" => "co_entitled" },
|
|
102
|
+
+ "metrics" => [{
|
|
103
|
+
+ "account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
104
|
+
+ "event_subtype" => "api-calls", "period" => "current_month",
|
|
105
|
+
+ "month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
106
|
+
+ }],
|
|
107
|
+
+ "rules" => [{
|
|
108
|
+
+ "id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
109
|
+
+ "environment_id" => "env_1", "name" => "Company Override",
|
|
110
|
+
+ "rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
111
|
+
+ "condition_groups" => [],
|
|
112
|
+
+ "conditions" => [
|
|
113
|
+
+ {
|
|
114
|
+
+ "id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
115
|
+
+ "condition_type" => "company", "operator" => "eq",
|
|
116
|
+
+ "resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
117
|
+
+ },
|
|
118
|
+
+ {
|
|
119
|
+
+ "id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
120
|
+
+ "condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
121
|
+
+ "metric_value" => 100, "metric_period" => "current_month",
|
|
122
|
+
+ "metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
123
|
+
+ }
|
|
124
|
+
+ ]
|
|
125
|
+
+ }]
|
|
126
|
+
+ }
|
|
127
|
+
+ end
|
|
128
|
+
+
|
|
129
|
+
+ def test_billing_metric_override_evaluates_without_trapping
|
|
130
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
131
|
+
+
|
|
132
|
+
+ assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
133
|
+
+ assert_match(/override/i, result[:reason].to_s)
|
|
134
|
+
+ end
|
|
135
|
+
+
|
|
136
|
+
+ def test_billing_metric_override_populates_reset_at
|
|
137
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
138
|
+
+
|
|
139
|
+
+ refute_nil result[:feature_usage_reset_at],
|
|
140
|
+
+ "reset-at should be computed from the injected host time"
|
|
141
|
+
+ end
|
|
142
|
+
+end
|
|
143
|
+
theirs_snapshot:
|
|
144
|
+
test/rules_engine_clock_test.rb: |
|
|
145
|
+
# frozen_string_literal: true
|
|
146
|
+
|
|
147
|
+
require_relative "test_helper"
|
|
148
|
+
require "minitest/autorun"
|
|
149
|
+
|
|
150
|
+
# Regression for SCHY-471.
|
|
151
|
+
#
|
|
152
|
+
# A company-override entitlement rule whose metric condition uses a
|
|
153
|
+
# calendar/billing metric period drives the engine into the metric-period-reset
|
|
154
|
+
# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
155
|
+
# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
156
|
+
# its default value for a company that is legitimately entitled. The host now
|
|
157
|
+
# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
158
|
+
class RulesEngineClockTest < Minitest::Test
|
|
159
|
+
def setup
|
|
160
|
+
@engine = Schematic::RulesEngine.new
|
|
161
|
+
@engine.initialize!
|
|
162
|
+
# The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
163
|
+
# (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
164
|
+
skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def flag
|
|
168
|
+
{
|
|
169
|
+
"id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
170
|
+
"environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
171
|
+
}
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Usage 40 < allocation 100, so the override grants the feature.
|
|
175
|
+
def entitled_company
|
|
176
|
+
{
|
|
177
|
+
"id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
178
|
+
"keys" => { "id" => "co_entitled" },
|
|
179
|
+
"metrics" => [{
|
|
180
|
+
"account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
181
|
+
"event_subtype" => "api-calls", "period" => "current_month",
|
|
182
|
+
"month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
183
|
+
}],
|
|
184
|
+
"rules" => [{
|
|
185
|
+
"id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
186
|
+
"environment_id" => "env_1", "name" => "Company Override",
|
|
187
|
+
"rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
188
|
+
"condition_groups" => [],
|
|
189
|
+
"conditions" => [
|
|
190
|
+
{
|
|
191
|
+
"id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
192
|
+
"condition_type" => "company", "operator" => "eq",
|
|
193
|
+
"resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
197
|
+
"condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
198
|
+
"metric_value" => 100, "metric_period" => "current_month",
|
|
199
|
+
"metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}]
|
|
203
|
+
}
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_billing_metric_override_evaluates_without_trapping
|
|
207
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
208
|
+
|
|
209
|
+
assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
210
|
+
assert_match(/override/i, result[:reason].to_s)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def test_billing_metric_override_populates_reset_at
|
|
214
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
215
|
+
|
|
216
|
+
refute_nil result[:feature_usage_reset_at],
|
|
217
|
+
"reset-at should be computed from the injected host time"
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
user_owned: true
|
|
221
|
+
- id: patch-ee61788c
|
|
222
|
+
content_hash: sha256:e652287219a0a709e16112ced444e6472c6fa8bdfe888edf868caaf9769a9472
|
|
223
|
+
original_commit: ee61788c5a83fce5dd5768b2536391459550d176
|
|
224
|
+
original_message: fix rubocop offenses in clock regression test (SCHY-471)
|
|
225
|
+
original_author: Christopher Brady <chris@schematichq.com>
|
|
226
|
+
base_generation: 6d4bb962eb2a83ad3a76662f58edbd07cc5fdadf
|
|
227
|
+
files:
|
|
228
|
+
- test/rules_engine_clock_test.rb
|
|
229
|
+
patch_content: |
|
|
230
|
+
diff --git a/test/rules_engine_clock_test.rb b/test/rules_engine_clock_test.rb
|
|
231
|
+
new file mode 100644
|
|
232
|
+
index 0000000..8711b5e
|
|
233
|
+
--- /dev/null
|
|
234
|
+
+++ b/test/rules_engine_clock_test.rb
|
|
235
|
+
@@ -0,0 +1,75 @@
|
|
236
|
+
+# frozen_string_literal: true
|
|
237
|
+
+
|
|
238
|
+
+require_relative "test_helper"
|
|
239
|
+
+require "minitest/autorun"
|
|
240
|
+
+
|
|
241
|
+
+# Regression for SCHY-471.
|
|
242
|
+
+#
|
|
243
|
+
+# A company-override entitlement rule whose metric condition uses a
|
|
244
|
+
+# calendar/billing metric period drives the engine into the metric-period-reset
|
|
245
|
+
+# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
246
|
+
+# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
247
|
+
+# its default value for a company that is legitimately entitled. The host now
|
|
248
|
+
+# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
249
|
+
+class RulesEngineClockTest < Minitest::Test
|
|
250
|
+
+ def setup
|
|
251
|
+
+ @engine = Schematic::RulesEngine.new
|
|
252
|
+
+ @engine.initialize!
|
|
253
|
+
+ # The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
254
|
+
+ # (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
255
|
+
+ skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
256
|
+
+ end
|
|
257
|
+
+
|
|
258
|
+
+ def flag
|
|
259
|
+
+ {
|
|
260
|
+
+ "id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
261
|
+
+ "environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
262
|
+
+ }
|
|
263
|
+
+ end
|
|
264
|
+
+
|
|
265
|
+
+ # Usage 40 < allocation 100, so the override grants the feature.
|
|
266
|
+
+ def entitled_company
|
|
267
|
+
+ {
|
|
268
|
+
+ "id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
269
|
+
+ "keys" => { "id" => "co_entitled" },
|
|
270
|
+
+ "metrics" => [{
|
|
271
|
+
+ "account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
272
|
+
+ "event_subtype" => "api-calls", "period" => "current_month",
|
|
273
|
+
+ "month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
274
|
+
+ }],
|
|
275
|
+
+ "rules" => [{
|
|
276
|
+
+ "id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
277
|
+
+ "environment_id" => "env_1", "name" => "Company Override",
|
|
278
|
+
+ "rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
279
|
+
+ "condition_groups" => [],
|
|
280
|
+
+ "conditions" => [
|
|
281
|
+
+ {
|
|
282
|
+
+ "id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
283
|
+
+ "condition_type" => "company", "operator" => "eq",
|
|
284
|
+
+ "resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
285
|
+
+ },
|
|
286
|
+
+ {
|
|
287
|
+
+ "id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
288
|
+
+ "condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
289
|
+
+ "metric_value" => 100, "metric_period" => "current_month",
|
|
290
|
+
+ "metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
291
|
+
+ }
|
|
292
|
+
+ ]
|
|
293
|
+
+ }]
|
|
294
|
+
+ }
|
|
295
|
+
+ end
|
|
296
|
+
+
|
|
297
|
+
+ def test_billing_metric_override_evaluates_without_trapping
|
|
298
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
299
|
+
+
|
|
300
|
+
+ assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
301
|
+
+ assert_match(/override/i, result[:reason].to_s)
|
|
302
|
+
+ end
|
|
303
|
+
+
|
|
304
|
+
+ def test_billing_metric_override_populates_reset_at
|
|
305
|
+
+ result = @engine.check_flag(flag, entitled_company)
|
|
306
|
+
+
|
|
307
|
+
+ refute_nil result[:feature_usage_reset_at],
|
|
308
|
+
+ "reset-at should be computed from the injected host time"
|
|
309
|
+
+ end
|
|
310
|
+
+end
|
|
311
|
+
theirs_snapshot:
|
|
312
|
+
test/rules_engine_clock_test.rb: |
|
|
313
|
+
# frozen_string_literal: true
|
|
314
|
+
|
|
315
|
+
require_relative "test_helper"
|
|
316
|
+
require "minitest/autorun"
|
|
317
|
+
|
|
318
|
+
# Regression for SCHY-471.
|
|
319
|
+
#
|
|
320
|
+
# A company-override entitlement rule whose metric condition uses a
|
|
321
|
+
# calendar/billing metric period drives the engine into the metric-period-reset
|
|
322
|
+
# code path, which needs a wall clock. On the raw wasm32-unknown-unknown build
|
|
323
|
+
# that path used to trap (+wasm unreachable+); the flag then wrongly fell back to
|
|
324
|
+
# its default value for a company that is legitimately entitled. The host now
|
|
325
|
+
# injects the current time via +setCurrentTimeMillis+ so this evaluates cleanly.
|
|
326
|
+
class RulesEngineClockTest < Minitest::Test
|
|
327
|
+
def setup
|
|
328
|
+
@engine = Schematic::RulesEngine.new
|
|
329
|
+
@engine.initialize!
|
|
330
|
+
# The wasm binary is fetched via scripts/download-wasm.sh and may be absent
|
|
331
|
+
# (or the wasmtime gem missing) in some environments — skip rather than fail.
|
|
332
|
+
skip "WASM rules engine unavailable (wasm binary or wasmtime gem missing)" unless @engine.initialized?
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def flag
|
|
336
|
+
{
|
|
337
|
+
"id" => "flag1", "key" => "mcp-access", "account_id" => "acc_1",
|
|
338
|
+
"environment_id" => "env_1", "default_value" => false, "rules" => []
|
|
339
|
+
}
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# Usage 40 < allocation 100, so the override grants the feature.
|
|
343
|
+
def entitled_company
|
|
344
|
+
{
|
|
345
|
+
"id" => "co_entitled", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
346
|
+
"keys" => { "id" => "co_entitled" },
|
|
347
|
+
"metrics" => [{
|
|
348
|
+
"account_id" => "acc_1", "environment_id" => "env_1", "company_id" => "co_entitled",
|
|
349
|
+
"event_subtype" => "api-calls", "period" => "current_month",
|
|
350
|
+
"month_reset" => "billing_cycle", "value" => 40, "created_at" => "2023-01-01T00:00:00Z"
|
|
351
|
+
}],
|
|
352
|
+
"rules" => [{
|
|
353
|
+
"id" => "rule_override", "flag_id" => "flag1", "account_id" => "acc_1",
|
|
354
|
+
"environment_id" => "env_1", "name" => "Company Override",
|
|
355
|
+
"rule_type" => "company_override", "priority" => 0, "value" => true,
|
|
356
|
+
"condition_groups" => [],
|
|
357
|
+
"conditions" => [
|
|
358
|
+
{
|
|
359
|
+
"id" => "cond_company", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
360
|
+
"condition_type" => "company", "operator" => "eq",
|
|
361
|
+
"resource_ids" => ["co_entitled"], "trait_value" => ""
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
"id" => "cond_metric", "account_id" => "acc_1", "environment_id" => "env_1",
|
|
365
|
+
"condition_type" => "metric", "operator" => "lt", "event_subtype" => "api-calls",
|
|
366
|
+
"metric_value" => 100, "metric_period" => "current_month",
|
|
367
|
+
"metric_period_month_reset" => "billing_cycle", "trait_value" => "100"
|
|
368
|
+
}
|
|
369
|
+
]
|
|
370
|
+
}]
|
|
371
|
+
}
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def test_billing_metric_override_evaluates_without_trapping
|
|
375
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
376
|
+
|
|
377
|
+
assert result[:value], "company override should grant the flag, not fall back to default false"
|
|
378
|
+
assert_match(/override/i, result[:reason].to_s)
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def test_billing_metric_override_populates_reset_at
|
|
382
|
+
result = @engine.check_flag(flag, entitled_company)
|
|
383
|
+
|
|
384
|
+
refute_nil result[:feature_usage_reset_at],
|
|
385
|
+
"reset-at should be computed from the injected host time"
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
user_owned: true
|
data/WASM_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.6.0
|
|
@@ -19,16 +19,18 @@ module Schematic
|
|
|
19
19
|
# @option request_options [Integer] :timeout_in_seconds
|
|
20
20
|
# @option params [String, nil] :ids
|
|
21
21
|
# @option params [String, nil] :q
|
|
22
|
+
# @option params [Schematic::Types::AccountMemberRole, nil] :role
|
|
22
23
|
# @option params [Integer, nil] :limit
|
|
23
24
|
# @option params [Integer, nil] :offset
|
|
24
25
|
#
|
|
25
26
|
# @return [Schematic::Accounts::Types::ListAccountMembersResponse]
|
|
26
27
|
def list_account_members(request_options: {}, **params)
|
|
27
28
|
params = Schematic::Internal::Types::Utils.normalize_keys(params)
|
|
28
|
-
query_param_names = %i[ids q limit offset]
|
|
29
|
+
query_param_names = %i[ids q role limit offset]
|
|
29
30
|
query_params = {}
|
|
30
31
|
query_params["ids"] = params[:ids] if params.key?(:ids)
|
|
31
32
|
query_params["q"] = params[:q] if params.key?(:q)
|
|
33
|
+
query_params["role"] = params[:role] if params.key?(:role)
|
|
32
34
|
query_params["limit"] = params[:limit] if params.key?(:limit)
|
|
33
35
|
query_params["offset"] = params[:offset] if params.key?(:offset)
|
|
34
36
|
params.except(*query_param_names)
|
|
@@ -95,16 +97,18 @@ module Schematic
|
|
|
95
97
|
# @option request_options [Integer] :timeout_in_seconds
|
|
96
98
|
# @option params [String, nil] :ids
|
|
97
99
|
# @option params [String, nil] :q
|
|
100
|
+
# @option params [Schematic::Types::AccountMemberRole, nil] :role
|
|
98
101
|
# @option params [Integer, nil] :limit
|
|
99
102
|
# @option params [Integer, nil] :offset
|
|
100
103
|
#
|
|
101
104
|
# @return [Schematic::Accounts::Types::CountAccountMembersResponse]
|
|
102
105
|
def count_account_members(request_options: {}, **params)
|
|
103
106
|
params = Schematic::Internal::Types::Utils.normalize_keys(params)
|
|
104
|
-
query_param_names = %i[ids q limit offset]
|
|
107
|
+
query_param_names = %i[ids q role limit offset]
|
|
105
108
|
query_params = {}
|
|
106
109
|
query_params["ids"] = params[:ids] if params.key?(:ids)
|
|
107
110
|
query_params["q"] = params[:q] if params.key?(:q)
|
|
111
|
+
query_params["role"] = params[:role] if params.key?(:role)
|
|
108
112
|
query_params["limit"] = params[:limit] if params.key?(:limit)
|
|
109
113
|
query_params["offset"] = params[:offset] if params.key?(:offset)
|
|
110
114
|
params.except(*query_param_names)
|
|
@@ -9,6 +9,7 @@ module Schematic
|
|
|
9
9
|
field :limit, -> { Integer }, optional: true, nullable: false
|
|
10
10
|
field :offset, -> { Integer }, optional: true, nullable: false
|
|
11
11
|
field :q, -> { String }, optional: true, nullable: false
|
|
12
|
+
field :role, -> { Schematic::Types::AccountMemberRole }, optional: true, nullable: false
|
|
12
13
|
end
|
|
13
14
|
end
|
|
14
15
|
end
|
|
@@ -6,6 +6,7 @@ module Schematic
|
|
|
6
6
|
class CountAccountMembersRequest < Internal::Types::Model
|
|
7
7
|
field :ids, -> { String }, optional: true, nullable: false
|
|
8
8
|
field :q, -> { String }, optional: true, nullable: false
|
|
9
|
+
field :role, -> { Schematic::Types::AccountMemberRole }, optional: true, nullable: false
|
|
9
10
|
field :limit, -> { Integer }, optional: true, nullable: false
|
|
10
11
|
field :offset, -> { Integer }, optional: true, nullable: false
|
|
11
12
|
end
|
|
@@ -9,6 +9,7 @@ module Schematic
|
|
|
9
9
|
field :limit, -> { Integer }, optional: true, nullable: false
|
|
10
10
|
field :offset, -> { Integer }, optional: true, nullable: false
|
|
11
11
|
field :q, -> { String }, optional: true, nullable: false
|
|
12
|
+
field :role, -> { Schematic::Types::AccountMemberRole }, optional: true, nullable: false
|
|
12
13
|
end
|
|
13
14
|
end
|
|
14
15
|
end
|
|
@@ -6,6 +6,7 @@ module Schematic
|
|
|
6
6
|
class ListAccountMembersRequest < Internal::Types::Model
|
|
7
7
|
field :ids, -> { String }, optional: true, nullable: false
|
|
8
8
|
field :q, -> { String }, optional: true, nullable: false
|
|
9
|
+
field :role, -> { Schematic::Types::AccountMemberRole }, optional: true, nullable: false
|
|
9
10
|
field :limit, -> { Integer }, optional: true, nullable: false
|
|
10
11
|
field :offset, -> { Integer }, optional: true, nullable: false
|
|
11
12
|
end
|