Skip to main content

Documento de Requisitos — Passar a receber o RecommendationsId (App)

Tarefa: #196024 Contexto: Sequência de implementação #6 Refinamento: Grill session 12/06/2026


Visão Geral

Ajustar o UpsellRecommendationController (App zzapp) para consumir o novo formato de resposta do BFF (POST bff/customer-product-recommendation/{codeStore}/{cpf}), extrair o recommendationsId retornado pelo servidor e repassá-lo ao criar o carrinho via POST api/cart.

Mudança na resposta consumida:

AntesDepois
[ { id, name, sku, ... } ]{ recommendationsId: "...", items: [ { id, name, sku, ... } ] }

Escopo restrito: apenas o fluxo de upsell (FLOW B) — UpsellRecommendationController. O fluxo de recomendação de produtos (ProductRecommendationProductsController, endpoint /bff/recommend-customer) não é alterado.

Papéis Envolvidos

PapelResponsabilidade
Desenvolvedor Front-endAlterar deserialização da resposta e extração do recommendationsId no UpsellRecommendationController

Requisitos Funcionais

RF-01 — Detecção do formato da resposta

História de Usuário: Como App, quero interpretar corretamente ambos os formatos de resposta do BFF, para não quebrar durante a transição entre versões do backend.

Critérios de Aceitação:

  1. WHEN a resposta do BFF for um Map contendo a chave items THEN o sistema SHALL tratá-la como o novo formato ({ recommendationsId, items })
  2. WHEN a resposta do BFF for um List (formato legado) THEN o sistema SHALL tratá-la como o formato antigo (array de itens, sem recommendationsId)
  3. WHEN o formato for detectado como legado THEN o sistema SHALL logar um warning e gerar recommendationsId local (UUID v4) como fallback

Casos de Borda:

  • Resposta null ou string vazia "": comportamento atual mantido — limpar recommendedItems

RF-02 — Extração do recommendationsId do novo formato

História de Usuário: Como App, quero capturar o recommendationsId gerado pelo BFF, para rastrear o fluxo de upsell ponta a ponta com o identificador do servidor.

Critérios de Aceitação:

  1. WHEN a resposta estiver no novo formato (Map com chave items) THEN o sistema SHALL extrair recommendationsId do mapa da resposta
  2. WHEN recommendationsId estiver presente e não-vazio THEN o sistema SHALL armazená-lo em UpsellRecommendationController.recommendationsId e em CartDTO.recommendationsId via addRecommendedItemsCached
  3. WHEN recommendationsId estiver ausente ou null no mapa da resposta THEN o sistema SHALL gerar recommendationsId local (UUID v4) como fallback e logar warning
  4. WHEN a lista items estiver vazia ([]) mas recommendationsId estiver presente THEN o sistema SHALL armazenar o recommendationsId mesmo sem itens recomendados

Casos de Borda:

  • recommendationsId com string vazia "": tratar como ausente (fallback UUID local)

RF-03 — Deserialização dos itens no novo formato

História de Usuário: Como App, quero extrair os itens recomendados do novo wrapper, mantendo o mesmo contrato de cada item individual.

Critérios de Aceitação:

  1. WHEN a resposta estiver no novo formato THEN o sistema SHALL extrair a lista da chave items e deserializar cada elemento com UpsellRecommendationItem.fromJson
  2. WHEN a resposta estiver no formato legado THEN o sistema SHALL manter a deserialização atual ((response as List).map(...))
  3. WHEN deserializando itens THEN o sistema SHALL manter o limite de 3 itens (take(3) — definição de produto)
  4. WHEN deserializando itens THEN o sistema SHALL manter a validação de cartIdLocal para evitar race condition (o carrinho ativo pode ter mudado durante a chamada HTTP)

Casos de Borda:

  • Nenhum — o contrato de cada UpsellRecommendationItem não muda

RF-04 — Comportamento em erros HTTP

História de Usuário: Como App, quero lidar com erros do BFF sem quebrar o fluxo de venda, mantendo comportamento retrocompatível.

Critérios de Aceitação:

  1. WHEN o BFF retornar erro HTTP (400, 404, 500, etc.) THEN o sistema SHALL manter o comportamento atual do bloco catch — setar hasError = true sem tentar extrair recommendationsId
  2. WHEN ocorrer erro THEN o recommendationsId no controller SHALL permanecer null
  3. WHEN o carrinho for enviado sem recommendationsId (campo null no CartDTO) THEN o toJson() SHALL omitir o campo do payload (comportamento atual mantido)

Casos de Borda:

  • O BFF, conforme Task #196023 RF-06, não retorna o wrapper { recommendationsId, items } em erros — retorna o erro AS IS

RF-05 — Preservação do recommendationsId no CartDTO

História de Usuário: Como App, quero que o recommendationsId trafegue junto ao carrinho até o POST api/cart, sem alterações no contrato do payload.

Critérios de Aceitação:

  1. WHEN CartDTO.recommendationsId for não-nulo THEN o toJson() SHALL incluir o campo "recommendationsId" com o valor
  2. WHEN CartDTO.recommendationsId for null THEN o toJson() SHALL omitir o campo (retrocompatível)
  3. WHEN o cart for persistido localmente THEN toJsonLocal() SHALL incluir o campo (se não-nulo) — comportamento atual mantido
  4. WHEN o cart for restaurado de persistência local THEN fromJson() SHALL ler o campo recommendationsId — comportamento atual mantido

Casos de Borda:

  • Nenhuma alteração necessária — CartDTO já suporta o campo

RF-06 — Comportamento do retry

História de Usuário: Como App, quero que o retry de recomendação obtenha um novo recommendationsId do BFF.

Critérios de Aceitação:

  1. WHEN o usuário acionar retry THEN o sistema SHALL resetar recommendationsId para null e hasLoadedRecommendations para false (comportamento atual)
  2. WHEN o novo fetch retornar sucesso THEN o sistema SHALL capturar o novo recommendationsId do BFF (aplicando RF-01 e RF-02)

Casos de Borda:

  • Comportamento atual mantido, sem alterações no método retry()

Fora de Escopo

  • Alterações no fluxo de recomendação de produtos (ProductRecommendationProductsController, endpoint /bff/recommend-customer)
  • Reset de hasLoadedRecommendations ao alterar itens do carrinho (mantido comportamento atual — recomendações não são re-buscadas após mudanças no carrinho)
  • Alterações no Portal (tratado na Task #196025)
  • Alterações no POST api/cart (tratado na Task #196022)
  • Alterações no UpsellRecommendationItem.fromJson (contrato de item individual não muda)

Dependências

DependênciaDescriçãoStatus
Task #196023BFF deve retornar RecommendationsResponse { recommendationsId, items }Pendente
Task #196022POST api/cart deve aceitar recommendationsIdPendente

Questões em Aberto

(nenhuma — todas resolvidas durante grill session 12/06/2026)

Decisões da Grill Session

DecisãoResolução
Formato da respostaDetecção automática (Map com items = novo; List = legado)
Fallback recommendationsIdUUID local quando ausente, com log de warning
Armazenar com items vaziosSim, se recommendationsId estiver presente
EscopoApenas FLOW B (upsell), não FLOW A
Erro HTTPNão extrair recommendationsId, manter comportamento atual
Re-busca ao mudar carrinhoNão — manter comportamento atual
Nome do campo no cartrecommendationsId (camelCase), omitido quando null