Task #194883 — Cart API: Endpoint para Remover Item de Cart Existente
Task pai: #194883 — [Back] 05 - Cart API: Remove Item de cart existente Contexto: US 194871 — MVP Upsell (Pedido)
Status do refinamento: concluido Requisitos EARS: task-194883-cart-api-remove-item-requisitos.md Pesquisa tecnica: pesquisa-remove-recommended-item.md ADRs: ADR-008
Contexto
O endpoint DELETE api/payment/v2/{id}/remove-recommended-item do checkout service precisa chamar a Cart API para remover um item do cart. A Cart API nao possui hoje um endpoint de remocao de item individual — a unica remocao existente e o DELETE api/cart que deleta o cart inteiro.
Esta task cria o endpoint interno que sera chamado exclusivamente pelo checkout service via ApiKey "internal".
Endpoint
DELETE api/cart/{cartId}/items/{cartItemId}
x-api-key: {internal api key}
Sem body.
Autenticacao
[AllowAnonymous] + [UseApiKey("internal")] + [AddSchema] — mesmo padrao do POST api/cart/{cartId}/items.
Sem JWT. A chamada vem exclusivamente do checkout service.
Fluxo do Handler
1. Buscar cart via GetByIdWithRecommendationsAsync(cartId)
2. Cart null? → 200 silencioso (idempotente)
3. SaleEcommerce == true? → 400 "Operacao nao disponivel para este tipo de pedido"
4. Buscar item em cart.CartItems por Id == cartItemId
5. Item null? → 200 silencioso (idempotente)
6. FromRecommendation == false? → 400 "Item nao originado de recomendacao"
7. cart.RevertRecommendedItem(cartItemId) [soft-delete + desvincula recomendação + recalcula total]
8. _cartRepository.Update(cart) + SaveAsync()
9. Erro persistência? → 500 "Erro interno ao processar a requisicao"
10. Sucesso → 200 sem body
Responsabilidades da Cart API
- Buscar o cart pelo
cartIdviaGetByIdWithRecommendationsAsync(tracking)- Retornar
200silencioso se nao encontrado (idempotente)
- Retornar
- Validar
SaleEcommerce == false- Retornar
400se e-commerce
- Retornar
- Buscar o
CartItempelocartItemIddentro da colecao do cart (EF global query filter exclui soft-deletados automaticamente)- Retornar
200silencioso se nao encontrado (idempotente)
- Retornar
- Validar que
item.FromRecommendation == true- Retornar
400se o item nao e originado de recomendacao
- Retornar
- Chamar
cart.RevertRecommendedItem(cartItemId)que executa:item.Delete()(soft-delete viaBaseEntity.Delete())- Desvincula a
CartItemRecommendationModel(CartItemId = null) para liberar re-adição CalculateTotal()(já filtraDateDeleted == null)
- Persistir via
Update(cart)+SaveAsync()e retornar200
A validacao de
PaymentStatus(cart nao pago) nao e responsabilidade da Cart API — e feita pelo checkout service antes de chamar este endpoint. A remocao e idempotente: se o item ja foi removido ou nao existe, retorna200silencioso.
Saida
| Código | Situação |
|---|---|
200 | Item removido com sucesso |
200 | Cart não encontrado (idempotente) |
200 | Item não encontrado — inexistente, já soft-deletado ou outro cart (idempotente) |
400 | SaleEcommerce == true — "Operacao nao disponivel para este tipo de pedido" |
400 | FromRecommendation == false — "Item nao originado de recomendacao" |
401 | ApiKey ausente ou inválida |
500 | Erro inesperado na persistência — "Erro interno ao processar a requisicao" |
Artefatos
Escopo: coezzion-service-cart
| Artefato | Tipo |
|---|---|
Cart.Domain/Commands/RemoveCartItemCommand.cs | Novo |
Cart.Domain/Services/ICartService.cs | Modificar |
Cart.API/Application/CartService.cs | Modificar |
Cart.API/Controllers/CartController.cs | Modificar |
Cart.UnitTests/Application/Commands/RemoveCartItemHandlerTests.cs | Novo |
Já implementado: coezzion-db-core (nao mexer)
| Artefato | Status |
|---|---|
CartModel.RevertRecommendedItem(int cartItemId) | ✅ Implementado |
CartModel.CalculateTotal() — filtra DateDeleted == null | ✅ Implementado |
CartItemsModel.FromRecommendation (bool) | ✅ Existe e mapeado |
Arquivos desta pasta
| Arquivo | Descricao |
|---|---|
task-194883-cart-api-remove-item.md | Este arquivo — sumario, indice da task e fluxo do endpoint |
task-194883-cart-api-remove-item-requisitos.md | Documento de requisitos EARS (pt-BR): REQs, respostas HTTP, fluxo do handler, questoes fechadas |