---
type: bi-app
tabelas:
  - "tabelas/fact_pedido_item.md"
  - "dim_cliente"      # nomeada em lineage.md; sem tabelas/*.md própria — gabarito
                        # deliberadamente pequeno, só o fato tem profiling completo
                        # (Fase 1: "KPI primeiro, banco depois", ver lineage.md)
  - "dim_produto"       # idem
  - "dim_vendedor"      # idem — SCD2, ver processos/faturamento.md#dimensões
  - "dim_loja"          # idem
  - "dim_calendario"    # conformada, já existe no dw-desk do tenant (ver
                        # processos/faturamento.md#dimensões)
relationships:                       # 4 (produto/cliente/vendedor/loja) herdados
                                      # 1:1 do STM de lineage.md; a 5ª (calendário)
                                      # é inferida por convenção, sem chave
                                      # explícita no STM — nenhum join NOVO é
                                      # criado aqui, mas nem todo item abaixo tem
                                      # o mesmo grau de rastro
  - de: "dim_produto.CODPROD"        # lookup direto (lineage.md#dimensões-chaves-usadas-no-fato)
    para: "fact_pedido_item.CODPROD"
    cardinalidade: 1:N
  - de: "dim_cliente.CODPARC"        # lookup direto
    para: "fact_pedido_item.CODPARC"
    cardinalidade: 1:N
  - de: "dim_vendedor.CODVEND"       # lookup direto; 0,2% órfão — ver evidência de
    para: "fact_pedido_item.CODVEND" # profiling em tabelas/fact_pedido_item.md
    cardinalidade: 1:N
  - de: "dim_loja.CODEMP"            # lookup direto
    para: "fact_pedido_item.CODEMP"
    cardinalidade: 1:N
  - de: "dim_calendario.data"        # nome de coluna inferido por convenção —
    para: "fact_pedido_item.data"    # lineage.md só documenta TGFCAB.DTNEG ->
    cardinalidade: 1:N               # fact.data (origem da coluna do FATO); sem
                                      # chave explícita do lado da dimensão, ver
                                      # incognitas.md#calendario-chave-join-inferida
razao_rel_tabela: 0.83   # 5 relationships / 6 tabelas (1 fato + 5 dims) — saudável, ≈1,0
expressions_tabela:
  - "metricas/receita-liquida.md"    # camada: tabela — mora em fact_pedido_item
  - "metricas/ticket-medio.md"       # camada: tabela — idem
expressions_app: []   # nenhuma métrica local nesta fase — as 2 únicas métricas do
                       # cubo já são camada: tabela (ver seção Expressions abaixo)
dashboards:
  - "dashboards/vendas-executivo.md"
bi_desk_destino: "Comercial — decisão da analista Camila Duarte"
confianca: confirmado   # rastro: bloco "Evidência do cubo" abaixo
---

# App — Vendas (o cubo)

Este é o único app da Fase 1: expõe `fact_pedido_item` mais as 5 dimensões
conformadas do processo Faturamento (Calendário, Cliente, Produto, Vendedor,
Loja), na razão exata do bus matrix aprovado em
[`projeto.md`](../projeto.md) — só a linha "Faturamento" tem `✓`; "Estoque/
ruptura" fica vazia nesta fase (ver [`fora-de-escopo.md`](../fora-de-escopo.md)).
O dashboard [Vendas Executivo](../dashboards/vendas-executivo.md) é o único
filho deste cubo.

## Por que estas tabelas convivem no mesmo app

Um fato só, cinco dimensões conformadas ligando nele — nenhuma dimensão liga
em mais de um fato (não há "dimensão-ponte" nem ciclo, ver
[`limites-horus.md`](../../../limites-horus.md)), então a regra de ouro
("todas as dimensões em comum entre fatos conectadas via dimensão") é
trivialmente satisfeita: não há segundo fato ainda para ter dimensão em
comum. `dim_calendario` já é conformada e reusada do dw-desk do tenant (ver
[`processos/faturamento.md`](../processos/faturamento.md#dimensões)); as
outras 4 nascem novas neste projeto.

Nenhum dos sinais de escalada para `fato-mestre` está presente hoje (ver
`limites-horus.md`, "Fato mestre é a escalada, não o default"): nenhuma
métrica é razão entre processos (Receita Líquida e Ticket Médio vivem inteiras
dentro de `fact_pedido_item`), não há funil/ciclo de vida da mesma entidade
em estados diferentes, não é negócio de ocupação de capacidade, e nenhum
widget do dashboard cruza dimensões que não sejam comuns — por isso
`estrategia: star`, coerente com o mesmo campo em
[`tabelas/fact_pedido_item.md`](../tabelas/fact_pedido_item.md).

## Evidência do cubo

| Decisão | Teste | Resultado | Status |
|---|---|---|---|
| `estrategia: star` (não `fato-mestre`) | checagem dos sinais de escalada de `limites-horus.md` contra o bus matrix de `projeto.md` | nenhum sinal presente: 1 fato ativo, 0 métrica-razão-entre-processos, 0 funil de estados, 0 negócio de capacidade | Validado |
| Razão relationships/tabela ≤ 1,5 | 5 relationships declarados ÷ 6 tabelas do cubo (1 fato + 5 dims) | 0,83 | Validado |
| Cobertura do bus matrix | toda tabela citada na linha "Faturamento" de `projeto.md` aparece em `tabelas:` acima | 6/6 (fato + 5 dims) | Validado |
| Nenhum join fora do lineage (dims de lookup direto) | as 4 linhas de `relationships:` (produto/cliente/vendedor/loja) conferidas contra a tabela "Dimensões (chaves usadas no fato)" de `lineage.md` | 4/4 batem 1:1, coluna física a coluna física, com o STM (nenhum join novo criado aqui) | Validado |
| Relationship com `dim_calendario` | mesma conferência aplicada à 5ª linha (`dim_calendario.data`) | `lineage.md` só documenta, para o calendário, a aresta table-level `DIMCAL --> FACT` no diagrama e a linha STM `TGFCAB.DTNEG → fact_pedido_item.data` — que registra a origem da coluna do FATO, não a chave de join do lado da dimensão; `data` é nome inferido por convenção, sem chave explícita no lineage | Premissa não validada — ver `incognitas.md#calendario-chave-join-inferida` |
| Dimensão comum a 2+ fatos conformada | busca por dimensão citada em 2 fatos no bus matrix | não aplicável — só 1 fato ativo nesta fase | Validado (critério vira relevante só quando "Estoque/ruptura" entrar) |

## Decisão em aberto (hipótese)

`confianca: hipótese` — se "Estoque/ruptura" (linha vazia do bus matrix em
`projeto.md`) virar um 2º fato deste mesmo app numa fase futura, a
`estrategia` pode precisar migrar de `star` para `fato-mestre`, dependendo de
como a pergunta de negócio cruzar os dois processos (ex.: "ruptura vs venda
do mesmo produto/loja" é razão entre processos — sinal de escalada segundo
`limites-horus.md`).
`origem`: leitura combinada da linha "Estoque/ruptura" vazia em `projeto.md`
com a régua "fato mestre é a escalada, não o default" de `limites-horus.md` —
não foi perguntado ao cliente porque a 2ª fase ainda nem tem escopo aberto
(ver `fora-de-escopo.md`, linha "Estoque/ruptura": "novo ciclo — nova linha
do bus matrix, grain e KPI cards próprios").

## Expressions

As 2 métricas do processo (`Receita Líquida`, `Ticket Médio`) já nascem
`camada: tabela` — moram em `fact_pedido_item` e qualquer app futuro que
reuse o fato as herda automaticamente (ver `limites-horus.md`, "dicionário
de métricas mora no fato"). Por isso `expressions_app` fica vazio nesta
fase: com 1 único dashboard e nenhuma métrica-só-deste-app ainda, não há
motivo para criar uma expression local — o dia em que aparecer uma métrica
que só faça sentido neste app específico (ex.: um corte que usa
`{FILTER|COLUMN=...}` só daqui), ela entra em `expressions_app`, nunca
duplicada na tabela.

## Nomeação do cubo

O arquivo do bundle chama este conceito de `vendas` (área de negócio); o
recurso publicado na plataforma mantém o id `vendas-executivo` — mesmo id
que `aceite.md` e os campos `teste_reconciliacao` de
`metricas/receita-liquida.md`/`metricas/ticket-medio.md` já usam nos comandos
`lumo app query app:vendas-executivo ...` — porque, nesta fase, cubo e
dashboard têm exatamente o mesmo público e a mesma razão de existir (1 app,
1 dashboard). Se um 2º dashboard for adicionado a este mesmo app no futuro,
o id do app deixa de coincidir com o nome de um dashboard específico — mas
isso ainda não aconteceu nesta fase.
