Cliax, Gestão para Clínicas
Detalhes do Projeto
- Período:
- 09.2026 → hoje
- Link
- cliax.com.br
- Company Project
- TypeScript
- Next.js
- React 19
- PostgreSQL
- Row-Level Security
- SaaS Multi-tenant
- Prisma
- Better Auth
- BullMQ
- fast-check
- Playwright
- Docker
- LGPD

Impacto em números
De 66 em produção, isoladas por clínica no banco
Contra Postgres real, com as suítes de isolamento
21/09 → 22/09/2026
Lista oficial do DATASUS, com busca sem acento
A transformação
Sobre o projeto
Clínica que parcela tratamento caro convive com três problemas de uma vez. Ninguém responde rápido quanto entra nos próximos quinze dias. Cada venda parcelada vira uma dúzia de lançamentos feitos à mão, e erro de digitação vira briga com paciente. E agenda, prontuário e financeiro moram em lugares diferentes, quando moram em algum.
O Cliax começa por essa conta. A venda de R$ 5.000 com R$ 1.000 de entrada e quatro parcelas todo dia 20 é lançada uma vez, e as parcelas se geram sozinhas. O painel do gerente segue uma regra só: todo número abre a lista que o compõe, e a soma da lista bate com o cartão.
A decisão que eu mais defendo no projeto é onde mora o isolamento entre clínicas. Filtrar por clinicId no código funciona até o dia em que alguém esquece um where. Aqui a aplicação conecta ao Postgres com um papel sem BYPASSRLS, e toda tabela com dado de clínica tem política de Row-Level Security. Se a política falhar, a consulta volta vazia, e não com o dado do vizinho.
Regra que ninguém cobra vira sugestão. As suítes rls-coverage e tenant-isolation quebram de propósito quando alguém cria uma tabela com clinicId e esquece a política ou a fábrica de teste. Desligar o RLS derruba 7 testes, e um teste de mutação confirmou que as suítes pegam a falha. Antes de adotar, medi o custo: cerca de 6 ms por transação, não por consulta. Isso virou regra de código, e cada tela agrupa as leituras numa transação só.
O prontuário vai pelo mesmo caminho. Recepção, financeiro e até o dono sem papel clínico recebem zero linhas, mesmo consultando o banco direto. Registro finalizado é travado por gatilho, correção entra como adendo com autor e hora, e cada registro leva um hash encadeado ao anterior do mesmo paciente. O PDF do prontuário confere a cadeia.
O resto é o que uma clínica espera encontrar, feito com o mesmo cuidado:
- agenda com cinco visões, arrastar para remarcar e conflito de horário barrado no banco;
- documentos com papel timbrado, variáveis e um QR que qualquer pessoa usa para conferir se o atestado é verdadeiro;
- prescrição pela Memed com o paciente já preenchido, esperando a homologação deles para ligar;
- link de reservas público, com limite por IP e por celular e o desafio anti-robô da Cloudflare pronto para ligar;
- o financeiro completo, construído e testado na última semana de setembro: taxa de cartão com recebível, caixa da recepção, repasse de profissionais, conciliação bancária por OFX, fechamento de mês e o lote do Carnê-Leão no layout da Receita.
Dinheiro é sempre inteiro em centavos, e data de vencimento é DATE, para não escorregar no fuso. O monólito é modular e o ESLint cobra as fronteiras: módulo não importa Next, domain/ não importa banco e ninguém entra no miolo de outro módulo sem passar pelo index.ts.
O desafio
Velocidade sem trava é imprudência. O primeiro commit é de 21 de setembro, e o sistema estava no ar no dia 22. Isso só foi possível porque a trava chegou antes da pressa: TDD nas regras de domínio, teste de propriedade com fast-check nos invariantes financeiros, integração contra Postgres de verdade e uma revisão de segurança a cada marco. Numa delas apareceram um redirecionamento aberto na entrada do modo suporte e um esgotamento de conexões no backoffice. Os dois foram fechados antes de alguém usar.
O mais difícil foi dizer não. Convênio, nota fiscal e odontograma ficaram para depois de propósito, e o produto está em piloto para aprender com clínica de verdade antes de endurecer regra que ninguém usou.
Métricas de Crescimento
Testes de integração ao longo da semana
Resultados
No ar desde 22/09/2026, em piloto. Em produção são 66 tabelas, 54 delas isoladas por RLS, e a suíte de integração passa 761 testes contra Postgres real. Em cinco dias ficaram prontos o financeiro, a agenda, o prontuário, os documentos clínicos, a integração com a Memed, o link de reservas e o backoffice de suporte, com segundo fator obrigatório para quem mexe com dado clínico.
Stack técnica
Next.js 16 e React 19
Monólito modular: rotas e server actions em src/app, regra de negócio em módulos que não conhecem o Next.
PostgreSQL 17 com Row-Level Security
A aplicação conecta como app_user, sem BYPASSRLS, e toda tabela com dado de clínica tem política.
Prisma 7
82 models e 33 migrations, publicadas em duas etapas: schema primeiro, código depois.
Better Auth
Segundo fator obrigatório para quem administra a clínica e para quem mexe com dado clínico.
BullMQ e Redis
Rotinas diárias idempotentes: alertas de vencimento, conciliação da cobrança e recebíveis de cartão.
Gotenberg
PDF de recibo, carnê, prontuário e documento clínico, gerado uma vez e guardado.
Vitest, fast-check e Playwright
Unidade, propriedade, integração contra Postgres real e jornadas no navegador.
Asaas e Memed
Cobrança com baixa automática por webhook e prescrição digital dentro do atendimento.
Galeria(2)

