familia 2.0.0.pre10 → 2.0.0.pre13

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +2 -3
  3. data/CHANGELOG.rst +507 -0
  4. data/CLAUDE.md +5 -55
  5. data/Gemfile +1 -6
  6. data/Gemfile.lock +13 -7
  7. data/changelog.d/README.md +45 -34
  8. data/changelog.d/scriv.ini +5 -0
  9. data/docs/archive/FAMILIA_RELATIONSHIPS.md +1 -1
  10. data/docs/archive/FAMILIA_UPDATE.md +1 -1
  11. data/docs/archive/README.md +15 -19
  12. data/docs/guides/Feature-System-Autoloading.md +228 -0
  13. data/docs/guides/Home.md +1 -1
  14. data/docs/guides/Implementation-Guide.md +1 -1
  15. data/docs/guides/relationships-methods.md +1 -1
  16. data/docs/guides/time-utilities.md +221 -0
  17. data/docs/migrating/.gitignore +2 -0
  18. data/docs/migrating/v2.0.0-pre.md +84 -0
  19. data/docs/migrating/v2.0.0-pre11.md +253 -0
  20. data/docs/migrating/v2.0.0-pre12.md +306 -0
  21. data/docs/migrating/v2.0.0-pre13.md +329 -0
  22. data/docs/migrating/v2.0.0-pre5.md +110 -0
  23. data/docs/migrating/v2.0.0-pre6.md +154 -0
  24. data/docs/migrating/v2.0.0-pre7.md +222 -0
  25. data/docs/overview.md +6 -7
  26. data/{examples/redis_command_validation_example.rb → docs/reference/auditing_database_commands.rb} +29 -32
  27. data/examples/autoloader/mega_customer/safe_dump_fields.rb +6 -0
  28. data/examples/autoloader/mega_customer.rb +17 -0
  29. data/examples/{bit_encoding_integration.rb → permissions.rb} +30 -27
  30. data/examples/{relationships_basic.rb → relationships.rb} +2 -3
  31. data/examples/safe_dump.rb +281 -0
  32. data/familia.gemspec +5 -4
  33. data/lib/familia/autoloader.rb +53 -0
  34. data/lib/familia/base.rb +57 -0
  35. data/lib/familia/data_type.rb +4 -0
  36. data/lib/familia/encryption/encrypted_data.rb +4 -4
  37. data/lib/familia/encryption/manager.rb +6 -4
  38. data/lib/familia/{encryption_request_cache.rb → encryption/request_cache.rb} +1 -1
  39. data/lib/familia/encryption.rb +1 -1
  40. data/lib/familia/errors.rb +5 -0
  41. data/lib/familia/features/autoloadable.rb +113 -0
  42. data/lib/familia/features/encrypted_fields/concealed_string.rb +4 -2
  43. data/lib/familia/features/expiration.rb +4 -0
  44. data/lib/familia/features/external_identifier.rb +310 -0
  45. data/lib/familia/features/object_identifier.rb +307 -0
  46. data/lib/familia/features/quantization.rb +5 -0
  47. data/lib/familia/features/safe_dump.rb +74 -73
  48. data/lib/familia/features.rb +109 -17
  49. data/lib/familia/field_type.rb +2 -0
  50. data/lib/familia/horreum/core/serialization.rb +3 -3
  51. data/lib/familia/horreum/subclass/definition.rb +50 -7
  52. data/lib/familia/horreum.rb +2 -0
  53. data/lib/familia/json_serializer.rb +70 -0
  54. data/lib/familia/logging.rb +12 -10
  55. data/lib/familia/refinements/logger_trace.rb +57 -0
  56. data/lib/familia/refinements/snake_case.rb +40 -0
  57. data/lib/familia/refinements/time_utils.rb +248 -0
  58. data/lib/familia/refinements.rb +3 -49
  59. data/lib/familia/secure_identifier.rb +51 -75
  60. data/lib/familia/utils.rb +2 -0
  61. data/lib/familia/validation/{test_helpers.rb → validation_helpers.rb} +2 -2
  62. data/lib/familia/validation.rb +1 -1
  63. data/lib/familia/verifiable_identifier.rb +162 -0
  64. data/lib/familia/version.rb +1 -1
  65. data/lib/familia.rb +15 -2
  66. data/try/core/autoloader_try.rb +112 -0
  67. data/try/core/extensions_try.rb +38 -21
  68. data/try/core/familia_extended_try.rb +4 -3
  69. data/try/core/secure_identifier_try.rb +47 -18
  70. data/try/core/time_utils_try.rb +130 -0
  71. data/try/core/verifiable_identifier_try.rb +171 -0
  72. data/try/data_types/datatype_base_try.rb +3 -2
  73. data/try/features/autoloadable/autoloadable_try.rb +61 -0
  74. data/try/features/encrypted_fields/concealed_string_core_try.rb +8 -3
  75. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +59 -17
  76. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +36 -12
  77. data/try/features/{external_identifiers/external_identifiers_try.rb → external_identifier/external_identifier_try.rb} +25 -28
  78. data/try/features/feature_improvements_try.rb +127 -0
  79. data/try/features/{object_identifiers/object_identifiers_integration_try.rb → object_identifier/object_identifier_integration_try.rb} +28 -30
  80. data/try/features/{object_identifiers/object_identifiers_try.rb → object_identifier/object_identifier_try.rb} +13 -13
  81. data/try/features/real_feature_integration_try.rb +8 -7
  82. data/try/features/safe_dump/safe_dump_autoloading_try.rb +111 -0
  83. data/try/features/safe_dump/safe_dump_try.rb +8 -9
  84. data/try/helpers/test_helpers.rb +41 -17
  85. data/try/integration/cross_component_try.rb +3 -1
  86. metadata +61 -26
  87. data/CHANGELOG.md +0 -184
  88. data/changelog.d/fragments/.keep +0 -0
  89. data/changelog.d/template.md.j2 +0 -29
  90. data/lib/familia/core_ext.rb +0 -135
  91. data/lib/familia/features/external_identifiers/external_identifier_field_type.rb +0 -120
  92. data/lib/familia/features/external_identifiers.rb +0 -111
  93. data/lib/familia/features/object_identifiers/object_identifier_field_type.rb +0 -91
  94. data/lib/familia/features/object_identifiers.rb +0 -194
  95. data/setup.cfg +0 -12
@@ -0,0 +1,306 @@
1
+ # Migrating Guide: v2.0.0-pre12
2
+
3
+ This version introduces significant security improvements to Familia's identifier system, including verifiable identifiers with HMAC signatures, scoped identifier namespaces, and hardened external identifier derivation to prevent potential security vulnerabilities.
4
+
5
+ ## VerifiableIdentifier Feature
6
+
7
+ ### Overview
8
+
9
+ The new `Familia::VerifiableIdentifier` module allows applications to create and verify identifiers with embedded HMAC signatures. This enables stateless confirmation that an identifier was generated by your application, preventing forged IDs from malicious sources.
10
+
11
+ ### Basic Usage
12
+
13
+ ```ruby
14
+ class Customer < Familia::Horreum
15
+ feature :verifiable_identifier
16
+
17
+ # Required: Set the HMAC secret (do this once in your app initialization)
18
+ # Generate with: SecureRandom.hex(64)
19
+ ENV['VERIFIABLE_ID_HMAC_SECRET'] = 'your_64_character_hex_secret'
20
+ end
21
+
22
+ # Generate a verifiable identifier
23
+ customer = Customer.new
24
+ verifiable_id = customer.generate_verifiable_id
25
+ # => "cust_1234567890abcdef_a1b2c3d4e5f6789..."
26
+
27
+ # Verify the identifier later (stateless verification)
28
+ if Customer.verified_identifier?(verifiable_id)
29
+ # Identifier is valid and was generated by this application
30
+ original_id = Customer.extract_identifier(verifiable_id)
31
+ customer = Customer.new(original_id)
32
+ else
33
+ # Identifier is forged or corrupted
34
+ raise SecurityError, "Invalid identifier"
35
+ end
36
+ ```
37
+
38
+ ### Scoped VerifiableIdentifier
39
+
40
+ The new `scope` parameter enables cryptographically isolated identifier namespaces for multi-tenant, multi-domain, or multi-environment applications.
41
+
42
+ #### Before (Global Scope)
43
+ ```ruby
44
+ # All identifiers share the same cryptographic space
45
+ admin_id = admin.generate_verifiable_id
46
+ user_id = user.generate_verifiable_id
47
+
48
+ # Risk: Cross-contamination between different contexts
49
+ ```
50
+
51
+ #### After (Scoped Namespaces)
52
+ ```ruby
53
+ # Production environment
54
+ prod_customer_id = customer.generate_verifiable_id(scope: 'production')
55
+ prod_admin_id = admin.generate_verifiable_id(scope: 'production:admin')
56
+
57
+ # Development environment
58
+ dev_customer_id = customer.generate_verifiable_id(scope: 'development')
59
+
60
+ # Multi-tenant application
61
+ tenant_a_id = user.generate_verifiable_id(scope: "tenant:#{tenant_a.id}")
62
+ tenant_b_id = user.generate_verifiable_id(scope: "tenant:#{tenant_b.id}")
63
+
64
+ # Verification requires matching scope
65
+ Customer.verified_identifier?(prod_customer_id, scope: 'production') # => true
66
+ Customer.verified_identifier?(prod_customer_id, scope: 'development') # => false
67
+ ```
68
+
69
+ **Scope Benefits:**
70
+ - **Multi-tenant isolation**: Tenant A cannot forge identifiers for Tenant B
71
+ - **Environment separation**: Production IDs cannot be used in development
72
+ - **Role-based security**: Admin scopes separate from user scopes
73
+ - **Full backward compatibility**: Existing code without scopes continues to work
74
+
75
+ ### Key Management
76
+
77
+ #### Secure Secret Generation
78
+ ```ruby
79
+ # Generate a cryptographically secure HMAC secret
80
+ require 'securerandom'
81
+ secret = SecureRandom.hex(64) # 512-bit secret
82
+ puts "VERIFIABLE_ID_HMAC_SECRET=#{secret}"
83
+ ```
84
+
85
+ #### Environment Configuration
86
+ ```ruby
87
+ # config/application.rb or equivalent
88
+ # Set this BEFORE any VerifiableIdentifier usage
89
+ ENV['VERIFIABLE_ID_HMAC_SECRET'] = Rails.application.credentials.verifiable_id_secret
90
+
91
+ # Or configure programmatically
92
+ Familia::VerifiableIdentifier.hmac_secret = your_secret_string
93
+ ```
94
+
95
+ ## ObjectIdentifier Feature Improvements
96
+
97
+ ### Method Renaming
98
+
99
+ Method names have been updated for clarity and consistency:
100
+
101
+ #### Before
102
+ ```ruby
103
+ customer = Customer.new
104
+ objid = customer.generate_objid # Unclear what this generates
105
+ extid = Customer.generate_extid(objid) # Less secure class method
106
+ ```
107
+
108
+ #### After
109
+ ```ruby
110
+ customer = Customer.new
111
+ objid = customer.generate_object_identifier # Clear: generates object ID
112
+ extid = customer.derive_external_identifier # Clear: derives from objid, instance method
113
+ ```
114
+
115
+ **Migration:**
116
+ - Replace `generate_objid` → `generate_object_identifier`
117
+ - Replace `generate_external_identifier` → `derive_external_identifier`
118
+ - Remove usage of `generate_extid` (deprecated for security reasons)
119
+
120
+ ### Provenance Tracking
121
+
122
+ ObjectIdentifier now tracks which generator was used for each identifier:
123
+
124
+ ```ruby
125
+ class Customer < Familia::Horreum
126
+ feature :object_identifier
127
+
128
+ # Configure generator type
129
+ object_identifier_generator :uuid_v7 # or :uuid_v4, :hex, custom proc
130
+ end
131
+
132
+ customer = Customer.new
133
+ objid = customer.generate_object_identifier
134
+
135
+ # Provenance information available
136
+ puts customer.object_identifier_generator_type # => :uuid_v7
137
+ puts customer.objid_format # => :uuid (normalized format)
138
+ ```
139
+
140
+ **Benefits:**
141
+ - **Security auditing**: Know which generator created each identifier
142
+ - **Format normalization**: Eliminates ambiguity between UUID and hex formats
143
+ - **Migration support**: Track mixed generator usage during transitions
144
+
145
+ ## ExternalIdentifier Security Hardening
146
+
147
+ ### Provenance Validation
148
+
149
+ ExternalIdentifier now validates that objid values come from the ObjectIdentifier feature before deriving external identifiers.
150
+
151
+ #### Before (Potential Security Risk)
152
+ ```ruby
153
+ # Could derive external IDs from any string, including malicious input
154
+ extid = customer.derive_external_identifier("malicious_input")
155
+ ```
156
+
157
+ #### After (Hardened)
158
+ ```ruby
159
+ customer = Customer.new
160
+ customer.generate_object_identifier # Must generate objid first
161
+
162
+ # Only works with validated objid from ObjectIdentifier feature
163
+ extid = customer.derive_external_identifier # Secure: uses validated objid
164
+ ```
165
+
166
+ ### Improved Security Model
167
+
168
+ External identifiers are now derived using the internal objid as a seed for a new random value, rather than directly deriving from objid.
169
+
170
+ #### Before
171
+ ```ruby
172
+ # Direct derivation could leak information about objid
173
+ extid = hash(objid) # Information leakage risk
174
+ ```
175
+
176
+ #### After
177
+ ```ruby
178
+ # objid used as seed for new random value
179
+ extid = secure_hash(objid + additional_entropy) # No information leakage
180
+ ```
181
+
182
+ ### Error Handling Improvements
183
+
184
+ External identifier now raises clear errors for invalid usage:
185
+
186
+ ```ruby
187
+ class Customer < Familia::Horreum
188
+ feature :external_identifier # Missing: object_identifier dependency
189
+ end
190
+
191
+ customer = Customer.new
192
+ # Raises ExternalIdentifierError instead of returning nil
193
+ customer.derive_external_identifier
194
+ # => Familia::ExternalIdentifierError: Model does not have an objid field
195
+ ```
196
+
197
+ ## Migration Steps
198
+
199
+ ### 1. Update Method Names
200
+
201
+ Replace deprecated method names in your codebase:
202
+
203
+ ```bash
204
+ # Search and replace patterns:
205
+ grep -r "generate_objid" --include="*.rb" .
206
+ # Replace with: generate_object_identifier
207
+
208
+ grep -r "generate_external_identifier" --include="*.rb" .
209
+ # Replace with: derive_external_identifier
210
+
211
+ grep -r "generate_extid" --include="*.rb" .
212
+ # Remove usage - use derive_external_identifier instead
213
+ ```
214
+
215
+ ### 2. Add HMAC Secret for VerifiableIdentifier
216
+
217
+ If you plan to use VerifiableIdentifier:
218
+
219
+ ```ruby
220
+ # Generate secret
221
+ require 'securerandom'
222
+ secret = SecureRandom.hex(64)
223
+
224
+ # Add to your environment configuration
225
+ # .env, Rails credentials, or similar
226
+ VERIFIABLE_ID_HMAC_SECRET=your_generated_secret
227
+
228
+ # Verify configuration
229
+ puts ENV['VERIFIABLE_ID_HMAC_SECRET']&.length # Should be 128 characters
230
+ ```
231
+
232
+ ### 3. Update ExternalIdentifier Usage
233
+
234
+ Ensure proper dependency chain:
235
+
236
+ ```ruby
237
+ class YourModel < Familia::Horreum
238
+ # Required: ObjectIdentifier must come before ExternalIdentifier
239
+ feature :object_identifier
240
+ feature :external_identifier
241
+
242
+ # Configure generator if needed
243
+ object_identifier_generator :uuid_v7
244
+ end
245
+
246
+ # Usage pattern
247
+ model = YourModel.new
248
+ model.generate_object_identifier # Generate objid first
249
+ extid = model.derive_external_identifier # Then derive external ID
250
+ ```
251
+
252
+ ### 4. Review Security-Sensitive Code
253
+
254
+ Audit any code that processes identifiers from external sources:
255
+
256
+ ```ruby
257
+ # Before: Potentially unsafe
258
+ def process_identifier(external_id)
259
+ # Could process forged identifiers
260
+ model = Model.find_by_external_id(external_id)
261
+ end
262
+
263
+ # After: With verification
264
+ def process_identifier(verifiable_id)
265
+ # Verify identifier authenticity first
266
+ unless Model.verified_identifier?(verifiable_id)
267
+ raise SecurityError, "Invalid identifier"
268
+ end
269
+
270
+ original_id = Model.extract_identifier(verifiable_id)
271
+ model = Model.new(original_id)
272
+ end
273
+ ```
274
+
275
+ ## Breaking Changes
276
+
277
+ 1. **`generate_extid` removed** - Use instance-level `derive_external_identifier` instead
278
+ 2. **ExternalIdentifier validation** - Now raises `ExternalIdentifierError` instead of returning `nil` for models without objid
279
+ 3. **Method names changed** - `generate_objid` → `generate_object_identifier`, `generate_external_identifier` → `derive_external_identifier`
280
+
281
+ ## New Security Capabilities
282
+
283
+ 1. **Cryptographic identifier verification** - Prevent forged IDs with HMAC signatures
284
+ 2. **Scoped namespaces** - Isolate identifiers by tenant, environment, or role
285
+ 3. **Provenance tracking** - Know which generator created each identifier
286
+ 4. **Information leakage prevention** - External IDs no longer directly expose internal IDs
287
+ 5. **Input validation** - Clear error messages for invalid operations
288
+
289
+ ## Testing Your Migration
290
+
291
+ ```ruby
292
+ # Test ObjectIdentifier changes
293
+ model = YourModel.new
294
+ objid = model.generate_object_identifier
295
+ extid = model.derive_external_identifier
296
+ puts "Generator: #{model.object_identifier_generator_type}"
297
+
298
+ # Test VerifiableIdentifier (if using)
299
+ vid = model.generate_verifiable_id
300
+ puts "Verifiable: #{YourModel.verified_identifier?(vid)}"
301
+
302
+ # Test scoped identifiers (if using)
303
+ scoped_vid = model.generate_verifiable_id(scope: 'production')
304
+ puts "Scoped valid: #{YourModel.verified_identifier?(scoped_vid, scope: 'production')}"
305
+ puts "Wrong scope: #{YourModel.verified_identifier?(scoped_vid, scope: 'development')}"
306
+ ```
@@ -0,0 +1,329 @@
1
+ # Migrating Guide: v2.0.0-pre13
2
+
3
+ This version introduces significant improvements to Familia's feature system, making it easier to organize and use features across complex projects through automatic discovery and loading of feature-specific configuration files.
4
+
5
+ ## Feature-Specific Autoloading System
6
+
7
+ ### Overview
8
+
9
+ The new autoloading system allows features to automatically discover and load extension files from your project directories. When you include a feature in your model, Familia now searches for configuration files using conventional patterns, enabling clean separation between core model definitions and feature-specific configurations.
10
+
11
+ ### Basic Usage
12
+
13
+ #### Before (Manual Configuration)
14
+ ```ruby
15
+ # app/models/user.rb
16
+ class User < Familia::Horreum
17
+ field :name, :email, :password
18
+
19
+ feature :safe_dump
20
+ # All configuration had to be done in the same file
21
+ safe_dump_fields :name, :email # password excluded for security
22
+ end
23
+ ```
24
+
25
+ #### After (Automatic Discovery)
26
+ ```ruby
27
+ # app/models/user.rb - Clean model definition
28
+ class User < Familia::Horreum
29
+ field :name, :email, :password
30
+ feature :safe_dump # ← Triggers autoloading
31
+ end
32
+
33
+ # app/models/user/safe_dump_extensions.rb - Automatically loaded
34
+ class User
35
+ safe_dump_fields :name, :email # password excluded for security
36
+ end
37
+ ```
38
+
39
+ ### File Naming Conventions
40
+
41
+ The autoloading system follows these patterns for discovering extension files:
42
+
43
+ #### Pattern: `{model_name}/{feature_name}_*.rb`
44
+
45
+ **Example Structures:**
46
+ ```
47
+ app/models/
48
+ ├── user.rb # Main model
49
+ ├── user/
50
+ │ ├── safe_dump_extensions.rb # SafeDump configuration
51
+ │ ├── safe_dump_custom.rb # Additional SafeDump setup
52
+ │ └── relationships_config.rb # Relationships configuration
53
+ ├── product.rb # Another model
54
+ └── product/
55
+ ├── safe_dump_fields.rb # Product's SafeDump config
56
+ └── expiration_settings.rb # Expiration configuration
57
+ ```
58
+
59
+ #### Supported Patterns
60
+ - `safe_dump_extensions.rb`
61
+ - `safe_dump_*.rb` (any filename starting with the feature name)
62
+ - `expiration_config.rb`
63
+ - `relationships_setup.rb`
64
+
65
+ ### Advanced Configuration Examples
66
+
67
+ #### Complex SafeDump Setup
68
+ ```ruby
69
+ # app/models/customer.rb
70
+ class Customer < Familia::Horreum
71
+ field :first_name, :last_name, :email, :phone
72
+ field :credit_card_number, :ssn, :internal_notes
73
+
74
+ feature :safe_dump
75
+ end
76
+
77
+ # app/models/customer/safe_dump_configuration.rb
78
+ class Customer
79
+ # Define which fields are safe for API responses
80
+ safe_dump_fields :first_name, :last_name, :email
81
+
82
+ # Custom serialization for specific fields
83
+ def safe_dump_email
84
+ email&.downcase
85
+ end
86
+
87
+ # Computed fields for API
88
+ def safe_dump_full_name
89
+ "#{first_name} #{last_name}".strip
90
+ end
91
+ end
92
+ ```
93
+
94
+ #### Multi-Feature Organization
95
+ ```ruby
96
+ # app/models/session.rb
97
+ class Session < Familia::Horreum
98
+ field :user_id, :token, :ip_address, :user_agent
99
+
100
+ feature :safe_dump
101
+ feature :expiration
102
+ end
103
+
104
+ # app/models/session/safe_dump_api.rb
105
+ class Session
106
+ safe_dump_fields :user_id, :ip_address
107
+ # token excluded for security
108
+ end
109
+
110
+ # app/models/session/expiration_policy.rb
111
+ class Session
112
+ # Sessions expire after 24 hours
113
+ def self.default_ttl
114
+ 24 * 60 * 60
115
+ end
116
+
117
+ # Cascade expiration to related data
118
+ cascade_expiration_to :user_sessions
119
+ end
120
+ ```
121
+
122
+ ### Consolidated Autoloader Architecture
123
+
124
+ #### Familia::Autoloader
125
+
126
+ The new `Familia::Autoloader` class provides a shared utility for consistent file loading patterns across the framework:
127
+
128
+ ```ruby
129
+ # Internal usage example (you typically won't call this directly)
130
+ autoloader = Familia::Autoloader.new(
131
+ base_class: User,
132
+ feature_name: :safe_dump,
133
+ search_patterns: ['user/safe_dump_*.rb']
134
+ )
135
+
136
+ # Discovers and loads matching files
137
+ autoloader.discover_and_load_extensions
138
+ ```
139
+
140
+ #### Autoloading Strategies
141
+
142
+ The autoloader supports multiple discovery strategies:
143
+
144
+ 1. **Directory-based**: Search in conventional directories
145
+ 2. **Pattern-based**: Use glob patterns for flexible matching
146
+ 3. **Explicit paths**: Load specific files when found
147
+
148
+ ### How Autoloading Works
149
+
150
+ #### Discovery Process
151
+
152
+ 1. **Feature Activation**: When `feature :safe_dump` is called
153
+ 2. **Path Resolution**: Autoloader determines search paths based on model location
154
+ 3. **Pattern Matching**: Searches for files matching `{model_name}/{feature_name}_*.rb`
155
+ 4. **File Loading**: Loads discovered files in alphabetical order
156
+ 5. **Extension Application**: Feature-specific methods become available
157
+
158
+ #### Search Locations
159
+
160
+ The autoloader searches in these locations (in order):
161
+
162
+ ```ruby
163
+ # If your model is in app/models/user.rb, it searches:
164
+ [
165
+ 'app/models/user/', # Same directory as model
166
+ 'lib/user/', # Lib directory
167
+ 'config/models/user/', # Config directory
168
+ './user/' # Current directory
169
+ ]
170
+ ```
171
+
172
+ ### Migration Steps
173
+
174
+ #### 1. Reorganize Existing Models
175
+
176
+ Move feature-specific configuration to separate files:
177
+
178
+ ```bash
179
+ # Create directories for feature configurations
180
+ mkdir -p app/models/user
181
+ mkdir -p app/models/product
182
+ mkdir -p app/models/order
183
+
184
+ # Move configurations
185
+ # From app/models/user.rb, extract safe_dump configuration to:
186
+ # app/models/user/safe_dump_extensions.rb
187
+ ```
188
+
189
+ #### 2. Update Model Files
190
+
191
+ Clean up your main model files:
192
+
193
+ ```ruby
194
+ # Before: Everything in one file
195
+ class User < Familia::Horreum
196
+ field :name, :email, :password, :role
197
+
198
+ feature :safe_dump
199
+ safe_dump_fields :name, :email
200
+
201
+ feature :expiration
202
+ def self.default_ttl
203
+ 86400
204
+ end
205
+ end
206
+
207
+ # After: Clean separation
208
+ class User < Familia::Horreum
209
+ field :name, :email, :password, :role
210
+
211
+ feature :safe_dump # Configuration auto-loaded
212
+ feature :expiration # Configuration auto-loaded
213
+ end
214
+ ```
215
+
216
+ #### 3. Create Extension Files
217
+
218
+ Set up your feature-specific configurations:
219
+
220
+ ```ruby
221
+ # app/models/user/safe_dump_extensions.rb
222
+ class User
223
+ safe_dump_fields :name, :email
224
+ # password and role excluded for security
225
+ end
226
+
227
+ # app/models/user/expiration_config.rb
228
+ class User
229
+ def self.default_ttl
230
+ 86400 # 24 hours
231
+ end
232
+ end
233
+ ```
234
+
235
+ ### Benefits of the New System
236
+
237
+ #### Code Organization
238
+ - **Separation of Concerns**: Feature logic separated from core model definition
239
+ - **Maintainability**: Easier to find and modify feature-specific code
240
+ - **Readability**: Core models are cleaner and more focused
241
+
242
+ #### Team Development
243
+ - **Reduced Conflicts**: Multiple developers can work on different features without merge conflicts
244
+ - **Feature Ownership**: Clear boundaries for feature-specific code
245
+ - **Testing**: Easier to test features in isolation
246
+
247
+ #### Scalability
248
+ - **Large Models**: Complex models remain manageable
249
+ - **Feature Growth**: New features can be added without bloating main model files
250
+ - **Refactoring**: Easier to extract and reorganize feature code
251
+
252
+ ### Debugging Autoloading
253
+
254
+ #### Enable Debug Output
255
+
256
+ ```ruby
257
+ # In your application initialization
258
+ ENV['FAMILIA_DEBUG'] = '1'
259
+
260
+ # Or programmatically
261
+ Familia::Features::Autoloadable.debug = true
262
+ ```
263
+
264
+ #### Debug Output Example
265
+ ```
266
+ [Familia::Autoloader] Searching for User safe_dump extensions...
267
+ [Familia::Autoloader] Found: app/models/user/safe_dump_extensions.rb
268
+ [Familia::Autoloader] Loading: app/models/user/safe_dump_extensions.rb
269
+ [Familia::Autoloader] SafeDump extension loaded successfully for User
270
+ ```
271
+
272
+ #### Troubleshooting
273
+
274
+ **Common Issues:**
275
+
276
+ 1. **File Not Found**: Ensure file naming follows the `{feature_name}_*.rb` pattern
277
+ 2. **Load Order**: Files are loaded alphabetically; prefix with numbers if order matters
278
+ 3. **Class Scope**: Extension files should reopen the same class as your model
279
+
280
+ **Validation:**
281
+ ```ruby
282
+ # Check if autoloading worked
283
+ User.respond_to?(:safe_dump_field_names) # => true
284
+ User.safe_dump_field_names # => [:name, :email]
285
+ ```
286
+
287
+ ### Backward Compatibility
288
+
289
+ The autoloading system is fully backward compatible:
290
+
291
+ - **Existing Models**: Continue to work without changes
292
+ - **Manual Configuration**: Still supported alongside autoloading
293
+ - **Gradual Migration**: You can migrate models one at a time
294
+
295
+ ### Performance Considerations
296
+
297
+ - **Load Time**: Files are loaded once during feature activation
298
+ - **Memory Usage**: No additional memory overhead after loading
299
+ - **Caching**: Discovered files are cached to avoid repeated filesystem scans
300
+
301
+ ### Testing Your Migration
302
+
303
+ ```ruby
304
+ # Test that autoloading is working
305
+ class TestUser < Familia::Horreum
306
+ field :name, :email
307
+ feature :safe_dump
308
+ end
309
+
310
+ # Verify extension methods are available
311
+ puts TestUser.respond_to?(:safe_dump_field_names)
312
+ puts TestUser.safe_dump_field_names.inspect
313
+
314
+ # Test instance methods
315
+ user = TestUser.new(name: "John", email: "john@example.com")
316
+ puts user.safe_dump.inspect
317
+ ```
318
+
319
+ ## New Capabilities
320
+
321
+ 1. **Automatic Extension Discovery**: No manual require statements needed
322
+ 2. **Conventional File Organization**: Standard patterns for consistent project structure
323
+ 3. **Feature Isolation**: Clean separation between core models and feature configurations
324
+ 4. **Shared Autoloader Infrastructure**: Consistent loading behavior across all features
325
+ 5. **Debug Support**: Built-in debugging for troubleshooting autoloading issues
326
+
327
+ ## Breaking Changes
328
+
329
+ **None** - This release is fully backward compatible. Existing models and feature configurations continue to work without modification.