CARACTERÍSTICAS / MULTI-TENANCY

Workspaces,
memberships,
y API keys.

Cada modelo está scopeado por org. Invitaciones, asignación de roles y API keys de tenant están cableadas de punta a punta. Impersonación de admin con cookies firmadas HMAC.

Construido alrededor del aggregate Organization.

Workspaces de org

Cada entidad de dominio lleva un orgId. Los repos lo enforce vía un DataSource scopeado — no hay leaks entre orgs.

Invitaciones

Tokens de invite con tiempo limitado, role-on-accept, expiración, revoke, resend. Templates de email listos en 3 idiomas.

API keys

Keys por tenant con permisos scopeados, rotation, tracking de last-used, BCrypt-hashed at rest. CLI incluido.

Roles de miembro

Owner, admin, member out of the box. Sumá roles en un archivo; ESLint te marca cada lugar que olvidaste actualizar.

Domain claim

Auto-join opcional por dominio de email — invitá al equipo claimeando acme.com una sola vez.

Impersonación

Los admins de plataforma pueden actuar como cualquier tenant para soporte. Cada acción se loggea + la cookie es HMAC-signed y short-lived.

Un repository pattern que conoce tu tenant.

El tenant scoping ocurre en la capa de datos, no en cada query. El constructor del repositorio recibe un OrgId; cada find/create/update lo lleva implícitamente. No podés leer accidentalmente datos de otra org.

modules/tenancy/infrastructure/orgScopedRepo.ts
 1  export class OrgScopedProjectRepo implements IProjectRepo {
 2    constructor(private readonly db: PrismaClient,
 3                private readonly orgId: OrgId) {}
 4  
 5    findAll() {
 6      return this.db.project.findMany({
 7        where: { orgId: this.orgId },
 8      });
 9    }
10  }

Multi-tenant desde la línea uno.

Nada de retrofittear org-scoping a los seis meses. UseDeploy lo hornea en el aggregate.