Pular para o conteúdo principal

Por Ranking — Emplacamento · Requisitos de Backend

Escopo deste documento: apenas backend (dados, serviços, endpoints, regras de agregação, filtros e controle de acesso). Todo item puramente de frontend/UX do documento original (layout, chips, tooltips, skeletons, sticky, badges de cor, paginação visual, modais) foi abstraído — só permanece o que o backend precisa produzir, filtrar ou validar.

Contexto

  • Origem dos dados: dw_emplacamento (data warehouse). Avaliar uso dos marts dw_emplacamento_mart (ver marts-emplacamento.md).
  • Atualização: D-1 (dia útil anterior). Toda data final de período é limitada a D-1.
  • A tela expõe 4 rankings independentes, cada um com sua própria consulta:
    1. Ranking anual por marcas
    2. Ranking de cidades (cross-tab)
    3. Ranking de concessionárias
    4. Ranking de modelos

Cada ranking é um conjunto de dados server-side: KPIs + série do gráfico (top N) + tabela de detalhamento + linha de totais. Todos derivam da mesma base filtrada.


1. Filtros (parâmetros de entrada)

1.1 Filtros primários (comuns / quase todas as abas)

ParâmetroAplicável aRegras de backend
periodo (data inicial, data final)TodasData final ≤ D-1. Validar no backend.
categoriaMarcas, Modelos, ConcessionáriasDefault "Todas" (sem filtro).
modalidadeMarcas, Modelos, CidadesDefault "Todas" (sem filtro).
areaAbrangenciaTodasDefault "Nacional". Opções: Nacional, Regiao Geografica, Regiao Metropolitana, Regiao Operacional, Estado, Cidade, Area de Influencia.
abrangenciaValorTodas (quando ≠ Nacional)Sub-valor geográfico correspondente ao tipo escolhido. Backend aplica o recorte espacial correto por tipo.

1.2 Filtros específicos por aba

AbaFiltros adicionais (impacto no backend)
MarcasacumuladoAno (bool) · tipoPessoa (Todas/Física/Jurídica) · relatorioDiario (bool)
ModelostipoSegmento · segmentos[] (só quando tipoSegmento ≠ Todos) · acumuladoAno · todosOsModelos (bool) · tipoPessoa
ConcessionáriasincluirNaoCadastrados (bool) · porGrupoConcessionaria (id/bool) · porGrupoEconomico (id/bool) · acumuladoAno · tipoPessoa
CidadestipoPessoa (afeta dados; não adiciona colunas — ver §4.2)

1.3 Regras de filtro no backend

  • RF039 / Acumulado do Ano: quando acumuladoAno = true, a data inicial é forçada para 01/01/[ano vigente]; data final permanece livre (≤ D-1). O backend deve ignorar qualquer data inicial recebida e aplicar 01/01 do ano corrente.
  • tipoPessoa:
    • Física ou Jurídica → filtra o volume; não retorna colunas PF/PJ separadas.
    • Todas → retorna volTotal + volPF + volPJ por entidade e no total (exceto Cidades — §4.2).
    • Sem filtro definido → tratar como padrão do produto (definir; provável Todas).
  • todosOsModelos (RF040): false → top 100 modelos; true → todos.
  • tipoSegmento / segmentos (RUX004): segmentos[] só é considerado quando tipoSegmento ≠ "Todos"; caso contrário ignorar.

2. Controle de acesso (RF041 / RUX015)

Regra obrigatoriamente validada no backend — não é restrição de frontend.

  • Perfil concessionária loja:
    • Pode visualizar o ranking completo de mercado (todas as concessionárias).
    • Ao usar porGrupoConcessionaria ou porGrupoEconomico, o backend só aceita grupos vinculados ao usuário autenticado.
    • O backend valida que o grupo informado pertence ao escopo do usuário antes de aplicar o filtro; grupo fora do escopo → rejeitar/ignorar (definir contrato de erro).
  • O endpoint que lista opções de grupo (para o filtro) deve retornar, para perfil loja, apenas os grupos do escopo do usuário.

3. KPIs e série do gráfico (comum a todas as abas)

Calculados server-side sobre a base filtrada, dados até D-1:

  • KPI Líder: entidade #1 por volume + sua participação de mercado (MS%).
  • KPI Volume total: soma do volume no período/filtro.
  • KPI Δ% Ano anterior: variação do volume total vs. mesmo período do ano anterior.
  • Série do gráfico (RF015): top 10 entidades, com duas medidas por entidade: volume e participacao (MS%).
  • Dados do tooltip (RF037): por entidade → nome, volume, MS%, Δ% ano anterior, referência de período D-1. (Backend fornece os números; render é frontend.)

4. Contrato de dados por aba (tabela + totais)

"Barra inline relativa ao líder" (RF036) é visual: o backend só precisa fornecer os volumes; a proporção é calculada no cliente. Não requer campo extra além do volume.

4.1 Ranking Anual por Marcas (RF016 / RF017) — redesenhado, ver decisão abaixo

Decisão de produto (pós-implementação): ao revisar a tela com dado real, "MS"/"MS Ant." (participação) ficaram redundantes com a barra do Vol Total, e "Δ% Ano Ant." (calculado sobre volume) não era comparável com MS/MS Ant. (calculados sobre participação) — misturava duas famílias de métrica na mesma linha. Redesenhado como um bloco só de Participação, com dois pares mês/ano e seus respectivos deltas (variação relativa, %):

Por marca:

  • ranking, marca
  • volTotal (+ volTotalPercent, usado só pela barra de fundo)
  • Bloco Mês (janela de calendário fixa, âncora na data de referência, independente de um Período customizado): participacaoMesAtual (mês civil atual, parcial), participacaoMesAnterior (mês civil anterior, completo), deltaMesPercent (variação relativa entre os dois)
  • Bloco Ano (janela do período resolvido — por padrão ano corrente até a última atualização): participacaoAnoAtual, participacaoAnoAnterior (mesmo período do ano anterior), deltaAnoPercent (variação relativa)

Linha Total: consolida volTotal; as 4 participações fecham em 100%. PF/PJ removidos desta aba — ver §4.5 (decisão revisada).

4.2 Ranking de Cidades — cross-tab (RF024 / RF025 / RF026 / RF038)

  • Estrutura cruzada: por cidade × top 5 marcas (por volume no período, mercado geral) + coluna "Outros" (demais marcas agregadas) + "Total".
  • Cada célula marca/outros/total: volume e percentual.
  • Máximo de 5 colunas de marca (as 5 líderes globais do recorte).
  • Linha Total ao final (por marca, outros e total geral).
  • tipoPessoa afeta os dados mas não gera colunas PF/PJ.

4.3 Ranking de Concessionárias (RF020–RF023)

Por concessionária:

  • posicao, codigo, grupoEconomico, grupoEmpresa, concessionaria, regionalOperacional, volume, cnpj

Agregações:

  • porGrupoConcessionaria = true → agrupar com subtotais por grupo de concessionária.
  • porGrupoEconomico = true → agrupar com subtotais por grupo econômico.
  • incluirNaoCadastrados → inclui/exclui concessionárias não cadastradas.
  • Linha "Total Geral" com volume. PF/PJ removidos — ver §4.5.

4.4 Ranking de Modelos (RF018 / RF019 / RF040)

Tabela unificada por modelo:

  • posicaoVigente, modelo, volVigente, pctVigente, classifVigente, volAnterior, pctAnterior, classifAnterior, deltaPosicao
  • Quando tipoPessoa = Todas: volPF, volPJ
  • todosOsModelos: false → top 100; true → todos.

Linha Total: consolida ambos os anos; inclui volPF/volPJ quando tipoPessoa = Todas.

4.5 Colunas PF/PJ (RF027 / RF032) — removidas (decisão revisada)

Decisão de produto (pós-implementação): o spec original (RF027) pedia volPF/volPJ ao lado do volTotal quando tipoPessoa = Todas. Na prática, tipo_pessoa é nulo em 86,5% do volume na origem (ver por-ranking-gaps.md §2.1) — as colunas ficavam "quase zeradas" perto do total e induziam a erro. Decisão: remover as colunas de exibição de Marcas e Concessionárias (as únicas que as tinham implementadas). Modelos e Cidades nunca tiveram essas colunas.

  • O filtro "Tipo de Pessoa" (Física/Jurídica) continua funcionando normalmente — restringe o volume da consulta inteira; é independente da exibição de colunas por linha.
  • Nenhuma tabela do Por Ranking expõe volPF/volPJ por entidade hoje.
  • Cidades: nunca retorna colunas PF/PJ (§4.2).

5. Busca, ordenação e paginação (server-side onde aplicável)

  • RF035 (Busca): busca textual por nome da entidade. Pode ser client-side sobre o conjunto retornado; se o volume de linhas exigir, backend deve suportar filtro por termo. Definir com base no tamanho esperado (ex.: Concessionárias/Modelos com todosOsModelos). A linha Total nunca é filtrada pela busca.
  • RF031 / RF034 (Paginação + ordenação): colunas ordenáveis; paginação do conjunto. A linha Total não é paginada — é sempre calculada sobre o total filtrado, não sobre a página. Decidir se ordenação/paginação são server-side ou client-side por aba.

6. Exportação (RF028–RF030)

  • Endpoint/serviço de geração de relatório por aba, formatos Excel / PDF / CSV.
  • Campos por aba:
    • Marcas: Vol Total · Part. Mês Atual · Part. Mês Anterior · Δ Mês · Part. Ano Atual · Part. Ano Anterior · Diferença
    • Modelos: Vol (ambos os anos) · Classif. · Δ Posição
    • Concessionárias: Posição · CNPJ · Vol
    • Cidades: Vol por marca (colunas dinâmicas conforme top 5)
  • A exportação usa os mesmos filtros/escopo da consulta (incl. controle de acesso §2).

7. Itens fora de escopo de backend (referência)

Abstraídos deste documento por serem puramente frontend/UX: RF001–RF003 (breadcrumb/abas/botão), RF008–RF013 (render de filtros/chips/badges), RF033–RF034 (parte visual), RF036 (barra inline — visual), RUX001–RUX014. Permanecem citados apenas quando impõem regra de dado (ex.: RF041/RUX015 = validação de escopo no backend; RF037 = payload do tooltip; RF036 = necessidade do volume).


8. Pendências a definir antes de implementar

  1. Usar dw_emplacamento direto ou os marts dw_emplacamento_mart? (ver marts doc).
  2. Contrato exato dos endpoints (1 por aba vs. 1 parametrizado por tipo).
  3. Comportamento default de tipoPessoa quando não enviado.
  4. Definição precisa de cada areaAbrangencia no schema (colunas geográficas usadas).
  5. Busca/ordenação/paginação: server-side vs. client-side por aba.
  6. Contrato de erro para grupo fora do escopo (§2).
  7. Origem do "mês atual/anterior" e "ano anterior" para os Δ% (calendário vs. período).