corteq 0.1.0

Enterprise-grade multi-tenant SaaS framework for Rust with security-first design
Documentation
//! Domain models for Corteq framework

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// Tenant domain model
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
pub struct Tenant {
    /// Unique identifier for the tenant
    pub id: Uuid,

    /// Human-readable name
    pub name: String,

    /// URL-safe slug for routing
    pub slug: String,

    /// Reference to encryption key for tenant data
    pub encryption_key_id: String,

    /// When the tenant was created
    pub created_at: DateTime<Utc>,

    /// When the tenant was last updated
    pub updated_at: DateTime<Utc>,

    /// Soft delete timestamp (None if active)
    pub deleted_at: Option<DateTime<Utc>>,
}

/// Tenant context extracted from request
///
/// This is the core security primitive that ensures all operations
/// are scoped to a specific tenant. Every request must have a valid
/// TenantContext to access tenant-scoped resources.
#[derive(Debug, Clone)]
pub struct TenantContext {
    /// The tenant ID
    pub tenant_id: Uuid,

    /// The tenant slug for routing/display
    pub tenant_slug: String,

    /// Encryption key ID for this tenant's data
    pub encryption_key_id: String,
}

impl TenantContext {
    /// Create a new tenant context
    pub fn new(tenant_id: Uuid, tenant_slug: String, encryption_key_id: String) -> Self {
        Self {
            tenant_id,
            tenant_slug,
            encryption_key_id,
        }
    }
}

impl From<Tenant> for TenantContext {
    fn from(tenant: Tenant) -> Self {
        Self {
            tenant_id: tenant.id,
            tenant_slug: tenant.slug,
            encryption_key_id: tenant.encryption_key_id,
        }
    }
}