Central de Docs

Safety Net Anti-Duplicidade

CX-014 — Eduzz CX Onboarding — 11/Mar/2026 — Portal 47558663 — EPIC Digital

3
WFs protegidos (EPIC)
4
WFs sem protecao
12
Duplicados corrigidos
1
Duplicado novo (11/Mar)

1 O Problema

A pipeline CX Onboarding possui 7 workflows diferentes que criam tickets. Quando a plataforma Eduzz dispara dois eventos quase simultaneamente (ex: "produto criado" e "produto publicado" com 1-2 segundos de diferenca), cada workflow verifica se a Conta Eduzz ja tem ticket associado. Como a associacao ainda nao foi registrada no HubSpot, ambos veem "nao existe" e ambos criam um ticket.

Resultado: 12 tickets duplicados identificados na pipeline entre 09-10/Mar/2026. Cada par tinha o mesmo eduzz_id em stages diferentes, criados por workflows diferentes com 1-5 segundos de diferenca.

Causa Raiz: Race Condition

T=0.000s   Evento "produto criado" chega ao HubSpot
T=0.100s   WF "Produto criado" inicia → verifica associacao → NAO TEM TICKET → cria Ticket A

T=1.000s   Evento "produto publicado" chega ao HubSpot
T=1.100s   WF "Produto publicado" inicia → verifica associacao → NAO TEM TICKET (Ticket A ainda nao associado) → cria Ticket B

T=2.000s   Associacao do Ticket A finaliza no HubSpot
T=2.500s   Resultado: 2 tickets para a mesma Conta Eduzz = DUPLICADO

O problema ocorre porque a verificacao por associacao HubSpot (typeId 267: Conta Eduzz ↔ Ticket) tem latencia. Entre o momento que um WF cria o ticket e o momento que a associacao e indexada, outros WFs podem criar tickets adicionais.

2 A Solucao: Flag Anti-Duplicidade

Em vez de depender apenas da associacao (lenta), usamos uma property booleana na Conta Eduzz que e setada imediatamente apos a criacao do ticket. Todos os workflows verificam essa flag antes de criar.

Property

CampoValor
Nometicket_onboarding_criado
ObjetoConta Eduzz (2-39559674)
Tipobooleancheckbox
Grupopipeline_onboarding
Valorestrue = ja tem ticket | vazio/null = nao tem

Como funciona

ANTES de criar ticket:
  IF ticket_onboarding_criado = true → SKIP (nao cria) → FIM
  ELSE → continua para criar ticket

APOS criar ticket:
  SET ticket_onboarding_criado = true na Conta Eduzz
  (executado imediatamente, antes de qualquer outro WF poder verificar)
Por que funciona: O SET da property e sincrono e instantaneo no HubSpot (<100ms). Mesmo que outro WF dispare 1 segundo depois, ele ja ve ticket_onboarding_criado = true e para. A janela de race condition cai de ~2s (associacao) para <100ms (property SET).

3 Workflows Protegidos

O Safety Net foi adicionado em 3 workflows que criam tickets na pipeline CX Onboarding:

WorkflowIDRevProtecao
[Onboarding] Criar objeto tickets 1763998812 39 Action 9: BRANCH IF ticket_onboarding_criado = true → END
Actions 10-13: SET ticket_onboarding_criado = true apos cada CREATE
[Onboarding] Produto criado (Rascunho) 1767242146 33 Action 12: BRANCH IF ticket_onboarding_criado = true → SKIP create
Action 13: SET ticket_onboarding_criado = true apos CREATE
[Onboarding] Produto publicado 1767243403 42 Action 14: BRANCH IF ticket_onboarding_criado = true → SKIP create
Action 15: SET ticket_onboarding_criado = true apos CREATE

Outros WFs que criam tickets (sem Safety Net)

Existem 4 WFs adicionais que criam tickets quando a Conta Eduzz ainda nao tem ticket associado. Esses WFs foram identificados pelos dados reais (campo hs_object_source_detail_1):

Workflow sourceTickets criadosSafety Net?
[Onboarding] Dados bancarios cadastrado55Nao
[Onboarding] Data dados bancarios aprovado37Nao
[Onboarding] Saque inicial35Nao
[Onboarding] Primeira venda25Nao
Duplicado comprovado: Em 11/Mar/2026, o eduzz_id 31259849 (Marla Cristina Kappaun Rodrigues) gerou 2 tickets com 12 segundos de diferenca. O WF "Dados bancarios aprovado" criou o ticket 43287991429 as 13:39:02, e o WF "Dados bancarios cadastrado" criou o ticket 43295951779 as 13:39:14. O segundo ticket ficou sem associacao e sem dados — exatamente o padrao de duplicidade.

4 Instrucoes: Aplicar Safety Net nos 4 WFs

Responsabilidade: Time Eduzz. Para evitar conflitos de edicao concorrente (como ocorreu em 10/Mar), a EPIC documentou o passo-a-passo abaixo para o time Eduzz implementar. O padrao e identico ao ja aplicado pela EPIC nos 3 WFs acima.

IDs dos 4 Workflows

#WorkflowIDRev atualTickets criados
1[Onboarding] Dados bancarios cadastrado17763702913162
2[Onboarding] Primeira venda17764970273127
3[Onboarding] Saque inicial17764971712943
4[Onboarding] Data dados bancarios aprovado atualizado17801390081940

Passo-a-passo (repetir para cada WF)

Passo 1 — Localizar a action CREATE TICKET

Abra o workflow no editor. Identifique a action que cria o ticket na pipeline CX Onboarding (855703910). Ela sera do tipo "Create record" → "Ticket".

Passo 2 — Adicionar IF/THEN ANTES do CREATE

Imediatamente antes da action de CREATE TICKET, adicione uma action "If/then branch" com a seguinte condicao:

Branch criteria:
  Object: Conta Eduzz (associada ao enrollment)
  Property: ticket_onboarding_criado
  Operator: is equal to
  Value: true

Se SIM (flag = true):
  → Nao fazer nada (branch vazio, vai para END)
  → Ticket ja existe, nao criar outro

Se NAO (flag vazio/null) — branch DEFAULT:
  → Continuar para o CREATE TICKET (mover a action existente para dentro deste branch)

Passo 3 — Adicionar SET flag APOS o CREATE

Dentro do branch DEFAULT (que cria o ticket), imediatamente apos a action CREATE TICKET, adicione uma action "Set property value":

Action: Set property value
  Object: Conta Eduzz (associada ao enrollment)
  Property: ticket_onboarding_criado
  Value: true
Ordem critica: O SET deve vir IMEDIATAMENTE apos o CREATE, antes de qualquer outra action. Isso minimiza a janela de tempo em que outro WF pode criar um duplicado.

Passo 4 — Validar e publicar

  1. Revisar que o IF/THEN esta ANTES do CREATE
  2. Revisar que o SET esta DEPOIS do CREATE
  3. Confirmar que a property e ticket_onboarding_criado (exatamente esse nome interno)
  4. Confirmar que o objeto e Conta Eduzz (custom object 2-39559674)
  5. Publicar o workflow (Turn on)

Diagrama visual do padrao

[Trigger: Custom Event]

IF ticket_onboarding_criado = true?
↓ NAO                  ↓ SIM
CREATE Ticket        END (skip)

SET flag = true

[Continua WF normalmente]

Checklist de validacao

WFIF/THEN adicionadoSET adicionadoPublicado
[Onboarding] Dados bancarios cadastradoPendentePendentePendente
[Onboarding] Primeira vendaPendentePendentePendente
[Onboarding] Saque inicialPendentePendentePendente
[Onboarding] Data dados bancarios aprovadoPendentePendentePendente

5 Duplicados Corrigidos (12 + 1)

Em 11/Mar/2026, foram identificados e corrigidos 12 pares de tickets duplicados. Para cada par, o ticket no stage mais avancado foi mantido e o outro foi deletado.

eduzz_idTicket mantidoStage mantidoTicket deletadoStage deletadoDelta criacao
5246783743157155647Publicou produto43227315730Nao publicou2s
9773132243294676579Publicou produto43288878967Criou produto1s
9160321643302619982Publicou produto43290901015Criou produto4s
8352737343301370222Publicou produto43284852520Criou produto5s
7730100743285789865Publicou produto43288732503Criou produto1s
6442026643223168173Ainda nao fez venda43229799060Criou produto1s
5566169843221466978Publicou produto43130107725Nao publicou12s
5078803843154856761Saque inicial43239995809Financeiro57s
3178847343299946098Publicou produto43287336805Criou produto10s
1586890643146955331Publicou produto43242679193Nao publicou1s
1529480443296697858Publicou produto43292758691Criou produto1s
133474034643309838349Publicou produto43297781272Criou produto2s

6 Acao Pendente: Flag Retroativo

320 Contas Eduzz possuem ticket na pipeline CX Onboarding mas nao tem a flag ticket_onboarding_criado = true. Essas contas estao vulneraveis a gerar duplicatas caso um novo evento chegue.

Por que 320 contas nao tem a flag?

O WF principal "Criar objeto tickets" (1763998812) sempre setou a flag apos criar ticket — por isso 613 contas tem true. Porem, os WFs "Produto criado", "Produto publicado" e outros criavam tickets sem setar a flag. Esses WFs foram corrigidos em 11/Mar, mas os tickets ja criados antes da correcao nao tiveram a flag setada.

O que o script faz

1. Buscar todos os tickets na pipeline CX Onboarding (855703910)
2. Para cada ticket, obter o eduzz_id
3. Buscar a Conta Eduzz correspondente
4. Se ticket_onboarding_criado != true → SET true

Metodo: HubSpot API PATCH /crm/v3/objects/2-39559674/{contaId}
Payload: { "properties": { "ticket_onboarding_criado": "true" } }
Estimativa: 320 chamadas API (~5 minutos com rate limit)

Perfil das 320 contas

MetricaValor
Perfil313 Produtores, 6 Clientes finais, 1 Agencia
Score NULL203 (63.4%)
Origem NULL203 (63.4%)
Com produto publicado165 (51.6%)
Com produto criado140 (43.8%)
Com primeira venda27 (8.4%)
Com saque57 (17.8%)

Impacto de nao executar

Se um novo evento chegar para qualquer uma dessas 320 contas (ex: primeiro saque, dados bancarios aprovados), os WFs que ainda nao tem Safety Net podem criar um segundo ticket duplicado. O risco e proporcional a atividade dessas contas na plataforma.

7 Resumo

ItemStatus
Property ticket_onboarding_criado criada na Conta EduzzOK
Safety Net no WF "Criar objeto tickets" (1763998812)Ativo (rev 46)
Safety Net no WF "Produto criado" (1767242146)Ativo (rev 38)
Safety Net no WF "Produto publicado" (1767243403)Ativo (rev 44)
12 + 1 tickets duplicados limposConcluido
Flag retroativo em 320 Contas EduzzPendente (script pronto)
Safety Net no WF "Dados bancarios cadastrado" (1776370291)Pendente — Time Eduzz (ver secao 4)
Safety Net no WF "Primeira venda" (1776497027)Pendente — Time Eduzz (ver secao 4)
Safety Net no WF "Saque inicial" (1776497171)Pendente — Time Eduzz (ver secao 4)
Safety Net no WF "Dados bancarios aprovado" (1780139008)Pendente — Time Eduzz (ver secao 4)