familia 2.0.0.pre5 → 2.0.0.pre6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +8 -5
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +4 -3
  5. data/docs/wiki/API-Reference.md +95 -18
  6. data/docs/wiki/Connection-Pooling-Guide.md +437 -0
  7. data/docs/wiki/Encrypted-Fields-Overview.md +40 -3
  8. data/docs/wiki/Expiration-Feature-Guide.md +596 -0
  9. data/docs/wiki/Feature-System-Guide.md +600 -0
  10. data/docs/wiki/Features-System-Developer-Guide.md +892 -0
  11. data/docs/wiki/Field-System-Guide.md +784 -0
  12. data/docs/wiki/Home.md +72 -15
  13. data/docs/wiki/Implementation-Guide.md +126 -33
  14. data/docs/wiki/Quantization-Feature-Guide.md +721 -0
  15. data/docs/wiki/RelatableObjects-Guide.md +563 -0
  16. data/docs/wiki/Security-Model.md +65 -25
  17. data/docs/wiki/Transient-Fields-Guide.md +280 -0
  18. data/lib/familia/base.rb +1 -1
  19. data/lib/familia/data_type/types/counter.rb +38 -0
  20. data/lib/familia/data_type/types/hashkey.rb +18 -0
  21. data/lib/familia/data_type/types/lock.rb +43 -0
  22. data/lib/familia/data_type/types/string.rb +9 -2
  23. data/lib/familia/data_type.rb +2 -2
  24. data/lib/familia/encryption/encrypted_data.rb +137 -0
  25. data/lib/familia/encryption/manager.rb +21 -4
  26. data/lib/familia/encryption/providers/aes_gcm_provider.rb +20 -0
  27. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +20 -0
  28. data/lib/familia/encryption.rb +1 -1
  29. data/lib/familia/errors.rb +17 -3
  30. data/lib/familia/features/encrypted_fields/concealed_string.rb +295 -0
  31. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +94 -26
  32. data/lib/familia/features/expiration.rb +1 -1
  33. data/lib/familia/features/quantization.rb +1 -1
  34. data/lib/familia/features/safe_dump.rb +1 -1
  35. data/lib/familia/features/transient_fields/redacted_string.rb +1 -1
  36. data/lib/familia/features/transient_fields.rb +1 -1
  37. data/lib/familia/field_type.rb +5 -2
  38. data/lib/familia/horreum/{connection.rb → core/connection.rb} +2 -8
  39. data/lib/familia/horreum/{database_commands.rb → core/database_commands.rb} +14 -3
  40. data/lib/familia/horreum/core/serialization.rb +535 -0
  41. data/lib/familia/horreum/{utils.rb → core/utils.rb} +0 -2
  42. data/lib/familia/horreum/core.rb +21 -0
  43. data/lib/familia/horreum/{settings.rb → shared/settings.rb} +0 -2
  44. data/lib/familia/horreum/{definition_methods.rb → subclass/definition.rb} +44 -28
  45. data/lib/familia/horreum/{management_methods.rb → subclass/management.rb} +9 -8
  46. data/lib/familia/horreum/{related_fields_management.rb → subclass/related_fields_management.rb} +15 -10
  47. data/lib/familia/horreum.rb +17 -17
  48. data/lib/familia/version.rb +1 -1
  49. data/lib/familia.rb +1 -1
  50. data/try/core/create_method_try.rb +240 -0
  51. data/try/core/database_consistency_try.rb +299 -0
  52. data/try/core/errors_try.rb +25 -4
  53. data/try/core/familia_try.rb +1 -1
  54. data/try/core/persistence_operations_try.rb +297 -0
  55. data/try/data_types/counter_try.rb +93 -0
  56. data/try/data_types/lock_try.rb +133 -0
  57. data/try/debugging/debug_aad_process.rb +82 -0
  58. data/try/debugging/debug_concealed_internal.rb +59 -0
  59. data/try/debugging/debug_concealed_reveal.rb +61 -0
  60. data/try/debugging/debug_context_aad.rb +68 -0
  61. data/try/debugging/debug_context_simple.rb +80 -0
  62. data/try/debugging/debug_cross_context.rb +62 -0
  63. data/try/debugging/debug_database_load.rb +64 -0
  64. data/try/debugging/debug_encrypted_json_check.rb +53 -0
  65. data/try/debugging/debug_encrypted_json_step_by_step.rb +62 -0
  66. data/try/debugging/debug_exists_lifecycle.rb +54 -0
  67. data/try/debugging/debug_field_decrypt.rb +74 -0
  68. data/try/debugging/debug_fresh_cross_context.rb +73 -0
  69. data/try/debugging/debug_load_path.rb +66 -0
  70. data/try/debugging/debug_method_definition.rb +46 -0
  71. data/try/debugging/debug_method_resolution.rb +41 -0
  72. data/try/debugging/debug_minimal.rb +24 -0
  73. data/try/debugging/debug_provider.rb +68 -0
  74. data/try/debugging/debug_secure_behavior.rb +73 -0
  75. data/try/debugging/debug_string_class.rb +46 -0
  76. data/try/debugging/debug_test.rb +46 -0
  77. data/try/debugging/debug_test_design.rb +80 -0
  78. data/try/encryption/encryption_core_try.rb +3 -3
  79. data/try/features/encrypted_fields_core_try.rb +19 -11
  80. data/try/features/encrypted_fields_integration_try.rb +66 -70
  81. data/try/features/encrypted_fields_no_cache_security_try.rb +22 -8
  82. data/try/features/encrypted_fields_security_try.rb +151 -144
  83. data/try/features/encryption_fields/aad_protection_try.rb +108 -23
  84. data/try/features/encryption_fields/concealed_string_core_try.rb +250 -0
  85. data/try/features/encryption_fields/context_isolation_try.rb +29 -8
  86. data/try/features/encryption_fields/error_conditions_try.rb +6 -6
  87. data/try/features/encryption_fields/fresh_key_derivation_try.rb +20 -14
  88. data/try/features/encryption_fields/fresh_key_try.rb +27 -22
  89. data/try/features/encryption_fields/key_rotation_try.rb +16 -10
  90. data/try/features/encryption_fields/nonce_uniqueness_try.rb +15 -13
  91. data/try/features/encryption_fields/secure_by_default_behavior_try.rb +310 -0
  92. data/try/features/encryption_fields/thread_safety_try.rb +6 -6
  93. data/try/features/encryption_fields/universal_serialization_safety_try.rb +174 -0
  94. data/try/features/feature_dependencies_try.rb +3 -3
  95. data/try/features/transient_fields_core_try.rb +1 -1
  96. data/try/features/transient_fields_integration_try.rb +1 -1
  97. data/try/helpers/test_helpers.rb +25 -0
  98. data/try/horreum/enhanced_conflict_handling_try.rb +1 -1
  99. data/try/horreum/initialization_try.rb +1 -1
  100. data/try/horreum/relations_try.rb +1 -1
  101. data/try/horreum/serialization_persistent_fields_try.rb +8 -8
  102. data/try/horreum/serialization_try.rb +39 -4
  103. data/try/models/customer_safe_dump_try.rb +1 -1
  104. data/try/models/customer_try.rb +1 -1
  105. metadata +51 -10
  106. data/TEST_COVERAGE.md +0 -40
  107. data/lib/familia/horreum/serialization.rb +0 -473
@@ -0,0 +1,600 @@
1
+ # Feature System Guide
2
+
3
+ ## Overview
4
+
5
+ Familia's feature system provides a modular architecture for extending Horreum classes with reusable functionality. Features are self-contained modules that can be mixed into classes with dependency management, conflict resolution, and automatic registration.
6
+
7
+ ## Core Concepts
8
+
9
+ ### Feature Architecture
10
+
11
+ The feature system consists of several key components:
12
+
13
+ 1. **Feature Modules**: Self-contained functionality modules
14
+ 2. **Registration System**: Automatic feature discovery and registration
15
+ 3. **Dependency Management**: Explicit feature dependencies
16
+ 4. **Conflict Resolution**: Handling method name conflicts
17
+ 5. **Category-based Fields**: Special field types for different purposes
18
+
19
+ ### Feature Lifecycle
20
+
21
+ ```ruby
22
+ # 1. Feature definition and registration (automatic)
23
+ class MyFeature
24
+ def self.included(base)
25
+ base.extend ClassMethods
26
+ base.prepend InstanceMethods
27
+ end
28
+
29
+ # Self-register with Familia
30
+ Familia::Base.add_feature self, :my_feature, depends_on: [:other_feature]
31
+ end
32
+
33
+ # 2. Feature activation in classes
34
+ class Customer < Familia::Horreum
35
+ feature :my_feature # Validates, checks dependencies, includes module
36
+ end
37
+
38
+ # 3. Runtime usage
39
+ customer = Customer.new
40
+ customer.my_feature_method # Available after feature inclusion
41
+ ```
42
+
43
+ ## Built-in Features
44
+
45
+ ### Core Features
46
+
47
+ #### Expiration
48
+ ```ruby
49
+ class Session < Familia::Horreum
50
+ feature :expiration
51
+ default_expiration 1.hour
52
+
53
+ field :user_id, :data
54
+ end
55
+
56
+ session = Session.new(user_id: 123)
57
+ session.update_expiration(30.minutes) # Custom TTL
58
+ session.ttl # Check remaining time
59
+ ```
60
+
61
+ #### SafeDump
62
+ ```ruby
63
+ class Customer < Familia::Horreum
64
+ feature :safe_dump
65
+
66
+ field :name, :email
67
+ field :ssn # Sensitive field
68
+ field :password # Sensitive field
69
+
70
+ # Whitelist fields for API responses
71
+ safe_dump_fields :name, :email # Excludes ssn, password
72
+ end
73
+
74
+ customer.safe_dump # => { name: "John", email: "john@example.com" }
75
+ customer.dump # => { name: "John", email: "john@example.com", ssn: "123-45-6789", password: "secret" }
76
+ ```
77
+
78
+ #### Encrypted Fields
79
+ ```ruby
80
+ class Vault < Familia::Horreum
81
+ feature :encrypted_fields
82
+
83
+ field :name # Regular field
84
+ encrypted_field :secret_key # Encrypted storage
85
+ encrypted_field :api_token # Another encrypted field
86
+ end
87
+
88
+ vault = Vault.new(secret_key: "super-secret")
89
+ vault.save
90
+ # secret_key is encrypted in Redis, decrypted on access
91
+ ```
92
+
93
+ #### Transient Fields
94
+ ```ruby
95
+ class ApiClient < Familia::Horreum
96
+ feature :transient_fields
97
+
98
+ field :endpoint # Persistent field
99
+ transient_field :auth_token # Runtime only, RedactedString
100
+ end
101
+
102
+ client = ApiClient.new(auth_token: ENV['API_TOKEN'])
103
+ client.auth_token.expose { |token| make_api_call(token) }
104
+ client.auth_token.clear! # Explicit cleanup
105
+ ```
106
+
107
+ #### Quantization
108
+ ```ruby
109
+ class Metric < Familia::Horreum
110
+ feature :quantization
111
+
112
+ field :value
113
+ quantized_field :hourly_stats, interval: 1.hour
114
+ quantized_field :daily_stats, interval: 1.day
115
+ end
116
+
117
+ # Automatically buckets data by time intervals
118
+ metric = Metric.new(value: 42)
119
+ metric.hourly_stats # Bucketed by hour
120
+ metric.daily_stats # Bucketed by day
121
+ ```
122
+
123
+ ## Creating Custom Features
124
+
125
+ ### Basic Feature Structure
126
+
127
+ ```ruby
128
+ module Familia
129
+ module Features
130
+ module MyCustomFeature
131
+ def self.included(base)
132
+ Familia.trace :LOADED, self, base, caller(1..1) if Familia.debug?
133
+ base.extend ClassMethods
134
+ base.prepend InstanceMethods # Use prepend for method interception
135
+ end
136
+
137
+ module ClassMethods
138
+ def custom_class_method
139
+ "Available on #{self} class"
140
+ end
141
+ end
142
+
143
+ module InstanceMethods
144
+ def custom_instance_method
145
+ "Available on #{self.class} instances"
146
+ end
147
+
148
+ # Intercept field access (if needed)
149
+ def field_value=(value)
150
+ # Custom processing before field assignment
151
+ processed_value = process_value(value)
152
+ super(processed_value) # Call original field setter
153
+ end
154
+ end
155
+
156
+ # Register the feature
157
+ Familia::Base.add_feature self, :my_custom_feature
158
+ end
159
+ end
160
+ end
161
+ ```
162
+
163
+ ### Advanced Feature with Dependencies
164
+
165
+ ```ruby
166
+ module Familia
167
+ module Features
168
+ module AdvancedAudit
169
+ def self.included(base)
170
+ base.extend ClassMethods
171
+ base.prepend InstanceMethods
172
+
173
+ # Initialize audit tracking
174
+ base.class_list :audit_log
175
+ base.class_hashkey :field_history
176
+ end
177
+
178
+ module ClassMethods
179
+ def enable_audit_for(*field_names)
180
+ @audited_fields ||= Set.new
181
+ @audited_fields.merge(field_names.map(&:to_sym))
182
+ end
183
+
184
+ def audited_fields
185
+ @audited_fields || Set.new
186
+ end
187
+ end
188
+
189
+ module InstanceMethods
190
+ def save
191
+ # Audit before saving
192
+ audit_changes if respond_to?(:audit_changes)
193
+ super
194
+ end
195
+
196
+ private
197
+
198
+ def audit_changes
199
+ self.class.audited_fields.each do |field|
200
+ if instance_variable_changed?(field)
201
+ record_field_change(field)
202
+ end
203
+ end
204
+ end
205
+
206
+ def record_field_change(field)
207
+ change_record = {
208
+ field: field,
209
+ old_value: instance_variable_was(field),
210
+ new_value: instance_variable_get("@#{field}"),
211
+ timestamp: Time.now.to_f
212
+ }
213
+
214
+ self.class.audit_log.append(change_record.to_json)
215
+ end
216
+ end
217
+
218
+ # Register with dependency on safe_dump
219
+ Familia::Base.add_feature self, :advanced_audit, depends_on: [:safe_dump]
220
+ end
221
+ end
222
+ end
223
+
224
+ # Usage
225
+ class Customer < Familia::Horreum
226
+ feature :safe_dump # Dependency satisfied first
227
+ feature :advanced_audit # Now can be loaded
228
+
229
+ enable_audit_for :name, :email, :status
230
+
231
+ field :name, :email, :status, :created_at
232
+ end
233
+ ```
234
+
235
+ ### Feature with Custom Field Types
236
+
237
+ ```ruby
238
+ module Familia
239
+ module Features
240
+ module TimestampTracking
241
+ def self.included(base)
242
+ base.extend ClassMethods
243
+
244
+ # Add timestamp fields automatically
245
+ base.timestamp_field :created_at
246
+ base.timestamp_field :updated_at
247
+ end
248
+
249
+ module ClassMethods
250
+ def timestamp_field(name, auto_update: true)
251
+ # Create custom field type for timestamps
252
+ require_relative '../field_types/timestamp_field_type'
253
+
254
+ field_type = TimestampFieldType.new(
255
+ name,
256
+ auto_update: auto_update,
257
+ format: :iso8601
258
+ )
259
+ register_field_type(field_type)
260
+ end
261
+ end
262
+
263
+ # Register feature
264
+ Familia::Base.add_feature self, :timestamp_tracking
265
+ end
266
+ end
267
+ end
268
+
269
+ # Custom field type (separate file)
270
+ class TimestampFieldType < Familia::FieldType
271
+ def initialize(name, auto_update: true, format: :unix, **options)
272
+ super(name, **options)
273
+ @auto_update = auto_update
274
+ @format = format
275
+ end
276
+
277
+ def serialize_value(record, value)
278
+ case @format
279
+ when :unix then value&.to_f
280
+ when :iso8601 then value&.iso8601
281
+ else value&.to_s
282
+ end
283
+ end
284
+
285
+ def deserialize_value(record, stored_value)
286
+ return nil if stored_value.nil?
287
+
288
+ case @format
289
+ when :unix then Time.at(stored_value.to_f)
290
+ when :iso8601 then Time.parse(stored_value)
291
+ else Time.parse(stored_value)
292
+ end
293
+ end
294
+ end
295
+ ```
296
+
297
+ ## Feature Dependencies
298
+
299
+ ### Declaring Dependencies
300
+
301
+ ```ruby
302
+ # Feature with dependencies
303
+ Familia::Base.add_feature MyFeature, :my_feature, depends_on: [:safe_dump, :expiration]
304
+
305
+ # Will verify dependencies when feature is activated:
306
+ class Model < Familia::Horreum
307
+ feature :safe_dump # Must be loaded first
308
+ feature :expiration # Must be loaded first
309
+ feature :my_feature # Dependencies satisfied
310
+ end
311
+ ```
312
+
313
+ ### Dependency Validation
314
+
315
+ ```ruby
316
+ # This will raise an error:
317
+ class BadModel < Familia::Horreum
318
+ feature :my_feature # Error: requires safe_dump, expiration
319
+ end
320
+ # => Familia::Problem: my_feature requires: safe_dump, expiration
321
+
322
+ # Correct order:
323
+ class GoodModel < Familia::Horreum
324
+ feature :safe_dump
325
+ feature :expiration
326
+ feature :my_feature # ✅ Dependencies satisfied
327
+ end
328
+ ```
329
+
330
+ ## Method Conflict Resolution
331
+
332
+ ### Conflict Detection
333
+
334
+ ```ruby
335
+ class Customer < Familia::Horreum
336
+ field :status # Defines status= and status methods
337
+
338
+ # This would conflict with field-generated method
339
+ def status
340
+ "custom implementation" # ⚠️ Potential conflict
341
+ end
342
+ end
343
+ ```
344
+
345
+ ### Conflict Resolution Strategies
346
+
347
+ ```ruby
348
+ # 1. Raise on conflict (default)
349
+ field :name, on_conflict: :raise # Raises if method exists
350
+
351
+ # 2. Skip definition if conflict
352
+ field :name, on_conflict: :skip # Skips if method exists
353
+
354
+ # 3. Warn but proceed
355
+ field :name, on_conflict: :warn # Warns but defines method
356
+
357
+ # 4. Ignore silently
358
+ field :name, on_conflict: :ignore # Proceeds without warning
359
+ ```
360
+
361
+ ### Using Prepend for Method Interception
362
+
363
+ ```ruby
364
+ module MyFeature
365
+ def self.included(base)
366
+ # Use prepend to intercept method calls
367
+ base.prepend InstanceMethods
368
+ end
369
+
370
+ module InstanceMethods
371
+ def save
372
+ # Pre-processing
373
+ validate_before_save
374
+
375
+ # Call original save method
376
+ result = super
377
+
378
+ # Post-processing
379
+ notify_after_save
380
+
381
+ result
382
+ end
383
+ end
384
+ end
385
+ ```
386
+
387
+ ## Feature Categories and Field Types
388
+
389
+ ### Field Categories
390
+
391
+ ```ruby
392
+ class Document < Familia::Horreum
393
+ field :title # Regular field
394
+ field :content, category: :encrypted # Encrypted field
395
+ field :api_key, category: :transient # Transient field
396
+ field :tags, category: :indexed # Custom category
397
+ end
398
+ ```
399
+
400
+ ### Category-based Processing
401
+
402
+ ```ruby
403
+ # Features can process fields by category
404
+ module IndexingFeature
405
+ def self.included(base)
406
+ base.extend ClassMethods
407
+
408
+ # Process all :indexed category fields
409
+ base.field_definitions.select { |f| f.category == :indexed }.each do |field|
410
+ create_index_for(field.name)
411
+ end
412
+ end
413
+ end
414
+ ```
415
+
416
+ ## Feature Discovery and Loading
417
+
418
+ ### Automatic Loading
419
+
420
+ Features are automatically loaded from the `lib/familia/features/` directory:
421
+
422
+ ```ruby
423
+ # lib/familia/features.rb automatically loads:
424
+ features_dir = File.join(__dir__, 'features')
425
+ Dir.glob(File.join(features_dir, '*.rb')).each do |feature_file|
426
+ require_relative feature_file
427
+ end
428
+ ```
429
+
430
+ ### Manual Feature Registration
431
+
432
+ ```ruby
433
+ # For features outside the standard directory
434
+ class ExternalFeature
435
+ # Feature implementation...
436
+ end
437
+
438
+ # Register manually
439
+ Familia::Base.add_feature ExternalFeature, :external_feature, depends_on: []
440
+ ```
441
+
442
+ ## Advanced Usage Patterns
443
+
444
+ ### Feature Composition
445
+
446
+ ```ruby
447
+ class AdvancedModel < Familia::Horreum
448
+ # Combine multiple features for rich functionality
449
+ feature :expiration # TTL support
450
+ feature :safe_dump # API-safe serialization
451
+ feature :encrypted_fields # Secure storage
452
+ feature :quantization # Time-based bucketing
453
+ feature :transient_fields # Runtime secrets
454
+
455
+ # Now has capabilities from all features
456
+ field :name
457
+ encrypted_field :api_key
458
+ transient_field :session_token
459
+ quantized_field :metrics, interval: 1.hour
460
+
461
+ default_expiration 24.hours
462
+ safe_dump_fields :name, :created_at
463
+ end
464
+ ```
465
+
466
+ ### Conditional Feature Loading
467
+
468
+ ```ruby
469
+ class ConfigurableModel < Familia::Horreum
470
+ # Load features based on configuration
471
+ if Rails.env.production?
472
+ feature :encrypted_fields
473
+ feature :advanced_audit
474
+ end
475
+
476
+ if defined?(Sidekiq)
477
+ feature :background_processing
478
+ end
479
+
480
+ feature :safe_dump # Always load
481
+ end
482
+ ```
483
+
484
+ ### Runtime Feature Checking
485
+
486
+ ```ruby
487
+ class Model < Familia::Horreum
488
+ feature :expiration
489
+
490
+ def has_ttl_support?
491
+ self.class.features_enabled.include?(:expiration)
492
+ end
493
+
494
+ def available_features
495
+ self.class.features_enabled
496
+ end
497
+ end
498
+
499
+ model = Model.new
500
+ model.available_features # => [:expiration]
501
+ model.has_ttl_support? # => true
502
+ ```
503
+
504
+ ## Testing Features
505
+
506
+ ### Feature Testing
507
+
508
+ ```ruby
509
+ RSpec.describe MyCustomFeature do
510
+ let(:test_class) do
511
+ Class.new(Familia::Horreum) do
512
+ feature :my_custom_feature
513
+ field :name
514
+ end
515
+ end
516
+
517
+ it "includes feature methods" do
518
+ instance = test_class.new
519
+ expect(instance).to respond_to(:custom_instance_method)
520
+ expect(test_class).to respond_to(:custom_class_method)
521
+ end
522
+
523
+ it "validates dependencies" do
524
+ expect {
525
+ Class.new(Familia::Horreum) do
526
+ feature :advanced_audit # Missing safe_dump dependency
527
+ end
528
+ }.to raise_error(Familia::Problem, /requires.*safe_dump/)
529
+ end
530
+ end
531
+ ```
532
+
533
+ ### Integration Testing
534
+
535
+ ```ruby
536
+ RSpec.describe "Feature Integration" do
537
+ it "combines features correctly" do
538
+ combined_class = Class.new(Familia::Horreum) do
539
+ feature :safe_dump
540
+ feature :expiration
541
+ feature :encrypted_fields
542
+
543
+ field :name
544
+ encrypted_field :secret
545
+ safe_dump_fields :name
546
+ default_expiration 1.hour
547
+ end
548
+
549
+ instance = combined_class.new(name: "test", secret: "hidden")
550
+
551
+ # All features work together
552
+ expect(instance.safe_dump).to eq(name: "test")
553
+ expect(instance.secret).to eq("hidden") # Decrypted
554
+ expect(instance.ttl).to be > 0 # Has expiration
555
+ end
556
+ end
557
+ ```
558
+
559
+ ## Best Practices
560
+
561
+ ### Feature Design
562
+
563
+ 1. **Single Responsibility**: Each feature should have one clear purpose
564
+ 2. **Minimal Dependencies**: Avoid complex dependency chains
565
+ 3. **Graceful Degradation**: Handle missing dependencies gracefully
566
+ 4. **Clear Naming**: Use descriptive feature and method names
567
+ 5. **Documentation**: Document feature capabilities and usage
568
+
569
+ ### Method Organization
570
+
571
+ ```ruby
572
+ module MyFeature
573
+ def self.included(base)
574
+ base.extend ClassMethods
575
+ base.prepend InstanceMethods # For interception
576
+ base.include HelperMethods # For additional utilities
577
+ end
578
+
579
+ module ClassMethods
580
+ # Class-level functionality
581
+ end
582
+
583
+ module InstanceMethods
584
+ # Instance method interception/override
585
+ end
586
+
587
+ module HelperMethods
588
+ # Additional utility methods
589
+ end
590
+ end
591
+ ```
592
+
593
+ ### Performance Considerations
594
+
595
+ 1. **Lazy Loading**: Initialize expensive resources only when needed
596
+ 2. **Caching**: Cache computed values appropriately
597
+ 3. **Method Interception**: Use prepend sparingly for performance-critical methods
598
+ 4. **Field Processing**: Minimize overhead in field serialization/deserialization
599
+
600
+ The feature system provides a powerful foundation for extending Familia with reusable, composable functionality while maintaining clean separation of concerns and explicit dependency management.