root@construct:~/projects/brasa-cargas$
<-- voltar para /projects

Brasa Cargas

Marketplace de fretes que fecha no WhatsApp

Next.jsReactDrizzlePostgreSQLStripeTwilio

>Contexto

O agenciador de cargas trabalha pelo WhatsApp e depende de um quadro de cargas de terceiros para achar motorista. A Brasa Cargas é um marketplace de fretes do Sudeste que fecha negócio no WhatsApp: empresas, transportadoras e agenciadores publicam cargas, o motorista encontra pelo Google ou por um link compartilhado e fala direto com quem publicou.

O agenciador é o cliente. Publicar é grátis e não pede cartão; os planos pagos deixam publicar mais cargas ao mesmo tempo. O motorista não paga e não instala aplicativo: abre no celular, entra com o Google e pronto. Ele é a liquidez que dá valor à carga publicada.

Fundei a Brasa em abril de 2026 com o nome Central de Cargas Ceasa, e em 29/06/2026 ela virou Brasa Cargas. Construo o produto sozinho, da arquitetura à operação, com agentes Claude Code e Codex e revisão cruzada entre modelos.

>Arquitetura (HLD)

A aplicação roda na Vercel: um app Next.js 16 (App Router, React 19) em Vercel Functions. Um middleware grava a origem da primeira visita e reescreve o subdomínio do agenciador para a página com a marca dele. O agenciador e o motorista abrem páginas renderizadas no servidor; as escritas passam por Server Actions e por route handlers em /api, que também recebem os webhooks de Stripe, Asaas e Twilio e trocam o código do login com o Google.

O estado fica no Railway. O Postgres, acessado pelo Drizzle, guarda o negócio inteiro. O Redis só segura o rate limit. Fotos de carga, documentos do motorista e logos vão para um bucket compatível com S3, com upload direto do navegador por URL pré-assinada.

O que é assíncrono são oito crons da Vercel que chamam rotas /api com um segredo. Expirar cargas roda a cada hora e o ciclo do trial uma vez por dia; a reconciliação do Pix, os avisos e o despacho de um outbox de eventos de domínio no Postgres, a cada dois minutos, ficam atrás de flags. A comissão com split pela subconta do agenciador está construída e desligada. O código fica no GitHub: push de branch vira preview na Vercel, produção só é construída com aprovação, e esse build aplica as migrações do Drizzle antes do next build. Não há GitHub Actions; lint, tipos, testes, build e checagem de migração rodam num hook de pre-push.

Passe o mouse ou foque uma peça: ela acende com as ligações.
quem usaVercelRailwayServiços externoscódigo e entrega1 Agenciador3 App Next.js 165 Route handlers /api2 Motorista7 Redis4 Build + migrações14 GitHub10 Stripe8 PostgreSQL6 Vercel Cron11 Asaas9 Bucket S312 Twilio13 Google OAuth
14 peças15 ligações5 áreas

Componentes

  • App Next.js na Vercel :: Páginas públicas de carga e de cidade, painel do agenciador, área do motorista e admin, renderizados no servidor em Vercel Functions, com um middleware na frente para atribuição e subdomínio com a marca do agenciador.
  • Route handlers /api :: As mesmas Vercel Functions servem as rotas de checkout, upload e login e os webhooks de Stripe, Asaas e Twilio; são elas que assinam as URLs do bucket e chamam os provedores.
  • Vercel Cron :: Oito rotinas que chamam rotas /api/cron com um segredo; expirar cargas e o ciclo do trial rodam direto, e reconciliação do Pix, avisos e o outbox de eventos ficam atrás de flags.
  • Postgres no Railway :: 76 tabelas e 121 migrações pelo Drizzle, com tenant por empresa do agenciador, motorista como identidade global e um outbox de eventos de domínio na mesma base.
  • Redis e bucket no Railway :: Redis só para rate limit; bucket compatível com S3 para fotos, documentos e logos, com URL pré-assinada e upload direto do navegador.
  • Pagamentos :: Assinatura no cartão pelo Stripe (checkout, portal e webhook) e no Pix pelo Asaas (cobrança e webhook); a comissão pela subconta do agenciador está desligada.
  • Login e mensagens :: Google OAuth com PKCE e link mágico para entrar, OTP do agenciador pelo Twilio Verify e WhatsApp pelo Twilio, com webhook de entrada assinado.
  • Deploy e observabilidade :: GitHub para o código, preview por branch e produção com aprovação na Vercel, migrações no build de produção, portão local no pre-push; Sentry para erros, Vercel Analytics e GA4 para uso.

>Trade-offs

Assinatura do agenciador como única receita nos primeiros 90 dias.

Alternativa descartada: Contar comissão, escrow ou taxa por frete como receita desde o início.

Por quê: A assinatura era o único trilho de dinheiro que podia virar receita real no trimestre; comissão e frete dependem de parecer jurídico e de provedor de pagamento (ADR 0018).

Comissão cobrada em Pix pela subconta do próprio agenciador no provedor de pagamento, com split nativo de uma parcela fixa para a plataforma.

Alternativa descartada: A plataforma cobrar a comissão na própria conta e repassar depois, ou cobrar sua taxa numa cobrança separada.

Por quê: Receber e repassar dinheiro de terceiro aproximaria a plataforma de uma instituição de pagamento, e o pagamento do frete ao motorista tem regras próprias (Lei 11.442, CIOT, piso mínimo da ANTT) que ficam fora da plataforma (ADR 0017, 0023 e 0024). O preço: a arquitetura está aprovada, a cobrança em produção não, e o trilho segue desligado.

WhatsApp por canal oficial (BSP da Twilio) e links wa.me.

Alternativa descartada: Bot não oficial no WhatsApp Web, ou integrar direto na Cloud API da Meta.

Por quê: O bot viola os termos e o número pode ser banido, o que contradiz a proposta anti-bloqueio do produto. A Cloud API travou na configuração do console; a Twilio deu número e sandbox na hora.

Lista de motoristas sem CPF, placa ou telefone; o telefone só aparece quando o motorista demonstrou interesse numa carga daquele agenciador.

Alternativa descartada: Usar a empresa como fronteira de acesso aos dados do motorista.

Por quê: Agenciadores self-serve compartilhavam a mesma empresa, o que daria acesso lateral a todos os motoristas. A revelação tem limite de 30 por dia e é auditada no serviço (ADR 0020, LGPD).

Avisar o motorista primeiro por uma caixa de entrada no painel.

Alternativa descartada: Começar por Web Push.

Por quê: O pedido de permissão do navegador é bloqueável e o iOS só entrega push para PWA instalado. Push ficou condicionado a provar que o motorista volta ao painel (ADR 0012).

>Destaques

  • >700+ motoristas cadastrados e 2.700+ cargas publicadas.
  • >Motorista entra sem instalar aplicativo: login com Google em 30 segundos, no celular.
  • >2.458 commits na main entre 14/04 e 20/10/2026.
  • >121 migrações de banco e 76 tabelas no Postgres.
  • >787 arquivos de teste e 75 specs E2E no Playwright.
  • >Calculadora de frete pelo piso da ANTT e páginas por cidade de origem e destino.

>Curiosidades

  • *O login por link mágico separa GET e POST porque WhatsApp, iMessage e Telegram abrem o link para montar a prévia. Se o GET consumisse o token, a prévia gastaria o acesso antes do toque do usuário.
  • *21/07/2026 foi o dia mais cheio do repositório: 195 commits. Julho inteiro somou 1.147.
  • *O primeiro commit é de 14/04/2026, e naquele dia entraram 15 commits na main.
Brasa Cargas | The Broad Way | Kinho.dev