Requisitos — [Front] Novo layout do card de produto
Task #196866
Task pai: US 196869 ADRs relacionados: — Contrato de referência: cart-detail.json
Status: refinado Sessão de grilling: 25/06/2026
Visão geral
Criar um novo componente de card de produto para a tela de Status do Pedido do zzapp, com layout conforme Figma, substituindo CartStatusProductCard apenas na seção "Itens" do detalhe do pedido.
O componente legado (CartStatusProductCard) permanece no projeto sem alterações para as demais telas. A substituição global ocorrerá em task futura, após validação do novo layout.
O novo componente expõe factory methods para duas variantes — item do pedido e item recomendado — preparando a integração do bloco "Recomendados" (task 196865).
Componente AS-IS: CartStatusProductCard em lib/screens/cart_status/widgets/cart_status_product_card.dart
Tela: CartStatusDetailScreen → seção _ContentProducts ("Itens")
Premissas
- O card exibe valores unitários nas linhas Valor e Desconto, desconsiderando o campo
quantity. A quantidade é exibida apenas como informação (Qtd), sem multiplicar os valores de preço ou desconto. - O valor exibido na linha Desconto é sempre monetário (
R$), nunca percentual. Quandodiscountfor1(percentage), o sistema calcula o valor monetário equivalente antes de renderizar.
Papéis
| Papel | Responsabilidade |
|---|---|
| Vendedora | Visualizar itens do pedido e recomendações com layout atualizado na tela de Status do Pedido |
| Desenvolvedor Front-end | Criar o novo componente, factory de variantes, enum DiscountType, atualizar ProductCartDetail e integrar na seção "Itens" |
Requisitos
RF-01 — Novo componente com factory de variantes
User Story: Como desenvolvedor front-end, eu quero um novo componente de card com factory para variantes, para reutilizar o mesmo layout visual em itens do pedido e itens recomendados sem alterar o componente legado.
Acceptance Criteria:
WHENo novo componente for implementadoTHENo sistemaSHALLcriá-lo em arquivo separado deCartStatusProductCard, sem remover nem alterar o componente legado.WHENo novo componente for instanciadoTHENo sistemaSHALLexpor factory methods para as variantesorderItem(item do pedido) erecommended(item recomendado).WHENa tela de Status do Pedido exibir a seção "Itens"THENo sistemaSHALLutilizar exclusivamente o novo componente na varianteorderItem.WHENqualquer outra tela do app utilizar card de produto hojeTHENo sistemaSHALLcontinuar usandoCartStatusProductCardsem alteração.
Casos de Borda:
WHENa factory receber dados incompletos para renderização mínima (nome, imagem, sku)THENo componenteSHALLrenderizar os campos disponíveis sem quebrar o layout.
RF-02 — Layout visual conforme Figma
User Story: Como vendedora, eu quero visualizar os produtos com o novo layout de card para ter uma experiência visual atualizada e consistente com o design.
Acceptance Criteria:
WHENum card for renderizado na varianteorderItemTHENo sistemaSHALLexibir: thumbnail, nome do produto, SKU, quantidade (Qtd), tamanho (TAM), linha Valor, linha de desconto (label conformeDiscountType), e linha Preço final, conforme Figma e referências visuais.WHENum card for renderizado na varianterecommendedTHENo sistemaSHALLexibir: thumbnail, nome do produto, SKU, quantidade fixa 1, tamanho (TAM), linha Valor, linha de desconto (label conformeDiscountType), e linha Preço final, conforme Figma.WHENo card for exibido para pedidos com estoque da loja ou Prateleira InfinitaTHENo sistemaSHALLaplicar o mesmo layout base, sem distinção visual por modalidade de estoque no nível do card.WHENo novo layout for aplicadoTHENo sistemaSHALL NOTexibir a linha Remarcação (substituída pelo tiposale).
Referência visual:


RF-03 — Enum DiscountType e labels
User Story: Como vendedora, eu quero identificar o tipo de desconto aplicado a cada item, para compreender a composição do preço.
Acceptance Criteria:
WHENo novo componente for implementadoTHENo sistemaSHALLdefinir o enumDiscountTypecom os valoresfuncionario,manual,saleenone.WHENDiscountTypefornoneTHENo sistemaSHALLexibir o label "Desconto" com valor R$ 0,00.WHENDiscountTypeformanualTHENo sistemaSHALLexibir o label "Desconto manual".WHENDiscountTypeforfuncionarioTHENo sistemaSHALLexibir o label "Desconto funcionário".WHENDiscountTypeforsaleTHENo sistemaSHALLexibir o label "Desconto sale".
RF-04 — Valor exibido na linha de desconto (lógica comum)
User Story: Como vendedora, eu quero ver o valor do desconto formatado corretamente, para entender o abatimento aplicado ao item.
Acceptance Criteria:
WHENo item não possuir desconto aplicável (sem valor de abatimento)THENo sistemaSHALLexibir a linha de desconto com valor R$ 0,00, sem prefixo "-", na corZZColors.neutralDark(color-neutral-dark).WHENo campodiscountfor1(percentage) e o valor monetário calculado for maior que zeroTHENo sistemaSHALLcalcular o desconto comofullPrice × (discountValue / 100)(valor unitário, conforme premissa) e exibir como moeda (- R$ {valor calculado}), prefixado com "-", na corZZColors.successMedium(color-feedback-success-medium).WHENo campodiscountfor2(value) ediscountValuefor maior que zeroTHENo sistemaSHALLexibir o valor como moeda (- R$ {discountValue}), prefixado com "-", na corZZColors.successMedium(color-feedback-success-medium).WHENo valor calculado do desconto for menor ou igual a zero (incluindo casossalecomfullPrice - priceigual a zero)THENo sistemaSHALLexibir R$ 0,00, sem prefixo "-", na corZZColors.neutralDark(color-neutral-dark).WHENo desconto for do tiposaleefullPrice - pricefor maior que zeroTHENo sistemaSHALLexibir o valor como moeda (- R$ {fullPrice - price}), prefixado com "-", na corZZColors.successMedium(color-feedback-success-medium).
Nota: A linha de desconto nunca exibe percentual (%). O campo discountValue em modo percentage representa o percentual aplicado; o valor renderizado é sempre o equivalente monetário unitário.
RF-05 — Mapeamento discountOrigin para itens do pedido
User Story: Como desenvolvedor front-end, eu quero derivar o DiscountType a partir dos dados da API, para exibir o label correto em itens do pedido.
Acceptance Criteria:
WHENdiscountOriginforNoneTHENo sistemaSHALLdefinirDiscountTypecomonone.WHENdiscountOriginforMarkdownTHENo sistemaSHALLdefinirDiscountTypecomosale.WHENdiscountOriginforManualehasEmployeeDiscountforfalseTHENo sistemaSHALLdefinirDiscountTypecomomanual.WHENdiscountOriginforManualehasEmployeeDiscountfortrueTHENo sistemaSHALLdefinirDiscountTypecomofuncionario.WHENdiscountOriginforBothehasEmployeeDiscountforfalseTHENo sistemaSHALLdefinirDiscountTypecomomanual.WHENdiscountOriginforBothehasEmployeeDiscountfortrueTHENo sistemaSHALLdefinirDiscountTypecomofuncionario.WHENo valor do desconto for calculadoTHENo sistemaSHALLaplicar a lógica de RF-04 com base emdiscountediscountValuedeProductCartDetail.
Enum da API:
CartItemDiscountOrigin: None | Markdown | Manual | Both
Significado de Both: item estava remarcado e a vendedora alterou o valor do desconto.
RF-06 — Linhas de preço em itens do pedido (orderItem)
User Story: Como vendedora, eu quero ver o valor, desconto e preço final de cada item do pedido, para acompanhar a composição do pedido.
Acceptance Criteria:
WHENum cardorderItemfor renderizadoTHENo sistemaSHALLexibir Valor comfullPrice(valor unitário, conforme premissa).WHENum cardorderItemfor renderizadoTHENo sistemaSHALLexibir Preço final comtotal.WHENum cardorderItemfor renderizadoTHENo sistemaSHALLexibir Qtd comquantitye TAM comsize.
RF-07 — Lógica de desconto em itens recomendados (recommended)
User Story: Como vendedora, eu quero visualizar o desconto de itens recomendados de forma clara, para apresentar opções complementares à cliente.
Acceptance Criteria:
WHENum cardrecommendedfor renderizadoTHENo sistemaSHALLexibir quantidade fixa 1.WHENhasEmployeeDiscountfortrueTHENo sistemaSHALLdefinirDiscountTypecomofuncionarioe aplicar RF-04.WHENhasEmployeeDiscountforfalseediscountfor maior que0THENo sistemaSHALLdefinirDiscountTypecomomanuale exibir o desconto monetário conforme RF-04.WHENpricefor menor quefullPriceediscountfor0THENo sistemaSHALLdefinirDiscountTypecomosalee exibir na linha de desconto o valorfullPrice - price.WHENo valorfullPrice - pricefor menor ou igual a zero no casosaleTHENo sistemaSHALLexibir R$ 0,00 na linha de desconto, conforme RF-04.4.WHENnenhuma das condições acima se aplicarTHENo sistemaSHALLdefinirDiscountTypecomononee exibir R$ 0,00 na linha de desconto, conforme RF-04.1.
Exemplos de referência:
Item recomendado com desconto manual:
{
"discount": 2,
"discountValue": 159.90,
"fullPrice": 359.90,
"price": 279.90,
"hasEmployeeDiscount": false
}
Item recomendado com desconto sale:
{
"discount": 0,
"discountValue": 0.00,
"fullPrice": 359.90,
"price": 279.90,
"hasEmployeeDiscount": false
}
Item recomendado com desconto funcionário:
{
"discount": 1,
"discountValue": 40.00,
"fullPrice": 239.90,
"price": 239.90,
"hasEmployeeDiscount": true
}
RF-08 — Linhas de preço em itens recomendados (recommended)
User Story: Como vendedora, eu quero ver o valor de referência e o preço final de itens recomendados, para entender a proposta de compra.
Acceptance Criteria:
WHENum cardrecommendedfor renderizadoTHENo sistemaSHALLexibir Valor comfullPrice.WHENdiscountfor0(none) ou2(value)THENo sistemaSHALLexibir Preço final comprice.WHENdiscountfor1(percentage)THENo sistemaSHALLexibir Preço final calculado comofullPricemenos o valor percentual dediscountValue.WHENo desconto for do tiposale(RF-07.4)THENo sistemaSHALLexibir Preço final comprice.
RF-09 — Tag "Item recomendado adicionado ao pedido"
User Story: Como vendedora, eu quero identificar visualmente itens que foram recomendados e adicionados ao pedido pela cliente, para acompanhar a conversão de upsell.
Acceptance Criteria:
WHENfromRecommendationfortrueTHENo componenteSHALLexibir a tag "Item recomendado adicionado ao pedido" conforme Figma (faixa verde com ícone de confirmação).WHENfromRecommendationforfalseTHENo componenteSHALL NOTexibir a tag.WHENa tag for exibidaTHENo componenteSHALLcontrolar a renderização exclusivamente com base na propfromRecommendation, sem implementar a lógica de movimentação entre blocos (task 196865).
RF-10 — Atualização do model ProductCartDetail
User Story: Como desenvolvedor front-end, eu quero consumir os novos campos da API de detalhe do pedido, para alimentar o novo componente com dados corretos.
Acceptance Criteria:
WHENa resposta da API de detalhe do pedido for parseadaTHENo modelProductCartDetailSHALLmapear os camposdiscountOrigin,fromRecommendationehasEmployeeDiscountconforme cart-detail.json.WHENdiscountOriginfor deserializadoTHENo sistemaSHALLmapeá-lo para o enumCartItemDiscountOrigin(None,Markdown,Manual,Both).WHENcampos legados ausentes na respostaTHENo sistemaSHALLaplicar defaults seguros (discountOrigin: None,fromRecommendation: false,hasEmployeeDiscount: false).
RF-11 — Preservação de comportamentos AS-IS
User Story: Como vendedora, eu quero que a troca visual do card não altere o funcionamento da tela de acompanhamento do pedido.
Acceptance Criteria:
WHENo novo card for exibido na seção "Itens"THENo sistemaSHALL NOTadicionar ações de toque ou navegação no card (comportamento AS-IS: card semonTap).WHENo detalhe do pedido for carregadoTHENo sistemaSHALLmanter o fluxo atual de fetch viaCartController.findeFutureBuilder.WHENo pedido for de Prateleira Infinita (saleEcommerce: true)THENo sistemaSHALLmanter o comportamento AS-IS de ocultar o bloco "Resumo do pedido" sem alterar o card de produto.WHENa listagem de pedidos for atualizada ao retornar do detalheTHENo sistemaSHALLmanter o refresh existente emcartStoreController.findSearchCartStore.
Fora de Escopo
- Exibição e lógica do bloco "Recomendados" na tela (task 196865) — esta task entrega o componente com factory
recommended, mas não integra o bloco - Lógica de movimentação de item entre blocos "Recomendados" e "Itens" quando a cliente adiciona via zzlink (task 196865)
- Substituição de
CartStatusProductCardem outras telas do app (task futura, pós-validação) - Alterações no fluxo de criação de carrinho
- Alterações no zzlink
- Alterações de contrato ou lógica de backend
Dependências
| Dependência | Descrição | Status |
|---|---|---|
| API Cart Detail | Endpoint deve retornar discountOrigin, fromRecommendation, hasEmployeeDiscount em productCartDetails e cartItemRecommendations | Disponível (ver cart-detail.json) |
| Figma ZZAPP 2.0 | Layout visual do card e tag de recomendado | Disponível |
| Task 196865 | Integração do bloco "Recomendados" usando factory recommended | Pendente |
CartStatusProductCard (legado) | Mantido sem alteração nas demais telas | Existente |