Pular para o conteúdo
Em produção · desde ago/2026

Um motor de comissão
que ninguém precisa conferir.

Escritórios de investimento calculam o repasse dos assessores em planilha. Um erro de fórmula significa alguém recebendo menos do que deveria, e ninguém descobre até a reclamação chegar. O splitOS troca a planilha por um motor de cálculo isolado e coberto por testes.

Meu papel
Produto, arquitetura e desenvolvimento
Período
Desde 2026 — em produção
Modelo
SaaS B2B multiempresa
Stack
Supabase · Cloudflare · JS sem bundler
O problema

A planilha funciona até o dia em que não funciona

O cálculo do repasse de um assessor não é uma multiplicação. Ele envolve percentual diferente para carteira própria e carteira tombada, retenção de imposto, custo de mesa que pode incidir sobre a margem ou sobre a receita líquida, mínimo garantido que às vezes soma e às vezes substitui a parte variável, e bônus de liderança sobre a produção do time.

Cada uma dessas regras vira uma coluna nova na planilha. Depois de alguns meses, ninguém no escritório sabe mais explicar por que a célula AC47 tem aquela fórmula — e ninguém consegue auditar um número que não sabe reproduzir.

Cálculo sem auditoria

Não há histórico de qual regra valia quando o pagamento foi feito.

Repasse divergente

O valor calculado e o valor pago não conversam, e a conciliação é manual.

Assessor no escuro

O profissional só descobre quanto vai receber quando o dinheiro cai.

Horas de retrabalho

Todo fechamento de mês recomeça o mesmo processo à mão.

Arquitetura

Estático na borda, autoridade no banco

Não existe servidor de aplicação. O front é estático e serve da borda do Cloudflare; a autoridade sobre quem vê o quê vive nas políticas do Postgres. Isso significa que não existe endpoint para esquecer de proteger — a permissão não está em código de rota, está em política de linha no banco.

Arquitetura do splitOS em três camadas O navegador executa a interface e o motor de cálculo. O Cloudflare Pages serve os arquivos estáticos e aplica cabeçalhos de segurança. O Supabase concentra autenticação, banco Postgres com permissão por linha e armazenamento de comprovantes. O Resend envia os e-mails transacionais. NAVEGADOR Interface 22 módulos ES Motor de cálculo puro · 39 asserts Importação planilha XLSX Store único load/save/sub BORDA — CLOUDFLARE PAGES Arquivos estáticos CSP por rota HSTS Preview por branch Deploy por push domínio próprio SUPABASE Auth papéis · reset Postgres RLS por linha Storage URL assinada TRANSACIONAL Resend SMTP · convites Edge Fn captação
O motor de cálculo roda no navegador e não conhece o DOM — a mesma função que gera a tela roda no Node durante os testes. A visão de cada assessor é publicada pelo administrador e filtrada por política de linha: ele não recebe os dados dos colegas e depois esconde na tela, ele nunca recebe.
Registros de decisão

Cinco escolhas e o que cada uma custou

Toda decisão de arquitetura tem consequência. Registrar só o lado bom é propaganda, não engenharia.

01

Motor de cálculo isolado, com teste antes de tudo

Situação
A matemática do repasse estava duplicada em quatro lugares do código. Corrigir uma regra exigia lembrar dos outros três, e uma divergência entre eles produzia dois números diferentes para o mesmo assessor.
Decisão
Extrair toda a matemática para um módulo que não conhece o DOM: recebe dados, devolve resultado. Roda no navegador e no Node sem alteração. Cobri com 39 asserções os casos que mudam o valor final — imposto sobre o mínimo, base do custo de mesa, bônus sobre a parte variável do time, retenção do escritório.
Consequência
Regra nova vira um teste antes de virar tela. Como o número vai para o bolso de alguém, essa foi a primeira coisa a ser testada, não a última.
Custo aceito
Manter o motor sem acesso ao DOM obriga a passar estado explicitamente. É mais verboso do que ler direto do formulário.
JavaScript puronode:testGitHub Actions
02

Permissão por linha, com função para evitar recursão

Situação
Três papéis com visões diferentes: o dono do escritório vê tudo, o sócio co-administrador vê o mesmo, o assessor vê apenas a própria remuneração. Filtrar isso no front seria enviar todos os dados e esconder o que não interessa — ou seja, não seria filtrar.
Decisão
Política por linha no Postgres, com a associação verificada pelo e-mail assinado no token. As políticas que precisavam se consultar entre si viraram funções com privilégio definido na criação, o que quebra a recursão que travava a avaliação.
Consequência
Um bug de interface não vira vazamento de dado. O banco recusa a linha antes de a tela existir.
Custo aceito
Depurar política é mais chato que depurar if. Um erro de política aparece como "sem resultado", não como mensagem de erro.
Postgres RLSJWTSupabase Auth
03

Comprovante por link assinado e temporário

Situação
Comprovantes de pagamento em PDF começaram guardados como texto no navegador. Estouravam a cota de armazenamento local e não existiam em outro dispositivo.
Decisão
Binário no bucket, organizado por escritório e por assessor, com os metadados no banco. O download gera uma URL assinada válida por poucos minutos, e a política do bucket garante que cada um só assina o próprio arquivo.
Consequência
Comprovante acessível de qualquer dispositivo, sem link permanente circulando por e-mail.
Custo aceito
Link expirado gera dúvida de suporte. Precisou de mensagem clara na interface explicando o motivo.
Supabase StorageURL assinadaPolíticas de bucket
04

Um incidente de produção que virou regra escrita

Situação
Em 29 de julho de 2026 o formulário de captação da landing parou de enviar. O sintoma era genérico: Failed to fetch. Nada havia mudado no formulário.
Causa raiz
Dois blocos do arquivo de cabeçalhos casavam com a mesma URL, e os dois definiam política de segurança de conteúdo. Quando o navegador recebe duas políticas, ele aplica a interseção das duas — a mais restritiva. A política global, mais fechada, anulava as origens externas liberadas na política específica.
Decisão
Regra de ouro registrada no próprio arquivo: um caminho nunca recebe política de conteúdo de mais de um bloco. O curinga passou a definir apenas cabeçalhos que não sofrem interseção. Cada rota que precisa de política tem bloco exclusivo.
Consequência
Rota nova exige bloco novo, e isso está escrito no arquivo que a próxima pessoa vai abrir. Também ficou registrado como investigar sem se trancar fora: usar o modo que apenas relata a violação em vez de bloquear.
CSPCloudflare PagesPostmortem
05

De arquivo único para 22 módulos, sem bundler

Situação
O sistema nasceu como um arquivo só. Estilo com cinco camadas de sobrescrita e mais de cem declarações forçadas, oito chaves de armazenamento soltas, e cálculo disparado a cada tecla digitada.
Decisão
Separar em módulos por responsabilidade, consolidar o estado em um store único com carregar, salvar e assinar, eliminar as camadas de sobrescrita do estilo, e reduzir o cálculo a um disparo por pausa de digitação com resultado reaproveitado quando a entrada não mudou.
Consequência
Integração contínua verificando a sintaxe de cada módulo e rodando os testes do motor em cada proposta de alteração. Nenhuma etapa de build: o que está no repositório é o que roda em produção.
Dívida registrada
Ainda restam manipuladores de evento declarados direto no HTML. Enquanto existirem, a política de conteúdo precisa permitir script embutido — que é justamente a parte que barra injeção. Está no board, com a versão forte da política já escrita e comentada, esperando.
ES ModulesSem bundlerCI
Estado atual

Onde o produto está

22
módulos ES em produção
39
asserções sobre o motor de cálculo
3
papéis com visão isolada no banco
0
etapas de build no deploy

O MVP entrou em agosto de 2026 e o produto abriu ao mercado em setembro. O roadmap seguinte trata de integrações com meios de pagamento e da expansão para outros setores de remuneração variável — consórcio, seguros e crédito têm o mesmo problema de comissionamento.

O que não está aqui: esquema de banco, políticas em detalhe, identificadores de projeto e condições comerciais. Produto em operação com dinheiro de cliente dentro não publica o mapa.

Se o seu caso parece com este

O que dá para reaproveitar

Esse conjunto de peças não é específico de comissionamento. É o mesmo esqueleto de qualquer operação onde o número calculado precisa ser defensável.

  • Regra de negócio hoje em planilha, virando motor testado com trilha de auditoria
  • Papéis com visões diferentes, resolvidos no banco e não na tela
  • Documento sensível com acesso temporário e rastreável
  • Entrega contínua sem etapa de build, com preview por branch
  • Migração de dados que já vivem no navegador para a nuvem, sem perder nada
Próximo passo

Tem um cálculo que ninguém consegue auditar?

Trinta minutos costumam bastar para eu dizer se é o meu tipo de problema — e, se não for, indicar quem resolve.

← Ver os outros projetos