Pular para conteúdo

Camadas e estrutura

TLDR: quatro camadas (domínio, aplicação, infraestrutura, apresentação), dependência sempre apontando pra dentro. Cada módulo de feature replica essa estrutura internamente, agrupado por área de negócio.

Termo Vá pra
O que cada camada contém As quatro camadas
A árvore de diretório completa Estrutura de diretórios
Como um módulo de feature é organizado Estrutura de um módulo
Todos os grupos e módulos existentes Grupos de módulo

As quatro camadas

flowchart TD
    A["Apresentação\nREST controllers, GraphQL resolvers"]
    B["Aplicação\ncommand handlers, query handlers, autorização"]
    C["Domínio\nentidades, contratos de repositório, erros, validação, scalars"]
    D["Infraestrutura\nTypeORM, Keycloak, BullMQ, filesystem, config"]

    A --> B --> C
    D -- "implementa contratos de" --> C

Domínio (src/domain/): a camada mais interna. Contém entidades com constructor privado e factory methods (create, load, update), schemas Zod (EntitySchema, CreateSchema, UpdateSchema), abstrações (IRepositoryCreate<T>, IRepositoryFindAll<T>, IPermissionChecker, IAccessContext), scalars semânticos (IdUuid, ScalarDateTimeString), erros de domínio (EntityValidationError, BusinessRuleViolationError) e os decorators de DI (Dep, Impl). Regra de ouro: o domínio nunca importa de infrastructure.*, server/, ou qualquer framework.

Aplicação (src/application/): orquestra o domínio. Contém command handlers (Create, Update, Delete), query handlers (FindOne, List), permission checkers, erros de aplicação (ResourceNotFoundError, ForbiddenError, UnauthorizedError, ValidationError, ConflictError, InternalError, ServiceUnavailableError) e helpers de paginação. Não contém regra de negócio (fica no domínio) nem detalhe de persistência (fica na infraestrutura).

Infraestrutura (src/infrastructure.*/): implementa os contratos do domínio com tecnologia concreta, um diretório por concern:

Diretório Tecnologia O que implementa
infrastructure.database TypeORM + PostgreSQL Repositórios, migrações, paginação, connection proxy
infrastructure.identity-provider Keycloak + JWKS Validação de token, admin client
infrastructure.message-broker BullMQ sobre PostgreSQL Publicação e consumo de mensagens
infrastructure.storage Filesystem + Sharp Upload e redimensionamento de arquivos/imagens
infrastructure.config NestJS ConfigModule Leitura de variável de ambiente
infrastructure.graphql Apollo Server Configuração GraphQL, DTOs base, cache LRU
infrastructure.logging Middleware próprio Correlation ID
infrastructure.authorization Implementações locais Permission checkers concretos
infrastructure.timetable-generator Contratos de mensagem Tipos e commands de geração de horário
infrastructure.dependency-injection NestJS DI Configuração do container

Apresentação (src/modules/*/presentation.*/): traduz protocolo externo (HTTP, GraphQL) em chamada pra aplicação. Regra: apresentação nunca acessa banco diretamente, sempre delega pra um handler.

Estrutura de diretórios

management-service/
├── .devcontainer/          # Dev Container (VS Code / WebStorm)
├── .docker/                # Containerfile e compose.yml
├── .deploy/                # Helm/Kubernetes e VPS via Docker Compose
├── .github/workflows/      # Pipelines de CI/CD
├── src/
│   ├── domain/             # Camada de domínio
│   ├── application/        # Camada de aplicação
│   ├── infrastructure.*/   # Um diretório por concern de infraestrutura
│   ├── modules/            # Módulos de feature
│   ├── server/             # Bootstrap NestJS, filtros, interceptors, auth
│   ├── shared/             # Mappers, validação, decorators compartilhados
│   ├── utils/              # Utilitários puros
│   ├── commands/           # Scripts CLI
│   └── test/                # Helpers de teste
├── justfile
└── .env.example

Estrutura de um módulo

Cada módulo em src/modules/<grupo>/<nome>/ replica a mesma estrutura hexagonal internamente:

modules/<grupo>/<nome-do-modulo>/
├── domain/
│   ├── authorization/      # IPermissionChecker
│   ├── commands/           # Definições de command
│   ├── queries/            # Definições de query, schemas, result types
│   ├── repositories/       # Contrato do repositório (Symbol + type)
│   └── shared/             # QueryFields, input refs
├── application/
│   ├── authorization/      # Implementação do permission checker
│   ├── commands/           # Command handlers + testes
│   └── queries/            # Query handlers + testes
├── infrastructure.database/
│   └── typeorm/            # Entidade TypeORM + adapter + mapper
├── presentation.rest/      # Controllers, DTOs, mappers
└── presentation.graphql/   # Resolvers, DTOs, mappers (quando aplicável)

Grupos de módulo

Grupo Módulos
acesso/ autenticacao, usuario (inclui perfil)
ambientes/ ambiente, bloco, campus
armazenamento/ arquivo, imagem, imagem-arquivo
ensino/ curso, diario, disciplina, modalidade, nivel-formacao, oferta-formacao, turma, entre outros
estagio/ candidatura, empresa, empresa-avaliacao, estagiario, estagio, folha-ponto, relatorio, responsavel-empresa, solicitacao
calendario/ agendamento, colecao, consultas, gerar-horario, grade-horaria, horario-consulta, horario-edicao, indisponibilidade-ambiente, indisponibilidade-professor, letivo, solicitacao-mudanca, turmas (disponibilidade)
localidades/ cidade, endereco, estado
relatorios/ relatorio

src/modules/@shared/ é legado em remoção, nunca importar dele, ver Decisões arquiteturais.

Diretórios compartilhados

Diretório Propósito
src/domain/ Entidades base, scalars, DI, metadata compartilhados
src/application/ Erros de aplicação, contratos de paginação
src/shared/ Validação Zod, mappers, decorators de apresentação
src/server/ Bootstrap NestJS, filtros, interceptors, auth, access context
src/utils/ Utilitários puros (datas, helpers)
src/commands/ Scripts CLI
src/test/ Helpers de teste (mocks, factories)