Problema
O Omni centraliza pacientes e agendamentos e automatiza confirmações, mantendo dados de clínicas diferentes separados. A solução combina um painel web, uma API de domínio e bots de automação.
Tecnologias
- Java 17
- Spring Boot 3
- PostgreSQL
- React 18
- TypeScript
- Python 3.12
- Docker
Decisões de engenharia
Camadas com responsabilidades distintas
A API usa Java 17 e Spring Boot 3, o painel usa React e TypeScript, e as automações rodam em Python. PostgreSQL mantém os dados transacionais.
Multi-tenancy por tenant_id
O isolamento usa um discriminador tenant_id e filtros do Hibernate na camada de acesso a dados. Autenticação usa JWT com renovação automática no cliente.
Serviços distribuídos
O frontend é publicado na Vercel, o backend em container no Render e o PostgreSQL no Supabase com pool de conexões gerenciado.
Rastreabilidade por requisição
O backend documenta logs com requestId, userId e tenantId, além de endpoint /health para acompanhar API e conexão com o banco.
Trade-offs
Isolamento concentrado na aplicação
A documentação informa que o banco não usa RLS: a separação entre clínicas depende do tenant_id e dos filtros aplicados no código Java.
Plano gratuito e cold start
O serviço gratuito do Render hiberna após inatividade. O frontend precisa comunicar o despertar da API e oferecer uma nova tentativa.
Mais serviços, mais operação
Separar frontend, API, banco e bots permite escolher a ferramenta de cada camada, mas amplia configuração de segredos, monitoramento e procedimentos de recuperação.
Evidências no repositório
- O guia de monitoramento descreve /health com estado da API e da conexão PostgreSQL.
- A documentação lista rate limiting nas rotas de autenticação e cabeçalhos de segurança configurados no Spring.
- O ambiente de produção usa PostgreSQL no Supabase por connection pool; o ambiente local é reproduzido com Docker Compose.
O que eu mudaria
Eu seguiria a recomendação do próprio guia de produção e moveria os bots para um worker de background dedicado. Também adicionaria uma segunda barreira de isolamento no banco para complementar os filtros de tenant da aplicação.
Fontes verificáveis
As afirmações desta página apontam para documentação e código públicos.
