familia 2.0.0.pre8 → 2.0.0.pre12

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +13 -0
  3. data/.github/workflows/docs.yml +1 -1
  4. data/.gitignore +9 -9
  5. data/.rubocop.yml +19 -0
  6. data/.yardopts +22 -1
  7. data/CHANGELOG.md +247 -0
  8. data/CLAUDE.md +12 -59
  9. data/Gemfile.lock +1 -1
  10. data/README.md +62 -2
  11. data/changelog.d/README.md +77 -0
  12. data/docs/archive/.gitignore +2 -0
  13. data/docs/archive/FAMILIA_RELATIONSHIPS.md +210 -0
  14. data/docs/archive/FAMILIA_TECHNICAL.md +823 -0
  15. data/docs/archive/FAMILIA_UPDATE.md +226 -0
  16. data/docs/archive/README.md +63 -0
  17. data/docs/guides/.gitignore +2 -0
  18. data/docs/{wiki → guides}/Home.md +1 -1
  19. data/docs/{wiki → guides}/Implementation-Guide.md +1 -1
  20. data/docs/{wiki → guides}/Relationships-Guide.md +103 -50
  21. data/docs/guides/relationships-methods.md +266 -0
  22. data/docs/migrating/.gitignore +2 -0
  23. data/docs/migrating/v2.0.0-pre.md +84 -0
  24. data/docs/migrating/v2.0.0-pre11.md +255 -0
  25. data/docs/migrating/v2.0.0-pre12.md +306 -0
  26. data/docs/migrating/v2.0.0-pre5.md +110 -0
  27. data/docs/migrating/v2.0.0-pre6.md +154 -0
  28. data/docs/migrating/v2.0.0-pre7.md +222 -0
  29. data/docs/overview.md +6 -7
  30. data/{examples/redis_command_validation_example.rb → docs/reference/auditing_database_commands.rb} +29 -32
  31. data/examples/{bit_encoding_integration.rb → permissions.rb} +30 -27
  32. data/examples/relationships.rb +205 -0
  33. data/examples/safe_dump.rb +281 -0
  34. data/familia.gemspec +4 -4
  35. data/lib/familia/base.rb +52 -0
  36. data/lib/familia/connection.rb +4 -21
  37. data/lib/familia/{encryption_request_cache.rb → encryption/request_cache.rb} +1 -1
  38. data/lib/familia/errors.rb +2 -0
  39. data/lib/familia/features/autoloader.rb +57 -0
  40. data/lib/familia/features/external_identifier.rb +310 -0
  41. data/lib/familia/features/object_identifier.rb +307 -0
  42. data/lib/familia/features/relationships/indexing.rb +160 -175
  43. data/lib/familia/features/relationships/membership.rb +16 -21
  44. data/lib/familia/features/relationships/tracking.rb +61 -21
  45. data/lib/familia/features/relationships.rb +15 -8
  46. data/lib/familia/features/safe_dump.rb +66 -72
  47. data/lib/familia/features.rb +93 -5
  48. data/lib/familia/horreum/subclass/definition.rb +49 -3
  49. data/lib/familia/horreum.rb +15 -24
  50. data/lib/familia/secure_identifier.rb +51 -75
  51. data/lib/familia/verifiable_identifier.rb +162 -0
  52. data/lib/familia/version.rb +1 -1
  53. data/lib/familia.rb +1 -0
  54. data/setup.cfg +5 -0
  55. data/try/core/secure_identifier_try.rb +47 -18
  56. data/try/core/verifiable_identifier_try.rb +171 -0
  57. data/try/features/{external_identifiers/external_identifiers_try.rb → external_identifier/external_identifier_try.rb} +25 -28
  58. data/try/features/feature_improvements_try.rb +126 -0
  59. data/try/features/{object_identifiers/object_identifiers_integration_try.rb → object_identifier/object_identifier_integration_try.rb} +28 -30
  60. data/try/features/{object_identifiers/object_identifiers_try.rb → object_identifier/object_identifier_try.rb} +13 -13
  61. data/try/features/real_feature_integration_try.rb +7 -6
  62. data/try/features/relationships/relationships_api_changes_try.rb +339 -0
  63. data/try/features/relationships/relationships_try.rb +6 -5
  64. data/try/features/safe_dump/safe_dump_try.rb +8 -9
  65. data/try/helpers/test_helpers.rb +17 -17
  66. metadata +62 -41
  67. data/examples/relationships_basic.rb +0 -273
  68. data/lib/familia/features/external_identifiers/external_identifier_field_type.rb +0 -120
  69. data/lib/familia/features/external_identifiers.rb +0 -111
  70. data/lib/familia/features/object_identifiers/object_identifier_field_type.rb +0 -91
  71. data/lib/familia/features/object_identifiers.rb +0 -194
  72. /data/docs/{wiki → guides}/API-Reference.md +0 -0
  73. /data/docs/{wiki → guides}/Connection-Pooling-Guide.md +0 -0
  74. /data/docs/{wiki → guides}/Encrypted-Fields-Overview.md +0 -0
  75. /data/docs/{wiki → guides}/Expiration-Feature-Guide.md +0 -0
  76. /data/docs/{wiki → guides}/Feature-System-Guide.md +0 -0
  77. /data/docs/{wiki → guides}/Features-System-Developer-Guide.md +0 -0
  78. /data/docs/{wiki → guides}/Field-System-Guide.md +0 -0
  79. /data/docs/{wiki → guides}/Quantization-Feature-Guide.md +0 -0
  80. /data/docs/{wiki → guides}/Security-Model.md +0 -0
  81. /data/docs/{wiki → guides}/Transient-Fields-Guide.md +0 -0
@@ -0,0 +1,222 @@
1
+ # Migrating Guide: Relationships System (v2.0.0-pre7)
2
+
3
+ This guide covers adopting the comprehensive relationships system introduced in v2.0.0-pre7.
4
+
5
+ ## Relationships System Overview
6
+
7
+ The v2.0.0-pre7 release introduces three powerful relationship types:
8
+
9
+ - **`tracked_in`** - Multi-presence tracking with score encoding
10
+ - **`indexed_by`** - O(1) hash-based lookups
11
+ - **`member_of`** - Bidirectional membership with collision-free naming
12
+
13
+ ## Migration Steps
14
+
15
+ ### 1. Enable Relationships Feature
16
+
17
+ Add the relationships feature to your models:
18
+
19
+ ```ruby
20
+ class Customer < Familia::Horreum
21
+ feature :relationships # Required for all relationship types
22
+
23
+ identifier_field :custid
24
+ field :custid, :name, :email
25
+ end
26
+ ```
27
+
28
+ ### 2. Choose Appropriate Relationship Types
29
+
30
+ **For Tracking Collections (sorted sets):**
31
+ ```ruby
32
+ class Customer < Familia::Horreum
33
+ feature :relationships
34
+
35
+ # Global tracking with score-based sorting
36
+ tracked_in :all_customers, type: :sorted_set, score: :created_at
37
+
38
+ # Scoped tracking
39
+ tracked_in :active_users, type: :sorted_set, score: :last_seen
40
+ end
41
+ ```
42
+
43
+ **For Fast Lookups (hash indexes):**
44
+ ```ruby
45
+ class Customer < Familia::Horreum
46
+ feature :relationships
47
+
48
+ # Global email index for O(1) lookups
49
+ indexed_by :email, :email_lookup, context: :global
50
+
51
+ # Domain-specific indexes
52
+ indexed_by :account_id, :account_lookup, context: Domain
53
+ end
54
+ ```
55
+
56
+ **For Bidirectional Membership:**
57
+ ```ruby
58
+ class Domain < Familia::Horreum
59
+ feature :relationships
60
+
61
+ # Belongs to customer's domains collection
62
+ member_of Customer, :domains, type: :set
63
+ end
64
+ ```
65
+
66
+ ### 3. Implement Permission Systems
67
+
68
+ For access-controlled relationships:
69
+
70
+ ```ruby
71
+ class Document < Familia::Horreum
72
+ feature :relationships
73
+ include Familia::Features::Relationships::PermissionManagement
74
+
75
+ # Permission-aware tracking
76
+ tracked_in Customer, :documents, score: :created_at
77
+
78
+ permission_tracking :user_permissions
79
+
80
+ def permission_bits
81
+ # Define permission levels (bit-encoded)
82
+ @permission_bits || 1 # Default: read-only
83
+ end
84
+ end
85
+ ```
86
+
87
+ ### 4. Update Queries
88
+
89
+ **Before (manual Redis operations):**
90
+ ```ruby
91
+ # Manual sorted set operations
92
+ redis.zadd("all_customers", customer.created_at, customer.custid)
93
+ customers = redis.zrange("all_customers", 0, -1)
94
+ ```
95
+
96
+ **After (relationship methods):**
97
+ ```ruby
98
+ # Automatic method generation
99
+ Customer.add_to_all_customers(customer)
100
+ customers = Customer.all_customers.to_a
101
+ ```
102
+
103
+ ## Relationship Method Patterns
104
+
105
+ ### `tracked_in` Methods
106
+ ```ruby
107
+ # Class methods generated:
108
+ Customer.add_to_all_customers(customer)
109
+ Customer.remove_from_all_customers(customer)
110
+ Customer.all_customers # Access sorted set directly
111
+ ```
112
+
113
+ ### `indexed_by` Methods
114
+ ```ruby
115
+ # Class methods generated:
116
+ Customer.add_to_email_lookup(customer)
117
+ Customer.remove_from_email_lookup(customer)
118
+ Customer.email_lookup.get(email) # O(1) lookup
119
+ ```
120
+
121
+ ### `member_of` Methods
122
+ ```ruby
123
+ # Instance methods generated:
124
+ domain.add_to_customer_domains(customer)
125
+ domain.remove_from_customer_domains(customer)
126
+ domain.in_customer_domains?(customer)
127
+ ```
128
+
129
+ ## Permission System Migration
130
+
131
+ ### Basic Permission Encoding
132
+ ```ruby
133
+ # Permission levels (bit-encoded)
134
+ READ = 1 # 001
135
+ WRITE = 4 # 100
136
+ DELETE = 32 # 100000
137
+ ADMIN = 128 # 10000000
138
+
139
+ # Combine permissions
140
+ user_permissions = READ | WRITE # Can read and write
141
+ admin_permissions = ADMIN # All permissions via hierarchy
142
+ ```
143
+
144
+ ### Time-Based Permission Scores
145
+ ```ruby
146
+ # Encode timestamp with permission bits
147
+ timestamp = Time.now.to_i
148
+ permissions = READ | WRITE
149
+ score = Familia::Features::Relationships::ScoreEncoding.encode_score(timestamp, permissions)
150
+
151
+ # Query by permission level
152
+ documents_with_write_access = customer.documents.accessible_items(
153
+ permissions: WRITE,
154
+ collection_key: customer.documents.key
155
+ )
156
+ ```
157
+
158
+ ## Performance Considerations
159
+
160
+ ### Relationship Type Selection
161
+
162
+ **Use `indexed_by` for:**
163
+ - Unique field lookups (email, username, ID)
164
+ - Fields that need O(1) access
165
+ - Reference relationships
166
+
167
+ **Use `tracked_in` for:**
168
+ - Time-ordered collections
169
+ - Scored/ranked relationships
170
+ - Permission-based access control
171
+
172
+ **Use `member_of` for:**
173
+ - Simple membership tracking
174
+ - Bidirectional relationships
175
+ - Set-based collections
176
+
177
+ ### Optimization Tips
178
+
179
+ **Batch Operations:**
180
+ ```ruby
181
+ # Instead of multiple individual operations
182
+ customers.each { |c| Customer.add_to_all_customers(c) }
183
+
184
+ # Use batch operations where available
185
+ Customer.all_customers.add_batch(customers.map(&:identifier),
186
+ customers.map(&:created_at))
187
+ ```
188
+
189
+ **Permission Queries:**
190
+ ```ruby
191
+ # Efficient permission filtering
192
+ accessible_docs = document.accessible_items(
193
+ collection_key: customer.documents.key,
194
+ minimum_permissions: READ
195
+ )
196
+ ```
197
+
198
+ ## Breaking Changes
199
+
200
+ ### Method Name Changes
201
+ - Relationship methods follow new naming patterns
202
+ - Previous manual Redis operations need updating
203
+ - Collection access methods standardized
204
+
205
+ ### Permission System
206
+ - New bit-encoded permission system
207
+ - Time-based scoring for temporal access
208
+ - Permission hierarchy implementation required
209
+
210
+ ## Next Steps
211
+
212
+ 1. **Analyze Existing Relationships:** Review current Redis operations for optimization opportunities
213
+ 2. **Choose Relationship Types:** Select appropriate types based on usage patterns
214
+ 3. **Implement Permissions:** Add access control where needed
215
+ 4. **Update Queries:** Replace manual operations with generated relationship methods
216
+ 5. **Test Performance:** Benchmark relationship operations under load
217
+
218
+ ## Resources
219
+
220
+ - [Relationships Methods Guide](../guides/relationships-methods.md) - Complete method reference
221
+ - [Relationships Guide](../guides/Relationships-Guide.md) - Implementation examples
222
+ - [Performance Guide](../guides/Implementation-Guide.md) - Optimization strategies
data/docs/overview.md CHANGED
@@ -118,17 +118,16 @@ This is ideal for temporary data like authentication tokens or cache entries.
118
118
 
119
119
  ### Safe Dumping for APIs
120
120
 
121
- Control which fields are exposed when serializing objects:
121
+ Control which fields are exposed when serializing objects using the clean DSL:
122
122
 
123
123
  ```ruby
124
124
  class User < Familia::Horreum
125
125
  feature :safe_dump
126
126
 
127
- @safe_dump_fields = [
128
- :id,
129
- :email,
130
- {full_name: ->(user) { "#{user.first_name} #{user.last_name}" }}
131
- ]
127
+ # Use clean DSL methods instead of @safe_dump_fields
128
+ safe_dump_field :id
129
+ safe_dump_field :email
130
+ safe_dump_field :full_name, ->(user) { "#{user.first_name} #{user.last_name}" }
132
131
 
133
132
  field :id, :email, :first_name, :last_name, :password_hash
134
133
  end
@@ -137,7 +136,7 @@ user.safe_dump
137
136
  #=> {id: "123", email: "alice@example.com", full_name: "Alice Smith"}
138
137
  ```
139
138
 
140
- Prevents accidental exposure of sensitive data in API responses.
139
+ The new DSL prevents accidental exposure of sensitive data and makes field definitions easier to organize in feature modules.
141
140
 
142
141
  ### Time-based Quantization
143
142
 
@@ -50,21 +50,21 @@ class TransferService
50
50
  end
51
51
  end
52
52
 
53
- puts "🧪 Redis Command Validation Framework Demo"
54
- puts "=" * 50
53
+ puts '🧪 Redis Command Validation Framework Demo'
54
+ puts '=' * 50
55
55
 
56
56
  # Clean up any existing test data
57
- cleanup_keys = Familia.dbclient.keys("account:*")
57
+ cleanup_keys = Familia.dbclient.keys('account:*')
58
58
  Familia.dbclient.del(*cleanup_keys) if cleanup_keys.any?
59
59
 
60
60
  # Example 1: Basic Command Recording
61
61
  puts "\n1. Basic Command Recording"
62
- puts "-" * 30
62
+ puts '-' * 30
63
63
 
64
64
  CommandRecorder = Familia::Validation::CommandRecorder
65
65
  CommandRecorder.start_recording
66
66
 
67
- account = Account.new(account_id: "acc001", balance: "1000", status: "active")
67
+ account = Account.new(account_id: 'acc001', balance: '1000', status: 'active')
68
68
  account.save
69
69
 
70
70
  commands = CommandRecorder.stop_recording
@@ -73,12 +73,12 @@ commands.commands.each { |cmd| puts " #{cmd}" }
73
73
 
74
74
  # Example 2: Transaction Detection
75
75
  puts "\n2. Transaction Detection"
76
- puts "-" * 30
76
+ puts '-' * 30
77
77
 
78
78
  CommandRecorder.start_recording
79
79
 
80
- acc1 = Account.new(account_id: "acc002", balance: "2000")
81
- acc2 = Account.new(account_id: "acc003", balance: "500")
80
+ acc1 = Account.new(account_id: 'acc002', balance: '2000')
81
+ acc2 = Account.new(account_id: 'acc003', balance: '500')
82
82
  acc1.save
83
83
  acc2.save
84
84
 
@@ -96,7 +96,7 @@ end
96
96
 
97
97
  # Example 3: Validation with Expectations DSL
98
98
  puts "\n3. Command Validation with Expectations"
99
- puts "-" * 30
99
+ puts '-' * 30
100
100
 
101
101
  begin
102
102
  validator = Familia::Validation::Validator.new
@@ -104,15 +104,15 @@ begin
104
104
  # This should pass - we expect the exact Redis commands
105
105
  result = validator.validate do |expect|
106
106
  expect.transaction do |tx|
107
- tx.hset("account:acc004:object", "balance", "1500")
108
- .hset("account:acc005:object", "balance", "1000")
109
- .hset("account:acc004:object", "last_updated", Familia::Validation::ArgumentMatcher.new(:any_string))
110
- .hset("account:acc005:object", "last_updated", Familia::Validation::ArgumentMatcher.new(:any_string))
107
+ tx.hset('account:acc004:object', 'balance', '1500')
108
+ .hset('account:acc005:object', 'balance', '1000')
109
+ .hset('account:acc004:object', 'last_updated', Familia::Validation::ArgumentMatcher.new(:any_string))
110
+ .hset('account:acc005:object', 'last_updated', Familia::Validation::ArgumentMatcher.new(:any_string))
111
111
  end
112
112
 
113
113
  # Execute the operation
114
- acc4 = Account.new(account_id: "acc004", balance: "2000")
115
- acc5 = Account.new(account_id: "acc005", balance: "500")
114
+ acc4 = Account.new(account_id: 'acc004', balance: '2000')
115
+ acc5 = Account.new(account_id: 'acc005', balance: '500')
116
116
  acc4.save
117
117
  acc5.save
118
118
 
@@ -121,51 +121,49 @@ begin
121
121
 
122
122
  puts "Validation result: #{result.valid? ? 'PASS ✅' : 'FAIL ❌'}"
123
123
  puts "Summary: #{result.summary}"
124
-
125
- rescue => e
124
+ rescue StandardError => e
126
125
  puts "Validation demo encountered error: #{e.message}"
127
- puts "This is expected as the framework needs Redis middleware integration"
126
+ puts 'This is expected as the framework needs Redis middleware integration'
128
127
  end
129
128
 
130
129
  # Example 4: Performance Analysis
131
130
  puts "\n4. Performance Analysis"
132
- puts "-" * 30
131
+ puts '-' * 30
133
132
 
134
133
  begin
135
134
  commands = Familia::Validation.capture_commands do
136
135
  # Create multiple accounts
137
136
  accounts = []
138
137
  (1..5).each do |i|
139
- account = Account.new(account_id: "perf#{i}", balance: "1000")
138
+ account = Account.new(account_id: "perf#{i}", balance: '1000')
140
139
  account.save
141
140
  accounts << account
142
141
  end
143
142
 
144
143
  # Perform operations
145
- accounts[0].balance = "1100"
144
+ accounts[0].balance = '1100'
146
145
  accounts[0].save
147
146
  end
148
147
 
149
148
  analyzer = Familia::Validation::PerformanceAnalyzer.new(commands)
150
149
  analysis = analyzer.analyze
151
150
 
152
- puts "Performance Analysis:"
151
+ puts 'Performance Analysis:'
153
152
  puts " Total Commands: #{analysis[:total_commands]}"
154
153
  puts " Command Types: #{analysis[:command_type_breakdown].keys.join(', ')}"
155
154
  puts " Efficiency Score: #{analysis[:efficiency_score]}/100"
156
-
157
- rescue => e
155
+ rescue StandardError => e
158
156
  puts "Performance analysis encountered error: #{e.message}"
159
157
  end
160
158
 
161
159
  # Example 5: Atomicity Validation
162
160
  puts "\n5. Atomicity Validation"
163
- puts "-" * 30
161
+ puts '-' * 30
164
162
 
165
163
  begin
166
164
  # Test atomic vs non-atomic operations
167
- acc6 = Account.new(account_id: "acc006", balance: "3000")
168
- acc7 = Account.new(account_id: "acc007", balance: "1000")
165
+ acc6 = Account.new(account_id: 'acc006', balance: '3000')
166
+ acc7 = Account.new(account_id: 'acc007', balance: '1000')
169
167
  acc6.save
170
168
  acc7.save
171
169
 
@@ -180,13 +178,12 @@ begin
180
178
  result = atomicity_validator.validate
181
179
 
182
180
  puts "Atomicity validation: #{result.valid? ? 'PASS ✅' : 'FAIL ❌'}"
183
-
184
- rescue => e
181
+ rescue StandardError => e
185
182
  puts "Atomicity validation encountered error: #{e.message}"
186
183
  end
187
184
 
188
185
  puts "\n6. Framework Architecture Overview"
189
- puts "-" * 30
186
+ puts '-' * 30
190
187
  puts "
191
188
  The Redis Command Validation Framework provides:
192
189
 
@@ -224,8 +221,8 @@ Key Benefits:
224
221
  "
225
222
 
226
223
  # Cleanup
227
- cleanup_keys = Familia.dbclient.keys("account:*")
224
+ cleanup_keys = Familia.dbclient.keys('account:*')
228
225
  Familia.dbclient.del(*cleanup_keys) if cleanup_keys.any?
229
226
 
230
227
  puts "\n🎉 Demo complete! The validation framework is ready for use."
231
- puts " See try/validation/ for comprehensive test examples."
228
+ puts ' See try/validation/ for comprehensive test examples.'
@@ -17,11 +17,11 @@ class User < Familia::Horreum
17
17
  field :user_id
18
18
  field :email
19
19
  field :name
20
- field :role # admin, editor, viewer, guest
20
+ field :role # admin, editor, viewer, guest
21
21
  field :created_at
22
22
 
23
- sorted_set :documents # Documents this user can access
24
- sorted_set :recent_activity # Recent document access
23
+ sorted_set :documents # Documents this user can access
24
+ sorted_set :recent_activity # Recent document access
25
25
  end
26
26
 
27
27
  class Document < Familia::Horreum
@@ -39,10 +39,10 @@ class Document < Familia::Horreum
39
39
  field :content
40
40
  field :created_at
41
41
  field :updated_at
42
- field :document_type # public, private, confidential
42
+ field :document_type # public, private, confidential
43
43
 
44
- sorted_set :collaborators # Users with access to this document
45
- list :audit_log # Track permission changes and access
44
+ sorted_set :collaborators # Users with access to this document
45
+ list :audit_log # Track permission changes and access
46
46
 
47
47
  # Add document to user's collection with specific permissions
48
48
  def share_with_user(user, *permissions)
@@ -78,7 +78,7 @@ class Document < Familia::Horreum
78
78
 
79
79
  # Get users with specific permission level or higher
80
80
  def users_with_permission(*required_permissions)
81
- all_permissions.select do |user_id, user_perms|
81
+ all_permissions.select do |_user_id, user_perms|
82
82
  required_permissions.all? { |perm| user_perms.include?(perm) }
83
83
  end.keys
84
84
  end
@@ -102,7 +102,7 @@ class Document < Familia::Horreum
102
102
  active_users: active_users,
103
103
  total_collaborators: collaborators.size,
104
104
  permission_breakdown: all_permissions,
105
- audit_entries: audit_log.range(0, 50)
105
+ audit_entries: audit_log.range(0, 50),
106
106
  }
107
107
  end
108
108
  end
@@ -113,10 +113,10 @@ class DocumentService
113
113
  ROLE_PERMISSIONS = {
114
114
  guest: [:read],
115
115
  viewer: [:read],
116
- commenter: [:read, :append],
117
- editor: [:read, :write, :edit],
118
- reviewer: [:read, :write, :edit, :delete],
119
- admin: [:read, :write, :edit, :delete, :configure, :transfer, :admin]
116
+ commenter: %i[read append],
117
+ editor: %i[read write edit],
118
+ reviewer: %i[read write edit delete],
119
+ admin: %i[read write edit delete configure transfer admin],
120
120
  }.freeze
121
121
 
122
122
  def self.create_document(owner, title, content, doc_type = 'private')
@@ -164,7 +164,7 @@ class DocumentService
164
164
 
165
165
  documents.each do |doc|
166
166
  users.each do |user|
167
- doc.revoke_access(user) # Clear existing
167
+ doc.revoke_access(user) # Clear existing
168
168
  doc.share_with_user(user, *permissions) if permissions
169
169
  end
170
170
  end
@@ -173,8 +173,8 @@ end
173
173
 
174
174
  # Example Usage and Demonstration
175
175
  if __FILE__ == $0
176
- puts "🚀 Familia Bit Encoding Integration Example"
177
- puts "=" * 50
176
+ puts '🚀 Familia Bit Encoding Integration Example'
177
+ puts '=' * 50
178
178
 
179
179
  # Create users
180
180
  alice = User.new(user_id: 'alice', email: 'alice@company.com', name: 'Alice Smith', role: 'admin')
@@ -182,9 +182,9 @@ if __FILE__ == $0
182
182
  charlie = User.new(user_id: 'charlie', email: 'charlie@company.com', name: 'Charlie Brown', role: 'viewer')
183
183
 
184
184
  # Create documents
185
- doc1 = DocumentService.create_document(alice, "Q4 Financial Report", "Confidential financial data...", 'confidential')
186
- doc2 = DocumentService.create_document(alice, "Team Meeting Notes", "Weekly standup notes...", 'private')
187
- doc3 = DocumentService.create_document(bob, "Project Proposal", "New feature proposal...", 'public')
185
+ doc1 = DocumentService.create_document(alice, 'Q4 Financial Report', 'Confidential financial data...', 'confidential')
186
+ doc2 = DocumentService.create_document(alice, 'Team Meeting Notes', 'Weekly standup notes...', 'private')
187
+ doc3 = DocumentService.create_document(bob, 'Project Proposal', 'New feature proposal...', 'public')
188
188
 
189
189
  # Share documents with different permission levels
190
190
  puts "\n📄 Document Sharing:"
@@ -209,14 +209,14 @@ if __FILE__ == $0
209
209
  analytics = doc1.access_analytics
210
210
  puts "Financial Report - Active Users: #{analytics[:active_users].size}"
211
211
  puts "Total Collaborators: #{analytics[:total_collaborators]}"
212
- puts "Permission Breakdown:"
212
+ puts 'Permission Breakdown:'
213
213
  analytics[:permission_breakdown].each do |user_id, perms|
214
214
  puts " #{user_id}: #{perms.join(', ')}"
215
215
  end
216
216
 
217
217
  # Demonstrate bit encoding efficiency
218
218
  puts "\n⚡ Bit Encoding Efficiency:"
219
- score = Familia::Features::Relationships::ScoreEncoding.encode_score(Time.now, [:read, :write, :edit, :delete])
219
+ score = Familia::Features::Relationships::ScoreEncoding.encode_score(Time.now, %i[read write edit delete])
220
220
  decoded = Familia::Features::Relationships::ScoreEncoding.decode_score(score)
221
221
  puts "Encoded score: #{score}"
222
222
  puts "Decoded permissions: #{decoded[:permission_list].join(', ')}"
@@ -225,13 +225,16 @@ if __FILE__ == $0
225
225
  # Cleanup
226
226
  puts "\n🧹 Cleanup:"
227
227
  [alice, bob, charlie].each { |user| user.documents.clear }
228
- [doc1, doc2, doc3].each { |doc| doc.clear_all_permissions; doc.collaborators.clear }
228
+ [doc1, doc2, doc3].each do |doc|
229
+ doc.clear_all_permissions
230
+ doc.collaborators.clear
231
+ end
229
232
 
230
- puts "✅ Integration example completed successfully!"
233
+ puts '✅ Integration example completed successfully!'
231
234
  puts "\nThis demonstrates:"
232
- puts "• Fine-grained permission management with 8-bit encoding"
233
- puts "• Role-based access control with business logic"
234
- puts "• Time-based analytics and audit trails"
235
- puts "• Efficient Redis storage with sorted sets"
236
- puts "• Production-ready error handling and validation"
235
+ puts '• Fine-grained permission management with 8-bit encoding'
236
+ puts '• Role-based access control with business logic'
237
+ puts '• Time-based analytics and audit trails'
238
+ puts '• Efficient Redis storage with sorted sets'
239
+ puts '• Production-ready error handling and validation'
237
240
  end