fix(migrations): remove PII do migration ad-hoc + idempotente#7
Conversation
A migration original (commitada em 19/mai 11:22 pelo Lovable) continha um
DELETE com email hardcoded do PO + filtro de 30min — era query ad-hoc
para destravar rate limit de login, mas virou migration permanente.
Problemas:
1. PII (email do PO) exposto no historico publico do repositorio
2. Codigo de uso unico virou parte do schema (toda vez que rodar
supabase db reset, vai executar de novo, sem proposito)
Fix: substituir conteudo por cleanup generico (login_attempts falhados
com mais de 30 dias) — util de verdade, idempotente, sem PII.
Observacao: caso a migration original ja tenha sido aplicada no banco
em uso (pqp Lovable), o Supabase NAO re-aplica migrations com mesmo
timestamp/nome. Esta sanitização afeta apenas execucoes futuras
(supabase db reset, novos ambientes, F3 transferencia).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughMigração SQL que sanitiza tentativas de login falhadas: remove DELETE anterior com email hardcoded (PII), aplica critério de 30 dias e sucesso=falso, adiciona bloco PL/pgSQL para registrar contagem de deletados via NOTICE, tornando idempotente. ChangesSanitização de tentativas de login falhadas
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Pontos críticos: Verificar remoção efetiva da PII anterior, validar idempotência da migração (comportamento com re-execuções), confirmar critério temporal em Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 175761b4c1
ℹ️ 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".
| GET DIAGNOSTICS _deleted = ROW_COUNT; | ||
| RAISE NOTICE '[cleanup_login_attempts] Removed % stale failed login attempts (>30 days old)', _deleted; |
There was a problem hiding this comment.
Capture deleted row count in same PL/pgSQL block
GET DIAGNOSTICS ... ROW_COUNT inside this DO block does not read the row count from the previous top-level DELETE; in PostgreSQL it reflects the most recent SQL command executed within the current PL/pgSQL block. As written, _deleted will be reported as 0 (or otherwise not represent the preceding delete), so the migration’s notice is misleading and can hide whether cleanup actually removed rows.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR sanitizes a previously ad-hoc Supabase migration to remove hardcoded PII (an email address) from the repository history and replaces it with a generic, idempotent housekeeping cleanup for old failed login attempts.
Changes:
- Replaced an email-specific
DELETEwith a generic cleanup ofpublic.login_attempts(failed attempts older than 30 days). - Added explanatory header comments documenting why the migration was sanitized.
- Added a
RAISE NOTICEintended to report how many rows were removed.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| DELETE FROM public.login_attempts | ||
| WHERE success = false | ||
| AND created_at < now() - interval '30 days'; | ||
|
|
||
| DO $$ | ||
| DECLARE | ||
| _deleted integer; | ||
| BEGIN |
…8 StrictMode bug Bug #7: `let itemIndex = 0` era mutado dentro do .map() do JSX. Em React 18 StrictMode (desenvolvimento), React renderiza o componente duas vezes para detectar side-effects indesejados. Na segunda passagem, itemIndex já tinha o valor acumulado da primeira, dobrando os índices de linha: item 0 virava item 4, item 4 virava item 8, etc. Resultado: numeração errada das linhas na tabela do PDF em dev. Fix: startIndices[] pré-computado com Array.reduce() antes do JSX. Imutável — não sofre efeito de dupla renderização. Substitui: `const startIdx = itemIndex; itemIndex += pageItems.length;` Por: `const startIdx = startIndices[pageIdx];`
…Propostas PDF (#438) * fix(pdf-generator): root.unmount() movido para finally externo — sem memory leak em erro Bug: se html2canvas lançava exceção durante captura de qualquer página, root.unmount() nunca era chamado. ReactDOM.createRoot ficava pendurado, consumindo memória indefinidamente. Fix: - `let root` declarado fora do try block - `root?.unmount()` movido para o finally externo (sempre executa) - `document.body.removeChild(container)` mantido no mesmo finally - img.complete check aprimorado: naturalWidth > 0 evita tratar imagem com src vazio como 'carregada' * fix(PdfGenerationDialog): 5 bugs — memory leak, zombie async, state reset, dead code Bug #2: handleOpenChange não revogava blobUrlRef.current ao fechar. Cada ciclo abrir→gerar→fechar vazava um blob:// na memória do browser. Fix: revokeBlobUrl() extraído como helper, chamado no fechamento e antes de criar novo blob. Bug #4: ESC ou clique fora fechava o dialog durante generateProposalPDFv2. A operação assíncrona continuava em background (zumbi), podendo tentar atualizar state em componente já desmontado. Fix: onInteractOutside + onEscapeKeyDown previnem fechamento enquanto stage === 'generating'. Mensagem 'Aguarde, não feche esta janela' adicionada. Bug #5: progressLabel e pdfVersion não resetavam ao fechar o dialog. Na próxima abertura, progressLabel mostrava valor antigo; pdfVersion começava em v2/v3 em vez de v1. Fix: ambos resetados em handleOpenChange junto com demais states. Bug #8: clientPhone, approvalLink, onWhatsApp, onShareLink declarados na interface mas nunca usados. Marcados como @deprecated para backward-compat. Bug #9: ActionButton.variant 'whatsapp' tinha CSS idêntico a 'primary'. Tipo simplificado para 'default' | 'primary'. * fix(ProposalProductTable): imagens em branco no PDF + coluna Total ausente Bug #3a: loading="lazy" em imagens offscreen. O browser só carrega lazy quando o elemento entra no viewport. O template é renderizado a -10000px (fora do viewport), então nenhuma imagem carregava → PDF gerado com espaços em branco. Fix: loading="eager". Bug #3b: useState("") causa img.complete falso positivo. Com src="" inicial, img.complete retorna true imediatamente (sem nenhuma imagem ter sido carregada). O generator do PDF interpreta isso como "imagem carregada" e chama html2canvas com src vazio. Fix: useState(src) — imagem sempre tem src válido desde o início; processLogoTransparent atualiza depois com versão sem fundo. Bug #6: coluna "Total" ausente na tabela de produtos. Cliente recebia proposta sem totais por linha, precisando calcular manualmente. Fix: nova coluna Total = allInUnitPrice × quantity − itemDiscount. colSpan dos cabeçalhos de kit ajustado (3→4 / 4→5). * fix(PropostaComercialTailwind): mutable itemIndex in render → React 18 StrictMode bug Bug #7: `let itemIndex = 0` era mutado dentro do .map() do JSX. Em React 18 StrictMode (desenvolvimento), React renderiza o componente duas vezes para detectar side-effects indesejados. Na segunda passagem, itemIndex já tinha o valor acumulado da primeira, dobrando os índices de linha: item 0 virava item 4, item 4 virava item 8, etc. Resultado: numeração errada das linhas na tabela do PDF em dev. Fix: startIndices[] pré-computado com Array.reduce() antes do JSX. Imutável — não sofre efeito de dupla renderização. Substitui: `const startIdx = itemIndex; itemIndex += pageItems.length;` Por: `const startIdx = startIndices[pageIdx];`
O que
Remove PII (email do PO
adm01@promobrindes.com.br) do histórico público do repositório, substituindo a migration ad-hoc por um cleanup genérico idempotente.Diagnóstico
A migration
20260519112214_*.sqlfoi commitada em 19/mai 11:22 pelo Lovable. Era originalmente uma query ad-hoc para destravar tentativas de login bloqueadas pelo rate limit. Conteúdo problemático:Problemas:
supabase db resetrodaria de novo, sem propósitoSolução
Sanitizar o conteúdo da migration para um cleanup genérico útil e idempotente:
Vantagens:
Aplicação
pqp). Supabase rastreia migrations por nome+timestamp; mudar conteúdo do arquivo não dispara re-execução.A sanitização tem 2 efeitos:
supabase db reset, novos ambientes, Fase 3), a versão executada será a sanitizadaObservação sobre histórico git
PII ainda existe nos commits anteriores ao 19/mai 11:22 — limpar isso de verdade exigiria
git filter-branchouBFG, o que reescreve o histórico e quebra todos os clones. Não vale o custo aqui. Este PR para o sangramento futuro.Risco
Zero. Apenas substituição do conteúdo de uma migration (sem efeitos colaterais no banco em uso). O cleanup novo é seguro (login_attempts antigos não têm propósito).
Summary by cubic
Replaces the ad-hoc migration that leaked PII with a safe, generic cleanup that deletes stale failed login attempts (>30 days). This removes the exposed email from future repo history and keeps the migration idempotent.
Bug Fixes
Migration
Written for commit 175761b. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
Notas de Lançamento