12 — Portal/Mural: superfície pública e cargas de pico
Pergunta: o Portal (Mural Olímpico) é a única superfície pública com tráfego não autenticado — como ele escala em janela de divulgação (10k acessos em 1 hora)?
Diferenças em relação ao admin
| Eixo | Admin/Coord | Portal/Mural |
|---|---|---|
| Autenticação | Sempre (cookie JWT) | Mista: anônimo (lookup escola) + OTP (mural autenticado) |
| Tráfego | Linear no número de usuários (~10–50 simultâneos) | Pulso: divulgação de resultado pode levar 5k–10k acessos/hora |
| Cache | React Query no cliente | Edge cache + snapshots (já existe mural_dados_publicados) |
| Custo de RLS | Por usuário, com filtro de escola | Por request anônimo, sem JWT — usa supabasePublic |
Edge functions no perímetro
mural-escola/— endpoint público do mural por slugportal-escola/— login do portal (CPF + OTP / matrícula + DN)mural-publicacoes— gestão (coord)mural-liberacoes— gate de publicação (coord)
Pontos de pressão
P1 — Lookup público pré-login
Toda chamada anônima ao mural exige supabasePublic (ver mem://architecture/mural-pre-login-privilege-requirement). Sob pico:
- Cada request faz um SELECT no banco para resolver slug → escola_id → snapshot.
- Sem cache de borda, 10k requests = 10k roundtrips ao Postgres.
- Hipótese: usar CDN cache (Cloudflare) com TTL curto (30s–5min) para o snapshot público — invalidado por edge function ao publicar.
P2 — Snapshot de resultados
mural_dados_publicados armazena snapshots imutáveis por publicação. Bom design — a leitura é O(1) por publicação. Confirmar que o JSONB do snapshot:
- Não embute lista gigante (10k alunos) num único registro — se sim, fragmentar por nível/turma.
- Tem índice em
(escola_id, publicacao_id).
P3 — Rate limiting do OTP
portal_otps + portal_rate_metrics + portal_login_tentativas — bom; já tem cooldown. Conferir se:
- A contagem de tentativas usa Redis (Upstash) e não SQL.
- O rate limit é por (IP, identificador) e não só por IP (proxy NAT compartilha).
P4 — Rotas privadas do mural
Após login do portal, queries são por aluno_id (poucos registros por aluno) — baixo risco.
Hipóteses
- H1: Sem edge cache, divulgação simultânea de resultados é o pior cenário de carga da plataforma — maior que qualquer ação interna do coord.
- H2: A latência percebida no Portal hoje (com carga baixa) é puramente cold-start de Edge Function (~150ms) — vai colapsar em pico.
- H3: O snapshot JSONB monolítico vai virar problema quando uma escola publicar 5k+ resultados num único nível.
Próximas etapas (auditoria, não fix)
- Medir tamanho real dos snapshots já publicados (
select pg_column_size(snapshot_jsonb) from mural_dados_publicados order by 1 desc limit 10). - Cruzar com
mem://features/mural-olimpico/publicacao-parcial-silenciosa(já endereçou correção de UX) — esta auditoria é performance, não correção lógica. - Avaliar Cloudflare cache para a rota pública.
Links
mem://architecture/mural-olimpico-snapshot-and-release-standard-v2mem://infrastructure/cloudflare-worker-v2-specificationsmem://infrastructure/upstash-redis-standard