Skip to main content

Requirements Document

Task: task-194883-cart-api-remove-item.md Contexto: CONTEXT Contexto US: US 194871 — MVP Upsell (Pedido) Pesquisa tecnica: pesquisa-remove-recommended-item.md ADRs: ADR-008

Status: refinado
Sessão de grilling: 2026-05-15, 2026-06-19


Endpoint interno da Cart API para remover um item recomendado de um carrinho existente. O endpoint DELETE api/cart/{cartId}/items/{cartItemId} é chamado exclusivamente pelo checkout service via x-api-key: "internal". A remoção aplica soft-delete no item, desvincula a recomendação associada (CartItemId = null) e recalcula os totais do cart, permitindo que a recomendação fique disponível para re-adição futura.

O endpoint segue semântica idempotente: se o cart ou item não existe (ou já foi removido), retorna 200 silencioso — o estado desejado já foi alcançado.

Glossary

  • Cart_API: Serviço responsável por gerenciar carrinhos de compras (coezzion-service-cart)
  • Checkout_Service: Serviço consumidor exclusivo deste endpoint (coezzion-service-checkout)
  • CartModel: Entidade que representa o carrinho, contendo coleções de CartItems e CartItemRecommendations
  • CartItemsModel: Entidade que representa um item do carrinho, com propriedade FromRecommendation indicando origem
  • CartItemRecommendationModel: Entidade que representa uma recomendação de item vinculada ao carrinho; campo CartItemId nullable indica se a recomendação foi efetivada
  • RemoveCartItemCommand: Command DTO contendo CartId e CartItemId, ambos inteiros vindos da rota
  • BaseResult: Objeto padrão de resposta de negócio da Cart API; quando válido sem erros produz HTTP 200, quando contém erros produz HTTP 400
  • ApiKey_Internal: Chave de autenticação configurada em appsettings.json para chamadas internas entre serviços
  • CartService: Serviço de aplicação que orquestra commands via métodos Handle sobrecarregados
  • RevertRecommendedItem: Método de domínio em CartModel que executa soft-delete do item, desvincula a recomendação e recalcula totais
  • SaleEcommerce: Flag booleana em CartModel que indica se o pedido é do tipo e-commerce (operação não permitida para este endpoint)

Requirements

Requisito 1: Autenticação via ApiKey

User Story: Como checkout service, quero chamar a Cart API sem JWT de usuário, para que eu possa remover itens recomendados do carrinho sem depender de contexto de sessão do cliente.

Critérios de Aceite

  1. WHEN uma requisição chega com header x-api-key contendo o valor correspondente à ApiKey_Internal, THE Cart_API SHALL processar a requisição normalmente
  2. WHEN uma requisição chega sem header x-api-key, THE Cart_API SHALL retornar HTTP 401
  3. WHEN uma requisição chega com header x-api-key contendo valor diferente da ApiKey_Internal, THE Cart_API SHALL retornar HTTP 401
  4. WHEN uma requisição contém header Authorization com Bearer token, THE Cart_API SHALL ignorar o token e autenticar exclusivamente pela ApiKey_Internal

Requisito 2: Contrato do Endpoint e Command

User Story: Como checkout service, quero um endpoint DELETE api/cart/{cartId}/items/{cartItemId} sem body, para que eu possa remover um item de um cart existente usando apenas identificadores na rota.

Critérios de Aceite

  1. WHEN uma requisição DELETE api/cart/{cartId}/items/{cartItemId} chega com ApiKey_Internal válida, THE Cart_API SHALL aceitar a requisição e iniciar o processamento
  2. WHEN o cartId na rota não é um inteiro válido, THE Cart_API SHALL retornar HTTP 400
  3. WHEN o cartItemId na rota não é um inteiro válido, THE Cart_API SHALL retornar HTTP 400
  4. THE Cart_API SHALL criar o RemoveCartItemCommand com CartId e CartItemId extraídos dos parâmetros da rota, sem desserialização de body

Requisito 3: Busca do Carrinho

User Story: Como Cart API, quero buscar o carrinho com suas recomendações e itens em uma única query com tracking, para que eu possa validar o estado e persistir alterações via EF Core change tracking.

Critérios de Aceite

  1. WHEN o endpoint é chamado com cartId válido, THE Cart_API SHALL buscar o CartModel pelo cartId via GetByIdWithRecommendationsAsync incluindo as coleções CartItems e CartItemRecommendations com tracking habilitado
  2. WHEN o CartModel não é encontrado para o cartId informado, THE Cart_API SHALL retornar HTTP 200 sem corpo e sem erros (idempotente)
  3. WHEN o CartModel é encontrado, THE Cart_API SHALL prosseguir com a validação de SaleEcommerce

Requisito 4: Validação de SaleEcommerce

User Story: Como Cart API, quero rejeitar operações em carts do tipo e-commerce, para que este endpoint interno seja utilizado apenas em pedidos do tipo venda assistida.

Critérios de Aceite

  1. WHEN o CartModel é encontrado e o campo SaleEcommerce é true, THE Cart_API SHALL retornar HTTP 400 com mensagem "Operacao nao disponivel para este tipo de pedido"
  2. WHEN o CartModel é encontrado e o campo SaleEcommerce é false, THE Cart_API SHALL prosseguir com a busca do item

Requisito 5: Busca do Item no Carrinho (Idempotente)

User Story: Como Cart API, quero localizar o item na coleção do cart carregado, para que eu possa validar sua origem antes de removê-lo.

Critérios de Aceite

  1. WHEN o CartModel é validado, THE Cart_API SHALL buscar o CartItemsModel com Id igual ao cartItemId na coleção CartItems do CartModel carregado
  2. WHEN o CartItemsModel não é encontrado na coleção (inexistente, já soft-deletado pelo EF global query filter, ou pertencente a outro cart), THE Cart_API SHALL retornar HTTP 200 sem corpo e sem erros (idempotente)
  3. WHEN o CartItemsModel é encontrado na coleção, THE Cart_API SHALL prosseguir com a validação de FromRecommendation

Requisito 6: Validação de Origem do Item (FromRecommendation)

User Story: Como Cart API, quero garantir que apenas itens originados de recomendações possam ser removidos por este endpoint, para que itens adicionados manualmente pelo vendedor não sejam removidos inadvertidamente.

Critérios de Aceite

  1. WHEN o CartItemsModel é encontrado e o campo FromRecommendation é false, THE Cart_API SHALL retornar HTTP 400 com mensagem "Item nao originado de recomendacao"
  2. WHEN o CartItemsModel é encontrado e o campo FromRecommendation é true, THE Cart_API SHALL prosseguir com a remoção do item

Requisito 7: Reverter Item Recomendado

User Story: Como Cart API, quero aplicar soft-delete no item, desvincular a recomendação e recalcular os totais do cart, para que o estado do carrinho permaneça consistente e a recomendação fique disponível para re-adição futura.

Critérios de Aceite

  1. WHEN o item é válido com FromRecommendation igual a true, THE Cart_API SHALL chamar RevertRecommendedItem no CartModel passando o cartItemId
  2. WHEN RevertRecommendedItem é executado, THE Cart_API SHALL garantir que o CartItemsModel recebe soft-delete via Delete() (campo DateDeleted preenchido)
  3. WHEN RevertRecommendedItem é executado, THE Cart_API SHALL garantir que o CartItemRecommendationModel vinculado tem o campo CartItemId setado para null
  4. WHEN RevertRecommendedItem é executado, THE Cart_API SHALL garantir que os totais do CartModel são recalculados excluindo itens com DateDeleted preenchido

Requisito 8: Persistência e Resposta

User Story: Como Cart API, quero persistir o carrinho atualizado de forma atômica e invalidar o cache, para que o estado do banco permaneça consistente e leituras subsequentes reflitam a remoção.

Critérios de Aceite

  1. WHEN RevertRecommendedItem é concluído, THE Cart_API SHALL chamar Update no repositório de cart seguido de SaveAsync para persistir as alterações
  2. WHEN Update é chamado no repositório, THE Cart_API SHALL invalidar automaticamente o cache do cart (comportamento já implementado no repositório)
  3. WHEN a persistência é bem-sucedida, THE Cart_API SHALL retornar HTTP 200 sem corpo na resposta
  4. IF ocorre erro inesperado durante a persistência, THEN THE Cart_API SHALL retornar HTTP 400 com mensagem "Erro interno ao processar a requisicao"