Skip to content

chore(eslint): fix 20 residual errors (Onda 5 PR 5.2.1)#111

Merged
adm01-debug merged 2 commits into
mainfrom
chore/onda-5-pr-5.2.1-eslint-residual-errors
May 9, 2026
Merged

chore(eslint): fix 20 residual errors (Onda 5 PR 5.2.1)#111
adm01-debug merged 2 commits into
mainfrom
chore/onda-5-pr-5.2.1-eslint-residual-errors

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 9, 2026

Resumo

Reduz ESLint errors de 128 → 108 (-20, -16%) limpando todos os errors não-import.
Os 108 restantes são todos no-restricted-imports que vão pro PR 5.3 (DDD refactor).

Diff stat

16 files changed, 35 insertions(+), 24 deletions(-)

Batches aplicados

Batch A — Mecânico (18 fixes)

Sub Regra Count Fix
A.1 no-unused-expressions (ternário-as-statement) 10 cond ? a() : b()if (cond) a(); else b();
A.2 no-empty-object-type 2 interface X extends Y {}type X = Y
A.3 no-useless-catch 1 Removido catch { throw err } mantendo finally
A.4 no-this-alias 1 const self = this removido (arrow functions herdam this)
A.5 no-require-imports 1 require('tailwindcss-animate')import no topo
A.6 no-unsafe-function-type 2 Function type → (type, listener) => void
A.7 react/no-danger 'rule not found' 1 Removido disable de regra inexistente (plugin não instalado)

Batch B — Lógica (2 fixes)

Sub Regra Count Fix
B.1 no-unsafe-optional-chaining 2 getClient()?.rpc() → guard com if (!client) return

Validação

  • bun run lint → 1438 problems (108 errors, 1330 warnings)
  • bun run build → ✓ built in 59.58s (zero regressões)

Por que A.7?

eslint-plugin-react não está instalado neste projeto (só react-hooks e react-refresh). O // eslint-disable-next-line react/no-danger referenciava uma regra que nunca esteve ativa. ESLint 9 ficou mais rigoroso e flaga isso. O dangerouslySetInnerHTML é seguro (input passa por DOMPurify), agora documentado em comentário regular.

Próximo (PR 5.3)

Os 108 no-restricted-imports restantes serão resolvidos no PR 5.3 — DDD refactor:

  • 106 INTRA-feature (codemod scripted)
  • 2 CROSS-feature (criar barrel)
  • Distribuição: 92 inbox, 8 auth, 3 connections, 3 admin, 2 sla

Governança

Considerado GRANDE (16 files), seguindo padrão Onda 1+2.
Stress-test de 8 cenários documentado no commit message.

🤖 Generated with Claude

Summary by CodeRabbit

Notas de Lançamento

  • Refactor

    • Simplificação de lógica condicional em vários componentes para melhor legibilidade, sem alterar comportamentos.
    • Atualização de declarações de tipo para alinhamento com padrões modernos.
    • Substituição de supressões ESLint por comentários de segurança e conversão de import de plugin para ES module.
  • Chores

    • Ajustes em seleção em massa, envio e contagem de resultados, resolução de cliente externo e tipagem para maior robustez.

Review Change Stack

Reduces ESLint errors from 128 → 108 (-20, -16%) by addressing all
non-import errors. Remaining 108 errors are all no-restricted-imports
which will be tackled in PR 5.3 (DDD refactor).

## Batch A — Mechanical (18 fixes)

### A.1 — no-unused-expressions (10 fixes, all ternary-as-statement)
Pattern: `cond ? a() : b();` → `if (cond) a(); else b();`

Files (all with same fix pattern):
- ContactBulkTagDialog.tsx, ContactGroupedList.tsx
- ProgressiveDisclosureDashboard.tsx
- useMediaLibrary.ts (3 occurrences)
- TranscriptionsHistoryView.tsx
- AudioRecorder.tsx, useFileUploadLogic.ts, useSipClient.ts

Semantically identical: ESLint flags ternary-as-statement because
the result is discarded; if/else is the idiomatic alternative.

### A.2 — no-empty-object-type (2 fixes)
- src/components/ui/command.tsx:24 — `interface CommandDialogProps extends DialogProps {}` → `type CommandDialogProps = DialogProps`
- src/components/ui/textarea.tsx:5 — same pattern

Both are internal types with no augmentation use case, so type alias
is equivalent and cleaner.

### A.3 — no-useless-catch (1 fix)
- src/features/inbox/hooks/useRealtimeInbox.ts:422
  Removed `try { ... } catch (err) { throw err } finally { ... }` →
  `try { ... } finally { ... }`. Catch-then-rethrow is a no-op.

### A.4 — no-this-alias (1 fix)
- src/lib/logger.ts:84 — `const self = this` removed.
  Arrow functions in the returned object literal already capture
  `this` from the parent method scope.

### A.5 — no-require-imports (1 fix)
- tailwind.config.ts:320 — `require('tailwindcss-animate')` →
  `import tailwindcssAnimate from 'tailwindcss-animate'` at top.
  Tailwind config is ESM, so this is the correct form.

### A.6 — no-unsafe-function-type (2 fixes, same line)
- src/hooks/usePerformanceOptimizations.ts:211 —
  `addEventListener?: Function; removeEventListener?: Function` →
  `addEventListener?: (type: string, listener: () => void) => void; removeEventListener?: (type: string, listener: () => void) => void`

The Network Information API uses standard EventTarget contract.

### A.7 — react/no-danger 'rule not found' (1 fix)
- src/components/contacts/SafeHtml.tsx:50 — removed
  `// eslint-disable-next-line react/no-danger` because
  eslint-plugin-react is NOT installed in the project (only
  react-hooks and react-refresh). The disable was referencing
  a rule that never existed in the config — ESLint 9 flags this.

  Replaced with a code comment documenting that
  dangerouslySetInnerHTML is safe here (input passed through
  DOMPurify.sanitize() above).

## Batch B — Logic (2 fixes)

### B.1 — no-unsafe-optional-chaining (2 fixes in useAutomations.ts)
- :80 — `await getClient()?.rpc(...)` could destructure undefined
  if getClient() returns null. Refactored:
  `const client = getClient(); if (!client) return; const { data } = await client.rpc(...)`
- :103 — same pattern, same refactor

## Validation

- bun run lint → 1438 problems (108 errors, 1330 warnings)
  - Errors went from 128 → 108 (-20)
  - All remaining errors are no-restricted-imports (PR 5.3 territory)
- bun run build → ✓ built in 59.58s (no regressions)

## Stress-test results
- Ternary → if/else: semantically identical (✓)
- Empty interface → type alias: both internal, no augmentation (✓)
- try/catch/finally → try/finally: re-throw is no-op (✓)
- const self = this → this in arrow: arrows inherit lexical this (✓)
- require → import: Tailwind ESM-compatible (✓)
- Function → specific signature: matches Network Info API (✓)
- react/no-danger removal: plugin not installed, no behavior change (✓)
- getClient() guard: prevents .rpc() on null (✓)
Copilot AI review requested due to automatic review settings May 9, 2026 11:42
@vercel
Copy link
Copy Markdown

vercel Bot commented May 9, 2026

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

Project Deployment Actions Updated (UTC)
zapp-web Ready Ready Preview, Comment May 9, 2026 11:50am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

Walkthrough

PR aplica refatorações locais: ternary → if/else em toggles/handlers, converte interfaces vazias para type aliases, valida cliente Supabase com getClient(), refina listeners, remove captura self no Logger e migra plugin Tailwind para import ES.

Changes

Definições de Tipo e Refinamento

Layer / File(s) Summary
Type Aliases
src/components/ui/command.tsx, src/components/ui/textarea.tsx
CommandDialogProps e TextareaProps convertidas de interfaces vazias para type aliases equivalentes (type = ...).
Type Narrowing & Guards
src/hooks/usePerformanceOptimizations.ts
navigator.connection listeners tipados como (type: string, listener: () => void); guards adicionados para addEventListener/removeEventListener antes de registrar/remover ovinte.

Padronização de Controle de Fluxo

Layer / File(s) Summary
Toggle de Seleção
src/components/contacts/ContactBulkTagDialog.tsx, src/components/contacts/ContactGroupedList.tsx, src/components/dashboard/ProgressiveDisclosureDashboard.tsx, src/components/transcriptions/TranscriptionsHistoryView.tsx
Ternary expressions refatoradas para if/else explícito em operações add/remove de Sets (toggleTag, toggleGroup, toggleSection, toggleContact).
Seleção em Massa
src/components/settings/media-library/useMediaLibrary.ts
toggleSelect usa functional updater; toggleSelectAll usa branches explícitas para setSelected(empty Set) ou Set(filteredIds); toast de reclassificação decide entre info (com erro count) ou success via if/else.
Handlers de Entrada
src/features/inbox/components/AudioRecorder.tsx, src/features/inbox/components/useFileUploadLogic.ts
Keydown pause/resume e contagem success/error refatoradas para if/else; fila, delays e iteração permanecem inalterados.

Resolução de Cliente e Error Handling

Layer / File(s) Summary
Client Resolution
src/hooks/useAutomations.ts
getClient() chamado e atribuído a client; função retorna cedo quando cliente ausente; RPCs subsequentes usam client validado (sem optional chaining).
Simplificação de Erro
src/features/inbox/hooks/useRealtimeInbox.ts
Removed catch/rethrow redundante; finally ainda executa refreshActiveConversation().
Reformatação
src/features/inbox/hooks/useSipClient.ts
hangUp reformatado para blocos claros chamando bye() quando estabelecido e cancel() caso contrário; comportamento preservado.

Configuração e Utilities

Layer / File(s) Summary
Logger Refactor
src/lib/logger.ts
Logger.withCorrelation() constrói funções que chamam this.debug/info/warn/error diretamente em vez de usar self capturado.
Module Config
tailwind.config.ts
tailwindcss-animate migrado de require() para import tailwindcssAnimate from "tailwindcss-animate" e plugin referenciado como tailwindcssAnimate.
Safety Note
src/components/contacts/SafeHtml.tsx
Comentário ESLint suppression substituído por nota que HTML foi sanitizado por DOMPurify; dangerouslySetInnerHTML permanece igual.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed O título descreve com precisão a natureza e o objetivo da PR: correção de 20 erros ESLint residuais em vários componentes através de refatorações mecânicas e lógicas.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 chore/onda-5-pr-5.2.1-eslint-residual-errors

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hooks/usePerformanceOptimizations.ts (1)

211-235: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Proteja registro de listener em navigator.connection e considere fallback

connection é checado, mas addEventListener/removeEventListener são opcionais na tipagem (linha 211) e são chamados sem guarda (linhas 229 e 234). O NetworkInformation API não é suportado em Firefox nem Safari — se a API não expõe esses métodos ou não existe naquela plataforma, o effect quebra e deixa listeners de window sem cleanup.

Patch sugerido
     if (connection) {
       setConnectionType(connection.effectiveType);
       setIsSlowConnection(
         connection.saveData || 
         connection.effectiveType === 'slow-2g' || 
         connection.effectiveType === '2g'
       );

       const handleChange = () => {
         setConnectionType(connection.effectiveType);
         setIsSlowConnection(
           connection.saveData || 
           connection.effectiveType === 'slow-2g' || 
           connection.effectiveType === '2g'
         );
       };

-      connection.addEventListener('change', handleChange);
+      if (connection.addEventListener && connection.removeEventListener) {
+        connection.addEventListener('change', handleChange);
+      } else if ('onchange' in connection) {
+        connection.onchange = handleChange;
+      }
       
       return () => {
         window.removeEventListener('online', handleOnline);
         window.removeEventListener('offline', handleOffline);
-        connection.removeEventListener('change', handleChange);
+        if (connection.removeEventListener) {
+          connection.removeEventListener('change', handleChange);
+        } else if ('onchange' in connection) {
+          connection.onchange = null;
+        }
       };
     }
🤖 Prompt for 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.

In `@src/hooks/usePerformanceOptimizations.ts` around lines 211 - 235, The effect
currently calls connection.addEventListener/removeEventListener without guarding
that those methods exist; update the connection branch to check that
connection.addEventListener and connection.removeEventListener are functions
before calling them (e.g., only add the handleChange listener when typeof
connection.addEventListener === 'function'), and likewise only call
connection.removeEventListener in the cleanup when typeof
connection.removeEventListener === 'function'; keep using the same handleChange,
setConnectionType and setIsSlowConnection logic and still clean up window
listeners (handleOnline/handleOffline) regardless.
🧹 Nitpick comments (1)
src/features/inbox/hooks/useSipClient.ts (1)

110-113: ⚡ Quick win

Restrinja cancel() apenas para estados válidos no sip.js

O else chama cancel() para qualquer estado diferente de Established, inclusive Terminated — estado terminal onde não faz sentido tentar cancelar de novo. Isso gera exceções esperadas e polui o log. Restrinja a cancel() apenas nos estados onde é válido (Initial e Establishing).

Patch sugerido
       try {
-        if (sessionRef.current.state === SessionState.Established) sessionRef.current.bye();
-        else sessionRef.current.cancel();
+        const state = sessionRef.current.state;
+        if (state === SessionState.Established) {
+          sessionRef.current.bye();
+        } else if (state === SessionState.Initial || state === SessionState.Establishing) {
+          sessionRef.current.cancel();
+        }
       } catch (err) { log.error('Hangup error:', err); }
🤖 Prompt for 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.

In `@src/features/inbox/hooks/useSipClient.ts` around lines 110 - 113, The hangup
logic calls sessionRef.current.cancel() for any non-Established state (including
Terminal), causing noisy exceptions; change the conditional so you call
sessionRef.current.bye() when sessionRef.current.state ===
SessionState.Established, and only call sessionRef.current.cancel() when
sessionRef.current.state is one of the valid cancelable states (e.g.,
SessionState.Initial or SessionState.Establishing); keep the try/catch around
the calls and continue logging errors via log.error('Hangup error:', err) but
avoid invoking cancel() for Terminated/Terminal states.
🤖 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 `@src/hooks/useAutomations.ts`:
- Around line 105-107: A chamada redundante a getClient() criando client2 e o
return podem abortar evaluate() prematuramente; substitua o uso de client2 por
reutilizar o cliente já validado (client) disponível na função evaluate(),
remova o return que interrompe a execução e, ao chamar
client.rpc("rpc_get_contact", ...), trate o caso de contact ausente de forma
não-bloqueante para que gatilhos sem tags ainda sejam avaliados; localize o
código onde client2 é definido/substituir e atualizar a chamada RPC para usar
client e checar/ignorar contact nulo em vez de abortar.

---

Outside diff comments:
In `@src/hooks/usePerformanceOptimizations.ts`:
- Around line 211-235: The effect currently calls
connection.addEventListener/removeEventListener without guarding that those
methods exist; update the connection branch to check that
connection.addEventListener and connection.removeEventListener are functions
before calling them (e.g., only add the handleChange listener when typeof
connection.addEventListener === 'function'), and likewise only call
connection.removeEventListener in the cleanup when typeof
connection.removeEventListener === 'function'; keep using the same handleChange,
setConnectionType and setIsSlowConnection logic and still clean up window
listeners (handleOnline/handleOffline) regardless.

---

Nitpick comments:
In `@src/features/inbox/hooks/useSipClient.ts`:
- Around line 110-113: The hangup logic calls sessionRef.current.cancel() for
any non-Established state (including Terminal), causing noisy exceptions; change
the conditional so you call sessionRef.current.bye() when
sessionRef.current.state === SessionState.Established, and only call
sessionRef.current.cancel() when sessionRef.current.state is one of the valid
cancelable states (e.g., SessionState.Initial or SessionState.Establishing);
keep the try/catch around the calls and continue logging errors via
log.error('Hangup error:', err) but avoid invoking cancel() for
Terminated/Terminal states.
🪄 Autofix (Beta)

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: cbd13a58-e08a-464b-8590-eaeebe3263c5

📥 Commits

Reviewing files that changed from the base of the PR and between e62e373 and 91dd2df.

📒 Files selected for processing (16)
  • src/components/contacts/ContactBulkTagDialog.tsx
  • src/components/contacts/ContactGroupedList.tsx
  • src/components/contacts/SafeHtml.tsx
  • src/components/dashboard/ProgressiveDisclosureDashboard.tsx
  • src/components/settings/media-library/useMediaLibrary.ts
  • src/components/transcriptions/TranscriptionsHistoryView.tsx
  • src/components/ui/command.tsx
  • src/components/ui/textarea.tsx
  • src/features/inbox/components/AudioRecorder.tsx
  • src/features/inbox/components/useFileUploadLogic.ts
  • src/features/inbox/hooks/useRealtimeInbox.ts
  • src/features/inbox/hooks/useSipClient.ts
  • src/hooks/useAutomations.ts
  • src/hooks/usePerformanceOptimizations.ts
  • src/lib/logger.ts
  • tailwind.config.ts
💤 Files with no reviewable changes (1)
  • src/features/inbox/hooks/useRealtimeInbox.ts

Comment thread src/hooks/useAutomations.ts Outdated
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 reduces ESLint error count by applying a set of mechanical refactors (ternary-as-statement → if/else, removing no-op catch, removing this aliasing, replacing empty interface extensions with type aliases) plus a couple of small logic guards around optional Supabase client usage.

Changes:

  • Replaced statement-style ternaries with explicit if/else blocks across UI and hook codepaths.
  • Removed a useless catch { throw err } while preserving finally behavior, and removed const self = this by relying on arrow-function this binding.
  • Replaced require() and unsafe Function typings with ES imports and explicit function signatures.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tailwind.config.ts Replaces require("tailwindcss-animate") with an ES import and uses it in plugins.
src/lib/logger.ts Removes self = this alias in withCorrelation() and uses arrow functions capturing this.
src/hooks/usePerformanceOptimizations.ts Replaces Function-typed Connection API listeners with explicit function signatures.
src/hooks/useAutomations.ts Adds guards for potentially-null external Supabase client before RPC calls.
src/features/inbox/hooks/useSipClient.ts Expands hangup ternary statement into a readable if/else.
src/features/inbox/hooks/useRealtimeInbox.ts Removes redundant catch/rethrow while keeping finally refresh behavior.
src/features/inbox/components/useFileUploadLogic.ts Replaces ternary-as-statement counter updates with if/else.
src/features/inbox/components/AudioRecorder.tsx Replaces pause/resume ternary-as-statement with if/else in key handler.
src/components/ui/textarea.tsx Converts empty interface extension to a type alias.
src/components/ui/command.tsx Converts empty interface extension to a type alias.
src/components/transcriptions/TranscriptionsHistoryView.tsx Replaces set-toggle ternary-as-statement with explicit if/else.
src/components/settings/media-library/useMediaLibrary.ts Replaces ternary-as-statement in selection + toast logic with if/else.
src/components/dashboard/ProgressiveDisclosureDashboard.tsx Replaces set-toggle ternary-as-statement with explicit if/else.
src/components/contacts/SafeHtml.tsx Removes disable for missing react/no-danger rule; keeps explanatory comment.
src/components/contacts/ContactGroupedList.tsx Replaces set-toggle ternary-as-statement with explicit if/else.
src/components/contacts/ContactBulkTagDialog.tsx Replaces set-toggle ternary-as-statement with explicit if/else.

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

Comment thread src/hooks/useAutomations.ts Outdated
Comment on lines +105 to +107
const client2 = getClient();
if (!client2) return;
const { data: contact } = await client2.rpc("rpc_get_contact", {
Comment on lines +211 to 212
const connection = (navigator as Navigator & { connection?: { effectiveType?: string; saveData?: boolean; addEventListener?: (type: string, listener: () => void) => void; removeEventListener?: (type: string, listener: () => void) => void } }).connection;
if (connection) {
CodeRabbit + Copilot review feedback addressed:

## Issue 1+2 (CodeRabbit + Copilot, useAutomations.ts:107)

**Before:**
```ts
const client2 = getClient();
if (!client2) return;  // ⚠️ Aborta evaluate inteiro!
const { data: contact } = await client2.rpc(...)
```

**Problem:** `getClient()` é chamado 2x desnecessariamente, e o
`return` dentro do try aborta evaluate() inteiro, pulando todos
os outros gatilhos que não dependem da snapshot de tags.

**Fix:** Reusa o `client` já validado na linha 80 (15 linhas antes).
Se `client.rpc()` falhar, o catch existente trata e segue evaluate.

```ts
try {
  // Reusa client validado acima — falha aqui só pula snapshot de tags, não aborta evaluate
  const { data: contact } = await client.rpc(...)
```

## Issue 3 (CodeRabbit outside-diff, usePerformanceOptimizations.ts:211-235)

**Before:**
```ts
connection.addEventListener('change', handleChange);
// cleanup:
connection.removeEventListener('change', handleChange);
```

**Problem:** A NetworkInformation API NÃO é suportada em Firefox e
Safari. Em browsers sem suporte, `connection` pode existir mas não
ter `addEventListener/removeEventListener` — chamadas quebram o
useEffect e deixam listeners de window sem cleanup.

**Fix:** Guard com `typeof === 'function'` antes de chamar.

```ts
if (typeof connection.addEventListener === 'function') {
  connection.addEventListener('change', handleChange);
}
// cleanup:
if (typeof connection.removeEventListener === 'function') {
  connection.removeEventListener('change', handleChange);
}
```

## Validation

- bun run lint → 108 errors (unchanged, all no-restricted-imports)
- bun run build → ✓ built in 58.18s
@adm01-debug
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

Address review feedback aplicado em commit 5996f8945:

Issue 1+2 (useAutomations.ts:107) — reusando client da linha 80, removido client2 e return que abortava evaluate.
Issue 3 (usePerformanceOptimizations.ts:211) — guard typeof === 'function' antes de chamar add/removeEventListener (Firefox/Safari sem NetworkInformation API).

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

@adm01-debug Entendido! Vou refazer a revisão completa do PR incluindo as correções aplicadas no commit 5996f8945.

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hooks/usePerformanceOptimizations.ts (1)

211-218: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Adicione fallbacks para propriedades opcionais da Network Information API

Em linhas 213 e 220-226, connection.effectiveType e connection.saveData podem vir undefined em navegadores sem suporte completo à API. Isso propaga estado inconsistente — connectionType é inicializado como string mas pode receber undefined.

Diff sugerido
    if (connection) {
+     const effectiveType = connection.effectiveType ?? 'unknown';
+     const saveData = connection.saveData ?? false;
-     setConnectionType(connection.effectiveType);
+     setConnectionType(effectiveType);
      setIsSlowConnection(
-       connection.saveData || 
-       connection.effectiveType === 'slow-2g' || 
-       connection.effectiveType === '2g'
+       saveData ||
+       effectiveType === 'slow-2g' ||
+       effectiveType === '2g'
      );

      const handleChange = () => {
+       const nextEffectiveType = connection.effectiveType ?? 'unknown';
+       const nextSaveData = connection.saveData ?? false;
-       setConnectionType(connection.effectiveType);
+       setConnectionType(nextEffectiveType);
        setIsSlowConnection(
-         connection.saveData || 
-         connection.effectiveType === 'slow-2g' || 
-         connection.effectiveType === '2g'
+         nextSaveData ||
+         nextEffectiveType === 'slow-2g' ||
+         nextEffectiveType === '2g'
        );
      };
🤖 Prompt for 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.

In `@src/hooks/usePerformanceOptimizations.ts` around lines 211 - 218, The hook
usePerformanceOptimizations reads navigator.connection which may have undefined
properties; update the code that calls setConnectionType and setIsSlowConnection
to guard and provide fallbacks: compute a safe string like const effectiveType =
connection?.effectiveType ?? 'unknown' before calling
setConnectionType(effectiveType), and compute a boolean for slow connection
using Boolean(connection?.saveData) || effectiveType === 'slow-2g' ||
effectiveType === '2g' before calling setIsSlowConnection; ensure you still
attach/remove listeners on connection when available and keep the same
identifiers (usePerformanceOptimizations, setConnectionType,
setIsSlowConnection, connection.effectiveType, connection.saveData).
🧹 Nitpick comments (1)
src/components/settings/media-library/useMediaLibrary.ts (1)

128-129: ⚡ Quick win

Comparação por tamanho em toggleSelectAll pode limpar seleção errada

Na Line 129, selected.size === filtered.length não garante que os mesmos IDs estão selecionados; com tamanhos iguais e conjuntos diferentes, o “selecionar todos” pode limpar indevidamente.

Diff sugerido
-  const toggleSelectAll = () => { if (selected.size === filtered.length) setSelected(new Set()); else setSelected(new Set(filtered.map(i => i.id))); };
+  const toggleSelectAll = () => {
+    const allFilteredSelected = filtered.length > 0 && filtered.every(i => selected.has(i.id));
+    if (allFilteredSelected) setSelected(new Set());
+    else setSelected(new Set(filtered.map(i => i.id)));
+  };
🤖 Prompt for 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.

In `@src/components/settings/media-library/useMediaLibrary.ts` around lines 128 -
129, The toggleSelectAll logic compares selected.size to filtered.length which
can be equal while containing different IDs; update the toggleSelectAll in
useMediaLibrary.ts to check whether all filtered items are actually selected
(e.g., verify every filtered id is present in the selected Set) and only clear
the selection if that containment check is true, otherwise set selected to a new
Set of filtered.map(i => i.id); reference the toggleSelectAll function and the
selected/filtered variables when making the change.
🤖 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.

Outside diff comments:
In `@src/hooks/usePerformanceOptimizations.ts`:
- Around line 211-218: The hook usePerformanceOptimizations reads
navigator.connection which may have undefined properties; update the code that
calls setConnectionType and setIsSlowConnection to guard and provide fallbacks:
compute a safe string like const effectiveType = connection?.effectiveType ??
'unknown' before calling setConnectionType(effectiveType), and compute a boolean
for slow connection using Boolean(connection?.saveData) || effectiveType ===
'slow-2g' || effectiveType === '2g' before calling setIsSlowConnection; ensure
you still attach/remove listeners on connection when available and keep the same
identifiers (usePerformanceOptimizations, setConnectionType,
setIsSlowConnection, connection.effectiveType, connection.saveData).

---

Nitpick comments:
In `@src/components/settings/media-library/useMediaLibrary.ts`:
- Around line 128-129: The toggleSelectAll logic compares selected.size to
filtered.length which can be equal while containing different IDs; update the
toggleSelectAll in useMediaLibrary.ts to check whether all filtered items are
actually selected (e.g., verify every filtered id is present in the selected
Set) and only clear the selection if that containment check is true, otherwise
set selected to a new Set of filtered.map(i => i.id); reference the
toggleSelectAll function and the selected/filtered variables when making the
change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 419fe45d-e76a-41de-8476-89fd9cb29dcb

📥 Commits

Reviewing files that changed from the base of the PR and between e62e373 and 5996f89.

📒 Files selected for processing (16)
  • src/components/contacts/ContactBulkTagDialog.tsx
  • src/components/contacts/ContactGroupedList.tsx
  • src/components/contacts/SafeHtml.tsx
  • src/components/dashboard/ProgressiveDisclosureDashboard.tsx
  • src/components/settings/media-library/useMediaLibrary.ts
  • src/components/transcriptions/TranscriptionsHistoryView.tsx
  • src/components/ui/command.tsx
  • src/components/ui/textarea.tsx
  • src/features/inbox/components/AudioRecorder.tsx
  • src/features/inbox/components/useFileUploadLogic.ts
  • src/features/inbox/hooks/useRealtimeInbox.ts
  • src/features/inbox/hooks/useSipClient.ts
  • src/hooks/useAutomations.ts
  • src/hooks/usePerformanceOptimizations.ts
  • src/lib/logger.ts
  • tailwind.config.ts
💤 Files with no reviewable changes (1)
  • src/features/inbox/hooks/useRealtimeInbox.ts

@adm01-debug adm01-debug merged commit c734349 into main May 9, 2026
10 of 11 checks passed
@adm01-debug adm01-debug deleted the chore/onda-5-pr-5.2.1-eslint-residual-errors branch May 9, 2026 12:03
adm01-debug added a commit that referenced this pull request May 9, 2026
🎉 Fecha Onda 5: 108 → 0 errors (-108).

ESLint TOTAL: 164 → 0 errors em 4 PRs (#109, #110, #111, este).

## Estratégia DDD

Regra `no-restricted-imports` (eslint.config.js) bloqueia:
1. Imports cross-feature deep (`@/features/X/...`) — força entry points
2. Imports relativos profundos (`../../...`)
3. INTRA-feature via alias (`@/features/X/Y` quando arquivo está em X)

## Batch A — INTRA-feature (106 fixes em 42 arquivos)

Pattern: `@/features/X/Y/Z` → caminho relativo via path.relative()

Ex (src/features/inbox/components/chat/ChatHeader.tsx):
- ANTES: `@/features/inbox/components/ai-tools/VisionIcon`
- DEPOIS: `../ai-tools/VisionIcon`

Distribuição:
- 92 inbox (52 chat, 12 contact-details, 8 components, 5 hooks, 3 services, 3 virtualized, 3 conversation-list, 2 realtime, 2 templates, 2 search, 1 monitoring, 1 mocks)
- 7 auth (5 components, 1 hooks, 1 context)
- 3 admin (2 hooks, 1 services)
- 3 connections (2 hooks, 1 services)
- 1 sla (1 components)

Script: /tmp/fix-intra.mjs (Node + path.relative)
- 106/106 sucesso, zero falhas
- 1 read/write por arquivo (eficiente)
- Ordem desc por linha (não invalida índices)

## Batch B — CROSS-feature (2 fixes)

Imports de outra feature DEVEM usar entry point (`@/features/X`),
não path interno (`@/features/X/hooks/...`).

Os barrels já existiam (`auth/index.ts` e `sla/index.ts` fazem
`export * from './hooks'`), só não estavam sendo usados:

- src/features/inbox/components/ChatPanel.tsx:
  `@/features/auth/hooks/useUserRole` → `@/features/auth`
- src/features/inbox/components/RealtimeInboxView.tsx:
  `@/features/sla/hooks/useSLAAlerts` → `@/features/sla`

## Validação

- bunx eslint . → 0 errors, 1330 warnings (Onda 5 ZERADA)
- bunx tsc --noEmit → ✓ sem erros (typecheck pristine)
- bun run build → ✓ built in 58.09s (zero regressões)
- 44 files changed, 108 insertions(+), 108 deletions(-)

## Stress-test (10 cenários)

✓ path.relative gera `../foo` ou `./foo` corretamente
✓ Sem imports circulares (auth/sla não importam inbox)
✓ Comments inline preservados (replace só no string interno)
✓ BOM/CRLF tratados pelo Node
✓ index.ts implícito resolvido pelo TS path mapping
✓ Build não quebrou — tsconfig path mapping continua funcionando
✓ Typecheck sem regressão
✓ Sem sessão paralela (verificado via git reflog)
✓ Barrels já existiam, useUserRole/useSLAAlerts já re-exportados
✓ Eslint --fix NÃO usado (só explicit replace, sem side effects)

## Pós-Onda 5

Próximo do roadmap pré-deploy:
- PR #108 (preserve/faxina) — decidir mergear ou fechar
- 8 dependabots — aplicar recomendação A (fechar com TODO pós-deploy)
- Fase B10 — patch 9 vulns npm
- Fase B5 — ENV_SETUP doc
- Fase C — Dockerfile + deploy zapp.atomicabr.com.br
adm01-debug added a commit that referenced this pull request May 9, 2026
🎉 Fecha Onda 5: 108 → 0 errors (-108).

ESLint TOTAL: 164 → 0 errors em 4 PRs (#109, #110, #111, este).

## Estratégia DDD

Regra `no-restricted-imports` (eslint.config.js) bloqueia:
1. Imports cross-feature deep (`@/features/X/...`) — força entry points
2. Imports relativos profundos (`../../...`)
3. INTRA-feature via alias (`@/features/X/Y` quando arquivo está em X)

## Batch A — INTRA-feature (106 fixes em 42 arquivos)

Pattern: `@/features/X/Y/Z` → caminho relativo via path.relative()

Ex (src/features/inbox/components/chat/ChatHeader.tsx):
- ANTES: `@/features/inbox/components/ai-tools/VisionIcon`
- DEPOIS: `../ai-tools/VisionIcon`

Distribuição:
- 92 inbox (52 chat, 12 contact-details, 8 components, 5 hooks, 3 services, 3 virtualized, 3 conversation-list, 2 realtime, 2 templates, 2 search, 1 monitoring, 1 mocks)
- 7 auth (5 components, 1 hooks, 1 context)
- 3 admin (2 hooks, 1 services)
- 3 connections (2 hooks, 1 services)
- 1 sla (1 components)

Script: /tmp/fix-intra.mjs (Node + path.relative)
- 106/106 sucesso, zero falhas
- 1 read/write por arquivo (eficiente)
- Ordem desc por linha (não invalida índices)

## Batch B — CROSS-feature (2 fixes)

Imports de outra feature DEVEM usar entry point (`@/features/X`),
não path interno (`@/features/X/hooks/...`).

Os barrels já existiam (`auth/index.ts` e `sla/index.ts` fazem
`export * from './hooks'`), só não estavam sendo usados:

- src/features/inbox/components/ChatPanel.tsx:
  `@/features/auth/hooks/useUserRole` → `@/features/auth`
- src/features/inbox/components/RealtimeInboxView.tsx:
  `@/features/sla/hooks/useSLAAlerts` → `@/features/sla`

## Validação

- bunx eslint . → 0 errors, 1330 warnings (Onda 5 ZERADA)
- bunx tsc --noEmit → ✓ sem erros (typecheck pristine)
- bun run build → ✓ built in 58.09s (zero regressões)
- 44 files changed, 108 insertions(+), 108 deletions(-)

## Stress-test (10 cenários)

✓ path.relative gera `../foo` ou `./foo` corretamente
✓ Sem imports circulares (auth/sla não importam inbox)
✓ Comments inline preservados (replace só no string interno)
✓ BOM/CRLF tratados pelo Node
✓ index.ts implícito resolvido pelo TS path mapping
✓ Build não quebrou — tsconfig path mapping continua funcionando
✓ Typecheck sem regressão
✓ Sem sessão paralela (verificado via git reflog)
✓ Barrels já existiam, useUserRole/useSLAAlerts já re-exportados
✓ Eslint --fix NÃO usado (só explicit replace, sem side effects)

## Pós-Onda 5

Próximo do roadmap pré-deploy:
- PR #108 (preserve/faxina) — decidir mergear ou fechar
- 8 dependabots — aplicar recomendação A (fechar com TODO pós-deploy)
- Fase B10 — patch 9 vulns npm
- Fase B5 — ENV_SETUP doc
- Fase C — Dockerfile + deploy zapp.atomicabr.com.br
adm01-debug added a commit that referenced this pull request May 9, 2026
…09) (#113)

Documenta o estado FINAL após:
- Onda 5 completa (164 → 0 errors em 4 PRs: #109, #110, #111, #112)
- 8 dependabots resolvidos (3 mergeados, 5 fechados, 1 preservation closed)

Estado atual:
- HEAD main: f1b3eab
- ESLint: 0 errors, 1330 warnings
- Branches remotas: 2 (main + preserve)
- PRs OPEN: 0

Conteúdo do handoff (718 linhas):
- TL;DR + estado atual com métricas
- Quem é Joaquim e workflow
- Histórico cronológico de TODOS os PRs (Schemas, Faxina pré-Onda, Ondas 1, 2, 5)
- Faxina de branches (491 → 2)
- Resolução técnica dos 8 dependabots
- Decisões técnicas-chave (React 18, Vite reject, Sentry accept, etc)
- 20 lições aprendidas
- Catálogo de notes em /workspace/notes/
- Pendências pré-deploy (Backup Supabase, RabbitMQ 69GB, Drift, Deploy VPS, FX-DEP-02)
- Backlogs de review skipped
- Como retomar (instruções pra próximo Claude)
- Apêndices: comandos úteis, infra VPS, Vercel, workflow

Este doc serve como ponto de retomada pra próxima sessão Claude
sem perder contexto.
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