Staging — Referência Rápida
Documento de referência preenchido com os valores reais do ambiente de staging. Para as motivações e decisões por trás do staging, ver STAGING_WHY.md. Para o guia de setup inicial, ver STAGING_SETUP.md.
Última atualização: 2026-04-05
1. Visão Geral da Infraestrutura
PRODUÇÃO STAGING
════════ ═══════
olp.digital staging.olp.digital
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Lovable Hosting │ │ Cloudflare Pages │
│ (frontend) │ │ Branch: main │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ CF Worker │ │ CF Worker │
│ gateway.olp │ │ gateway-staging │
│ .digital │ │ .olp.digital │
│ │ │ │
│ COOKIE_DOMAIN: │ │ COOKIE_DOMAIN: │
│ .olp.digital │ │ .staging.olp │
│ │ │ .digital │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Supabase PROD │ │ Supabase STAGING │
│ mjvuzsizjlca... │ │ nrgcajnhpjmw... │
│ │ │ │
│ JWT_SECRET: A │ ← DIFERENTES → │ JWT_SECRET: B │
│ PEPPER: X │ │ PEPPER: Y │
│ 52+ Edge Funcs │ │ 52+ Edge Funcs │
└──────────────────┘ └──────────────────┘
⚠️ Token assinado com JWT_SECRET A NÃO funciona no ambiente B (e vice-versa)2. URLs e Endpoints
| Recurso | URL |
|---|---|
| Frontend | https://staging.olp.digital |
| Worker Gateway | https://gateway-staging.olp.digital |
| Supabase API | https://nrgcajnhpjmwilfcmqyb.supabase.co |
| Edge Functions | https://nrgcajnhpjmwilfcmqyb.supabase.co/functions/v1/<nome> |
| Supabase Dashboard | https://supabase.com/dashboard/project/nrgcajnhpjmwilfcmqyb |
| Portal Monteiro Lobato | https://staging.olp.digital/escola/monteiro-lobato |
| Portal Nova Era | https://staging.olp.digital/escola/nova-era |
3. Supabase Staging — Identificadores
| Item | Valor |
|---|---|
| Project Ref | nrgcajnhpjmwilfcmqyb |
| Região | (mesma de produção) |
| Anon Key | Configurada no Cloudflare Pages e GitHub Secrets |
⚠️ Nunca commitar o service_role_key no código. Está apenas nos GitHub Secrets.
4. Secrets — Supabase Staging
Secrets configurados via Supabase Dashboard → Settings → Edge Functions → Secrets.
| Secret | Status | Nota |
|---|---|---|
OLP_JWT_SECRET | ✅ Configurado | Próprio do staging (≠ produção) |
OLP_PEPPER_SECRET | ✅ Configurado | Próprio do staging (≠ produção) |
E2E_TEST_PASSWORD | ✅ Configurado | Mesmo valor no GitHub Actions |
CRON_SECRET | ✅ Configurado | Próprio do staging (≠ produção) |
WASENDER_API_KEY | ✅ Configurado | Credenciais de staging |
WASENDER_WEBHOOK_SECRET | ✅ Configurado | Credenciais de staging |
NTFY_TOPIC | ✅ Configurado | Tópico diferente de produção |
SUPABASE_URL | ✅ Auto | Preenchido automaticamente |
SUPABASE_ANON_KEY | ✅ Auto | Preenchido automaticamente |
SUPABASE_SERVICE_ROLE_KEY | ✅ Auto | Preenchido automaticamente |
SUPABASE_DB_URL | ✅ Auto | Preenchido automaticamente |
SUPABASE_PUBLISHABLE_KEY | ✅ Auto | Mesmo valor do anon key |
OLP_PORTAL_SECRET | N/A | Portal usa OLP_JWT_SECRET (unificado). Não existe no código — ver AUTHENTICATION.md |
TWILIO_* | ❌ Descontinuado | Twilio removido — Wasender é o provedor exclusivo |
MP_ACCESS_TOKEN | ❌ Pendente | MercadoPago não configurado |
Regra de isolamento
CORRETO:
OLP_JWT_SECRET do staging ≠ OLP_JWT_SECRET da produção
OLP_PEPPER_SECRET do staging ≠ OLP_PEPPER_SECRET da produção
CRON_SECRET do staging ≠ CRON_SECRET da produção
NTFY_TOPIC do staging ≠ NTFY_TOPIC da produção
ERRADO:
Qualquer secret de segurança igual entre staging e produção5. Rotação de Secrets
Quando rotacionar
- Suspeita de comprometimento
- Rotação periódica (recomendado: a cada 90 dias para secrets de segurança)
- Mudança de pessoal com acesso
Processo de rotação
# 1. Gerar novo valor
NEW_SECRET=$(openssl rand -hex 32)
# 2. Atualizar no Supabase
supabase secrets set --project-ref nrgcajnhpjmwilfcmqyb \
OLP_JWT_SECRET="$NEW_SECRET"
# 3. Redeploy de TODAS as Edge Functions que usam o secret
# (o redeploy faz as funções lerem o novo valor do env)
supabase functions deploy --project-ref nrgcajnhpjmwilfcmqyb
# 4. Validar
curl -X POST "https://nrgcajnhpjmwilfcmqyb.supabase.co/functions/v1/auth-diagnostics" \
-H "Content-Type: application/json" \
-d '{"action": "check"}'Dependências de cada secret
| Secret | Edge Functions que dependem | Impacto da rotação |
|---|---|---|
OLP_JWT_SECRET | Todas que usam auth-helpers.ts (extractAuthenticatedUser) — ~45 funções | Todas as sessões existentes são invalidadas (JWT assinado com secret antigo falha verificação) |
OLP_PEPPER_SECRET | send-otp, verify-otp (hash do OTP) | OTPs pendentes falham verificação — novos OTPs funcionam normalmente |
CRON_SECRET | faturamento-cron, maintenance-cron, healthcheck-cron | Crons autenticados via header X-Cron-Secret param de funcionar até atualizar o caller (Supabase cron ou externo) |
E2E_TEST_PASSWORD | e2e-login | Testes CI falham até atualizar o GitHub Secret correspondente |
WASENDER_API_KEY | send-otp (envio via WaSender) | Envio de mensagens WhatsApp falha |
Ordem recomendada para rotação do OLP_JWT_SECRET
- Gerar novo valor
supabase secrets setcom novo valor- Redeploy de todas as Edge Functions
- Nota: usuários logados serão deslogados (cookie
olp_authcontém JWT inválido) - Validar com
auth-diagnosticsou login de teste viae2e-login
6. Impacto dos Secrets Pendentes
| Secret pendente | Funcionalidade quebrada no staging | Testes afetados | Workaround |
|---|---|---|---|
| Seed data do mural | Portal mural sem dados (mural_liberacoes, mural_dados_publicados, escola_mural_config) | E2E de mural não rodam no CI | Nenhum — testes de mural estão desabilitados |
TWILIO_* | (Descontinuado — Wasender é o provedor exclusivo) | N/A | N/A |
MP_ACCESS_TOKEN | mercadopago-preference retorna erro ao criar preferência de pagamento; mercadopago-webhook não valida assinatura | Fluxo de pagamento completo não testável | Nenhum — pagamentos não são alvo dos testes CI |
7. Mecanismo do e2e-login
O login direto para testes automatizados funciona por ausência intencional de secret em produção — sem flags de ambiente, sem código condicional. O E2E_TEST_PASSWORD é a senha real dos usuários de teste, e o e2e-login autentica legitimamente, apenas pulando o envio de OTP WhatsApp.
Como funciona
1. Edge Function `e2e-login` registrada em config.toml com verify_jwt = false
2. Recebe: { cpf_or_code, papel? } + header X-E2E-Key
3. Valida: X-E2E-Key === Deno.env.get("E2E_TEST_PASSWORD")
4. Se válido: busca usuário → gera JWT → seta cookie olp_auth → retorna dadosPor que é seguro
PRODUÇÃO:
E2E_TEST_PASSWORD não está configurado
→ Deno.env.get("E2E_TEST_PASSWORD") retorna undefined
→ "qualquer-valor" === undefined → false
→ 401 Unauthorized (SEMPRE)
STAGING:
E2E_TEST_PASSWORD está configurado
→ header deve conter o valor exato
→ 200 OK + JWT + cookieNão é uma flag de ambiente. A segurança não depende de NODE_ENV=production ou qualquer condicional. Depende da ausência física do secret no ambiente de produção. Mesmo que alguém descubra o nome do header e da Edge Function, sem o secret correto a resposta é sempre 401.
8. Secrets — GitHub Actions
Repository secrets configurados em Settings → Secrets and variables → Actions.
| Secret | Status | Uso |
|---|---|---|
SUPABASE_ACCESS_TOKEN | ✅ | Token pessoal do Supabase CLI |
STAGING_PROJECT_REF | ✅ | nrgcajnhpjmwilfcmqyb |
STAGING_SUPABASE_URL | ✅ | https://nrgcajnhpjmwilfcmqyb.supabase.co |
STAGING_SUPABASE_ANON_KEY | ✅ | Anon key do projeto staging |
E2E_TEST_PASSWORD | ✅ | Mesmo valor do Supabase staging |
SUPABASE_SERVICE_ROLE_KEY | ✅ | Para operações administrativas no CI |
NTFY_TOPIC_URL | ✅ | Notificações de falha do CI (hash ou URL completa) |
Como o CI usa os secrets
env:
VITE_SUPABASE_URL: ${{ secrets.STAGING_SUPABASE_URL }}
VITE_SUPABASE_PUBLISHABLE_KEY: ${{ secrets.STAGING_SUPABASE_ANON_KEY }}
E2E_TEST_PASSWORD: ${{ secrets.E2E_TEST_PASSWORD }}9. Frontend — Cloudflare Pages
| Item | Valor |
|---|---|
| Plataforma | Cloudflare Pages |
| Branch | main |
| Build Command | bun install && bun run build |
| Output Directory | dist |
| Domínio | staging.olp.digital (CNAME no Cloudflare DNS) |
Variáveis de ambiente (Cloudflare Pages Dashboard)
| 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 |
10. Worker Gateway — Cloudflare
| Item | Valor |
|---|---|
| Nome | olp-gateway-staging |
| URL | https://gateway-staging.olp.digital |
| COOKIE_DOMAIN | .staging.olp.digital |
| SUPABASE_URL | https://nrgcajnhpjmwilfcmqyb.supabase.co |
O Worker reescreve os cookies olp_auth e olp_mural com Domain=.staging.olp.digital para que funcionem no frontend.
11. Dados de Teste
Ver seed_test_users.sql para referência completa.
Escolas
| Nome | Slug (mural) | Uso |
|---|---|---|
| Escola Municipal Monteiro Lobato | monteiro-lobato | Escola principal |
| Colegio Particular Nova Era | nova-era | IDOR cross-escola |
| Rede Educacional Futuro | — | Multi-role |
Usuários (7 ativos)
| Nome | Código | Papel | Escola |
|---|---|---|---|
| Dev Admin | 42970698064 | administrador | Global |
| Dev Especialista | 63100416066 | especialista | Global |
| Dev Coordenador | 99407464075 | coordenador | Monteiro Lobato |
| Dev Diretor | 61626069026 | diretor | Monteiro Lobato |
| Dev Escola | 77457094000157 | escola | Monteiro Lobato |
| Dev Testes Multi Role | 40750810017 | 9+ papéis | Todas |
| Dev Coordenador da Nova Era | 47691226080 | coordenador | Nova Era |
Multi-Role detalhamento
O usuário 40750810017 possui: administrador, especialista, coordenador (×3 escolas), diretor, escola, pedagogico, professor.
12. Pipeline CI
lint-and-build → deploy-staging → contract-tests → security-tests → e2e
(smoke test) (IDOR bloqueador) (Playwright)O que cada job precisa
| Job | Secrets | Dados no banco |
|---|---|---|
deploy-staging | SUPABASE_ACCESS_TOKEN, STAGING_PROJECT_REF | — |
contract-tests | STAGING_SUPABASE_URL, STAGING_SUPABASE_ANON_KEY, E2E_TEST_PASSWORD | 7 usuários com CPFs exatos |
security-tests | Idem | Coord Monteiro + Coord Nova Era |
e2e | Idem + BASE_URL=staging.olp.digital | Admin, Coordenador, Edge Functions deployadas |
13. Storage Buckets
| Bucket | Público | Status |
|---|---|---|
banners-login | ✅ | Criado |
curso-thumbnails | ✅ | Criado |
tutoriais-thumbnails | ✅ | Criado |
mural-imagens | ✅ | Criado |
14. Diferenças Staging vs Produção
| Aspecto | Produção | Staging | Impacto no staging |
|---|---|---|---|
| Supabase Ref | mjvuzsizjlcalyfmbquy | nrgcajnhpjmwilfcmqyb | Dados e sessões completamente isolados |
| Domínio | olp.digital | staging.olp.digital | Cookies não vazam entre ambientes |
| Frontend | Lovable hosting | Cloudflare Pages | Deploy via CF Pages Dashboard ou CI |
| Gateway Worker | gateway.olp.digital | gateway-staging.olp.digital | Reescrita de cookies no domínio staging |
| WhatsApp (Wasender) | Ativo | ✅ Configurado | Provedor exclusivo de mensagens |
| Pagamentos (MP) | Ativo | ❌ Não configurado | Fluxo de pagamento/fatura não testável |
| Notificações (WaSender) | Ativo | ✅ Configurado | WhatsApp funcional para testes |
| NTFY | Tópico de produção | Tópico separado | Alertas de CI não poluem produção |
E2E_TEST_PASSWORD | ❌ Não existe | ✅ Configurado | Senha dos usuários de teste para login direto (sem OTP) |
e2e-login | Retorna 401 sempre | ✅ Funcional | Ver §7 — Mecanismo do e2e-login |
| Portal (mural) | Ativo (via OLP_JWT_SECRET unificado) | ❌ Sem seed data do mural | Testes E2E de portal desabilitados |
15. Troubleshooting
| Erro | Causa | Fix |
|---|---|---|
| 404 "Usuário não encontrado" | Usuário de teste não criado | Criar via UI com CPF exato |
| 500 em auth | Catch block da EF não mapeia erro | Corrigir a função |
| 401 com cookie válido | OLP_JWT_SECRET não bate | Verificar secret no Supabase staging |
| CORS bloqueado | Origem não em ALLOWED_ORIGINS | Verificar cors-helpers.ts |
| Cookie não setado | Worker não reescreve Domain | Verificar COOKIE_DOMAIN no Worker |
| Edge Function timeout | Cold start | Aumentar timeout ou warmup |
| CI falha "env not set" | Secret faltando no GitHub | Adicionar em Settings → Secrets |
16. Referências
- Staging WHY — Motivações e decisões arquiteturais
- Setup Guide — Guia de setup inicial (template)
- Seed Test Users — Referência de dados de teste
- Testing Master — Estratégia de testes
- Authentication — Fluxo de autenticação
- Cloudflare Worker — Documentação do Worker