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

๐Ÿงน Data Maintenance

  1. Housekeeping - Declarative cleanup chores for drifted field values

๐Ÿ› ๏ธ 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