Skip to content

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

  1. Pré-requisitos
  2. Supabase — Novo Projeto
  3. Banco de Dados — Clone do Schema + Seed
  4. Secrets do Supabase
  5. Storage Buckets
  6. Edge Functions — Deploy Completo
  7. Cloudflare Worker — Novo Gateway
  8. CORS — Atualizar Origens
  9. Frontend — Deploy no Cloudflare Pages
  10. Validação Pós-Deploy
  11. Cuidados de Segurança
  12. Teardown
  13. Seed de Dados de Teste
  14. Sincronização de Migrations

1. Pré-requisitos

ItemDescriçã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 GitHubMesmo repo, branch main (Cloudflare Pages faz deploy automático)
Supabase CLInpm i -g supabase (v1.200+)
Wrangler CLInpm i -g wrangler (para deploy do Worker)
Acesso ao dump de produçãoVia pg_dump ou Supabase Dashboard > Database > Backups

2. Supabase — Novo Projeto

  1. Criar novo projeto na mesma conta Supabase (ou conta separada, se preferir isolamento de billing)
  2. Criar novo projeto (região: preferencialmente a mesma de produção)
  3. Anotar:
    • SUPABASE_URL (ex: https://xxxx.supabase.co)
    • SUPABASE_ANON_KEY
    • SUPABASE_SERVICE_ROLE_KEY
    • SUPABASE_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

bash
# 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.sql

3.2 Importar no projeto staging

bash
# Via psql
psql "$STAGING_DB_URL" -f production_dump.sql

# Ou via Supabase Dashboard > SQL Editor: colar e executar

3.3 Sanitizar dados sensíveis

sql
-- 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:

bash
psql "$STAGING_DB_URL" -f docs/staging/seed.sql

Ver 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:

sql
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.

bash
# 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

SecretComo gerar/obterObrigatório
OLP_JWT_SECRETopenssl rand -hex 32 (usado por sistema e portal — unificado)
OLP_PEPPER_SECRETopenssl rand -hex 32 (hash de OTP em password-helper.ts)
CRON_SECRETopenssl rand -hex 32
E2E_TEST_PASSWORDSenha dos usuários Dev — mesmo valor no GitHub Actions✅ (CI)
WASENDER_API_KEYAPI key do Wasender (WhatsApp) de staging
WASENDER_WEBHOOK_SECRETSecret do webhook Wasender de staging
NTFY_TOPICTópico ntfy.sh separado de produção (alertas push)
MP_ACCESS_TOKENToken de teste do MercadoPago (TEST-xxxx)❌ (não configurado)
SUPABASE_URLAuto-preenchido pelo projetoAuto
SUPABASE_ANON_KEYAuto-preenchido pelo projetoAuto
SUPABASE_SERVICE_ROLE_KEYAuto-preenchido pelo projetoAuto
SUPABASE_DB_URLAuto-preenchido pelo projetoAuto
SUPABASE_PUBLISHABLE_KEYMesmo valor do SUPABASE_ANON_KEYAuto

⚠️ MercadoPago: Usar credenciais de teste para sandbox.


5. Storage Buckets

Recriar os 4 buckets públicos no projeto staging:

sql
-- 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

bash
supabase link --project-ref nrgcajnhpjmwilfcmqyb

6.2 Deploy de todas as funções

bash
# 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
done

6.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-password

7. Cloudflare Worker — Novo Gateway

7.1 Criar novo Worker

bash
# No diretório do Worker existente
cp -r gateway-worker gateway-worker-staging
cd gateway-worker-staging

7.2 Atualizar variáveis do Worker

toml
# 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 staging

7.3 Deploy

bash
wrangler deploy

7.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:

typescript
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

  1. Importar repositório GitHub
  2. Selecionar branch main
  3. Framework preset: Nenhum (custom)

9.2 Variáveis de ambiente no Cloudflare Pages

VariávelValor
VITE_SUPABASE_PROJECT_IDnrgcajnhpjmwilfcmqyb
VITE_SUPABASE_PUBLISHABLE_KEY(anon key do staging)
VITE_SUPABASE_URLhttps://nrgcajnhpjmwilfcmqyb.supabase.co
VITE_USE_WORKERtrue
VITE_WORKER_URLhttps://gateway-staging.olp.digital

9.3 Build settings

Build Command: bun install && bun run build
Output Directory: dist

9.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

markdown
□ 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

bash
# 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

CuidadoMotivo
Nunca usar secrets de produção no stagingComprometimento do staging não afeta produção
Nunca conectar staging ao banco de produçãoIsolamento total de dados
Usar Wasender de stagingEvitar envio para números de produção
Usar MercadoPago sandboxEvitar transações financeiras reais
Sanitizar dump antes de importarRemover telefones, tokens e dados pessoais reais
Não expor o staging publicamenteUsar IP allowlist ou auth básica no Cloudflare
Documentar todos os testes realizadosAuditoria e rastreabilidade

⚠️ Durante o pentest

PráticaDescrição
Rate limitingTestar brute force em OTP (máx 5 tentativas)
CORS bypassTentar requisições de origens não autorizadas
JWT tamperingModificar payload/signature do token
RLS bypassTentar acessar dados de outra escola via API
InjectionSQL injection em campos de busca e formulários
Cookie theftVerificar flags HttpOnly, Secure, SameSite
Privilege escalationTentar ações de admin com token de professor
IDORTrocar 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:

bash
# 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 staging

13. 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

bash
# 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)

bash
# 1. Linkar ao projeto staging
supabase link --project-ref <staging-ref>

# 2. Aplicar todas as migrations do repositório
supabase db push

Isso 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:

bash
# Marcar migrations como aplicadas sem executá-las
psql "$STAGING_DB_URL" -f docs/staging/staging_mark_migrations.sql

O 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:

bash
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