Achado — Comportamentos do ShowCaseDetailController não resolvidos para showCaseType = 4
Decisão do design doc afetada: #4 — Detalhe Condicional por showCaseType
Arquivo: lib/screens/show_case/show_case_detail/show_case_detail_controller.dart
Status: Resolvido
1. Semântica de "a data mudou" no enableEditButton
Requisito RF-04 AC10 / US CA-3: botão ATUALIZAR VITRINE "habilitado somente se a data de expiração mudou".
Getter atual (linha 87-90):
bool get enableEditButton => (hasNameChanged.value ||
hasProductsChanged.value ||
(expirationDate.value != null))
&& detail.value != null && detail.value!.showCaseItems.isNotEmpty;
expirationDate.value != null não compara com o valor original carregado (detail.value!.dateExpiration) — é só "o usuário tocou no campo de data e escolheu algo". Ou seja, hoje (para showCaseType = 1), se o vendedor abrir o seletor de data e escolher a mesma data que já estava salva, o botão já habilita mesmo assim. Essa é a semântica já existente, não uma introduzida por esta task.
Pergunta: para showCaseType = 4, queremos manter essa mesma semântica "tocou no campo = habilita" (igual ao que já existe para Store, sem mudança de comportamento), ou implementar uma comparação real (expirationDate.value != detail.value!.dateExpiration) só para SellerStock? Isso criaria uma pequena inconsistência de comportamento entre os dois tipos, mas atenderia ao AC de forma mais literal.
2. Guard showCaseItems.isNotEmpty e o caso de estoque zerado
O mesmo getter também exige detail.value!.showCaseItems.isNotEmpty para habilitar o botão. Para SellerStock, showCaseItems é o preview (até 4 itens) — se a loja estiver com zero produtos em estoque no momento da consulta, essa lista viria vazia e o botão ATUALIZAR VITRINE ficaria permanentemente desabilitado, mesmo que o vendedor altere a data de expiração.
Pergunta: esse guard deve ser ignorado para showCaseType = 4 (já que a existência de produtos no preview não tem relação com a possibilidade de atualizar a data), ou é um cenário aceitável/improvável de não tratar agora?
3. Sincronização do nome/título antes do GET de detalhe resolver
Em onInit() (linha 50-67):
arguments = Get.arguments as ShowCaseDetailScreenArguments;
nameController.text = arguments.catalogName; // valor síncrono, vindo da listagem
...
loadData(arguments); // GET assíncrono, só resolve depois
E na tela (show_case_detail_screen.dart:52): appBarTitle: controller.arguments.catalogName — o título da AppBar também usa o valor síncrono vindo da navegação (ShowCaseResponseItem.name da listagem), não o campo showCaseType/name do GET de detalhe (que só chega depois).
Pergunta: o contrato garante que, na listagem (v2), o campo name de uma vitrine SellerStock já vem como "Estoque da loja" desde o primeiro momento (antes mesmo do GET de detalhe)? Se sim, não há problema — arguments.catalogName já nasce correto e não há "flash" de texto errado. Se não houver essa garantia, a tela mostraria brevemente um título/nome incorreto até o GET de detalhe resolver e o branching por showCaseType ser aplicado.
4. Conteúdo do PUT quando showCaseType = 4
Contrato (frontend-contract-diff.md): "showCaseType = 4 (SellerStock) → API ignora todos os campos exceto dateExpiration".
O design doc mostra, na seção Data Models, um payload de exemplo com "showCaseItems": [], mas na seção de Implementação da Decisão #4 diz apenas "PUT envia showCaseType=4 + todos os campos". Como o updateShowCase() atual monta showCaseItems: detail.value!.showCaseItems.map((e) => e.productId).toList(), se reaproveitado sem alteração, o PUT enviaria os 4 productIds do preview (não uma lista vazia) — o que é inofensivo pois a API ignora o campo, mas diverge do exemplo [] documentado.
Pergunta: vale a pena forçar showCaseItems: [] explicitamente no PUT quando showCaseType == 4 (por clareza de intenção no código, já que esses IDs não representam a vitrine real), ou está tudo bem deixar o valor que já estiver carregado, já que a API ignora de qualquer forma?
Resolução
Ponto 1 (semântica de "a data mudou"): implementar comparação real (expirationDate.value != null && expirationDate.value != detail.value?.dateExpiration) para os dois tipos (Store e SellerStock), uniformizando o comportamento — isso corrige um bug de comportamento já existente hoje em Store, não só um requisito novo do SellerStock.
Ponto 2 (guard de estoque vazio): ignorar o guard showCaseItems.isNotEmpty quando showCaseType == 4. Uma loja com estoque zerado ainda deve poder atualizar a data de expiração da sua vitrine SellerStock.
Ponto 3 (sincronização nome/título): confirmado pelo usuário — o backend garante name = "Estoque da loja" já na listagem v2 para vitrines SellerStock. Sem risco de "flash" de texto errado; arguments.catalogName já nasce correto antes do GET de detalhe resolver. Nenhuma mudança necessária no fluxo de sincronização.
Ponto 4 (payload do PUT): forçar showCaseItems: [] explicitamente em updateShowCase() quando showCaseType == 4, para deixar explícito no código que os productIds do preview não representam a vitrine real.
Todos os 4 pontos confirmados com o usuário na sessão de grilling.