Auditoria de Performance — Resultados (Coordenador) e Tabelas Escaláveis
Status: Coleta de evidência (sem fix nesta entrega) Data: 2026-06-04 Alvo primário: Tela
Resultadosdo Coordenador Alvo expandido: Todas as features escaláveis do Coordenador + tabelas que crescem com volume escolar Modo: auditoria fundamentalista, em arquivos quebrados, com referência cruzada
TL;DR (a frase que importa)
A regressão de performance é consequência direta do fix de Silent Data Loss do incidente Nível S (commit 2026-06-04 H7/H8). Trocamos um cap silencioso de 1000 linhas por um caminho que drena ~2k linhas em todo mount E em toda paginação (paginação é client-side em cima de uma drenagem completa). A solução não é desfazer o fix — é paginar no servidor (cursor/range), agregar via SQL (em vez de drenar para JS), e mover writes em lote para o padrão de fila persistente já validado pela Importação Inteligente de Alunos.
Mapa de evidência
| Arquivo | Pergunta que responde |
|---|---|
| 01_RESULTADOS_COORDENADOR.md | Por que a tela demora ~6s no mount + ~2s na tabela? |
| 02_PAGINATION_FETCHALL_TRADEOFF.md | Por que paginar piora ao invés de melhorar? |
| 03_RECOMPUTE_BATCH_HOTPATH.md | Por que recompute trava a UI em escolas grandes? |
| 04_ALUNOS_ESCOLA_BENCHMARK.md | Como a Importação Inteligente resolveu — qual é o padrão a replicar? |
| 05_COORDENADOR_FEATURES_SWEEP.md | Que outras features do coord vão quebrar em 5k alunos? |
| 06_TABELAS_ESCALAVEIS_INVENTARIO.md | Quais tabelas crescem e como hoje são lidas? |
| 07_ANTIPATTERNS_LOOKUP_POR_NOME.md | Onde há lookup frágil (string match) que precisa virar UUID? |
| 08_REACT_QUERY_CACHE_AUDIT.md | A cache do React Query está bem dimensionada? keepPreviousData? |
| 09_INDEX_AND_EXPLAIN_BASELINE.md | Há índices DB para os queries hot? Quais EXPLAINs rodar? |
| 10_VIRTUALIZATION_AND_RENDER_COST.md | Onde o React vai engasgar mesmo após o fetch ficar rápido? |
| 11_ADMIN_ESPECIALISTA_SCALABILITY.md | Admin/Especialista têm os mesmos hotpaths do Coord? |
| 12_PORTAL_MURAL_SCALABILITY.md | Como o Portal público aguenta 10k acessos em pico de divulgação? |
| 13_LOGS_AND_OBSERVABILITY_SELF_SCALING.md | logs_transacoes cresce sem limite — quando vira o próximo gargalo? |
| 14_REALTIME_AND_BACKGROUND_JOBS.md | Subscriptions realtime e crons custam quanto silenciosamente? |
| 99_REGRA_QUALIDADE_PERFORMANCE.md | Qual SSOT de performance vamos adotar (proposta, sem implementar)? |
Síntese: 11 frentes candidatas (ordem de impacto × esforço)
| # | Frente | Impacto | Esforço | Detalhe |
|---|---|---|---|---|
| F1 | Paginação real no servidor em handleListByOlimpiada (range no PostgREST + total via count='exact') | 🟢🟢🟢 alto | M | Hoje drena 100% + paginar em JS — ver 02 §3 |
| F2 | Substituir fetchAllRows por SQL agregado em handleStats, handleStatsAgregados, handleBatchInit | 🟢🟢🟢 alto | M | 4 de 8 chamadas hoje são puramente agregadas — 02 §4 |
| F3 | recompute/set_premiacao_batch em fila persistente com task_id + polling (padrão Alunos) | 🟢🟢 médio-alto | M-G | Hoje síncrono — estoura 150s em 8k inscrições — 03 §2-3 |
| F4 | batch_init consolidando olimpiadas + stats + statsAgregados em uma única RPC SQL | 🟢🟢 médio | P | Hoje 3 actions sequenciais + drenagem — 01 §3 |
| F5 | Sweep coord: aplicar (F1/F2) em Inscrições, Mensagens, Mural admin, Controle | 🟢🟢 médio | G | Análise em 05 |
| F6 | Padronizar lookup por UUID (proibir .eq('nome', ...) em domínio multi-tenant) | 🟢 baixo agora, 🟢🟢🟢 alto em incidente | P | Ver 07 |
| F7 | Defaults RQ: refetchOnWindowFocus: false global + placeholderData: keepPreviousData obrigatório em listas paginadas | 🟢🟢 médio | P | Hoje refetch agressivo sem keepPreviousData — 08 |
| F8 | Índices compostos faltantes (resultados_aluno, mensagens_enviadas, logs_transacoes) — migration CONCURRENTLY | 🟢🟢 médio | P | Sem evidência de seq scan, mas alto risco — 09 |
| F9 | Particionar logs_transacoes por mês + retenção 12m + sampling de ações de alta frequência | 🟢🟢 médio | M | Tabela sem TTL — próxima crise antes do Resultados — 13 |
| F10 | Edge cache (Cloudflare) para mural-escola público com TTL curto + invalidação por publicação | 🟢🟢 médio | M | Picos de divulgação = pior cenário de carga — 12 |
| F11 | Estender sweep para Admin (admin-logs, admin-financeiro) e Especialista (especialista-cronograma) | 🟢🟢 médio | M-G | Equivalente cross-escola do problema Resultados — 11 |
O que NÃO está nesta auditoria (deliberadamente)
- Mudança de código de produção.
- Memória
mem://nova — só após o SSOT do arquivo 99 ser aprovado. - Decisão sobre Cloudflare Worker/Redis para fila — registrado como hipótese em 03, não como conclusão.
- Testes novos.
Próxima rodada (a abrir como planos separados, em ondas)
- Onda A — Leitura UI rápida: F1 + F2 + F4. Critério de saída: tela Resultados ≤1.5s TTFB e troca de página ≤300ms para 2k inscrições.
- Onda B — Writes em lote seguros: F3. Critério de saída:
recomputeem 8k inscrições devolvetask_idem <300ms e completa em background com progresso visível. - Onda C — Sweep: F5 + F6 + adoção do SSOT (99).
Convenção dos arquivos filhos
Cada arquivo segue:
- Contexto (uma frase, ligação ao TL;DR)
- Evidência (path:linha, query SQL, contagem)
- Hipóteses + impacto (numeradas Pxx)
- O que NÃO é a causa (eliminadas)
- Próximas etapas (link reverso ao 00 + frentes)