arcadiasuite/docs/ANALISE_ATENDEON_XOS.md

395 lines
11 KiB
Markdown

# 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)
```typescript
// 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:**
```sql
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)
```typescript
// Atendeon: TicketNote.ts
{
note: string,
userId: number, // Quem escreveu
contactId: number, // Sobre qual contato
ticketId: number, // Em qual ticket
}
```
**Sugestão para XOS:**
```sql
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)
```typescript
// 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:**
```sql
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)
```typescript
// 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:**
```sql
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)
```typescript
// 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:**
```sql
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)
```typescript
// 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:**
```sql
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:
```typescript
// 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
```typescript
// 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
```typescript
// 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