Familia v2.0 Documentation

Welcome to the comprehensive documentation for Familia v2.0. This guide collection provides detailed explanations of all major features including security, connection management, architecture, and object relationships.

📖 Documentation Layers

  • Overview - Conceptual introduction and getting started
  • Technical Reference - Implementation patterns and technical details
  • This Guide Collection - Deep-dive topic guides with detailed prose and examples

📚 Guide Structure

🏗️ Architecture & System Design

  1. Feature System - Modular architecture with dependencies and autoloader patterns
  2. Feature System for Developers - Advanced feature development patterns
  3. Field System - Field definitions and data type mappings
  4. Logging - Logger configuration and database command logging

🔐 Security & Special Fields

  1. Encrypted Fields - Persistent encrypted storage with modular providers
  2. Transient Fields - Non-persistent secure data handling with RedactedString
  3. Encryption Guide - Legacy encryption documentation
  4. Object Identifiers - Automatic ID generation with configurable strategies
  5. External Identifiers - Integration with external systems and legacy data

🔗 Object Relationships

  1. Relationships - Object relationships and membership system
  2. Relationship Methods - Detailed method reference for relationships

⏱️ Time & Analytics Features

  1. Expiration - TTL management and cascading expiration
  2. Quantization - Time-based data bucketing for analytics
  3. Time Literals - Time manipulation and formatting utilities

🛠️ Implementation & Usage

  1. Optimized Loading - Reduce Redis commands by 50-96% for bulk object loading (new!)

🚀 Quick Start Examples

Encrypted Fields (Persistent)

class User < Familia::Horreum
  feature :encrypted_fields
  encrypted_field :secret_recipe
end

# Configure encryption
Familia.configure do |config|
  config.encryption_keys = { v1: ENV['FAMILIA_ENCRYPTION_KEY'] }
  config.current_key_version = :v1
end

user = User.new(secret_recipe: "donna's cookies")
user.save
user.secret_recipe  # => "donna's cookies" (automatically decrypted)

Feature System (Modular)

class Customer < Familia::Horreum
  feature :safe_dump       # API-safe serialization
  feature :expiration      # TTL support
  feature :encrypted_fields # Secure storage

  field :name, :email
  encrypted_field :api_key
  default_expiration 24.hours
  safe_dump_fields :name, :email
end

Connection Pooling (Performance)

# Configure connection provider for multi-database pooling
Familia.connection_provider = lambda do |uri|
  parsed = URI.parse(uri) # => URI::Redis
  pool_key = "#{parsed.host}:#{parsed.port}/#{parsed.db || 0}"

  @pools[pool_key] ||= ConnectionPool.new(size: 10) do
    Redis.new(host: parsed.host, port: parsed.port, db: parsed.db || 0)
  end

  @pools[pool_key].with { |conn| conn }
end

Object Relationships

class Customer < Familia::Horreum
  feature :relationships
  identifier_field :custid
  field :custid, :name, :email
  set :domains  # Customer collections
end

class Domain < Familia::Horreum
  feature :relationships
  identifier_field :domain_id
  field :domain_id, :name, :dns_zone
  participates_in Customer, :domains  # Bidirectional membership
end

# Create objects and establish relationships
customer = Customer.new(custid: "cust123", name: "Acme Corp")
domain = Domain.new(domain_id: "dom456", name: "acme.com")

# Ruby-like syntax for relationships
customer.domains << domain  # Clean collection syntax

# Query relationships
domain.in_customer_domains?(customer.custid)  # => true
customer.domains.member?(domain.identifier)   # => true

Object Identifiers (Auto-generation)

class Document < Familia::Horreum
  feature :object_identifier, generator: :uuid_v4
  field :title, :content
end

class Session < Familia::Horreum
  feature :object_identifier, generator: :hex
  field :user_id, :data
end

# Automatic ID generation
doc = Document.create(title: "My Document")
doc.objid  # => "f47ac10b-58cc-4372-a567-0e02b2c3d479"

session = Session.create(user_id: "123")
session.objid  # => "a1b2c3d4e5f6"

External Identifiers (Legacy Integration)

class ExternalUser < Familia::Horreum
  feature :external_identifier
  field :internal_id, :external_id, :name
end

# Map external system IDs to internal objects
user = ExternalUser.create(
  internal_id: SecureRandom.uuid,
  external_id: "ext_12345",
  name: "Legacy User"
)

# Find by external ID
found = ExternalUser.find_by_external_id("ext_12345")

Quantization (Analytics)

class MetricsBucket < Familia::Horreum
  feature :quantization
  field :metric_key, :value_count
  string :counter, quantize: [10.minutes, '%H:%M']
end

# Automatic time bucketing for analytics
MetricsBucket.record_event("page_view")  # Groups into 10-min buckets

Optimized Loading (Performance)

# Skip EXISTS check (50% reduction)
user = User.find_by_id(123, check_exists: false)

# Pipelined bulk loading (96% reduction for N objects)
 = customer..rangebyscore(start_time, end_time)
# => ["id1", "id2", ..., "id14"]  # 14 metadata objects

# Traditional: 28 Redis commands (14 EXISTS + 14 HGETALL)
 = .map { |id| Metadata.find_by_id(id) }

# Optimized: 1 pipelined batch with 14 HGETALL commands
 = Metadata.load_multi().compact