{
  "methodologies": [
    {
      "version": "analytics-v1",
      "name": "Camada analitica v1 (guarda-chuva)",
      "description": "Regras transversais: semana ISO 8601 em America/Sao_Paulo (offset fixo -03, DST abolido em 2019); spend/impressions = faixas Meta da ultima observacao por anuncio com collected_at <= fim da semana; midpoint=(lower+upper)/2; percentis percent_rank*100 SOMENTE dentro do mesmo cargo; ausencia de dado nunca vira zero (colunas *_status).",
      "formula_json": {
        "week": "ISO 8601 (segunda a domingo)",
        "spend": "faixas Meta, ultima observacao por anuncio ate o fim da semana; midpoint=(lower+upper)/2",
        "timezone": "America/Sao_Paulo",
        "utc_offset": "-03:00",
        "percentiles": "percent_rank * 100 dentro do mesmo cargo e mesma semana",
        "missing_data": {
          "ads_status": [
            "observed",
            "zero_ads_full_sweep"
          ],
          "finance_status": [
            "observed",
            "not_found_in_dataset"
          ],
          "instagram_status": [
            "observed",
            "no_public_instagram",
            "not_collected_in_window"
          ],
          "dependency_status": [
            "computed",
            "no_paid_expenses"
          ]
        }
      },
      "valid_from": "2026-08-28T03:00:00.000Z"
    },
    {
      "version": "paid-dependency-v1",
      "name": "Dependencia de Midia Paga v1",
      "description": "Proporcao tse_boosting_paid / tse_paid_total, apenas despesas kind=paga (contratada JAMAIS entra no quociente). NULL quando denominador ausente ou zero.",
      "formula_json": {
        "null_when": "denominador ausente ou zero (dependency_status=no_paid_expenses)",
        "numerator": "soma de campaign_expenses kind=paga com origem_despesa ILIKE %mpulsionamento%, data_despesa <= fim da semana",
        "denominator": "soma de campaign_expenses kind=paga, data_despesa <= fim da semana"
      },
      "valid_from": "2026-08-28T03:00:00.000Z"
    },
    {
      "version": "presence-v1",
      "name": "Indice de Presenca Digital v1",
      "description": "Score aditivo 0-100 com 4 componentes binarios observaveis de 25 pontos cada. Nenhuma interpretacao subjetiva; nenhum LLM.",
      "formula_json": {
        "week": "ISO 8601, America/Sao_Paulo",
        "scale": "0-100",
        "components": {
          "declaredProfile": {
            "rule": "existe vinculo status=declarado (rede declarada ao TSE); a declaracao acompanha o registro de candidatura, anterior ao periodo analisado, entao vale para todas as semanas do recorte",
            "points": 25
          },
          "metaAdsObserved": {
            "rule": "existe anuncio Meta vinculado com periodo de veiculacao intersectando a semana (start <= fim; stop nulo ou >= inicio)",
            "points": 25
          },
          "confirmedProfile": {
            "rule": "existe vinculo status=confirmado com validated_at <= fim da semana",
            "points": 25
          },
          "instagramObserved": {
            "rule": "existe snapshot de perfil instagram publico (declarado/confirmado) com observed_at na janela de 28 dias terminando no fim da semana",
            "points": 25
          }
        },
        "window_days_instagram": 28
      },
      "valid_from": "2026-08-28T03:00:00.000Z"
    },
    {
      "version": "structure-v1",
      "name": "Estrutura Digital de Campanha v1",
      "description": "Score aditivo 0-100 com 4 componentes binarios observaveis de 25 pontos cada (pesos iguais, decisao documentada). Mede estrutura observavel, nao qualidade.",
      "formula_json": {
        "scale": "0-100",
        "weights": "iguais por decisao metodologica explicita",
        "components": {
          "adsRecurrence": {
            "rule": "anuncios Meta ativos em >= 2 das ultimas 4 semanas (incluindo a corrente)",
            "points": 25
          },
          "multiPlatform": {
            "rule": ">= 2 plataformas distintas com vinculo publico (declarado vale para todo o recorte; confirmado a partir da validacao)",
            "points": 25
          },
          "confirmedProfile": {
            "rule": ">= 1 vinculo confirmado por validacao humana com validated_at <= fim da semana",
            "points": 25
          },
          "instagramContinuity": {
            "rule": "instagram observado na janela de 28 dias terminando no fim da semana",
            "points": 25
          }
        }
      },
      "valid_from": "2026-08-28T03:00:00.000Z"
    }
  ]
}