SaaS de IA multi-tenant · Python e Next.js

Hyre

Plataforma de IA para empresários: a primeira versão, em hyre.global, oferece agentes especializados que atendem e vendem pelo WhatsApp; a segunda versão reorganiza o produto em chat multimodelo com crédito pré-pago, cofre de credenciais e tarefas supervisionadas.

Papel
Fundador e CEO · estratégia, produto e direção técnica do desenvolvimento
Organização e período
Hyre, parte do Lins Capital Group · ago/2025 – atual
Plataformas
Web (site público) · Painel do cliente · Painel administrativo · WhatsApp (v1) · Aplicativo móvel (Expo)
Página pública da Hyre que apresenta a equipe de agentes de IA por área: comercial, financeiro, documentos, suporte, agenda, pós-venda e gestão.
Site da Hyre, página de agentes

01 / Contexto

História e problema

Para quem
Empresários e pequenas e médias empresas que atendem clientes pelo WhatsApp e querem automatizar atendimento, vendas, cobrança e rotinas administrativas sem montar uma equipe de tecnologia.
Problema
Atendimento comercial, cobrança e pós-venda dependiam de pessoas respondendo manualmente, fora do horário e sem histórico unificado. A primeira versão resolveu isso com agentes especializados por função. Em setembro de 2026, a auditoria do código mostrou que cerca de metade do backend existia só para esses agentes e que faltavam peças centrais para um modelo de crédito pré-pago, o que levou à decisão de reorganizar o produto.
Restrições
Equipe enxuta. Credenciais de clientes e de provedores precisam ficar fora do alcance dos modelos. Cobrança em dinheiro real exige consistência contábil em cada lançamento.
  1. mar/2026

    Início do repositório com o nome LinsOS: backend FastAPI, painéis owner e tenant em Next.js e primeiros agentes de WhatsApp (570 commits no mês).

  2. ago/2026

    Mudança de marca de LinsOS para Hyre e publicação do site hyre.global com cadastro, planos e catálogo de agentes.

  3. 20/09/2026

    Auditoria de código e segurança sobre o snapshot da versão 1 e decisão de reorganizar o produto como chat multimodelo com crédito em dólar.

  4. 29/09 a 02/10/2026

    Versão 2: ledger de crédito, cofre de credenciais, tarefas supervisionadas e conectores com aprovação; 473 testes Python, 52 web e 20 mobile aprovados.

  5. 01/10/2026

    Definição da referência de marca HYRE e Hyre Labs para a nova versão.

02 / Papel

Minha responsabilidade

Liderança e direção

  • Defini o posicionamento do produto e a decisão de sair dos agentes de WhatsApp para um chat multimodelo com crédito pré-pago e conexões governadas.
  • Fechei as regras de negócio da versão 2: crédito somente em dólar via Stripe, planos Free, Pro e Max, provedores pagos suportados e margem fixa calculada em centavos inteiros.
  • Estabeleci os critérios de liberação: cada recurso vai a produção com migrations ensaiadas, build, testes integrados e autorização explícita.
  • Priorizei o cronograma em 15 etapas e 70 tarefas e a ordem de execução dos blocos de segurança, cobrança e conexões.

Execução técnica direta

  • Dirigi a arquitetura do backend em FastAPI com SQLAlchemy assíncrono, PostgreSQL e Redis, e dos painéis owner e tenant em Next.js.
  • Validei a integração com o WhatsApp via Evolution API na versão 1, com uma instância por agente e por cliente.
  • Revisei e aprovei as políticas de isolamento por tenant (RLS no PostgreSQL), cifragem de credenciais e idempotência de webhooks.
  • Fiz commits próprios de ajustes de marca e build na mudança de LinsOS para Hyre (27 commits com meu nome no histórico da versão 1).

Trabalho da equipe

  • Equipe de desenvolvimento sob minha coordenação, com nomes preservados.
  • Parceiro de tecnologia responsável por grande parte da implementação da versão 1, seguindo a direção de produto e arquitetura que eu defini.

03 / Arquitetura

Arquitetura documentada

A Hyre é um monorepo com API Python, aplicação web Next.js e aplicativo Expo, implantado com Docker Compose. A versão 1 recebe mensagens do WhatsApp pela Evolution API e as processa no motor de agentes. A versão 2 mantém a mesma base técnica e substitui o motor de agentes por um chat com roteamento entre modelos, ledger de crédito, cofre de credenciais e um executor de tarefas separado da API.

Arquitetura da Hyre (base comum das versões 1 e 2)
  1. Clientes
    • Site e painel Next.js
    • App Expo (esqueleto)
    • WhatsApp (v1)
  2. Entrada
    • Nginx
    • Evolution API (v1)
    • Webhooks Stripe
  3. API
    • FastAPI assíncrono
    • Chat com streaming (v2)
    • Motor de agentes (v1)
  4. Processamento
    • Rotinas em background
    • Executor de tarefas (v2)
  5. Dados
    • PostgreSQL 16 com RLS
    • Redis 7
    • Cofre cifrado (v2)
  6. Provedores de IA
    • OpenAI · Anthropic
    • Google · xAI · Groq

Camadas e tecnologias

Frontend
Next.js 16 com React 19, TypeScript, TanStack Query, Axios e next-intl, com painéis separados para o operador da plataforma (owner) e para o cliente (tenant). Na versão 2, a renovação de sessão compara sessão, usuário, empresa e versão de autenticação antes de reaproveitar uma resposta, e o chat consome eventos SSE (meta, delta, escalate, usage, done). Aplicativo Expo com token em SecureStore e bibliotecas de sessão compartilhadas com a web.
API
FastAPI com SQLAlchemy 2 assíncrono e asyncpg, migrations Alembic, autenticação JWT com PyJWT (identificador por token e revogação no Redis), hash bcrypt na autenticação, limitação de taxa com slowapi, middleware de auditoria e Sentry. Na versão 1, o motor de agentes aplica limites do plano, horário de atendimento, temas bloqueados, detecção de irritação com transferência para humano e uma hierarquia de prioridade entre agentes para o mesmo contato.
Isolamento por cliente
Row Level Security no PostgreSQL com o cliente (tenant) fixado no contexto de cada transação, para não vazar contexto entre requisições que reutilizam a conexão do pool. Na versão 1 a proteção era incremental (a sessão nascia com bypass ligado e só os endpoints de tenant o desligavam). Na versão 2 o bypass nasce desligado em toda transação, as tabelas novas usam FORCE ROW LEVEL SECURITY e a travessia entre tenants exige chamada explícita após autorizar o operador.
Credenciais
Versão 1: chaves de provedores, WhatsApp e pagamentos cifradas em repouso com Fernet na fronteira do ORM, com chave mestra separada do banco. Versão 2: cofre com AES-GCM, chaves versionadas por identificador e dados associados que amarram cada segredo a tenant, usuário, registro e versão; sem fallback para texto puro. Um filtro de redação remove credenciais conhecidas e padrões comuns de chaves de entradas, saídas de modelo e logs.
Processamento assíncrono
Na versão 1, as rotinas periódicas (atualização de CRM, follow-up, alertas e mensagens agendadas) rodam como tarefas assíncronas dentro do processo da API, e a memória do contato é atualizada em background. Na versão 2, tarefas longas vão para uma fila no PostgreSQL consumida por um executor separado com SELECT FOR UPDATE SKIP LOCKED, uma tarefa por vez por usuário, cotas por hora e por dia e sem nova tentativa automática após o despacho.
Modelos de IA
Versão 1: modelo configurável por agente e por tarefa, com cadeia de fallback e provedores OpenAI, Anthropic, Google e Groq, transcrição de áudio e repetição com backoff exponencial para 429 e 5xx. Versão 2: cliente de streaming próprio, sem SDK, com três dialetos (compatível com OpenAI, Anthropic e Google) cobrindo OpenAI, xAI, Anthropic, Gemini e modelos próprios hospedados em endpoint compatível; roteamento híbrido decide o modelo antes da resposta quando a confiança é alta e reavalia depois quando é média.
Cobrança
Stripe com verificação de assinatura dos webhooks e idempotência por INSERT com chave única. Na versão 2, crédito pré-pago em centavos inteiros, ledger append-only protegido por trigger, conferência do saldo a cada lançamento, reserva do pior caso antes de chamar o provedor e liquidação pelo preço cotado na reserva.
Infraestrutura e qualidade
Docker Compose com PostgreSQL 16, Redis 7 com persistência, API e web publicadas apenas no loopback atrás do Nginx; Evolution API em compose próprio na versão 1. CI em GitHub Actions com testes offline Python, testes Node de web e mobile, upgrade completo de migrations em banco vazio, testes de RLS e triggers com papel sem superusuário, lint, build e auditoria de dependências.

04 / Decisões

Decisões técnicas e compromissos

Reorganizar o produto e retirar o motor de agentes do núcleo

Problema
A auditoria de setembro de 2026 mostrou que cerca de 21 mil linhas, aproximadamente metade do backend, existiam só para os agentes de WhatsApp, com dependências (Evolution API, MongoDB, assinatura digital, dados financeiros) que ampliavam a superfície de ataque, e que o modelo de crédito pré-pago desejado não tinha tabela, trava de concorrência nem histórico.
Decisão
Definir a versão 2 como chat multimodelo com crédito em dólar e conexões governadas, remover o código exclusivo dos agentes e manter as tabelas de mensagens em modo somente leitura, sem apagá-las.
Motivo
Concentrar o esforço nas peças que sustentam um SaaS cobrado por uso (isolamento, ledger, credenciais) e reduzir dependências sem função no produto novo. As mensagens antigas são histórico de consumo e não podem ser perdidas.
Compromisso
Convivem duas linhas de produto durante a transição, e parte do que foi construído para os agentes deixa de ser usado.
Aprendizado
Medir quanto do código serve à proposta atual antes de acrescentar recursos evita endurecer a segurança de módulos que serão descartados.

RLS no PostgreSQL, primeiro incremental e depois por padrão

Problema
A versão 1 dependia de centenas de filtros manuais por tenant nas consultas; um filtro esquecido poderia expor dados de outro cliente.
Decisão
Adotar Row Level Security com o tenant fixado por transação. Na versão 1, a adoção foi incremental, com bypass ligado por padrão para não quebrar painel owner, webhooks e rotinas de fundo. Na versão 2, o contexto é restaurado em toda transação com bypass desligado, e a travessia entre tenants exige chamada explícita.
Motivo
Com RLS, uma consulta sem filtro devolve zero linhas em vez de vazar dados. A versão incremental permitiu ligar a proteção em produção sem interromper o serviço; a versão por padrão fecha as lacunas que a própria implementação anterior reconhecia.
Compromisso
Rotinas do operador passam a precisar de autorização explícita e justificável para atravessar tenants, e os testes de RLS precisam rodar em PostgreSQL real com papel sem superusuário para serem conclusivos.

Credenciais fora do alcance dos modelos

Problema
Na primeira versão, chaves de provedores, de WhatsApp e de pagamento chegaram a ficar em texto puro em colunas JSON; com tarefas executadas por modelos e conexões a serviços de terceiros, um segredo exposto no contexto do modelo poderia ser repetido em uma resposta.
Decisão
Cifrar credenciais em repouso (Fernet na v1, cofre AES-GCM com chaves versionadas e dados associados ao tenant e ao usuário na v2), entregar a chave apenas ao transporte privado que faz a chamada HTTP e redigir segredos conhecidos e padrões de chave em entradas, saídas e logs. Respostas com credencial ficam retidas em buffer antes de chegar ao usuário.
Motivo
Separar o segredo do banco muda o impacto de um vazamento de dump, e vincular o texto cifrado ao dono impede que um registro copiado para outro tenant seja decifrado. Manter a chave fora do prompt elimina a classe de vazamento pelo próprio modelo.
Compromisso
O cofre fica indisponível se a configuração de chaves faltar, por decisão de falhar fechado; o buffer de proteção atrasa a exibição da resposta, e o filtro de padrões é defesa adicional, não detector universal.

Crédito com reserva do pior caso e ledger append-only

Problema
Cobrar por token em um chat com streaming exige debitar um valor que só é conhecido ao final da resposta, sob concorrência, sem deixar saldo negativo nem cobrar duas vezes um webhook reenviado.
Decisão
Valores em centavos inteiros, margem arredondada para cima, reserva do custo máximo antes de chamar o provedor, liquidação pelo preço cotado e gravado na reserva, ledger append-only protegido por trigger, conferência do saldo a cada lançamento e trava por carteira com SELECT FOR UPDATE. Custo acima da reserva bloqueia a carteira até conciliação, em vez de ajustar o saldo automaticamente.
Motivo
A soma do ledger precisa sempre bater com o saldo, e erros de arredondamento com valores em ponto flutuante viram dinheiro perdido ou cobrado a mais. Quando o provedor não informa uso, cobrar pelo pior caso é mais seguro do que estimar.
Compromisso
A reserva do pior caso pode recusar mensagens de clientes com saldo baixo, e divergências exigem conciliação manual.

Executor de tarefas sem repetição automática após o despacho

Problema
Tarefas executadas por agentes podem ter efeito externo; se o processo cair depois de enviar a tarefa ao gateway, não há como provar se a ação aconteceu, e uma repetição automática poderia executá-la duas vezes.
Decisão
Fila de tarefas no PostgreSQL consumida por executor separado, ativado por configuração, uma tarefa em andamento por usuário, aprovação vinculada à versão de autenticação e conferida no worker, cotas por usuário e por tenant e nenhuma repetição automática: tarefas interrompidas viram estado incerto para reconciliação. Na v1, a repetição com backoff vale apenas para chamadas de LLM, que não têm efeito colateral além do custo.
Motivo
Diferenciar operações repetíveis (geração de texto) de operações com efeito externo evita duplicidades e mantém a decisão de reexecutar com uma pessoa.
Compromisso
Falhas transitórias exigem ação manual e reduzem a taxa de conclusão automática.

05 / Funcionamento

Fluxo e modelo

Mensagem paga no chat da versão 2 (dados sintéticos)

  1. Usuária do tenant Exemplo Ltda., plano Pro, envia uma pergunta na conversa.
  2. A API confere plano e limite diário e grava a mensagem com o tenant fixado na transação.
  3. O roteador escolhe o modelo; com confiança alta, decide antes de gerar a resposta.
  4. O serviço de crédito reserva o custo máximo da resposta na carteira, com trava.
  5. O provedor responde em streaming; a saída passa pelo filtro de credenciais antes de ser exibida.
  6. O uso real é liquidado pelo preço cotado na reserva e lançado no ledger; o evento usage informa o novo saldo.
  7. Se o modelo básico respondeu e o plano permite, o roteador reavalia e pode emitir uma segunda resposta de um modelo maior na mesma stream.

Modelo lógico simplificado

tenant
id, nome, plano, ativo, suspenso
Carteira de crédito
cliente, saldo em centavos
Lançamento de crédito
cliente, valor em centavos, saldo após o lançamento, origem, referência (somente inserção)
Reserva de crédito
cliente, teto em centavos, provedor, modelo, preços cotados, situação
Conversa e mensagem
cliente, usuário, papel, modelo, tokens de entrada e saída
Execução de tarefa
cliente, usuário, situação, versão, prazo de aprovação, erro
Segredo do cofre
cliente, usuário, versão, envelope cifrado

06 / Evidências

Resultados e próximos passos

Resultados e evidências

  • Versão 1 em hyre.global desde agosto de 2026, com site, cadastro, planos e painel do cliente; dez agentes especializados no código.
  • Versão 2 com chat multimodelo, ledger de crédito, cofre de credenciais e executor de tarefas; 473 testes Python, 52 testes web e 20 testes mobile aprovados em 02/10/2026.
  • Auditoria de segurança registrada sobre a versão 1, com pontos a preservar (RLS, JWT com revogação, credenciais cifradas) e correções priorizadas para a versão 2.

Próximos passos

  • O catálogo de conectores é amplo; próximo passo: ampliar os adaptadores dedicados, priorizados pelo uso dos clientes.
  • Na versão 1, o processamento de fundo roda dentro do processo da API, com um único worker. Próximo passo: mover essas rotinas para um worker dedicado.
  • A reserva do pior caso privilegia a segurança do saldo sobre a experiência de quem tem pouco crédito. Próximo passo: estimativas de uso por modelo para reservas mais justas.

07 / Telas

Galeria

Próximo estudo de caso

Lins Payments
Todos os projetos