ื“ืœื’ ืœืชื•ื›ืŸ ื”ืจืืฉื™

Multi-Tenant Data Flow

How requests are scoped to tenants throughout the stack.

Request Flowโ€‹

Layer-by-Layerโ€‹

1. JWT Tokenโ€‹

Every JWT contains the tenantId:

{
"id": "user-uuid",
"tenantId": "tenant-uuid",
"role": "ADMIN",
"exp": 1735689600
}

2. RequestContextโ€‹

RequestContext stores the current tenant in async local storage:

RequestContext.currentTenantId(); // returns tenant UUID

3. Guard Layerโ€‹

TenantPermissionGuard validates:

  • Token contains valid tenantId
  • Tenant exists and is active

4. Service Layerโ€‹

All services extend TenantAwareCrudService which auto-filters by tenant:

// Automatically adds WHERE tenantId = :currentTenant
const tasks = await this.taskService.findAll();

5. Repository Layerโ€‹

Query builders append tenant filter:

SELECT * FROM task
WHERE "tenantId" = 'tenant-uuid'
AND "organizationId" = 'org-uuid'

Cross-Tenant Accessโ€‹

Only SUPER_ADMIN role can access data across tenants.