Skip to content

Lovable sync 1777152806#31

Closed
adm01-debug wants to merge 14 commits into
mainfrom
lovable-sync-1777152806
Closed

Lovable sync 1777152806#31
adm01-debug wants to merge 14 commits into
mainfrom
lovable-sync-1777152806

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

📝 Descrição

🎯 Tipo de Mudança

  • 🐛 Bug fix (correção de bug)
  • ✨ Nova feature (funcionalidade nova)
  • 💥 Breaking change (mudança que quebra compatibilidade)
  • 📚 Documentação
  • 🎨 Estilo/UI
  • ♻️ Refatoração
  • ⚡ Performance
  • ✅ Testes
  • 🔧 DevOps/CI
  • 🔒 Segurança

📷 Screenshots (se aplicável)

🧪 Testes Realizados

  • Testei localmente
  • Testes unitários passam (npm run test)
  • Testes E2E passam (npm run test:e2e)
  • Testei no ambiente de staging
  • Testei em múltiplos navegadores
  • Testei em dispositivos móveis

✅ Checklist

  • Código segue o padrão do projeto
  • Self-review realizado
  • Comentei código complexo
  • Documentação atualizada (se necessário)
  • Sem console.log ou debug code
  • Sem secrets/credenciais hardcoded
  • Tipos TypeScript corretos
  • RLS policies consideradas (se DB)

🔗 Issues Relacionadas

⚠️ Notas para Reviewer

lovable-dev Bot and others added 14 commits April 25, 2026 21:29
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
X-Lovable-Edit-ID: edt-01c46b8e-ac19-4fb3-91ec-301840140d0c
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
X-Lovable-Edit-ID: edt-aa87ae41-6fe7-418d-85ab-46cad5ff2c67
Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 27, 2026 12:17
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Warning

Rate limit exceeded

@adm01-debug has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 42 minutes and 13 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a9808f9-efca-4c0d-a931-8efb96d52f0f

📥 Commits

Reviewing files that changed from the base of the PR and between 4c46c48 and 8191c2f.

📒 Files selected for processing (9)
  • src/components/connections/ConnectionsView.tsx
  • src/components/connections/QrTtlBadge.tsx
  • src/components/connections/RefreshQrButton.tsx
  • src/components/connections/__tests__/RefreshQrButton.test.tsx
  • src/hooks/connections/__tests__/qrAutoRefresh.test.ts
  • src/hooks/connections/__tests__/qrTtlFallback.test.ts
  • src/hooks/connections/qrAutoRefresh.ts
  • src/hooks/connections/qrTtlFallback.ts
  • src/hooks/useConnectionsManager.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lovable-sync-1777152806

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts the QR-code TTL handling for Evolution connections by adding a history-based TTL inference fallback and persisting TTL diagnostics into qr_attempts.metadata, while also simplifying/removing some QR-related UI/components and associated tests.

Changes:

  • Add inferTtlFromHistory (pure function) + unit tests to infer QR TTL from recent qr_attempts.metadata when the Evolution API doesn’t provide TTL.
  • Extend useConnectionsManager to (a) detect TTL with provenance/raw value, (b) optionally infer TTL via recent history, and (c) record TTL diagnostics into qr_attempts.metadata.
  • Remove qrAutoRefresh helper + tests, and remove RefreshQrButton / QrTtlBadge components (and tests), simplifying the refresh button in ConnectionsView.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/hooks/useConnectionsManager.ts Adds TTL detection struct, history inference query, and metadata recording; inlines auto-refresh decision logic.
src/hooks/connections/qrTtlFallback.ts New pure TTL inference helper for fallback based on historical samples.
src/hooks/connections/qrAutoRefresh.ts Removed previously testable auto-refresh decision helper.
src/hooks/connections/tests/qrTtlFallback.test.ts Adds unit tests for TTL inference helper.
src/hooks/connections/tests/qrAutoRefresh.test.ts Removes unit tests for auto-refresh decision logic.
src/components/connections/ConnectionsView.tsx Removes TTL badge + custom refresh button and replaces with a simpler outline button.
src/components/connections/RefreshQrButton.tsx Removed (previously provided cooldown/stabilization/diagnostics UX).
src/components/connections/tests/RefreshQrButton.test.tsx Removed tests for the deleted refresh button behavior.
src/components/connections/QrTtlBadge.tsx Removed TTL source/TTL display badge component.
Comments suppressed due to low confidence (1)

src/hooks/useConnectionsManager.ts:927

  • A lógica de decisão do auto-refresh foi inlinada no useEffect e os testes unitários anteriores para essa decisão foram removidos. Como esse agendamento é sensível a edge-cases de tempo (delay <= 0, dialog fechado, troca de attemptId), recomendo reintroduzir um helper puro (como era o evaluateAutoRefresh) e cobri-lo com testes, ou adicionar novos testes que validem o comportamento equivalente.
  // Auto-refresh: regenerate the QR ~5s before it expires (at 55s of the 60s TTL)
  // so the user never has to manually click "Atualizar" mid-scan.
  //
  // Strict guard: only schedules and only fires while the dialog is OPEN and the
  // current status is 'pending' (status local já reconciliado com a fonte de
  // verdade `qr_attempts.status` pelo effect acima). Se o status no banco virar
  // `connected`/`error`/`expired`, o effect de reconciliação atualiza
  // `qrCodeDialog.status`, fazendo este effect re-rodar e cancelar o timer
  // pendente via cleanup — assim o auto-refresh nunca dispara contra um QR já
  // aprovado ou falho no servidor.
  useEffect(() => {
    if (!qrCodeDialog.open) {
      log.debug('[qr-auto-refresh] not_scheduled', { reason: 'dialog_closed' });
      return;
    }
    if (qrCodeDialog.status !== 'pending') {
      log.debug('[qr-auto-refresh] not_scheduled', { reason: 'status_not_pending', status: qrCodeDialog.status });
      return;
    }
    if (!qrCodeDialog.expiresAt) {
      log.debug('[qr-auto-refresh] not_scheduled', { reason: 'no_expires_at' });
      return;
    }
    const delay = qrCodeDialog.expiresAt - 5_000 - Date.now();
    if (delay <= 0) {
      log.debug('[qr-auto-refresh] not_scheduled', { reason: 'already_past_window', delay });
      return;
    }

    log.info('[qr-auto-refresh] scheduled', { delayMs: delay, attemptId: qrCodeDialog.attemptId });
    const scheduledForAttempt = qrCodeDialog.attemptId;
    const generationAtSchedule = dialogGenRef.current;
    const timer = setTimeout(() => {
      // Defesa extra contra race condition: se o usuário fechou o diálogo
      // entre o agendamento e o disparo, dialogGenRef avançou — abortar.
      if (dialogGenRef.current !== generationAtSchedule) {
        log.info('[qr-auto-refresh] fire_aborted', { reason: 'dialog_closed_before_fire', attemptId: scheduledForAttempt });
        return;
      }
      // Re-check the latest dialog state at fire time — the props captured in
      // closure may be stale if the user already closed the dialog or another
      // refresh raced ahead. We use the functional setter to read the freshest
      // state without adding it to the dependency array.
      setQrCodeDialog((current) => {
        if (
          current.open &&
          current.status === 'pending' &&
          current.attemptId === scheduledForAttempt
        ) {
          log.info('[qr-auto-refresh] firing', { attemptId: scheduledForAttempt });
          void handleRefreshQrCode();
        } else {
          log.info('[qr-auto-refresh] fire_skipped', {
            reason: !current.open ? 'dialog_closed' : current.status !== 'pending' ? 'status_changed' : 'attempt_changed',
            currentStatus: current.status,
            currentAttemptId: current.attemptId,
            scheduledForAttempt,
          });
        }
        return current;
      });
    }, delay);
    return () => clearTimeout(timer);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [qrCodeDialog.open, qrCodeDialog.status, qrCodeDialog.expiresAt, qrCodeDialog.attemptId]);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +493 to +507
try {
const ttlEffectiveSeconds = Math.round(ttl.ttlMs / 1000);
await supabase
.from('qr_attempts')
.update({
metadata: {
ttl_detected_seconds: ttl.rawSeconds,
ttl_effective_seconds: ttlEffectiveSeconds,
ttl_source: ttl.source,
expires_at: new Date(expiresAtMs).toISOString(),
recorded_at: new Date().toISOString(),
},
})
.eq('id', attemptId);
log.info('[qr-attempt] ttl_recorded', {
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

O supabase.from('qr_attempts').update(...).eq(...) não lança exceção quando falha; ele retorna { error }. Hoje recordQrAttemptTtl só tem try/catch e não checa error, então falhas de RLS/rede podem passar silenciosamente. Capture o retorno e faça early-return/log quando error vier preenchido (idealmente também logar quando data vier vazio).

Copilot uses AI. Check for mistakes.
Comment on lines 28 to 32
import { ConnectionCard } from './ConnectionCard';
import { DegradedQuickActions } from './DegradedQuickActions';
import { QrCountdown } from './QrCountdown';
import { QrTtlBadge } from './QrTtlBadge';
import { QrAttemptHistory } from './QrAttemptHistory';
import { RefreshQrButton } from './RefreshQrButton';
import { IdempotencyMissBanner } from './IdempotencyMissBanner';
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

Este PR removeu componentes/UX (ex.: QrTtlBadge, RefreshQrButton) e também testes associados, mas a descrição do PR está vazia e não menciona essas remoções. Para facilitar revisão e evitar regressões não intencionais, documente explicitamente no PR o motivo/impacto dessas remoções e quais comportamentos esperados mudaram (ex.: cooldown/diagnóstico do refresh).

Copilot uses AI. Check for mistakes.
Comment on lines +478 to +505
/**
* Persiste no `qr_attempts.metadata` o TTL detectado e o efetivo (em segundos)
* usados para calcular o `expiresAt`. Usado pelo time comercial para
* correlacionar falhas de pareamento com o tempo de rotação real entregue
* pela Evolution API.
*
* Faz merge não-destrutivo via spread no payload — qualquer outro campo de
* metadata adicionado no futuro continua intacto.
*/
const recordQrAttemptTtl = async (
attemptId: string | null,
ttl: DetectedQrTtl,
expiresAtMs: number,
) => {
if (!attemptId) return;
try {
const ttlEffectiveSeconds = Math.round(ttl.ttlMs / 1000);
await supabase
.from('qr_attempts')
.update({
metadata: {
ttl_detected_seconds: ttl.rawSeconds,
ttl_effective_seconds: ttlEffectiveSeconds,
ttl_source: ttl.source,
expires_at: new Date(expiresAtMs).toISOString(),
recorded_at: new Date().toISOString(),
},
})
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

recordQrAttemptTtl afirma fazer “merge não-destrutivo” na metadata, mas o .update({ metadata: { ... } }) substitui o JSON inteiro (jsonb) e pode apagar campos já existentes em qr_attempts.metadata. Ajuste a implementação para realmente mesclar (ex.: ler metadata atual e fazer spread, ou usar um merge no lado do Postgres via jsonb_set/||), ou então corrija o comentário para refletir que é overwrite completo.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8191c2f96b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +130 to +132
.from('qr_attempts')
.select('metadata')
.eq('instance_id', instanceId)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Run TTL inference where qr_attempts SELECT is allowed

This history lookup is executed in the client, but the qr_attempts SELECT policy only allows admins/supervisors (see supabase/migrations/20260423111614_2c3337b5-0191-432c-ab25-0fd708ff1d34.sql, lines 25-28). For authenticated users outside those roles, this call will always hit the error branch and fall back to the fixed default TTL, so the new inference path never actually works in that context. Consider moving the read to a privileged RPC/Edge Function or granting scoped read access for a user's own attempts.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

🛑 Cannot be folded into the umbrella merge PR #32

This branch has no common ancestor with current main. It is 1,886 commits ahead with a diff of 257 files / +1,805 / −29,197 lines from main — almost certainly an obsolete Lovable snapshot from before a rebase.

The newer Lovable sync #30 (lovable-sync-1777290333) was successfully folded into #32. This older snapshot is likely superseded.

Recommendation:

  • Close this PR if Lovable sync 1777290333 #30 already covers what this introduced, or
  • Cherry-pick any individual commits worth keeping onto current main.

Generated by Claude Code

@adm01-debug adm01-debug deleted the lovable-sync-1777152806 branch May 9, 2026 01:41
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.

2 participants