Transferência de cliente por organização
TLDR: mover o vínculo de um cliente com organizações específicas para outro cliente, sem unificar os cadastros nem desativar ninguém.
Contexto
Existem situações em que um mesmo comprador ficou dividido em dois cadastros, com emails diferentes. O merge total existente resolve o caso extremo, mas não serve quando o ajuste precisa ser parcial — quando só algumas organizações devem mudar de dono e os dois cadastros precisam continuar existindo.
Caso real que motivou a mudança:
- Cliente A (cadastro principal) está em
ibft. - Cliente B (mesma pessoa, com outro email) está em
onionecitrg. - Queremos trazer
citrgpara o Cliente A e manteronionno Cliente B. - Resultado esperado: Cliente A fica com
ibftecitrg; Cliente B permanece comonion.
Objetivos
- Permitir uma transferência por organização, não um merge completo.
- Exigir do operador o email de origem, o email de destino e as organizações a transferir.
- Oferecer para seleção apenas organizações que realmente pertencem ao cliente de origem.
- Manter os dois clientes ativos após a transferência.
- Limitar o impacto ao escopo selecionado — vínculos e pagamentos das organizações escolhidas.
- Atualizar o Asaas apenas para as organizações selecionadas.
- Registrar a operação em log para auditoria.
Fora de escopo
- Desativar o cliente de origem.
- Alterar email de qualquer cliente.
- Executar sincronização global para sistemas externos.
- Atualizar o Asaas fora do conjunto de organizações escolhido.
- Processar todas as organizações de uma vez.
Mudanças
Fluxo principal
- O operador abre a opção “Transferir por organização”.
- Informa o email do cliente que vai ceder as organizações (origem).
- Informa o email do cliente que vai receber as organizações (destino).
- O sistema mostra somente as organizações que podem ser transferidas.
- O operador escolhe quais organizações mover.
- Antes de finalizar, o sistema mostra um resumo do que vai mudar.
- O operador confirma.
- O sistema realiza a transferência e mostra a confirmação.
- O sistema atualiza o Asaas apenas nas organizações selecionadas.
- O histórico da ação fica salvo para consulta futura.
Exceções e tratamento esperado
| # | Situação | Causa | Tratamento |
|---|---|---|---|
| 1 | Email de origem não encontrado | Não existe cliente com o email informado | Bloquear a ação e orientar o operador a revisar o email |
| 2 | Email de destino não encontrado | Não existe cliente de destino com o email informado | Bloquear a ação e orientar correção |
| 3 | Origem e destino são o mesmo cliente | Operador informou o mesmo email, ou clientes equivalentes | Bloquear a ação com mensagem clara |
| 4 | Nenhuma organização elegível | Cliente de origem não tem vínculo nas organizações desejadas | Impedir a confirmação e informar que não há itens para transferir |
| 5 | Organização inválida selecionada | Tentativa de transferir organização que não pertence à origem | Bloquear a operação por segurança |
| 6 | Conflito no destino | Cliente de destino já tem vínculo que conflita com o transferido | Aplicar a regra definida — bloquear com mensagem clara ou tratar como idempotente |
| 7 | Duas transferências simultâneas para a mesma origem | Concorrência operacional | Proteger a execução para garantir consistência e evitar duplicidade |
| 8 | Falha inesperada durante a execução | Erro interno ou indisponibilidade temporária | Falhar com segurança, sem resultado parcial inconsistente, e registrar log |
| 9 | Falha ao atualizar o Asaas no escopo | Indisponibilidade ou erro de comunicação com o Asaas | Exibir mensagem para nova tentativa controlada e registrar em detalhe no histórico |
Como verificar
- Criar dois clientes com vínculos em organizações diferentes e transferir apenas uma organização — confirmar que apenas os
OrganizationCustomerePaymentdaquela organização mudaram de dono. - Confirmar que ambos os clientes continuam com
active = truee com os emails originais. - Confirmar que o
IbftEmailSyncJobnão é acionado neste fluxo. - Rodar a mesma transferência duas vezes e confirmar que não há duplicação de vínculo.
- Conferir o registro de auditoria em
WebhookLogcom oevent_typeda transferência.
Documentação
- Plano de implementação: ../plans/20260407150300_organization_transfer.md
- Implementação:
app/services/organization_customer_transfer_service.rb,app/jobs/organization_customer_transfer_job.rb,app/admin/customers.rb