Files
b2bcall/agente.md
B2BCall Bootstrap 8d522e93a3 feat: bootstrap b2bcall architecture
- 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
2026-08-27 10:17:07 -03:00

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:

  1. analisar o servidor;
  2. preparar o ambiente;
  3. instalar Docker e dependências necessárias;
  4. criar a estrutura do projeto;
  5. criar os containers;
  6. configurar PostgreSQL;
  7. configurar Redis se necessário;
  8. instalar/configurar Asterisk;
  9. construir backend;
  10. construir frontend;
  11. construir o motor do discador;
  12. integrar o backend ao Asterisk;
  13. implementar autenticação;
  14. implementar RBAC/permissões;
  15. implementar todas as telas solicitadas;
  16. implementar métricas;
  17. implementar relatórios;
  18. implementar monitoramento em tempo real;
  19. implementar auditoria;
  20. implementar segurança;
  21. criar migrations;
  22. criar testes;
  23. executar os testes;
  24. corrigir os problemas encontrados;
  25. subir o ambiente;
  26. validar os health checks;
  27. documentar;
  28. 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:

  1. gerar nova configuração;
  2. validar;
  3. manter backup;
  4. tentar reload seguro;
  5. verificar resultado;
  6. caso inválido, não ativar;
  7. 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:

  1. upload;
  2. detectar delimitador;
  3. preview;
  4. mapear colunas;
  5. validar;
  6. normalizar telefones;
  7. detectar duplicados;
  8. 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;
  • .env de 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:

  1. verificar permissões;
  2. instalar dependências;
  3. instalar Docker;
  4. instalar Compose plugin;
  5. criar diretórios;
  6. gerar secrets;
  7. preparar .env;
  8. buildar containers;
  9. iniciar PostgreSQL/Redis;
  10. executar migrations;
  11. iniciar Asterisk;
  12. iniciar API/workers/frontend;
  13. executar health checks;
  14. 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:

  1. fazer login;
  2. cadastrar usuário;
  3. cadastrar perfil;
  4. alterar permissões;
  5. cadastrar ramal;
  6. visualizar seu status;
  7. cadastrar trunk;
  8. cadastrar dialplan;
  9. cadastrar fila;
  10. cadastrar agente;
  11. associar agente a fila;
  12. cadastrar pausa;
  13. logar como agente;
  14. colocar agente em pausa;
  15. retirar pausa;
  16. cadastrar campanha;
  17. configurar CPS;
  18. importar CSV;
  19. iniciar campanha;
  20. pausar campanha;
  21. visualizar discagem;
  22. visualizar agentes;
  23. visualizar fila;
  24. visualizar TME;
  25. visualizar TMA;
  26. pesquisar chamadas;
  27. filtrar por ramal;
  28. filtrar por fila;
  29. exportar relatório;
  30. administrar configurações necessárias do Asterisk;
  31. 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 .env commitado;
  • 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.