Visão geral
Painel de métricas em tempo real: outro serviço do backend alimenta uma métrica via gRPC (contrato tipado, HTTP/2), que é transmitida instantaneamente via SignalR (WebSocket) a todo cliente conectado no grupo daquela loja. O backplane de Redis permite escalar horizontalmente — cliente conectado na instância B recebe métrica que chegou via gRPC na instância A, sem nenhuma delas saber da existência da outra.
Como funciona
IngestaoMetricasService (implementação do serviço gRPC) valida a métrica no domínio puro
(Metrica.Criar, sem dependência de infraestrutura) e, se válida, transmite pro grupo SignalR
da loja. Grupo por loja, não broadcast global: cada cliente só vê o que pediu pra ver. Erro de
validação vira RpcException(InvalidArgument), o jeito idiomático de sinalizar isso em gRPC.
Testes
21 testes automatizados: 12 de domínio, 7 unitários (hub e serviço gRPC com dependências mockadas) e 2 de integração ponta a ponta — sobe a aplicação inteira em memória e prova o caminho real (gRPC → SignalR) sem precisar de infraestrutura externa.
Sobre a infraestrutura real
docker-compose.yml sobe Redis e duas instâncias da API pra provar o scale-out na prática:
métrica enviada numa instância aparece no navegador conectado na outra. O backplane Redis só
ativa quando há connection string configurada — sem ela, a API roda em instância única, o que
é o cenário coberto pelos testes automatizados (documentado com clareza no README, junto com o
porquê).
Stack
.NET 8, ASP.NET Core, SignalR, gRPC, Redis, xUnit, Moq, Docker, GitHub Actions.