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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.fern/metadata.json +2 -2
  3. data/.fern/replay.lock +350 -2
  4. data/WASM_VERSION +1 -1
  5. data/lib/schematic/accounts/client.rb +6 -2
  6. data/lib/schematic/accounts/types/count_account_members_params.rb +1 -0
  7. data/lib/schematic/accounts/types/count_account_members_request.rb +1 -0
  8. data/lib/schematic/accounts/types/list_account_members_params.rb +1 -0
  9. data/lib/schematic/accounts/types/list_account_members_request.rb +1 -0
  10. data/lib/schematic/catalogs/client.rb +480 -0
  11. data/lib/schematic/catalogs/types/create_catalog_request_body.rb +13 -0
  12. data/lib/schematic/catalogs/types/create_catalog_response.rb +12 -0
  13. data/lib/schematic/catalogs/types/delete_catalog_response.rb +12 -0
  14. data/lib/schematic/catalogs/types/get_catalog_response.rb +12 -0
  15. data/lib/schematic/catalogs/types/get_configuration_response.rb +12 -0
  16. data/lib/schematic/catalogs/types/get_credit_bundles_in_catalog_response.rb +12 -0
  17. data/lib/schematic/catalogs/types/get_derived_features_response.rb +12 -0
  18. data/lib/schematic/catalogs/types/get_plans_in_catalog_response.rb +12 -0
  19. data/lib/schematic/catalogs/types/list_catalogs_params.rb +15 -0
  20. data/lib/schematic/catalogs/types/list_catalogs_request.rb +14 -0
  21. data/lib/schematic/catalogs/types/list_catalogs_response.rb +12 -0
  22. data/lib/schematic/catalogs/types/update_catalog_configuration_request_body.rb +20 -0
  23. data/lib/schematic/catalogs/types/update_catalog_request_body.rb +14 -0
  24. data/lib/schematic/catalogs/types/update_catalog_response.rb +12 -0
  25. data/lib/schematic/catalogs/types/update_configuration_response.rb +12 -0
  26. data/lib/schematic/checkout/client.rb +69 -0
  27. data/lib/schematic/checkout/types/get_company_billing_details_response.rb +12 -0
  28. data/lib/schematic/checkout/types/update_company_billing_details_request_body.rb +15 -0
  29. data/lib/schematic/checkout/types/update_company_billing_details_response.rb +12 -0
  30. data/lib/schematic/client.rb +11 -1
  31. data/lib/schematic/components/client.rb +37 -0
  32. data/lib/schematic/components/types/bind_catalog_request_body.rb +12 -0
  33. data/lib/schematic/components/types/bind_catalog_response.rb +12 -0
  34. data/lib/schematic/dataexports/client.rb +76 -0
  35. data/lib/schematic/dataexports/types/create_data_export_request_body.rb +3 -3
  36. data/lib/schematic/dataexports/types/get_data_export_response.rb +12 -0
  37. data/lib/schematic/dataexports/types/list_data_exports_params.rb +15 -0
  38. data/lib/schematic/dataexports/types/list_data_exports_request.rb +14 -0
  39. data/lib/schematic/dataexports/types/list_data_exports_response.rb +12 -0
  40. data/lib/schematic/licenses/client.rb +138 -0
  41. data/lib/schematic/licenses/types/count_licenses_params.rb +16 -0
  42. data/lib/schematic/licenses/types/count_licenses_request.rb +15 -0
  43. data/lib/schematic/licenses/types/count_licenses_response.rb +12 -0
  44. data/lib/schematic/licenses/types/get_single_license_response.rb +12 -0
  45. data/lib/schematic/licenses/types/list_licenses_params.rb +16 -0
  46. data/lib/schematic/licenses/types/list_licenses_request.rb +15 -0
  47. data/lib/schematic/licenses/types/list_licenses_response.rb +12 -0
  48. data/lib/schematic/planbundle/types/create_custom_plan_bundle_request_body.rb +1 -0
  49. data/lib/schematic/planmigrations/client.rb +32 -0
  50. data/lib/schematic/planmigrations/types/preview_migration_request_body.rb +14 -0
  51. data/lib/schematic/planmigrations/types/preview_migration_response.rb +12 -0
  52. data/lib/schematic/types/audit_log_export_metadata.rb +13 -0
  53. data/lib/schematic/types/billing_credit_grant_zeroed_out_reason.rb +1 -0
  54. data/lib/schematic/types/catalog_config_ordered_bundle.rb +9 -0
  55. data/lib/schematic/types/catalog_config_ordered_bundle_response_data.rb +9 -0
  56. data/lib/schematic/types/catalog_config_ordered_entitlement.rb +10 -0
  57. data/lib/schematic/types/catalog_config_ordered_entitlement_response_data.rb +10 -0
  58. data/lib/schematic/types/catalog_config_ordered_plan.rb +10 -0
  59. data/lib/schematic/types/catalog_config_ordered_plan_response_data.rb +10 -0
  60. data/lib/schematic/types/catalog_configuration_response_data.rb +19 -0
  61. data/lib/schematic/types/catalog_credit_bundle_i_ds_response_data.rb +9 -0
  62. data/lib/schematic/types/catalog_derived_feature_response_data.rb +11 -0
  63. data/lib/schematic/types/catalog_derived_features_response_data.rb +9 -0
  64. data/lib/schematic/types/catalog_plan_i_ds_response_data.rb +9 -0
  65. data/lib/schematic/types/catalog_response_data.rb +22 -0
  66. data/lib/schematic/types/company_billing_address_view.rb +14 -0
  67. data/lib/schematic/types/company_billing_checkout_settings.rb +11 -0
  68. data/lib/schematic/types/company_billing_details_response_data.rb +13 -0
  69. data/lib/schematic/types/company_billing_details_view.rb +13 -0
  70. data/lib/schematic/types/company_feature_usage_export_metadata.rb +25 -0
  71. data/lib/schematic/types/company_plan_detail_response_data.rb +1 -0
  72. data/lib/schematic/types/component_response_data.rb +1 -0
  73. data/lib/schematic/types/create_entitlement_in_bundle_request_body.rb +1 -0
  74. data/lib/schematic/types/credits_auto_topup_success.rb +12 -0
  75. data/lib/schematic/types/credits_credit_purchase_success.rb +14 -0
  76. data/lib/schematic/types/credits_webhook_company_summary.rb +10 -0
  77. data/lib/schematic/types/credits_webhook_credit_summary.rb +10 -0
  78. data/lib/schematic/types/customer_billing_address.rb +14 -0
  79. data/lib/schematic/types/data_export_metadata.rb +14 -0
  80. data/lib/schematic/types/data_export_output_file_type.rb +3 -14
  81. data/lib/schematic/types/data_export_response_data.rb +3 -3
  82. data/lib/schematic/types/data_export_type.rb +3 -14
  83. data/lib/schematic/types/feature_detail_response_data.rb +3 -0
  84. data/lib/schematic/types/feature_entitlement.rb +1 -0
  85. data/lib/schematic/types/feature_in_plan_response_data.rb +2 -0
  86. data/lib/schematic/types/feature_response_data.rb +2 -0
  87. data/lib/schematic/types/feature_type.rb +1 -0
  88. data/lib/schematic/types/feature_view.rb +2 -0
  89. data/lib/schematic/types/license_response_data.rb +12 -0
  90. data/lib/schematic/types/plan_catalog_membership_response_data.rb +10 -0
  91. data/lib/schematic/types/plan_detail_response_data.rb +1 -0
  92. data/lib/schematic/types/plan_group_plan_detail_response_data.rb +1 -0
  93. data/lib/schematic/types/plan_version_migration_preview_company_response_data.rb +14 -0
  94. data/lib/schematic/types/plan_version_migration_preview_response_data.rb +9 -0
  95. data/lib/schematic/types/plan_view_public_response_data.rb +1 -0
  96. data/lib/schematic/types/preview_subscription_discount_response_data.rb +19 -0
  97. data/lib/schematic/types/preview_subscription_finance_response_data.rb +2 -0
  98. data/lib/schematic/types/rulesengine_feature_entitlement.rb +1 -0
  99. data/lib/schematic/types/rulesengine_warning_tier.rb +10 -0
  100. data/lib/schematic/types/upsert_company_request_body.rb +2 -0
  101. data/lib/schematic/types/warning_tier.rb +10 -0
  102. data/lib/schematic/types/webhook_request_type.rb +2 -0
  103. data/lib/schematic/version.rb +1 -1
  104. data/lib/schematic/wasm/rulesengine.wasm +0 -0
  105. data/lib/schematic.rb +105 -39
  106. data/reference.md +1800 -301
  107. metadata +68 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d171ff79b7e78a9a60d576805e1c8d4b679b08a69d87414759421e7b5c58db5
4
- data.tar.gz: 1a042b9844338a76b885fcb14f19f003663f234fc64077c9ed55e57e85bf0553
3
+ metadata.gz: a42d012076b989e91c5c9019e981ee2af4e4f5f7115aaa1b304bed519c44a454
4
+ data.tar.gz: dd803e3554e9f425bdd2deb7f8b56b57c16483da2f86437e4f8400dae3ba1962
5
5
  SHA512:
6
- metadata.gz: 10072bf845fc063191774457072a90f0be6da68cb8e4bfdfa381481e0fa9ac3ac9cfd3cb8ed6c416fcf4f6d73a63fafcf2f7587f92f27cd147494ef9d87f8db9
7
- data.tar.gz: dc208fa7352fede21e1fa3577bb7837a85c5968cb0a904be863636f568b73b4949a397408d40ee589d25f83d8a7bc5fb995fea2c358be2e6d296d88b72980bcf
6
+ metadata.gz: 73bac05632b13d3839a98d2fa63b207243e6fa291bb255f9750af3d1658ac56373aedd630ecb3967ec580c2af9b819af176fa60c7a27897e7b6d72a34e1d9509
7
+ data.tar.gz: c014f30d286b1b01b25cafe35426efb6841c4861f6e8de6e362fbe9f2ca366f0680fb2ff2f2ea8994514f7b3f6e652bd167ca8d4a66f2de1906a0c297922fe45
data/.fern/metadata.json CHANGED
@@ -13,6 +13,6 @@
13
13
  "webrick": ">= 1.0"
14
14
  }
15
15
  },
16
- "originGitCommit": "19cafdf92ab056ef6ba803bf1e352b0422a8ec45",
17
- "sdkVersion": "1.4.9"
16
+ "originGitCommit": "340529eacf4f1dcc5522e771872c1dd94b9c4891",
17
+ "sdkVersion": "1.4.11"
18
18
  }
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
- current_generation: c93862aca1a52c6c033c908ebab873ca9ef6e401
40
- patches: []
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.5.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