opaque_id 1.2.0 → 1.4.0

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.
@@ -0,0 +1,17 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
2
+ <defs>
3
+ <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#a855f7;stop-opacity:1" />
5
+ <stop offset="100%" style="stop-color:#c084fc;stop-opacity:1" />
6
+ </linearGradient>
7
+ </defs>
8
+
9
+ <!-- Background circle -->
10
+ <circle cx="16" cy="16" r="15" fill="#0a0a0a" stroke="url(#gradient)" stroke-width="2"/>
11
+
12
+ <!-- Letter O -->
13
+ <circle cx="16" cy="16" r="8" fill="none" stroke="url(#gradient)" stroke-width="2.5"/>
14
+
15
+ <!-- Inner dot -->
16
+ <circle cx="16" cy="16" r="3" fill="url(#gradient)"/>
17
+ </svg>
@@ -0,0 +1,65 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" width="1200" height="630">
2
+ <defs>
3
+ <linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#0a0a0a;stop-opacity:1" />
5
+ <stop offset="100%" style="stop-color:#1a1a1a;stop-opacity:1" />
6
+ </linearGradient>
7
+ <linearGradient id="textGradient" x1="0%" y1="0%" x2="100%" y2="0%">
8
+ <stop offset="0%" style="stop-color:#a855f7;stop-opacity:1" />
9
+ <stop offset="100%" style="stop-color:#c084fc;stop-opacity:1" />
10
+ </linearGradient>
11
+ </defs>
12
+
13
+ <!-- Background -->
14
+ <rect width="1200" height="630" fill="url(#bgGradient)"/>
15
+
16
+ <!-- Logo -->
17
+ <circle cx="150" cy="150" r="60" fill="none" stroke="url(#textGradient)" stroke-width="8"/>
18
+ <circle cx="150" cy="150" r="25" fill="url(#textGradient)"/>
19
+
20
+ <!-- Title -->
21
+ <text x="300" y="180" font-family="Arial, sans-serif" font-size="72" font-weight="bold" fill="url(#textGradient)">
22
+ OpaqueId
23
+ </text>
24
+
25
+ <!-- Subtitle -->
26
+ <text x="300" y="240" font-family="Arial, sans-serif" font-size="32" fill="#e0e0e0">
27
+ Documentation
28
+ </text>
29
+
30
+ <!-- Description -->
31
+ <text x="300" y="320" font-family="Arial, sans-serif" font-size="24" fill="#b0b0b0">
32
+ Generate cryptographically secure, collision-free opaque IDs
33
+ </text>
34
+ <text x="300" y="360" font-family="Arial, sans-serif" font-size="24" fill="#b0b0b0">
35
+ for ActiveRecord models
36
+ </text>
37
+
38
+ <!-- Features -->
39
+ <text x="300" y="420" font-family="Arial, sans-serif" font-size="18" fill="#808080">
40
+ • High Performance • Rails Integration • Secure Generation
41
+ </text>
42
+
43
+ <!-- URL -->
44
+ <text x="300" y="480" font-family="Arial, sans-serif" font-size="20" fill="#a855f7">
45
+ nyaggah.github.io/opaque_id
46
+ </text>
47
+
48
+ <!-- Code example -->
49
+ <rect x="800" y="200" width="350" height="200" fill="#1a1a1a" stroke="#333333" stroke-width="2" rx="8"/>
50
+ <text x="820" y="230" font-family="Monaco, monospace" font-size="16" fill="#e0e0e0">
51
+ class User &lt; ApplicationRecord
52
+ </text>
53
+ <text x="820" y="260" font-family="Monaco, monospace" font-size="16" fill="#e0e0e0">
54
+ include OpaqueId::Model
55
+ </text>
56
+ <text x="820" y="290" font-family="Monaco, monospace" font-size="16" fill="#e0e0e0">
57
+ end
58
+ </text>
59
+ <text x="820" y="330" font-family="Monaco, monospace" font-size="16" fill="#a855f7">
60
+ # user.opaque_id
61
+ </text>
62
+ <text x="820" y="360" font-family="Monaco, monospace" font-size="16" fill="#10b981">
63
+ # =&gt; "V1StGXR8_Z5jdHi6B-myT"
64
+ </text>
65
+ </svg>
@@ -0,0 +1,551 @@
1
+ ---
2
+ layout: default
3
+ title: Configuration
4
+ nav_order: 5
5
+ description: "Complete configuration guide with all options and examples"
6
+ permalink: /configuration/
7
+ ---
8
+
9
+ # Configuration
10
+
11
+ OpaqueId provides extensive configuration options to customize ID generation for your specific needs. This guide covers all available configuration options with practical examples.
12
+
13
+ - TOC
14
+ {:toc}
15
+
16
+ ## Model-Level Configuration
17
+
18
+ Configure OpaqueId on a per-model basis using class-level settings.
19
+
20
+ ### Basic Configuration
21
+
22
+ ```ruby
23
+ class User < ApplicationRecord
24
+ include OpaqueId::Model
25
+
26
+ # Custom column name
27
+ self.opaque_id_column = :public_id
28
+
29
+ # Custom length (default: 21)
30
+ self.opaque_id_length = 15
31
+
32
+ # Custom alphabet (default: ALPHANUMERIC_ALPHABET)
33
+ self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
34
+
35
+ # Require letter start (default: false)
36
+ self.opaque_id_require_letter_start = true
37
+
38
+ # Max retry attempts (default: 3)
39
+ self.opaque_id_max_retry = 5
40
+
41
+ # Characters to purge from generated IDs (default: [])
42
+ self.opaque_id_purge_chars = ['0', 'O', 'l', 'I']
43
+ end
44
+ ```
45
+
46
+ ### Configuration Options Reference
47
+
48
+ | Option | Type | Default | Description |
49
+ | -------------------------------- | ------- | ----------------------- | --------------------------------------------- |
50
+ | `opaque_id_column` | Symbol | `:opaque_id` | Column name for storing the opaque ID |
51
+ | `opaque_id_length` | Integer | `21` | Length of generated IDs |
52
+ | `opaque_id_alphabet` | String | `ALPHANUMERIC_ALPHABET` | Character set for ID generation |
53
+ | `opaque_id_require_letter_start` | Boolean | `false` | Require IDs to start with a letter |
54
+ | `opaque_id_max_retry` | Integer | `3` | Maximum retry attempts for collision handling |
55
+ | `opaque_id_purge_chars` | Array | `[]` | Characters to exclude from generated IDs |
56
+
57
+ ## Global Configuration
58
+
59
+ Configure OpaqueId globally using an initializer.
60
+
61
+ ### Basic Global Configuration
62
+
63
+ ```ruby
64
+ # config/initializers/opaque_id.rb
65
+ OpaqueId.configure do |config|
66
+ config.default_length = 15
67
+ config.default_alphabet = OpaqueId::STANDARD_ALPHABET
68
+ end
69
+ ```
70
+
71
+ ### Advanced Global Configuration
72
+
73
+ ```ruby
74
+ # config/initializers/opaque_id.rb
75
+ OpaqueId.configure do |config|
76
+ # Set default values for all models
77
+ config.default_length = 21
78
+ config.default_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
79
+
80
+ # Configure specific models
81
+ config.models = {
82
+ 'User' => {
83
+ length: 15,
84
+ alphabet: OpaqueId::STANDARD_ALPHABET,
85
+ require_letter_start: true
86
+ },
87
+ 'Order' => {
88
+ length: 12,
89
+ alphabet: OpaqueId::ALPHANUMERIC_ALPHABET,
90
+ column: :public_id
91
+ }
92
+ }
93
+ end
94
+ ```
95
+
96
+ ## Alphabet Configuration
97
+
98
+ ### Built-in Alphabets
99
+
100
+ #### ALPHANUMERIC_ALPHABET (Default)
101
+
102
+ ```ruby
103
+ # Characters: A-Z, a-z, 0-9 (62 characters)
104
+ # Use case: General purpose, URL-safe
105
+ # Example output: "V1StGXR8_Z5jdHi6B-myT"
106
+
107
+ class User < ApplicationRecord
108
+ include OpaqueId::Model
109
+ self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
110
+ end
111
+ ```
112
+
113
+ #### STANDARD_ALPHABET
114
+
115
+ ```ruby
116
+ # Characters: A-Z, a-z, 0-9, -, _ (64 characters)
117
+ # Use case: Fastest generation, URL-safe
118
+ # Example output: "V1StGXR8_Z5jdHi6B-myT"
119
+
120
+ class User < ApplicationRecord
121
+ include OpaqueId::Model
122
+ self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
123
+ end
124
+ ```
125
+
126
+ ### Custom Alphabets
127
+
128
+ #### Numeric Only
129
+
130
+ ```ruby
131
+ class Order < ApplicationRecord
132
+ include OpaqueId::Model
133
+
134
+ # Generate numeric-only IDs
135
+ self.opaque_id_alphabet = "0123456789"
136
+ self.opaque_id_length = 10
137
+ end
138
+
139
+ # Example output: "1234567890"
140
+ ```
141
+
142
+ #### Hexadecimal
143
+
144
+ ```ruby
145
+ class ApiKey < ApplicationRecord
146
+ include OpaqueId::Model
147
+
148
+ # Generate hexadecimal IDs
149
+ self.opaque_id_alphabet = "0123456789abcdef"
150
+ self.opaque_id_length = 16
151
+ end
152
+
153
+ # Example output: "a1b2c3d4e5f67890"
154
+ ```
155
+
156
+ #### URL-Safe Characters
157
+
158
+ ```ruby
159
+ class Article < ApplicationRecord
160
+ include OpaqueId::Model
161
+
162
+ # Generate URL-safe IDs
163
+ self.opaque_id_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
164
+ self.opaque_id_length = 8
165
+ end
166
+
167
+ # Example output: "V1StGXR8"
168
+ ```
169
+
170
+ #### Base64-Style
171
+
172
+ ```ruby
173
+ class Document < ApplicationRecord
174
+ include OpaqueId::Model
175
+
176
+ # Generate Base64-style IDs
177
+ self.opaque_id_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
178
+ self.opaque_id_length = 12
179
+ end
180
+
181
+ # Example output: "V1StGXR8_Z5j"
182
+ ```
183
+
184
+ ## Length Configuration
185
+
186
+ ### Short IDs (8-12 characters)
187
+
188
+ ```ruby
189
+ class ShortUrl < ApplicationRecord
190
+ include OpaqueId::Model
191
+
192
+ # Short IDs for URLs
193
+ self.opaque_id_length = 8
194
+ self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
195
+ end
196
+
197
+ # Example output: "V1StGXR8"
198
+ ```
199
+
200
+ ### Medium IDs (15-21 characters)
201
+
202
+ ```ruby
203
+ class User < ApplicationRecord
204
+ include OpaqueId::Model
205
+
206
+ # Standard length for general use
207
+ self.opaque_id_length = 21
208
+ self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
209
+ end
210
+
211
+ # Example output: "V1StGXR8_Z5jdHi6B-myT"
212
+ ```
213
+
214
+ ### Long IDs (32+ characters)
215
+
216
+ ```ruby
217
+ class ApiKey < ApplicationRecord
218
+ include OpaqueId::Model
219
+
220
+ # Long IDs for sensitive data
221
+ self.opaque_id_length = 32
222
+ self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
223
+ end
224
+
225
+ # Example output: "V1StGXR8_Z5jdHi6B-myT1234567890"
226
+ ```
227
+
228
+ ## Column Name Configuration
229
+
230
+ ### Custom Column Names
231
+
232
+ ```ruby
233
+ class User < ApplicationRecord
234
+ include OpaqueId::Model
235
+
236
+ # Use a different column name
237
+ self.opaque_id_column = :public_id
238
+ end
239
+
240
+ # Now the methods use the custom column name
241
+ user = User.create!(name: "John Doe")
242
+ puts user.public_id
243
+ # => "V1StGXR8_Z5jdHi6B-myT"
244
+
245
+ user = User.find_by_public_id("V1StGXR8_Z5jdHi6B-myT")
246
+ ```
247
+
248
+ ### Multiple Column Names
249
+
250
+ ```ruby
251
+ class User < ApplicationRecord
252
+ include OpaqueId::Model
253
+ self.opaque_id_column = :public_id
254
+ end
255
+
256
+ class Order < ApplicationRecord
257
+ include OpaqueId::Model
258
+ self.opaque_id_column = :order_number
259
+ end
260
+
261
+ class Product < ApplicationRecord
262
+ include OpaqueId::Model
263
+ self.opaque_id_column = :sku
264
+ end
265
+ ```
266
+
267
+ ## Validation Configuration
268
+
269
+ ### Letter Start Requirement
270
+
271
+ ```ruby
272
+ class User < ApplicationRecord
273
+ include OpaqueId::Model
274
+
275
+ # Require IDs to start with a letter
276
+ self.opaque_id_require_letter_start = true
277
+ end
278
+
279
+ # This will retry until it generates an ID starting with a letter
280
+ user = User.create!(name: "John Doe")
281
+ puts user.opaque_id
282
+ # => "V1StGXR8_Z5jdHi6B-myT" (starts with 'V')
283
+ ```
284
+
285
+ ### Character Purging
286
+
287
+ ```ruby
288
+ class User < ApplicationRecord
289
+ include OpaqueId::Model
290
+
291
+ # Exclude confusing characters
292
+ self.opaque_id_purge_chars = ['0', 'O', 'l', 'I']
293
+ end
294
+
295
+ # Generated IDs will not contain these characters
296
+ user = User.create!(name: "John Doe")
297
+ puts user.opaque_id
298
+ # => "V1StGXR8_Z5jdHi6B-myT" (no '0', 'O', 'l', 'I')
299
+ ```
300
+
301
+ ## Collision Handling Configuration
302
+
303
+ ### Retry Attempts
304
+
305
+ ```ruby
306
+ class User < ApplicationRecord
307
+ include OpaqueId::Model
308
+
309
+ # Increase retry attempts for high-volume applications
310
+ self.opaque_id_max_retry = 10
311
+ end
312
+ ```
313
+
314
+ ### Custom Collision Handling
315
+
316
+ ```ruby
317
+ class User < ApplicationRecord
318
+ include OpaqueId::Model
319
+
320
+ private
321
+
322
+ def set_opaque_id
323
+ retries = 0
324
+ max_retries = opaque_id_max_retry
325
+
326
+ begin
327
+ self.opaque_id = generate_opaque_id
328
+ rescue OpaqueId::GenerationError => e
329
+ retries += 1
330
+ if retries < max_retries
331
+ retry
332
+ else
333
+ # Custom fallback logic
334
+ self.opaque_id = generate_fallback_id
335
+ end
336
+ end
337
+ end
338
+
339
+ def generate_fallback_id
340
+ # Fallback generation method
341
+ "fallback_#{SecureRandom.hex(10)}"
342
+ end
343
+ end
344
+ ```
345
+
346
+ ## Environment-Specific Configuration
347
+
348
+ ### Development Environment
349
+
350
+ ```ruby
351
+ # config/environments/development.rb
352
+ if Rails.env.development?
353
+ OpaqueId.configure do |config|
354
+ # Shorter IDs for development
355
+ config.default_length = 8
356
+ config.default_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
357
+ end
358
+ end
359
+ ```
360
+
361
+ ### Production Environment
362
+
363
+ ```ruby
364
+ # config/environments/production.rb
365
+ if Rails.env.production?
366
+ OpaqueId.configure do |config|
367
+ # Longer IDs for production
368
+ config.default_length = 21
369
+ config.default_alphabet = OpaqueId::STANDARD_ALPHABET
370
+ end
371
+ end
372
+ ```
373
+
374
+ ### Test Environment
375
+
376
+ ```ruby
377
+ # config/environments/test.rb
378
+ if Rails.env.test?
379
+ OpaqueId.configure do |config|
380
+ # Predictable IDs for testing
381
+ config.default_length = 10
382
+ config.default_alphabet = "0123456789"
383
+ end
384
+ end
385
+ ```
386
+
387
+ ## Configuration Examples by Use Case
388
+
389
+ ### E-commerce Application
390
+
391
+ ```ruby
392
+ # Orders - short, numeric IDs
393
+ class Order < ApplicationRecord
394
+ include OpaqueId::Model
395
+
396
+ self.opaque_id_column = :order_number
397
+ self.opaque_id_length = 8
398
+ self.opaque_id_alphabet = "0123456789"
399
+ end
400
+
401
+ # Products - medium, alphanumeric IDs
402
+ class Product < ApplicationRecord
403
+ include OpaqueId::Model
404
+
405
+ self.opaque_id_column = :sku
406
+ self.opaque_id_length = 12
407
+ self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
408
+ end
409
+
410
+ # Users - standard IDs
411
+ class User < ApplicationRecord
412
+ include OpaqueId::Model
413
+
414
+ self.opaque_id_length = 21
415
+ self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
416
+ end
417
+ ```
418
+
419
+ ### API Development
420
+
421
+ ```ruby
422
+ # API Keys - long, secure IDs
423
+ class ApiKey < ApplicationRecord
424
+ include OpaqueId::Model
425
+
426
+ self.opaque_id_length = 32
427
+ self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
428
+ self.opaque_id_require_letter_start = true
429
+ end
430
+
431
+ # API Tokens - medium, URL-safe IDs
432
+ class ApiToken < ApplicationRecord
433
+ include OpaqueId::Model
434
+
435
+ self.opaque_id_column = :token
436
+ self.opaque_id_length = 24
437
+ self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
438
+ end
439
+ ```
440
+
441
+ ### Content Management
442
+
443
+ ```ruby
444
+ # Articles - short, URL-friendly IDs
445
+ class Article < ApplicationRecord
446
+ include OpaqueId::Model
447
+
448
+ self.opaque_id_column = :slug
449
+ self.opaque_id_length = 8
450
+ self.opaque_id_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
451
+ end
452
+
453
+ # Comments - standard IDs
454
+ class Comment < ApplicationRecord
455
+ include OpaqueId::Model
456
+
457
+ self.opaque_id_length = 15
458
+ self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
459
+ end
460
+ ```
461
+
462
+ ## Configuration Validation
463
+
464
+ ### Validate Configuration
465
+
466
+ ```ruby
467
+ class User < ApplicationRecord
468
+ include OpaqueId::Model
469
+
470
+ validate :validate_opaque_id_configuration
471
+
472
+ private
473
+
474
+ def validate_opaque_id_configuration
475
+ if opaque_id_length < 8
476
+ errors.add(:base, "Opaque ID length must be at least 8 characters")
477
+ end
478
+
479
+ if opaque_id_alphabet.size < 16
480
+ errors.add(:base, "Opaque ID alphabet must have at least 16 characters")
481
+ end
482
+
483
+ if opaque_id_max_retry < 1
484
+ errors.add(:base, "Opaque ID max retry must be at least 1")
485
+ end
486
+ end
487
+ end
488
+ ```
489
+
490
+ ### Configuration Testing
491
+
492
+ ```ruby
493
+ # test/models/user_test.rb
494
+ class UserTest < ActiveSupport::TestCase
495
+ test "opaque_id configuration is valid" do
496
+ user = User.new(name: "Test User")
497
+
498
+ assert user.valid?
499
+ assert_equal 21, user.class.opaque_id_length
500
+ assert_equal OpaqueId::ALPHANUMERIC_ALPHABET, user.class.opaque_id_alphabet
501
+ end
502
+
503
+ test "opaque_id generation works with custom configuration" do
504
+ user = User.new(name: "Test User")
505
+ user.class.opaque_id_length = 15
506
+ user.class.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
507
+
508
+ user.save!
509
+
510
+ assert_equal 15, user.opaque_id.length
511
+ assert user.opaque_id.match?(/\A[A-Za-z0-9_-]+\z/)
512
+ end
513
+ end
514
+ ```
515
+
516
+ ## Best Practices
517
+
518
+ ### 1. Choose Appropriate Length
519
+
520
+ - **Short IDs (8-12)**: Public URLs, user-facing identifiers
521
+ - **Medium IDs (15-21)**: General purpose, internal references
522
+ - **Long IDs (32+)**: Sensitive data, API keys, tokens
523
+
524
+ ### 2. Select Suitable Alphabets
525
+
526
+ - **ALPHANUMERIC_ALPHABET**: General purpose, URL-safe
527
+ - **STANDARD_ALPHABET**: Fastest generation, URL-safe
528
+ - **Custom alphabets**: Specific requirements (numeric, hexadecimal, etc.)
529
+
530
+ ### 3. Configure Collision Handling
531
+
532
+ - **Low volume**: Default retry attempts (3)
533
+ - **High volume**: Increase retry attempts (5-10)
534
+ - **Critical systems**: Implement custom fallback logic
535
+
536
+ ### 4. Use Environment-Specific Settings
537
+
538
+ - **Development**: Shorter IDs for easier testing
539
+ - **Production**: Longer IDs for better security
540
+ - **Test**: Predictable IDs for consistent testing
541
+
542
+ ## Next Steps
543
+
544
+ Now that you understand configuration options:
545
+
546
+ 1. **Explore [Alphabets](alphabets.md)** for detailed alphabet information
547
+ 2. **Check out [Use Cases](use-cases.md)** for real-world configuration examples
548
+ 3. **Review [Performance](performance.md)** for configuration optimization tips
549
+ 4. **Read [API Reference](api-reference.md)** for complete configuration documentation
550
+ 5. **Learn about [Algorithms](algorithms.md)** for technical implementation details
551
+ 6. **Understand [Security](security.md)** for security considerations