familia 2.0.0.pre14 → 2.0.0.pre16

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 (276) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/code-quality.yml +138 -0
  3. data/.github/workflows/code-smellage.yml +145 -0
  4. data/.github/workflows/docs.yml +31 -8
  5. data/.gitignore +1 -1
  6. data/.pre-commit-config.yaml +7 -1
  7. data/.reek.yml +98 -0
  8. data/.rubocop.yml +48 -10
  9. data/.talismanrc +9 -0
  10. data/.yardopts +18 -13
  11. data/CHANGELOG.rst +66 -6
  12. data/CLAUDE.md +1 -1
  13. data/Gemfile +6 -5
  14. data/Gemfile.lock +99 -23
  15. data/LICENSE.txt +1 -1
  16. data/README.md +285 -85
  17. data/changelog.d/README.md +2 -2
  18. data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
  19. data/docs/archive/FAMILIA_TECHNICAL.md +41 -41
  20. data/docs/archive/FAMILIA_UPDATE.md +3 -3
  21. data/docs/archive/README.md +3 -2
  22. data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
  23. data/docs/conf.py +29 -0
  24. data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
  25. data/docs/guides/feature-encrypted-fields.md +785 -0
  26. data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
  27. data/docs/guides/feature-external-identifiers.md +637 -0
  28. data/docs/guides/feature-object-identifiers.md +435 -0
  29. data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
  30. data/docs/guides/feature-relationships-methods.md +684 -0
  31. data/docs/guides/feature-relationships.md +200 -0
  32. data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
  33. data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
  34. data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
  35. data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
  36. data/docs/guides/index.md +176 -0
  37. data/docs/guides/{Security-Model.md → security-model.md} +1 -1
  38. data/docs/migrating/v2.0.0-pre.md +1 -1
  39. data/docs/migrating/v2.0.0-pre11.md +4 -4
  40. data/docs/migrating/v2.0.0-pre12.md +2 -2
  41. data/docs/migrating/v2.0.0-pre13.md +1 -1
  42. data/docs/migrating/v2.0.0-pre5.md +33 -12
  43. data/docs/migrating/v2.0.0-pre6.md +2 -2
  44. data/docs/migrating/v2.0.0-pre7.md +8 -8
  45. data/docs/overview.md +623 -19
  46. data/docs/reference/api-technical.md +1365 -0
  47. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +7 -0
  48. data/examples/autoloader/mega_customer/safe_dump_fields.rb +1 -1
  49. data/examples/autoloader/mega_customer.rb +3 -1
  50. data/examples/encrypted_fields.rb +378 -0
  51. data/examples/json_usage_patterns.rb +144 -0
  52. data/examples/relationships.rb +13 -13
  53. data/examples/safe_dump.rb +6 -6
  54. data/examples/single_connection_transaction_confusions.rb +379 -0
  55. data/lib/familia/base.rb +49 -10
  56. data/lib/familia/connection/handlers.rb +223 -0
  57. data/lib/familia/connection/individual_command_proxy.rb +64 -0
  58. data/lib/familia/connection/middleware.rb +75 -0
  59. data/lib/familia/connection/operation_core.rb +93 -0
  60. data/lib/familia/connection/operations.rb +277 -0
  61. data/lib/familia/connection/pipeline_core.rb +87 -0
  62. data/lib/familia/connection/transaction_core.rb +100 -0
  63. data/lib/familia/connection.rb +60 -186
  64. data/lib/familia/data_type/commands.rb +53 -51
  65. data/lib/familia/data_type/serialization.rb +108 -107
  66. data/lib/familia/data_type/types/counter.rb +1 -1
  67. data/lib/familia/data_type/types/hashkey.rb +13 -10
  68. data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
  69. data/lib/familia/data_type/types/lock.rb +3 -2
  70. data/lib/familia/data_type/types/sorted_set.rb +26 -15
  71. data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -5
  72. data/lib/familia/data_type/types/unsorted_set.rb +20 -27
  73. data/lib/familia/data_type.rb +75 -47
  74. data/lib/familia/distinguisher.rb +85 -0
  75. data/lib/familia/encryption/encrypted_data.rb +15 -24
  76. data/lib/familia/encryption/manager.rb +6 -4
  77. data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
  78. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
  79. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
  80. data/lib/familia/encryption/request_cache.rb +7 -7
  81. data/lib/familia/encryption.rb +2 -3
  82. data/lib/familia/errors.rb +9 -3
  83. data/lib/familia/{autoloader.rb → features/autoloader.rb} +49 -23
  84. data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
  85. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
  86. data/lib/familia/features/encrypted_fields.rb +68 -66
  87. data/lib/familia/features/expiration/extensions.rb +61 -0
  88. data/lib/familia/features/expiration.rb +35 -87
  89. data/lib/familia/features/external_identifier.rb +11 -12
  90. data/lib/familia/features/object_identifier.rb +58 -20
  91. data/lib/familia/features/quantization.rb +17 -22
  92. data/lib/familia/features/relationships/README.md +97 -0
  93. data/lib/familia/features/relationships/collection_operations.rb +104 -0
  94. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
  95. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +301 -0
  96. data/lib/familia/features/relationships/indexing.rb +176 -256
  97. data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
  98. data/lib/familia/features/relationships/participation/participant_methods.rb +160 -0
  99. data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
  100. data/lib/familia/features/relationships/participation.rb +656 -0
  101. data/lib/familia/features/relationships/participation_relationship.rb +31 -0
  102. data/lib/familia/features/relationships/score_encoding.rb +20 -20
  103. data/lib/familia/features/relationships.rb +69 -271
  104. data/lib/familia/features/safe_dump.rb +127 -132
  105. data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
  106. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
  107. data/lib/familia/features/transient_fields.rb +5 -5
  108. data/lib/familia/features.rb +21 -21
  109. data/lib/familia/field_type.rb +24 -4
  110. data/lib/familia/horreum/core/connection.rb +229 -26
  111. data/lib/familia/horreum/core/database_commands.rb +27 -17
  112. data/lib/familia/horreum/core/serialization.rb +40 -20
  113. data/lib/familia/horreum/core/utils.rb +2 -1
  114. data/lib/familia/horreum/shared/settings.rb +2 -1
  115. data/lib/familia/horreum/subclass/definition.rb +33 -45
  116. data/lib/familia/horreum/subclass/management.rb +72 -24
  117. data/lib/familia/horreum/subclass/related_fields_management.rb +82 -21
  118. data/lib/familia/horreum.rb +196 -114
  119. data/lib/familia/json_serializer.rb +0 -1
  120. data/lib/familia/logging.rb +11 -114
  121. data/lib/familia/refinements/dear_json.rb +122 -0
  122. data/lib/familia/refinements/logger_trace.rb +20 -17
  123. data/lib/familia/refinements/stylize_words.rb +65 -0
  124. data/lib/familia/refinements/time_literals.rb +60 -52
  125. data/lib/familia/refinements.rb +2 -1
  126. data/lib/familia/secure_identifier.rb +60 -28
  127. data/lib/familia/settings.rb +83 -7
  128. data/lib/familia/utils.rb +5 -87
  129. data/lib/familia/verifiable_identifier.rb +4 -4
  130. data/lib/familia/version.rb +1 -1
  131. data/lib/familia.rb +72 -15
  132. data/lib/middleware/database_middleware.rb +56 -14
  133. data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
  134. data/try/configuration/scenarios_try.rb +1 -1
  135. data/try/connection/fiber_context_preservation_try.rb +250 -0
  136. data/try/connection/handler_constraints_try.rb +59 -0
  137. data/try/connection/operation_mode_guards_try.rb +208 -0
  138. data/try/connection/pipeline_fallback_integration_try.rb +128 -0
  139. data/try/connection/responsibility_chain_tracking_try.rb +72 -0
  140. data/try/connection/transaction_fallback_integration_try.rb +288 -0
  141. data/try/connection/transaction_mode_permissive_try.rb +153 -0
  142. data/try/connection/transaction_mode_strict_try.rb +98 -0
  143. data/try/connection/transaction_mode_warn_try.rb +131 -0
  144. data/try/connection/transaction_modes_try.rb +249 -0
  145. data/try/core/autoloader_try.rb +129 -11
  146. data/try/core/connection_try.rb +7 -7
  147. data/try/core/conventional_inheritance_try.rb +130 -0
  148. data/try/core/create_method_try.rb +15 -23
  149. data/try/core/database_consistency_try.rb +10 -10
  150. data/try/core/errors_try.rb +8 -11
  151. data/try/core/familia_extended_try.rb +2 -2
  152. data/try/core/familia_members_methods_try.rb +76 -0
  153. data/try/core/isolated_dbclient_try.rb +165 -0
  154. data/try/core/middleware_try.rb +16 -16
  155. data/try/core/persistence_operations_try.rb +4 -4
  156. data/try/core/pools_try.rb +42 -26
  157. data/try/core/secure_identifier_try.rb +28 -24
  158. data/try/core/time_utils_try.rb +10 -10
  159. data/try/core/tools_try.rb +1 -1
  160. data/try/core/utils_try.rb +2 -2
  161. data/try/data_types/boolean_try.rb +4 -4
  162. data/try/data_types/datatype_base_try.rb +0 -2
  163. data/try/data_types/list_try.rb +10 -10
  164. data/try/data_types/sorted_set_try.rb +5 -5
  165. data/try/data_types/string_try.rb +12 -12
  166. data/try/data_types/unsortedset_try.rb +33 -0
  167. data/try/debugging/cache_behavior_tracer.rb +7 -7
  168. data/try/debugging/debug_aad_process.rb +1 -1
  169. data/try/debugging/debug_concealed_internal.rb +1 -1
  170. data/try/debugging/debug_cross_context.rb +1 -1
  171. data/try/debugging/debug_fresh_cross_context.rb +1 -1
  172. data/try/debugging/encryption_method_tracer.rb +10 -10
  173. data/try/edge_cases/hash_symbolization_try.rb +1 -1
  174. data/try/edge_cases/ttl_side_effects_try.rb +1 -1
  175. data/try/encryption/config_persistence_try.rb +2 -2
  176. data/try/encryption/encryption_core_try.rb +19 -19
  177. data/try/encryption/instance_variable_scope_try.rb +1 -1
  178. data/try/encryption/module_loading_try.rb +2 -2
  179. data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
  180. data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
  181. data/try/encryption/secure_memory_handling_try.rb +1 -1
  182. data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
  183. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
  184. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
  185. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
  186. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
  187. data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
  188. data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
  189. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
  190. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
  191. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
  192. data/try/features/external_identifier/external_identifier_try.rb +1 -1
  193. data/try/features/feature_dependencies_try.rb +3 -3
  194. data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
  195. data/try/features/object_identifier/object_identifier_try.rb +10 -0
  196. data/try/features/quantization/quantization_try.rb +1 -1
  197. data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
  198. data/try/features/relationships/indexing_try.rb +433 -0
  199. data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
  200. data/try/features/relationships/participation_commands_verification_try.rb +105 -0
  201. data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
  202. data/try/features/relationships/participation_reverse_index_try.rb +196 -0
  203. data/try/features/relationships/relationships_api_changes_try.rb +72 -71
  204. data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
  205. data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
  206. data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
  207. data/try/features/relationships/relationships_performance_try.rb +20 -20
  208. data/try/features/relationships/relationships_try.rb +27 -38
  209. data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
  210. data/try/features/transient_fields/refresh_reset_try.rb +1 -1
  211. data/try/features/transient_fields/simple_refresh_test.rb +1 -1
  212. data/try/helpers/test_cleanup.rb +86 -0
  213. data/try/helpers/test_helpers.rb +3 -3
  214. data/try/horreum/base_try.rb +3 -2
  215. data/try/horreum/commands_try.rb +1 -1
  216. data/try/horreum/destroy_related_fields_cleanup_try.rb +330 -0
  217. data/try/horreum/initialization_try.rb +11 -7
  218. data/try/horreum/relations_try.rb +21 -13
  219. data/try/horreum/serialization_try.rb +12 -11
  220. data/try/integration/cross_component_try.rb +3 -3
  221. data/try/memory/memory_basic_test.rb +1 -1
  222. data/try/memory/memory_docker_ruby_dump.sh +1 -1
  223. data/try/models/customer_safe_dump_try.rb +1 -1
  224. data/try/models/customer_try.rb +8 -10
  225. data/try/models/datatype_base_try.rb +3 -3
  226. data/try/models/familia_object_try.rb +9 -8
  227. data/try/performance/benchmarks_try.rb +2 -2
  228. data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
  229. data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
  230. data/try/prototypes/atomic_saves_v4.rb +1 -1
  231. data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
  232. data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  233. data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  234. data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
  235. data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
  236. data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
  237. data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
  238. data/try/prototypes/pooling/pool_siege.rb +11 -11
  239. data/try/prototypes/pooling/run_stress_tests.rb +7 -7
  240. data/try/refinements/dear_json_array_methods_try.rb +53 -0
  241. data/try/refinements/dear_json_hash_methods_try.rb +54 -0
  242. data/try/refinements/logger_trace_methods_try.rb +44 -0
  243. data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
  244. data/try/refinements/time_literals_string_methods_try.rb +80 -0
  245. metadata +77 -45
  246. data/.rubocop_todo.yml +0 -208
  247. data/docs/connection_pooling.md +0 -192
  248. data/docs/guides/Connection-Pooling-Guide.md +0 -437
  249. data/docs/guides/Encrypted-Fields-Overview.md +0 -101
  250. data/docs/guides/Feature-System-Autoloading.md +0 -228
  251. data/docs/guides/Home.md +0 -116
  252. data/docs/guides/Relationships-Guide.md +0 -737
  253. data/docs/guides/relationships-methods.md +0 -266
  254. data/docs/reference/auditing_database_commands.rb +0 -228
  255. data/examples/permissions.rb +0 -240
  256. data/lib/familia/features/autoloadable.rb +0 -113
  257. data/lib/familia/features/relationships/cascading.rb +0 -437
  258. data/lib/familia/features/relationships/membership.rb +0 -497
  259. data/lib/familia/features/relationships/permission_management.rb +0 -264
  260. data/lib/familia/features/relationships/querying.rb +0 -615
  261. data/lib/familia/features/relationships/redis_operations.rb +0 -274
  262. data/lib/familia/features/relationships/tracking.rb +0 -418
  263. data/lib/familia/refinements/snake_case.rb +0 -40
  264. data/lib/familia/validation/command_recorder.rb +0 -336
  265. data/lib/familia/validation/expectations.rb +0 -519
  266. data/lib/familia/validation/validation_helpers.rb +0 -443
  267. data/lib/familia/validation/validator.rb +0 -412
  268. data/lib/familia/validation.rb +0 -140
  269. data/try/data_types/set_try.rb +0 -33
  270. data/try/features/autoloadable/autoloadable_try.rb +0 -61
  271. data/try/features/relationships/categorical_permissions_try.rb +0 -515
  272. data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -111
  273. data/try/validation/atomic_operations_try.rb.disabled +0 -320
  274. data/try/validation/command_validation_try.rb.disabled +0 -207
  275. data/try/validation/performance_validation_try.rb.disabled +0 -324
  276. data/try/validation/real_world_scenarios_try.rb.disabled +0 -390
@@ -1,228 +0,0 @@
1
- # Feature System Autoloading
2
-
3
- ## Overview
4
-
5
- Familia's feature system includes an autoloading mechanism that automatically discovers and loads feature-specific extension files when features are included in your classes. This allows you to keep your main model files clean while organizing feature-specific configurations in separate files.
6
-
7
- ## The Problem It Solves
8
-
9
- When you include a feature like `safe_dump` in a Familia class:
10
-
11
- ```ruby
12
- class User < Familia::Horreum
13
- feature :safe_dump # This line should trigger autoloading
14
- end
15
- ```
16
-
17
- You want to be able to define the safe dump configuration in a separate file:
18
-
19
- ```ruby
20
- # user/safe_dump_extensions.rb
21
- class User
22
- safe_dump_fields :name, :email # Don't dump :password
23
- end
24
- ```
25
-
26
- But there's a **timing problem**: when should this extension file be loaded?
27
-
28
- ## Why Standard `included` Hook Doesn't Work
29
-
30
- The original approach tried to use the standard `included` hook:
31
-
32
- ```ruby
33
- module SafeDump
34
- def self.included(base)
35
- # Try to autoload here - BUT THIS IS TOO EARLY!
36
- autoload_files_for(base)
37
- end
38
- end
39
- ```
40
-
41
- **Problem**: This happens **during** the feature inclusion process, before the feature is fully set up. The class isn't in a stable state yet.
42
-
43
- ## The Solution: Post-Inclusion Hook
44
-
45
- The `post_inclusion_autoload` system works in **two phases**:
46
-
47
- ### Phase 1: Feature System Hook
48
-
49
- In `lib/familia/features.rb`, after including the feature module:
50
-
51
- ```ruby
52
- def feature(feature_name, **options)
53
- # ... setup code ...
54
-
55
- include feature_class # Include the feature module
56
-
57
- # NOW call the post-inclusion hook
58
- if feature_class.respond_to?(:post_inclusion_autoload)
59
- feature_class.post_inclusion_autoload(self, feature_name, options)
60
- end
61
- end
62
- ```
63
-
64
- ### Phase 2: Autoloadable Implementation
65
-
66
- The `post_inclusion_autoload` method in `lib/familia/features/autoloadable.rb`:
67
-
68
- 1. **Gets the source location** of the user's class file using Ruby's introspection:
69
- ```ruby
70
- location_info = Module.const_source_location(base.name)
71
- source_location = location_info&.first # e.g., "/path/to/models/user.rb"
72
- ```
73
-
74
- 2. **Calculates extension file paths** based on conventions:
75
- ```ruby
76
- base_dir = File.dirname(location_path) # "/path/to/models"
77
- model_name = base.name.snake_case # "user"
78
-
79
- # Look for files like:
80
- patterns = [
81
- "/path/to/models/user/safe_dump_*.rb",
82
- "/path/to/models/user/features/safe_dump_*.rb",
83
- "/path/to/models/features/safe_dump_*.rb"
84
- ]
85
- ```
86
-
87
- 3. **Loads any matching files** found in those locations
88
-
89
- ## Why This Timing Matters
90
-
91
- ```ruby
92
- class User < Familia::Horreum
93
- feature :safe_dump # ← Timing is critical here
94
- end
95
- ```
96
-
97
- **What happens in order:**
98
-
99
- 1. `feature :safe_dump` is called
100
- 2. Feature system includes `Familia::Features::SafeDump` module
101
- 3. **Feature is now fully included and stable**
102
- 4. `post_inclusion_autoload` is called
103
- 5. Extension files are discovered and loaded
104
- 6. `safe_dump_fields :name, :email` executes in the extension file
105
-
106
- ## File Naming Conventions
107
-
108
- The autoloading system looks for files matching these patterns (in order of precedence):
109
-
110
- 1. `{model_directory}/{model_name}/{feature_name}_*.rb`
111
- 2. `{model_directory}/{model_name}/features/{feature_name}_*.rb`
112
- 3. `{model_directory}/features/{feature_name}_*.rb`
113
-
114
- ### Examples
115
-
116
- For a `User` class defined in `app/models/user.rb` with `feature :safe_dump`:
117
-
118
- ```
119
- app/models/user/safe_dump_extensions.rb # ← Most specific
120
- app/models/user/safe_dump_config.rb # ← Also matches pattern
121
- app/models/user/features/safe_dump_*.rb # ← Feature subdirectory
122
- app/models/features/safe_dump_*.rb # ← Shared feature configs
123
- ```
124
-
125
- ## Complete Example
126
-
127
- ### Main Model File
128
-
129
- ```ruby
130
- # app/models/user.rb
131
- class User < Familia::Horreum
132
- field :name
133
- field :email
134
- field :password
135
- field :created_at
136
-
137
- feature :safe_dump # ← Triggers autoloading
138
- feature :expiration
139
- end
140
- ```
141
-
142
- ### Safe Dump Extensions
143
-
144
- ```ruby
145
- # app/models/user/safe_dump_extensions.rb
146
- class User
147
- # Configure which fields are safe to dump in API responses
148
- safe_dump_fields :name, :email, :created_at
149
- # Note: :password is intentionally excluded for security
150
-
151
- def safe_dump_display_name
152
- "#{name} (#{email})"
153
- end
154
- end
155
- ```
156
-
157
- ### Expiration Extensions
158
-
159
- ```ruby
160
- # app/models/user/expiration_config.rb
161
- class User
162
- # Set default TTL for user objects
163
- expires_in 30.days
164
-
165
- # Custom expiration logic
166
- def should_expire?
167
- !active? && last_login_at < 90.days.ago
168
- end
169
- end
170
- ```
171
-
172
- ### Result
173
-
174
- After loading, the `User` class has:
175
- - `User.safe_dump_field_names` returns `[:name, :email, :created_at]`
176
- - `User.ttl` returns the configured expiration
177
- - All extension methods are available on instances
178
-
179
- ## Key Benefits
180
-
181
- 1. **Separation of Concerns**: Main model file focuses on core definition, extension files handle feature-specific configuration
182
-
183
- 2. **Convention Over Configuration**: No manual requires, just follow naming conventions
184
-
185
- 3. **Safe Timing**: Extension files load after the feature is fully set up
186
-
187
- 4. **Thread Safe**: No shared state between classes
188
-
189
- 5. **Discoverable**: Clear file organization makes extensions easy to find
190
-
191
- ## Why It's Better Than Alternatives
192
-
193
- - **Manual requires**: Error-prone, verbose, easy to forget
194
- - **Configuration blocks**: Clutters the main model file
195
- - **Included hook**: Wrong timing, class not stable yet
196
- - **Class_eval strings**: Complex, hard to debug and maintain
197
-
198
- The `post_inclusion_autoload` system provides a clean, automatic, and safe way to extend feature behavior without polluting the main class definitions.
199
-
200
- ## Implementation Details
201
-
202
- ### Autoloadable Module
203
-
204
- Features that support autoloading include the `Familia::Features::Autoloadable` module:
205
-
206
- ```ruby
207
- module Familia::Features::SafeDump
208
- include Familia::Features::Autoloadable # ← Enables autoloading
209
-
210
- # Feature implementation...
211
- end
212
- ```
213
-
214
- ### Anonymous Class Handling
215
-
216
- The system gracefully handles edge cases:
217
-
218
- - **Anonymous classes**: Classes without names (e.g., `Class.new`) are skipped
219
- - **Eval contexts**: Classes defined in `eval` or irb are skipped
220
- - **Missing files**: No errors if extension files don't exist
221
-
222
- ### Error Handling
223
-
224
- - Missing extension files are silently ignored
225
- - Syntax errors in extension files propagate normally
226
- - `NameError` during constant resolution is caught and logged
227
-
228
- This robust error handling ensures the autoloading system never breaks your application, even with unusual class definitions or missing files.
data/docs/guides/Home.md DELETED
@@ -1,116 +0,0 @@
1
- # Familia v2.0 Documentation
2
-
3
- Welcome to the comprehensive documentation for Familia v2.0. This wiki covers all major features including security, connection management, architecture, and object relationships.
4
-
5
- ## 📚 Documentation Structure
6
-
7
- ### 🔐 Security & Data Protection
8
-
9
- 1. **[Encrypted Fields Overview](Encrypted-Fields-Overview.md)** - Persistent encrypted storage with modular providers
10
- 2. **[Transient Fields Guide](Transient-Fields-Guide.md)** - Non-persistent secure data handling with RedactedString
11
- 3. **[Security Model](Security-Model.md)** - Cryptographic design and Ruby memory limitations
12
-
13
- ### 🏗️ Architecture & System Design
14
-
15
- 4. **[Feature System Guide](Feature-System-Guide.md)** - Modular architecture with dependencies and conflict resolution _(new!)_
16
- 5. **[Connection Pooling Guide](Connection-Pooling-Guide.md)** - Provider pattern for efficient Redis/Valkey pooling _(new!)_
17
- 6. **[Relationships Guide](Relationships-Guide.md)** - Object relationships and membership system _(new!)_
18
-
19
- ### 🛠️ Implementation & Usage
20
-
21
- 7. **[Implementation Guide](Implementation-Guide.md)** - Configuration, providers, and advanced usage
22
- 8. **[API Reference](API-Reference.md)** - Complete class and method documentation
23
-
24
- ### 🚀 Operations (As Needed)
25
-
26
- 9. **[Migrating Guide](Migrating-Guide.md)** - Upgrading existing fields _(coming soon)_
27
- 10. **[Key Management](Key-Management.md)** - Rotation and best practices _(coming soon)_
28
-
29
- ## 🚀 Quick Start Examples
30
-
31
- ### Encrypted Fields (Persistent)
32
- ```ruby
33
- class User < Familia::Horreum
34
- feature :encrypted_fields
35
- encrypted_field :secret_recipe
36
- end
37
-
38
- # Configure encryption
39
- Familia.configure do |config|
40
- config.encryption_keys = { v1: ENV['FAMILIA_ENCRYPTION_KEY'] }
41
- config.current_key_version = :v1
42
- end
43
-
44
- user = User.new(secret_recipe: "donna's cookies")
45
- user.save
46
- user.secret_recipe # => "donna's cookies" (automatically decrypted)
47
- ```
48
-
49
- ### Feature System (Modular)
50
- ```ruby
51
- class Customer < Familia::Horreum
52
- feature :safe_dump # API-safe serialization
53
- feature :expiration # TTL support
54
- feature :encrypted_fields # Secure storage
55
-
56
- field :name, :email
57
- encrypted_field :api_key
58
- default_expiration 24.hours
59
- safe_dump_fields :name, :email
60
- end
61
- ```
62
-
63
- ### Connection Pooling (Performance)
64
- ```ruby
65
- # Configure connection provider for multi-database pooling
66
- Familia.connection_provider = lambda do |uri|
67
- parsed = URI.parse(uri)
68
- pool_key = "#{parsed.host}:#{parsed.port}/#{parsed.db || 0}"
69
-
70
- @pools[pool_key] ||= ConnectionPool.new(size: 10) do
71
- Redis.new(host: parsed.host, port: parsed.port, db: parsed.db || 0)
72
- end
73
-
74
- @pools[pool_key].with { |conn| conn }
75
- end
76
- ```
77
-
78
- ### Object Relationships
79
- ```ruby
80
- class Customer < Familia::Horreum
81
- feature :relationships
82
- identifier_field :custid
83
- field :custid, :name, :email
84
-
85
- # Customer collections
86
- set :domains
87
- end
88
-
89
- class Domain < Familia::Horreum
90
- feature :relationships
91
- identifier_field :domain_id
92
- field :domain_id, :name, :dns_zone
93
-
94
- # Declare membership in customer collections
95
- member_of Customer, :domains, type: :set
96
- end
97
-
98
- # Create objects and establish relationships
99
- customer = Customer.new(custid: "cust123", name: "Acme Corp")
100
- domain = Domain.new(domain_id: "dom456", name: "acme.com")
101
-
102
- # Establish bidirectional relationship
103
- domain.add_to_customer_domains(customer.custid)
104
- customer.domains.add(domain.identifier)
105
-
106
- # Query relationships
107
- domain.in_customer_domains?(customer.custid) # => true
108
- customer.domains.member?(domain.identifier) # => true
109
- ```
110
-
111
-
112
- ## Related Resources
113
-
114
- - [Familia README](https://github.com/delano/familia) - Main project documentation
115
- - [Issue #57](https://github.com/delano/familia/issues/57) - Original feature proposal
116
- - [Issue #58](https://github.com/delano/familia/issues/58) - Wiki documentation tracking