Documento Técnico: Recomendação Backend MN2J

Autenticação e Multi-Tenancy

1. Introdução

Este documento visa definir as melhores práticas e tecnologias para o desenvolvimento do backend do projeto MN2J, especialmente no que tange a:

2. Metodologia Multi-Tenant Recomendada

2.1. Abordagem recomendada: Shared Database + Shared Schema com Tenant ID

Definição:

Todas as entidades no banco de dados possuem um campo obrigatório tenant_id (UUID/string), que indica a qual tenant (cliente, anfitrião ou empresa) aquele registro pertence.

Por que essa abordagem?

2.2 Outras abordagens (não recomendadas para MN2J atualmente)

Abordagem Quando usar? Por que evitar no MN2J agora?
Tenant-per-schema Empresas B2B com poucos tenants Complexidade de migração e manutenção
Tenant-per-database Enterprise, compliance estrita Custo e complexidade elevados
Keycloak (multi-realm) Enterprise, sistemas internos Overkill para app público; integrações complexas

3. Tecnologias Recomendadas

Componente Tecnologia Sugerida Motivação
Backend Node.js com NestJS Framework modular, robusto e suporte a Middleware
ORM Prisma ORM Tipagem segura, fácil integração multi-tenant
Banco de Dados PostgreSQL Suporte a RLS, JSONB, escalável, confiável
Cache Redis Sessões, filas (Bull), cache
Autenticação JWT + Passport.js Leve, flexível, sob controle, integra fácil
Storage AWS S3 (produção) / local (MVP) Armazenamento escalável de arquivos/imagens
CI/CD GitHub Actions Automação de testes e deploys

4. Modelagem de Dados: Exemplo Multi-Tenant

4.1 Exemplo: Tabela Booking

CREATE TABLE bookings ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL, user_id UUID NOT NULL, space_id UUID NOT NULL, start_date DATE NOT NULL, end_date DATE NOT NULL, status VARCHAR(50), created_at TIMESTAMP DEFAULT now(), updated_at TIMESTAMP DEFAULT now() ); CREATE INDEX idx_bookings_tenant ON bookings (tenant_id);

4.2 Exemplo: Relação User e Tenant

CREATE TABLE tenants ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, plan VARCHAR(50) DEFAULT 'free', created_at TIMESTAMP DEFAULT now() ); CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants(id), email TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, role VARCHAR(50) DEFAULT 'user', created_at TIMESTAMP DEFAULT now() ); CREATE INDEX idx_users_tenant ON users (tenant_id);

5. Migrações Tenant-Aware

6. Estratégias Modernas de Consulta e APIs

Query exemplo (Prisma):

const bookings = await prisma.booking.findMany({ where: { tenant_id: currentTenantId }, });

7. Autenticação e Justificativa para Não Usar Keycloak

Aspecto Keycloak JWT + Passport.js (Recomendado)
Complexidade Alta — Setup e manutenção Baixa — integração direta no NestJS
Customização UX Difícil Totalmente customizável no frontend
Multi-tenant Multi-realm, porém pesado Controle nativo com tenant_id no token
Custo Alto (infra + manutenção) Baixo (infra mínima)
Experiência do usuário Pode ser pesada Ágil e simples

Resumo:

Para MN2J, que é uma plataforma pública B2C com milhares de usuários e tenants, usar JWT com Passport em NestJS é a abordagem mais leve, flexível e econômica, mantendo o controle total sobre o fluxo.

8. Considerações Finais e Próximos Passos

  1. Definir schema inicial com tenant_id obrigatório.
  2. Criar middleware/guard NestJS para resolver tenant via JWT.
  3. Configurar Prisma para aplicar filtros multi-tenant automaticamente.
  4. Implementar migrações e testes completos.
  5. Construir painel admin para criação/controle de tenants.
  6. Monitorar e ajustar performance conforme crescimento.

Anexo: Exemplo Básico Middleware Tenant Guard (NestJS)

@Injectable() export class TenantGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { const req = context.switchToHttp().getRequest(); if (!req.user || !req.user.tenant_id) { throw new UnauthorizedException('Tenant not found in token'); } req.tenantId = req.user.tenant_id; return true; } }