Pular para conteúdo

Configuração de campanhas por loja

As personalizações são específicas da loja selecionada. Sem personalização, permanecem os textos e as regras atuais. As regras de oferta, as curvas e os segmentos Ozcan podem ser personalizados sem alterar as outras lojas.

A ordem das abas é Visão geral, Ofertas sugeridas, Clientes, Produtos Relacionados, Personalização de ofertas e Regras fuzzy. A leitura por objetivo e por cliente é feita em Ofertas sugeridas e Clientes; mensagens e cupons são editados somente em Personalização de ofertas. Os atalhos de objetivo da visão geral e do assistente abrem o objetivo correspondente em Ofertas sugeridas, que lista os objetivos sempre em ordem numérica (O1 a O14).

Ofertas reúne a tabela de cupons por objetivo e a coluna Mensagem, com seleção da oferta do objetivo, da reserva (segunda opção) e das receitas. A edição abre campos obrigatórios, variáveis disponíveis, validação e prévia na própria célula. O contador de alterações e o botão Salvar alterações consideram cupons e mensagens; tudo é salvo em uma única transação. Mensagens inválidas impedem o salvamento.

Regras fuzzy reúne, nesta ordem: variáveis em lista expansível (uma aberta por vez), regras de oferta com seletores de objetivo/oferta e regras de segmento de cliente. A regra salva aparece como SE condições ENTÃO resultado, com as faixas numéricas de cada nível; o resumo usa os critérios salvos, enquanto o formulário conserva as alterações até salvar.

Parâmetros disponíveis

Grupo Parâmetros Aplicação
Mensagens Texto por objetivo, receita ou mensagem de reserva do objetivo; campos de preenchimento; prévia Próxima consulta de ofertas
Direcionamento Condições de uma regra; combinação de níveis baixo/médio/alto; prioridade alta/baixa das ofertas já vinculadas Próximo recálculo ou reimportação da loja
Régua da loja Quatro pontos das curvas baixo/médio/alto por variável; restauração do padrão do motor Próximo recálculo ou reimportação da loja
Cupons Um código por objetivo, tipo, valor/descrição, compra mínima, validade e status Compartilhado por todas as receitas e mensagens de reserva do objetivo
Dados automáticos Nome do cliente, produto sugerido, benefício e desconto padrão do objetivo Preenchidos quando disponíveis
Dados da campanha Preço, valor mínimo, quantidade, prazo, brinde e outros campos do modelo; valores numerados como {1} Placeholders para preenchimento; não calculados pelo editor

Critérios do motor

Objetivos e receitas entram como elegíveis a partir de 0,50 na escala de 0 a 1. Os níveis são relativos à distribuição dos clientes da loja, não cortes absolutos em reais ou dias. As faixas padrão de influência baixo (0–0,45), médio (0,20–0,80) e alto (0,55–1) se sobrepõem e vêm do YAML do motor; a loja pode personalizá-las na régua. Condições de critérios distintos se combinam por E; níveis do mesmo critério se combinam por OU.

Feature Nome na interface Interpretação
recencia Compra recente Alto = comprou mais recentemente; o número de dias é invertido
frequencia Frequência de compra Quantidade de pedidos
valor Valor total gasto Valor acumulado das compras
regularidade Variação entre compras Baixo = intervalos mais regulares
recop Atraso na recompra Tempo desde a compra comparado ao ciclo esperado
sensibilidade_preco Sensibilidade a preço Sinal histórico calculado de sensibilidade
profundidade_cesta Itens por cesta Profundidade histórica das compras
proximidade_aniversario Dias até o aniversário Baixo = aniversário mais próximo
impacto_calendario Relevância do calendário Impacto de datas e ocasiões
ticket_medio Ticket médio Valor médio histórico dos pedidos
afinidade_cross_sell Afinidade com produtos complementares Associação de compras (Market Basket)
concentracao_categoria_favorita Preferência por categoria Concentração das compras na categoria favorita
estoque_cliente Cobertura de estoque Alto = maior excesso entre produtos já comprados pelo cliente
lancamento_categoria_favorita Novidades na categoria favorita Alto = lançamento mais recente; número de dias invertido

O tier exibido não é uma condição direta dessas regras. A regra especial de cadastro sem compra, o fallback genérico, o limiar de elegibilidade (0,5), o algoritmo de produtos e os horários não são editados nesta tela. As curvas do motor de ofertas podem ser ajustadas por loja em Regras fuzzy. As cinco variáveis comuns também são usadas na segmentação Ozcan. Cada curva possui quatro pontos ordenados entre 0 e 1, e os níveis podem se sobrepor. Os percentis são recalculados com os dados da loja em cada execução; não existe nesta tela agendamento de recalibração a cada 90 dias.

Textos podem usar campos nomeados, por exemplo {customer_name}, {product}, {discount}, ou numerados, por exemplo Leve o combo por R$ {1}. Campos sem valor permanecem visíveis para preenchimento, em vez de serem apagados.

O editor salva texto e valores juntos e exige o preenchimento dos campos obrigatórios. O código {coupon} vem do objetivo e não pode ser alterado no editor de uma receita. Desconto, compra mínima e validade são preenchidos com as condições do cupom, quando disponíveis; valores específicos da mensagem podem ser personalizados. A prévia usa um nome e um produto ilustrativos, sem inventar preços ou códigos.

As associações ficam em objective_coupons dentro do JSON da configuração existente. Para configurações antigas, o motor prefere o cupom do objetivo ou, na ausência dele, o da primeira receita por ID. Essa leitura não altera os dados existentes. Ao salvar a tabela, consolida os vínculos do objetivo e preserva os campos e textos de cada oferta. Renomear um código pela API de cupons também atualiza seus vínculos por objetivo.

Produtos recomendados por cliente

As ofertas com produto (O4, O5 e O9) recebem produtos escolhidos para cada cliente, calculados a cada Recalcular ou Atualizar dados e gravados em platform.produtos_recomendados_snapshot (até 6 por cliente e objetivo). Cada objetivo segue uma cascata, da camada mais personalizada à lista da loja; a última camada garante produto a todo cliente da oferta, inclusive a quem nunca comprou.

Objetivo Camadas, em ordem
O5 · complementares Regras de associação a partir do que o cliente comprou (lift acima de 1,0, peso maior para compras recentes) → mais vendidos das categorias preferidas → mais vendidos da loja. Nunca repete o que o cliente já comprou, salvo se ele já comprou todo o catálogo disponível.
O4 · quantidade O que o cliente mais compra → mais vendidos das mesmas categorias ainda não comprados → mais vendidos da loja.
O9 · giro de estoque Produto de pior giro entre os que o cliente comprou → estoque parado das categorias preferidas → estoque parado da loja → mais vendidos da loja.

Produtos com estoque zerado no catálogo ficam de fora. A API devolve o motivo de cada produto (motivo e produto_origem em produtos_sugeridos), exibido na ficha do cliente, e usa o primeiro produto da oferta em {complementary_product} e o produto que originou a associação em {trigger_product}. Os parâmetros (lift mínimo, quantidade, meia-vida da recência) ficam em app/engine/tools/produtos_recomendados.yml. Loja ainda não recalculada depois da implantação usa a lista da loja até o próximo cálculo.

Persistência e publicação

Personalizações ficam na tabela platform.marketing_campaign_settings, por empresa_id, como diferenças em relação aos padrões. A restauração remove a diferença e volta ao padrão. Mudanças nos critérios exigem atualizar os dados da loja. Mudanças no texto invalidam o cache local das ofertas.

Esta atualização usa a tabela de configurações existente e não acrescenta migração. Para publicar no modo trunk atual, seguir a esteira: MR diretamente para main, build/release e deploy manual de produção. Quando promotion for retomado, usar o fluxo via develop/HML. Não atualizar arquivos diretamente na antiga VPS. Um ambiente que ainda não possui a tabela de configurações deve executar as migrações pendentes pelo procedimento de deploy.

Na raiz do checkout atualizado do servidor:

docker compose -f infra/docker-compose.yaml build marketing-campaigns frontend-entrypoint panel
docker compose -f infra/docker-compose.yaml up -d --no-deps --force-recreate marketing-campaigns frontend-entrypoint panel

A mensagem de reserva (por exemplo, “separamos sua seleção favorita”) aparece quando um objetivo é elegível, mas nenhuma oferta específica fornece texto correspondente. Textos, inclusive os de reserva, são editados na coluna Mensagem do catálogo de Ofertas.

O catálogo registra cupons já existentes no e-commerce, sem criá-los nessa plataforma. Cupons inativos ou vencidos são sinalizados na tabela e impedem salvar novas mensagens que usem seu código. Vínculos existentes são preservados. Cupons antigos sem cadastro permanecem visíveis para registro. Se um objetivo tinha mais de um código, a tela indica os códigos anteriores e pede revisão antes de consolidar os vínculos. Renomear um código pela API atualiza os objetivos vinculados na mesma transação; excluir um cupom em uso exige remover esses vínculos primeiro.

Os endpoints administrativos usam a loja selecionada e exigem acesso de administrador:

  • GET /api/marketing/lojas/{loja_id}/configuracao-campanhas: catálogo, régua efetiva e cupons com used_in.
  • PUT .../objetivos: {"objectives":{"O8":{"code":"VOLTE10","type":"percent","value":"10%","minimum":100,"expires_on":"2026-12-31","active":true},"O9":null}}. Salva a tabela em uma transação; null remove o vínculo do objetivo.
  • PUT .../editor/{oferta}: {"text":"Olá {customer_name}, use {coupon}.","fields":{}}. Salva texto e campos juntos, usando o cupom do objetivo e validando os placeholders.
  • PUT .../parametros/{name}: {"ranges":{"low":[0,0,0.25,0.45],"medium":[0.2,0.4,0.6,0.8],"high":[0.55,0.75,1,1]}}. ranges: null restaura o padrão da variável.
  • PUT .../cupons/{code}: {"code":"VOLTE10","type":"percent","value":"10%","minimum":100,"expires_on":"2026-12-31","active":true}. remove: true exclui; um code diferente renomeia o cupom.

Regras de segmento e compatibilidade do motor

Os nove segmentos e seus critérios padrão vêm de fuzzy_segmentos.yml, incluindo Precisa de atenção, presente no motor. Personalizações ficam em segment_rules no JSON existente de configurações por loja. Os dois pipelines aplicam as regras e curvas efetivas antes de salvar o snapshot. Restaurar remove a personalização; os resultados mudam após Atualizar dados ou reimportar a loja. As regras mantêm o segmento de destino e aceitam apenas variáveis e níveis reconhecidos pelo motor.

O motor de ofertas possui prioridades Alta e Baixa. Os níveis Baixo, Médio e Alto são níveis de entrada das variáveis, não três prioridades de saída. Não foi inventada uma prioridade média. Regras compartilhadas entre objetivos/receitas indicam todos os destinos no editor.

A regra R_lancamento_recente aparece como Lançamentos recentes na categoria favorita. O critério é lancamento_categoria_favorita, calculado pela data de criação do produto mais recente na categoria favorita. Ele não mede a última compra do cliente (recencia); o critério do motor foi preservado e o título foi alinhado a ele.

Novos endpoints administrativos, específicos por loja:

  • PUT .../configuracao-campanhas/catalogo: objectives e messages (texto, campos e opção restore) salvos atomicamente, sem resultados parciais.
  • PUT .../configuracao-campanhas/segmentos/{name}: critérios de um segmento ou restore: true para restaurar o padrão.
  • O catálogo GET inclui segment_rules e segment_features derivados do motor.

Produtos Relacionados mantém a paginação e ordenação no servidor. O card Como ler mostra um exemplo de 100 pedidos (20 com A, 10 com B e 5 com ambos): suporte 5%, confiança A→B 25% e lift 2,5. O SVG distingue os grupos; cada coluna tem sua própria ajuda antes do ícone de ordenação.

Esta atualização usa o JSON de configurações existente, sem migração. Para publicar, reconstrua marketing-campaigns, frontend-entrypoint e panel. Recalcule a loja após mudar curvas ou critérios; alterações de mensagens e cupons ficam disponíveis nas próximas consultas.

Persistência das regras de associação

Os dois caminhos de importação salvam a competência das regras mensais na coluna SQL mes. O motor usa o nome month, mas a inserção direta com SQLAlchemy Core exige o nome físico mes. Somente regras gerais têm mes IS NULL; regras mensais sem competência são rejeitadas antes da substituição dos dados. Uma execução sem regras remove resultados antigos apenas da loja recalculada.

Versões anteriores perdiam a competência mensal na inserção, fazendo regras mensais aparecerem na consulta de regras gerais e distorcendo a estimativa de pedidos. Após publicar o serviço marketing-campaigns corrigido, reimporte/recalcule a base afetada pelo painel. Não basta reiniciar o serviço: os registros antigos não contêm a competência e precisam ser gerados novamente. Não há migração de estrutura. Com suporte mínimo de 2%, a tabela geral pode ficar vazia quando nenhum par atinge esse corte na base inteira, mesmo que existam associações mensais.