# Dicionário e metodologia

## Escopo e origem

Marca fictícia Lume, coleção Entretempo. Dados integralmente sintéticos de **01/08/2026 a 28/08/2026**, sem operação comercial real. Os nomes e preços seguem `portfolio/shared/products.json`. O gerador não usa APIs ou informações pessoais. A semente é `20260828`, com algoritmo LCG de 32 bits documentado em `data/provenance.json`.

Cada pedido recebe um único canal sintético. Não há rastreamento observado de cliques, identificador de cliente, janela de conversão ou atribuição multicanal. “Receita atribuída” significa somente a soma de pedidos associados ao canal na base fictícia. Um pedido pode incluir vários itens e unidades; não representa um cliente único.

As datas são chaves de calendário no formato `AAAA-MM-DD`, sem horário. Não há conversão de fuso. O cenário usa 28 dias completos e comparáveis, divididos em dois períodos de 14 dias: 01–14 e 15–28. Esta divisão não equivale a um experimento controlado.

## `orders.json`

Uma linha por pedido. Chave única: `id`. Total: 228 linhas, sendo 214 `pago` e 14 `cancelado`.

| Campo | Tipo e unidade | Significado |
|---|---|---|
| `id` | texto | Identificador sintético estável, como `LUME-0001`. |
| `date` | texto de data ISO | Data do pedido, usada em todos os filtros e agrupamentos. |
| `channel` | enum | `social-pago`, `busca-paga`, `organico`, `email` ou `direto`. |
| `status` | enum | `pago` ou `cancelado`. Cancelados ficam fora de todas as métricas de pedidos, receita, produtos, descontos e estornos. |
| `items` | array não vazio | Linhas de produto do pedido. |
| `items[].sku` | texto | SKU existente no catálogo canônico. |
| `items[].quantity` | inteiro positivo | Unidades originalmente compradas na linha. |
| `items[].unitPriceCents` | inteiro, centavos BRL | Preço unitário da transação antes de desconto. No dataset coincide com o catálogo. |
| `discountCents` | inteiro, centavos BRL | Desconto total do pedido, sem distribuição entre SKUs. |
| `refundCents` | inteiro, centavos BRL | Valor estornado do pedido, já considerado após desconto. Sem identificação do SKU devolvido ou data própria do estorno. |

Pedidos estornados integralmente continuam com status `pago`: contam como pedido pago e conversão, mas sua receita após ajustes é zero. Portanto, o denominador do ticket médio inclui esses pedidos. O dataset contém estornos parciais e integrais para testar essa regra.

Todo estorno é atribuído à **data original do pedido**, porque não há data de evento financeiro. A análise é uma visão dos pedidos do período após ajustes informados, não fluxo de caixa diário nem relatório contábil. Um estorno de uma compra antiga, ocorrido no período, não está representado nesta estrutura.

## `traffic.json`

Uma linha por data e canal. Chave única: `date` + `channel`. São 28 × 5 = 140 linhas. Há cobertura dos cinco canais em todos os dias.

| Campo | Tipo e unidade | Significado |
|---|---|---|
| `date` | texto de data ISO | Data de referência da sessão e do gasto. |
| `channel` | enum | Mesma lista de canais dos pedidos. |
| `sessions` | inteiro não negativo | Sessões simuladas. Sessões não representam pessoas únicas. |
| `spendCents` | inteiro, centavos BRL | Investimento simulado em mídia. Somente `social-pago` e `busca-paga` podem ter gasto. |

Gasto zero em orgânico, e-mail e direto significa **ausência de gasto de mídia nesta base**, não ausência de custos de produção, equipe, ferramentas ou operação. A base não contém impressões, cliques ou custos de produto. CPC, CTR, margem, ROI e lucro não podem ser calculados.

## Fórmulas e saída de `calculateMetrics`

Todas as somas monetárias usam centavos inteiros. As divisões são feitas sobre os totais do recorte, nunca pela média das taxas de dias ou canais. O ticket médio é arredondado ao centavo somente ao final.

| Campo | Cálculo e limite |
|---|---|
| `grossCents` | Soma de `quantity × unitPriceCents` em pedidos pagos. |
| `discountCents` | Soma dos descontos dos pedidos pagos. |
| `refundCents` | Soma dos estornos dos pedidos pagos. |
| `revenueCents` | `grossCents − discountCents − refundCents`. Usar o rótulo “Receita após descontos e estornos”. Não desconta impostos, custos de mercadoria, frete ou operação. |
| `orders` | Contagem de pedidos com status `pago`, inclusive os integralmente estornados. |
| `sessions` | Soma de sessões no mesmo recorte de data e canal. |
| `spendCents` | Soma de gasto nos canais pagos do recorte. |
| `aovCents` | `revenueCents / orders`, arredondado ao centavo. `null` se não há pedidos pagos. |
| `conversionRate` | `orders / sessions`. Fração, por exemplo `0.01865` = aproximadamente `1,865%`. `null` sem sessões; zero quando há sessões e nenhum pedido. Não mede compradores únicos. |
| `roas` | Receita após ajustes atribuída a `social-pago` + `busca-paga`, dividida pelo gasto desses canais no mesmo recorte. `null` sem gasto. Rótulo: **ROAS da mídia paga**. Não usar receita de orgânico, e-mail ou direto no numerador. |
| `daily` | Datas em ordem crescente, com `revenueCents` e `orders`. Inclui dias sem pedidos como zero. |
| `channels` | Cinco canais em ordem fixa, ou apenas o canal filtrado. Receita, pedidos, sessões, gasto, conversão e ROAS. ROAS de canais sem mídia é sempre `null`. |
| `products` | Seis SKUs em ordem de catálogo, com nome, unidades e valor **bruto** dos itens pagos. Sem rateio de descontos/estornos, logo não representa receita após ajustes nem unidades líquidas de devolução por SKU. |
| `insights` | Lista `{title, body}` produzida por regras determinísticas a partir do recorte. Declara contagens, fórmulas e limites. Não há chamada de IA. |

### Filtros e ausência de dados

`from` e `to` são inclusivos e podem ser omitidos separadamente. Sem datas explícitas, o eixo diário vai da menor à maior data presente nos dados. Com início e fim informados, o eixo diário cobre cada dia solicitado, mesmo sem pedidos. O canal omitido inclui os cinco canais; qualquer outro valor deve ser um dos cinco IDs válidos.

Intervalo invertido, data inexistente, canal desconhecido, ID duplicado, tráfego duplicado, SKU fora do catálogo, valores fracionários de centavos e desconto + estorno maior que o bruto geram erro explícito. O módulo não corrige registros silenciosamente. A comparação de campos monetários depende de entradas dentro da faixa de inteiros seguros de JavaScript, adequada a este dataset demonstrativo.

Uma lista de tráfego vazia não permite distinguir coleta ausente de ausência real de tráfego. Nesse caso, taxas sem denominador retornam `null`; não se presume completude. A cobertura completa foi verificada especificamente para o dataset entregue.

## CSVs

Os arquivos usam UTF-8, vírgula como separador e fim de linha CRLF. Números são valores sem símbolo de moeda ou separador de milhar. Datas ISO são texto intencional para interoperabilidade. Ao abrir em uma planilha brasileira, selecione vírgula como delimitador e mantenha a unidade centavos; divida por 100 apenas na apresentação monetária.

| Arquivo | Granularidade |
|---|---|
| `exports/orders.csv` | Uma linha por pedido, incluindo os cancelados. Ajustes aparecem uma única vez. |
| `exports/order-items.csv` | Uma linha por item, com `orderId` e `line` como chave composta; `lineGrossCents` é quantidade × preço. |
| `exports/traffic.csv` | Uma linha por dia e canal. |
| `exports/products.csv` | Um SKU por linha, com nome, categoria e preço canônico. |

Relacionar itens ao pedido por `orderId` para obter status, data e canal. **Não somar descontos ou estornos após repeti-los em cada item de uma junção**: os ajustes têm granularidade de pedido. Para reproduzir os indicadores, primeiro agregue itens por pedido, aplique os ajustes uma vez e exclua cancelados.

## Desenho do cenário e limites de interpretação

O gerador aumenta deliberadamente sessões e gasto do social pago na segunda metade, troca o conjunto principal de produtos por opções de menor preço e aplica desconto de 15% nesses pedidos. As outras regras adicionam variação determinística em tráfego, cestas e estornos. Esses são parâmetros do cenário sintético, não fatos descobertos sobre consumidores.

É possível decompor aritmeticamente a queda da receita em cestas, descontos e estornos. Não é possível estimar com esta base o efeito causal do aumento de mídia sobre intenção de compra, conversão, retenção ou lucro. A comparação entre períodos também mistura audiência, produto e oferta. E-mail tem uma base pequena e diferente dos canais de aquisição; sua conversão superior não garante potencial de expansão.

## Verificação

Os testes incluem uma base manual de quatro pedidos, com receita esperada de 3.000 centavos após um cancelamento e dois tipos de estorno. Um segundo cálculo independente usa inteiros `BigInt` no dataset completo e confere cinco recortes, os totais por canal e por dia. O valor bruto por produto também reconcilia com o bruto geral. Constantes externas ao gerador fixam os totais esperados do cenário.

`expected-metrics.json` contém os recortes `all`, `firstHalf`, `secondHalf`, `socialFirstHalf` e `socialSecondHalf`. O arquivo inclui também os textos determinísticos do recorte. Alterar o cálculo ou os dados exige executar os testes; não considerar um snapshot recém-exportado como prova por si só.
