HerbLeaf
HerbLeaf — Loja, conteúdo e comunidade para cultivo indoor
Uma loja de insumos e equipamentos para cultivo indoor com tudo ao redor: guias, notícias, glossário e uma comunidade moderada. Quem chega aprende, monta o kit e compra sem sair do site.

- 63
- 50
- 3
Problema.
Quem começa um cultivo indoor compra às cegas: o catálogo é grande, o conteúdo costuma viver longe da loja e a comunidade, em outro lugar. Para a HerbLeaf há ainda um fator que muda a engenharia: plataformas de pagamento e de anúncios leem a vitrine, então o que pode aparecer nela precisa ser controlado de ponta a ponta.
Solução.
Uma plataforma em três camadas no mesmo site. A loja tem catálogo, carrinho, checkout com Mercado Pago, frete pelo Melhor Envio e pedidos. O conteúdo editorial reúne notícias, guias, e-books, vídeos, glossário, agenda de eventos e calculadoras de luz e de VPD. A comunidade tem feed, perfis, diários e mensagens, com moderação. Um admin faz o papel de CMS para tudo isso.
Resultado.
No ar em herbleaf.com.br, com as 63 telas do design, a API própria, o admin, o checkout, as regras de compliance e a esteira de deploy. A comunidade, já construída com moderação, abre por uma chave de liberação.
A parte difícil.
Todo projeto tem um ponto em que a solução óbvia não serve. Aqui foram estes.
Termos que a vitrine não pode exibir, em três camadas
Os robôs de plataformas de pagamento e de anúncios leem a vitrine: home, loja, produto, carrinho, checkout e páginas institucionais. Uma lista de termos não pode aparecer em nenhum campo dela, nem em texto, meta, alt, dados estruturados, slug ou seed. A regra vive em três camadas: um lint no CI varre o código público; o backend recusa com erro 422, apontando o caminho do campo, qualquer escrita do admin nas tabelas da vitrine; e uma migration falha se o banco de produção ainda tiver o termo. O backend recusa em vez de reescrever, porque reescrever calado esconderia do editor que o texto dele mudou. O conteúdo editorial segue outra regra, de conteúdo e não de vocabulário, e por isso fica fora dessa varredura.
Reproduzir 63 telas sem melhorar o design
O export do design é a fonte de verdade e não se altera. Ele não traz telas de celular, então o mobile é derivado do desktop por regras escritas (grades de 4 para 2 para 1 coluna, barra lateral que vira chips, hero que empilha) e aprovado em preview. A única mudança permitida sem perguntar é a que não altera o resultado visual, como trocar um span clicável por um botão com rótulo de acessibilidade. Cores e medidas vêm de tokens, nunca de hex solto no componente, e uma revisão de fidelidade das 63 telas corrigiu as divergências altas e médias. O resto ficou registrado em notas de design.
Em pagamento, quem decide o preço é o servidor
O front nunca fala com o banco. O pedido chega à API, que recalcula preços, frete e cupom e só então cria a preferência no Mercado Pago. O webhook confere a assinatura, consulta a API do Mercado Pago para confirmar o pagamento e é idempotente: a baixa de estoque acontece uma única vez, mesmo se o aviso chegar duplicado. O frete usa o Melhor Envio por OAuth, com renovação automática do token.
Comunidade com moderação desde o primeiro dia
Texto com intenção de venda ou troca não publica, nem no feed, nem em comentário, nem em mensagem privada. A mesma expressão roda no navegador, que avisa na hora, e no servidor, que é quem vale; mudar uma sem a outra faria a tela prometer o que o servidor recusa. A primeira publicação de cada pessoa entra em fila, e o admin tem aprovação, remoção, banimento e denúncias.
Conteúdo automático que entra como rascunho
Notícias e eventos chegam por uma automação que adapta o texto à voz da casa. Cada item é identificado pela URL de origem, para não duplicar, passa pelo mesmo portão de compliance e entra sempre como rascunho, numa fila do admin para publicar, editar ou excluir. A capa da fonte não é copiada por causa de licença: a matéria usa uma capa da editoria, e o botão de usar a imagem da fonte fica a cargo de quem edita.
Docker sozinho não reinicia o que está travado
Em Docker standalone, um container marcado como não saudável fica como está, e só o Swarm o reinicia. Um watchdog agendado no systemd, a cada 5 minutos, confere os containers, reinicia os que travaram, olha memória e disco e testa o endpoint público de fora, que pega problema de túnel mesmo com o container saudável. Todo container tem teto de memória, e um vazamento mata o container em vez de derrubar a máquina. Na esteira, um deploy que não sobe volta sozinho para a imagem anterior.
O que eu fiz.
- Plano de execução em blocos, com cada decisão de produto e de design registrada e numerada
- Front-end em Next.js 16, React 19 e TypeScript estrito, com Tailwind v4 e tokens de design
- API própria em Node e TypeScript, único ponto de acesso a dados, sobre Supabase (Postgres, storage e migrations)
- Checkout com Mercado Pago Checkout Pro, cálculo de frete pelo Melhor Envio, rastreio de pedidos no admin, cupons e baixa de estoque
- Admin com editor de blocos, gestão de pedidos, catálogo, conteúdo e fila de moderação
- Esteira no GitHub Actions até a produção, e rotinas de watchdog e backup na VPS
- Ingestão automática de notícias e eventos por automação, sempre entrando como rascunho
- Agentes de IA no marketing, em um repositório irmão: um grupo para pesquisar fornecedores e parcerias e outro para inteligência de SEO
Stack.
Quer algo parecido?
Este projeto é do tipo desenvolvimento de sistemas sob medida. A partir de R$ 9.900 + R$ 490/mês. Me conta o que você precisa e respondo pessoalmente. Se preferir escrever, use o formulário.