Pular para o conteúdo principal

View — detalhamento de chassi (drawer Por Marca)

✅ RESOLVIDO (2026-07-29). A view dw_emplacamento_mart.emplacamento_detalhe_drawer foi criada pelo time de dados com todos os campos necessários e fabricante/grupomodeloveiculo alinhados ao grid (emplacamento_kpi_dia). O chassi-service.ts já consulta a view diretamente (sem joins no app).

Regra de ouro de performance: filtrar por intervalo de data (data BETWEEN mês-início AND âncora), nunca por ano/mes. A view deriva ano/mes via EXTRACT, que não usa o índice composto veiculo_sk + data → plano ~37s. Com data BETWEEN, ~0,3–1,4s. regiao_operacional vem NULL (não existe na origem) — filtro de Área por "Região Operacional" não afeta o chassi. O texto abaixo é o pedido original.

Pedido pro time de dados. Contexto: o drawer de drill-down do relatório Por Marca (apps/web/app/[locale]/emplacamento/home/[account]/reports/por-marca/_components/brand-drawer.tsx) precisa listar os veículos (1 linha por chassi) de uma marca/modelo dentro do mês selecionado, agrupados por CNPJ da concessionária.

Validado direto contra o DW de produção em 2026-07-28 (introspecção de information_schema + queries reais).


O que já existe

dw_emplacamento_mart.emplacamento_detalhe já é um mart no grão de chassi (~4M linhas, materializado por ano/mês) — é exatamente o "Mart 2" descrito em docs/vona/marts-emplacamento.md. Ele tem:

data, numero_chassis, numero_placa, fabricante, modelo, subsegmento,
segmento, cilindradas, municipio, estado, cnpj, razao_social,
is_cpf_empresa, modalidade, tipo_pessoa, ano_fabricacao,
grupo_economico_codigo, grupo_economico_nome, ano, mes

O que falta nele pra servir o drawer com os mesmos filtros do resto do relatório Por Marca:

  1. grupomodeloveiculo — o drawer abre a partir de uma linha de modelo (ex.: "STRADA"), não da versão completa (modelo no mart de detalhe é "FIAT/STRADA RANCH T200AT"). Sem essa coluna não dá pra filtrar o drawer pelo modelo clicado.
  2. Colunas de região usadas pelo filtro "Área de Abrangência" e "Grupo ABRACAF" do relatório: regiao_geografica, regiao_metropolitana, area_influencia_nome, conc_regiao_abracaf (hoje só existem no mart agregado emplacamento_kpi_dia, prefixadas local_regiao_*/conc_regiao_*).
  3. regiao_operacional — usada pelo filtro de área, mas não existe em nenhuma dimensão crua (dim_local não tem essa coluna); só aparece já materializada em emplacamento_kpi_dia. Não sei de onde o ETL deriva esse valor — perguntar ao time de dados junto com os gaps já levantados em marts-emplacamento.md.

Implementação atual (interim, sem a view)

Enquanto a view não existe, chassi-service.ts (apps/web/app/[locale]/emplacamento/home/[account]/reports/por-marca/_lib/server/chassi-service.ts) consulta emplacamento_detalhe com LEFT JOIN pontual em dw_emplacamento.fato_emplacamentos + dim_veiculo (só pra resolver grupomodeloveiculo) e em dim_local/dim_concessionaria (pra resolver região/área). Funciona, mas paga o custo de 4 joins em runtime a cada abertura de drawer — e não consegue filtrar por "Região Operacional" (item 3 acima).

DDL proposta

Adicionar as colunas que faltam directamente em dw_emplacamento_mart.emplacamento_detalhe (fica 1 mart só, sem precisar manter uma view separada) ou, se preferirem não mexer no mart existente agora, uma view fina só com o que falta, para o app fazer o join só uma vez no schema:

-- Opção A (preferida): estender o mart existente com as colunas que faltam.
-- Mesma materialização/refresh que emplacamento_detalhe já tem hoje.
ALTER TABLE dw_emplacamento_mart.emplacamento_detalhe
ADD COLUMN grupomodeloveiculo_codigo integer,
ADD COLUMN grupomodeloveiculo text,
ADD COLUMN regiao_geografica text,
ADD COLUMN regiao_metropolitana text,
ADD COLUMN regiao_operacional text, -- se o ETL souber derivar
ADD COLUMN area_influencia_codigo text,
ADD COLUMN area_influencia_nome text,
ADD COLUMN conc_regiao_abracaf text,
ADD COLUMN conc_regiao_abcnissan text,
ADD COLUMN conc_regiao_abrare text;

-- Popular no mesmo job que já materializa emplacamento_detalhe, com os
-- mesmos joins usados em emplacamento_kpi_dia:
-- dim_veiculo via veiculo_sk (fato_emplacamentos)
-- dim_local via local_sk (fato_emplacamentos)
-- dim_concessionaria via concessionaria_sk (fato_emplacamentos)

CREATE INDEX IF NOT EXISTS ix_emplacamento_detalhe_grupomodelo
ON dw_emplacamento_mart.emplacamento_detalhe (fabricante, grupomodeloveiculo);
-- Opção B: view somente com o essencial pro drawer, caso não queiram
-- alterar o mart de detalhe agora. Roda os mesmos 3 LEFT JOINs que o app
-- faz hoje em runtime, mas resolvidos uma vez só no banco (planner pode
-- cachear plano; ainda assim é join a cada SELECT, não é ganho de
-- performance real vs. opção A — só evita mexer no mart existente).
CREATE VIEW dw_emplacamento_mart.emplacamento_detalhe_chassi AS
SELECT
ed.data,
ed.numero_chassis,
ed.numero_placa,
ed.fabricante,
dv.grupomodeloveiculo,
ed.modelo AS versao,
ed.segmento,
ed.cilindradas,
ed.municipio,
ed.estado,
ed.cnpj,
ed.razao_social,
ed.modalidade,
ed.tipo_pessoa,
dl.regiao_geografica,
dl.regiao_metropolitana,
dc.area_influencia_nome,
dc.regiao_abracaf AS conc_regiao_abracaf,
ed.ano,
ed.mes
FROM dw_emplacamento_mart.emplacamento_detalhe ed
LEFT JOIN dw_emplacamento.fato_emplacamentos fe
ON fe.numero_chassis = ed.numero_chassis
AND fe.data_emplacamento = ed.data
LEFT JOIN dw_emplacamento.dim_veiculo dv ON dv.veiculo_sk = fe.veiculo_sk
-- (municipio, estado) é a chave única real em dim_local — município sozinho
-- se repete entre estados (ex.: "SAO CARLOS"), causaria fan-out.
LEFT JOIN dw_emplacamento.dim_local dl
ON dl.municipio = ed.municipio AND dl.estado = ed.estado
LEFT JOIN dw_emplacamento.dim_concessionaria dc ON dc.cnpj = ed.cnpj;

Recomendação: opção A. É a mesma materialização que já existe pro mart de detalhe, só com colunas a mais — zero joins em runtime pro app, e mantém paridade de filtros com emplacamento_kpi_dia (mesmas colunas, mesma convenção de nomes local_regiao_*/conc_regiao_* documentada em marts-emplacamento.md).

Quando a view/coluna existir

Trocar a query em chassi-service.ts (queryChassiDetails) por um SELECT direto em dw_emplacamento_mart.emplacamento_detalhe (sem os 3 LEFT JOIN manuais) — a função já isola essa query num único lugar comentado apontando pra este documento.