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 martsdw_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:
- Ranking anual por marcas
- Ranking de cidades (cross-tab)
- Ranking de concessionárias
- 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âmetro | Aplicável a | Regras de backend |
|---|---|---|
periodo (data inicial, data final) | Todas | Data final ≤ D-1. Validar no backend. |
categoria | Marcas, Modelos, Concessionárias | Default "Todas" (sem filtro). |
modalidade | Marcas, Modelos, Cidades | Default "Todas" (sem filtro). |
areaAbrangencia | Todas | Default "Nacional". Opções: Nacional, Regiao Geografica, Regiao Metropolitana, Regiao Operacional, Estado, Cidade, Area de Influencia. |
abrangenciaValor | Todas (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
| Aba | Filtros adicionais (impacto no backend) |
|---|---|
| Marcas | acumuladoAno (bool) · tipoPessoa (Todas/Física/Jurídica) · relatorioDiario (bool) |
| Modelos | tipoSegmento · segmentos[] (só quando tipoSegmento ≠ Todos) · acumuladoAno · todosOsModelos (bool) · tipoPessoa |
| Concessionárias | incluirNaoCadastrados (bool) · porGrupoConcessionaria (id/bool) · porGrupoEconomico (id/bool) · acumuladoAno · tipoPessoa |
| Cidades | tipoPessoa (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 para01/01/[ano vigente]; data final permanece livre (≤ D-1). O backend deve ignorar qualquer data inicial recebida e aplicar01/01do ano corrente. tipoPessoa:FísicaouJurídica→ filtra o volume; não retorna colunas PF/PJ separadas.Todas→ retornavolTotal+volPF+volPJpor 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 quandotipoSegmento≠ "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
porGrupoConcessionariaouporGrupoEconomico, 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:
volumeeparticipacao(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,marcavolTotal(+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:
volumeepercentual. - Máximo de 5 colunas de marca (as 5 líderes globais do recorte).
- Linha Total ao final (por marca, outros e total geral).
tipoPessoaafeta 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/volPJao lado dovolTotalquandotipoPessoa = Todas. Na prática,tipo_pessoaé nulo em 86,5% do volume na origem (verpor-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/volPJpor 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
- Usar
dw_emplacamentodireto ou os martsdw_emplacamento_mart? (ver marts doc). - Contrato exato dos endpoints (1 por aba vs. 1 parametrizado por
tipo). - Comportamento default de
tipoPessoaquando não enviado. - Definição precisa de cada
areaAbrangenciano schema (colunas geográficas usadas). - Busca/ordenação/paginação: server-side vs. client-side por aba.
- Contrato de erro para grupo fora do escopo (§2).
- Origem do "mês atual/anterior" e "ano anterior" para os Δ% (calendário vs. período).