Skip to content

fix: harden product simulation hooks lint#166

Merged
adm01-debug merged 1 commit into
mainfrom
fix/batch-products-simulation-hooks-lint-hardening
May 23, 2026
Merged

fix: harden product simulation hooks lint#166
adm01-debug merged 1 commit into
mainfrom
fix/batch-products-simulation-hooks-lint-hardening

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

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

Resumo

  • Estabiliza arrays derivados em useVariantStock para corrigir dependências de hooks e remove minQuantityNeeded!.
  • Remove non-null assertions de agrupamentos por Map em imagens, fornecedores e simulação externa.
  • Adiciona guards de productId/clientId em queries habilitadas condicionalmente.
  • Tipifica guards de tabelas de preço por cor/área e corrige dependency array de múltiplas técnicas.
  • Remove assertions no agrupamento de replies de comentários de orçamento.

Validação

  • npx.cmd eslint src/hooks/products/useVariantStock.ts src/hooks/simulation/useTechniquePricingOptions.ts src/hooks/simulation/useExternalSimulator.ts src/hooks/products/useProductImages.ts src/hooks/products/useSupplierComparison.ts src/hooks/products/useProductFreshnessOverride.ts src/hooks/bi/useClientOrdersHistory.ts src/hooks/quotes/useQuoteComments.ts
  • npx.cmd eslint no conjunto ampliado usado no levantamento: 0 errors; warnings reduziram de 47 para 17
  • git diff --check
  • VITE_SUPABASE_URL=https://doufsxqlfjyuvxuezpln.supabase.co VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_test npm.cmd run build

Observação: o push normal foi bloqueado pelo hook local já conhecido scripts/check-eslint-baseline.mjs com eslint falhou com status null; após validação manual acima, a branch foi publicada com HUSKY=0.


Summary by cubic

Hardened product and simulation hooks by removing non-null assertions, adding query guards, and stabilizing memoized arrays to satisfy ESLint and prevent edge-case crashes. Also improved pricing option logic with typed guards and fixed dependency keys for multi-technique flows.

  • Bug Fixes

    • Stabilized derived arrays in useVariantStock and removed unsafe minQuantityNeeded!.
    • Added productId/clientId guards for conditionally enabled @tanstack/react-query queries; return safe defaults when absent.
    • Fixed comment reply grouping in useQuoteComments and Map usages in images/external data to avoid non-null assertions.
  • Refactors

    • Introduced typed guards for color/area price tables and corrected dependency keys in multi-technique pricing.
    • Replaced non-null assertions with safe Map patterns across images, supplier comparison, and external simulator; normalized query keys and ordering.

Written for commit 84dca07. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Aprimorado o tratamento de casos onde informações podem estar ausentes, resultando em comportamento mais previsível da aplicação.
  • Refactor

    • Otimizadas operações internas para melhor performance.
    • Melhorado o enriquecimento de dados de produtos com informações de imagens.
    • Refinada a validação de parâmetros em diversas operações.

Review Change Stack

Copilot AI review requested due to automatic review settings May 23, 2026 17:01
@vercel
Copy link
Copy Markdown

vercel Bot commented May 23, 2026

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

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 23, 2026 5:02pm

@supabase
Copy link
Copy Markdown

supabase Bot commented May 23, 2026

This pull request has been ignored for the connected project doufsxqlfjyuvxuezpln because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Walkthrough

Refatoração distribuída de 8 hooks React com foco em null safety, consolidação de padrão Map aggregate, e enriquecimento de imagens de produtos. Removidas non-null assertions (!) e substituídas por guards explícitos retornando defaults. Integração de product images em simulator com agrupamento seguro por product_id.

Changes

Refatoração de hooks: null safety e agregação

Layer / File(s) Summary
Guarding de valores ausentes em hooks de query
src/hooks/bi/useClientOrdersHistory.ts, src/hooks/products/useProductFreshnessOverride.ts, src/hooks/quotes/useQuoteComments.ts
clientId, productId e parent_id agora têm guarda explícita que retorna payload default ou null ao invés de depender de non-null assertions. Evita dereference de undefined em queries Supabase.
Consolidação do padrão Map get/set em agregações
src/hooks/products/useProductImages.ts, src/hooks/products/useSupplierComparison.ts
Refatoração de has() + set() + get()!.push() para get(...) ?? [] + set() + push(), garantindo tipo seguro em todas as agregações Map sem assertions.
Ajustes de formatação e validação em quote comments
src/hooks/quotes/useQuoteComments.ts
Padronização de aspas simples em imports e calls Supabase, mais remoção de asserção (!) na construção de árvore de replies com validação explícita antes de indexação.
Refatoração de cálculo e Map em supplier comparison
src/hooks/products/useSupplierComparison.ts
Ajustes menores de formatação em priceDiffPercent (unilinha) e refatoração de agregação Map em getSupplierProductsInCategory com padrão get/set seguro.
Integração de enriquecimento product images em simulator
src/hooks/simulation/useExternalSimulator.ts
Adição de lógica de busca/agrupamento de product_images por product_id em três hooks, com ordenação por display_order, seleção de primária via is_primary, e população de primary_image_url/image_url/images. Atenção: Novos campos no tipo ExternalProduct refletem origin product_images.
Memoização de derivações em variant stock
src/hooks/products/useVariantStock.ts
Cálculo de productStocks, rawAlerts, futureStock via useMemo com fallback para arrays vazios; remoção de non-null assertion em filtro minQuantityNeeded com variável local.
Type guards e refatoração de technique pricing options
src/hooks/simulation/useTechniquePricingOptions.ts
Mudança substancial: Introdução de hasMaxColors() e hasAreaSize() type guards para filtragem segura de pricing tables; reescrita de colorOptions/sizeOptions com Set/Map; reimplementação de getTableForSelection() com filtro por dimensões exatas (width/height cm); carregamento paralelo via Promise.all com limit: 100 para cada técnica.
Refinements em product freshness override
src/hooks/products/useProductFreshnessOverride.ts
Normalização de imports/constantes (aspas simples), compatibilização de productId fallback em queryKey/queryFn, padronização de mensagens de erro em upsert/delete.
Defaults e imports em client orders history
src/hooks/bi/useClientOrdersHistory.ts
Reformatação imports (aspas simples), guarda explícita de clientId com payload default (orders: [], contadores zero, lastOrderAt null).

Sequence Diagram(s)

Não aplicável — mudanças consistem em refatorações internas de hooks, removals de assertions, consolidações de pattern, sem novas integrações multi-componente significativas.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutos

Justificativa: Mix de refatorações de pattern (Map aggregation), guarding defensivo (null checks), e uma integração substancial de imagens em simulator. Requer verificação de type safety em múltiplos arquivos, validação de padrão Map em 3+ hooks, e atenção especial a useExternalSimulator (enriquecimento com imagens) e useTechniquePricingOptions (type guards em filtering). Sem novas APIs públicas, logo baixo risco de breaking changes.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% 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 'fix: harden product simulation hooks lint' é específico e direto, refletindo a essência das mudanças: remoção de non-null assertions e hardening de hooks em validação de lint.
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 fix/batch-products-simulation-hooks-lint-hardening

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

Copy link
Copy Markdown
Contributor

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

Este PR endurece e estabiliza hooks relacionados a simulação/produtos/cotações, com foco em eliminar non-null assertions, melhorar guards de queries condicionais e ajustar dependências/memoização para satisfazer regras de lint (especialmente hooks/exhaustive-deps) sem alterar a intenção funcional.

Changes:

  • Adiciona type guards (hasMaxColors/hasAreaSize) para remover asserts e tornar o acesso a campos nullable mais seguro em pricing tables.
  • Remove non-null assertions em agrupamentos via Map (imagens, fornecedores e replies de comentários), substituindo por inicialização segura.
  • Adiciona guards explícitos em queryFn quando enabled depende de productId/clientId, e estabiliza dependências (ex.: key de múltiplas técnicas).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/hooks/simulation/useTechniquePricingOptions.ts Type guards para tabelas de preço e estabilização de dependência no hook multi-técnica.
src/hooks/simulation/useExternalSimulator.ts Remove non-null assertions e padroniza agrupamento de imagens por Map.
src/hooks/quotes/useQuoteComments.ts Remove non-null assertions ao montar árvore de replies, com guard para parent_id.
src/hooks/products/useVariantStock.ts Memoização de arrays derivados de data para estabilizar dependências e remove ! em filtro.
src/hooks/products/useSupplierComparison.ts Remove non-null assertion ao agrupar produtos por fornecedor em Map.
src/hooks/products/useProductImages.ts Remove non-null assertion ao agrupar imagens em batch por Map.
src/hooks/products/useProductFreshnessOverride.ts Guard explícito de productId no queryFn (alinhado ao enabled).
src/hooks/bi/useClientOrdersHistory.ts Guard explícito de clientId no queryFn (alinhado ao enabled) e ajustes de lint.

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

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: 84dca07eb6

ℹ️ 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".

}

function hasMaxColors(table: PriceTableEntry): table is PriceTableEntry & { max_colors: number } {
return table.price_by_color && typeof table.max_colors === 'number';
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 Coerce numeric bridge fields before filtering options

The new guard typeof table.max_colors === 'number' filters out rows where external-db-bridge serializes numeric DB fields as strings (a case already handled elsewhere in the repo, e.g. by parsing max_cores before use). In that scenario, valid customization_price_tables rows are dropped, so colorOptions/sizeOptions become incomplete or empty and the simulator can hide valid pricing choices for a technique.

Useful? React with 👍 / 👎.

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: 3

Caution

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

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

193-233: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Evite sobrescrever estado com resposta antiga no useEffect assíncrono
Quando techniqueCodesKey muda rápido, uma execução anterior pode terminar depois e sobrescrever setAllTables(results) e setIsLoading(false) com dados obsoletos. Adicione cleanup/cancelamento antes de atualizar o estado.

💡 Sugestão de ajuste
  useEffect(() => {
+    let cancelled = false;
     const codes = techniqueCodesKey ? techniqueCodesKey.split(',').filter(Boolean) : [];

     if (codes.length === 0) {
       setAllTables({});
       return;
     }

     const fetchAll = async () => {
       setIsLoading(true);
       const results: Record<string, PriceTableEntry[]> = {};

       await Promise.all(
         codes.map(async (code) => {
           try {
             const { data, error } = await supabase.functions.invoke('external-db-bridge', {
               body: {
                 table: 'customization_price_tables',
                 operation: 'select',
                 filters: { table_code: code },
                 limit: 100,
               },
             });

             if (!error && data?.success && data?.data?.records) {
               results[code] = data.data.records;
             } else if (!error && Array.isArray(data?.data)) {
               results[code] = data.data;
             }
           } catch (err) {
             console.error(`Error fetching pricing for ${code}:`, err);
           }
         }),
       );

-      setAllTables(results);
-      setIsLoading(false);
+      if (!cancelled) {
+        setAllTables(results);
+        setIsLoading(false);
+      }
     };

     fetchAll();
+    return () => {
+      cancelled = true;
+    };
   }, [techniqueCodesKey]);
🤖 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/simulation/useTechniquePricingOptions.ts` around lines 193 - 233,
The async useEffect in useTechniquePricingOptions may set state from stale
fetches when techniqueCodesKey changes quickly; modify fetchAll to support
cancellation by creating a local cancelled flag or AbortController tied to the
effect (inside useEffect) and check it before calling setAllTables and
setIsLoading (and before assigning to results) so returned results from prior
invocations are ignored; ensure the effect returns a cleanup that flips the
cancelled flag or aborts the controller and that you check cancellation after
each await inside fetchAll (references: useEffect, fetchAll, setAllTables,
setIsLoading, techniqueCodesKey).
🤖 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/quotes/useQuoteComments.ts`:
- Line 173: The insert into workspace_notifications currently ignores Supabase
errors; change the call in useQuoteComments (where notifications is inserted) to
capture the result and handle errors: const { data, error } = await
supabase.from('workspace_notifications').insert(notifications); then if (error)
either throw error or log/report it (e.g., processLogger.error /
Sentry.captureException) so failures (RLS/invalid payload) are not swallowed by
the surrounding try/catch that is non-blocking; ensure you reference the same
notifications variable and preserve existing behavior when data is returned.

In `@src/hooks/simulation/useExternalSimulator.ts`:
- Around line 357-365: A consulta atual chama
invokeExternalDb<ProductImageRecord>('product_images','select',...) sem filtrar
por product_id e depois filtra imagens em memória (imagesResult), o que pode
causar perda por limit e I/O desnecessário; update a chamada a invokeExternalDb
para incluir um filtro de product_id usando os ids de produtos em contexto (ex.:
filters: { is_active: true, product_id: { in: productIds } }) e ajustar/remover
o limit ou torná-lo suficientemente grande por produto, para que a filtragem por
product_id ocorra na query e não apenas em memória; referências-chave:
invokeExternalDb, 'product_images', ProductImageRecord, imagesResult e o código
que atualmente faz o .filter em memória.

In `@src/hooks/simulation/useTechniquePricingOptions.ts`:
- Around line 191-195: The current techniqueCodesKey uses join(',')/split(',')
which breaks if a technique code contains a comma; replace that with an
unambiguous serialization: set techniqueCodesKey =
JSON.stringify(techniqueCodes) and inside the useEffect derive codes via
JSON.parse(techniqueCodesKey) (or fallback to []), and keep the effect
dependency on techniqueCodesKey; update references to techniqueCodesKey,
useEffect, and techniqueCodes accordingly.

---

Outside diff comments:
In `@src/hooks/simulation/useTechniquePricingOptions.ts`:
- Around line 193-233: The async useEffect in useTechniquePricingOptions may set
state from stale fetches when techniqueCodesKey changes quickly; modify fetchAll
to support cancellation by creating a local cancelled flag or AbortController
tied to the effect (inside useEffect) and check it before calling setAllTables
and setIsLoading (and before assigning to results) so returned results from
prior invocations are ignored; ensure the effect returns a cleanup that flips
the cancelled flag or aborts the controller and that you check cancellation
after each await inside fetchAll (references: useEffect, fetchAll, setAllTables,
setIsLoading, techniqueCodesKey).
🪄 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: e763b545-76b0-4165-9636-2cda59a438d6

📥 Commits

Reviewing files that changed from the base of the PR and between 755f307 and 84dca07.

📒 Files selected for processing (8)
  • src/hooks/bi/useClientOrdersHistory.ts
  • src/hooks/products/useProductFreshnessOverride.ts
  • src/hooks/products/useProductImages.ts
  • src/hooks/products/useSupplierComparison.ts
  • src/hooks/products/useVariantStock.ts
  • src/hooks/quotes/useQuoteComments.ts
  • src/hooks/simulation/useExternalSimulator.ts
  • src/hooks/simulation/useTechniquePricingOptions.ts

}));

await supabase.from("workspace_notifications").insert(notifications);
await supabase.from('workspace_notifications').insert(notifications);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verifica chamadas de escrita no hook sem checagem explícita de `error`
rg -n -C2 "supabase\.from\('.*'\)\.(insert|update|delete|upsert)\(" src/hooks/quotes/useQuoteComments.ts

Repository: adm01-debug/promo-gifts-v4

Length of output: 604


🏁 Script executed:

#!/bin/bash
# Checa chamadas específicas de escrita sem destructurar `error`
rg -n "workspace_notifications" src/hooks/quotes/useQuoteComments.ts
rg -n "await supabase\.from\('.*'\)\.insert\(" -n src/hooks/quotes/useQuoteComments.ts

Repository: adm01-debug/promo-gifts-v4

Length of output: 300


🏁 Script executed:

#!/bin/bash
# Verifica se há algum outro insert/delete/update/upsert aguardado sem `{ error }`
rg -n -C1 "await supabase\.from\('.*'\)\.(insert|update|delete|upsert)\(" src/hooks/quotes/useQuoteComments.ts

Repository: adm01-debug/promo-gifts-v4

Length of output: 407


🏁 Script executed:

#!/bin/bash
# Checa ocorrências do insert que estava sendo apontado
rg -n "workspace_notifications" src/hooks/quotes/useQuoteComments.ts

# Mostra todos os awaited inserts no arquivo (para comparar com checagem de `error`)
rg -n "await supabase\.from\('.*'\)\.insert\(" src/hooks/quotes/useQuoteComments.ts

# Verifica contexto de writes aguardadas (insert/update/delete/upsert)
rg -n -C2 "await supabase\.from\('.*'\)\.(insert|update|delete|upsert)\(" src/hooks/quotes/useQuoteComments.ts

Repository: adm01-debug/promo-gifts-v4

Length of output: 834


Valide o erro do insert em workspace_notifications
O await supabase.from('workspace_notifications').insert(notifications); (linha 173) não checa { error }; mesmo estando em try/catch com catch { // Non-blocking }, falhas do Supabase (RLS/payload inválido) viram falha silenciosa porque não há throw.

🔧 Ajuste sugerido
-    await supabase.from('workspace_notifications').insert(notifications);
+    const { error: notifyError } = await supabase
+      .from('workspace_notifications')
+      .insert(notifications);
+    if (notifyError) throw notifyError;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await supabase.from('workspace_notifications').insert(notifications);
const { error: notifyError } = await supabase
.from('workspace_notifications')
.insert(notifications);
if (notifyError) throw notifyError;
🤖 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/quotes/useQuoteComments.ts` at line 173, The insert into
workspace_notifications currently ignores Supabase errors; change the call in
useQuoteComments (where notifications is inserted) to capture the result and
handle errors: const { data, error } = await
supabase.from('workspace_notifications').insert(notifications); then if (error)
either throw error or log/report it (e.g., processLogger.error /
Sentry.captureException) so failures (RLS/invalid payload) are not swallowed by
the surrounding try/catch that is non-blocking; ensure you reference the same
notifications variable and preserve existing behavior when data is returned.

Comment on lines +357 to +365
const imagesResult = await invokeExternalDb<ProductImageRecord>(
'product_images',
'select',
{
filters: { is_active: true },
select: 'product_id, url_cdn, image_type, is_primary, display_order',
orderBy: { column: 'display_order', ascending: true },
limit: 2000,
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Filtre product_images por product_id na query para evitar perda de imagens e custo desnecessário.

Em Line 361 você busca todas as imagens ativas e só filtra em memória depois (Line 372). Com limit: 2000 (Line 364), isso pode excluir imagens de produtos retornados quando a tabela crescer, além de aumentar I/O sem necessidade.

Diff sugerido
           const imagesResult = await invokeExternalDb<ProductImageRecord>(
             'product_images',
             'select',
             {
-              filters: { is_active: true },
+              filters: { product_id: productIds, is_active: true },
               select: 'product_id, url_cdn, image_type, is_primary, display_order',
               orderBy: { column: 'display_order', ascending: true },
-              limit: 2000,
+              limit: Math.max(productIds.length * 8, 100),
             },
           );

Also applies to: 372-374

🤖 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/simulation/useExternalSimulator.ts` around lines 357 - 365, A
consulta atual chama
invokeExternalDb<ProductImageRecord>('product_images','select',...) sem filtrar
por product_id e depois filtra imagens em memória (imagesResult), o que pode
causar perda por limit e I/O desnecessário; update a chamada a invokeExternalDb
para incluir um filtro de product_id usando os ids de produtos em contexto (ex.:
filters: { is_active: true, product_id: { in: productIds } }) e ajustar/remover
o limit ou torná-lo suficientemente grande por produto, para que a filtragem por
product_id ocorra na query e não apenas em memória; referências-chave:
invokeExternalDb, 'product_images', ProductImageRecord, imagesResult e o código
que atualmente faz o .filter em memória.

Comment on lines +191 to +195
const techniqueCodesKey = techniqueCodes.join(',');

useEffect(() => {
if (techniqueCodes.length === 0) {
const codes = techniqueCodesKey ? techniqueCodesKey.split(',').filter(Boolean) : [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

join(',')/split(',') pode quebrar código de técnica contendo vírgula.

A chave derivada por vírgula não é robusta para todos os valores possíveis. Prefira manter techniqueCodes como fonte e usar uma serialização sem ambiguidade para a dependência (ex.: JSON.stringify(techniqueCodes)).

🤖 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/simulation/useTechniquePricingOptions.ts` around lines 191 - 195,
The current techniqueCodesKey uses join(',')/split(',') which breaks if a
technique code contains a comma; replace that with an unambiguous serialization:
set techniqueCodesKey = JSON.stringify(techniqueCodes) and inside the useEffect
derive codes via JSON.parse(techniqueCodesKey) (or fallback to []), and keep the
effect dependency on techniqueCodesKey; update references to techniqueCodesKey,
useEffect, and techniqueCodes accordingly.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 8 files

Re-trigger cubic

@adm01-debug adm01-debug merged commit a209263 into main May 23, 2026
29 of 31 checks passed
@adm01-debug adm01-debug deleted the fix/batch-products-simulation-hooks-lint-hardening branch May 23, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants