Site Institucional — Documentação de Manutenção¶
Uso interno
Este documento contém referências à estrutura interna de sistemas. Não compartilhar externamente.
Versão: 1.0 · Atualizado: Março 2026
Visão Geral¶
O site institucional da Veggi (institucional.grupoveggi.com.br) é composto por um frontend React hospedado no Cloudflare Pages e um backend via Cloudflare Worker (rd-leads). Os formulários de captação do site enviam dados de leads para o RD Station Marketing via API, que por sua vez dispara automações para criação de negociações no RD CRM.
Componentes¶
| Componente | Tecnologia | Onde fica |
|---|---|---|
| Frontend | React + TypeScript (Vite), gerado no Lovable | Cloudflare Pages |
| Backend | Cloudflare Worker rd-leads |
Cloudflare Workers |
| Captcha | Cloudflare Turnstile | Embutido no frontend |
| CRM / Marketing | RD Station (via API OAuth) | Serviço externo |
Repositório¶
| Campo | Valor |
|---|---|
| GitHub | veggidocs/veggi-stylecatalogue |
| Branch principal | main |
| Editor de código | VS Code via GitHub Desktop |
Infraestrutura Cloudflare¶
Cloudflare Pages — Frontend¶
- Projeto:
veggi-style-catalogue - Domínio customizado:
institucional.grupoveggi.com.br - Build command:
npm run build - Output directory:
dist - Deploy automático: Sim — qualquer push na branch
maindispara novo deploy
Variáveis de ambiente configuradas no Pages:
| Variável | Tipo | Descrição |
|---|---|---|
VITE_TURNSTILE_SITE_KEY |
Texto | Chave pública do Turnstile (exibida no frontend) |
Warning
Para editar: Cloudflare → Pages → veggi-style-catalogue → Configurações → Variáveis de ambiente. É necessário reimplantar após salvar para que a variável entre em vigor.
Cloudflare Worker — rd-leads (Backend)¶
- Nome:
rd-leads - URL pública:
api.grupoveggi.com.br - Arquivo principal:
worker.js(código único, sem dependências externas)
Variáveis de ambiente (Secrets) configuradas no Worker:
| Variável | Tipo | Descrição |
|---|---|---|
ALLOWED_ORIGIN |
Secreto | Domínio autorizado a chamar o Worker |
TURNSTILE_SECRET |
Secreto | Chave secreta do Turnstile para validação server-side |
RD_CLIENT_ID |
Secreto | Client ID do app OAuth no RD Station |
RD_CLIENT_SECRET |
Secreto | Client Secret do app OAuth no RD Station |
RD_REFRESH_TOKEN |
Secreto | Refresh Token OAuth do RD Station |
Warning
Para editar secrets: Cloudflare → Workers → rd-leads → Configurações → Variáveis e segredos → clicar no ícone de lápis ao lado de cada secret.
Fluxo Completo: Envio de Formulário¶
Usuário preenche formulário no site institucional
│
▼
Frontend exibe widget do Turnstile (captcha)
│
▼
Frontend envia POST para api.grupoveggi.com.br/{rota}
│
▼
Worker rd-leads recebe a requisição
│
├── Verifica CORS (bloqueia se origin ≠ ALLOWED_ORIGIN → 403)
│
├── Valida presença do token Turnstile (ausente → 400)
│
├── Verifica token Turnstile com API da Cloudflare (inválido → 403)
│
├── Obtém token OAuth do RD Station (usa cache em memória ~1h)
│
├── Envia evento de conversão para a API do RD Station
│
└── Retorna { ok: true } para o frontend
│
▼
RD Station Marketing recebe a conversão
│
▼
Automação dispara → cria negociação no RD CRM
Rotas do Worker¶
O Worker aceita apenas requisições POST em duas rotas. Qualquer outra rota ou método retorna erro.
| Rota | Conversion Identifier | Formulário |
|---|---|---|
POST /convert/querorevender |
institucional_quero_revender |
Página "Quero Revender" |
POST /convert/ja-soucliente |
institucional_ja_sou_cliente |
Página "Já sou Cliente" |
Respostas de erro do Worker:
| Status | Mensagem | Causa |
|---|---|---|
| 204 | (sem corpo) | Preflight CORS (OPTIONS) — comportamento normal |
| 400 | JSON inválido |
Body da requisição não é JSON válido |
| 400 | captcha obrigatório |
Campo turnstileToken ausente no body |
| 400 | email obrigatório |
Campo email ausente ou vazio |
| 403 | Forbidden origin |
Origin da requisição ≠ ALLOWED_ORIGIN |
| 403 | captcha inválido |
Token Turnstile rejeitado pela API da Cloudflare |
| 404 | Invalid route |
Rota não mapeada no Worker |
| 405 | Method Not Allowed |
Método diferente de POST ou OPTIONS |
| 502 | Erro no RD |
Falha na chamada à API do RD Station |
Campos Enviados ao RD Station¶
Todos os campos são enviados com event_type: CONVERSION e event_family: CDP.
| Campo | Obrigatório | Descrição |
|---|---|---|
email |
✅ Sim | E-mail do lead |
name |
Não | Nome completo |
mobile_phone |
Não | Telefone |
city |
Não | Cidade |
cf_segmento_da_loja |
Não | Campo customizado: segmento da loja |
cf_tipo_de_revenda_0 |
Não | Campo customizado: tipo de revenda |
cf_instagram_da_loja |
Não | Campo customizado: Instagram da loja |
cf_possui_cnpj |
Não | Campo customizado: possui CNPJ? |
cf_cnpj |
Não | Campo customizado: número do CNPJ |
traffic_source |
Não | Origem do tráfego |
utm_source |
Não | UTM Source |
utm_medium |
Não | UTM Medium |
utm_campaign |
Não | UTM Campaign |
utm_content |
Não | UTM Content |
utm_term |
Não | UTM Term |
created_at |
Não | Data/hora da conversão |
Automações RD Station¶
Após o Worker registrar a conversão, o RD Station Marketing dispara automações que criam negociações no RD CRM:
| Conversion Identifier | Automação no RD Marketing | Resultado no CRM |
|---|---|---|
institucional_quero_revender |
[CRM] Site Institucional - Quero Revender |
Cria negociação no RD CRM |
institucional_ja_sou_cliente |
[CRM] Site Institucional - Já sou Cliente |
Cria negociação no RD CRM |
Warning
Se conversões chegam no RD Marketing mas as negociações não aparecem no CRM, verificar se as duas automações estão ativas no painel do RD Station Marketing.
Segurança¶
CORS¶
O Worker bloqueia qualquer requisição cujo header Origin seja diferente do domínio configurado em ALLOWED_ORIGIN. Isso impede que outros sites chamem a API diretamente.
Warning
Atenção ao trocar de domínio: se o site mudar de URL (ex: migração, homologação em domínio temporário), o secret ALLOWED_ORIGIN precisa ser atualizado no Worker. Caso contrário, todos os formulários retornam 403 Forbidden origin e as conversões param de ser registradas.
Captcha (Turnstile)¶
Toda submissão é validada em duas etapas:
- Frontend — exibe o widget do Turnstile ao usuário e gera o token
- Worker (server-side) — verifica o token com a API da Cloudflare antes de processar qualquer dado
Se o token for inválido, ausente ou já utilizado, o Worker retorna 403 e a conversão não é registrada.
Autenticação com RD Station (OAuth)¶
O Worker usa OAuth 2.0 com grant_type: refresh_token. O token de acesso é cacheado em memória com validade de ~1 hora (com margem de 60 segundos para renovação antecipada). Isso evita chamar a API de autenticação do RD a cada requisição.
Warning
O cache é por instância do Worker. Em caso de reinicialização (cold start), um novo token é buscado automaticamente na primeira requisição.
Mapa de Credenciais¶
| Credencial | Onde fica | Onde é usada |
|---|---|---|
VITE_TURNSTILE_SITE_KEY |
Cloudflare Pages → Variáveis de ambiente | Frontend (widget Turnstile) |
TURNSTILE_SECRET |
Cloudflare Worker rd-leads → Secrets |
Worker (verificação server-side) |
ALLOWED_ORIGIN |
Cloudflare Worker rd-leads → Secrets |
Worker (validação de CORS) |
RD_CLIENT_ID |
Cloudflare Worker rd-leads → Secrets |
Worker (OAuth RD Station) |
RD_CLIENT_SECRET |
Cloudflare Worker rd-leads → Secrets |
Worker (OAuth RD Station) |
RD_REFRESH_TOKEN |
Cloudflare Worker rd-leads → Secrets |
Worker (OAuth RD Station) |
Info
Nenhuma credencial está exposta no código-fonte do repositório GitHub.
Guia de Diagnóstico¶
Formulário não envia (sem erro visível no site)¶
| Sintoma | Causa provável | Ação |
|---|---|---|
| Botão não responde / sem feedback | Erro silencioso no frontend | Abrir DevTools (F12) → Console → tentar enviar → verificar erros em vermelho |
Console mostra TurnstileError |
VITE_TURNSTILE_SITE_KEY não configurada ou incorreta |
Verificar variável no Cloudflare Pages → reimplantar |
| Nenhuma requisição aparece no Network | Frontend não está chamando a API | Verificar URL da API no código do frontend |
Worker retorna erro¶
| Código | Causa provável | Ação |
|---|---|---|
403 Forbidden origin |
ALLOWED_ORIGIN desatualizado |
Atualizar o secret no Worker → aguardar ~1 min |
403 captcha inválido |
TURNSTILE_SECRET errado ou token expirado |
Verificar secret no Worker e chave no painel Turnstile |
502 Erro no RD |
Token OAuth inválido ou Refresh Token expirado | Verificar secrets RD_CLIENT_ID, RD_CLIENT_SECRET, RD_REFRESH_TOKEN no Worker |
Conversão chega no RD Marketing mas não gera negociação no CRM¶
| Sintoma | Causa provável | Ação |
|---|---|---|
| Lead aparece no RD Marketing sem negociação no CRM | Automação desativada | Verificar se [CRM] Site Institucional - Quero Revender e [CRM] Site Institucional - Já sou Cliente estão ativas no RD Marketing |
| Automação ativa mas negociação não cria | Configuração incorreta da automação | Revisar as etapas de ação dentro de cada automação no RD Station |
Deploy não atualizou o site¶
| Sintoma | Causa provável | Ação |
|---|---|---|
| Alteração não aparece no site | Push não foi para a branch main |
Verificar branch no GitHub |
| Deploy falhou no Cloudflare | Erro de build | Cloudflare → Pages → veggi-style-catalogue → Implantações → ver log do build |
| Erro de lockfile no build | Conflito entre bun.lockb e package-lock.json |
Remover bun.lockb do repositório e fazer novo push |
Como fazer deploy de atualização¶
O deploy é 100% automático. Qualquer push no branch main do repositório veggidocs/veggi-stylecatalogue no GitHub dispara um novo build no Cloudflare Pages.
Passos para atualizar:
- Editar o arquivo desejado no repositório
- Fazer commit e push no branch
main - Aguardar 1–2 minutos
- Verificar o resultado em Workers & Pages →
veggi-style-catalogue→ aba Implantações
Para atualizações maiores (recomendado):
- Criar um branch separado (ex:
fix/constante-url) - Fazer as alterações e abrir um Pull Request
- O Cloudflare Pages cria automaticamente um preview URL para testar
- Após validar, fazer merge no
main
Melhorias Sugeridas¶
- Implementar log de erros do Worker em tabela PostgreSQL ou KV, para rastreabilidade das falhas de conversão
- Considerar múltiplos valores em
ALLOWED_ORIGINpara suportar ambientes de homologação sem alterar o ambiente de produção - Mover o
RD_REFRESH_TOKENpara rotação automática — tokens OAuth do RD Station podem expirar por inatividade prolongada - Adicionar proteção de branch
mainno GitHub para evitar push direto sem revisão
Histórico de Mudanças¶
| Data | O que foi feito |
|---|---|
| Mar/2026 | Migração do frontend do Netlify para Cloudflare Pages |
| Mar/2026 | Correção do ALLOWED_ORIGIN para o novo domínio Cloudflare |
| Mar/2026 | Configuração da variável VITE_TURNSTILE_SITE_KEY no Cloudflare Pages |
| Mar/2026 | Remoção do bun.lockb para corrigir erro de build no Pages |
Links Úteis¶
| Recurso | Link |
|---|---|
| Cloudflare Dashboard | https://dash.cloudflare.com |
| Worker rd-leads | Cloudflare → Workers & Pages → rd-leads |
| Pages veggi-style-catalogue | Cloudflare → Workers & Pages → veggi-style-catalogue |
| Turnstile (gerenciar chaves) | Cloudflare → Turnstile |
| RD Station Marketing | https://app.rdstation.com.br |
| RD Station API Docs | https://developers.rdstation.com |
| Repositório GitHub | https://github.com/veggidocs/veggi-stylecatalogue |