Elysia Tools

Browse tools, examples, visual explainers, and topic guides from one clear workspace.

Top Categories

Hubs

Language
ZHDERUPTENFRES

Elysia Tools

Navigation

Architecture

Multi-Tenant Architecture Samples

Comprehensive multi-tenant architecture patterns covering data isolation, tenant management, resource quotas, and white-label solutions

Samples

Entries inside this sample collection

CodeComplex

Data Isolation Strategies

Implementing different data isolation patterns for multi-tenant applications

Difficulty

8/10

Estimated time

45 min

Tags

data-isolation, database-strategies, multi-tenant-architecture

Prerequisites

Database design knowledge, Multi-tenancy concepts

plaintext

// Multi-Tenant Data Isolation Patterns

// Tenant Context
interface TenantContext {
  tenantId: string
  tenantName: string
  domain: string
  plan: 'basic' | 'premium' | 'enterprise'
  settings: TenantSettings
  createdAt: Date
}

interface TenantSettings {
  timezone: string
  currency: string
  locale: string
  features: Record<string, boolean>
  limits: ResourceLimits
}

interface ResourceLimits {
  maxUsers: number
  maxStorage: number // in GB
  maxApiCalls: number
  maxProjects: number
}

// Strategy 1: Database per Tenant (Complete Isolation)
class DatabasePerTenantStrategy {
  private connections: Map<string, any> = new Map()

  constructor(private connectionStringTemplate: string) {
    // Template: "postgresql://user:password@localhost/tenant_{tenant_id}_db"
  }

  async getConnection(tenantId: string): Promise<any> {
    let connection = this.connections.get(tenantId)

    if (!connection) {
      const connectionString = this.connectionStringTemplate.replace('{tenant_id}', tenantId)
      connection = await this.createConnection(connectionString)
      this.connections.set(tenantId, connection)
    }

    return connection
  }

  private async createConnection(connectionString: string): Promise<any> {
    // Simulated database connection
    console.log(`Creating connection to: ${connectionString}`)
    return {
      query: async (sql: string, params?: any[]) => {
        console.log(`[${this.extractTenantId(connectionString)}] Executing: ${sql}`, params || [])
        return { rows: [], rowCount: 0 }
      },
      close: async () => {
        console.log(`Closing connection: ${connectionString}`)
      }
    }
  }

  private extractTenantId(connectionString: string): string {
    const match = connectionString.match(/tenant_(.+?)_db/)
    return match ? match[1] : 'unknown'
  }

  async createTenantDatabase(tenantId: string, schema: string): Promise<void> {
    console.log(`Creating database schema for tenant ${tenantId}`)
    // In real implementation, would execute SQL CREATE DATABASE and schema setup
  }

  async dropTenantDatabase(tenantId: string): Promise<void> {
    console.log(`Dropping database for tenant ${tenantId}`)
    const connection = this.connections.get(tenantId)
    if (connection) {
      await connection.close()
      this.connections.delete(tenantId)
    }
  }
}

// Strategy 2: Schema per Tenant (Shared Database)
class SchemaPerTenantStrategy {
  private connection: any
  private tenantSchemas: Set<string> = new Set()
  private initialized: Promise<void>

  constructor(private connectionString: string) {
    this.initialized = this.initializeConnection()
  }

  private async initializeConnection(): Promise<void> {
    this.connection = {
      query: async (sql: string, params?: any[]) => {
        console.log(`Executing: ${sql}`, params || [])
        return { rows: [], rowCount: 0 }
      }
    }
  }

  async getConnection(tenantId: string): Promise<any> {
    await this.initialized
    const schemaName = `tenant_${tenantId}`

    if (!this.tenantSchemas.has(tenantId)) {
      await this.createTenantSchema(tenantId)
    }

    return {
      query: async (sql: string, params?: any[]) => {
        const schemaSql = sql.replace(/FROM\s+(\w+)/gi, `FROM ${schemaName}.$1`)
        const schemaSql2 = schemaSql.replace(/INSERT\s+INTO\s+(\w+)/gi, `INSERT INTO ${schemaName}.$1`)
        const schemaSql3 = schemaSql2.replace(/UPDATE\s+(\w+)/gi, `UPDATE ${schemaName}.$1`)
        const finalSql = schemaSql3.replace(/DELETE\s+FROM\s+(\w+)/gi, `DELETE FROM ${schemaName}.$1`)

        console.log(`[${schemaName}] ${finalSql}`, params || [])
        return { rows: [], rowCount: 0 }
      }
    }
  }

  async createTenantSchema(tenantId: string): Promise<void> {
    const schemaName = `tenant_${tenantId}`
    console.log(`Creating schema ${schemaName}`)

    // Simulate schema creation
    await this.connection.query(`CREATE SCHEMA IF NOT EXISTS ${schemaName}`)

    // Create tables in schema
    const tables = [
      `CREATE TABLE IF NOT EXISTS ${schemaName}.users (id SERIAL PRIMARY KEY, name VARCHAR(255))`,
      `CREATE TABLE IF NOT EXISTS ${schemaName}.products (id SERIAL PRIMARY KEY, name VARCHAR(255), price DECIMAL)`
    ]

    for (const tableSql of tables) {
      await this.connection.query(tableSql)
    }

    this.tenantSchemas.add(tenantId)
  }

  async dropTenantSchema(tenantId: string): Promise<void> {
    const schemaName = `tenant_${tenantId}`
    console.log(`Dropping schema ${schemaName}`)
    await this.connection.query(`DROP SCHEMA IF EXISTS ${schemaName} CASCADE`)
    this.tenantSchemas.delete(tenantId)
  }
}

// Strategy 3: Shared Table with Tenant Column (Row-Level Security)
class SharedTableStrategy {
  private connection: any
  private tenantContext: TenantContext | null = null

  constructor(connectionString: string) {
    this.initializeConnection(connectionString)
  }

  private async initializeConnection(connectionString: string): Promise<void> {
    this.connection = {
      query: async (sql: string, params?: any[]) => {
        console.log(`[Shared] ${sql}`, params || [])
        return { rows: [], rowCount: 0 }
      }
    }

    // Enable row-level security
    await this.setupRowLevelSecurity()
  }

  setTenantContext(tenant: TenantContext): void {
    this.tenantContext = tenant
  }

  async query(sql: string, params?: any[]): Promise<any> {
    if (!this.tenantContext) {
      throw new Error('Tenant context not set')
    }

    // Add tenant filter to all queries
    let tenantAwareSql = sql

    // Add WHERE clause for tenant_id if not present
    if (!sql.toLowerCase().includes('tenant_id')) {
      if (sql.toLowerCase().includes('where')) {
        tenantAwareSql = sql.replace(/where/gi, `WHERE tenant_id = '${this.tenantContext.tenantId}' AND`)
      } else if (sql.toLowerCase().includes('from') && !sql.toLowerCase().includes('update') && !sql.toLowerCase().includes('delete')) {
        tenantAwareSql = sql.replace(/from\s+(\w+)/gi, `FROM $1 WHERE tenant_id = '${this.tenantContext.tenantId}'`)
      }
    }

    // Automatically add tenant_id to INSERT statements
    if (sql.toLowerCase().startsWith('insert')) {
      const hasTenantId = sql.toLowerCase().includes('tenant_id')
      if (!hasTenantId) {
        const valuesMatch = sql.match(/VALUES\s*\((.*?)\)/i)
        if (valuesMatch) {
          const existingValues = valuesMatch[1]
          const newValues = existingValues ? `${existingValues}, '${this.tenantContext.tenantId}'` : `'${this.tenantContext.tenantId}'`
          tenantAwareSql = sql.replace(/values\s*\((.*?)\)/i, `VALUES (${newValues})`)

          // Add tenant_id to column list
          tenantAwareSql = tenantAwareSql.replace(/insert\s+into\s+(\w+)\s*\((.*?)\)/i, (match, table, columns) => {
            if (columns) {
              return `INSERT INTO ${table} (${columns}, tenant_id)`
            }
            return match
          })
        }
      }
    }

    return await this.connection.query(tenantAwareSql, params)
  }

  private async setupRowLevelSecurity(): Promise<void> {
    console.log('Setting up row-level security policies')

    // Simulate RLS setup
    const policies = [
      'CREATE POLICY tenant_isolation ON users FOR ALL TO application_user USING (tenant_id = current_setting('app.current_tenant_id')::uuid)',
      'CREATE POLICY tenant_isolation ON products FOR ALL TO application_user USING (tenant_id = current_setting('app.current_tenant_id')::uuid)'
    ]

    for (const policy of policies) {
      await this.connection.query(policy)
    }
  }

  async createTenant(tenant: TenantContext): Promise<void> {
    // Create tenant-specific views or triggers if needed
    console.log(`Setting up tenant ${tenant.tenantId} in shared database`)
  }

  async removeTenant(tenantId: string): Promise<void> {
    // Soft delete or archive tenant data
    await this.connection.query(
      `UPDATE users SET deleted_at = NOW() WHERE tenant_id = $1`,
      [tenantId]
    )
  }
}

// Strategy 4: Hybrid Approach (Based on tenant plan)
class HybridDataIsolationStrategy {
  private databaseStrategy: DatabasePerTenantStrategy
  private schemaStrategy: SchemaPerTenantStrategy
  private sharedStrategy: SharedTableStrategy

  constructor() {
    this.databaseStrategy = new DatabasePerTenantStrategy('postgresql://user:password@localhost/tenant_{tenant_id}_db')
    this.schemaStrategy = new SchemaPerTenantStrategy('postgresql://user:password@localhost/multi_tenant_db')
    this.sharedStrategy = new SharedTableStrategy('postgresql://user:password@localhost/multi_tenant_db')
  }

  async getConnection(tenant: TenantContext): Promise<any> {
    switch (tenant.plan) {
      case 'enterprise':
        return await this.databaseStrategy.getConnection(tenant.tenantId)

      case 'premium':
        return await this.schemaStrategy.getConnection(tenant.tenantId)

      case 'basic':
        this.sharedStrategy.setTenantContext(tenant)
        return this.sharedStrategy

      default:
        throw new Error(`Unknown tenant plan: ${tenant.plan}`)
    }
  }

  async createTenant(tenant: TenantContext): Promise<void> {
    switch (tenant.plan) {
      case 'enterprise':
        await this.databaseStrategy.createTenantDatabase(tenant.tenantId, 'enterprise_schema')
        break

      case 'premium':
        await this.schemaStrategy.createTenantSchema(tenant.tenantId)
        break

      case 'basic':
        await this.sharedStrategy.createTenant(tenant)
        break
    }
  }

  async removeTenant(tenantId: string, plan: string): Promise<void> {
    switch (plan) {
      case 'enterprise':
        await this.databaseStrategy.dropTenantDatabase(tenantId)
        break

      case 'premium':
        await this.schemaStrategy.dropTenantSchema(tenantId)
        break

      case 'basic':
        await this.sharedStrategy.removeTenant(tenantId)
        break
    }
  }

  async getTenantDataUsage(tenant: TenantContext): Promise<{
    storageUsed: number
    recordCount: number
    databaseSize: number
  }> {
    const connection = await this.getConnection(tenant)

    // Simulate data usage query
    const usage = {
      storageUsed: Math.floor(Math.random() * 100), // GB
      recordCount: Math.floor(Math.random() * 1000000),
      databaseSize: Math.floor(Math.random() * 1000) // MB
    }

    console.log(`Tenant ${tenant.tenantId} usage:`, usage)
    return usage
  }
}

// Data Migration between Strategies
class DataMigrationService {
  async migrateTenant(
    fromStrategy: string,
    toStrategy: string,
    tenant: TenantContext
  ): Promise<{
    success: boolean
    recordsMigrated: number
    duration: number
    errors: string[]
  }> {
    const startTime = Date.now()
    const errors: string[] = []
    let recordsMigrated = 0

    console.log(`Starting migration for tenant ${tenant.tenantId} from ${fromStrategy} to ${toStrategy}`)

    try {
      // Simulate migration process
      const tables = ['users', 'products', 'orders']

      for (const table of tables) {
        console.log(`Migrating table: ${table}`)

        // Simulate data extraction and loading
        const recordCount = Math.floor(Math.random() * 10000)
        recordsMigrated += recordCount

        // Simulate processing time
        await new Promise(resolve => setTimeout(resolve, 100))
      }

      console.log(`Migration completed successfully. Records migrated: ${recordsMigrated}`)
    } catch (error) {
      errors.push(error instanceof Error ? error.message : 'Unknown error')
      console.error(`Migration failed:`, errors)
    }

    const duration = Date.now() - startTime

    return {
      success: errors.length === 0,
      recordsMigrated,
      duration,
      errors
    }
  }

  async validateMigration(
    sourceTenant: TenantContext,
    targetTenant: TenantContext
  ): Promise<{
    isValid: boolean
    discrepancies: Array<{
      table: string
      sourceCount: number
      targetCount: number
      difference: number
    }>
  }> {
    console.log(`Validating migration from ${sourceTenant.tenantId} to ${targetTenant.tenantId}`)

    // Simulate validation
    const tables = ['users', 'products', 'orders']
    const discrepancies = []

    for (const table of tables) {
      const sourceCount = Math.floor(Math.random() * 10000)
      const targetCount = sourceCount + Math.floor(Math.random() * 10) - 5 // Small random difference
      const difference = Math.abs(sourceCount - targetCount)

      if (difference > 0) {
        discrepancies.push({
          table,
          sourceCount,
          targetCount,
          difference
        })
      }
    }

    return {
      isValid: discrepancies.length === 0,
      discrepancies
    }
  }
}

// Performance Monitoring for Multi-Tenant Systems
class MultiTenantPerformanceMonitor {
  private queryMetrics: Map<string, Array<{ duration: number; timestamp: Date }>> = new Map()
  private connectionMetrics: Map<string, { active: number; total: number; errors: number }> = new Map()

  recordQuery(tenantId: string, duration: number): void {
    if (!this.queryMetrics.has(tenantId)) {
      this.queryMetrics.set(tenantId, [])
    }

    const metrics = this.queryMetrics.get(tenantId)!
    metrics.push({ duration, timestamp: new Date() })

    // Keep only last 1000 queries per tenant
    if (metrics.length > 1000) {
      metrics.shift()
    }
  }

  recordConnection(tenantId: string, isActive: boolean, isError: boolean = false): void {
    if (!this.connectionMetrics.has(tenantId)) {
      this.connectionMetrics.set(tenantId, { active: 0, total: 0, errors: 0 })
    }

    const metrics = this.connectionMetrics.get(tenantId)!

    if (isActive) {
      metrics.active++
    } else {
      metrics.active = Math.max(0, metrics.active - 1)
    }

    metrics.total++
    if (isError) {
      metrics.errors++
    }
  }

  getTenantMetrics(tenantId: string): {
    avgQueryTime: number
    totalQueries: number
    activeConnections: number
    errorRate: number
  } {
    const queryMetrics = this.queryMetrics.get(tenantId) || []
    const connectionMetrics = this.connectionMetrics.get(tenantId) || { active: 0, total: 0, errors: 0 }

    const avgQueryTime = queryMetrics.length > 0
      ? queryMetrics.reduce((sum, m) => sum + m.duration, 0) / queryMetrics.length
      : 0

    const errorRate = connectionMetrics.total > 0
      ? connectionMetrics.errors / connectionMetrics.total
      : 0

    return {
      avgQueryTime,
      totalQueries: queryMetrics.length,
      activeConnections: connectionMetrics.active,
      errorRate
    }
  }

  identifySlowTenants(thresholdMs: number = 1000): Array<{
    tenantId: string
    avgQueryTime: number
    totalQueries: number
  }> {
    const slowTenants: Array<{
      tenantId: string
      avgQueryTime: number
      totalQueries: number
    }> = []

    for (const [tenantId, queryMetrics] of this.queryMetrics.entries()) {
      if (queryMetrics.length === 0) continue

      const avgQueryTime = queryMetrics.reduce((sum, m) => sum + m.duration, 0) / queryMetrics.length

      if (avgQueryTime > thresholdMs) {
        slowTenants.push({
          tenantId,
          avgQueryTime,
          totalQueries: queryMetrics.length
        })
      }
    }

    return slowTenants.sort((a, b) => b.avgQueryTime - a.avgQueryTime)
  }
}

// Usage Examples
async function dataIsolationExample() {
  console.log('=== Multi-Tenant Data Isolation Strategies ===\n')

  // Create sample tenant contexts
  const enterpriseTenant: TenantContext = {
    tenantId: 'enterprise-123',
    tenantName: 'Acme Corporation',
    domain: 'acme.corp',
    plan: 'enterprise',
    settings: {
      timezone: 'UTC',
      currency: 'USD',
      locale: 'en-US',
      features: { 'advanced-analytics': true, 'custom-integrations': true },
      limits: { maxUsers: 1000, maxStorage: 1000, maxApiCalls: 10000000, maxProjects: 100 }
    },
    createdAt: new Date()
  }

  const premiumTenant: TenantContext = {
    tenantId: 'premium-456',
    tenantName: 'Startup Inc',
    domain: 'startup.io',
    plan: 'premium',
    settings: {
      timezone: 'America/New_York',
      currency: 'USD',
      locale: 'en-US',
      features: { 'advanced-analytics': true, 'custom-integrations': false },
      limits: { maxUsers: 100, maxStorage: 100, maxApiCalls: 1000000, maxProjects: 20 }
    },
    createdAt: new Date()
  }

  const basicTenant: TenantContext = {
    tenantId: 'basic-789',
    tenantName: 'Small Business LLC',
    domain: 'smallbiz.com',
    plan: 'basic',
    settings: {
      timezone: 'America/Los_Angeles',
      currency: 'USD',
      locale: 'en-US',
      features: { 'advanced-analytics': false, 'custom-integrations': false },
      limits: { maxUsers: 10, maxStorage: 10, maxApiCalls: 100000, maxProjects: 5 }
    },
    createdAt: new Date()
  }

  // Test different strategies
  console.log('1. Database per Tenant Strategy')
  const dbStrategy = new DatabasePerTenantStrategy('postgresql://user:password@localhost/tenant_{tenant_id}_db')
  await dbStrategy.getConnection(enterpriseTenant.tenantId)

  console.log('\n2. Schema per Tenant Strategy')
  const schemaStrategy = new SchemaPerTenantStrategy('postgresql://user:password@localhost/multi_tenant_db')
  await schemaStrategy.getConnection(premiumTenant.tenantId)

  console.log('\n3. Shared Table Strategy')
  const sharedStrategy = new SharedTableStrategy('postgresql://user:password@localhost/multi_tenant_db')
  sharedStrategy.setTenantContext(basicTenant)
  await sharedStrategy.query('SELECT * FROM users')

  console.log('\n4. Hybrid Strategy')
  const hybridStrategy = new HybridDataIsolationStrategy()

  // Create tenants with different plans
  await hybridStrategy.createTenant(enterpriseTenant)
  await hybridStrategy.createTenant(premiumTenant)
  await hybridStrategy.createTenant(basicTenant)

  // Get connections for different tenants
  await hybridStrategy.getConnection(enterpriseTenant)
  await hybridStrategy.getConnection(premiumTenant)
  await hybridStrategy.getConnection(basicTenant)

  // Monitor data usage
  console.log('\n5. Data Usage Monitoring')
  for (const tenant of [enterpriseTenant, premiumTenant, basicTenant]) {
    const usage = await hybridStrategy.getTenantDataUsage(tenant)
    console.log(`Tenant ${tenant.tenantId} (${tenant.plan}):`, usage)
  }

  // Performance monitoring
  console.log('\n6. Performance Monitoring')
  const monitor = new MultiTenantPerformanceMonitor()

  // Simulate some queries
  for (let i = 0; i < 10; i++) {
    monitor.recordQuery(enterpriseTenant.tenantId, Math.random() * 200 + 50)
    monitor.recordQuery(premiumTenant.tenantId, Math.random() * 300 + 100)
    monitor.recordQuery(basicTenant.tenantId, Math.random() * 500 + 200)
  }

  // Get metrics
  for (const tenantId of [enterpriseTenant.tenantId, premiumTenant.tenantId, basicTenant.tenantId]) {
    const metrics = monitor.getTenantMetrics(tenantId)
    console.log(`Tenant ${tenantId} metrics:`, metrics)
  }

  // Identify slow tenants
  const slowTenants = monitor.identifySlowTenants(400)
  if (slowTenants.length > 0) {
    console.log('\nSlow tenants identified:', slowTenants)
  }
}

export {
  TenantContext,
  TenantSettings,
  ResourceLimits,
  DatabasePerTenantStrategy,
  SchemaPerTenantStrategy,
  SharedTableStrategy,
  HybridDataIsolationStrategy,
  DataMigrationService,
  MultiTenantPerformanceMonitor,
  dataIsolationExample
}
        
CodeComplex

Tenant Management

Comprehensive tenant lifecycle management with onboarding, configuration, and monitoring

Difficulty

7/10

Estimated time

60 min

Tags

tenant-management, lifecycle, upgrades-downgrades

Prerequisites

Understanding of SaaS architecture, User management concepts

plaintext

// Tenant Management System

// Tenant Types and Plans
enum TenantPlan {
  BASIC = 'basic',
  PREMIUM = 'premium',
  ENTERPRISE = 'enterprise'
}

enum TenantStatus {
  PENDING = 'pending',
  ACTIVE = 'active',
  SUSPENDED = 'suspended',
  TERMINATED = 'terminated'
}

interface Tenant {
  id: string
  name: string
  domain: string
  plan: TenantPlan
  status: TenantStatus
  settings: TenantSettings
  billing: BillingInfo
  createdAt: Date
  updatedAt: Date
  activatedAt?: Date
  suspendedAt?: Date
  terminatedAt?: Date
}

interface TenantSettings {
  timezone: string
  currency: string
  locale: string
  theme: {
    primaryColor: string
    logo: string
    customCSS?: string
  }
  features: Record<string, boolean>
  limits: ResourceLimits
  notifications: NotificationSettings
}

interface BillingInfo {
  billingEmail: string
  paymentMethod: string
  nextBillingDate: Date
  subscriptionAmount: number
  currency: string
  isActive: boolean
}

interface ResourceLimits {
  maxUsers: number
  maxStorage: number // GB
  maxApiCalls: number
  maxProjects: number
  maxIntegrations: number
  bandwidthLimit: number // GB/month
}

interface NotificationSettings {
  email: boolean
  sms: boolean
  inApp: boolean
  alerts: {
    diskUsage: boolean
    apiLimit: boolean
    userLimit: boolean
    billing: boolean
  }
}

// Tenant Repository
interface ITenantRepository {
  create(tenant: Omit<Tenant, 'id' | 'createdAt' | 'updatedAt'>): Promise<Tenant>
  findById(id: string): Promise<Tenant | null>
  findByDomain(domain: string): Promise<Tenant | null>
  update(id: string, updates: Partial<Tenant>): Promise<Tenant>
  delete(id: string): Promise<void>
  findAll(filters?: TenantFilters): Promise<Tenant[]>
  findActiveTenants(): Promise<Tenant[]>
}

interface TenantFilters {
  plan?: TenantPlan
  status?: TenantStatus
  createdAfter?: Date
  createdBefore?: Date
  limit?: number
  offset?: number
}

class InMemoryTenantRepository implements ITenantRepository {
  private tenants: Map<string, Tenant> = new Map()

  async create(tenantData: Omit<Tenant, 'id' | 'createdAt' | 'updatedAt'>): Promise<Tenant> {
    const tenant: Tenant = {
      ...tenantData,
      id: crypto.randomUUID(),
      createdAt: new Date(),
      updatedAt: new Date()
    }

    this.tenants.set(tenant.id, tenant)
    return tenant
  }

  async findById(id: string): Promise<Tenant | null> {
    return this.tenants.get(id) || null
  }

  async findByDomain(domain: string): Promise<Tenant | null> {
    for (const tenant of this.tenants.values()) {
      if (tenant.domain === domain) {
        return tenant
      }
    }
    return null
  }

  async update(id: string, updates: Partial<Tenant>): Promise<Tenant> {
    const tenant = this.tenants.get(id)
    if (!tenant) {
      throw new Error(`Tenant not found: ${id}`)
    }

    const updatedTenant = {
      ...tenant,
      ...updates,
      updatedAt: new Date()
    }

    this.tenants.set(id, updatedTenant)
    return updatedTenant
  }

  async delete(id: string): Promise<void> {
    if (!this.tenants.has(id)) {
      throw new Error(`Tenant not found: ${id}`)
    }
    this.tenants.delete(id)
  }

  async findAll(filters?: TenantFilters): Promise<Tenant[]> {
    let tenants = Array.from(this.tenants.values())

    if (filters) {
      if (filters.plan) {
        tenants = tenants.filter(t => t.plan === filters.plan)
      }
      if (filters.status) {
        tenants = tenants.filter(t => t.status === filters.status)
      }
      if (filters.createdAfter) {
        tenants = tenants.filter(t => t.createdAt >= filters.createdAfter!)
      }
      if (filters.createdBefore) {
        tenants = tenants.filter(t => t.createdAt <= filters.createdBefore!)
      }
    }

    return tenants.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
  }

  async findActiveTenants(): Promise<Tenant[]> {
    return Array.from(this.tenants.values()).filter(t => t.status === TenantStatus.ACTIVE)
  }
}

// Tenant Onboarding Service
class TenantOnboardingService {
  constructor(
    private tenantRepository: ITenantRepository,
    private notificationService: NotificationService,
    private provisioningService: TenantProvisioningService
  ) {}

  async onboardTenant(request: TenantOnboardingRequest): Promise<{
    tenant: Tenant
    onboardingSteps: OnboardingStep[]
  }> {
    console.log(`Starting onboarding for: ${request.name}`)

    const onboardingSteps: OnboardingStep[] = []

    // Step 1: Validate request
    onboardingSteps.push(await this.validateOnboardingRequest(request))

    // Step 2: Create tenant
    const tenant = await this.createTenantFromRequest(request)
    onboardingSteps.push({
      step: 'CREATE_TENANT',
      status: 'COMPLETED',
      message: 'Tenant record created',
      timestamp: new Date()
    })

    // Step 3: Provision resources
    onboardingSteps.push(await this.provisioningService.provisionTenantResources(tenant))

    // Step 4: Configure initial settings
    onboardingSteps.push(await this.configureTenantSettings(tenant))

    // Step 5: Send welcome email
    onboardingSteps.push(await this.sendWelcomeNotification(tenant))

    // Step 6: Activate tenant
    const activatedTenant = await this.activateTenant(tenant.id)
    onboardingSteps.push({
      step: 'ACTIVATE_TENANT',
      status: 'COMPLETED',
      message: 'Tenant activated successfully',
      timestamp: new Date()
    })

    return {
      tenant: activatedTenant,
      onboardingSteps
    }
  }

  private async validateOnboardingRequest(request: TenantOnboardingRequest): Promise<OnboardingStep> {
    // Validate domain uniqueness
    const existingTenant = await this.tenantRepository.findByDomain(request.domain)
    if (existingTenant) {
      throw new Error(`Domain ${request.domain} is already taken`)
    }

    // Validate email format
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    if (!emailRegex.test(request.adminEmail)) {
      throw new Error('Invalid admin email format')
    }

    // Validate plan
    if (!Object.values(TenantPlan).includes(request.plan as TenantPlan)) {
      throw new Error(`Invalid plan: ${request.plan}`)
    }

    return {
      step: 'VALIDATE_REQUEST',
      status: 'COMPLETED',
      message: 'Request validation passed',
      timestamp: new Date()
    }
  }

  private async createTenantFromRequest(request: TenantOnboardingRequest): Promise<Tenant> {
    const defaultSettings = this.getDefaultTenantSettings(request.plan as TenantPlan)
    const defaultLimits = this.getDefaultResourceLimits(request.plan as TenantPlan)

    const tenant = await this.tenantRepository.create({
      name: request.name,
      domain: request.domain,
      plan: request.plan as TenantPlan,
      status: TenantStatus.PENDING,
      settings: {
        ...defaultSettings,
        limits: defaultLimits
      },
      billing: {
        billingEmail: request.adminEmail,
        paymentMethod: 'CREDIT_CARD',
        nextBillingDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days from now
        subscriptionAmount: this.getPlanPricing(request.plan as TenantPlan),
        currency: 'USD',
        isActive: false
      }
    })

    return tenant
  }

  private async configureTenantSettings(tenant: Tenant): Promise<OnboardingStep> {
    // Configure default features based on plan
    const features = this.getDefaultFeatures(tenant.plan)

    await this.tenantRepository.update(tenant.id, {
      settings: {
        ...tenant.settings,
        features
      }
    })

    return {
      step: 'CONFIGURE_SETTINGS',
      status: 'COMPLETED',
      message: 'Default settings configured',
      timestamp: new Date()
    }
  }

  private async sendWelcomeNotification(tenant: Tenant): Promise<OnboardingStep> {
    try {
      await this.notificationService.sendWelcomeEmail(tenant)
      return {
        step: 'SEND_WELCOME_EMAIL',
        status: 'COMPLETED',
        message: 'Welcome email sent',
        timestamp: new Date()
      }
    } catch (error) {
      return {
        step: 'SEND_WELCOME_EMAIL',
        status: 'FAILED',
        message: error instanceof Error ? error.message : 'Failed to send welcome email',
        timestamp: new Date()
      }
    }
  }

  private async activateTenant(tenantId: string): Promise<Tenant> {
    return await this.tenantRepository.update(tenantId, {
      status: TenantStatus.ACTIVE,
      activatedAt: new Date(),
      billing: {
        // This should merge with existing billing info
        billingEmail: '', // Will be set in update
        paymentMethod: '',
        nextBillingDate: new Date(),
        subscriptionAmount: 0,
        currency: 'USD',
        isActive: true
      }
    })
  }

  private getDefaultTenantSettings(plan: TenantPlan): Omit<TenantSettings, 'limits'> {
    const baseSettings = {
      timezone: 'UTC',
      currency: 'USD',
      locale: 'en-US',
      theme: {
        primaryColor: '#007bff',
        logo: '/default-logo.png'
      },
      notifications: {
        email: true,
        sms: false,
        inApp: true,
        alerts: {
          diskUsage: true,
          apiLimit: true,
          userLimit: true,
          billing: true
        }
      }
    }

    return baseSettings
  }

  private getDefaultResourceLimits(plan: TenantPlan): ResourceLimits {
    switch (plan) {
      case TenantPlan.BASIC:
        return {
          maxUsers: 5,
          maxStorage: 10,
          maxApiCalls: 10000,
          maxProjects: 3,
          maxIntegrations: 2,
          bandwidthLimit: 50
        }

      case TenantPlan.PREMIUM:
        return {
          maxUsers: 50,
          maxStorage: 100,
          maxApiCalls: 1000000,
          maxProjects: 20,
          maxIntegrations: 10,
          bandwidthLimit: 500
        }

      case TenantPlan.ENTERPRISE:
        return {
          maxUsers: 1000,
          maxStorage: 1000,
          maxApiCalls: 10000000,
          maxProjects: 100,
          maxIntegrations: 50,
          bandwidthLimit: 5000
        }

      default:
        throw new Error(`Unknown plan: ${plan}`)
    }
  }

  private getDefaultFeatures(plan: TenantPlan): Record<string, boolean> {
    const baseFeatures = {
      'dashboard': true,
      'user-management': true,
      'basic-analytics': true
    }

    switch (plan) {
      case TenantPlan.BASIC:
        return baseFeatures

      case TenantPlan.PREMIUM:
        return {
          ...baseFeatures,
          'advanced-analytics': true,
          'api-access': true,
          'team-collaboration': true,
          'export-data': true
        }

      case TenantPlan.ENTERPRISE:
        return {
          ...baseFeatures,
          'advanced-analytics': true,
          'api-access': true,
          'team-collaboration': true,
          'export-data': true,
          'custom-integrations': true,
          'single-sign-on': true,
          'white-label': true,
          'dedicated-support': true,
          'audit-logs': true,
          'custom-domains': true
        }

      default:
        return baseFeatures
    }
  }

  private getPlanPricing(plan: TenantPlan): number {
    switch (plan) {
      case TenantPlan.BASIC: return 29
      case TenantPlan.PREMIUM: return 99
      case TenantPlan.ENTERPRISE: return 499
      default: return 0
    }
  }
}

// Tenant Lifecycle Management
class TenantLifecycleManager {
  constructor(
    private tenantRepository: ITenantRepository,
    private monitoringService: TenantMonitoringService,
    private notificationService: NotificationService
  ) {}

  async upgradeTenantPlan(tenantId: string, newPlan: TenantPlan): Promise<Tenant> {
    const tenant = await this.tenantRepository.findById(tenantId)
    if (!tenant) {
      throw new Error(`Tenant not found: ${tenantId}`)
    }

    if (tenant.plan === newPlan) {
      throw new Error(`Tenant already on plan: ${newPlan}`)
    }

    console.log(`Upgrading tenant ${tenantId} from ${tenant.plan} to ${newPlan}`)

    // Update resource limits
    const newLimits = this.getResourceLimitsForPlan(newPlan)
    const newFeatures = this.getFeaturesForPlan(newPlan)

    const updatedTenant = await this.tenantRepository.update(tenantId, {
      plan: newPlan,
      settings: {
        ...tenant.settings,
        limits: newLimits,
        features: newFeatures
      },
      billing: {
        ...tenant.billing,
        subscriptionAmount: this.getPlanPrice(newPlan)
      }
    })

    // Send notification
    await this.notificationService.sendPlanUpgradeNotification(updatedTenant, tenant.plan)

    return updatedTenant
  }

  async suspendTenant(tenantId: string, reason: string): Promise<Tenant> {
    const tenant = await this.tenantRepository.findById(tenantId)
    if (!tenant) {
      throw new Error(`Tenant not found: ${tenantId}`)
    }

    if (tenant.status === TenantStatus.SUSPENDED) {
      throw new Error('Tenant is already suspended')
    }

    console.log(`Suspending tenant ${tenantId}. Reason: ${reason}`)

    const updatedTenant = await this.tenantRepository.update(tenantId, {
      status: TenantStatus.SUSPENDED,
      suspendedAt: new Date()
    })

    // Disable access
    await this.monitoringService.disableTenantAccess(tenantId)

    // Send notification
    await this.notificationService.sendSuspensionNotification(updatedTenant, reason)

    return updatedTenant
  }

  async reactivateTenant(tenantId: string): Promise<Tenant> {
    const tenant = await this.tenantRepository.findById(tenantId)
    if (!tenant) {
      throw new Error(`Tenant not found: ${tenantId}`)
    }

    if (tenant.status !== TenantStatus.SUSPENDED) {
      throw new Error('Only suspended tenants can be reactivated')
    }

    console.log(`Reactivating tenant ${tenantId}`)

    const updatedTenant = await this.tenantRepository.update(tenantId, {
      status: TenantStatus.ACTIVE,
      suspendedAt: undefined
    })

    // Enable access
    await this.monitoringService.enableTenantAccess(tenantId)

    // Send notification
    await this.notificationService.sendReactivationNotification(updatedTenant)

    return updatedTenant
  }

  async terminateTenant(tenantId: string, reason: string): Promise<void> {
    const tenant = await this.tenantRepository.findById(tenantId)
    if (!tenant) {
      throw new Error(`Tenant not found: ${tenantId}`)
    }

    console.log(`Terminating tenant ${tenantId}. Reason: ${reason}`)

    // Mark as terminated
    await this.tenantRepository.update(tenantId, {
      status: TenantStatus.TERMINATED,
      terminatedAt: new Date()
    })

    // Archive data
    await this.monitoringService.archiveTenantData(tenantId)

    // Disable access
    await this.monitoringService.disableTenantAccess(tenantId)

    // Send final notification
    await this.notificationService.sendTerminationNotification(tenant, reason)
  }

  private getResourceLimitsForPlan(plan: TenantPlan): ResourceLimits {
    // Implementation would get the limits for the specified plan
    // This is simplified for the example
    return {
      maxUsers: 100,
      maxStorage: 100,
      maxApiCalls: 1000000,
      maxProjects: 20,
      maxIntegrations: 10,
      bandwidthLimit: 500
    }
  }

  private getFeaturesForPlan(plan: TenantPlan): Record<string, boolean> {
    // Implementation would get the features for the specified plan
    return {
      'dashboard': true,
      'user-management': true,
      'basic-analytics': true
    }
  }

  private getPlanPrice(plan: TenantPlan): number {
    switch (plan) {
      case TenantPlan.BASIC: return 29
      case TenantPlan.PREMIUM: return 99
      case TenantPlan.ENTERPRISE: return 499
      default: return 0
    }
  }
}

// Supporting Interfaces and Classes

interface TenantOnboardingRequest {
  name: string
  domain: string
  adminEmail: string
  plan: string
  companySize?: string
  industry?: string
}

interface OnboardingStep {
  step: string
  status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED'
  message: string
  timestamp: Date
  error?: string
}

interface NotificationService {
  sendWelcomeEmail(tenant: Tenant): Promise<void>
  sendPlanUpgradeNotification(tenant: Tenant, oldPlan: TenantPlan): Promise<void>
  sendSuspensionNotification(tenant: Tenant, reason: string): Promise<void>
  sendReactivationNotification(tenant: Tenant): Promise<void>
  sendTerminationNotification(tenant: Tenant, reason: string): Promise<void>
}

interface TenantProvisioningService {
  provisionTenantResources(tenant: Tenant): Promise<OnboardingStep>
}

interface TenantMonitoringService {
  disableTenantAccess(tenantId: string): Promise<void>
  enableTenantAccess(tenantId: string): Promise<void>
  archiveTenantData(tenantId: string): Promise<void>
}

// Mock implementations for demo purposes
class MockNotificationService implements NotificationService {
  async sendWelcomeEmail(tenant: Tenant): Promise<void> {
    console.log(`Sending welcome email to ${tenant.billing.billingEmail}`)
  }

  async sendPlanUpgradeNotification(tenant: Tenant, oldPlan: TenantPlan): Promise<void> {
    console.log(`Sending plan upgrade notification to ${tenant.billing.billingEmail}`)
  }

  async sendSuspensionNotification(tenant: Tenant, reason: string): Promise<void> {
    console.log(`Sending suspension notification to ${tenant.billing.billingEmail}`)
  }

  async sendReactivationNotification(tenant: Tenant): Promise<void> {
    console.log(`Sending reactivation notification to ${tenant.billing.billingEmail}`)
  }

  async sendTerminationNotification(tenant: Tenant, reason: string): Promise<void> {
    console.log(`Sending termination notification to ${tenant.billing.billingEmail}`)
  }
}

class MockTenantProvisioningService implements TenantProvisioningService {
  async provisionTenantResources(tenant: Tenant): Promise<OnboardingStep> {
    console.log(`Provisioning resources for tenant ${tenant.id} (${tenant.plan})`)

    // Simulate resource provisioning
    await new Promise(resolve => setTimeout(resolve, 1000))

    return {
      step: 'PROVISION_RESOURCES',
      status: 'COMPLETED',
      message: 'Resources provisioned successfully',
      timestamp: new Date()
    }
  }
}

class MockTenantMonitoringService implements TenantMonitoringService {
  async disableTenantAccess(tenantId: string): Promise<void> {
    console.log(`Disabling access for tenant ${tenantId}`)
  }

  async enableTenantAccess(tenantId: string): Promise<void> {
    console.log(`Enabling access for tenant ${tenantId}`)
  }

  async archiveTenantData(tenantId: string): Promise<void> {
    console.log(`Archiving data for tenant ${tenantId}`)
  }
}

// Usage Example
async function tenantManagementExample() {
  console.log('=== Tenant Management System ===\n')

  // Setup services
  const tenantRepository = new InMemoryTenantRepository()
  const notificationService = new MockNotificationService()
  const provisioningService = new MockTenantProvisioningService()
  const monitoringService = new MockTenantMonitoringService()

  const onboardingService = new TenantOnboardingService(
    tenantRepository,
    notificationService,
    provisioningService
  )

  const lifecycleManager = new TenantLifecycleManager(
    tenantRepository,
    monitoringService,
    notificationService
  )

  // Onboard new tenants
  console.log('1. Onboarding New Tenants')

  const basicTenantRequest: TenantOnboardingRequest = {
    name: 'Small Business Inc',
    domain: 'smallbusiness.app',
    adminEmail: 'admin@smallbusiness.com',
    plan: 'basic',
    companySize: '1-10',
    industry: 'Technology'
  }

  const basicResult = await onboardingService.onboardTenant(basicTenantRequest)
  console.log(`Basic tenant onboarded: ${basicResult.tenant.name} (${basicResult.tenant.id})`)

  const enterpriseTenantRequest: TenantOnboardingRequest = {
    name: 'Enterprise Corp',
    domain: 'enterprise.corp',
    adminEmail: 'it@enterprise.com',
    plan: 'enterprise',
    companySize: '1000+',
    industry: 'Finance'
  }

  const enterpriseResult = await onboardingService.onboardTenant(enterpriseTenantRequest)
  console.log(`Enterprise tenant onboarded: ${enterpriseResult.tenant.name} (${enterpriseResult.tenant.id})`)

  // Display onboarding steps
  console.log('\nOnboarding steps for ${basicResult.tenant.name}:')
  basicResult.onboardingSteps.forEach(step => {
    console.log(`  ${step.step}: ${step.status} - ${step.message}`)
  })

  // List all active tenants
  console.log('\n2. Active Tenants')
  const activeTenants = await tenantRepository.findActiveTenants()
  activeTenants.forEach(tenant => {
    console.log(`  ${tenant.name} (${tenant.plan}) - ${tenant.domain}`)
  })

  // Upgrade tenant plan
  console.log('\n3. Upgrading Tenant Plan')
  const upgradedTenant = await lifecycleManager.upgradeTenantPlan(
    basicResult.tenant.id,
    TenantPlan.PREMIUM
  )
  console.log(`Upgraded ${upgradedTenant.name} to ${upgradedTenant.plan}`)

  // Suspend tenant
  console.log('\n4. Suspending Tenant')
  const suspendedTenant = await lifecycleManager.suspendTenant(
    enterpriseResult.tenant.id,
    'Payment overdue'
  )
  console.log(`Suspended ${suspendedTenant.name} for: Payment overdue`)

  // Reactivate tenant
  console.log('\n5. Reactivating Tenant')
  await new Promise(resolve => setTimeout(resolve, 1000)) // Simulate payment
  const reactivatedTenant = await lifecycleManager.reactivateTenant(suspendedTenant.id)
  console.log(`Reactivated ${reactivatedTenant.name}`)

  // Get tenant statistics
  console.log('\n6. Tenant Statistics')
  const allTenants = await tenantRepository.findAll()
  const statsByPlan = allTenants.reduce((acc, tenant) => {
    acc[tenant.plan] = (acc[tenant.plan] || 0) + 1
    return acc
  }, {} as Record<string, number>)

  console.log('Tenants by plan:', statsByPlan)

  const statsByStatus = allTenants.reduce((acc, tenant) => {
    acc[tenant.status] = (acc[tenant.status] || 0) + 1
    return acc
  }, {} as Record<string, number>)

  console.log('Tenants by status:', statsByStatus)
}

export {
  Tenant,
  TenantPlan,
  TenantStatus,
  TenantSettings,
  BillingInfo,
  ResourceLimits,
  NotificationSettings,
  ITenantRepository,
  InMemoryTenantRepository,
  TenantOnboardingService,
  TenantLifecycleManager,
  TenantOnboardingRequest,
  OnboardingStep,
  MockNotificationService,
  MockTenantProvisioningService,
  MockTenantMonitoringService,
  tenantManagementExample
}
        
CodeComplex

Resource Quotas and Limits

Implementing resource quota management with monitoring, alerts, and enforcement

Difficulty

8/10

Estimated time

50 min

Tags

resource-quotas, limits-management, usage-monitoring

Prerequisites

Monitoring systems knowledge, Rate limiting concepts

plaintext

// Resource Quota Management System

// Resource Types and Quota Definitions
enum ResourceType {
  USERS = 'users',
  STORAGE = 'storage',
  API_CALLS = 'api_calls',
  PROJECTS = 'projects',
  INTEGRATIONS = 'integrations',
  BANDWIDTH = 'bandwidth'
}

interface ResourceQuota {
  resourceType: ResourceType
  limit: number
  current: number
  period?: 'monthly' | 'daily' | 'yearly'
  resetDate?: Date
  unit: string
}

interface TenantQuota {
  tenantId: string
  quotas: Map<ResourceType, ResourceQuota>
  lastUpdated: Date
}

interface UsageRecord {
  tenantId: string
  resourceType: ResourceType
  amount: number
  timestamp: Date
  metadata?: Record<string, any>
}

interface QuotaAlert {
  tenantId: string
  resourceType: ResourceType
  alertType: 'WARNING' | 'CRITICAL' | 'EXCEEDED'
  currentUsage: number
  limit: number
  percentage: number
  timestamp: Date
}

// Resource Usage Tracker
class ResourceUsageTracker {
  private usageRecords: Map<string, UsageRecord[]> = new Map()
  private tenantQuotas: Map<string, TenantQuota> = new Map()

  // Record resource usage
  recordUsage(tenantId: string, resourceType: ResourceType, amount: number, metadata?: Record<string, any>): void {
    const record: UsageRecord = {
      tenantId,
      resourceType,
      amount,
      timestamp: new Date(),
      metadata
    }

    const key = `${tenantId}:${resourceType}`
    if (!this.usageRecords.has(key)) {
      this.usageRecords.set(key, [])
    }

    this.usageRecords.get(key)!.push(record)

    // Keep only last 10000 records per resource per tenant
    const records = this.usageRecords.get(key)!
    if (records.length > 10000) {
      records.splice(0, records.length - 10000)
    }
  }

  // Get current usage for a specific resource
  getCurrentUsage(tenantId: string, resourceType: ResourceType, period?: 'daily' | 'monthly'): number {
    const key = `${tenantId}:${resourceType}`
    const records = this.usageRecords.get(key) || []

    if (!period) {
      // Return total usage
      return records.reduce((total, record) => total + record.amount, 0)
    }

    const now = new Date()
    const cutoffDate = this.getCutoffDate(now, period)

    return records
      .filter(record => record.timestamp >= cutoffDate)
      .reduce((total, record) => total + record.amount, 0)
  }

  // Get usage trend for analytics
  getUsageTrend(tenantId: string, resourceType: ResourceType, days: number = 30): Array<{
    date: string
    usage: number
  }> {
    const key = `${tenantId}:${resourceType}`
    const records = this.usageRecords.get(key) || []

    const endDate = new Date()
    const startDate = new Date(endDate.getTime() - (days * 24 * 60 * 60 * 1000))

    // Group usage by day
    const dailyUsage: Record<string, number> = {}

    for (const record of records) {
      if (record.timestamp >= startDate && record.timestamp <= endDate) {
        const dateKey = record.timestamp.toISOString().split('T')[0]
        dailyUsage[dateKey] = (dailyUsage[dateKey] || 0) + record.amount
      }
    }

    // Fill missing days with 0 usage
    const trend: Array<{ date: string; usage: number }> = []
    for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
      const dateKey = date.toISOString().split('T')[0]
      trend.push({
        date: dateKey,
        usage: dailyUsage[dateKey] || 0
      })
    }

    return trend
  }

  // Get top resource consumers
  getTopConsumers(resourceType: ResourceType, limit: number = 10): Array<{
    tenantId: string
    usage: number
  }> {
    const tenantUsage: Record<string, number> = {}

    for (const [key, records] of this.usageRecords.entries()) {
      if (key.endsWith(`:${resourceType}`)) {
        const tenantId = key.split(':')[0]
        const usage = records.reduce((total, record) => total + record.amount, 0)
        tenantUsage[tenantId] = usage
      }
    }

    return Object.entries(tenantUsage)
      .map(([tenantId, usage]) => ({ tenantId, usage }))
      .sort((a, b) => b.usage - a.usage)
      .slice(0, limit)
  }

  private getCutoffDate(date: Date, period: 'daily' | 'monthly'): Date {
    if (period === 'daily') {
      const cutoff = new Date(date)
      cutoff.setHours(0, 0, 0, 0)
      return cutoff
    } else if (period === 'monthly') {
      const cutoff = new Date(date.getFullYear(), date.getMonth(), 1)
      return cutoff
    }

    return new Date(0)
  }

  // Set tenant quota
  setTenantQuota(tenantId: string, quotas: Map<ResourceType, ResourceQuota>): void {
    this.tenantQuotas.set(tenantId, {
      tenantId,
      quotas: new Map(quotas),
      lastUpdated: new Date()
    })
  }

  // Get tenant quota
  getTenantQuota(tenantId: string): TenantQuota | null {
    return this.tenantQuotas.get(tenantId) || null
  }
}

// Quota Enforcement Engine
class QuotaEnforcementEngine {
  private alertThresholds: Map<ResourceType, { warning: number; critical: number }> = new Map([
    [ResourceType.USERS, { warning: 0.8, critical: 0.95 }],
    [ResourceType.STORAGE, { warning: 0.8, critical: 0.95 }],
    [ResourceType.API_CALLS, { warning: 0.8, critical: 0.95 }],
    [ResourceType.PROJECTS, { warning: 0.8, critical: 0.95 }],
    [ResourceType.INTEGRATIONS, { warning: 0.8, critical: 0.95 }],
    [ResourceType.BANDWIDTH, { warning: 0.8, critical: 0.95 }]
  ])

  constructor(
    private usageTracker: ResourceUsageTracker,
    private alertService: QuotaAlertService,
    private enforcementActions: QuotaEnforcementActions
  ) {}

  // Check if action can be performed (soft check)
  canPerformAction(
    tenantId: string,
    resourceType: ResourceType,
    additionalAmount: number = 1
  ): {
    allowed: boolean
    currentUsage: number
    limit: number
    remaining: number
    percentageUsed: number
  } {
    const quota = this.usageTracker.getTenantQuota(tenantId)
    if (!quota) {
      return { allowed: false, currentUsage: 0, limit: 0, remaining: 0, percentageUsed: 100 }
    }

    const resourceQuota = quota.quotas.get(resourceType)
    if (!resourceQuota) {
      return { allowed: false, currentUsage: 0, limit: 0, remaining: 0, percentageUsed: 100 }
    }

    const currentUsage = this.getCurrentUsage(tenantId, resourceType, resourceQuota.period)
    const newTotalUsage = currentUsage + additionalAmount
    const remaining = Math.max(0, resourceQuota.limit - newTotalUsage)
    const percentageUsed = (newTotalUsage / resourceQuota.limit) * 100

    const allowed = newTotalUsage <= resourceQuota.limit

    return {
      allowed,
      currentUsage,
      limit: resourceQuota.limit,
      remaining,
      percentageUsed
    }
  }

  // Enforce quota check (hard check with potential action)
  async enforceQuota(
    tenantId: string,
    resourceType: ResourceType,
    additionalAmount: number = 1,
    actionContext?: Record<string, any>
  ): Promise<{
    allowed: boolean
    reason?: string
    action?: string
  }> {
    const check = this.canPerformAction(tenantId, resourceType, additionalAmount)

    if (!check.allowed) {
      // Quota exceeded
      await this.handleQuotaExceeded(tenantId, resourceType, check, actionContext)

      return {
        allowed: false,
        reason: `Quota exceeded for ${resourceType}. Current: ${check.currentUsage}, Limit: ${check.limit}`,
        action: await this.enforcementActions.getEnforcementAction(tenantId, resourceType, check.percentageUsed)
      }
    }

    // Check for approaching limits
    await this.checkApproachingLimits(tenantId, resourceType, check)

    // Record the usage
    this.usageTracker.recordUsage(tenantId, resourceType, additionalAmount, actionContext)

    return { allowed: true }
  }

  // Reset quotas that are period-based
  async resetPeriodicQuotas(): Promise<void> {
    const now = new Date()
    const tenants = await this.getAllTenants()

    for (const tenant of tenants) {
      const quota = this.usageTracker.getTenantQuota(tenant.id)
      if (!quota) continue

      for (const [resourceType, resourceQuota] of quota.quotas.entries()) {
        if (resourceQuota.period && resourceQuota.resetDate && now >= resourceQuota.resetDate) {
          await this.resetQuota(tenant.id, resourceType)
        }
      }
    }
  }

  private async handleQuotaExceeded(
    tenantId: string,
    resourceType: ResourceType,
    check: any,
    context?: Record<string, any>
  ): Promise<void> {
    await this.alertService.sendQuotaAlert({
      tenantId,
      resourceType,
      alertType: 'EXCEEDED',
      currentUsage: check.currentUsage,
      limit: check.limit,
      percentage: check.percentageUsed,
      timestamp: new Date()
    })

    await this.enforcementActions.executeEnforcementAction(tenantId, resourceType, 'EXCEEDED', context)
  }

  private async checkApproachingLimits(
    tenantId: string,
    resourceType: ResourceType,
    check: any
  ): Promise<void> {
    const thresholds = this.alertThresholds.get(resourceType)
    if (!thresholds) return

    const { warning, critical } = thresholds

    if (check.percentageUsed >= critical) {
      await this.alertService.sendQuotaAlert({
        tenantId,
        resourceType,
        alertType: 'CRITICAL',
        currentUsage: check.currentUsage,
        limit: check.limit,
        percentage: check.percentageUsed,
        timestamp: new Date()
      })
    } else if (check.percentageUsed >= warning) {
      await this.alertService.sendQuotaAlert({
        tenantId,
        resourceType,
        alertType: 'WARNING',
        currentUsage: check.currentUsage,
        limit: check.limit,
        percentage: check.percentageUsed,
        timestamp: new Date()
      })
    }
  }

  private getCurrentUsage(tenantId: string, resourceType: ResourceType, period?: string): number {
    if (period === 'monthly') {
      return this.usageTracker.getCurrentUsage(tenantId, resourceType, 'monthly')
    } else if (period === 'daily') {
      return this.usageTracker.getCurrentUsage(tenantId, resourceType, 'daily')
    }
    return this.usageTracker.getCurrentUsage(tenantId, resourceType)
  }

  private async resetQuota(tenantId: string, resourceType: ResourceType): Promise<void> {
    const quota = this.usageTracker.getTenantQuota(tenantId)
    if (!quota) return

    const resourceQuota = quota.quotas.get(resourceType)
    if (!resourceQuota || !resourceQuota.period) return

    // Update reset date for next period
    const now = new Date()
    let nextResetDate: Date

    if (resourceQuota.period === 'monthly') {
      nextResetDate = new Date(now.getFullYear(), now.getMonth() + 1, 1)
    } else if (resourceQuota.period === 'daily') {
      nextResetDate = new Date(now.getTime() + 24 * 60 * 60 * 1000)
    } else {
      return
    }

    resourceQuota.resetDate = nextResetDate

    console.log(`Reset quota for tenant ${tenantId}, resource ${resourceType}`)
  }

  private async getAllTenants(): Promise<Array<{ id: string }>> {
    // In real implementation, this would query the tenant repository
    // For demo, return sample data
    return [
      { id: 'tenant-1' },
      { id: 'tenant-2' },
      { id: 'tenant-3' }
    ]
  }
}

// Quota Alert Service
interface QuotaAlertService {
  sendQuotaAlert(alert: QuotaAlert): Promise<void>
}

class EmailQuotaAlertService implements QuotaAlertService {
  async sendQuotaAlert(alert: QuotaAlert): Promise<void> {
    const alertLevel = alert.alertType.toLowerCase()
    const subject = `Quota ${alertLevel}: ${alert.resourceType} for tenant ${alert.tenantId}`

    console.log(`=== EMAIL ALERT ===`)
    console.log(`To: admin@${alert.tenantId}.com`)
    console.log(`Subject: ${subject}`)
    console.log(`Message: `)
    console.log(`  Resource: ${alert.resourceType}`)
    console.log(`  Current Usage: ${alert.currentUsage}`)
    console.log(`  Limit: ${alert.limit}`)
    console.log(`  Usage: ${alert.percentage.toFixed(1)}%`)
    console.log(`  Alert Level: ${alert.alertType}`)
    console.log(`================`)
  }
}

// Quota Enforcement Actions
interface QuotaEnforcementActions {
  getEnforcementAction(tenantId: string, resourceType: ResourceType, percentageUsed: number): Promise<string>
  executeEnforcementAction(tenantId: string, resourceType: ResourceType, alertType: string, context?: Record<string, any>): Promise<void>
}

class DefaultQuotaEnforcementActions implements QuotaEnforcementActions {
  async getEnforcementAction(tenantId: string, resourceType: ResourceType, percentageUsed: number): Promise<string> {
    if (percentageUsed >= 100) {
      switch (resourceType) {
        case ResourceType.API_CALLS:
          return 'THROTTLE_API'
        case ResourceType.STORAGE:
          return 'BLOCK_UPLOADS'
        case ResourceType.USERS:
          return 'BLOCK_USER_CREATION'
        case ResourceType.BANDWIDTH:
          return 'THROTTLE_BANDWIDTH'
        default:
          return 'BLOCK_ACTION'
      }
    }

    return 'ALLOW_WITH_WARNING'
  }

  async executeEnforcementAction(
    tenantId: string,
    resourceType: ResourceType,
    alertType: string,
    context?: Record<string, any>
  ): Promise<void> {
    const action = await this.getEnforcementAction(tenantId, resourceType, 100)

    console.log(`=== ENFORCEMENT ACTION ===`)
    console.log(`Tenant: ${tenantId}`)
    console.log(`Resource: ${resourceType}`)
    console.log(`Alert Type: ${alertType}`)
    console.log(`Action: ${action}`)

    switch (action) {
      case 'THROTTLE_API':
        console.log(`→ API requests will be throttled for tenant ${tenantId}`)
        break
      case 'BLOCK_UPLOADS':
        console.log(`→ File uploads blocked for tenant ${tenantId}`)
        break
      case 'BLOCK_USER_CREATION':
        console.log(`→ New user creation blocked for tenant ${tenantId}`)
        break
      case 'THROTTLE_BANDWIDTH':
        console.log(`→ Bandwidth throttled for tenant ${tenantId}`)
        break
      case 'BLOCK_ACTION':
        console.log(`→ Action blocked for tenant ${tenantId}`)
        break
    }
    console.log(`=========================`)
  }
}

// Quota Analytics Dashboard
class QuotaAnalytics {
  constructor(private usageTracker: ResourceUsageTracker) {}

  // Get quota utilization report
  async getQuotaUtilizationReport(tenantId: string): Promise<{
    resourceUtilization: Array<{
      resourceType: ResourceType
      current: number
      limit: number
      percentage: number
      status: 'HEALTHY' | 'WARNING' | 'CRITICAL' | 'EXCEEDED'
    }>
    overallHealth: 'HEALTHY' | 'WARNING' | 'CRITICAL'
    recommendations: string[]
  }> {
    const quota = this.usageTracker.getTenantQuota(tenantId)
    if (!quota) {
      throw new Error(`No quota found for tenant ${tenantId}`)
    }

    const resourceUtilization: Array<{
      resourceType: ResourceType
      current: number
      limit: number
      percentage: number
      status: 'HEALTHY' | 'WARNING' | 'CRITICAL' | 'EXCEEDED'
    }> = []

    for (const [resourceType, resourceQuota] of quota.quotas.entries()) {
      const current = this.usageTracker.getCurrentUsage(
        tenantId,
        resourceType,
        resourceQuota.period as any
      )
      const percentage = (current / resourceQuota.limit) * 100

      let status: 'HEALTHY' | 'WARNING' | 'CRITICAL' | 'EXCEEDED'
      if (percentage >= 100) {
        status = 'EXCEEDED'
      } else if (percentage >= 95) {
        status = 'CRITICAL'
      } else if (percentage >= 80) {
        status = 'WARNING'
      } else {
        status = 'HEALTHY'
      }

      resourceUtilization.push({
        resourceType,
        current,
        limit: resourceQuota.limit,
        percentage,
        status
      })
    }

    const overallHealth = this.calculateOverallHealth(resourceUtilization)
    const recommendations = this.generateRecommendations(resourceUtilization)

    return {
      resourceUtilization,
      overallHealth,
      recommendations
    }
  }

  // Get capacity planning insights
  async getCapacityPlanningInsights(days: number = 30): Promise<{
    resourceGrowth: Record<ResourceType, number>
    tenantGrowth: Record<string, number>
    predictedExhaustion: Array<{
      tenantId: string
      resourceType: ResourceType
      estimatedDaysToExhaustion: number
    }>
  }> {
    const resourceGrowth: Record<string, number> = {}
    const tenantGrowth: Record<string, number> = {}
    const predictedExhaustion: Array<{
      tenantId: string
      resourceType: ResourceType
      estimatedDaysToExhaustion: number
    }> = []

    // Calculate growth rates for each resource type
    for (const resourceType of Object.values(ResourceType)) {
      const trend = this.usageTracker.getUsageTrend('sample-tenant', resourceType as ResourceType, days)
      if (trend.length > 1) {
        const growth = ((trend[trend.length - 1].usage - trend[0].usage) / trend[0].usage) * 100
        resourceGrowth[resourceType] = growth
      }
    }

    // Predict exhaustion for tenants approaching limits
    // This is a simplified prediction algorithm
    const sampleTenants = ['tenant-1', 'tenant-2', 'tenant-3']

    for (const tenantId of sampleTenants) {
      const quota = this.usageTracker.getTenantQuota(tenantId)
      if (!quota) continue

      for (const [resourceType, resourceQuota] of quota.quotas.entries()) {
        const current = this.usageTracker.getCurrentUsage(tenantId, resourceType, resourceQuota.period as any)
        const remaining = resourceQuota.limit - current

        if (remaining > 0) {
          const trend = this.usageTracker.getUsageTrend(tenantId, resourceType, 7) // Last 7 days
          if (trend.length > 1) {
            const dailyUsage = (trend[trend.length - 1].usage - trend[0].usage) / trend.length
            if (dailyUsage > 0) {
              const daysToExhaustion = Math.floor(remaining / dailyUsage)
              if (daysToExhaustion < 30) { // Only show if exhausted within 30 days
                predictedExhaustion.push({
                  tenantId,
                  resourceType,
                  estimatedDaysToExhaustion: daysToExhaustion
                })
              }
            }
          }
        }
      }
    }

    return {
      resourceGrowth,
      tenantGrowth,
      predictedExhaustion
    }
  }

  private calculateOverallHealth(utilization: any[]): 'HEALTHY' | 'WARNING' | 'CRITICAL' {
    const criticalCount = utilization.filter(u => u.status === 'CRITICAL' || u.status === 'EXCEEDED').length
    const warningCount = utilization.filter(u => u.status === 'WARNING').length

    if (criticalCount > 0) {
      return 'CRITICAL'
    } else if (warningCount > 0) {
      return 'WARNING'
    } else {
      return 'HEALTHY'
    }
  }

  private generateRecommendations(utilization: any[]): string[] {
    const recommendations: string[] = []

    for (const util of utilization) {
      if (util.percentage >= 80) {
        switch (util.resourceType) {
          case ResourceType.STORAGE:
            recommendations.push('Consider upgrading your plan or archiving old files to free up storage space.')
            break
          case ResourceType.API_CALLS:
            recommendations.push('Optimize API usage or upgrade to a plan with higher API limits.')
            break
          case ResourceType.USERS:
            recommendations.push('Upgrade your plan to accommodate more users or remove inactive accounts.')
            break
          case ResourceType.BANDWIDTH:
            recommendations.push('Monitor bandwidth usage and consider upgrading for higher limits.')
            break
        }
      }
    }

    if (recommendations.length === 0) {
      recommendations.push('Your resource usage is within healthy limits.')
    }

    return recommendations
  }
}

// Usage Example
async function resourceQuotaExample() {
  console.log('=== Resource Quota Management System ===\n')

  // Initialize services
  const usageTracker = new ResourceUsageTracker()
  const alertService = new EmailQuotaAlertService()
  const enforcementActions = new DefaultQuotaEnforcementActions()
  const quotaEngine = new QuotaEnforcementEngine(usageTracker, alertService, enforcementActions)
  const analytics = new QuotaAnalytics(usageTracker)

  // Set up tenant quotas
  console.log('1. Setting up tenant quotas')

  const tenantQuotas = new Map<ResourceType, ResourceQuota>([
    [ResourceType.USERS, { resourceType: ResourceType.USERS, limit: 100, current: 0, unit: 'users' }],
    [ResourceType.STORAGE, { resourceType: ResourceType.STORAGE, limit: 1000, current: 0, unit: 'MB', period: 'monthly' }],
    [ResourceType.API_CALLS, { resourceType: ResourceType.API_CALLS, limit: 10000, current: 0, unit: 'calls', period: 'monthly' }],
    [ResourceType.PROJECTS, { resourceType: ResourceType.PROJECTS, limit: 50, current: 0, unit: 'projects' }]
  ])

  usageTracker.setTenantQuota('tenant-demo', tenantQuotas)

  // Simulate usage
  console.log('\n2. Simulating resource usage')

  // Add some users
  for (let i = 0; i < 75; i++) {
    await quotaEngine.enforceQuota('tenant-demo', ResourceType.USERS, 1, { action: 'create_user' })
  }

  // Simulate API calls (gradually approaching limit)
  for (let i = 0; i < 8500; i++) {
    await quotaEngine.enforceQuota('tenant-demo', ResourceType.API_CALLS, 1, { endpoint: '/api/data' })
  }

  // Add storage usage
  for (let i = 0; i < 850; i++) {
    await quotaEngine.enforceQuota('tenant-demo', ResourceType.STORAGE, 1, { file_size: 1024 * 1024 })
  }

  // Check quota status
  console.log('\n3. Current quota status')

  const currentQuota = usageTracker.getTenantQuota('tenant-demo')!
  for (const [resourceType, quota] of currentQuota.quotas.entries()) {
    const current = usageTracker.getCurrentUsage('tenant-demo', resourceType, quota.period as any)
    const percentage = (current / quota.limit) * 100
    console.log(`${resourceType}: ${current}/${quota.limit} (${percentage.toFixed(1)}%)`)
  }

  // Test quota enforcement
  console.log('\n4. Testing quota enforcement')

  const userCheck = quotaEngine.canPerformAction('tenant-demo', ResourceType.USERS, 30)
  console.log('Can add 30 users:', userCheck.allowed, '- Remaining:', userCheck.remaining)

  const apiCheck = quotaEngine.canPerformAction('tenant-demo', ResourceType.API_CALLS, 2000)
  console.log('Can make 2000 API calls:', apiCheck.allowed, '- Remaining:', apiCheck.remaining)

  // Try to exceed quota
  console.log('\n5. Attempting to exceed quotas')

  try {
    await quotaEngine.enforceQuota('tenant-demo', ResourceType.API_CALLS, 2000, { endpoint: '/api/bulk-data' })
    console.log('Bulk API call succeeded')
  } catch (error) {
    console.log('Bulk API call blocked:', error)
  }

  // Generate quota report
  console.log('\n6. Quota utilization report')

  const report = await analytics.getQuotaUtilizationReport('tenant-demo')
  console.log('Overall health:', report.overallHealth)
  console.log('\nResource utilization:')
  report.resourceUtilization.forEach(util => {
    console.log(`  ${util.resourceType}: ${util.percentage.toFixed(1)}% (${util.status})`)
  })

  if (report.recommendations.length > 0) {
    console.log('\nRecommendations:')
    report.recommendations.forEach(rec => console.log(`  • ${rec}`))
  }

  // Capacity planning insights
  console.log('\n7. Capacity planning insights')

  const insights = await analytics.getCapacityPlanningInsights(30)
  console.log('Resource growth rates:')
  Object.entries(insights.resourceGrowth).forEach(([resource, growth]) => {
    console.log(`  ${resource}: ${growth.toFixed(1)}%`)
  })

  if (insights.predictedExhaustion.length > 0) {
    console.log('\nResources approaching limits:')
    insights.predictedExhaustion.forEach(pred => {
      console.log(`  ${pred.tenantId} - ${pred.resourceType}: ${pred.estimatedDaysToExhaustion} days`)
    })
  } else {
    console.log('\nNo resources predicted to exhaust within 30 days')
  }
}

export {
  ResourceType,
  ResourceQuota,
  TenantQuota,
  UsageRecord,
  QuotaAlert,
  ResourceUsageTracker,
  QuotaEnforcementEngine,
  QuotaAlertService,
  EmailQuotaAlertService,
  QuotaEnforcementActions,
  DefaultQuotaEnforcementActions,
  QuotaAnalytics,
  resourceQuotaExample
}
        
CodeComplex

White-Label Solutions

Implementing customizable white-label solutions with branding, themes, and multi-brand support

Difficulty

9/10

Estimated time

70 min

Tags

white-label-solutions, brand-customization, theme-management

Prerequisites

Frontend development knowledge, CSS/JavaScript understanding

plaintext

// White-Label Solution Management System

// Brand Configuration
interface BrandConfig {
  tenantId: string
  brandId: string
  name: string
  domain: string
  logo: {
    primary: string
    secondary?: string
    favicon?: string
    emailLogo?: string
  }
  colors: {
    primary: string
    secondary: string
    accent: string
    background: string
    text: string
    error: string
    success: string
    warning: string
  }
  typography: {
    fontFamily: string
    headingFont?: string
    baseFontSize: string
    scale: number[]
  }
  layout: {
    headerHeight: string
    sidebarWidth: string
    borderRadius: string
    spacing: {
      small: string
      medium: string
      large: string
    }
  }
  customCSS?: string
  customJS?: string
  features: {
    showBranding: boolean
    allowCustomDomain: boolean
    customLogin: boolean
    customEmails: boolean
    whiteLabelReports: boolean
  }
  integration: {
    analytics: AnalyticsConfig
    support: SupportConfig
    notifications: NotificationConfig
  }
  createdAt: Date
  updatedAt: Date
}

interface AnalyticsConfig {
  provider: 'google' | 'mixpanel' | 'segment' | 'custom'
  trackingId: string
  customScript?: string
}

interface SupportConfig {
  provider: 'intercom' | 'zendesk' | 'custom'
  apiKey: string
  customWidget?: string
}

interface NotificationConfig {
  emailProvider: 'sendgrid' | 'ses' | 'mailgun' | 'custom'
  smsProvider: 'twilio' | 'custom'
  templates: EmailTemplates
}

interface EmailTemplates {
  welcome: EmailTemplate
  passwordReset: EmailTemplate
  invitation: EmailTemplate
  billing: EmailTemplate
  support: EmailTemplate
}

interface EmailTemplate {
  subject: string
  htmlContent: string
  textContent?: string
  variables: string[]
}

// Theme Management Service
class ThemeManagementService {
  private themes: Map<string, BrandConfig> = new Map()
  private defaultTheme: BrandConfig

  constructor() {
    this.defaultTheme = this.createDefaultTheme()
  }

  // Create or update brand configuration
  async saveBrandConfig(brandConfig: BrandConfig): Promise<BrandConfig> {
    // Validate brand configuration
    this.validateBrandConfig(brandConfig)

    // Generate CSS theme
    const themeCSS = this.generateThemeCSS(brandConfig)

    // Store the configuration
    this.themes.set(brandConfig.brandId, {
      ...brandConfig,
      updatedAt: new Date()
    })

    console.log(`Saved brand config for ${brandConfig.name} (${brandConfig.brandId})`)
    return brandConfig
  }

  // Get brand configuration
  getBrandConfig(brandId: string): BrandConfig | null {
    return this.themes.get(brandId) || null
  }

  // Get brand configuration by domain
  getBrandConfigByDomain(domain: string): BrandConfig | null {
    for (const brand of this.themes.values()) {
      if (brand.domain === domain) {
        return brand
      }
    }
    return null
  }

  // Generate CSS theme from brand configuration
  generateThemeCSS(brandConfig: BrandConfig): string {
    const { colors, typography, layout } = brandConfig

    return `
/* Custom Theme for ${brandConfig.name} */
:root {
  /* Colors */
  --primary-color: ${colors.primary};
  --primary-hover: ${this.adjustColor(colors.primary, -10)};
  --primary-light: ${this.adjustColor(colors.primary, 80)};
  --secondary-color: ${colors.secondary};
  --accent-color: ${colors.accent};
  --background-color: ${colors.background};
  --text-color: ${colors.text};
  --text-muted: ${this.adjustColor(colors.text, 60)};
  --border-color: ${this.adjustColor(colors.text, 20)};
  --error-color: ${colors.error};
  --success-color: ${colors.success};
  --warning-color: ${colors.warning};

  /* Typography */
  --font-family: ${typography.fontFamily};
  --heading-font: ${typography.headingFont || typography.fontFamily};
  --font-size-base: ${typography.baseFontSize};
  --font-scale: ${typography.scale.join(', ')};

  /* Layout */
  --header-height: ${layout.headerHeight};
  --sidebar-width: ${layout.sidebarWidth};
  --border-radius: ${layout.borderRadius};
  --spacing-small: ${layout.spacing.small};
  --spacing-medium: ${layout.spacing.medium};
  --spacing-large: ${layout.spacing.large};
}

/* Component Styles */
.btn-primary {
  background-color: var(--primary-color);
  border-color: var(--primary-color);
  color: white;
}

.btn-primary:hover {
  background-color: var(--primary-hover);
  border-color: var(--primary-hover);
}

.card {
  background-color: var(--background-color);
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.header {
  height: var(--header-height);
  background-color: var(--primary-color);
  color: white;
}

.sidebar {
  width: var(--sidebar-width);
  background-color: var(--background-color);
  border-right: 1px solid var(--border-color);
}

.text-primary { color: var(--primary-color); }
.text-secondary { color: var(--secondary-color); }
.text-accent { color: var(--accent-color); }
.text-muted { color: var(--text-muted); }

.bg-primary { background-color: var(--primary-color); }
.bg-secondary { background-color: var(--secondary-color); }
.bg-accent { background-color: var(--accent-color); }

/* Custom styles */
${brandConfig.customCSS || ''}
`
  }

  // Generate theme JavaScript for dynamic styling
  generateThemeJS(brandConfig: BrandConfig): string {
    return `
// Dynamic Theme for ${brandConfig.name}
(function() {
  const theme = ${JSON.stringify(brandConfig, null, 2)};

  // Apply theme dynamically
  function applyTheme() {
    const root = document.documentElement;

    // Set CSS custom properties
    Object.entries(theme.colors).forEach(([key, value]) => {
      const cssVar = `--${key.replace(/([A-Z])/g, '-$1').toLowerCase()}-color`;
      root.style.setProperty(cssVar, value);
    });

    // Set custom fonts
    if (theme.typography.fontFamily) {
      root.style.setProperty('--font-family', theme.typography.fontFamily);
    }

    // Update logos
    const logoElements = document.querySelectorAll('[data-brand-logo]');
    logoElements.forEach(el => {
      el.src = theme.logo.primary;
      el.alt = theme.name;
    });

    // Update favicon
    if (theme.logo.favicon) {
      const favicon = document.querySelector('link[rel="icon"]') || document.createElement('link');
      favicon.rel = 'icon';
      favicon.href = theme.logo.favicon;
      document.head.appendChild(favicon);
    }

    // Update page title
    if (document.title.includes('[BRAND_NAME]')) {
      document.title = document.title.replace('[BRAND_NAME]', theme.name);
    }
  }

  // Apply theme immediately
  applyTheme();

  // Re-apply theme on DOM changes
  const observer = new MutationObserver(applyTheme);
  observer.observe(document.body, { childList: true, subtree: true });

  // Export theme for other components
  window.currentTheme = theme;
})();
${brandConfig.customJS || ''}
`
  }

  // Clone existing theme
  cloneTheme(sourceBrandId: string, newBrandId: string, overrides: Partial<BrandConfig>): BrandConfig {
    const sourceTheme = this.themes.get(sourceBrandId)
    if (!sourceTheme) {
      throw new Error(`Source theme not found: ${sourceBrandId}`)
    }

    const clonedTheme: BrandConfig = {
      ...sourceTheme,
      brandId: newBrandId,
      ...overrides,
      createdAt: new Date(),
      updatedAt: new Date()
    }

    return clonedTheme
  }

  // Reset theme to default
  resetToDefault(brandId: string): BrandConfig {
    const currentTheme = this.themes.get(brandId)
    if (!currentTheme) {
      throw new Error(`Theme not found: ${brandId}`)
    }

    const defaultTheme: BrandConfig = {
      ...this.defaultTheme,
      brandId: currentTheme.brandId,
      tenantId: currentTheme.tenantId,
      name: currentTheme.name,
      domain: currentTheme.domain
    }

    this.themes.set(brandId, defaultTheme)
    return defaultTheme
  }

  // Export theme configuration
  exportTheme(brandId: string): string {
    const theme = this.themes.get(brandId)
    if (!theme) {
      throw new Error(`Theme not found: ${brandId}`)
    }

    return JSON.stringify(theme, null, 2)
  }

  // Import theme configuration
  importTheme(themeJson: string): BrandConfig {
    try {
      const theme = JSON.parse(themeJson) as BrandConfig
      this.validateBrandConfig(theme)
      this.themes.set(theme.brandId, theme)
      return theme
    } catch (error) {
      throw new Error(`Invalid theme configuration: ${error}`)
    }
  }

  private validateBrandConfig(brandConfig: BrandConfig): void {
    if (!brandConfig.brandId || !brandConfig.tenantId || !brandConfig.name) {
      throw new Error('Required fields missing: brandId, tenantId, name')
    }

    // Validate color format (hex)
    const colorFields = Object.values(brandConfig.colors)
    for (const color of colorFields) {
      if (!this.isValidHexColor(color)) {
        throw new Error(`Invalid color format: ${color}`)
      }
    }

    // Validate logo URLs
    if (!this.isValidUrl(brandConfig.logo.primary)) {
      throw new Error(`Invalid primary logo URL: ${brandConfig.logo.primary}`)
    }
  }

  private createDefaultTheme(): BrandConfig {
    return {
      tenantId: 'default',
      brandId: 'default',
      name: 'Default Brand',
      domain: 'app.example.com',
      logo: {
        primary: '/assets/default-logo.png',
        secondary: '/assets/default-logo-light.png',
        favicon: '/assets/default-favicon.ico',
        emailLogo: '/assets/default-email-logo.png'
      },
      colors: {
        primary: '#007bff',
        secondary: '#6c757d',
        accent: '#28a745',
        background: '#ffffff',
        text: '#212529',
        error: '#dc3545',
        success: '#28a745',
        warning: '#ffc107'
      },
      typography: {
        fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
        baseFontSize: '16px',
        scale: [0.75, 0.875, 1, 1.125, 1.25, 1.5, 1.875, 2.25, 3]
      },
      layout: {
        headerHeight: '64px',
        sidebarWidth: '250px',
        borderRadius: '4px',
        spacing: {
          small: '8px',
          medium: '16px',
          large: '24px'
        }
      },
      features: {
        showBranding: true,
        allowCustomDomain: false,
        customLogin: false,
        customEmails: false,
        whiteLabelReports: false
      },
      integration: {
        analytics: {
          provider: 'google',
          trackingId: 'GA-DEFAULT'
        },
        support: {
          provider: 'intercom',
          apiKey: 'default-key'
        },
        notifications: {
          emailProvider: 'sendgrid',
          smsProvider: 'twilio',
          templates: this.getDefaultEmailTemplates()
        }
      },
      createdAt: new Date(),
      updatedAt: new Date()
    }
  }

  private getDefaultEmailTemplates(): EmailTemplates {
    return {
      welcome: {
        subject: 'Welcome to {{brand_name}}!',
        htmlContent: `
          <h1>Welcome to {{brand_name}}!</h1>
          <p>Thank you for joining us. Your account has been successfully created.</p>
          <p>Click <a href="{{login_url}}">here</a> to log in.</p>
        `,
        variables: ['brand_name', 'login_url', 'user_name']
      },
      passwordReset: {
        subject: 'Password Reset Request',
        htmlContent: `
          <h1>Password Reset</h1>
          <p>You requested a password reset for your {{brand_name}} account.</p>
          <p>Click <a href="{{reset_url}}">here</a> to reset your password.</p>
        `,
        variables: ['brand_name', 'reset_url', 'user_name']
      },
      invitation: {
        subject: 'Invitation to join {{brand_name}}',
        htmlContent: `
          <h1>You're Invited!</h1>
          <p>You have been invited to join {{brand_name}}.</p>
          <p>Click <a href="{{invite_url}}">here</a> to accept the invitation.</p>
        `,
        variables: ['brand_name', 'invite_url', 'inviter_name', 'team_name']
      },
      billing: {
        subject: 'Invoice from {{brand_name}}',
        htmlContent: `
          <h1>Invoice {{invoice_number}}</h1>
          <p>Your invoice from {{brand_name}} is ready.</p>
          <p>Amount: {{amount}} {{currency}}</p>
          <p>Due date: {{due_date}}</p>
        `,
        variables: ['brand_name', 'invoice_number', 'amount', 'currency', 'due_date']
      },
      support: {
        subject: 'Support Ticket Update - {{ticket_id}}',
        htmlContent: `
          <h1>Support Ticket Update</h1>
          <p>Your support ticket {{ticket_id}} has been updated.</p>
          <p>Message: {{message}}</p>
        `,
        variables: ['brand_name', 'ticket_id', 'message', 'support_agent']
      }
    }
  }

  private isValidHexColor(color: string): boolean {
    return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color)
  }

  private isValidUrl(url: string): boolean {
    try {
      new URL(url)
      return true
    } catch {
      return false
    }
  }

  private adjustColor(color: string, amount: number): string {
    const num = parseInt(color.replace('#', ''), 16)
    const r = Math.min(255, Math.max(0, (num >> 16) + amount))
    const g = Math.min(255, Math.max(0, ((num >> 8) & 0x00FF) + amount))
    const b = Math.min(255, Math.max(0, (num & 0x0000FF) + amount))
    return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0')}`
  }
}

// Brand Middleware for Web Applications
class BrandMiddleware {
  constructor(private themeService: ThemeManagementService) {}

  // Express.js middleware example
  expressMiddleware() {
    return (req: any, res: any, next: any) => {
      const domain = req.hostname
      const brand = this.themeService.getBrandConfigByDomain(domain)

      if (brand) {
        req.brand = brand
        res.locals.brand = brand

        // Set brand-specific headers
        res.setHeader('X-Brand-ID', brand.brandId)
        res.setHeader('X-Brand-Name', brand.name)

        // Inject brand variables into templates
        res.locals.theme = {
          css: this.themeService.generateThemeCSS(brand),
          js: this.themeService.generateThemeJS(brand)
        }
      } else {
        // Use default theme
        req.brand = this.themeService.getBrandConfig('default')
        res.locals.brand = req.brand
        res.locals.theme = {
          css: this.themeService.generateThemeCSS(req.brand),
          js: this.themeService.generateThemeJS(req.brand)
        }
      }

      next()
    }
  }

  // Generate HTML with brand styling
  generateBrandedHTML(template: string, brand: BrandConfig): string {
    const themeCSS = this.themeService.generateThemeCSS(brand)
    const themeJS = this.themeService.generateThemeJS(brand)

    return template
      .replace('{{BRAND_CSS}}', themeCSS)
      .replace('{{BRAND_JS}}', themeJS)
      .replace('{{BRAND_NAME}}', brand.name)
      .replace('{{BRAND_LOGO}}', brand.logo.primary)
      .replace('{{FAVICON}}', brand.logo.favicon || '')
      .replace('{{PRIMARY_COLOR}}', brand.colors.primary)
      .replace('{{SECONDARY_COLOR}}', brand.colors.secondary)
  }
}

// Email Template Service for White-Label
class WhiteLabelEmailService {
  constructor(private themeService: ThemeManagementService) {}

  // Generate branded email template
  generateBrandedEmail(
    brandId: string,
    templateType: keyof EmailTemplates,
    variables: Record<string, any>
  ): {
    subject: string
    htmlContent: string
    textContent?: string
  } {
    const brand = this.themeService.getBrandConfig(brandId)
    if (!brand) {
      throw new Error(`Brand not found: ${brandId}`)
    }

    const template = brand.integration.notifications.templates[templateType]

    // Replace template variables
    let subject = template.subject
    let htmlContent = template.htmlContent
    let textContent = template.textContent

    for (const [key, value] of Object.entries(variables)) {
      const placeholder = `{{${key}}}`
      subject = subject.replace(new RegExp(placeholder, 'g'), String(value))
      htmlContent = htmlContent.replace(new RegExp(placeholder, 'g'), String(value))
      if (textContent) {
        textContent = textContent.replace(new RegExp(placeholder, 'g'), String(value))
      }
    }

    // Add brand styling to email
    const brandedHTML = `
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="utf-8">
        <title>${subject}</title>
        <style>
          .email-header {
            background-color: ${brand.colors.primary};
            color: white;
            padding: 20px;
            text-align: center;
          }
          .email-body {
            font-family: ${brand.typography.fontFamily};
            color: ${brand.colors.text};
            padding: 20px;
            max-width: 600px;
            margin: 0 auto;
          }
          .email-footer {
            background-color: ${brand.colors.background};
            border-top: 1px solid ${brand.colors.secondary};
            padding: 20px;
            text-align: center;
            color: ${brand.colors.text};
            font-size: 14px;
          }
          .brand-logo {
            max-height: 40px;
            margin-bottom: 10px;
          }
          .btn-primary {
            background-color: ${brand.colors.primary};
            color: white;
            padding: 12px 24px;
            text-decoration: none;
            border-radius: ${brand.layout.borderRadius};
            display: inline-block;
          }
        </style>
      </head>
      <body>
        <div class="email-header">
          <img src="${brand.logo.emailLogo}" alt="${brand.name}" class="brand-logo">
          <h1>${brand.name}</h1>
        </div>
        <div class="email-body">
          ${htmlContent}
        </div>
        <div class="email-footer">
          <p>© ${new Date().getFullYear()} ${brand.name}. All rights reserved.</p>
          <p>This email was sent to {{recipient_email}}</p>
        </div>
      </body>
      </html>
    `

    return {
      subject,
      htmlContent: brandedHTML,
      textContent
    }
  }

  // Send branded email
  async sendBrandedEmail(
    brandId: string,
    to: string[],
    templateType: keyof EmailTemplates,
    variables: Record<string, any>
  ): Promise<void> {
    const email = this.generateBrandedEmail(brandId, templateType, variables)

    console.log(`=== SENDING BRANDED EMAIL ===`)
    console.log(`Brand: ${brandId}`)
    console.log(`To: ${to.join(', ')}`)
    console.log(`Subject: ${email.subject}`)
    console.log(`Template: ${templateType}`)

    // In real implementation, this would integrate with email service
    // await emailProvider.send(email)

    console.log(`Email sent successfully`)
    console.log(`=========================`)
  }
}

// Custom Domain Management
class CustomDomainService {
  private customDomains: Map<string, { tenantId: string; brandId: string; ssl: boolean; verified: boolean }> = new Map()

  // Add custom domain
  async addCustomDomain(tenantId: string, brandId: string, domain: string): Promise<void> {
    if (this.customDomains.has(domain)) {
      throw new Error(`Domain ${domain} is already registered`)
    }

    // Validate domain
    if (!this.isValidDomain(domain)) {
      throw new Error(`Invalid domain: ${domain}`)
    }

    // Generate DNS records for verification
    const dnsRecords = this.generateDNSRecords(domain, tenantId)

    console.log(`=== CUSTOM DOMAIN SETUP ===`)
    console.log(`Domain: ${domain}`)
    console.log(`Tenant: ${tenantId}`)
    console.log(`Brand: ${brandId}`)
    console.log(`\nDNS Records to configure:`)
    console.log(`CNAME: ${domain} -> ${dnsRecords.cname}`)
    console.log(`TXT: ${dnsRecords.txt.name} -> ${dnsRecords.txt.value}`)
    console.log(`========================`)

    // Store domain (pending verification)
    this.customDomains.set(domain, {
      tenantId,
      brandId,
      ssl: false,
      verified: false
    })
  }

  // Verify custom domain
  async verifyCustomDomain(domain: string): Promise<boolean> {
    const domainConfig = this.customDomains.get(domain)
    if (!domainConfig) {
      throw new Error(`Domain not found: ${domain}`)
    }

    // Simulate DNS verification
    console.log(`Verifying domain: ${domain}`)

    // In real implementation, this would check DNS records
    const isVerified = Math.random() > 0.2 // 80% success rate for demo

    if (isVerified) {
      domainConfig.verified = true
      domainConfig.ssl = true // Auto-provision SSL
      console.log(`Domain ${domain} verified successfully!`)
    } else {
      console.log(`Domain ${domain} verification failed. Please check DNS records.`)
    }

    return isVerified
  }

  // Get domain configuration
  getDomainConfig(domain: string) {
    return this.customDomains.get(domain) || null
  }

  // Get all domains for tenant
  getTenantDomains(tenantId: string): Array<{
    domain: string
    brandId: string
    verified: boolean
    ssl: boolean
  }> {
    const domains = []

    for (const [domain, config] of this.customDomains.entries()) {
      if (config.tenantId === tenantId) {
        domains.push({
          domain,
          brandId: config.brandId,
          verified: config.verified,
          ssl: config.ssl
        })
      }
    }

    return domains
  }

  private isValidDomain(domain: string): boolean {
    const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])*$/;
    return domainRegex.test(domain)
  }

  private generateDNSRecords(domain: string, tenantId: string): {
    cname: string
    txt: { name: string; value: string }
  } {
    const verificationToken = crypto.randomUUID().replace(/-/g, '')

    return {
      cname: `app.example.com`,
      txt: {
        name: `_verification-challenge.${domain}`,
        value: `tenant-${tenantId}-${verificationToken}`
      }
    }
  }
}

// Usage Example
async function whiteLabelExample() {
  console.log('=== White-Label Solution Management ===\n')

  // Initialize services
  const themeService = new ThemeManagementService()
  const brandMiddleware = new BrandMiddleware(themeService)
  const emailService = new WhiteLabelEmailService(themeService)
  const domainService = new CustomDomainService()

  // Create custom brand configuration
  console.log('1. Creating custom brand configuration')

  const techCorpBrand: BrandConfig = {
    tenantId: 'tech-corp-123',
    brandId: 'tech-corp-brand',
    name: 'TechCorp Analytics',
    domain: 'analytics.techcorp.com',
    logo: {
      primary: 'https://assets.techcorp.com/logo-primary.png',
      secondary: 'https://assets.techcorp.com/logo-light.png',
      favicon: 'https://assets.techcorp.com/favicon.ico',
      emailLogo: 'https://assets.techcorp.com/email-logo.png'
    },
    colors: {
      primary: '#2563eb',
      secondary: '#64748b',
      accent: '#10b981',
      background: '#ffffff',
      text: '#1f2937',
      error: '#ef4444',
      success: '#10b981',
      warning: '#f59e0b'
    },
    typography: {
      fontFamily: '"Inter", sans-serif',
      headingFont: '"Inter Display", sans-serif',
      baseFontSize: '16px',
      scale: [0.75, 0.875, 1, 1.125, 1.25, 1.5, 1.875, 2.25, 3]
    },
    layout: {
      headerHeight: '72px',
      sidebarWidth: '280px',
      borderRadius: '8px',
      spacing: {
        small: '12px',
        medium: '20px',
        large: '32px'
      }
    },
    customCSS: `
      .tech-corp-button {
        background: linear-gradient(135deg, #2563eb, #1d4ed8);
        border: none;
        transition: all 0.3s ease;
      }

      .tech-corp-button:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
      }
    `,
    features: {
      showBranding: false,
      allowCustomDomain: true,
      customLogin: true,
      customEmails: true,
      whiteLabelReports: true
    },
    integration: {
      analytics: {
        provider: 'segment',
        trackingId: 'seg_techcorp_123abc'
      },
      support: {
        provider: 'zendesk',
        apiKey: 'zendesk_techcorp_key'
      },
      notifications: {
        emailProvider: 'sendgrid',
        smsProvider: 'twilio',
        templates: themeService['getDefaultEmailTemplates']()
      }
    },
    createdAt: new Date(),
    updatedAt: new Date()
  }

  await themeService.saveBrandConfig(techCorpBrand)

  // Create second brand (agency model)
  console.log('\n2. Creating agency brand (cloned from first)')

  const agencyBrand = themeService.cloneTheme('tech-corp-brand', 'digital-agency-brand', {
    tenantId: 'digital-agency-456',
    name: 'Digital Agency Pro',
    domain: 'pro.digitalagency.io',
    colors: {
      primary: '#7c3aed',
      secondary: '#6b7280',
      accent: '#ec4899',
      background: '#ffffff',
      text: '#111827',
      error: '#dc2626',
      success: '#059669',
      warning: '#d97706'
    },
    logo: {
      primary: 'https://assets.digitalagency.io/logo.png',
      favicon: 'https://assets.digitalagency.io/favicon.ico'
    }
  })

  await themeService.saveBrandConfig(agencyBrand)

  // Generate theme files
  console.log('\n3. Generating theme assets')

  const techCorpCSS = themeService.generateThemeCSS(techCorpBrand)
  const techCorpJS = themeService.generateThemeJS(techCorpBrand)

  console.log(`Generated CSS for ${techCorpBrand.name} (${techCorpCSS.length} chars)`)
  console.log(`Generated JS for ${techCorpBrand.name} (${techCorpJS.length} chars)`)

  // Template rendering example
  console.log('\n4. Template rendering example')

  const htmlTemplate = `
    <!DOCTYPE html>
    <html>
    <head>
      <title>{{BRAND_NAME}} - Dashboard</title>
      <link rel="icon" href="{{FAVICON}}">
      <style>{{BRAND_CSS}}</style>
    </head>
    <body>
      <header class="header">
        <img src="{{BRAND_LOGO}}" alt="{{BRAND_NAME}}" height="32">
      </header>
      <main>
        <h1 class="text-primary">Welcome to {{BRAND_NAME}}</h1>
        <p>Your customized dashboard experience.</p>
      </main>
      <script>{{BRAND_JS}}</script>
    </body>
    </html>
  `

  const brandedHTML = brandMiddleware.generateBrandedHTML(htmlTemplate, techCorpBrand)
  console.log(`Generated branded HTML for ${techCorpBrand.name} (${brandedHTML.length} chars)`)

  // Branded email example
  console.log('\n5. Branded email generation')

  const welcomeEmail = emailService.generateBrandedEmail('tech-corp-brand', 'welcome', {
    brand_name: techCorpBrand.name,
    login_url: 'https://analytics.techcorp.com/login',
    user_name: 'John Doe'
  })

  console.log(`Generated welcome email subject: ${welcomeEmail.subject}`)

  // Send branded email
  await emailService.sendBrandedEmail(
    'tech-corp-brand',
    ['john.doe@company.com'],
    'welcome',
    {
      brand_name: techCorpBrand.name,
      login_url: 'https://analytics.techcorp.com/login',
      user_name: 'John Doe',
      recipient_email: 'john.doe@company.com'
    }
  )

  // Custom domain setup
  console.log('\n6. Custom domain configuration')

  await domainService.addCustomDomain(
    'tech-corp-123',
    'tech-corp-brand',
    'analytics.techcorp.com'
  )

  await domainService.addCustomDomain(
    'digital-agency-456',
    'digital-agency-brand',
    'clients.pro.digitalagency.io'
  )

  // Simulate domain verification
  await domainService.verifyCustomDomain('analytics.techcorp.com')

  // Get domain information
  const tenantDomains = domainService.getTenantDomains('tech-corp-123')
  console.log('\n7. Tenant domain status')
  tenantDomains.forEach(domain => {
    console.log(`  ${domain.domain}: ${domain.verified ? 'Verified' : 'Pending'} (SSL: ${domain.ssl})`)
  })

  // Theme analytics
  console.log('\n8. Theme management summary')
  console.log('Total brands configured:', Array.from(themeService['themes'].keys()).length)
  console.log('Custom domains configured:', Array.from(domainService['customDomains'].keys()).length)
}

export {
  BrandConfig,
  ThemeManagementService,
  BrandMiddleware,
  WhiteLabelEmailService,
  CustomDomainService,
  whiteLabelExample
}
        

Tools

Tools frequently paired with this sample

Related

Related sample collections

Related

Related workflows

Hub

Infer JSON Schema from Samples and Spreadsheets

Derive a reviewable JSON Schema draft from representative JSON samples or XLSX rows, then inspect types, requiredness, nulls, and outliers before treating it as a contract.

Hub

Multitrack Audio Mixing and Overlay

Balance multiple audio sources, place timed layers, smooth handoffs with crossfades, and verify a clean, non-clipping result by listening and checking peaks.

Hub

Prepare and Verify Multilingual Web Typography

Check font coverage, compare heading and body pairs with real copy, configure variable axes, and deliver responsive CSS with verified fallback behavior.

Hub

Fan Out One PDF into Personalized Copies and Deliver the Batch

Fill one finished PDF form with a list of records to get a copy per recipient, mark the whole batch with a watermark, split merged output back into individual files, and compress everything into one delivery ZIP.

Home
Tools3212
Workbench
Samples593
Visualizations471
Viewers103
Hubs239
Tags333
Images, Audio & Video657

Image, audio, and video processing, conversion, and optimization tools

Math, Date & Finance647

Calculators, numerics, date logic, statistics, and finance tools

Design & Color298

Color, layout, graphics, visual styling, and design helper tools

Text & Writing209

Writing, cleanup, formatting, extraction, and text analysis tools

Developer & Web193

Developer utilities, networking, web debugging, and automation helpers

Conversion & Encoding175

Format, file, archive, unit, and encoding conversion tools

Lead Generation Quiz Launch and Contact Handoff
Memorial Drafts: Family Review and Print Handoff
Private Habit Records: Backup, Restore and Sharing Review
Article to X and LinkedIn Drafts: Fact Review and Handoff
Markdown Interactive Deck Review and Offline Handoff

© 2026 Elysia Tools. All rights reserved.

DocsPricingAboutTerms of ServicePrivacy PolicyCookiesContact

Development

Multi-Pattern Matcher

Match multiple regex patterns against text in one operation

Media

Audio Multi-band Compressor

Apply compression to specific frequency bands (3-band crossover + compressors)

Health

Extended BMR Calculator (Mifflin / Schofield Multi-Formula Comparison)

Compare Mifflin-St Jeor, original and revised Harris-Benedict, Schofield (FAO/WHO/UNU), and Katch-McArdle BMR equations side by side with mean and spread in kcal/day. Not medical advice.

Utilities

Multi-Timezone Working-Hours Overlap Finder

Find meeting windows where 2–6 participants across time zones are all working. Computes UTC intersection, ranks by comfort, exports .ics.

Data Visualization

Multi-level Pie Chart Generator

Create concentric multi-level pie charts with hierarchical relationships and interactive drill-down functionality

Data Processing

Multi-Table Joiner

Merge and join multiple tables with various join types (inner, left, right, full)

Document Tools

PDF Multi-Column Layout (PDF多栏排版)

Create newspaper/magazine style documents with 2 or 3 columns

Math & Numbers

M/M/c Multi-Server Queue Calculator

Steady-state M/M/c metrics with the Erlang-C formula: offered load, P0, Pw, Lq, L, W, Wq plus Little's-law cross-checks; unstable λ ≥ cμ inputs are rejected.

Architecture

Event Sourcing Samples

Comprehensive event sourcing patterns covering event storage, CQRS architecture, state reconstruction, and event versioning strategies