Adição ao MVP original (ADR-0018). A camada semântica descreve, em YAML e no padrão do dbt/MetricFlow, o que se mede no modelo estrela: entidades, dimensões, métricas e consultas salvas. Qualquer ferramenta compatível calcula as métricas do mesmo jeito, sem reescrever a regra em DAX, SQL ou planilha.
O documento tem duas partes:
- Parte A — Negócio: o que os dados significam. As bases, os conceitos do cadastro CNPJ
(empresa × estabelecimento, porte, MEI, situação cadastral…), o ciclo de vida, a ontologia que liga os conceitos
às entidades e métricas, um glossário e perguntas frequentes com
mf query. Leia antes de usar as métricas. - Parte B — Estrutura técnica: como a camada é construída: arquivos, entidades, métricas, consultas salvas, testes e limites.
Toda regra legal ou de negócio da Parte A tem a fonte indicada entre colchetes, como [IN 2.119, art. 9º]. A
lista completa, com link e data de acesso, está em A7. Os números de exemplo vêm das fixtures
sintéticas do make ci, não do cadastro real. As regras que dá para conferir no dado estão catalogadas em
REGRAS_NEGOCIO.md (RN-xx), com o resultado do dado real em
RELATORIO_REGRAS_NEGOCIO.md (ADR-0020).
Dados abertos do CNPJ (Receita Federal). O CNPJ é o cadastro da RFB com as informações cadastrais das pessoas jurídicas e de outras entidades de interesse das administrações tributárias. A RFB publica uma cópia em dados abertos, com atualização mensal [Dados.gov.br]. Cada mês é um extrato completo do cadastro: uma fotografia, não um registro de eventos. O projeto baixa os arquivos de cada mês (ADR-0003) e usa:
| Arquivo da RFB | Uma linha por | O que traz | Staging |
|---|---|---|---|
| Empresas | empresa (CNPJ básico) | razão social, natureza jurídica, qualificação do responsável, capital social, porte, ente federativo responsável | stg_rfb__empresas |
| Estabelecimentos | estabelecimento (CNPJ completo) | matriz/filial, nome fantasia, situação cadastral (data e motivo), início de atividade, CNAE principal e secundárias, endereço, município, situação especial | stg_rfb__estabelecimentos |
| Simples | empresa (CNPJ básico) | opção pelo Simples e pelo MEI, com as datas de opção e de exclusão | stg_rfb__simples |
| Domínios | código | CNAEs, municípios, naturezas jurídicas e motivos da situação cadastral (o leiaute descreve os três primeiros; o arquivo de motivos é publicado junto) | stg_rfb__cnaes, stg_rfb__municipios, stg_rfb__naturezas, stg_rfb__motivos |
O leiaute [RFB-Leiaute] também descreve o arquivo Sócios (quadro societário, com CPF parcialmente ocultado) e os domínios de países e de qualificações. O projeto não ingere Sócios e descarta e-mail e telefones no staging (ADR-0008). Ninguém aqui responde "quem é dono de quê".
Os códigos de situação cadastral, porte e matriz/filial não têm arquivo de domínio na RFB: estão no leiaute e o
projeto os guarda nos seeds dominio_situacao_cadastral, dominio_porte e dominio_matriz_filial.
Base dos Dados. O portal Base dos Dados publica tabelas públicas já tratadas (ADR-0015). O projeto usa:
- diretório de municípios (código IBGE, código RFB, UF, meso/microrregião, regiões intermediária e imediata,
centroide):
stg_bd__municipios; - CNAE com a hierarquia completa:
stg_bd__cnaes; - população estimada (
stg_bd__populacao) e PIB municipal (stg_bd__pib); - incremento
enriquecimento_bd: Censo 2022 por município (stg_bd__censo_2022_municipio), regiões metropolitanas (stg_bd__regioes_metropolitanas) e vizinhança entre municípios (stg_bd__vizinhanca).
Esses dados viram atributos de dim_municipio e dim_cnae. Na camada semântica, aparecem como dimensões
(municipio__sigla_uf, cnae__descricao_secao…), nunca como métricas (ver B7).
O número de inscrição tem 14 posições [RFB-Leiaute]:
| Parte | Posições | Nome no leiaute | Coluna no projeto |
|---|---|---|---|
| básico (raiz) | 1 a 8 | CNPJ BÁSICO | cnpj_raiz |
| ordem | 9 a 12 | CNPJ ORDEM ("número do estabelecimento") | cnpj_ordem |
| dígitos verificadores | 13 e 14 | CNPJ DV | cnpj_dv |
cnpj_completo é a concatenação das três partes. O básico identifica a empresa; o completo, o
estabelecimento.
CNPJ alfanumérico. Desde julho de 2026, as 12 primeiras posições podem ter letras maiúsculas (A a Z) além de números; os 2 dígitos verificadores continuam numéricos, calculados pelo módulo 11 [IN 2.119, art. 2º, parágrafo único; RFB-Alfanumérico]. O primeiro foi gerado em 31/07/2026 [RFB-Notícia]. Os CNPJs numéricos continuam válidos e não mudam [RFB-Alfanumérico, perguntas 6 e 7]. Por isso:
- não trate o CNPJ como número (o projeto o guarda como texto);
- não use "ordem
0001" como sinônimo de matriz: o que diz se é matriz é o identificador matriz/filial (eh_matriz).
O teste cnpj_dv_valido já confere os dígitos dos dois formatos (regra RN-17).
É a distinção mais importante para usar as métricas.
- Empresa é a entidade inscrita no CNPJ (sociedade, empresário individual, órgão público, associação…). É identificada pelo CNPJ básico e tem uma linha no arquivo Empresas.
- Estabelecimento é o "local privado ou público, edificado ou não, móvel ou imóvel, próprio ou de terceiros, físico ou virtual, onde a entidade exerce suas atividades" [IN 2.119, art. 5º]. Toda entidade e cada um de seus estabelecimentos precisa de inscrição [IN 2.119, art. 4º]. Cada estabelecimento tem um CNPJ completo e uma linha no arquivo Estabelecimentos.
Uma empresa tem um ou mais estabelecimentos. Atributos ficam em lugares diferentes: natureza jurídica, porte, capital social e opção pelo Simples/MEI são da empresa; situação cadastral, CNAE, endereço, município e data de início de atividade são do estabelecimento [RFB-Leiaute].
No projeto, o grão das fatos é o estabelecimento (fct_estabelecimentos, entidade semântica
estabelecimento). Não há uma entidade semântica "empresa": os atributos da empresa foram copiados para cada
estabelecimento dela. Consequências:
qtd_estabelecimentoseqtd_ativoscontam estabelecimentos, não empresas;- para contar empresas, conte as matrizes (
qtd_matrizes). Nas fixtures, em 2026-09, são 18 estabelecimentos e 16 matrizes: duas empresas têm uma filial cada; - atributos da empresa repetidos (capital social) não podem ser somados por estabelecimento.
O identificador matriz/filial vale 1 (matriz) ou 2 (filial) [RFB-Leiaute]; o projeto o guarda em
matriz_filial_codigo e na flag eh_matriz. O projeto lê a inscrição da entidade como a da matriz, com as
filiais em inscrição própria. É uma leitura, não texto expresso: o art. 9º fala da inscrição "da entidade ou do
estabelecimento filial" [IN 2.119, art. 9º], e o art. 4º, § 1º, inscreve os estados, o DF e os municípios "na
condição de estabelecimento matriz" [IN 2.119, art. 4º, § 1º]. A entidade pode transformar uma filial em matriz
[IN 2.119, art. 4º, § 3º], e a baixa da matriz implica a baixa de todas as filiais [IN 2.119, art. 24, § 2º]
(regra RN-14). A matriz baixada, inapta ou nula também impede a inscrição de filial
[IN 2.119, art. 21, IV] (RN-27).
Contar empresas pelas matrizes supõe uma matriz por CNPJ básico. As fixtures cumprem isso. No dado real de
2026-09 há 70.085.592 matrizes para 70.085.591 CNPJs básicos: todo básico tem matriz, e só um (08314885) tem
duas (conferência da RSEM no dado real de 2026-09; regra RN-16).
- Razão social é o "nome empresarial da pessoa jurídica" e está no arquivo Empresas [RFB-Leiaute]
(
razao_social). No empresário individual e no MEI, ela termina com o CPF do titular; o projeto mascara esse trecho no gold (ADR-0008). - Nome fantasia é do estabelecimento (
nome_fantasia) e pode vir vazio.
Nenhum dos dois é dimensão da camada semântica: são nomes, não categorias.
É a forma jurídica da entidade, com código de 4 dígitos no arquivo Empresas e descrição no domínio Naturezas [RFB-Leiaute]. A tabela oficial é a da CONCLA/IBGE, organizada em cinco grupos [CONCLA-NJ]:
| Grupo | Exemplos (código CONCLA – descrição) |
|---|---|
| 1. Administração Pública | 101-5 Órgão Público do Poder Executivo Federal; 103-1 Órgão Público do Poder Executivo Municipal; 124-4 Município |
| 2. Entidades Empresariais | 213-5 Empresário (Individual); 206-2 Sociedade Empresária Limitada; 205-4 Sociedade Anônima Fechada; 204-6 Sociedade Anônima Aberta |
| 3. Entidades sem Fins Lucrativos | 399-9 Associação Privada |
| 4. Pessoas Físicas | — |
| 5. Organizações Internacionais e Outras Instituições Extraterritoriais | — |
O ente federativo responsável só é preenchido para as naturezas do grupo 1XXX [RFB-Leiaute]
(ente_federativo_responsavel; regra RN-20). Nas fixtures do CI, o código 2062 traz a descrição "Sociedade Empresária
Limitada", a mesma do 206-2 da CONCLA.
MEI não é natureza jurídica. Pela lei, o MEI é o empresário individual do art. 966 do Código Civil ou o
empreendedor que exerça atividades extrativistas, atividades autorizadas pelo CGSN ou atividades de
industrialização, comercialização e serviços no âmbito rural [LC 123, art. 18-A, § 1º, I a III, redação da LC
188/2021]. A CONCLA não associa o MEI a uma natureza. No dado real, quase todo MEI tem a natureza 213-5
Empresário (Individual): dos 17.527.414 estabelecimentos com opcao_mei em 2026-09, 17.526.176 (99,99 %) têm
o código 2135, 1.237 têm 2062 (Sociedade Empresária Limitada) e 1 tem 2070 (Sociedade Empresária em Nome
Coletivo). É observação do projeto, não regra (conferência da RSEM no dado real de 2026-09; contada por empresa
na RN-08). Já a natureza de sociedade contraria o § 1º, que só admite o empresário
individual ou o empreendedor (RN-29). Para achar MEI, use
opcao_mei, não a natureza.
No projeto: dim_natureza_juridica, entidade natureza_juridica, dimensões
natureza_juridica__descricao_natureza_juridica e natureza_juridica__codigo_natureza_juridica. Só a fato
detalhada a tem: o resumo mensal não tem natureza jurídica.
É o "capital social da empresa", no arquivo Empresas [RFB-Leiaute]. O projeto o repete em cada estabelecimento de
fct_estabelecimentos (capital_social). Some só nas matrizes: é o que fazem capital_social_total e
capital_social_medio (capital por matriz, ou seja, por empresa).
Código do porte da empresa [RFB-Leiaute], no seed dominio_porte:
| Leiaute | Seed (codigo, rotulo) |
Significado | Limite de receita bruta anual |
|---|---|---|---|
| 00 – Não informado | 0, N/A | não informado | — |
| 01 – Micro empresa | 1, MICRO | microempresa (ME) | até R$ 360.000,00 [LC 123, art. 3º, I] |
| 03 – Empresa de pequeno porte | 3, PEQUENA | empresa de pequeno porte (EPP) | acima de R$ 360.000,00 e até R$ 4.800.000,00 [LC 123, art. 3º, II] |
| 05 – Demais | 5, DEMAIS | nem ME nem EPP | — |
Cuidados:
- O porte é declarado, não medido. O enquadramento como ME ou EPP é feito por declaração arquivada no registro (Junta Comercial) [Lei 8.934, art. 32, II, d; LC 123, art. 3º]. Os dados abertos não trazem a receita; não há como conferir o porte com eles.
- MEI não é porte. Não há código de porte para MEI no leiaute; o MEI é uma opção de tributação (veja abaixo).
- Os limites acima são os da LC 123 em vigor em 2026-10-10 (redação da LC 155/2016) [LC 123].
- O seed descreve "05 DEMAIS" como "Demais (médio e grande porte)". "Médio e grande porte" é um rótulo do projeto: o leiaute diz só "Demais".
- "Não informado" aparece de dois jeitos: o código 00 da RFB (rótulo
N/A) e o membro-1(NÃO INFORMADO) do modelo estrela, para porte vazio ou fora do domínio.
No projeto: dim_porte, entidade porte, dimensões porte__rotulo_porte e porte__codigo_porte.
Simples Nacional é o "Regime Especial Unificado de Arrecadação de Tributos e Contribuições devidos pelas Microempresas e Empresas de Pequeno Porte" [LC 123, art. 12]. A opção é anual, irretratável no ano-calendário [LC 123, art. 16] e, pela redação vigente em 2026-10-10, formalizada até o último dia útil de janeiro, com efeito desde 1º de janeiro [CGSN 140, art. 6º, § 1º]. O arquivo Simples traz, por CNPJ básico, a opção (S, N ou em branco), a data de opção e a data de exclusão [RFB-Leiaute].
Mudança já publicada: Resolução CGSN nº 190/2026. Com efeitos a partir de 1º de janeiro de 2027, ela muda o art. 6º, § 1º: a opção passa a ser formalizada de 1º a 30 de setembro e vale a partir do ano-calendário seguinte; um novo § 1º-B permite cancelá-la até 30 de novembro [CGSN 190, arts. 1º e 9º]. Para o ano-calendário de 2027, a janela é de 1º de setembro a 15 de outubro de 2026 [CGSN 194, art. 1º, que dá nova redação ao art. 1º da Resolução CGSN nº 186/2026]. Ou seja, quem opta pelo Simples para 2027 o faz ainda em 2026, e a data de opção do arquivo Simples pode ser anterior ao início dos efeitos. No extrato de 2026-09, 10 opções têm data de 1º/1/2027: o campo guarda a data de efeito, e a RN-13 aceita a opção até 1º de janeiro seguinte. O regime vale desde 1º de julho de 2007 [LC 123, art. 88] e o SIMEI, desde 1º de julho de 2009 [LC 128, art. 14, III] (RN-25, RN-26).
MEI (microempreendedor individual) é o optante pelo Simples Nacional que recolhe em valores fixos mensais (o SIMEI) [LC 123, art. 18-A]: o empresário individual ou o empreendedor das atividades listadas no § 1º (veja Natureza jurídica). Para ser MEI:
- receita bruta anual de até R$ 81.000,00 no ano anterior [LC 123, art. 18-A, § 1º; CGSN 140, art. 100; Portal do Empreendedor]. No ano de abertura, o limite é de R$ 6.750,00 por mês de atividade [LC 123, art. 18-A, § 2º]. O transportador autônomo de cargas tem limite de R$ 251.600,00 [CGSN 140, art. 100, § 1º-A, I; Portal do Empreendedor];
- só as ocupações permitidas [CGSN 140, art. 100; Portal do Empreendedor];
- um único estabelecimento e nenhuma participação em outra empresa como titular, sócio ou administrador
[LC 123, art. 18-A, § 4º, II e III]. O dado real tem exceções: 3.749 filiais de empresas com
opcao_mei(conferência da RSEM no dado real de 2026-09; regra RN-05). Comoqtd_ativos_meiconta estabelecimentos, ela pode passar um pouco do número de empresas MEI; - no máximo um empregado, com salário mínimo ou piso da categoria [LC 123, art. 18-C; CGSN 140, art. 105].
Todo MEI é optante pelo Simples (RN-06) e é modalidade de microempresa [LC 123, art. 18-E, § 3º] (RN-07); o contrário não vale. Sair do SIMEI (desenquadramento) não exclui a empresa do Simples Nacional [CGSN 140, art. 115, § 1º]. O arquivo Simples traz a opção pelo MEI e suas datas [RFB-Leiaute].
Os limites de R$ 81.000,00 e R$ 251.600,00 foram conferidos em 2026-10-10 nas três fontes acima. Eles mudam por lei; confira antes de citá-los num relatório.
Mudança em discussão: PLP nº 186/2026. O projeto, do Poder Executivo, foi apresentado em 29/06/2026. Ele propõe subir o teto do MEI para R$ 110 mil em 2027 e R$ 140 mil em 2028 e permitir até dois empregados [Câmara-Notícia]. Em 2026-10-10, não está aprovado:
- na Câmara, a situação é "Aguardando Despacho do Presidente da Câmara dos Deputados" [Câmara-PLP 186];
- o MEMP diz que os valores "ainda não estão em vigor" e que vale o limite de R$ 81 mil [MEMP-Teto];
- nenhuma lei complementar de 2026 publicada até então trata do MEI [Planalto-LCP], e o texto compilado da LC 123 segue com R$ 81.000,00 e um empregado [LC 123].
A mesma página do MEMP diz, em outra resposta, que o MEI "agora" pode contratar dois funcionários, o que contradiz a lei vigente. Valem a LC 123 e a tramitação.
No projeto:
opcao_simpleseopcao_mei(emstg_rfb__simplese emfct_estabelecimentos);- empresa sem registro no arquivo Simples vira
falsenas duas flags. O leiaute também prevê o valor "em branco – outros"; - a fato tem um teste: MEI implica Simples (
not opcao_mei or opcao_simples); - a flag é a situação no extrato: as datas de opção e exclusão ficam no staging (
dat_opcao_mei,dat_exclusao_mei,dat_opcao_simples,dat_exclusao_simples); - métricas
qtd_ativos_meiepct_mei_entre_ativos; dimensõesresumo_mensal__opcao_meieestabelecimento__opcao_mei.
A inscrição no CNPJ da entidade ou de cada filial está numa de cinco situações [IN 2.119, art. 9º]. Os códigos são
os do leiaute [RFB-Leiaute], iguais aos do seed dominio_situacao_cadastral:
| Código | Situação | Pode ocorrer quando (resumo) | Fonte |
|---|---|---|---|
| 2 | ATIVA | inscrição regular | [IN 2.119, art. 9º] |
| 3 | SUSPENSA | interrupção temporária das atividades comunicada pela entidade; inconsistência cadastral; não localização no endereço; indício de interposição fraudulenta de sócio; procedimento de inaptidão em curso; ordem judicial; entre outras | [IN 2.119, art. 37] |
| 4 | INAPTA | omissão de declarações por 90 dias ou mais após o prazo; inexistência de fato (sem patrimônio ou capacidade operacional, não localizada, atividades paralisadas sem comunicação); irregularidade no comércio exterior; fraude; suspensa há um ano ou mais; entre outras | [IN 2.119, art. 38] |
| 8 | BAIXADA | a pedido: extinção (liquidação, incorporação, fusão, cisão total) ou fim da falência. De ofício: inapta não regularizada em 180 dias, registro extinto no órgão de registro, ordem judicial, falência ou liquidação extrajudicial, óbito do MEI, decisão administrativa | [IN 2.119, arts. 24 e 31] |
| 1 | NULA | o ato cadastral foi declarado nulo: mais de um CNPJ para o mesmo estabelecimento, vício no ato ou inscrição de quem não devia ser inscrito. O efeito retroage ao início do ato | [IN 2.119, art. 34] |
Os arts. 31 e 38 dizem que a inscrição "pode ser baixada de ofício" e "pode ser declarada inapta": os prazos da tabela (90 dias, 1 ano, 180 dias) são condições, não gatilhos automáticos. A inaptidão por omissão é declarada por ato declaratório executivo (ADE) "com a relação das inscrições" [IN 2.119, art. 39]: chega em lotes, numa data só (veja o cuidado na A3).
Pontos que mudam a leitura das métricas:
- "Ativa" não quer dizer "em operação". As situações cadastrais "não se confundem com a condição de atividade ou inatividade para fins tributários" [IN 2.119, art. 9º, parágrafo único]. Um estabelecimento parado segue ATIVO até ser suspenso, declarado inapto ou baixado (ressalva R3-19 do guia Power BI).
- Motivo. Cada situação tem um motivo codificado [RFB-Leiaute], descrito no arquivo de motivos da RFB. O projeto o guarda no
staging (
motivo_situacao_codigo,stg_rfb__motivos) e não o leva à estrela. O ATIVO tem o motivo 00 (SEM MOTIVO): é a tradução de "ativa não tem encerramento" (RN-10). - Data da situação é a "data do evento da situação cadastral" [RFB-Leiaute] (
dat_situacao). Num ativo, costuma coincidir com a data de início de atividade (observação do projeto, sem fonte da RFB). Regras RN-11 a RN-13: o não ativo tem a data, ela não antecede o início de atividade e não passa do limite do extrato (o dia seguinte à data de referência).
No projeto: dim_situacao_cadastral, entidade situacao_cadastral, dimensão
situacao_cadastral__rotulo_situacao_cadastral e a flag eh_ativa (código 2).
É a "situação especial da empresa" e a "data em que a empresa entrou em situação especial", campos do arquivo
Estabelecimentos [RFB-Leiaute]. O leiaute não lista os valores possíveis. O projeto mantém os campos só no staging
(situacao_especial, dat_situacao_especial); os dois andam juntos (RN-15).
É a "data de início da atividade" do estabelecimento [RFB-Leiaute] (dat_inicio_atividade). No projeto:
- base da idade (
idade_anos, só para ativos, em relação à data do extrato) e das métricasidade_media_anosesoma_idade_anos_ativos; - base das aberturas (
aberturas) e das coortes de sobrevivência (mart_sobrevivencia_coorte).
Data ausente vira a chave -1 e data anterior a 1900 vira -2. Nenhuma das duas gera evento nem coorte.
A CNAE (Classificação Nacional de Atividades Econômicas) é mantida pela CONCLA/IBGE, hoje na versão CNAE-Subclasses 2.3. Tem cinco níveis, por exemplo para a pergunta-guia do projeto [CONCLA-CNAE]:
| Nível | Código | Exemplo |
|---|---|---|
| Seção | G | Comércio; reparação de veículos automotores e motocicletas |
| Divisão | 47 | Comércio varejista |
| Grupo | 47.4 | Comércio varejista de material de construção |
| Classe | 47.41-5 | Comércio varejista de tintas e materiais para pintura |
| Subclasse | 4741-5/00 | Comércio varejista de tintas e materiais para pintura |
Cada estabelecimento tem um CNAE fiscal principal e zero ou mais secundários, estes separados por vírgula no arquivo [RFB-Leiaute] (regras RN-01 a RN-04). No projeto:
- o principal vira
cnae_principal(7 dígitos, como4741500) esk_cnae; dim_cnaetraz os cinco níveis (dimensõescnae__codigo_subclasse,cnae__descricao_secaoetc.), da Base dos Dados;- os secundários ficam na ponte
bridge_estabelecimento_cnae_secundario, fora da camada semântica (ver B7).
As métricas usam só o CNAE principal: um estabelecimento que vende tintas como atividade secundária não entra
em cnae__codigo_subclasse = '4741500'.
O arquivo Estabelecimentos traz a UF e o "código do município de jurisdição onde se encontra o estabelecimento"
[RFB-Leiaute]. Esse código é da tabela da RFB (domínio Municípios, 4 dígitos), não é o código IBGE
(7 dígitos). O projeto converte um no outro pelo diretório de municípios da Base dos Dados (codigo_rfb →
id_municipio_ibge) e usa o código IBGE como chave (sk_municipio).
Sem par, o estabelecimento fica no membro -1 de dim_municipio. O código existe no domínio da RFB
(RN-19). Os casos conhecidos estão no seed
excecoes_conhecidas_municipio: o código 9707 (EXTERIOR, UF EX) e municípios criados depois da base.
A RFB não publica "eventos": publica a situação atual de cada estabelecimento, com a data e o motivo dela. O diagrama mostra as transições previstas na IN RFB 2.119/2022 [IN 2.119].
stateDiagram-v2
[*] --> ATIVA : inscrição (art. 4º)
ATIVA --> SUSPENSA : art. 37 (interrupção comunicada, inconsistência, não localizada…)
SUSPENSA --> ATIVA : regularização / restabelecimento (art. 37, § 3º)
ATIVA --> INAPTA : pode, art. 38 (omissão ≥ 90 dias, inexistência de fato…)
SUSPENSA --> INAPTA : pode, se suspensa ≥ 1 ano (arts. 38, X, e 46)
INAPTA --> ATIVA : regularização (arts. 39, 46, § 2º, e 47)
INAPTA --> SUSPENSA : motivo da suspensão anterior persiste (art. 47, par. único)
ATIVA --> BAIXADA : a pedido (art. 24) ou de ofício (art. 31)
INAPTA --> BAIXADA : pode, de ofício, após 180 dias sem regularizar (art. 31, I)
BAIXADA --> ATIVA : restabelecimento (art. 26)
ATIVA --> NULA : nulidade do ato cadastral (art. 34)
Notas:
- A suspensão pela interrupção comunicada e por ordem judicial só vira inaptidão depois de 5 anos [IN 2.119, art. 46, § 1º].
- A baixa da matriz leva junto todas as filiais [IN 2.119, art. 24, § 2º]. A baixa não apaga dívidas: tributos ainda podem ser lançados e cobrados depois dela [IN 2.119, art. 24, § 4º].
- Empresa × estabelecimento no ciclo de vida. Nos dados abertos, a situação cadastral está no arquivo
Estabelecimentos. Como o projeto lê a inscrição da entidade como a da matriz (veja
Matriz × filial), lê também a "situação da empresa" como a da matriz: filtre
eh_matriz. Uma empresa ATIVA pode ter filiais baixadas.
O que o extrato mensal mostra, e o que não mostra.
- Mostra a situação no dia do extrato e a data do último evento de situação. Transições intermediárias entre dois extratos não aparecem: um estabelecimento suspenso e reativado no mesmo mês segue ATIVO.
- Comparando dois extratos se vê a variação líquida do estoque (é o que fazem
qtd_ativos_mes_anteriorevariacao_mensal_ativos), não quem entrou e quem saiu. Se um CNPJ deixar de constar no extrato, o projeto deixa de vê-lo. - O cadastro guarda também o que já foi encerrado: as análises originais do MVP observaram que a base traz "todas
as empresas que já foram abertas na história, incluindo as que foram fechadas"
(notebook 2.2). Por isso
qtd_estabelecimentosinclui baixados; useqtd_ativospara o estoque ativo.
Ligação com as métricas.
| Pergunta | Métrica | Regra do projeto |
|---|---|---|
| Quantos estão ativos hoje? | qtd_ativos |
situação ATIVA no extrato do mês. Ativa ≠ em operação |
| Quantos abriram no período? | aberturas |
estabelecimentos do extrato corrente pela data de início de atividade válida |
| Quantos encerraram no período? | encerramentos |
estabelecimentos não ativos (nula, suspensa, inapta ou baixada, não só baixada) pela data da situação válida |
| Quantos fecharam de vez? | baixas |
só os BAIXADOS, pela data da situação válida |
| Saldo | saldo_aberturas_encerramentos |
aberturas − encerramentos |
| Quantos sobrevivem? | taxa_sobrevivencia_3a etc. |
elegíveis da coorte de abertura que seguiam ativos N anos depois da abertura: ativos hoje ou encerrados a partir do aniversário de N anos. Não é "ainda ativo": um estabelecimento aberto em 2015 e baixado em 2024 sobrevive aos 3 e aos 5 anos |
Aberturas e encerramentos são eventos derivados pelo projeto (regra de mart_dinamica_mercado), não eventos
publicados pela RFB. Como só existe a situação atual, um inativo reativado deixa de contar como encerramento, e um
suspenso conta como encerramento enquanto estiver suspenso.
Cuidado: lotes de inaptidão e período parcial. Dois efeitos distorcem encerramentos e o saldo de um ano:
- Inaptidões em lote. A inaptidão por omissão é declarada por ADE com uma lista de inscrições [IN 2.119, art. 39] e pode ser revertida com a regularização [IN 2.119, arts. 39, parágrafo único, e 47]. Um lote põe a mesma data da situação em milhões de estabelecimentos. No dado real de 2026-09, 1.883.442 dos 4.243.776 encerramentos com data em 2026 (44 %) são INAPTA, contra 629 em 2025. O saldo de 2026 cai para 63.019, contra 2.270.025 em 2025, e o ano parece de mercado estagnado (conferência da RSEM no dado real de 2026-09).
- Ano e mês parciais. O extrato vai até a data de referência. O de 2026-09 é de 12/09: setembro tem só 12 dias de aberturas (179.463, contra 522.738 em agosto), e 2026 vai só até 12/09 (mesma fonte).
Para "fechamentos definitivos", use baixas ou quebre encerramentos por
situacao_cadastral__rotulo_situacao_cadastral. Compare anos completos, ou o mesmo período nos dois anos.
A ontologia formal está em docs/ontologia/rfb_cnpj.ttl (OWL, Turtle). Ela define os
conceitos e as relações e anota em cada conceito a entidade semântica, as dimensões, as métricas, os modelos e as
colunas do projeto. O teste tests/integration/test_ontologia.py confere a cobertura nos dois sentidos: todo nome
anotado existe nos manifestos do dbt, e toda entidade semântica e toda métrica está mapeada.
classDiagram
direction LR
class Empresa {
CNPJ básico
razão social
capital social
}
class Estabelecimento {
CNPJ completo
nome fantasia
data de início de atividade
data da situação
}
class Matriz
class Filial
class NaturezaJuridica
class Porte
class OpcaoSimplesNacional {
data de opção
data de exclusão
}
class OpcaoMEI
class SituacaoCadastral
class MotivoSituacaoCadastral
class SubclasseCnae
class ClasseCnae
class GrupoCnae
class DivisaoCnae
class SecaoCnae
class Municipio
class UnidadeFederativa
class RegiaoGeografica
Empresa "1" --> "1..*" Estabelecimento : possui
Estabelecimento <|-- Matriz
Estabelecimento <|-- Filial
Empresa --> "1" NaturezaJuridica : tem
Empresa --> "1" Porte : tem
Empresa --> "0..1" OpcaoSimplesNacional : tem
OpcaoSimplesNacional <|-- OpcaoMEI
Estabelecimento --> "1" SituacaoCadastral : tem
Estabelecimento --> "0..1" MotivoSituacaoCadastral : tem
Estabelecimento --> "1" SubclasseCnae : CNAE principal
Estabelecimento --> "0..*" SubclasseCnae : CNAEs secundárias
SubclasseCnae --> ClasseCnae : subordinada a
ClasseCnae --> GrupoCnae : subordinada a
GrupoCnae --> DivisaoCnae : subordinada a
DivisaoCnae --> SecaoCnae : subordinada a
Estabelecimento --> "1" Municipio : localiza-se em
Municipio --> "1" UnidadeFederativa : pertence a
Municipio --> RegiaoGeografica : pertence a
Os conceitos analíticos do projeto (fotografia mensal, abertura, encerramento, baixa e coorte) estão na ontologia, mas fora do diagrama: são regras do projeto, não conceitos da RFB. O teste também confere a afinidade: cada métrica fica num conceito que anota o modelo semântico dela (pela entidade, pelo modelo, pela coluna ou pela dimensão).
Onde cada conceito está no projeto. Colunas no formato modelo.coluna.
| Conceito | Staging | Estrela | Semântica (entidade / dimensão) | Métricas |
|---|---|---|---|---|
| Empresa | stg_rfb__empresas.cnpj_raiz |
— (atributos copiados em fct_estabelecimentos) |
— (sem entidade) | qtd_matrizes |
| Estabelecimento | stg_rfb__estabelecimentos.cnpj_completo |
fct_estabelecimentos.cnpj_completo |
estabelecimento |
qtd_estabelecimentos |
| Matriz / filial | stg_rfb__estabelecimentos.matriz_filial_codigo |
fct_estabelecimentos.eh_matriz |
estabelecimento__eh_matriz |
qtd_matrizes |
| Razão social | stg_rfb__empresas.razao_social |
— | — | — |
| Nome fantasia | stg_rfb__estabelecimentos.nome_fantasia |
— | — | — |
| Natureza jurídica | stg_rfb__empresas.natureza_juridica_codigo |
dim_natureza_juridica |
natureza_juridica / natureza_juridica__descricao_natureza_juridica |
via aberturas, encerramentos |
| Capital social | stg_rfb__empresas.capital_social |
fct_estabelecimentos.capital_social |
— | capital_social_total, capital_social_medio |
| Porte | stg_rfb__empresas.porte_codigo |
dim_porte |
porte / porte__rotulo_porte |
todas, como recorte |
| Simples Nacional | stg_rfb__simples.opcao_simples |
fct_estabelecimentos.opcao_simples |
estabelecimento__opcao_simples |
— |
| MEI | stg_rfb__simples.opcao_mei |
fct_estabelecimentos.opcao_mei, fct_resumo_mensal.opcao_mei |
resumo_mensal__opcao_mei, estabelecimento__opcao_mei |
qtd_ativos_mei, pct_mei_entre_ativos |
| Situação cadastral | stg_rfb__estabelecimentos.situacao_codigo |
dim_situacao_cadastral, fct_estabelecimentos.eh_ativa |
situacao_cadastral / situacao_cadastral__rotulo_situacao_cadastral, estabelecimento__eh_ativa |
qtd_ativos, pct_ativos |
| Data da situação | stg_rfb__estabelecimentos.dat_situacao |
fct_estabelecimentos.sk_data_situacao |
estabelecimento__data_situacao |
encerramentos, baixas |
| Motivo da situação | stg_rfb__estabelecimentos.motivo_situacao_codigo |
— | — | — |
| Situação especial | stg_rfb__estabelecimentos.situacao_especial |
— | — | — |
| Início de atividade | stg_rfb__estabelecimentos.dat_inicio_atividade |
fct_estabelecimentos.sk_data_inicio_atividade, fct_estabelecimentos.idade_anos |
estabelecimento__data_inicio_atividade |
aberturas, idade_media_anos, soma_idade_anos_ativos |
| CNAE principal | stg_rfb__estabelecimentos.cnae_principal |
dim_cnae, fct_estabelecimentos.sk_cnae |
cnae / cnae__codigo_subclasse … cnae__descricao_secao |
todas, como recorte |
| CNAEs secundárias | stg_rfb__estabelecimentos.cnaes_secundarios_lista |
bridge_estabelecimento_cnae_secundario |
— (fora da camada) | — |
| Município | stg_rfb__estabelecimentos.municipio_rfb_codigo |
dim_municipio |
municipio / municipio__nome_municipio, municipio__sigla_uf, municipio__nome_regiao … |
todas, como recorte |
| Fotografia mensal | — | fct_resumo_mensal |
resumo_mensal |
qtd_ativos_mes_anterior, variacao_mensal_ativos, variacao_mensal_ativos_pct |
| Abertura / encerramento / baixa | — | mart_dinamica_mercado |
estabelecimento |
aberturas, encerramentos, baixas, saldo_aberturas_encerramentos |
| Coorte de abertura | — | mart_sobrevivencia_coorte |
coorte_sobrevivencia |
elegiveis_3a, sobreviventes_3a, taxa_sobrevivencia_3a (e 1a, 5a) |
| Termo | Significado |
|---|---|
| CNPJ básico (raiz) | 8 primeiros caracteres do CNPJ; identifica a empresa (cnpj_raiz) |
| CNPJ completo | 14 posições; identifica o estabelecimento (cnpj_completo) |
| Empresa | entidade inscrita no CNPJ; no projeto, contada pelas matrizes |
| Estabelecimento | local onde a empresa atua (matriz ou filial); grão das fatos |
| Matriz / filial | identificador 1 / 2 do leiaute (eh_matriz) |
| ME / EPP | microempresa / empresa de pequeno porte, pela receita bruta anual (LC 123, art. 3º); no cadastro, declaradas |
| Simples Nacional | regime de tributação unificado da LC 123 para ME e EPP (opcao_simples) |
| MEI | empresário individual (ou empreendedor das atividades do art. 18-A, § 1º, da LC 123) no SIMEI, receita até R$ 81 mil/ano em 2026 (PLP 186/2026 propõe mudar) (opcao_mei); não é porte nem natureza jurídica |
| Situação cadastral | ATIVA, SUSPENSA, INAPTA, BAIXADA ou NULA, por estabelecimento |
| Ativo | situação ATIVA no extrato; não prova operação |
| Abertura | estabelecimento contado na data de início de atividade (regra do projeto) |
| Encerramento | estabelecimento não ativo contado na data da situação (regra do projeto) |
| Baixa | estabelecimento BAIXADO contado na data da situação (regra do projeto) |
| Sobrevivente a N anos | elegível da coorte ativo hoje ou encerrado a partir do aniversário de N anos (regra do projeto) |
| Fotografia mensal | o extrato de um mês; não se somam meses. Num período maior, vale o último mês em que o recorte filtrado tem linhas |
| CNAE | classificação de atividades da CONCLA/IBGE; seção → divisão → grupo → classe → subclasse |
| Município RFB | código de 4 dígitos da RFB, diferente do código IBGE |
Membro -1 |
"NÃO INFORMADO": valor sem par na dimensão |
Os exemplos rodam em transform/, com RAIZ_DADOS apontando para os dados (no CI, .tmp/ci/dados). As saídas
e os números citados vêm das fixtures do make ci (meses 2026-08 e 2026-09), não do cadastro real. Os poucos
números que ficam na prosa são conferidos por test_numeros_citados_na_doc_batem_com_as_fixtures; para os
demais, veja a saída do comando.
Quantos MEI ativos há em cada UF?
uv run mf query --metrics qtd_ativos_mei,qtd_ativos,pct_mei_entre_ativos --group-by metric_time__month,municipio__sigla_uf
uv run mf query --metrics qtd_ativos_mei --group-by metric_time__month --where "{{ Dimension('municipio__sigla_uf') }} = 'ES'"Recorte sem MEI sai vazio, não zero. Lembre que qtd_ativos_mei conta estabelecimentos (há MEI com filial no dado
real, veja Simples Nacional e MEI).
Quantas empresas há, e não estabelecimentos?
uv run mf query --metrics qtd_matrizes,qtd_estabelecimentos --group-by metric_time__month
uv run mf query --metrics qtd_matrizes,qtd_estabelecimentos --group-by metric_time__month --where "{{ Dimension('situacao_cadastral__rotulo_situacao_cadastral') }} = 'ATIVA'"Onde há filial, a saída tem mais estabelecimentos que matrizes. Com o filtro de ATIVA, a situação filtrada é a de cada estabelecimento: conta a matriz ativa, não a empresa como um todo.
Por que não posso somar os meses?
Cada mês é uma fotografia do cadastro inteiro. O mesmo estabelecimento ativo aparece em todos os meses em que segue
ativo; somar 2026-08 (10) e 2026-09 (11) daria 21 ativos que não existem. As métricas de contagem do resumo
declaram non_additive_dimension: num período maior que o mês, vale o último mês em que o recorte filtrado tem
linhas (veja a próxima pergunta).
uv run mf query --metrics qtd_ativos --group-by metric_time__month
uv run mf query --metrics qtd_ativos --group-by metric_time__yearA segunda consulta devolve 11 para 2026 (o valor de 2026-09), não 21.
Quantos há agora num recorte filtrado?
Cuidado com o filtro. O MetricFlow escolhe o "último mês" depois de aplicar o --where: se o filtro não deixa
nenhuma linha no último mês, ele usa o mês mais recente que sobrou, e devolve uma fotografia velha em vez de zero
ou vazio. Vale para a consulta por ano e para a consulta sem tempo. Nas fixtures, uma filial de Água Branca/PB
estava SUSPENSA em 2026-08 e foi baixada antes do extrato de 2026-09:
uv run mf query --metrics qtd_estabelecimentos --group-by metric_time__year --where "{{ Dimension('municipio__sigla_uf') }} = 'PB' and {{ Dimension('situacao_cadastral__rotulo_situacao_cadastral') }} = 'SUSPENSA'"A consulta devolve 1 para 2026 (a fotografia de 2026-08), embora em 2026-09 não haja nenhuma suspensa na PB. Para o estoque atual:
-
agrupe por
metric_time__month, ou filtremetric_timeno mês desejado (vazio quer dizer nenhum):uv run mf query --metrics qtd_estabelecimentos --group-by metric_time__month --where "{{ Dimension('municipio__sigla_uf') }} = 'PB' and {{ Dimension('situacao_cadastral__rotulo_situacao_cadastral') }} = 'SUSPENSA' and {{ TimeDimension('metric_time', 'month') }} = '2026-09-01'" -
não filtre a situação: agrupe por ela, ou use
qtd_ativosem vez deqtd_estabelecimentoscom filtroATIVA. O resumo guarda as linhas das outras situações, então o recorte continua com linhas no último mês e a fotografia sai certa:uv run mf query --metrics qtd_estabelecimentos,qtd_ativos --group-by metric_time__year,situacao_cadastral__rotulo_situacao_cadastral --where "{{ Dimension('municipio__sigla_uf') }} = 'PB'"
O teste test_fotografia_com_filtro_vale_o_ultimo_mes_em_que_o_recorte_tem_linhas documenta esse comportamento.
No dado real ele aparece a partir do segundo mês da série.
Como os estabelecimentos se distribuem por situação cadastral?
uv run mf query --metrics qtd_estabelecimentos --group-by metric_time__month,situacao_cadastral__rotulo_situacao_cadastralEm 2026-09, a saída mostra as situações ATIVA, INAPTA e BAIXADA; em 2026-08, também SUSPENSA.
Qual a idade média dos ativos por porte num mês?
uv run mf query --metrics qtd_ativos,idade_media_anos --group-by porte__rotulo_porte --where "{{ TimeDimension('metric_time', 'month') }} = '2026-09-01'"Lembre que o porte é declarado e que N/A (código 00) e NÃO INFORMADO (membro -1) são coisas diferentes.
Os encerramentos são só baixas?
Não. Pela regra do projeto, encerramento é todo estabelecimento não ativo com data da situação válida. Para só
as baixas, use baixas:
uv run mf query --metrics encerramentos --group-by metric_time__year,situacao_cadastral__rotulo_situacao_cadastral
uv run mf query --metrics encerramentos,baixas --group-by metric_time__yearNas fixtures, há encerramentos BAIXADA e INAPTA; o baixado sem data da situação não aparece. No dado real, a diferença é grande no ano de um lote de inaptidão (veja a A3).
Quantas aberturas houve por natureza jurídica, e por matriz ou filial?
uv run mf query --metrics aberturas --group-by natureza_juridica__descricao_natureza_juridica
uv run mf query --metrics aberturas,encerramentos --group-by estabelecimento__eh_matrizNatureza jurídica só existe na fato detalhada: combine-a com aberturas e encerramentos, não com as métricas do
resumo mensal.
Quantos ativos há por seção da CNAE?
uv run mf query --metrics qtd_ativos --group-by metric_time__month,cnae__descricao_secao --where "{{ TimeDimension('metric_time', 'month') }} = '2026-09-01'"O recorte é pelo CNAE principal. O membro NÃO INFORMADO reúne CNAEs sem par na Base dos Dados.
Acessadas em 2026-10-10.
| Chave | Fonte | O que sustenta |
|---|---|---|
| RFB-Leiaute | Receita Federal, Novo Layout dos Dados Abertos do CNPJ (PDF, 6 p.) | arquivos e campos (Empresas, Estabelecimentos, Simples, Sócios e os domínios de países, municípios, qualificações, naturezas e CNAEs); códigos de porte, matriz/filial, situação cadastral e opção Simples/MEI; ente federativo só no grupo 1XXX; CNAEs secundárias separadas por vírgula; CPF ocultado em Sócios |
| Dados.gov.br | Portal de Dados Abertos, Cadastro Nacional da Pessoa Jurídica – CNPJ | o que é o CNPJ; atualização mensal |
| IN 2.119 | Instrução Normativa RFB nº 2.119, de 6 de dezembro de 2022, texto multivigente (alterações até a IN RFB nº 2.345/2026) | formato alfanumérico (art. 2º); inscrição (art. 4º); estabelecimento (art. 5º); situações e "não se confundem com atividade" (art. 9º); baixa (arts. 24, 26, 31); nulidade (art. 34); suspensão (art. 37); inaptidão (arts. 38, 39, 46, 47) |
| RFB-Alfanumérico | Receita Federal, Perguntas e respostas: CNPJ alfanumérico | 14 posições, letras A–Z, DV por módulo 11; CNPJs atuais não mudam; os dois formatos coexistem |
| RFB-Notícia | Receita Federal, Receita Federal gera o primeiro CNPJ em formato alfanumérico (31/07/2026) | data do primeiro CNPJ alfanumérico |
| LC 123 | Lei Complementar nº 123, de 14 de dezembro de 2006, texto compilado do Planalto | limites de ME e EPP (art. 3º); Simples Nacional (art. 12); opção pelo Simples (art. 16); MEI: limite, estabelecimento único, sem outra empresa (art. 18-A); um empregado (art. 18-C); vigência do regime em 1º/7/2007 (art. 88) |
| LC 128 | Lei Complementar nº 128, de 19 de dezembro de 2008, Planalto (conferida em 2026-10-13) | os arts. 18-A a 18-C da LC 123 (SIMEI) produzem efeitos a partir de 1º/7/2009 (art. 14, III) |
| CGSN 140 | Resolução CGSN nº 140, de 22 de maio de 2018, texto multivigente | prazo da opção (art. 6º); MEI, ocupações e limite do transportador (art. 100); empregado do MEI (art. 105); desenquadramento do SIMEI não exclui do Simples (art. 115) |
| Lei 8.934 | Lei nº 8.934, de 18 de novembro de 1994 | arquivamento das declarações de microempresa no registro (art. 32, II, d) |
| Portal do Empreendedor | gov.br, O que você precisa saber antes de se tornar um MEI | requisitos do MEI; R$ 81.000,00 e R$ 251.600,00 |
| Câmara-PLP 186 | Câmara dos Deputados, ficha de tramitação do PLP 186/2026 | autor, apresentação (29/06/2026), situação "Aguardando Despacho do Presidente da Câmara dos Deputados"; último andamento em 24/08/2026 (requerimento de apensação) |
| Câmara-Notícia | Agência Câmara, Projeto do governo aumenta teto da receita de MEI para até R$ 140 mil em 2028 (30/06/2026) | conteúdo do PLP: R$ 110 mil (2027), R$ 140 mil (2028), até dois empregados |
| MEMP-Teto | Ministério do Empreendedorismo, Teto do MEI (modificado em 16/09/2026) | PLP "em tramitação", valores "ainda não estão em vigor", limite de R$ 81 mil válido |
| Planalto-LCP | Presidência da República, quadro das leis complementares | nenhuma LC de 2026 (até a LC 237, de 15/09/2026) altera o MEI |
| CONCLA-NJ | IBGE/CONCLA, Tabela de Natureza Jurídica 2021 | grupos e códigos de natureza jurídica |
| CONCLA-CNAE | IBGE/CONCLA, busca online CNAE-Subclasses 2.3, subclasse 4741-5/00 | hierarquia da CNAE e o exemplo de tintas |
Usamos o padrão novo de YAML da camada semântica, suportado pelo dbt-core 1.12+ e pelo dbt v2 (Fusion). As anotações ficam junto do modelo, no mesmo YAML que já documenta colunas e testes:
| Arquivo | O que define |
|---|---|
transform/models/marts/core/_core__models.yml |
modelos semânticos das dimensões e das duas fatos, métricas do resumo mensal e da fato detalhada, time spine (dim_data) |
transform/models/marts/analytics/_analytics__models.yml |
modelo semântico e métricas de mart_sobrevivencia_coorte |
transform/models/marts/_marts__saved_queries.yml |
consultas salvas (saved queries) |
docs/ontologia/rfb_cnpj.ttl |
ontologia: conceitos de negócio mapeados para entidades, dimensões e métricas (A4) |
Elementos do padrão usados aqui:
| Chave (no modelo) | Função |
|---|---|
semantic_model: { enabled: true } |
transforma o modelo dbt num modelo semântico |
entity: (na coluna) |
chave de junção: primary (o grão do modelo) ou foreign (aponta para outra entidade); aceita description |
dimension: (na coluna) |
atributo para agrupar e filtrar (categorical ou time) |
derived_semantics.dimensions |
dimensão calculada por expressão SQL (ex.: data a partir de sk_data) |
agg_time_dimension |
dimensão de tempo padrão das métricas do modelo (vira metric_time nas consultas) |
primary_entity |
entidade do modelo quando o grão é composto (sem coluna de chave única) |
metrics: |
métricas simple, ratio e derived do próprio modelo |
time_spine: |
calendário diário que o MetricFlow usa para deslocamentos e janelas |
O detalhe dos campos de cada tabela (tipo, grão, chaves, domínio, origem, e as entidades, dimensões e métricas
desta camada em cada modelo) está no dicionário de dados, gerado do manifesto do dbt
(make dicionario, ADR-0019).
erDiagram
resumo_mensal }o--|| municipio : sk_municipio
resumo_mensal }o--|| cnae : sk_cnae
resumo_mensal }o--|| porte : sk_porte
resumo_mensal }o--|| situacao_cadastral : sk_situacao_cadastral
estabelecimento }o--|| municipio : sk_municipio
estabelecimento }o--|| cnae : sk_cnae
estabelecimento }o--|| natureza_juridica : sk_natureza_juridica
estabelecimento }o--|| porte : sk_porte
estabelecimento }o--|| situacao_cadastral : sk_situacao_cadastral
coorte_sobrevivencia }o--|| cnae : sk_cnae
coorte_sobrevivencia }o--|| porte : sk_porte
| Modelo semântico | Entidade principal | Dimensões |
|---|---|---|
dim_municipio |
municipio (sk_municipio) |
nome_municipio, sigla_uf, nome_uf, nome_regiao, meso/microrregião, regiões intermediária e imediata, id_municipio_ibge, nome_regiao_metropolitana (incremento enriquecimento BD) |
dim_cnae |
cnae (sk_cnae) |
códigos e descrições de seção, divisão, grupo, classe e subclasse |
dim_natureza_juridica |
natureza_juridica |
código e descrição |
dim_porte |
porte |
codigo_porte, rotulo_porte |
dim_situacao_cadastral |
situacao_cadastral |
codigo_situacao_cadastral, rotulo_situacao_cadastral |
fct_resumo_mensal |
resumo_mensal (grão composto) |
tempo mes (mensal), opcao_mei |
fct_estabelecimentos |
estabelecimento (cnpj_completo) |
tempo data_inicio_atividade e data_situacao (diárias), opcao_simples, opcao_mei, eh_matriz, eh_ativa |
mart_sobrevivencia_coorte |
coorte_sobrevivencia (grão composto) |
tempo coorte (anual), uf |
Nas consultas, a dimensão de outro modelo é acessada pela entidade: municipio__sigla_uf, cnae__descricao_secao,
porte__rotulo_porte. O membro -1 (NÃO INFORMADO) de cada dimensão aparece como um valor normal. Não existe
entidade "empresa": ver A2.
As métricas do resumo mensal são as mesmas medidas DAX do guia Power BI,
agora definidas uma vez e fora da ferramenta de BI. A equivalência vale no grão mensal: num visual por ano (ou
sem mês), o DAX SUM soma os meses, e a métrica usa o último mês (fotografia, abaixo). Para comparar um número do
painel com o mf, filtre um mês nos dois.
| Métrica | Tipo | Definição | Medida DAX equivalente |
|---|---|---|---|
qtd_estabelecimentos |
simple (sum, fotografia) | sum(qtd_estabelecimentos) |
Qtd Estabelecimentos |
qtd_ativos |
simple (sum, fotografia) | sum(qtd_ativos) |
Qtd Ativos |
qtd_ativos_mei |
simple (sum, fotografia) | sum(qtd_ativos) com filtro opcao_mei |
Qtd Ativos MEI |
qtd_matrizes |
simple (sum, fotografia) | sum(qtd_matrizes) |
Qtd Matrizes |
capital_social_total |
simple (sum, fotografia) | sum(soma_capital_social_matrizes) |
Capital Social Total (R$) |
soma_idade_anos_ativos |
simple (sum, fotografia) | sum(soma_idade_anos) (numerador) |
— |
pct_ativos |
ratio | qtd_ativos / qtd_estabelecimentos |
% Ativos |
idade_media_anos |
ratio | soma_idade_anos_ativos / qtd_ativos |
Idade Média (anos) |
capital_social_medio |
ratio | capital_social_total / qtd_matrizes |
Capital Social Médio (R$) |
pct_mei_entre_ativos |
ratio | qtd_ativos_mei / qtd_ativos |
% MEI entre Ativos |
qtd_ativos_mes_anterior |
derived | qtd_ativos com offset_window: 1 month |
Qtd Ativos Mês Anterior |
variacao_mensal_ativos |
derived | qtd_ativos − mês anterior |
Variação Mensal de Ativos |
variacao_mensal_ativos_pct |
derived | (qtd_ativos − anterior) / anterior |
Variação Mensal de Ativos (%) |
aberturas |
simple (count) | estabelecimentos pela data de início, só com data válida | — (regra de mart_dinamica_mercado) |
encerramentos |
simple (count) | não ativos (not eh_ativa) pela data da situação (agg_time_dimension próprio), só com data válida |
— (regra de mart_dinamica_mercado) |
baixas |
simple (count) | só BAIXADA pela data da situação, só com data válida | — |
saldo_aberturas_encerramentos |
derived | aberturas − encerramentos (lado sem evento conta 0) |
— (saldo de mart_dinamica_mercado) |
elegiveis_{1,3,5}a, sobreviventes_{1,3,5}a |
simple (sum) | colunas de mart_sobrevivencia_coorte |
— |
taxa_sobrevivencia_{1,3,5}a |
ratio | sobreviventes / elegíveis (soma os estratos antes de dividir) |
Taxa de Sobrevivência 3a |
Fotografia mensal (non_additive_dimension). O resumo mensal é uma fotografia: somar qtd_ativos de vários
meses contaria o mesmo estabelecimento várias vezes (é o cuidado "Não some meses" do guia Power BI). As métricas
de contagem do resumo declaram non_additive_dimension: { name: mes, window_agg: max }. Num grão maior que o mês
(ano, ou sem tempo), o MetricFlow usa o último mês do período em que o recorte filtrado tem linhas, em vez da
soma. Nas fixtures do CI, qtd_ativos por ano dá 11 (o valor de 2026-09), não 21 (08 + 09). Testes de
integração impedem a regressão.
Limitação: o último mês é escolhido depois do filtro. O MetricFlow calcula o MAX(mes) sobre as linhas que
sobram do --where. Se o filtro esvazia o último mês, a consulta devolve o mês anterior com linhas, e não zero. O
MetricFlow não oferece um MAX fora do filtro. Para estoque atual, agrupe por metric_time__month ou filtre o
mês, e prefira qtd_ativos a qtd_estabelecimentos com filtro ATIVA (exemplo na
A6).
Ratios somam antes de dividir. idade_media_anos e taxa_sobrevivencia_3a dividem somas, nunca tiram média
de médias. Por isso a taxa de um estado ou de um ano é ponderada pelo número de estabelecimentos.
| Saved query | Pergunta |
|---|---|
serie_mensal_ativos_por_uf |
ativos, % de ativos e idade média por mês e UF |
estudo_caso_fundao_tintas |
pergunta-guia do MVP: lojas de tintas (CNAE 4741500) em Fundão/ES por mês e porte |
dinamica_anual_por_secao_cnae |
aberturas, encerramentos e saldo por ano e seção CNAE. O último ano é parcial, e os encerramentos incluem inaptidões em lote (veja a A3) |
sobrevivencia_por_coorte_e_porte |
taxas de sobrevivência a 1, 3 e 5 anos por coorte e porte |
O CLI do MetricFlow (mf, pacote dbt-metricflow) vem nas dependências de desenvolvimento (make setup). Ele lê o
projeto dbt de transform/ e consulta o DuckDB de RAIZ_DADOS (o mesmo warehouse.duckdb do pipeline).
make semantica # parse + mf validate-configs (inclusive contra o warehouse) + lista de métricas
cd transform
uv run mf list metrics # métricas e dimensões disponíveis
uv run mf query --saved-query estudo_caso_fundao_tintas
uv run mf query --metrics qtd_ativos,pct_ativos --group-by metric_time__month,municipio__sigla_uf \
--where "{{ Dimension('municipio__nome_regiao') }} = 'Sudeste'"
uv run mf query --metrics idade_media_anos --group-by metric_time__month --explain # mostra o SQL gerado
uv run mf query --metrics aberturas,encerramentos --group-by metric_time__year --csv dinamica.csvResultado do estudo de caso nas fixtures do CI, igual ao do notebook 4 em 2026-09 (1 loja ativa, MICRO, 3,9 anos):
metric_time__month porte__rotulo_porte qtd_estabelecimentos qtd_ativos idade_media_anos
2026-09-01 MICRO 2 1 3.9
Outros consumidores:
- Documento OSI. O
dbt parsegravatransform/target/osi_document.json, a camada semântica no formato aberto Open Semantic Interchange, para ferramentas que o leem. - Power BI. Continua com as medidas DAX do guia: o Power BI não lê MetricFlow diretamente. A tabela da
B3 é o dicionário entre as duas. Use
mf query --csvou--explainpara conferir um número do painel num mês: num total por ano, oSUMdo DAX soma os meses e a métrica não. - dbt Semantic Layer (dbt platform). O mesmo YAML serve, se um dia o projeto for para a plataforma.
tests/integration/test_camada_semantica.py:mf validate-configssem erros, inclusive contra o warehouse;- as 10 métricas simples e ratio do resumo iguais ao SQL direto no gold, no mês, no ano e sem tempo (no ano e sem tempo, a fotografia do último mês, também nos numeradores dos ratios);
- fotografia sem soma de meses, e a fixture discriminando o último mês da soma em todas as contagens;
- fotografia com filtro: o último mês em que o recorte tem linhas (a limitação da B3);
qtd_ativos_mes_anterior,variacao_mensal_ativosevariacao_mensal_ativos_pctcom o mês anterior;- estudo de caso de Fundão e as saved queries
serie_mensal_ativos_por_ufesobrevivencia_por_coorte_e_porte, iguais ao SQL; - aberturas, encerramentos e saldo iguais a
mart_dinamica_mercadopor ano e por ano × seção CNAE; baixasigual às baixadas com data válida, menor que os encerramentos;- elegíveis, sobreviventes e taxas a 1, 3 e 5 anos iguais ao mart, somando os estratos;
- os números citados nesta doc iguais aos das fixtures.
tests/integration/test_escopo_meta.py: modelos semânticos, métricas e saved queries commeta.escopo(e tag, nas saved queries).tests/integration/test_ontologia.py: a ontologia parseia, tem rótulos em português, cobre a camada nos dois sentidos (todo nome anotado existe nos manifestos; toda entidade e toda métrica tem conceito) e põe cada métrica num conceito que anota o modelo semântico dela (afinidade).tests/integration/test_doc_semantica.py: a parte estática descripts/verificar_doc_semantica.py(identificadores, links e âncoras desta doc). Os exemplosmfrodam só quando o script é chamado com a opção de executar os exemplos, fora do CI.- Mutações verificadas (todas reprovadas pelos testes):
- tirar o
non_additive_dimensionde uma contagem, ou do numerador de um ratio (soma_idade_anos_ativos,capital_social_total); - deslocar 2 meses no lugar de 1, ou dividir a variação % pelo mês corrente;
- tirar o filtro de MEI de
qtd_ativos_mei; trocar o denominador depct_ativos; trocar o numerador da taxa de 1 ano pelo de 3 anos; - trocar o filtro de
baixaspor não ativos;window_agg: minna fotografia; - remover o
meta.escopode uma métrica; - tirar o mapeamento de uma métrica da ontologia, mapeá-la num conceito de outro modelo ou mapear um conceito para um nome inexistente.
- tirar o
-
Densidades por população ou domicílio (ativos por 10 mil hab., por mil domicílios) não viraram métricas: a população é atributo da dimensão e precisaria ser somada uma vez por município, o que o MetricFlow não faz numa métrica de outra tabela. Use
mart_concorrencia_area_mercado(já calculaativos_por_mil_domicilios) ou o DAX do guia Power BI. -
CNAEs secundários (bridge muitos-para-muitos) e vizinhança ficam fora da camada semântica: o MetricFlow não modela pontes muitos-para-muitos.
-
aberturas,encerramentose o saldo seguem a regra demart_dinamica_mercado: abertura pela data de início; encerramento = estabelecimento não ativo (baixado, suspenso, inapto ou nulo, não só baixado) pela data da situação; data ausente ou inválida (-1/-2) não gera evento. Por ano, e por ano × qualquer dimensão do estabelecimento, os números são os do mart. Como o mart, olham só o extrato corrente: estabelecimentos que sumiram do cadastro não entram, e um inativo reativado deixa de contar como encerramento. Num período com eventos só de um lado, a métrica do outro lado sai vazia (nula) e o saldo a trata como 0 (coalescena expressão: o dbt-core 1.12.5 descartafill_nulls_withnas métricas do YAML novo). -
Inaptidões em lote e ano parcial distorcem
encerramentose o saldo de um ano: no dado real de 2026-09, 44 % dos encerramentos de 2026 são INAPTA, e 2026 vai só até 12/09. Usebaixasou a quebra por situação, e compare períodos completos (A3). -
Fotografia com filtro: o último mês é escolhido depois do
--where(B3). -
Datas sentinela no time spine. O
dim_datatem 1899-12-30 e 1899-12-31 (membros-2e-1), e elas aparecem em consultas de dimensão pura (mf query --group-by metric_time__day). Nenhuma métrica é afetada: as do resumo começam em 2026, eaberturas,encerramentosebaixasfiltram as datas nulas. Uma métrica futura comjoin_to_timespineoucumulativeveria esses dois dias; se incomodar, crie um time spine próprio, sem os membros-1e-2. -
Bug do partial parse (dbt-core 1.12.5). Depois de editar um YAML com métricas, o próximo comando dbt pode falhar com
dbt found two metrics with the name .... Rodedbt parse --no-partial-parseuma vez. Os alvosmake ci,make pipeline,make atualizaremake semanticajá fazem isso. -
dbt v2 (Fusion). O YAML desta camada é aceito pelo dbt v2. Por compatibilidade:
- os
input_metricssão sempre objetos ({ name: ... }); - as saved queries não usam
order_by.
A migração do motor continua adiada pelo ADR-0017.
- os
- Métrica nova sobre um modelo que já é semântico: acrescente-a em
metrics:do modelo, comdescription,label,config: { meta: { escopo: adicao } }. Contagens do resumo mensal levam onon_additive_dimension. - Dimensão nova: marque a coluna com
dimension: categorical. Para tempo, usedimension: time+granularity, ou umaderived_semantics.dimensionscomexpr. - Modelo novo:
semantic_model: { enabled: true, config: { meta: { escopo: adicao } } }, uma entidadeprimary(ouprimary_entity),foreignpara as dimensões eagg_time_dimension. - Mapeie a métrica ou a entidade nova num conceito de
docs/ontologia/rfb_cnpj.ttl(rfbo:metricaDbt,rfbo:entidadeSemantica) e na tabela da A4: otest_ontologia.pyfalha sem isso. - Rode
make semanticae acrescente um caso emtest_camada_semantica.pyque compare a métrica com o SQL direto.