Skip to main content

Code Review — US 196053 (zzapp — Criação de vitrines com estoque completo da loja)

Branch: feat/196053_vitrine_estoque_loja
Base: origin/develop (merge-base cf3c1caa)
Data: 2026-07-07
Escopo: 27 arquivos, +1363 / −138 linhas


Summary

A branch entrega o fluxo de Vitrine de Estoque da Loja (SellerStock) para a US 196053: bottom sheet de escolha de modalidade (CA-1), listagem v2 com hasSellerStock (CA-2), criação automática via POST sem seleção de produtos, tela de detalhe adaptada (nome fixo, produtos somente leitura, data de expiração editável), eventos Rewards 71–73 (CA-6), migração de ShowCaseType para enum string da API e suíte de testes unitários/widget para modelos, ApiUtils e ShowCaseDetailLayout.

Contra os critérios de aceite CA-1 a CA-6, o fluxo vendedor no app está majoritariamente correto: bottom sheet, bloqueio com mensagem quando já existe vitrine SellerStock, criação sem etapa de produtos e rewards integrados. Os principais riscos são bugs de navegação/back (PopScope sem handler de gesto do sistema, rota inconsistente após exclusão), impossibilidade de salvar alteração de data de expiração em SellerStock (CA-3), retry que pode criar vitrine duplicada (CA-2), e lacunas de cobertura em controllers/telas. CA-4 e a URL distinta para analytics (CA-5) dependem de web/back-end; no app, falta evento Firebase na criação SellerStock.

Veredito: Solicitar alterações antes do merge — 6 bugs identificados (navegação, persistência de expiração, retry duplicado). Nenhum bloqueio de contrato de API nos modelos testados; testes novos são sólidos nos arquivos cobertos.


Validação dos Critérios de Aceite

CritérioStatusEvidência / Observação
CA-1 — Bottom sheet de modalidadeAtendidoShowCaseTypeSelectionBottomSheet em my_show_case_controller.dart:89 com opções "Vitrine do estoque da loja" e "Criar nova vitrine".
CA-2 — Uma vitrine ativa por vendedorParcialhasSellerStock da API v2 bloqueia opção com mensagem (show_case_type_selection_bottom_sheet.dart:60-65). Risco de duplicata no retry (Issue 3) e flag desatualizada pós-criação (Issue 10).
CA-3 — Regras SellerStockParcialCriação sem produtos (createAndLoad), nome fixo, produtos não editáveis (hideProductActions). Data editável no header mas botão "ATUALIZAR VITRINE" oculto para SellerStock (Issue 1).
CA-4 — Experiência da clienteFora do escopo (app)Abas "Recomendados"/"Mais produtos" são web; não avaliado neste diff.
CA-5 — Identificação/analyticsParcialshowCaseType no request/response; rewards OK. URL vem da API. Sem FirebaseService.logCreateCatalog na criação SellerStock (Issue 9).
CA-6 — RewardsAtendidoCreateSellerStockShowcaseRewardEvent, CopiedSellerStockShowcaseLinkRewardEvent, SharedSellerStockShowcaseLinkRewardEvent (IDs 71–73) em show_case_detail_controller.dart.

Cobertura de Código vs develop

Comparação gerada com flutter test --coverage em ambas as branches (mesmo ambiente local).

Suite de testes

Métricadevelopfeat/196053_vitrine_estoque_lojaDelta
Testes executados449479+30
Arquivos de teste novos7ver lista abaixo

Novos arquivos de teste (+1181 linhas):

  • test/models/show_case/create_show_case_request_test.dart (61 linhas)
  • test/models/show_case/show_case_detail_response_test.dart (124 linhas)
  • test/models/show_case/show_case_list_v2_response_test.dart (113 linhas)
  • test/models/show_case/show_case_type_test.dart (59 linhas)
  • test/models/show_case/update_show_case_request_test.dart (66 linhas)
  • test/screens/show_case/widgets/show_case_detail_layout_test.dart (130 linhas)
  • test/shared/utils/api_utils_test.dart (628 linhas)

Cobertura global (lcov)

BranchLinhas cobertasLinhas rastreadas%
develop3.10545.9916,75%
feat/196053_vitrine_estoque_loja3.28946.2327,11%
Delta+184+241+0,36 pp

Cobertura nos arquivos alterados (lib/)

ArquivodevelopfeatDelta
create_show_case_request.dart0,0% (0/14)100% (15/15)+100 pp
show_case_detail_response.dart0,0% (0/77)43,8% (35/80)+43,8 pp
show_case_list_v2_response.dart— (novo)54,2% (13/24)novo
update_show_case_request.dart0,0% (0/16)100% (17/17)+100 pp
show_case_type.dart— (novo)100% (12/12)novo
show_case_detail_layout.dart1,7% (1/58)89,1% (57/64)+87,3 pp
api_utils.dart98,6% (210/213)98,6% (210/213)~0 pp
show_case_type_selection_bottom_sheet.dart— (novo)0,0% (0/43)novo
show_case_detail_controller.dart0,0% (0/148)0,0% (0/231)~0 pp
show_case_detail_screen.dart0,0% (0/90)0,0% (0/104)~0 pp
my_show_case_controller.dart0,0% (0/35)0,0% (0/53)~0 pp
show_case_search_products_controller.dart0,0% (0/304)0,0% (0/305)~0 pp
reward_events_ids_enum.dart0,0% (0/64)0,0% (0/67)~0 pp
tag.dart5,0% (1/20)3,3% (1/30)−1,7 pp

Análise de cobertura

Pontos fortes: modelos de request/response, enum ShowCaseType, ApiUtils (URLs v2) e ShowCaseDetailLayout com cobertura excelente (43–100%). A suíte ganhou 30 testes e +1181 linhas de teste focadas na feature.

Lacunas:

  • Controllers e telas de detalhe/listagem permanecem sem cobertura (~0%) — fluxos CA-1/CA-2/CA-3 não são exercitados end-to-end.
  • show_case_type_selection_bottom_sheet.dart e eventos Rewards SellerStock sem testes.
  • Cobertura global sobe pouco (+0,36 pp) porque a base do app é grande; o ganho real está nos modelos e layout extraídos.

Issues

Issue 1 — Severity: bug

  • File: lib/screens/show_case/show_case_detail/show_case_detail_screen.dart:231
  • Description: CA-3 permite editar a data de expiração (máx. 30 dias) para SellerStock, mas o footer oculta "ATUALIZAR VITRINE" quando isSellerStock é true, enquanto o campo de data permanece editável. O usuário altera a data localmente sem poder persistir, exceto via diálogo de saída.
  • Suggestion: Exibir "ATUALIZAR VITRINE" para SellerStock quando apenas expirationDate mudou, ou auto-salvar na alteração de data.
  • Status: open

Issue 2 — Severity: bug

  • File: lib/screens/show_case/widgets/show_case_detail_layout.dart:106
  • Description: PopScope usa canPop: false quando onPopScope é fornecido, mas onPopInvokedWithResult não está ligado. Apenas o botão da app-bar chama onPopScope; o back do sistema/gesto fica bloqueado sem handler.
  • Suggestion: Adicionar onPopInvokedWithResult para disparar o mesmo fluxo de alterações não salvas e navegação.
  • Status: open

Issue 3 — Severity: bug

  • File: lib/screens/show_case/show_case_detail/show_case_detail_controller.dart:227
  • Description: retryCreate() sempre chama createAndLoad() (novo POST). Se o POST inicial teve sucesso mas loadData() falhou, o retry cria segunda vitrine SellerStock, violando CA-2.
  • Suggestion: Se arguments.catalogId != null, retry deve apenas chamar loadData(arguments).
  • Status: open

Issue 4 — Severity: bug

  • File: lib/screens/show_case/show_case_detail/show_case_detail_controller.dart:337
  • Description: backToShowCasePage() navega para AppRoutes.showCase, enquanto onPopScope usa AppRoutes.storeShowCaseList. Após exclusão, o usuário pode cair na rota errada.
  • Suggestion: Alinhar backToShowCasePage() com onPopScope.
  • Status: open

Issue 5 — Severity: bug

  • File: lib/screens/show_case/show_case_detail/show_case_detail_controller.dart:491
  • Description: Em onPopScope, ao escolher "Salvar", updateShowCase é aguardado mas Get.until executa mesmo se a validação/salvamento falhar. Alterações podem ser descartadas silenciosamente.
  • Suggestion: Navegar somente após salvamento bem-sucedido. Replicar em recommend_show_case_detail_controller.dart:274.
  • Status: open

Issue 6 — Severity: bug

  • File: lib/screens/show_case/search/show_case_search_products_controller.dart:463
  • Description: Future.delayed(Duration(seconds: 1)) hard-coded antes do bottom sheet de sucesso para contornar race com loading/POST. UX lenta e ainda sujeita a falhas intermitentes.
  • Suggestion: Corrigir a causa raiz (ordem de dismiss do loader vs. exibição do bottom sheet) em vez de delay fixo.
  • Status: open

Issue 7 — Severity: suggestion

  • File: lib/screens/show_case/widgets/show_case_type_selection_bottom_sheet.dart:62
  • Description: Descrição da opção "Vitrine do estoque da loja" (quando habilitada) repete o copy de vitrine personalizada, confundindo o usuário.
  • Suggestion: Copy específico sobre compartilhar o catálogo completo da loja sem curadoria manual.
  • Status: open

Issue 8 — Severity: suggestion

  • File: lib/screens/show_case/show_case_detail/show_case_detail_controller.dart:130
  • Description: productCountText para SellerStock usa "produtos recomendados", inadequado para estoque completo da loja.
  • Suggestion: Usar "produtos disponíveis" ou "produtos no estoque da loja".
  • Status: open

Issue 9 — Severity: suggestion

  • File: lib/screens/show_case/show_case_detail/show_case_detail_controller.dart:202
  • Description: Criação de vitrine personalizada registra FirebaseService.logCreateCatalog('fast'), mas createAndLoad() SellerStock não registra evento equivalente (CA-5).
  • Suggestion: Adicionar evento Firebase/analytics distinto para criação SellerStock.
  • Status: open

Issue 10 — Severity: suggestion

  • File: lib/screens/show_case/show_case/my_show_case_controller.dart:141
  • Description: hasSellerStock só atualiza no _load() da listagem. Após criar SellerStock, o bottom sheet pode ainda permitir nova tentativa até o refetch.
  • Suggestion: Atualizar hasSellerStock otimisticamente após criação bem-sucedida.
  • Status: open

Issue 11 — Severity: nit

  • File: lib/theme_widgets/tag/tag.dart:60
  • Description: Refatoração global de ZzTag (altura fixa, ZzTagSize.sm default) pode alterar layout de tags existentes no app.
  • Suggestion: Validar regressão visual ou limitar mudança ao tema newFeature.
  • Status: open

Issue 12 — Severity: nit

  • File: lib/screens/show_case/recommend_show_case_detail/recommend_show_case_detail_controller.dart:259
  • Description: Indentação inconsistente no método onPopScope introduzido no refactor.
  • Suggestion: Rodar formatter nos arquivos alterados.
  • Status: open

Contagem de Issues

SeveridadeQuantidade
bug6
suggestion4
nit2
Total12

Recomendações antes do merge

  1. Bugs de navegação e persistência — Prioridade alta: corrigir Issues 1–5 (expiração SellerStock, PopScope, retry, rotas pós-delete, salvamento no pop).
  2. CA-2 — Garantir que retry e flag hasSellerStock não permitam segunda criação (Issues 3 e 10).
  3. Testes de controller/tela — Adicionar testes para ShowCaseDetailController, bottom sheet e fluxo de criação SellerStock.
  4. Escopo — Revisar impacto global da refatoração de ZzTag (Issue 11) e remover Future.delayed (Issue 6).
  5. QA manual — Validar back do sistema Android, exclusão de vitrine, edição de data SellerStock e copy do bottom sheet.

Referências

  • User Story: 196053.md
  • Diff: feat/196053_vitrine_estoque_loja vs origin/develop
  • Review ID interno: 6fa9db99