arcadiasuite/docs/ANALISE_ATENDEON_XOS.md

11 KiB

Análise Atendeon → XOS

Projeto: https://github.com/JonasRodriguesPachceo/atendeon
Stack: Node.js (TypeScript) + React + PostgreSQL + Baileys
Data: 29/01/2026


Resumo do Projeto Atendeon

O Atendeon é uma central de atendimento WhatsApp multi-empresa (SaaS) completa com:

  • 477 arquivos TypeScript no backend
  • 41 Models (Sequelize/PostgreSQL)
  • 35+ Services organizados por domínio
  • Integração completa com Baileys (WhatsApp não-oficial)
  • Suporte a Typebot, N8N e OpenAI

Funcionalidades do Atendeon vs XOS Atual

O que o Atendeon tem que NOS FALTA

Funcionalidade Atendeon XOS Atual Prioridade
Filas de Atendimento (Queues) Completo Não existe 🔴 Alta
Distribuição Round-Robin Por fila/equipe Não existe 🔴 Alta
Notas Internas (TicketNote) Model dedicado Não existe 🔴 Alta
Mensagens Rápidas (QuickMessage) Com atalhos Não existe 🟠 Média
Agendamento de Mensagens Schedule model Não existe 🟠 Média
Tracking de Ticket TicketTraking Não existe 🟠 Média
Horário de Funcionamento outOfHoursMessage Não existe 🟡 Baixa
Rating/Avaliação UserRating Não existe 🟡 Baixa
Campos Customizados ContactCustomField customFields JSONB OK
Multi-WhatsApp Whatsapp model Não integrado 🔴 Alta
Chatbot/Typebot Integração nativa Não existe 🟠 Média
Integração N8N QueueIntegrations Não existe 🟠 Média
Prompts OpenAI Prompt model Manus Agent OK
Campanhas com 5 msgs message1-5 🟡 content único 🟠 Média
Disparo em massa CampaignShipping 🟡 Estrutura só 🔴 Alta
Listas de Contatos ContactList/Item Não existe 🟠 Média
Tags em Tickets TicketTag M:N 🟡 Array no ticket OK
Importação de Contatos ImportService Não existe 🟠 Média

Models do Atendeon que Devemos Criar

1. Filas de Atendimento (Queue)

// Atendeon: Queue.ts
{
  name: string,
  color: string,
  greetingMessage: string,        // Mensagem de boas-vindas
  outOfHoursMessage: string,      // Fora do expediente
  schedules: JSONB,               // Horários de funcionamento
  orderQueue: number,             // Ordem na distribuição
}
// Relacionamentos:
// - BelongsToMany → Users (UserQueue)
// - BelongsToMany → Whatsapps (WhatsappQueue)

Sugestão para XOS:

CREATE TABLE xos_queues (
  id SERIAL PRIMARY KEY,
  tenant_id INTEGER REFERENCES tenants(id),
  name VARCHAR(100) NOT NULL,
  color VARCHAR(20),
  greeting_message TEXT,
  out_of_hours_message TEXT,
  schedules JSONB, -- [{dayOfWeek: 1, startTime: "09:00", endTime: "18:00"}]
  order_priority INTEGER DEFAULT 0,
  is_active BOOLEAN DEFAULT true
);

CREATE TABLE xos_queue_users (
  queue_id INTEGER REFERENCES xos_queues(id),
  user_id VARCHAR REFERENCES users(id),
  is_active BOOLEAN DEFAULT true,
  PRIMARY KEY (queue_id, user_id)
);

2. Notas Internas (TicketNote)

// Atendeon: TicketNote.ts
{
  note: string,
  userId: number,    // Quem escreveu
  contactId: number, // Sobre qual contato
  ticketId: number,  // Em qual ticket
}

Sugestão para XOS:

CREATE TABLE xos_internal_notes (
  id SERIAL PRIMARY KEY,
  conversation_id INTEGER REFERENCES xos_conversations(id),
  contact_id INTEGER REFERENCES xos_contacts(id),
  user_id VARCHAR REFERENCES users(id),
  content TEXT NOT NULL,
  is_pinned BOOLEAN DEFAULT false,
  created_at TIMESTAMP DEFAULT NOW()
);

3. Mensagens Rápidas (QuickMessage)

// Atendeon: QuickMessage.ts
{
  shortcode: string,  // Ex: "/preco", "/horario"
  message: string,
  mediaPath: string,  // Anexo opcional
  mediaName: string,
  userId: number,     // Dono da msg rápida
}

Sugestão para XOS:

CREATE TABLE xos_quick_messages (
  id SERIAL PRIMARY KEY,
  tenant_id INTEGER REFERENCES tenants(id),
  shortcode VARCHAR(50) NOT NULL, -- "/preco"
  title VARCHAR(200),
  content TEXT NOT NULL,
  media_url TEXT,
  media_type VARCHAR(30), -- image, file, audio
  scope VARCHAR(20) DEFAULT 'personal', -- personal, team, company
  user_id VARCHAR REFERENCES users(id),
  usage_count INTEGER DEFAULT 0,
  created_at TIMESTAMP DEFAULT NOW()
);

4. Agendamento de Mensagens (Schedule)

// Atendeon: Schedule.ts
{
  body: string,       // Conteúdo da mensagem
  sendAt: Date,       // Quando enviar
  sentAt: Date,       // Quando foi enviada
  status: string,     // pending, sent, failed
  contactId: number,
  ticketId: number,
  mediaPath: string,
}

Sugestão para XOS:

CREATE TABLE xos_scheduled_messages (
  id SERIAL PRIMARY KEY,
  tenant_id INTEGER REFERENCES tenants(id),
  contact_id INTEGER REFERENCES xos_contacts(id),
  conversation_id INTEGER REFERENCES xos_conversations(id),
  content TEXT NOT NULL,
  media_url TEXT,
  media_type VARCHAR(30),
  scheduled_at TIMESTAMP NOT NULL,
  sent_at TIMESTAMP,
  status VARCHAR(20) DEFAULT 'pending', -- pending, sent, failed, cancelled
  error_message TEXT,
  created_by VARCHAR REFERENCES users(id),
  created_at TIMESTAMP DEFAULT NOW()
);

5. Tracking de Atendimento (TicketTraking)

// Atendeon: TicketTraking.ts
{
  ticketId: number,
  startedAt: Date,      // Início do atendimento
  queuedAt: Date,       // Quando entrou na fila
  finishedAt: Date,     // Quando finalizou
  ratingAt: Date,       // Quando foi avaliado
  chatbotAt: Date,      // Quando passou pelo bot
  rated: boolean,
}

Sugestão para XOS:

CREATE TABLE xos_conversation_tracking (
  id SERIAL PRIMARY KEY,
  conversation_id INTEGER REFERENCES xos_conversations(id) UNIQUE,
  queued_at TIMESTAMP,
  first_response_at TIMESTAMP,
  assigned_at TIMESTAMP,
  chatbot_ended_at TIMESTAMP,
  human_started_at TIMESTAMP,
  resolved_at TIMESTAMP,
  rated_at TIMESTAMP,
  rating_score INTEGER, -- 1-5
  rating_comment TEXT,
  total_duration_seconds INTEGER, -- calculado
  response_time_seconds INTEGER   -- calculado
);

6. Conexões WhatsApp (Whatsapp)

// Atendeon: Whatsapp.ts
{
  name: string,
  session: string,           // Dados da sessão Baileys
  qrcode: string,            // QR code atual
  status: string,            // CONNECTED, DISCONNECTED, QR
  greetingMessage: string,
  farewellMessage: string,
  complationMessage: string, // Ao finalizar ticket
  ratingMessage: string,
  expiresTicket: number,     // Minutos para expirar
  expiresInactiveMessage: string,
  maxUseBotQueues: number,
}

Sugestão para XOS:

CREATE TABLE xos_whatsapp_connections (
  id SERIAL PRIMARY KEY,
  tenant_id INTEGER REFERENCES tenants(id),
  name VARCHAR(100) NOT NULL,
  phone_number VARCHAR(20),
  status VARCHAR(30) DEFAULT 'disconnected', -- connected, disconnected, qr_pending
  qr_code TEXT,
  session_data JSONB, -- Dados Baileys
  greeting_message TEXT,
  farewell_message TEXT,
  completion_message TEXT,
  rating_message TEXT,
  out_of_hours_message TEXT,
  ticket_expires_minutes INTEGER DEFAULT 1440, -- 24h
  inactive_message TEXT,
  is_default BOOLEAN DEFAULT false,
  last_seen_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE xos_whatsapp_queue_links (
  whatsapp_id INTEGER REFERENCES xos_whatsapp_connections(id),
  queue_id INTEGER REFERENCES xos_queues(id),
  PRIMARY KEY (whatsapp_id, queue_id)
);

Services do Atendeon para Referência

Distribuição de Tickets

O Atendeon usa o conceito de Filas para distribuir leads:

// FindOrCreateTicketService.ts (simplificado)
const ticket = await Ticket.create({
  contactId,
  whatsappId,
  status: "pending",  // Aguardando na fila
  queueId: defaultQueue.id,
  // NÃO atribui userId ainda - fica na fila
});

// UpdateTicketService.ts - Quando atendente pega o ticket
ticket.userId = attendantId;
ticket.status = "open";

Lógica de Round-Robin

// Distribui entre usuários da fila
const usersInQueue = await UserQueue.findAll({
  where: { queueId },
  include: [{ model: User, where: { online: true }}]
});

// Pega o próximo da lista (round-robin)
const nextUser = usersInQueue[currentIndex % usersInQueue.length];

Chatbot com Opções

// QueueOption.ts - Menu do chatbot
{
  title: string,       // "Vendas"
  option: string,      // "1"
  message: string,     // Resposta quando selecionar
  parentId: number,    // Para sub-menus
  queueId: number,
}

Plano de Implementação

Fase 1: Estrutura Base (1-2 semanas)

  1. Criar tabelas: xos_queues, xos_queue_users
  2. Criar tabelas: xos_internal_notes, xos_quick_messages
  3. Criar tabelas: xos_scheduled_messages
  4. Criar tabelas: xos_conversation_tracking
  5. Atualizar APIs XOS com novos endpoints

Fase 2: Distribuição de Leads (1 semana)

  1. Implementar lógica de filas
  2. Round-robin entre atendentes
  3. Status: pending → open → resolved

Fase 3: Integração WhatsApp (2-3 semanas)

  1. Criar xos_whatsapp_connections
  2. Integrar Baileys existente do projeto
  3. Sincronizar mensagens com xos_messages
  4. QR Code e gestão de sessões

Fase 4: Features Avançadas (2 semanas)

  1. Chatbot com menu de opções
  2. Horário de funcionamento
  3. Mensagens automáticas
  4. Sistema de avaliação

Código que Podemos Reutilizar

1. wbotMessageListener.ts (62KB)

  • Lógica completa de recebimento de mensagens
  • Tratamento de mídia (áudio, imagem, vídeo)
  • Integração com OpenAI
  • Fluxo de chatbot

2. providers.ts (79KB)

  • Abstração do Baileys
  • Gestão de sessões
  • Envio de mensagens

3. UpdateTicketService.ts

  • Lógica de transferência entre filas
  • Tracking de tempos
  • Notificações

4. CampaignService/

  • Disparo em massa
  • Agendamento
  • Estatísticas

Comparativo Final

Aspecto Atendeon XOS
Foco WhatsApp CRM puro Plataforma multi-propósito
Multi-tenant Por company Por tenant
ORM Sequelize Drizzle
Real-time Socket.IO Socket.IO
WhatsApp Baileys integrado Baileys separado
AI OpenAI básico Manus Agent completo
Código ~500 arquivos Integrado na Suite

Vantagens do Atendeon

  • Sistema maduro e testado
  • Lógica de filas pronta
  • Chatbot funcional

Vantagens do XOS

  • Arquitetura mais moderna
  • IA mais avançada (Manus)
  • Integração com ERP
  • Multi-canal nativo

Recomendação

Estratégia: Não copiar código diretamente, mas usar como referência para:

  1. Schema de dados → Adaptar models do Atendeon para Drizzle/PostgreSQL
  2. Lógica de negócio → Implementar distribuição de leads similar
  3. Fluxos de chatbot → Replicar QueueOption para menus
  4. Tracking → Copiar conceito de TicketTraking

Estimativa de Desenvolvimento:

  • Estrutura básica: 2-3 semanas
  • Integração WhatsApp: 2-3 semanas
  • Features completas: 4-6 semanas

Total: ~2 meses para paridade com Atendeon