architecture.md 4.8 KB

Arquitetura — Backend

Visão geral

O backend segue uma arquitetura em camadas com bootstrap por factories. Cada domínio de negócio é encapsulado em um conjunto padronizado de arquivos.

index.js
└── CoreFactory.Iniciar()
    ├── BancoFactory   → conecta ao MySQL, valida conexão
    └── ServerFactory  → cria o Express app, registra middlewares, sobe o servidor
         └── Roteamento.IniciarRoteamento(app)
              └── Domínios: Auth · Chat · Conversations · Documents · Ingest · Search · Usuario
                   └── *.Rotas.js → *.Controller.js → *Service.js → Model (Objection)

Camadas

Factories (src/factories/)

Responsáveis pelo bootstrap da aplicação. Chamadas em sequência por index.js na raiz.

Factory Responsabilidade
Core.factory.js Orquestra Banco + Server
Banco.factory.js Conecta ao MySQL e valida a conexão
Server.factory.js Cria o app Express, registra middlewares globais, sobe o servidor HTTP

Roteamento (src/routes/index.js)

A classe Roteamento registra todos os domínios no Express via IniciarRoteamento(app). Cada domínio tem seu próprio arquivo *.Rotas.js que define as rotas e middlewares daquele domínio.

Todos os domínios são montados sob o prefixo /api, que recebe dois middlewares globais antes de qualquer rota: rateLimitMiddleware (RateLimit.js) e authMiddleware (Validajwt.js). Ou seja, o JWT é decodificado globalmente; os middlewares requireUser/requireAdmin por rota apenas verificam o resultado.

Controllers (src/controllers/)

Recebem a requisição HTTP, extraem os dados necessários (params, body, user) e delegam ao Service correspondente. Não contêm lógica de negócio.

Services (src/services/)

Contêm toda a lógica de negócio. São chamados pelos controllers. Podem chamar Models (Objection) ou clients externos (Qdrant, Ollama).

Models (src/models/)

Modelos Objection.js. Mapeiam as tabelas do MySQL e definem relacionamentos.

Model Tabela
Usuario.model.js usuarios
RefreshToken.model.js refresh_tokens
Conversation.model.js conversations
Message.model.js messages

Middleware (src/middleware/)

Arquivo Função
Validajwt.js Verifica e decodifica o JWT do header Authorization
RequireUser.js Exige usuário autenticado (qualquer nível)
RequireAdmin.js Exige nível "3" (administrador)
Validate.js Valida body/params/query com schema zod (schema.parse())
ParseId.js Converte req.params.id para número e valida
RateLimit.js Rate limiting por IP
ErrorHandler.js Captura erros e formata a resposta de erro

Schemas de validação (src/middleware/schemas/)

Schemas zod usados com o middleware Validate (que chama schema.parse()). Um arquivo por domínio que exige validação:

Arquivo Domínio
Chat.Schema.js Corpo do chat
Ingest.Schema.js Corpo do ingest
Search.Schema.js Corpo da busca
Usuario.Schema.js Criar, atualizar e alterar senha de usuário

Padrão de arquivos por domínio

Todo domínio segue a convenção de nomenclatura abaixo:

src/
├── routes/        NomeDoModulo.Rotas.js
├── controllers/   NomeDoModulo.Controller.js
├── services/      nomeDoModuloService.js
├── models/        NomeDoModulo.model.js          (se houver tabela)
└── middleware/
    └── schemas/   NomeDoModulo.Schema.js         (se houver validação)

Alias ESM (#*)

O package.json define um alias de importação para evitar caminhos relativos longos:

"imports": {
  "#*": "./src/*"
}

Como ficaria:

import { UsuarioController } from "#controllers/Usuario.Controller.js";
import { db } from "#config/db.config.js";

Estado atual: o alias está definido e funciona, mas ainda não é usado em nenhum arquivo do src/ — todo o código usa imports relativos (../config/db.config.js). Foi adicionado na refatoração para espelhar o @ do minha_back, mas a migração dos imports não foi feita.

Domínios existentes

Domínio Prefix da rota Descrição
Auth /api/auth Login, logout, refresh de token
Chat /api/chat Envio de mensagens ao LLM
Conversations /api/conversations CRUD de conversas persistidas
Documents /api/documents Listagem e exclusão de documentos
Ingest /api/ingest Ingestão de conteúdo na base RAG
Search /api/search Busca semântica nos documentos
Usuario /api/users CRUD de usuários do sistema

Health check

GET /health — retorna o status de todos os serviços:

{
  "ok": true,
  "checks": {
    "api": true,
    "db": true,
    "qdrant": true,
    "ollama": true
  }
}