← Voltar aos projetos
Produto & SaaS

Termins.Online

Um SaaS multi-tenant de agendamento para salões e negócios de serviço na Suíça, em cinco idiomas, com página pública de reserva por subdomínio, sinal via TWINT e recursos liberados por plano. Inclui uma auditoria de segurança que fechou quatro falhas críticas de isolamento entre clientes.

Termins.Online
Tipo
Produto & SaaS
Stack
SaaSReactSupabaseSecurity

Resultado em uma frase

Um SaaS de agendamento para salões suíços saiu de um protótipo para uma plataforma multi-tenant em cinco idiomas, e uma auditoria de segurança fechou as falhas que permitiam a qualquer pessoa na internet virar administrador da plataforma.

  • Cliente: Termins.Online, SaaS de agendamento para salões e negócios de serviço na Suíça
    • Meu papel: produto, frontend, backend no Supabase, migração de plataforma, auditoria e correções de segurança
      • Prazo: de março a julho de 2026
        • Resultado principal: 4 falhas críticas e 4 altas de isolamento entre clientes corrigidas antes do lançamento

        O contexto

        Na Suíça, salão de beleza, barbearia e estúdio vivem de agenda cheia e de cliente que aparece. O mercado pede um produto local: preços em francos, sinal pago por TWINT, fuso de Zurique e atendimento em alemão, francês e italiano. Cada negócio precisava da própria página de reserva, sem depender de marketplace.

        O problema

        O produto nasceu rápido, como protótipo, para validar o mercado. Isso entregou telas e fluxos em semanas, mas a base precisava sair de uma plataforma fechada para um backend próprio e, principalmente, aguentar dados de vários negócios no mesmo banco sem que um enxergasse o outro. Protótipo funciona na demo; isolamento entre clientes é o que decide se ele pode ir para produção.

        A abordagem

        • Migrar para um backend próprio: levei o schema e a autenticação para o Supabase, com Postgres, RLS e funções de borda em Deno, para ter controle real sobre dados, regras e custos.
          • Dois caminhos de tenant, bem separados: no app autenticado, o negócio vem do perfil do usuário; na reserva pública, vem do subdomínio do salão. Cada caminho tem suas regras.
            • Auditar antes de lançar: antes de abrir para clientes, fiz uma auditoria completa seguindo o OWASP, rastreando o fluxo de dados do frontend às funções e às políticas do banco, e listando só o que era explorável de verdade.

            A solução

            Página de reserva por salão. Cada negócio tem seu subdomínio, com serviços, profissionais, horários disponíveis e sinal via TWINT. O cliente marca, recebe confirmação e lembrete por e-mail e pode cancelar pelo portal. Página pública de reserva de um salão O painel do negócio. Agenda, disponibilidade, profissionais com convite por e-mail, serviços por categoria, clientes, campanhas de e-mail, relatórios exportáveis em PDF e configurações de lembretes. Os recursos e limites (profissionais, serviços, agendamentos) são liberados pelo plano de cada negócio, com exceções configuráveis por cliente. Agenda e painel do negócio Administração da plataforma. Um painel para o dono do SaaS criar negócios, ajustar planos e dar suporte, com log de ações administrativas.

            Por baixo do capô

            React 18 com Vite, TanStack Query e shadcn/ui no frontend, i18n próprio em alemão, francês, italiano, português e inglês, datas sempre gravadas em UTC e formatadas no fuso de cada negócio. Supabase com Postgres, RLS, dezenas de migrations e 18 edge functions em Deno para reservas públicas, convites, campanhas, lembretes e relatórios, com e-mail via Resend.

            A auditoria encontrou a causa raiz por trás de quase tudo: a autorização confiava no cliente. O cadastro público copiava o papel do usuário a partir dos metadados enviados pelo navegador, então bastava uma requisição para virar administrador da plataforma. A política de atualização do perfil não tinha WITH CHECK, então um usuário podia apontar a própria conta para outro negócio e ganhar acesso total a ele. Funções públicas aceitavam IDs sem checar a quem pertenciam, permitindo cancelar agendamentos e ler dados de clientes de outros salões. As correções foram feitas no banco e nas funções: papel fixo no cadastro com provisionamento privilegiado só pelo servidor, WITH CHECK nas políticas, membros restritos à equipe, verificação de posse em cada função pública e fechamento de um relay de e-mail aberto.

            Resultados

            • 4 falhas críticas e 4 altas corrigidas, incluindo tomada total da plataforma com uma única requisição anônima
              • Isolamento entre negócios garantido pelo banco, não pela interface
                • Plataforma em cinco idiomas, com fuso, moeda e pagamento locais
                  • Reserva pública por subdomínio, sem marketplace intermediando o cliente do salão
                    • Pendências de menor risco documentadas com plano de correção, em vez de esquecidas

                    O que eu levo deste projeto

                    Velocidade na primeira versão não responde a pergunta "quem pode escrever no meu banco?". Essa resposta continua sendo trabalho de engenharia, e precisa vir antes do primeiro cliente, não depois do primeiro incidente.

Tem um desafio parecido?

Me conte o que você precisa construir, seja um produto, uma automação ou um sistema com IA, e eu te mostro o caminho mais curto até a produção.

Outros projetos