ADR-001 — Uso de ILogQueueService para logs de negócio em handlers de query
Data: 2026-05-14
Status: Aceito
Contexto: Task #193232 — Ajuste endpoint GET api/payment/v2/{id} (GetInfo) — Upsell no fluxo de vendas
Autor: Pesquisa gerada via análise de código (OpenCode)
Contexto
Durante o desenvolvimento da Task #193232, surgiu a necessidade de registrar um evento de negócio no GetInfoQueryHandler: quando os itens recomendados de um carrinho não são retornados por expiração da janela de 1 hora, o sistema deve notificar o AllLogs.
O GetInfoQueryHandler é um handler de query (somente leitura) e, até este momento, não utilizava ILogQueueService. A dúvida era: devemos usar logging convencional (ILogger) ou a fila AllLogs (ILogQueueService)?
Decisão
Usar ILogQueueService com LogQueueMessageEvent.SaveLogOrderHistoryMessage, injetando-o no construtor do GetInfoQueryHandler.
O padrão de chamada é:
_ = _logQueueService.EnqueueAsync(
LogQueueMessageEvent.SaveLogOrderHistoryMessage(
_userProvider.GetSchemaName(),
order.Id,
$"Itens recomendados não retornados para CartId {cart.Id}: janela de 1 hora expirada."));
Justificativa
Por que ILogQueueService e não ILogger?
| Critério | ILogger | ILogQueueService (AllLogs) |
|---|---|---|
| Visibilidade para o negócio | Apenas infraestrutura/dev | Visível via sql para análise de vendas |
| Padrão adotado no checkout | Não usado para eventos de negócio | Padrão consolidado em todos os handlers de payment |
Rastreabilidade por paymentId | Não | Sim — o log é indexado por paymentId |
| Usado em handlers de query | Inédito | Primeira vez, mas sem impedimento técnico |
O AllLogs é o canal padrão para eventos de negócio rastreáveis por pedido na Checkout API. O uso de ILogger seria adequado apenas para diagnósticos técnicos de infraestrutura.
Por que é aceitável em um handler de query?
Handlers de query (CQRS) idealmente não produzem efeitos colaterais. No entanto, o envio para fila de log é um efeito colateral de observabilidade — não altera o estado do domínio nem da resposta. É fire-and-forget (_ = ...), portanto não bloqueia nem altera o resultado da query.
Esse padrão já é usado em serviços de suporte ao fluxo de pagamento (FinishOrderCommandHandler, FinishPaymentService) e é considerado aceitável pelo time.
Consequências
Positivas
- Log rastreável por
paymentIdno AllLogs, visível para suporte. - Consistência com o padrão do restante da Checkout API.
- Fire-and-forget não impacta performance do endpoint.
Negativas / Atenções
GetInfoQueryHandlerpassa a ter uma dependência a mais (ILogQueueService) — quebrando a pureza de query do CQRS.- Se a fila AllLogs estiver indisponível, o log é perdido silenciosamente (comportamento padrão da fila).
Mudanças de código implicadas
GetInfoQueryHandler.cs — adicionar ao construtor:
// Campo
private readonly ILogQueueService _logQueueService;
// Parâmetro no construtor
ILogQueueService logQueueService
// Atribuição no corpo do construtor
_logQueueService = logQueueService;
Referências
- Pesquisa: padrão de uso do ILogQueueService
coezzion-service-checkout/src/Checkout.API/Application/Messages/Commands/FinishCommands/FinishOrderCommandHandler.cscoezzion-service-checkout/src/Checkout.Infraestructure/Payment/FinishPaymentService.cscoezzion-service-checkout/src/Checkout.Domain/Events/LogQueueMessageEvent.cs