convert_sdk 1.0.0

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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +191 -0
  4. data/.yardopts +16 -0
  5. data/CONTRIBUTING.md +131 -0
  6. data/LICENSE +201 -0
  7. data/README.md +183 -0
  8. data/RELEASE.md +313 -0
  9. data/Rakefile +16 -0
  10. data/convert_sdk.gemspec +50 -0
  11. data/lib/convert_sdk/api_manager.rb +288 -0
  12. data/lib/convert_sdk/background_timer.rb +129 -0
  13. data/lib/convert_sdk/bucketed_feature.rb +35 -0
  14. data/lib/convert_sdk/bucketed_variation.rb +43 -0
  15. data/lib/convert_sdk/bucketing_manager.rb +134 -0
  16. data/lib/convert_sdk/client.rb +417 -0
  17. data/lib/convert_sdk/comparisons.rb +257 -0
  18. data/lib/convert_sdk/config.rb +214 -0
  19. data/lib/convert_sdk/config_validator.rb +127 -0
  20. data/lib/convert_sdk/context.rb +618 -0
  21. data/lib/convert_sdk/data_manager.rb +897 -0
  22. data/lib/convert_sdk/data_store_manager.rb +185 -0
  23. data/lib/convert_sdk/enums/bucketing_error.rb +18 -0
  24. data/lib/convert_sdk/enums/feature_status.rb +13 -0
  25. data/lib/convert_sdk/enums/goal_data_key.rb +62 -0
  26. data/lib/convert_sdk/enums/log_level.rb +22 -0
  27. data/lib/convert_sdk/enums/rule_error.rb +19 -0
  28. data/lib/convert_sdk/enums/system_events.rb +29 -0
  29. data/lib/convert_sdk/event_manager.rb +125 -0
  30. data/lib/convert_sdk/experience_manager.rb +69 -0
  31. data/lib/convert_sdk/feature_manager.rb +367 -0
  32. data/lib/convert_sdk/fork_guard.rb +144 -0
  33. data/lib/convert_sdk/http_client.rb +198 -0
  34. data/lib/convert_sdk/log_manager.rb +168 -0
  35. data/lib/convert_sdk/murmur_hash3.rb +129 -0
  36. data/lib/convert_sdk/redactor.rb +93 -0
  37. data/lib/convert_sdk/rule_manager.rb +242 -0
  38. data/lib/convert_sdk/segments_manager.rb +241 -0
  39. data/lib/convert_sdk/sentinel.rb +57 -0
  40. data/lib/convert_sdk/stores/memory_store.rb +55 -0
  41. data/lib/convert_sdk/stores/redis_store.rb +126 -0
  42. data/lib/convert_sdk/version.rb +14 -0
  43. data/lib/convert_sdk/visitors_queue.rb +190 -0
  44. data/lib/convert_sdk.rb +218 -0
  45. data/scripts/check-generated-rbs-header.sh +41 -0
  46. data/steep/config_contract_probe.rb +154 -0
  47. metadata +93 -0
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Steep-checked contract probe — SYNTHETIC VALUES ONLY. NOT runtime code.
4
+ #
5
+ # This file lives OUTSIDE lib/ (register #18 / architecture Decision 5) and is
6
+ # never required by the SDK. It exists solely as the build-time drift gate:
7
+ # Steep checks it as part of the :probe target (strict diagnostics), and any
8
+ # field the SDK depends on that has been dropped or renamed in the regenerated
9
+ # RBS will cause Steep to fail on the probe line that includes it.
10
+ #
11
+ # == How the drift gate fires
12
+ #
13
+ # Each call below passes a hash literal containing every field the SDK depends on
14
+ # to a typed helper method (sig/convert_sdk/config/probe_helpers.rbs). With
15
+ # strict diagnostics in the :probe Steepfile target:
16
+ #
17
+ # 1. When a depended field is REMOVED from the regenerated record type, the
18
+ # hash literal here still includes that key.
19
+ # 2. Steep raises `UnknownRecordKey` (warning) + `ArgumentTypeMismatch` (error)
20
+ # on the exact literal line — surfacing which field drifted.
21
+ # 3. `steep check` exits non-zero, blocking the backend-opened PR pre-merge.
22
+ #
23
+ # This is the true Ruby analogue of JS's typed consumers: the probe curates the
24
+ # "fields we depend on" surface explicitly. Adding a new reader dependency means
25
+ # adding that field to the literal below.
26
+ #
27
+ # == Additive-safe (AC2)
28
+ #
29
+ # When a NEW field is added to the record, the probe does NOT include it. Steep
30
+ # is silent (no error). The runtime readers use plain-hash `fetch`/`[]` which
31
+ # ignore unknown fields — additive changes never break either gate.
32
+ #
33
+ # == Field coverage rules (D6)
34
+ #
35
+ # Include ONLY fields the SDK reads AND that are declared in the generated RBS.
36
+ # Fields the SDK reads that the spec OMITS (spec-completeness gaps) are COMMENTED
37
+ # with a "D6 spec-gap" note — including them would produce a false positive.
38
+ #
39
+ # Current D6 spec-completeness gaps (backend follow-up required):
40
+ # - goal fields: is_system, selected_default, status — absent from config_goal
41
+ # (present in real config; recorded in research:F3/D6)
42
+
43
+ module ConvertSdk
44
+ # ── config_response_data (the top-level "data" envelope) ──────────────────
45
+ probe_response_data_fields(
46
+ "account_id" => nil, # => DataManager#account_id reads data["account_id"]
47
+ "project" => nil, # => DataManager#project reads data["project"]
48
+ "experiences" => nil, # => DataManager#experiences reads data["experiences"]
49
+ "archived_experiences" => nil, # => DataManager#archived_experiences (:297) -> archived?
50
+ "features" => nil, # => DataManager#features reads data["features"]
51
+ "goals" => nil, # => DataManager#goals reads data["goals"]
52
+ "audiences" => nil, # => DataManager#audiences reads data["audiences"]
53
+ "segments" => nil, # => DataManager#segments reads data["segments"]
54
+ "locations" => nil # => DataManager#locations reads data["locations"]
55
+ )
56
+
57
+ # ── config_project ─────────────────────────────────────────────────────────
58
+ probe_project_fields(
59
+ "id" => nil, # => DataManager#project_id reads project["id"]
60
+ "name" => nil,
61
+ "type" => nil
62
+ )
63
+
64
+ # ── config_experience ──────────────────────────────────────────────────────
65
+ probe_experience_fields(
66
+ "id" => nil, # => eligible_experience, archived?, build_bucketed_variation
67
+ "key" => nil, # => find_by_key, build_bucketed_variation
68
+ "name" => nil, # => build_bucketed_variation
69
+ "type" => nil, # => present in spec; read via various gates
70
+ "status" => nil, # => environment + status gates
71
+ "environment" => nil, # => environment_match? reads experience["environment"]
72
+ "locations" => nil, # => match_locations reads experience["locations"]
73
+ "site_area" => nil, # => match_locations reads experience["site_area"]
74
+ "audiences" => nil, # => audiences_to_check, custom_segments_matched?
75
+ "variations" => nil, # => variation_list reads experience["variations"]
76
+ "goals" => nil, # => experience["goals"] consumed by readers
77
+ "settings" => { "matching_options" => { "audiences" => nil } } # => all_match_required? (:730-731)
78
+ )
79
+
80
+ # ── experience_variation ───────────────────────────────────────────────────
81
+ probe_variation_fields(
82
+ "id" => nil, # => build_bucketed_variation, retrieve_variation, build_buckets
83
+ "key" => nil, # => build_bucketed_variation
84
+ "name" => nil, # => build_bucketed_variation
85
+ "status" => nil, # => bucketable_variation? reads variation["status"]
86
+ "traffic_allocation" => nil, # => bucketable_variation?, build_buckets, build_bucketed_variation
87
+ "changes" => nil # => build_bucketed_variation reads variation["changes"]
88
+ )
89
+
90
+ # ── config_goal ────────────────────────────────────────────────────────────
91
+ # D6 spec-gaps: "is_system", "selected_default", "status" omitted (present in
92
+ # real config per test-config.json; absent from config_goal spec — F3/D6).
93
+ probe_goal_fields(
94
+ "id" => nil, # => DataManager#convert reads goal["id"] for dedup + wire payload
95
+ "name" => nil,
96
+ "key" => nil, # => find_by_key (goal_by_key) matches on goal["key"]
97
+ "type" => nil, # => goal_type discriminator union (all 10 values — AC4)
98
+ "rules" => nil # => rule walks reference goal["rules"]
99
+ )
100
+
101
+ # ── config_audience ────────────────────────────────────────────────────────
102
+ probe_audience_fields(
103
+ "id" => nil, # => items_by_ids matching
104
+ "key" => nil, # => find_by_key
105
+ "name" => nil,
106
+ "type" => nil, # => audiences_to_check reads audience["type"] == "permanent"
107
+ "rules" => nil # => matched_audiences walks audience["rules"]
108
+ )
109
+
110
+ # ── config_location ────────────────────────────────────────────────────────
111
+ probe_location_fields(
112
+ "id" => nil, # => match_location_list / items_by_ids
113
+ "key" => nil, # => find_by_key
114
+ "name" => nil,
115
+ "rules" => nil # => match_location_list walks location["rules"]
116
+ )
117
+
118
+ # ── config_segment ─────────────────────────────────────────────────────────
119
+ probe_segment_fields(
120
+ "id" => nil, # => custom_segments_matched? reads seg["id"]
121
+ "key" => nil, # => find_by_key
122
+ "name" => nil,
123
+ "rules" => nil
124
+ )
125
+
126
+ # ── config_feature ─────────────────────────────────────────────────────────
127
+ probe_feature_fields(
128
+ "id" => nil, # => feature_by_key resolution chain
129
+ "key" => nil, # => find_by_key
130
+ "name" => nil,
131
+ "variables" => nil # => FeatureManager reads feature["variables"]
132
+ )
133
+
134
+ # ── feature_variable ───────────────────────────────────────────────────────
135
+ probe_variable_fields(
136
+ "key" => nil, # => FeatureManager reads variable["key"]
137
+ "type" => nil # => feature_variable_type discriminator
138
+ )
139
+
140
+ # ── ga integration ─────────────────────────────────────────────────────────
141
+ probe_ga_fields(
142
+ "type" => nil, # => ga_integration_type discriminator (ga3 | ga4)
143
+ "enabled" => nil
144
+ )
145
+
146
+ # ── feature_change_data (variation change substructure — Facet 2) ──────────
147
+ probe_change_fields(
148
+ "type" => nil, # => FeatureManager reads change["type"] == FULLSTACK_FEATURE (:199)
149
+ "data" => { # => change["data"] (:213)
150
+ "feature_id" => nil, # => data["feature_id"] (:223)
151
+ "variables_data" => nil # => data["variables_data"] (:217)
152
+ }
153
+ )
154
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: convert_sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Convert Insights, Inc.
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: The official Convert Experiences Ruby SDK. Provides bucketing-compatible
13
+ A/B testing, feature flag evaluation, and personalizations for server-side Ruby
14
+ applications (Rails, Sinatra, Hanami, and plain scripts). Zero runtime dependencies.
15
+ email:
16
+ - support@convert.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".rspec"
22
+ - ".rubocop.yml"
23
+ - ".yardopts"
24
+ - CONTRIBUTING.md
25
+ - LICENSE
26
+ - README.md
27
+ - RELEASE.md
28
+ - Rakefile
29
+ - convert_sdk.gemspec
30
+ - lib/convert_sdk.rb
31
+ - lib/convert_sdk/api_manager.rb
32
+ - lib/convert_sdk/background_timer.rb
33
+ - lib/convert_sdk/bucketed_feature.rb
34
+ - lib/convert_sdk/bucketed_variation.rb
35
+ - lib/convert_sdk/bucketing_manager.rb
36
+ - lib/convert_sdk/client.rb
37
+ - lib/convert_sdk/comparisons.rb
38
+ - lib/convert_sdk/config.rb
39
+ - lib/convert_sdk/config_validator.rb
40
+ - lib/convert_sdk/context.rb
41
+ - lib/convert_sdk/data_manager.rb
42
+ - lib/convert_sdk/data_store_manager.rb
43
+ - lib/convert_sdk/enums/bucketing_error.rb
44
+ - lib/convert_sdk/enums/feature_status.rb
45
+ - lib/convert_sdk/enums/goal_data_key.rb
46
+ - lib/convert_sdk/enums/log_level.rb
47
+ - lib/convert_sdk/enums/rule_error.rb
48
+ - lib/convert_sdk/enums/system_events.rb
49
+ - lib/convert_sdk/event_manager.rb
50
+ - lib/convert_sdk/experience_manager.rb
51
+ - lib/convert_sdk/feature_manager.rb
52
+ - lib/convert_sdk/fork_guard.rb
53
+ - lib/convert_sdk/http_client.rb
54
+ - lib/convert_sdk/log_manager.rb
55
+ - lib/convert_sdk/murmur_hash3.rb
56
+ - lib/convert_sdk/redactor.rb
57
+ - lib/convert_sdk/rule_manager.rb
58
+ - lib/convert_sdk/segments_manager.rb
59
+ - lib/convert_sdk/sentinel.rb
60
+ - lib/convert_sdk/stores/memory_store.rb
61
+ - lib/convert_sdk/stores/redis_store.rb
62
+ - lib/convert_sdk/version.rb
63
+ - lib/convert_sdk/visitors_queue.rb
64
+ - scripts/check-generated-rbs-header.sh
65
+ - steep/config_contract_probe.rb
66
+ homepage: https://www.convert.com
67
+ licenses:
68
+ - Apache-2.0
69
+ metadata:
70
+ homepage_uri: https://www.convert.com
71
+ source_code_uri: https://github.com/convertcom/ruby-sdk
72
+ changelog_uri: https://github.com/convertcom/ruby-sdk/releases
73
+ documentation_uri: https://github.com/convertcom/ruby-sdk/wiki
74
+ rubygems_mfa_required: 'true'
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.1.0
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubygems_version: 3.6.9
90
+ specification_version: 4
91
+ summary: Convert Experiences FullStack Ruby SDK for A/B testing, feature flags, and
92
+ personalizations.
93
+ test_files: []