Ambiente de Staging — Guia de Configuração (Setup Inicial)
Checklist para recriar o ambiente de staging do zero. Para as motivações e decisões por trás do staging, ver STAGING_WHY.md. Para referência rápida do ambiente já configurado, ver STAGING_REFERENCE.md.
Última atualização: 2026-04-05
Índice
- Pré-requisitos
- Supabase — Novo Projeto
- Banco de Dados — Clone do Schema + Seed
- Secrets do Supabase
- Storage Buckets
- Edge Functions — Deploy Completo
- Cloudflare Worker — Novo Gateway
- CORS — Atualizar Origens
- Frontend — Deploy no Cloudflare Pages
- Validação Pós-Deploy
- Cuidados de Segurança
- Teardown
- Seed de Dados de Teste
- Sincronização de Migrations
1. Pré-requisitos
| Item | Descrição |
|---|---|
| Projeto Supabase separado (mesma conta OK) | Projeto isolado na mesma organização — o importante é isolamento de secrets e dados, não de conta |
| Conta Cloudflare (mesma conta OK — Pages e Worker no mesmo painel) | Cloudflare Pages para o frontend + Worker para o gateway, ambos no mesmo painel |
| Repositório GitHub | Mesmo repo, branch main (Cloudflare Pages faz deploy automático) |
| Supabase CLI | npm i -g supabase (v1.200+) |
| Wrangler CLI | npm i -g wrangler (para deploy do Worker) |
| Acesso ao dump de produção | Via pg_dump ou Supabase Dashboard > Database > Backups |
2. Supabase — Novo Projeto
- Criar novo projeto na mesma conta Supabase (ou conta separada, se preferir isolamento de billing)
- Criar novo projeto (região: preferencialmente a mesma de produção)
- Anotar:
SUPABASE_URL(ex:https://xxxx.supabase.co)SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYSUPABASE_DB_URL(connection string do Postgres)project-ref(o ID do projeto)
3. Banco de Dados — Clone do Schema + Seed
3.1 Exportar dump de produção
# Opção A: Via Supabase CLI
supabase db dump --project-ref mjvuzsizjlcalyfmbquy -f production_dump.sql
# Opção B: Via pg_dump direto
pg_dump "postgresql://postgres:[PASSWORD]@db.mjvuzsizjlcalyfmbquy.supabase.co:5432/postgres" \
--schema=public \
--no-owner \
--no-privileges \
-f production_dump.sql3.2 Importar no projeto staging
# Via psql
psql "$STAGING_DB_URL" -f production_dump.sql
# Ou via Supabase Dashboard > SQL Editor: colar e executar3.3 Sanitizar dados sensíveis
-- Limpar OTPs e tokens
TRUNCATE login_otps, portal_otps, cadastro_tokens;
-- Anonimizar telefones (manter formato válido para testes)
UPDATE usuarios SET telefone = '+5511999' || LPAD((ROW_NUMBER() OVER())::text, 6, '0')
WHERE telefone IS NOT NULL;
UPDATE responsaveis SET telefone = '+5511888' || LPAD((ROW_NUMBER() OVER())::text, 6, '0');
-- Limpar logs antigos
TRUNCATE logs_transacoes;
-- Limpar dados do MercadoPago
UPDATE escola_faturas SET
gateway_payment_id = NULL,
gateway_preference_id = NULL,
gateway_response = NULL,
link_pagamento = NULL,
pix_qrcode = NULL,
pix_copia_cola = NULL;3.4 Seed de dados de teste
Após sanitizar, popular com dados fictícios usando o script:
psql "$STAGING_DB_URL" -f docs/staging/seed.sqlVer Seção 13 para detalhes do seed.
3.5 Verificar Database Functions e Triggers
As funções (gerar_numero_fatura, update_updated_at_column, etc.) e triggers vêm no dump. Confirmar que existem:
SELECT routine_name FROM information_schema.routines
WHERE routine_schema = 'public' AND routine_type = 'FUNCTION';4. Secrets do Supabase
Todos os secrets devem ser regenerados no projeto staging. Nenhum valor de produção deve ser reutilizado.
# Configurar secrets via CLI
supabase secrets set --project-ref nrgcajnhpjmwilfcmqyb \
OLP_JWT_SECRET="$(openssl rand -hex 32)" \
CRON_SECRET="$(openssl rand -hex 32)"Lista completa de secrets
| Secret | Como gerar/obter | Obrigatório |
|---|---|---|
OLP_JWT_SECRET | openssl rand -hex 32 (usado por sistema e portal — unificado) | ✅ |
OLP_PEPPER_SECRET | openssl rand -hex 32 (hash de OTP em password-helper.ts) | ✅ |
CRON_SECRET | openssl rand -hex 32 | ✅ |
E2E_TEST_PASSWORD | Senha dos usuários Dev — mesmo valor no GitHub Actions | ✅ (CI) |
WASENDER_API_KEY | API key do Wasender (WhatsApp) de staging | ✅ |
WASENDER_WEBHOOK_SECRET | Secret do webhook Wasender de staging | ✅ |
NTFY_TOPIC | Tópico ntfy.sh separado de produção (alertas push) | ✅ |
MP_ACCESS_TOKEN | Token de teste do MercadoPago (TEST-xxxx) | ❌ (não configurado) |
SUPABASE_URL | Auto-preenchido pelo projeto | Auto |
SUPABASE_ANON_KEY | Auto-preenchido pelo projeto | Auto |
SUPABASE_SERVICE_ROLE_KEY | Auto-preenchido pelo projeto | Auto |
SUPABASE_DB_URL | Auto-preenchido pelo projeto | Auto |
SUPABASE_PUBLISHABLE_KEY | Mesmo valor do SUPABASE_ANON_KEY | Auto |
⚠️ MercadoPago: Usar credenciais de teste para sandbox.
5. Storage Buckets
Recriar os 4 buckets públicos no projeto staging:
-- Via SQL Editor do Supabase staging
INSERT INTO storage.buckets (id, name, public) VALUES
('banners-login', 'banners-login', true),
('curso-thumbnails', 'curso-thumbnails', true),
('tutoriais-thumbnails', 'tutoriais-thumbnails', true),
('mural-imagens', 'mural-imagens', true);Recriar as políticas de storage (se existirem) conforme o ambiente de produção.
6. Edge Functions — Deploy Completo
6.1 Linkar CLI ao projeto staging
supabase link --project-ref nrgcajnhpjmwilfcmqyb6.2 Deploy de todas as funções
# Deploy em lote (script):
for dir in supabase/functions/*/; do
fname=$(basename "$dir")
if [ "$fname" != "_shared" ]; then
echo "Deploying $fname..."
supabase functions deploy "$fname" --project-ref nrgcajnhpjmwilfcmqyb
fi
done6.3 Verificar config.toml
O supabase/config.toml deve ter verify_jwt = false para todas as funções (já está configurado). O mesmo arquivo é usado para ambos os ambientes.
6.4 Lista de funções (referência)
SSOT: A lista canônica está em
supabase/config.toml. Esta lista é referência aproximada.
admin-assinaturas admin-cron-monitor admin-dashboard
admin-escola-dados admin-escolas admin-faturas
admin-logs admin-planos admin-sms-logs
admin-usuarios-escola admin-usuarios
auth-diagnostics cadastro-escola-publica comunicacao-escola
coordenador-olimpiadas coordenador-videos
diretor-dashboard e2e-login escola-dados
escola-dashboard escola-pagamentos especialista-banners
especialista-curso-videos especialista-cursos especialista-headers
especialista-olimpiadas especialista-templates especialista-tutoriais
eventos-calendario-trial eventos-calendario faturamento-cron
gestao-alunos gestao-responsaveis gestao-resultados
gestao-turmas gestao-usuarios-escola healthcheck-cron
inscricoes-olimpiada logout maintenance-cron
me mercadopago-preference mercadopago-webhook
mural-escola notificacoes portal-escola
select-role send-otp tarefas-escola
user-permissions user-presence user-profile
verify-otp verify-password7. Cloudflare Worker — Novo Gateway
7.1 Criar novo Worker
# No diretório do Worker existente
cp -r gateway-worker gateway-worker-staging
cd gateway-worker-staging7.2 Atualizar variáveis do Worker
# wrangler.toml
name = "olp-gateway-staging"
[vars]
SUPABASE_URL = "https://nrgcajnhpjmwilfcmqyb.supabase.co"
SUPABASE_ANON_KEY = "<staging-anon-key>"
COOKIE_DOMAIN = ".staging.olp.digital" # ou o domínio do staging7.3 Deploy
wrangler deploy7.4 Configurar rota/domínio
- Opção A: Subdomínio —
gateway-staging.olp.digital(via DNS Cloudflare) - Opção B: Worker route —
staging-gateway.olp.digital/*
7.5 Ajustar reescrita de cookies
O Worker reescreve cookies olp_auth e olp_mural para o domínio configurado em COOKIE_DOMAIN. Verificar que o domínio do staging está correto para que os cookies funcionem no frontend.
8. CORS — Atualizar Origens
8.1 No código
Editar supabase/functions/_shared/cors-helpers.ts e adicionar a origem do frontend staging:
const ALLOWED_ORIGINS = [
'http://localhost:5173',
'http://localhost:8080',
// Produção
'https://olp.digital',
// Staging
'https://staging.olp.digital',
];8.2 Lembrete
A função isOriginAllowed() já aceita automaticamente qualquer *.lovable.app e *.lovableproject.com. Origens customizadas como staging.olp.digital precisam ser adicionadas explicitamente na lista.
9. Frontend — Deploy no Cloudflare Pages
9.1 Criar projeto no Cloudflare Pages
- Importar repositório GitHub
- Selecionar branch
main - Framework preset: Nenhum (custom)
9.2 Variáveis de ambiente no Cloudflare Pages
| Variável | Valor |
|---|---|
VITE_SUPABASE_PROJECT_ID | nrgcajnhpjmwilfcmqyb |
VITE_SUPABASE_PUBLISHABLE_KEY | (anon key do staging) |
VITE_SUPABASE_URL | https://nrgcajnhpjmwilfcmqyb.supabase.co |
VITE_USE_WORKER | true |
VITE_WORKER_URL | https://gateway-staging.olp.digital |
9.3 Build settings
Build Command: bun install && bun run build
Output Directory: dist9.4 Domínio
Configurar staging.olp.digital apontando para o projeto Cloudflare Pages via CNAME no DNS do Cloudflare.
10. Validação Pós-Deploy
Checklist funcional
□ Frontend carrega sem erros de console
□ CORS: sem erros de preflight no DevTools
□ Login OTP: fluxo completo funciona (usar e2e-login ou Wasender de staging)
□ Portal Aluno: acesso por matrícula + data nascimento
□ Portal Responsável: acesso por CPF + OTP
□ Dashboard escola: dados carregam do banco staging
□ Edge Functions: todas respondem (testar via curl)
□ Worker Gateway: cookies `olp_auth` setados no domínio correto
□ Storage: upload/download de imagens funciona
□ Logs: registros aparecem em `logs_transacoes`Script de verificação rápida
# Testar Edge Function diretamente
curl -X POST "https://nrgcajnhpjmwilfcmqyb.supabase.co/functions/v1/me" \
-H "Content-Type: application/json" \
-d '{"action": "ping"}'
# Testar via Gateway
curl -X POST "https://gateway-staging.olp.digital/me" \
-H "Content-Type: application/json" \
-d '{"action": "ping"}'11. Cuidados de Segurança
⚠️ Antes do pentest
| Cuidado | Motivo |
|---|---|
| Nunca usar secrets de produção no staging | Comprometimento do staging não afeta produção |
| Nunca conectar staging ao banco de produção | Isolamento total de dados |
| Usar Wasender de staging | Evitar envio para números de produção |
| Usar MercadoPago sandbox | Evitar transações financeiras reais |
| Sanitizar dump antes de importar | Remover telefones, tokens e dados pessoais reais |
| Não expor o staging publicamente | Usar IP allowlist ou auth básica no Cloudflare |
| Documentar todos os testes realizados | Auditoria e rastreabilidade |
⚠️ Durante o pentest
| Prática | Descrição |
|---|---|
| Rate limiting | Testar brute force em OTP (máx 5 tentativas) |
| CORS bypass | Tentar requisições de origens não autorizadas |
| JWT tampering | Modificar payload/signature do token |
| RLS bypass | Tentar acessar dados de outra escola via API |
| Injection | SQL injection em campos de busca e formulários |
| Cookie theft | Verificar flags HttpOnly, Secure, SameSite |
| Privilege escalation | Tentar ações de admin com token de professor |
| IDOR | Trocar IDs em endpoints para acessar recursos alheios |
⚠️ Após o pentest
- Documentar vulnerabilidades encontradas em relatório formal
- Classificar por severidade (Critical / High / Medium / Low / Info)
- Criar issues no GitHub para cada vulnerabilidade
- Destruir ambiente staging (ver Teardown)
12. Teardown
Após concluir o pentest, destruir o ambiente para evitar custos e exposição:
# 1. Deletar projeto Supabase staging
# Via Dashboard: Settings > General > Delete Project
# 2. Deletar Worker Cloudflare
wrangler delete --name olp-gateway-staging
# 3. Deletar projeto Cloudflare Pages
# Via Cloudflare Dashboard → Pages → selecionar projeto → Settings → Delete Project
# 4. Remover DNS staging (se configurado)
# Via Cloudflare Dashboard: remover registros de staging.olp.digital e gateway-staging.olp.digital
# 5. Limpar branch staging (se não for mais necessária)
git branch -d staging
git push origin --delete staging13. Seed de Dados de Teste
O arquivo docs/staging/seed.sql contém dados fictícios completos para popular o banco de staging. Ele cria:
- 3 escolas (pública, privada, rede) com endereços
- 11 usuários cobrindo todos os 11 papéis do sistema
- 1 especialista e 1 administrador (papéis globais)
- Turmas por série (6º ao 9º EF) para cada escola
- Alunos distribuídos nas turmas com dados realistas
- Responsáveis vinculados aos alunos
- 3 olimpíadas com fases, níveis e cronograma
- Adesões das escolas às olimpíadas
- Inscrições de alunos nas olimpíadas
- Planos e assinaturas para cada escola
- Portal config com slugs e métodos de acesso por série
- Publicações no mural olímpico
Como usar
# Após importar o schema (dump) e sanitizar
psql "$STAGING_DB_URL" -f docs/staging/seed.sql⚠️ O seed usa UUIDs fixos (
aaaaaaaa-...) para facilitar referências cruzadas nos testes. Nunca usar esses UUIDs em produção.
14. Sincronização de Migrations
Fluxo normal (CI/CD)
O job deploy-staging do pipeline CI executa supabase db push automaticamente a cada push na branch main. Isso aplica todas as migrations pendentes em supabase/migrations/ ao banco do staging.
Setup do zero — duas abordagens
Abordagem A: Migrations puras (recomendado para ambientes limpos)
# 1. Linkar ao projeto staging
supabase link --project-ref <staging-ref>
# 2. Aplicar todas as migrations do repositório
supabase db pushIsso aplica as migrations sequencialmente, recriando o schema completo. Ideal para um projeto Supabase recém-criado.
Abordagem B: Import via pg_dump + marcar migrations
Se o schema foi importado via pg_dump (Seção 3), as migrations já estão refletidas no banco mas o Supabase não sabe disso. Executar o supabase db push causaria conflitos (tabelas já existem).
Solução: marcar todas as migrations como já aplicadas usando o script de referência:
# Marcar migrations como aplicadas sem executá-las
psql "$STAGING_DB_URL" -f docs/staging/staging_mark_migrations.sqlO arquivo staging_mark_migrations.sql insere registros na tabela supabase_migrations.schema_migrations para cada arquivo em supabase/migrations/, indicando que já foram aplicadas.
Novas migrations após setup
Após o setup inicial (por qualquer abordagem), novas migrations criadas no repositório serão aplicadas automaticamente pelo CI ou manualmente via:
supabase db push --project-ref <staging-ref>Diagrama de Arquitetura Staging
┌──────────────────────────┐
│ Cloudflare Pages │
│ staging.olp.digital │
│ Branch: main │
│ Build: bun run build │
└──────────┬───────────────┘
│ HTTPS
▼
┌──────────────────────────┐
│ Cloudflare Worker │
│ gateway-staging │
│ .olp.digital │
│ - Cookie rewrite │
│ - Geo headers │
│ - CORS proxy │
└──────────┬───────────────┘
│ HTTPS
▼
┌──────────────────────────┐
│ Supabase Staging │
│ Ref: nrgcajnhpjmwilfcmqyb │
│ - Edge Functions (52+) │
│ - Postgres │
│ - Storage (4 buckets) │
│ - Secrets (isolados) │
└──────────────────────────┘Referências
- Staging WHY — Motivações e decisões arquiteturais
- Staging Reference — Valores reais do ambiente atual
- Seed Test Users — Referência de dados de teste
- Testing Master — Estratégia de testes
- Cloudflare Worker Gateway — Documentação do Worker
- Authentication — Fluxo de autenticação