Skip to main content

Stack tecnológica


Estrutura de pastas


Multi-tenancy

O sistema é estritamente multi-tenant. Cada empresa (tenant) enxerga apenas os seus próprios dados. A isolamento funciona em três camadas:

Três componentes da tenancy

Regra crítica: O TenantSubscriber só garante isolamento em inserts. Todas as queries (find, createQueryBuilder, etc.) devem filtrar por tenantId explicitamente no service. Nunca confie apenas no subscriber para leitura.

TenantBaseEntity

Toda entity de domínio herda de TenantBaseEntity, que já traz as colunas id, tenantId, createdAt e updatedAt:

CQRS — Command / Query

Módulos complexos (como catalog) separam leitura e escrita em services distintos:

Regras de performance (QueryService)

  1. Sem joins pesados em listagem — agregados como BOM, componentes e estoque só são carregados em endpoints de detalhe (findOne).
  2. Paginação obrigatória — todo endpoint de lista deve paginar.
  3. Índices compostos — sempre criar @Index em combinações tenantId + campo_de_filtro.

Padrão de transação (CommandService)

Sempre passe o manager recebido no callback para métodos auxiliares. Isso garante que tudo roda dentro da mesma transação.

Autenticação

Guards

  • JwtAuthGuard — protege todas as rotas autenticadas.
  • ThrottlerGuard — rate limit global: 200 req/min por IP.

Filas e processamento assíncrono

Jobs assíncronos usam BullMQ com Redis como broker:

Configuração global

Padrão Outbox

O módulo common/outbox/ implementa o padrão Transactional Outbox: eventos são gravados no banco dentro da mesma transação da operação de domínio e depois processados pelo worker. Isso garante consistência mesmo que o Redis esteja temporariamente indisponível.

Integrações com marketplaces

A camada de integrações segue o padrão Adapter:

Fluxo de conexão OAuth

  1. Frontend redireciona o usuário para a URL de autorização do marketplace.
  2. Marketplace redireciona de volta para POST /integrations/oauth/callback.
  3. Backend troca o code por tokens de acesso.
  4. Tokens são criptografados com TOKEN_ENCRYPTION_KEY e salvos no banco.
  5. Um @Cron job renova tokens automaticamente antes de expirarem.

Serviço de tokens

O módulo integrations/tokens/ gerencia o armazenamento seguro dos tokens OAuth:
  • Criptografia AES usando a variável TOKEN_ENCRYPTION_KEY.
  • Cada par de tokens (access + refresh) é associado ao tenantId + marketplace.
  • Renovação automática via scheduler.

Módulos do sistema

Módulo Catalog em detalhe

O catálogo é o módulo mais extenso. Seus services cobrem:

Padrões de código

Entities

DTOs

Error handling


Testes


Checklist para novos desenvolvedores

1

Entenda a multi-tenancy

Leia common/tenancy/ — middleware, subscriber e TenantAwareService. Toda query deve filtrar por tenantId.
2

Crie a Entity

Em src/seu-modulo/entities/. Herde de TenantBaseEntity. Use snake_case para colunas e crie índices.
3

Crie os DTOs

Separe CreateXDto, UpdateXDto e, se necessário, BulkCreateXDto. Use class-validator.
4

Crie o Service

Para módulos simples, um único service. Para módulos complexos, separe em Command e Query.
5

Crie o Controller

Defina endpoints REST. Decore com @ApiTags, @ApiResponse para o Swagger.
6

Registre no Module

Adicione controllers e providers no module do domínio. Importe no AppModule se for um módulo novo.
7

Gere a Migration

npm run migration:generate -- --name=NomeDaAlteracao → revise → npm run migration:run.