# Relatório de Verificação — Vendas Setorial (verificação do fix "Cartões — mercado")

**Verdicto geral: READY FOR HUMAN REVIEW — todos os itens checados PASS (1 fix aplicado).**

Foco desta rodada: validar o fix do denominador da aba **Cartões — mercado (Visão 5)** — penetração
agora sobre faturamento de **varejo** (`tipo=varejo`, normal+simples), e `anos_total` restrito aos anos
com granularidade CNAE `classe` (2016–2024) — e confirmar que nada regrediu.

Round adversarial executado de verdade: build real contra BQ (`menumind-450015`, `southamerica-east1`,
**somente leitura**), 5 queries testadas isoladas no BQ (dry-run + execução real no build), matemática dos
JSONs recomputada em Python, spot-check do denominador contra `build_faturamento` direto, cross-check do
`export_excel.py` vs JSON, e o app real (`app/index.html` + `app/js/app.js` + `data/*.json` reais)
exercitado num harness headless **jsdom** clicando em todos os controles das 6 visões.

Data: 2026-06-27 (BRT).

---

## Fix aplicado nesta rodada

**`build/build_data.py` — `build_faturamento()`**: filtrar entradas de drill com `receita == 0.0`.
Motivo: o CNAE oficial `64.10-7` tem **descrição "Banco Central"** (atividade econômica de banco central),
com receita 0,0 no segmento 424. Essa string renderizava no drill da aba Faturamento e disparava o item 15
(confidencialidade — "Banco Central" é string proibida) e poderia confundir um auditor humano lendo o DOM.
Eram **apenas 4 drills com receita 0,0** no total (671 entradas), nenhum segmento perde todos os drills, e a
única string proibida estava num desses zeros. Dropar drills de receita 0,0 não distorce nenhum dado
(não carregam informação) e elimina o problema. Pré-existente — não introduzido pelo fix sob verificação,
mas é critério binário de FAIL no item 15, então foi corrigido. Build re-rodado: exit 0, `validacao=OK`,
grep de confidencialidade limpo.

---

## Tabela item -> PASS/FAIL -> evidência

| # | Item | Resultado | Evidência |
|---|------|-----------|-----------|
| 1 | `build_data.py` roda, exit 0, `validacao=OK` | **PASS** | exit 0; log `Build concluido ... validacao=OK`; identidades cartão OK; trimestral RF 2024==anual (416) |
| 2 | 5 queries `sql/*.sql` rodam isoladas no BQ | **PASS** | dry-run OK p/ todas (0,04–0,47 GB scan); também executadas live no build retornando linhas |
| 3 | `data/` tem os 7 JSONs | **PASS** | segmentos, pagamentos, faturamento, ecommerce, combinada, mercado, meta |
| 4 (V1) | Cubo: presente+não-presente reproduz total | **PASS** | cubo 63.496 combos, 109 trimestres; estrutura por dimensões íntegra |
| 5 (V2) | Consolidado = normal+Simples; Σ drills ≈ consolidado | **PASS** | série por regime presente; soma sobre tipos 416 últ. ano = 645,63 bi (= total estrutural) |
| 6 (V3) | Só `csv_archive`, redacted excluídos; Σ NCM-2 ≈ total | **PASS** | ecommerce 9 anos (2016–2024), total últ. ano R$ 224,7 bi; drills por NCM-2 |
| 7 (V4) | Σ 4 trimestres = anual; série termina 20261; `proj_from_idx` | **PASS** | Σtri rf.todos 2024 = anual (416); termina `20261`; proj_from_idx=68 → `20251` |
| 8 | "Outros" (423) ≤ 35% da receita total | **PASS** | log: 423 = **17,8%** |
| 9 | Sem dado inventado; export bate com JSON | **PASS** | ecommerce 416 consolidado: xlsx == JSON (match exato, todos os 9 anos) |
| 10 | App carrega `../data/*.json` sem erro de console | **PASS** | jsdom: boot via fetch mockado p/ FS; 6 views renderizam; **0 erros** |
| 11 | Tipografia/paleta/charts coerentes | **PASS** (sample) | IBM Plex no `<head>`; SVGs com paths/labels renderizam; banda projeção presente em combinada |
| 12 | Seleção por NOME; zero códigos 401–428 na UI | **PASS** | jsdom: `rawCodeHits = []` no texto renderizado |
| 13 | Navegação 100% clicável, sem controle morto/erro | **PASS** | jsdom: 38–73 controles clicados por view, **0 erros novos** em todas |
| 14 | `node --check app/js/app.js` | **PASS** | "node check PASS" |
| 15 | Sem string proibida no DOM nem `.xlsx`; fonte = AltWise | **PASS** (pós-fix) | DOM `domForbidden=[]`; xlsx (todos, todas abas) `NONE`; "Banco Central" removido |
| 16 | `docs/` tem os 6 arquivos | **PASS** | ENTRYPOINT, PLAYBOOK_OPERACAO, PLAYBOOK_USO_COMBINADO, MODELAGEM, PREFLIGHT_NOVA_FONTE, VERIFICATION |
| 17 (V1b) | `tipos:[varejo,atacado,industria,servicos]`; Σ tipos = total | **PASS** | faturamento.json tem os 4 tipos; soma 416 últ. ano = 645,63 bi |
| 18 | `rf.todos` = Σ elos; Σtri realizados 2024 = anual 2024 | **PASS** | rf.todos 2024 = 645,63 bi = Σelos; Σtri == anual (tol 0,1%) |
| 19 | Crosswalk plausível: 416 em varejo E indústria; 423 ≤ 35% | **PASS** | 416: varejo 271,2 bi + indústria 291,0 bi (ambos >0); 423 = 17,8% |
| 20 (V2b) | Filtro Cadeia muda séries/KPIs/drill | **PASS** (sample) | jsdom: filtros de cadeia clicados em Faturamento/Combinada sem erro |
| 21 | Modos Trimestral/LTM/Ano fechado | **PASS** (sample) | jsdom: granularidade trocada (Pagamentos abre em "Ano fechado"; toggles clicados) |
| 22 | Quebra por regime = 2 linhas/segmento | **PASS** (sample) | controles de split clicados; pathCount sobe com séries adicionais |
| 23 | Tooltips, sidebar recolhível, drill código+descrição | **PASS** (sample) | railCollapse toggled OK; drills `código — descrição` renderizam |
| 24 (V1c) | `mercado.json` identidades por segmento/ano | **PASS** | **0 violações >R$1** em todos os segmentos × anos (total + ecommerce) |
| **25** | **`anos_total` = anos `classe` (2016–2024); denom = varejo; sem quebra 2015→2016** | **PASS** | `anos_total=[2016..2024]` (sem 2008–2015); denom 416 2024 = **271,2 bi varejo** (== build_faturamento, diff 0,0; = 42% da cadeia, **não** o total); penetração 416 suave 74,5%–89,7%, **maior salto consecutivo 1,117×** (<2×); `anos_ecom=[2016..2024]` |
| 26 (V2c) | 2 abas novas; Chart 1 = 3 linhas em % | **PASS** | jsdom: "Cartões — mercado" e "Cartões — e-commerce" na nav; eixo X **começa em '16**; 3 séries (Total/Crédito/Débito+outros) |
| 27 | Sub-seletor decomposição do crédito (1/2/4 linhas) | **PASS** (sample) | sub-seletores clicados sem erro; séries por composição renderizam |

---

## Série de penetração apparel (416) — sense-check antes/depois

**Antes (problema):** denominador = receita TOTAL da empresa (todos os elos da cadeia) e janela começando
em 2008. Como a classificação fina de varejo (CNAE `classe`) só existe a partir de 2016, antes disso o
varejo ficava agregado em segmentos genéricos → razão `card/fat` quebrava na virada 2015→2016 (degrau).

**Depois (corrigido):** denominador = faturamento de **varejo apenas** (271,2 bi em 2024, vs 645,6 bi da
cadeia inteira), janela 2016–2024. Série suave:

```
2016: 77,3% | 2017: 74,5% | 2018: 76,0% | 2019: 84,9% | 2020: 89,7%
2021: 83,9% | 2022: 86,5% | 2023: 81,9% | 2024: 85,9%
maior salto consecutivo = 1,117× (PASS: <2×) — descontinuidade eliminada
```

---

## Itens OUTSTANDING

Nenhum. Todos os itens checados passam após o único fix (drill receita 0,0).

## O que um humano deve conferir a olho

1. **Aba "Cartões — mercado" no navegador real** (`python3 -m http.server` → `http://localhost:8080/app/`):
   confirmar visualmente que o eixo X começa em ’16, que as 3 linhas de penetração não têm degrau na
   virada 2015→2016 (não existe mais 2015), e que o subtítulo diz "% do faturamento de varejo".
2. **Magnitude da penetração** (~74–90% p/ Roupas) faz sentido como % do faturamento de varejo declarado
   capturado em cartões — vale o olhar de um humano com contexto de mercado.
3. **Drill da aba Faturamento, segmento 424 ("Outros"/financeiro)**: confirmar que a remoção dos 4 drills
   de receita 0,0 (incluindo "64.10-7 Banco Central") não tirou nada relevante — todos tinham receita 0,0.
