# Valia × RD Station — Análise de Identidade de Contatos **Data:** 2026-06-01 **Contexto:** Avaliação de viabilidade de substituição do Responsys pelo RD Station Marketing **Questão central:** Como tratar registros com emails iguais para pessoas diferentes (e/ou mesma pessoa com múltiplos planos e emails distintos)? > **Documento mestre (operação + treinamento + técnico):** [`valia-rd-station-consolidado-2026-06-01.md`](valia-rd-station-consolidado-2026-06-01.md) --- ## 1. O Problema Real (Valia) A Valia possui uma estrutura de dados que não mapeia 1:1 com o modelo convencional de CRM de marketing: | Cenário | Descrição | Exemplo | |---------|-----------|---------| | **A** | Mesma pessoa, emails diferentes por plano | Bernardo com plano de 2005 (email antigo) e plano de 2025 (email novo) | | **B** | Email de titular usado para dependente | Pai coloca o próprio email no plano Pré-Valer do filho | | **C** | Mesmo email, múltiplos planos | Pessoa com CPF único, 3 contratos diferentes (FSS distintos) | | **D** | Mesmo CPF, comportamentos diferentes por plano | Quero falar do plano X sem que o titular do plano Y receba | **Identificadores da Valia:** - **CPF** = identidade da pessoa física (pode repetir em múltiplos registros) - **FSS** = identidade do contrato/plano (único por contratação) - **Email** = informativo, pode ser qualquer email, não é chave de negócio --- ## 2. Como o RD Station Funciona (Limitações Encontradas) ### 2.1 Chave primária: o email é intocável > **Fonte:** [developers.rdstation.com/reference/contatos](https://developers.rdstation.com/reference/contatos) O campo `email` é a **única chave de identificação nativa** do RD Station Marketing. - Ao criar um contato com email já cadastrado → erro `EMAIL_ALREADY_IN_USE` - Não há opção de configurar outra chave primária nativa - Identificadores disponíveis via API: `email` ou `uuid` (gerado automaticamente pelo RD) ``` GET/PATCH /platform/contacts/email:{email} GET/PATCH /platform/contacts/uuid:{uuid} ``` **Impacto para a Valia:** O RD Station, por padrão, tratará "a pessoa" como "o email". Isso conflita diretamente com os cenários A, B e C acima. --- ### 2.2 Campos Personalizados disponíveis > **Fonte:** [developers.rdstation.com/reference/campos-personalizados](https://developers.rdstation.com/reference/campos-personalizados) Tipos suportados no Marketing API: - `STRING` — texto aberto - `STRING[]` — lista de strings (múltipla escolha) - `INTEGER` — número inteiro - `BOOLEAN` — verdadeiro/falso No CRM (vendas): - `text`, `option`, `date`, `multiple_choice` - Campo do tipo **único** (impede duplicatas — útil para CPF) **O que isso abre:** É possível criar `cf_cpf`, `cf_fss`, `cf_plano_tipo`, `cf_data_admissao`, `cf_estado_civil`, etc. como campos personalizados e usá-los em **segmentação e automação**. --- ### 2.3 Eventos de Conversão — a grande alavanca > **Fonte:** [developers.rdstation.com/reference/evento-de-conversao-padrao](https://developers.rdstation.com/reference/evento-de-conversao-padrao) Endpoint: `POST /platform/events?event_type=conversion` Cada chamada registra um **evento no histórico do contato** com campos customizados. O campo `conversion_identifier` nomeia o evento. ```json { "event_type": "CONVERSION", "event_family": "CDP", "payload": { "conversion_identifier": "admissao_plano", "email": "pessoa@email.com", "cf_fss": "FSS-00123", "cf_plano_tipo": "PREVALER", "cf_data_admissao": "2025-06-01" } } ``` **Por que isso importa:** As automações do RD Station podem ser disparadas por eventos de conversão específicos, e a segmentação pode filtrar por quem converteu em `admissao_plano`. Isso é exatamente o modelo que o Thiago validou para as automações de admissão. --- ### 2.4 Segmentação: o que funciona - Por valor de campo personalizado (`cf_fss == "FSS-00123"`) - Por tag acumulada no contato - Por evento de conversão (quem fez conversão X nos últimos N dias) - Por campo padrão (estado civil, cidade, etc.) **O que NÃO funciona nativamente:** Segmentar por "qual plano gerou o email de admissão" se o mesmo email tiver múltiplos planos — o contato é um só e os campos seriam sobrescritos. --- ## 3. Opções Arquiteturais ### Opção A — One Contact per Email (abordagem nativa) **Para quem:** Cenário em que a pessoa tem sempre o mesmo email e, no máximo, 2-3 planos. **Como funciona:** - Email = chave primária (como o RD quer) - CPF salvo como `cf_cpf` (campo único no CRM) - FSS de cada plano salvo em slots numerados: `cf_fss_1`, `cf_fss_2`, `cf_fss_3` - Tags indicam os tipos de plano: `plano:prevaler`, `plano:previdencia` - Eventos de conversão registram mudanças por FSS específico **Vantagens:** - Implementação mais simples - Totalmente nativa no RD - Segmentação por campos personalizados funciona **Limitações:** - Número fixo de slots de FSS (precisa definir um teto) - Cenário B (email do pai no plano do filho) gera um contato híbrido confuso - Cenário A (pessoa com emails diferentes por plano) cria dois contatos separados no RD **Viabilidade:** Média — funciona para a maioria dos casos, mas falha nos cenários edge --- ### Opção B — One Contact per FSS (contrato como unidade) **Para quem:** Quando cada contrato precisa de comunicação 100% independente. **Como funciona:** - Email de contato no RD = `{cpf}-{fss}@valia-rds.internal` (sintético, gerado pelo middleware) - Email real da pessoa = salvo em `cf_email_real_1`, `cf_email_real_2` - **Envio via API**: o RD envia para o campo `email` primário (sintético) — isso não funciona para email real - O middleware intercepta antes do envio e substitui o destinatário **⚠️ Problema crítico:** O RD Station envia emails para o campo `email` do contato. Com email sintético, os disparos não chegam à pessoa real sem uma camada extra de intercepção — que o RD não oferece nativamente. **Viabilidade:** Baixa sem um middleware muito pesado --- ### Opção C — Middleware com Identity Resolution (RECOMENDADA) **Para quem:** Operação robusta com múltiplos cenários de identidade. **Arquitetura:** ``` Valia (ERP/API) ↓ [Middleware M2BR] ├── Identity Resolver (CPF + FSS → email canônico) ├── Conflict Manager (mesmo email, planos diferentes) └── Event Router (qual evento vai para qual contato) ↓ RD Station API ``` **Regras do Identity Resolver:** 1. **CPF como chave de busca**: middleware busca contatos no RD pelo `cf_cpf` 2. **Email canônico**: elege o email mais recente (ou o mais "ativo") como email principal no RD 3. **Emails alternativos**: armazenados em `cf_email_plano_1`, `cf_email_plano_2` 4. **FSS como discriminador**: cada comunicação carrega o FSS → automação filtra pelo FSS correto **Para o Cenário B (pai + filho com mesmo email):** - Middleware detecta: CPF diferente, mesmo email - Cria um segundo contato com email `{cpf_filho}@alias.valia` - Salva `cf_email_real = email_do_pai` e `cf_responsavel_cpf = cpf_pai` - O disparo de email usa template com variável `{{cf_email_real}}` como destinatário (via API de envio transacional) **Vantagens:** - Resolve todos os cenários edge - Mantém o RD Station como "fonte de verdade de marketing" - Permite automações nativas do RD (com segmentação por FSS) - Histórico de eventos por plano fica no RD Station **Desafios:** - Middleware tem lógica não trivial - Precisa da documentação de como o Responsys resolve hoje (dever de casa do Bruno) - Envio para `cf_email_real` pode exigir API transacional separada **Viabilidade:** Alta — é o caminho mais robusto --- ### Opção D — Eventos como registro principal de plano **Complementar à Opção C — para automações específicas** Em vez de usar apenas campos fixos para dados de plano, cada mudança relevante é um evento de conversão: | Evento | `conversion_identifier` | Campos customizados | |--------|--------------------------|---------------------| | Admissão | `admissao_plano` | `cf_fss`, `cf_plano_tipo`, `cf_data_admissao` | | Mudança estado civil | `mudanca_estado_civil` | `cf_fss`, `cf_estado_civil_novo`, `cf_data_mudanca` | | Atualização cadastral | `atualizacao_cadastral` | `cf_fss`, campos atualizados | **Automação por evento:** - Trigger: "Quem converteu em `admissao_plano` nos últimos 30 dias" - Segmentação adicional: `cf_plano_tipo == PREVALER` - Email disparado: somente para esse segmento Isso resolve exatamente o que Thiago validou: "a gente vai transformar a data de admissão num evento... a gente pode pegar quem converteu nos últimos 30 dias." --- ## 4.1 Automações E/F (mockup + sandbox) Cenários operacionais além de duplicados, modelados no protótipo **https://mockupvalia.m2br.com/**: | ID | Dor | Middleware | RD | |----|-----|------------|-----| | **E** | Admissão entre dias 1–5 → ofertas **todo mês** nessa janela | `day(cf_data_de_admissao)` → `cf_dia_ciclo_mensal` ou tag `ciclo-admissao:01-05` · `RULE_ADMISSION_CYCLE_DAY` | Workflow **recorrente mensal** + segmento dia 1–5 | | **F** | SOLTEIRO→CASADO → upgrade plano + parceiro dependente | `mudanca_estado_civil` + elegibilidade `cf_plano` · dependente → alias (cenário B) · `RULE_ESTADO_CIVIL_UPGRADE` | Automação por **evento** (não mensal) | - Visual: [`mvp/visual/cenario-e.html`](mvp/visual/cenario-e.html), [`cenario-f.html`](mvp/visual/cenario-f.html), [`fluxos-automacao.html`](mvp/visual/fluxos-automacao.html) - Sandbox: fixtures `cenario_e.json`, `cenario_f.json` · smoke **ST-07** (ciclo) e **ST-08** (civil + dependente) --- ## 4. Estado Civil — Análise Específica **Pergunta da reunião:** Precisa de histórico de estado civil ou só o último status? **Conclusão (confirmada pelo Bruno):** Só o último status interessa para o disparo. **Implementação no RD:** ```json PATCH /platform/contacts/email:{email} { "cf_estado_civil": "Casado" } ``` O campo é sobrescrito — sem histórico no RD. O histórico fica no sistema da Valia/middleware. **Automação de "casou":** - O sistema da Valia detecta mudança → chama middleware → middleware envia evento de conversão `mudanca_estado_civil` - A automação no RD dispara para quem converteu nesse evento - Campo `cf_estado_civil` atualizado para `Casado` **Ou via API direta (se a Valia conseguir fazer a notificação):** ```json POST /platform/events?event_type=conversion { "event_type": "CONVERSION", "event_family": "CDP", "payload": { "conversion_identifier": "mudanca_estado_civil", "email": "bernardo@email.com", "cf_fss": "FSS-00123", "cf_estado_civil_novo": "Casado" } } ``` → Automação no RD dispara email de atualização de beneficiários imediatamente. --- ## 5. Smoke Tests — Resultados Reais (2026-06-01) Todos os testes foram executados contra a **conta real da Valia no RD Station** usando as credenciais OAuth já configuradas na intranet M2BR (`RDSTATION_VALIA_ACCESS_TOKEN`). > **Importante descoberto:** a conta Valia já possui **43 campos customizados** configurados, incluindo exatamente os que precisamos: `cf_cpf`, `cf_fss`, `cf_estado_civil`, `cf_data_de_admissao`, `cf_plano`. Não é necessário criar campos novos para o MVP. --- ### ST-01 ✅ PASS — Upsert contato com `cf_cpf` e `cf_fss` ``` HTTP 200 { "uuid": "5441b820-94bb-487f-ae0c-ec7f30608646", "email": "m2br.smoke.test.valia@gmail.com", "cf_cpf": "00000000000", "cf_fss": "FSS-SMOKE-001", "tags": ["smoke-test", "plano:prevaler"] } ``` → Campos `cf_cpf` e `cf_fss` **já existem na conta** e aceitam valor via PATCH. --- ### ST-02 ✅ PASS — Detecção de email duplicado (cenário pai+filho) ``` HTTP 400 {"error_type": "EMAIL_ALREADY_IN_USE", "error_message": "Email already in use"} ``` → Comportamento confirmado: qualquer tentativa de criar segundo contato com mesmo email é bloqueada. O middleware deve capturar esse erro e aplicar a lógica de alias. --- ### ST-03 ✅ PASS — Evento `admissao_plano` ``` HTTP 200 {"event_uuid": "10865fd6-1063-4fe7-b69e-ea1ec3bc2bbf"} ``` → Evento registrado no histórico do contato com `cf_fss: FSS-SMOKE-001`. --- ### ST-04 ✅ PASS — Evento `mudanca_estado_civil` ``` HTTP 200 {"event_uuid": "bb20e1f8-5fbd-4cb6-8743-b625682b8400"} ``` → Evento registrado. O campo `cf_fss` viaja junto no payload, permitindo que a automação identifique qual plano gerou a mudança. --- ### ST-04b ✅ PASS — Atualizar `cf_estado_civil` no perfil do contato **Descoberta crítica:** o campo `cf_estado_civil` já existe na conta Valia como campo de **seleção única** com opções predefinidas: ``` Valores válidos: CASADO | UNIÃO ESTÁVEL | SOLTEIRO | SEPARADO JUDICIAL | OUTROS | DIVORCIADO | VIÚVO ``` Enviar `"Casado"` retorna erro `MUST_BE_VALID_OPTION`. Enviar `"CASADO"` retorna HTTP 200. → **O middleware deve normalizar os valores de estado civil para maiúsculas** antes de enviar ao RD. --- ### ST-05 ✅ PASS — Histórico de eventos do contato A API retorna **array direto** (não objeto com chave `events`): ```json [ { "event_type": "CONVERSION", "event_identifier": "mudanca_estado_civil", "event_timestamp": "2026-06-01T15:29:47.712-03:00", "payload": { "email": "m2br.smoke.test.valia@gmail.com", "conversion_identifier": "mudanca_estado_civil", "cf_fss": "FSS-SMOKE-001" } }, { "event_type": "CONVERSION", "event_identifier": "admissao_plano", "event_timestamp": "2026-06-01T15:29:48.138-03:00", "payload": { "email": "m2br.smoke.test.valia@gmail.com", "conversion_identifier": "admissao_plano", "cf_fss": "FSS-SMOKE-001" } } ] ``` → `cf_fss` confirmado no payload dos eventos — segmentação por FSS é viável. → **Atenção:** campos customizados extras enviados no evento (`cf_data_admissao`, `cf_plano_tipo`) **não aparecem no histórico** — só os campos padrão do RD Station são persistidos no payload do evento. Os campos customizados são aplicados no perfil do contato, não no evento. --- ### ST-06 ✅ PASS — Campos customizados da conta A conta Valia já possui **43 campos customizados**. Os mais relevantes para o projeto: | Campo | Tipo | Label | |-------|------|-------| | `cf_cpf` | STRING | CPF | | `cf_fss` | STRING | FSS | | `cf_estado_civil` | STRING (seleção) | Estado Civil | | `cf_data_de_admissao` | STRING | Data de admissão | | `cf_data_de_adesao_do_plano` | STRING | Data de adesão do plano | | `cf_plano` | STRING | Plano | | `cf_cliente_valia` | STRING | Cliente Valia? | | `cf_situacao` | STRING | Situação | | `cf_tributacao` | STRING | Tributação | | `cf_perfil_de_investimento` | STRING | Perfil de investimento | | `cf_tipo_participante` | STRING | Tipo Participante | | `cf_sexo` | STRING | Sexo | → **Não é necessário criar nenhum campo customizado novo para o MVP.** A infraestrutura já está montada. --- ## 6. O que Falta para Avançar ### Dever de casa do lado Valia (Bruno Thales) - [ ] **Documentar a solução do Responsys**: qual é a lógica de concatenação de chaves implementada? Quais tabelas/campos diferenciam os registros? Esse é o insumo principal para mapear as regras para o middleware. - [ ] **Mapear volume de cenários edge**: quantos participantes têm mais de um plano? Quantos usam email do responsável? Define se a Opção A é suficiente ou se a C é necessária. - [ ] **Confirmar capacidade de API em tempo real na Valia**: para o fluxo de casamento/admissão — sem isso, volta para lotes e perde a automação instantânea. - [ ] **Confirmar valores de estado civil usados no sistema da Valia** para mapear corretamente para os valores do RD: `CASADO | UNIÃO ESTÁVEL | SOLTEIRO | SEPARADO JUDICIAL | OUTROS | DIVORCIADO | VIÚVO` ### Do lado da M2BR — concluído ✅ - [x] Executar ST-01 a ST-06 com credenciais reais da conta RD da Valia — **todos passaram** - [x] Confirmar que `cf_cpf`, `cf_fss`, `cf_estado_civil`, `cf_data_de_admissao` já existem na conta - [x] Confirmar estrutura da resposta da API de eventos (array direto, não objeto) - [x] Prototipar middleware de Identity Resolution com dry-run dos 3 cenários - [x] Confirmar que a conta Valia está no plano que suporta API 2.0 ✅ ### Próximos passos técnicos - [ ] Ajustar o protótipo do middleware para usar os nomes de campo reais da conta (`cf_plano` em vez de `cf_plano_tipo`, `cf_data_de_admissao` em vez de `cf_data_admissao`) - [ ] Criar segmentação de teste no painel RD por `cf_fss` e validar que automações disparam corretamente - [ ] Definir estratégia para campos customizados extras que faltam no evento (campo no perfil vs. payload do evento) - [ ] Levantar com a Valia se existe campo de `cf_fss` já populado na base atual ou se é campo novo ### Para a próxima reunião - [ ] Apresentar resultados dos smoke tests (este documento) - [ ] Apresentar proposta de arquitetura Opção C com diagrama - [ ] Trazer escopo do treinamento RD Station para a equipe Valia (pauta levantada pelo Bernardo) --- ## 7. Resumo Executivo | Questão | Status | |---------|--------| | RD Station trata email como chave única? | ✅ Sim — confirmado na documentação | | É possível usar CPF como identificador alternativo? | ⚠️ Só como campo customizado — não como chave de API | | Automações por data de admissão (evento)? | ✅ Sim — via Conversion Events + segmentação por `cf_data_admissao` | | Automação de mudança de estado civil? | ✅ Sim — evento `mudanca_estado_civil` + field update | | Múltiplos planos com emails diferentes (Cenário A)? | ⚠️ Requer middleware de resolução de identidade por CPF | | Email do pai no plano do filho (Cenário B)? | ⚠️ Requer alias de email + campo `cf_email_real` | | O RD substitui o Responsys para a Valia hoje? | ❌ Não diretamente — precisa de middleware + configuração específica | | O RD pode substituir o Responsys com trabalho adicional? | ✅ Sim — e a infraestrutura de campos já está montada (43 campos, incluindo cf_cpf e cf_fss) | | A conta Valia já tem os campos necessários? | ✅ Sim — cf_cpf, cf_fss, cf_estado_civil, cf_data_de_admissao já existem | | Smoke tests executados contra a API real? | ✅ Sim — ST-01 a ST-06 todos passaram em 2026-06-01 | **Bottom line:** O RD Station _pode_ resolver o problema da Valia, mas não "fora da caixa". O caminho passa por um middleware de identity resolution + uso de campos customizados + eventos de conversão. A complexidade é menor do que a que a Valia teve com o Responsys (que levou anos para um "dinossauro" do Oracle resolver), mas ainda exige planejamento cuidadoso antes de qualquer migração. --- --- ## 8. MVP Sandbox (implementado) Pasta: [`clientes/valia/mvp/`](mvp/) · Protótipo visual: [`mvp/visual/`](mvp/visual/) (`index.html` — fluxos A–D para workshop) - **Isolamento:** tag `smoke-test`, emails `@smoke.valia-m2br.test`, sem alterar intranet/webhook - **Runner:** `python3 -m mvp.runner --dry-run` | `--run` - **Cleanup:** `python3 -m mvp.cleanup --dry-run` | `--confirm` (via `manifest_latest.json`) - **Resultado 2026-06-01:** cenários A, B e C **PASS** na API real **Descobertas adicionais no MVP:** - `cf_plano` é seleção única (valores fixos: PREVALER, VALIAPREV, etc.) - Tags RD devem ser **minúsculas** - Campos `cf_email_alternativo`, `cf_email_real` **não existem** na conta — metadata no campo `bio` (JSON) - Cenário A com emails diferentes pode gerar **2 contatos** no RD (limitação nativa); email canônico mais recente fica no segundo --- *Gerado por M2BR em 2026-06-01 com base em pesquisa na documentação oficial do RD Station Developers Portal e análise da transcrição de reunião Valia × M2BR.*