familia 2.0.0.pre5 → 2.0.0.pre7

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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/claude-code-review.yml +57 -0
  3. data/.github/workflows/claude.yml +71 -0
  4. data/.gitignore +5 -1
  5. data/.rubocop.yml +3 -0
  6. data/CLAUDE.md +32 -10
  7. data/Gemfile +2 -2
  8. data/Gemfile.lock +4 -3
  9. data/docs/wiki/API-Reference.md +95 -18
  10. data/docs/wiki/Connection-Pooling-Guide.md +437 -0
  11. data/docs/wiki/Encrypted-Fields-Overview.md +40 -3
  12. data/docs/wiki/Expiration-Feature-Guide.md +596 -0
  13. data/docs/wiki/Feature-System-Guide.md +631 -0
  14. data/docs/wiki/Features-System-Developer-Guide.md +892 -0
  15. data/docs/wiki/Field-System-Guide.md +784 -0
  16. data/docs/wiki/Home.md +82 -15
  17. data/docs/wiki/Implementation-Guide.md +126 -33
  18. data/docs/wiki/Quantization-Feature-Guide.md +721 -0
  19. data/docs/wiki/Relationships-Guide.md +684 -0
  20. data/docs/wiki/Security-Model.md +65 -25
  21. data/docs/wiki/Transient-Fields-Guide.md +280 -0
  22. data/examples/bit_encoding_integration.rb +237 -0
  23. data/examples/redis_command_validation_example.rb +231 -0
  24. data/examples/relationships_basic.rb +273 -0
  25. data/lib/familia/base.rb +1 -1
  26. data/lib/familia/connection.rb +3 -3
  27. data/lib/familia/data_type/types/counter.rb +38 -0
  28. data/lib/familia/data_type/types/hashkey.rb +18 -0
  29. data/lib/familia/data_type/types/lock.rb +43 -0
  30. data/lib/familia/data_type/types/string.rb +9 -2
  31. data/lib/familia/data_type.rb +9 -6
  32. data/lib/familia/encryption/encrypted_data.rb +137 -0
  33. data/lib/familia/encryption/manager.rb +21 -4
  34. data/lib/familia/encryption/providers/aes_gcm_provider.rb +20 -0
  35. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +20 -0
  36. data/lib/familia/encryption.rb +1 -1
  37. data/lib/familia/errors.rb +17 -3
  38. data/lib/familia/features/encrypted_fields/concealed_string.rb +293 -0
  39. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +94 -26
  40. data/lib/familia/features/encrypted_fields.rb +413 -4
  41. data/lib/familia/features/expiration.rb +319 -33
  42. data/lib/familia/features/quantization.rb +385 -44
  43. data/lib/familia/features/relationships/cascading.rb +438 -0
  44. data/lib/familia/features/relationships/indexing.rb +370 -0
  45. data/lib/familia/features/relationships/membership.rb +503 -0
  46. data/lib/familia/features/relationships/permission_management.rb +264 -0
  47. data/lib/familia/features/relationships/querying.rb +620 -0
  48. data/lib/familia/features/relationships/redis_operations.rb +274 -0
  49. data/lib/familia/features/relationships/score_encoding.rb +442 -0
  50. data/lib/familia/features/relationships/tracking.rb +379 -0
  51. data/lib/familia/features/relationships.rb +466 -0
  52. data/lib/familia/features/safe_dump.rb +1 -1
  53. data/lib/familia/features/transient_fields/redacted_string.rb +1 -1
  54. data/lib/familia/features/transient_fields.rb +192 -10
  55. data/lib/familia/features.rb +2 -1
  56. data/lib/familia/field_type.rb +5 -2
  57. data/lib/familia/horreum/{connection.rb → core/connection.rb} +2 -8
  58. data/lib/familia/horreum/{database_commands.rb → core/database_commands.rb} +14 -3
  59. data/lib/familia/horreum/core/serialization.rb +535 -0
  60. data/lib/familia/horreum/{utils.rb → core/utils.rb} +0 -2
  61. data/lib/familia/horreum/core.rb +21 -0
  62. data/lib/familia/horreum/{settings.rb → shared/settings.rb} +0 -2
  63. data/lib/familia/horreum/{definition_methods.rb → subclass/definition.rb} +45 -29
  64. data/lib/familia/horreum/{management_methods.rb → subclass/management.rb} +9 -8
  65. data/lib/familia/horreum/{related_fields_management.rb → subclass/related_fields_management.rb} +15 -10
  66. data/lib/familia/horreum.rb +17 -17
  67. data/lib/familia/validation/command_recorder.rb +336 -0
  68. data/lib/familia/validation/expectations.rb +519 -0
  69. data/lib/familia/validation/test_helpers.rb +443 -0
  70. data/lib/familia/validation/validator.rb +412 -0
  71. data/lib/familia/validation.rb +140 -0
  72. data/lib/familia/version.rb +1 -1
  73. data/lib/familia.rb +1 -1
  74. data/try/core/create_method_try.rb +240 -0
  75. data/try/core/database_consistency_try.rb +299 -0
  76. data/try/core/errors_try.rb +25 -4
  77. data/try/core/familia_try.rb +1 -1
  78. data/try/core/persistence_operations_try.rb +297 -0
  79. data/try/data_types/counter_try.rb +93 -0
  80. data/try/data_types/lock_try.rb +133 -0
  81. data/try/debugging/debug_aad_process.rb +82 -0
  82. data/try/debugging/debug_concealed_internal.rb +59 -0
  83. data/try/debugging/debug_concealed_reveal.rb +61 -0
  84. data/try/debugging/debug_context_aad.rb +68 -0
  85. data/try/debugging/debug_context_simple.rb +80 -0
  86. data/try/debugging/debug_cross_context.rb +62 -0
  87. data/try/debugging/debug_database_load.rb +64 -0
  88. data/try/debugging/debug_encrypted_json_check.rb +53 -0
  89. data/try/debugging/debug_encrypted_json_step_by_step.rb +62 -0
  90. data/try/debugging/debug_exists_lifecycle.rb +54 -0
  91. data/try/debugging/debug_field_decrypt.rb +74 -0
  92. data/try/debugging/debug_fresh_cross_context.rb +73 -0
  93. data/try/debugging/debug_load_path.rb +66 -0
  94. data/try/debugging/debug_method_definition.rb +46 -0
  95. data/try/debugging/debug_method_resolution.rb +41 -0
  96. data/try/debugging/debug_minimal.rb +24 -0
  97. data/try/debugging/debug_provider.rb +68 -0
  98. data/try/debugging/debug_secure_behavior.rb +73 -0
  99. data/try/debugging/debug_string_class.rb +46 -0
  100. data/try/debugging/debug_test.rb +46 -0
  101. data/try/debugging/debug_test_design.rb +80 -0
  102. data/try/edge_cases/hash_symbolization_try.rb +1 -0
  103. data/try/edge_cases/reserved_keywords_try.rb +1 -0
  104. data/try/edge_cases/string_coercion_try.rb +2 -0
  105. data/try/encryption/encryption_core_try.rb +6 -4
  106. data/try/features/categorical_permissions_try.rb +515 -0
  107. data/try/features/encrypted_fields_core_try.rb +19 -11
  108. data/try/features/encrypted_fields_integration_try.rb +66 -70
  109. data/try/features/encrypted_fields_no_cache_security_try.rb +22 -8
  110. data/try/features/encrypted_fields_security_try.rb +151 -144
  111. data/try/features/encryption_fields/aad_protection_try.rb +108 -23
  112. data/try/features/encryption_fields/concealed_string_core_try.rb +253 -0
  113. data/try/features/encryption_fields/context_isolation_try.rb +30 -8
  114. data/try/features/encryption_fields/error_conditions_try.rb +6 -6
  115. data/try/features/encryption_fields/fresh_key_derivation_try.rb +20 -14
  116. data/try/features/encryption_fields/fresh_key_try.rb +27 -22
  117. data/try/features/encryption_fields/key_rotation_try.rb +16 -10
  118. data/try/features/encryption_fields/nonce_uniqueness_try.rb +15 -13
  119. data/try/features/encryption_fields/secure_by_default_behavior_try.rb +310 -0
  120. data/try/features/encryption_fields/thread_safety_try.rb +6 -6
  121. data/try/features/encryption_fields/universal_serialization_safety_try.rb +174 -0
  122. data/try/features/feature_dependencies_try.rb +3 -3
  123. data/try/features/relationships_edge_cases_try.rb +145 -0
  124. data/try/features/relationships_performance_minimal_try.rb +132 -0
  125. data/try/features/relationships_performance_simple_try.rb +155 -0
  126. data/try/features/relationships_performance_try.rb +420 -0
  127. data/try/features/relationships_performance_working_try.rb +144 -0
  128. data/try/features/relationships_try.rb +237 -0
  129. data/try/features/safe_dump_try.rb +3 -0
  130. data/try/features/transient_fields/redacted_string_try.rb +2 -0
  131. data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
  132. data/try/features/transient_fields_core_try.rb +1 -1
  133. data/try/features/transient_fields_integration_try.rb +1 -1
  134. data/try/helpers/test_helpers.rb +26 -1
  135. data/try/horreum/base_try.rb +14 -8
  136. data/try/horreum/enhanced_conflict_handling_try.rb +3 -1
  137. data/try/horreum/initialization_try.rb +1 -1
  138. data/try/horreum/relations_try.rb +2 -2
  139. data/try/horreum/serialization_persistent_fields_try.rb +8 -8
  140. data/try/horreum/serialization_try.rb +39 -4
  141. data/try/models/customer_safe_dump_try.rb +1 -1
  142. data/try/models/customer_try.rb +1 -1
  143. data/try/validation/atomic_operations_try.rb.disabled +320 -0
  144. data/try/validation/command_validation_try.rb.disabled +207 -0
  145. data/try/validation/performance_validation_try.rb.disabled +324 -0
  146. data/try/validation/real_world_scenarios_try.rb.disabled +390 -0
  147. metadata +81 -12
  148. data/TEST_COVERAGE.md +0 -40
  149. data/lib/familia/features/relatable_objects.rb +0 -125
  150. data/lib/familia/horreum/serialization.rb +0 -473
  151. data/try/features/relatable_objects_try.rb +0 -220
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: familia
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre5
4
+ version: 2.0.0.pre7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -121,6 +121,8 @@ extensions: []
121
121
  extra_rdoc_files: []
122
122
  files:
123
123
  - ".github/workflows/ci.yml"
124
+ - ".github/workflows/claude-code-review.yml"
125
+ - ".github/workflows/claude.yml"
124
126
  - ".github/workflows/docs.yml"
125
127
  - ".gitignore"
126
128
  - ".pre-commit-config.yaml"
@@ -132,15 +134,25 @@ files:
132
134
  - Gemfile.lock
133
135
  - LICENSE.txt
134
136
  - README.md
135
- - TEST_COVERAGE.md
136
137
  - bin/irb
137
138
  - docs/connection_pooling.md
138
139
  - docs/overview.md
139
140
  - docs/wiki/API-Reference.md
141
+ - docs/wiki/Connection-Pooling-Guide.md
140
142
  - docs/wiki/Encrypted-Fields-Overview.md
143
+ - docs/wiki/Expiration-Feature-Guide.md
144
+ - docs/wiki/Feature-System-Guide.md
145
+ - docs/wiki/Features-System-Developer-Guide.md
146
+ - docs/wiki/Field-System-Guide.md
141
147
  - docs/wiki/Home.md
142
148
  - docs/wiki/Implementation-Guide.md
149
+ - docs/wiki/Quantization-Feature-Guide.md
150
+ - docs/wiki/Relationships-Guide.md
143
151
  - docs/wiki/Security-Model.md
152
+ - docs/wiki/Transient-Fields-Guide.md
153
+ - examples/bit_encoding_integration.rb
154
+ - examples/redis_command_validation_example.rb
155
+ - examples/relationships_basic.rb
144
156
  - familia.gemspec
145
157
  - lib/familia.rb
146
158
  - lib/familia/base.rb
@@ -149,12 +161,15 @@ files:
149
161
  - lib/familia/data_type.rb
150
162
  - lib/familia/data_type/commands.rb
151
163
  - lib/familia/data_type/serialization.rb
164
+ - lib/familia/data_type/types/counter.rb
152
165
  - lib/familia/data_type/types/hashkey.rb
153
166
  - lib/familia/data_type/types/list.rb
167
+ - lib/familia/data_type/types/lock.rb
154
168
  - lib/familia/data_type/types/sorted_set.rb
155
169
  - lib/familia/data_type/types/string.rb
156
170
  - lib/familia/data_type/types/unsorted_set.rb
157
171
  - lib/familia/encryption.rb
172
+ - lib/familia/encryption/encrypted_data.rb
158
173
  - lib/familia/encryption/manager.rb
159
174
  - lib/familia/encryption/provider.rb
160
175
  - lib/familia/encryption/providers/aes_gcm_provider.rb
@@ -165,10 +180,19 @@ files:
165
180
  - lib/familia/errors.rb
166
181
  - lib/familia/features.rb
167
182
  - lib/familia/features/encrypted_fields.rb
183
+ - lib/familia/features/encrypted_fields/concealed_string.rb
168
184
  - lib/familia/features/encrypted_fields/encrypted_field_type.rb
169
185
  - lib/familia/features/expiration.rb
170
186
  - lib/familia/features/quantization.rb
171
- - lib/familia/features/relatable_objects.rb
187
+ - lib/familia/features/relationships.rb
188
+ - lib/familia/features/relationships/cascading.rb
189
+ - lib/familia/features/relationships/indexing.rb
190
+ - lib/familia/features/relationships/membership.rb
191
+ - lib/familia/features/relationships/permission_management.rb
192
+ - lib/familia/features/relationships/querying.rb
193
+ - lib/familia/features/relationships/redis_operations.rb
194
+ - lib/familia/features/relationships/score_encoding.rb
195
+ - lib/familia/features/relationships/tracking.rb
172
196
  - lib/familia/features/safe_dump.rb
173
197
  - lib/familia/features/transient_fields.rb
174
198
  - lib/familia/features/transient_fields/redacted_string.rb
@@ -176,44 +200,76 @@ files:
176
200
  - lib/familia/features/transient_fields/transient_field_type.rb
177
201
  - lib/familia/field_type.rb
178
202
  - lib/familia/horreum.rb
179
- - lib/familia/horreum/connection.rb
180
- - lib/familia/horreum/database_commands.rb
181
- - lib/familia/horreum/definition_methods.rb
182
- - lib/familia/horreum/management_methods.rb
183
- - lib/familia/horreum/related_fields_management.rb
184
- - lib/familia/horreum/serialization.rb
185
- - lib/familia/horreum/settings.rb
186
- - lib/familia/horreum/utils.rb
203
+ - lib/familia/horreum/core.rb
204
+ - lib/familia/horreum/core/connection.rb
205
+ - lib/familia/horreum/core/database_commands.rb
206
+ - lib/familia/horreum/core/serialization.rb
207
+ - lib/familia/horreum/core/utils.rb
208
+ - lib/familia/horreum/shared/settings.rb
209
+ - lib/familia/horreum/subclass/definition.rb
210
+ - lib/familia/horreum/subclass/management.rb
211
+ - lib/familia/horreum/subclass/related_fields_management.rb
187
212
  - lib/familia/logging.rb
188
213
  - lib/familia/multi_result.rb
189
214
  - lib/familia/refinements.rb
190
215
  - lib/familia/secure_identifier.rb
191
216
  - lib/familia/settings.rb
192
217
  - lib/familia/utils.rb
218
+ - lib/familia/validation.rb
219
+ - lib/familia/validation/command_recorder.rb
220
+ - lib/familia/validation/expectations.rb
221
+ - lib/familia/validation/test_helpers.rb
222
+ - lib/familia/validation/validator.rb
193
223
  - lib/familia/version.rb
194
224
  - lib/middleware/database_middleware.rb
195
225
  - try/configuration/scenarios_try.rb
196
226
  - try/core/base_enhancements_try.rb
197
227
  - try/core/connection_try.rb
228
+ - try/core/create_method_try.rb
229
+ - try/core/database_consistency_try.rb
198
230
  - try/core/errors_try.rb
199
231
  - try/core/extensions_try.rb
200
232
  - try/core/familia_extended_try.rb
201
233
  - try/core/familia_try.rb
202
234
  - try/core/middleware_try.rb
235
+ - try/core/persistence_operations_try.rb
203
236
  - try/core/pools_try.rb
204
237
  - try/core/secure_identifier_try.rb
205
238
  - try/core/settings_try.rb
206
239
  - try/core/tools_try.rb
207
240
  - try/core/utils_try.rb
208
241
  - try/data_types/boolean_try.rb
242
+ - try/data_types/counter_try.rb
209
243
  - try/data_types/datatype_base_try.rb
210
244
  - try/data_types/hash_try.rb
211
245
  - try/data_types/list_try.rb
246
+ - try/data_types/lock_try.rb
212
247
  - try/data_types/set_try.rb
213
248
  - try/data_types/sorted_set_try.rb
214
249
  - try/data_types/string_try.rb
215
250
  - try/debugging/README.md
216
251
  - try/debugging/cache_behavior_tracer.rb
252
+ - try/debugging/debug_aad_process.rb
253
+ - try/debugging/debug_concealed_internal.rb
254
+ - try/debugging/debug_concealed_reveal.rb
255
+ - try/debugging/debug_context_aad.rb
256
+ - try/debugging/debug_context_simple.rb
257
+ - try/debugging/debug_cross_context.rb
258
+ - try/debugging/debug_database_load.rb
259
+ - try/debugging/debug_encrypted_json_check.rb
260
+ - try/debugging/debug_encrypted_json_step_by_step.rb
261
+ - try/debugging/debug_exists_lifecycle.rb
262
+ - try/debugging/debug_field_decrypt.rb
263
+ - try/debugging/debug_fresh_cross_context.rb
264
+ - try/debugging/debug_load_path.rb
265
+ - try/debugging/debug_method_definition.rb
266
+ - try/debugging/debug_method_resolution.rb
267
+ - try/debugging/debug_minimal.rb
268
+ - try/debugging/debug_provider.rb
269
+ - try/debugging/debug_secure_behavior.rb
270
+ - try/debugging/debug_string_class.rb
271
+ - try/debugging/debug_test.rb
272
+ - try/debugging/debug_test_design.rb
217
273
  - try/debugging/encryption_method_tracer.rb
218
274
  - try/debugging/provider_diagnostics.rb
219
275
  - try/edge_cases/empty_identifiers_try.rb
@@ -231,11 +287,13 @@ files:
231
287
  - try/encryption/providers/xchacha20_poly1305_provider_try.rb
232
288
  - try/encryption/roundtrip_validation_try.rb
233
289
  - try/encryption/secure_memory_handling_try.rb
290
+ - try/features/categorical_permissions_try.rb
234
291
  - try/features/encrypted_fields_core_try.rb
235
292
  - try/features/encrypted_fields_integration_try.rb
236
293
  - try/features/encrypted_fields_no_cache_security_try.rb
237
294
  - try/features/encrypted_fields_security_try.rb
238
295
  - try/features/encryption_fields/aad_protection_try.rb
296
+ - try/features/encryption_fields/concealed_string_core_try.rb
239
297
  - try/features/encryption_fields/context_isolation_try.rb
240
298
  - try/features/encryption_fields/error_conditions_try.rb
241
299
  - try/features/encryption_fields/fresh_key_derivation_try.rb
@@ -244,12 +302,19 @@ files:
244
302
  - try/features/encryption_fields/memory_security_try.rb
245
303
  - try/features/encryption_fields/missing_current_key_version_try.rb
246
304
  - try/features/encryption_fields/nonce_uniqueness_try.rb
305
+ - try/features/encryption_fields/secure_by_default_behavior_try.rb
247
306
  - try/features/encryption_fields/thread_safety_try.rb
307
+ - try/features/encryption_fields/universal_serialization_safety_try.rb
248
308
  - try/features/expiration_try.rb
249
309
  - try/features/feature_dependencies_try.rb
250
310
  - try/features/quantization_try.rb
251
311
  - try/features/real_feature_integration_try.rb
252
- - try/features/relatable_objects_try.rb
312
+ - try/features/relationships_edge_cases_try.rb
313
+ - try/features/relationships_performance_minimal_try.rb
314
+ - try/features/relationships_performance_simple_try.rb
315
+ - try/features/relationships_performance_try.rb
316
+ - try/features/relationships_performance_working_try.rb
317
+ - try/features/relationships_try.rb
253
318
  - try/features/safe_dump_advanced_try.rb
254
319
  - try/features/safe_dump_try.rb
255
320
  - try/features/transient_fields/redacted_string_try.rb
@@ -296,6 +361,10 @@ files:
296
361
  - try/prototypes/pooling/lib/visualize_stress_results.rb
297
362
  - try/prototypes/pooling/pool_siege.rb
298
363
  - try/prototypes/pooling/run_stress_tests.rb
364
+ - try/validation/atomic_operations_try.rb.disabled
365
+ - try/validation/command_validation_try.rb.disabled
366
+ - try/validation/performance_validation_try.rb.disabled
367
+ - try/validation/real_world_scenarios_try.rb.disabled
299
368
  homepage: https://github.com/delano/familia
300
369
  licenses:
301
370
  - MIT
data/TEST_COVERAGE.md DELETED
@@ -1,40 +0,0 @@
1
- # Encryption Test Coverage
2
-
3
- ## Summary
4
- - **149/150 tests passing** (99.3%)
5
- - **12 test files**, 281ms execution
6
- - **1 failing test** in integration suite
7
-
8
- ## Test Distribution
9
-
10
- | Category | Files | Tests | Status |
11
- |----------|-------|-------|---------|
12
- | Core Encryption | 6 | 77 | ✅ All Pass |
13
- | Providers | 2 | 39 | ✅ All Pass |
14
- | Encrypted Fields | 4 | 53 | ⚠️ 1 Failure |
15
-
16
- ## Key Test Areas
17
-
18
- ### Security Testing (59 tests)
19
- - No key caching (22 tests)
20
- - AAD tampering detection (15 tests)
21
- - Memory wiping verification (11 tests)
22
- - Context isolation (11 tests)
23
-
24
- ### Provider Testing (39 tests)
25
- - XChaCha20-Poly1305: 19 tests
26
- - AES-GCM: 20 tests
27
- - Round-trip encryption/decryption
28
- - Nonce uniqueness and tampering detection
29
-
30
- ### Integration Testing (53 tests)
31
- - Mixed field types with encryption
32
- - Provider selection and algorithm handling
33
- - Full model initialization workflows
34
-
35
- ## Action Items
36
- - [ ] Fix failing integration test in `encrypted_fields_integration_try.rb:186`
37
- - [x] All security properties validated
38
- - [x] Both encryption providers fully tested
39
-
40
- ## Coverage Assessment: **Production Ready**
@@ -1,125 +0,0 @@
1
- # apps/api/v2/models/features/relatable_object.rb
2
-
3
- module V2
4
- module Features
5
- class RelatableObjectError < Familia::Problem; end
6
-
7
- # RelatableObject
8
- #
9
- # Provides the standard core object fields and methods.
10
- #
11
- module RelatableObject
12
- def self.included(base)
13
- base.class_sorted_set :relatable_objids
14
- base.class_hashkey :owners
15
-
16
- # NOTE: we do not automatically assign the objid field as the
17
- # main identifier field. That's up to the implementing class.
18
- base.field :objid
19
- base.field :extid
20
- base.field :api_version
21
-
22
- base.extend(ClassMethods)
23
-
24
- # prepend ensures our methods execute BEFORE field-generated accessors
25
- # include would place them AFTER, but they'd never execute because
26
- # attr_reader doesn't call super - it just returns the instance variable
27
- #
28
- # Method lookup chain:
29
- # prepend: [InstanceMethods] → [Field Methods] → [Parent]
30
- # include: [Field Methods] → [InstanceMethods] → [Parent]
31
- # (stops here, no super) (never reached)
32
- #
33
- base.prepend(InstanceMethods)
34
- end
35
-
36
- module InstanceMethods
37
- # We lazily generate the object ID and external ID when they are first
38
- # accessed so that we can instantiate and load existing objects, without
39
- # eagerly generating them, only to be overridden by the storage layer.
40
- #
41
- def init
42
- super if defined?(super) # Only call if parent has init
43
-
44
- @api_version ||= 'v2'
45
- end
46
-
47
- def objid
48
- @objid ||= begin # lazy loader
49
- generated_id = self.class.generate_objid
50
- # Using the attr_writer method ensures any future Familia
51
- # enhancements to the setter are properly invoked (as opposed
52
- # to directly assigning @objid).
53
- self.objid = generated_id
54
- end
55
- end
56
- alias relatable_objid objid
57
-
58
- def extid
59
- @extid ||= begin # lazy loader
60
- generated_id = self.class.generate_extid
61
- self.extid = generated_id
62
- end
63
- end
64
- alias external_identifier extid
65
-
66
- # Check if the given customer is the owner of this domain
67
- #
68
- # @param cust [V2::Customer, String] The customer object or customer ID to check
69
- # @return [Boolean] true if the customer is the owner, false otherwise
70
- def owner?(related_object)
71
- self.class.relatable?(related_object) do
72
- # Check the hash (our objid => related_object's objid)
73
- owner_objid = self.class.owners.get(objid).to_s
74
- return false if owner_objid.empty?
75
-
76
- owner_objid.eql?(related_object.objid)
77
- end
78
- end
79
-
80
- def owned?
81
- # We can only have an owner if we are relatable ourselves.
82
- return false unless is_a?(RelatableObject)
83
-
84
- # If our object identifier is present, we have an owner
85
- self.class.owners.key?(objid)
86
- end
87
- end
88
-
89
- module ClassMethods
90
- def relatable?(obj, &)
91
- is_relatable = obj.is_a?(RelatableObject)
92
- err_klass = V2::Features::RelatableObjectError
93
- raise err_klass, 'Not relatable object' unless is_relatable
94
- raise err_klass, 'No self-ownership' if obj.class == self
95
-
96
- block_given? ? yield : is_relatable
97
- end
98
-
99
- def find_by_objid(objid)
100
- return nil if objid.to_s.empty?
101
-
102
- if Familia.debug?
103
- reference = caller(1..1).first
104
- Familia.trace :FIND_BY_OBJID, Familia.dbclient(uri), objkey, reference
105
- end
106
-
107
- find_by_key objkey
108
- end
109
-
110
- def generate_objid
111
- SecureRandom.uuid_v7
112
- end
113
-
114
- # Guaranteed length of 54
115
- def generate_extid
116
- format('ext_%s', Familia.generate_id)
117
- end
118
- end
119
- extend ClassMethods
120
-
121
- # Self-register the kids for martial arts classes
122
- Familia::Base.add_feature self, :relatable_object
123
- end
124
- end
125
- end