Skip to content

Branch Leaderboard

Visão Geral

Ranking de unidades por KPI configurável. Útil para chains que querem visibilidade comparativa entre filiais e gerar competição saudável (ou identificar quem precisa suporte).

Visível só quando o tenant tem 2+ branches ativas.

Localização

CamadaArquivo
Servicebackend/src/branches/branch-leaderboard.service.ts
Controllerbackend/src/orders/orders.controller.ts (endpoint stats/branch-leaderboard)
Viewfrontend-react/src/views/admin/BranchLeaderboardView.tsx
Variant cozinhafrontend-react/src/views/admin/KitchenBranchLeaderboardView.tsx

Rotas

RotaConteúdo
/admin/branch-leaderboardRanking geral
/admin/kitchen/branch-leaderboardVariante focada em SLA da cozinha

KPIs Disponíveis

KPICálculoSentido
revenueΣ revenueMaior = melhor
avgTicketrevenue ÷ coversMaior = melhor
cmvPercentCOGS ÷ revenue × 100Menor = melhor
tableTurnovercovers ÷ tables ÷ horasMaior = melhor
kdsSlaCompliance% pedidos delivered dentro de slaMinutesMaior = melhor
cancellationRatecancelled ÷ totalMenor = melhor

Default ordering por revenue descendente. Toggle no header altera KPI ordenado.


Endpoint

GET /t/:slug/orders/stats/branch-leaderboard?from=&to=&kpi=revenue

Resposta:

json
{
  "period": { "from": "2026-04-01", "to": "2026-04-30" },
  "kpi": "revenue",
  "branches": [
    {
      "branchId": "...",
      "name": "Centro",
      "revenue": 285400,
      "covers": 4720,
      "avgTicket": 60.46,
      "cmvPercent": 31.2,
      "tableTurnover": 2.8,
      "rank": 1,
      "deltaVsLastPeriod": 0.085
    }
  ]
}

deltaVsLastPeriod permite o frontend mostrar setas de tendência (▲ verde ou ▼ vermelho).


Aggregation

BranchLeaderboardService.getRanking(tenantId, period, kpi):

  1. KpiSnapshot por branch agrupando o período
  2. Computa o KPI selecionado
  3. Ordena conforme sentido (maior ou menor primeiro)
  4. Calcula deltaVsLastPeriod lendo o período anterior de mesma duração
  5. Atribui rank em sequência

Performance: aproximadamente 50ms para 10 branches × 30 dias. Para chains de 100+ unidades, considere cache Redis (TTL 1 hora) — não implementado por ora.


Anonimização (Franchise mode)

Quando o tenant é franqueador (Tenant.isFranchisor: true), o leaderboard mostrado para uma franquia individual é anonimizado:

  • Sua própria unidade aparece com nome
  • Outras unidades viram "Unidade #2", "Unidade #3", etc.
  • Posição relativa preservada

Master franchisor vê tudo com nome.

Lógica em BranchLeaderboardService.applyAnonymization(viewerTenantId, ranking).


Variant: Kitchen Leaderboard

KitchenBranchLeaderboardView foca em métricas operacionais:

  • SLA compliance (% dentro do tempo configurado)
  • Tempo médio de preparo por categoria
  • Throughput pico (pedidos/hora no horário mais movimentado)

Útil para gerentes de cozinha competirem em eficiência sem entrar em revenue (que pode depender de fatores fora do controle deles, como localização).


Permissões

  • Permission.ReportsViewAll para ver leaderboard geral
  • Permission.OrdersViewAll para ver kitchen leaderboard
  • Branch managers veem apenas o ranking — não números absolutos das outras unidades (a menos que sejam admin)

Lançado sob a licença MIT.