- docs/ARCHITECTURE.md: decisoes de arquitetura (monorepo, rede Asterisk host mode, realtime PJSIP, camada de telefonia, seguranca desde o design) - TODO.md: checklist vivo de implementacao por fases - estrutura inicial do monorepo (apps/, packages/, infrastructure/, scripts/) - docker-compose.yml: postgres 17 + redis 7 com healthchecks, sem portas publicadas no host, schema 'asterisk' dedicado no Postgres - .env.example + scripts/generate-secrets.sh
48 KiB
PROMPT MESTRE — B2BCall
Você é o arquiteto principal, engenheiro de software sênior, DevOps, DBA PostgreSQL e especialista em telefonia VoIP/Call Center responsável por projetar e implementar do zero uma plataforma profissional de discagem preditiva chamada:
B2BCall
Você está trabalhando diretamente em um servidor:
- Debian 13
- Instalação limpa
- Servidor dedicado à aplicação
- Diretório principal:
/opt/b2bcall - Logo existente em:
/opt/b2bcall/b2bcall.png - Banco de dados: PostgreSQL
- Telefonia: Asterisk
- SIP: PJSIP
- Frontend e backend preferencialmente em TypeScript
- Toda a aplicação deve funcionar em containers Docker
- O Asterisk não possuirá IP público
- O Asterisk ficará atrás de um OpenSIPS
- Os troncos SIP serão acessados através de IPs privados
- Nenhuma porta SIP, AMI, ARI, PostgreSQL ou Redis deve ficar desnecessariamente exposta à Internet
A aplicação deve ser moderna, segura, modular, escalável e adequada para ambiente de produção.
1. REGRA PRINCIPAL DE EXECUÇÃO
NÃO produza apenas documentação.
NÃO faça apenas mockups.
NÃO faça somente o frontend.
NÃO pare depois de criar a estrutura inicial.
NÃO deixe funções principais marcadas como TODO.
Você deve efetivamente:
- analisar o servidor;
- preparar o ambiente;
- instalar Docker e dependências necessárias;
- criar a estrutura do projeto;
- criar os containers;
- configurar PostgreSQL;
- configurar Redis se necessário;
- instalar/configurar Asterisk;
- construir backend;
- construir frontend;
- construir o motor do discador;
- integrar o backend ao Asterisk;
- implementar autenticação;
- implementar RBAC/permissões;
- implementar todas as telas solicitadas;
- implementar métricas;
- implementar relatórios;
- implementar monitoramento em tempo real;
- implementar auditoria;
- implementar segurança;
- criar migrations;
- criar testes;
- executar os testes;
- corrigir os problemas encontrados;
- subir o ambiente;
- validar os health checks;
- documentar;
- continuar até que o sistema esteja operacional.
Trabalhe de maneira AUTÔNOMA.
Quando houver mais de uma abordagem tecnicamente válida, escolha a solução que considerar mais adequada para produção e documente a decisão.
Não interrompa o desenvolvimento a cada decisão pequena para perguntar ao usuário.
Somente pare por algo realmente impossível de resolver sem informação externa, como uma senha de uma operadora que não foi fornecida.
2. OBJETIVO DO PRODUTO
O B2BCall será uma plataforma profissional de Call Center e discagem preditiva.
Deve possuir:
- Asterisk integrado;
- ramais;
- agentes;
- filas;
- pausas;
- troncos;
- dialplans;
- campanhas;
- leads;
- discador preditivo;
- controle CPS;
- monitoramento em tempo real;
- dashboards;
- TME;
- TMA;
- relatórios;
- RBAC;
- administração completa;
- configuração do Asterisk;
- auditoria;
- segurança;
- observabilidade.
Não quero um simples sistema de “click to call”.
Quero um verdadeiro:
Predictive Dialer / Automatic Call Distribution System.
3. ARQUITETURA TECNOLÓGICA
Use preferencialmente um monorepo TypeScript.
Uma arquitetura recomendada é:
/opt/b2bcall
├── apps
│ ├── frontend
│ ├── api
│ ├── dialer-worker
│ ├── asterisk-events
│ └── scheduler
├── packages
│ ├── database
│ ├── shared
│ ├── types
│ ├── ui
│ └── telephony
├── infrastructure
│ ├── asterisk
│ ├── nginx
│ ├── postgres
│ └── docker
├── scripts
├── docs
├── docker-compose.yml
├── .env.example
├── .gitignore
└── README.md
Pode adaptar a estrutura se houver justificativa técnica.
Stack sugerida
Frontend
- Next.js
- React
- TypeScript
- Tailwind CSS
- shadcn/ui ou componentes equivalentes
- TanStack Query
- WebSocket para dados em tempo real
Backend
Preferencialmente:
- Node.js
- TypeScript
- NestJS
Pode utilizar Fastify como HTTP adapter.
Banco
- PostgreSQL 17 ou versão estável compatível
- migrations obrigatórias
- índices corretamente planejados
- transactions
- constraints
- foreign keys
- JSONB apenas quando fizer sentido
Cache/mensageria
Redis pode ser utilizado para:
- filas internas;
- locks;
- presença;
- sessões em tempo real;
- workers;
- campanhas;
- rate limit;
- eventos.
Pode utilizar BullMQ.
Telefonia
Use:
Asterisk 22 LTS
com:
- PJSIP;
- AMI;
- ARI quando realmente necessário;
- CDR;
- CEL;
- queue_log;
- app_queue.
Não utilize chan_sip.
4. DOCKER
Toda a solução deve ser containerizada.
Criar no mínimo serviços equivalentes a:
b2bcall-frontend
b2bcall-api
b2bcall-worker
b2bcall-asterisk-events
b2bcall-scheduler
b2bcall-asterisk
b2bcall-postgres
b2bcall-redis
b2bcall-nginx
Avalie cuidadosamente a rede do Asterisk.
Como RTP possui uma quantidade significativa de portas UDP, considere utilizar network_mode: host para o container do Asterisk caso isso simplifique e torne a operação mais confiável.
Se utilizar host network, documente detalhadamente os impactos.
Os outros containers devem permanecer em redes Docker privadas sempre que possível.
PostgreSQL e Redis não devem ficar expostos publicamente.
Adicionar:
- restart policies;
- health checks;
- volumes persistentes;
- logging;
- dependency checks;
- resource considerations.
5. TOPOLOGIA SIP
A arquitetura é:
INTERNET
|
[ OpenSIPS ]
|
rede SIP privada
|
[ Asterisk ]
|
[ B2BCall ]
E para operadoras:
Asterisk
|
rede privada
|
Troncos SIP
O Asterisk NÃO possui IP público.
Nunca assuma que ele precisa registrar troncos pela Internet.
Permitir troncos:
- IP Authentication;
- Username/password quando necessário;
- PJSIP registration quando necessário.
Permitir configuração de:
- IP;
- porta;
- transporte;
- codecs;
- DTMF;
- From User;
- From Domain;
- Contact User;
- Outbound Proxy;
- identificação por IP;
- autenticação;
- caller ID;
- limites;
- context;
- qualify;
- timers.
Criar ACLs e configurações de segurança.
AMI e ARI jamais deverão estar publicamente acessíveis.
6. ASTERISK REALTIME
Avalie utilizar Asterisk Realtime + ODBC/PostgreSQL para objetos PJSIP.
Exemplos:
- ps_endpoints
- ps_auths
- ps_aors
- ps_contacts
- ps_endpoint_id_ips
- ps_registrations
O banco de aplicação deve continuar possuindo seu próprio modelo de domínio.
Não misture indiscriminadamente tabelas da aplicação com tabelas internas do Asterisk.
Uma boa estratégia é utilizar schemas separados:
public/application
asterisk
ou configuração equivalente.
7. INTEGRAÇÃO ASTERISK
O backend deve possuir uma camada:
TelephonyProvider
e implementação:
AsteriskTelephonyProvider
Não espalhe comandos AMI dentro de controllers da aplicação.
Criar serviço central responsável por:
- Originate;
- Hangup;
- QueuePause;
- QueueAdd;
- QueueRemove;
- ExtensionState;
- DeviceState;
- QueueStatus;
- PJSIPShowEndpoints;
- PJSIPShowContacts;
- reload;
- eventos;
- canais;
- bridges;
- chamadas.
Utilize AMI principalmente para eventos administrativos e controle.
Utilize ARI quando o controle de canais/bridges exigir ARI.
8. EVENTOS EM TEMPO REAL
Criar serviço dedicado que permaneça conectado ao AMI.
Ele deve consumir eventos como:
- Newchannel;
- DialBegin;
- DialEnd;
- BridgeEnter;
- BridgeLeave;
- Hangup;
- Newstate;
- DeviceStateChange;
- QueueMemberStatus;
- QueueMemberPause;
- AgentConnect;
- AgentComplete;
- QueueCallerJoin;
- QueueCallerLeave;
- QueueCallerAbandon;
- ContactStatus;
- PeerStatus/PJSIP equivalentes.
Normalizar esses eventos.
Persistir eventos importantes.
Transmitir dados do estado atual para o frontend utilizando WebSocket.
Nunca fazer o frontend executar polling a cada segundo no Asterisk.
9. AUTENTICAÇÃO
Criar autenticação profissional.
Login:
- e-mail;
- senha.
Implementar:
- Argon2id para hash;
- access token;
- refresh token;
- cookies HttpOnly quando aplicável;
- Secure;
- SameSite;
- rotação de refresh token;
- logout;
- revogação de sessão;
- recuperação de senha;
- token de recuperação com validade;
- auditoria;
- proteção contra enumeração de usuários.
Nunca armazenar senha em texto puro.
Nunca armazenar JWT em localStorage se puder ser evitado.
10. RATE LIMIT
É obrigatório implementar proteção contra força bruta.
Exemplo:
5 tentativas de login / minuto / IP
com bloqueio progressivo.
Implementar também limites por:
- IP;
- usuário;
- endpoint sensível.
Registrar tentativas excessivas no audit log.
Redis poderá ser utilizado para rate limiting distribuído.
11. RBAC — PERMISSÕES
Criar RBAC completo.
Não faça simplesmente:
if user.role == admin
Criar:
users
roles
permissions
user_roles
role_permissions
Perfis iniciais:
super_admin
admin
supervisor
agent
Porém os níveis NÃO devem ser fixos.
O super_admin precisa possuir uma tela de:
Perfis e Permissões
onde possa definir exatamente o que cada perfil pode acessar.
Exemplos:
dashboard.view
trunks.view
trunks.create
trunks.update
trunks.delete
extensions.view
extensions.create
extensions.update
extensions.delete
dialplans.view
dialplans.create
dialplans.update
dialplans.delete
queues.view
queues.create
queues.update
queues.delete
agents.view
agents.create
agents.update
agents.delete
campaigns.view
campaigns.create
campaigns.start
campaigns.pause
campaigns.stop
campaigns.update
campaigns.delete
reports.view
reports.export
monitoring.view
asterisk.view
asterisk.configure
asterisk.reload
users.view
users.create
users.update
roles.manage
audit.view
settings.manage
O frontend deve esconder funcionalidades sem permissão.
MAS:
a segurança sempre deve ser validada novamente pelo backend.
Nunca confie apenas no frontend.
12. AUDITORIA
Criar audit_logs.
Registrar no mínimo:
- login;
- logout;
- login inválido;
- criação;
- edição;
- exclusão;
- início de campanha;
- pausa de campanha;
- encerramento de campanha;
- alteração de trunk;
- alteração de ramal;
- alteração de fila;
- alteração de agente;
- alteração do Asterisk;
- reload;
- alteração de permissões.
Guardar:
user_id
action
entity_type
entity_id
before
after
ip_address
user_agent
created_at
Para campos sensíveis, nunca salvar segredos abertos no before/after.
13. TELA DE TRONCOS
Criar menu:
Telefonia → Troncos
Permitir:
- adicionar;
- editar;
- ativar;
- desativar;
- duplicar;
- excluir;
- testar.
Campos:
-
Nome
-
Tecnologia: PJSIP
-
Tipo:
- IP
- autenticação
- registration
-
Host
-
Porta
-
Transporte
-
Username
-
Password
-
From User
-
From Domain
-
Contact User
-
Outbound Proxy
-
Context
-
Caller ID
-
Codecs
-
DTMF mode
-
Qualify
-
Max Channels
-
CPS máximo
-
ACL
-
IPs permitidos
-
Enabled
Mostrar status:
ONLINE
OFFLINE
UNREACHABLE
UNKNOWN
Nunca mostrar a senha completa depois de salva.
14. TELA DE RAMAIS
Criar:
Telefonia → Ramais
Campos:
- número;
- nome;
- senha SIP;
- caller ID;
- contexto;
- codecs;
- transporte;
- max contacts;
- qualify;
- enabled.
Gerar senha SIP segura automaticamente.
Permitir resetar a senha.
Mostrar status em tempo real.
15. PAINEL VISUAL DE RAMAIS
Criar uma tela específica:
Monitoramento → Ramais
Cada ramal deverá aparecer em um card/quadrado.
Exemplo:
┌──────────────────┐
│ RAMAL 1001 │
│ João Silva │
│ DISPONÍVEL │
│ 00:04:32 │
└──────────────────┘
Utilizar EXATAMENTE esta convenção principal:
CINZA = ramal offline
VERDE = ramal disponível
LARANJA = ramal ocupado
AZUL = agente logado
VERMELHO = agente em pausa
Como alguns estados podem coexistir, implementar a seguinte prioridade visual:
PAUSA
↓
EM CHAMADA
↓
AGENTE LOGADO
↓
REGISTRADO/DISPONÍVEL
↓
OFFLINE
Ou seja:
pausa -> vermelho
ocupado -> laranja
agente -> azul
disponível -> verde
offline -> cinza
Mostrar opcionalmente:
- agente;
- ramal;
- fila;
- duração do estado;
- duração da chamada;
- campanha atual.
Atualização via WebSocket.
16. AGENTES
Separar claramente:
usuário da aplicação
de:
agente de Call Center
Uma pessoa pode possuir usuário e agente associados.
Criar:
agents
agent_sessions
Campos do agente:
- código;
- nome;
- usuário associado;
- ativo;
- filas;
- campanhas permitidas;
- ramal atual.
Permitir login dinâmico de agente.
17. TELA DO AGENTE
Após login, o agente deve possuir uma interface simplificada.
Mostrar:
Agente
Ramal
Fila
Campanha
Estado
Tempo no estado
Chamada atual
Telefone
Nome do lead
Botões:
DISPONÍVEL
PAUSA
FINALIZAR PAUSA
Quando clicar em PAUSA, abrir os motivos cadastrados.
Exemplo:
Banheiro
Almoço
Lanche
Reunião
Treinamento
Suporte
Particular
Registrar:
- início;
- fim;
- duração;
- motivo;
- usuário;
- agente;
- ramal.
O agente deve conseguir logar e deslogar das filas conforme suas permissões.
18. CADASTRO DE PAUSAS
Criar:
Call Center → Motivos de Pausa
Campos:
Nome
Código
Descrição
Tempo máximo opcional
Remunerada SIM/NÃO
Ativa SIM/NÃO
Permitir relatórios de pausas posteriormente.
19. FILAS
Criar:
Call Center → Filas
Configurar:
- Nome
- Número
- Strategy
- Timeout
- Retry
- Wrap-up time
- Max length
- Music on Hold
- Announce
- Service Level
- Auto Fill
- Ring in use
- Weight
- Members
Strategies:
ringall
leastrecent
fewestcalls
random
rrmemory
rrordered
linear
wrandom
Mostrar explicação amigável de cada strategy na interface.
20. MONITORAMENTO DE FILAS
Criar:
Monitoramento → Filas
Cada fila deve mostrar em tempo real:
- chamadas aguardando;
- agentes logados;
- agentes disponíveis;
- agentes ocupados;
- agentes pausados;
- agentes offline;
- maior tempo de espera atual;
- TME;
- TMA;
- abandonos;
- chamadas atendidas;
- service level;
- taxa de abandono.
Permitir expandir uma fila e visualizar agentes individualmente.
21. DIALPLAN
Criar:
Telefonia → Dialplan
Não criar somente um textarea.
Criar editor estruturado permitindo:
Context
Extension
Priority
Application
Arguments
Enabled
Order
Por exemplo:
Context: outbound
Extension: _X.
Application: Dial
Arguments: PJSIP/${EXTEN}@trunk01
Também disponibilizar um modo:
Advanced
somente para super_admin ou permissão equivalente.
Antes de aplicar um dialplan:
- gerar nova configuração;
- validar;
- manter backup;
- tentar reload seguro;
- verificar resultado;
- caso inválido, não ativar;
- permitir rollback.
Versionar alterações.
Criar:
dialplan_versions
22. ADMINISTRAÇÃO DO ASTERISK
Criar menu:
Sistema → Asterisk
Quero uma interface de administração suficientemente completa para gerenciar os parâmetros necessários ao B2BCall.
Separar por abas.
Geral
- system name;
- language;
- default context;
- timezone;
- sounds;
- MOH.
PJSIP
- transports;
- UDP/TCP/TLS;
- bind;
- local_net;
- external signaling;
- external media;
- timers;
- codecs;
- endpoint defaults.
RTP
- RTP start;
- RTP end;
- ICE se necessário;
- symmetric RTP;
- configurações relevantes.
Filas
Parâmetros globais.
CDR
Configuração.
CEL
Configuração.
Logs
Configuração e nível de log.
AMI
Exibir STATUS da integração.
Não mostrar senha AMI aberta.
ARI
Exibir STATUS da integração.
Modules
Listar módulos carregados.
Diagnóstico
Permitir executar comandos seguros e previamente permitidos como:
core show uptime
core show channels
pjsip show endpoints
pjsip show contacts
queue show
module show
NÃO implemente uma shell Linux arbitrária pela interface web.
Isso seria uma vulnerabilidade crítica.
23. VERSIONAMENTO DAS CONFIGURAÇÕES DO ASTERISK
Toda alteração gerada pela aplicação deve possuir versão.
Criar algo como:
asterisk_config_versions
Guardar:
- usuário;
- data;
- tipo;
- configuração anterior;
- nova configuração;
- status;
- resultado do reload.
Disponibilizar:
Rollback
para versões anteriores.
24. CAMPANHAS
Criar:
Discador → Campanhas
Campos mínimos:
Nome
Descrição
Fila
Tronco
Caller ID
Dialplan/context
Status
Data inicial
Data final
Dias da semana
Horário inicial
Horário final
Timezone
CPS
Máximo de chamadas simultâneas
Pacing inicial
Pacing mínimo
Pacing máximo
Taxa alvo de abandono
Tempo máximo aguardando agente
Tempo de ring
Número máximo de tentativas
Intervalo entre tentativas
Retry BUSY
Retry NO ANSWER
Retry CONGESTION
AMD ligado/desligado
Status:
DRAFT
READY
RUNNING
PAUSED
DRAINING
STOPPED
COMPLETED
Botões:
INICIAR
PAUSAR
RETOMAR
PARAR
DRENAR
DRAINING significa:
- não originar novas chamadas;
- deixar as existentes terminarem.
25. CPS — CALLS PER SECOND
CPS é requisito obrigatório.
Cada campanha deve possuir:
campaign.max_cps
Cada trunk também:
trunk.max_cps
O limite real deve ser:
min(campaign.max_cps, trunk.available_cps)
Implementar token bucket ou algoritmo equivalente.
Não pode simplesmente executar um loop com sleep.
Tem que funcionar de maneira correta mesmo com múltiplos workers.
Utilize Redis para coordenação distribuída se necessário.
26. LEADS
Cada campanha possuirá leads.
Criar tabela leads.
Campos mínimos:
id
campaign_id
name
phone
normalized_phone
status
attempt_count
last_attempt_at
next_attempt_at
last_result
created_at
updated_at
Permitir dados adicionais:
custom_fields JSONB
Status possíveis:
NEW
READY
RESERVED
DIALING
RINGING
ANSWERED
CONNECTED_AGENT
BUSY
NO_ANSWER
FAILED
INVALID
VOICEMAIL
CALLBACK
COMPLETED
DO_NOT_CALL
MAX_ATTEMPTS
27. IMPORTAÇÃO CSV
Criar na campanha:
Importar Leads
Formato mínimo:
nome,telefone
Joao Silva,48999999999
Maria Souza,11999999999
Interface deve permitir:
- upload;
- detectar delimitador;
- preview;
- mapear colunas;
- validar;
- normalizar telefones;
- detectar duplicados;
- importar.
Mostrar:
Total: 10.000
Válidos: 9.850
Inválidos: 100
Duplicados: 50
Permitir baixar CSV dos registros rejeitados.
Não carregar arquivo gigantesco inteiro na memória.
Faça processamento streaming/batch. x
28. NORMALIZAÇÃO DE TELEFONE
Criar serviço dedicado de normalização.
Não espalhar regexes pelo código.
Preparar inicialmente para números brasileiros.
Guardar:
phone_original
phone_normalized
Arquitetura deve permitir suporte futuro a E.164 internacional.
29. LISTA DE SUPRESSÃO
Implementar:
Do Not Call / Lista de Bloqueio
Uma campanha não deve discar um número presente nessa lista.
Criar:
suppression_list
Permitir:
- adicionar manualmente;
- importar CSV;
- pesquisar;
- remover com permissão;
- informar motivo;
- auditoria.
Antes de originar:
CHECK SUPPRESSION
obrigatoriamente.
30. MOTOR DO DISCADOR PREDITIVO
Este é um dos componentes MAIS IMPORTANTES do projeto.
NÃO implemente simplesmente:
for lead:
originate()
Isso NÃO é discador preditivo.
Criar um serviço:
PredictiveDialerEngine
responsável por decidir continuamente quantas chamadas devem ser originadas.
Deve considerar:
- agentes logados;
- agentes disponíveis;
- agentes ocupados;
- agentes em wrap-up;
- agentes pausados;
- chamadas atualmente discando;
- chamadas tocando;
- chamadas atendidas aguardando agente;
- answer rate histórico;
- taxa de chamadas ocupadas;
- taxa de não atendimento;
- tempo médio até atendimento;
- TMA;
- agentes que provavelmente ficarão disponíveis;
- abandono recente;
- CPS disponível;
- limite de concorrência;
- pacing configurado.
31. ALGORITMO PREDITIVO
Implementar inicialmente um algoritmo conservador e adaptativo.
Mantenha estatísticas por campanha.
Exemplo:
answer_probability
average_answer_delay
average_talk_time
abandon_rate
available_agents
busy_agents
dialing_calls
ringing_calls
Utilize EWMA ou método estatístico equivalente para evitar variações violentas.
Calcular aproximadamente:
expected_agent_supply =
agentes_disponiveis
+
agentes_com_probabilidade_de_liberacao_no_horizonte
Depois estimar:
expected_answers = calls_to_dial * answer_probability
e ajustar para que:
expected_answers ~= capacidade prevista de agentes
Adicionar multiplicador:
pacing_factor
Porém sempre respeitando:
CPS
max_concurrent_calls
max_pacing
max_abandon_rate
available_agents
trunk capacity
campaign schedule
32. PREVISÃO DE LIBERAÇÃO DE AGENTES
Para tornar o discador realmente preditivo, utilize:
TMA histórico
tempo atual da chamada
distribuição histórica de duração
para estimar quais agentes podem ficar disponíveis dentro de um horizonte curto.
Não precisa construir machine learning.
Uma abordagem estatística eficiente, explicável e determinística é preferível inicialmente.
Documentar detalhadamente o algoritmo em:
docs/PREDICTIVE_DIALER.md
33. CONTROLE DE ABANDONO
O motor deve possuir proteção contra abandono excessivo.
Se:
abandon_rate > target_abandon_rate
o pacing deve cair automaticamente.
Se subir muito:
pacing -> modo conservador
Se necessário:
suspender novas originações
Nunca desenhar o sistema para originar milhares de chamadas sem agentes com o objetivo de verificar se números atendem.
A intenção do discador é estabelecer comunicação real entre lead e agente.
34. PROTEÇÃO REGULATÓRIA / COMPLIANCE
Criar uma área:
Sistema → Compliance de Chamadas
Não hardcode regras de uma única legislação dentro do motor.
Criar parâmetros configuráveis.
Registrar:
total_calls
answered_calls
short_calls
abandoned_calls
calls_per_number
calls_per_day
calls_per_month
Criar alertas relacionados a:
- volume excessivo;
- chamadas curtas;
- abandono;
- excesso de tentativas;
- horário permitido;
- supressão;
- caller ID.
Para operação brasileira, preparar indicadores considerando que chamadas de curta duração são particularmente relevantes para fiscalização.
Adicionar suporte de configuração de identificação/caller ID apropriado para campanhas de telemarketing, inclusive numeração 0303 quando aplicável ao caso de uso.
Adicionar contador mensal para identificar operações de alto volume que possam exigir mecanismos adicionais de autenticação de chamadas pela rede.
O sistema deve AJUDAR a cumprir regras.
Nunca implementar funcionalidades destinadas a burlar mecanismos antispam, autenticação, identificação de origem ou bloqueios das operadoras.
35. RESERVA CONCORRENTE DE LEADS
É obrigatório evitar que dois workers disquem para o mesmo lead.
Utilizar mecanismo transacional como:
SELECT ...
FOR UPDATE SKIP LOCKED
ou solução equivalente.
Transição:
READY
↓
RESERVED
↓
DIALING
Tem que ser atômica.
Implementar timeout de reservation para recuperar leads caso um worker morra.
36. IDEMPOTÊNCIA
Originação deve possuir:
attempt_id
call_id
uniqueid
linkedid
Nunca originar novamente uma tentativa já confirmada simplesmente porque houve timeout da API.
Construir chamadas como state machine.
Exemplo:
CREATED
RESERVED
ORIGINATING
RINGING
ANSWERED
QUEUED
AGENT_CONNECTED
COMPLETED
FAILED
Persistir as transições relevantes.
37. CALL FLOW PREDITIVO
Fluxo esperado:
Lead
↓
PredictiveDialer
↓
CPS limiter
↓
Asterisk Originate
↓
Trunk
↓
Destino
Quando a chamada atende:
ANSWER
↓
opcional AMD
↓
humano
↓
Fila Asterisk
↓
Agente disponível
↓
Bridge
Persistir todos os timestamps.
38. AMD
Adicionar Answering Machine Detection como recurso OPCIONAL.
Nunca deixar AMD obrigatório.
Configurar por campanha.
Possíveis resultados:
HUMAN
MACHINE
NOT_SURE
HANGUP
Criar parâmetros avançados apenas para administrador.
Registrar resultado para posterior otimização.
39. AFTER CALL / WRAP-UP
Implementar:
wrap_up_time
Durante wrap-up o agente não deve ser tratado pelo predictive engine como imediatamente disponível.
Mostrar estado:
WRAP UP
e tempo restante.
40. DISPOSIÇÃO DA CHAMADA
Após atendimento, permitir ao agente classificar a ligação.
Exemplos:
VENDA
SEM INTERESSE
CALLBACK
NÚMERO ERRADO
NÃO LIGAR NOVAMENTE
CAIXA POSTAL
OUTRO
Criar tela administrativa para configurar disposições.
Uma disposição pode possuir ações.
Exemplo:
CALLBACK
-> solicitar data/hora
DO_NOT_CALL
-> adicionar automaticamente à suppression_list
41. CALLBACK
Permitir agendar retorno.
Campos:
lead
agent
campaign
scheduled_at
timezone
notes
O scheduler deve colocar o lead novamente em condição de discagem no horário correto.
Permitir callback:
para qualquer agente
ou:
preferencialmente para o mesmo agente
42. CDR / HISTÓRICO DE CHAMADAS
Criar modelo consolidado próprio.
Capturar:
call_id
asterisk_uniqueid
linkedid
campaign
lead
queue
agent
extension
trunk
caller
called
start_at
ring_at
answer_at
queue_enter_at
agent_answer_at
end_at
duration
billsec
talk_time
wait_time
disposition
hangup_cause
amd_result
Nunca depender exclusivamente do CDR nativo para reconstruir toda a jornada do Call Center.
Utilizar:
- CDR;
- CEL;
- AMI Events;
- queue_log.
43. RELATÓRIO DE CHAMADAS
Criar:
Relatórios → Chamadas
Filtros:
- data inicial;
- data final;
- ramal;
- agente;
- fila;
- campanha;
- tronco;
- telefone;
- status;
- disposição.
Colunas:
Data
Origem
Destino
Campanha
Fila
Agente
Ramal
Tronco
Espera
Conversação
Duração
Resultado
Hangup Cause
Permitir exportar CSV.
Paginação obrigatoriamente server-side.
Não carregar milhões de registros de uma vez no browser.
44. TME
Implementar TME — Tempo Médio de Espera.
Calcular principalmente:
agent_answer_at - queue_enter_at
para chamadas atendidas.
Separadamente mostrar:
tempo médio antes do abandono
Não misturar as duas métricas silenciosamente.
Documentar a definição utilizada.
45. TMA
Implementar:
TMA — Tempo Médio de Atendimento
Calcular principalmente:
SUM(talk_time) / answered_calls
Permitir futuramente visualizar:
Talk Time
Talk + Wrap-Up
como indicadores separados.
46. DASHBOARD
Criar um dashboard moderno.
Cards principais:
Chamadas hoje
Chamadas atendidas
Chamadas em andamento
Chamadas aguardando
Agentes disponíveis
Agentes ocupados
Agentes pausados
TME
TMA
Taxa de atendimento
Taxa de abandono
Gráficos:
Chamadas por hora
Line/area chart.
Atendidas x abandonadas
TME ao longo do dia
TMA ao longo do dia
Agentes por estado
Campanhas
Mostrar:
Discando
Ringing
Atendidas
Conectadas
CPS atual
Pacing
Answer Rate
Abandono
Não criar gráficos falsos.
Todos devem utilizar informações reais do banco/Asterisk.
47. DASHBOARD DO DISCADOR
Criar painel específico por campanha mostrando em tempo real:
CPS configurado
CPS atual
Chamadas discando
Chamadas tocando
Atendidas
Na fila
Conectadas em agente
Agentes disponíveis
Pacing atual
Answer rate
Abandon rate
TME
TMA
Leads restantes
Leads processados
Isso será extremamente importante para operação.
48. STATUS DOS AGENTES
Estados canônicos:
OFFLINE
LOGGED_IN
AVAILABLE
RINGING
IN_CALL
WRAP_UP
PAUSED
Não inferir tudo diretamente de uma única variável do Asterisk.
Criar máquina de estados consistente.
Registrar início/fim de cada estado.
Isso permitirá calcular produtividade posteriormente.
49. RELATÓRIO DE AGENTES
Criar:
Relatórios → Agentes
Exibir:
Tempo logado
Tempo disponível
Tempo em chamada
Tempo pausado
Tempo wrap-up
Chamadas atendidas
TMA
Detalhar pausas:
motivo
início
fim
duração
50. QUEUE_LOG
Utilizar os dados do queue_log porque ele contém eventos específicos de ACD que um CDR tradicional não representa corretamente.
Capturar eventos relevantes como:
- ENTERQUEUE;
- CONNECT;
- COMPLETEAGENT;
- COMPLETECALLER;
- ABANDON;
- RINGNOANSWER;
- TRANSFER;
- PAUSE;
- UNPAUSE.
Normalizar no PostgreSQL.
Não basear TME/TMA exclusivamente em parsing periódico de arquivo.
Preferencialmente capturar eventos em tempo real e utilizar queue_log também para reconciliação/auditoria.
51. RECONCILIAÇÃO
Eventos podem eventualmente ser perdidos por restart de algum worker.
Criar rotina de reconciliação.
Ela deve comparar informações recentes com:
- CDR;
- CEL;
- queue_log;
- estados persistidos.
Corrigir chamadas que ficaram indevidamente em:
RINGING
IN_PROGRESS
CONNECTED
após falha/restart.
52. INTERFACE
Quero uma aplicação:
- bonita;
- moderna;
- clean;
- corporativa;
- rápida;
- responsiva;
- com excelente UX.
Utilizar a logo:
/opt/b2bcall/b2bcall.png
Copiar/processar para o diretório apropriado do frontend.
Não modificar a logo original.
Menu sugerido:
Dashboard
Discador
├─ Campanhas
├─ Leads
├─ Importações
├─ Callbacks
└─ Lista de Bloqueio
Call Center
├─ Agentes
├─ Filas
├─ Motivos de Pausa
└─ Disposições
Telefonia
├─ Ramais
├─ Troncos
└─ Dialplan
Monitoramento
├─ Filas
├─ Agentes
├─ Ramais
└─ Campanhas
Relatórios
├─ Chamadas
├─ Agentes
├─ Filas
└─ Campanhas
Sistema
├─ Usuários
├─ Perfis e Permissões
├─ Asterisk
├─ Compliance
├─ Auditoria
└─ Configurações
53. BANCO DE DADOS
Planejar pelo menos entidades equivalentes a:
users
sessions
roles
permissions
user_roles
role_permissions
agents
agent_sessions
agent_state_events
pause_reasons
agent_pause_events
extensions
trunks
queues
queue_members
dialplans
dialplan_versions
campaigns
campaign_schedules
campaign_agents
lead_imports
leads
dial_attempts
calls
call_events
queue_events
call_dispositions
call_callbacks
suppression_list
asterisk_config_versions
audit_logs
application_settings
Adicionar tabelas auxiliares necessárias.
Criar índices para consultas de alto volume.
Especial atenção para índices envolvendo:
campaign_id
status
next_attempt_at
created_at
phone_normalized
call_id
linkedid
queue_id
agent_id
extension_id
54. VOLUME DE DADOS
Projetar desde o início considerando milhões de registros de chamadas.
Não criar relatórios que façam:
SELECT * FROM calls;
Implementar:
- paginação;
- índices;
- filtros;
- agregações;
- query plans razoáveis.
Avaliar particionamento temporal posteriormente para:
calls
call_events
queue_events
audit_logs
Não precisa particionar prematuramente se não houver necessidade, mas documentar estratégia de crescimento.
55. SEGURANÇA DE SEGREDOS
Criar:
.env
.env.example
.env obrigatoriamente em .gitignore.
Segredos:
- PostgreSQL;
- Redis;
- JWT;
- encryption key;
- AMI;
- ARI;
- SIP;
- SMTP.
Nunca commitar.
Nunca imprimir em logs.
Credenciais de trunk devem ser criptografadas em repouso quando forem mantidas pelo aplicativo.
Utilizar AES-256-GCM ou mecanismo equivalente com master key externa ao banco.
56. FIREWALL
Configurar firewall utilizando nftables ou abordagem adequada ao Debian 13.
Princípio:
default deny para serviços administrativos/telefônicos sensíveis.
Permitir SIP no Asterisk somente de:
- OpenSIPS autorizado;
- operadoras privadas;
- redes explicitamente configuradas.
AMI:
somente aplicação.
ARI:
somente aplicação.
PostgreSQL:
somente containers/localhost necessário.
Redis:
somente containers.
Não bloquear SSH durante a instalação.
57. HTTP SECURITY
Implementar:
- Content Security Policy;
- X-Content-Type-Options;
- Referrer-Policy;
- HSTS quando HTTPS;
- CORS restritivo;
- CSRF quando necessário;
- Helmet ou equivalente;
- input validation;
- DTO validation.
Não confiar em entrada do usuário.
58. SQL SECURITY
Nunca concatenar SQL manualmente com dados fornecidos pelo usuário.
Utilizar queries parametrizadas/ORM.
Importação de CSV também deve ser tratada como entrada não confiável.
59. ASTERISK CONFIG SECURITY
O editor avançado de configuração é uma área sensível.
Antes de gravar:
- validar seção;
- validar formato;
- impedir path traversal;
- nunca aceitar caminho arbitrário;
- nunca permitir gravar fora de diretórios permitidos;
- criar backup;
- versionar;
- validar;
- reload controlado.
Nunca transformar a interface do Asterisk em uma execução remota de comandos Linux.
60. LOGS
Utilizar logs estruturados JSON no backend.
Campos úteis:
timestamp
level
service
request_id
user_id
campaign_id
call_id
attempt_id
message
Nunca registrar:
- senha;
- SIP password;
- JWT;
- refresh token;
- credencial AMI;
- credencial ARI.
61. CORRELATION ID
Cada request HTTP deve possuir:
request_id
Cada tentativa:
attempt_id
Cada chamada:
call_id
Relacionar com:
Asterisk UNIQUEID
Asterisk LINKEDID
Isso será fundamental para troubleshooting.
62. HEALTH CHECKS
Criar:
/api/health
/api/health/live
/api/health/ready
Verificar:
- API;
- PostgreSQL;
- Redis;
- AMI;
- Asterisk.
Dashboard administrativo deve mostrar:
API OK
Postgres OK
Redis OK
Asterisk OK
AMI OK
63. BACKUP
Criar scripts/documentação para backup de:
- PostgreSQL;
- configurações Asterisk;
.envde maneira segura;- uploads relevantes.
Adicionar procedimento de restore.
64. TESTES
Criar testes reais.
Unit tests
Principalmente:
- predictive engine;
- CPS limiter;
- permissions;
- phone normalization;
- retry strategy;
- state machines;
- TME/TMA;
- scheduling.
Integration
- PostgreSQL;
- Redis;
- repositories;
- API;
- AMI adapter mockado.
E2E
Pelo menos:
login
criar agente
criar ramal
criar fila
criar trunk
criar campanha
importar CSV
iniciar campanha em modo simulado
pausar campanha
relatórios
RBAC
65. MODO DE SIMULAÇÃO
Criar um recurso muito importante:
DIALER_SIMULATION=true
Neste modo:
NÃO realizar chamadas externas.
Simular:
ANSWER
BUSY
NO ANSWER
ANSWER DELAY
TALK TIME
Isso permitirá testar o predictive engine sem gerar milhares de chamadas reais.
Criar testes utilizando esse modo.
66. TESTE DO PREDICTIVE ENGINE
Criar simulador com, por exemplo:
20 agentes
10 CPS
30% answer rate
10 segundos answer delay
180 segundos TMA
Verificar:
- pacing;
- disponibilidade;
- abandono;
- CPS;
- estabilização.
Gerar logs/estatísticas.
O motor não pode oscilar violentamente.
67. GIT
Inicializar Git em:
/opt/b2bcall
Criar .gitignore.
Commits organizados por etapas.
Exemplos:
feat: bootstrap b2bcall architecture
feat: add authentication and RBAC
feat: add asterisk pjsip integration
feat: add call center queues
feat: add campaign management
feat: implement predictive dialing engine
feat: add realtime monitoring
feat: add call reports
feat: add security hardening
test: add predictive dialer simulation
Nunca versionar segredos.
68. DOCUMENTAÇÃO
Criar:
README.md
docs/ARCHITECTURE.md
docs/INSTALL.md
docs/ASTERISK.md
docs/OPENSIPS.md
docs/PREDICTIVE_DIALER.md
docs/DATABASE.md
docs/SECURITY.md
docs/OPERATIONS.md
docs/BACKUP_RESTORE.md
docs/API.md
docs/TROUBLESHOOTING.md
CHANGELOG.md
69. TODO OPERACIONAL
Durante o desenvolvimento mantenha:
TODO.md
Exemplo:
[x] Docker
[x] PostgreSQL
[x] Redis
[x] Authentication
[x] RBAC
[x] Asterisk
[x] Extensions
[x] Trunks
[ ] Queues
[ ] Agents
[ ] Campaigns
[ ] Predictive Engine
Quando terminar um item:
- testar;
- marcar
[x]; - continuar para o próximo.
Não utilize o TODO como desculpa para deixar funcionalidades incompletas.
No final, nenhum requisito principal deste documento deve permanecer pendente.
70. BOOTSTRAP DO SUPER ADMIN
Na primeira instalação criar um usuário super_admin.
Nunca utilizar senha padrão como:
admin
123456
password
Gerar senha aleatória forte.
Mostrar apenas uma vez ao final da instalação.
Idealmente criar:
/opt/b2bcall/FIRST_LOGIN.txt
com:
chmod 600
Orientar que o arquivo seja removido após primeiro acesso.
Forçar troca da senha no primeiro login.
71. SEED
Criar seed inicial contendo:
- permissões;
- perfil super_admin;
- admin;
- supervisor;
- agent;
- motivos básicos de pausa;
- disposições padrão.
Mas tudo deve poder ser alterado posteriormente.
72. NÃO CRIAR DADOS FAKE EM PRODUÇÃO
Dados demonstrativos somente quando:
SEED_DEMO_DATA=true
Por padrão:
false
Dashboard de produção nunca deve apresentar números inventados.
73. UX DE ERROS
Não mostrar ao usuário:
500 Internal Server Error
sem contexto.
Mostrar mensagem amigável e gerar:
request_id
para suporte técnico.
No log técnico, manter detalhes.
74. PERFORMANCE
Evitar:
- N+1 queries;
- polling desnecessário;
- carregamento completo de tabelas;
- processamento pesado dentro de HTTP request;
- bloqueio do event loop;
- originação síncrona de milhares de chamadas.
Utilizar workers.
75. CONTROLE DE CAMPANHA DISTRIBUÍDO
O motor deve impedir dois workers de controlarem simultaneamente a mesma campanha.
Criar distributed lock.
Exemplo conceitual:
dialer:campaign:{id}:lock
com:
- TTL;
- renewal;
- ownership token.
Se worker morrer, outro poderá assumir posteriormente.
76. PAUSA IMEDIATA
Quando administrador clicar:
PAUSAR CAMPANHA
não originar nenhuma nova chamada.
As chamadas já existentes podem continuar.
Em:
STOP
definir comportamento de maneira clara e segura.
Não derrubar ligações de clientes/agentes sem confirmação explícita.
77. MONITORAMENTO DO TRONCO
Monitorar:
- status;
- chamadas atuais;
- CPS atual;
- CPS limite;
- channels limit;
- tentativas;
- falhas;
- congestion;
- SIP response codes quando disponíveis.
Mostrar no dashboard.
78. HANGUP CAUSE
Guardar informações de encerramento.
Normalizar resultados como:
ANSWERED
BUSY
NO_ANSWER
REJECTED
CONGESTION
INVALID_NUMBER
NETWORK_FAILURE
CANCELLED
Mas preservar também o código original recebido do Asterisk/rede.
79. RETRY ENGINE
Criar regras por campanha.
Exemplo:
BUSY -> 15 minutos
NO ANSWER -> 60 minutos
CONGESTION -> 5 minutos
FAILED -> 30 minutos
Limitar quantidade máxima de tentativas.
Permitir personalização.
Nunca rediscagem infinita.
80. HORÁRIO DE CAMPANHA
Scheduler deve impedir discagem fora do período configurado.
Considerar timezone.
Por exemplo:
America/Sao_Paulo
Configurar:
- segunda;
- terça;
- quarta;
- quinta;
- sexta;
- sábado;
- domingo.
Campanha fora do horário:
WAITING_SCHEDULE
81. ARQUITETURA DE FRONTEND
Criar componentes reutilizáveis.
Evitar páginas gigantes com milhares de linhas.
Separar:
components
features
hooks
services
schemas
types
Usar tabelas com:
- busca;
- filtros;
- paginação;
- ordenação;
- loading;
- empty state;
- error state.
82. DESIGN
A aparência deve lembrar sistemas SaaS/Contact Center modernos.
Utilizar:
- sidebar;
- topbar;
- cards;
- tabelas profissionais;
- badges;
- tooltips;
- gráficos;
- skeleton loading;
- dialogs;
- toast notifications.
Evitar aparência de:
- sistema antigo;
- FreePBX clone;
- formulário HTML cru;
- bootstrap antigo.
A identidade visual deve utilizar a logo do B2BCall.
Criar light/dark mode se não prejudicar o desenvolvimento.
83. API
Utilizar REST bem estruturada inicialmente.
Exemplos:
/api/auth
/api/users
/api/roles
/api/permissions
/api/extensions
/api/trunks
/api/dialplans
/api/agents
/api/queues
/api/pause-reasons
/api/campaigns
/api/campaigns/:id/leads
/api/campaigns/:id/start
/api/campaigns/:id/pause
/api/campaigns/:id/stop
/api/reports/calls
/api/reports/agents
/api/monitoring/extensions
/api/monitoring/queues
/api/monitoring/campaigns
/api/asterisk
/api/compliance
/api/audit
Gerar OpenAPI/Swagger.
Swagger administrativo deve poder ser desabilitado em produção.
84. VALIDATION
Usar validação forte de schemas/DTO.
Exemplo:
CPS:
>= 1
Telefone:
validar e normalizar.
Datas:
validar timezone.
UUID:
validar.
IDs fornecidos pelo usuário nunca devem ser confiados sem validação.
85. MIGRATIONS
Nenhuma alteração de banco manual sem migration.
Criar comandos:
npm run db:migrate
npm run db:seed
ou equivalentes.
86. DEPLOYMENT
Criar script:
scripts/install.sh
para servidor Debian 13 limpo.
Ele deve:
- verificar permissões;
- instalar dependências;
- instalar Docker;
- instalar Compose plugin;
- criar diretórios;
- gerar secrets;
- preparar
.env; - buildar containers;
- iniciar PostgreSQL/Redis;
- executar migrations;
- iniciar Asterisk;
- iniciar API/workers/frontend;
- executar health checks;
- mostrar resultado.
Também criar:
scripts/update.sh
scripts/backup.sh
scripts/restore.sh
scripts/healthcheck.sh
87. NGINX / REVERSE PROXY
Criar reverse proxy.
Expor para a LAN preferencialmente apenas:
80
443
WebSocket precisa funcionar corretamente.
Preparar suporte HTTPS.
Se nenhum domínio/certificado estiver disponível inicialmente, documentar como ativar certificado posteriormente.
Não inventar domínio.
88. RESTART SEGURO
Restart da API não deve destruir campanhas.
Estado importante sempre no:
- PostgreSQL;
- Redis quando apropriado.
Ao reiniciar worker:
- recuperar campanhas RUNNING;
- reconciliar chamadas;
- limpar reservations expiradas;
- reassumir locks;
- continuar operação corretamente.
89. OBSERVABILIDADE
Criar no mínimo:
- logs estruturados;
- health checks;
- métricas internas.
Preparar endpoint Prometheus:
/metrics
Métricas úteis:
b2bcall_calls_total
b2bcall_calls_answered_total
b2bcall_calls_abandoned_total
b2bcall_campaign_cps
b2bcall_agents_available
b2bcall_agents_busy
b2bcall_agents_paused
b2bcall_queue_waiting
b2bcall_dialer_active_calls
Pode adicionar outras.
90. REQUISITOS DE ACEITE
O projeto NÃO está terminado enquanto eu não conseguir realizar, pela interface:
- fazer login;
- cadastrar usuário;
- cadastrar perfil;
- alterar permissões;
- cadastrar ramal;
- visualizar seu status;
- cadastrar trunk;
- cadastrar dialplan;
- cadastrar fila;
- cadastrar agente;
- associar agente a fila;
- cadastrar pausa;
- logar como agente;
- colocar agente em pausa;
- retirar pausa;
- cadastrar campanha;
- configurar CPS;
- importar CSV;
- iniciar campanha;
- pausar campanha;
- visualizar discagem;
- visualizar agentes;
- visualizar fila;
- visualizar TME;
- visualizar TMA;
- pesquisar chamadas;
- filtrar por ramal;
- filtrar por fila;
- exportar relatório;
- administrar configurações necessárias do Asterisk;
- consultar audit log.
91. ACEITE DO DIALER
Além da interface, provar através de teste/simulação que:
configured CPS = 5
não origina mais de 5 novas chamadas em qualquer janela apropriada de 1 segundo.
Provar que:
campaign max concurrent = 20
não ultrapassa 20 chamadas simultâneas.
Provar que:
- lead não é discado duas vezes simultaneamente;
- campanha pausada não gera novas chamadas;
- worker reiniciado recupera operação;
- pacing cai quando abandono sobe;
- lead bloqueado não é chamado;
- campanha fora do horário não chama.
92. ACEITE DE SEGURANÇA
Verificar:
- nenhuma senha no Git;
- nenhum
.envcommitado; - PostgreSQL não público;
- Redis não público;
- AMI não público;
- ARI não público;
- rate limit funcionando;
- RBAC funcionando no backend;
- usuário agent não acessa configuração Asterisk;
- agent não consegue elevar a própria permissão;
- SQL injection protegida;
- path traversal protegido;
- logs sem credenciais.
93. ACEITE ASTERISK
Executar e documentar resultado de:
asterisk -rx "core show version"
asterisk -rx "core show uptime"
asterisk -rx "pjsip show endpoints"
asterisk -rx "pjsip show contacts"
asterisk -rx "queue show"
Validar comunicação:
API -> AMI -> Asterisk
94. QUALITY GATE
Antes de declarar terminado:
Executar:
lint
typecheck
unit tests
integration tests
e2e tests
docker compose config
docker compose ps
health checks
Corrigir erros.
Não simplesmente informar que existem erros conhecidos.
95. README FINAL
No final atualizar README com:
B2BCall
Architecture
Requirements
Installation
First Login
Configuration
OpenSIPS Integration
Trunks
Agents
Queues
Campaigns
Predictive Dialer
Reports
Backup
Update
Troubleshooting
96. RELATÓRIO FINAL DA IMPLEMENTAÇÃO
Somente depois de efetivamente terminar, apresentar um resumo contendo:
B2BCall version:
Asterisk version:
Node version:
PostgreSQL version:
Docker version:
Containers:
...
URLs:
...
Super admin:
...
Health:
...
Tests:
...
Pending:
...
Se existir algo pendente, explicar claramente.
97. DECISÕES TÉCNICAS IMPORTANTES
Tenha especialmente em mente:
Asterisk não é banco de negócio
O estado de campanhas/leads/agentes deve estar no PostgreSQL.
Redis não é fonte permanente
Informações importantes devem sobreviver à perda do Redis.
AMI events são assíncronos
Não presuma que Originate HTTP concluído significa chamada completada.
LINKEDID é importante
Uma chamada poderá possuir múltiplos canais Asterisk.
Calls devem possuir ID próprio
Não utilize UNIQUEID do Asterisk como primary key de negócio.
WebSocket é para visualização
O banco continua sendo fonte persistente.
O predictive dialer precisa ser controlável
Sempre permitir:
PAUSE
DRAIN
STOP
Segurança deve existir desde a arquitetura
Não adicionar segurança apenas no final.
98. PRIMEIRA TAREFA
Comece AGORA.
Primeiro:
cd /opt/b2bcall
Analise:
pwd
ls -lah
cat /etc/os-release
uname -a
ip addr
df -h
free -h
Verifique a existência:
/opt/b2bcall/b2bcall.png
Depois crie:
docs/ARCHITECTURE.md
TODO.md
Defina a arquitetura inicial.
Em seguida inicialize o Git e comece efetivamente a implantação.
NÃO pare após criar os documentos.
Continue imediatamente para:
Docker
↓
PostgreSQL
↓
Redis
↓
Asterisk
↓
Backend
↓
Authentication
↓
RBAC
↓
Telefonia
↓
Call Center
↓
Campanhas
↓
Predictive Dialer
↓
Frontend
↓
Monitoring
↓
Reports
↓
Security
↓
Tests
↓
Production validation
Trabalhe até alcançar os critérios de aceite.
99. PRINCÍPIO FINAL
Este projeto será usado como uma plataforma real de Call Center.
Portanto, sempre prefira:
correto > rápido
seguro > conveniente
transacional > improvisado
observável > caixa-preta
configurável > hardcoded
testado > presumido
Não entregue apenas uma demonstração.
Construa o B2BCall como uma aplicação que possa realmente evoluir para produção.