cellarvinhostechteam/novo-app-cellar
feat/tab-pop-to-top · 22 de setembro de 2026 às 12:53 · gpt-5.6-sol
A alteração apresenta riscos relevantes de segurança e publicação. O principal problema é o envio de credencial de autenticação na query string de uma WebView, agravado pela liberação global de HTTP sem TLS. A configuração de produção também mantém OneSignal/APNs em modo de desenvolvimento, e atualizações OTA para o canal production podem ser disparadas por uma mensagem de commit na branch development. Há ainda caminhos que podem bloquear indefinidamente a inicialização, numeração fixa de builds, scripts de migração defeituosos e ausência de testes automatizados para o comportamento tab-pop-to-top. Score: 52/100.
Token de autenticação é inserido diretamente na URL da WebView
securitysrc/components/home/ClubeWelcome.tsxA navegação para GeneralWebview monta `https://socio.cellarvinhos.com/loginWebview?email=${userEmail}&tokenVtex=${authCookie?.Value}`. O token e o e-mail passam a fazer parte da URL, podendo aparecer em histórico, logs, telemetria, relatórios de erro e redirecionamentos. Além disso, os valores não usam `encodeURIComponent`, então caracteres como `&`, `+`, `#` ou `=` podem corromper os parâmetros.
Transporte inseguro está habilitado globalmente em iOS e Android
securityapp.config.jsNo iOS, `NSAppTransportSecurity.NSAllowsArbitraryLoads` está definido como `true` em `infoPlist` e também repetido na configuração de `ios`. No Android, `usesCleartextTraffic: true` permite tráfego HTTP sem criptografia para todo o aplicativo.
Build de produção mantém configuração de push em modo de desenvolvimento
reliabilityapp.config.jsA configuração fixa `entitlements['aps-environment']` como `development` e o `onesignal-expo-plugin` usa `mode: 'development'`. O perfil production de `eas.json` não fornece configuração alternativa, portanto o mesmo app.config é usado no build de produção.
Push na branch development pode publicar OTA diretamente no canal production
reliability.eas/workflows/publish-development-updates.yml:14O job `dev_update_production` é executado em pushes para `development` quando a mensagem do último commit contém simultaneamente `update` e `production`; o destino configurado é `channel: production`. Não há aprovação, tag, branch protegida ou outro gate mostrado no workflow.
Verificação de atualização pode manter o aplicativo em tela vazia indefinidamente
reliabilityApp.tsxEnquanto `isCheckingUpdates` é verdadeiro, o componente retorna `null`. Esse estado só é liberado após os awaits sequenciais de `VersionCheck.needUpdate()`, `Updates.checkForUpdateAsync()` e, quando aplicável, `Updates.fetchUpdateAsync()`. O código não impõe timeout ou fallback caso uma dessas Promises permaneça pendente.
Builds de produção reutilizam números fixos de versão nativa
reliabilityeas.jsonO EAS usa `appVersionSource: 'local'` e o profile production define `autoIncrement: false`. Em `app.config.js`, `ios.buildNumber` e `android.versionCode` estão ambos fixos em `70`. Builds subsequentes preservam esses números e não podem ser submetidos como novas versões depois que o número for usado nas lojas.
Falha no carregamento das fontes impede a aplicação de sair do splash
reliabilityApp.tsxSomente o primeiro retorno de `useFonts` é capturado: `const [fontsLoaded] = useFonts(...)`. A renderização continua retornando `AnimatedSplash` enquanto `!fontsLoaded`, sem tratar o erro retornado pelo hook. Assim, uma falha definitiva de fonte não possui caminho de fallback.
Script de substituição nunca adiciona o import de AppScrollView após transformar o arquivo
maintainabilityreplace_scrollviews.jsO script primeiro substitui `<ScrollView` por `<AppScrollView` e depois verifica `if (!content.includes('AppScrollView'))` antes de adicionar o import. Após qualquer substituição, essa condição é necessariamente falsa, mesmo quando não existe import, deixando o arquivo transformado com identificador não definido.
Falha no AsyncStorage pode impedir o fechamento do modal
reliabilitysrc/components/home/SelecaoCupons/HowToUseCouponsModal.tsx`handleClose` aguarda `AsyncStorage.setItem` ou `removeItem` antes de chamar `onClose`, sem `try/finally`. Se a persistência rejeitar, `onClose()` não é executado. O `loadPref` também faz leitura sem tratamento de erro, podendo gerar rejeição não tratada.
Consulta da vitrine é criada mesmo para usuários que não podem visualizar o componente
performancesrc/components/home/MinhaVitrine.tsx`useAdegaProductsQuery(skus)` é chamado antes do retorno que verifica `user?.clube !== true` e outros critérios. Quando o usuário não possui SKUs, ainda é fornecida a lista padrão `869214074, 869214847, 869214391`, embora o componente possa retornar `null` logo depois.
Não há infraestrutura ou scripts de testes para validar o comportamento da branch
testingpackage.jsonOs scripts disponíveis incluem start, builds, submits e upload de sourcemaps, mas não existe script de teste, lint ou typecheck. As dependências também não mostram runner de testes. Entre os arquivos enviados não há teste para tab-pop-to-top, deep links, atualização OTA, push ou persistência do modal.
Cálculo de offset para PDP no BolaoButton é inalcançável
maintainabilitysrc/components/home/Bolao/BolaoButton.tsxO código calcula `isPDP`, `pdpOffset` e adiciona esse valor a `dynamicBottom`, mas posteriormente retorna `null` sempre que `currentRouteName !== 'Home'`. Portanto, quando a rota é `Produto`, o botão não é renderizado e o offset específico de PDP nunca é usado.