Case 04Gestão de academias
GymOS
Matrícula, mensalidade e check-in de duas unidades num só sistema.
Sistema de gestão que concebi e construí sozinho para uma academia de bairro com duas unidades: cadastro do aluno, planos, cobrança recorrente, check-in, aulas, treinos e indicadores em um só lugar. A recepção para de conferir caderno e planilha, e a inadimplência passa a ser tratada no dia em que acontece.
- Cliente
- Academia de bairro em São José dos Campos · 2 unidades
- Período
- 2026
- Equipe
- Projeto solo · do discovery à implantação
- Papel
- Engenheiro full stack · projeto sob medida de ponta a ponta
- Stack
- Next.js · React · TypeScript · Tailwind CSS · NestJS · Prisma
- Confidencialidade
- Dados de clientes preservados
Resultados em números
- 500+alunos ativos gerenciadosduas unidades e 30 professores no mesmo sistema
- 40%menos inadimplência em seis mesescobrança recorrente com régua de tentativas
- 3 spara liberar a entrada do alunoantes, conferência manual de ficha e pagamento
- 12 hpor semana devolvidas à recepçãosem planilha de cobrança nem caderno de entrada
O contexto do negócio
- Cliente
- Academia de bairro em São José dos Campos · 2 unidades
- Período
- 2026
A academia atende mais de 500 alunos em duas unidades no mesmo bairro, com 30 professores revezando turnos e turmas. Até então, a operação rodava em fichas de papel, planilhas por unidade e mensalidade cobrada no balcão. A recepção conferia o nome do aluno num caderno, ninguém sabia com segurança quem estava em dia, quem podia treinar na outra unidade ou quando um plano vencia, e a inadimplência só aparecia no fechamento do mês, quando já era difícil recuperar.
O desafio
O dono não queria um software genérico de prateleira: queria que o sistema seguisse as regras da casa. Isso significava controlar acesso por plano e por unidade, cobrar todo mês sem depender de alguém lembrando, bloquear e liberar o aluno conforme o pagamento e dar aos professores a agenda e a lista de alunos sem expor o financeiro. Tudo isso para uma equipe que nunca tinha usado sistema nenhum.
Duas unidades, uma operação
Cada unidade tem horários, capacidade e equipe próprios, mas o aluno é um só. Há planos que valem para uma unidade e planos que valem para as duas, e o gerente de cada casa só deve enxergar a sua.
Inadimplência descoberta tarde
Sem cobrança recorrente, a mensalidade dependia do aluno lembrar e da recepção anotar. Quem atrasava continuava treinando por semanas até alguém perceber na planilha.
Recepção como gargalo
No horário de pico, a fila se formava na entrada: procurar a ficha, conferir o pagamento, perguntar o plano. A conferência manual atrasava o aluno e deixava passar quem não podia entrar.
O que entreguei
Construí o GymOS como um monorepo com API em NestJS, painéis em Next.js e PostgreSQL via Prisma. Cada pessoa tem sua porta de entrada: recepção e gestão no painel da academia, professores no portal do instrutor, alunos na própria área com check-in, aulas, treinos e progresso. Por trás, uma regra única de acesso decide quem entra em cada unidade, e uma régua de cobrança recorrente cobra, tenta de novo, bloqueia e libera sozinha.
Cobrança recorrente com régua
Mensalidade gerada no vencimento, até 3 tentativas em 0, 3 e 7 dias e bloqueio automático de quem não pagou.
Check-in com regra única
Status, plano, congelamento, débitos, unidade e limite semanal conferidos em uma chamada, do app do aluno ou da recepção.
Portal do professor e área do aluno
Professores com agenda, turmas e presença; alunos com treinos, reservas de aula e evolução das medidas.
Painel de gestão e BI
Receita recorrente, churn, ticket médio, ocupação por horário, financeiro, PDV e estoque das duas unidades.
Como funciona
Siga o trabalho atravessando o sistema, etapa por etapa, ou clique em qualquer componente do quadro para ver o que ele faz.
arraste para ver o fluxo
Legenda
- Síncrono
- Assíncrono
- Canal seguro
- Integração externa
Descrição textual do fluxo
- De Recepção e gestão para API GymOS — Matrícula e gestão (síncrono).
- De Área do aluno para API GymOS — Check-in e reservas (síncrono).
- De Portal do professor para API GymOS — Agenda e presença (síncrono).
- De API GymOS para Controle de acesso — Valida entrada (síncrono).
- De API GymOS para Cobrança recorrente — Ativa o plano (síncrono).
- De API GymOS para Aulas e treinos — Reserva e treino (síncrono).
- De Controle de acesso para Base da academia — Registra check-in (síncrono).
- De Cobrança recorrente para Base da academia — Atualiza assinatura (síncrono).
- De Cobrança recorrente para Filas e tempo real — Enfileira aviso (assíncrono).
- De Cobrança recorrente para Gateway de pagamento — Cobra mensalidade (integração externa).
- De Aulas e treinos para Base da academia — Presença e treinos (síncrono).
- De Filas e tempo real para E-mail — Envia com retentativa (assíncrono).
Percorra o fluxo
←→trocam de etapa
5 etapas
Do começo ao fim
Escolha uma etapa ou pressione Reproduzir para acompanhar o fluxo inteiro. Enquanto isso, o quadro destaca por onde o trabalho passa.
Componentes do sistema
Ficha completa do aluno
- O que resolve
- Substituir a ficha de papel por um cadastro que acompanha o aluno do primeiro dia à renovação.
- Como funciona
- A matrícula reúne CPF, contato, contato de emergência, endereço preenchido pelo CEP via ViaCEP, questionário PAR-Q e observações de saúde. Avaliações físicas guardam peso, percentual de gordura e perímetros; anexos guardam foto e contrato. Toda mudança de status fica no histórico, e o aluno recebe um link para ativar a própria conta.
NestJS · Prisma · PostgreSQL · ViaCEP
Planos e assinaturas
- O que resolve
- Traduzir os planos da academia em regras que o sistema aplica sozinho.
- Como funciona
- Cada plano define preço, ciclo mensal, trimestral ou anual, taxa de matrícula, limite de acessos por semana e se vale para uma unidade ou para as duas. A assinatura pode ser congelada, cancelada com motivo ou expirada, gera o contrato do aluno e alimenta o relatório de adesões contra cancelamentos.
NestJS · Prisma · Next.js
Cobrança recorrente e régua de inadimplência
- O que resolve
- Cobrar todo mês sem depender de ninguém lembrar, e agir no mesmo dia em que o pagamento falha.
- Como funciona
- O processo de cobrança encontra as assinaturas que vencem, gera o pagamento uma única vez por vencimento e faz até três tentativas, em 0, 3 e 7 dias. Cada tentativa e cada evento ficam registrados. Esgotadas as tentativas, a assinatura vira inadimplente e o aluno é suspenso; quando o pagamento entra, o próximo vencimento é calculado e o acesso volta na hora.
NestJS · Prisma · PostgreSQL
Gateway de pagamento por adaptador
- O que resolve
- Receber a confirmação de pagamento com segurança e sem nunca processar o mesmo evento duas vezes.
- Como funciona
- O gateway fica atrás de uma interface única, com adaptador para Stripe e um adaptador de testes. Todo webhook tem a assinatura HMAC SHA-256 conferida em comparação de tempo constante, e o identificador do evento é único no banco: se o gateway reenviar, o evento duplicado é descartado sem efeito colateral.
NestJS · Stripe · HMAC
Controle de acesso nas unidades
- O que resolve
- Decidir em segundos, e sempre do mesmo jeito, se o aluno pode entrar naquela unidade.
- Como funciona
- Uma única validação confere status do aluno, assinatura ativa, congelamento, pagamentos e faturas vencidas, unidade permitida pelo plano e limite semanal de acessos, e impede check-in duplicado no mesmo dia. A mesma regra atende o app do aluno, a recepção e um endpoint de integração pronto para catraca.
NestJS · Prisma · Next.js
Aulas, treinos e portal do professor
- O que resolve
- Organizar a rotina dos 30 professores e dar ao aluno o treino e a agenda no celular.
- Como funciona
- Aulas têm unidade, professor, dia, horário e capacidade; a reserva respeita as vagas e passa por reservada, check-in, presente, falta ou cancelada. O professor vê a própria agenda e seus alunos e marca presença. Treinos reúnem exercícios com séries, repetições, descanso e vídeo, e o aluno acompanha a evolução das medidas na própria área.
Next.js · NestJS · Prisma
Decisões que sustentam o sistema
Uma base, duas unidades
Em vez de um sistema por unidade, cada registro carrega a academia e a unidade, e o gerente só enxerga a sua. O aluno continua sendo um só, o plano decide onde ele treina e o dono vê as duas casas juntas. Abrir uma terceira unidade vira cadastro, não projeto.
A regra de acesso mora em um lugar só
App do aluno, recepção e catraca chamam a mesma validação. Assim não existe "na recepção passa, no app não": qualquer ajuste de regra vale para todas as portas de entrada ao mesmo tempo.
Inadimplência resolvida pela régua, não por pessoas
Escolhi três tentativas espaçadas em 0, 3 e 7 dias, com suspensão automática no fim e reativação automática no pagamento. A recepção deixa de ter a conversa difícil no balcão e o aluno sabe exatamente o que acontece se atrasar.
Gateway atrás de um adaptador
A cobrança fala com uma interface, não com um fornecedor. Trocar de gateway ou testar o fluxo inteiro sem cobrar ninguém é questão de configuração, e os webhooks assinados e idempotentes protegem o financeiro de reenvios e requisições forjadas.
Resultado para o negócio
A inadimplência deixou de ser descoberta no fechamento: quem não paga é avisado, cobrado de novo em 3 e 7 dias e bloqueado na entrada até regularizar.
O check-in na recepção caiu de cerca de 1 minuto para poucos segundos, e a fila do horário de pico acabou.
O dono acompanha receita recorrente, churn e ocupação das duas unidades em tempo real, sem montar planilha.
Os 30 professores passaram a ver agenda, turmas e alunos no próprio portal, e a troca de horários saiu do grupo de mensagens.
Meu papel
- Papel
- Engenheiro full stack · projeto sob medida de ponta a ponta
- Equipe
- Projeto solo · do discovery à implantação
Fiz o GymOS sozinho, como projeto sob medida para o cliente. Comecei sentando com o dono e com a recepção para entender como a academia funcionava de verdade: planos, exceções, horários de pico, o que travava o dia a dia. A partir daí desenhei a arquitetura, modelei os dados, construí a API, os painéis e a área do aluno, coloquei em produção com Docker, treinei a equipe das duas unidades e sigo dando suporte e evoluindo o sistema com eles.
Pelo que respondi
- Conduzi o discovery com o dono e a recepção e transformei as regras da casa em requisitos.
- Modelei o domínio em PostgreSQL com Prisma: alunos, planos, assinaturas, pagamentos, faturas, check-ins, aulas e treinos.
- Construí a API modular em NestJS com JWT, cinco papéis de acesso e escopo por unidade.
- Implementei a cobrança recorrente, a régua de inadimplência e os webhooks assinados do gateway.
- Desenvolvi os painéis em Next.js para gestão, professores e alunos, com indicadores em Recharts.
- Implantei com Docker, treinei a equipe das duas unidades e mantenho o suporte.
Stack por camada
Interface
- Next.js
- React
- TypeScript
- Tailwind CSS
- Recharts
Backend
- NestJS
- Node.js
- Prisma
- Zod
- JWT
Dados e filas
- PostgreSQL
- Redis
- BullMQ
- Socket.IO
Infra e qualidade
- Docker
- Docker Compose
- Jest
- Playwright
- Swagger
O que levo deste projeto
Em projeto sob medida, o discovery é metade do produto. As regras que mais importavam, como plano que vale para as duas unidades ou limite de acessos por semana, só apareceram conversando com a recepção no horário de pico.
Implantar é também treinar. A adoção nas duas unidades veio quando cada perfil passou a ter uma tela pensada para o seu dia, e não um painel com tudo para todos.
Dinheiro pede idempotência desde o primeiro dia. Tratar webhook repetido e cobrança duplicada como regra, e não como exceção, evitou qualquer lançamento em dobro no financeiro.