familia 2.0.0.pre12 → 2.0.0.pre14

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +2 -3
  3. data/CHANGELOG.rst +529 -0
  4. data/CLAUDE.md +1 -1
  5. data/Gemfile +1 -6
  6. data/Gemfile.lock +13 -7
  7. data/README.md +21 -2
  8. data/changelog.d/README.md +5 -5
  9. data/{setup.cfg → changelog.d/scriv.ini} +1 -1
  10. data/docs/guides/Feature-System-Autoloading.md +228 -0
  11. data/docs/guides/time-utilities.md +221 -0
  12. data/docs/migrating/v2.0.0-pre11.md +14 -16
  13. data/docs/migrating/v2.0.0-pre13.md +95 -0
  14. data/docs/migrating/v2.0.0-pre14.md +37 -0
  15. data/examples/autoloader/mega_customer/safe_dump_fields.rb +6 -0
  16. data/examples/autoloader/mega_customer.rb +17 -0
  17. data/examples/safe_dump.rb +1 -1
  18. data/familia.gemspec +1 -0
  19. data/lib/familia/autoloader.rb +53 -0
  20. data/lib/familia/base.rb +5 -0
  21. data/lib/familia/data_type.rb +4 -0
  22. data/lib/familia/encryption/encrypted_data.rb +4 -4
  23. data/lib/familia/encryption/manager.rb +6 -4
  24. data/lib/familia/encryption.rb +1 -1
  25. data/lib/familia/errors.rb +3 -0
  26. data/lib/familia/features/autoloadable.rb +113 -0
  27. data/lib/familia/features/encrypted_fields/concealed_string.rb +4 -2
  28. data/lib/familia/features/expiration.rb +4 -0
  29. data/lib/familia/features/external_identifier.rb +3 -3
  30. data/lib/familia/features/quantization.rb +5 -0
  31. data/lib/familia/features/safe_dump.rb +7 -0
  32. data/lib/familia/features.rb +20 -16
  33. data/lib/familia/field_type.rb +2 -0
  34. data/lib/familia/horreum/core/serialization.rb +3 -3
  35. data/lib/familia/horreum/subclass/definition.rb +3 -4
  36. data/lib/familia/horreum.rb +2 -0
  37. data/lib/familia/json_serializer.rb +70 -0
  38. data/lib/familia/logging.rb +12 -10
  39. data/lib/familia/refinements/logger_trace.rb +57 -0
  40. data/lib/familia/refinements/snake_case.rb +40 -0
  41. data/lib/familia/refinements/time_literals.rb +279 -0
  42. data/lib/familia/refinements.rb +3 -49
  43. data/lib/familia/utils.rb +2 -0
  44. data/lib/familia/validation/{test_helpers.rb → validation_helpers.rb} +2 -2
  45. data/lib/familia/validation.rb +1 -1
  46. data/lib/familia/version.rb +1 -1
  47. data/lib/familia.rb +15 -3
  48. data/try/core/autoloader_try.rb +112 -0
  49. data/try/core/extensions_try.rb +38 -21
  50. data/try/core/familia_extended_try.rb +4 -3
  51. data/try/core/time_utils_try.rb +130 -0
  52. data/try/data_types/datatype_base_try.rb +3 -2
  53. data/try/features/autoloadable/autoloadable_try.rb +61 -0
  54. data/try/features/encrypted_fields/concealed_string_core_try.rb +8 -3
  55. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +59 -17
  56. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +36 -12
  57. data/try/features/external_identifier/external_identifier_try.rb +26 -0
  58. data/try/features/feature_improvements_try.rb +2 -1
  59. data/try/features/real_feature_integration_try.rb +1 -1
  60. data/try/features/safe_dump/safe_dump_autoloading_try.rb +111 -0
  61. data/try/helpers/test_helpers.rb +24 -0
  62. data/try/integration/cross_component_try.rb +3 -1
  63. metadata +34 -6
  64. data/CHANGELOG.md +0 -247
  65. data/lib/familia/core_ext.rb +0 -135
  66. data/lib/familia/features/autoloader.rb +0 -57
@@ -0,0 +1,111 @@
1
+ # try/features/safe_dump/safe_dump_autoloading_try.rb
2
+
3
+ require_relative '../../../lib/familia'
4
+ require 'fileutils'
5
+ require 'tmpdir'
6
+
7
+ # Create test directory structure for SafeDump autoloading testing
8
+ @test_dir = Dir.mktmpdir('familia_safe_dump_autoload_test')
9
+ @model_file = File.join(@test_dir, 'test_safe_dump_model.rb')
10
+ @extension_file = File.join(@test_dir, 'test_safe_dump_model', 'safe_dump_extensions.rb')
11
+ @extension_dir = File.join(@test_dir, 'test_safe_dump_model')
12
+
13
+ # Create directory structure
14
+ FileUtils.mkdir_p(@extension_dir)
15
+
16
+ # Write test model file that uses SafeDump
17
+ File.write(@model_file, <<~RUBY)
18
+ class TestSafeDumpModel < Familia::Horreum
19
+ field :name
20
+ field :email
21
+ field :secret
22
+
23
+ feature :safe_dump
24
+ end
25
+ RUBY
26
+
27
+ # Write extension file (pattern: model_name/safe_dump_*.rb)
28
+ File.write(@extension_file, <<~RUBY)
29
+ class TestSafeDumpModel
30
+ # Define safe dump fields
31
+ safe_dump_fields :name, :email
32
+
33
+ # Add method to verify autoloading worked
34
+ def extension_loaded?
35
+ true
36
+ end
37
+ end
38
+ RUBY
39
+
40
+ ## Test that SafeDump includes Autoloadable
41
+ Familia::Features::SafeDump.ancestors.include?(Familia::Features::Autoloadable)
42
+ #=> true
43
+
44
+ ## Test that SafeDump has post_inclusion_autoload capability
45
+ Familia::Features::SafeDump.respond_to?(:post_inclusion_autoload)
46
+ #=> true
47
+
48
+ ## Test SafeDump autoloading by loading model file
49
+ @model_instance = nil
50
+
51
+ begin
52
+ require @model_file
53
+ @model_instance = TestSafeDumpModel.new(
54
+ name: 'John Doe',
55
+ email: 'john@example.com',
56
+ secret: 'hidden data'
57
+ )
58
+ true
59
+ rescue => e
60
+ false
61
+ end
62
+ #=> true
63
+
64
+ ## Test that autoloaded extension method is available
65
+ @model_instance.respond_to?(:extension_loaded?)
66
+ #=> true
67
+
68
+ ## Test autoloaded extension method works
69
+ @model_instance.extension_loaded?
70
+ #=> true
71
+
72
+ ## Test that model was created successfully
73
+ @model_instance.class.name
74
+ #=> "TestSafeDumpModel"
75
+
76
+ ## Test that feature_options were set up correctly
77
+ TestSafeDumpModel.respond_to?(:feature_options)
78
+ #=> true
79
+
80
+ ## Test that safe_dump fields were loaded from extension file
81
+ TestSafeDumpModel.safe_dump_field_names.sort
82
+ #=> [:email, :name]
83
+
84
+ ## Test that safe_dump functionality works with autoloaded fields
85
+ @dump_result = @model_instance.safe_dump
86
+ @dump_result.keys.sort
87
+ #=> [:email, :name]
88
+
89
+ ## Test that only safe fields are dumped
90
+ @dump_result[:name]
91
+ #=> "John Doe"
92
+
93
+ ## Test that email field is included
94
+ @dump_result[:email]
95
+ #=> "john@example.com"
96
+
97
+ ## Test that secret field is excluded (not in safe_dump_fields)
98
+ @dump_result.key?(:secret)
99
+ #=> false
100
+
101
+ ## Test that feature_options can be retrieved
102
+ @options = TestSafeDumpModel.feature_options(:safe_dump)
103
+ @options.is_a?(Hash)
104
+ #=> true
105
+
106
+ ## Test safe_dump feature is recognized
107
+ TestSafeDumpModel.features_enabled.include?(:safe_dump)
108
+ #=> true
109
+
110
+ # Cleanup test files and directories
111
+ FileUtils.rm_rf(@test_dir)
@@ -12,6 +12,8 @@ Familia.enable_database_logging = true
12
12
  Familia.enable_database_counter = true
13
13
 
14
14
  class Bone < Familia::Horreum
15
+ using Familia::Refinements::TimeLiterals
16
+
15
17
  identifier_field :token
16
18
  field :token
17
19
  field :name
@@ -39,6 +41,9 @@ class Bourne < Familia::Horreum
39
41
  end
40
42
 
41
43
  class Customer < Familia::Horreum
44
+
45
+ using Familia::Refinements::TimeLiterals
46
+
42
47
  logical_database 15 # Use something other than the default DB
43
48
  default_expiration 5.years
44
49
 
@@ -101,6 +106,8 @@ end
101
106
  @c.custid = 'd@example.com'
102
107
 
103
108
  class Session < Familia::Horreum
109
+ using Familia::Refinements::TimeLiterals
110
+
104
111
  logical_database 14 # don't use Onetime's default DB
105
112
  default_expiration 180.minutes
106
113
 
@@ -123,6 +130,8 @@ end
123
130
  @s = Session.new
124
131
 
125
132
  class CustomDomain < Familia::Horreum
133
+ using Familia::Refinements::TimeLiterals
134
+
126
135
  feature :expiration
127
136
 
128
137
  class_sorted_set :values
@@ -152,6 +161,8 @@ end
152
161
  @d.custid = @c.custid
153
162
 
154
163
  class Limiter < Familia::Horreum
164
+ using Familia::Refinements::TimeLiterals
165
+
155
166
  feature :expiration
156
167
  feature :quantization
157
168
 
@@ -229,3 +240,16 @@ module ConcealedStringTestHelper
229
240
  end
230
241
  end
231
242
  end
243
+
244
+ # Helper module for testing refinements in tryouts
245
+ module RefinedContext
246
+ using Familia::Refinements::TimeLiterals
247
+
248
+ def self.eval_in_refined_context(code)
249
+ eval(code)
250
+ end
251
+
252
+ def self.instance_eval_in_refined_context(code)
253
+ instance_eval(code)
254
+ end
255
+ end
@@ -2,7 +2,9 @@
2
2
 
3
3
  require_relative '../helpers/test_helpers'
4
4
 
5
- TestUser = Class.new(Familia::Horreum) do
5
+ class TestUser < Familia::Horreum
6
+ using Familia::Refinements::SnakeCase
7
+
6
8
  identifier_field :email
7
9
  field :email
8
10
  field :name
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.pre12
4
+ version: 2.0.0.pre14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -65,6 +65,20 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '1.7'
68
+ - !ruby/object:Gem::Dependency
69
+ name: oj
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.16'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.16'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: redis
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -129,7 +143,7 @@ files:
129
143
  - ".rubocop.yml"
130
144
  - ".rubocop_todo.yml"
131
145
  - ".yardopts"
132
- - CHANGELOG.md
146
+ - CHANGELOG.rst
133
147
  - CLAUDE.md
134
148
  - Gemfile
135
149
  - Gemfile.lock
@@ -137,6 +151,7 @@ files:
137
151
  - README.md
138
152
  - bin/irb
139
153
  - changelog.d/README.md
154
+ - changelog.d/scriv.ini
140
155
  - docs/archive/.gitignore
141
156
  - docs/archive/FAMILIA_RELATIONSHIPS.md
142
157
  - docs/archive/FAMILIA_TECHNICAL.md
@@ -148,6 +163,7 @@ files:
148
163
  - docs/guides/Connection-Pooling-Guide.md
149
164
  - docs/guides/Encrypted-Fields-Overview.md
150
165
  - docs/guides/Expiration-Feature-Guide.md
166
+ - docs/guides/Feature-System-Autoloading.md
151
167
  - docs/guides/Feature-System-Guide.md
152
168
  - docs/guides/Features-System-Developer-Guide.md
153
169
  - docs/guides/Field-System-Guide.md
@@ -158,23 +174,28 @@ files:
158
174
  - docs/guides/Security-Model.md
159
175
  - docs/guides/Transient-Fields-Guide.md
160
176
  - docs/guides/relationships-methods.md
177
+ - docs/guides/time-utilities.md
161
178
  - docs/migrating/.gitignore
162
179
  - docs/migrating/v2.0.0-pre.md
163
180
  - docs/migrating/v2.0.0-pre11.md
164
181
  - docs/migrating/v2.0.0-pre12.md
182
+ - docs/migrating/v2.0.0-pre13.md
183
+ - docs/migrating/v2.0.0-pre14.md
165
184
  - docs/migrating/v2.0.0-pre5.md
166
185
  - docs/migrating/v2.0.0-pre6.md
167
186
  - docs/migrating/v2.0.0-pre7.md
168
187
  - docs/overview.md
169
188
  - docs/reference/auditing_database_commands.rb
189
+ - examples/autoloader/mega_customer.rb
190
+ - examples/autoloader/mega_customer/safe_dump_fields.rb
170
191
  - examples/permissions.rb
171
192
  - examples/relationships.rb
172
193
  - examples/safe_dump.rb
173
194
  - familia.gemspec
174
195
  - lib/familia.rb
196
+ - lib/familia/autoloader.rb
175
197
  - lib/familia/base.rb
176
198
  - lib/familia/connection.rb
177
- - lib/familia/core_ext.rb
178
199
  - lib/familia/data_type.rb
179
200
  - lib/familia/data_type/commands.rb
180
201
  - lib/familia/data_type/serialization.rb
@@ -196,7 +217,7 @@ files:
196
217
  - lib/familia/encryption/request_cache.rb
197
218
  - lib/familia/errors.rb
198
219
  - lib/familia/features.rb
199
- - lib/familia/features/autoloader.rb
220
+ - lib/familia/features/autoloadable.rb
200
221
  - lib/familia/features/encrypted_fields.rb
201
222
  - lib/familia/features/encrypted_fields/concealed_string.rb
202
223
  - lib/familia/features/encrypted_fields/encrypted_field_type.rb
@@ -229,22 +250,26 @@ files:
229
250
  - lib/familia/horreum/subclass/definition.rb
230
251
  - lib/familia/horreum/subclass/management.rb
231
252
  - lib/familia/horreum/subclass/related_fields_management.rb
253
+ - lib/familia/json_serializer.rb
232
254
  - lib/familia/logging.rb
233
255
  - lib/familia/multi_result.rb
234
256
  - lib/familia/refinements.rb
257
+ - lib/familia/refinements/logger_trace.rb
258
+ - lib/familia/refinements/snake_case.rb
259
+ - lib/familia/refinements/time_literals.rb
235
260
  - lib/familia/secure_identifier.rb
236
261
  - lib/familia/settings.rb
237
262
  - lib/familia/utils.rb
238
263
  - lib/familia/validation.rb
239
264
  - lib/familia/validation/command_recorder.rb
240
265
  - lib/familia/validation/expectations.rb
241
- - lib/familia/validation/test_helpers.rb
266
+ - lib/familia/validation/validation_helpers.rb
242
267
  - lib/familia/validation/validator.rb
243
268
  - lib/familia/verifiable_identifier.rb
244
269
  - lib/familia/version.rb
245
270
  - lib/middleware/database_middleware.rb
246
- - setup.cfg
247
271
  - try/configuration/scenarios_try.rb
272
+ - try/core/autoloader_try.rb
248
273
  - try/core/base_enhancements_try.rb
249
274
  - try/core/connection_try.rb
250
275
  - try/core/create_method_try.rb
@@ -258,6 +283,7 @@ files:
258
283
  - try/core/pools_try.rb
259
284
  - try/core/secure_identifier_try.rb
260
285
  - try/core/settings_try.rb
286
+ - try/core/time_utils_try.rb
261
287
  - try/core/tools_try.rb
262
288
  - try/core/utils_try.rb
263
289
  - try/core/verifiable_identifier_try.rb
@@ -310,6 +336,7 @@ files:
310
336
  - try/encryption/providers/xchacha20_poly1305_provider_try.rb
311
337
  - try/encryption/roundtrip_validation_try.rb
312
338
  - try/encryption/secure_memory_handling_try.rb
339
+ - try/features/autoloadable/autoloadable_try.rb
313
340
  - try/features/encrypted_fields/aad_protection_try.rb
314
341
  - try/features/encrypted_fields/concealed_string_core_try.rb
315
342
  - try/features/encrypted_fields/context_isolation_try.rb
@@ -344,6 +371,7 @@ files:
344
371
  - try/features/relationships/relationships_performance_working_try.rb
345
372
  - try/features/relationships/relationships_try.rb
346
373
  - try/features/safe_dump/safe_dump_advanced_try.rb
374
+ - try/features/safe_dump/safe_dump_autoloading_try.rb
347
375
  - try/features/safe_dump/safe_dump_try.rb
348
376
  - try/features/transient_fields/redacted_string_try.rb
349
377
  - try/features/transient_fields/refresh_reset_try.rb
data/CHANGELOG.md DELETED
@@ -1,247 +0,0 @@
1
- # CHANGELOG.md
2
-
3
- All notable changes to Familia are documented here.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- <!--scriv-insert-here-->
9
-
10
- <a id='changelog-2.0.0.pre12'></a>
11
- ## 2.0.0.pre12 — 2025-09-04
12
-
13
- ### Added
14
-
15
- - Added the `Familia::VerifiableIdentifier` module to create and verify identifiers with an embedded HMAC signature. This allows an application to stateless-ly confirm that an identifier was generated by itself, preventing forged IDs from malicious sources.
16
-
17
- - **Scoped VerifiableIdentifier**: Added `scope` parameter to `generate_verifiable_id()` and `verified_identifier?()` methods, enabling cryptographically isolated identifier namespaces for multi-tenant, multi-domain, or multi-environment applications while maintaining full backward compatibility with existing code.
18
-
19
- ### Changed
20
-
21
- - ObjectIdentifier feature now tracks which generator (uuid_v7, uuid_v4, hex, or custom) was used for each objid to provide provenance information for security-sensitive operations.
22
- - Updated external identifier derivation to normalize objid format based on the known generator type, eliminating format ambiguity between UUID and hex formats.
23
-
24
- - Refactored identifier generation methods for clarity and consistency. Method `generate_objid` is now `generate_object_identifier`, and `generate_external_identifier` is now `derive_external_identifier` to reflect its deterministic nature.
25
-
26
- ### Removed
27
-
28
- - Removed the `generate_extid` class method, which was less secure than the instance-level derivation logic.
29
-
30
- ### Security
31
-
32
- - Hardened external identifier derivation with provenance validation. ExternalIdentifier now validates that objid values come from the ObjectIdentifier feature before deriving external identifiers, preventing derivation from potentially malicious or unvalidated objid values while maintaining deterministic behavior for legitimate use cases.
33
-
34
- - Improved the security of external identifiers (`extid`) by using the internal object identifier (`objid`) as a seed for a new random value, rather than deriving the `extid` directly. This prevents potential information leakage from the internal `objid`.
35
-
36
- ### Documentation
37
-
38
- - Added detailed YARD documentation for `VerifiableIdentifier`, explaining how to securely generate and manage the required `VERIFIABLE_ID_HMAC_SECRET` key.
39
-
40
- ### AI Assistance
41
-
42
- - Security analysis of external identifier derivation and hardened design approach was discussed and developed with AI assistance, including provenance tracking, validation logic, format normalization, and comprehensive test updates.
43
-
44
- - Implementation of scoped verifiable identifiers was developed with AI assistance to ensure cryptographic security properties and comprehensive test coverage.
45
-
46
- <a id='changelog-2.0.0.pre11'></a>
47
- ## 2.0.0.pre11 - 2025-09-03
48
-
49
- ### Added
50
-
51
- - **Enhanced Feature System**: Introduced a hierarchical feature system with ancestry chain traversal for model-specific feature registration. This enables better organization, standardized naming, and automatic loading of project-specific features via the new `Familia::Features::Autoloader` module.
52
- - **Improved SafeDump DSL**: Replaced the internal `@safe_dump_fields` implementation with a cleaner, more robust DSL using `safe_dump_field` and `safe_dump_fields` methods.
53
- - Added `generate_short_id` and `shorten_securely` utility methods for creating short, secure identifiers, adapted from `OT::Utils::SecureNumbers`.
54
- - For a detailed guide on migrating to the new feature system, see `docs/migration/v2.0.0-pre11.md`.
55
-
56
- ### Changed
57
-
58
- - External identifier now raises an `ExternalIdentifierError` if the model does not have an objid field. Previously: returned nil. In practice this should never happen, since the external_identifier feature declares its dependency on object_identifier.
59
- - Moved lib/familia/encryption_request_cache.rb to lib/familia/encryption/request_cache.rb for consistency.
60
- - **Simplified ObjectIdentifier Feature Implementation**: Consolidated the ObjectIdentifier feature from two files (~190 lines) to a single file (~140 lines) by moving the ObjectIdentifierFieldType class inline. This reduces complexity while maintaining all existing functionality including lazy generation, data integrity preservation, and multiple generator strategies.
61
- - **Renamed Identifier Features to Singular Form**: Renamed `object_identifier` → `object_identifier` and `external_identifier` → `external_identifier` for more accurate naming. Added full-length aliases (`object_identifier`/`external_identifier`) alongside the short forms (`objid`/`extid`) for clarity when needed.
62
- - **Simplified ExternalIdentifier Feature Implementation**: Consolidated the ExternalIdentifier feature from two files (~240 lines) to a single file (~120 lines) by moving the ExternalIdentifierFieldType class inline, following the same pattern as ObjectIdentifier.
63
-
64
- ### Fixed
65
-
66
- - Fixed external identifier generation returning all zeros for UUID-based objids. The `shorten_to_external_id` method now correctly handles both 256-bit secure identifiers and 128-bit UUIDs by detecting input length and applying appropriate bit truncation only when needed.
67
-
68
- ### Security
69
-
70
- - Improved input validation in `shorten_to_external_id` method by replacing insecure character count checking with proper bit length calculation and explicit validation. Invalid inputs now raise clear error messages instead of being silently processed incorrectly.
71
-
72
- <a id='changelog-2.0.0-pre10'></a>
73
- ## 2.0.0-pre10 - 2025-09-02
74
-
75
- ### Added
76
-
77
- - The `Familia::Horreum` initializer now supports creating an object directly from its identifier by passing a single argument (e.g., `Customer.new(customer_id)`). This provides a more convenient and intuitive way to instantiate objects from lookups.
78
-
79
- - Automatic indexing and class-level tracking on `save()` operations, eliminating the need for manual index updates.
80
- - Enhanced collection syntax supports the Ruby-idiomatic `<<` operator for more natural relationship management.
81
-
82
- ### Changed
83
-
84
- - The `member_of` relationship is now bidirectional. A single call to `member.add_to_owner_collection(owner)` is sufficient to establish the relationship, removing the need for a second, redundant call on the owner object. This fixes bugs where members could be added to collections twice.
85
-
86
- - **BREAKING**: Refactored Familia Relationships API to remove "global" terminology and simplify method generation. (Closes #86)
87
- - Split `generate_indexing_instance_methods` into focused `generate_direct_index_methods` and `generate_relationship_index_methods` for better separation between direct class-level and relationship-based indexing.
88
- - Simplified method generation by removing complex global vs parent conditionals.
89
- - All indexes are now stored at the class level for consistency.
90
-
91
- ### Fixed
92
-
93
- - Fixed a bug in the `class_indexed_by` feature where finder methods (e.g., `find_by_email`) would fail to correctly instantiate objects from the index, returning partially-formed objects.
94
-
95
- - Refactored connection handling to properly cache and reuse Redis connections. This eliminates repetitive "Overriding existing connection" warnings and improves performance.
96
-
97
- - Method generation now works consistently for both `class_indexed_by` and `indexed_by` with a `parent:`.
98
- - Resolved metadata storage issues for dynamically created classes.
99
- - Improved error handling for nil class names in tracking relationships.
100
-
101
- ### Documentation
102
-
103
- - Updated the `examples/relationships_basic.rb` script to reflect the improved, bidirectional `member_of` API and to ensure a clean database state for each run.
104
-
105
- ### AI Assistance
106
-
107
- - This refactoring was implemented with Claude Code assistance, including comprehensive test updates and API modernization.
108
-
109
- <a id='changelog-2.0.0-pre9'></a>
110
- ## 2.0.0-pre9 - 2025-09-02
111
-
112
- ### Added
113
-
114
- - Added `class_tracked_in` method for global tracking relationships following Horreum's established `class_` prefix convention
115
- - Added `class_indexed_by` method for global index relationships with consistent API design
116
-
117
- ### Changed
118
-
119
- - **BREAKING**: `tracked_in :global, collection` syntax now raises ArgumentError - use `class_tracked_in collection` instead
120
- - **BREAKING**: `indexed_by field, index, context: :global` syntax replaced with `class_indexed_by field, index`
121
- - **BREAKING**: `indexed_by field, index, context: SomeClass` syntax replaced with `indexed_by field, index, parent: SomeClass`
122
- - Relationships API now provides consistent parameter naming across all relationship types
123
-
124
- ### Documentation
125
-
126
- - Updated Relationships Guide with new API syntax and migration examples
127
- - Updated relationships method documentation with new method signatures
128
- - Updated basic relationships example to demonstrate new API patterns
129
- - Added tryouts test coverage in try/features/relationships/relationships_api_changes_try.rb
130
-
131
-
132
- <a id='changelog-2.0.0-pre8'></a>
133
- ## 2.0.0-pre8 - 2025-09-01
134
-
135
- ### Added
136
-
137
- - Implemented Scriv-based changelog system for sustainable documentation
138
- - Added fragment-based workflow for tracking changes
139
- - Created structured changelog templates and configuration
140
-
141
- ### Documentation
142
-
143
- - Set up Scriv configuration and directory structure
144
- - Created README for changelog fragment workflow
145
-
146
- <!-- scriv-end-here -->
147
-
148
- <a id='changelog-2.0.0-pre7'></a>
149
- ## 2.0.0-pre7 - 2025-08-31
150
-
151
- ### Added
152
-
153
- - Comprehensive relationships system with three relationship types:
154
- - `tracked_in` - Multi-presence tracking with score encoding
155
- - `indexed_by` - O(1) hash-based lookups
156
- - `member_of` - Bidirectional membership with collision-free naming
157
- - Categorical permission system with bit-encoded permissions
158
- - Time-based permission scoring for temporal access control
159
- - Permission tier hierarchies with inheritance patterns
160
- - Scalable permission management for large object collections
161
- - Score-based sorting with custom scoring functions
162
- - Permission-aware queries filtering by access levels
163
- - Relationship validation framework ensuring data integrity
164
-
165
- ### Changed
166
-
167
- - Performance optimizations for large-scale relationship operations
168
-
169
- ### Security
170
-
171
- - GitHub Actions security hardening with matrix optimization
172
-
173
-
174
- <a id='changelog-2.0.0-pre6'></a>
175
- ## 2.0.0-pre6 - 2025-08-15
176
-
177
- ### Added
178
-
179
- - New `save_if_not_exists` method for conditional persistence
180
- - Atomic persistence operations with transaction support
181
- - Enhanced error handling for persistence failures
182
- - Improved data consistency guarantees
183
-
184
- ### Changed
185
-
186
- - Connection provider pattern for flexible pooling strategies
187
- - Multi-database support with intelligent pool management
188
- - Thread-safe connection handling for concurrent applications
189
- - Configurable pool sizing and timeout management
190
- - Modular class structure with cleaner separation of concerns
191
- - Enhanced feature system with dependency management
192
- - Improved inheritance patterns for better code organization
193
- - Streamlined base class functionality
194
-
195
- ### Fixed
196
-
197
- - Critical security fixes in Ruby workflow vulnerabilities
198
- - Systematic dependency resolution via multi-constraint optimization
199
-
200
-
201
- <a id='changelog-2.0.0-pre5'></a>
202
- ## 2.0.0-pre5 - 2025-08-05
203
-
204
- ### Added
205
-
206
- - Field-level encryption with transparent access patterns
207
- - Multiple encryption providers:
208
- - XChaCha20-Poly1305 (preferred, requires rbnacl)
209
- - AES-256-GCM (fallback, OpenSSL-based)
210
- - Field-specific key derivation for cryptographic domain separation
211
- - Configurable key versioning supporting key rotation
212
- - Non-persistent field storage for sensitive runtime data
213
- - RedactedString wrapper preventing accidental logging/serialization
214
- - Memory-safe handling of sensitive data in Ruby objects
215
- - API-safe serialization excluding transient fields
216
-
217
- ### Security
218
-
219
- - Encryption field security hardening with additional validation
220
- - Enhanced memory protection for sensitive data handling
221
- - Improved key management patterns and best practices
222
- - Security test suite expansion with comprehensive coverage
223
-
224
-
225
- <a id='changelog-2.0.0-pre'></a>
226
- ## 2.0.0-pre - 2025-07-25
227
-
228
- ### Added
229
-
230
- - Complete API redesign for clarity and modern Ruby conventions
231
- - Valkey compatibility alongside traditional Redis support
232
- - Ruby 3.4+ modernization with fiber and thread safety improvements
233
- - Connection pooling foundation with provider pattern architecture
234
-
235
- ### Changed
236
-
237
- - `Familia::Base` replaced by `Familia::Horreum` as the primary base class
238
- - Connection configuration moved from simple string to block-based setup
239
- - Feature activation changed from `include` to `feature` declarations
240
- - Method naming updated for consistency (`delete` → `destroy`, `exists` → `exists?`, `dump` → `serialize`)
241
-
242
- ### Documentation
243
-
244
- - YARD documentation workflow with automated GitHub Pages deployment
245
- - Comprehensive migrating guide for v1.x to v2.0.0-pre transition
246
-
247
- <!-- scriv-end-here -->