QABot

Revisão técnica assistida por IA

Histórico757c1cda-0222-4621-a812-246c96c55cc0
ANÁLISE SALVA

cellarvinhostechteam/novo-app-cellar

feat/tab-pop-to-top · 22 de setembro de 2026 às 12:54 · gpt-5.6-sol

55/ 100

A implementação apresenta riscos relevantes em segurança de transporte, publicação acidental em produção e exposição de credenciais. Também há um bug reproduzível no script de migração de ScrollView, falhas de confiabilidade no modal de cupons e ausência de testes automatizados. Score: 55/100.

Achados 11

24 arquivos analisados

Alto

Tráfego HTTP sem criptografia está liberado globalmente em iOS e Android

security
app.config.js

A configuração define NSAllowsArbitraryLoads: true no iOS, tanto diretamente quanto em infoPlist, e usesCleartextTraffic: true no Android. Isso permite conexões HTTP não criptografadas para qualquer domínio.

RecomendaçãoDesabilitar NSAllowsArbitraryLoads e usesCleartextTraffic. Se algum serviço legado exigir HTTP, criar exceções restritas aos domínios necessários e adicionar testes de integração que confirmem o funcionamento exclusivamente por HTTPS.
Alto

Push notification de produção está configurado explicitamente em modo de desenvolvimento

reliability
app.config.js

O entitlement aps-environment está definido como development e o onesignal-expo-plugin recebe mode: "development" sem diferenciação por perfil EAS. Os mesmos valores são usados pelo perfil production.

RecomendaçãoDerivar mode e aps-environment do perfil/ambiente de build, usando production em builds de distribuição. Validar em CI o config gerado por expo config para cada perfil e executar um teste real de recebimento de push em build de produção.
Alto

Commits na branch development podem publicar OTA diretamente no canal production

reliability
.eas/workflows/publish-development-updates.yml

O workflow executa em pushes para development e publica no channel production quando a mensagem do commit contém simultaneamente as substrings "update" e "production". Uma mensagem como "do not update production" também satisfaz a condição, sem aprovação ou validação adicional.

RecomendaçãoRemover publicação de production a partir de development. Usar branch/tag protegida, condição exata ou input explícito, aprovação de ambiente e checks obrigatórios antes de publicar no canal production.
Alto

Token de autenticação e e-mail são inseridos diretamente na URL do WebView

security
src/components/home/ClubeWelcome.tsx

A navegação constrói a URL https://socio.cellarvinhos.com/loginWebview?email=${userEmail}&tokenVtex=${authCookie?.Value}. Credenciais em query string podem aparecer em logs, telemetria, histórico e cabeçalhos de referência. Os valores também não são codificados; e-mails com '+' ou tokens contendo '&', '#' ou '=' podem ser interpretados incorretamente.

RecomendaçãoTrocar o login por uma requisição POST ou por código de uso único, curto e revogável. Não transportar cookie/token persistente em query string. Como mitigação mínima, aplicar encodeURIComponent aos parâmetros e garantir que URL, breadcrumbs e eventos do WebView sejam sanitizados.
Alto

Script substitui ScrollView, mas não adiciona o import de AppScrollView

bug
replace_scrollviews.js

O script primeiro substitui '<ScrollView' por '<AppScrollView' e depois testa if (!content.includes('AppScrollView')). Após a substituição, essa condição sempre será falsa, portanto importStatement nunca é inserido em arquivos que ainda não importavam AppScrollView. O resultado é código com identificador não definido.

RecomendaçãoVerificar a existência do import antes de substituir as tags ou detectar especificamente uma declaração de import, por exemplo com AST. Adicionar teste de fixture cobrindo arquivo com ScrollView importado de react-native e confirmar que o resultado contém tags e import válidos.
Médio

Falha no AsyncStorage pode impedir o fechamento do modal

reliability
src/components/home/SelecaoCupons/HowToUseCouponsModal.tsx

handleClose aguarda AsyncStorage.setItem ou removeItem antes de chamar onClose, sem try/finally. Se a operação rejeitar, onClose não é executado. loadPref também chama getItem sem tratamento de erro, podendo gerar rejeição não tratada.

RecomendaçãoEnvolver leitura e escrita em try/catch e chamar onClose dentro de finally. Registrar a falha sem bloquear a interação. Testar rejeições de getItem, setItem e removeItem.
Médio

Consulta da vitrine é executada mesmo quando o componente será ocultado

performance
src/components/home/MinhaVitrine.tsx

useAdegaProductsQuery(skus) é chamado antes da condição que retorna null para usuários que não pertencem ao clube. Além disso, skus recebe uma lista padrão, fazendo com que usuários sem skus personalizados ainda possam disparar a consulta.

RecomendaçãoAdicionar opção enabled à query com a mesma condição de elegibilidade do componente, por exemplo usuário do clube, cluster válido e SKUs presentes. Evitar a lista padrão quando a vitrine não será exibida e criar teste garantindo que usuários inelegíveis não acionem a API.
Médio

Build de produção também pode ser disparado por texto ambíguo em commit de development

reliability
.eas/workflows/create-development-builds.yml

O job dev_build_production roda em push para development quando a mensagem contém as substrings "build" e "production". Não há aprovação, tag, branch de release ou correspondência exata do comando.

RecomendaçãoRestringir builds de produção a tags ou branches protegidas e exigir aprovação do ambiente. Se comandos por commit forem mantidos, usar formato exato e inequívoco, como uma diretiva isolada, além de checagens obrigatórias.
Médio

Não há infraestrutura de testes automatizados declarada

testing
package.json

Os scripts disponíveis cobrem execução, build, submit e upload de source maps, mas não há script de test, lint ou typecheck. Também não há dependência de runner de testes entre as dependências fornecidas.

RecomendaçãoAdicionar no mínimo scripts de typecheck, lint e testes unitários. Priorizar casos para tab press/pop-to-top, deep links, scripts de migração, persistência do modal, feature flags e condições de publicação EAS; torná-los obrigatórios antes de builds e updates.
Baixo

Logs verbosos do OneSignal ficam habilitados também em produção

security
App.tsx

OneSignal.Debug.setLogLevel(LogLevel.Verbose) é executado no escopo global sem condição de __DEV__ ou ambiente.

RecomendaçãoUsar LogLevel.Verbose apenas em desenvolvimento e nível mínimo ou desativado em produção, reduzindo exposição de metadados de notificação e ruído operacional.
Baixo

Áreas vazias do conteúdo do modal podem propagar toque para o backdrop

reliability
src/components/home/SelecaoCupons/HowToUseCouponsModal.tsx

O conteúdo usa pointerEvents="box-none", que impede o próprio container de ser alvo de toque. Como o backdrop abaixo fecha o modal, toques em áreas do container não cobertas por filhos interativos podem atingir o backdrop, contrariando o comentário de que o conteúdo está isolado.

RecomendaçãoRemover box-none ou usar uma camada de conteúdo que capture os toques. Adicionar teste de interação verificando que tocar dentro do cartão não fecha o modal e tocar fora fecha.