Skip to main content

title: “Multi-Tenant Architecture” description: “Arsitektur multi-tenant: CompanySwitcher 893 baris, quadruple persistence, subdomain detection, plan-based slot limits, dan data isolation.”

Multi-Tenant Architecture

Multi-Tenant Quinn of Spicy menggunakan arsitektur multi-tenant yang memungkinkan satu sistem digunakan oleh multiple perusahaan (tenants) dengan isolasi data penuh. CompanySwitcher.jsx (893 baris) adalah komponen utama yang menangani switching antar company dengan quadruple persistence pattern, plan-based slot limits, dan real-time synchronization. Sistem ini mendukung subdomain-based tenant detection untuk custom domain (erp.snishop.com, snishop.id, apotekpro.id) dengan fallback ke selector UI. Setiap entity yang company-specific memiliki field company_id yang otomatis di-filter di setiap query, memastikan data isolation 100%. Multi-tenant architecture ini cocok untuk franchise, holding company, consultant/agency, dan SaaS platform yang melayani multiple bisnis.

Arsitektur Komponen

Entity & Model

Company

User (Multi-Tenant Fields)

CompanyMember

Fitur Utama

1. Quadruple Persistence Pattern

Company context disimpan di 4 layer untuk memastikan durability: Resolution Priority:

2. Plan-Based Slot Limits

Setiap subscription plan memiliki batas jumlah company yang bisa diakses:

3. Subdomain Detection

tenantHelper.js (80 baris) mendeteksi tenant dari subdomain: Base Domains: Detection Logic: Excluded Environments: Preview environments (base44.app, vercel.app, netlify.app, hostinger.com) tidak melakukan tenant resolution untuk mencegah accidental data leakage.

4. Company Switching Flow

5. Data Isolation

Setiap entity yang company-specific memiliki field company_id: Automatic Filtering: Statistics:

6. Company Creation

Idempotency Key: Mencegah duplikasi company creation akibat network retry atau double-click.

7. Demo Mode Support

CompanySwitcher mendukung demo mode untuk trial experience:

8. Real-time Synchronization

CompanySwitcher listen ke multiple events untuk real-time updates:

Use Cases

1. Franchise

Satu sistem untuk multiple outlet/franchise:
  • Tiap outlet = 1 company
  • Headquarter bisa lihat semua outlet
  • Tiap outlet punya data terpisah

2. Holding Company

Parent company dengan multiple subsidiaries:
  • Parent = 1 company
  • Subsidiaries = multiple companies
  • Parent bisa akses semua subsidiaries
  • Subsidiaries hanya lihat data sendiri

3. Consultant / Agency

Konsultan yang handle multiple clients:
  • Consultant = 1 user
  • Clients = multiple companies
  • Consultant bisa switch antar client
  • Tiap client data terpisah

Security

1. Data Isolation

  • Enforced di database level
  • Automatic filtering di semua queries
  • Cross-company access = error + alert

2. Audit Trail

Setiap akses ke data company lain dicatat:

3. Subdomain Sanitization

tenantHelper.js melakukan sanitization untuk mencegah injection:
  • Remove special characters
  • Lowercase normalization
  • Length validation
  • Reserved name check

Integrasi Cross-Module

Troubleshooting

User tidak bisa switch company

Penyebab: User belum di-assign ke company lain atau slot limit tercapai Solusi: Admin assign user ke company yang dimaksud atau upgrade plan

Data tidak muncul setelah switch

Penyebab: Company baru belum punya data Solusi: Create data di company baru, atau import dari company lama

Error “Access denied to company X”

Penyebab: User tidak punya akses ke company X Solusi: Admin assign user ke company X dengan role yang sesuai

Subdomain tidak terdeteksi

Penyebab: Domain termasuk preview environment atau subdomain tidak valid Solusi: Check base domain list dan gunakan dev override via URL param

Tips

  • Quadruple persistence memastikan company context survive browser restart dan sync antar device
  • Plan-based slot limits mencegah abuse — upgrade plan jika butuh lebih banyak company
  • Subdomain detection otomatis untuk custom domain — tidak perlu manual config
  • BroadcastChannel sync memastikan semua tab mendapat update real-time saat switch company
  • Idempotency key mencegah duplikasi company creation — aman dari network retry
  • Demo mode berguna untuk onboarding — calon user bisa trial tanpa commitment

Referensi Entity Schema (base44)

Dokumentasi schema lengkap untuk setiap entity yang terlibat dalam arsitektur multi-tenant, diekstrak langsung dari file definisi JSONC di base44/entities/.

Entity Relationship Diagram


Schema Detail per Entity

Company

Entity utama yang merepresentasikan satu tenant/perusahaan dalam sistem multi-tenant. Sub-field settings:

User

Entity pengguna sistem dengan field-field multi-tenant yang memungkinkan satu user mengakses beberapa company.

CompanyMember

Entity yang merepresentasikan keanggotaan seorang user dalam suatu company. Setiap baris adalah relasi many-to-many antara User dan Company dengan role dan permission tersendiri.

CompanyInvitation

Entity undangan untuk bergabung ke suatu company. Mengikuti lifecycle invitation: dibuat -> diterima/ditolak/kedaluwarsa.

Workspace

Entity workspace yang mendukung scoped task/note management dalam suatu company. Workspace bisa bersifat company-scoped atau personal. Sub-field settings:

WorkspaceMember

Entity keanggotaan dalam workspace. Setiap baris adalah relasi many-to-many antara User dan Workspace. Sub-field permissions:

Subscription

Entity langganan yang bisa melekat ke user (personal) atau ke company.

Diagram Status: Sikapus Undangan Company

Diagram Status: Keanggotaan CompanyMember

Diagram Status: Langganan Subscription


Diagram Sekuens: Undangan & Penerimaan Member Baru

Diagram Sekuens: Pembuatan Workspace dalam Company

Diagram Sekuens: Switch Company dengan Quadruple Persistence


Tabel Enum Lengkap

Company.industry

Company.owner_subscription_plan & User.subscription_plan

CompanyMember.role

CompanyMember.status

CompanyInvitation.status

User.role

User.admin_type

User.admin_tier

User.membership_duration_type

WorkspaceMember.role

Workspace.settings.default_task_priority

Subscription.billing_cycle

Subscription.status

Company.settings.batch_allocation_strategy

Company.settings.tax.mode

Company.settings.tax.rounding

Company.settings.spoilage_default_treatment


Tabel RBAC: Hak Akses CompanyMember

Tabel berikut merinci hak akses (permissions) yang dapat di-set per CompanyMember. Default nilai menunjukkan permission untuk role employee.

Matriks Role vs Permission (Rekomendasi Default)