Nota para revisão: o texto abaixo descreve fielmente a arquitetura e funcionalidades já documentadas no site. Não há métricas de negócio (pedidos processados, faturamento, tempo de entrega médio) registradas para citar em Resultados — se você tiver esses dados e permissão do cliente para divulgar, encaixo aqui.
Problema
Um comércio de bebidas que quer vender online precisa de muito mais do que um catálogo com carrinho de compras. Entram em jogo regras específicas do setor e do modelo de negócio local: janela de funcionamento (a loja não pode aceitar pedido fora do horário), entrega por zona geográfica com taxa diferente por bairro, cupons de desconto, e sobretudo pagamento — no caso de PIX, o pedido não pode ficar em limbo enquanto o pagamento não é confirmado, e o carrinho precisa ser bloqueado durante a transação para evitar concorrência entre o cliente pagando e o estoque sendo alterado por outro processo.
O desafio técnico central era montar um sistema onde essas regras de negócio ficassem isoladas e testáveis, sem se misturar com a camada de apresentação, e onde a confirmação de pagamento via webhook fosse tratada de forma confiável — sem pedidos "perdidos" entre o pagamento feito pelo cliente e a confirmação recebida pelo sistema.
Solução
Desenvolvi o Barbosa Bebidas como um e-commerce completo estruturado em monorepo, separando claramente a aplicação voltada ao cliente do backoffice administrativo, mas mantendo os dois no mesmo repositório para facilitar versionamento e deploy conjunto.
O app cliente é construído em Next.js 15 com TypeScript e Tailwind, funcionando como PWA/WebView — o que permite uma experiência próxima de app nativo sem a complexidade de publicar em lojas de aplicativo. O backoffice é um painel em Laravel 12 com Filament, que serve tanto a API REST consumida pelo app cliente quanto a interface administrativa usada pela operação da loja (gestão de produtos, pedidos, zonas de entrega, cupons).
Pagamento é processado via PagBank, com suporte a cartão e PIX. Para PIX especificamente, implementei webhook de confirmação de pagamento e bloqueio de carrinho durante a janela da transação — o pedido fica reservado (estoque e disponibilidade) até a confirmação chegar via webhook ou o tempo da transação expirar, evitando que dois clientes concorram pelo mesmo item enquanto um pagamento está em processamento.
Arquitetura
A separação entre app cliente (Next.js) e backoffice (Laravel/Filament) segue o padrão de frontend e backend desacoplados, comunicando por API REST autenticada com Sanctum. Essa divisão permite que o app cliente seja otimizado para performance e SEO (Next.js) enquanto o backoffice foca em produtividade administrativa (Filament gera CRUD administrativo rápido sobre os mesmos modelos usados pela API).
A decisão arquitetural mais relevante do projeto foi isolar toda regra de negócio por domínio em Actions — em vez de lógica de negócio espalhada em controllers ou models, cada operação de negócio (aplicar cupom, calcular taxa de entrega por zona, processar confirmação de pagamento, abrir/fechar a loja automaticamente por horário) vive em uma Action dedicada. Isso facilita testar cada regra isoladamente e evita que o comportamento do sistema fique implícito ou espalhado por múltiplos arquivos.
Todo cálculo financeiro (preço final, desconto de cupom, taxa de entrega) é feito no backend, nunca confiando em valores calculados no cliente — uma prática necessária em qualquer e-commerce para evitar manipulação de preço no frontend.
As zonas de entrega com taxa por bairro e a abertura/fechamento automático da loja por horário são regras operacionais que respondem à realidade do negócio: a loja física tem horário de funcionamento e área de entrega delimitada, e o sistema reflete isso automaticamente em vez de depender de alguém desligando o site manualmente.
O deploy é feito em Docker, com Nginx como proxy, SSL e Cloudflare na frente — uma configuração de infraestrutura direta, sem depender de plataformas gerenciadas específicas para e-commerce.
Decisões de design
O uso de monorepo para separar app cliente e backoffice, mas mantendo os dois versionados juntos, facilita mudanças que afetam os dois lados ao mesmo tempo — por exemplo, uma alteração de contrato de API (novo campo, novo endpoint) pode ser revisada e integrada em um único commit que toca frontend e backend, em vez de coordenar dois repositórios e dois deploys separados.
A escolha de Sanctum para autenticação, em vez de um sistema de token mais pesado como OAuth2/Passport, reflete o formato do consumo da API: o app cliente Next.js é primeiro-parte (não é uma integração de terceiro consumindo a API), então o modelo de autenticação de Sanctum baseado em cookies/token simples para SPAs é suficiente e mais simples de operar.
A automação de abertura e fechamento da loja por horário e o cálculo de taxa de entrega por zona são exemplos do tipo de regra que, se deixada solta em controllers, tende a se espalhar e duplicar conforme o sistema cresce (a mesma verificação de "a loja está aberta?" sendo reimplementada em múltiplos lugares). Isolar essas regras em Actions dedicadas significa que qualquer ponto do sistema que precise verificar o status da loja ou calcular frete chama a mesma Action, com o mesmo comportamento garantido.
Stack
Next.js 15, TypeScript e Tailwind (app cliente, PWA/WebView), Laravel 12 e Filament (backoffice, API REST e painel administrativo), MySQL (persistência), Sanctum (autenticação da API), PagBank (pagamento cartão e PIX com webhook), Docker, Nginx, SSL e Cloudflare (infraestrutura e deploy).
Interface do Sistema

