familia 2.0.0.pre7 → 2.0.0.pre10
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +13 -0
- data/.github/workflows/docs.yml +1 -1
- data/.gitignore +9 -9
- data/.rubocop.yml +19 -0
- data/.yardopts +22 -1
- data/CHANGELOG.md +184 -0
- data/CLAUDE.md +8 -5
- data/Gemfile +1 -1
- data/Gemfile.lock +3 -3
- data/README.md +97 -2
- data/changelog.d/README.md +66 -0
- data/changelog.d/fragments/.keep +0 -0
- data/changelog.d/template.md.j2 +29 -0
- data/docs/archive/.gitignore +2 -0
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +210 -0
- data/docs/archive/FAMILIA_TECHNICAL.md +823 -0
- data/docs/archive/FAMILIA_UPDATE.md +226 -0
- data/docs/archive/README.md +67 -0
- data/docs/guides/.gitignore +2 -0
- data/docs/{wiki → guides}/Feature-System-Guide.md +0 -15
- data/docs/{wiki → guides}/Relationships-Guide.md +103 -50
- data/docs/guides/relationships-methods.md +266 -0
- data/examples/relationships_basic.rb +90 -157
- data/familia.gemspec +4 -4
- data/lib/familia/connection.rb +4 -21
- data/lib/familia/features/external_identifiers/external_identifier_field_type.rb +120 -0
- data/lib/familia/features/external_identifiers.rb +111 -0
- data/lib/familia/features/object_identifiers/object_identifier_field_type.rb +91 -0
- data/lib/familia/features/object_identifiers.rb +194 -0
- data/lib/familia/features/relationships/cascading.rb +0 -1
- data/lib/familia/features/relationships/indexing.rb +160 -176
- data/lib/familia/features/relationships/membership.rb +16 -22
- data/lib/familia/features/relationships/querying.rb +7 -12
- data/lib/familia/features/relationships/score_encoding.rb +1 -3
- data/lib/familia/features/relationships/tracking.rb +61 -22
- data/lib/familia/features/relationships.rb +15 -8
- data/lib/familia/features/transient_fields.rb +8 -10
- data/lib/familia/features.rb +16 -13
- data/lib/familia/horreum/core/serialization.rb +2 -5
- data/lib/familia/horreum/subclass/definition.rb +36 -0
- data/lib/familia/horreum.rb +15 -24
- data/lib/familia/version.rb +1 -3
- data/setup.cfg +12 -0
- data/try/core/errors_try.rb +1 -1
- data/try/features/{encrypted_fields_core_try.rb → encrypted_fields/encrypted_fields_core_try.rb} +1 -1
- data/try/features/{encrypted_fields_integration_try.rb → encrypted_fields/encrypted_fields_integration_try.rb} +1 -1
- data/try/features/{encrypted_fields_no_cache_security_try.rb → encrypted_fields/encrypted_fields_no_cache_security_try.rb} +1 -1
- data/try/features/{encrypted_fields_security_try.rb → encrypted_fields/encrypted_fields_security_try.rb} +1 -1
- data/try/features/{expiration_try.rb → expiration/expiration_try.rb} +1 -1
- data/try/features/external_identifiers/external_identifiers_try.rb +203 -0
- data/try/features/object_identifiers/object_identifiers_integration_try.rb +289 -0
- data/try/features/object_identifiers/object_identifiers_try.rb +191 -0
- data/try/features/{quantization_try.rb → quantization/quantization_try.rb} +1 -1
- data/try/features/{categorical_permissions_try.rb → relationships/categorical_permissions_try.rb} +1 -1
- data/try/features/relationships/relationships_api_changes_try.rb +339 -0
- data/try/features/{relationships_edge_cases_try.rb → relationships/relationships_edge_cases_try.rb} +1 -1
- data/try/features/{relationships_performance_minimal_try.rb → relationships/relationships_performance_minimal_try.rb} +1 -1
- data/try/features/{relationships_performance_simple_try.rb → relationships/relationships_performance_simple_try.rb} +1 -1
- data/try/features/{relationships_performance_try.rb → relationships/relationships_performance_try.rb} +1 -1
- data/try/features/{relationships_performance_working_try.rb → relationships/relationships_performance_working_try.rb} +1 -1
- data/try/features/{relationships_try.rb → relationships/relationships_try.rb} +7 -6
- data/try/features/{safe_dump_advanced_try.rb → safe_dump/safe_dump_advanced_try.rb} +1 -1
- data/try/features/{safe_dump_try.rb → safe_dump/safe_dump_try.rb} +1 -1
- data/try/features/{transient_fields_core_try.rb → transient_fields/transient_fields_core_try.rb} +1 -1
- data/try/features/{transient_fields_integration_try.rb → transient_fields/transient_fields_integration_try.rb} +1 -1
- metadata +80 -60
- /data/docs/{wiki → guides}/API-Reference.md +0 -0
- /data/docs/{wiki → guides}/Connection-Pooling-Guide.md +0 -0
- /data/docs/{wiki → guides}/Encrypted-Fields-Overview.md +0 -0
- /data/docs/{wiki → guides}/Expiration-Feature-Guide.md +0 -0
- /data/docs/{wiki → guides}/Features-System-Developer-Guide.md +0 -0
- /data/docs/{wiki → guides}/Field-System-Guide.md +0 -0
- /data/docs/{wiki → guides}/Home.md +0 -0
- /data/docs/{wiki → guides}/Implementation-Guide.md +0 -0
- /data/docs/{wiki → guides}/Quantization-Feature-Guide.md +0 -0
- /data/docs/{wiki → guides}/Security-Model.md +0 -0
- /data/docs/{wiki → guides}/Transient-Fields-Guide.md +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/aad_protection_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/concealed_string_core_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/context_isolation_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/error_conditions_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/fresh_key_derivation_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/fresh_key_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/key_rotation_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/memory_security_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/missing_current_key_version_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/nonce_uniqueness_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/secure_by_default_behavior_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/thread_safety_try.rb +0 -0
- /data/try/features/{encryption_fields → encrypted_fields}/universal_serialization_safety_try.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f09bb44b39f033bc38faaff02dd33c645ecd6a98bee533a756707daeb47e00c
|
4
|
+
data.tar.gz: 77afd574073258009058ed9f638151b1ca26ba65d06b49f841ad46b52e50a82a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9bf8c181236218f04e7fff9902b63521d316265792a416525ee5da671789ddd636c372d0481b926b9b65b3116680bac698ebef6d37fd3d0117c9235053b98aa
|
7
|
+
data.tar.gz: d046f73ca2f6d46833e4bdb0f2a59c6c400b807f5e44f92657a470bd50c09ffae56debfd991f6513898a603ce44e761047d1e4449f8526d3d2a5ac333ebb8e72
|
data/.github/workflows/ci.yml
CHANGED
@@ -66,3 +66,16 @@ jobs:
|
|
66
66
|
|
67
67
|
- name: Run the tryouts
|
68
68
|
run: bundle exec try -vf
|
69
|
+
|
70
|
+
- name: Validate examples
|
71
|
+
continue-on-error: true
|
72
|
+
run: |
|
73
|
+
echo "=== Validating example syntax ==="
|
74
|
+
find examples/ -name "*.rb" -exec ruby -c {} \;
|
75
|
+
|
76
|
+
echo "=== Running executable examples ==="
|
77
|
+
cd examples
|
78
|
+
for example in *.rb; do
|
79
|
+
echo "Running $example..."
|
80
|
+
ruby "$example" || echo "Warning: $example failed to run"
|
81
|
+
done
|
data/.github/workflows/docs.yml
CHANGED
@@ -41,7 +41,7 @@ jobs:
|
|
41
41
|
|
42
42
|
- name: Build YARD documentation
|
43
43
|
run: |
|
44
|
-
bundle exec yard doc --output-dir ./doc
|
44
|
+
bundle exec yard doc --output-dir ./doc
|
45
45
|
# Ensure doc directory exists and create .nojekyll file to prevent GitHub Pages Jekyll processing
|
46
46
|
mkdir -p ./doc
|
47
47
|
touch ./doc/.nojekyll
|
data/.gitignore
CHANGED
@@ -12,20 +12,20 @@
|
|
12
12
|
.*.json
|
13
13
|
*.env
|
14
14
|
*.log
|
15
|
-
*.md
|
16
|
-
.mcp.json
|
17
|
-
!README.md
|
18
|
-
!CLAUDE.md
|
19
15
|
*.txt
|
20
|
-
!LICENSE.txt
|
21
16
|
.ruby-version
|
22
17
|
appendonlydir
|
23
|
-
etc/config
|
24
18
|
log
|
25
19
|
tmp
|
26
20
|
vendor
|
27
21
|
*.gem
|
28
22
|
doc/
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
|
24
|
+
# Ignore WIP or temp dev files with uppercase names
|
25
|
+
[A-Z]*.md
|
26
|
+
|
27
|
+
# Exclusions
|
28
|
+
!README.md
|
29
|
+
!CHANGELOG.md
|
30
|
+
!CLAUDE.md
|
31
|
+
!LICENSE.txt
|
data/.rubocop.yml
CHANGED
@@ -34,6 +34,25 @@ AllCops:
|
|
34
34
|
- "try/*.rb"
|
35
35
|
- "vendor/**/*"
|
36
36
|
|
37
|
+
#
|
38
|
+
# Trailing commas
|
39
|
+
Style/TrailingCommaInHashLiteral:
|
40
|
+
EnforcedStyleForMultiline: comma
|
41
|
+
Enabled: true
|
42
|
+
|
43
|
+
Style/TrailingCommaInArrayLiteral:
|
44
|
+
EnforcedStyleForMultiline: comma
|
45
|
+
Enabled: true
|
46
|
+
|
47
|
+
Style/TrailingCommaInArguments:
|
48
|
+
Enabled: true
|
49
|
+
|
50
|
+
Style/TrailingCommaInBlockArgs:
|
51
|
+
Enabled: true
|
52
|
+
|
53
|
+
Lint/TrailingCommaInAttributeDeclaration:
|
54
|
+
Enabled: true
|
55
|
+
|
37
56
|
Gemspec/DeprecatedAttributeAssignment:
|
38
57
|
Enabled: true
|
39
58
|
|
data/.yardopts
CHANGED
@@ -4,6 +4,27 @@
|
|
4
4
|
--markup-provider kramdown
|
5
5
|
--protected
|
6
6
|
--no-private
|
7
|
+
--embed-mixin ClassMethods
|
8
|
+
--embed-mixin Features
|
9
|
+
--tag feature:"Feature"
|
10
|
+
--tag since:"Since Version"
|
11
|
+
--tag example:"Example Usage"
|
12
|
+
--tag note:"Note"
|
13
|
+
--tag warning:"Warning"
|
14
|
+
--tag deprecated:"Deprecated"
|
15
|
+
--hide-tag nodoc
|
16
|
+
--exclude lib/familia/version.rb
|
7
17
|
lib/**/*.rb
|
8
18
|
-
|
9
|
-
|
19
|
+
CHANGELOG.md
|
20
|
+
LICENSE.txt
|
21
|
+
docs/guides/Home.md
|
22
|
+
docs/guides/Getting-Started.md
|
23
|
+
docs/guides/Feature-System-Guide.md
|
24
|
+
docs/guides/Relationships-Guide.md
|
25
|
+
docs/guides/relationships-methods.md
|
26
|
+
docs/guides/Encrypted-Fields-Overview.md
|
27
|
+
docs/guides/Connection-Pooling-Guide.md
|
28
|
+
docs/reference/api-technical.md
|
29
|
+
docs/migration/*.md
|
30
|
+
examples/*.rb
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,184 @@
|
|
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-pre10'></a>
|
11
|
+
## [2.0.0-pre10] - 2025-09-02 18:07:56.439890
|
12
|
+
|
13
|
+
### Added
|
14
|
+
|
15
|
+
- 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.
|
16
|
+
|
17
|
+
- Automatic indexing and class-level tracking on `save()` operations, eliminating the need for manual index updates.
|
18
|
+
- Enhanced collection syntax supports the Ruby-idiomatic `<<` operator for more natural relationship management.
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
|
22
|
+
- 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.
|
23
|
+
|
24
|
+
- **BREAKING**: Refactored Familia Relationships API to remove "global" terminology and simplify method generation. (Closes #86)
|
25
|
+
- 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.
|
26
|
+
- Simplified method generation by removing complex global vs parent conditionals.
|
27
|
+
- All indexes are now stored at the class level for consistency.
|
28
|
+
|
29
|
+
### Fixed
|
30
|
+
|
31
|
+
- 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.
|
32
|
+
|
33
|
+
- Refactored connection handling to properly cache and reuse Redis connections. This eliminates repetitive "Overriding existing connection" warnings and improves performance.
|
34
|
+
|
35
|
+
- Method generation now works consistently for both `class_indexed_by` and `indexed_by` with a `parent:`.
|
36
|
+
- Resolved metadata storage issues for dynamically created classes.
|
37
|
+
- Improved error handling for nil class names in tracking relationships.
|
38
|
+
|
39
|
+
### Documentation
|
40
|
+
|
41
|
+
- 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.
|
42
|
+
|
43
|
+
### AI Assistance
|
44
|
+
|
45
|
+
- This refactoring was implemented with Claude Code assistance, including comprehensive test updates and API modernization.
|
46
|
+
|
47
|
+
<a id='changelog-2.0.0-pre9'></a>
|
48
|
+
# [2.0.0-pre9] - 2025-09-02 00:35:28.974817
|
49
|
+
|
50
|
+
## Added
|
51
|
+
|
52
|
+
- Added `class_tracked_in` method for global tracking relationships following Horreum's established `class_` prefix convention
|
53
|
+
- Added `class_indexed_by` method for global index relationships with consistent API design
|
54
|
+
|
55
|
+
## Changed
|
56
|
+
|
57
|
+
- **BREAKING**: `tracked_in :global, collection` syntax now raises ArgumentError - use `class_tracked_in collection` instead
|
58
|
+
- **BREAKING**: `indexed_by field, index, context: :global` syntax replaced with `class_indexed_by field, index`
|
59
|
+
- **BREAKING**: `indexed_by field, index, context: SomeClass` syntax replaced with `indexed_by field, index, parent: SomeClass`
|
60
|
+
- Relationships API now provides consistent parameter naming across all relationship types
|
61
|
+
|
62
|
+
## Documentation
|
63
|
+
|
64
|
+
- Updated Relationships Guide with new API syntax and migration examples
|
65
|
+
- Updated relationships method documentation with new method signatures
|
66
|
+
- Updated basic relationships example to demonstrate new API patterns
|
67
|
+
- Added tryouts test coverage in try/features/relationships/relationships_api_changes_try.rb
|
68
|
+
|
69
|
+
|
70
|
+
<a id='changelog-2.0.0-pre8'></a>
|
71
|
+
## [2.0.0-pre8] - 2025-09-01
|
72
|
+
|
73
|
+
#### Added
|
74
|
+
|
75
|
+
- Implemented Scriv-based changelog system for sustainable documentation
|
76
|
+
- Added fragment-based workflow for tracking changes
|
77
|
+
- Created structured changelog templates and configuration
|
78
|
+
|
79
|
+
### Documentation
|
80
|
+
|
81
|
+
- Set up Scriv configuration and directory structure
|
82
|
+
- Created README for changelog fragment workflow
|
83
|
+
|
84
|
+
|
85
|
+
<a id='changelog-2.0.0-pre7'></a>
|
86
|
+
## [2.0.0-pre7] - 2025-08-31
|
87
|
+
|
88
|
+
### Added
|
89
|
+
|
90
|
+
- Comprehensive relationships system with three relationship types:
|
91
|
+
- `tracked_in` - Multi-presence tracking with score encoding
|
92
|
+
- `indexed_by` - O(1) hash-based lookups
|
93
|
+
- `member_of` - Bidirectional membership with collision-free naming
|
94
|
+
- Categorical permission system with bit-encoded permissions
|
95
|
+
- Time-based permission scoring for temporal access control
|
96
|
+
- Permission tier hierarchies with inheritance patterns
|
97
|
+
- Scalable permission management for large object collections
|
98
|
+
- Score-based sorting with custom scoring functions
|
99
|
+
- Permission-aware queries filtering by access levels
|
100
|
+
- Relationship validation framework ensuring data integrity
|
101
|
+
|
102
|
+
### Changed
|
103
|
+
|
104
|
+
- Performance optimizations for large-scale relationship operations
|
105
|
+
|
106
|
+
### Security
|
107
|
+
|
108
|
+
- GitHub Actions security hardening with matrix optimization
|
109
|
+
|
110
|
+
|
111
|
+
<a id='changelog-2.0.0-pre6'></a>
|
112
|
+
## [2.0.0-pre6] - 2025-08-15
|
113
|
+
|
114
|
+
### Added
|
115
|
+
|
116
|
+
- New `save_if_not_exists` method for conditional persistence
|
117
|
+
- Atomic persistence operations with transaction support
|
118
|
+
- Enhanced error handling for persistence failures
|
119
|
+
- Improved data consistency guarantees
|
120
|
+
|
121
|
+
### Changed
|
122
|
+
|
123
|
+
- Connection provider pattern for flexible pooling strategies
|
124
|
+
- Multi-database support with intelligent pool management
|
125
|
+
- Thread-safe connection handling for concurrent applications
|
126
|
+
- Configurable pool sizing and timeout management
|
127
|
+
- Modular class structure with cleaner separation of concerns
|
128
|
+
- Enhanced feature system with dependency management
|
129
|
+
- Improved inheritance patterns for better code organization
|
130
|
+
- Streamlined base class functionality
|
131
|
+
|
132
|
+
### Fixed
|
133
|
+
|
134
|
+
- Critical security fixes in Ruby workflow vulnerabilities
|
135
|
+
- Systematic dependency resolution via multi-constraint optimization
|
136
|
+
|
137
|
+
|
138
|
+
<a id='changelog-2.0.0-pre5'></a>
|
139
|
+
## [2.0.0-pre5] - 2025-08-05
|
140
|
+
|
141
|
+
### Added
|
142
|
+
|
143
|
+
- Field-level encryption with transparent access patterns
|
144
|
+
- Multiple encryption providers:
|
145
|
+
- XChaCha20-Poly1305 (preferred, requires rbnacl)
|
146
|
+
- AES-256-GCM (fallback, OpenSSL-based)
|
147
|
+
- Field-specific key derivation for cryptographic domain separation
|
148
|
+
- Configurable key versioning supporting key rotation
|
149
|
+
- Non-persistent field storage for sensitive runtime data
|
150
|
+
- RedactedString wrapper preventing accidental logging/serialization
|
151
|
+
- Memory-safe handling of sensitive data in Ruby objects
|
152
|
+
- API-safe serialization excluding transient fields
|
153
|
+
|
154
|
+
### Security
|
155
|
+
|
156
|
+
- Encryption field security hardening with additional validation
|
157
|
+
- Enhanced memory protection for sensitive data handling
|
158
|
+
- Improved key management patterns and best practices
|
159
|
+
- Security test suite expansion with comprehensive coverage
|
160
|
+
|
161
|
+
|
162
|
+
<a id='changelog-2.0.0-pre'></a>
|
163
|
+
## [2.0.0-pre] - 2025-07-25
|
164
|
+
|
165
|
+
### Added
|
166
|
+
|
167
|
+
- Complete API redesign for clarity and modern Ruby conventions
|
168
|
+
- Valkey compatibility alongside traditional Redis support
|
169
|
+
- Ruby 3.4+ modernization with fiber and thread safety improvements
|
170
|
+
- Connection pooling foundation with provider pattern architecture
|
171
|
+
|
172
|
+
### Changed
|
173
|
+
|
174
|
+
- `Familia::Base` replaced by `Familia::Horreum` as the primary base class
|
175
|
+
- Connection configuration moved from simple string to block-based setup
|
176
|
+
- Feature activation changed from `include` to `feature` declarations
|
177
|
+
- Method naming updated for consistency (`delete` → `destroy`, `exists` → `exists?`, `dump` → `serialize`)
|
178
|
+
|
179
|
+
### Documentation
|
180
|
+
|
181
|
+
- YARD documentation workflow with automated GitHub Pages deployment
|
182
|
+
- Comprehensive migration guide for v1.x to v2.0.0-pre transition
|
183
|
+
|
184
|
+
<!-- scriv-end-here -->
|
data/CLAUDE.md
CHANGED
@@ -44,18 +44,21 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
44
44
|
- **Generate documentation**: `bundle exec yard`
|
45
45
|
- **Code linting**: `bundle exec rubocop`
|
46
46
|
|
47
|
+
### Changelog Management
|
48
|
+
|
49
|
+
Add changelog fragment with each user-facing or documented change (optional but encouraged). See:
|
50
|
+
@changelog.d/README.md
|
51
|
+
|
47
52
|
### Known Issues & Quirks
|
48
|
-
- **Reserved Keywords**: Cannot use `ttl`, `db`, `redis` as field names - use prefixed alternatives
|
53
|
+
- **Reserved Keywords**: Cannot use `ttl`, `db`, `valkey`, `redis` as field names - use prefixed alternatives
|
49
54
|
- **Empty Identifiers**: Cause stack overflow in key generation - validate before operations
|
50
55
|
- **Connection Pool Race Conditions**: Thread safety issues under high concurrency
|
51
|
-
- **Manual Key Sync**: `key` field doesn't auto-sync with identifier changes
|
52
|
-
- **RedisType Redis Parameter**: `:redis` parameter silently ignored (missing setter)
|
53
56
|
|
54
57
|
### Debugging
|
55
|
-
- **Database command logging**:
|
58
|
+
- **Database command logging**: You can request real-time Database command monitoring from the user
|
56
59
|
- Shows all Database operations with timestamps, database numbers, and full commands
|
57
60
|
- Updates live as tests run or code executes
|
58
|
-
- Essential for debugging Familia ORM Database interactions
|
61
|
+
- Essential for debugging Familia ORM Database interactions, multi/exec, pipelining, logical_database issues
|
59
62
|
|
60
63
|
### Testing Framework
|
61
64
|
This project uses `tryouts` instead of RSpec/Minitest. Test files are located in the `try/` directory and follow the pattern `*_try.rb`.
|
data/Gemfile
CHANGED
@@ -9,7 +9,7 @@ group :test do
|
|
9
9
|
gem 'tryouts', path: '../tryouts'
|
10
10
|
gem 'uri-valkey', path: '..//uri-valkey/gems', glob: 'uri-valkey.gemspec'
|
11
11
|
else
|
12
|
-
gem 'tryouts', '~> 3.5.
|
12
|
+
gem 'tryouts', '~> 3.5.2', require: false
|
13
13
|
end
|
14
14
|
gem 'concurrent-ruby', '~> 1.3.5', require: false
|
15
15
|
gem 'ruby-prof'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
familia (2.0.0.
|
4
|
+
familia (2.0.0.pre10)
|
5
5
|
benchmark
|
6
6
|
connection_pool
|
7
7
|
csv
|
@@ -113,7 +113,7 @@ GEM
|
|
113
113
|
ruby-progressbar (1.13.0)
|
114
114
|
stackprof (0.2.27)
|
115
115
|
stringio (3.1.7)
|
116
|
-
tryouts (3.5.
|
116
|
+
tryouts (3.5.2)
|
117
117
|
concurrent-ruby (~> 1.0)
|
118
118
|
irb
|
119
119
|
minitest (~> 5.0)
|
@@ -148,7 +148,7 @@ DEPENDENCIES
|
|
148
148
|
rubocop-thread_safety
|
149
149
|
ruby-prof
|
150
150
|
stackprof
|
151
|
-
tryouts (~> 3.5.
|
151
|
+
tryouts (~> 3.5.2)
|
152
152
|
yard (~> 0.9)
|
153
153
|
|
154
154
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -118,9 +118,104 @@ user.transaction do |conn|
|
|
118
118
|
end
|
119
119
|
```
|
120
120
|
|
121
|
-
|
121
|
+
### Object Relationships
|
122
122
|
|
123
|
-
Familia
|
123
|
+
Familia includes a powerful relationships system for managing object associations:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
class Customer < Familia::Horreum
|
127
|
+
feature :relationships
|
128
|
+
|
129
|
+
identifier_field :custid
|
130
|
+
field :custid, :name, :email
|
131
|
+
set :domains # Collection for related objects
|
132
|
+
|
133
|
+
# Automatic indexing and tracking
|
134
|
+
class_indexed_by :email, :email_lookup
|
135
|
+
class_tracked_in :all_customers, score: :created_at
|
136
|
+
end
|
137
|
+
|
138
|
+
class Domain < Familia::Horreum
|
139
|
+
feature :relationships
|
140
|
+
|
141
|
+
identifier_field :domain_id
|
142
|
+
field :domain_id, :name, :status
|
143
|
+
|
144
|
+
# Bidirectional membership
|
145
|
+
member_of Customer, :domains
|
146
|
+
end
|
147
|
+
|
148
|
+
# Clean, Ruby-like syntax
|
149
|
+
customer = Customer.new(custid: "cust123", email: "admin@acme.com")
|
150
|
+
customer.save # Automatically indexed and tracked
|
151
|
+
|
152
|
+
domain = Domain.new(domain_id: "dom456", name: "acme.com")
|
153
|
+
customer.domains << domain # Clean collection syntax
|
154
|
+
|
155
|
+
# Fast O(1) lookups
|
156
|
+
found_customer = Customer.find_by_email("admin@acme.com")
|
157
|
+
```
|
158
|
+
|
159
|
+
## Advanced Features
|
160
|
+
|
161
|
+
### Relationships and Associations
|
162
|
+
|
163
|
+
Familia provides three types of relationships with automatic management:
|
164
|
+
|
165
|
+
- **`member_of`** - Bidirectional membership with clean `<<` operator support
|
166
|
+
- **`indexed_by`** - O(1) hash-based field lookups (class-level or relationship-scoped)
|
167
|
+
- **`tracked_in`** - Scored collections for rankings, time-series, and analytics
|
168
|
+
|
169
|
+
All relationships support automatic indexing and tracking - objects are automatically added to class-level collections when saved, with no manual management required.
|
170
|
+
|
171
|
+
## Organizing Complex Models
|
172
|
+
|
173
|
+
For large applications, you can organize model complexity using custom features:
|
174
|
+
|
175
|
+
### Self-Registering Features
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
# app/features/customer_management.rb
|
179
|
+
module MyApp::Features::CustomerManagement
|
180
|
+
Familia::Base.add_feature(self, :customer_management)
|
181
|
+
|
182
|
+
def self.included(base)
|
183
|
+
base.extend(ClassMethods)
|
184
|
+
end
|
185
|
+
|
186
|
+
module ClassMethods
|
187
|
+
def create_with_validation(attrs)
|
188
|
+
# Complex creation logic
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def complex_business_method
|
193
|
+
# Instance methods
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# models/customer.rb
|
198
|
+
class Customer < Familia::Horreum
|
199
|
+
field :email, :name
|
200
|
+
feature :customer_management # Clean model definition
|
201
|
+
end
|
202
|
+
```
|
203
|
+
|
204
|
+
This keeps complex models organized while maintaining Familia's clean, declarative style.
|
205
|
+
|
206
|
+
## AI Development Assistance
|
207
|
+
|
208
|
+
This version of Familia was developed with assistance from AI tools. The following tools provided significant help with architecture design, code generation, and documentation:
|
209
|
+
|
210
|
+
- **Google Gemini** - Refactoring, code generation, and documentation.
|
211
|
+
- **Claude Sonnet 4, Opus 4.1** - Architecture design, code generation, and documentation
|
212
|
+
- **Claude Desktop & Claude Code (Max plan)** - Interactive development sessions and debugging
|
213
|
+
- **GitHub Copilot** - Code completion and refactoring assistance
|
214
|
+
- **Qodo Merge Pro** - Code review and quality improvements
|
215
|
+
|
216
|
+
I remain responsible for all design decisions and the final code. I believe in being transparent about development tools, especially as AI becomes more integrated into our workflows as developers.
|
217
|
+
|
218
|
+
## Epilogue
|
124
219
|
|
125
220
|
For more information, visit:
|
126
221
|
- [Github Repository](https://github.com/delano/familia)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Changelog Fragments
|
2
|
+
|
3
|
+
This directory contains changelog fragments managed by [Scriv](https://scriv.readthedocs.io/).
|
4
|
+
|
5
|
+
## Our Approach
|
6
|
+
|
7
|
+
Changelogs are for humans and agents, not just machines. We follow the core principles of [Keep a Changelog](https://keepachangelog.com) to ensure our release notes are clear, consistent, and trustworthy.
|
8
|
+
|
9
|
+
To achieve this, we use a fragment-based workflow with `scriv`. Instead of a single, large `CHANGELOG.md` file that can cause merge conflicts, each developer includes a small changelog fragment with their pull request. At release time, these fragments are collected and aggregated into the main changelog.
|
10
|
+
|
11
|
+
This approach provides several benefits:
|
12
|
+
- **Reduces Merge Conflicts:** Developers can work in parallel without conflicting over a central changelog file.
|
13
|
+
- **Improves Developer Experience:** Creating a small, focused fragment is a simple and repeatable task during development.
|
14
|
+
- **Ensures Consistency:** Automation helps maintain a consistent structure for all changelog entries.
|
15
|
+
- **Builds Trust:** A clear and well-maintained changelog communicates respect for our users and collaborators.
|
16
|
+
|
17
|
+
## How to Add a Changelog Entry
|
18
|
+
|
19
|
+
1. **Create a New Fragment:**
|
20
|
+
```bash
|
21
|
+
scriv create
|
22
|
+
```
|
23
|
+
This will create a new file in the `changelog.d/fragments/` directory.
|
24
|
+
|
25
|
+
**Alternative:** Use `scriv create --edit` to create and immediately open in your editor.
|
26
|
+
**Important:** You must add content and save before exiting, or scriv will abort with "Empty fragment, aborting..."
|
27
|
+
|
28
|
+
2. **Edit the Fragment File:**
|
29
|
+
Open the newly created file and add your entry under the relevant category. See the guidelines below for writing good entries.
|
30
|
+
|
31
|
+
3. **Commit with Your Code:**
|
32
|
+
```bash
|
33
|
+
git add changelog.d/fragments/your_fragment_name.md
|
34
|
+
git commit
|
35
|
+
```
|
36
|
+
|
37
|
+
## Fragment Guidelines
|
38
|
+
|
39
|
+
- **One Fragment Per Change:** Keep each fragment focused on a single feature, fix, or improvement.
|
40
|
+
- **Documenting AI Assistance:** If a change involved significant AI assistance, place it in its own fragment. This ensures the `### AI Assistance` section clearly corresponds to the single change described in that fragment.
|
41
|
+
- **Write for a Human Audience:** Describe the *impact* of the change, not just the implementation details.
|
42
|
+
- **Good:** "Improved the performance and stability of Redis connections under high load."
|
43
|
+
- **Bad:** "Refactored the `RedisManager` to use a connection pool."
|
44
|
+
- **Be Specific:** Avoid generic messages like "fixed a bug." Clearly state what was fixed.
|
45
|
+
- **Include Context:** Reference issue or pull request numbers to provide a link to the discussion and implementation details. `scriv` will automatically create links for them.
|
46
|
+
- **Example:** `- Fixed a bug where users could not reset their passwords. (Closes #123)`
|
47
|
+
|
48
|
+
### Categories
|
49
|
+
|
50
|
+
Use these categories from [Keep a Changelog](https://keepachangelog.com):
|
51
|
+
|
52
|
+
- **Added**: New features or capabilities.
|
53
|
+
- **Changed**: Changes to existing functionality.
|
54
|
+
- **Deprecated**: Soon-to-be removed features.
|
55
|
+
- **Removed**: Now removed features.
|
56
|
+
- **Fixed**: Bug fixes.
|
57
|
+
- **Security**: Security-related improvements.
|
58
|
+
- **Documentation**: Documentation improvements.
|
59
|
+
|
60
|
+
## Release Process
|
61
|
+
|
62
|
+
At release time, an authorized maintainer will collect all fragments into the main `CHANGELOG.md` file:
|
63
|
+
|
64
|
+
```bash
|
65
|
+
scriv collect --version 2.0.0
|
66
|
+
```
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<!--
|
2
|
+
A new scriv fragment. Uncomment sections as needed.
|
3
|
+
Reference issues or pull requests in parentheses at the end of the entry.
|
4
|
+
Example: - Fixed a bug in the connection pool. (Closes #123)
|
5
|
+
-->
|
6
|
+
|
7
|
+
### Added
|
8
|
+
<!-- - New features or capabilities -->
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
<!-- - Changes to existing functionality -->
|
12
|
+
|
13
|
+
### Deprecated
|
14
|
+
<!-- - Soon-to-be removed features -->
|
15
|
+
|
16
|
+
### Removed
|
17
|
+
<!-- - Now removed features -->
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
<!-- - Bug fixes -->
|
21
|
+
|
22
|
+
### Security
|
23
|
+
<!-- - Security-related improvements -->
|
24
|
+
|
25
|
+
### Documentation
|
26
|
+
<!-- - Documentation improvements -->
|
27
|
+
|
28
|
+
### AI Assistance
|
29
|
+
<!-- - Briefly describe how AI was used for this change (e.g., "Refactoring and documentation by Gemini"). -->
|