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

3535 lines
48 KiB
Markdown

# 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 é:
```text
/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:
```text
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 é:
```text
INTERNET
|
[ OpenSIPS ]
|
rede SIP privada
|
[ Asterisk ]
|
[ B2BCall ]
```
E para operadoras:
```text
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:
```text
public/application
asterisk
```
ou configuração equivalente.
---
# 7. INTEGRAÇÃO ASTERISK
O backend deve possuir uma camada:
```text
TelephonyProvider
```
e implementação:
```text
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:
```text
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:
```text
if user.role == admin
```
Criar:
```text
users
roles
permissions
user_roles
role_permissions
```
Perfis iniciais:
```text
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:
```text
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:
```text
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:
```text
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:
```text
┌──────────────────┐
│ RAMAL 1001 │
│ João Silva │
│ DISPONÍVEL │
│ 00:04:32 │
└──────────────────┘
```
Utilizar EXATAMENTE esta convenção principal:
```text
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:
```text
PAUSA
EM CHAMADA
AGENTE LOGADO
REGISTRADO/DISPONÍVEL
OFFLINE
```
Ou seja:
```text
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:
```text
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:
```text
Agente
Ramal
Fila
Campanha
Estado
Tempo no estado
Chamada atual
Telefone
Nome do lead
```
Botões:
```text
DISPONÍVEL
PAUSA
FINALIZAR PAUSA
```
Quando clicar em PAUSA, abrir os motivos cadastrados.
Exemplo:
```text
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:
```text
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:
```text
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:
```text
Context
Extension
Priority
Application
Arguments
Enabled
Order
```
Por exemplo:
```text
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:
```text
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:
```text
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:
```text
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:
```text
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:
```text
DRAFT
READY
RUNNING
PAUSED
DRAINING
STOPPED
COMPLETED
```
Botões:
```text
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:
```text
campaign.max_cps
```
Cada trunk também:
```text
trunk.max_cps
```
O limite real deve ser:
```text
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:
```text
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:
```text
custom_fields JSONB
```
Status possíveis:
```text
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:
```csv
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:
```text
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:
```text
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:
```text
suppression_list
```
Permitir:
* adicionar manualmente;
* importar CSV;
* pesquisar;
* remover com permissão;
* informar motivo;
* auditoria.
Antes de originar:
```text
CHECK SUPPRESSION
```
obrigatoriamente.
---
# 30. MOTOR DO DISCADOR PREDITIVO
Este é um dos componentes MAIS IMPORTANTES do projeto.
NÃO implemente simplesmente:
```text
for lead:
originate()
```
Isso NÃO é discador preditivo.
Criar um serviço:
```text
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:
```text
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:
```text
expected_agent_supply =
agentes_disponiveis
+
agentes_com_probabilidade_de_liberacao_no_horizonte
```
Depois estimar:
```text
expected_answers = calls_to_dial * answer_probability
```
e ajustar para que:
```text
expected_answers ~= capacidade prevista de agentes
```
Adicionar multiplicador:
```text
pacing_factor
```
Porém sempre respeitando:
```text
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:
```text
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:
```text
docs/PREDICTIVE_DIALER.md
```
---
# 33. CONTROLE DE ABANDONO
O motor deve possuir proteção contra abandono excessivo.
Se:
```text
abandon_rate > target_abandon_rate
```
o pacing deve cair automaticamente.
Se subir muito:
```text
pacing -> modo conservador
```
Se necessário:
```text
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:
```text
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:
```sql
SELECT ...
FOR UPDATE SKIP LOCKED
```
ou solução equivalente.
Transição:
```text
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:
```text
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:
```text
CREATED
RESERVED
ORIGINATING
RINGING
ANSWERED
QUEUED
AGENT_CONNECTED
COMPLETED
FAILED
```
Persistir as transições relevantes.
---
# 37. CALL FLOW PREDITIVO
Fluxo esperado:
```text
Lead
PredictiveDialer
CPS limiter
Asterisk Originate
Trunk
Destino
```
Quando a chamada atende:
```text
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:
```text
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:
```text
wrap_up_time
```
Durante wrap-up o agente não deve ser tratado pelo predictive engine como imediatamente disponível.
Mostrar estado:
```text
WRAP UP
```
e tempo restante.
---
# 40. DISPOSIÇÃO DA CHAMADA
Após atendimento, permitir ao agente classificar a ligação.
Exemplos:
```text
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:
```text
CALLBACK
-> solicitar data/hora
```
```text
DO_NOT_CALL
-> adicionar automaticamente à suppression_list
```
---
# 41. CALLBACK
Permitir agendar retorno.
Campos:
```text
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:
```text
para qualquer agente
```
ou:
```text
preferencialmente para o mesmo agente
```
---
# 42. CDR / HISTÓRICO DE CHAMADAS
Criar modelo consolidado próprio.
Capturar:
```text
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:
```text
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:
```text
agent_answer_at - queue_enter_at
```
para chamadas atendidas.
Separadamente mostrar:
```text
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:
```text
SUM(talk_time) / answered_calls
```
Permitir futuramente visualizar:
```text
Talk Time
Talk + Wrap-Up
```
como indicadores separados.
---
# 46. DASHBOARD
Criar um dashboard moderno.
Cards principais:
```text
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:
```text
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:
```text
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:
```text
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:
```text
Tempo logado
Tempo disponível
Tempo em chamada
Tempo pausado
Tempo wrap-up
Chamadas atendidas
TMA
```
Detalhar pausas:
```text
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:
```text
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:
```text
/opt/b2bcall/b2bcall.png
```
Copiar/processar para o diretório apropriado do frontend.
Não modificar a logo original.
Menu sugerido:
```text
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:
```text
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:
```text
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:
```sql
SELECT * FROM calls;
```
Implementar:
* paginação;
* índices;
* filtros;
* agregações;
* query plans razoáveis.
Avaliar particionamento temporal posteriormente para:
```text
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:
```text
.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:
```text
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:
```text
request_id
```
Cada tentativa:
```text
attempt_id
```
Cada chamada:
```text
call_id
```
Relacionar com:
```text
Asterisk UNIQUEID
Asterisk LINKEDID
```
Isso será fundamental para troubleshooting.
---
# 62. HEALTH CHECKS
Criar:
```text
/api/health
/api/health/live
/api/health/ready
```
Verificar:
* API;
* PostgreSQL;
* Redis;
* AMI;
* Asterisk.
Dashboard administrativo deve mostrar:
```text
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:
```text
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:
```text
DIALER_SIMULATION=true
```
Neste modo:
**NÃO realizar chamadas externas.**
Simular:
```text
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:
```text
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:
```text
/opt/b2bcall
```
Criar `.gitignore`.
Commits organizados por etapas.
Exemplos:
```text
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:
```text
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:
```text
TODO.md
```
Exemplo:
```text
[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:
```text
admin
123456
password
```
Gerar senha aleatória forte.
Mostrar apenas uma vez ao final da instalação.
Idealmente criar:
```text
/opt/b2bcall/FIRST_LOGIN.txt
```
com:
```bash
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:
```text
SEED_DEMO_DATA=true
```
Por padrão:
```text
false
```
Dashboard de produção nunca deve apresentar números inventados.
---
# 73. UX DE ERROS
Não mostrar ao usuário:
```text
500 Internal Server Error
```
sem contexto.
Mostrar mensagem amigável e gerar:
```text
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:
```text
dialer:campaign:{id}:lock
```
com:
* TTL;
* renewal;
* ownership token.
Se worker morrer, outro poderá assumir posteriormente.
---
# 76. PAUSA IMEDIATA
Quando administrador clicar:
```text
PAUSAR CAMPANHA
```
não originar nenhuma nova chamada.
As chamadas já existentes podem continuar.
Em:
```text
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:
```text
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:
```text
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:
```text
America/Sao_Paulo
```
Configurar:
* segunda;
* terça;
* quarta;
* quinta;
* sexta;
* sábado;
* domingo.
Campanha fora do horário:
```text
WAITING_SCHEDULE
```
---
# 81. ARQUITETURA DE FRONTEND
Criar componentes reutilizáveis.
Evitar páginas gigantes com milhares de linhas.
Separar:
```text
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:
```text
/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:
```text
>= 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:
```bash
npm run db:migrate
npm run db:seed
```
ou equivalentes.
---
# 86. DEPLOYMENT
Criar script:
```text
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:
```text
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:
```text
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:
```text
/metrics
```
Métricas úteis:
```text
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:
```text
configured CPS = 5
```
não origina mais de 5 novas chamadas em qualquer janela apropriada de 1 segundo.
Provar que:
```text
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:
```text
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:
```text
API -> AMI -> Asterisk
```
---
# 94. QUALITY GATE
Antes de declarar terminado:
Executar:
```text
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:
```text
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:
```text
PAUSE
DRAIN
STOP
```
### Segurança deve existir desde a arquitetura
Não adicionar segurança apenas no final.
---
# 98. PRIMEIRA TAREFA
Comece AGORA.
Primeiro:
```bash
cd /opt/b2bcall
```
Analise:
```bash
pwd
ls -lah
cat /etc/os-release
uname -a
ip addr
df -h
free -h
```
Verifique a existência:
```text
/opt/b2bcall/b2bcall.png
```
Depois crie:
```text
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:
```text
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:
```text
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.