Engenharia de Software · Backend

Salus

Fundamentos de backend em TypeScript, Node.js, Express, PostgreSQL e Prisma, com Clean Architecture, modelagem de domínio, TDD, autenticação JWT e isolamento por usuário.

Visitar site

Problema

Exercícios de backend frequentemente param no CRUD feliz: sem regras de domínio consistentes, sem persistência bem isolada, sem autenticação real e sem testes suficientes para evitar regressões.

O Salus trabalha um problema pequeno mas realista: gestão de pacientes com regras de domínio e autenticação de usuários. O repositório é público, então cada decisão descrita aqui pode ser inspecionada no código.

Decisões de engenharia

  • Arquitetura em camadas, com as dependências apontando para o domínio.
  • Domínio independente de Express e Prisma; os casos de uso não conhecem o Prisma.
  • Contratos definidos por repository interfaces; Prisma isolado na camada de infraestrutura.
  • Casos de uso dependem de ports/interfaces (repositórios, PasswordHasher, TokenGenerator), não de implementações de infraestrutura; doubles em memória permitem testar a aplicação sem banco.
  • Composição via factories, com injeção explícita de dependências.
  • Código explícito e legível: entidades protegem seus próprios invariantes e erros de domínio são mapeados para HTTP sem vazar stack (princípios de Clean Code).
  • PostgreSQL como persistência e Docker Compose para o ambiente local.
  • Senhas com Argon2 + pepper server-side; JWT obrigatório nas rotas de pacientes, verificado com issuer, audience, subject e expiry.
  • Tratamento global de erros: erros inesperados não vazam stack ao cliente.

Implementação

O fluxo conceitual da API:

HTTP → Routes / Controllers → Application / Use Cases → Domain → Repository abstraction → Prisma adapter → PostgreSQL.

As entidades protegem invariantes como nome, CPF com dígitos verificadores, telefone e data de nascimento. A infraestrutura implementa os contratos definidos pelas camadas internas, sem que o domínio conheça detalhes de framework ou de banco.

Qualidade

64 testes automatizados — 47 unitários e 17 de integração — cobrindo domínio, use cases, adapters, HTTP, isolamento entre usuários, autorização, paginação, confirmação de constraints e PostgreSQL real nos testes de integração. Os testes protegem regras de domínio e decisões da aplicação contra regressões.

O desenvolvimento do Salus foi conduzido com TDD, usando os testes para orientar a implementação e evolução das regras de domínio e dos casos de uso. A implementação foi feita manualmente, sem geração de código por IA.

A fase posterior de production hardening foi desenvolvida com assistência de agente/IA sob revisão humana. Ela não altera a origem manual do core descrito acima.

O CI executa, em sequência:

typecheck → lint → unit tests → build → integration tests.

Segurança

O que o projeto garante hoje:

  • Hash de senhas com Argon2 + pepper server-side; hash nunca retornado nas respostas.
  • JWT assinado com secret vindo do ambiente; variáveis validadas no boot.
  • Arquivo .env fora do Git.
  • Erros inesperados respondidos sem expor stack ao cliente.

Segurança e confiabilidade

As rotas de pacientes exigem JWT verificado. Consultas e mutações são escopadas por ownerId, isolando os pacientes de cada usuário; um acesso cross-user retorna 404. A API valida requests com Zod, normaliza email e CPF, trata conflitos UNIQUE explicitamente e usa erros tipados.

O acesso às coleções usa cursor pagination com limite padrão 20 e máximo 100, ordenação estável por createdAt + id, índice correspondente e UNIQUE(ownerId, cpf). O runtime inclui X-Request-Id, logs JSON redigidos, liveness, readiness com banco, graceful shutdown, migrations versionadas e artifact smoke test.

Trade-offs

  • Modular monolith em vez de microservices: um único deploy, sem o custo de rede e observabilidade distribuída para este tamanho de problema.
  • As repository interfaces adicionam uma pequena camada de mapping, mas isolam o Prisma e deixam os casos de uso testáveis sem banco.
  • JWT stateless simplifica a infraestrutura, mas o access token tem validade de 7 dias e não há revogação nem refresh.
  • O readiness timeout não cancela a query subjacente; shutdown durante uma request longa ainda não tem teste determinístico.
  • Não há rate limiting; advisories de dependências permanecem documentados para acompanhamento.

Limitações

O case não reivindica production-ready, enterprise-grade ou segurança completa. Os riscos residuais incluem ausência de rate limiting, diferença de timing entre email inexistente e senha incorreta, access token de 7 dias sem revogação, readiness timeout sem cancelamento da query subjacente, shutdown durante request longa sem teste determinístico e advisories de dependências documentados.

Voltar aos projetos

VAMOS CONVERSAR

Bons produtos começam com uma boa conversa.

Oportunidades profissionais, parcerias ou uma conversa sobre Engenharia de IA, software e produto.

Conectar no LinkedIn