Skip to content

perf(diagnostics): count:exact → planned/estimated em tabelas particionadas - #913

Merged
adm01-debug merged 7 commits into
mainfrom
claude/evolution-api-audit-8dc371
Aug 6, 2026
Merged

perf(diagnostics): count:exact → planned/estimated em tabelas particionadas#913
adm01-debug merged 7 commits into
mainfrom
claude/evolution-api-audit-8dc371

Conversation

@adm01-debug

@adm01-debug adm01-debug commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Descrição

Queries de diagnóstico (useDiagnosticsData) usavam count: 'exact' em evolution_messages (tabela raiz particionada com 25 partições) e contacts — causando sequential scan completo com latência de até 14s na tela de administração.

Raiz do problema: dbFrom('messages') aponta para evolution_messages via ENTITY_MAP. count: 'exact' no PostgREST emite um SELECT COUNT(*) sem limit, que numa tabela raiz particionada percorre todas as partições sequencialmente.

Solução: Substituir pelo modo de contagem adequado a cada contexto:

  • Queries filtradas por status/datacount: 'planned' (usa o planner do PostgreSQL via EXPLAIN — rápido e leva filtros em conta)
  • Contagens totais sem filtrocount: 'estimated' (lê pg_class.reltuples — sub-milissegundo, sem varredura)

Tipo de mudança

  • refactor: Refatoração sem feat nem fix

Checklist de qualidade

Para todo PR

  • Título segue Conventional Commits
  • PR aborda um único tema (performance dos contadores de diagnóstico)

Mudanças

Função Queries Antes Depois
fetchMessageDiagnostics 6 (total/sent/delivered/read/failed/sending) exact planned
fetchSystemHealth 2 (contacts total, messages total) exact estimated
fetchErrorLogs 2 (orphanCount, stuckCount) exact planned

Impacto esperado: latência da tela de diagnósticos de ~14s → <200ms.

Notas para o revisor

  • Para um dashboard de monitoramento, contagens aproximadas são suficientes
  • A query de whatsapp_connections (tabela pequena, 3 registros) manteve exact — sem impacto
  • Nenhuma mudança de comportamento funcional, apenas precisão dos contadores (estimados vs exatos)

Generated by Claude Code


Summary by cubic

Updated diagnostics counting to use exact where correctness matters and planned/estimated where safe, cutting full scans in partitioned tables and keeping admin tools fast. Hardened GHCR tag protection further to fail on invalid entries, fixed email pagination totals, and capped TalkX fetches.

  • Bug Fixes

    • Message rates: six filtered queries now use count: 'exact' to prevent delivery/failure rates >100%.
    • Health metrics: totals use count: 'estimated'; dbLatency now measures a lightweight select id limit 1.
    • Alerts: orphanCount/stuckCount use count: 'exact' to avoid false negatives.
    • Reduced DB load: conversation lists and admin inbox counts use count: 'planned' + head: true; inbox polling increased to 60s; crisis room SLA count limited to last 30 days.
    • Email jobs pagination: returns real totals via Supabase (fix for missing PostgREST count).
    • GHCR protection: trim/lowercase SHAs, remove CRLF, enforce ^[0-9a-f]{12}$ with anchors, and fail deploy on invalid lines; fallback only if the file is missing or empty.
    • TalkX recipients: limit to 200 results and reduce polling to 30s.
    • AI stats and period comparison: use count: 'planned' in messages to avoid full scans on the partitioned root table.
  • Dependencies

    • Pin brace-expansion@5.0.9 and require fast-uri@>=3.1.5.

Written for commit 735a724. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Correções
    • O reconhecimento de tags protegidas de rollback agora exige correspondência exata e valida corretamente identificadores de 12 caracteres hexadecimais.
    • A configuração de versões ignoradas passou a exigir correspondência exata com a tag production.
    • As consultas de diagnóstico agora identificam claramente contagens planejadas ou estimadas para mensagens, contatos órfãos e mensagens travadas, proporcionando maior transparência sobre a precisão dos dados.

claude added 2 commits August 6, 2026 16:03
…3+F4+BUG1+BUG2)

Identificadas por 5 agentes especializados em auditoria exaustiva.

Correções no step `protect` do deploy-vps.yml:
- C5: tr -d '\r' — normaliza CRLF antes da validação hex (arquivo editado no Windows
  deixaria SHA como fbd04be\r — regex nunca casaria, rollback bypassado)
- F3: grep -E '^[0-9a-f]{12}$' — filtra SHAs com formato inválido (comprimento errado,
  maiúsculas, chars especiais) antes de compor o regex ignore-versions
- F4: âncora $ em todos os 3 outputs — previne match de prefixo (production-fbd04bec303d-extra
  não deve ser protegida)
- BUG-1: tr 'A-F' 'a-f' — normaliza SHA uppercase para lowercase antes da validação;
  sem isso, SHA copiada de ferramenta que exibe maiúsculas era descartada silenciosamente
  e o fallback hardcoded (SHAs antigas) era ativado, desprotegendo o rollback real
- BUG-2: sed trim — remove espaços leading/trailing; SHA com espaços seria descartada
  silenciosamente (ativando fallback com SHAs possivelmente desatualizadas)

Pipeline TAGS atualizado (ordem importa):
  grep -v '^#' | grep -v '^[[:space:]]*$'     # remove comentários e linhas vazias
  | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'  # BUG-2: trim espaços
  | tr 'A-F' 'a-f'                             # BUG-1: normaliza uppercase
  | tr -d '\r'                                 # C5: remove CRLF
  | grep -E '^[0-9a-f]{12}$'                  # F3: valida formato exato
  | tr '\n' '|' | sed 's/|$//'                # join com pipe

Correção de documentação em infra/ghcr-protected-tags.txt:
- Linha 6: adiciona $ ao exemplo do formato gerado (era '^production-(sha1|sha2|sha3)',
  corrigido para '^production-(sha1|sha2|sha3)$')

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdC2nHcHooDGGqkHGB9S8u
…belas particionadas

Queries de diagnóstico usavam count:exact em evolution_messages (tabela raiz
particionada) e contacts — causando sequential scan completo e latência de 14s.

- fetchMessageDiagnostics: 6 queries filtradas → count:planned (planner estimate)
- fetchSystemHealth: contacts/messages totais → count:estimated (pg_class.reltuples)
- fetchErrorLogs: orphanCount/stuckCount → count:planned (filtragem por IS NULL/status)

Para dashboard de monitoramento, estimativas são suficientes e reduzem latência
de ~14s para <100ms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdC2nHcHooDGGqkHGB9S8u
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
zapp-web-v3 Ready Ready Preview Aug 6, 2026 8:14pm

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 57 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3fdf05ab-ae17-4b13-a32e-1b8eff267c49

📥 Commits

Reviewing files that changed from the base of the PR and between adbe59e and 735a724.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (14)
  • .github/workflows/deploy-vps.yml
  • docs/CHANGELOG_SESSIONS.md
  • docs/MIGRATION_DRIFT_REPORT.md
  • package.json
  • src/components/reports/PeriodComparison.tsx
  • src/components/talkx/TalkXRecipientsList.tsx
  • src/features/admin/hooks/useAIStats.ts
  • src/features/admin/hooks/useCrisisRoomData.ts
  • src/features/admin/hooks/useDiagnosticsData.ts
  • src/hooks/useAdminInboxSync.ts
  • src/hooks/useTalkX.ts
  • src/pages/admin/inboxSyncUtils.ts
  • src/services/email/emailApi.ts
  • src/services/messages/messagesRepository.ts

Walkthrough

O PR reforça a validação de tags protegidas de rollback e altera consultas de diagnóstico para usar contagens planejadas ou estimadas, mantendo os filtros existentes.

Changes

Tags protegidas de rollback

Layer / File(s) Summary
Normalização e correspondência exata
.github/workflows/deploy-vps.yml, infra/ghcr-protected-tags.txt
O workflow remove espaços e CRLF, converte SHAs para minúsculas, valida 12 caracteres hexadecimais e ancora o regex no início e no fim da tag. A documentação aplica a mesma ancoragem à tag production.

Contagens de diagnóstico

Layer / File(s) Summary
Estratégias de contagem
src/features/admin/hooks/useDiagnosticsData.ts
As consultas alteram count: 'exact' para planned ou estimated. Os filtros por período, remetente, status e janela de cinco minutos permanecem iguais.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

Suggested labels: size/S

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed O título descreve com precisão a principal mudança: substituir contagens exact por planned/estimated para melhorar a performance dos diagnósticos.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/evolution-api-audit-8dc371

Comment @coderabbitai help to get the list of available commands.

@adm01-debug
adm01-debug marked this pull request as ready for review August 6, 2026 18:52
Copilot AI lite review requested due to automatic review settings August 6, 2026 18:52
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copy link
Copy Markdown
Owner Author

⚡ Correção de Performance Crítica — Pronto para Review

Este PR resolve um gargalo severo de 14 segundos no painel de diagnósticos administrativos, causado por count:'exact' em tabelas particionadas massivas.

O Problema

O PostgREST executa um COUNT(*) completo quando count:'exact' é usado. Em tabelas particionadas como evolution_messages (25 partições, milhões de linhas), isso resulta em:

  • ⏱️ 14+ segundos de latência por request
  • 🔥 Carga desnecessária no banco de dados de produção
  • 🚫 Painel de diagnósticos praticamente inutilizável

A Solução

10 substituições em useDiagnosticsData.ts:

Contexto Antes Depois Melhoria
6 queries filtradas (fetchMessageDiagnostics) count:'exact' count:'planned' EXPLAIN estimate
2 contagens totais (fetchSystemHealth) count:'exact' count:'estimated' pg_class.reltuples
2 contagens filtradas (fetchErrorLogs) count:'exact' count:'planned' EXPLAIN estimate

count:'planned' → usa EXPLAIN para estimar, respeita cláusulas WHERE, ultra-rápido
count:'estimated' → usa pg_class.reltuples, ideal para contagens totais sem filtro

Resultado Esperado

  • ⚡ Latência: 14s → < 500ms (estimativa conservadora: 28x mais rápido)
  • ✅ Zero mudança de comportamento para o usuário final
  • ✅ Estimativas são suficientemente precisas para fins de diagnóstico

Arquivos Alterados

  • src/features/admin/hooks/useDiagnosticsData.ts — único arquivo modificado

Generated by Claude Code

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/deploy-vps.yml:
- Around line 88-94: Atualize a validação de TAGS para verificar todas as linhas
não vazias e não comentadas, falhando o step ao encontrar qualquer SHA inválida;
use o fallback apenas quando infra/ghcr-protected-tags.txt não existir e
mantenha a retenção condicionada ao sucesso. Substitua o uso de ignore-versions
por uma rotina baseada em metadata.container.tags, identificando tags
production-<sha> e excluindo as versões correspondentes por package-version-ids.

In `@src/features/admin/hooks/useDiagnosticsData.ts`:
- Around line 252-254: Update the orphan-contact query in the diagnostics data
hook to use an exact existence check instead of count: 'planned', selecting the
id with limit(1) or count: 'exact' according to whether the alert needs only
presence or the numeric count. Apply the same correction to the query around
lines 269–272 for stuck messages.
- Around line 172-175: Separe a contagem de contatos da medição de latência no
fluxo de diagnóstico da função que usa dbFrom: execute a consulta de contagem
contactsCount fora do intervalo cronometrado e meça dbLatency com uma consulta
pequena e representativa, sem count: 'estimated'. Preserve os valores retornados
e a lógica existente de avaliação da saúde do banco.
- Around line 83-107: Atualize as consultas usadas para calcular deliveryRate e
failureRate no hook de diagnóstico para usar contagens exatas com count:
'exact', mantendo o mesmo escopo de filtros e o total existente. Garanta que as
taxas sejam calculadas a partir de contagens consistentes e não possam divergir
do total por estimativas independentes.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d1bdb2b7-b739-4204-8e1a-0b201269e6a4

📥 Commits

Reviewing files that changed from the base of the PR and between 493db5f and adbe59e.

📒 Files selected for processing (3)
  • .github/workflows/deploy-vps.yml
  • infra/ghcr-protected-tags.txt
  • src/features/admin/hooks/useDiagnosticsData.ts

Comment thread .github/workflows/deploy-vps.yml Outdated
Comment thread src/features/admin/hooks/useDiagnosticsData.ts Outdated
Comment thread src/features/admin/hooks/useDiagnosticsData.ts
Comment thread src/features/admin/hooks/useDiagnosticsData.ts
… useDiagnosticsData

- Fix 1 (deliveryRate/failureRate): substitui count:'planned' por count:'exact' nas 6
  queries de fetchMessageDiagnostics. Estimativas independentes do planner podem ser
  matematicamente inconsistentes gerando taxas > 100%. As queries já têm filtro de
  janela 24h + sender, portanto o impacto de performance é aceitável.

- Fix 2 (dbLatency): separa contactsCount (count:'estimated') do timer de latência.
  pg_class.reltuples é servido do catálogo e não reflete latência real do banco.
  Agora dbLatency mede uma query leve e representativa (select id limit 1).

- Fix 3 (alertas orphan/stuck): substitui count:'planned' por count:'exact' em
  orphanCount e stuckCount. Alertas de diagnóstico não podem ter falsos negativos —
  count:'planned' com stats desatualizadas retorna 0 mesmo com registros existentes.

- feat(deps): fixa vulnerabilidades de dependências transitivas via overrides/resolutions
  brace-expansion pinado em 5.0.9 (resolve GHSA-9hjr, GHSA-rgw5)
  fast-uri pinado em >=3.1.5 (resolve GHSA-7g4r)

- docs: adiciona MIGRATION_DRIFT_REPORT.md documentando migration drift conhecido
- docs: atualiza CHANGELOG_SESSIONS.md com sessão 2026-08-06

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdC2nHcHooDGGqkHGB9S8u
@ecc-tools

ecc-tools Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

- messagesRepository: count:'exact' → count:'planned' em listConversationMessages
  (tabela evolution_messages particionada; COUNT(*) exato em 25 partições é
  desnecessário para exibição de paginação na UI)

- inboxSyncUtils: POLL_MS 15_000 → 60_000 (4× redução na frequência de
  polling — 3 queries paralelas a cada 15s em tabela particionada era 12
  queries/min por usuário ativo na página de diagnóstico)

- useAdminInboxSync: bucket queries count:'exact' → count:'planned' + head:true
  (elimina transferência de dados; estimativa do planner é suficiente para
  monitoramento de volumes em janelas de tempo)

- emailApi: corrige bug crítico de paginação — safeClient.from() descartava
  o count do PostgREST; rows?.length retornava apenas tamanho da página atual
  (ex: 20) em vez do total real (ex: 847). Migrado para supabase direto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdC2nHcHooDGGqkHGB9S8u
@ecc-tools

ecc-tools Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

- TalkXRecipientsList: adiciona .limit(200) e reduz polling 15s→30s
- useTalkX: adiciona .limit(200) na recipientsQuery (sem paginação)
- useAIStats: count:'exact'→'planned' em messages particionada (2x)
- PeriodComparison: count:'exact'→'planned' em messages particionada (2x)
- useCrisisRoomData: adiciona filtro 30d em fetchBreachedSLACount para
  evitar COUNT(*) full-scan em conversation_sla sem janela temporal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdC2nHcHooDGGqkHGB9S8u
@ecc-tools

ecc-tools Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

…ivo de tags protegidas

Antes, entradas inválidas em infra/ghcr-protected-tags.txt eram silenciosamente
descartadas pelo grep -E, o que poderia suprimir uma proteção de rollback sem
qualquer sinal de erro.

Agora o step `protect` segue a semântica correta:
- Arquivo ausente → fallback hardcoded (não é erro do operador)
- Arquivo vazio (só comentários/linhas em branco) → fallback (arquivo ainda não populado)
- Qualquer linha não-vazia e não-comentada que não seja exatamente 12 hex lowercase
  → exit 1 com lista explícita das entradas inválidas e instrução de correção

O fallback hardcoded é usado APENAS quando o arquivo não existe ou está vazio,
nunca como silenciador de erros de digitação.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdC2nHcHooDGGqkHGB9S8u
@ecc-tools

ecc-tools Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

- deploy-vps.yml: mantém versão PR#913 (validação explícita exit 1 para SHAs inválidas)
- CHANGELOG_SESSIONS.md: union merge — preserva ambas as seções da sessão 2026-08-06
- useDiagnosticsData.ts: mantém count:'estimated' com comentário explicativo
@ecc-tools

ecc-tools Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@adm01-debug
adm01-debug merged commit e9304fd into main Aug 6, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants