Guia completo para colocar o VITALE no ar em vitale.acacianegocios.com.br usando Cloudflare Pages + Supabase + Claude API.
Sem código de produção a editar — apenas configuração e copy-paste.
⏱ Tempo total estimado: 45-60 minutos · Custo inicial: R$ 0,00
💡 Como usar este guia: Marque cada item conforme conclui. Sua progressão é salva no navegador automaticamente. Use os botões 📋 Copiar nos blocos de código para evitar erros de digitação.
PASSO 01
Criar projeto no Supabase
⏱ ~5 minutos
O Supabase será o banco de dados e sistema de autenticação. Tier gratuito comporta até ~200 usuários ativos.
Acesse supabase.com e clique em Start your project
Faça login com GitHub (recomendado) ou e-mail
Clique em New project
Preencha:
Name: vitale-prod
Database password: gere uma senha forte e salve em local seguro (gerenciador de senhas). Você vai precisar caso queira acessar o banco diretamente.
Region: South America (São Paulo) — menor latência para Brasil
Pricing plan: Free
Clique em Create new project e aguarde ~2 minutos enquanto o Supabase provisiona
⚠️ Senha do banco: Anote agora. O Supabase só mostra essa senha UMA vez. Se perder, precisa fazer reset (mais trabalho).
Depois que o projeto subir, copie estas duas chaves (você vai precisar):
No menu lateral esquerdo: ⚙️ Project Settings → API
Copie e guarde em um arquivo de texto temporário dois valores:
Project URL — algo como https://xxxxx.supabase.co
anon public key — chave longa começando com eyJ... (é segura para usar no frontend)
🚨 NUNCA copie a chave service_role (também mostrada nessa página). Ela tem acesso total e jamais pode ir para o frontend.
✓ Checklist do Passo 1
Projeto Supabase criado e provisionamento concluído
Senha do banco salva em local seguro
SUPABASE_URL copiada
SUPABASE_ANON_KEY copiada
PASSO 02
Rodar o schema SQL
⏱ ~3 minutos
Vamos criar todas as tabelas (perfis, pesos, medicações, etc.), políticas de segurança (RLS) e inserir as feature flags padrão.
No Supabase, menu lateral: SQL Editor (ícone </>)
Clique em + New query
Abra o arquivo supabase/schema.sql do projeto VITALE (em seu computador, descompactado do zip)
Copie TODO o conteúdo do arquivo e cole no SQL Editor do Supabase
Clique em Run (botão verde, canto inferior direito) ou pressione Ctrl+Enter
Aguarde a mensagem Success. No rows returned aparecer
O que esse SQL faz: Cria 7 tabelas (profiles, weights, medicacoes, submetas, feature_flags, error_logs, usage_analytics), define triggers que criam o perfil automaticamente quando alguém se cadastra, configura Row Level Security para que cada usuário só veja seus próprios dados, e insere 12 feature flags na tabela (3 já habilitadas, 9 desabilitadas para você liberar pela Torre).
Depois de rodar, vá em Table Editor (menu lateral) e confira: você deve ver as 7 tabelas listadas. Clique em feature_flags — deve ter 12 linhas.
✓ Checklist do Passo 2
SQL rodado com sucesso (mensagem de Success)
7 tabelas aparecem em Table Editor
Tabela feature_flags tem 12 linhas
PASSO 03
Configurar autenticação
⏱ ~5 minutos
Vamos ativar login por e-mail+senha e por link mágico (passwordless), e ajustar as URLs de redirecionamento para que o domínio final funcione.
3.1 — URLs de redirect
No Supabase, menu lateral: Authentication → URL Configuration
localhost:8788 é necessário se você quiser testar com wrangler pages dev antes de subir. Pode remover depois do deploy.
3.2 — Email templates em português
Authentication → Email Templates
Para Confirm signup, customize o subject e o corpo:
Subject: VITALE — Confirme seu cadastro
No corpo, troque o texto padrão por uma mensagem em português (mantenha a variável {{ .ConfirmationURL }}):
<h2>Bem-vindo ao VITALE</h2>
<p>Clique no link abaixo para confirmar seu cadastro:</p>
<p><a href="{{ .ConfirmationURL }}">Confirmar cadastro</a></p>
<p>Se você não pediu este cadastro, ignore este e-mail.</p>
Faça o mesmo para Magic Link:
Subject: VITALE — Seu link de acesso
Body:
<h2>Acesso ao VITALE</h2>
<p>Clique no link abaixo para entrar (válido por 1 hora):</p>
<p><a href="{{ .ConfirmationURL }}">Entrar no VITALE</a></p>
<p>Se não foi você, ignore este e-mail.</p>
Clique em Save changes ao final
3.3 — Confirme as providers
Authentication → Providers
Confirme que Email está habilitado (geralmente já está por padrão)
Em Email Settings:
Confirm email: ON (recomendado — evita signups com e-mails falsos)
Secure email change: ON
💡 Sobre Google OAuth: Pulamos no MVP para você lançar mais rápido. Adicionar Google depois é simples: vai em Authentication → Providers → Google → Enable e segue a configuração do Google Cloud Console. Mas por enquanto, e-mail+senha + magic link já atende ótimo.
✓ Checklist do Passo 3
Site URL configurada
Redirect URLs adicionadas (5 entradas)
Email template "Confirm signup" em português
Email template "Magic Link" em português
Confirm email = ON
PASSO 04
Criar conta Anthropic e gerar API Key
⏱ ~5 minutos
A API Claude alimenta o OCR de screenshots e o Coach IA. Pagamento por uso — sem mensalidade fixa. Estimativa para beta de 5-10 usuários: R$ 30-80/mês.
Vá em Settings → Billing e adicione um cartão de crédito (Anthropic cobra em USD)
Recomendo adicionar créditos pré-pagos de USD 20 inicialmente (~R$ 100). É melhor que pay-as-you-go porque você não corre risco de receber uma fatura enorme se algo der errado
Vá em Settings → Limits e configure um spend limit mensal (ex: USD 30) como segurança extra
Vá em Settings → API Keys
Clique em + Create Key, dê o nome vitale-prod
Copie a chave (formato sk-ant-api03-...) e guarde em local seguro. Aparece UMA vez só.
⚠️ Segurança crítica: Essa chave dá acesso à sua conta paga. NUNCA a coloque em código JavaScript do frontend. NUNCA a commite no Git. Ela vai como variável de ambiente no Cloudflare (Passo 6).
Quais modelos o VITALE usa:
• OCR de imagens: claude-haiku-4-5-20251001 — barato e excelente para visão computacional
• Coach IA (mensagens motivacionais): claude-sonnet-4-6 — análise mais nuançada
Esses modelos estão hardcoded em functions/api/ocr.js e functions/api/chat.js. Se quiser trocar depois, é só editar essas duas linhas.
✓ Checklist do Passo 4
Conta Anthropic criada
Cartão / créditos pré-pagos adicionados
Spend limit mensal configurado
API key gerada e salva em local seguro
PASSO 05
Subir projeto no GitHub
⏱ ~10 minutos
O Cloudflare Pages faz deploy automático cada vez que você dá git push. Sem GitHub, não há deploy automático.
5.1 — Substituir as chaves do Supabase no código
Antes de subir, você precisa colar a URL e a chave do Supabase em 3 arquivos:
Substitua COLE_SUA_URL_AQUI pela sua URL real e COLE_SUA_ANON_KEY_AQUI pela anon key.
💡 Por que a anon key pode ir no frontend? Ela só permite operações limitadas pelas suas políticas RLS (que você criou no Passo 2). Mesmo se alguém pegar essa chave, ela é inútil sem credenciais de usuário válidas.
Visibility: Private (importante — seu código tem chaves)
Deixe os demais campos vazios (não marque "Add README")
Clique em Create repository
5.3 — Subir os arquivos
Opção A — Pelo navegador (mais simples):
No repositório recém-criado, clique em uploading an existing file
Arraste TODA a pasta vitale/ descompactada (não a pasta zipada — só o conteúdo dela)
Em Commit message, escreva Initial commit — VITALE v4
Clique em Commit changes
Opção B — Pelo terminal (se você tem git instalado):
cd caminho/para/vitale
git init
git add .
git commit -m "Initial commit — VITALE v4"
git branch -M main
git remote add origin https://github.com/SEU_USUARIO/vitale.git
git push -u origin main
⚠️ Antes de fazer commit: Confirme que o repositório está privado. Mesmo a anon key sendo "segura", é boa prática não expor o código de auth publicamente até maturação.
✓ Checklist do Passo 5
SUPABASE_URL e ANON_KEY coladas em index.html
SUPABASE_URL e ANON_KEY coladas em app.html
SUPABASE_URL e ANON_KEY coladas em admin.html
Repositório privado criado no GitHub
Arquivos do projeto subidos no repo
PASSO 06
Configurar Cloudflare Pages
⏱ ~8 minutos
O Cloudflare Pages é o hosting. Ele puxa o repositório do GitHub e serve o site através de uma CDN global super rápida. Free tier: 500 deploys/mês + 100.000 invocações de Pages Functions/dia.
6.1 — Conectar o repositório
Acesse dash.cloudflare.com (mesma conta que tem o domínio acacianegocios.com.br)
Menu lateral: Workers & Pages
Clique em Create → Pages → Connect to Git
Autorize o Cloudflare a acessar seu GitHub (primeira vez)
Selecione o repositório vitale
Clique em Begin setup
6.2 — Configurar o build
Project name: vitale
Production branch: main
Framework preset: None
Build command: deixe VAZIO (não temos build step, é HTML puro)
Build output directory: / (raiz)
Clique em Save and Deploy
Aguarde 1-2 minutos. Você verá no painel: Success! Your project is live com uma URL temporária tipo vitale-xyz.pages.dev.
🎉 O site já está no ar nesse domínio temporário! Mas ainda falta a variável de ambiente do Claude API e o subdomínio personalizado.
6.3 — Adicionar variável de ambiente ANTHROPIC_API_KEY
No projeto recém-criado: Settings → Environment variables
Em Production, clique em Add variable
Preencha:
Variable name: ANTHROPIC_API_KEY
Value: cole a chave que você criou no Passo 4 (sk-ant-api03-...)
Type: marque Encrypted (importante!)
Clique em Save
IMPORTANTE: depois de adicionar a variável, vá em Deployments e clique em Retry deployment no último deploy (variáveis novas só pegam efeito em deploys subsequentes)
🚨 Se esquecer essa variável: O OCR e o Coach IA vão retornar erro 500. É a causa mais comum de problemas no deploy.
✓ Checklist do Passo 6
Repo conectado ao Cloudflare Pages
Build configurado (sem build command, output /)
Deploy inicial concluído com sucesso
ANTHROPIC_API_KEY adicionada como Encrypted
Retry deployment executado após adicionar a env var
URL temporária .pages.dev acessível
PASSO 07
Apontar vitale.acacianegocios.com.br
⏱ ~5 minutos
Como o domínio acacianegocios.com.br já está no Cloudflare, adicionar um subdomínio é trivial.
No projeto Pages: Custom domains → Set up a custom domain
Digite: vitale.acacianegocios.com.br
Clique em Continue
O Cloudflare detecta que o domínio raiz é dele e oferece Activate domain automaticamente — clique nisso
Cloudflare cria sozinho o registro CNAME apontando para o .pages.dev
💡 Se algo der errado: Vá em Cloudflare Dashboard → acacianegocios.com.br → DNS → Records e confirme que existe um registro CNAME vitale apontando para vitale.pages.dev (ou similar) com a nuvem laranja (proxied).
https://vitale.acacianegocios.com.br carrega a tela de login
PASSO 08
Primeiro acesso e promoção a admin
⏱ ~3 minutos
Você precisa ser admin para acessar a Torre de Comando. Para isso, primeiro cria a conta normal, depois roda um SQL para promover-se.
Acesse https://vitale.acacianegocios.com.br
Aba Criar Conta
Use seu e-mail principal e uma senha forte
Cheque a caixa de entrada — deve chegar o e-mail de confirmação. Clique no link
Após confirmar, você será redirecionado para o app. Vai aparecer o onboarding pedindo nome + altura + peso atual. Preencha
Agora você está logado como usuário comum. Para virar admin:
Volte ao Supabase: SQL Editor → + New query
Cole e ajuste com seu e-mail real:
update public.profiles
set role = 'admin'
where email = 'seu.email@gmail.com';
Clique em Run
No app VITALE, faça logout (menu do usuário → Sair)
Logue novamente
Clique no seu avatar no canto superior direito — deve aparecer agora 🏛️ Torre de Comando em dourado
Clique e navegue pela Torre. Pronto, você é admin!
✓ Checklist do Passo 8
Conta criada e e-mail confirmado
Onboarding completado
SQL de promoção a admin rodado com sucesso
Logout + login feito após promoção
Link da Torre de Comando aparece no menu
Torre de Comando abre e mostra os KPIs
PASSO 09
Testes pós-deploy (checklist completo)
⏱ ~10 minutos
Antes de liberar para outros usuários, valide TODO o fluxo principal. Cada item testado é um bug a menos chegando ao usuário final.
🧪 Bateria de testes
Login com senha funciona Logue com a conta criada no Passo 8
Logout funciona Menu → Sair, deve voltar para tela de login
Magic link funciona Faça logout, peça um magic link com seu e-mail, abra o link da caixa de entrada
Adicionar peso manual funciona Aba "Importar" → Registro único → preencha data e peso → ADICIONAR
Dashboard reflete o peso novo Volte ao Dashboard, peso atual e IMC devem aparecer
Importar 5+ pesos via texto funciona Aba Importar → Texto → cole várias linhas no formato YYYY-MM-DD: XX.Xkg
Gráfico aparece com projeção Dashboard mostra linha verde (real) + dourada tracejada (projeção)
Histórico mostra todos os pesos Aba Histórico, tabela com data/peso/IMC/variação
Deletar peso funciona Histórico → 🗑️ em qualquer linha → confirma → recarrega
Tentativa de adicionar peso com data futura é rejeitada Erro claro deve aparecer
Substituir peso de data existente funciona Adicione peso de uma data que já existe → confirma substituição
Settings → Salvar perfil funciona Mude o nome, salve, recarregue — deve persistir
Torre — Feature flags: toggle funciona Desligue uma flag enabled → recarregue o app → a tab/seção some
Torre — Logs de Erro acessível Aba Erros, mesmo que vazia
Torre — Visão Geral mostra os KPIs Número de usuários, pesos, erros
Coach IA (Fase 3) — ative a flag e teste Torre → flag coach_ia ON → recarregue o app → mensagem do coach deve vir da IA real (mais longa e personalizada)
OCR (Fase 3) — ative a flag e teste Torre → flag ocr_imagem ON → Importar → faça upload de screenshot do Apple Health/balança → IA extrai os dados
Medicações (Fase 4) — ative e adicione uma Torre → medicacoes ON → tab aparece → cadastre uma medicação
PDF (Fase 5) — ative e gere Torre → relatorio_pdf ON → Relatório → Gerar PDF (deve baixar)
Mobile — abrir o site no celular funciona Layout responsivo, header empilha, tabs roláveis
Encontrou bug? Anote em algum lugar — talvez em uma issue no GitHub. Mesmo se for cosmético. Bugs cosméticos viram bugs grandes quando se acumulam.
PASSO 10
Liberar usuários gradualmente
⏱ ~5 minutos
Agora você pode convidar suas primeiras pessoas. Recomendo a estratégia abaixo:
10.1 — Estratégia de rollout
Semana
Quantos
O que fazer
1
1-2 pessoas próximas
Feedback rápido, bugs críticos
2
5 pessoas
Testar variedade de devices/sistemas
3
10-15 pessoas
Liberar Fase 3 (Coach IA, OCR)
4
20+ pessoas
Liberar Fase 4 e 5
10.2 — Como convidar
Não tem "sistema de convites" no MVP — basta passar o link https://vitale.acacianegocios.com.br e a pessoa se cadastra direto. Para controlar quem pode entrar, use UM dos dois caminhos:
Confiança: você passa o link só para pessoas selecionadas. Mais simples.
Aprovação manual: deixe Confirm email = ON e, antes de cada confirmação chegar, vá em Supabase → Authentication → Users e remova quem não devia. Mais trabalhoso, mas seguro.
10.3 — Acompanhamento
Acesse a Torre de Comando diariamente nos primeiros 7-14 dias:
Visão Geral: vê quantos signaram, quantos estão ativos
Erros: se aparecer erro novo, ataque imediatamente
Usuários: monitora se alguém parou de usar (pode ser bug ou tédio — pergunte!)
10.4 — Liberação por % de rollout
Para liberar uma feature gradualmente:
Torre → Feature Flags → ache a flag
Toggle ON
Slider de Rollout %: comece com 25%
Aguarde 24h, sem erros novos? Suba para 50%
Mais 24h ok? 100%
Cada usuário "cai" deterministicamente em um % (sempre o mesmo % para o mesmo user_id). Então 25% de rollout significa que 25% dos seus usuários veem a feature, e os mesmos 25% continuam vendo na próxima sessão.
✓ Checklist do Passo 10
Primeiro usuário externo convidado
Primeiro usuário externo conseguiu se cadastrar e usar
Estratégia de rollout das próximas semanas planejada
⚠️ TROUBLESHOOTING
Problemas comuns & soluções
❓ O site abre mas dá erro ao tentar logar/cadastrar
Causa provável: Você esqueceu de colar SUPABASE_URL e ANON_KEY nos arquivos HTML. Solução: Abra o console do navegador (F12). Se aparecer erro como Invalid URL ou SUPABASE_URL not configured, é isso. Volte ao Passo 5.1.
❓ OCR / Coach IA retornam "Servidor não configurado"
Causa: ANTHROPIC_API_KEY não foi adicionada OU foi adicionada mas o deploy não foi refeito depois. Solução: Cloudflare Pages → Settings → Environment variables → confirme que está lá. Depois: Deployments → Retry deployment no último.
❓ E-mail de confirmação não chega
Causa 1: Caixa de spam — sempre cheque primeiro. Causa 2: Você usou um domínio que o Supabase free tier limita (4 e-mails/hora). Aguarde ou use outro e-mail. Causa 3: Rate limit da Supabase. Veja em Authentication → Rate Limits.
❓ Magic link clicado, mas volta para tela de login
Causa: Redirect URL faltando em Authentication → URL Configuration. Solução: Confirme que https://vitale.acacianegocios.com.br E https://vitale.acacianegocios.com.br/app.html estão na lista de Redirect URLs.
❓ Torre de Comando dá redirect para /app.html
Causa: Sua conta não é admin. Solução: Rode o SQL do Passo 8 com seu e-mail correto. Verifique em Supabase → Table Editor → profiles que sua linha tem role = 'admin'. Faça logout e login.
❓ Feature flag toggleada mas não muda no app
Causa: Cache de flags do frontend (60 segundos). Solução: Aguarde 1 minuto OU recarregue forçado com Ctrl+Shift+R (Cmd+Shift+R no Mac).
❓ Gráfico não aparece no Dashboard
Causa: Você precisa de pelo menos 2 registros de peso para o gráfico ser construído. Solução: Adicione mais um peso em outra data.
❓ Custo da Claude API subindo demais
Solução: Torre → Feature Flags → diminua o rollout_pct de coach_ia e ocr_imagem para 25% ou 50%. Confirme o spend limit em console.anthropic.com → Settings → Limits.
❓ Site fora do ar / lento
Causa 1: Cloudflare Pages teve um incidente — cheque cloudflarestatus.com. Causa 2: Supabase teve um incidente — cheque status.supabase.com. Causa 3: Você atingiu free tier (improvável com beta pequeno).
❓ Erros aparecendo na aba Erros da Torre
Solução: Cada erro mostra contexto (qual função quebrou), mensagem e stack trace. Copie o erro e envie para o desenvolvedor / Claude para diagnóstico. Enquanto isso, considere desligar a feature relacionada pelo flag para não impactar mais usuários.
❓ Quero atualizar o código depois do primeiro deploy
Solução: É só dar git push com o código novo no branch main. O Cloudflare Pages detecta sozinho e refaz o deploy em ~1 minuto.
🎉 Pronto! Se chegou até aqui, o VITALE está oficialmente no ar. Acompanhe a Torre de Comando nos primeiros dias com atenção — é onde você vai descobrir bugs e padrões de uso antes dos seus usuários sentirem.